å°ãåãŸã§ãããã8ãšãã¥ã¬ãŒã¿ãŒã®äœæã«é¢ããèšäºãHabréã«æ²èŒãããŸãããããã«ããããšãã¥ã¬ãŒã¿ãŒã®äœææ¹æ³ãå°ãªããšãè¡šé¢çã«ç解ããããšãã§ããŸããã ãšãã¥ã¬ãŒã¿ãŒãå®è£ ããåŸãããã«é²ãã§ããããã«æãããŸããã éžæã¯å ã®ã²ãŒã ããŒã€ã«ããã£ãã çµå±ã®ãšããããã®éžæã¯ãããæ·±å»ãªãã®ãå®è£ ãããç¶æ³ã«çæ³çã§ããããšãã¥ã¬ãŒã¿ãŒã®éçºçµéšã¯ã»ãšãã©ãããŸããã
ãšãã¥ã¬ãŒã·ã§ã³ã«é¢ããŠã¯ãã²ãŒã ããŒã€ã¯æ¯èŒçåçŽã§ãããããã§ãããªãã®éã®æ å ±ã調ã¹ãå¿ èŠããããŸãã ãã®ãããGameboyãšãã¥ã¬ãŒã¿ãŒã®éçºã«é¢ããèšäºãããã€ããããŸãã æçµçµæã¯ãä»ã®ãšãã¥ã¬ãŒã¿ãŒã«ã¯ãªãããšãå€ããµãŠã³ããå«ãããªãªãžãã«ã®ã»ãŒãã¹ãŠã®æ©èœããµããŒããããäºææ§ã®è¯ããšãã¥ã¬ãŒã¿ãŒã«ãªããŸãã ããŸããšããŠããšãã¥ã¬ãŒã¿ã¯ã»ãšãã©ãã¹ãŠã®ãã¹ãROMã«åæ ŒããŸãããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸãã
ãããã®èšäºã«ã¯ããšãã¥ã¬ãŒã¿ãŒå®è£ ã®å®å šãªèª¬æã¯å«ãŸããŸããã ããã¯å€§ããããŠãå®è£ ããã®é¢å¿ã¯ãã¹ãŠæ¶ããŸãã ãŸããªå Žåã«ã®ã¿ç¹å®ã®ã³ãŒãã«å°éããŸãã å®è£ ã®å°ããªãã³ãã䜿çšããŠãããçè«çãªèª¬æãè¡ããšããã¿ã¹ã¯ãèªåã§èšå®ããŸããçæ³çã«ã¯ããšãã¥ã¬ãŒã¿ãç°¡åã«äœæã§ããåæã«èªåã§äœæãããããªæ°åã«ãªããŸãã å¿ èŠã«å¿ããŠãç¬èªã®å®è£ ãåç §ããŸã-å¿ èŠã«å¿ããŠã倧éã®ã³ãŒãè¡ãç Žãããšãªãé©åãªã³ãŒããèŠã€ããããšãã§ããŸãã
ãã®èšäºã§ã¯ãGameboyãç解ãããã®ããã»ããµãšã¡ã¢ãªããšãã¥ã¬ãŒãããããšããå§ããŸãã
ã²ãŒã ããŒã€ãšãã¥ã¬ãŒã¿ã®äœæãããŒã1
ã²ãŒã ããŒã€ãšãã¥ã¬ãŒã¿ã®äœæãããŒã2
ã²ãŒã ããŒã€ãšãã¥ã¬ãŒã¿ã®äœæãããŒã3
ç®æ¬¡
ã¯ããã«å»ºç¯
CPU
äžæ
èšæ¶
ãããã«
ã¯ããã«
Gameboyã¯ã1989幎ã«çºå£²ããã任倩å ã®ãã³ããã«ãã³ã³ãœãŒã«ã§ãã ããã¯å ã®çœé»ã®ã²ãŒã ããŒã€ã«ã€ããŠã§ãã ã¬ã€ããããããŸããŸãªããã¥ã¡ã³ãã§ã¯ãã²ãŒã ããŒã€ãšããã³ãŒãåã䜿çšãããŠããããšã«æ³šæããŠãã ãã-DMGïŒDot Matrix GameïŒã ããã«äœ¿çšããŸãã
éå§ããåã«ãDMGã®æè¡çç¹æ§ãç解ããå¿ èŠããããŸãã
CPU | 4.19 MHzã®åšæ³¢æ°ã§åäœãã8ãããSharp LR35902 |
RAM | 8 kB |
ãããªã¡ã¢ãª | 8 kB |
ç»é¢è§£å床 | 160x144 |
åçŽåšæ³¢æ° | 59.73 Hz |
é³ | 4ãã£ã³ãã«ãã¹ãã¬ãªãµãŠã³ã |
件åã確èªãããã次ã®ã¹ãããã¯ããã¥ã¡ã³ãã§ãã å¿ èŠãªæ å ±ã倧éã«ãããããèšäºã®ãã¹ãŠãå®å šã«æ²èŒããããšã¯ã§ããªããããäºåã«ããã¥ã¡ã³ããæºåããå¿ èŠããããŸãã
Gameboy CPU ManualãšããDMGã®çŽ æŽãããããã¥ã¡ã³ãããããŸãã èåãªéçºè ããã®ããã€ãã®æåãªããã¥ã¡ã³ããå«ãŸããŠãããå¿ èŠãªã»ãŒãã¹ãŠã®æ å ±ãå«ãŸããŠããŸãã åœç¶ãããã§ãã¹ãŠã§ã¯ãããŸãããããã®æ®µéã§ã¯ããã§ååã§ãã
æ£åŒãªãã®ã§ãã£ãŠããææžã«èª€ããããããšãããã«èŠåããŸãã ãã®äžé£ã®èšäºã®äžã§ãç§ãèŠã€ããããšãã§ããããŸããŸãªææžã®ãã¹ãŠã®æ¬ ç¹ã«èšåããããšããŸãïŒèŠããŠãããŠãã ããïŒã ãŸããå€ãã®ã®ã£ãããåããããšããŸãã çµè«ãšããŠã¯ãDMGã®å æ¬çãªèª¬æã¯ãããŸããã å©çšå¯èœãªè³æã¯ãå€ãã®ã³ã³ãœãŒã«ããŒãã®äœæ¥ã«ã€ããŠã®è¡šé¢çãªã¢ã€ãã¢ã®ã¿ãæäŸããŸãã ããã°ã©ããŒããã®ãããªãèœãšãç©ŽããèªèããŠããªãå Žåããšãã¥ã¬ãŒã¿ãŒã®éçºã¯æã£ããããã¯ããã«è€éã«ãªããŸãã DMGã¯ãä¿¡é Œã§ãã詳现ãªæ å ±ãæå ã«çœ®ããŠãããšç°¡åã§ãã ãããŠåé¡ã¯ãå€ãã®éèŠãªè©³çŽ°ãä»ã®ãšãã¥ã¬ãŒã¿ãŒã®ãœãŒã¹ã³ãŒãããããåŠã¹ãªããšããããšã§ããããããããã¯ç§ãã¡ã®ä»äºã容æã«ããŸããã ããç¥ãããŠãããšãã¥ã¬ãŒã¿ãŒã®ã³ãŒãã¯ãè€éãããïŒGambatteïŒããã²ã©ãå±±ã»ã©ã®äœå質ã®ã³ãŒãã§ãïŒVisual Boy Advance-æ¶ãªãã«ã³ãŒããèŠãããšã¯ã§ããŸããïŒã
èšäºã¯ç§ã®ãšãã¥ã¬ãŒã¿ãŒã«ç®ãåããŠæžããããã®ãªã®ã§ãCookie ãœãŒã¹ãšCookie Cookieãžã®ãªã³ã¯ãããã«ç€ºããŸãã
建ç¯
å°æ¥ã®ãšãã¥ã¬ãŒã¿ã®ã¢ãŒããã¯ãã£ããå§ããŸãããã DMGããšãã¥ã¬ãŒãããã«ã¯ãäºãã«ã»ãŒç¬ç«ããå€ãã®ã¢ãžã¥ãŒã«ãå®è£ ããå¿ èŠããããŸãã ãã®ãããªç¶æ³ã§ã¯ããã¹ãŠã1ã€ã®ããŒãã«å ¥ããã®ã¯æããªããšã§ãïŒä»ã®ãšãã¥ã¬ãŒã¿ã§ããèŠãããŸããããã«ã¡ã¯VBAïŒã ãããšã¬ã¬ã³ããªãœãªã¥ãŒã·ã§ã³ã¯ãDMGã®åã ã®éšåããéã®éšåããšãã¥ã¬ãŒãããåå¥ã®ã¯ã©ã¹ãšããŠå®è£ ããããšã§ããããã«ã¯çç±ããããŸã-ãšãã¥ã¬ãŒã¿ã®éçºãå§ããã®ã¯ããã¹ãŠã®ã³ã³ããŒãã³ãã1ã€ã®ã¹ãŒããŒã¯ã©ã¹ã«ãªã£ãŠããããã§ãã 誰ããããã¹ãããšã ããããã°ãç©äºã¯ãã£ãšæ¥œã«ãªãããšãããã«æããã«ãªããŸããã ãã®ã¢ãããŒãã«ã¯æãããªè€éããããããšãèªèãã䟡å€ã¯ãããŸããã ã¯ã©ã¹ã®è²¬ä»»ãæ£ããåºå¥ããã«ã¯ãDMGã®å éšæ§é ãååã«ç解ããå¿ èŠããããŸãã
ããã§ã¯å§ããŸãããã
CPU
DMGã«ã¯ã4194304 Hzã®åšæ³¢æ°ã§åäœãã8ãããSharp LR35902ããã»ããµãå«ãŸããŠããŸãïŒãã®ãããªç²ŸåºŠã«é©ããªãã§ãã ãããä»åŸãã®çªå·ãå¿ èŠã«ãªããŸãïŒã Zilog Z80ããã»ããµã®ç°¡æããŒãžã§ã³ãšèŠãªãããšãã§ããŸããããã¯ãIntel 8080ã«åºã¥ããŠããŸããZ80ãšæ¯èŒãããšãäžéšã®ã¬ãžã¹ã¿ãšåœä»€ã»ãããæ¬ èœããŠããŸããããã»ããµã«ã¯ã8ã€ã®8ãããã¬ãžã¹ã¿AãBãCãDãEãFãHãLãããã³2ã€ã®16ãããå°çšã¬ãžã¹ã¿ïŒPCããã³SPïŒãå«ãŸããŠããŸãã äžéšã®åœä»€ã§ã¯ã8ãããã¬ãžã¹ã¿ãçµã¿åãããŠ16ãããã¬ãžã¹ã¿ãšããŠäœ¿çšã§ããŸããã€ãŸããAFãBCãDEãHLã§ãã ããšãã°ãBCã¬ãžã¹ã¿ã¯ãæ¥çãã¬ãžã¹ã¿Bããã³Cã§ãããCã¬ãžã¹ã¿ã¯äžäœãã€ããšããŠæ©èœããBã¯äžäœãã€ããšããŠæ©èœããŸãã
ã¬ãžã¹ã¿AãBãCãDãEãHãLã¯æ±çšã¬ãžã¹ã¿ã§ãã ã¬ãžã¹ã¿AãããããªãŒã§ãã ã¬ãžã¹ã¿Fã«ã¯ããã»ããµãââã©ã°ãå«ãŸããŠãããçŽæ¥ã¢ã¯ã»ã¹ã§ããŸããã 以äžã¯ã¬ãžã¹ã¿ã®æŠèŠã§ãã ããã0ã3ã¯äœ¿çšãããŸããã
ããã | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
æ | Z | N | H | C | 0 | 0 | 0 | 0 |
ãã©ã°ã®ç®çïŒ
- ãŒããã©ã°ïŒZïŒ-æåŸã®æ°åŠæŒç®ã®çµæããŒããŸãã¯2ã€ã®ãªãã©ã³ããæ¯èŒæã«çããããšãå€æããå Žåããã©ã°ãèšå®ãããŸãïŒãããã¯1ïŒã
- æžç®ãã©ã°ïŒNïŒ-æåŸã®æäœãæžç®ã§ãã£ãå Žåããã©ã°ãèšå®ãããŸãã
- ããŒããã£ãªãŒãã©ã°ïŒHïŒ-æåŸã®æ°åŠçæäœã®çµæãšããŠãäžäœããŒããã€ãããã®è»¢éãçºçããå Žåããã©ã°ãèšå®ãããŸãã
- ãã£ãªãŒãã©ã°ïŒCïŒ-æåŸã®æ°åŠçæäœã®çµæãšããŠè»¢éãçºçããå Žåããã©ã°ãèšå®ãããŸãã
ãæ³åã®ãšãããã¬ãžã¹ã¿PCïŒããã°ã©ã ã«ãŠã³ã¿ãŒïŒã¯åœä»€ã«ãŠã³ã¿ãŒã§ããã次ã®åœä»€ã®ã¢ãã¬ã¹ãå«ãŸããŠããŸãã
SPã¬ãžã¹ã¿ïŒã¹ã¿ãã¯ãã€ã³ã¿ãŒïŒã¯ããããããã¹ã¿ãã¯ã®æäžéšãžã®ãã€ã³ã¿ãŒã§ãã ç¥èã®ãªã人ã«ãšã£ãŠã¯ãã¹ã¿ãã¯ã¯å€æ°ã®å€ãæ»ãã¢ãã¬ã¹ãªã©ãæžã蟌ãŸããã¡ã¢ãªé åã§ãã SPã«ã¯ãã¹ã¿ãã¯ã®æäžäœã®ã¢ãã¬ã¹ãå«ãŸããŸã-ã¹ã¿ãã¯ã¯ãé«ããäœã«æé·ããŸãã 圌ã«ãšã£ãŠã¯ãåžžã«å°ãªããšã2ã€ã®æäœããããŸãã PUSHã䜿çšãããšãç¹å®ã®å€ãæ¿å ¥ã§ããŸãããŸããSPã¬ãžã¹ã¿ãåæžããã次ã«æ°ããå€ãæ¿å ¥ãããŸãã POPã䜿çšãããšãå€ãååŸã§ããŸãããŸããã¢ãã¬ã¹SPã§å€ãã¡ã¢ãªããååŸããã次ã«SPãå¢å ããŸãã
ããã»ããµã«ã¯ãããããIMEïŒå²ã蟌ã¿ãã¹ã¿ãŒã€ããŒãã«ïŒãå«ãŸããŠããŸããããã¯ãå²ã蟌ã¿åŠçãèš±å¯ãããã©ã°ã§ãã ãããããç¡å¹ïŒ0ïŒãšæå¹ïŒ1ïŒã®2ã€ã®å€ãåããŸãã
çè«ã«ããããã¹ãŠã®å®è£ ãéå§ã§ããŸãã 8ãããã®ã¬ãžã¹ã¿ãš16ãããã®ãã¢ã®äž¡æ¹ã䜿çšããå¿ èŠãããããããããæäœã䜿çšããã«ããããšã¬ãžã¹ã¿ã®äž¡æ¹ã«åæã«ã¢ã¯ã»ã¹ã§ããã¡ã«ããºã ãå®è£ ããããšããå§ãããŸãã ãããè¡ãã«ã¯ã次ã®ã¿ã€ãã宣èšããŸãã
union WordRegister { struct { BYTE L; BYTE H; } bytes; WORD word; };
ããã»ããµã¬ãžã¹ã¿ããã¢ãšããŠä¿åããWordRegisterã¢ãœã·ãšãŒã·ã§ã³ã®ãããã§åã ã®ããŒãã«ã¢ã¯ã»ã¹ã§ããŸãã ã¯ãŒããã£ãŒã«ãã¯ã16ãããã¬ãžã¹ã¿å šäœãžã®ã¢ã¯ã»ã¹ãæäŸããŸãã ããã€ãããã£ãŒã«ãã¯ããã¢ã®åã ã®ã¬ãžã¹ã¿ãžã®ã¢ã¯ã»ã¹ãæäŸããŸãã å¯äžã®ããšã¯ãã¬ãžã¹ã¿AãšFãå¥ã ã«ä¿åããããšã§ãã ã¬ãžã¹ã¿Aã¯ããããªãŒã§ãããããé »ç¹ã«äœ¿çšãããŸãã ã¬ãžã¹ã¿Fã§ã®åæ§ã®ç¶æ³-ããã»ããµãââã©ã°ã¯ãããªãé »ç¹ã«èšå®ããå¿ èŠããããŸãã
ããã»ããµèªäœã®å®è£ ãéå§ããŸããã-Cookieboy :: CPUã¯ã©ã¹ããããæ åœããŸãã åœä»€ã®èªã¿åããšå®è¡ã¯ãéåžžã®æ¹æ³ã§å®è£ ãããŸã-ã¡ã¢ãªãããªãã³ãŒããèªã¿åããã¹ã€ããæ§æã䜿çšããŠãã³ãŒãããã³å®è¡ããŸãïŒ
BYTE opcode = MMC.Read(PC); PC++; switch (opcode) { case 0x00: break; }
ãã¹ãŠã®ãªãã³ãŒãã®é·ãã¯1ãã€ãã§ãããäžéšã®åœä»€ã¯ãããããã¬ãã£ãã¯ã¹ã䜿çšããŸã-æåã®ãã€ãã¯åœä»€ã»ããã®ãã¬ãã£ãã¯ã¹ã§ãïŒç§ãã¡ã«ãšã£ãŠå¯äžã®ãã¬ãã£ãã¯ã¹ã¯0xCBã§ãïŒã2çªç®ã®ãã€ãã¯ãã®ã»ããã®ãªãã³ãŒãã§ãã å®è£ ã¯åºæ¬çã§ãã0xCBã«åºäŒã£ããããã«ãå¥ã®ãã€ããèªã¿åãããã¹ããããã¹ã€ããã§ãã³ãŒãããŸãã
ãã®ã³ãŒãã¯ã1ã€ã®åŒã³åºãã§1ã€ã®ããã»ããµåœä»€ãå®è¡ããä»ã®å¿ èŠãªæäœãå®è¡ããvoid StepïŒïŒé¢æ°ã«é 眮ãããŸãã
åœç¶ãã¡ã¢ãªã®èªã¿åããšæžã蟌ã¿ã«ã¯ãå¥ã®ã¯ã©ã¹-Cookieboy :: Memoryãå¿ èŠã§ãããã®ãªããžã§ã¯ãã¯ãäžèšã® "MMC"ãšããååã§èŠãããšãã§ããŸãã ãã®æ®µéã§ã¯ãåºæ¬çãªã¡ãœãããæã€ã¹ã¿ãã§ååã§ãã
class Memory { public: void Write(WORD addr, BYTE value); BYTE Read(WORD addr); };
DMGããã»ããµã«ã¯ããªãå€æ°ã®åœä»€ãããããã®ãªã¹ãã¯Gameboy CPUããã¥ã¢ã«ã«èšèŒãããŠããŸãã ãŸããã©ã®ããã»ããµãââã©ã°ãèšå®ããå¿ èŠãããããååœä»€ã«å¿ èŠãªã¯ããã¯ãµã€ã¯ã«æ°ã瀺ããŸãã ãã©ã°ã®èª¬æã泚ææ·±ãèªãã§ãã ãã-ãã©ã°ã®èšå®ãæ£ããå®è£ ãããŠããªããšããã°ãã°ã²ãŒã ãåäœããªããªãããããã°ãæ·åã«å€ãããŸãã ããããç§ã¯å°ãå®å¿ããŸã-ããã»ããµãââã©ã°çšã®ãã¹ãROMããããŸãããROMã®å®è¡ã«ã¯ãŸã çšé ãã§ãã
察çãšããã°ã ããã8ãååã«åçŽã§ããããã®ãšãã¥ã¬ãŒã·ã§ã³ãåœä»€å®è¡ã®é·ããèæ ®ããå¿ èŠããªãã£ãå ŽåãDMGã§ã¯ç¶æ³ãç°ãªããŸãã ã³ã³ãœãŒã«ã®ã³ã³ããŒãã³ãã¯äœãšãæ©èœããŸããããã¯ããã¯ãžã§ãã¬ãŒã¿ãŒã䜿çšããŠåæãããŸãã ç§ãã¡ã«ãšã£ãŠãããã¯ããšãã¥ã¬ãŒã¿ã®ãã¹ãŠã®ã³ã³ããŒãã³ãã®åäœãããã»ããµãšåæããå¿ èŠãããããšãæå³ããŸãã
ãã®åé¡ã解決ããã®ã¯éåžžã«ç°¡åã§ãã ããã»ããµã¯ããšãã¥ã¬ãŒã¿ã®äžå¿çãªãªã³ã¯ã§ãã æ瀺ã«åŸã£ãŠããã¹ãŠã®ã³ã³ããŒãã³ããçžäºã«åæãããããã«ããã»ããµããµã€ã¯ã«ã§è²»ãããæéãä»ã®ã³ã³ããŒãã³ãã«è»¢éããŸãã ãããè¡ãã«ã¯ãSYNC_WITH_CPUãã¯ãïŒclockDeltaïŒã䜿çšããŸãããã®ãã¯ãã¯ãåœä»€ã®å®è¡ã«ããã»ããµãŒãè²»ãããæéã転éããŸãã ãšãã¥ã¬ãŒã¿ã®æ®ãã®ã³ã³ããŒãã³ãã®åææ©èœããã§ã«åŒã³åºããŠããŸãã åæã®åé¡ã®è§£æ±ºçã¯ãããã»ããµã®ã¯ã©ã¹ã§ã¯ãªããŠããããã»ããµã®ã¯ã©ã¹ãè¶ ããŠç°¡åã«ç§»åã§ããŸãã
ã³ã³ãœãŒã«ã®ã³ã³ããŒãã³ãã¯åæã«åäœããããã»ããµãåœä»€ã®å®è¡ãå®äºãããŸã§èª°ãåŸ ã¡ãŸããã äžéšã®åœä»€ã¯å®è¡ã«æéããããããã®éçšã§ããŒã¿ãã¡ã¢ãªã«èªã¿æžããããŸãã ããã»ããµã¯ããæ³åã®ãšãããã¡ã¢ãªã®èªã¿åã/æžã蟌ã¿ã«äžå®ã®æéãè²»ãããŸãïŒ4ã¯ããã¯ãµã€ã¯ã«ïŒã ããã¯ãå®è¡äžã«ã¡ã¢ãªã®å 容ãå€æŽãããå¯èœæ§ããããšããäºå®ã«ã€ãªãããŸãããã¡ãããããããšãã¥ã¬ãŒãããããšããå§ãããŸãã
ãã®å Žåãå®è¡ããã»ã¹ã§åæãã¯ããæ°å䜿çšããå¿ èŠããããŸããããã«ãããèªã¿åããŸãã¯æžã蟌ã¿æã«æ£ããããŒã¿ãã¡ã¢ãªå ã«ãããŸããã ã»ãšãã©ã®åœä»€ã¯ããã®ãããªæ£ç¢ºãªåæãå¿ èŠãšãããå®è¡åŸã«å®è¡ã§ããããã«ããŸãã ãã®ä»ã«ã¯ãåææ©èœãšã¡ã¢ãªã®èªã¿åã/æžã蟌ã¿æäœã®æ£ç¢ºãªã·ãŒã±ã³ã¹ãå¿ èŠã§ãã
ããã«ãããããããç°ãªãæ¹æ³ã§è¡ãæ¹ãããæ£ç¢ºã§çŸããã§ãã 1ãã€ãã®ã¡ã¢ãªããã®åæžã蟌ã¿ãŸãã¯èªã¿åãæäœã«ã¯4ã¯ããã¯ãµã€ã¯ã«ãããããšã確å®ã«ããã£ãŠããŸãã è£å©çãªèªã¿åãããã³æžã蟌ã¿é¢æ°ãè¿œå ããã ãã§ååã§ããããããèªäœãåæé¢æ°ãåŒã³åºããŸãã ãããå®è¡ããããšããã«ãå®éã®å®è¡æéã¯èªã¿åãããã³æžã蟌ã¿æäœã§æ§æããããããã»ãšãã©ã®åœä»€ã¯ããã«æ£ããæéãèŠã€ããŸãã ã³ãã³ãã®ãªãã³ãŒãã®ååŸãããã«é©çšãããŸãã ããã¯ãŸãã«ãšãã¥ã¬ãŒã¿ãŒã§è¡ã£ãããšã§ãæåã®åæãšã¿ã€ãã³ã°ããã»ãŒå®å šã«è§£æŸãããŸããã ç§ã®ä»å ¥ãå¿ èŠãªæ瀺ã¯ãããã§ããã
次ã«ãããŒã䜿çšããŠç¶æ³ãæ確ã«ããããã«å°ãè±ç·ããŸãããã ããŸããŸãªããã¥ã¡ã³ãã«æ··ä¹±ããããŸãã ããšãã°ãNOPã®æéã4å°ç¯ããã®ä»ã®å°ç¯-1å°ç¯ãªã©ãæ°åãèšè¿°ããããã¥ã¡ã³ãããããŸãïŒããšãã°ã任倩å ã®å ¬åŒããã¥ã¡ã³ãã«èšèŒãããŠããŸãïŒã çç±ãç解ããã«ã¯ãçè«ã«å°ã泚æãããã䟡å€ããããŸãã
ããã»ããµåœä»€ã«ã¯ããã·ã³ãµã€ã¯ã«ãšåŒã°ããç¹å®ã®æéããããŸãã 1ãã·ã³ãµã€ã¯ã«ã§ãããã»ããµã¯ãªãã³ãŒãã®èªã¿åãããã³ãŒããã³ãã³ãã®å®è¡ãªã©ã1ã€ã®ã¢ã¯ã·ã§ã³ãå®è¡ã§ããŸãã ã¡ã¢ãªå ã®å€ã®èªã¿åããŸãã¯æžã蟌ã¿ã ããã»ããµã¯1ã€ã®ãã·ã³ãµã€ã¯ã«ã§è€æ°ã®æäœãå®è¡ã§ããããããã·ã³ãµã€ã¯ã«ã¯ãã·ã³ãµã€ã¯ã«ã§æ§æãããŸãã ãããŠãç§ãã¡ã¯ããã»ããµã«æ¥ãŸãã NOPã4ãµã€ã¯ã«ç¶ããšèšãã°ããã·ã³ãµã€ã¯ã«ã®ããšã§ãã NOPã®1ã¯ããã¯ãµã€ã¯ã«ã«ã€ããŠè©±ããŠããå Žåããã·ã³ãµã€ã¯ã«ã«ã€ããŠè©±ããŠããããšã«ãªããŸãã ããã¯ãŸãã«DMGããã»ããµãŒã®ä»çµã¿ã§ã-ãã®ãã·ã³ãµã€ã¯ã«ã¯4ãã·ã³ãµã€ã¯ã«ç¶ããå€ãã®åœä»€ã«ã¯æ£ç¢ºã«4ãµã€ã¯ã«ãŸãã¯1ãã·ã³ãµã€ã¯ã«ããããŸã-DMGããã»ããµãŒã¯ã¡ã¢ãªãããªãã³ãŒããèªã¿åãããã³ãŒãããããã4ãã·ã³ãµã€ã¯ã«ã§åœä»€ãå®è¡ã§ããŸãã
以äžã§ã¯ããã銎æã¿ã®ãããã·ã³ã¯ããã¯ã䜿çšããŸãã ãããã¯ãã¯ããã¯ãžã§ãã¬ãŒã¿ãŒã®1åšæã«å¯Ÿå¿ããŸããã€ãŸãããããã¯ãšãã¥ã¬ãŒã¿ã«ãšã£ãŠæå°ã§åå²ã§ããªãæéåäœã§ãã ãããã£ãŠãNOPæäœã¯4ã¡ãžã£ãŒç¶ããŸãã
ãã®æ®µéã§ã¯ããã¹ãŠã®ããã»ããµåœä»€ãå®å šã«ãšãã¥ã¬ãŒãããããšããã§ã«å¯èœã§ãã ãããšã¯å¥ã«ããããã®ããã€ãã«èšåãã䟡å€ããããŸãïŒ
- HALTã«ã¯ãCPUããã¥ã¢ã«ïŒ2.7.3ãäœé»åã¢ãŒãïŒã§èª¬æãããŠãããããªãèå³æ·±ãåäœããããŸãã é¡ã決å®ãããšãHALTåœä»€ãã¹ãã倱æããŸãã ããã§ã¯ãåœä»€èªäœã®å®è£ ãšå²ã蟌ã¿ãã³ãã©ãŒã®å®è£ ã®äž¡æ¹ã«æ³šæããå¿ èŠããããŸãïŒããã«ã€ããŠã¯åŸã§èª¬æããŸãïŒã åœä»€ã®å®è£ ã¯ãIMEããŒãã§ãçŸæç¹ã§åŠçããå¿ èŠã®ããå²ã蟌ã¿ããªãå Žåã«ã®ã¿ãå®è¡ãäžæåæ¢ããã«èšåããããã°ã«ã€ãªãããããªãã®ã§ãïŒããã«ã€ããŠã¯åŸã§èª¬æããŸãïŒ-ããã¯ã»ãšãã©ã®ããã¥ã¡ã³ãã§çç¥ãããŠããæåŸã®ãã€ã³ãã§ãã ãã以å€ã®å Žåããã°ã¯ãªããå®è¡ã¯äžæãããŸãã åœç¶ãã¯ããã¯ãžã§ãã¬ãŒã¿ãŒãšä»ã®ãã¹ãŠã®ã³ã³ããŒãã³ãã¯äœæ¥ãç¶ç¶ããŸããã€ãŸããåæé¢æ°ãåŒã³åºãç¶ãã4ã€ã®ã¡ãžã£ãŒãåŒæ°ãšããŠäžããå¿ èŠããããŸãïŒãã®ã¢ãŒãã§1ã¯ããã¯ãµã€ã¯ã«ãã«ãŠã³ãããããšã¯æå³ããããŸããïŒã ããã»ããµãNOPãå®è¡ããŠããããã§ãã
- POP AFã§ã¯ãFã¬ãžã¹ã¿ã«æªäœ¿çšã®ãããããããšããäºå®ãèæ ®ãã䟡å€ããããŸãã ãããè¡ãã«ã¯ãã¬ãžã¹ã¿Fã®å 容ãã¹ã¿ãã¯ããåé€ãããåŸãã¬ãžã¹ã¿Fã®äžäœ4ãããããªã»ããããå¿ èŠããããŸãã
- åœä»€RLCAãRLAãRRCAãRRAã¯ãã¬ãžã¹ã¿Fã®ãã©ã°Zãåžžã«ãªã»ããããŸãã
ãããã®æ¬ ç¹ã«å ããŠãä»ã«ããããŸãã CPUããã¥ã¢ã«ã«ã¯ãåœä»€ã®æéã«é¢ããäžå®å šãªèª¬æãå«ãŸããŠããŸãã ãæ³åã®ãšãããæ¡ä»¶åå²åœä»€ã¯ãåå²ãçºçãããã©ããã«å¿ããŠç°ãªãæéãæã€å¿ èŠããããŸãã ãã¹ãROMã䜿çšããããšãã§ããŸããããããã®åœä»€ã®ããã«åç¬ã§ã¯æ£åžžã«åäœããªãããããã¹ããéå§ããªããŠãäžæãªãšã©ãŒã衚瀺ãããŸãã ãããã®æ瀺ã®æéã瀺ãè¡šã¯æ¬¡ã®ãšããã§ãã
ãªãã³ãŒã | 移è¡ã¯çºçããŸããã§ãã | 移è¡ãçºçããŸãã |
0xC2ã0xCAã0xD2ã0xDA | 12 | 16 |
0x20,0x28,0x30,0x38 | 8 | 12 |
0xC4ã0xCCã0xD4ã0xDC | 12 | 24 |
0xC0,0xC8,0xD0,0xD8 | 8 | 20 |
ãŸããåœä»€RST nïŒãªãã³ãŒã0xC7ã0xCFã0xD7ã0xDFã0xE7ã0xEFã0xF7ã0xFFïŒã®é·ããééã£ãŠããŸãã æ£ããå€ã¯16ã¡ãžã£ãŒã§ãã
ãã®ãããçŸæç¹ã§ã¯ããããã»ããµãã¯ã¡ã¢ãªããåœä»€ãèªã¿åããå®è¡ããä»ã®ã³ã³ããŒãã³ããããèªäœãšåæã§ããŸãïŒåæäžããããã¯ãã¹ãŠãããŒé¢æ°ã§ãïŒã ãã®åŸããã¹ãŠã®äœæ¥ãå®äºããåŸã«äžæããã£ããã©ããã確èªããå¿ èŠããããŸãã
äžæ
å²ã蟌ã¿ã¯ãçŸåšã®ããã»ããµåœä»€ã®å®è¡ãäžæåæ¢ããå¶åŸ¡ãå²ã蟌ã¿ãã³ãã©ã«è»¢éããã€ãã³ãã§ãã DMGã¯ãã®ååã«åºã¥ããŠæ©èœããŸããåæäžã«ããšãã¥ã¬ãŒã¿ã®ä»ã®ã³ã³ããŒãã³ãã®åæã¡ãœãããåŒã³åºããŠãå²ã蟌ã¿ãèŠæ±ããå ŽåããããŸãã DMGã§ã¯ãããã¯æ¬¡ã®ããã«è¡ãããŸãã IFïŒå²ã蟌ã¿ãã©ã°ïŒãšIEïŒå²ã蟌ã¿ã€ããŒãã«ïŒã®2ã€ã®ã¬ãžã¹ã¿ããããŸãïŒãããã®å Žæã«ã€ããŠã¯åŸã§èª¬æããŸãïŒã ãããã®ãããã«ã¯ç¹å®ã®ç®çããããäž¡æ¹ã®ã¬ãžã¹ã¿ã§åãã§ãã
ããã | äžæ |
4 | ãžã§ã€ããã |
3 | ã·ãªã¢ã«I / O転éå®äº |
2 | ã¿ã€ããŒãªãŒããŒãã㌠|
1 | LCDC |
0 | Vãã©ã³ã¯ |
IFã¬ãžã¹ã¿ãããã¯ãã©ã®å²ã蟌ã¿ãèŠæ±ããããã瀺ããŸãã ããããèšå®ãããŠããå Žåãå²ã蟌ã¿ãèŠæ±ãããŸãã
IEã¬ãžã¹ã¿ãããã¯ãå²ã蟌ã¿åŠçãæå¹ã«ããŸãã ãããã1ã«èšå®ããã察å¿ããå²ã蟌ã¿ãèŠæ±ãããå ŽåãåŠçãããŸãã ããã§ãªãå Žåãå²ã蟌ã¿ã¯åŠçãããŸããã
ã芧ã®ãšããããããã®åäžã®å²ãåœãŠã¯éåžžã«äŸ¿å©ã§ãããè«çæŒç®ANDã䜿çšããŠãã©ã®å²ã蟌ã¿ãåŠçããå¿ èŠãããããèŠã€ããããšãã§ããŸãã
éèŠãªè©³çŽ°ã®1ã€ã¯ãå²ã蟌ã¿ã«ãããHALTãŸãã¯STOPã®å®è¡ã®çµæãšããŠçºçããã·ã£ããããŠã³ç¶æ ããããã»ããµã埩垰ããããšã§ãã ãããŠãããã§å²ã蟌ã¿ã¬ãžã¹ã¿ããã§ãã¯ãããã¢ã«ãŽãªãºã ã¯éåžžã«éèŠã§ãã ã¢ã«ãŽãªãºã ã¯æ¬¡ã®ãšããã§ãã
- åŠçãã䟡å€ã®ããå²ã蟌ã¿ããããã©ããã確èªããŸãã ããã¯ãIEã¬ãžã¹ã¿ãšIFã¬ãžã¹ã¿éã®è«çANDæŒç®ã䜿çšããŠè¡ãããŸãã ãŸããæäžäœã®3ãããã¯äž¡æ¹ã®ã¬ãžã¹ã¿ã§äœ¿çšãããªããããçµæãšæ°å€0x1Fã§è«çANDæŒç®ãå®è¡ããŠãçºçããå¯èœæ§ã®ãããŽããåé€ãã䟡å€ããããŸãã
- ãã®ãããªäžæããªããã°ãé¢æ°ãçµäºããŸãã ãããããªããä»ããã«ããã»ããµãã·ã£ããããŠã³ç¶æ ãã埩垰ãããªããã°ãªããŸããã
- çŸåšãå²ã蟌ã¿ã®åŠçãéå§ããŠããŸãã ãããè¡ãããã«ãIMEãã©ã°ãåŠçãçŠæ¢ããŠãããã©ããã確èªããŸãã ããã§ãªãå ŽåïŒ
- ãŒãIME;
- PCã¬ãžã¹ã¿ãã¹ã¿ãã¯ã«ããŒãããŸãã
- PCã¬ãžã¹ã¿ãã¡ã¢ãªå ã®ãã³ãã©ãŒã®ã¢ãã¬ã¹ã«èšå®ããŠãå²ã蟌ã¿ãã³ãã©ãŒãåŒã³åºããŸãã
- IFã¬ãžã¹ã¿ããããåŠçæžã¿ã®å²ã蟌ã¿ã«èšå®ããŸãã
å²ã蟌ã¿ã¯äžåºŠã«1ã€ãã€ãå³å¯ã«å®çŸ©ãããé åºã§åŠçãããŸãã ãã³ãã©ãŒã®åªå é äœãšã¢ãã¬ã¹ã«é¢ãããã¹ãŠã®æ å ±ã¯ãCPUããã¥ã¢ã«ã«ç€ºãããŠããŸãã
éèŠãªè©³çŽ°ã ç¹°ãè¿ãã«ãªããŸããã誰ããèãããããããŸããïŒå²ã蟌ã¿ã®åŠçã¯ããã·ãŒãžã£ã®åŒã³åºããšéåžžã«äŒŒãŠãããããæéããããã¯ãã§ãã ããã¯äºå®ã§ããã20ã®å¯Ÿçãå¿ èŠã§ãã äœããã®çç±ã§ãDMGã説æããããã¥ã¡ã³ãã§ã¯ãã®ç¹ã¯çç¥ãããŠããŸãã
次ã«ãå®è£ ãéå§ããŸãã cookieboy :: Interruptsã¯ã©ã¹ã察åŠããŸãã IEããã³IFã¬ãžã¹ã¿ãé 眮ãããããã®ã¬ãžã¹ã¿ã«ã¢ã¯ã»ã¹ããé¢æ°ã宣èšããŸãïŒåŸã§å¿ èŠã«ãªããŸãïŒããŸããç¹å®ã®å²ã蟌ã¿ãèŠæ±ã§ããé¢æ°ïŒäœããã®å²ã蟌ã¿ãèŠæ±ãããã³ã«ããããæäœããå¿ èŠã¯ãããŸããïŒ ã ãŸããåŠçãã䟡å€ã®ããå²ã蟌ã¿ããã§ãã¯ããé¢æ°ãå¿ èŠã§ãã ãã®é¢æ°ã®åŒã³åºããããã»ããµã®ã¹ãããé¢æ°ã®æåŸã«é 眮ããããã«ã³ã³ããŒãã³ããåæããŸãã
å²ã蟌ã¿èŠæ±ã«ã€ããŠå°ãã ããã¯ãIFã¬ãžã¹ã¿ã®å¯Ÿå¿ããããããèšå®ããããšã«ããè¡ãããŸãã ã€ã³ã¹ããŒã«åã«ãIEã±ãŒã¹ã®æ€èšŒã¯å¿ èŠãããŸããã ãã®äžã®ããããç¹å®ã®å²ã蟌ã¿ãçŠæ¢ããŠããå Žåã§ãããã®å²ã蟌ã¿ã®ããã«IFã¬ãžã¹ã¿ã®ããããèšå®ããŸãã
Cookieboy :: Interruptsã®å®è£ ã®ãœãŒã¹ã³ãŒããèŠããšã䜿çšãããŠããªããã¹ãŠã®ãããã1ã«èšå®ããåŸïŒå€0xE0ãšã®ORæŒç®ïŒãIEããã³IFã¬ãžã¹ã¿ã®å€ãè¿ããŠããããšã«æ°ä»ããããããŸããã ç§ã«ã¯çç±ããããŸãã I / OããŒãã®å€ãã®ã¬ãžã¹ã¿ïŒä»¥äžã§è©³ãã説æããŸãïŒã¯ãã¹ãŠã®ãããã䜿çšããããã§ã¯ãããŸããããä»ã®ã¬ãžã¹ã¿ã¯äžéšã®ããããŸãã¯ã¬ãžã¹ã¿å šäœãžã®èªã¿åãã¢ã¯ã»ã¹ãäžåºŠã«å¶éããŸãã ãããèæ ®ã«å ¥ããå¿ èŠããããŸãããã®ãããæªäœ¿çšã§èªã¿åãçŠæ¢ã®ããããè¿ãåã«1ã«èšå®ããå¿ èŠããããŸãã
ãŸãšãããšã ãšãã¥ã¬ãŒã¿ã¯ããã»ããµåœä»€ãå®è¡ãããšãã¥ã¬ãŒã¿ã®ãã¹ãŠã®ã³ã³ããŒãã³ããçžäºã«åæãããå²ã蟌ã¿ãåŠçããŸãã 確ãã«ããããŸã§ã®ãšããã¯ãã¹ãŠèšèã ãã§ãã æ¬åœã«æ©èœãããšãã¥ã¬ãŒã¿ãŒãååŸããã«ã¯ãDMGã¡ã¢ãªããšãã¥ã¬ãŒãããå¿ èŠããããŸãã
èšæ¶
äºåã«1ã€ã®çšèª-ã¡ã¢ãªãã³ã¯ãå®çŸ©ããŸãã ããã«ãããå³å¯ã«å®çŸ©ããããµã€ãºã®ã¡ã¢ãªé åãæå³ããŸãã ãã³ã¯ã«ã¯2ã€ã®ã¿ã€ãããããŸã-é·ãã0x4000ãã€ãã®ROMãã³ã¯ãšé·ãã0x2000ã®RAMãã³ã¯ïŒ16é²æ°ã·ã¹ãã ã«æ £ããã°ãç§ã«ãšã£ãŠãããªãã«ãšã£ãŠãç°¡åã«ãªããŸãïŒã ãªããããå¿ èŠãªã®ã§ããïŒ DMGããã»ããµã¯16ãããã¢ãã¬ã¹ãåŠçã§ããŸããã€ãŸããã¢ãã¬ã¹ã¹ããŒã¹ã¯0x10000ãã€ãã«å¶éãããŠããŸãã ãããã®ãã¡ãã²ãŒã ã®ã€ã¡ãŒãžçšã«äºçŽãããŠããã®ã¯0x8000ãã€ãã®ã¿ã§ãã ã»ãšãã©ã®å Žåãããã§ã¯ååã§ã¯ãªããã¡ã¢ãªãã³ã¯ãæ©èœããŸããã¡ã¢ãªãã³ã¯ãªãã§ã¢ãã¬ã¹0x4000-0x7FFFã«ç®ãåãããšãã²ãŒã ã®ã€ã¡ãŒãžã§ãã®ã¢ãã¬ã¹ã«å°éããŸãã ã¡ã¢ãªãã³ã¯ã䜿çšããŠãç»åããã³ã¯ã«åå²ããããã«èšå®ã§ããã¢ãã¬ã¹0x4000-0x7FFFã§éžæãããã³ã¯ã衚瀺ãããŸãã ãããã£ãŠããã®é åã®ããæç¹ã§ã¯2çªç®ã®éè¡ãå¥ã®æç¹ã§ã¯10çªç®ã§ãã ç§ãã¡ãæãããã«ãäžè¬çã«ã ãããã£ãŠãä»®æ³ã¢ãã¬ã¹ãšç©çã¢ãã¬ã¹ã«å°éããŸãã 0x4000-0x7FFFã¯ãç©çã¢ãã¬ã¹ãšäžèŽããå¿ èŠã®ãªãä»®æ³ã¢ãã¬ã¹ã§ãã ç©çã¢ãã¬ã¹ã¯ãã¡ã¢ãªã»ã«ãã¢ã¯ã»ã¹ãããå®éã®ã¢ãã¬ã¹ã§ãã
ããã¯ãã¹ãŠãDMGã0x8000ãã€ãã ãã§ãªããã¢ãã¬ã¹ç©ºéå šäœãã¯ããã«è¶ ããã²ãŒã ã€ã¡ãŒãžã§åäœã§ããããã«ããããã«å¿ èŠã§ãã èšèã§èšãã°ãããã¯ãã¹ãŠè€éãããããã«æãããããããŸããããå®è£ äžã«ããããã¯èª¬æãããããå®è£ ãç°¡åã§é«éãªéåžžã«åºæ¬çãªãã®ã§ããããšã¯æããã§ãã
RAMã«ãåãããšãåœãŠã¯ãŸããŸãã ãã³ã¯ã䜿çšãããšãã«ãŒããªããžã«ãã€ã¯ããµãŒããããé 眮ããããšã«ãããããªã¥ãŒã ãæ¡åŒµã§ããŸãã ããã«ããã®æ¹æ³ã§ãã«ãŒããªããžã«å èµãããããããªãŒã䜿çšããŠRAMã«é»åãäŸçµŠããæ¬æ Œçãªã¹ãã¬ãŒãžã·ã¹ãã ãå®è£ ã§ããŸãã
ä»®æ³ã¢ãã¬ã¹ãç©çã¢ãã¬ã¹ã«å€æããã¿ã¹ã¯ã¯ãã«ãŒããªããžå ã«ããMBCã³ã³ãããŒã©ãŒã«ãããŸãã ROMé åã§ã®ãã¹ãŠã®èªã¿åãããã³æžã蟌ã¿æäœã¯ããããééããŸãã å€éšRAMã«é¢é£ä»ããããæäœãããã«ãªãã€ã¬ã¯ããããŸãã
åœç¶ãROMã®å 容ãå€æŽããããšã¯ã§ããŸããã æžã蟌ã¿æäœã¯ãMBCã®å¶åŸ¡ã³ãã³ããšããŠäœ¿çšãããŸãã CPUããã¥ã¢ã«ã§ã¯ãã©ã®ã¢ãã¬ã¹ãã©ã®æ©èœãæ åœããŠããã®ããèªãããšãã§ããŸãã ãããã£ãŠãç¹å®ã®ã¢ãã¬ã¹ã«çªå·9ãæžã蟌ãã ã®ã§ããã³ã¯9ãéžæããããšèšããŸãããã®åŸã0x4000-0x7FFFã«é£çµ¡ããŠãã®å 容ãèªã¿åãããšãã§ããŸãã
次ã®å³ã¯ãæãåçŽãªMBCæäœã¹ããŒã ã瀺ããŠããŸãã ããã§ã¯ãäžéšã®å®éã®ã³ã³ãããŒã©ãŒãšåæ§ã«ãé å0x0000-0x3FFFã¯åžžã«ãã³ã¯0ã«ãªãã€ã¬ã¯ããããŸãããé å0x4000-0x7FFFã¯çŸåšã®ãã³ã¯ã«ãªãã€ã¬ã¯ããããŸãã
DMGã¢ãã¬ã¹ç©ºéã¹ããŒã ãæ€èšããŠãã ããã
èšæ¶éš | éå§ã¢ãã¬ã¹ | çµäºäœæ |
ROMãã³ã¯0 | 0x0000 | 0x3FFF |
åãæ¿ãå¯èœãªROMãã³ã¯ | 0x4000 | 0x7FFF |
ãããªã©ã | 0x8000 | 0x9FFF |
åãæ¿ãå¯èœãªã©ã ãã³ã¯ | 0xA000 | 0xBFFF |
å èµRAM 1 | 0xC000 | 0xDFFF |
å èµRAM 1ã®ãšã³ãŒ | 0xE000 | 0xFDFF |
ãªãŒã | 0xFE00 | 0xFE9F |
æªäœ¿çš | 0xFEA0 | 0xFEFF |
I / OããŒã | 0xFF00 | 0xFF4B |
æªäœ¿çš | 0xFF4C | 0xFF7F |
å èµRAM 2 | 0xFF80 | 0xFFFE |
å²ã蟌ã¿èš±å¯ã¬ãžã¹ã¿ | 0xFFFF | 0xFFFF |
åã»ã¯ã·ã§ã³ã®è©³çŽ°ïŒ
- ROMãã³ã¯0ãåãæ¿ãå¯èœãªROMãã³ã¯ã ãããã®é åã¯ãã§ã«æ€èšæžã¿ã§ãã
- ãããªRAMã ã°ã©ãã£ãã¯ã¹ãå®è£ ãããšãã¯ã詳现ãæ€èšããŸãã
- å éšRAM 1. DMGå ã®RAMã
- å éšRAM 1ã®ãšã³ãŒãããã¯ãå éšRAM 1ã®å 容ãè€è£œããŸãã
- OAM ããã¯ãã¹ãã©ã€ãã®èª¬æãä¿åãããå Žæã§ãã
- I / OããŒãã ããã§ãä»ã®DMGã³ã³ããŒãã³ãã®ã¬ãžã¹ã¿ã«ã¢ã¯ã»ã¹ã§ããŸãã
- å éšRAM 2. DMGå ã®RAMã
- å²ã蟌ã¿ã€ããŒãã«ã¬ãžã¹ã¿ã ãã®ã¬ãžã¹ã¿ã¯ãç¹å®ã®å²ã蟌ã¿ã®åŠçãæå¹ã«ãããã©ã°ãæ ŒçŽããŸãã ããã¯ããã§ã«èª¬æãããã®ãšåãIEã¬ãžã¹ã¿ã§ãã
ãšãã¥ã¬ãŒã¿ã®ã¢ãŒããã¯ãã£ã¯åDMGã³ã³ããŒãã³ããç¬èªã®ã¯ã©ã¹ãæã£ãŠããããšãåæãšããŠãããããã¡ã¢ãªããšãã¥ã¬ãŒãããCookieboy :: Memoryã¯ã©ã¹ã«ã¯ãROMãã³ã¯ãå éšRAM 1ãå éšRAM 1ã®ãšã³ãŒãåãæ¿ãå¯èœãªRAMãã³ã¯ãå éšRAMã®ã¿ãå«ãŸããŸã2.ä»ã®ãã¹ãŠã®é åã«ã¢ã¯ã»ã¹ãããšã察å¿ããã¯ã©ã¹ã®ã¢ã¯ã»ã¹ã¡ãœãããåŒã³åºãããŸãã
ã¡ã¢ãªå ã®èªã¿åãããã³æžã蟌ã¿æäœããå§ããŸãããã ãã¹ãŠãéåžžã«ç°¡åã§ã-ã¢ãã¬ã¹ãèŠãŠã察å¿ããã¡ã¢ãªé åã«æäœããªãã€ã¬ã¯ãããŸãã ç§ã¯æ¬¡ã®ããã«ããŸããã ã芧ã®ãšãããå€ãã®ã¡ã¢ãªé åãé©åã«é 眮ãããŠãããããã¹ã€ãããšè«çæŒç®ã䜿çšããŠãã¹ãŠãå®è£ ã§ããŸãã ããã¯æ¬¡ã®ãããªãã®ã§ãã
switch (addr & 0xF000) { case 0x8000: case 0x9000: // break; }
ãããŠãããã°ãæ¡ä»¶æ§é ã¯ãããŸããã çŸæç¹ã§ã¯ãã¡ã¢ãªã®äžéšã®é åã¯ãŸã å®è£ ãããŠããªãä»ã®ã¯ã©ã¹ïŒãããªã¡ã¢ãªãªã©ïŒã«ããããã空çœã®ãŸãŸã«ããããšãã§ããŸãã Cookieboy :: Memoryã«ãããã®ã ããå®è£ ã§ããŸãã ããã§ã¯ãROMãã³ã¯ãšåãæ¿ãå¯èœRAMãã³ã¯ã«æ³šæãã䟡å€ããããŸãã
ROMãåãå€ããã«ãŒããªããžã«MBCã³ã³ãããŒã©ãŒãå«ãŸããŠããå Žåããããã®ã¡ã¢ãªãŒé åã«ãããã®ã³ã³ãããŒã©ãŒã®ããžãã¯ãå®è£ ããå¿ èŠããããŸãã ããã¯éåžžã«ç°¡åã«å®è¡ã§ããŸãããããã®é åãžã®ã¢ã¯ã»ã¹ã¯ã察å¿ããMBCã³ã³ãããŒã©ãŒã«ãã£ãŠå®è£ ãããã¯ã©ã¹ã«ãªãã€ã¬ã¯ããããã©ãã§ãã©ã®ããã«ãäœã決å®ã§ããããã«ãªããŸãã MBC 2ãšMMM01ã®2ã€ã®äŸãèŠãŠã¿ãŸãããã æåã®äŸã¯ãæ®ãã®å®è£ ãå¯èœã«ããäŸã§ãã MMM01ã¯ããªãå¥åŠãªMBCã§ãã , MBC. DMG.
MBC. :
const int ROMBankSize = 0x4000; const int RAMBankSize = 0x2000; class MBC { public: virtual void Write(WORD addr, BYTE value) = 0; virtual BYTE Read(WORD addr) = 0; virtual bool SaveRAM(const char *path, DWORD RAMSize); virtual bool LoadRAM(const char *path, DWORD RAMSize); protected: MBC(BYTE *ROM, DWORD ROMSize, BYTE *RAMBanks, DWORD RAMSize) : ROM(ROM), ROMSize(ROMSize), RAMBanks(RAMBanks), RAMSize(RAMSize) {} BYTE *ROM; BYTE *RAMBanks; DWORD ROMOffset; DWORD RAMOffset; DWORD ROMSize; DWORD RAMSize; };
, â Cookieboy::Memory. RAM. , . â RAMBanks , . :
- ROM. .
- RAMBanks. .
- RAMOffset ROMOffset. , .
- ROMSize RAMSize, , . , .
, , MBC2. , , :
class MBC2 : public MBC { public: MBC2(BYTE *ROM, DWORD ROMSize, BYTE *RAMBanks, DWORD RAMSize) : MBC(ROM, ROMSize, RAMBanks, RAMSize) { ROMOffset = ROMBankSize; RAMOffset = 0; } virtual void Write(WORD addr, BYTE value) { switch (addr & 0xF000) { //ROM bank switching case 0x2000: case 0x3000: ROMOffset = value & 0xF; ROMOffset %= ROMSize; if (ROMOffset == 0) { ROMOffset = 1; } ROMOffset *= ROMBankSize; break; //RAM bank 0 case 0xA000: case 0xB000: RAMBanks[addr - 0xA000] = value & 0xF; break; } } virtual BYTE Read(WORD addr) { switch (addr & 0xF000) { //ROM bank 0 case 0x0000: case 0x1000: case 0x2000: case 0x3000: return ROM[addr]; //ROM bank 1 case 0x4000: case 0x5000: case 0x6000: case 0x7000: return ROM[ROMOffset + (addr - 0x4000)]; //RAM bank 0 case 0xA000: case 0xB000: return RAMBanks[addr - 0xA000] & 0xF; } return 0xFF; } };
. ROMOffset ROM. . MBC2 512 4- RAM. , , 512 , 4 .
. MBC. MBC2 ROM. 4 0x2000-0x3FFF. , .. 0x0000-0x3FFF. ROM. , . , , . , . WordZap. ( DMG , , ), .
, 0xFF â DMG , .
, MMM01. , , . ã³ãŒãïŒ
class MBC_MMM01 : public MBC { public: enum MMM01ModesEnum { MMM01MODE_ROMONLY = 0, MMM01MODE_BANKING = 1 }; MBC_MMM01(BYTE *ROM, DWORD ROMSize, BYTE *RAMBanks, DWORD RAMSize) : MBC(ROM, ROMSize, RAMBanks, RAMSize) { ROMOffset = ROMBankSize; RAMOffset = 0; RAMEnabled = false; Mode = MMM01MODE_ROMONLY; ROMBase = 0x0; } virtual void Write(WORD addr, BYTE value) { switch (addr & 0xF000) { //Modes switching case 0x0000: case 0x1000: if (Mode == MMM01MODE_ROMONLY) { Mode = MMM01MODE_BANKING; } else { RAMEnabled = (value & 0x0F) == 0x0A; } break; //ROM bank switching case 0x2000: case 0x3000: if (Mode == MMM01MODE_ROMONLY) { ROMBase = value & 0x3F; ROMBase %= ROMSize - 2; ROMBase *= ROMBankSize; } else { if (value + ROMBase / ROMBankSize > ROMSize - 3) { value = (ROMSize - 3 - ROMBase / ROMBankSize) & 0xFF; } ROMOffset = value * ROMBankSize; } break; //RAM bank switching in banking mode case 0x4000: case 0x5000: if (Mode == MMM01MODE_BANKING) { value %= RAMSize; RAMOffset = value * RAMBankSize; } break; //Switchable RAM bank case 0xA000: case 0xB000: if (RAMEnabled) { RAMBanks[RAMOffset + (addr - 0xA000)] = value; } break; } } virtual BYTE Read(WORD addr) { if (Mode == MMM01MODE_ROMONLY) { switch (addr & 0xF000) { //ROM bank 0 case 0x0000: case 0x1000: case 0x2000: case 0x3000: //ROM bank 1 case 0x4000: case 0x5000: case 0x6000: case 0x7000: return ROM[addr]; //Switchable RAM bank case 0xA000: case 0xB000: if (RAMEnabled) { return RAMBanks[RAMOffset + (addr - 0xA000)]; } } } else { switch (addr & 0xF000) { //ROM bank 0 case 0x0000: case 0x1000: case 0x2000: case 0x3000: return ROM[ROMBankSize * 2 + ROMBase + addr]; //ROM bank 1 case 0x4000: case 0x5000: case 0x6000: case 0x7000: return ROM[ROMBankSize * 2 + ROMBase + ROMOffset + (addr - 0x4000)]; //Switchable RAM bank case 0xA000: case 0xB000: if (RAMEnabled) { return RAMBanks[RAMOffset + (addr - 0xA000)]; } } } return 0xFF; } private: bool RAMEnabled; MMM01ModesEnum Mode; DWORD ROMBase; };
, . â , , . , MMM01 2 , .
, I/O ports. ãªããªã DMG , - . I/O ports DMG: , , , .. , , Cookieboy::Memory . CPU Manual. . , â IF. , Cookieboy::Interrupts. , .. .
â ROM . , DMG.
Bootstrap ROM', DMG. Cookieboy::Memory. , Nintendo. 256 , 0 â .. PC . , 0xFF50. , , â Bootstrap ROM' . , . , .
. Bootstrap ROM , . , ROM, .
, DMG . , . â . , . , . .
, . . PC 0x100 â . , I/O ports , Bootstrap ROM â CPU Manual. , , , Bootstrap ROM. EmulateBIOS, .
, . , . ( MBC-) . CPU Manual. , Bootstrap ROM. , DMG. â Nintendo. ROM Nintendo, Bootstrap ROM. . â CPU Manual. . :
BYTE Complement = 0; for (int i = 0x134; i <= 0x14C; i++) { Complement = Complement - ROM[i] - 1; } if (Complement != ROM[0x14D]) { // }
, MBC .
, , «», . MB, , , .
, .