--- /dev/null
+Àî¹çƲ¥é¥¤¥»¥ó¥¹-01 ver.1.0
+ 2000.12.30 H.Kawai (Àî¹ç½¨¼Â)
+ 2007.10.07 ¥ê¥ó¥¯½¤Àµ:¤¢¤Ã¤¤£
+
+£°¡¥³µÍ×
+
+ Ê¿¤¿¤¯¸À¤¦¤È¡¢¡Ö¥Õ¥ê¡¼¥½¥Õ¥È¤Ç¤¹¡£»ÈÍÑÁ°»ÈÍѸå¤ËÂвÁ¤ò»Ùʧ¤¦¤³¤È¤Ê¤¯¡¢¼«Í³¤Ë»È
+¤¨¤Þ¤¹¡£¥³¥Ô¡¼¤·¤Æ¤â¤¤¤¤¤Ç¤¹¡£²þÊѤ·¤Æ¤â¤¤¤¤¤Ç¤¹¡£¾¦¶ÈÍøÍѤ·¤Æ¤â¤¤¤¤¤Ç¤¹¡£¤Ç¤â¥Ð
+¥°¤Ê¤É¤Ç»³²¤¬½Ð¤Æ¤âÀÕǤ¤Ï¤È¤ì¤Þ¤»¤ó¡£¡×¤Ã¤Æ¤³¤È¤Ç¤¹¡£
+
+ ÍøÍѼԤä²þÊѤ·¤¿¤ê»²¹Í¤Ë¤·¤¿¤ê¤¹¤ë¿Í¤ÎÍø±×¤Î¤¿¤á¤Ë¡¢¥×¥í¥°¥é¥àÃæ¤Ç»È¤Ã¤Æ¤¤¤ë¥¢
+¥ë¥´¥ê¥º¥à¤ÇÃøºî¼Ô¤¬¾ÍèÆõö¤ò¤È¤ë¤³¤È¤¬¤¢¤Ã¤Æ¤â¡¢ÆõöÎÁ¤òÍ׵ᤷ¤¿¤ê¤Ï¤·¤Ê¤¤¤È¤¤
+¤¦Êݾڤ⤢¤ê¤Þ¤¹¡£
+
+£±¡¥ÌÜŪ
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤ÇÄ󶡤µ¤ì¤ë¥½¥Õ¥È¥¦¥§¥¢¤Ï¡¢¾¯¤·¤Ç¤â¿¤¯¤Î¿Í¤ËÍø±×¤ò¤â¤¿¤é¤·¡¢¥½
+¥Õ¥È¥¦¥§¥¢µ»½Ñ¤Î¿ÊÊâ¤Ë¾¯¤·¤Ç¤â¹×¸¥¤Ç¤¤ì¤Ð¤È¤¤¤¦ÌÜŪ¤Ç¸ø³«¤¹¤ë¡£
+
+£²¡¥¼ñ»Ý
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤Ï¡¢Ãøºî¸¢¤òÊü´þ¤¹¤ë¤â¤Î¤Ç¤Ï¤Ê¤¤¡ÊÆÈÀêŪ¤Ë¥³¥Ô¡¼¤¹¤ë¸¢Íø¤ÏÊü´þ¤·
+¤Æ¤¤¤ë¡Ë¡£ÍøÍѼԤϤ³¤Î¥½¥Õ¥È¥¦¥§¥¢¤Î°ìÉô¤Þ¤¿¤ÏÁ´Éô¤ò¼«Í³¤Ë¥³¥Ô¡¼¤·¡¢ºÆÇÛÉÛ¤¹¤ë¤³
+¤È¤¬¤Ç¤¤ë¡£ÍøÍѤ˺ݤ·¤ÆÂвÁ¤òÍ׵ᤷ¤Ê¤¤¡£²òÀÏ¡¢²þÊѤâÂвÁ¤Ê¤·¤Ëǧ¤á¤ë¡£
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤¬Å¬ÍѤµ¤ì¤ë¥½¥Õ¥È¥¦¥§¥¢¤ÎÍøÍѤˤĤ¤¤Æ¡¢¾¦¶ÈŪ¤ÊÍøÍѤâ̵¾ò·ï¤Çǧ
+¤á¤ë¡£¤½¤Î¤Þ¤Þͽþ¤ÇÈÎÇ䤷¤Æ¤â¹½¤ï¤Ê¤¤¡£
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤¬Å¬ÍѤµ¤ì¤ë¥½¥Õ¥È¥¦¥§¥¢¤Î°ìÉô¤Þ¤¿¤ÏÁ´Éô¤ò¸µ¤Ë¤·¤ÆºîÀ®¤µ¤ì¤¿¥½¥Õ
+¥È¥¦¥§¥¢¡Ê°Ê¹ß¡¢ÇÉÀ¸Êª¤È¾Î¤¹¤ë¡Ë¤ËÂФ·¡¢¤É¤ó¤Ê¥é¥¤¥»¥ó¥¹¤òÉÕÍ¿¤·¤Æ¤â¤è¤¤¡£¤¹¤Ê¤ï
+¤Á¡¢ÇÉÀ¸Êª¤¬¥³¥Ô¡¼¶Ø»ß¤Ç¤¢¤Ã¤Æ¤â¤è¤¤¤·¡¢ÇÉÀ¸Êª¤¬Í½þ¤Ç¤·¤«ÇÛÉÛ¤µ¤ì¤Ê¤¯¤Æ¤â¹½¤ï¤Ê
+¤¤¡£¤â¤Á¤í¤ó̵½þ¤Ç¤¢¤Ã¤Æ¤â¤è¤¤¡£ÇÉÀ¸Êª¤ËÂФ¹¤ëÃøºî¸¢¤Ï¡¢ÇÉÀ¸Êª¤òÀ¸À®¤·¤¿¼Ô¤Ëµ¢¤·
+¡¢¤³¤Î¥é¥¤¥»¥ó¥¹¤¬Å¬ÍѤµ¤ì¤ë¥½¥Õ¥È¥¦¥§¥¢¤ÎÃøºî¼Ô¤¬ÇÉÀ¸Êª¤ËÂФ·¤ÆÃøºî¸¢¤ò¼çÄ¥¤¹¤ë
+¤³¤È¤Ï¤Ê¤¤¡£
+
+ ÇÉÀ¸Êª¤Î¥É¥¥å¥á¥ó¥ÈÃæ¤Ë¡¢¸µ¤Ë¤·¤¿¥½¥Õ¥È¥¦¥§¥¢¤ÎÃøºî¼Ô¤ò¾Ò²ð¤¹¤ëµÁ̳¤Ï¤Ê¤¤¡£¤³
+¤Îʸ¤Ï¡¢¤â¤Á¤í¤ó¡¢¾Ò²ð¤¹¤ë¤³¤È¤ò¶Ø»ß¤¹¤ë¤â¤Î¤Ç¤â¤Ê¤¤¡£
+
+ ÇÉÀ¸Êª¤Î¸ø³«¤ËºÝ¤·¤Æ¡¢¸µ¤Ë¤·¤¿¥½¥Õ¥È¥¦¥§¥¢¤ÎÃøºî¼Ô¤Ë³Îǧ¤ò¼è¤ëµÁ̳¤Ï¤Ê¤¤¡£¤³¤Î
+ʸ¤Ï¡¢¤â¤Á¤í¤ó¡¢³Îǧ¤ò¶Ø»ß¤¹¤ë¤â¤Î¤Ç¤Ï¤Ê¤¤¡£
+
+ Ãøºî¼Ô¤Ï¡¢¥½¥Õ¥È¥¦¥§¥¢¤Î¼Á¤òÊݾڤ·¤Ê¤¤¡£¤·¤¿¤¬¤Ã¤Æ¡¢¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤ÇÈï³²¤òÈï
+¤Ã¤¿¤ê¡¢´üÂÔ¤·¤¿·ë²Ì¤¬ÆÀ¤é¤ì¤Ê¤¯¤Æ¤â¡¢Ãøºî¼Ô¤ÏÀÕǤ¤òÉé¤ï¤Ê¤¤¡£
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤¬Å¬ÍѤµ¤ì¤ë¥½¥Õ¥È¥¦¥§¥¢¤Ç»È¤ï¤ì¤Æ¤¤¤ëµ»½Ñ¤Ë¤Ä¤¤¤Æ¤Ï¡¢»öÁ°¤ËÃøºî
+¼Ô¤Ëµö¤µ¤ì¤¿¼Ô°Ê³°¤¬Æõö¤ò¼èÆÀ¤¹¤ë¤³¤È¤Ï¶Ø»ß¤¹¤ë¡£¿·¤¿¤Êµ»½Ñ¤ò²Ã¤¨¤¿ÇÉÀ¸Êª¤òÀ¸À®
+¤·¡¢¤½¤ÎÄɲ䵤줿Éôʬ¤ÎÆõö¤ò¤È¤ë¤³¤È¤Ïǧ¤á¤ë¡£Ãøºî¼Ô¤¬¥½¥Õ¥È¥¦¥§¥¢Ãæ¤Îµ»½Ñ¤ËÂÐ
+¤·¤Æ¸å¤«¤éÆõö¤ò¤È¤ë¤³¤È¤Ï¤¢¤ê¤¦¤ë¤¬¡¢ÇÉÀ¸Êª¤ä¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤ÎÍøÍѤËÂФ·¤ÆÆõö
+ÎÁ¤ä¤½¤Î¾¤ÎÂвÁ¤òµá¤á¤ë¤³¤È¤Ï¤Ê¤¤¤³¤È¤òÊݾڤ¹¤ë¡£¤³¤ÎÊݾڤϡ¢Æõö¼èÆÀÁ°¤ËÀ¸À®¤µ
+¤ì¤¿ÇÉÀ¸Êª¤À¤±¤Ç¤Ê¤¯¡¢Æõö¼èÆÀ¸å¤ËÀ¸À®¤µ¤ì¤¿ÇÉÀ¸Êª¤Ë¤âŬÍѤµ¤ì¤ë¡£
+
+ ²òÀÏ·ë²Ì¤ò¤Þ¤È¤á¤ÆÆõö¤ò¤È¤ë¤³¤È¤Ë¤Ï»öÁ°¤ÎÃøºî¼Ô¤Îµö²Ä¤¬É¬ÍפÀ¤«¡¢Æõö¤ò¤È¤ë¤³
+¤È°Ê³°¤Ë¤Ä¤¤¤Æ¤Ï²¿¤éÀ©¸Â¤Ï¤Ê¤¤¡£
+
+£³¡¥ÊäÂ
+
+ ´ðËÜŪ¤Ë¡¢¥³¥Ô¡¼¤ÏÂç´¿·Þ¤Ç¤¹¡£¤â¤·¡¢Ãøºî¼Ô¤Ë²¿¤«²¸¤ò´¶¤¸¤¿¤é¡¢°ì¿Í¤Ç¤â¿¤¯¤Î¿Í
+¤Ë¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤ò¤¹¤¹¤á¤Æ¡¢¥³¥Ô¡¼¤·¤Æ¤¢¤²¤Æ²¼¤µ¤¤¡£Ãøºî¼Ô¤Ï¿¤¯¤Î¿Í¤Ë»È¤Ã¤Æ¤â
+¤é¤¤¤¿¤¤¤È»×¤Ã¤Æ¤¤¤ë¤Î¤Ç¡¢¥³¥Ô¡¼¤¹¤ì¤ÐÃøºî¼Ô¤Ï´î¤Ó¤Þ¤¹¡£¤½¤ì¤Ç¤â¤ê¤Ê¤¤¤È´¶¤¸¤¿
+¤é¡¢À§Èó¡¢´¶ÁÛ¤òÃøºî¼Ô¤ËÁ÷¤Ã¤Æ¤¢¤²¤Æ²¼¤µ¤¤¡£¤½¤¦¤¹¤ì¤Ð¡¢¤â¤Ã¤È´î¤Ö¤Ç¤·¤ç¤¦¡£
+
+ ¤³¤ì¤Ç¥é¥¤¥»¥ó¥¹¤µ¤ì¤¿¥½¥Õ¥È¥¦¥§¥¢¤ÎÃøºî¸¢¾ðÊó¤À¤±¤ò²þÊѤ·¡¢¤½¤ì¤òºÆÇÛÉÛ¤¹¤ë¤³
+¤È¤Ï¤³¤Î¥é¥¤¥»¥ó¥¹¤Ë¤è¤Ã¤Æ¶Ø»ß¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£ÇÉÀ¸Êª°·¤¤¤Ç¤¹¡£¤³¤ì¤ÏÈ´¤±·ê¤Ç¤Ï¤Ê
+¤¤¤Ç¤¹¡£¤·¤¿¤¬¤Ã¤Æ¡¢Ãøºî¸¢¾ðÊó¤À¤±¤ò½ñ¤´¹¤¨¤ÆºÆÇÛÉÛ¤¹¤ë¤³¤È¤¬É¬Íפʤ顢¤·¤Æ¤¤¤¿
+¤À¤¤¤Æ¤«¤Þ¤¤¤Þ¤»¤ó¡£
+
+ ¥Ð¥°¤ò¼è¤Ã¤¿¤ê¡¢µ¡Ç½¤òÄɲ䷤Ƥ¤¤¿¤À¤¯¤Î¤Ï¤â¤Á¤í¤ó¤Ç¤¹¤¬¡¢¥×¥í¥°¥é¥à¤ËÃð¼á¤òÉÕ
+¤±¤ÆÆɤߤ䤹¤¯¤·¤¿¤ê¡¢¥É¥¥å¥á¥ó¥È¤òÊ䤹¤ë¤Ê¤É¡¢¤½¤¦¤¤¤¦¥Ð¥¤¥Ê¥ê¡¼¤ä¼Â¹Ô·ë²Ì¤Ë
+È¿±Ç¤µ¤ì¤Ê¤¤¤è¤¦¤Ê²þÊѤâÂç´¿·Þ¤Ç¤¹¡£¤½¤¦¤¤¤¦ÇÉÀ¸Êª¤¬¤Ç¤¤¿¤é¡¢Ï¢Íí¤·¤Æ¤â¤é¤¨¤ë¤È
+¤¦¤ì¤·¤¤¤Ç¤¹¡ÊµÁ̳¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡Ë¡£
+
+ ²¿¤«µ¿ÌäÅÀ¤¬¤¢¤Ã¤¿¤ê¡¢ÇÉÀ¸Êª¤òºîÀ®¤¹¤ë¾å¤Ç¾ðÊó¤¬ÉÔ¤·¤Æ¤¤¤ë¤È´¶¤¸¤¿¤é¡¢Ãøºî¼Ô
+¤ËÏ¢Íí¤ò¤È¤Ã¤Æ¼ÁÌ䤹¤ë¤³¤È¤¬¤Ç¤¤Þ¤¹¡£¤¿¤À¡¢Ãøºî¼Ô¤ÎÅÔ¹ç¤Ç¤¹¤°¤Ë¤ÏÊÖ»ö¤¬¤Ç¤¤Ê¤¤
+¤«¤â¤·¤ì¤Þ¤»¤ó¡£¤½¤ì¤Ï¤´ÍƼϤ¯¤À¤µ¤¤¡£¤³¤Î¥é¥¤¥»¥ó¥¹¤½¤Î¤â¤Î¤ÎÉÔÈ÷¤Ê¤É¤ò»ØŦ¤¹¤ë
+¾ì¹ç¤Ï¡¢Ãøºî¼Ô¤«Àî¹çƲ¤Ë¤´Ï¢Íí¤¯¤À¤µ¤¤¡£
+
+ ¤â¤·¤«¤¹¤ë¤È¡¢¤³¤ì¤Ç¥é¥¤¥»¥ó¥¹¤µ¤ì¤¿¥½¥Õ¥È¥¦¥§¥¢¤ÇÍøÍѤµ¤ì¤Æ¤¤¤ëµ»½Ñ¤Ë¤Ä¤¤¤Æ¡¢
+Ãøºî¼Ô¤Îµö²Ä¤Î̵¤¤¼Ô¤¬Æõö¤ò¼èÆÀ¤¹¤ë¤³¤È¤ò¶Ø¤¸¤Æ¤¤¤ë¤³¤È¤¬¡¢ÆüËܤÎÆõöË¡¤ËÄñ¿¨¤·
+¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡Ê¤´°Õ¸«¤òÂԤäƤ¤¤Þ¤¹¡Ë¡£¤³¤ì¤Ë¤Ä¤¤¤Æ¡¢¥é¥¤¥»¥ó¥¹¤òºÇ½é¤ËÄó
+¾§¤·¤¿Àî¹ç½¨¼Â¤Î¸«²ò¤ò°Ê²¼¤Ë½ñ¤¤¤Æ¤ª¤¤Þ¤¹¡£
+
+ ÆõöË¡¤¬À©Äꤵ¤ì¤¿Çطʤˤϡ¢È¯ÌÀ¼Ô¤¬¼«Ê¬¤ÎȯÌÀ¤Ë¤è¤ëÍø±×¤ò¼é¤ë¤¿¤á¤ËȯÌÀ¤Î¾ÜºÙ
+¤ò¸øɽ¤·¤Ê¤¤¤³¤È¤¬²Ê³Øµ»½Ñ¤Î¿ÊÊâ¤òÃ٤餻¤ë¤«¤é¡¢¸øɽ¤·¤Æ¤â¤é¤¦Âå¤ï¤ê¤Ë°ìÄê´ü´Ö¤Î
+ÆÈÀêÍøÍѤòˡŪ¤ËÊݸ¤ë¡¢¤È¤¤¤¦Àº¿À¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥é¥¤¥»¥ó¥¹¤Ç¤Ï¡¢È¯ÌÀ¤Î¾ÜºÙ¤ò
+°Õ¿ÞŪ¤Ë±£¤¹¤Ä¤â¤ê¤Ï¤Ê¤¯¡¢¤·¤¿¤¬¤Ã¤ÆÆõö¤ò¼è¤ë¤³¤È¤ò¶Ø»ß¤·¤Æ¤âÆõöË¡¤ÎÀº¿À¤Ë¤ÏÈ¿
+¤·¤Æ¤¤¤Ê¤¤¤È¹Í¤¨¤Æ¤¤¤Þ¤¹¡£¤à¤·¤í¡¢¤³¤Î¥é¥¤¥»¥ó¥¹¤ÎÀº¿À¤òµâ¤Þ¤Ê¤¤¼Ô¤¬Æõö¤ò¼èÆÀ¤·
+¥ª¥ê¥¸¥Ê¥ë¤Î¥½¥Õ¥È¥¦¥§¥¢¤äÇÉÀ¸Êª¤ËÂФ·¤ÆÆõöÎÁ¤òÀÁµá¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤É԰¤ÎÊý¤¬¡¢
+²Ê³Øµ»½Ñ¤Î¿ÊÊâ¤òÃ٤餻¤ë¤È¹Í¤¨¤Þ¤¹¡£¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ÎÉ԰¤ò»öÁ°¤Ëʧ¿¡¤·¤¿¤³¤Î¥é¥¤
+¥»¥ó¥¹¤ÏÆõöË¡¤ËŬ¤Ã¤¿¤â¤Î¤À¤È¹Í¤¨¤Æ¤¤¤Þ¤¹¡£
+
+ ¤â¤Á¤í¤ó¡¢°ìÈְ¿´¤Ê¤Î¤Ï¡¢¥ª¥ê¥¸¥Ê¥ë¤Î¥½¥Õ¥È¥¦¥§¥¢¤ÇȯÌÀ¤Èǧ¤á¤é¤ì¤ë¤¹¤Ù¤Æ¤Î¤â
+¤Î¤Ë¤Ä¤¤¤ÆÃøºî¼Ô¤¬Æõö¤ò¼èÆÀ¤·¤Æ¡¢Â¾¼Ô¤ÎÆõö¼èÆÀ¤ò»öÁ°¤Ë˸¤²¤ì¤Ð¤¤¤¤¤Î¤Ç¤¹¤¬¡¢¤½
+¤ì¤ÏÃøºî¼Ô¤Ë¤ÏÉéô¤Ë¤Ê¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¤½¤ÎÉéô¤È¥½¥Õ¥È¥¦¥§¥¢¤ò¸ø³«¤¹¤ë¤«¤É¤¦¤«
+¤òÅ·Çé¤Ë¤«¤±¤Ê¤±¤ì¤Ð¤¤¤±¤Ê¤¤¤È¤·¤¿¤é¡¢¸ø³«¤ò¤¢¤¤é¤á¤Æ¤·¤Þ¤¦¾ì¹ç¤â¤¢¤ë¤«¤â¤·¤ì¤Þ
+¤»¤ó¡£¤½¤ì¤ÏÆõöË¡¤ÎÀº¿À¤Î´üÂÔ¤¹¤ë¤â¤Î¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤·¡¢²æ¡¹¤ÎÌÜŪ¡Ê¡Ö£±¡¥ÌÜŪ¡×
+¤ò»²¾È¡Ë¤Ë¤â±è¤¤¤Þ¤»¤ó¡£
+
+ ¤Þ¤¿¡¢È¯ÌÀ¤Î¾ÜºÙ¤¬ÆõöË¡¤Î·Á¼°¤Ë¤è¤Ã¤Æµ½Ò¤µ¤ì¤Æ¤¤¤Ê¤¤¤¿¤á¤ËÌÀ¤é¤«¤Ç¤Ê¤¤¾ì¹ç¡¢
+Ãøºî¼Ô°Ê³°¤Î¤â¤Î¤¬µö²Ä¤Ê¤¯¤½¤ì¤ò²òÀϤ·¤ÆÌÀ¤é¤«¤Ë¤¹¤ë¤³¤È¤Ï¡¢¤³¤Î¥é¥¤¥»¥ó¥¹¤Çǧ¤á
+¤é¤ì¤Æ¤¤¤Æ¤¤¤Þ¤¹¡£¤½¤ì¤ò̵½þ¤Ç¸ø³«¤·¤Æ¤â¤¤¤¤¤Ç¤¹¤·¡¢Í½þ¤ÇÈÎÇ䤹¤ë¤³¤È¤â¤Ç¤¤Þ¤¹
+¡£
+
+ ¤Ê¤ª¡¢¤³¤ì¤Ç¥é¥¤¥»¥ó¥¹¤µ¤ì¤¿¥½¥Õ¥È¥¦¥§¥¢Ãæ¤Î¤¹¤Ù¤Æ¤Îµ»½Ñ¤ËÂФ·¤Æ¡¢ÍøÍѤ˺ݤ·¤Æ
+ÆõöÎÁ¤ò»Ùʧ¤¦¿´ÇÛ¤¬Á´¤¯Ìµ¤¤¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¸ø³«¤Î»þÅÀ¤Ç͸ú¤ÊÆõö¤Ë¤è¤ëµ»½Ñ
+¤¬¥½¥Õ¥È¥¦¥§¥¢Æâ¤Ç»È¤ï¤ì¤Æ¤¤¤ì¤Ð¡¢¤½¤ì¤Ë¤Ä¤¤¤Æ¤ÏÆõöÊÝ»ý¼Ô¤«¤é¤ÎÆõöÎÁÍ׵᤬¤¢¤ê
+¤¨¤Þ¤¹¡£¤³¤Î¥é¥¤¥»¥ó¥¹¤¬ÆõöÎÁ¤Î¿´ÇÛ̵¤·¤ÈÊݾڤ·¤Æ¤¤¤ë¤Î¤Ï¡¢¤³¤Î¥½¥Õ¥È¥¦¥§¥¢Æâ¤Ç
+¿·¤¿¤ËȯÌÀ¤Èǧ¤á¤é¤ì¤ëµ»½Ñ¤ËÂФ·¤Æ¤Î¤ß¤Ç¤¹¡£
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤ò¼«Ê¬¤Î¥½¥Õ¥È¥¦¥§¥¢¤ËŬÍѤ·¤¿¤¤¤È»×¤¦Êý¤¬¤ª¤é¤ì¤Þ¤·¤¿¤é¡¢»öÁ°¡¦
+»ö¸å¤Ëµö²Ä¤òµá¤á¤ë¤³¤È¤Ê¤¯»È¤Ã¤Æ¤¤¤¿¤À¤¤¤Æ¤«¤Þ¤¤¤Þ¤»¤ó¡£¤â¤·ÉÔÅԹ礬¤¢¤ì¤Ð¡¢¥é¥¤
+¥»¥ó¥¹Ê¸¤ò²þÊѤ·¤Æ»È¤Ã¤Æ¤¤¤¿¤À¤¤¤Æ¤â¤¤¤¤¤Ç¤¹¡£²þÊѤκݤˤϡ¢º®Íð¤òËɤ°¤¿¤á¤Ë¥é¥¤
+¥»¥ó¥¹Ì¾¤òÊѹ¹¤¹¤ë¤Î¤ò˺¤ì¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+£´¡¥¥ê¥ó¥¯
+
+ Àî¹ç½¨¼ÂURL http://k.osask.jp/
+ e-mail kawai@osask.jp
--- /dev/null
+¤³¤Î¥½¥Õ¥È¥¦¥¨¥¢¤Ïºä°æ¹°Î¼¤Ë¤è¤Ã¤ÆºîÀ®¤µ¤ì¤¿¤â¤Î¤Ç¤¢¤ê¡¤KL-01¤ÇÇÛÉÛ¤·¤Þ¤¹¡¥
+KL-01¤Ë¤Ä¤¤¤Æ¤ÏźÉդΠKL-01 ¤«¡¤¤â¤·¤¯¤Ï°Ê²¼¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡¥
+
+http://wiki.osask.jp/?KL-01
+
+°Ê¾å
--- /dev/null
+PREFIX = /usr/local
+ARCH = h8300-elf
+BINDIR = $(PREFIX)/bin
+ADDNAME = $(ARCH)-
+
+AR = $(BINDIR)/$(ADDNAME)ar
+AS = $(BINDIR)/$(ADDNAME)as
+CC = $(BINDIR)/$(ADDNAME)gcc
+LD = $(BINDIR)/$(ADDNAME)ld
+NM = $(BINDIR)/$(ADDNAME)nm
+OBJCOPY = $(BINDIR)/$(ADDNAME)objcopy
+OBJDUMP = $(BINDIR)/$(ADDNAME)objdump
+RANLIB = $(BINDIR)/$(ADDNAME)ranlib
+STRIP = $(BINDIR)/$(ADDNAME)strip
+
+H8WRITE = ../../tools/kz_h8write/kz_h8write
+
+# FreeBSD-4.x:/dev/cuaaX, FreeBSD-6.x:/dev/cuadX, FreeBSD(USB):/dev/cuaUx
+# Linux:/dev/ttySx, Linux(USB):/dev/ttyUSBx, Windows:comX
+H8WRITE_SERDEV = /dev/ttyUSB0
+
+OBJS = vector.o startup.o intr.o main.o interrupt.o
+OBJS += lib.o serial.o xmodem.o elf.o dram.o
+OBJS += led.o
+OBJS += re.o
+OBJS += sw.o
+OBJS += lcd.o
+OBJS += mmc.o pff.o
+OBJS += vs1011e.o
+
+TARGET = kzload
+
+CFLAGS = -Wall -mh -nostdinc -nostdlib -fno-builtin
+#CFLAGS += -mint32 # int¤ò32¥Ó¥Ã¥È¤Ë¤¹¤ë¤È³Ý»»¡¿³ä»»¤¬¤Ç¤¤Ê¤¯¤Ê¤ë
+CFLAGS += -I.
+#CFLAGS += -g
+CFLAGS += -Os
+CFLAGS += -DKZLOAD
+
+LFLAGS = -static -T ld.scr -L. -lgcc
+
+.SUFFIXES: .c .o
+.SUFFIXES: .s .o
+.SUFFIXES: .S .o
+
+all : $(TARGET)
+
+$(TARGET) : $(OBJS)
+ $(CC) $(OBJS) -o $(TARGET) $(CFLAGS) $(LFLAGS)
+ cp $(TARGET) $(TARGET).elf
+ $(STRIP) $(TARGET)
+
+.c.o : $<
+ $(CC) -c $(CFLAGS) $<
+
+.s.o : $<
+ $(CC) -c $(CFLAGS) $<
+
+.S.o : $<
+ $(CC) -c $(CFLAGS) $<
+
+$(TARGET).mot : $(TARGET)
+ $(OBJCOPY) -O srec $(TARGET) $(TARGET).mot
+
+image : $(TARGET).mot
+
+write : $(TARGET).mot
+ $(H8WRITE) -3069 -f20 $(TARGET).mot $(H8WRITE_SERDEV)
+
+clean :
+ rm -f $(OBJS) $(TARGET) $(TARGET).elf $(TARGET).mot
+
+console :
+ minicom -o console -b 9600 -D $(H8WRITE_SERDEV)
--- /dev/null
+#ifndef _DEFINES_H_INCLUDED_
+#define _DEFINES_H_INCLUDED_
+
+#define NULL ((void *)0)
+#define SERIAL_DEFAULT_DEVICE 1
+
+typedef char int8;
+typedef short int16;
+typedef long int32;
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned long uint32;
+
+#endif
--- /dev/null
+/*-----------------------------------------------------------------------\r
+/ PFF - Low level disk interface modlue include file (C)ChaN, 2010\r
+/-----------------------------------------------------------------------*/\r
+\r
+#ifndef _DISKIO\r
+#define _DISKIO\r
+\r
+#include "integer.h"\r
+#include "pff.h"\r
+\r
+\r
+/* Status of Disk Functions */\r
+typedef BYTE DSTATUS;\r
+\r
+#define STA_NOINIT 0x01 /* Drive not initialized */\r
+#define STA_NODISK 0x02 /* No medium in the drive */\r
+\r
+\r
+/* Results of Disk Functions */\r
+typedef enum {\r
+ RES_OK = 0, /* 0: Function succeeded */\r
+ RES_ERROR, /* 1: Disk error */\r
+ RES_NOTRDY, /* 2: Not ready */\r
+ RES_PARERR /* 3: Invalid parameter */\r
+} DRESULT;\r
+\r
+\r
+/*---------------------------------------*/\r
+/* Prototypes for disk control functions */\r
+\r
+DSTATUS disk_initialize (void);\r
+#if _USE_READ\r
+DRESULT disk_readp (BYTE*, DWORD, WORD, WORD);\r
+#endif\r
+#if _USE_WRITE\r
+DRESULT disk_writep (const BYTE*, DWORD);\r
+#endif\r
+\r
+#endif\r
--- /dev/null
+#include "defines.h"
+#include "lib.h"
+#include "dram.h"
+
+#define H8_3069F_ABWCR ((volatile uint8 *)0xfee020)
+#define H8_3069F_ASTCR ((volatile uint8 *)0xfee021)
+#define H8_3069F_RTCOR ((volatile uint8 *)0xfee02a)
+#define H8_3069F_RTMCSR ((volatile uint8 *)0xfee028)
+#define H8_3069F_DRCRB ((volatile uint8 *)0xfee027)
+#define H8_3069F_DRCRA ((volatile uint8 *)0xfee026)
+
+#define H8_3069F_P1DDR ((volatile uint8 *)0xfee000)
+#define H8_3069F_P2DDR ((volatile uint8 *)0xfee001)
+#define H8_3069F_P8DDR ((volatile uint8 *)0xfee007)
+#define H8_3069F_PBDDR ((volatile uint8 *)0xfee00a)
+
+#define H8_3069F_WCRH ((volatile uint8 *)0xfee022)
+#define H8_3069F_WCRL ((volatile uint8 *)0xfee023)
+
+typedef struct {
+ union {
+ volatile uint8 val8[4];
+ volatile uint16 val16[2];
+ volatile uint32 val32[1];
+ } u;
+} val_t;
+
+int dram_init()
+{
+ int i, j;
+
+ *H8_3069F_ABWCR = 0xff;
+ *H8_3069F_RTCOR = 0x03; /* ¥ê¥Õ¥ì¥Ã¥·¥å¼þ´ü¤òû¤á¤ËÀßÄê */
+ *H8_3069F_RTMCSR = 0x37;
+ *H8_3069F_DRCRB = 0x8f; /* ¥¦¥¨¥¤¥ÈÁÞÆþ */
+ *H8_3069F_DRCRA = 0x20;
+
+ *H8_3069F_P1DDR = 0xff;
+ *H8_3069F_P2DDR = 0x07;
+ *H8_3069F_P8DDR = 0xee;
+ *H8_3069F_PBDDR = 0x6c;
+
+ for (i = 0; i < 200; i++) {
+ for (j = 0; j < 200; j++) {
+ asm volatile ("nop");
+ }
+ }
+
+ /*
+ * 3¥¹¥Æ¡¼¥È¥¢¥¯¥»¥¹
+ */
+ *H8_3069F_WCRH = 0xff;
+ *H8_3069F_WCRL = 0xff;
+
+ /*
+ * 3¥¹¥Æ¡¼¥È¥¢¥¯¥»¥¹
+ */
+ *H8_3069F_ASTCR = 0xff;
+
+ return 0;
+}
+
+static int check_val(volatile val_t *p, volatile val_t *wval)
+{
+ volatile val_t rval;
+
+ p->u.val8[0] = wval->u.val8[0]; p->u.val8[1] = wval->u.val8[1];
+ p->u.val8[2] = wval->u.val8[2]; p->u.val8[3] = wval->u.val8[3];
+ rval.u.val8[0] = p->u.val8[0]; rval.u.val8[1] = p->u.val8[1];
+ rval.u.val8[2] = p->u.val8[2]; rval.u.val8[3] = p->u.val8[3];
+
+ if (rval.u.val32[0] != wval->u.val32[0])
+ return -1;
+
+ p->u.val16[0] = wval->u.val16[0]; p->u.val16[1] = wval->u.val16[1];
+ rval.u.val16[0] = p->u.val16[0]; rval.u.val16[1] = p->u.val16[1];
+
+ if (rval.u.val32[0] != wval->u.val32[0])
+ return -1;
+
+ p->u.val32[0] = wval->u.val32[0];
+ rval.u.val32[0] = p->u.val32[0];
+
+ if (rval.u.val32[0] != wval->u.val32[0])
+ return -1;
+
+ return 0;
+}
+
+int dram_check()
+{
+ uint32 *p;
+ int err;
+ val_t val;
+
+ puts("DRAM checking...\n");
+
+ for (p = (uint32 *)DRAM_START; p < (uint32 *)DRAM_END; p++) {
+ putxval((unsigned long)p, 8);
+ err = 1;
+
+ val.u.val32[0] = (uint32)p;
+ if (check_val((val_t *)p, &val) < 0)
+ goto err;
+
+ val.u.val32[0] = 0;
+ if (check_val((val_t *)p, &val) < 0)
+ goto err;
+
+ val.u.val32[0] = 0xffffffffUL;
+ if (check_val((val_t *)p, &val) < 0)
+ goto err;
+
+ puts("\x08\x08\x08\x08\x08\x08\x08\x08");
+ }
+ puts("\nall check OK.\n");
+ return 0;
+
+err:
+ puts("\nERROR: ");
+ putxval((unsigned long)*p, 8);
+ puts("\n");
+ return -1;
+}
+
+static uint32 dram_check2_val0(uint32 *addr) { return 0x55555555UL; }
+static uint32 dram_check2_val1(uint32 *addr) { return 0xaaaaaaaaUL; }
+static uint32 dram_check2_val2(uint32 *addr) { return 0x00000000UL; }
+static uint32 dram_check2_val3(uint32 *addr) { return 0xffffffffUL; }
+static uint32 dram_check2_val4(uint32 *addr) { return (uint32)addr; }
+static uint32 dram_check2_val5(uint32 *addr) { return ~(uint32)addr; }
+
+int dram_check2()
+{
+ uint32 *p;
+ int ret = 0, i;
+ uint32 (*getval[])(uint32 *) = {
+ dram_check2_val0,
+ dram_check2_val1,
+ dram_check2_val2,
+ dram_check2_val3,
+ dram_check2_val4,
+ dram_check2_val5,
+ NULL
+ };
+
+ for (i = 0; getval[i]; i++) {
+
+ puts("DRAM check pattern: ");
+ putxval(i, 0);
+
+ puts("\nDRAM setting...\n");
+
+ for (p = (uint32 *)DRAM_START; p < (uint32 *)DRAM_END; p++) {
+ *p = getval[i](p);
+ if (!((uint32)p & 0xfff)) {
+ putxval((unsigned long)p, 8);
+ puts("\x08\x08\x08\x08\x08\x08\x08\x08");
+ }
+ }
+
+ puts("\nDRAM checking...\n");
+
+ for (p = (uint32 *)DRAM_START; p < (uint32 *)DRAM_END; p++) {
+ if (*p != getval[i](p)) {
+ puts("\nERROR! :");
+ putxval((unsigned long)p, 8);
+ puts(" ");
+ putxval((unsigned long)*p, 8);
+ puts("\n");
+ ret = -1;
+ }
+ if (!((uint32)p & 0xfff)) {
+ putxval((unsigned long)p, 8);
+ puts("\x08\x08\x08\x08\x08\x08\x08\x08");
+ }
+ }
+
+ puts("\n");
+
+ }
+
+ if (ret == 0) {
+ puts("\nall check OK.\n");
+ }
+
+ return ret;
+}
+
+int dram_clear()
+{
+ uint32 *p;
+
+ puts("DRAM clearing...\n");
+
+ for (p = (uint32 *)DRAM_START; p < (uint32 *)DRAM_END; p++)
+ *p = 0;
+
+ puts("DRAM cleared.\n");
+
+ return 0;
+}
--- /dev/null
+#ifndef _DRAM_H_INCLUDED_
+#define _DRAM_H_INCLUDED_
+
+#define DRAM_START 0x400000
+#define DRAM_END 0x600000
+
+int dram_init();
+int dram_check();
+int dram_check2();
+int dram_clear();
+
+#endif
--- /dev/null
+#include "defines.h"
+#include "elf.h"
+#include "lib.h"
+
+struct elf_header {
+ struct {
+ unsigned char magic[4];
+ unsigned char class;
+ unsigned char format;
+ unsigned char version;
+ unsigned char abi;
+ unsigned char abi_version;
+ unsigned char reserve[7];
+ } id;
+ short type;
+ short arch;
+ long version;
+ long entry_point;
+ long program_header_offset;
+ long section_header_offset;
+ long flags;
+ short header_size;
+ short program_header_size;
+ short program_header_num;
+ short section_header_size;
+ short section_header_num;
+ short section_name_index;
+};
+
+struct elf_program_header {
+ long type;
+ long offset;
+ long virtual_addr;
+ long physical_addr;
+ long file_size;
+ long memory_size;
+ long flags;
+ long align;
+};
+
+/* ELF¥Ø¥Ã¥À¤Î¥Á¥§¥Ã¥¯ */
+static int elf_check(struct elf_header *header)
+{
+ if (memcmp(header->id.magic, "\x7f" "ELF", 4))
+ return -1;
+
+ if (header->id.class != 1) return -1; /* ELF32 */
+ if (header->id.format != 2) return -1; /* Big endian */
+ if (header->id.version != 1) return -1; /* version 1 */
+ if (header->type != 2) return -1; /* Executable file */
+ if (header->version != 1) return -1; /* version 1 */
+
+ /* Hitachi H8/300 or H8/300H */
+ if ((header->arch != 46) && (header->arch != 47)) return -1;
+
+ return 0;
+}
+
+/* ¥»¥°¥á¥ó¥Èñ°Ì¤Ç¤Î¥í¡¼¥É */
+static int elf_load_program(struct elf_header *header)
+{
+ int i;
+ struct elf_program_header *phdr;
+
+ for (i = 0; i < header->program_header_num; i++) {
+ /* ¥×¥í¥°¥é¥à¡¦¥Ø¥Ã¥À¤ò¼èÆÀ */
+ phdr = (struct elf_program_header *)
+ ((char *)header + header->program_header_offset +
+ header->program_header_size * i);
+
+ if (phdr->type != 1) /* ¥í¡¼¥É²Äǽ¤Ê¥»¥°¥á¥ó¥È¤«¡© */
+ continue;
+
+ memcpy((char *)phdr->physical_addr, (char *)header + phdr->offset,
+ phdr->file_size);
+ memset((char *)phdr->physical_addr + phdr->file_size, 0,
+ phdr->memory_size - phdr->file_size);
+ }
+
+ return 0;
+}
+
+char *elf_load(char *buf)
+{
+ struct elf_header *header = (struct elf_header *)buf;
+
+ if (elf_check(header) < 0) /* ELF¥Ø¥Ã¥À¤Î¥Á¥§¥Ã¥¯ */
+ return NULL;
+
+ if (elf_load_program(header) < 0) /* ¥»¥°¥á¥ó¥Èñ°Ì¤Ç¤Î¥í¡¼¥É */
+ return NULL;
+
+ return (char *)header->entry_point;
+}
--- /dev/null
+#ifndef _ELF_H_INCLUDED_
+#define _ELF_H_INCLUDED_
+
+char *elf_load(char *buf);
+
+#endif
--- /dev/null
+/*-------------------------------------------*/\r
+/* Integer type definitions for FatFs module */\r
+/*-------------------------------------------*/\r
+\r
+#ifndef _INTEGER\r
+#define _INTEGER\r
+\r
+#include "defines.h"\r
+\r
+/* These types must be 16-bit, 32-bit or larger integer */\r
+typedef int16 INT;\r
+typedef uint16 UINT;\r
+\r
+/* These types must be 8-bit integer */\r
+typedef int8 CHAR;\r
+typedef uint8 UCHAR;\r
+typedef uint8 BYTE;\r
+\r
+/* These types must be 16-bit integer */\r
+typedef int16 SHORT;\r
+typedef uint16 USHORT;\r
+typedef uint16 WORD;\r
+typedef uint16 WCHAR;\r
+\r
+/* These types must be 32-bit integer */\r
+typedef int32 LONG;\r
+typedef uint32 ULONG;\r
+typedef uint32 DWORD;\r
+\r
+#endif\r
--- /dev/null
+#include "defines.h"
+#include "intr.h"
+#include "interrupt.h"
+
+/* ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤Î½é´ü²½ */
+int softvec_init(void)
+{
+ int type;
+ for (type = 0; type < SOFTVEC_TYPE_NUM; type++)
+ softvec_setintr(type, NULL);
+ return 0;
+}
+
+/* ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤ÎÀßÄê */
+int softvec_setintr(softvec_type_t type, softvec_handler_t handler)
+{
+ SOFTVECS[type] = handler;
+ return 0;
+}
+
+/*
+ * ¶¦Ä̳ä¹þ¤ß¥Ï¥ó¥É¥é¡¥
+ * ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤ò¸«¤Æ¡¤³Æ¥Ï¥ó¥É¥é¤Ëʬ´ô¤¹¤ë¡¥
+ */
+void interrupt(softvec_type_t type, unsigned long sp)
+{
+ softvec_handler_t handler = SOFTVECS[type];
+ if (handler)
+ handler(type, sp);
+}
--- /dev/null
+#ifndef _INTERRUPT_H_INCLUDED_
+#define _INTERRUPT_H_INCLUDED_
+
+/* °Ê²¼¤Ï¥ê¥ó¥«¡¦¥¹¥¯¥ê¥×¥È¤ÇÄêµÁ¤·¤Æ¤¢¤ë¥·¥ó¥Ü¥ë */
+extern char softvec;
+#define SOFTVEC_ADDR (&softvec)
+
+typedef short softvec_type_t;
+
+typedef void (*softvec_handler_t)(softvec_type_t type, unsigned long sp);
+
+#define SOFTVECS ((softvec_handler_t *)SOFTVEC_ADDR)
+
+#define INTR_ENABLE asm volatile ("andc.b #0x3f,ccr")
+#define INTR_DISABLE asm volatile ("orc.b #0xc0,ccr")
+
+/* ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤Î½é´ü²½ */
+int softvec_init(void);
+
+/* ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤ÎÀßÄê */
+int softvec_setintr(softvec_type_t type, softvec_handler_t handler);
+
+/* ¶¦Ä̳ä¹þ¤ß¥Ï¥ó¥É¥é */
+void interrupt(softvec_type_t type, unsigned long sp);
+
+#endif
--- /dev/null
+#include "intr.h"\r
+ .h8300h\r
+ .section .text\r
+\r
+ .global _intr_softerr\r
+# .type _intr_softerr,@function\r
+_intr_softerr:\r
+ mov.l er6,@-er7\r
+ mov.l er5,@-er7\r
+ mov.l er4,@-er7\r
+ mov.l er3,@-er7\r
+ mov.l er2,@-er7\r
+ mov.l er1,@-er7\r
+ mov.l er0,@-er7\r
+ mov.l er7,er1\r
+ mov.l #_intrstack,sp\r
+ mov.l er1,@-er7\r
+ mov.w #SOFTVEC_TYPE_SOFTERR,r0\r
+ jsr @_interrupt\r
+ mov.l @er7+,er1\r
+ mov.l er1,er7\r
+ mov.l @er7+,er0\r
+ mov.l @er7+,er1\r
+ mov.l @er7+,er2\r
+ mov.l @er7+,er3\r
+ mov.l @er7+,er4\r
+ mov.l @er7+,er5\r
+ mov.l @er7+,er6\r
+ rte\r
+\r
+ .global _intr_syscall\r
+# .type _intr_syscall,@function\r
+_intr_syscall:\r
+ mov.l er6,@-er7\r
+ mov.l er5,@-er7\r
+ mov.l er4,@-er7\r
+ mov.l er3,@-er7\r
+ mov.l er2,@-er7\r
+ mov.l er1,@-er7\r
+ mov.l er0,@-er7\r
+ mov.l er7,er1\r
+ mov.l #_intrstack,sp\r
+ mov.l er1,@-er7\r
+ mov.w #SOFTVEC_TYPE_SYSCALL,r0\r
+ jsr @_interrupt\r
+ mov.l @er7+,er1\r
+ mov.l er1,er7\r
+ mov.l @er7+,er0\r
+ mov.l @er7+,er1\r
+ mov.l @er7+,er2\r
+ mov.l @er7+,er3\r
+ mov.l @er7+,er4\r
+ mov.l @er7+,er5\r
+ mov.l @er7+,er6\r
+ rte\r
+\r
+ .global _intr_serintr\r
+# .type _intr_serintr,@function\r
+_intr_serintr:\r
+ mov.l er6,@-er7\r
+ mov.l er5,@-er7\r
+ mov.l er4,@-er7\r
+ mov.l er3,@-er7\r
+ mov.l er2,@-er7\r
+ mov.l er1,@-er7\r
+ mov.l er0,@-er7\r
+ mov.l er7,er1\r
+ mov.l #_intrstack,sp\r
+ mov.l er1,@-er7\r
+ mov.w #SOFTVEC_TYPE_SERINTR,r0\r
+ jsr @_interrupt\r
+ mov.l @er7+,er1\r
+ mov.l er1,er7\r
+ mov.l @er7+,er0\r
+ mov.l @er7+,er1\r
+ mov.l @er7+,er2\r
+ mov.l @er7+,er3\r
+ mov.l @er7+,er4\r
+ mov.l @er7+,er5\r
+ mov.l @er7+,er6\r
+ rte\r
+\r
+ .global _intr_timintr\r
+# .type _intr_timintr,@function\r
+_intr_timintr:\r
+ mov.l er6,@-er7\r
+ mov.l er5,@-er7\r
+ mov.l er4,@-er7\r
+ mov.l er3,@-er7\r
+ mov.l er2,@-er7\r
+ mov.l er1,@-er7\r
+ mov.l er0,@-er7\r
+ mov.l er7,er1\r
+ mov.l #_intrstack,sp\r
+ mov.l er1,@-er7\r
+ mov.w #SOFTVEC_TYPE_TIMINTR,r0\r
+ jsr @_interrupt\r
+ mov.l @er7+,er1\r
+ mov.l er1,er7\r
+ mov.l @er7+,er0\r
+ mov.l @er7+,er1\r
+ mov.l @er7+,er2\r
+ mov.l @er7+,er3\r
+ mov.l @er7+,er4\r
+ mov.l @er7+,er5\r
+ mov.l @er7+,er6\r
+ rte\r
+\r
+ .global _intr_ir_edge\r
+# .type _intr_ir_edge,@function\r
+_intr_ir_edge:\r
+ mov.l er6,@-er7\r
+ mov.l er5,@-er7\r
+ mov.l er4,@-er7\r
+ mov.l er3,@-er7\r
+ mov.l er2,@-er7\r
+ mov.l er1,@-er7\r
+ mov.l er0,@-er7\r
+ mov.l er7,er1\r
+ mov.l #_intrstack,sp\r
+ mov.l er1,@-er7\r
+ mov.w #SOFTVEC_TYPE_IR_EDGE,r0\r
+ jsr @_interrupt\r
+ mov.l @er7+,er1\r
+ mov.l er1,er7\r
+ mov.l @er7+,er0\r
+ mov.l @er7+,er1\r
+ mov.l @er7+,er2\r
+ mov.l @er7+,er3\r
+ mov.l @er7+,er4\r
+ mov.l @er7+,er5\r
+ mov.l @er7+,er6\r
+ rte\r
+\r
+ .global _intr_ir_tovf\r
+# .type _intr_ir_tovf,@function\r
+_intr_ir_tovf:\r
+ mov.l er6,@-er7\r
+ mov.l er5,@-er7\r
+ mov.l er4,@-er7\r
+ mov.l er3,@-er7\r
+ mov.l er2,@-er7\r
+ mov.l er1,@-er7\r
+ mov.l er0,@-er7\r
+ mov.l er7,er1\r
+ mov.l #_intrstack,sp\r
+ mov.l er1,@-er7\r
+ mov.w #SOFTVEC_TYPE_IR_TOVF,r0\r
+ jsr @_interrupt\r
+ mov.l @er7+,er1\r
+ mov.l er1,er7\r
+ mov.l @er7+,er0\r
+ mov.l @er7+,er1\r
+ mov.l @er7+,er2\r
+ mov.l @er7+,er3\r
+ mov.l @er7+,er4\r
+ mov.l @er7+,er5\r
+ mov.l @er7+,er6\r
+ rte\r
--- /dev/null
+#ifndef _INTR_H_INCLUDED_
+#define _INTR_H_INCLUDED_
+
+/* ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤ÎÄêµÁ */
+
+#define SOFTVEC_TYPE_NUM 6
+
+#define SOFTVEC_TYPE_SOFTERR 0
+#define SOFTVEC_TYPE_SYSCALL 1
+#define SOFTVEC_TYPE_SERINTR 2
+#define SOFTVEC_TYPE_TIMINTR 3
+#define SOFTVEC_TYPE_IR_EDGE 4
+#define SOFTVEC_TYPE_IR_TOVF 5
+
+#endif
--- /dev/null
+#include "lcd.h"
+#include "defines.h"
+
+static const uint8 FONT_X = 5;
+static const uint8 FONT_Y = 7;
+static const uint16 FONT_MIN_CODE = 0x20;
+static const uint16 FONT_MAX_CODE = 0x7F;
+
+#define swap(a,b) {int c=a;a=b;b=c;}
+#define abs(n) (((int)(n) < 0) ? ((int)(n) * (-1)) : (n))
+
+#define H8_3069F_P4DDR ((volatile uint8 *)0xFEE003)
+#define H8_3069F_P4DR ((volatile uint8 *)0xFFFFD3)
+#define H8_3069F_CSCR ((volatile uint8 *)0xFEE01F)
+
+#define LCD_ADDR_LEFT ((volatile uint8 *)0x800000)
+#define LCD_ADDR_RIGHT ((volatile uint8 *)0xA00000)
+#define LCD_AOFS_CMD (0)
+#define LCD_AOFS_DAT (1 << 3)
+
+#define BIT_LCD_RES (1 << 7)
+#define BIT_SDC_CS (1 << 0)
+#define BIT_VSCCS (1 << 2)
+#define BIT_VSDCS (1 << 3)
+#define BIT_VSRST (1 << 5)
+
+#define LCD1_CMD(VAL) \
+ do { \
+ *(LCD_ADDR_LEFT + LCD_AOFS_CMD) = (VAL); \
+ } while (0)
+
+#define LCD1_DAT_WRITE(VAL) \
+ do { \
+ *(LCD_ADDR_LEFT + LCD_AOFS_DAT) = (VAL); \
+ } while (0)
+
+#define LCD1_DAT_READ() (*(LCD_ADDR_LEFT + LCD_AOFS_DAT))
+
+#define LCD2_CMD(VAL) \
+ do { \
+ *(LCD_ADDR_RIGHT + LCD_AOFS_CMD) = (VAL); \
+ } while (0)
+
+#define LCD2_DAT_WRITE(VAL) \
+ do { \
+ *(LCD_ADDR_RIGHT + LCD_AOFS_DAT) = (VAL); \
+ } while (0)
+
+#define LCD2_DAT_READ() (*(LCD_ADDR_RIGHT + LCD_AOFS_DAT))
+
+static const uint8 font5x7_data[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, // (white space)
+ 0x00, 0x00, 0x5F, 0x00, 0x00, // !
+ 0x00, 0x07, 0x00, 0x07, 0x00, // "
+ 0x14, 0x7F, 0x14, 0x7F, 0x14, // #
+ 0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
+ 0x23, 0x13, 0x08, 0x64, 0x62, // %
+ 0x36, 0x49, 0x55, 0x22, 0x50, // &
+ 0x00, 0x05, 0x03, 0x00, 0x00, // '
+ 0x00, 0x1C, 0x22, 0x41, 0x00, // (
+ 0x00, 0x41, 0x22, 0x1C, 0x00, // )
+ 0x08, 0x2A, 0x1C, 0x2A, 0x08, // *
+ 0x08, 0x08, 0x3E, 0x08, 0x08, // +
+ 0x00, 0x50, 0x30, 0x00, 0x00, // ,
+ 0x08, 0x08, 0x08, 0x08, 0x08, // -
+ 0x00, 0x60, 0x60, 0x00, 0x00, // .
+ 0x20, 0x10, 0x08, 0x04, 0x02, // /
+ 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
+ 0x00, 0x42, 0x7F, 0x40, 0x00, // 1
+ 0x42, 0x61, 0x51, 0x49, 0x46, // 2
+ 0x21, 0x41, 0x45, 0x4B, 0x31, // 3
+ 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
+ 0x27, 0x45, 0x45, 0x45, 0x39, // 5
+ 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
+ 0x01, 0x71, 0x09, 0x05, 0x03, // 7
+ 0x36, 0x49, 0x49, 0x49, 0x36, // 8
+ 0x06, 0x49, 0x49, 0x29, 0x1E, // 9
+ 0x00, 0x36, 0x36, 0x00, 0x00, // :
+ 0x00, 0x56, 0x36, 0x00, 0x00, // ;
+ 0x00, 0x08, 0x14, 0x22, 0x41, // <
+ 0x14, 0x14, 0x14, 0x14, 0x14, // =
+ 0x41, 0x22, 0x14, 0x08, 0x00, // >
+ 0x02, 0x01, 0x51, 0x09, 0x06, // ?
+ 0x32, 0x49, 0x79, 0x41, 0x3E, // @
+ 0x7E, 0x11, 0x11, 0x11, 0x7E, // A
+ 0x7F, 0x49, 0x49, 0x49, 0x36, // B
+ 0x3E, 0x41, 0x41, 0x41, 0x22, // C
+ 0x7F, 0x41, 0x41, 0x22, 0x1C, // D
+ 0x7F, 0x49, 0x49, 0x49, 0x41, // E
+ 0x7F, 0x09, 0x09, 0x01, 0x01, // F
+ 0x3E, 0x41, 0x41, 0x51, 0x32, // G
+ 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
+ 0x00, 0x41, 0x7F, 0x41, 0x00, // I
+ 0x20, 0x40, 0x41, 0x3F, 0x01, // J
+ 0x7F, 0x08, 0x14, 0x22, 0x41, // K
+ 0x7F, 0x40, 0x40, 0x40, 0x40, // L
+ 0x7F, 0x02, 0x04, 0x02, 0x7F, // M
+ 0x7F, 0x04, 0x08, 0x10, 0x7F, // N
+ 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
+ 0x7F, 0x09, 0x09, 0x09, 0x06, // P
+ 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
+ 0x7F, 0x09, 0x19, 0x29, 0x46, // R
+ 0x46, 0x49, 0x49, 0x49, 0x31, // S
+ 0x01, 0x01, 0x7F, 0x01, 0x01, // T
+ 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
+ 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
+ 0x7F, 0x20, 0x18, 0x20, 0x7F, // W
+ 0x63, 0x14, 0x08, 0x14, 0x63, // X
+ 0x03, 0x04, 0x78, 0x04, 0x03, // Y
+ 0x61, 0x51, 0x49, 0x45, 0x43, // Z
+ 0x00, 0x00, 0x7F, 0x41, 0x41, // [
+ 0x02, 0x04, 0x08, 0x10, 0x20, // /
+ 0x41, 0x41, 0x7F, 0x00, 0x00, // ]
+ 0x04, 0x02, 0x01, 0x02, 0x04, // ^
+ 0x40, 0x40, 0x40, 0x40, 0x40, // _
+ 0x00, 0x01, 0x02, 0x04, 0x00, // `
+ 0x20, 0x54, 0x54, 0x54, 0x78, // a
+ 0x7F, 0x48, 0x44, 0x44, 0x38, // b
+ 0x38, 0x44, 0x44, 0x44, 0x20, // c
+ 0x38, 0x44, 0x44, 0x48, 0x7F, // d
+ 0x38, 0x54, 0x54, 0x54, 0x18, // e
+ 0x08, 0x7E, 0x09, 0x01, 0x02, // f
+ 0x08, 0x14, 0x54, 0x54, 0x3C, // g
+ 0x7F, 0x08, 0x04, 0x04, 0x78, // h
+ 0x00, 0x44, 0x7D, 0x40, 0x00, // i
+ 0x20, 0x40, 0x44, 0x3D, 0x00, // j
+ 0x00, 0x7F, 0x10, 0x28, 0x44, // k
+ 0x00, 0x41, 0x7F, 0x40, 0x00, // l
+ 0x7C, 0x04, 0x18, 0x04, 0x78, // m
+ 0x7C, 0x08, 0x04, 0x04, 0x78, // n
+ 0x38, 0x44, 0x44, 0x44, 0x38, // o
+ 0x7C, 0x14, 0x14, 0x14, 0x08, // p
+ 0x08, 0x14, 0x14, 0x18, 0x7C, // q
+ 0x7C, 0x08, 0x04, 0x04, 0x08, // r
+ 0x48, 0x54, 0x54, 0x54, 0x20, // s
+ 0x04, 0x3F, 0x44, 0x40, 0x20, // t
+ 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
+ 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
+ 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
+ 0x44, 0x28, 0x10, 0x28, 0x44, // x
+ 0x0C, 0x50, 0x50, 0x50, 0x3C, // y
+ 0x44, 0x64, 0x54, 0x4C, 0x44, // z
+ 0x00, 0x08, 0x36, 0x41, 0x00, // {
+ 0x00, 0x00, 0x7F, 0x00, 0x00, // |
+ 0x00, 0x41, 0x36, 0x08, 0x00, // }
+ 0x08, 0x08, 0x2A, 0x1C, 0x08, // ->
+ 0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
+};
+
+void lcd_init(void)
+{
+ *H8_3069F_P4DDR = BIT_LCD_RES | BIT_SDC_CS | BIT_VSCCS | BIT_VSDCS | BIT_VSRST;
+
+ /*
+ * L->H : 68K mode.
+ */
+ *H8_3069F_P4DR &= ~BIT_LCD_RES;
+ asm volatile ("nop");
+ asm volatile ("nop");
+ asm volatile ("nop");
+ asm volatile ("nop");
+ *H8_3069F_P4DR |= BIT_LCD_RES;
+
+ *H8_3069F_CSCR = 0x3F;
+
+ LCD1_CMD(0xE2); // Reset
+ LCD1_CMD(0xA4); // Static Drive Off
+ LCD1_CMD(0xC0); // Display Start Line
+ LCD1_CMD(0xAF); // Display On
+ LCD1_CMD(0xB8); // Page Address Setup
+ LCD1_CMD(0x00); // Column Address
+
+ LCD2_CMD(0xE2); // Reset
+ LCD2_CMD(0xA4); // Static Drive Off
+ LCD2_CMD(0xC0); // Display Start Line
+ LCD2_CMD(0xAF); // Display On
+ LCD2_CMD(0xB8); // Page Address Setup
+ LCD2_CMD(0x00); // Column Address
+}
+
+void lcd_clear(void)
+{
+ int p, c;
+
+ for (p = 0; p <= 3; p++) {
+ LCD1_CMD(0xB8 | (p & 0x03)); // Page Address Setup
+ LCD1_CMD(0x00 | (0 & 0x7F)); // Column Address
+ for (c = 0; c < 62; c++) {
+ LCD1_DAT_WRITE(0);
+ }
+
+ LCD2_CMD(0xB8 | (p & 0x03)); // Page Address Setup
+ LCD2_CMD(0x00 | (0 & 0x7F)); // Column Address
+ for (c = 0; c < 62; c++) {
+ LCD2_DAT_WRITE(0);
+ }
+ }
+}
+
+void lcd_set_pixel(int x, int y, int reverse)
+{
+ volatile uint8 dat;
+ int p, c;
+
+ if (x <= 60) {
+ p = y / 8;
+ c = x;
+ LCD1_CMD(0xB8 | (p & 0x03)); // Page Address Setup
+ LCD1_CMD(0x00 | (c & 0x7F)); // Column Address
+ LCD1_CMD(0xE0);
+ dat = LCD1_DAT_READ(); // Dummy Read
+ dat = LCD1_DAT_READ(); // Real Read
+ if (reverse) {
+ dat |= (1 << (y % 8));
+ } else {
+ dat &= ~(1 << (y % 8));
+ }
+ LCD1_DAT_WRITE(dat);
+ LCD1_CMD(0xEE);
+ } else {
+ p = y / 8;
+ c = x - 61;
+ LCD2_CMD(0xB8 | (p & 0x03)); // Page Address Setup
+ LCD2_CMD(0x00 | (c & 0x7F)); // Column Address
+ LCD2_CMD(0xE0);
+ dat = LCD2_DAT_READ(); // Dummy Read
+ dat = LCD2_DAT_READ(); // Real Read
+ if (reverse) {
+ dat |= (1 << (y % 8));
+ } else {
+ dat &= ~(1 << (y % 8));
+ }
+ LCD2_DAT_WRITE(dat);
+ LCD2_CMD(0xEE);
+ }
+}
+
+void lcd_draw_line(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 reverse)
+{
+ int x;
+ /*
+ * Bresenham's line algorithm
+ */
+ uint8 steep = abs(y2 - y1) > abs(x2 - x1);
+ if (steep) {
+ swap(x1, y1);
+ swap(x2, y2);
+ }
+ if (x1 > x2) {
+ swap(x1, x2);
+ swap(y1, y2);
+ }
+ int deltax = x2 - x1;
+ int deltay = abs(y2 - y1);
+ int error = deltax / 2;
+ int ystep;
+ int y = y1;
+ if (y1 < y2) {
+ ystep = 1;
+ } else {
+ ystep = -1;
+ }
+ for (x = x1; x <= x2; x++) {
+ if (steep) {
+ if (reverse) {
+ lcd_set_pixel(y, x, 0);
+ } else {
+ lcd_set_pixel(y, x, 1);
+ }
+ } else {
+ if (reverse) {
+ lcd_set_pixel(x, y, 0);
+ } else {
+ lcd_set_pixel(x, y, 1);
+ }
+ }
+ error = error - deltay;
+ if (error < 0) {
+ y = y + ystep;
+ error = error + deltax;
+ }
+ }
+}
+
+void lcd_draw_box(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 reverse)
+{
+ int x, y;
+ for (x = x1; x <= x2; x++) {
+ if (reverse) {
+ lcd_set_pixel(x, y1, 0);
+ lcd_set_pixel(x, y2, 0);
+ } else {
+ lcd_set_pixel(x, y1, 1);
+ lcd_set_pixel(x, y2, 1);
+ }
+ }
+ for (y = y1; y <= y2; y++) {
+ if (reverse) {
+ lcd_set_pixel(x1, y, 0);
+ lcd_set_pixel(x2, y, 0);
+ } else {
+ lcd_set_pixel(x1, y, 1);
+ lcd_set_pixel(x2, y, 1);
+ }
+ }
+}
+
+void lcd_fill_box(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 reverse)
+{
+ int x, y;
+ for (x = x1; x <= x2; x++) {
+ for (y = y1; y <= y2; y++) {
+ if (reverse) {
+ lcd_set_pixel(x, y, 0);
+ } else {
+ lcd_set_pixel(x, y, 1);
+ }
+ }
+ }
+}
+
+void lcd_draw_string(uint8 x, uint8 y, char *str, uint8 reverse)
+{
+ char *p = str;
+ int cnt = 0;
+ while (*p) {
+ lcd_draw_char(x + (FONT_X * cnt), y, *p, reverse);
+ p++;
+ cnt++;
+ }
+}
+
+void lcd_draw_char(uint8 x, uint8 y, char c, uint8 reverse)
+{
+ int i, j;
+ if ((FONT_MIN_CODE <= c) &&(c <= FONT_MAX_CODE)) {
+ int aofs = (c - FONT_MIN_CODE) * FONT_X;
+ for (i = 0; i < FONT_X; i++) {
+ uint8 pat = font5x7_data[aofs + i];
+ for (j = 0; j < FONT_Y; j++) {
+ if (pat & (1 << j)) {
+ if (reverse) {
+ lcd_set_pixel(x + i, y + j, 0);
+ } else {
+ lcd_set_pixel(x + i, y + j, 1);
+ }
+ } else {
+ if (reverse) {
+ lcd_set_pixel(x + i, y + j, 1);
+ } else {
+ lcd_set_pixel(x + i, y + j, 0);
+ }
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < FONT_X; i++) {
+ uint8 pat = (i % 2) ? 0x55 : 0xAA;
+ for (j = 0; j < FONT_Y; j++) {
+ if (pat & (1 << j)) {
+ if (reverse) {
+ lcd_set_pixel(x + i, y + j, 0);
+ } else {
+ lcd_set_pixel(x + i, y + j, 1);
+ }
+ } else {
+ if (reverse) {
+ lcd_set_pixel(x + i, y + j, 1);
+ } else {
+ lcd_set_pixel(x + i, y + j, 0);
+ }
+ }
+ }
+ }
+ }
+}
+
+void lcd_draw_checkbox(
+ uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 state, uint8 reverse)
+{
+ lcd_draw_box(x1, y1, x2, y2, reverse);
+ if (state) {
+ lcd_draw_line(x1, y1, x2, y2, reverse);
+ lcd_draw_line(x1, y2, x2, y1, reverse);
+ }
+}
+
+void lcd_draw_progressbar(
+ uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ int min, int max, int value, uint8 reverse)
+{
+ lcd_draw_box(x1, y1, x2, y2, reverse);
+ if ((value < min) || (max < value)) {
+ return;
+ }
+ int tmp_max = max - min;
+ int tmp_val = value - min;
+ int pix = ((x2 - x1) * tmp_val) / tmp_max;
+ lcd_fill_box(x1 + 1, y1 + 1, x1 + pix - 1, y2 - 1, reverse);
+ lcd_fill_box(x1 + pix, y1 + 1, x2 - 1, y2 - 1, !reverse);
+}
+
--- /dev/null
+#ifndef _LCD_H_INCLUDED_
+#define _LCD_H_INCLUDED_
+
+#include "defines.h"
+
+void lcd_init(void);
+void lcd_clear(void);
+void lcd_set_pixel(int x, int y, int reverse);
+void lcd_draw_line(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ uint8 reverse);
+void lcd_draw_box(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ uint8 reverse);
+void lcd_fill_box(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ uint8 reverse);
+void lcd_draw_string(uint8 x, uint8 y, char *str, uint8 reverse);
+void lcd_draw_char(uint8 x, uint8 y, char c, uint8 reverse);
+void lcd_draw_checkbox(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ uint8 state, uint8 reverse);
+void lcd_draw_progressbar(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ int min, int max, int value, uint8 reverse);
+
+#endif
+
--- /dev/null
+/* OUTPUT_FORMAT("elf32-h8300") */
+OUTPUT_ARCH(h8300h)
+ENTRY("_start")
+
+MEMORY
+{
+ /* internal ROM (512KB) */
+ romall(rx) : o = 0x000000, l = 0x080000 /* 512KB */
+ vectors(r) : o = 0x000000, l = 0x000100 /* top of ROM */
+ rom(rx) : o = 0x000100, l = 0x07ff00
+
+ /* DRAM (2MB) */
+ dramall(rwx) : o = 0x400000, l = 0x200000 /* 2MB */
+ buffer(rwx) : o = 0x500000, l = 0x100000 /* 1MB */
+
+ /* internal RAM (16KB) */
+ ramall(rwx) : o = 0xffbf20, l = 0x004000 /* 16KB */
+ softvec(rw) : o = 0xffbf20, l = 0x000040 /* top of RAM */
+ data(rwx) : o = 0xffc000, l = 0x003f00
+ bootstack(rw) : o = 0xffff00, l = 0x000000
+ intrstack(rw) : o = 0xffff00, l = 0x000000 /* end of RAM */
+}
+
+SECTIONS
+{
+ .vectors : {
+ vector.o(.data)
+ } > vectors
+
+ .text : {
+ _text_start = . ;
+ *(.text)
+ _etext = . ;
+ } > rom
+
+ .rodata : {
+ _rodata_start = . ;
+ *(.strings)
+ *(.rodata)
+ *(.rodata.*)
+ . = ALIGN(4);
+ _erodata = . ;
+ } > rom
+
+ .softvec : {
+ _softvec = .;
+ } > softvec
+
+ .buffer : {
+ _buffer_start = . ;
+ } > buffer
+
+ .data : {
+ _data_start = . ;
+ *(.data)
+ _edata = . ;
+ } > data AT> rom
+
+ .bss : {
+ _bss_start = . ;
+ *(.bss)
+ *(COMMON)
+ _ebss = . ;
+ } > data AT> rom
+
+ . = ALIGN(4);
+ _end = . ;
+
+ .bootstack : {
+ _bootstack = .;
+ } > bootstack
+
+ .intrstack : {
+ _intrstack = .;
+ } > intrstack
+}
--- /dev/null
+#include "led.h"
+#include "defines.h"
+
+#define H8_3069F_PADDR ((volatile uint8 *)0xFEE009)
+#define H8_3069F_PADR ((volatile uint8 *)0xFFFFD9)
+
+#define MASK_LEDG (1 << 2)
+#define MASK_LEDR (1 << 3)
+#define MASK_LED1 (1 << 6)
+#define MASK_LED2 (1 << 7)
+
+int led_init(void)
+{
+ volatile uint8 mask = MASK_LED1 | MASK_LED2 | MASK_LEDG | MASK_LEDR;
+
+ /*
+ * ¥Ý¡¼¥È¥Ç¥£¥ì¥¯¥·¥ç¥ó¤òÀßÄꤹ¤ëÁ°¤Ë¥Ç¡¼¥¿¥ì¥¸¥¹¥¿¤ò½é´ü²½¤¹¤ë¡£
+ * ÉéÏÀÍý¤Ê¤Î¤Ç¡¢½é´üÃͤΥ¼¥í¤À¤È½ÐÎϤˤ·¤¿»þÅÀ¤ÇÅÀÅô¾õÂ֤Ȥʤ롣
+ */
+ *H8_3069F_PADR |= mask;
+
+ /*
+ * ¥Ý¡¼¥ÈA¤Î¥Ó¥Ã¥È2,3,6,7¤Ï½ÐÎϥݡ¼¥È¤È¤·¤ÆÀßÄꤹ¤ë¡£
+ *
+ * ¥Ç¡¼¥¿¥Ç¥£¥ì¥¯¥·¥ç¥ó¥ì¥¸¥¹¥¿¤ÏWrite Only¤Ê¤Î¤Ç¡¢
+ * ¾¤Î¥Ó¥Ã¥È¤ÎÀßÄ꤬ɬÍפˤʤä¿»þÅÀ¤Ç¡¢
+ * ¥Ý¡¼¥ÈÆþ½ÐÎÏÀßÄê¤ò¤Þ¤È¤á¤Æ´ÉÍý¤¹¤ë¤è¤¦¤Ê
+ * ²¿¤é¤«¤ÎÂкö¤¬É¬ÍפȤʤë¤À¤í¤¦¡£
+ */
+ *H8_3069F_PADDR = 0xCC;
+
+ return 0;
+}
+
+int led_write(led_target_t target, led_state_t state)
+{
+ volatile uint8 mask = 0x00;
+
+ switch (target) {
+ case Led1:
+ mask = MASK_LED1;
+ break;
+ case Led2:
+ mask = MASK_LED2;
+ break;
+ case LedG:
+ mask = MASK_LEDG;
+ break;
+ case LedR:
+ mask = MASK_LEDR;
+ break;
+ default:
+ return -1;
+ }
+
+ switch (state) {
+ case LedOn:
+ *H8_3069F_PADR &= ~mask;
+ break;
+ case LedOff:
+ *H8_3069F_PADR |= mask;
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int led_toggle(led_target_t target)
+{
+ volatile uint8 mask = 0x00;
+
+ switch (target) {
+ case Led1:
+ mask = MASK_LED1;
+ break;
+ case Led2:
+ mask = MASK_LED2;
+ break;
+ case LedG:
+ mask = MASK_LEDG;
+ break;
+ case LedR:
+ mask = MASK_LEDR;
+ break;
+ default:
+ return -1;
+ }
+
+ if (*H8_3069F_PADR & mask) {
+ *H8_3069F_PADR &= ~mask;
+ } else {
+ *H8_3069F_PADR |= mask;
+ }
+
+ return 0;
+}
+
--- /dev/null
+#ifndef _LED_H_INCLUDED_
+#define _LED_H_INCLUDED_
+
+typedef enum {
+ Led1,
+ Led2,
+ LedG,
+ LedR,
+} led_target_t;
+
+typedef enum {
+ LedOn,
+ LedOff,
+} led_state_t;
+
+int led_init(void);
+int led_write(led_target_t target, led_state_t state);
+int led_toggle(led_target_t target);
+
+#endif
+
--- /dev/null
+#include "defines.h"
+#include "serial.h"
+#include "lib.h"
+
+void *memset(void *b, int c, long len)
+{
+ char *p;
+ for (p = b; len > 0; len--)
+ *(p++) = c;
+ return b;
+}
+
+void *memcpy(void *dst, const void *src, long len)
+{
+ char *d = dst;
+ const char *s = src;
+ for (; len > 0; len--)
+ *(d++) = *(s++);
+ return dst;
+}
+
+int memcmp(const void *b1, const void *b2, long len)
+{
+ const char *p1 = b1, *p2 = b2;
+ for (; len > 0; len--) {
+ if (*p1 != *p2)
+ return (*p1 > *p2) ? 1 : -1;
+ p1++;
+ p2++;
+ }
+ return 0;
+}
+
+int strlen(const char *s)
+{
+ int len;
+ for (len = 0; *s; s++, len++)
+ ;
+ return len;
+}
+
+char *strcpy(char *dst, const char *src)
+{
+ char *d = dst;
+ for (;; dst++, src++) {
+ *dst = *src;
+ if (!*src) break;
+ }
+ return d;
+}
+
+int strcmp(const char *s1, const char *s2)
+{
+ while (*s1 || *s2) {
+ if (*s1 != *s2)
+ return (*s1 > *s2) ? 1 : -1;
+ s1++;
+ s2++;
+ }
+ return 0;
+}
+
+int strncmp(const char *s1, const char *s2, int len)
+{
+ while ((*s1 || *s2) && (len > 0)) {
+ if (*s1 != *s2)
+ return (*s1 > *s2) ? 1 : -1;
+ s1++;
+ s2++;
+ len--;
+ }
+ return 0;
+}
+
+/* £±Ê¸»úÁ÷¿® */
+int putc(unsigned char c)
+{
+ if (c == '\n')
+ serial_send_byte(SERIAL_DEFAULT_DEVICE, '\r');
+ return serial_send_byte(SERIAL_DEFAULT_DEVICE, c);
+}
+
+/* £±Ê¸»ú¼õ¿® */
+unsigned char getc(void)
+{
+ unsigned char c = serial_recv_byte(SERIAL_DEFAULT_DEVICE);
+ c = (c == '\r') ? '\n' : c;
+ putc(c); /* ¥¨¥³¡¼¡¦¥Ð¥Ã¥¯ */
+ return c;
+}
+
+/* ʸ»úÎóÁ÷¿® */
+int puts(unsigned char *str)
+{
+ while (*str)
+ putc(*(str++));
+ return 0;
+}
+
+/* ʸ»úÎó¼õ¿® */
+int gets(unsigned char *buf)
+{
+ int i = 0;
+ unsigned char c;
+ do {
+ c = getc();
+ if (c == '\n')
+ c = '\0';
+ buf[i++] = c;
+ } while (c);
+ return i - 1;
+}
+
+/* ¿ôÃͤÎ16¿Êɽ¼¨ */
+int putxval(unsigned long value, int column)
+{
+ char buf[9];
+ char *p;
+
+ p = buf + sizeof(buf) - 1;
+ *(p--) = '\0';
+
+ if (!value && !column)
+ column++;
+
+ while (value || column) {
+ *(p--) = "0123456789abcdef"[value & 0xf];
+ value >>= 4;
+ if (column) column--;
+ }
+
+ puts(p + 1);
+
+ return 0;
+}
--- /dev/null
+#ifndef _LIB_H_INCLUDED_
+#define _LIB_H_INCLUDED_
+
+void *memset(void *b, int c, long len);
+void *memcpy(void *dst, const void *src, long len);
+int memcmp(const void *b1, const void *b2, long len);
+int strlen(const char *s);
+char *strcpy(char *dst, const char *src);
+int strcmp(const char *s1, const char *s2);
+int strncmp(const char *s1, const char *s2, int len);
+
+int putc(unsigned char c); /* £±Ê¸»úÁ÷¿® */
+unsigned char getc(void); /* £±Ê¸»ú¼õ¿® */
+int puts(unsigned char *str); /* ʸ»úÎóÁ÷¿® */
+int gets(unsigned char *buf); /* ʸ»úÎó¼õ¿® */
+int putxval(unsigned long value, int column); /* ¿ôÃͤÎ16¿Êɽ¼¨ */
+
+#endif
--- /dev/null
+#include "defines.h"
+#include "interrupt.h"
+#include "serial.h"
+#include "xmodem.h"
+#include "elf.h"
+#include "dram.h"
+#include "lib.h"
+#include "led.h"
+#include "re.h"
+#include "sw.h"
+#include "lcd.h"
+#include "pff.h"
+#include "vs1011e.h"
+
+static int init(void)
+{
+ /* °Ê²¼¤Ï¥ê¥ó¥«¡¦¥¹¥¯¥ê¥×¥È¤ÇÄêµÁ¤·¤Æ¤¢¤ë¥·¥ó¥Ü¥ë */
+ extern int erodata, data_start, edata, bss_start, ebss;
+
+ /*
+ * ¥Ç¡¼¥¿Îΰè¤ÈBSSÎΰè¤ò½é´ü²½¤¹¤ë¡¥¤³¤Î½èÍý°Ê¹ß¤Ç¤Ê¤¤¤È¡¤
+ * ¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤¬½é´ü²½¤µ¤ì¤Æ¤¤¤Ê¤¤¤Î¤ÇÃí°Õ¡¥
+ */
+ memcpy(&data_start, &erodata, (long)&edata - (long)&data_start);
+ memset(&bss_start, 0, (long)&ebss - (long)&bss_start);
+
+ /* ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¤ê¹þ¤ß¥Ù¥¯¥¿¤ò½é´ü²½¤¹¤ë */
+ softvec_init();
+
+ /* ¥·¥ê¥¢¥ë¤Î½é´ü²½ */
+ serial_init(SERIAL_DEFAULT_DEVICE);
+
+ /* DRAM¤Î½é´ü²½ */
+ dram_init();
+
+ /* LED¤Î½é´ü²½ */
+ led_init();
+
+ /* ¥í¡¼¥¿¥ê¡¼¥¨¥ó¥³¡¼¥À¡¼¤Î½é´ü²½ */
+ re_init();
+
+ /* ¥¹¥¤¥Ã¥Á¤Î½é´ü²½ */
+ sw_init();
+
+ /* LCD¤Î½é´ü²½ */
+ lcd_init();
+
+ /* splash */
+ lcd_clear();
+ lcd_draw_box(0, 0, 121, 31, 0);
+ lcd_draw_string(2, 2, "KOZOS EXPBRD #00", 0);
+
+ /* VS1011e */
+ vs1011e_init();
+
+ volatile int i;
+ vs1011e_sinetest_init();
+ for (i = 0; i < 20000; i++) { }
+ vs1011e_sinetest_fini();
+ for (i = 0; i < 20000; i++) { }
+ vs1011e_sinetest_init();
+ for (i = 0; i < 20000; i++) { }
+ vs1011e_sinetest_fini();
+ for (i = 0; i < 20000; i++) { }
+ vs1011e_sinetest_init();
+ for (i = 0; i < 20000; i++) { }
+ vs1011e_sinetest_fini();
+
+ return 0;
+}
+
+void die(int code)
+{
+ puts("die with code 0x");
+ putxval(code, 4);
+ puts(".\n");
+ while (1) { }
+}
+
+int main(void)
+{
+ static unsigned char *loadbuf = NULL;
+ char *entry_point;
+ void (*f)(void);
+ extern int buffer_start; /* ¥ê¥ó¥«¡¦¥¹¥¯¥ê¥×¥È¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥Ð¥Ã¥Õ¥¡ */
+
+ INTR_DISABLE; /* ³ä¹þ¤ß̵¸ú¤Ë¤¹¤ë */
+
+ init();
+
+ FATFS fatfs;
+ WORD br, i;
+ BYTE buff[64];
+ int rc;
+
+ lcd_draw_string(2, 10, "Booting...", 0);
+ led_write(Led1, LedOff);
+ led_write(Led2, LedOff);
+ led_write(LedG, LedOn);
+ led_write(LedR, LedOff);
+
+ /*
+ * SD¥«¡¼¥É¤ò¥Þ¥¦¥ó¥È¡£
+ */
+ rc = pf_mount(&fatfs);
+ if (rc) {
+ lcd_draw_string(2, 10, "SD mount failed.", 0);
+ led_write(LedG, LedOff);
+ led_write(LedR, LedOn);
+ die(rc);
+ }
+
+ /*
+ * ¥Õ¥¡¥¤¥ë¤ò³«¤¯¡£
+ */
+ puts("\n\nOpen kozos boot image.\n");
+ rc = pf_open("kozos");
+ if (rc) {
+ lcd_draw_string(2, 10, "No boot image.", 0);
+ led_write(LedG, LedOff);
+ led_write(LedR, LedOn);
+ die(rc);
+ }
+
+ /*
+ * SD¥«¡¼¥É¾å¤ÎOS¥¤¥á¡¼¥¸¤ò¥á¥â¥ê¾å¤ËÆɤ߹þ¤ß¡£
+ */
+ puts("Reading...\n");
+ loadbuf = (char *)(&buffer_start);
+ for (;;) {
+ rc = pf_read(buff, sizeof(buff), &br);
+ if (rc || !br) {
+ break;
+ }
+ for (i = 0; i < br; i++) {
+ *loadbuf = buff[i];
+ loadbuf++;
+ }
+ lcd_draw_progressbar(5, 20, 121 - 5, 25, 0, 100, fatfs.fptr * 100 / fatfs.fsize, 0);
+ }
+ if (rc) {
+ puts("error.\n");
+ lcd_draw_string(2, 10, "File read error.", 0);
+ led_write(LedG, LedOff);
+ led_write(LedR, LedOn);
+ die(rc);
+ }
+ led_write(Led1, LedOff);
+ led_write(Led2, LedOff);
+
+ /*
+ * ¥á¥â¥ê¾å¤ËŸ³«(¥í¡¼¥É)
+ */
+ puts("Extracting...\n");
+ loadbuf = (char *)(&buffer_start);
+ entry_point = elf_load(loadbuf);
+
+ /*
+ * ¼Â¹Ô¡£
+ */
+ puts("Running...\n");
+ if (!entry_point) {
+ puts("error.\n");
+ lcd_draw_string(2, 10, "Run error.", 0);
+ led_write(LedG, LedOff);
+ led_write(LedR, LedOn);
+ } else {
+ lcd_clear();
+ led_write(Led1, LedOff);
+ led_write(Led2, LedOff);
+ led_write(LedG, LedOff);
+ led_write(LedR, LedOff);
+ f = (void (*)(void))entry_point;
+ f();
+ }
+
+ for (;;) { }
+
+ return 0;
+}
+
--- /dev/null
+/*------------------------------------------------------------------------/\r
+/ Bitbanging MMCv3/SDv1/SDv2 (in SPI mode) control module for PFF\r
+/-------------------------------------------------------------------------/\r
+/\r
+/ Copyright (C) 2010, ChaN, all right reserved.\r
+/\r
+/ * This software is a free software and there is NO WARRANTY.\r
+/ * No restriction on use. You can use, modify and redistribute it for\r
+/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.\r
+/ * Redistributions of source code must retain the above copyright notice.\r
+/\r
+/--------------------------------------------------------------------------/\r
+ Features:\r
+\r
+ * Very Easy to Port\r
+ It uses only 4-6 bit of GPIO port. No interrupt, no SPI port is used.\r
+\r
+ * Platform Independent\r
+ You need to modify only a few macros to control GPIO ports.\r
+\r
+/-------------------------------------------------------------------------*/\r
+\r
+\r
+#include "diskio.h"\r
+\r
+#define H8_3069F_P4DR ((volatile uint8 *)0xFFFFD3)\r
+#define H8_3069F_PBDR ((volatile uint8 *)0xFFFFDA)\r
+\r
+#define PB_BIT_SCLK (1 << 5)\r
+#define PB_BIT_MOSI (1 << 6)\r
+#define PB_BIT_MISO (1 << 7)\r
+#define P4_BIT_CS (1 << 0)\r
+\r
+/*-------------------------------------------------------------------------*/\r
+/* Platform dependent macros and functions needed to be modified */\r
+/*-------------------------------------------------------------------------*/\r
+\r
+#define INIT_PORT() do { } while (0) /* Initialize MMC control port (CS/CLK/DI:output, DO:input) */\r
+#define DLY_US(n) do { volatile uint32 dlycnt; for (dlycnt = 0; dlycnt < (n) * 10; dlycnt++) {} } while (0) /* Delay n microseconds */\r
+#define FORWARD(d) do { } while (0) /* Data in-time processing function (depends on the project) */\r
+\r
+#define CS_H() do { *H8_3069F_P4DR |= P4_BIT_CS; } while (0) /* Set MMC CS "high" */\r
+#define CS_L() do { *H8_3069F_P4DR &= ~P4_BIT_CS; } while (0) /* Set MMC CS "low" */\r
+#define CK_H() do { *H8_3069F_PBDR |= PB_BIT_SCLK; } while (0) /* Set MMC SCLK "high" */\r
+#define CK_L() do { *H8_3069F_PBDR &= ~PB_BIT_SCLK; } while (0) /* Set MMC SCLK "low" */\r
+#define DI_H() do { *H8_3069F_PBDR |= PB_BIT_MOSI; } while (0) /* Set MMC DI "high" */\r
+#define DI_L() do { *H8_3069F_PBDR &= ~PB_BIT_MOSI; } while (0) /* Set MMC DI "low" */\r
+#define DO ((*H8_3069F_PBDR & PB_BIT_MISO) ? 1 : 0) /* Get MMC DO value (high:true, low:false) */\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Module Private Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+/* Definitions for MMC/SDC command */\r
+#define CMD0 (0x40+0) /* GO_IDLE_STATE */\r
+#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */\r
+#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */\r
+#define CMD8 (0x40+8) /* SEND_IF_COND */\r
+#define CMD16 (0x40+16) /* SET_BLOCKLEN */\r
+#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */\r
+#define CMD24 (0x40+24) /* WRITE_BLOCK */\r
+#define CMD55 (0x40+55) /* APP_CMD */\r
+#define CMD58 (0x40+58) /* READ_OCR */\r
+\r
+/* Card type flags (CardType) */\r
+#define CT_MMC 0x01 /* MMC ver 3 */\r
+#define CT_SD1 0x02 /* SD ver 1 */\r
+#define CT_SD2 0x04 /* SD ver 2 */\r
+#define CT_SDC (CT_SD1|CT_SD2) /* SD */\r
+#define CT_BLOCK 0x08 /* Block addressing */\r
+\r
+\r
+\r
+static\r
+BYTE CardType; /* b0:MMC, b1:SDv1, b2:SDv2, b3:Block addressing */\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Transmit a byte to the MMC (bitbanging) */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+void xmit_mmc (\r
+ BYTE d /* Data to be sent */\r
+)\r
+{\r
+ if (d & 0x80) DI_H(); else DI_L(); /* bit7 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x40) DI_H(); else DI_L(); /* bit6 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x20) DI_H(); else DI_L(); /* bit5 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x10) DI_H(); else DI_L(); /* bit4 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x08) DI_H(); else DI_L(); /* bit3 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x04) DI_H(); else DI_L(); /* bit2 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x02) DI_H(); else DI_L(); /* bit1 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x01) DI_H(); else DI_L(); /* bit0 */\r
+ CK_H(); CK_L();\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Receive a byte from the MMC (bitbanging) */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+BYTE rcvr_mmc (void)\r
+{\r
+ BYTE r;\r
+\r
+\r
+ DI_H(); /* Send 0xFF */\r
+\r
+ r = 0; if (DO) r++; /* bit7 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit6 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit5 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit4 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit3 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit2 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit1 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit0 */\r
+ CK_H(); CK_L();\r
+\r
+ return r;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Skip bytes on the MMC (bitbanging) */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+void skip_mmc (\r
+ WORD n /* Number of bytes to skip */\r
+)\r
+{\r
+ DI_H(); /* Send 0xFF */\r
+\r
+ do {\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ } while (--n);\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Deselect the card and release SPI bus */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+void release_spi (void)\r
+{\r
+ CS_H();\r
+ rcvr_mmc();\r
+}\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Send a command packet to MMC */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+BYTE send_cmd (\r
+ BYTE cmd, /* Command byte */\r
+ DWORD arg /* Argument */\r
+)\r
+{\r
+ BYTE n, res;\r
+\r
+\r
+ if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */\r
+ cmd &= 0x7F;\r
+ res = send_cmd(CMD55, 0);\r
+ if (res > 1) return res;\r
+ }\r
+\r
+ /* Select the card */\r
+ CS_H(); rcvr_mmc();\r
+ CS_L(); rcvr_mmc();\r
+\r
+ /* Send a command packet */\r
+ xmit_mmc(cmd); /* Start + Command index */\r
+ xmit_mmc((BYTE)(arg >> 24)); /* Argument[31..24] */\r
+ xmit_mmc((BYTE)(arg >> 16)); /* Argument[23..16] */\r
+ xmit_mmc((BYTE)(arg >> 8)); /* Argument[15..8] */\r
+ xmit_mmc((BYTE)arg); /* Argument[7..0] */\r
+ n = 0x01; /* Dummy CRC + Stop */\r
+ if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */\r
+ if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */\r
+ xmit_mmc(n);\r
+\r
+ /* Receive a command response */\r
+ n = 10; /* Wait for a valid response in timeout of 10 attempts */\r
+ do {\r
+ res = rcvr_mmc();\r
+ } while ((res & 0x80) && --n);\r
+\r
+ return res; /* Return with the response value */\r
+}\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Public Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Initialize Disk Drive */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+DSTATUS disk_initialize (void)\r
+{\r
+ BYTE n, cmd, ty, buf[4];\r
+ UINT tmr;\r
+\r
+\r
+ INIT_PORT();\r
+\r
+ CS_H();\r
+ skip_mmc(10); /* Dummy clocks */\r
+\r
+ ty = 0;\r
+ if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */\r
+ if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */\r
+ for (n = 0; n < 4; n++) buf[n] = rcvr_mmc(); /* Get trailing return value of R7 resp */\r
+ if (buf[2] == 0x01 && buf[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */\r
+ for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state (ACMD41 with HCS bit) */\r
+ if (send_cmd(ACMD41, 1UL << 30) == 0) break;\r
+ DLY_US(1000);\r
+ }\r
+ if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */\r
+ for (n = 0; n < 4; n++) buf[n] = rcvr_mmc();\r
+ ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */\r
+ }\r
+ }\r
+ } else { /* SDv1 or MMCv3 */\r
+ if (send_cmd(ACMD41, 0) <= 1) {\r
+ ty = CT_SD1; cmd = ACMD41; /* SDv1 */\r
+ } else {\r
+ ty = CT_MMC; cmd = CMD1; /* MMCv3 */\r
+ }\r
+ for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state */\r
+ if (send_cmd(ACMD41, 0) == 0) break;\r
+ DLY_US(1000);\r
+ }\r
+ if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */\r
+ ty = 0;\r
+ }\r
+ }\r
+ CardType = ty;\r
+ release_spi();\r
+\r
+ return ty ? 0 : STA_NOINIT;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read partial sector */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+DRESULT disk_readp (\r
+ BYTE *buff, /* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */\r
+ DWORD lba, /* Sector number (LBA) */\r
+ WORD ofs, /* Byte offset to read from (0..511) */\r
+ WORD cnt /* Number of bytes to read (ofs + cnt mus be <= 512) */\r
+)\r
+{\r
+ DRESULT res;\r
+ BYTE d;\r
+ WORD bc, tmr;\r
+\r
+\r
+ if (!(CardType & CT_BLOCK)) lba *= 512; /* Convert to byte address if needed */\r
+\r
+ res = RES_ERROR;\r
+ if (send_cmd(CMD17, lba) == 0) { /* READ_SINGLE_BLOCK */\r
+\r
+ tmr = 1000;\r
+ do { /* Wait for data packet in timeout of 100ms */\r
+ DLY_US(100);\r
+ d = rcvr_mmc();\r
+ } while (d == 0xFF && --tmr);\r
+\r
+ if (d == 0xFE) { /* A data packet arrived */\r
+ bc = 514 - ofs - cnt;\r
+\r
+ /* Skip leading bytes */\r
+ if (ofs) skip_mmc(ofs);\r
+\r
+ /* Receive a part of the sector */\r
+ if (buff) { /* Store data to the memory */\r
+ do\r
+ *buff++ = rcvr_mmc();\r
+ while (--cnt);\r
+ } else { /* Forward data to the outgoing stream */\r
+ do {\r
+ d = rcvr_mmc();\r
+ FORWARD(d);\r
+ } while (--cnt);\r
+ }\r
+\r
+ /* Skip trailing bytes and CRC */\r
+ skip_mmc(bc);\r
+\r
+ res = RES_OK;\r
+ }\r
+ }\r
+\r
+ release_spi();\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Write partial sector */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_WRITE\r
+\r
+DRESULT disk_writep (\r
+ const BYTE *buff, /* Pointer to the bytes to be written (NULL:Initiate/Finalize sector write) */\r
+ DWORD sa /* Number of bytes to send, Sector number (LBA) or zero */\r
+)\r
+{\r
+ DRESULT res;\r
+ WORD bc, tmr;\r
+ static WORD wc;\r
+\r
+\r
+ res = RES_ERROR;\r
+\r
+ if (buff) { /* Send data bytes */\r
+ bc = (WORD)sa;\r
+ while (bc && wc) { /* Send data bytes to the card */\r
+ xmit_mmc(*buff++);\r
+ wc--; bc--;\r
+ }\r
+ res = RES_OK;\r
+ } else {\r
+ if (sa) { /* Initiate sector write process */\r
+ if (!(CardType & CT_BLOCK)) sa *= 512; /* Convert to byte address if needed */\r
+ if (send_cmd(CMD24, sa) == 0) { /* WRITE_SINGLE_BLOCK */\r
+ xmit_mmc(0xFF); xmit_mmc(0xFE); /* Data block header */\r
+ wc = 512; /* Set byte counter */\r
+ res = RES_OK;\r
+ }\r
+ } else { /* Finalize sector write process */\r
+ bc = wc + 2;\r
+ while (bc--) xmit_mmc(0); /* Fill left bytes and CRC with zeros */\r
+ if ((rcvr_mmc() & 0x1F) == 0x05) { /* Receive data resp and wait for end of write process in timeout of 300ms */\r
+ for (tmr = 10000; rcvr_mmc() != 0xFF && tmr; tmr--) /* Wait for ready (max 1000ms) */\r
+ DLY_US(100);\r
+ if (tmr) res = RES_OK;\r
+ }\r
+ release_spi();\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+#endif\r
--- /dev/null
+/*----------------------------------------------------------------------------/\r
+/ Petit FatFs - FAT file system module R0.02a (C)ChaN, 2010\r
+/-----------------------------------------------------------------------------/\r
+/ Petit FatFs module is an open source software to implement FAT file system to\r
+/ small embedded systems. This is a free software and is opened for education,\r
+/ research and commercial developments under license policy of following trems.\r
+/\r
+/ Copyright (C) 2010, ChaN, all right reserved.\r
+/\r
+/ * The Petit FatFs module is a free software and there is NO WARRANTY.\r
+/ * No restriction on use. You can use, modify and redistribute it for\r
+/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.\r
+/ * Redistributions of source code must retain the above copyright notice.\r
+/\r
+/-----------------------------------------------------------------------------/\r
+/ Jun 15,'09 R0.01a First release. (Branched from FatFs R0.07b.)\r
+/\r
+/ Dec 14,'09 R0.02 Added multiple code page support.\r
+/ Added write funciton.\r
+/ Changed stream read mode interface.\r
+/ Dec 07,'10 R0.02a Added some configuration options.\r
+/ Fixed fails to open objects with DBCS character.\r
+/----------------------------------------------------------------------------*/\r
+\r
+#include "pff.h" /* Petit FatFs configurations and declarations */\r
+#include "diskio.h" /* Declarations of low level disk I/O functions */\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Module Private Definitions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+\r
+#if _FS_FAT32\r
+#define LD_CLUST(dir) (((DWORD)LD_WORD(dir+DIR_FstClusHI)<<16) | LD_WORD(dir+DIR_FstClusLO))\r
+#else\r
+#define LD_CLUST(dir) LD_WORD(dir+DIR_FstClusLO)\r
+#endif\r
+\r
+\r
+/*--------------------------------------------------------*/\r
+/* DBCS code ranges and SBCS extend char conversion table */\r
+\r
+#if _CODE_PAGE == 932 /* Japanese Shift-JIS */\r
+#define _DF1S 0x81 /* DBC 1st byte range 1 start */\r
+#define _DF1E 0x9F /* DBC 1st byte range 1 end */\r
+#define _DF2S 0xE0 /* DBC 1st byte range 2 start */\r
+#define _DF2E 0xFC /* DBC 1st byte range 2 end */\r
+#define _DS1S 0x40 /* DBC 2nd byte range 1 start */\r
+#define _DS1E 0x7E /* DBC 2nd byte range 1 end */\r
+#define _DS2S 0x80 /* DBC 2nd byte range 2 start */\r
+#define _DS2E 0xFC /* DBC 2nd byte range 2 end */\r
+\r
+#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x40\r
+#define _DS1E 0x7E\r
+#define _DS2S 0x80\r
+#define _DS2E 0xFE\r
+\r
+#elif _CODE_PAGE == 949 /* Korean */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x41\r
+#define _DS1E 0x5A\r
+#define _DS2S 0x61\r
+#define _DS2E 0x7A\r
+#define _DS3S 0x81\r
+#define _DS3E 0xFE\r
+\r
+#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x40\r
+#define _DS1E 0x7E\r
+#define _DS2S 0xA1\r
+#define _DS2E 0xFE\r
+\r
+#elif _CODE_PAGE == 437 /* U.S. (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 720 /* Arabic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 737 /* Greek (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \\r
+ 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 775 /* Baltic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \\r
+ 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \\r
+ 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 857 /* Turkish (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 862 /* Hebrew (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 866 /* Russian (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \\r
+ 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}\r
+\r
+#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1253 /* Greek (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \\r
+ 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}\r
+\r
+#elif _CODE_PAGE == 1254 /* Turkish (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1256 /* Arabic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1257 /* Baltic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */\r
+#define _DF1S 0\r
+\r
+#else\r
+#error Unknown code page\r
+\r
+#endif\r
+\r
+\r
+\r
+/* Character code support macros */\r
+\r
+#define IsUpper(c) (((c)>='A')&&((c)<='Z'))\r
+#define IsLower(c) (((c)>='a')&&((c)<='z'))\r
+\r
+#if _DF1S /* DBCS configuration */\r
+\r
+#ifdef _DF2S /* Two 1st byte areas */\r
+#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))\r
+#else /* One 1st byte area */\r
+#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)\r
+#endif\r
+\r
+#ifdef _DS3S /* Three 2nd byte areas */\r
+#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))\r
+#else /* Two 2nd byte areas */\r
+#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))\r
+#endif\r
+\r
+#else /* SBCS configuration */\r
+\r
+#define IsDBCS1(c) 0\r
+#define IsDBCS2(c) 0\r
+\r
+#endif /* _DF1S */\r
+\r
+\r
+/* FatFs refers the members in the FAT structures with byte offset instead\r
+/ of structure member because there are incompatibility of the packing option\r
+/ between various compilers. */\r
+\r
+#define BS_jmpBoot 0\r
+#define BS_OEMName 3\r
+#define BPB_BytsPerSec 11\r
+#define BPB_SecPerClus 13\r
+#define BPB_RsvdSecCnt 14\r
+#define BPB_NumFATs 16\r
+#define BPB_RootEntCnt 17\r
+#define BPB_TotSec16 19\r
+#define BPB_Media 21\r
+#define BPB_FATSz16 22\r
+#define BPB_SecPerTrk 24\r
+#define BPB_NumHeads 26\r
+#define BPB_HiddSec 28\r
+#define BPB_TotSec32 32\r
+#define BS_55AA 510\r
+\r
+#define BS_DrvNum 36\r
+#define BS_BootSig 38\r
+#define BS_VolID 39\r
+#define BS_VolLab 43\r
+#define BS_FilSysType 54\r
+\r
+#define BPB_FATSz32 36\r
+#define BPB_ExtFlags 40\r
+#define BPB_FSVer 42\r
+#define BPB_RootClus 44\r
+#define BPB_FSInfo 48\r
+#define BPB_BkBootSec 50\r
+#define BS_DrvNum32 64\r
+#define BS_BootSig32 66\r
+#define BS_VolID32 67\r
+#define BS_VolLab32 71\r
+#define BS_FilSysType32 82\r
+\r
+#define MBR_Table 446\r
+\r
+#define DIR_Name 0\r
+#define DIR_Attr 11\r
+#define DIR_NTres 12\r
+#define DIR_CrtTime 14\r
+#define DIR_CrtDate 16\r
+#define DIR_FstClusHI 20\r
+#define DIR_WrtTime 22\r
+#define DIR_WrtDate 24\r
+#define DIR_FstClusLO 26\r
+#define DIR_FileSize 28\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Private Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+\r
+static\r
+FATFS *FatFs; /* Pointer to the file system object (logical drive) */\r
+\r
+\r
+/* Fill memory */\r
+static\r
+void mem_set (void* dst, int val, int cnt) {\r
+ char *d = (char*)dst;\r
+ while (cnt--) *d++ = (char)val;\r
+}\r
+\r
+/* Compare memory to memory */\r
+static\r
+int mem_cmp (const void* dst, const void* src, int cnt) {\r
+ const char *d = (const char *)dst, *s = (const char *)src;\r
+ int r = 0;\r
+ while (cnt-- && (r = *d++ - *s++) == 0) ;\r
+ return r;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* FAT access - Read value of a FAT entry */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+CLUST get_fat ( /* 1:IO error, Else:Cluster status */\r
+ CLUST clst /* Cluster# to get the link information */\r
+)\r
+{\r
+ WORD wc, bc, ofs;\r
+ BYTE buf[4];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (clst < 2 || clst >= fs->n_fatent) /* Range check */\r
+ return 1;\r
+\r
+ switch (fs->fs_type) {\r
+#if _FS_FAT12\r
+ case FS_FAT12 :\r
+ bc = (WORD)clst; bc += bc / 2;\r
+ ofs = bc % 512; bc /= 512;\r
+ if (ofs != 511) {\r
+ if (disk_readp(buf, fs->fatbase + bc, ofs, 2)) break;\r
+ } else {\r
+ if (disk_readp(buf, fs->fatbase + bc, 511, 1)) break;\r
+ if (disk_readp(buf+1, fs->fatbase + bc + 1, 0, 1)) break;\r
+ }\r
+ wc = LD_WORD(buf);\r
+ return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);\r
+#endif\r
+ case FS_FAT16 :\r
+ if (disk_readp(buf, fs->fatbase + clst / 256, (WORD)(((WORD)clst % 256) * 2), 2)) break;\r
+ return LD_WORD(buf);\r
+#if _FS_FAT32\r
+ case FS_FAT32 :\r
+ if (disk_readp(buf, fs->fatbase + clst / 128, (WORD)(((WORD)clst % 128) * 4), 4)) break;\r
+ return LD_DWORD(buf) & 0x0FFFFFFF;\r
+#endif\r
+ }\r
+\r
+ return 1; /* An error occured at the disk I/O layer */\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Get sector# from cluster# */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */\r
+ CLUST clst /* Cluster# to be converted */\r
+)\r
+{\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ clst -= 2;\r
+ if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */\r
+ return (DWORD)clst * fs->csize + fs->database;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Rewind directory index */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_rewind (\r
+ DIR *dj /* Pointer to directory object */\r
+)\r
+{\r
+ CLUST clst;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ dj->index = 0;\r
+ clst = dj->sclust;\r
+ if (clst == 1 || clst >= fs->n_fatent) /* Check start cluster range */\r
+ return FR_DISK_ERR;\r
+ if (_FS_FAT32 && !clst && fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */\r
+ clst = (CLUST)fs->dirbase;\r
+ dj->clust = clst; /* Current cluster */\r
+ dj->sect = clst ? clust2sect(clst) : fs->dirbase; /* Current sector */\r
+\r
+ return FR_OK; /* Seek succeeded */\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Move directory index next */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table */\r
+ DIR *dj /* Pointer to directory object */\r
+)\r
+{\r
+ CLUST clst;\r
+ WORD i;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ i = dj->index + 1;\r
+ if (!i || !dj->sect) /* Report EOT when index has reached 65535 */\r
+ return FR_NO_FILE;\r
+\r
+ if (!(i % 16)) { /* Sector changed? */\r
+ dj->sect++; /* Next sector */\r
+\r
+ if (dj->clust == 0) { /* Static table */\r
+ if (i >= fs->n_rootdir) /* Report EOT when end of table */\r
+ return FR_NO_FILE;\r
+ }\r
+ else { /* Dynamic table */\r
+ if (((i / 16) & (fs->csize-1)) == 0) { /* Cluster changed? */\r
+ clst = get_fat(dj->clust); /* Get next cluster */\r
+ if (clst <= 1) return FR_DISK_ERR;\r
+ if (clst >= fs->n_fatent) /* When it reached end of dynamic table */\r
+ return FR_NO_FILE; /* Report EOT */\r
+ dj->clust = clst; /* Initialize data for new cluster */\r
+ dj->sect = clust2sect(clst);\r
+ }\r
+ }\r
+ }\r
+\r
+ dj->index = i;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Find an object in the directory */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_find (\r
+ DIR *dj, /* Pointer to the directory object linked to the file name */\r
+ BYTE *dir /* 32-byte working buffer */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE c;\r
+\r
+\r
+ res = dir_rewind(dj); /* Rewind directory object */\r
+ if (res != FR_OK) return res;\r
+\r
+ do {\r
+ res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */\r
+ ? FR_DISK_ERR : FR_OK;\r
+ if (res != FR_OK) break;\r
+ c = dir[DIR_Name]; /* First character */\r
+ if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */\r
+ if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */\r
+ break;\r
+ res = dir_next(dj); /* Next entry */\r
+ } while (res == FR_OK);\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read an object from the directory */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_DIR\r
+static\r
+FRESULT dir_read (\r
+ DIR *dj, /* Pointer to the directory object to store read object name */\r
+ BYTE *dir /* 32-byte working buffer */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE a, c;\r
+\r
+\r
+ res = FR_NO_FILE;\r
+ while (dj->sect) {\r
+ res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */\r
+ ? FR_DISK_ERR : FR_OK;\r
+ if (res != FR_OK) break;\r
+ c = dir[DIR_Name];\r
+ if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */\r
+ a = dir[DIR_Attr] & AM_MASK;\r
+ if (c != 0xE5 && c != '.' && !(a & AM_VOL)) /* Is it a valid entry? */\r
+ break;\r
+ res = dir_next(dj); /* Next entry */\r
+ if (res != FR_OK) break;\r
+ }\r
+\r
+ if (res != FR_OK) dj->sect = 0;\r
+\r
+ return res;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Pick a segment and create the object name in directory form */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+#ifdef _EXCVT\r
+ static const BYTE cvt[] = _EXCVT;\r
+#endif\r
+\r
+static\r
+FRESULT create_name (\r
+ DIR *dj, /* Pointer to the directory object */\r
+ const char **path /* Pointer to pointer to the segment in the path string */\r
+)\r
+{\r
+ BYTE c, d, ni, si, i, *sfn;\r
+ const char *p;\r
+\r
+ /* Create file name in directory form */\r
+ sfn = dj->fn;\r
+ mem_set(sfn, ' ', 11);\r
+ si = i = 0; ni = 8;\r
+ p = *path;\r
+ for (;;) {\r
+ c = p[si++];\r
+ if (c <= ' ' || c == '/') break; /* Break on end of segment */\r
+ if (c == '.' || i >= ni) {\r
+ if (ni != 8 || c != '.') break;\r
+ i = 8; ni = 11;\r
+ continue;\r
+ }\r
+#ifdef _EXCVT\r
+ if (c >= 0x80) /* To upper extended char (SBCS) */\r
+ c = cvt[c - 0x80];\r
+#endif\r
+ if (IsDBCS1(c) && i < ni - 1) { /* DBC 1st byte? */\r
+ d = p[si++]; /* Get 2nd byte */\r
+ sfn[i++] = c;\r
+ sfn[i++] = d;\r
+ } else { /* Single byte code */\r
+ if (IsLower(c)) c -= 0x20; /* toupper */\r
+ sfn[i++] = c;\r
+ }\r
+ }\r
+ *path = &p[si]; /* Rerurn pointer to the next segment */\r
+\r
+ sfn[11] = (c <= ' ') ? 1 : 0; /* Set last segment flag if end of path */\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Get file information from directory entry */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_DIR\r
+static\r
+void get_fileinfo ( /* No return code */\r
+ DIR *dj, /* Pointer to the directory object */\r
+ BYTE *dir, /* 32-byte working buffer */\r
+ FILINFO *fno /* Pointer to store the file information */\r
+)\r
+{\r
+ BYTE i, c;\r
+ char *p;\r
+\r
+\r
+ p = fno->fname;\r
+ if (dj->sect) {\r
+ for (i = 0; i < 8; i++) { /* Copy file name body */\r
+ c = dir[i];\r
+ if (c == ' ') break;\r
+ if (c == 0x05) c = 0xE5;\r
+ *p++ = c;\r
+ }\r
+ if (dir[8] != ' ') { /* Copy file name extension */\r
+ *p++ = '.';\r
+ for (i = 8; i < 11; i++) {\r
+ c = dir[i];\r
+ if (c == ' ') break;\r
+ *p++ = c;\r
+ }\r
+ }\r
+ fno->fattrib = dir[DIR_Attr]; /* Attribute */\r
+ fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */\r
+ fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */\r
+ fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */\r
+ }\r
+ *p = 0;\r
+}\r
+#endif /* _USE_DIR */\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Follow a file path */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */\r
+ DIR *dj, /* Directory object to return last directory and found object */\r
+ BYTE *dir, /* 32-byte working buffer */\r
+ const char *path /* Full-path string to find a file or directory */\r
+)\r
+{\r
+ FRESULT res;\r
+\r
+\r
+ while (*path == ' ') path++; /* Skip leading spaces */\r
+ if (*path == '/') path++; /* Strip heading separator */\r
+ dj->sclust = 0; /* Set start directory (always root dir) */\r
+\r
+ if ((BYTE)*path <= ' ') { /* Null path means the root directory */\r
+ res = dir_rewind(dj);\r
+ dir[0] = 0;\r
+\r
+ } else { /* Follow path */\r
+ for (;;) {\r
+ res = create_name(dj, &path); /* Get a segment */\r
+ if (res != FR_OK) break;\r
+ res = dir_find(dj, dir); /* Find it */\r
+ if (res != FR_OK) { /* Could not find the object */\r
+ if (res == FR_NO_FILE && !*(dj->fn+11))\r
+ res = FR_NO_PATH;\r
+ break;\r
+ }\r
+ if (*(dj->fn+11)) break; /* Last segment match. Function completed. */\r
+ if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */\r
+ res = FR_NO_PATH; break;\r
+ }\r
+ dj->sclust = LD_CLUST(dir);\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Check a sector if it is an FAT boot record */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */\r
+ BYTE *buf, /* Working buffer */\r
+ DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */\r
+)\r
+{\r
+ if (disk_readp(buf, sect, 510, 2)) /* Read the boot sector */\r
+ return 3;\r
+ if (LD_WORD(buf) != 0xAA55) /* Check record signature */\r
+ return 2;\r
+\r
+ if (!disk_readp(buf, sect, BS_FilSysType, 2) && LD_WORD(buf) == 0x4146) /* Check FAT12/16 */\r
+ return 0;\r
+ if (_FS_FAT32 && !disk_readp(buf, sect, BS_FilSysType32, 2) && LD_WORD(buf) == 0x4146) /* Check FAT32 */\r
+ return 0;\r
+ return 1;\r
+}\r
+\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Public Functions\r
+\r
+--------------------------------------------------------------------------*/\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Mount/Unmount a Locical Drive */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT pf_mount (\r
+ FATFS *fs /* Pointer to new file system object (NULL: Unmount) */\r
+)\r
+{\r
+ BYTE fmt, buf[36];\r
+ DWORD bsect, fsize, tsect, mclst;\r
+\r
+\r
+ FatFs = 0;\r
+ if (!fs) return FR_OK; /* Unregister fs object */\r
+\r
+ if (disk_initialize() & STA_NOINIT) /* Check if the drive is ready or not */\r
+ return FR_NOT_READY;\r
+\r
+ /* Search FAT partition on the drive */\r
+ bsect = 0;\r
+ fmt = check_fs(buf, bsect); /* Check sector 0 as an SFD format */\r
+ if (fmt == 1) { /* Not an FAT boot record, it may be FDISK format */\r
+ /* Check a partition listed in top of the partition table */\r
+ if (disk_readp(buf, bsect, MBR_Table, 16)) { /* 1st partition entry */\r
+ fmt = 3;\r
+ } else {\r
+ if (buf[4]) { /* Is the partition existing? */\r
+ bsect = LD_DWORD(&buf[8]); /* Partition offset in LBA */\r
+ fmt = check_fs(buf, bsect); /* Check the partition */\r
+ }\r
+ }\r
+ }\r
+ if (fmt == 3) return FR_DISK_ERR;\r
+ if (fmt) return FR_NO_FILESYSTEM; /* No valid FAT patition is found */\r
+\r
+ /* Initialize the file system object */\r
+ if (disk_readp(buf, bsect, 13, sizeof(buf))) return FR_DISK_ERR;\r
+\r
+ fsize = LD_WORD(buf+BPB_FATSz16-13); /* Number of sectors per FAT */\r
+ if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13);\r
+\r
+ fsize *= buf[BPB_NumFATs-13]; /* Number of sectors in FAT area */\r
+ fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */\r
+ fs->csize = buf[BPB_SecPerClus-13]; /* Number of sectors per cluster */\r
+ fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13); /* Nmuber of root directory entries */\r
+ tsect = LD_WORD(buf+BPB_TotSec16-13); /* Number of sectors on the file system */\r
+ if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13);\r
+ mclst = (tsect /* Last cluster# + 1 */\r
+ - LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16\r
+ ) / fs->csize + 2;\r
+ fs->n_fatent = (CLUST)mclst;\r
+\r
+ fmt = FS_FAT16; /* Determine the FAT sub type */\r
+ if (mclst < 0xFF7) /* Number of clusters < 0xFF5 */\r
+#if _FS_FAT12\r
+ fmt = FS_FAT12;\r
+#else\r
+ return FR_NO_FILESYSTEM;\r
+#endif\r
+ if (mclst >= 0xFFF7) /* Number of clusters >= 0xFFF5 */\r
+#if _FS_FAT32\r
+ fmt = FS_FAT32;\r
+#else\r
+ return FR_NO_FILESYSTEM;\r
+#endif\r
+\r
+ fs->fs_type = fmt; /* FAT sub-type */\r
+ if (_FS_FAT32 && fmt == FS_FAT32)\r
+ fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13)); /* Root directory start cluster */\r
+ else\r
+ fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */\r
+ fs->database = fs->fatbase + fsize + fs->n_rootdir / 16; /* Data start sector (lba) */\r
+\r
+ fs->flag = 0;\r
+ FatFs = fs;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Open or Create a File */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT pf_open (\r
+ const char *path /* Pointer to the file name */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj;\r
+ BYTE sp[12], dir[32];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) /* Check file system */\r
+ return FR_NOT_ENABLED;\r
+\r
+ fs->flag = 0;\r
+ dj.fn = sp;\r
+ res = follow_path(&dj, dir, path); /* Follow the file path */\r
+ if (res != FR_OK) return res; /* Follow failed */\r
+ if (!dir[0] || (dir[DIR_Attr] & AM_DIR)) /* It is a directory */\r
+ return FR_NO_FILE;\r
+\r
+ fs->org_clust = LD_CLUST(dir); /* File start cluster */\r
+ fs->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */\r
+ fs->fptr = 0; /* File pointer */\r
+ fs->flag = FA_OPENED;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read File */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_READ\r
+\r
+FRESULT pf_read (\r
+ void* buff, /* Pointer to the read buffer (NULL:Forward data to the stream)*/\r
+ WORD btr, /* Number of bytes to read */\r
+ WORD* br /* Pointer to number of bytes read */\r
+)\r
+{\r
+ DRESULT dr;\r
+ CLUST clst;\r
+ DWORD sect, remain;\r
+ WORD rcnt;\r
+ BYTE cs, *rbuff = buff;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ *br = 0;\r
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */\r
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */\r
+ return FR_NOT_OPENED;\r
+\r
+ remain = fs->fsize - fs->fptr;\r
+ if (btr > remain) btr = (WORD)remain; /* Truncate btr by remaining bytes */\r
+\r
+ while (btr) { /* Repeat until all data transferred */\r
+ if ((fs->fptr % 512) == 0) { /* On the sector boundary? */\r
+ cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */\r
+ if (!cs) { /* On the cluster boundary? */\r
+ clst = (fs->fptr == 0) ? /* On the top of the file? */\r
+ fs->org_clust : get_fat(fs->curr_clust);\r
+ if (clst <= 1) goto fr_abort;\r
+ fs->curr_clust = clst; /* Update current cluster */\r
+ }\r
+ sect = clust2sect(fs->curr_clust); /* Get current sector */\r
+ if (!sect) goto fr_abort;\r
+ fs->dsect = sect + cs;\r
+ }\r
+ rcnt = (WORD)(512 - (fs->fptr % 512)); /* Get partial sector data from sector buffer */\r
+ if (rcnt > btr) rcnt = btr;\r
+ dr = disk_readp(!buff ? 0 : rbuff, fs->dsect, (WORD)(fs->fptr % 512), rcnt);\r
+ if (dr) goto fr_abort;\r
+ fs->fptr += rcnt; rbuff += rcnt; /* Update pointers and counters */\r
+ btr -= rcnt; *br += rcnt;\r
+ }\r
+\r
+ return FR_OK;\r
+\r
+fr_abort:\r
+ fs->flag = 0;\r
+ return FR_DISK_ERR;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Write File */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_WRITE\r
+\r
+FRESULT pf_write (\r
+ const void* buff, /* Pointer to the data to be written */\r
+ WORD btw, /* Number of bytes to write (0:Finalize the current write operation) */\r
+ WORD* bw /* Pointer to number of bytes written */\r
+)\r
+{\r
+ CLUST clst;\r
+ DWORD sect, remain;\r
+ const BYTE *p = buff;\r
+ BYTE cs;\r
+ WORD wcnt;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ *bw = 0;\r
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */\r
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */\r
+ return FR_NOT_OPENED;\r
+\r
+ if (!btw) { /* Finalize request */\r
+ if ((fs->flag & FA__WIP) && disk_writep(0, 0)) goto fw_abort;\r
+ fs->flag &= ~FA__WIP;\r
+ return FR_OK;\r
+ } else { /* Write data request */\r
+ if (!(fs->flag & FA__WIP)) /* Round-down fptr to the sector boundary */\r
+ fs->fptr &= 0xFFFFFE00;\r
+ }\r
+ remain = fs->fsize - fs->fptr;\r
+ if (btw > remain) btw = (WORD)remain; /* Truncate btw by remaining bytes */\r
+\r
+ while (btw) { /* Repeat until all data transferred */\r
+ if (((WORD)fs->fptr % 512) == 0) { /* On the sector boundary? */\r
+ cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */\r
+ if (!cs) { /* On the cluster boundary? */\r
+ clst = (fs->fptr == 0) ? /* On the top of the file? */\r
+ fs->org_clust : get_fat(fs->curr_clust);\r
+ if (clst <= 1) goto fw_abort;\r
+ fs->curr_clust = clst; /* Update current cluster */\r
+ }\r
+ sect = clust2sect(fs->curr_clust); /* Get current sector */\r
+ if (!sect) goto fw_abort;\r
+ fs->dsect = sect + cs;\r
+ if (disk_writep(0, fs->dsect)) goto fw_abort; /* Initiate a sector write operation */\r
+ fs->flag |= FA__WIP;\r
+ }\r
+ wcnt = 512 - ((WORD)fs->fptr % 512); /* Number of bytes to write to the sector */\r
+ if (wcnt > btw) wcnt = btw;\r
+ if (disk_writep(p, wcnt)) goto fw_abort; /* Send data to the sector */\r
+ fs->fptr += wcnt; p += wcnt; /* Update pointers and counters */\r
+ btw -= wcnt; *bw += wcnt;\r
+ if (((WORD)fs->fptr % 512) == 0) {\r
+ if (disk_writep(0, 0)) goto fw_abort; /* Finalize the currtent secter write operation */\r
+ fs->flag &= ~FA__WIP;\r
+ }\r
+ }\r
+\r
+ return FR_OK;\r
+\r
+fw_abort:\r
+ fs->flag = 0;\r
+ return FR_DISK_ERR;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Seek File R/W Pointer */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_LSEEK\r
+\r
+FRESULT pf_lseek (\r
+ DWORD ofs /* File pointer from top of file */\r
+)\r
+{\r
+ CLUST clst;\r
+ DWORD bcs, sect, ifptr;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */\r
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */\r
+ return FR_NOT_OPENED;\r
+\r
+ if (ofs > fs->fsize) ofs = fs->fsize; /* Clip offset with the file size */\r
+ ifptr = fs->fptr;\r
+ fs->fptr = 0;\r
+ if (ofs > 0) {\r
+ bcs = (DWORD)fs->csize * 512; /* Cluster size (byte) */\r
+ if (ifptr > 0 &&\r
+ (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */\r
+ fs->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */\r
+ ofs -= fs->fptr;\r
+ clst = fs->curr_clust;\r
+ } else { /* When seek to back cluster, */\r
+ clst = fs->org_clust; /* start from the first cluster */\r
+ fs->curr_clust = clst;\r
+ }\r
+ while (ofs > bcs) { /* Cluster following loop */\r
+ clst = get_fat(clst); /* Follow cluster chain */\r
+ if (clst <= 1 || clst >= fs->n_fatent) goto fe_abort;\r
+ fs->curr_clust = clst;\r
+ fs->fptr += bcs;\r
+ ofs -= bcs;\r
+ }\r
+ fs->fptr += ofs;\r
+ sect = clust2sect(clst); /* Current sector */\r
+ if (!sect) goto fe_abort;\r
+ fs->dsect = sect + (fs->fptr / 512 & (fs->csize - 1));\r
+ }\r
+\r
+ return FR_OK;\r
+\r
+fe_abort:\r
+ fs->flag = 0;\r
+ return FR_DISK_ERR;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Create a Directroy Object */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_DIR\r
+\r
+FRESULT pf_opendir (\r
+ DIR *dj, /* Pointer to directory object to create */\r
+ const char *path /* Pointer to the directory path */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE sp[12], dir[32];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) { /* Check file system */\r
+ res = FR_NOT_ENABLED;\r
+ } else {\r
+ dj->fn = sp;\r
+ res = follow_path(dj, dir, path); /* Follow the path to the directory */\r
+ if (res == FR_OK) { /* Follow completed */\r
+ if (dir[0]) { /* It is not the root dir */\r
+ if (dir[DIR_Attr] & AM_DIR) /* The object is a directory */\r
+ dj->sclust = LD_CLUST(dir);\r
+ else /* The object is not a directory */\r
+ res = FR_NO_PATH;\r
+ }\r
+ if (res == FR_OK)\r
+ res = dir_rewind(dj); /* Rewind dir */\r
+ }\r
+ if (res == FR_NO_FILE) res = FR_NO_PATH;\r
+ }\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read Directory Entry in Sequense */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT pf_readdir (\r
+ DIR *dj, /* Pointer to the open directory object */\r
+ FILINFO *fno /* Pointer to file information to return */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE sp[12], dir[32];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) { /* Check file system */\r
+ res = FR_NOT_ENABLED;\r
+ } else {\r
+ dj->fn = sp;\r
+ if (!fno) {\r
+ res = dir_rewind(dj);\r
+ } else {\r
+ res = dir_read(dj, dir);\r
+ if (res == FR_NO_FILE) {\r
+ dj->sect = 0;\r
+ res = FR_OK;\r
+ }\r
+ if (res == FR_OK) { /* A valid entry is found */\r
+ get_fileinfo(dj, dir, fno); /* Get the object information */\r
+ res = dir_next(dj); /* Increment index for next */\r
+ if (res == FR_NO_FILE) {\r
+ dj->sect = 0;\r
+ res = FR_OK;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+\r
+#endif /* _USE_DIR */\r
+\r
--- /dev/null
+/*---------------------------------------------------------------------------/\r
+/ Petit FatFs - FAT file system module include file R0.02a (C)ChaN, 2010\r
+/----------------------------------------------------------------------------/\r
+/ Petit FatFs module is an open source software to implement FAT file system to\r
+/ small embedded systems. This is a free software and is opened for education,\r
+/ research and commercial developments under license policy of following trems.\r
+/\r
+/ Copyright (C) 2010, ChaN, all right reserved.\r
+/\r
+/ * The Petit FatFs module is a free software and there is NO WARRANTY.\r
+/ * No restriction on use. You can use, modify and redistribute it for\r
+/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.\r
+/ * Redistributions of source code must retain the above copyright notice.\r
+/\r
+/----------------------------------------------------------------------------*/\r
+\r
+#include "integer.h"\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Petit FatFs Configuration Options\r
+/\r
+/ CAUTION! Do not forget to make clean the project after any changes to\r
+/ the configuration options.\r
+/\r
+/----------------------------------------------------------------------------*/\r
+#ifndef _FATFS\r
+#define _FATFS\r
+\r
+#define _USE_READ 1 /* 1:Enable pf_read() */\r
+\r
+#define _USE_DIR 1 /* 1:Enable pf_opendir() and pf_readdir() */\r
+\r
+#define _USE_LSEEK 1 /* 1:Enable pf_lseek() */\r
+\r
+#define _USE_WRITE 1 /* 1:Enable pf_write() */\r
+\r
+#define _FS_FAT12 1 /* 1:Enable FAT12 support */\r
+#define _FS_FAT32 1 /* 1:Enable FAT32 support */\r
+\r
+\r
+#define _CODE_PAGE 1\r
+/* Defines which code page is used for path name. Supported code pages are:\r
+/ 932, 936, 949, 950, 437, 720, 737, 775, 850, 852, 855, 857, 858, 862, 866,\r
+/ 874, 1250, 1251, 1252, 1253, 1254, 1255, 1257, 1258 and 1 (ASCII only).\r
+/ SBCS code pages except for 1 requiers a case conversion table. This\r
+/ might occupy 128 bytes on the RAM on some platforms, e.g. avr-gcc. */\r
+\r
+\r
+#define _WORD_ACCESS 0\r
+/* The _WORD_ACCESS option defines which access method is used to the word\r
+/ data in the FAT structure.\r
+/\r
+/ 0: Byte-by-byte access. Always compatible with all platforms.\r
+/ 1: Word access. Do not choose this unless following condition is met.\r
+/\r
+/ When the byte order on the memory is big-endian or address miss-aligned\r
+/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.\r
+/ If it is not the case, the value can also be set to 1 to improve the\r
+/ performance and code efficiency. */\r
+\r
+\r
+/* End of configuration options. Do not change followings without care. */\r
+/*--------------------------------------------------------------------------*/\r
+\r
+\r
+\r
+#if _FS_FAT32\r
+#define CLUST DWORD\r
+#else\r
+#define CLUST WORD\r
+#endif\r
+\r
+\r
+/* File system object structure */\r
+\r
+typedef struct {\r
+ BYTE fs_type; /* FAT sub type */\r
+ BYTE flag; /* File status flags */\r
+ BYTE csize; /* Number of sectors per cluster */\r
+ BYTE pad1;\r
+ WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */\r
+ CLUST n_fatent; /* Number of FAT entries (= number of clusters + 2) */\r
+ DWORD fatbase; /* FAT start sector */\r
+ DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */\r
+ DWORD database; /* Data start sector */\r
+ DWORD fptr; /* File R/W pointer */\r
+ DWORD fsize; /* File size */\r
+ CLUST org_clust; /* File start cluster */\r
+ CLUST curr_clust; /* File current cluster */\r
+ DWORD dsect; /* File current data sector */\r
+} FATFS;\r
+\r
+/* Directory object structure */\r
+\r
+typedef struct {\r
+ WORD index; /* Current read/write index number */\r
+ BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */\r
+ CLUST sclust; /* Table start cluster (0:Static table) */\r
+ CLUST clust; /* Current cluster */\r
+ DWORD sect; /* Current sector */\r
+} DIR;\r
+\r
+/* File status structure */\r
+\r
+typedef struct {\r
+ DWORD fsize; /* File size */\r
+ WORD fdate; /* Last modified date */\r
+ WORD ftime; /* Last modified time */\r
+ BYTE fattrib; /* Attribute */\r
+ char fname[13]; /* File name */\r
+} FILINFO;\r
+\r
+\r
+\r
+/* File function return code (FRESULT) */\r
+\r
+typedef enum {\r
+ FR_OK = 0, /* 0 */\r
+ FR_DISK_ERR, /* 1 */\r
+ FR_NOT_READY, /* 2 */\r
+ FR_NO_FILE, /* 3 */\r
+ FR_NO_PATH, /* 4 */\r
+ FR_NOT_OPENED, /* 5 */\r
+ FR_NOT_ENABLED, /* 6 */\r
+ FR_NO_FILESYSTEM /* 7 */\r
+} FRESULT;\r
+\r
+\r
+\r
+/*--------------------------------------------------------------*/\r
+/* Petit FatFs module application interface */\r
+\r
+FRESULT pf_mount (FATFS*); /* Mount/Unmount a logical drive */\r
+FRESULT pf_open (const char*); /* Open a file */\r
+FRESULT pf_read (void*, WORD, WORD*); /* Read data from the open file */\r
+FRESULT pf_write (const void*, WORD, WORD*); /* Write data to the open file */\r
+FRESULT pf_lseek (DWORD); /* Move file pointer of the open file */\r
+FRESULT pf_opendir (DIR*, const char*); /* Open a directory */\r
+FRESULT pf_readdir (DIR*, FILINFO*); /* Read a directory item from the open directory */\r
+\r
+\r
+\r
+/*--------------------------------------------------------------*/\r
+/* Flags and offset address */\r
+\r
+/* File status flag (FATFS.flag) */\r
+\r
+#define FA_OPENED 0x01\r
+#define FA_WPRT 0x02\r
+#define FA__WIP 0x40\r
+\r
+\r
+/* FAT sub type (FATFS.fs_type) */\r
+\r
+#define FS_FAT12 1\r
+#define FS_FAT16 2\r
+#define FS_FAT32 3\r
+\r
+\r
+/* File attribute bits for directory entry */\r
+\r
+#define AM_RDO 0x01 /* Read only */\r
+#define AM_HID 0x02 /* Hidden */\r
+#define AM_SYS 0x04 /* System */\r
+#define AM_VOL 0x08 /* Volume label */\r
+#define AM_LFN 0x0F /* LFN entry */\r
+#define AM_DIR 0x10 /* Directory */\r
+#define AM_ARC 0x20 /* Archive */\r
+#define AM_MASK 0x3F /* Mask of defined bits */\r
+\r
+\r
+/*--------------------------------*/\r
+/* Multi-byte word access macros */\r
+\r
+#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */\r
+#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))\r
+#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))\r
+#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)\r
+#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)\r
+#else /* Use byte-by-byte access to the FAT structure */\r
+#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))\r
+#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))\r
+#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)\r
+#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)\r
+#endif\r
+\r
+\r
+#endif /* _FATFS */\r
--- /dev/null
+#include "re.h"
+
+#define H8_3069F_TMDR ((volatile uint8 *)0xFFFF62)
+#define H8_3069F_TSTR ((volatile uint8 *)0xFFFF60)
+#define H8_3069F_16TCNT2H ((volatile uint8 *)0xFFFF7A)
+#define H8_3069F_16TCNT2L ((volatile uint8 *)0xFFFF7B)
+
+#define TMDR_BIT_MDF (1 << 6)
+#define TSTR_BIT_STR2 (1 << 2)
+
+int re_init(void)
+{
+ *H8_3069F_TMDR = TMDR_BIT_MDF;
+ *H8_3069F_TSTR = TSTR_BIT_STR2;
+
+ return 0;
+}
+
+uint16 re_read(void)
+{
+ return ((*H8_3069F_16TCNT2H) << 8) | (*H8_3069F_16TCNT2L << 0);
+}
+
--- /dev/null
+#ifndef _RE_H_INCLUDED_
+#define _RE_H_INCLUDED_
+
+#include "defines.h"
+
+int re_init(void);
+uint16 re_read(void);
+
+#endif
+
--- /dev/null
+#include "defines.h"
+#include "serial.h"
+
+#define SERIAL_SCI_NUM 3
+
+#define H8_3069F_SCI0 ((volatile struct h8_3069f_sci *)0xffffb0)
+#define H8_3069F_SCI1 ((volatile struct h8_3069f_sci *)0xffffb8)
+#define H8_3069F_SCI2 ((volatile struct h8_3069f_sci *)0xffffc0)
+
+struct h8_3069f_sci {
+ volatile uint8 smr;
+ volatile uint8 brr;
+ volatile uint8 scr;
+ volatile uint8 tdr;
+ volatile uint8 ssr;
+ volatile uint8 rdr;
+ volatile uint8 scmr;
+};
+
+#define H8_3069F_SCI_SMR_CKS_PER1 (0<<0)
+#define H8_3069F_SCI_SMR_CKS_PER4 (1<<0)
+#define H8_3069F_SCI_SMR_CKS_PER16 (2<<0)
+#define H8_3069F_SCI_SMR_CKS_PER64 (3<<0)
+#define H8_3069F_SCI_SMR_MP (1<<2)
+#define H8_3069F_SCI_SMR_STOP (1<<3)
+#define H8_3069F_SCI_SMR_OE (1<<4)
+#define H8_3069F_SCI_SMR_PE (1<<5)
+#define H8_3069F_SCI_SMR_CHR (1<<6)
+#define H8_3069F_SCI_SMR_CA (1<<7)
+
+#define H8_3069F_SCI_SCR_CKE0 (1<<0)
+#define H8_3069F_SCI_SCR_CKE1 (1<<1)
+#define H8_3069F_SCI_SCR_TEIE (1<<2)
+#define H8_3069F_SCI_SCR_MPIE (1<<3)
+#define H8_3069F_SCI_SCR_RE (1<<4) /* ¼õ¿®Í¸ú */
+#define H8_3069F_SCI_SCR_TE (1<<5) /* Á÷¿®Í¸ú */
+#define H8_3069F_SCI_SCR_RIE (1<<6) /* ¼õ¿®³ä¹þ¤ß͸ú */
+#define H8_3069F_SCI_SCR_TIE (1<<7) /* Á÷¿®³ä¹þ¤ß͸ú */
+
+#define H8_3069F_SCI_SSR_MPBT (1<<0)
+#define H8_3069F_SCI_SSR_MPB (1<<1)
+#define H8_3069F_SCI_SSR_TEND (1<<2)
+#define H8_3069F_SCI_SSR_PER (1<<3)
+#define H8_3069F_SCI_SSR_FERERS (1<<4)
+#define H8_3069F_SCI_SSR_ORER (1<<5)
+#define H8_3069F_SCI_SSR_RDRF (1<<6) /* ¼õ¿®´°Î» */
+#define H8_3069F_SCI_SSR_TDRE (1<<7) /* Á÷¿®´°Î» */
+
+static struct {
+ volatile struct h8_3069f_sci *sci;
+} regs[SERIAL_SCI_NUM] = {
+ { H8_3069F_SCI0 },
+ { H8_3069F_SCI1 },
+ { H8_3069F_SCI2 },
+};
+
+/* ¥Ç¥Ð¥¤¥¹½é´ü²½ */
+int serial_init(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+
+ sci->scr = 0;
+ sci->smr = 0;
+ sci->brr = 64; /* 20MHz¤Î¥¯¥í¥Ã¥¯¤«¤é9600bps¤òÀ¸À®(25MHz¤Î¾ì¹ç¤Ï80¤Ë¤¹¤ë) */
+ sci->scr = H8_3069F_SCI_SCR_RE | H8_3069F_SCI_SCR_TE; /* Á÷¼õ¿®²Äǽ */
+ sci->ssr = 0;
+
+ return 0;
+}
+
+/* Á÷¿®²Äǽ¤«¡© */
+int serial_is_send_enable(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ return (sci->ssr & H8_3069F_SCI_SSR_TDRE);
+}
+
+/* £±Ê¸»úÁ÷¿® */
+int serial_send_byte(int index, unsigned char c)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+
+ /* Á÷¿®²Äǽ¤Ë¤Ê¤ë¤Þ¤ÇÂÔ¤Ä */
+ while (!serial_is_send_enable(index))
+ ;
+ sci->tdr = c;
+ sci->ssr &= ~H8_3069F_SCI_SSR_TDRE; /* Á÷¿®³«»Ï */
+
+ return 0;
+}
+
+/* ¼õ¿®²Äǽ¤«¡© */
+int serial_is_recv_enable(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ return (sci->ssr & H8_3069F_SCI_SSR_RDRF);
+}
+
+/* £±Ê¸»ú¼õ¿® */
+unsigned char serial_recv_byte(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ unsigned char c;
+
+ /* ¼õ¿®Ê¸»ú¤¬Íè¤ë¤Þ¤ÇÂÔ¤Ä */
+ while (!serial_is_recv_enable(index))
+ ;
+ c = sci->rdr;
+ sci->ssr &= ~H8_3069F_SCI_SSR_RDRF; /* ¼õ¿®´°Î» */
+
+ return c;
+}
--- /dev/null
+#ifndef _SERIAL_H_INCLUDED_
+#define _SERIAL_H_INCLUDED_
+
+int serial_init(int index); /* ¥Ç¥Ð¥¤¥¹½é´ü²½ */
+int serial_is_send_enable(int index); /* Á÷¿®²Äǽ¤«¡© */
+int serial_send_byte(int index, unsigned char b); /* £±Ê¸»úÁ÷¿® */
+int serial_is_recv_enable(int index); /* ¼õ¿®²Äǽ¤«¡© */
+unsigned char serial_recv_byte(int index); /* £±Ê¸»ú¼õ¿® */
+
+#endif
--- /dev/null
+ .h8300h\r
+ .section .text\r
+ .global _start\r
+# .type _start,@function\r
+_start:\r
+ mov.l #_bootstack,sp\r
+ jsr @_main\r
+\r
+1:\r
+ bra 1b\r
--- /dev/null
+#include "sw.h"
+
+#define H8_3069F_P7DR ((volatile uint8 *)0xFFFFD6)
+#define H8_3069F_PADR ((volatile uint8 *)0xFFFFD9)
+
+#define SW_BIT_P7_SW1 (1 << 0)
+#define SW_BIT_P7_SW2 (1 << 1)
+#define SW_BIT_PA_SWRE (1 << 4)
+
+int sw_init(void)
+{
+ return 0;
+}
+
+uint8 sw_read(sw_target_t target)
+{
+ uint8 c = 0;
+ switch (target) {
+ case Sw1:
+ c = (*H8_3069F_P7DR & SW_BIT_P7_SW1) ? 0 : 1;
+ break;
+ case Sw2:
+ c = (*H8_3069F_P7DR & SW_BIT_P7_SW2) ? 0 : 1;
+ break;
+ case SwRe:
+ c = (*H8_3069F_PADR & SW_BIT_PA_SWRE) ? 0 : 1;
+ break;
+ }
+ return c;
+}
+
--- /dev/null
+#ifndef _SW_H_INCLUDED_
+#define _SW_H_INCLUDED_
+
+#include "defines.h"
+
+typedef enum {
+ Sw1,
+ Sw2,
+ SwRe,
+} sw_target_t;
+
+int sw_init(void);
+uint8 sw_read(sw_target_t target);
+
+#endif
+
--- /dev/null
+#include "defines.h"
+
+extern void start(void); /* ¥¹¥¿¡¼¥È¡¦¥¢¥Ã¥× */
+extern void intr_softerr(void); /* ¥½¥Õ¥È¥¦¥¨¥¢¡¦¥¨¥é¡¼ */
+extern void intr_syscall(void); /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë */
+extern void intr_serintr(void); /* ¥·¥ê¥¢¥ë³ä¹þ¤ß */
+extern void intr_timintr(void); /* ¥¿¥¤¥Þ³ä¹þ¤ß */
+extern void intr_ir_edge(void); /* ¥ê¥â¥³¥ó¥¨¥Ã¥¸³ä¹þ¤ß */
+extern void intr_ir_tovf(void); /* ¥ê¥â¥³¥ó¥¿¥¤¥Þ¡¼¥ª¡¼¥Ð¡¼¥Õ¥í¡¼³ä¹þ¤ß */
+
+/*
+ * ³ä¹þ¤ß¥Ù¥¯¥¿¤ÎÀßÄê¡¥
+ * ¥ê¥ó¥«¡¦¥¹¥¯¥ê¥×¥È¤ÎÄêµÁ¤Ë¤è¤ê¡¤ÀèƬÈÖÃϤËÇÛÃÖ¤µ¤ì¤ë¡¥
+ */
+void (*vectors[])(void) = {
+ start, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ intr_syscall, intr_softerr, intr_softerr, intr_softerr,
+ NULL, NULL, NULL, NULL, intr_ir_edge, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, intr_ir_tovf, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ intr_timintr, intr_timintr, intr_timintr, intr_timintr,
+ intr_timintr, intr_timintr, intr_timintr, intr_timintr,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ intr_serintr, intr_serintr, intr_serintr, intr_serintr,
+ intr_serintr, intr_serintr, intr_serintr, intr_serintr,
+ intr_serintr, intr_serintr, intr_serintr, intr_serintr,
+};
--- /dev/null
+
+#include "vs1011e.h"
+
+#define VS1011E_OPCODE_READ 0x03
+#define VS1011E_OPCODE_WRITE 0x02
+
+#define REGADDR_MODE 0x00
+#define REGADDR_STATUS 0x01
+#define REGADDR_BASS 0x02
+#define REGADDR_CLOCKF 0x03
+#define REGADDR_DECODE_TIME 0x04
+#define REGADDR_AUDATA 0x05
+#define REGADDR_WRAM 0x06
+#define REGADDR_WRAMADDR 0x07
+#define REGADDR_HDAT0 0x08
+#define REGADDR_HDAT1 0x09
+#define REGADDR_AIADDR 0x0A
+#define REGADDR_VOL 0x0B
+#define REGADDR_AICTRL0 0x0C
+#define REGADDR_AICTRL1 0x0D
+#define REGADDR_AICTRL2 0x0E
+#define REGADDR_AICTRL3 0x0F
+
+#define SM_DIFF (1 << 0)
+#define SM_LAYER12 (1 << 1)
+#define SM_RESET (1 << 2)
+#define SM_OUTOFWAV (1 << 3)
+#define SM_SETTOZERO1 (1 << 4)
+#define SM_TESTS (1 << 5)
+#define SM_STREAM (1 << 6)
+#define SM_SETTOZERO2 (1 << 7)
+#define SM_DACT (1 << 8)
+#define SM_SDIORD (1 << 9)
+#define SM_SDISHARE (1 << 10)
+#define SM_SDINEW (1 << 11)
+#define SM_SETTOZERO3 (1 << 12)
+#define SM_SETTOZERO4 (1 << 13)
+
+#define SCI_BASS_BITBASS_ST_AMP 12
+#define SCI_BASS_BITBASS_ST_FREQ 8
+#define SCI_BASS_BITBASS_SB_AMP 4
+#define SCI_BASS_BITBASS_SB_FREQ 0
+
+#define VS1011E_VSCTL1() do { *H8_3069F_P4DR |= P4DR_BIT_VSCCS; } while (0)
+#define VS1011E_VSCTL0() do { *H8_3069F_P4DR &= ~P4DR_BIT_VSCCS; } while (0)
+
+#define VS1011E_VSDAT1() do { *H8_3069F_P4DR |= P4DR_BIT_VSDCS; } while (0)
+#define VS1011E_VSDAT0() do { *H8_3069F_P4DR &= ~P4DR_BIT_VSDCS; } while (0)
+
+#define VS1011E_RESET1() do { *H8_3069F_P4DR |= P4DR_BIT_VSRST; } while (0)
+#define VS1011E_RESET0() do { *H8_3069F_P4DR &= ~P4DR_BIT_VSRST; } while (0)
+
+#define VS1011E_CHK_DREQ() (((*H8_3069F_P4DR) & P4DR_BIT_VSDREQ) ? 0 : 1)
+
+#define H8_3069F_P4DR ((volatile uint8 *)0xFFFFD3)
+#define P4DR_BIT_VSCCS (1 << 2)
+#define P4DR_BIT_VSDCS (1 << 3)
+#define P4DR_BIT_VSDREQ (1 << 4)
+#define P4DR_BIT_VSRST (1 << 5)
+
+#define H8_3069F_PBDR ((volatile uint8 *)0xFFFFDA)
+#define PBDR_BIT_SCLK (1 << 5)
+#define PBDR_BIT_MOSI (1 << 6)
+#define PBDR_BIT_MISO (1 << 7)
+
+#define CS_H() do { *H8_3069F_P4DR |= P4DR_BIT_CS; } while (0) /* Set MMC CS "high" */
+#define CS_L() do { *H8_3069F_P4DR &= ~P4DR_BIT_CS; } while (0) /* Set MMC CS "low" */
+#define CK_H() do { *H8_3069F_PBDR |= PBDR_BIT_SCLK; } while (0) /* Set MMC SCLK "high" */
+#define CK_L() do { *H8_3069F_PBDR &= ~PBDR_BIT_SCLK; } while (0) /* Set MMC SCLK "low" */
+#define DI_H() do { *H8_3069F_PBDR |= PBDR_BIT_MOSI; } while (0) /* Set MMC DI "high" */
+#define DI_L() do { *H8_3069F_PBDR &= ~PBDR_BIT_MOSI; } while (0) /* Set MMC DI "low" */
+#define DO ((*H8_3069F_PBDR & PBDR_BIT_MISO) ? 1 : 0) /* Get MMC DO value (high:true, low:false) */
+
+static void _delay_ms(int ms)
+{
+ int i;
+ for (i = 0; i < ms * 10000; i++) {
+ }
+}
+
+static void _delay_us(int us)
+{
+ int i;
+ for (i = 0; i < us * 10; i++) {
+ }
+}
+
+static void SPI_TX(uint8 d)
+{
+ if (d & 0x80) DI_H(); else DI_L(); /* bit7 */
+ CK_H(); CK_L();
+ if (d & 0x40) DI_H(); else DI_L(); /* bit6 */
+ CK_H(); CK_L();
+ if (d & 0x20) DI_H(); else DI_L(); /* bit5 */
+ CK_H(); CK_L();
+ if (d & 0x10) DI_H(); else DI_L(); /* bit4 */
+ CK_H(); CK_L();
+ if (d & 0x08) DI_H(); else DI_L(); /* bit3 */
+ CK_H(); CK_L();
+ if (d & 0x04) DI_H(); else DI_L(); /* bit2 */
+ CK_H(); CK_L();
+ if (d & 0x02) DI_H(); else DI_L(); /* bit1 */
+ CK_H(); CK_L();
+ if (d & 0x01) DI_H(); else DI_L(); /* bit0 */
+ CK_H(); CK_L();
+}
+static uint8 SPI_RX()
+{
+ uint8 r;
+
+ DI_H(); /* Send 0xFF */
+
+ r = 0; if (DO) r++; /* bit7 */
+ CK_H(); CK_L();
+ r <<= 1; if (DO) r++; /* bit6 */
+ CK_H(); CK_L();
+ r <<= 1; if (DO) r++; /* bit5 */
+ CK_H(); CK_L();
+ r <<= 1; if (DO) r++; /* bit4 */
+ CK_H(); CK_L();
+ r <<= 1; if (DO) r++; /* bit3 */
+ CK_H(); CK_L();
+ r <<= 1; if (DO) r++; /* bit2 */
+ CK_H(); CK_L();
+ r <<= 1; if (DO) r++; /* bit1 */
+ CK_H(); CK_L();
+ r <<= 1; if (DO) r++; /* bit0 */
+ CK_H(); CK_L();
+
+ return r;
+}
+
+static void vs1011e_read(uint8 addr, uint16 * stat);
+static void vs1011e_write(uint8 addr, uint16 stat);
+
+void vs1011e_init()
+{
+ vs1011e_reset_by_hardware();
+ vs1011e_reset_by_software();
+}
+
+void vs1011e_reset_by_hardware()
+{
+ // Assert vs1011 reset
+ VS1011E_RESET0();
+ // Delay 30ms
+ _delay_ms(30);
+ // Deassert CS by setting to high level
+ VS1011E_VSCTL1();
+ // Deassert DCS
+ VS1011E_VSDAT1();
+ // Release vs1011 reset
+ VS1011E_RESET1();
+ // Delay 10ms (2.5ms accordig to datasheet)
+ _delay_ms(10);
+ // Set volume to minimum
+ vs1011e_write(REGADDR_VOL, 0xFFFF);
+ // Set CLOCKF
+ vs1011e_write(REGADDR_CLOCKF, 0x9800);
+ // Delay 1ms
+ _delay_ms(1);
+ // Set slow sample rate for slow analog part startup
+ vs1011e_write(REGADDR_AUDATA, 10);
+ // Delay 100ms
+ _delay_ms(100);
+ // Switch on the analog parts
+ vs1011e_write(REGADDR_VOL, 0xFEFE);
+ vs1011e_write(REGADDR_AUDATA, 44101);
+ vs1011e_write(REGADDR_VOL, 0x0202);
+}
+
+void vs1011e_reset_by_software()
+{
+ uint16 i;
+
+ // Delay 200ms
+ _delay_ms(200);
+ // Set SW reset bit, set VS1011 native mode on SPI
+ vs1011e_write(REGADDR_MODE,
+ SM_LAYER12 | SM_RESET | SM_SDINEW | SM_TESTS);
+ // Delay 2us
+ _delay_us(2);
+ // Rewrite SCI_CLOCKF after soft reset
+ vs1011e_write(REGADDR_CLOCKF, 0x9800);
+ // Assert DCS
+ VS1011E_VSDAT0();
+ // Check the DREQ.
+ while (VS1011E_CHK_DREQ()) {
+ }
+ // Send 0x53 to SPI
+ SPI_TX(0x53);
+ // Send 1024 nulls
+ for (i = 0; i < 1024; i++) {
+ // Check the DREQ.
+ while (VS1011E_CHK_DREQ()) {
+ }
+ SPI_TX(0x00);
+ }
+ // Deassert DCS
+ VS1011E_VSDAT1();
+}
+
+void vs1011e_cancel_data()
+{
+ uint16 i;
+ while (VS1011E_CHK_DREQ()) {
+ }
+
+ VS1011E_VSDAT0();
+ for (i = 0; i < 2048; i++) {
+ while (VS1011E_CHK_DREQ()) {
+ }
+ SPI_TX(0x00);
+ }
+ VS1011E_VSDAT1();
+}
+
+void vs1011e_set_enhancer(uint8 st_amp, uint8 st_freq, uint8 sb_amp,
+ uint8 sb_freq)
+{
+ uint16 val =
+ (st_amp << SCI_BASS_BITBASS_ST_AMP) |
+ (st_freq << SCI_BASS_BITBASS_ST_FREQ) |
+ (sb_amp << SCI_BASS_BITBASS_SB_AMP) |
+ (sb_freq << SCI_BASS_BITBASS_SB_FREQ);
+ vs1011e_write(REGADDR_BASS, val);
+}
+
+void vs1011e_get_enhancer(uint8 * st_amp, uint8 * st_freq,
+ uint8 * sb_amp, uint8 * sb_freq)
+{
+ uint16 val;
+ vs1011e_read(REGADDR_BASS, &val);
+ *st_amp = (val >> SCI_BASS_BITBASS_ST_AMP) & 0x0F;
+ *st_freq = (val >> SCI_BASS_BITBASS_ST_FREQ) & 0x0F;
+ *sb_amp = (val >> SCI_BASS_BITBASS_SB_AMP) & 0x0F;
+ *sb_freq = (val >> SCI_BASS_BITBASS_SB_FREQ) & 0x0F;
+}
+
+void vs1011e_volume_read(uint8 * left, uint8 * right)
+{
+ uint16 val;
+ vs1011e_read(REGADDR_VOL, &val);
+ *left = val >> 8;
+ *right = val >> 0;
+}
+
+void vs1011e_volume_write(const uint8 left, const uint8 right)
+{
+ uint16 val =
+ (((uint16) left << 8) & 0xFF00) | (((uint16) right << 0) &
+ 0x00FF);
+ vs1011e_write(REGADDR_VOL, val);
+}
+
+void vs1011e_play(int8(*func) (uint8 * buf, const uint16 len))
+{
+#define UNITBYTE (128)
+ uint8 i;
+ uint8 buf[UNITBYTE];
+ while (1) {
+ /*
+ * Read the song data.
+ */
+ int8 len = func(buf, UNITBYTE);
+ if (len <= 0) {
+ return;
+ }
+ /*
+ * Send the data.
+ */
+ for (i = 0; i < UNITBYTE; i++) {
+ while (VS1011E_CHK_DREQ()) { }
+ VS1011E_VSDAT0();
+ SPI_TX(*(buf + i));
+ VS1011E_VSDAT1();
+ }
+ }
+}
+
+void vs1011e_decodetime_read(uint16 * sec)
+{
+ vs1011e_read(REGADDR_DECODE_TIME, sec);
+}
+
+void vs1011e_decodetime_write(const uint16 sec)
+{
+ vs1011e_write(REGADDR_DECODE_TIME, sec);
+}
+
+void vs1011e_sinetest_init()
+{
+ while (VS1011E_CHK_DREQ()) {
+ }
+
+ VS1011E_VSDAT0();
+ SPI_TX(0x53);
+ SPI_TX(0xEF);
+ SPI_TX(0x6E);
+ SPI_TX(0xF0);
+ SPI_TX(0x00);
+ SPI_TX(0x00);
+ SPI_TX(0x00);
+ SPI_TX(0x00);
+ VS1011E_VSDAT1();
+}
+
+void vs1011e_sinetest_fini()
+{
+ while (VS1011E_CHK_DREQ()) {
+ }
+
+ VS1011E_VSDAT0();
+ SPI_TX(0x45);
+ SPI_TX(0x78);
+ SPI_TX(0x69);
+ SPI_TX(0x74);
+ SPI_TX(0x00);
+ SPI_TX(0x00);
+ SPI_TX(0x00);
+ SPI_TX(0x00);
+ VS1011E_VSDAT1();
+
+ vs1011e_cancel_data();
+}
+
+void vs1011e_register_print()
+{
+#if 0
+ uint8 i;
+ uint16 val;
+ xprintf(PSTR("===================\r\n"));
+ for (i = 0; i <= 0x0F; i++) {
+ vs1011e_read(i, &val);
+ xprintf(PSTR("0x%02X: 0x%04X\r\n"), i, val);
+ }
+ xprintf(PSTR("===================\r\n"));
+#endif
+}
+
+static void vs1011e_read(uint8 addr, uint16 * stat)
+{
+ while (VS1011E_CHK_DREQ()) {
+ }
+
+ VS1011E_VSCTL0();
+
+ SPI_TX(VS1011E_OPCODE_READ);
+ SPI_TX(addr);
+
+ *stat = 0;
+ *stat |= SPI_RX() << 8;
+ *stat |= SPI_RX();
+
+ VS1011E_VSCTL1();
+}
+
+static void vs1011e_write(uint8 addr, uint16 stat)
+{
+ while (VS1011E_CHK_DREQ()) {
+ }
+
+ VS1011E_VSCTL0();
+
+ SPI_TX(VS1011E_OPCODE_WRITE);
+ SPI_TX(addr);
+
+ SPI_TX(stat >> 8);
+ SPI_TX(stat >> 0);
+
+ VS1011E_VSCTL1();
+}
--- /dev/null
+#ifndef VS1011_H
+#define VS1011_H
+
+#include "defines.h"
+
+void vs1011e_init(void);
+void vs1011e_reset_by_hardware(void);
+void vs1011e_reset_by_software(void);
+void vs1011e_cancel_data(void);
+void vs1011e_set_enhancer(uint8 st_amp, uint8 st_freq, uint8 sb_amp, uint8 sb_freq);
+void vs1011e_get_enhancer(uint8 * st_amp, uint8 * st_freq, uint8 * sb_amp, uint8 * sb_freq);
+void vs1011e_volume_read(uint8 * left, uint8 * right);
+void vs1011e_volume_write(const uint8 left, const uint8 right);
+void vs1011e_play(int8(*func) (uint8 * buf, const uint16 len));
+void vs1011e_decodetime_read(uint16 * sec);
+void vs1011e_decodetime_write(const uint16 sec);
+void vs1011e_register_print(void);
+
+void vs1011e_sinetest_init(void);
+void vs1011e_sinetest_fini(void);
+
+#endif
+
--- /dev/null
+#include "defines.h"
+#include "serial.h"
+#include "lib.h"
+#include "xmodem.h"
+
+#define XMODEM_SOH 0x01
+#define XMODEM_STX 0x02
+#define XMODEM_EOT 0x04
+#define XMODEM_ACK 0x06
+#define XMODEM_NAK 0x15
+#define XMODEM_CAN 0x18
+#define XMODEM_EOF 0x1a /* Ctrl-Z */
+
+#define XMODEM_BLOCK_SIZE 128
+
+/* ¼õ¿®³«»Ï¤µ¤ì¤ë¤Þ¤ÇÁ÷¿®Í×µá¤ò½Ð¤¹ */
+static int xmodem_wait(void)
+{
+ long cnt = 0;
+
+ while (!serial_is_recv_enable(SERIAL_DEFAULT_DEVICE)) {
+ if (++cnt >= 2000000) {
+ cnt = 0;
+ serial_send_byte(SERIAL_DEFAULT_DEVICE, XMODEM_NAK);
+ }
+ }
+
+ return 0;
+}
+
+/* ¥Ö¥í¥Ã¥¯Ã±°Ì¤Ç¤Î¼õ¿® */
+static int xmodem_read_block(unsigned char block_number, char *buf)
+{
+ unsigned char c, block_num, check_sum;
+ int i;
+
+ block_num = serial_recv_byte(SERIAL_DEFAULT_DEVICE);
+ if (block_num != block_number)
+ return -1;
+
+ block_num ^= serial_recv_byte(SERIAL_DEFAULT_DEVICE);
+ if (block_num != 0xff)
+ return -1;
+
+ check_sum = 0;
+ for (i = 0; i < XMODEM_BLOCK_SIZE; i++) {
+ c = serial_recv_byte(SERIAL_DEFAULT_DEVICE);
+ *(buf++) = c;
+ check_sum += c;
+ }
+
+ check_sum ^= serial_recv_byte(SERIAL_DEFAULT_DEVICE);
+ if (check_sum)
+ return -1;
+
+ return i;
+}
+
+long xmodem_recv(char *buf)
+{
+ int r, receiving = 0;
+ long size = 0;
+ unsigned char c, block_number = 1;
+
+ while (1) {
+ if (!receiving)
+ xmodem_wait(); /* ¼õ¿®³«»Ï¤µ¤ì¤ë¤Þ¤ÇÁ÷¿®Í×µá¤ò½Ð¤¹ */
+
+ c = serial_recv_byte(SERIAL_DEFAULT_DEVICE);
+
+ if (c == XMODEM_EOT) { /* ¼õ¿®½ªÎ» */
+ serial_send_byte(SERIAL_DEFAULT_DEVICE, XMODEM_ACK);
+ break;
+ } else if (c == XMODEM_CAN) { /* ¼õ¿®ÃæÃÇ */
+ return -1;
+ } else if (c == XMODEM_SOH) { /* ¼õ¿®³«»Ï */
+ receiving++;
+ r = xmodem_read_block(block_number, buf); /* ¥Ö¥í¥Ã¥¯Ã±°Ì¤Ç¤Î¼õ¿® */
+ if (r < 0) { /* ¼õ¿®¥¨¥é¡¼ */
+ serial_send_byte(SERIAL_DEFAULT_DEVICE, XMODEM_NAK);
+ } else { /* Àµ¾ï¼õ¿® */
+ block_number++;
+ size += r;
+ buf += r;
+ serial_send_byte(SERIAL_DEFAULT_DEVICE, XMODEM_ACK);
+ }
+ } else {
+ if (receiving)
+ return -1;
+ }
+ }
+
+ return size;
+}
--- /dev/null
+#ifndef _XMODEM_H_INCLUDED_
+#define _XMODEM_H_INCLUDED_
+
+long xmodem_recv(char *buf);
+
+#endif
--- /dev/null
+Àî¹çƲ¥é¥¤¥»¥ó¥¹-01 ver.1.0
+ 2000.12.30 H.Kawai (Àî¹ç½¨¼Â)
+ 2007.10.07 ¥ê¥ó¥¯½¤Àµ:¤¢¤Ã¤¤£
+
+£°¡¥³µÍ×
+
+ Ê¿¤¿¤¯¸À¤¦¤È¡¢¡Ö¥Õ¥ê¡¼¥½¥Õ¥È¤Ç¤¹¡£»ÈÍÑÁ°»ÈÍѸå¤ËÂвÁ¤ò»Ùʧ¤¦¤³¤È¤Ê¤¯¡¢¼«Í³¤Ë»È
+¤¨¤Þ¤¹¡£¥³¥Ô¡¼¤·¤Æ¤â¤¤¤¤¤Ç¤¹¡£²þÊѤ·¤Æ¤â¤¤¤¤¤Ç¤¹¡£¾¦¶ÈÍøÍѤ·¤Æ¤â¤¤¤¤¤Ç¤¹¡£¤Ç¤â¥Ð
+¥°¤Ê¤É¤Ç»³²¤¬½Ð¤Æ¤âÀÕǤ¤Ï¤È¤ì¤Þ¤»¤ó¡£¡×¤Ã¤Æ¤³¤È¤Ç¤¹¡£
+
+ ÍøÍѼԤä²þÊѤ·¤¿¤ê»²¹Í¤Ë¤·¤¿¤ê¤¹¤ë¿Í¤ÎÍø±×¤Î¤¿¤á¤Ë¡¢¥×¥í¥°¥é¥àÃæ¤Ç»È¤Ã¤Æ¤¤¤ë¥¢
+¥ë¥´¥ê¥º¥à¤ÇÃøºî¼Ô¤¬¾ÍèÆõö¤ò¤È¤ë¤³¤È¤¬¤¢¤Ã¤Æ¤â¡¢ÆõöÎÁ¤òÍ׵ᤷ¤¿¤ê¤Ï¤·¤Ê¤¤¤È¤¤
+¤¦Êݾڤ⤢¤ê¤Þ¤¹¡£
+
+£±¡¥ÌÜŪ
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤ÇÄ󶡤µ¤ì¤ë¥½¥Õ¥È¥¦¥§¥¢¤Ï¡¢¾¯¤·¤Ç¤â¿¤¯¤Î¿Í¤ËÍø±×¤ò¤â¤¿¤é¤·¡¢¥½
+¥Õ¥È¥¦¥§¥¢µ»½Ñ¤Î¿ÊÊâ¤Ë¾¯¤·¤Ç¤â¹×¸¥¤Ç¤¤ì¤Ð¤È¤¤¤¦ÌÜŪ¤Ç¸ø³«¤¹¤ë¡£
+
+£²¡¥¼ñ»Ý
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤Ï¡¢Ãøºî¸¢¤òÊü´þ¤¹¤ë¤â¤Î¤Ç¤Ï¤Ê¤¤¡ÊÆÈÀêŪ¤Ë¥³¥Ô¡¼¤¹¤ë¸¢Íø¤ÏÊü´þ¤·
+¤Æ¤¤¤ë¡Ë¡£ÍøÍѼԤϤ³¤Î¥½¥Õ¥È¥¦¥§¥¢¤Î°ìÉô¤Þ¤¿¤ÏÁ´Éô¤ò¼«Í³¤Ë¥³¥Ô¡¼¤·¡¢ºÆÇÛÉÛ¤¹¤ë¤³
+¤È¤¬¤Ç¤¤ë¡£ÍøÍѤ˺ݤ·¤ÆÂвÁ¤òÍ׵ᤷ¤Ê¤¤¡£²òÀÏ¡¢²þÊѤâÂвÁ¤Ê¤·¤Ëǧ¤á¤ë¡£
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤¬Å¬ÍѤµ¤ì¤ë¥½¥Õ¥È¥¦¥§¥¢¤ÎÍøÍѤˤĤ¤¤Æ¡¢¾¦¶ÈŪ¤ÊÍøÍѤâ̵¾ò·ï¤Çǧ
+¤á¤ë¡£¤½¤Î¤Þ¤Þͽþ¤ÇÈÎÇ䤷¤Æ¤â¹½¤ï¤Ê¤¤¡£
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤¬Å¬ÍѤµ¤ì¤ë¥½¥Õ¥È¥¦¥§¥¢¤Î°ìÉô¤Þ¤¿¤ÏÁ´Éô¤ò¸µ¤Ë¤·¤ÆºîÀ®¤µ¤ì¤¿¥½¥Õ
+¥È¥¦¥§¥¢¡Ê°Ê¹ß¡¢ÇÉÀ¸Êª¤È¾Î¤¹¤ë¡Ë¤ËÂФ·¡¢¤É¤ó¤Ê¥é¥¤¥»¥ó¥¹¤òÉÕÍ¿¤·¤Æ¤â¤è¤¤¡£¤¹¤Ê¤ï
+¤Á¡¢ÇÉÀ¸Êª¤¬¥³¥Ô¡¼¶Ø»ß¤Ç¤¢¤Ã¤Æ¤â¤è¤¤¤·¡¢ÇÉÀ¸Êª¤¬Í½þ¤Ç¤·¤«ÇÛÉÛ¤µ¤ì¤Ê¤¯¤Æ¤â¹½¤ï¤Ê
+¤¤¡£¤â¤Á¤í¤ó̵½þ¤Ç¤¢¤Ã¤Æ¤â¤è¤¤¡£ÇÉÀ¸Êª¤ËÂФ¹¤ëÃøºî¸¢¤Ï¡¢ÇÉÀ¸Êª¤òÀ¸À®¤·¤¿¼Ô¤Ëµ¢¤·
+¡¢¤³¤Î¥é¥¤¥»¥ó¥¹¤¬Å¬ÍѤµ¤ì¤ë¥½¥Õ¥È¥¦¥§¥¢¤ÎÃøºî¼Ô¤¬ÇÉÀ¸Êª¤ËÂФ·¤ÆÃøºî¸¢¤ò¼çÄ¥¤¹¤ë
+¤³¤È¤Ï¤Ê¤¤¡£
+
+ ÇÉÀ¸Êª¤Î¥É¥¥å¥á¥ó¥ÈÃæ¤Ë¡¢¸µ¤Ë¤·¤¿¥½¥Õ¥È¥¦¥§¥¢¤ÎÃøºî¼Ô¤ò¾Ò²ð¤¹¤ëµÁ̳¤Ï¤Ê¤¤¡£¤³
+¤Îʸ¤Ï¡¢¤â¤Á¤í¤ó¡¢¾Ò²ð¤¹¤ë¤³¤È¤ò¶Ø»ß¤¹¤ë¤â¤Î¤Ç¤â¤Ê¤¤¡£
+
+ ÇÉÀ¸Êª¤Î¸ø³«¤ËºÝ¤·¤Æ¡¢¸µ¤Ë¤·¤¿¥½¥Õ¥È¥¦¥§¥¢¤ÎÃøºî¼Ô¤Ë³Îǧ¤ò¼è¤ëµÁ̳¤Ï¤Ê¤¤¡£¤³¤Î
+ʸ¤Ï¡¢¤â¤Á¤í¤ó¡¢³Îǧ¤ò¶Ø»ß¤¹¤ë¤â¤Î¤Ç¤Ï¤Ê¤¤¡£
+
+ Ãøºî¼Ô¤Ï¡¢¥½¥Õ¥È¥¦¥§¥¢¤Î¼Á¤òÊݾڤ·¤Ê¤¤¡£¤·¤¿¤¬¤Ã¤Æ¡¢¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤ÇÈï³²¤òÈï
+¤Ã¤¿¤ê¡¢´üÂÔ¤·¤¿·ë²Ì¤¬ÆÀ¤é¤ì¤Ê¤¯¤Æ¤â¡¢Ãøºî¼Ô¤ÏÀÕǤ¤òÉé¤ï¤Ê¤¤¡£
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤¬Å¬ÍѤµ¤ì¤ë¥½¥Õ¥È¥¦¥§¥¢¤Ç»È¤ï¤ì¤Æ¤¤¤ëµ»½Ñ¤Ë¤Ä¤¤¤Æ¤Ï¡¢»öÁ°¤ËÃøºî
+¼Ô¤Ëµö¤µ¤ì¤¿¼Ô°Ê³°¤¬Æõö¤ò¼èÆÀ¤¹¤ë¤³¤È¤Ï¶Ø»ß¤¹¤ë¡£¿·¤¿¤Êµ»½Ñ¤ò²Ã¤¨¤¿ÇÉÀ¸Êª¤òÀ¸À®
+¤·¡¢¤½¤ÎÄɲ䵤줿Éôʬ¤ÎÆõö¤ò¤È¤ë¤³¤È¤Ïǧ¤á¤ë¡£Ãøºî¼Ô¤¬¥½¥Õ¥È¥¦¥§¥¢Ãæ¤Îµ»½Ñ¤ËÂÐ
+¤·¤Æ¸å¤«¤éÆõö¤ò¤È¤ë¤³¤È¤Ï¤¢¤ê¤¦¤ë¤¬¡¢ÇÉÀ¸Êª¤ä¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤ÎÍøÍѤËÂФ·¤ÆÆõö
+ÎÁ¤ä¤½¤Î¾¤ÎÂвÁ¤òµá¤á¤ë¤³¤È¤Ï¤Ê¤¤¤³¤È¤òÊݾڤ¹¤ë¡£¤³¤ÎÊݾڤϡ¢Æõö¼èÆÀÁ°¤ËÀ¸À®¤µ
+¤ì¤¿ÇÉÀ¸Êª¤À¤±¤Ç¤Ê¤¯¡¢Æõö¼èÆÀ¸å¤ËÀ¸À®¤µ¤ì¤¿ÇÉÀ¸Êª¤Ë¤âŬÍѤµ¤ì¤ë¡£
+
+ ²òÀÏ·ë²Ì¤ò¤Þ¤È¤á¤ÆÆõö¤ò¤È¤ë¤³¤È¤Ë¤Ï»öÁ°¤ÎÃøºî¼Ô¤Îµö²Ä¤¬É¬ÍפÀ¤«¡¢Æõö¤ò¤È¤ë¤³
+¤È°Ê³°¤Ë¤Ä¤¤¤Æ¤Ï²¿¤éÀ©¸Â¤Ï¤Ê¤¤¡£
+
+£³¡¥ÊäÂ
+
+ ´ðËÜŪ¤Ë¡¢¥³¥Ô¡¼¤ÏÂç´¿·Þ¤Ç¤¹¡£¤â¤·¡¢Ãøºî¼Ô¤Ë²¿¤«²¸¤ò´¶¤¸¤¿¤é¡¢°ì¿Í¤Ç¤â¿¤¯¤Î¿Í
+¤Ë¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤ò¤¹¤¹¤á¤Æ¡¢¥³¥Ô¡¼¤·¤Æ¤¢¤²¤Æ²¼¤µ¤¤¡£Ãøºî¼Ô¤Ï¿¤¯¤Î¿Í¤Ë»È¤Ã¤Æ¤â
+¤é¤¤¤¿¤¤¤È»×¤Ã¤Æ¤¤¤ë¤Î¤Ç¡¢¥³¥Ô¡¼¤¹¤ì¤ÐÃøºî¼Ô¤Ï´î¤Ó¤Þ¤¹¡£¤½¤ì¤Ç¤â¤ê¤Ê¤¤¤È´¶¤¸¤¿
+¤é¡¢À§Èó¡¢´¶ÁÛ¤òÃøºî¼Ô¤ËÁ÷¤Ã¤Æ¤¢¤²¤Æ²¼¤µ¤¤¡£¤½¤¦¤¹¤ì¤Ð¡¢¤â¤Ã¤È´î¤Ö¤Ç¤·¤ç¤¦¡£
+
+ ¤³¤ì¤Ç¥é¥¤¥»¥ó¥¹¤µ¤ì¤¿¥½¥Õ¥È¥¦¥§¥¢¤ÎÃøºî¸¢¾ðÊó¤À¤±¤ò²þÊѤ·¡¢¤½¤ì¤òºÆÇÛÉÛ¤¹¤ë¤³
+¤È¤Ï¤³¤Î¥é¥¤¥»¥ó¥¹¤Ë¤è¤Ã¤Æ¶Ø»ß¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£ÇÉÀ¸Êª°·¤¤¤Ç¤¹¡£¤³¤ì¤ÏÈ´¤±·ê¤Ç¤Ï¤Ê
+¤¤¤Ç¤¹¡£¤·¤¿¤¬¤Ã¤Æ¡¢Ãøºî¸¢¾ðÊó¤À¤±¤ò½ñ¤´¹¤¨¤ÆºÆÇÛÉÛ¤¹¤ë¤³¤È¤¬É¬Íפʤ顢¤·¤Æ¤¤¤¿
+¤À¤¤¤Æ¤«¤Þ¤¤¤Þ¤»¤ó¡£
+
+ ¥Ð¥°¤ò¼è¤Ã¤¿¤ê¡¢µ¡Ç½¤òÄɲ䷤Ƥ¤¤¿¤À¤¯¤Î¤Ï¤â¤Á¤í¤ó¤Ç¤¹¤¬¡¢¥×¥í¥°¥é¥à¤ËÃð¼á¤òÉÕ
+¤±¤ÆÆɤߤ䤹¤¯¤·¤¿¤ê¡¢¥É¥¥å¥á¥ó¥È¤òÊ䤹¤ë¤Ê¤É¡¢¤½¤¦¤¤¤¦¥Ð¥¤¥Ê¥ê¡¼¤ä¼Â¹Ô·ë²Ì¤Ë
+È¿±Ç¤µ¤ì¤Ê¤¤¤è¤¦¤Ê²þÊѤâÂç´¿·Þ¤Ç¤¹¡£¤½¤¦¤¤¤¦ÇÉÀ¸Êª¤¬¤Ç¤¤¿¤é¡¢Ï¢Íí¤·¤Æ¤â¤é¤¨¤ë¤È
+¤¦¤ì¤·¤¤¤Ç¤¹¡ÊµÁ̳¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡Ë¡£
+
+ ²¿¤«µ¿ÌäÅÀ¤¬¤¢¤Ã¤¿¤ê¡¢ÇÉÀ¸Êª¤òºîÀ®¤¹¤ë¾å¤Ç¾ðÊó¤¬ÉÔ¤·¤Æ¤¤¤ë¤È´¶¤¸¤¿¤é¡¢Ãøºî¼Ô
+¤ËÏ¢Íí¤ò¤È¤Ã¤Æ¼ÁÌ䤹¤ë¤³¤È¤¬¤Ç¤¤Þ¤¹¡£¤¿¤À¡¢Ãøºî¼Ô¤ÎÅÔ¹ç¤Ç¤¹¤°¤Ë¤ÏÊÖ»ö¤¬¤Ç¤¤Ê¤¤
+¤«¤â¤·¤ì¤Þ¤»¤ó¡£¤½¤ì¤Ï¤´ÍƼϤ¯¤À¤µ¤¤¡£¤³¤Î¥é¥¤¥»¥ó¥¹¤½¤Î¤â¤Î¤ÎÉÔÈ÷¤Ê¤É¤ò»ØŦ¤¹¤ë
+¾ì¹ç¤Ï¡¢Ãøºî¼Ô¤«Àî¹çƲ¤Ë¤´Ï¢Íí¤¯¤À¤µ¤¤¡£
+
+ ¤â¤·¤«¤¹¤ë¤È¡¢¤³¤ì¤Ç¥é¥¤¥»¥ó¥¹¤µ¤ì¤¿¥½¥Õ¥È¥¦¥§¥¢¤ÇÍøÍѤµ¤ì¤Æ¤¤¤ëµ»½Ñ¤Ë¤Ä¤¤¤Æ¡¢
+Ãøºî¼Ô¤Îµö²Ä¤Î̵¤¤¼Ô¤¬Æõö¤ò¼èÆÀ¤¹¤ë¤³¤È¤ò¶Ø¤¸¤Æ¤¤¤ë¤³¤È¤¬¡¢ÆüËܤÎÆõöË¡¤ËÄñ¿¨¤·
+¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡Ê¤´°Õ¸«¤òÂԤäƤ¤¤Þ¤¹¡Ë¡£¤³¤ì¤Ë¤Ä¤¤¤Æ¡¢¥é¥¤¥»¥ó¥¹¤òºÇ½é¤ËÄó
+¾§¤·¤¿Àî¹ç½¨¼Â¤Î¸«²ò¤ò°Ê²¼¤Ë½ñ¤¤¤Æ¤ª¤¤Þ¤¹¡£
+
+ ÆõöË¡¤¬À©Äꤵ¤ì¤¿Çطʤˤϡ¢È¯ÌÀ¼Ô¤¬¼«Ê¬¤ÎȯÌÀ¤Ë¤è¤ëÍø±×¤ò¼é¤ë¤¿¤á¤ËȯÌÀ¤Î¾ÜºÙ
+¤ò¸øɽ¤·¤Ê¤¤¤³¤È¤¬²Ê³Øµ»½Ñ¤Î¿ÊÊâ¤òÃ٤餻¤ë¤«¤é¡¢¸øɽ¤·¤Æ¤â¤é¤¦Âå¤ï¤ê¤Ë°ìÄê´ü´Ö¤Î
+ÆÈÀêÍøÍѤòˡŪ¤ËÊݸ¤ë¡¢¤È¤¤¤¦Àº¿À¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥é¥¤¥»¥ó¥¹¤Ç¤Ï¡¢È¯ÌÀ¤Î¾ÜºÙ¤ò
+°Õ¿ÞŪ¤Ë±£¤¹¤Ä¤â¤ê¤Ï¤Ê¤¯¡¢¤·¤¿¤¬¤Ã¤ÆÆõö¤ò¼è¤ë¤³¤È¤ò¶Ø»ß¤·¤Æ¤âÆõöË¡¤ÎÀº¿À¤Ë¤ÏÈ¿
+¤·¤Æ¤¤¤Ê¤¤¤È¹Í¤¨¤Æ¤¤¤Þ¤¹¡£¤à¤·¤í¡¢¤³¤Î¥é¥¤¥»¥ó¥¹¤ÎÀº¿À¤òµâ¤Þ¤Ê¤¤¼Ô¤¬Æõö¤ò¼èÆÀ¤·
+¥ª¥ê¥¸¥Ê¥ë¤Î¥½¥Õ¥È¥¦¥§¥¢¤äÇÉÀ¸Êª¤ËÂФ·¤ÆÆõöÎÁ¤òÀÁµá¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤É԰¤ÎÊý¤¬¡¢
+²Ê³Øµ»½Ñ¤Î¿ÊÊâ¤òÃ٤餻¤ë¤È¹Í¤¨¤Þ¤¹¡£¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ÎÉ԰¤ò»öÁ°¤Ëʧ¿¡¤·¤¿¤³¤Î¥é¥¤
+¥»¥ó¥¹¤ÏÆõöË¡¤ËŬ¤Ã¤¿¤â¤Î¤À¤È¹Í¤¨¤Æ¤¤¤Þ¤¹¡£
+
+ ¤â¤Á¤í¤ó¡¢°ìÈְ¿´¤Ê¤Î¤Ï¡¢¥ª¥ê¥¸¥Ê¥ë¤Î¥½¥Õ¥È¥¦¥§¥¢¤ÇȯÌÀ¤Èǧ¤á¤é¤ì¤ë¤¹¤Ù¤Æ¤Î¤â
+¤Î¤Ë¤Ä¤¤¤ÆÃøºî¼Ô¤¬Æõö¤ò¼èÆÀ¤·¤Æ¡¢Â¾¼Ô¤ÎÆõö¼èÆÀ¤ò»öÁ°¤Ë˸¤²¤ì¤Ð¤¤¤¤¤Î¤Ç¤¹¤¬¡¢¤½
+¤ì¤ÏÃøºî¼Ô¤Ë¤ÏÉéô¤Ë¤Ê¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¤½¤ÎÉéô¤È¥½¥Õ¥È¥¦¥§¥¢¤ò¸ø³«¤¹¤ë¤«¤É¤¦¤«
+¤òÅ·Çé¤Ë¤«¤±¤Ê¤±¤ì¤Ð¤¤¤±¤Ê¤¤¤È¤·¤¿¤é¡¢¸ø³«¤ò¤¢¤¤é¤á¤Æ¤·¤Þ¤¦¾ì¹ç¤â¤¢¤ë¤«¤â¤·¤ì¤Þ
+¤»¤ó¡£¤½¤ì¤ÏÆõöË¡¤ÎÀº¿À¤Î´üÂÔ¤¹¤ë¤â¤Î¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤·¡¢²æ¡¹¤ÎÌÜŪ¡Ê¡Ö£±¡¥ÌÜŪ¡×
+¤ò»²¾È¡Ë¤Ë¤â±è¤¤¤Þ¤»¤ó¡£
+
+ ¤Þ¤¿¡¢È¯ÌÀ¤Î¾ÜºÙ¤¬ÆõöË¡¤Î·Á¼°¤Ë¤è¤Ã¤Æµ½Ò¤µ¤ì¤Æ¤¤¤Ê¤¤¤¿¤á¤ËÌÀ¤é¤«¤Ç¤Ê¤¤¾ì¹ç¡¢
+Ãøºî¼Ô°Ê³°¤Î¤â¤Î¤¬µö²Ä¤Ê¤¯¤½¤ì¤ò²òÀϤ·¤ÆÌÀ¤é¤«¤Ë¤¹¤ë¤³¤È¤Ï¡¢¤³¤Î¥é¥¤¥»¥ó¥¹¤Çǧ¤á
+¤é¤ì¤Æ¤¤¤Æ¤¤¤Þ¤¹¡£¤½¤ì¤ò̵½þ¤Ç¸ø³«¤·¤Æ¤â¤¤¤¤¤Ç¤¹¤·¡¢Í½þ¤ÇÈÎÇ䤹¤ë¤³¤È¤â¤Ç¤¤Þ¤¹
+¡£
+
+ ¤Ê¤ª¡¢¤³¤ì¤Ç¥é¥¤¥»¥ó¥¹¤µ¤ì¤¿¥½¥Õ¥È¥¦¥§¥¢Ãæ¤Î¤¹¤Ù¤Æ¤Îµ»½Ñ¤ËÂФ·¤Æ¡¢ÍøÍѤ˺ݤ·¤Æ
+ÆõöÎÁ¤ò»Ùʧ¤¦¿´ÇÛ¤¬Á´¤¯Ìµ¤¤¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¸ø³«¤Î»þÅÀ¤Ç͸ú¤ÊÆõö¤Ë¤è¤ëµ»½Ñ
+¤¬¥½¥Õ¥È¥¦¥§¥¢Æâ¤Ç»È¤ï¤ì¤Æ¤¤¤ì¤Ð¡¢¤½¤ì¤Ë¤Ä¤¤¤Æ¤ÏÆõöÊÝ»ý¼Ô¤«¤é¤ÎÆõöÎÁÍ׵᤬¤¢¤ê
+¤¨¤Þ¤¹¡£¤³¤Î¥é¥¤¥»¥ó¥¹¤¬ÆõöÎÁ¤Î¿´ÇÛ̵¤·¤ÈÊݾڤ·¤Æ¤¤¤ë¤Î¤Ï¡¢¤³¤Î¥½¥Õ¥È¥¦¥§¥¢Æâ¤Ç
+¿·¤¿¤ËȯÌÀ¤Èǧ¤á¤é¤ì¤ëµ»½Ñ¤ËÂФ·¤Æ¤Î¤ß¤Ç¤¹¡£
+
+ ¤³¤Î¥é¥¤¥»¥ó¥¹¤ò¼«Ê¬¤Î¥½¥Õ¥È¥¦¥§¥¢¤ËŬÍѤ·¤¿¤¤¤È»×¤¦Êý¤¬¤ª¤é¤ì¤Þ¤·¤¿¤é¡¢»öÁ°¡¦
+»ö¸å¤Ëµö²Ä¤òµá¤á¤ë¤³¤È¤Ê¤¯»È¤Ã¤Æ¤¤¤¿¤À¤¤¤Æ¤«¤Þ¤¤¤Þ¤»¤ó¡£¤â¤·ÉÔÅԹ礬¤¢¤ì¤Ð¡¢¥é¥¤
+¥»¥ó¥¹Ê¸¤ò²þÊѤ·¤Æ»È¤Ã¤Æ¤¤¤¿¤À¤¤¤Æ¤â¤¤¤¤¤Ç¤¹¡£²þÊѤκݤˤϡ¢º®Íð¤òËɤ°¤¿¤á¤Ë¥é¥¤
+¥»¥ó¥¹Ì¾¤òÊѹ¹¤¹¤ë¤Î¤ò˺¤ì¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+£´¡¥¥ê¥ó¥¯
+
+ Àî¹ç½¨¼ÂURL http://k.osask.jp/
+ e-mail kawai@osask.jp
--- /dev/null
+¤³¤Î¥½¥Õ¥È¥¦¥¨¥¢¤Ïºä°æ¹°Î¼¤Ë¤è¤Ã¤ÆºîÀ®¤µ¤ì¤¿¤â¤Î¤Ç¤¢¤ê¡¤KL-01¤ÇÇÛÉÛ¤·¤Þ¤¹¡¥
+KL-01¤Ë¤Ä¤¤¤Æ¤ÏźÉդΠKL-01 ¤«¡¤¤â¤·¤¯¤Ï°Ê²¼¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡¥
+
+http://wiki.osask.jp/?KL-01
+
+°Ê¾å
--- /dev/null
+PREFIX = /usr/local
+ARCH = h8300-elf
+BINDIR = $(PREFIX)/bin
+ADDNAME = $(ARCH)-
+
+AR = $(BINDIR)/$(ADDNAME)ar
+AS = $(BINDIR)/$(ADDNAME)as
+CC = $(BINDIR)/$(ADDNAME)gcc
+LD = $(BINDIR)/$(ADDNAME)ld
+NM = $(BINDIR)/$(ADDNAME)nm
+OBJCOPY = $(BINDIR)/$(ADDNAME)objcopy
+OBJDUMP = $(BINDIR)/$(ADDNAME)objdump
+RANLIB = $(BINDIR)/$(ADDNAME)ranlib
+STRIP = $(BINDIR)/$(ADDNAME)strip
+
+KZ_XMODEM = ../../tools/kz_xmodem/kz_xmodem
+KZ_XMODEM_SERDEV = /dev/ttyUSB0
+
+OBJS = startup.o main.o interrupt.o
+OBJS += lib.o serial.o timer.o
+OBJS += led.o leddrv.o
+OBJS += re.o
+OBJS += sw.o
+OBJS += lcd.o
+OBJS += remocon.o
+OBJS += mmc.o pff.o
+
+# sources of kozos
+OBJS += kozos.o syscall.o memory.o consdrv.o timerdrv.o command.o clock.o
+
+TARGET = kozos
+
+CFLAGS = -Wall -mh -nostdinc -nostdlib -fno-builtin
+#CFLAGS += -mint32 # int¤ò32¥Ó¥Ã¥È¤Ë¤¹¤ë¤È³Ý»»¡¿³ä»»¤¬¤Ç¤¤Ê¤¯¤Ê¤ë
+CFLAGS += -I.
+#CFLAGS += -g
+CFLAGS += -Os
+CFLAGS += -DKOZOS
+
+LFLAGS = -static -T ld.scr -L. -lgcc
+
+.SUFFIXES: .c .o
+.SUFFIXES: .s .o
+.SUFFIXES: .S .o
+
+all : $(TARGET)
+
+$(TARGET) : $(OBJS)
+ $(CC) $(OBJS) -o $(TARGET) $(CFLAGS) $(LFLAGS)
+ cp $(TARGET) $(TARGET).elf
+ $(STRIP) $(TARGET)
+
+.c.o : $<
+ $(CC) -c $(CFLAGS) $<
+
+.s.o : $<
+ $(CC) -c $(CFLAGS) $<
+
+.S.o : $<
+ $(CC) -c $(CFLAGS) $<
+
+clean :
+ rm -f $(OBJS) $(TARGET) $(TARGET).elf
+
+load :
+ $(KZ_XMODEM) $(TARGET) $(KZ_XMODEM_SERDEV)
+
+console :
+ minicom -o console -b 9600 -D $(KZ_XMODEM_SERDEV)
+
--- /dev/null
+#include "defines.h"
+#include "kozos.h"
+#include "consdrv.h"
+#include "timerdrv.h"
+#include "leddrv.h"
+#include "lib.h"
+#include "sw.h"
+#include "lcd.h"
+#include "re.h"
+#include "pff.h"
+
+/* ¥³¥ó¥½¡¼¥ë¤Ø¤Îʸ»úÎó½ÐÎϤò¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Ë°ÍÍꤹ¤ë */
+static void send_write(char *str)
+{
+ char *p;
+ int len;
+ len = strlen(str);
+ p = kz_kmalloc(len + 2);
+ p[0] = '0';
+ p[1] = CONSDRV_CMD_WRITE;
+ memcpy(&p[2], str, len);
+ kz_send(MSGBOX_ID_CONSOUTPUT, len + 2, p);
+}
+
+/* ¥¿¥¤¥Þ¤Î¥«¥¦¥ó¥È³«»Ï¤ò¥¿¥¤¥Þ¡¦¥É¥é¥¤¥Ð¤Ë°ÍÍꤹ¤ë */
+static void send_start(int msec)
+{
+ struct timerreq *req;
+ req = kz_kmalloc(sizeof(*req));
+ req->id = MSGBOX_ID_TIMEXPIRE;
+ req->msec = msec;
+ kz_send(MSGBOX_ID_TIMDRIVE, TIMERDRV_CMD_START, (char *)req);
+}
+
+static void send_led_write(int target, int state)
+{
+ char *p;
+ p = kz_kmalloc(2);
+ p[0] = state ? LEDDRV_CMD_LED_ON : LEDDRV_CMD_LED_OFF;
+ p[1] = '0' + target;
+ kz_send(MSGBOX_ID_LEDDRIVE, 2, p);
+}
+
+static void send_led_toggle(int target)
+{
+ char *p;
+ p = kz_kmalloc(2);
+ p[0] = LEDDRV_CMD_LED_TOGGLE;
+ p[1] = '0' + target;
+ kz_send(MSGBOX_ID_LEDDRIVE, 2, p);
+}
+
+static void die(int code)
+{
+ puts("die with code 0x");
+ putxval(code, 4);
+ puts(".\n");
+ while (1) { }
+}
+
+static int func_fread(void *buf, const uint32 size, void *extobj)
+{
+ WORD br;
+ int rc = pf_read(buf, size, &br);
+ return rc ? 1 : 0;
+}
+
+static void func_pixel_write(const int x, const int y, const uint8 r, const uint8 g, const uint8 b, void *extobj)
+{
+ lcd_set_pixel(x, y, 0);
+}
+
+int clock_main(int argc, char *argv[])
+{
+ uint8 val = 0;
+
+ re_init();
+ lcd_init();
+ sw_init();
+
+ uint16 prev = 0, curr = 0;
+ while (1) {
+ val = (val + 1) % 101;
+ lcd_draw_progressbar(5, 20, 121 - 5, 25, 0, 100, val, 0);
+
+ send_start(10);
+ kz_recv(MSGBOX_ID_TIMEXPIRE, NULL, NULL);
+ if (sw_read(Sw1)) {
+ send_led_write(0, 1);
+ } else {
+ send_led_toggle(0);
+ }
+
+ send_start(10);
+ kz_recv(MSGBOX_ID_TIMEXPIRE, NULL, NULL);
+ if (sw_read(Sw2)) {
+ send_led_write(1, 1);
+ } else {
+ send_led_toggle(1);
+ }
+
+ curr = re_read();
+ if (curr != prev) {
+ int dir = (int)(curr & 0xff) - (int)(prev & 0xff);
+ if (dir < 0) {
+ if (-32 < dir) {
+ send_write("<-\n");
+ send_led_toggle(2);
+ send_led_write(3, 0);
+ }
+ } else {
+ if (dir < 32) {
+ send_write("->\n");
+ send_led_write(2, 0);
+ send_led_toggle(3);
+ }
+ }
+ prev = curr;
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+#include "defines.h"
+#include "kozos.h"
+#include "consdrv.h"
+#include "timerdrv.h"
+#include "leddrv.h"
+#include "lib.h"
+
+/* ¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Î»ÈÍѳ«»Ï¤ò¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Ë°ÍÍꤹ¤ë */
+static void send_use(int index)
+{
+ char *p;
+ p = kz_kmalloc(3);
+ p[0] = '0';
+ p[1] = CONSDRV_CMD_USE;
+ p[2] = '0' + index;
+ kz_send(MSGBOX_ID_CONSOUTPUT, 3, p);
+}
+
+/* ¥³¥ó¥½¡¼¥ë¤Ø¤Îʸ»úÎó½ÐÎϤò¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Ë°ÍÍꤹ¤ë */
+static void send_write(char *str)
+{
+ char *p;
+ int len;
+ len = strlen(str);
+ p = kz_kmalloc(len + 2);
+ p[0] = '0';
+ p[1] = CONSDRV_CMD_WRITE;
+ memcpy(&p[2], str, len);
+ kz_send(MSGBOX_ID_CONSOUTPUT, len + 2, p);
+}
+
+/* ¥¿¥¤¥Þ¤Î¥«¥¦¥ó¥È³«»Ï¤ò¥¿¥¤¥Þ¡¦¥É¥é¥¤¥Ð¤Ë°ÍÍꤹ¤ë */
+static void send_start(int msec)
+{
+ struct timerreq *req;
+ req = kz_kmalloc(sizeof(*req));
+ req->id = MSGBOX_ID_CONSINPUT;
+ req->msec = msec;
+ kz_send(MSGBOX_ID_TIMDRIVE, TIMERDRV_CMD_START, (char *)req);
+}
+
+static void send_led_toggle(int target)
+{
+ char *p;
+ p = kz_kmalloc(2);
+ p[0] = LEDDRV_CMD_LED_TOGGLE;
+ p[1] = '0' + target;
+ kz_send(MSGBOX_ID_LEDDRIVE, 2, p);
+}
+
+int command_main(int argc, char *argv[])
+{
+ char *p;
+ int size;
+
+ send_use(SERIAL_DEFAULT_DEVICE);
+
+ while (1) {
+ send_write("command> "); /* ¥×¥í¥ó¥×¥Èɽ¼¨ */
+
+ /* ¥³¥ó¥½¡¼¥ë¤«¤é¤Î¼õ¿®Ê¸»úÎó¤ò¼õ¤±¼è¤ë */
+ kz_recv(MSGBOX_ID_CONSINPUT, &size, &p);
+ if (p == NULL) {
+ send_write("expired.\n");
+ continue;
+ }
+ p[size] = '\0';
+
+ if (!strncmp(p, "echo", 4)) { /* echo¥³¥Þ¥ó¥É */
+ send_write(p + 4); /* echo¤Ë³¤¯Ê¸»úÎó¤ò½ÐÎϤ¹¤ë */
+ send_write("\n");
+ } else if (!strncmp(p, "timer", 4)) { /* timer¥³¥Þ¥ó¥É */
+ send_write("timer start.\n");
+ send_start(1000);
+ } else if (!strncmp(p, "led1", 4)) {
+ send_led_toggle(0);
+ } else if (!strncmp(p, "led2", 4)) {
+ send_led_toggle(1);
+ } else if (!strncmp(p, "ledg", 4)) {
+ send_led_toggle(2);
+ } else if (!strncmp(p, "ledr", 4)) {
+ send_led_toggle(3);
+ } else {
+ send_write("unknown.\n");
+ }
+
+ kz_kmfree(p);
+ }
+
+ return 0;
+}
--- /dev/null
+#include "defines.h"
+#include "kozos.h"
+#include "intr.h"
+#include "interrupt.h"
+#include "serial.h"
+#include "lib.h"
+#include "consdrv.h"
+
+#define CONS_BUFFER_SIZE 24
+
+static struct consreg {
+ kz_thread_id_t id; /* ¥³¥ó¥½¡¼¥ë¤òÍøÍѤ¹¤ë¥¹¥ì¥Ã¥É */
+ int index; /* ÍøÍѤ¹¤ë¥·¥ê¥¢¥ë¤ÎÈÖ¹æ */
+
+ char *send_buf; /* Á÷¿®¥Ð¥Ã¥Õ¥¡ */
+ char *recv_buf; /* ¼õ¿®¥Ð¥Ã¥Õ¥¡ */
+ int send_len; /* Á÷¿®¥Ð¥Ã¥Õ¥¡Ãæ¤Î¥Ç¡¼¥¿¥µ¥¤¥º */
+ int recv_len; /* ¼õ¿®¥Ð¥Ã¥Õ¥¡Ãæ¤Î¥Ç¡¼¥¿¥µ¥¤¥º */
+
+ /* kozos.c ¤Î kz_msgbox ¤ÈƱÍͤÎÍýͳ¤Ç¡¤¥À¥ß¡¼¡¦¥á¥ó¥Ð¤Ç¥µ¥¤¥ºÄ´À°¤¹¤ë */
+ long dummy[3];
+} consreg[CONSDRV_DEVICE_NUM];
+
+/*
+ * °Ê²¼¤Î£²¤Ä¤Î´Ø¿ô(send_char(), send_string())¤Ï³ä¹þ¤ß½èÍý¤È¥¹¥ì¥Ã¥É¤«¤é
+ * ¸Æ¤Ð¤ì¤ë¤¬Á÷¿®¥Ð¥Ã¥Õ¥¡¤òÁàºî¤·¤Æ¤ª¤êºÆÆþÉԲĤΤ¿¤á¡¤¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ó½Ð¤¹
+ * ¾ì¹ç¤ÏÇÓ¾¤Î¤¿¤á³ä¹þ¤ß¶Ø»ß¾õÂ֤ǸƤ֤³¤È¡¥
+ */
+
+/* Á÷¿®¥Ð¥Ã¥Õ¥¡¤ÎÀèƬ£±Ê¸»ú¤òÁ÷¿®¤¹¤ë */
+static void send_char(struct consreg *cons)
+{
+ int i;
+ serial_send_byte(cons->index, cons->send_buf[0]);
+ cons->send_len--;
+ /* ÀèƬʸ»ú¤òÁ÷¿®¤·¤¿¤Î¤Ç¡¤£±Ê¸»ú¤Ö¤ó¤º¤é¤¹ */
+ for (i = 0; i < cons->send_len; i++)
+ cons->send_buf[i] = cons->send_buf[i + 1];
+}
+
+/* ʸ»úÎó¤òÁ÷¿®¥Ð¥Ã¥Õ¥¡¤Ë½ñ¤¹þ¤ßÁ÷¿®³«»Ï¤¹¤ë */
+static void send_string(struct consreg *cons, char *str, int len)
+{
+ int i;
+ for (i = 0; i < len; i++) { /* ʸ»úÎó¤òÁ÷¿®¥Ð¥Ã¥Õ¥¡¤Ë¥³¥Ô¡¼ */
+ if (str[i] == '\n') /* \n¢ª\r\n¤ËÊÑ´¹ */
+ cons->send_buf[cons->send_len++] = '\r';
+ cons->send_buf[cons->send_len++] = str[i];
+ }
+ /*
+ * Á÷¿®³ä¹þ¤ß̵¸ú¤Ê¤é¤Ð¡¤Á÷¿®³«»Ï¤µ¤ì¤Æ¤¤¤Ê¤¤¤Î¤ÇÁ÷¿®³«»Ï¤¹¤ë¡¥
+ * Á÷¿®³ä¹þ¤ß͸ú¤Ê¤é¤ÐÁ÷¿®³«»Ï¤µ¤ì¤Æ¤ª¤ê¡¤Á÷¿®³ä¹þ¤ß¤Î±äŤÇ
+ * Á÷¿®¥Ð¥Ã¥Õ¥¡Æâ¤Î¥Ç¡¼¥¿¤¬½ç¼¡Á÷¿®¤µ¤ì¤ë¤Î¤Ç¡¤²¿¤â¤·¤Ê¤¯¤Æ¤è¤¤¡¥
+ */
+ if (cons->send_len && !serial_intr_is_send_enable(cons->index)) {
+ serial_intr_send_enable(cons->index); /* Á÷¿®³ä¹þ¤ß͸ú²½ */
+ send_char(cons); /* Á÷¿®³«»Ï */
+ }
+}
+
+/*
+ * °Ê²¼¤Ï³ä¹þ¤ß¥Ï¥ó¥É¥é¤«¤é¸Æ¤Ð¤ì¤ë³ä¹þ¤ß½èÍý¤Ç¤¢¤ê¡¤ÈóƱ´ü¤Ç
+ * ¸Æ¤Ð¤ì¤ë¤Î¤Ç¡¤¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Ê¤É¤ò¸Æ¤Ó½Ð¤¹¾ì¹ç¤Ë¤ÏÃí°Õ¤¬É¬Íס¥
+ * ´ðËܤȤ·¤Æ¡¤°Ê²¼¤Î¤¤¤º¤ì¤«¤ËÅö¤Æ¤Ï¤Þ¤ë´Ø¿ô¤·¤«¸Æ¤Ó½Ð¤·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
+ * ¡¦ºÆÆþ²Äǽ¤Ç¤¢¤ë¡¥
+ * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤Ï̵¤¤´Ø¿ô¤Ç¤¢¤ë¡¥
+ * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤¬¤¢¤ë¤¬¡¤³ä¹þ¤ß¶Ø»ß¤Ç¸Æ¤Ó½Ð¤·¤Æ¤¤¤ë¡¥
+ * ¤Þ¤¿Èó¥³¥ó¥Æ¥¥¹¥È¾õÂ֤ǸƤФì¤ë¤¿¤á¡¤¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ÏÍøÍѤ·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
+ * (¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤òÍøÍѤ¹¤ë¤³¤È)
+ */
+static int consdrv_intrproc(struct consreg *cons)
+{
+ unsigned char c;
+ char *p;
+
+ if (serial_is_recv_enable(cons->index)) { /* ¼õ¿®³ä¹þ¤ß */
+ c = serial_recv_byte(cons->index);
+ if (c == '\r') /* ²þ¹Ô¥³¡¼¥ÉÊÑ´¹(\r¢ª\n) */
+ c = '\n';
+
+ send_string(cons, &c, 1); /* ¥¨¥³¡¼¥Ð¥Ã¥¯½èÍý */
+
+ if (cons->id) {
+ if (c != '\n') {
+ /* ²þ¹Ô¤Ç¤Ê¤¤¤Ê¤é¡¤¼õ¿®¥Ð¥Ã¥Õ¥¡¤Ë¥Ð¥Ã¥Õ¥¡¥ê¥ó¥°¤¹¤ë */
+ cons->recv_buf[cons->recv_len++] = c;
+ } else {
+ /*
+ * Enter¤¬²¡¤µ¤ì¤¿¤é¡¤¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤò
+ * ¥³¥Þ¥ó¥É½èÍý¥¹¥ì¥Ã¥É¤ËÄÌÃΤ¹¤ë¡¥
+ * (³ä¹þ¤ß¥Ï¥ó¥É¥é¤Ê¤Î¤Ç¡¤¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤òÍøÍѤ¹¤ë)
+ */
+ p = kx_kmalloc(CONS_BUFFER_SIZE);
+ memcpy(p, cons->recv_buf, cons->recv_len);
+ kx_send(MSGBOX_ID_CONSINPUT, cons->recv_len, p);
+ cons->recv_len = 0;
+ }
+ }
+ }
+
+ if (serial_is_send_enable(cons->index)) { /* Á÷¿®³ä¹þ¤ß */
+ if (!cons->id || !cons->send_len) {
+ /* Á÷¿®¥Ç¡¼¥¿¤¬Ìµ¤¤¤Ê¤é¤Ð¡¤Á÷¿®½èÍý½ªÎ» */
+ serial_intr_send_disable(cons->index);
+ } else {
+ /* Á÷¿®¥Ç¡¼¥¿¤¬¤¢¤ë¤Ê¤é¤Ð¡¤°ú³¤Á÷¿®¤¹¤ë */
+ send_char(cons);
+ }
+ }
+
+ return 0;
+}
+
+/* ³ä¹þ¤ß¥Ï¥ó¥É¥é */
+static void consdrv_intr(void)
+{
+ int i;
+ struct consreg *cons;
+
+ for (i = 0; i < CONSDRV_DEVICE_NUM; i++) {
+ cons = &consreg[i];
+ if (cons->id) {
+ if (serial_is_send_enable(cons->index) ||
+ serial_is_recv_enable(cons->index))
+ /* ³ä¹þ¤ß¤¬¤¢¤ë¤Ê¤é¤Ð¡¤³ä¹þ¤ß½èÍý¤ò¸Æ¤Ó½Ð¤¹ */
+ consdrv_intrproc(cons);
+ }
+ }
+}
+
+static int consdrv_init(void)
+{
+ memset(consreg, 0, sizeof(consreg));
+ return 0;
+}
+
+/* ¥¹¥ì¥Ã¥É¤«¤é¤ÎÍ×µá¤ò½èÍý¤¹¤ë */
+static int consdrv_command(struct consreg *cons, kz_thread_id_t id,
+ int index, int size, char *command)
+{
+ switch (command[0]) {
+ case CONSDRV_CMD_USE: /* ¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Î»ÈÍѳ«»Ï */
+ cons->id = id;
+ cons->index = command[1] - '0';
+ cons->send_buf = kz_kmalloc(CONS_BUFFER_SIZE);
+ cons->recv_buf = kz_kmalloc(CONS_BUFFER_SIZE);
+ cons->send_len = 0;
+ cons->recv_len = 0;
+ serial_init(cons->index);
+ serial_intr_recv_enable(cons->index); /* ¼õ¿®³ä¹þ¤ß͸ú²½(¼õ¿®³«»Ï) */
+ break;
+
+ case CONSDRV_CMD_WRITE: /* ¥³¥ó¥½¡¼¥ë¤Ø¤Îʸ»úÎó½ÐÎÏ */
+ /*
+ * send_string()¤Ç¤ÏÁ÷¿®¥Ð¥Ã¥Õ¥¡¤òÁàºî¤·¤Æ¤ª¤êºÆÆþÉԲĤʤΤǡ¤
+ * ÇÓ¾¤Î¤¿¤á¤Ë³ä¹þ¤ß¶Ø»ß¤Ë¤·¤Æ¸Æ¤Ó½Ð¤¹¡¥
+ */
+ INTR_DISABLE;
+ send_string(cons, command + 1, size - 1); /* ʸ»úÎó¤ÎÁ÷¿® */
+ INTR_ENABLE;
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int consdrv_main(int argc, char *argv[])
+{
+ int size, index;
+ kz_thread_id_t id;
+ char *p;
+
+ consdrv_init();
+ kz_setintr(SOFTVEC_TYPE_SERINTR, consdrv_intr); /* ³ä¹þ¤ß¥Ï¥ó¥É¥éÀßÄê */
+
+ while (1) {
+ id = kz_recv(MSGBOX_ID_CONSOUTPUT, &size, &p);
+ index = p[0] - '0';
+ consdrv_command(&consreg[index], id, index, size - 1, p + 1);
+ kz_kmfree(p);
+ }
+
+ return 0;
+}
--- /dev/null
+#ifndef _CONSDRV_H_INCLUDED_
+#define _CONSDRV_H_INCLUDED_
+
+#define CONSDRV_DEVICE_NUM 1
+#define CONSDRV_CMD_USE 'u' /* ¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Î»ÈÍѳ«»Ï */
+#define CONSDRV_CMD_WRITE 'w' /* ¥³¥ó¥½¡¼¥ë¤Ø¤Îʸ»úÎó½ÐÎÏ */
+
+#endif
--- /dev/null
+#ifndef _DEFINES_H_INCLUDED_
+#define _DEFINES_H_INCLUDED_
+
+#define NULL ((void *)0)
+#define SERIAL_DEFAULT_DEVICE 1
+#define TIMER_DEFAULT_DEVICE 1
+
+typedef char int8;
+typedef short int16;
+typedef long int32;
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned long uint32;
+
+typedef uint32 kz_thread_id_t;
+typedef int (*kz_func_t)(int argc, char *argv[]);
+typedef void (*kz_handler_t)(void);
+
+typedef enum {
+ MSGBOX_ID_CONSINPUT = 0,
+ MSGBOX_ID_CONSOUTPUT,
+ MSGBOX_ID_TIMDRIVE,
+ MSGBOX_ID_TIMEXPIRE,
+ MSGBOX_ID_LEDDRIVE,
+ MSGBOX_ID_NUM
+} kz_msgbox_id_t;
+
+#endif
--- /dev/null
+/*-----------------------------------------------------------------------\r
+/ PFF - Low level disk interface modlue include file (C)ChaN, 2010\r
+/-----------------------------------------------------------------------*/\r
+\r
+#ifndef _DISKIO\r
+#define _DISKIO\r
+\r
+#include "integer.h"\r
+#include "pff.h"\r
+\r
+\r
+/* Status of Disk Functions */\r
+typedef BYTE DSTATUS;\r
+\r
+#define STA_NOINIT 0x01 /* Drive not initialized */\r
+#define STA_NODISK 0x02 /* No medium in the drive */\r
+\r
+\r
+/* Results of Disk Functions */\r
+typedef enum {\r
+ RES_OK = 0, /* 0: Function succeeded */\r
+ RES_ERROR, /* 1: Disk error */\r
+ RES_NOTRDY, /* 2: Not ready */\r
+ RES_PARERR /* 3: Invalid parameter */\r
+} DRESULT;\r
+\r
+\r
+/*---------------------------------------*/\r
+/* Prototypes for disk control functions */\r
+\r
+DSTATUS disk_initialize (void);\r
+#if _USE_READ\r
+DRESULT disk_readp (BYTE*, DWORD, WORD, WORD);\r
+#endif\r
+#if _USE_WRITE\r
+DRESULT disk_writep (const BYTE*, DWORD);\r
+#endif\r
+\r
+#endif\r
--- /dev/null
+/*-------------------------------------------*/\r
+/* Integer type definitions for FatFs module */\r
+/*-------------------------------------------*/\r
+\r
+#ifndef _INTEGER\r
+#define _INTEGER\r
+\r
+#include "defines.h"\r
+\r
+/* These types must be 16-bit, 32-bit or larger integer */\r
+typedef int16 INT;\r
+typedef uint16 UINT;\r
+\r
+/* These types must be 8-bit integer */\r
+typedef int8 CHAR;\r
+typedef uint8 UCHAR;\r
+typedef uint8 BYTE;\r
+\r
+/* These types must be 16-bit integer */\r
+typedef int16 SHORT;\r
+typedef uint16 USHORT;\r
+typedef uint16 WORD;\r
+typedef uint16 WCHAR;\r
+\r
+/* These types must be 32-bit integer */\r
+typedef int32 LONG;\r
+typedef uint32 ULONG;\r
+typedef uint32 DWORD;\r
+\r
+#endif\r
--- /dev/null
+#include "defines.h"
+#include "intr.h"
+#include "interrupt.h"
+
+/* ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤Î½é´ü²½ */
+int softvec_init(void)
+{
+ int type;
+ for (type = 0; type < SOFTVEC_TYPE_NUM; type++)
+ softvec_setintr(type, NULL);
+ return 0;
+}
+
+/* ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤ÎÀßÄê */
+int softvec_setintr(softvec_type_t type, softvec_handler_t handler)
+{
+ SOFTVECS[type] = handler;
+ return 0;
+}
+
+/*
+ * ¶¦Ä̳ä¹þ¤ß¥Ï¥ó¥É¥é¡¥
+ * ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤ò¸«¤Æ¡¤³Æ¥Ï¥ó¥É¥é¤Ëʬ´ô¤¹¤ë¡¥
+ */
+void interrupt(softvec_type_t type, unsigned long sp)
+{
+ softvec_handler_t handler = SOFTVECS[type];
+ if (handler)
+ handler(type, sp);
+}
--- /dev/null
+#ifndef _INTERRUPT_H_INCLUDED_
+#define _INTERRUPT_H_INCLUDED_
+
+/* °Ê²¼¤Ï¥ê¥ó¥«¡¦¥¹¥¯¥ê¥×¥È¤ÇÄêµÁ¤·¤Æ¤¢¤ë¥·¥ó¥Ü¥ë */
+extern char softvec;
+#define SOFTVEC_ADDR (&softvec)
+
+typedef short softvec_type_t;
+
+typedef void (*softvec_handler_t)(softvec_type_t type, unsigned long sp);
+
+#define SOFTVECS ((softvec_handler_t *)SOFTVEC_ADDR)
+
+#define INTR_ENABLE asm volatile ("andc.b #0x3f,ccr")
+#define INTR_DISABLE asm volatile ("orc.b #0xc0,ccr")
+
+/* ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤Î½é´ü²½ */
+int softvec_init(void);
+
+/* ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤ÎÀßÄê */
+int softvec_setintr(softvec_type_t type, softvec_handler_t handler);
+
+/* ¶¦Ä̳ä¹þ¤ß¥Ï¥ó¥É¥é */
+void interrupt(softvec_type_t type, unsigned long sp);
+
+#endif
--- /dev/null
+#ifndef _INTR_H_INCLUDED_
+#define _INTR_H_INCLUDED_
+
+/* ¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤ÎÄêµÁ */
+
+#define SOFTVEC_TYPE_NUM 6
+
+#define SOFTVEC_TYPE_SOFTERR 0
+#define SOFTVEC_TYPE_SYSCALL 1
+#define SOFTVEC_TYPE_SERINTR 2
+#define SOFTVEC_TYPE_TIMINTR 3
+#define SOFTVEC_TYPE_IR_EDGE 4
+#define SOFTVEC_TYPE_IR_TOVF 5
+
+#endif
--- /dev/null
+#include "defines.h"
+#include "kozos.h"
+#include "intr.h"
+#include "interrupt.h"
+#include "syscall.h"
+#include "memory.h"
+#include "lib.h"
+
+#define THREAD_NUM 8
+#define PRIORITY_NUM 16
+#define THREAD_NAME_SIZE 15
+
+/* ¥¹¥ì¥Ã¥É¡¦¥³¥ó¥Æ¥¥¹¥È */
+typedef struct _kz_context {
+ uint32 sp; /* ¥¹¥¿¥Ã¥¯¡¦¥Ý¥¤¥ó¥¿ */
+} kz_context;
+
+/* ¥¿¥¹¥¯¡¦¥³¥ó¥È¥í¡¼¥ë¡¦¥Ö¥í¥Ã¥¯(TCB) */
+typedef struct _kz_thread {
+ struct _kz_thread *next;
+ char name[THREAD_NAME_SIZE + 1]; /* ¥¹¥ì¥Ã¥É̾ */
+ int priority; /* Í¥ÀèÅÙ */
+ char *stack; /* ¥¹¥¿¥Ã¥¯ */
+ uint32 flags; /* ³Æ¼ï¥Õ¥é¥° */
+#define KZ_THREAD_FLAG_READY (1 << 0)
+
+ struct { /* ¥¹¥ì¥Ã¥É¤Î¥¹¥¿¡¼¥È¡¦¥¢¥Ã¥×(thread_init())¤ËÅϤ¹¥Ñ¥é¥á¡¼¥¿ */
+ kz_func_t func; /* ¥¹¥ì¥Ã¥É¤Î¥á¥¤¥ó´Ø¿ô */
+ int argc; /* ¥¹¥ì¥Ã¥É¤Î¥á¥¤¥ó´Ø¿ô¤ËÅϤ¹ argc */
+ char **argv; /* ¥¹¥ì¥Ã¥É¤Î¥á¥¤¥ó´Ø¿ô¤ËÅϤ¹ argv */
+ } init;
+
+ struct { /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ëÍѥХåե¡ */
+ kz_syscall_type_t type;
+ kz_syscall_param_t *param;
+ } syscall;
+
+ kz_context context; /* ¥³¥ó¥Æ¥¥¹¥È¾ðÊó */
+} kz_thread;
+
+/* ¥á¥Ã¥»¡¼¥¸¡¦¥Ð¥Ã¥Õ¥¡ */
+typedef struct _kz_msgbuf {
+ struct _kz_msgbuf *next;
+ kz_thread *sender; /* ¥á¥Ã¥»¡¼¥¸¤òÁ÷¿®¤·¤¿¥¹¥ì¥Ã¥É */
+ struct { /* ¥á¥Ã¥»¡¼¥¸¤Î¥Ñ¥é¥á¡¼¥¿ÊݸÎΰè */
+ int size;
+ char *p;
+ } param;
+} kz_msgbuf;
+
+/* ¥á¥Ã¥»¡¼¥¸¡¦¥Ü¥Ã¥¯¥¹ */
+typedef struct _kz_msgbox {
+ kz_thread *receiver; /* ¼õ¿®ÂÔ¤Á¾õÂ֤Υ¹¥ì¥Ã¥É */
+ kz_msgbuf *head;
+ kz_msgbuf *tail;
+
+ /*
+ * H8¤Ï16¥Ó¥Ã¥ÈCPU¤Ê¤Î¤Ç¡¤32¥Ó¥Ã¥ÈÀ°¿ô¤ËÂФ·¤Æ¤Î¾è»»Ì¿Î᤬̵¤¤¡¥¤è¤Ã¤Æ
+ * ¹½Â¤ÂΤΥµ¥¤¥º¤¬£²¤Î³¬¾è¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤¤¤È¡¤¹½Â¤ÂΤÎÇÛÎó¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹
+ * ·×»»¤Ç¾è»»¤¬»È¤ï¤ì¤Æ¡Ö___mulsi3¤¬Ìµ¤¤¡×¤Ê¤É¤Î¥ê¥ó¥¯¡¦¥¨¥é¡¼¤Ë¤Ê¤ë¾ì¹ç¤¬
+ * ¤¢¤ë¡¥(£²¤Î³¬¾è¤Ê¤é¤Ð¥·¥Õ¥È±é»»¤¬ÍøÍѤµ¤ì¤ë¤Î¤ÇÌäÂê¤Ï½Ð¤Ê¤¤)
+ * Âкö¤È¤·¤Æ¡¤¥µ¥¤¥º¤¬£²¤Î³¬¾è¤Ë¤Ê¤ë¤è¤¦¤Ë¥À¥ß¡¼¡¦¥á¥ó¥Ð¤ÇÄ´À°¤¹¤ë¡¥
+ * ¾¹½Â¤ÂΤÇƱÍͤΥ¨¥é¡¼¤¬½Ð¤¿¾ì¹ç¤Ë¤Ï¡¤Æ±ÍͤÎÂнè¤ò¤¹¤ë¤³¤È¡¥
+ */
+ long dummy[1];
+} kz_msgbox;
+
+/* ¥¹¥ì¥Ã¥É¤Î¥ì¥Ç¥£¡¼¡¦¥¥å¡¼ */
+static struct {
+ kz_thread *head;
+ kz_thread *tail;
+} readyque[PRIORITY_NUM];
+
+static kz_thread *current; /* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É */
+static kz_thread threads[THREAD_NUM]; /* ¥¿¥¹¥¯¡¦¥³¥ó¥È¥í¡¼¥ë¡¦¥Ö¥í¥Ã¥¯ */
+static kz_handler_t handlers[SOFTVEC_TYPE_NUM]; /* ³ä¹þ¤ß¥Ï¥ó¥É¥é */
+static kz_msgbox msgboxes[MSGBOX_ID_NUM]; /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ü¥Ã¥¯¥¹ */
+
+void dispatch(kz_context *context);
+
+/* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥¥å¡¼¤«¤éÈ´¤½Ð¤¹ */
+static int getcurrent(void)
+{
+ if (current == NULL) {
+ return -1;
+ }
+ if (!(current->flags & KZ_THREAD_FLAG_READY)) {
+ /* ¤¹¤Ç¤Ë̵¤¤¾ì¹ç¤Ï̵»ë */
+ return 1;
+ }
+
+ /* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É¤Ïɬ¤ºÀèƬ¤Ë¤¢¤ë¤Ï¤º¤Ê¤Î¤Ç¡¤ÀèƬ¤«¤éÈ´¤½Ð¤¹ */
+ readyque[current->priority].head = current->next;
+ if (readyque[current->priority].head == NULL) {
+ readyque[current->priority].tail = NULL;
+ }
+ current->flags &= ~KZ_THREAD_FLAG_READY;
+ current->next = NULL;
+
+ return 0;
+}
+
+/* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥¥å¡¼¤Ë·Ò¤²¤ë */
+static int putcurrent(void)
+{
+ if (current == NULL) {
+ return -1;
+ }
+ if (current->flags & KZ_THREAD_FLAG_READY) {
+ /* ¤¹¤Ç¤Ëͤë¾ì¹ç¤Ï̵»ë */
+ return 1;
+ }
+
+ /* ¥ì¥Ç¥£¡¼¡¦¥¥å¡¼¤ÎËöÈø¤ËÀܳ¤¹¤ë */
+ if (readyque[current->priority].tail) {
+ readyque[current->priority].tail->next = current;
+ } else {
+ readyque[current->priority].head = current;
+ }
+ readyque[current->priority].tail = current;
+ current->flags |= KZ_THREAD_FLAG_READY;
+
+ return 0;
+}
+
+static void thread_end(void)
+{
+ kz_exit();
+}
+
+/* ¥¹¥ì¥Ã¥É¤Î¥¹¥¿¡¼¥È¡¦¥¢¥Ã¥× */
+static void thread_init(kz_thread *thp)
+{
+ /* ¥¹¥ì¥Ã¥É¤Î¥á¥¤¥ó´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹ */
+ thp->init.func(thp->init.argc, thp->init.argv);
+ thread_end();
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_run():¥¹¥ì¥Ã¥É¤Îµ¯Æ°) */
+static kz_thread_id_t thread_run(kz_func_t func, char *name, int priority,
+ int stacksize, int argc, char *argv[])
+{
+ int i;
+ kz_thread *thp;
+ uint32 *sp;
+ extern char userstack; /* ¥ê¥ó¥«¡¦¥¹¥¯¥ê¥×¥È¤ÇÄêµÁ¤µ¤ì¤ë¥¹¥¿¥Ã¥¯Îΰè */
+ static char *thread_stack = &userstack;
+
+ /* ¶õ¤¤¤Æ¤¤¤ë¥¿¥¹¥¯¡¦¥³¥ó¥È¥í¡¼¥ë¡¦¥Ö¥í¥Ã¥¯¤ò¸¡º÷ */
+ for (i = 0; i < THREAD_NUM; i++) {
+ thp = &threads[i];
+ if (!thp->init.func) /* ¸«¤Ä¤«¤Ã¤¿ */
+ break;
+ }
+ if (i == THREAD_NUM) /* ¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿ */
+ return -1;
+
+ memset(thp, 0, sizeof(*thp));
+
+ /* ¥¿¥¹¥¯¡¦¥³¥ó¥È¥í¡¼¥ë¡¦¥Ö¥í¥Ã¥¯(TCB)¤ÎÀßÄê */
+ strcpy(thp->name, name);
+ thp->next = NULL;
+ thp->priority = priority;
+ thp->flags = 0;
+
+ thp->init.func = func;
+ thp->init.argc = argc;
+ thp->init.argv = argv;
+
+ /* ¥¹¥¿¥Ã¥¯Îΰè¤ò³ÍÆÀ */
+ memset(thread_stack, 0, stacksize);
+ thread_stack += stacksize;
+
+ thp->stack = thread_stack; /* ¥¹¥¿¥Ã¥¯¤òÀßÄê */
+
+ /* ¥¹¥¿¥Ã¥¯¤Î½é´ü²½ */
+ sp = (uint32 *)thp->stack;
+ *(--sp) = (uint32)thread_end;
+
+ /*
+ * ¥×¥í¥°¥é¥à¡¦¥«¥¦¥ó¥¿¤òÀßÄꤹ¤ë¡¥
+ * ¥¹¥ì¥Ã¥É¤ÎÍ¥ÀèÅÙ¤¬¥¼¥í¤Î¾ì¹ç¤Ë¤Ï¡¤³ä¹þ¤ß¶Ø»ß¥¹¥ì¥Ã¥É¤È¤¹¤ë¡¥
+ */
+ *(--sp) = (uint32)thread_init | ((uint32)(priority ? 0 : 0xc0) << 24);
+
+ *(--sp) = 0; /* ER6 */
+ *(--sp) = 0; /* ER5 */
+ *(--sp) = 0; /* ER4 */
+ *(--sp) = 0; /* ER3 */
+ *(--sp) = 0; /* ER2 */
+ *(--sp) = 0; /* ER1 */
+
+ /* ¥¹¥ì¥Ã¥É¤Î¥¹¥¿¡¼¥È¡¦¥¢¥Ã¥×(thread_init())¤ËÅϤ¹°ú¿ô */
+ *(--sp) = (uint32)thp; /* ER0 */
+
+ /* ¥¹¥ì¥Ã¥É¤Î¥³¥ó¥Æ¥¥¹¥È¤òÀßÄê */
+ thp->context.sp = (uint32)sp;
+
+ /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ò¸Æ¤Ó½Ð¤·¤¿¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥¥å¡¼¤ËÌ᤹ */
+ putcurrent();
+
+ /* ¿·µ¬ºîÀ®¤·¤¿¥¹¥ì¥Ã¥É¤ò¡¤¥ì¥Ç¥£¡¼¡¦¥¥å¡¼¤ËÀܳ¤¹¤ë */
+ current = thp;
+ putcurrent();
+
+ return (kz_thread_id_t)current;
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_exit():¥¹¥ì¥Ã¥É¤Î½ªÎ») */
+static int thread_exit(void)
+{
+ /*
+ * ËÜÍè¤Ê¤é¥¹¥¿¥Ã¥¯¤â²òÊü¤·¤ÆºÆÍøÍѤǤ¤ë¤è¤¦¤Ë¤¹¤Ù¤¤À¤¬¾Êά¡¥
+ * ¤³¤Î¤¿¤á¡¤¥¹¥ì¥Ã¥É¤òÉÑÈˤËÀ¸À®¡¦¾Ãµî¤¹¤ë¤è¤¦¤Ê¤³¤È¤Ï¸½¾õ¤Ç¤Ç¤¤Ê¤¤¡¥
+ */
+ puts(current->name);
+ puts(" EXIT.\n");
+ memset(current, 0, sizeof(*current));
+ return 0;
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_wait():¥¹¥ì¥Ã¥É¤Î¼Â¹Ô¸¢Êü´þ) */
+static int thread_wait(void)
+{
+ putcurrent();
+ return 0;
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_sleep():¥¹¥ì¥Ã¥É¤Î¥¹¥ê¡¼¥×) */
+static int thread_sleep(void)
+{
+ return 0;
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_wakeup():¥¹¥ì¥Ã¥É¤Î¥¦¥§¥¤¥¯¡¦¥¢¥Ã¥×) */
+static int thread_wakeup(kz_thread_id_t id)
+{
+ /* ¥¦¥§¥¤¥¯¡¦¥¢¥Ã¥×¤ò¸Æ¤Ó½Ð¤·¤¿¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥¥å¡¼¤ËÌ᤹ */
+ putcurrent();
+
+ /* »ØÄꤵ¤ì¤¿¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥¥å¡¼¤ËÀܳ¤·¤Æ¥¦¥§¥¤¥¯¡¦¥¢¥Ã¥×¤¹¤ë */
+ current = (kz_thread *)id;
+ putcurrent();
+
+ return 0;
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_getid():¥¹¥ì¥Ã¥ÉID¼èÆÀ) */
+static kz_thread_id_t thread_getid(void)
+{
+ putcurrent();
+ return (kz_thread_id_t)current;
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_chpri():¥¹¥ì¥Ã¥É¤ÎÍ¥ÀèÅÙÊѹ¹) */
+static int thread_chpri(int priority)
+{
+ int old = current->priority;
+ if (priority >= 0)
+ current->priority = priority; /* Í¥ÀèÅÙÊѹ¹ */
+ putcurrent(); /* ¿·¤·¤¤Í¥ÀèÅ٤Υì¥Ç¥£¡¼¡¦¥¥å¡¼¤Ë·Ò¤®Ä¾¤¹ */
+ return old;
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_kmalloc():ưŪ¥á¥â¥ê³ÍÆÀ) */
+static void *thread_kmalloc(int size)
+{
+ putcurrent();
+ return kzmem_alloc(size);
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_kfree():¥á¥â¥ê²òÊü) */
+static int thread_kmfree(char *p)
+{
+ kzmem_free(p);
+ putcurrent();
+ return 0;
+}
+
+/* ¥á¥Ã¥»¡¼¥¸¤ÎÁ÷¿®½èÍý */
+static void sendmsg(kz_msgbox *mboxp, kz_thread *thp, int size, char *p)
+{
+ kz_msgbuf *mp;
+
+ /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ð¥Ã¥Õ¥¡¤ÎºîÀ® */
+ mp = (kz_msgbuf *)kzmem_alloc(sizeof(*mp));
+ if (mp == NULL)
+ kz_sysdown();
+ mp->next = NULL;
+ mp->sender = thp;
+ mp->param.size = size;
+ mp->param.p = p;
+
+ /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ü¥Ã¥¯¥¹¤ÎËöÈø¤Ë¥á¥Ã¥»¡¼¥¸¤òÀܳ¤¹¤ë */
+ if (mboxp->tail) {
+ mboxp->tail->next = mp;
+ } else {
+ mboxp->head = mp;
+ }
+ mboxp->tail = mp;
+}
+
+/* ¥á¥Ã¥»¡¼¥¸¤Î¼õ¿®½èÍý */
+static void recvmsg(kz_msgbox *mboxp)
+{
+ kz_msgbuf *mp;
+ kz_syscall_param_t *p;
+
+ /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ü¥Ã¥¯¥¹¤ÎÀèƬ¤Ë¤¢¤ë¥á¥Ã¥»¡¼¥¸¤òÈ´¤½Ð¤¹ */
+ mp = mboxp->head;
+ mboxp->head = mp->next;
+ if (mboxp->head == NULL)
+ mboxp->tail = NULL;
+ mp->next = NULL;
+
+ /* ¥á¥Ã¥»¡¼¥¸¤ò¼õ¿®¤¹¤ë¥¹¥ì¥Ã¥É¤ËÊÖ¤¹ÃͤòÀßÄꤹ¤ë */
+ p = mboxp->receiver->syscall.param;
+ p->un.recv.ret = (kz_thread_id_t)mp->sender;
+ if (p->un.recv.sizep)
+ *(p->un.recv.sizep) = mp->param.size;
+ if (p->un.recv.pp)
+ *(p->un.recv.pp) = mp->param.p;
+
+ /* ¼õ¿®ÂÔ¤Á¥¹¥ì¥Ã¥É¤Ï¤¤¤Ê¤¯¤Ê¤Ã¤¿¤Î¤Ç¡¤NULL¤ËÌ᤹ */
+ mboxp->receiver = NULL;
+
+ /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ð¥Ã¥Õ¥¡¤Î²òÊü */
+ kzmem_free(mp);
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_send():¥á¥Ã¥»¡¼¥¸Á÷¿®) */
+static int thread_send(kz_msgbox_id_t id, int size, char *p)
+{
+ kz_msgbox *mboxp = &msgboxes[id];
+
+ putcurrent();
+ sendmsg(mboxp, current, size, p); /* ¥á¥Ã¥»¡¼¥¸¤ÎÁ÷¿®½èÍý */
+
+ /* ¼õ¿®ÂÔ¤Á¥¹¥ì¥Ã¥É¤¬Â¸ºß¤·¤Æ¤¤¤ë¾ì¹ç¤Ë¤Ï¼õ¿®½èÍý¤ò¹Ô¤¦ */
+ if (mboxp->receiver) {
+ current = mboxp->receiver; /* ¼õ¿®ÂÔ¤Á¥¹¥ì¥Ã¥É */
+ recvmsg(mboxp); /* ¥á¥Ã¥»¡¼¥¸¤Î¼õ¿®½èÍý */
+ putcurrent(); /* ¼õ¿®¤Ë¤è¤êÆ°ºî²Äǽ¤Ë¤Ê¤Ã¤¿¤Î¤Ç¡¤¥Ö¥í¥Ã¥¯²ò½ü¤¹¤ë */
+ }
+
+ return size;
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_recv():¥á¥Ã¥»¡¼¥¸¼õ¿®) */
+static kz_thread_id_t thread_recv(kz_msgbox_id_t id, int *sizep, char **pp)
+{
+ kz_msgbox *mboxp = &msgboxes[id];
+
+ if (mboxp->receiver) /* ¾¤Î¥¹¥ì¥Ã¥É¤¬¤¹¤Ç¤Ë¼õ¿®ÂÔ¤Á¤·¤Æ¤¤¤ë */
+ kz_sysdown();
+
+ mboxp->receiver = current; /* ¼õ¿®ÂÔ¤Á¥¹¥ì¥Ã¥É¤ËÀßÄê */
+
+ if (mboxp->head == NULL) {
+ /*
+ * ¥á¥Ã¥»¡¼¥¸¡¦¥Ü¥Ã¥¯¥¹¤Ë¥á¥Ã¥»¡¼¥¸¤¬Ìµ¤¤¤Î¤Ç¡¤¥¹¥ì¥Ã¥É¤ò
+ * ¥¹¥ê¡¼¥×¤µ¤»¤ë¡¥(¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤¬¥Ö¥í¥Ã¥¯¤¹¤ë)
+ */
+ return -1;
+ }
+
+ recvmsg(mboxp); /* ¥á¥Ã¥»¡¼¥¸¤Î¼õ¿®½èÍý */
+ putcurrent(); /* ¥á¥Ã¥»¡¼¥¸¤ò¼õ¿®¤Ç¤¤¿¤Î¤Ç¡¤¥ì¥Ç¥£¡¼¾õÂ֤ˤ¹¤ë */
+
+ return current->syscall.param->un.recv.ret;
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_setintr():³ä¹þ¤ß¥Ï¥ó¥É¥éÅÐÏ¿) */
+static int thread_setintr(softvec_type_t type, kz_handler_t handler)
+{
+ static void thread_intr(softvec_type_t type, unsigned long sp);
+
+ /*
+ * ³ä¹þ¤ß¤ò¼õ¤±ÉÕ¤±¤ë¤¿¤á¤Ë¡¤¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤Ë
+ * OS¤Î³ä¹þ¤ß½èÍý¤ÎÆþ¸ý¤È¤Ê¤ë´Ø¿ô¤òÅÐÏ¿¤¹¤ë¡¥
+ */
+ softvec_setintr(type, thread_intr);
+
+ handlers[type] = handler; /* OS¦¤«¤é¸Æ¤Ó½Ð¤¹³ä¹þ¤ß¥Ï¥ó¥É¥é¤òÅÐÏ¿ */
+ putcurrent();
+
+ return 0;
+}
+
+static void call_functions(kz_syscall_type_t type, kz_syscall_param_t *p)
+{
+ /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î¼Â¹ÔÃæ¤Ëcurrent¤¬½ñ¤´¹¤ï¤ë¤Î¤ÇÃí°Õ */
+ switch (type) {
+ case KZ_SYSCALL_TYPE_RUN: /* kz_run() */
+ p->un.run.ret = thread_run(p->un.run.func, p->un.run.name,
+ p->un.run.priority, p->un.run.stacksize,
+ p->un.run.argc, p->un.run.argv);
+ break;
+ case KZ_SYSCALL_TYPE_EXIT: /* kz_exit() */
+ /* TCB¤¬¾Ãµî¤µ¤ì¤ë¤Î¤Ç¡¤Ìá¤êÃͤò½ñ¤¹þ¤ó¤Ç¤Ï¤¤¤±¤Ê¤¤ */
+ thread_exit();
+ break;
+ case KZ_SYSCALL_TYPE_WAIT: /* kz_wait() */
+ p->un.wait.ret = thread_wait();
+ break;
+ case KZ_SYSCALL_TYPE_SLEEP: /* kz_sleep() */
+ p->un.sleep.ret = thread_sleep();
+ break;
+ case KZ_SYSCALL_TYPE_WAKEUP: /* kz_wakeup() */
+ p->un.wakeup.ret = thread_wakeup(p->un.wakeup.id);
+ break;
+ case KZ_SYSCALL_TYPE_GETID: /* kz_getid() */
+ p->un.getid.ret = thread_getid();
+ break;
+ case KZ_SYSCALL_TYPE_CHPRI: /* kz_chpri() */
+ p->un.chpri.ret = thread_chpri(p->un.chpri.priority);
+ break;
+ case KZ_SYSCALL_TYPE_KMALLOC: /* kz_kmalloc() */
+ p->un.kmalloc.ret = thread_kmalloc(p->un.kmalloc.size);
+ break;
+ case KZ_SYSCALL_TYPE_KMFREE: /* kz_kmfree() */
+ p->un.kmfree.ret = thread_kmfree(p->un.kmfree.p);
+ break;
+ case KZ_SYSCALL_TYPE_SEND: /* kz_send() */
+ p->un.send.ret = thread_send(p->un.send.id,
+ p->un.send.size, p->un.send.p);
+ break;
+ case KZ_SYSCALL_TYPE_RECV: /* kz_recv() */
+ p->un.recv.ret = thread_recv(p->un.recv.id,
+ p->un.recv.sizep, p->un.recv.pp);
+ break;
+ case KZ_SYSCALL_TYPE_SETINTR: /* kz_setintr() */
+ p->un.setintr.ret = thread_setintr(p->un.setintr.type,
+ p->un.setintr.handler);
+ break;
+ default:
+ break;
+ }
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý */
+static void syscall_proc(kz_syscall_type_t type, kz_syscall_param_t *p)
+{
+ /*
+ * ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ò¸Æ¤Ó½Ð¤·¤¿¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥¥å¡¼¤«¤é
+ * ³°¤·¤¿¾õÂ֤ǽèÍý´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹¡¥¤³¤Î¤¿¤á¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ò
+ * ¸Æ¤Ó½Ð¤·¤¿¥¹¥ì¥Ã¥É¤ò¤½¤Î¤Þ¤ÞÆ°ºî·Ñ³¤µ¤»¤¿¤¤¾ì¹ç¤Ë¤Ï¡¤
+ * ½èÍý´Ø¿ô¤ÎÆâÉô¤Ç putcurrent() ¤ò¹Ô¤¦É¬Íפ¬¤¢¤ë¡¥
+ */
+ getcurrent();
+ call_functions(type, p);
+}
+
+/* ¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤Î½èÍý */
+static void srvcall_proc(kz_syscall_type_t type, kz_syscall_param_t *p)
+{
+ /*
+ * ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤È¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤Î½èÍý´Ø¿ô¤ÎÆâÉô¤Ç¡¤
+ * ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î¼Â¹Ô¤·¤¿¥¹¥ì¥Ã¥ÉID¤òÆÀ¤ë¤¿¤á¤Ë current ¤ò
+ * »²¾È¤·¤Æ¤¤¤ëÉôʬ¤¬¤¢¤ê(¤¿¤È¤¨¤Ð thread_send() ¤Ê¤É)¡¤
+ * current ¤¬»Ä¤Ã¤Æ¤¤¤ë¤È¸íÆ°ºî¤¹¤ë¤¿¤á NULL ¤ËÀßÄꤹ¤ë¡¥
+ * ¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤Ï thread_intrvec() ÆâÉô¤Î³ä¹þ¤ß¥Ï¥ó¥É¥é¸Æ¤Ó½Ð¤·¤Î
+ * ±äĹ¤Ç¸Æ¤Ð¤ì¤Æ¤¤¤ë¤Ï¤º¤Ç¤Ê¤Î¤Ç¡¤¸Æ¤Ó½Ð¤·¸å¤Ë thread_intrvec() ¤Ç
+ * ¥¹¥±¥¸¥å¡¼¥ê¥ó¥°½èÍý¤¬¹Ô¤ï¤ì¡¤current ¤ÏºÆÀßÄꤵ¤ì¤ë¡¥
+ */
+ current = NULL;
+ call_functions(type, p);
+}
+
+/* ¥¹¥ì¥Ã¥É¤Î¥¹¥±¥¸¥å¡¼¥ê¥ó¥° */
+static void schedule(void)
+{
+ int i;
+
+ /*
+ * Í¥Àè½ç°Ì¤Î¹â¤¤½ç(Í¥ÀèÅ٤οôÃͤµ¤¤½ç)¤Ë¥ì¥Ç¥£¡¼¡¦¥¥å¡¼¤ò¸«¤Æ¡¤
+ * Æ°ºî²Äǽ¤Ê¥¹¥ì¥Ã¥É¤ò¸¡º÷¤¹¤ë¡¥
+ */
+ for (i = 0; i < PRIORITY_NUM; i++) {
+ if (readyque[i].head) /* ¸«¤Ä¤«¤Ã¤¿ */
+ break;
+ }
+ if (i == PRIORITY_NUM) /* ¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿ */
+ kz_sysdown();
+
+ current = readyque[i].head; /* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É¤ËÀßÄꤹ¤ë */
+}
+
+static void syscall_intr(void)
+{
+ syscall_proc(current->syscall.type, current->syscall.param);
+}
+
+static void softerr_intr(void)
+{
+ puts(current->name);
+ puts(" DOWN.\n");
+ getcurrent(); /* ¥ì¥Ç¥£¡¼¥¥å¡¼¤«¤é³°¤¹ */
+ thread_exit(); /* ¥¹¥ì¥Ã¥É½ªÎ»¤¹¤ë */
+}
+
+/* ³ä¹þ¤ß½èÍý¤ÎÆþ¸ý´Ø¿ô */
+static void thread_intr(softvec_type_t type, unsigned long sp)
+{
+ /* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É¤Î¥³¥ó¥Æ¥¥¹¥È¤òÊݸ¤¹¤ë */
+ current->context.sp = sp;
+
+ /*
+ * ³ä¹þ¤ß¤´¤È¤Î½èÍý¤ò¼Â¹Ô¤¹¤ë¡¥
+ * SOFTVEC_TYPE_SYSCALL, SOFTVEC_TYPE_SOFTERR ¤Î¾ì¹ç¤Ï
+ * syscall_intr(), softerr_intr() ¤¬¥Ï¥ó¥É¥é¤ËÅÐÏ¿¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¤
+ * ¤½¤ì¤é¤¬¼Â¹Ô¤µ¤ì¤ë¡¥
+ * ¤½¤ì°Ê³°¤Î¾ì¹ç¤Ï¡¤kz_setintr()¤Ë¤è¤Ã¤Æ¥æ¡¼¥¶ÅÐÏ¿¤µ¤ì¤¿¥Ï¥ó¥É¥é¤¬
+ * ¼Â¹Ô¤µ¤ì¤ë¡¥
+ */
+ if (handlers[type])
+ handlers[type]();
+
+ schedule(); /* ¥¹¥ì¥Ã¥É¤Î¥¹¥±¥¸¥å¡¼¥ê¥ó¥° */
+
+ /*
+ * ¥¹¥ì¥Ã¥É¤Î¥Ç¥£¥¹¥Ñ¥Ã¥Á
+ * (dispatch()´Ø¿ô¤ÎËÜÂΤÏstartup.s¤Ë¤¢¤ê¡¤¥¢¥»¥ó¥Ö¥é¤Çµ½Ò¤µ¤ì¤Æ¤¤¤ë)
+ */
+ dispatch(¤t->context);
+ /* ¤³¤³¤Ë¤ÏÊ֤äƤ³¤Ê¤¤ */
+}
+
+void kz_start(kz_func_t func, char *name, int priority, int stacksize,
+ int argc, char *argv[])
+{
+ kzmem_init(); /* ưŪ¥á¥â¥ê¤Î½é´ü²½ */
+
+ /*
+ * °Ê¹ß¤Ç¸Æ¤Ó½Ð¤¹¥¹¥ì¥Ã¥É´ØÏ¢¤Î¥é¥¤¥Ö¥é¥ê´Ø¿ô¤ÎÆâÉô¤Ç current ¤ò
+ * ¸«¤Æ¤¤¤ë¾ì¹ç¤¬¤¢¤ë¤Î¤Ç¡¤current ¤ò NULL ¤Ë½é´ü²½¤·¤Æ¤ª¤¯¡¥
+ */
+ current = NULL;
+
+ memset(readyque, 0, sizeof(readyque));
+ memset(threads, 0, sizeof(threads));
+ memset(handlers, 0, sizeof(handlers));
+ memset(msgboxes, 0, sizeof(msgboxes));
+
+ /* ³ä¹þ¤ß¥Ï¥ó¥É¥é¤ÎÅÐÏ¿ */
+ thread_setintr(SOFTVEC_TYPE_SYSCALL, syscall_intr); /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë */
+ thread_setintr(SOFTVEC_TYPE_SOFTERR, softerr_intr); /* ¥À¥¦¥óÍ×°øȯÀ¸ */
+
+ /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ëȯ¹ÔÉԲĤʤΤÇľÀÜ´Ø¿ô¤ò¸Æ¤Ó½Ð¤·¤Æ¥¹¥ì¥Ã¥ÉºîÀ®¤¹¤ë */
+ current = (kz_thread *)thread_run(func, name, priority, stacksize,
+ argc, argv);
+
+ /* ºÇ½é¤Î¥¹¥ì¥Ã¥É¤òµ¯Æ° */
+ dispatch(¤t->context);
+
+ /* ¤³¤³¤Ë¤ÏÊ֤äƤ³¤Ê¤¤ */
+}
+
+void kz_sysdown(void)
+{
+ puts("system error!\n");
+ while (1)
+ ;
+}
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¸Æ¤Ó½Ð¤·Íѥ饤¥Ö¥é¥ê´Ø¿ô */
+void kz_syscall(kz_syscall_type_t type, kz_syscall_param_t *param)
+{
+ current->syscall.type = type;
+ current->syscall.param = param;
+ asm volatile ("trapa #0"); /* ¥È¥é¥Ã¥×³ä¹þ¤ßȯ¹Ô */
+}
+
+/* ¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¸Æ¤Ó½Ð¤·Íѥ饤¥Ö¥é¥ê´Ø¿ô */
+void kz_srvcall(kz_syscall_type_t type, kz_syscall_param_t *param)
+{
+ srvcall_proc(type, param);
+}
--- /dev/null
+#ifndef _KOZOS_H_INCLUDED_
+#define _KOZOS_H_INCLUDED_
+
+#include "defines.h"
+#include "interrupt.h"
+#include "syscall.h"
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë */
+kz_thread_id_t kz_run(kz_func_t func, char *name, int priority, int stacksize,
+ int argc, char *argv[]);
+void kz_exit(void);
+int kz_wait(void);
+int kz_sleep(void);
+int kz_wakeup(kz_thread_id_t id);
+kz_thread_id_t kz_getid(void);
+int kz_chpri(int priority);
+void *kz_kmalloc(int size);
+int kz_kmfree(void *p);
+int kz_send(kz_msgbox_id_t id, int size, char *p);
+kz_thread_id_t kz_recv(kz_msgbox_id_t id, int *sizep, char **pp);
+int kz_setintr(softvec_type_t type, kz_handler_t handler);
+
+/* ¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë */
+int kx_wakeup(kz_thread_id_t id);
+void *kx_kmalloc(int size);
+int kx_kmfree(void *p);
+int kx_send(kz_msgbox_id_t id, int size, char *p);
+
+/* ¥é¥¤¥Ö¥é¥ê´Ø¿ô */
+void kz_start(kz_func_t func, char *name, int priority, int stacksize,
+ int argc, char *argv[]);
+void kz_sysdown(void);
+void kz_syscall(kz_syscall_type_t type, kz_syscall_param_t *param);
+void kz_srvcall(kz_syscall_type_t type, kz_syscall_param_t *param);
+
+/* ¥·¥¹¥Æ¥à¡¦¥¿¥¹¥¯ */
+int consdrv_main(int argc, char *argv[]);
+int timerdrv_main(int argc, char *argv[]);
+int leddrv_main(int argc, char *argv[]);
+
+/* ¥æ¡¼¥¶¡¦¥¿¥¹¥¯ */
+int command_main(int argc, char *argv[]);
+int clock_main(int argc, char *argv[]);
+int remocon_main(int argc, char *argv[]);
+
+#endif
--- /dev/null
+#include "lcd.h"
+#include "defines.h"
+
+static const uint8 FONT_X = 5;
+static const uint8 FONT_Y = 7;
+static const uint16 FONT_MIN_CODE = 0x20;
+static const uint16 FONT_MAX_CODE = 0x7F;
+
+#define swap(a,b) {int c=a;a=b;b=c;}
+#define abs(n) (((int)(n) < 0) ? ((int)(n) * (-1)) : (n))
+
+#define H8_3069F_P4DDR ((volatile uint8 *)0xFEE003)
+#define H8_3069F_P4DR ((volatile uint8 *)0xFFFFD3)
+#define H8_3069F_CSCR ((volatile uint8 *)0xFEE01F)
+
+#define LCD_ADDR_LEFT ((volatile uint8 *)0x800000)
+#define LCD_ADDR_RIGHT ((volatile uint8 *)0xA00000)
+#define LCD_AOFS_CMD (0)
+#define LCD_AOFS_DAT (1 << 3)
+
+#define BIT_LCD_RES (1 << 7)
+#define BIT_SDC_CS (1 << 0)
+
+#define LCD1_CMD(VAL) \
+ do { \
+ *(LCD_ADDR_LEFT + LCD_AOFS_CMD) = (VAL); \
+ } while (0)
+
+#define LCD1_DAT_WRITE(VAL) \
+ do { \
+ *(LCD_ADDR_LEFT + LCD_AOFS_DAT) = (VAL); \
+ } while (0)
+
+#define LCD1_DAT_READ() (*(LCD_ADDR_LEFT + LCD_AOFS_DAT))
+
+#define LCD2_CMD(VAL) \
+ do { \
+ *(LCD_ADDR_RIGHT + LCD_AOFS_CMD) = (VAL); \
+ } while (0)
+
+#define LCD2_DAT_WRITE(VAL) \
+ do { \
+ *(LCD_ADDR_RIGHT + LCD_AOFS_DAT) = (VAL); \
+ } while (0)
+
+#define LCD2_DAT_READ() (*(LCD_ADDR_RIGHT + LCD_AOFS_DAT))
+
+static const uint8 font5x7_data[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, // (white space)
+ 0x00, 0x00, 0x5F, 0x00, 0x00, // !
+ 0x00, 0x07, 0x00, 0x07, 0x00, // "
+ 0x14, 0x7F, 0x14, 0x7F, 0x14, // #
+ 0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
+ 0x23, 0x13, 0x08, 0x64, 0x62, // %
+ 0x36, 0x49, 0x55, 0x22, 0x50, // &
+ 0x00, 0x05, 0x03, 0x00, 0x00, // '
+ 0x00, 0x1C, 0x22, 0x41, 0x00, // (
+ 0x00, 0x41, 0x22, 0x1C, 0x00, // )
+ 0x08, 0x2A, 0x1C, 0x2A, 0x08, // *
+ 0x08, 0x08, 0x3E, 0x08, 0x08, // +
+ 0x00, 0x50, 0x30, 0x00, 0x00, // ,
+ 0x08, 0x08, 0x08, 0x08, 0x08, // -
+ 0x00, 0x60, 0x60, 0x00, 0x00, // .
+ 0x20, 0x10, 0x08, 0x04, 0x02, // /
+ 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
+ 0x00, 0x42, 0x7F, 0x40, 0x00, // 1
+ 0x42, 0x61, 0x51, 0x49, 0x46, // 2
+ 0x21, 0x41, 0x45, 0x4B, 0x31, // 3
+ 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
+ 0x27, 0x45, 0x45, 0x45, 0x39, // 5
+ 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
+ 0x01, 0x71, 0x09, 0x05, 0x03, // 7
+ 0x36, 0x49, 0x49, 0x49, 0x36, // 8
+ 0x06, 0x49, 0x49, 0x29, 0x1E, // 9
+ 0x00, 0x36, 0x36, 0x00, 0x00, // :
+ 0x00, 0x56, 0x36, 0x00, 0x00, // ;
+ 0x00, 0x08, 0x14, 0x22, 0x41, // <
+ 0x14, 0x14, 0x14, 0x14, 0x14, // =
+ 0x41, 0x22, 0x14, 0x08, 0x00, // >
+ 0x02, 0x01, 0x51, 0x09, 0x06, // ?
+ 0x32, 0x49, 0x79, 0x41, 0x3E, // @
+ 0x7E, 0x11, 0x11, 0x11, 0x7E, // A
+ 0x7F, 0x49, 0x49, 0x49, 0x36, // B
+ 0x3E, 0x41, 0x41, 0x41, 0x22, // C
+ 0x7F, 0x41, 0x41, 0x22, 0x1C, // D
+ 0x7F, 0x49, 0x49, 0x49, 0x41, // E
+ 0x7F, 0x09, 0x09, 0x01, 0x01, // F
+ 0x3E, 0x41, 0x41, 0x51, 0x32, // G
+ 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
+ 0x00, 0x41, 0x7F, 0x41, 0x00, // I
+ 0x20, 0x40, 0x41, 0x3F, 0x01, // J
+ 0x7F, 0x08, 0x14, 0x22, 0x41, // K
+ 0x7F, 0x40, 0x40, 0x40, 0x40, // L
+ 0x7F, 0x02, 0x04, 0x02, 0x7F, // M
+ 0x7F, 0x04, 0x08, 0x10, 0x7F, // N
+ 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
+ 0x7F, 0x09, 0x09, 0x09, 0x06, // P
+ 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
+ 0x7F, 0x09, 0x19, 0x29, 0x46, // R
+ 0x46, 0x49, 0x49, 0x49, 0x31, // S
+ 0x01, 0x01, 0x7F, 0x01, 0x01, // T
+ 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
+ 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
+ 0x7F, 0x20, 0x18, 0x20, 0x7F, // W
+ 0x63, 0x14, 0x08, 0x14, 0x63, // X
+ 0x03, 0x04, 0x78, 0x04, 0x03, // Y
+ 0x61, 0x51, 0x49, 0x45, 0x43, // Z
+ 0x00, 0x00, 0x7F, 0x41, 0x41, // [
+ 0x02, 0x04, 0x08, 0x10, 0x20, // /
+ 0x41, 0x41, 0x7F, 0x00, 0x00, // ]
+ 0x04, 0x02, 0x01, 0x02, 0x04, // ^
+ 0x40, 0x40, 0x40, 0x40, 0x40, // _
+ 0x00, 0x01, 0x02, 0x04, 0x00, // `
+ 0x20, 0x54, 0x54, 0x54, 0x78, // a
+ 0x7F, 0x48, 0x44, 0x44, 0x38, // b
+ 0x38, 0x44, 0x44, 0x44, 0x20, // c
+ 0x38, 0x44, 0x44, 0x48, 0x7F, // d
+ 0x38, 0x54, 0x54, 0x54, 0x18, // e
+ 0x08, 0x7E, 0x09, 0x01, 0x02, // f
+ 0x08, 0x14, 0x54, 0x54, 0x3C, // g
+ 0x7F, 0x08, 0x04, 0x04, 0x78, // h
+ 0x00, 0x44, 0x7D, 0x40, 0x00, // i
+ 0x20, 0x40, 0x44, 0x3D, 0x00, // j
+ 0x00, 0x7F, 0x10, 0x28, 0x44, // k
+ 0x00, 0x41, 0x7F, 0x40, 0x00, // l
+ 0x7C, 0x04, 0x18, 0x04, 0x78, // m
+ 0x7C, 0x08, 0x04, 0x04, 0x78, // n
+ 0x38, 0x44, 0x44, 0x44, 0x38, // o
+ 0x7C, 0x14, 0x14, 0x14, 0x08, // p
+ 0x08, 0x14, 0x14, 0x18, 0x7C, // q
+ 0x7C, 0x08, 0x04, 0x04, 0x08, // r
+ 0x48, 0x54, 0x54, 0x54, 0x20, // s
+ 0x04, 0x3F, 0x44, 0x40, 0x20, // t
+ 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
+ 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
+ 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
+ 0x44, 0x28, 0x10, 0x28, 0x44, // x
+ 0x0C, 0x50, 0x50, 0x50, 0x3C, // y
+ 0x44, 0x64, 0x54, 0x4C, 0x44, // z
+ 0x00, 0x08, 0x36, 0x41, 0x00, // {
+ 0x00, 0x00, 0x7F, 0x00, 0x00, // |
+ 0x00, 0x41, 0x36, 0x08, 0x00, // }
+ 0x08, 0x08, 0x2A, 0x1C, 0x08, // ->
+ 0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
+};
+
+void lcd_init(void)
+{
+ *H8_3069F_P4DDR = BIT_LCD_RES | BIT_SDC_CS;
+
+ /*
+ * L->H : 68K mode.
+ */
+ *H8_3069F_P4DR &= ~BIT_LCD_RES;
+ asm volatile ("nop");
+ asm volatile ("nop");
+ asm volatile ("nop");
+ asm volatile ("nop");
+ *H8_3069F_P4DR |= BIT_LCD_RES;
+
+ *H8_3069F_CSCR = 0x3F;
+
+ LCD1_CMD(0xE2); // Reset
+ LCD1_CMD(0xA4); // Static Drive Off
+ LCD1_CMD(0xC0); // Display Start Line
+ LCD1_CMD(0xAF); // Display On
+ LCD1_CMD(0xB8); // Page Address Setup
+ LCD1_CMD(0x00); // Column Address
+
+ LCD2_CMD(0xE2); // Reset
+ LCD2_CMD(0xA4); // Static Drive Off
+ LCD2_CMD(0xC0); // Display Start Line
+ LCD2_CMD(0xAF); // Display On
+ LCD2_CMD(0xB8); // Page Address Setup
+ LCD2_CMD(0x00); // Column Address
+}
+
+void lcd_clear(void)
+{
+ int p, c;
+
+ for (p = 0; p <= 3; p++) {
+ LCD1_CMD(0xB8 | (p & 0x03)); // Page Address Setup
+ LCD1_CMD(0x00 | (0 & 0x7F)); // Column Address
+ for (c = 0; c < 62; c++) {
+ LCD1_DAT_WRITE(0);
+ }
+
+ LCD2_CMD(0xB8 | (p & 0x03)); // Page Address Setup
+ LCD2_CMD(0x00 | (0 & 0x7F)); // Column Address
+ for (c = 0; c < 62; c++) {
+ LCD2_DAT_WRITE(0);
+ }
+ }
+}
+
+void lcd_set_pixel(int x, int y, int reverse)
+{
+ volatile uint8 dat;
+ int p, c;
+
+ if (x <= 60) {
+ p = y / 8;
+ c = x;
+ LCD1_CMD(0xB8 | (p & 0x03)); // Page Address Setup
+ LCD1_CMD(0x00 | (c & 0x7F)); // Column Address
+ LCD1_CMD(0xE0);
+ dat = LCD1_DAT_READ(); // Dummy Read
+ dat = LCD1_DAT_READ(); // Real Read
+ if (reverse) {
+ dat |= (1 << (y % 8));
+ } else {
+ dat &= ~(1 << (y % 8));
+ }
+ LCD1_DAT_WRITE(dat);
+ LCD1_CMD(0xEE);
+ } else {
+ p = y / 8;
+ c = x - 61;
+ LCD2_CMD(0xB8 | (p & 0x03)); // Page Address Setup
+ LCD2_CMD(0x00 | (c & 0x7F)); // Column Address
+ LCD2_CMD(0xE0);
+ dat = LCD2_DAT_READ(); // Dummy Read
+ dat = LCD2_DAT_READ(); // Real Read
+ if (reverse) {
+ dat |= (1 << (y % 8));
+ } else {
+ dat &= ~(1 << (y % 8));
+ }
+ LCD2_DAT_WRITE(dat);
+ LCD2_CMD(0xEE);
+ }
+}
+
+void lcd_draw_line(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 reverse)
+{
+ int x;
+ /*
+ * Bresenham's line algorithm
+ */
+ uint8 steep = abs(y2 - y1) > abs(x2 - x1);
+ if (steep) {
+ swap(x1, y1);
+ swap(x2, y2);
+ }
+ if (x1 > x2) {
+ swap(x1, x2);
+ swap(y1, y2);
+ }
+ int deltax = x2 - x1;
+ int deltay = abs(y2 - y1);
+ int error = deltax / 2;
+ int ystep;
+ int y = y1;
+ if (y1 < y2) {
+ ystep = 1;
+ } else {
+ ystep = -1;
+ }
+ for (x = x1; x <= x2; x++) {
+ if (steep) {
+ if (reverse) {
+ lcd_set_pixel(y, x, 0);
+ } else {
+ lcd_set_pixel(y, x, 1);
+ }
+ } else {
+ if (reverse) {
+ lcd_set_pixel(x, y, 0);
+ } else {
+ lcd_set_pixel(x, y, 1);
+ }
+ }
+ error = error - deltay;
+ if (error < 0) {
+ y = y + ystep;
+ error = error + deltax;
+ }
+ }
+}
+
+void lcd_draw_box(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 reverse)
+{
+ int x, y;
+ for (x = x1; x <= x2; x++) {
+ if (reverse) {
+ lcd_set_pixel(x, y1, 0);
+ lcd_set_pixel(x, y2, 0);
+ } else {
+ lcd_set_pixel(x, y1, 1);
+ lcd_set_pixel(x, y2, 1);
+ }
+ }
+ for (y = y1; y <= y2; y++) {
+ if (reverse) {
+ lcd_set_pixel(x1, y, 0);
+ lcd_set_pixel(x2, y, 0);
+ } else {
+ lcd_set_pixel(x1, y, 1);
+ lcd_set_pixel(x2, y, 1);
+ }
+ }
+}
+
+void lcd_fill_box(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 reverse)
+{
+ int x, y;
+ for (x = x1; x <= x2; x++) {
+ for (y = y1; y <= y2; y++) {
+ if (reverse) {
+ lcd_set_pixel(x, y, 0);
+ } else {
+ lcd_set_pixel(x, y, 1);
+ }
+ }
+ }
+}
+
+void lcd_draw_string(uint8 x, uint8 y, char *str, uint8 reverse)
+{
+ char *p = str;
+ int cnt = 0;
+ while (*p) {
+ lcd_draw_char(x + (FONT_X * cnt), y, *p, reverse);
+ p++;
+ cnt++;
+ }
+}
+
+void lcd_draw_char(uint8 x, uint8 y, char c, uint8 reverse)
+{
+ int i, j;
+ if ((FONT_MIN_CODE <= c) &&(c <= FONT_MAX_CODE)) {
+ int aofs = (c - FONT_MIN_CODE) * FONT_X;
+ for (i = 0; i < FONT_X; i++) {
+ uint8 pat = font5x7_data[aofs + i];
+ for (j = 0; j < FONT_Y; j++) {
+ if (pat & (1 << j)) {
+ if (reverse) {
+ lcd_set_pixel(x + i, y + j, 0);
+ } else {
+ lcd_set_pixel(x + i, y + j, 1);
+ }
+ } else {
+ if (reverse) {
+ lcd_set_pixel(x + i, y + j, 1);
+ } else {
+ lcd_set_pixel(x + i, y + j, 0);
+ }
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < FONT_X; i++) {
+ uint8 pat = (i % 2) ? 0x55 : 0xAA;
+ for (j = 0; j < FONT_Y; j++) {
+ if (pat & (1 << j)) {
+ if (reverse) {
+ lcd_set_pixel(x + i, y + j, 0);
+ } else {
+ lcd_set_pixel(x + i, y + j, 1);
+ }
+ } else {
+ if (reverse) {
+ lcd_set_pixel(x + i, y + j, 1);
+ } else {
+ lcd_set_pixel(x + i, y + j, 0);
+ }
+ }
+ }
+ }
+ }
+}
+
+void lcd_draw_checkbox(
+ uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 state, uint8 reverse)
+{
+ lcd_draw_box(x1, y1, x2, y2, reverse);
+ if (state) {
+ lcd_draw_line(x1, y1, x2, y2, reverse);
+ lcd_draw_line(x1, y2, x2, y1, reverse);
+ }
+}
+
+void lcd_draw_progressbar(
+ uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ int min, int max, int value, uint8 reverse)
+{
+ lcd_draw_box(x1, y1, x2, y2, reverse);
+ if ((value < min) || (max < value)) {
+ return;
+ }
+ int tmp_max = max - min;
+ int tmp_val = value - min;
+ int pix = ((x2 - x1) * tmp_val) / tmp_max;
+ lcd_fill_box(x1 + 1, y1 + 1, x1 + pix - 1, y2 - 1, reverse);
+ lcd_fill_box(x1 + pix, y1 + 1, x2 - 1, y2 - 1, !reverse);
+}
+
--- /dev/null
+#ifndef _LCD_H_INCLUDED_
+#define _LCD_H_INCLUDED_
+
+#include "defines.h"
+
+void lcd_init(void);
+void lcd_clear(void);
+void lcd_set_pixel(int x, int y, int reverse);
+void lcd_draw_line(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ uint8 reverse);
+void lcd_draw_box(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ uint8 reverse);
+void lcd_fill_box(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ uint8 reverse);
+void lcd_draw_string(uint8 x, uint8 y, char *str, uint8 reverse);
+void lcd_draw_char(uint8 x, uint8 y, char c, uint8 reverse);
+void lcd_draw_checkbox(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ uint8 state, uint8 reverse);
+void lcd_draw_progressbar(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ int min, int max, int value, uint8 reverse);
+
+#endif
+
--- /dev/null
+OUTPUT_FORMAT("elf32-h8300")
+OUTPUT_ARCH(h8300h)
+ENTRY("_start")
+
+MEMORY
+{
+ /* DRAM (2MB) */
+ dramall(rwx) : o = 0x400000, l = 0x200000 /* 2MB */
+ ram(rwx) : o = 0x400000 + 0x100, l = 0x200000 - 0x100
+
+ /* internal RAM (16KB) */
+ ramall(rwx) : o = 0xffbf20, l = 0x004000 /* 16KB */
+ softvec(rw) : o = 0xffbf20, l = 0x000040 /* top of RAM */
+ userstack(rw) : o = 0xffc000, l = 0x003f00
+ bootstack(rw) : o = 0xffff00, l = 0x000000
+ intrstack(rw) : o = 0xffff00, l = 0x000000 /* end of RAM */
+}
+
+SECTIONS
+{
+ .softvec : {
+ _softvec = .;
+ } > softvec
+
+ .text : {
+ _text_start = . ;
+ *(.text)
+ _etext = . ;
+ } > ram
+
+ .rodata : {
+ _rodata_start = . ;
+ *(.strings)
+ *(.rodata)
+ *(.rodata.*)
+ _erodata = . ;
+ } > ram
+
+ .data : {
+ _data_start = . ;
+ *(.data)
+ _edata = . ;
+ } > ram
+
+ .bss : {
+ _bss_start = . ;
+ *(.bss)
+ *(COMMON)
+ _ebss = . ;
+ } > ram
+
+ . = ALIGN(4);
+ _end = . ;
+
+ .freearea : {
+ _freearea = .;
+ } > ram
+
+ .userstack : {
+ _userstack = .;
+ } > userstack
+
+ .bootstack : {
+ _bootstack = .;
+ } > bootstack
+
+ .intrstack : {
+ _intrstack = .;
+ } > intrstack
+}
--- /dev/null
+#include "led.h"
+#include "defines.h"
+
+#define H8_3069F_PADDR ((volatile uint8 *)0xFEE009)
+#define H8_3069F_PADR ((volatile uint8 *)0xFFFFD9)
+
+#define MASK_LEDG (1 << 2)
+#define MASK_LEDR (1 << 3)
+#define MASK_LED1 (1 << 6)
+#define MASK_LED2 (1 << 7)
+
+int led_init(void)
+{
+ volatile uint8 mask = MASK_LED1 | MASK_LED2 | MASK_LEDG | MASK_LEDR;
+
+ /*
+ * ¥Ý¡¼¥È¥Ç¥£¥ì¥¯¥·¥ç¥ó¤òÀßÄꤹ¤ëÁ°¤Ë¥Ç¡¼¥¿¥ì¥¸¥¹¥¿¤ò½é´ü²½¤¹¤ë¡£
+ * ÉéÏÀÍý¤Ê¤Î¤Ç¡¢½é´üÃͤΥ¼¥í¤À¤È½ÐÎϤˤ·¤¿»þÅÀ¤ÇÅÀÅô¾õÂ֤Ȥʤ롣
+ */
+ *H8_3069F_PADR |= mask;
+
+ /*
+ * ¥Ý¡¼¥ÈA¤Î¥Ó¥Ã¥È2,3,6,7¤Ï½ÐÎϥݡ¼¥È¤È¤·¤ÆÀßÄꤹ¤ë¡£
+ *
+ * ¥Ç¡¼¥¿¥Ç¥£¥ì¥¯¥·¥ç¥ó¥ì¥¸¥¹¥¿¤ÏWrite Only¤Ê¤Î¤Ç¡¢
+ * ¾¤Î¥Ó¥Ã¥È¤ÎÀßÄ꤬ɬÍפˤʤä¿»þÅÀ¤Ç¡¢
+ * ¥Ý¡¼¥ÈÆþ½ÐÎÏÀßÄê¤ò¤Þ¤È¤á¤Æ´ÉÍý¤¹¤ë¤è¤¦¤Ê
+ * ²¿¤é¤«¤ÎÂкö¤¬É¬ÍפȤʤë¤À¤í¤¦¡£
+ */
+ *H8_3069F_PADDR = 0xCC;
+
+ return 0;
+}
+
+int led_write(led_target_t target, led_state_t state)
+{
+ volatile uint8 mask = 0x00;
+
+ switch (target) {
+ case Led1:
+ mask = MASK_LED1;
+ break;
+ case Led2:
+ mask = MASK_LED2;
+ break;
+ case LedG:
+ mask = MASK_LEDG;
+ break;
+ case LedR:
+ mask = MASK_LEDR;
+ break;
+ default:
+ return -1;
+ }
+
+ switch (state) {
+ case LedOn:
+ *H8_3069F_PADR &= ~mask;
+ break;
+ case LedOff:
+ *H8_3069F_PADR |= mask;
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int led_toggle(led_target_t target)
+{
+ volatile uint8 mask = 0x00;
+
+ switch (target) {
+ case Led1:
+ mask = MASK_LED1;
+ break;
+ case Led2:
+ mask = MASK_LED2;
+ break;
+ case LedG:
+ mask = MASK_LEDG;
+ break;
+ case LedR:
+ mask = MASK_LEDR;
+ break;
+ default:
+ return -1;
+ }
+
+ if (*H8_3069F_PADR & mask) {
+ *H8_3069F_PADR &= ~mask;
+ } else {
+ *H8_3069F_PADR |= mask;
+ }
+
+ return 0;
+}
+
--- /dev/null
+#ifndef _LED_H_INCLUDED_
+#define _LED_H_INCLUDED_
+
+typedef enum {
+ Led1,
+ Led2,
+ LedG,
+ LedR,
+} led_target_t;
+
+typedef enum {
+ LedOn,
+ LedOff,
+} led_state_t;
+
+int led_init(void);
+int led_write(led_target_t target, led_state_t state);
+int led_toggle(led_target_t target);
+
+#endif
+
--- /dev/null
+#include "leddrv.h"
+#include "led.h"
+#include "kozos.h"
+
+/* \e$B%9%l%C%I$+$i$NMW5a$r=hM}$9$k\e(B */
+static int leddrv_command(char *p)
+{
+ int cmd = p[0];
+ int led = p[1] - '0';
+ switch (cmd) {
+ case LEDDRV_CMD_LED_ON:
+ led_write(led, LedOn);
+ break;
+ case LEDDRV_CMD_LED_OFF:
+ led_write(led, LedOff);
+ break;
+ case LEDDRV_CMD_LED_TOGGLE:
+ led_toggle(led);
+ break;
+ default:
+ break;
+ }
+ kz_kmfree(p);
+
+ return 0;
+}
+
+int leddrv_main(int argc, char *argv[])
+{
+ int size;
+ char *p;
+
+ led_init();
+ while (1) {
+ kz_recv(MSGBOX_ID_LEDDRIVE, &size, &p);
+ leddrv_command(p);
+ }
+
+ return 0;
+}
--- /dev/null
+#ifndef _LEDDRV_H_INCLUDED_
+#define _LEDDRV_H_INCLUDED_
+
+#define LEDDRV_CMD_LED_ON 'o' /* LED¤ÎÅÀÅô */
+#define LEDDRV_CMD_LED_OFF 'x' /* LED¤Î¾ÃÅô */
+#define LEDDRV_CMD_LED_TOGGLE 't' /* LED¤Î¥È¥°¥ë */
+
+#endif
--- /dev/null
+#include "defines.h"
+#include "serial.h"
+#include "lib.h"
+
+void *memset(void *b, int c, long len)
+{
+ char *p;
+ for (p = b; len > 0; len--)
+ *(p++) = c;
+ return b;
+}
+
+void *memcpy(void *dst, const void *src, long len)
+{
+ char *d = dst;
+ const char *s = src;
+ for (; len > 0; len--)
+ *(d++) = *(s++);
+ return dst;
+}
+
+int memcmp(const void *b1, const void *b2, long len)
+{
+ const char *p1 = b1, *p2 = b2;
+ for (; len > 0; len--) {
+ if (*p1 != *p2)
+ return (*p1 > *p2) ? 1 : -1;
+ p1++;
+ p2++;
+ }
+ return 0;
+}
+
+int strlen(const char *s)
+{
+ int len;
+ for (len = 0; *s; s++, len++)
+ ;
+ return len;
+}
+
+char *strcpy(char *dst, const char *src)
+{
+ char *d = dst;
+ for (;; dst++, src++) {
+ *dst = *src;
+ if (!*src) break;
+ }
+ return d;
+}
+
+int strcmp(const char *s1, const char *s2)
+{
+ while (*s1 || *s2) {
+ if (*s1 != *s2)
+ return (*s1 > *s2) ? 1 : -1;
+ s1++;
+ s2++;
+ }
+ return 0;
+}
+
+int strncmp(const char *s1, const char *s2, int len)
+{
+ while ((*s1 || *s2) && (len > 0)) {
+ if (*s1 != *s2)
+ return (*s1 > *s2) ? 1 : -1;
+ s1++;
+ s2++;
+ len--;
+ }
+ return 0;
+}
+
+/* £±Ê¸»úÁ÷¿® */
+int putc(unsigned char c)
+{
+ if (c == '\n')
+ serial_send_byte(SERIAL_DEFAULT_DEVICE, '\r');
+ return serial_send_byte(SERIAL_DEFAULT_DEVICE, c);
+}
+
+/* £±Ê¸»ú¼õ¿® */
+unsigned char getc(void)
+{
+ unsigned char c = serial_recv_byte(SERIAL_DEFAULT_DEVICE);
+ c = (c == '\r') ? '\n' : c;
+ putc(c); /* ¥¨¥³¡¼¡¦¥Ð¥Ã¥¯ */
+ return c;
+}
+
+/* ʸ»úÎóÁ÷¿® */
+int puts(unsigned char *str)
+{
+ while (*str)
+ putc(*(str++));
+ return 0;
+}
+
+/* ʸ»úÎó¼õ¿® */
+int gets(unsigned char *buf)
+{
+ int i = 0;
+ unsigned char c;
+ do {
+ c = getc();
+ if (c == '\n')
+ c = '\0';
+ buf[i++] = c;
+ } while (c);
+ return i - 1;
+}
+
+/* ¿ôÃͤÎ16¿Êɽ¼¨ */
+int putxval(unsigned long value, int column)
+{
+ char buf[9];
+ char *p;
+
+ p = buf + sizeof(buf) - 1;
+ *(p--) = '\0';
+
+ if (!value && !column)
+ column++;
+
+ while (value || column) {
+ *(p--) = "0123456789abcdef"[value & 0xf];
+ value >>= 4;
+ if (column) column--;
+ }
+
+ puts(p + 1);
+
+ return 0;
+}
--- /dev/null
+#ifndef _LIB_H_INCLUDED_
+#define _LIB_H_INCLUDED_
+
+void *memset(void *b, int c, long len);
+void *memcpy(void *dst, const void *src, long len);
+int memcmp(const void *b1, const void *b2, long len);
+int strlen(const char *s);
+char *strcpy(char *dst, const char *src);
+int strcmp(const char *s1, const char *s2);
+int strncmp(const char *s1, const char *s2, int len);
+
+int putc(unsigned char c); /* £±Ê¸»úÁ÷¿® */
+unsigned char getc(void); /* £±Ê¸»ú¼õ¿® */
+int puts(unsigned char *str); /* ʸ»úÎóÁ÷¿® */
+int gets(unsigned char *buf); /* ʸ»úÎó¼õ¿® */
+int putxval(unsigned long value, int column); /* ¿ôÃͤÎ16¿Êɽ¼¨ */
+
+#endif
--- /dev/null
+#include "defines.h"
+#include "kozos.h"
+#include "interrupt.h"
+#include "lib.h"
+
+/* ¥·¥¹¥Æ¥à¡¦¥¿¥¹¥¯¤È¥æ¡¼¥¶¡¦¥¿¥¹¥¯¤Îµ¯Æ° */
+static int start_threads(int argc, char *argv[])
+{
+ kz_run(consdrv_main, "consdrv", 1, 0x200, 0, NULL);
+ kz_run(command_main, "command", 8, 0x200, 0, NULL);
+ kz_run(timerdrv_main, "timerdrv", 2, 0x100, 0, NULL);
+ kz_run(leddrv_main, "leddrv", 7, 0x100, 0, NULL);
+ kz_run(clock_main, "clock", 9, 0x200, 0, NULL);
+ kz_run(remocon_main, "remocon", 10, 0x100, 0, NULL);
+
+ kz_chpri(15); /* Í¥Àè½ç°Ì¤ò²¼¤²¤Æ¡¤¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¤Ë°Ü¹Ô¤¹¤ë */
+ INTR_ENABLE; /* ³ä¹þ¤ß͸ú¤Ë¤¹¤ë */
+ while (1) {
+ asm volatile ("sleep"); /* ¾ÊÅÅÎϥ⡼¥É¤Ë°Ü¹Ô */
+ }
+
+ return 0;
+}
+
+int main(void)
+{
+ INTR_DISABLE; /* ³ä¹þ¤ß̵¸ú¤Ë¤¹¤ë */
+
+ puts("kozos boot succeed!\n");
+
+ /* OS¤ÎÆ°ºî³«»Ï */
+ kz_start(start_threads, "idle", 0, 0x100, 0, NULL);
+ /* ¤³¤³¤Ë¤ÏÌá¤Ã¤Æ¤³¤Ê¤¤ */
+
+ return 0;
+}
--- /dev/null
+#include "defines.h"
+#include "kozos.h"
+#include "lib.h"
+#include "memory.h"
+
+/*
+ * ¥á¥â¥ê¡¦¥Ö¥í¥Ã¥¯¹½Â¤ÂÎ
+ * (³ÍÆÀ¤µ¤ì¤¿³ÆÎΰè¤Ï¡¤ÀèƬ¤Ë°Ê²¼¤Î¹½Â¤ÂΤò»ý¤Ã¤Æ¤¤¤ë)
+ */
+typedef struct _kzmem_block {
+ struct _kzmem_block *next;
+ int size;
+} kzmem_block;
+
+/* ¥á¥â¥ê¡¦¥×¡¼¥ë */
+typedef struct _kzmem_pool {
+ int size;
+ int num;
+ kzmem_block *free;
+} kzmem_pool;
+
+/* ¥á¥â¥ê¡¦¥×¡¼¥ë¤ÎÄêµÁ(¸Ä¡¹¤Î¥µ¥¤¥º¤È¸Ä¿ô) */
+static kzmem_pool pool[] = {
+ { 16, 8, NULL }, { 32, 8, NULL }, { 64, 4, NULL },
+};
+
+#define MEMORY_AREA_NUM (sizeof(pool) / sizeof(*pool))
+
+/* ¥á¥â¥ê¡¦¥×¡¼¥ë¤Î½é´ü²½ */
+static int kzmem_init_pool(kzmem_pool *p)
+{
+ int i;
+ kzmem_block *mp;
+ kzmem_block **mpp;
+ extern char freearea; /* ¥ê¥ó¥«¡¦¥¹¥¯¥ê¥×¥È¤ÇÄêµÁ¤µ¤ì¤ë¶õ¤Îΰè */
+ static char *area = &freearea;
+
+ mp = (kzmem_block *)area;
+
+ /* ¸Ä¡¹¤ÎÎΰè¤ò¤¹¤Ù¤Æ²òÊüºÑ¤ß¥ê¥ó¥¯¥ê¥¹¥È¤Ë·Ò¤° */
+ mpp = &p->free;
+ for (i = 0; i < p->num; i++) {
+ *mpp = mp;
+ memset(mp, 0, sizeof(*mp));
+ mp->size = p->size;
+ mpp = &(mp->next);
+ mp = (kzmem_block *)((char *)mp + p->size);
+ area += p->size;
+ }
+
+ return 0;
+}
+
+/* ưŪ¥á¥â¥ê¤Î½é´ü²½ */
+int kzmem_init(void)
+{
+ int i;
+ for (i = 0; i < MEMORY_AREA_NUM; i++) {
+ kzmem_init_pool(&pool[i]); /* ³Æ¥á¥â¥ê¡¦¥×¡¼¥ë¤ò½é´ü²½¤¹¤ë */
+ }
+ return 0;
+}
+
+/* ưŪ¥á¥â¥ê¤Î³ÍÆÀ */
+void *kzmem_alloc(int size)
+{
+ int i;
+ kzmem_block *mp;
+ kzmem_pool *p;
+
+ for (i = 0; i < MEMORY_AREA_NUM; i++) {
+ p = &pool[i];
+ if (size <= p->size - sizeof(kzmem_block)) {
+ if (p->free == NULL) { /* ²òÊüºÑ¤ßÎΰ褬̵¤¤(¥á¥â¥ê¡¦¥Ö¥í¥Ã¥¯ÉÔÂ) */
+ kz_sysdown();
+ return NULL;
+ }
+ /* ²òÊüºÑ¤ß¥ê¥ó¥¯¥ê¥¹¥È¤«¤éÎΰè¤ò¼èÆÀ¤¹¤ë */
+ mp = p->free;
+ p->free = p->free->next;
+ mp->next = NULL;
+
+ /*
+ * ¼ÂºÝ¤ËÍøÍѲÄǽ¤ÊÎΰè¤Ï¡¤¥á¥â¥ê¡¦¥Ö¥í¥Ã¥¯¹½Â¤ÂΤÎľ¸å¤ÎÎΰè¤Ë
+ * ¤Ê¤ë¤Î¤Ç¡¤Ä¾¸å¤Î¥¢¥É¥ì¥¹¤òÊÖ¤¹¡¥
+ */
+ return mp + 1;
+ }
+ }
+
+ /* »ØÄꤵ¤ì¤¿¥µ¥¤¥º¤ÎÎΰè¤ò³ÊǼ¤Ç¤¤ë¥á¥â¥ê¡¦¥×¡¼¥ë¤¬Ìµ¤¤ */
+ kz_sysdown();
+ return NULL;
+}
+
+/* ¥á¥â¥ê¤Î²òÊü */
+void kzmem_free(void *mem)
+{
+ int i;
+ kzmem_block *mp;
+ kzmem_pool *p;
+
+ /* Îΰè¤ÎľÁ°¤Ë¤¢¤ë(¤Ï¤º¤Î)¥á¥â¥ê¡¦¥Ö¥í¥Ã¥¯¹½Â¤ÂΤò¼èÆÀ */
+ mp = ((kzmem_block *)mem - 1);
+
+ for (i = 0; i < MEMORY_AREA_NUM; i++) {
+ p = &pool[i];
+ if (mp->size == p->size) {
+ /* Îΰè¤ò²òÊüºÑ¤ß¥ê¥ó¥¯¥ê¥¹¥È¤ËÌ᤹ */
+ mp->next = p->free;
+ p->free = mp;
+ return;
+ }
+ }
+
+ kz_sysdown();
+}
--- /dev/null
+#ifndef _KOZOS_MEMORY_H_INCLUDED_
+#define _KOZOS_MEMORY_H_INCLUDED_
+
+int kzmem_init(void); /* ưŪ¥á¥â¥ê¤Î½é´ü²½ */
+void *kzmem_alloc(int size); /* ưŪ¥á¥â¥ê¤Î³ÍÆÀ */
+void kzmem_free(void *mem); /* ¥á¥â¥ê¤Î²òÊü */
+
+#endif
--- /dev/null
+/*------------------------------------------------------------------------/\r
+/ Bitbanging MMCv3/SDv1/SDv2 (in SPI mode) control module for PFF\r
+/-------------------------------------------------------------------------/\r
+/\r
+/ Copyright (C) 2010, ChaN, all right reserved.\r
+/\r
+/ * This software is a free software and there is NO WARRANTY.\r
+/ * No restriction on use. You can use, modify and redistribute it for\r
+/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.\r
+/ * Redistributions of source code must retain the above copyright notice.\r
+/\r
+/--------------------------------------------------------------------------/\r
+ Features:\r
+\r
+ * Very Easy to Port\r
+ It uses only 4-6 bit of GPIO port. No interrupt, no SPI port is used.\r
+\r
+ * Platform Independent\r
+ You need to modify only a few macros to control GPIO ports.\r
+\r
+/-------------------------------------------------------------------------*/\r
+\r
+\r
+#include "diskio.h"\r
+\r
+#define H8_3069F_P4DR ((volatile uint8 *)0xFFFFD3)\r
+#define H8_3069F_PBDR ((volatile uint8 *)0xFFFFDA)\r
+\r
+#define PB_BIT_SCLK (1 << 5)\r
+#define PB_BIT_MOSI (1 << 6)\r
+#define PB_BIT_MISO (1 << 7)\r
+#define P4_BIT_CS (1 << 0)\r
+\r
+/*-------------------------------------------------------------------------*/\r
+/* Platform dependent macros and functions needed to be modified */\r
+/*-------------------------------------------------------------------------*/\r
+\r
+#define INIT_PORT() do { } while (0) /* Initialize MMC control port (CS/CLK/DI:output, DO:input) */\r
+#define DLY_US(n) do { volatile uint32 dlycnt; for (dlycnt = 0; dlycnt < (n) * 10; dlycnt++) {} } while (0) /* Delay n microseconds */\r
+#define FORWARD(d) do { } while (0) /* Data in-time processing function (depends on the project) */\r
+\r
+#define CS_H() do { *H8_3069F_P4DR |= P4_BIT_CS; } while (0) /* Set MMC CS "high" */\r
+#define CS_L() do { *H8_3069F_P4DR &= ~P4_BIT_CS; } while (0) /* Set MMC CS "low" */\r
+#define CK_H() do { *H8_3069F_PBDR |= PB_BIT_SCLK; } while (0) /* Set MMC SCLK "high" */\r
+#define CK_L() do { *H8_3069F_PBDR &= ~PB_BIT_SCLK; } while (0) /* Set MMC SCLK "low" */\r
+#define DI_H() do { *H8_3069F_PBDR |= PB_BIT_MOSI; } while (0) /* Set MMC DI "high" */\r
+#define DI_L() do { *H8_3069F_PBDR &= ~PB_BIT_MOSI; } while (0) /* Set MMC DI "low" */\r
+#define DO ((*H8_3069F_PBDR & PB_BIT_MISO) ? 1 : 0) /* Get MMC DO value (high:true, low:false) */\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Module Private Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+/* Definitions for MMC/SDC command */\r
+#define CMD0 (0x40+0) /* GO_IDLE_STATE */\r
+#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */\r
+#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */\r
+#define CMD8 (0x40+8) /* SEND_IF_COND */\r
+#define CMD16 (0x40+16) /* SET_BLOCKLEN */\r
+#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */\r
+#define CMD24 (0x40+24) /* WRITE_BLOCK */\r
+#define CMD55 (0x40+55) /* APP_CMD */\r
+#define CMD58 (0x40+58) /* READ_OCR */\r
+\r
+/* Card type flags (CardType) */\r
+#define CT_MMC 0x01 /* MMC ver 3 */\r
+#define CT_SD1 0x02 /* SD ver 1 */\r
+#define CT_SD2 0x04 /* SD ver 2 */\r
+#define CT_SDC (CT_SD1|CT_SD2) /* SD */\r
+#define CT_BLOCK 0x08 /* Block addressing */\r
+\r
+\r
+\r
+static\r
+BYTE CardType; /* b0:MMC, b1:SDv1, b2:SDv2, b3:Block addressing */\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Transmit a byte to the MMC (bitbanging) */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+void xmit_mmc (\r
+ BYTE d /* Data to be sent */\r
+)\r
+{\r
+ if (d & 0x80) DI_H(); else DI_L(); /* bit7 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x40) DI_H(); else DI_L(); /* bit6 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x20) DI_H(); else DI_L(); /* bit5 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x10) DI_H(); else DI_L(); /* bit4 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x08) DI_H(); else DI_L(); /* bit3 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x04) DI_H(); else DI_L(); /* bit2 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x02) DI_H(); else DI_L(); /* bit1 */\r
+ CK_H(); CK_L();\r
+ if (d & 0x01) DI_H(); else DI_L(); /* bit0 */\r
+ CK_H(); CK_L();\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Receive a byte from the MMC (bitbanging) */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+BYTE rcvr_mmc (void)\r
+{\r
+ BYTE r;\r
+\r
+\r
+ DI_H(); /* Send 0xFF */\r
+\r
+ r = 0; if (DO) r++; /* bit7 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit6 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit5 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit4 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit3 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit2 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit1 */\r
+ CK_H(); CK_L();\r
+ r <<= 1; if (DO) r++; /* bit0 */\r
+ CK_H(); CK_L();\r
+\r
+ return r;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Skip bytes on the MMC (bitbanging) */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+void skip_mmc (\r
+ WORD n /* Number of bytes to skip */\r
+)\r
+{\r
+ DI_H(); /* Send 0xFF */\r
+\r
+ do {\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ CK_H(); CK_L();\r
+ } while (--n);\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Deselect the card and release SPI bus */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+void release_spi (void)\r
+{\r
+ CS_H();\r
+ rcvr_mmc();\r
+}\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Send a command packet to MMC */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+BYTE send_cmd (\r
+ BYTE cmd, /* Command byte */\r
+ DWORD arg /* Argument */\r
+)\r
+{\r
+ BYTE n, res;\r
+\r
+\r
+ if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */\r
+ cmd &= 0x7F;\r
+ res = send_cmd(CMD55, 0);\r
+ if (res > 1) return res;\r
+ }\r
+\r
+ /* Select the card */\r
+ CS_H(); rcvr_mmc();\r
+ CS_L(); rcvr_mmc();\r
+\r
+ /* Send a command packet */\r
+ xmit_mmc(cmd); /* Start + Command index */\r
+ xmit_mmc((BYTE)(arg >> 24)); /* Argument[31..24] */\r
+ xmit_mmc((BYTE)(arg >> 16)); /* Argument[23..16] */\r
+ xmit_mmc((BYTE)(arg >> 8)); /* Argument[15..8] */\r
+ xmit_mmc((BYTE)arg); /* Argument[7..0] */\r
+ n = 0x01; /* Dummy CRC + Stop */\r
+ if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */\r
+ if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */\r
+ xmit_mmc(n);\r
+\r
+ /* Receive a command response */\r
+ n = 10; /* Wait for a valid response in timeout of 10 attempts */\r
+ do {\r
+ res = rcvr_mmc();\r
+ } while ((res & 0x80) && --n);\r
+\r
+ return res; /* Return with the response value */\r
+}\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Public Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Initialize Disk Drive */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+DSTATUS disk_initialize (void)\r
+{\r
+ BYTE n, cmd, ty, buf[4];\r
+ UINT tmr;\r
+\r
+\r
+ INIT_PORT();\r
+\r
+ CS_H();\r
+ skip_mmc(10); /* Dummy clocks */\r
+\r
+ ty = 0;\r
+ if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */\r
+ if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */\r
+ for (n = 0; n < 4; n++) buf[n] = rcvr_mmc(); /* Get trailing return value of R7 resp */\r
+ if (buf[2] == 0x01 && buf[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */\r
+ for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state (ACMD41 with HCS bit) */\r
+ if (send_cmd(ACMD41, 1UL << 30) == 0) break;\r
+ DLY_US(1000);\r
+ }\r
+ if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */\r
+ for (n = 0; n < 4; n++) buf[n] = rcvr_mmc();\r
+ ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */\r
+ }\r
+ }\r
+ } else { /* SDv1 or MMCv3 */\r
+ if (send_cmd(ACMD41, 0) <= 1) {\r
+ ty = CT_SD1; cmd = ACMD41; /* SDv1 */\r
+ } else {\r
+ ty = CT_MMC; cmd = CMD1; /* MMCv3 */\r
+ }\r
+ for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state */\r
+ if (send_cmd(ACMD41, 0) == 0) break;\r
+ DLY_US(1000);\r
+ }\r
+ if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */\r
+ ty = 0;\r
+ }\r
+ }\r
+ CardType = ty;\r
+ release_spi();\r
+\r
+ return ty ? 0 : STA_NOINIT;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read partial sector */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+DRESULT disk_readp (\r
+ BYTE *buff, /* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */\r
+ DWORD lba, /* Sector number (LBA) */\r
+ WORD ofs, /* Byte offset to read from (0..511) */\r
+ WORD cnt /* Number of bytes to read (ofs + cnt mus be <= 512) */\r
+)\r
+{\r
+ DRESULT res;\r
+ BYTE d;\r
+ WORD bc, tmr;\r
+\r
+\r
+ if (!(CardType & CT_BLOCK)) lba *= 512; /* Convert to byte address if needed */\r
+\r
+ res = RES_ERROR;\r
+ if (send_cmd(CMD17, lba) == 0) { /* READ_SINGLE_BLOCK */\r
+\r
+ tmr = 1000;\r
+ do { /* Wait for data packet in timeout of 100ms */\r
+ DLY_US(100);\r
+ d = rcvr_mmc();\r
+ } while (d == 0xFF && --tmr);\r
+\r
+ if (d == 0xFE) { /* A data packet arrived */\r
+ bc = 514 - ofs - cnt;\r
+\r
+ /* Skip leading bytes */\r
+ if (ofs) skip_mmc(ofs);\r
+\r
+ /* Receive a part of the sector */\r
+ if (buff) { /* Store data to the memory */\r
+ do\r
+ *buff++ = rcvr_mmc();\r
+ while (--cnt);\r
+ } else { /* Forward data to the outgoing stream */\r
+ do {\r
+ d = rcvr_mmc();\r
+ FORWARD(d);\r
+ } while (--cnt);\r
+ }\r
+\r
+ /* Skip trailing bytes and CRC */\r
+ skip_mmc(bc);\r
+\r
+ res = RES_OK;\r
+ }\r
+ }\r
+\r
+ release_spi();\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Write partial sector */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_WRITE\r
+\r
+DRESULT disk_writep (\r
+ const BYTE *buff, /* Pointer to the bytes to be written (NULL:Initiate/Finalize sector write) */\r
+ DWORD sa /* Number of bytes to send, Sector number (LBA) or zero */\r
+)\r
+{\r
+ DRESULT res;\r
+ WORD bc, tmr;\r
+ static WORD wc;\r
+\r
+\r
+ res = RES_ERROR;\r
+\r
+ if (buff) { /* Send data bytes */\r
+ bc = (WORD)sa;\r
+ while (bc && wc) { /* Send data bytes to the card */\r
+ xmit_mmc(*buff++);\r
+ wc--; bc--;\r
+ }\r
+ res = RES_OK;\r
+ } else {\r
+ if (sa) { /* Initiate sector write process */\r
+ if (!(CardType & CT_BLOCK)) sa *= 512; /* Convert to byte address if needed */\r
+ if (send_cmd(CMD24, sa) == 0) { /* WRITE_SINGLE_BLOCK */\r
+ xmit_mmc(0xFF); xmit_mmc(0xFE); /* Data block header */\r
+ wc = 512; /* Set byte counter */\r
+ res = RES_OK;\r
+ }\r
+ } else { /* Finalize sector write process */\r
+ bc = wc + 2;\r
+ while (bc--) xmit_mmc(0); /* Fill left bytes and CRC with zeros */\r
+ if ((rcvr_mmc() & 0x1F) == 0x05) { /* Receive data resp and wait for end of write process in timeout of 300ms */\r
+ for (tmr = 10000; rcvr_mmc() != 0xFF && tmr; tmr--) /* Wait for ready (max 1000ms) */\r
+ DLY_US(100);\r
+ if (tmr) res = RES_OK;\r
+ }\r
+ release_spi();\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+#endif\r
--- /dev/null
+/*----------------------------------------------------------------------------/\r
+/ Petit FatFs - FAT file system module R0.02a (C)ChaN, 2010\r
+/-----------------------------------------------------------------------------/\r
+/ Petit FatFs module is an open source software to implement FAT file system to\r
+/ small embedded systems. This is a free software and is opened for education,\r
+/ research and commercial developments under license policy of following trems.\r
+/\r
+/ Copyright (C) 2010, ChaN, all right reserved.\r
+/\r
+/ * The Petit FatFs module is a free software and there is NO WARRANTY.\r
+/ * No restriction on use. You can use, modify and redistribute it for\r
+/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.\r
+/ * Redistributions of source code must retain the above copyright notice.\r
+/\r
+/-----------------------------------------------------------------------------/\r
+/ Jun 15,'09 R0.01a First release. (Branched from FatFs R0.07b.)\r
+/\r
+/ Dec 14,'09 R0.02 Added multiple code page support.\r
+/ Added write funciton.\r
+/ Changed stream read mode interface.\r
+/ Dec 07,'10 R0.02a Added some configuration options.\r
+/ Fixed fails to open objects with DBCS character.\r
+/----------------------------------------------------------------------------*/\r
+\r
+#include "pff.h" /* Petit FatFs configurations and declarations */\r
+#include "diskio.h" /* Declarations of low level disk I/O functions */\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Module Private Definitions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+\r
+#if _FS_FAT32\r
+#define LD_CLUST(dir) (((DWORD)LD_WORD(dir+DIR_FstClusHI)<<16) | LD_WORD(dir+DIR_FstClusLO))\r
+#else\r
+#define LD_CLUST(dir) LD_WORD(dir+DIR_FstClusLO)\r
+#endif\r
+\r
+\r
+/*--------------------------------------------------------*/\r
+/* DBCS code ranges and SBCS extend char conversion table */\r
+\r
+#if _CODE_PAGE == 932 /* Japanese Shift-JIS */\r
+#define _DF1S 0x81 /* DBC 1st byte range 1 start */\r
+#define _DF1E 0x9F /* DBC 1st byte range 1 end */\r
+#define _DF2S 0xE0 /* DBC 1st byte range 2 start */\r
+#define _DF2E 0xFC /* DBC 1st byte range 2 end */\r
+#define _DS1S 0x40 /* DBC 2nd byte range 1 start */\r
+#define _DS1E 0x7E /* DBC 2nd byte range 1 end */\r
+#define _DS2S 0x80 /* DBC 2nd byte range 2 start */\r
+#define _DS2E 0xFC /* DBC 2nd byte range 2 end */\r
+\r
+#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x40\r
+#define _DS1E 0x7E\r
+#define _DS2S 0x80\r
+#define _DS2E 0xFE\r
+\r
+#elif _CODE_PAGE == 949 /* Korean */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x41\r
+#define _DS1E 0x5A\r
+#define _DS2S 0x61\r
+#define _DS2E 0x7A\r
+#define _DS3S 0x81\r
+#define _DS3E 0xFE\r
+\r
+#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x40\r
+#define _DS1E 0x7E\r
+#define _DS2S 0xA1\r
+#define _DS2E 0xFE\r
+\r
+#elif _CODE_PAGE == 437 /* U.S. (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 720 /* Arabic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 737 /* Greek (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \\r
+ 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 775 /* Baltic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \\r
+ 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \\r
+ 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 857 /* Turkish (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 862 /* Hebrew (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 866 /* Russian (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \\r
+ 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}\r
+\r
+#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1253 /* Greek (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \\r
+ 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}\r
+\r
+#elif _CODE_PAGE == 1254 /* Turkish (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1256 /* Arabic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1257 /* Baltic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */\r
+#define _DF1S 0\r
+\r
+#else\r
+#error Unknown code page\r
+\r
+#endif\r
+\r
+\r
+\r
+/* Character code support macros */\r
+\r
+#define IsUpper(c) (((c)>='A')&&((c)<='Z'))\r
+#define IsLower(c) (((c)>='a')&&((c)<='z'))\r
+\r
+#if _DF1S /* DBCS configuration */\r
+\r
+#ifdef _DF2S /* Two 1st byte areas */\r
+#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))\r
+#else /* One 1st byte area */\r
+#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)\r
+#endif\r
+\r
+#ifdef _DS3S /* Three 2nd byte areas */\r
+#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))\r
+#else /* Two 2nd byte areas */\r
+#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))\r
+#endif\r
+\r
+#else /* SBCS configuration */\r
+\r
+#define IsDBCS1(c) 0\r
+#define IsDBCS2(c) 0\r
+\r
+#endif /* _DF1S */\r
+\r
+\r
+/* FatFs refers the members in the FAT structures with byte offset instead\r
+/ of structure member because there are incompatibility of the packing option\r
+/ between various compilers. */\r
+\r
+#define BS_jmpBoot 0\r
+#define BS_OEMName 3\r
+#define BPB_BytsPerSec 11\r
+#define BPB_SecPerClus 13\r
+#define BPB_RsvdSecCnt 14\r
+#define BPB_NumFATs 16\r
+#define BPB_RootEntCnt 17\r
+#define BPB_TotSec16 19\r
+#define BPB_Media 21\r
+#define BPB_FATSz16 22\r
+#define BPB_SecPerTrk 24\r
+#define BPB_NumHeads 26\r
+#define BPB_HiddSec 28\r
+#define BPB_TotSec32 32\r
+#define BS_55AA 510\r
+\r
+#define BS_DrvNum 36\r
+#define BS_BootSig 38\r
+#define BS_VolID 39\r
+#define BS_VolLab 43\r
+#define BS_FilSysType 54\r
+\r
+#define BPB_FATSz32 36\r
+#define BPB_ExtFlags 40\r
+#define BPB_FSVer 42\r
+#define BPB_RootClus 44\r
+#define BPB_FSInfo 48\r
+#define BPB_BkBootSec 50\r
+#define BS_DrvNum32 64\r
+#define BS_BootSig32 66\r
+#define BS_VolID32 67\r
+#define BS_VolLab32 71\r
+#define BS_FilSysType32 82\r
+\r
+#define MBR_Table 446\r
+\r
+#define DIR_Name 0\r
+#define DIR_Attr 11\r
+#define DIR_NTres 12\r
+#define DIR_CrtTime 14\r
+#define DIR_CrtDate 16\r
+#define DIR_FstClusHI 20\r
+#define DIR_WrtTime 22\r
+#define DIR_WrtDate 24\r
+#define DIR_FstClusLO 26\r
+#define DIR_FileSize 28\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Private Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+\r
+static\r
+FATFS *FatFs; /* Pointer to the file system object (logical drive) */\r
+\r
+\r
+/* Fill memory */\r
+static\r
+void mem_set (void* dst, int val, int cnt) {\r
+ char *d = (char*)dst;\r
+ while (cnt--) *d++ = (char)val;\r
+}\r
+\r
+/* Compare memory to memory */\r
+static\r
+int mem_cmp (const void* dst, const void* src, int cnt) {\r
+ const char *d = (const char *)dst, *s = (const char *)src;\r
+ int r = 0;\r
+ while (cnt-- && (r = *d++ - *s++) == 0) ;\r
+ return r;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* FAT access - Read value of a FAT entry */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+CLUST get_fat ( /* 1:IO error, Else:Cluster status */\r
+ CLUST clst /* Cluster# to get the link information */\r
+)\r
+{\r
+ WORD wc, bc, ofs;\r
+ BYTE buf[4];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (clst < 2 || clst >= fs->n_fatent) /* Range check */\r
+ return 1;\r
+\r
+ switch (fs->fs_type) {\r
+#if _FS_FAT12\r
+ case FS_FAT12 :\r
+ bc = (WORD)clst; bc += bc / 2;\r
+ ofs = bc % 512; bc /= 512;\r
+ if (ofs != 511) {\r
+ if (disk_readp(buf, fs->fatbase + bc, ofs, 2)) break;\r
+ } else {\r
+ if (disk_readp(buf, fs->fatbase + bc, 511, 1)) break;\r
+ if (disk_readp(buf+1, fs->fatbase + bc + 1, 0, 1)) break;\r
+ }\r
+ wc = LD_WORD(buf);\r
+ return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);\r
+#endif\r
+ case FS_FAT16 :\r
+ if (disk_readp(buf, fs->fatbase + clst / 256, (WORD)(((WORD)clst % 256) * 2), 2)) break;\r
+ return LD_WORD(buf);\r
+#if _FS_FAT32\r
+ case FS_FAT32 :\r
+ if (disk_readp(buf, fs->fatbase + clst / 128, (WORD)(((WORD)clst % 128) * 4), 4)) break;\r
+ return LD_DWORD(buf) & 0x0FFFFFFF;\r
+#endif\r
+ }\r
+\r
+ return 1; /* An error occured at the disk I/O layer */\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Get sector# from cluster# */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */\r
+ CLUST clst /* Cluster# to be converted */\r
+)\r
+{\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ clst -= 2;\r
+ if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */\r
+ return (DWORD)clst * fs->csize + fs->database;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Rewind directory index */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_rewind (\r
+ DIR *dj /* Pointer to directory object */\r
+)\r
+{\r
+ CLUST clst;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ dj->index = 0;\r
+ clst = dj->sclust;\r
+ if (clst == 1 || clst >= fs->n_fatent) /* Check start cluster range */\r
+ return FR_DISK_ERR;\r
+ if (_FS_FAT32 && !clst && fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */\r
+ clst = (CLUST)fs->dirbase;\r
+ dj->clust = clst; /* Current cluster */\r
+ dj->sect = clst ? clust2sect(clst) : fs->dirbase; /* Current sector */\r
+\r
+ return FR_OK; /* Seek succeeded */\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Move directory index next */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table */\r
+ DIR *dj /* Pointer to directory object */\r
+)\r
+{\r
+ CLUST clst;\r
+ WORD i;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ i = dj->index + 1;\r
+ if (!i || !dj->sect) /* Report EOT when index has reached 65535 */\r
+ return FR_NO_FILE;\r
+\r
+ if (!(i % 16)) { /* Sector changed? */\r
+ dj->sect++; /* Next sector */\r
+\r
+ if (dj->clust == 0) { /* Static table */\r
+ if (i >= fs->n_rootdir) /* Report EOT when end of table */\r
+ return FR_NO_FILE;\r
+ }\r
+ else { /* Dynamic table */\r
+ if (((i / 16) & (fs->csize-1)) == 0) { /* Cluster changed? */\r
+ clst = get_fat(dj->clust); /* Get next cluster */\r
+ if (clst <= 1) return FR_DISK_ERR;\r
+ if (clst >= fs->n_fatent) /* When it reached end of dynamic table */\r
+ return FR_NO_FILE; /* Report EOT */\r
+ dj->clust = clst; /* Initialize data for new cluster */\r
+ dj->sect = clust2sect(clst);\r
+ }\r
+ }\r
+ }\r
+\r
+ dj->index = i;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Find an object in the directory */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_find (\r
+ DIR *dj, /* Pointer to the directory object linked to the file name */\r
+ BYTE *dir /* 32-byte working buffer */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE c;\r
+\r
+\r
+ res = dir_rewind(dj); /* Rewind directory object */\r
+ if (res != FR_OK) return res;\r
+\r
+ do {\r
+ res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */\r
+ ? FR_DISK_ERR : FR_OK;\r
+ if (res != FR_OK) break;\r
+ c = dir[DIR_Name]; /* First character */\r
+ if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */\r
+ if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */\r
+ break;\r
+ res = dir_next(dj); /* Next entry */\r
+ } while (res == FR_OK);\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read an object from the directory */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_DIR\r
+static\r
+FRESULT dir_read (\r
+ DIR *dj, /* Pointer to the directory object to store read object name */\r
+ BYTE *dir /* 32-byte working buffer */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE a, c;\r
+\r
+\r
+ res = FR_NO_FILE;\r
+ while (dj->sect) {\r
+ res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */\r
+ ? FR_DISK_ERR : FR_OK;\r
+ if (res != FR_OK) break;\r
+ c = dir[DIR_Name];\r
+ if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */\r
+ a = dir[DIR_Attr] & AM_MASK;\r
+ if (c != 0xE5 && c != '.' && !(a & AM_VOL)) /* Is it a valid entry? */\r
+ break;\r
+ res = dir_next(dj); /* Next entry */\r
+ if (res != FR_OK) break;\r
+ }\r
+\r
+ if (res != FR_OK) dj->sect = 0;\r
+\r
+ return res;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Pick a segment and create the object name in directory form */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+#ifdef _EXCVT\r
+ static const BYTE cvt[] = _EXCVT;\r
+#endif\r
+\r
+static\r
+FRESULT create_name (\r
+ DIR *dj, /* Pointer to the directory object */\r
+ const char **path /* Pointer to pointer to the segment in the path string */\r
+)\r
+{\r
+ BYTE c, d, ni, si, i, *sfn;\r
+ const char *p;\r
+\r
+ /* Create file name in directory form */\r
+ sfn = dj->fn;\r
+ mem_set(sfn, ' ', 11);\r
+ si = i = 0; ni = 8;\r
+ p = *path;\r
+ for (;;) {\r
+ c = p[si++];\r
+ if (c <= ' ' || c == '/') break; /* Break on end of segment */\r
+ if (c == '.' || i >= ni) {\r
+ if (ni != 8 || c != '.') break;\r
+ i = 8; ni = 11;\r
+ continue;\r
+ }\r
+#ifdef _EXCVT\r
+ if (c >= 0x80) /* To upper extended char (SBCS) */\r
+ c = cvt[c - 0x80];\r
+#endif\r
+ if (IsDBCS1(c) && i < ni - 1) { /* DBC 1st byte? */\r
+ d = p[si++]; /* Get 2nd byte */\r
+ sfn[i++] = c;\r
+ sfn[i++] = d;\r
+ } else { /* Single byte code */\r
+ if (IsLower(c)) c -= 0x20; /* toupper */\r
+ sfn[i++] = c;\r
+ }\r
+ }\r
+ *path = &p[si]; /* Rerurn pointer to the next segment */\r
+\r
+ sfn[11] = (c <= ' ') ? 1 : 0; /* Set last segment flag if end of path */\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Get file information from directory entry */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_DIR\r
+static\r
+void get_fileinfo ( /* No return code */\r
+ DIR *dj, /* Pointer to the directory object */\r
+ BYTE *dir, /* 32-byte working buffer */\r
+ FILINFO *fno /* Pointer to store the file information */\r
+)\r
+{\r
+ BYTE i, c;\r
+ char *p;\r
+\r
+\r
+ p = fno->fname;\r
+ if (dj->sect) {\r
+ for (i = 0; i < 8; i++) { /* Copy file name body */\r
+ c = dir[i];\r
+ if (c == ' ') break;\r
+ if (c == 0x05) c = 0xE5;\r
+ *p++ = c;\r
+ }\r
+ if (dir[8] != ' ') { /* Copy file name extension */\r
+ *p++ = '.';\r
+ for (i = 8; i < 11; i++) {\r
+ c = dir[i];\r
+ if (c == ' ') break;\r
+ *p++ = c;\r
+ }\r
+ }\r
+ fno->fattrib = dir[DIR_Attr]; /* Attribute */\r
+ fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */\r
+ fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */\r
+ fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */\r
+ }\r
+ *p = 0;\r
+}\r
+#endif /* _USE_DIR */\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Follow a file path */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */\r
+ DIR *dj, /* Directory object to return last directory and found object */\r
+ BYTE *dir, /* 32-byte working buffer */\r
+ const char *path /* Full-path string to find a file or directory */\r
+)\r
+{\r
+ FRESULT res;\r
+\r
+\r
+ while (*path == ' ') path++; /* Skip leading spaces */\r
+ if (*path == '/') path++; /* Strip heading separator */\r
+ dj->sclust = 0; /* Set start directory (always root dir) */\r
+\r
+ if ((BYTE)*path <= ' ') { /* Null path means the root directory */\r
+ res = dir_rewind(dj);\r
+ dir[0] = 0;\r
+\r
+ } else { /* Follow path */\r
+ for (;;) {\r
+ res = create_name(dj, &path); /* Get a segment */\r
+ if (res != FR_OK) break;\r
+ res = dir_find(dj, dir); /* Find it */\r
+ if (res != FR_OK) { /* Could not find the object */\r
+ if (res == FR_NO_FILE && !*(dj->fn+11))\r
+ res = FR_NO_PATH;\r
+ break;\r
+ }\r
+ if (*(dj->fn+11)) break; /* Last segment match. Function completed. */\r
+ if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */\r
+ res = FR_NO_PATH; break;\r
+ }\r
+ dj->sclust = LD_CLUST(dir);\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Check a sector if it is an FAT boot record */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */\r
+ BYTE *buf, /* Working buffer */\r
+ DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */\r
+)\r
+{\r
+ if (disk_readp(buf, sect, 510, 2)) /* Read the boot sector */\r
+ return 3;\r
+ if (LD_WORD(buf) != 0xAA55) /* Check record signature */\r
+ return 2;\r
+\r
+ if (!disk_readp(buf, sect, BS_FilSysType, 2) && LD_WORD(buf) == 0x4146) /* Check FAT12/16 */\r
+ return 0;\r
+ if (_FS_FAT32 && !disk_readp(buf, sect, BS_FilSysType32, 2) && LD_WORD(buf) == 0x4146) /* Check FAT32 */\r
+ return 0;\r
+ return 1;\r
+}\r
+\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Public Functions\r
+\r
+--------------------------------------------------------------------------*/\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Mount/Unmount a Locical Drive */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT pf_mount (\r
+ FATFS *fs /* Pointer to new file system object (NULL: Unmount) */\r
+)\r
+{\r
+ BYTE fmt, buf[36];\r
+ DWORD bsect, fsize, tsect, mclst;\r
+\r
+\r
+ FatFs = 0;\r
+ if (!fs) return FR_OK; /* Unregister fs object */\r
+\r
+ if (disk_initialize() & STA_NOINIT) /* Check if the drive is ready or not */\r
+ return FR_NOT_READY;\r
+\r
+ /* Search FAT partition on the drive */\r
+ bsect = 0;\r
+ fmt = check_fs(buf, bsect); /* Check sector 0 as an SFD format */\r
+ if (fmt == 1) { /* Not an FAT boot record, it may be FDISK format */\r
+ /* Check a partition listed in top of the partition table */\r
+ if (disk_readp(buf, bsect, MBR_Table, 16)) { /* 1st partition entry */\r
+ fmt = 3;\r
+ } else {\r
+ if (buf[4]) { /* Is the partition existing? */\r
+ bsect = LD_DWORD(&buf[8]); /* Partition offset in LBA */\r
+ fmt = check_fs(buf, bsect); /* Check the partition */\r
+ }\r
+ }\r
+ }\r
+ if (fmt == 3) return FR_DISK_ERR;\r
+ if (fmt) return FR_NO_FILESYSTEM; /* No valid FAT patition is found */\r
+\r
+ /* Initialize the file system object */\r
+ if (disk_readp(buf, bsect, 13, sizeof(buf))) return FR_DISK_ERR;\r
+\r
+ fsize = LD_WORD(buf+BPB_FATSz16-13); /* Number of sectors per FAT */\r
+ if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13);\r
+\r
+ fsize *= buf[BPB_NumFATs-13]; /* Number of sectors in FAT area */\r
+ fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */\r
+ fs->csize = buf[BPB_SecPerClus-13]; /* Number of sectors per cluster */\r
+ fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13); /* Nmuber of root directory entries */\r
+ tsect = LD_WORD(buf+BPB_TotSec16-13); /* Number of sectors on the file system */\r
+ if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13);\r
+ mclst = (tsect /* Last cluster# + 1 */\r
+ - LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16\r
+ ) / fs->csize + 2;\r
+ fs->n_fatent = (CLUST)mclst;\r
+\r
+ fmt = FS_FAT16; /* Determine the FAT sub type */\r
+ if (mclst < 0xFF7) /* Number of clusters < 0xFF5 */\r
+#if _FS_FAT12\r
+ fmt = FS_FAT12;\r
+#else\r
+ return FR_NO_FILESYSTEM;\r
+#endif\r
+ if (mclst >= 0xFFF7) /* Number of clusters >= 0xFFF5 */\r
+#if _FS_FAT32\r
+ fmt = FS_FAT32;\r
+#else\r
+ return FR_NO_FILESYSTEM;\r
+#endif\r
+\r
+ fs->fs_type = fmt; /* FAT sub-type */\r
+ if (_FS_FAT32 && fmt == FS_FAT32)\r
+ fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13)); /* Root directory start cluster */\r
+ else\r
+ fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */\r
+ fs->database = fs->fatbase + fsize + fs->n_rootdir / 16; /* Data start sector (lba) */\r
+\r
+ fs->flag = 0;\r
+ FatFs = fs;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Open or Create a File */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT pf_open (\r
+ const char *path /* Pointer to the file name */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj;\r
+ BYTE sp[12], dir[32];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) /* Check file system */\r
+ return FR_NOT_ENABLED;\r
+\r
+ fs->flag = 0;\r
+ dj.fn = sp;\r
+ res = follow_path(&dj, dir, path); /* Follow the file path */\r
+ if (res != FR_OK) return res; /* Follow failed */\r
+ if (!dir[0] || (dir[DIR_Attr] & AM_DIR)) /* It is a directory */\r
+ return FR_NO_FILE;\r
+\r
+ fs->org_clust = LD_CLUST(dir); /* File start cluster */\r
+ fs->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */\r
+ fs->fptr = 0; /* File pointer */\r
+ fs->flag = FA_OPENED;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read File */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_READ\r
+\r
+FRESULT pf_read (\r
+ void* buff, /* Pointer to the read buffer (NULL:Forward data to the stream)*/\r
+ WORD btr, /* Number of bytes to read */\r
+ WORD* br /* Pointer to number of bytes read */\r
+)\r
+{\r
+ DRESULT dr;\r
+ CLUST clst;\r
+ DWORD sect, remain;\r
+ WORD rcnt;\r
+ BYTE cs, *rbuff = buff;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ *br = 0;\r
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */\r
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */\r
+ return FR_NOT_OPENED;\r
+\r
+ remain = fs->fsize - fs->fptr;\r
+ if (btr > remain) btr = (WORD)remain; /* Truncate btr by remaining bytes */\r
+\r
+ while (btr) { /* Repeat until all data transferred */\r
+ if ((fs->fptr % 512) == 0) { /* On the sector boundary? */\r
+ cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */\r
+ if (!cs) { /* On the cluster boundary? */\r
+ clst = (fs->fptr == 0) ? /* On the top of the file? */\r
+ fs->org_clust : get_fat(fs->curr_clust);\r
+ if (clst <= 1) goto fr_abort;\r
+ fs->curr_clust = clst; /* Update current cluster */\r
+ }\r
+ sect = clust2sect(fs->curr_clust); /* Get current sector */\r
+ if (!sect) goto fr_abort;\r
+ fs->dsect = sect + cs;\r
+ }\r
+ rcnt = (WORD)(512 - (fs->fptr % 512)); /* Get partial sector data from sector buffer */\r
+ if (rcnt > btr) rcnt = btr;\r
+ dr = disk_readp(!buff ? 0 : rbuff, fs->dsect, (WORD)(fs->fptr % 512), rcnt);\r
+ if (dr) goto fr_abort;\r
+ fs->fptr += rcnt; rbuff += rcnt; /* Update pointers and counters */\r
+ btr -= rcnt; *br += rcnt;\r
+ }\r
+\r
+ return FR_OK;\r
+\r
+fr_abort:\r
+ fs->flag = 0;\r
+ return FR_DISK_ERR;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Write File */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_WRITE\r
+\r
+FRESULT pf_write (\r
+ const void* buff, /* Pointer to the data to be written */\r
+ WORD btw, /* Number of bytes to write (0:Finalize the current write operation) */\r
+ WORD* bw /* Pointer to number of bytes written */\r
+)\r
+{\r
+ CLUST clst;\r
+ DWORD sect, remain;\r
+ const BYTE *p = buff;\r
+ BYTE cs;\r
+ WORD wcnt;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ *bw = 0;\r
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */\r
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */\r
+ return FR_NOT_OPENED;\r
+\r
+ if (!btw) { /* Finalize request */\r
+ if ((fs->flag & FA__WIP) && disk_writep(0, 0)) goto fw_abort;\r
+ fs->flag &= ~FA__WIP;\r
+ return FR_OK;\r
+ } else { /* Write data request */\r
+ if (!(fs->flag & FA__WIP)) /* Round-down fptr to the sector boundary */\r
+ fs->fptr &= 0xFFFFFE00;\r
+ }\r
+ remain = fs->fsize - fs->fptr;\r
+ if (btw > remain) btw = (WORD)remain; /* Truncate btw by remaining bytes */\r
+\r
+ while (btw) { /* Repeat until all data transferred */\r
+ if (((WORD)fs->fptr % 512) == 0) { /* On the sector boundary? */\r
+ cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */\r
+ if (!cs) { /* On the cluster boundary? */\r
+ clst = (fs->fptr == 0) ? /* On the top of the file? */\r
+ fs->org_clust : get_fat(fs->curr_clust);\r
+ if (clst <= 1) goto fw_abort;\r
+ fs->curr_clust = clst; /* Update current cluster */\r
+ }\r
+ sect = clust2sect(fs->curr_clust); /* Get current sector */\r
+ if (!sect) goto fw_abort;\r
+ fs->dsect = sect + cs;\r
+ if (disk_writep(0, fs->dsect)) goto fw_abort; /* Initiate a sector write operation */\r
+ fs->flag |= FA__WIP;\r
+ }\r
+ wcnt = 512 - ((WORD)fs->fptr % 512); /* Number of bytes to write to the sector */\r
+ if (wcnt > btw) wcnt = btw;\r
+ if (disk_writep(p, wcnt)) goto fw_abort; /* Send data to the sector */\r
+ fs->fptr += wcnt; p += wcnt; /* Update pointers and counters */\r
+ btw -= wcnt; *bw += wcnt;\r
+ if (((WORD)fs->fptr % 512) == 0) {\r
+ if (disk_writep(0, 0)) goto fw_abort; /* Finalize the currtent secter write operation */\r
+ fs->flag &= ~FA__WIP;\r
+ }\r
+ }\r
+\r
+ return FR_OK;\r
+\r
+fw_abort:\r
+ fs->flag = 0;\r
+ return FR_DISK_ERR;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Seek File R/W Pointer */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_LSEEK\r
+\r
+FRESULT pf_lseek (\r
+ DWORD ofs /* File pointer from top of file */\r
+)\r
+{\r
+ CLUST clst;\r
+ DWORD bcs, sect, ifptr;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */\r
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */\r
+ return FR_NOT_OPENED;\r
+\r
+ if (ofs > fs->fsize) ofs = fs->fsize; /* Clip offset with the file size */\r
+ ifptr = fs->fptr;\r
+ fs->fptr = 0;\r
+ if (ofs > 0) {\r
+ bcs = (DWORD)fs->csize * 512; /* Cluster size (byte) */\r
+ if (ifptr > 0 &&\r
+ (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */\r
+ fs->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */\r
+ ofs -= fs->fptr;\r
+ clst = fs->curr_clust;\r
+ } else { /* When seek to back cluster, */\r
+ clst = fs->org_clust; /* start from the first cluster */\r
+ fs->curr_clust = clst;\r
+ }\r
+ while (ofs > bcs) { /* Cluster following loop */\r
+ clst = get_fat(clst); /* Follow cluster chain */\r
+ if (clst <= 1 || clst >= fs->n_fatent) goto fe_abort;\r
+ fs->curr_clust = clst;\r
+ fs->fptr += bcs;\r
+ ofs -= bcs;\r
+ }\r
+ fs->fptr += ofs;\r
+ sect = clust2sect(clst); /* Current sector */\r
+ if (!sect) goto fe_abort;\r
+ fs->dsect = sect + (fs->fptr / 512 & (fs->csize - 1));\r
+ }\r
+\r
+ return FR_OK;\r
+\r
+fe_abort:\r
+ fs->flag = 0;\r
+ return FR_DISK_ERR;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Create a Directroy Object */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_DIR\r
+\r
+FRESULT pf_opendir (\r
+ DIR *dj, /* Pointer to directory object to create */\r
+ const char *path /* Pointer to the directory path */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE sp[12], dir[32];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) { /* Check file system */\r
+ res = FR_NOT_ENABLED;\r
+ } else {\r
+ dj->fn = sp;\r
+ res = follow_path(dj, dir, path); /* Follow the path to the directory */\r
+ if (res == FR_OK) { /* Follow completed */\r
+ if (dir[0]) { /* It is not the root dir */\r
+ if (dir[DIR_Attr] & AM_DIR) /* The object is a directory */\r
+ dj->sclust = LD_CLUST(dir);\r
+ else /* The object is not a directory */\r
+ res = FR_NO_PATH;\r
+ }\r
+ if (res == FR_OK)\r
+ res = dir_rewind(dj); /* Rewind dir */\r
+ }\r
+ if (res == FR_NO_FILE) res = FR_NO_PATH;\r
+ }\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read Directory Entry in Sequense */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT pf_readdir (\r
+ DIR *dj, /* Pointer to the open directory object */\r
+ FILINFO *fno /* Pointer to file information to return */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE sp[12], dir[32];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) { /* Check file system */\r
+ res = FR_NOT_ENABLED;\r
+ } else {\r
+ dj->fn = sp;\r
+ if (!fno) {\r
+ res = dir_rewind(dj);\r
+ } else {\r
+ res = dir_read(dj, dir);\r
+ if (res == FR_NO_FILE) {\r
+ dj->sect = 0;\r
+ res = FR_OK;\r
+ }\r
+ if (res == FR_OK) { /* A valid entry is found */\r
+ get_fileinfo(dj, dir, fno); /* Get the object information */\r
+ res = dir_next(dj); /* Increment index for next */\r
+ if (res == FR_NO_FILE) {\r
+ dj->sect = 0;\r
+ res = FR_OK;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+\r
+#endif /* _USE_DIR */\r
+\r
--- /dev/null
+/*---------------------------------------------------------------------------/\r
+/ Petit FatFs - FAT file system module include file R0.02a (C)ChaN, 2010\r
+/----------------------------------------------------------------------------/\r
+/ Petit FatFs module is an open source software to implement FAT file system to\r
+/ small embedded systems. This is a free software and is opened for education,\r
+/ research and commercial developments under license policy of following trems.\r
+/\r
+/ Copyright (C) 2010, ChaN, all right reserved.\r
+/\r
+/ * The Petit FatFs module is a free software and there is NO WARRANTY.\r
+/ * No restriction on use. You can use, modify and redistribute it for\r
+/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.\r
+/ * Redistributions of source code must retain the above copyright notice.\r
+/\r
+/----------------------------------------------------------------------------*/\r
+\r
+#include "integer.h"\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Petit FatFs Configuration Options\r
+/\r
+/ CAUTION! Do not forget to make clean the project after any changes to\r
+/ the configuration options.\r
+/\r
+/----------------------------------------------------------------------------*/\r
+#ifndef _FATFS\r
+#define _FATFS\r
+\r
+#define _USE_READ 1 /* 1:Enable pf_read() */\r
+\r
+#define _USE_DIR 1 /* 1:Enable pf_opendir() and pf_readdir() */\r
+\r
+#define _USE_LSEEK 1 /* 1:Enable pf_lseek() */\r
+\r
+#define _USE_WRITE 1 /* 1:Enable pf_write() */\r
+\r
+#define _FS_FAT12 1 /* 1:Enable FAT12 support */\r
+#define _FS_FAT32 1 /* 1:Enable FAT32 support */\r
+\r
+\r
+#define _CODE_PAGE 1\r
+/* Defines which code page is used for path name. Supported code pages are:\r
+/ 932, 936, 949, 950, 437, 720, 737, 775, 850, 852, 855, 857, 858, 862, 866,\r
+/ 874, 1250, 1251, 1252, 1253, 1254, 1255, 1257, 1258 and 1 (ASCII only).\r
+/ SBCS code pages except for 1 requiers a case conversion table. This\r
+/ might occupy 128 bytes on the RAM on some platforms, e.g. avr-gcc. */\r
+\r
+\r
+#define _WORD_ACCESS 0\r
+/* The _WORD_ACCESS option defines which access method is used to the word\r
+/ data in the FAT structure.\r
+/\r
+/ 0: Byte-by-byte access. Always compatible with all platforms.\r
+/ 1: Word access. Do not choose this unless following condition is met.\r
+/\r
+/ When the byte order on the memory is big-endian or address miss-aligned\r
+/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.\r
+/ If it is not the case, the value can also be set to 1 to improve the\r
+/ performance and code efficiency. */\r
+\r
+\r
+/* End of configuration options. Do not change followings without care. */\r
+/*--------------------------------------------------------------------------*/\r
+\r
+\r
+\r
+#if _FS_FAT32\r
+#define CLUST DWORD\r
+#else\r
+#define CLUST WORD\r
+#endif\r
+\r
+\r
+/* File system object structure */\r
+\r
+typedef struct {\r
+ BYTE fs_type; /* FAT sub type */\r
+ BYTE flag; /* File status flags */\r
+ BYTE csize; /* Number of sectors per cluster */\r
+ BYTE pad1;\r
+ WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */\r
+ CLUST n_fatent; /* Number of FAT entries (= number of clusters + 2) */\r
+ DWORD fatbase; /* FAT start sector */\r
+ DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */\r
+ DWORD database; /* Data start sector */\r
+ DWORD fptr; /* File R/W pointer */\r
+ DWORD fsize; /* File size */\r
+ CLUST org_clust; /* File start cluster */\r
+ CLUST curr_clust; /* File current cluster */\r
+ DWORD dsect; /* File current data sector */\r
+} FATFS;\r
+\r
+/* Directory object structure */\r
+\r
+typedef struct {\r
+ WORD index; /* Current read/write index number */\r
+ BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */\r
+ CLUST sclust; /* Table start cluster (0:Static table) */\r
+ CLUST clust; /* Current cluster */\r
+ DWORD sect; /* Current sector */\r
+} DIR;\r
+\r
+/* File status structure */\r
+\r
+typedef struct {\r
+ DWORD fsize; /* File size */\r
+ WORD fdate; /* Last modified date */\r
+ WORD ftime; /* Last modified time */\r
+ BYTE fattrib; /* Attribute */\r
+ char fname[13]; /* File name */\r
+} FILINFO;\r
+\r
+\r
+\r
+/* File function return code (FRESULT) */\r
+\r
+typedef enum {\r
+ FR_OK = 0, /* 0 */\r
+ FR_DISK_ERR, /* 1 */\r
+ FR_NOT_READY, /* 2 */\r
+ FR_NO_FILE, /* 3 */\r
+ FR_NO_PATH, /* 4 */\r
+ FR_NOT_OPENED, /* 5 */\r
+ FR_NOT_ENABLED, /* 6 */\r
+ FR_NO_FILESYSTEM /* 7 */\r
+} FRESULT;\r
+\r
+\r
+\r
+/*--------------------------------------------------------------*/\r
+/* Petit FatFs module application interface */\r
+\r
+FRESULT pf_mount (FATFS*); /* Mount/Unmount a logical drive */\r
+FRESULT pf_open (const char*); /* Open a file */\r
+FRESULT pf_read (void*, WORD, WORD*); /* Read data from the open file */\r
+FRESULT pf_write (const void*, WORD, WORD*); /* Write data to the open file */\r
+FRESULT pf_lseek (DWORD); /* Move file pointer of the open file */\r
+FRESULT pf_opendir (DIR*, const char*); /* Open a directory */\r
+FRESULT pf_readdir (DIR*, FILINFO*); /* Read a directory item from the open directory */\r
+\r
+\r
+\r
+/*--------------------------------------------------------------*/\r
+/* Flags and offset address */\r
+\r
+/* File status flag (FATFS.flag) */\r
+\r
+#define FA_OPENED 0x01\r
+#define FA_WPRT 0x02\r
+#define FA__WIP 0x40\r
+\r
+\r
+/* FAT sub type (FATFS.fs_type) */\r
+\r
+#define FS_FAT12 1\r
+#define FS_FAT16 2\r
+#define FS_FAT32 3\r
+\r
+\r
+/* File attribute bits for directory entry */\r
+\r
+#define AM_RDO 0x01 /* Read only */\r
+#define AM_HID 0x02 /* Hidden */\r
+#define AM_SYS 0x04 /* System */\r
+#define AM_VOL 0x08 /* Volume label */\r
+#define AM_LFN 0x0F /* LFN entry */\r
+#define AM_DIR 0x10 /* Directory */\r
+#define AM_ARC 0x20 /* Archive */\r
+#define AM_MASK 0x3F /* Mask of defined bits */\r
+\r
+\r
+/*--------------------------------*/\r
+/* Multi-byte word access macros */\r
+\r
+#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */\r
+#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))\r
+#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))\r
+#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)\r
+#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)\r
+#else /* Use byte-by-byte access to the FAT structure */\r
+#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))\r
+#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))\r
+#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)\r
+#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)\r
+#endif\r
+\r
+\r
+#endif /* _FATFS */\r
--- /dev/null
+#include "re.h"
+
+#define H8_3069F_TMDR ((volatile uint8 *)0xFFFF62)
+#define H8_3069F_TSTR ((volatile uint8 *)0xFFFF60)
+#define H8_3069F_16TCNT2H ((volatile uint8 *)0xFFFF7A)
+#define H8_3069F_16TCNT2L ((volatile uint8 *)0xFFFF7B)
+
+#define TMDR_BIT_MDF (1 << 6)
+#define TSTR_BIT_STR2 (1 << 2)
+
+int re_init(void)
+{
+ *H8_3069F_TMDR |= TMDR_BIT_MDF;
+ *H8_3069F_TSTR |= TSTR_BIT_STR2;
+
+ return 0;
+}
+
+uint16 re_read(void)
+{
+ return ((*H8_3069F_16TCNT2H) << 8) | (*H8_3069F_16TCNT2L << 0);
+}
+
--- /dev/null
+#ifndef _RE_H_INCLUDED_
+#define _RE_H_INCLUDED_
+
+#include "defines.h"
+
+int re_init(void);
+uint16 re_read(void);
+
+#endif
+
--- /dev/null
+#include "remocon.h"
+#include "defines.h"
+#include "kozos.h"
+#include "intr.h"
+#include "led.h"
+#include "lib.h"
+#include "consdrv.h"
+
+#define H8_3069F_ISCR ((volatile uint8 *)0xFEE014)
+#define H8_3069F_IER ((volatile uint8 *)0xFEE015)
+#define H8_3069F_ISR ((volatile uint8 *)0xFEE016)
+
+#define H8_3069F_TSTR ((volatile uint8 *)0xFFFF60)
+#define H8_3069F_TISRC ((volatile uint8 *)0xFFFF66)
+#define H8_3069F_16TCR0 ((volatile uint8 *)0xFFFF68)
+#define H8_3069F_TIOR0 ((volatile uint8 *)0xFFFF69)
+#define H8_3069F_16TCNT0H ((volatile uint8 *)0xFFFF6A)
+#define H8_3069F_16TCNT0L ((volatile uint8 *)0xFFFF6B)
+
+#define MAX_BIT_COUNT (64)
+
+typedef enum {
+ WaitLeader,
+ FoundLeader,
+ Receiving,
+ Received
+} ir_state_t;
+
+static uint16 bitcnt = 0;
+static uint16 tmrovf = 0;
+static uint8 data[MAX_BIT_COUNT / 8];
+static ir_state_t irs = WaitLeader;
+
+static void remocon_intr_edge(void)
+{
+ switch (irs) {
+ case WaitLeader:
+ *H8_3069F_16TCNT0H = 0;
+ *H8_3069F_16TCNT0L = 0;
+ *H8_3069F_TSTR |= (1 << 0);
+ bitcnt = 0;
+ tmrovf = 0;
+ irs = FoundLeader;
+ break;
+ case FoundLeader:
+ *H8_3069F_16TCNT0H = 0;
+ *H8_3069F_16TCNT0L = 0;
+ irs = Receiving;
+ break;
+ case Receiving:
+ if (bitcnt < MAX_BIT_COUNT) {
+ if ((bitcnt % 8) == 0) {
+ data[bitcnt / 8] = 0;
+ }
+ uint16 tmrval =
+ ((*H8_3069F_16TCNT0H) << 8) |
+ ((*H8_3069F_16TCNT0L) << 0);
+ if (tmrval > 0x1077) {
+ data[bitcnt / 8] |= (1 << (bitcnt % 8));
+ }
+ bitcnt++;
+ }
+ *H8_3069F_16TCNT0H = 0;
+ *H8_3069F_16TCNT0L = 0;
+ if (32 <= bitcnt) {
+ irs = Received;
+ }
+ break;
+ case Received:
+ break;
+ default:
+ break;
+ }
+
+}
+
+static void remocon_intr_tovf(void)
+{
+ *H8_3069F_TISRC &= ~(1 << 0);
+ tmrovf = 1;
+ *H8_3069F_TSTR &= ~(1 << 0);
+}
+
+/* \e$B%3%s%=!<%k$X$NJ8;zNs=PNO$r%3%s%=!<%k!&%I%i%$%P$K0MMj$9$k\e(B */
+static void send_write(char *str)
+{
+ char *p;
+ int len;
+ len = strlen(str);
+ p = kz_kmalloc(len + 2);
+ p[0] = '0';
+ p[1] = CONSDRV_CMD_WRITE;
+ memcpy(&p[2], str, len);
+ kz_send(MSGBOX_ID_CONSOUTPUT, len + 2, p);
+}
+
+int remocon_main(int argc, char *argv[])
+{
+ kz_setintr(SOFTVEC_TYPE_IR_EDGE, remocon_intr_edge);
+ kz_setintr(SOFTVEC_TYPE_IR_TOVF, remocon_intr_tovf);
+ *H8_3069F_ISCR |= (1 << 4);
+ *H8_3069F_IER |= (1 << 4);
+
+ *H8_3069F_TISRC |= (1 << 4);
+ *H8_3069F_16TCR0 = 0x03;
+
+ while (1) {
+ if (tmrovf) {
+ if (bitcnt > 0) {
+ if (bitcnt == 32) {
+ int i;
+ for (i = 0; i < bitcnt; i++) {
+ if (data[i / 8] & (1 << (i % 8))) {
+ send_write("1");
+ } else {
+ send_write("0");
+ }
+ }
+ send_write("\n");
+ }
+ bitcnt = 0;
+ }
+ tmrovf = 0;
+ irs = WaitLeader;
+ }
+ }
+
+ return 0;
+}
+
--- /dev/null
+
+#ifndef _REMOCON_H_
+#define _REMOCON_H_
+void remocon_init(void);
+#endif
--- /dev/null
+#include "defines.h"
+#include "serial.h"
+
+#define SERIAL_SCI_NUM 3
+
+#define H8_3069F_SCI0 ((volatile struct h8_3069f_sci *)0xffffb0)
+#define H8_3069F_SCI1 ((volatile struct h8_3069f_sci *)0xffffb8)
+#define H8_3069F_SCI2 ((volatile struct h8_3069f_sci *)0xffffc0)
+
+struct h8_3069f_sci {
+ volatile uint8 smr;
+ volatile uint8 brr;
+ volatile uint8 scr;
+ volatile uint8 tdr;
+ volatile uint8 ssr;
+ volatile uint8 rdr;
+ volatile uint8 scmr;
+};
+
+#define H8_3069F_SCI_SMR_CKS_PER1 (0<<0)
+#define H8_3069F_SCI_SMR_CKS_PER4 (1<<0)
+#define H8_3069F_SCI_SMR_CKS_PER16 (2<<0)
+#define H8_3069F_SCI_SMR_CKS_PER64 (3<<0)
+#define H8_3069F_SCI_SMR_MP (1<<2)
+#define H8_3069F_SCI_SMR_STOP (1<<3)
+#define H8_3069F_SCI_SMR_OE (1<<4)
+#define H8_3069F_SCI_SMR_PE (1<<5)
+#define H8_3069F_SCI_SMR_CHR (1<<6)
+#define H8_3069F_SCI_SMR_CA (1<<7)
+
+#define H8_3069F_SCI_SCR_CKE0 (1<<0)
+#define H8_3069F_SCI_SCR_CKE1 (1<<1)
+#define H8_3069F_SCI_SCR_TEIE (1<<2)
+#define H8_3069F_SCI_SCR_MPIE (1<<3)
+#define H8_3069F_SCI_SCR_RE (1<<4) /* ¼õ¿®Í¸ú */
+#define H8_3069F_SCI_SCR_TE (1<<5) /* Á÷¿®Í¸ú */
+#define H8_3069F_SCI_SCR_RIE (1<<6) /* ¼õ¿®³ä¹þ¤ß͸ú */
+#define H8_3069F_SCI_SCR_TIE (1<<7) /* Á÷¿®³ä¹þ¤ß͸ú */
+
+#define H8_3069F_SCI_SSR_MPBT (1<<0)
+#define H8_3069F_SCI_SSR_MPB (1<<1)
+#define H8_3069F_SCI_SSR_TEND (1<<2)
+#define H8_3069F_SCI_SSR_PER (1<<3)
+#define H8_3069F_SCI_SSR_FERERS (1<<4)
+#define H8_3069F_SCI_SSR_ORER (1<<5)
+#define H8_3069F_SCI_SSR_RDRF (1<<6) /* ¼õ¿®´°Î» */
+#define H8_3069F_SCI_SSR_TDRE (1<<7) /* Á÷¿®´°Î» */
+
+static struct {
+ volatile struct h8_3069f_sci *sci;
+} regs[SERIAL_SCI_NUM] = {
+ { H8_3069F_SCI0 },
+ { H8_3069F_SCI1 },
+ { H8_3069F_SCI2 },
+};
+
+/* ¥Ç¥Ð¥¤¥¹½é´ü²½ */
+int serial_init(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+
+ sci->scr = 0;
+ sci->smr = 0;
+ sci->brr = 64; /* 20MHz¤Î¥¯¥í¥Ã¥¯¤«¤é9600bps¤òÀ¸À®(25MHz¤Î¾ì¹ç¤Ï80¤Ë¤¹¤ë) */
+ sci->scr = H8_3069F_SCI_SCR_RE | H8_3069F_SCI_SCR_TE; /* Á÷¼õ¿®²Äǽ */
+ sci->ssr = 0;
+
+ return 0;
+}
+
+/* Á÷¿®²Äǽ¤«¡© */
+int serial_is_send_enable(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ return (sci->ssr & H8_3069F_SCI_SSR_TDRE);
+}
+
+/* £±Ê¸»úÁ÷¿® */
+int serial_send_byte(int index, unsigned char c)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+
+ /* Á÷¿®²Äǽ¤Ë¤Ê¤ë¤Þ¤ÇÂÔ¤Ä */
+ while (!serial_is_send_enable(index))
+ ;
+ sci->tdr = c;
+ sci->ssr &= ~H8_3069F_SCI_SSR_TDRE; /* Á÷¿®³«»Ï */
+
+ return 0;
+}
+
+/* ¼õ¿®²Äǽ¤«¡© */
+int serial_is_recv_enable(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ return (sci->ssr & H8_3069F_SCI_SSR_RDRF);
+}
+
+/* £±Ê¸»ú¼õ¿® */
+unsigned char serial_recv_byte(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ unsigned char c;
+
+ /* ¼õ¿®Ê¸»ú¤¬Íè¤ë¤Þ¤ÇÂÔ¤Ä */
+ while (!serial_is_recv_enable(index))
+ ;
+ c = sci->rdr;
+ sci->ssr &= ~H8_3069F_SCI_SSR_RDRF; /* ¼õ¿®´°Î» */
+
+ return c;
+}
+
+/* Á÷¿®³ä¹þ¤ß͸ú¤«¡© */
+int serial_intr_is_send_enable(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ return (sci->scr & H8_3069F_SCI_SCR_TIE) ? 1 : 0;
+}
+
+/* Á÷¿®³ä¹þ¤ß͸ú²½ */
+void serial_intr_send_enable(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ sci->scr |= H8_3069F_SCI_SCR_TIE;
+}
+
+/* Á÷¿®³ä¹þ¤ß̵¸ú²½ */
+void serial_intr_send_disable(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ sci->scr &= ~H8_3069F_SCI_SCR_TIE;
+}
+
+/* ¼õ¿®³ä¹þ¤ß͸ú¤«¡© */
+int serial_intr_is_recv_enable(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ return (sci->scr & H8_3069F_SCI_SCR_RIE) ? 1 : 0;
+}
+
+/* ¼õ¿®³ä¹þ¤ß͸ú²½ */
+void serial_intr_recv_enable(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ sci->scr |= H8_3069F_SCI_SCR_RIE;
+}
+
+/* ¼õ¿®³ä¹þ¤ß̵¸ú²½ */
+void serial_intr_recv_disable(int index)
+{
+ volatile struct h8_3069f_sci *sci = regs[index].sci;
+ sci->scr &= ~H8_3069F_SCI_SCR_RIE;
+}
--- /dev/null
+#ifndef _SERIAL_H_INCLUDED_
+#define _SERIAL_H_INCLUDED_
+
+int serial_init(int index); /* ¥Ç¥Ð¥¤¥¹½é´ü²½ */
+int serial_is_send_enable(int index); /* Á÷¿®²Äǽ¤«¡© */
+int serial_send_byte(int index, unsigned char b); /* £±Ê¸»úÁ÷¿® */
+int serial_is_recv_enable(int index); /* ¼õ¿®²Äǽ¤«¡© */
+unsigned char serial_recv_byte(int index); /* £±Ê¸»ú¼õ¿® */
+int serial_intr_is_send_enable(int index); /* Á÷¿®³ä¹þ¤ß͸ú¤«¡© */
+void serial_intr_send_enable(int index); /* Á÷¿®³ä¹þ¤ß͸ú²½ */
+void serial_intr_send_disable(int index); /* Á÷¿®³ä¹þ¤ß̵¸ú²½ */
+int serial_intr_is_recv_enable(int index); /* ¼õ¿®³ä¹þ¤ß͸ú¤«¡© */
+void serial_intr_recv_enable(int index); /* ¼õ¿®³ä¹þ¤ß͸ú²½ */
+void serial_intr_recv_disable(int index); /* ¼õ¿®³ä¹þ¤ß̵¸ú²½ */
+
+#endif
--- /dev/null
+ .h8300h\r
+ .section .text\r
+ .global _start\r
+# .type _start,@function\r
+_start:\r
+ mov.l #_bootstack,sp\r
+ jsr @_main\r
+\r
+1:\r
+ bra 1b\r
+\r
+ .global _dispatch\r
+# .type _dispatch,@function\r
+_dispatch:\r
+ mov.l @er0,er7\r
+ mov.l @er7+,er0\r
+ mov.l @er7+,er1\r
+ mov.l @er7+,er2\r
+ mov.l @er7+,er3\r
+ mov.l @er7+,er4\r
+ mov.l @er7+,er5\r
+ mov.l @er7+,er6\r
+ rte\r
--- /dev/null
+#include "sw.h"
+
+#define H8_3069F_P7DR ((volatile uint8 *)0xFFFFD6)
+#define H8_3069F_PADR ((volatile uint8 *)0xFFFFD9)
+
+#define SW_BIT_P7_SW1 (1 << 0)
+#define SW_BIT_P7_SW2 (1 << 1)
+#define SW_BIT_PA_SWRE (1 << 4)
+
+int sw_init(void)
+{
+ return 0;
+}
+
+uint8 sw_read(sw_target_t target)
+{
+ uint8 c = 0;
+ switch (target) {
+ case Sw1:
+ c = (*H8_3069F_P7DR & SW_BIT_P7_SW1) ? 0 : 1;
+ break;
+ case Sw2:
+ c = (*H8_3069F_P7DR & SW_BIT_P7_SW2) ? 0 : 1;
+ break;
+ case SwRe:
+ c = (*H8_3069F_PADR & SW_BIT_PA_SWRE) ? 0 : 1;
+ break;
+ }
+ return c;
+}
+
--- /dev/null
+#ifndef _SW_H_INCLUDED_
+#define _SW_H_INCLUDED_
+
+#include "defines.h"
+
+typedef enum {
+ Sw1,
+ Sw2,
+ SwRe,
+} sw_target_t;
+
+int sw_init(void);
+uint8 sw_read(sw_target_t target);
+
+#endif
+
--- /dev/null
+#include "defines.h"
+#include "kozos.h"
+#include "interrupt.h"
+#include "syscall.h"
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë */
+
+kz_thread_id_t kz_run(kz_func_t func, char *name, int priority, int stacksize,
+ int argc, char *argv[])
+{
+ kz_syscall_param_t param;
+ param.un.run.func = func;
+ param.un.run.name = name;
+ param.un.run.priority = priority;
+ param.un.run.stacksize = stacksize;
+ param.un.run.argc = argc;
+ param.un.run.argv = argv;
+ kz_syscall(KZ_SYSCALL_TYPE_RUN, ¶m);
+ return param.un.run.ret;
+}
+
+void kz_exit(void)
+{
+ kz_syscall(KZ_SYSCALL_TYPE_EXIT, NULL);
+}
+
+int kz_wait(void)
+{
+ kz_syscall_param_t param;
+ kz_syscall(KZ_SYSCALL_TYPE_WAIT, ¶m);
+ return param.un.wait.ret;
+}
+
+int kz_sleep(void)
+{
+ kz_syscall_param_t param;
+ kz_syscall(KZ_SYSCALL_TYPE_SLEEP, ¶m);
+ return param.un.sleep.ret;
+}
+
+int kz_wakeup(kz_thread_id_t id)
+{
+ kz_syscall_param_t param;
+ param.un.wakeup.id = id;
+ kz_syscall(KZ_SYSCALL_TYPE_WAKEUP, ¶m);
+ return param.un.wakeup.ret;
+}
+
+kz_thread_id_t kz_getid(void)
+{
+ kz_syscall_param_t param;
+ kz_syscall(KZ_SYSCALL_TYPE_GETID, ¶m);
+ return param.un.getid.ret;
+}
+
+int kz_chpri(int priority)
+{
+ kz_syscall_param_t param;
+ param.un.chpri.priority = priority;
+ kz_syscall(KZ_SYSCALL_TYPE_CHPRI, ¶m);
+ return param.un.chpri.ret;
+}
+
+void *kz_kmalloc(int size)
+{
+ kz_syscall_param_t param;
+ param.un.kmalloc.size = size;
+ kz_syscall(KZ_SYSCALL_TYPE_KMALLOC, ¶m);
+ return param.un.kmalloc.ret;
+}
+
+int kz_kmfree(void *p)
+{
+ kz_syscall_param_t param;
+ param.un.kmfree.p = p;
+ kz_syscall(KZ_SYSCALL_TYPE_KMFREE, ¶m);
+ return param.un.kmfree.ret;
+}
+
+int kz_send(kz_msgbox_id_t id, int size, char *p)
+{
+ kz_syscall_param_t param;
+ param.un.send.id = id;
+ param.un.send.size = size;
+ param.un.send.p = p;
+ kz_syscall(KZ_SYSCALL_TYPE_SEND, ¶m);
+ return param.un.send.ret;
+}
+
+kz_thread_id_t kz_recv(kz_msgbox_id_t id, int *sizep, char **pp)
+{
+ kz_syscall_param_t param;
+ param.un.recv.id = id;
+ param.un.recv.sizep = sizep;
+ param.un.recv.pp = pp;
+ kz_syscall(KZ_SYSCALL_TYPE_RECV, ¶m);
+ return param.un.recv.ret;
+}
+
+int kz_setintr(softvec_type_t type, kz_handler_t handler)
+{
+ kz_syscall_param_t param;
+ param.un.setintr.type = type;
+ param.un.setintr.handler = handler;
+ kz_syscall(KZ_SYSCALL_TYPE_SETINTR, ¶m);
+ return param.un.setintr.ret;
+}
+
+/* ¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë */
+
+int kx_wakeup(kz_thread_id_t id)
+{
+ kz_syscall_param_t param;
+ param.un.wakeup.id = id;
+ kz_srvcall(KZ_SYSCALL_TYPE_WAKEUP, ¶m);
+ return param.un.wakeup.ret;
+}
+
+void *kx_kmalloc(int size)
+{
+ kz_syscall_param_t param;
+ param.un.kmalloc.size = size;
+ kz_srvcall(KZ_SYSCALL_TYPE_KMALLOC, ¶m);
+ return param.un.kmalloc.ret;
+}
+
+int kx_kmfree(void *p)
+{
+ kz_syscall_param_t param;
+ param.un.kmfree.p = p;
+ kz_srvcall(KZ_SYSCALL_TYPE_KMFREE, ¶m);
+ return param.un.kmfree.ret;
+}
+
+int kx_send(kz_msgbox_id_t id, int size, char *p)
+{
+ kz_syscall_param_t param;
+ param.un.send.id = id;
+ param.un.send.size = size;
+ param.un.send.p = p;
+ kz_srvcall(KZ_SYSCALL_TYPE_SEND, ¶m);
+ return param.un.send.ret;
+}
--- /dev/null
+#ifndef _KOZOS_SYSCALL_H_INCLUDED_
+#define _KOZOS_SYSCALL_H_INCLUDED_
+
+#include "defines.h"
+#include "interrupt.h"
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ëÈÖ¹æ¤ÎÄêµÁ */
+typedef enum {
+ KZ_SYSCALL_TYPE_RUN = 0,
+ KZ_SYSCALL_TYPE_EXIT,
+ KZ_SYSCALL_TYPE_WAIT,
+ KZ_SYSCALL_TYPE_SLEEP,
+ KZ_SYSCALL_TYPE_WAKEUP,
+ KZ_SYSCALL_TYPE_GETID,
+ KZ_SYSCALL_TYPE_CHPRI,
+ KZ_SYSCALL_TYPE_KMALLOC,
+ KZ_SYSCALL_TYPE_KMFREE,
+ KZ_SYSCALL_TYPE_SEND,
+ KZ_SYSCALL_TYPE_RECV,
+ KZ_SYSCALL_TYPE_SETINTR,
+} kz_syscall_type_t;
+
+/* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¸Æ¤Ó½Ð¤·»þ¤Î¥Ñ¥é¥á¡¼¥¿³ÊǼ°è¤ÎÄêµÁ */
+typedef struct {
+ union {
+ struct {
+ kz_func_t func;
+ char *name;
+ int priority;
+ int stacksize;
+ int argc;
+ char **argv;
+ kz_thread_id_t ret;
+ } run;
+ struct {
+ int dummy;
+ } exit;
+ struct {
+ int ret;
+ } wait;
+ struct {
+ int ret;
+ } sleep;
+ struct {
+ kz_thread_id_t id;
+ int ret;
+ } wakeup;
+ struct {
+ kz_thread_id_t ret;
+ } getid;
+ struct {
+ int priority;
+ int ret;
+ } chpri;
+ struct {
+ int size;
+ void *ret;
+ } kmalloc;
+ struct {
+ char *p;
+ int ret;
+ } kmfree;
+ struct {
+ kz_msgbox_id_t id;
+ int size;
+ char *p;
+ int ret;
+ } send;
+ struct {
+ kz_msgbox_id_t id;
+ int *sizep;
+ char **pp;
+ kz_thread_id_t ret;
+ } recv;
+ struct {
+ softvec_type_t type;
+ kz_handler_t handler;
+ int ret;
+ } setintr;
+ } un;
+} kz_syscall_param_t;
+
+#endif
--- /dev/null
+#include "defines.h"
+#include "timer.h"
+
+#define TIMER_TMR_NUM 2
+
+#define H8_3069F_TMR01 ((volatile struct h8_3069f_tmr *)0xffff80)
+#define H8_3069F_TMR23 ((volatile struct h8_3069f_tmr *)0xffff90)
+
+struct h8_3069f_tmr {
+ volatile uint8 tcr0;
+ volatile uint8 tcr1;
+ volatile uint8 tcsr0;
+ volatile uint8 tcsr1;
+ volatile uint8 tcora0;
+ volatile uint8 tcora1;
+ volatile uint8 tcorb0;
+ volatile uint8 tcorb1;
+ volatile uint16 tcnt;
+};
+
+#define H8_3069F_TMR_TCR_DISCLK (0<<0)
+#define H8_3069F_TMR_TCR_CLK8 (1<<0)
+#define H8_3069F_TMR_TCR_CLK64 (2<<0)
+#define H8_3069F_TMR_TCR_CLK8192 (3<<0)
+#define H8_3069F_TMR_TCR_OVF (4<<0)
+#define H8_3069F_TMR_TCR_CMFA (4<<0)
+#define H8_3069F_TMR_TCR_CLKUP (5<<0)
+#define H8_3069F_TMR_TCR_CLKDOWN (6<<0)
+#define H8_3069F_TMR_TCR_CLKBOTH (7<<0)
+
+#define H8_3069F_TMR_TCR_CCLR_DISCLR (0<<3)
+#define H8_3069F_TMR_TCR_CCLR_CLRCMFA (1<<3)
+#define H8_3069F_TMR_TCR_CCLR_CLRCMFB (2<<3)
+#define H8_3069F_TMR_TCR_CCLR_DISINPB (3<<3)
+
+#define H8_3069F_TMR_TCR_OVIE (1<<5)
+#define H8_3069F_TMR_TCR_CMIEA (1<<6)
+#define H8_3069F_TMR_TCR_CMIEB (1<<7)
+
+#define H8_3069F_TMR_TCSR_OS_NOACT (0<<0)
+#define H8_3069F_TMR_TCSR_OIS_NOACT (0<<2)
+#define H8_3069F_TMR_TCSR_ADTE (1<<4)
+#define H8_3069F_TMR_TCSR_ICE (1<<4)
+#define H8_3069F_TMR_TCSR_OVF (1<<5)
+#define H8_3069F_TMR_TCSR_CMFA (1<<6)
+#define H8_3069F_TMR_TCSR_CMFB (1<<7)
+
+static struct {
+ volatile struct h8_3069f_tmr *tmr;
+} regs[TIMER_TMR_NUM] = {
+ { H8_3069F_TMR01 },
+ { H8_3069F_TMR23 },
+};
+
+/* ¥¿¥¤¥Þ³«»Ï */
+int timer_start(int index, int msec, int flags)
+{
+ volatile struct h8_3069f_tmr *tmr = regs[index].tmr;
+ int count;
+ uint8 tcr;
+
+ tcr = H8_3069F_TMR_TCR_OVF;
+ if (flags & TIMER_START_FLAG_CYCLE)
+ tcr |= H8_3069F_TMR_TCR_CCLR_CLRCMFA;
+ else
+ tcr |= H8_3069F_TMR_TCR_CCLR_DISCLR;
+ tmr->tcr0 = tcr;
+ tmr->tcr1 = H8_3069F_TMR_TCR_CLK8192 | H8_3069F_TMR_TCR_CCLR_DISCLR;
+
+ tmr->tcsr0 = 0;
+ tmr->tcsr1 = 0;
+
+ count = msec / 105; /* 20MHz: (msec * 20000000 / 8192 / 256 / 1000) */
+
+ tmr->tcnt = 0;
+ tmr->tcora0 = count;
+ tmr->tcr0 |= H8_3069F_TMR_TCR_CMIEA; /* ³ä¹þ¤ß͸ú²½ */
+
+ return 0;
+}
+
+/* ¥¿¥¤¥ÞËþλ¤·¤¿¤«¡© */
+int timer_is_expired(int index)
+{
+ volatile struct h8_3069f_tmr *tmr = regs[index].tmr;
+ return (tmr->tcsr0 & H8_3069F_TMR_TCSR_CMFA) ? 1 : 0;
+}
+
+/* ¥¿¥¤¥ÞËþλ½èÍý */
+int timer_expire(int index)
+{
+ volatile struct h8_3069f_tmr *tmr = regs[index].tmr;
+
+ tmr->tcsr0 &= ~H8_3069F_TMR_TCSR_CMFA;
+
+ return 0;
+}
+
+/* ¥¿¥¤¥Þ¥¥ã¥ó¥»¥ë */
+int timer_cancel(int index)
+{
+ volatile struct h8_3069f_tmr *tmr = regs[index].tmr;
+
+ timer_expire(index);
+
+ tmr->tcr0 = 0;
+ tmr->tcr1 = 0;
+
+ tmr->tcr0 &= ~H8_3069F_TMR_TCR_CMIEA; /* ³ä¹þ¤ß̵¸ú²½ */
+
+ return 0;
+}
+
+/* ¥¿¥¤¥ÞÆ°ºîÃ椫¡© */
+int timer_is_running(int index)
+{
+ volatile struct h8_3069f_tmr *tmr = regs[index].tmr;
+ return (tmr->tcr0 & H8_3069F_TMR_TCR_CMIEA) ? 1 : 0;
+}
+
+/* ¥¿¥¤¥Þ¤Î¸½ºßÃÍ */
+int timer_gettime(int index)
+{
+ volatile struct h8_3069f_tmr *tmr = regs[index].tmr;
+ volatile int count;
+ int msec;
+
+ /*
+ * ¼þ´ü¥¿¥¤¥Þ¤Î¾ì¹ç¤ÏÆ°ºîÃ椫¤É¤¦¤«¤Î¥Á¥§¥Ã¥¯¤Îľ¸å¤Ë¥¿¥¤¥ÞËþλ¤¹¤ë¤È
+ * ¥«¥¦¥ó¥¿¤¬¥¼¥í¤Ë½é´ü²½¤µ¤ì¤Æ¤·¤Þ¤¦¤Î¤Ç¡¤Á°¤â¤Ã¤ÆÃͤò¼èÆÀ¤·¤Æ¤ª¤¯¡¥
+ */
+ count = tmr->tcnt;
+ msec = count * 2 / 5; /* 20MHz: (count * 8192 * 1000 / 20000000) */
+
+ return timer_is_running(index) ? msec : -1;
+}
--- /dev/null
+#ifndef _TIMER_H_INCLUDED_
+#define _TIMER_H_INCLUDED_
+
+#define TIMER_START_FLAG_CYCLE (1<<0)
+
+int timer_start(int index, int msec, int flags); /* ¥¿¥¤¥Þ³«»Ï */
+int timer_is_expired(int index); /* ¥¿¥¤¥ÞËþλ¤·¤¿¤«¡© */
+int timer_expire(int index); /* ¥¿¥¤¥ÞËþλ½èÍý */
+int timer_cancel(int index); /* ¥¿¥¤¥Þ¥¥ã¥ó¥»¥ë */
+int timer_is_running(int index); /* ¥¿¥¤¥ÞÆ°ºîÃ椫¡© */
+int timer_gettime(int index); /* ¥¿¥¤¥Þ¤Î¸½ºßÃÍ */
+
+#endif
--- /dev/null
+#include "defines.h"
+#include "kozos.h"
+#include "intr.h"
+#include "interrupt.h"
+#include "timer.h"
+#include "lib.h"
+#include "timerdrv.h"
+
+struct timerbuf {
+ struct timerbuf *next;
+ kz_msgbox_id_t id; /* ¥¿¥¤¥ÞËþλ»þ¤Î¥á¥Ã¥»¡¼¥¸Á÷¿®Àè */
+ int msec;
+};
+
+static struct timerreg {
+ struct timerbuf *timers; /* ¥¿¥¤¥Þ¡¦¥Ð¥Ã¥Õ¥¡¤Î¥ê¥ó¥¯¥ê¥¹¥È */
+ int index; /* ÍøÍѤ¹¤ë¥¿¥¤¥Þ¤ÎÈÖ¹æ */
+} timerreg;
+
+/*
+ * °Ê²¼¤Ï³ä¹þ¤ß¥Ï¥ó¥É¥é¤Ç¤¢¤ê¡¤ÈóƱ´ü¤Ç¸Æ¤Ð¤ì¤ë¤Î¤Ç¡¤¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Ê¤É¤ò
+ * ¸Æ¤Ó½Ð¤¹¾ì¹ç¤Ë¤ÏÃí°Õ¤¬É¬Íס¥
+ * ´ðËܤȤ·¤Æ¡¤°Ê²¼¤Î¤¤¤º¤ì¤«¤ËÅö¤Æ¤Ï¤Þ¤ë´Ø¿ô¤·¤«¸Æ¤Ó½Ð¤·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
+ * ¡¦ºÆÆþ²Äǽ¤Ç¤¢¤ë¡¥
+ * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤Ï̵¤¤´Ø¿ô¤Ç¤¢¤ë¡¥
+ * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤¬¤¢¤ë¤¬¡¤³ä¹þ¤ß¶Ø»ß¤Ç¸Æ¤Ó½Ð¤·¤Æ¤¤¤ë¡¥
+ * ¤Þ¤¿Èó¥³¥ó¥Æ¥¥¹¥È¾õÂ֤ǸƤФì¤ë¤¿¤á¡¤¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ÏÍøÍѤ·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
+ * (¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤òÍøÍѤ¹¤ë¤³¤È)
+ */
+static void timerdrv_intr(void)
+{
+ struct timerreg *tim = &timerreg;
+
+ if (timer_is_expired(tim->index)) { /* ¥¿¥¤¥Þ³ä¹þ¤ß */
+ timer_cancel(tim->index);
+ kx_send(MSGBOX_ID_TIMDRIVE, TIMERDRV_CMD_EXPIRE, NULL);
+ }
+}
+
+static int timerdrv_init(void)
+{
+ memset(&timerreg, 0, sizeof(timerreg));
+ timerreg.index = TIMER_DEFAULT_DEVICE;
+ return 0;
+}
+
+/* ¥¹¥ì¥Ã¥É¤«¤é¤ÎÍ×µá¤ò½èÍý¤¹¤ë */
+static int timerdrv_command(struct timerreg *tim, int cmd, char *p)
+{
+ struct timerbuf *tmbuf;
+ struct timerbuf **tmbufp;
+ struct timerreq *req;
+ int t, msec;
+
+ switch (cmd) {
+ case TIMERDRV_CMD_EXPIRE: /* ¥¿¥¤¥ÞËþλ */
+ tmbuf = tim->timers;
+ if (tmbuf) {
+ tim->timers = tmbuf->next;
+ kz_send(tmbuf->id, 0, NULL);
+ kz_kmfree(tmbuf);
+ if (tim->timers)
+ timer_start(tim->index, tim->timers->msec, 0);
+ }
+ break;
+
+ case TIMERDRV_CMD_START: /* ¥¿¥¤¥Þ¤Î¥¹¥¿¡¼¥È */
+ req = (struct timerreq *)p;
+
+ tmbuf = kz_kmalloc(sizeof(*tmbuf));
+ tmbuf->next = NULL;
+ tmbuf->id = req->id;
+ tmbuf->msec = req->msec;
+
+ t = 0;
+ if (tim->timers) {
+ t = timer_gettime(tim->index);
+ }
+
+ for (tmbufp = &tim->timers;; tmbufp = &(*tmbufp)->next) {
+ if (*tmbufp == NULL) {
+ *tmbufp = tmbuf;
+ if (tmbufp == &tim->timers)
+ timer_start(tim->index, tim->timers->msec, 0);
+ break;
+ }
+ msec = (*tmbufp)->msec - t;
+ if (msec < 0) msec = 0;
+ if (tmbuf->msec < msec) {
+ (*tmbufp)->msec = msec - tmbuf->msec;
+ tmbuf->next = *tmbufp;
+ *tmbufp = tmbuf;
+ timer_start(tim->index, tim->timers->msec, 0);
+ break;
+ }
+ t = 0;
+ tmbuf->msec -= msec;
+ }
+
+ kz_kmfree(p);
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int timerdrv_main(int argc, char *argv[])
+{
+ int cmd;
+ char *p;
+
+ timerdrv_init();
+ kz_setintr(SOFTVEC_TYPE_TIMINTR, timerdrv_intr); /* ³ä¹þ¤ß¥Ï¥ó¥É¥éÀßÄê */
+
+ while (1) {
+ kz_recv(MSGBOX_ID_TIMDRIVE, &cmd, &p);
+ timerdrv_command(&timerreg, cmd, p);
+ }
+
+ return 0;
+}
--- /dev/null
+#ifndef _TIMERDRV_H_INCLUDED_
+#define _TIMERDRV_H_INCLUDED_
+
+#define TIMERDRV_DEVICE_NUM 1
+#define TIMERDRV_CMD_EXPIRE 'e' /* ¥¿¥¤¥ÞËþλ */
+#define TIMERDRV_CMD_START 's' /* ¥¿¥¤¥Þ¤Î¥¹¥¿¡¼¥È */
+
+struct timerreq {
+ kz_msgbox_id_t id; /* ¥¿¥¤¥ÞËþλ»þ¤Î¥á¥Ã¥»¡¼¥¸Á÷¿®Àè */
+ int msec;
+};
+
+#endif
(os)
======================================================================
+09
+======================================================================
+ 08のジャンクなbootloadを若干修正したバージョン。
+
+ (bootload)
+
+ (os)
+
+======================================================================
tools/kz_h8write
======================================================================