dcpu.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. #ifdef CPU_CPP
  2. uint8 CPU::dreadb(uint32 addr) {
  3. if((addr & 0x40ffff) >= 0x2000 && (addr & 0x40ffff) <= 0x5fff) {
  4. //$[00-3f|80-bf]:[2000-5fff]
  5. //do not read MMIO registers within debugger
  6. return 0x00;
  7. }
  8. return bus.read(addr);
  9. }
  10. uint16 CPU::dreadw(uint32 addr) {
  11. uint16 r;
  12. r = dreadb((addr + 0) & 0xffffff) << 0;
  13. r |= dreadb((addr + 1) & 0xffffff) << 8;
  14. return r;
  15. }
  16. uint32 CPU::dreadl(uint32 addr) {
  17. uint32 r;
  18. r = dreadb((addr + 0) & 0xffffff) << 0;
  19. r |= dreadb((addr + 1) & 0xffffff) << 8;
  20. r |= dreadb((addr + 2) & 0xffffff) << 16;
  21. return r;
  22. }
  23. uint32 CPU::decode(uint8 offset_type, uint32 addr) {
  24. uint32 r = 0;
  25. switch(offset_type) {
  26. case OPTYPE_DP:
  27. r = (regs.d + (addr & 0xffff)) & 0xffff;
  28. break;
  29. case OPTYPE_DPX:
  30. r = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
  31. break;
  32. case OPTYPE_DPY:
  33. r = (regs.d + regs.y + (addr & 0xffff)) & 0xffff;
  34. break;
  35. case OPTYPE_IDP:
  36. addr = (regs.d + (addr & 0xffff)) & 0xffff;
  37. r = (regs.db << 16) + dreadw(addr);
  38. break;
  39. case OPTYPE_IDPX:
  40. addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
  41. r = (regs.db << 16) + dreadw(addr);
  42. break;
  43. case OPTYPE_IDPY:
  44. addr = (regs.d + (addr & 0xffff)) & 0xffff;
  45. r = (regs.db << 16) + dreadw(addr) + regs.y;
  46. break;
  47. case OPTYPE_ILDP:
  48. addr = (regs.d + (addr & 0xffff)) & 0xffff;
  49. r = dreadl(addr);
  50. break;
  51. case OPTYPE_ILDPY:
  52. addr = (regs.d + (addr & 0xffff)) & 0xffff;
  53. r = dreadl(addr) + regs.y;
  54. break;
  55. case OPTYPE_ADDR:
  56. r = (regs.db << 16) + (addr & 0xffff);
  57. break;
  58. case OPTYPE_ADDR_PC:
  59. r = (regs.pc.b << 16) + (addr & 0xffff);
  60. break;
  61. case OPTYPE_ADDRX:
  62. r = (regs.db << 16) + (addr & 0xffff) + regs.x;
  63. break;
  64. case OPTYPE_ADDRY:
  65. r = (regs.db << 16) + (addr & 0xffff) + regs.y;
  66. break;
  67. case OPTYPE_IADDR_PC:
  68. r = (regs.pc.b << 16) + (addr & 0xffff);
  69. break;
  70. case OPTYPE_IADDRX:
  71. r = (regs.pc.b << 16) + ((addr + regs.x) & 0xffff);
  72. break;
  73. case OPTYPE_ILADDR:
  74. r = addr;
  75. break;
  76. case OPTYPE_LONG:
  77. r = addr;
  78. break;
  79. case OPTYPE_LONGX:
  80. r = (addr + regs.x);
  81. break;
  82. case OPTYPE_SR:
  83. r = (regs.s + (addr & 0xff)) & 0xffff;
  84. break;
  85. case OPTYPE_ISRY:
  86. addr = (regs.s + (addr & 0xff)) & 0xffff;
  87. r = (regs.db << 16) + dreadw(addr) + regs.y;
  88. break;
  89. case OPTYPE_RELB:
  90. r = (regs.pc.b << 16) + ((regs.pc.w + 2) & 0xffff);
  91. r += int8(addr);
  92. break;
  93. case OPTYPE_RELW:
  94. r = (regs.pc.b << 16) + ((regs.pc.w + 3) & 0xffff);
  95. r += int16(addr);
  96. break;
  97. }
  98. return(r & 0xffffff);
  99. }
  100. void CPU::disassemble_opcode(char *output) {
  101. static reg24_t pc;
  102. char t[256];
  103. char *s = output;
  104. if(in_opcode() == true) {
  105. strcpy(s, "?????? <CPU within opcode>");
  106. return;
  107. }
  108. pc.d = regs.pc.d;
  109. sprintf(s, "%.6x ", (uint32)pc.d);
  110. uint8 op = dreadb(pc.d); pc.w++;
  111. uint8 op0 = dreadb(pc.d); pc.w++;
  112. uint8 op1 = dreadb(pc.d); pc.w++;
  113. uint8 op2 = dreadb(pc.d);
  114. #define op8 ((op0))
  115. #define op16 ((op0) | (op1 << 8))
  116. #define op24 ((op0) | (op1 << 8) | (op2 << 16))
  117. #define a8 (regs.e || regs.p.m)
  118. #define x8 (regs.e || regs.p.x)
  119. switch(op) {
  120. case 0x00: sprintf(t, "brk #$%.2x ", op8); break;
  121. case 0x01: sprintf(t, "ora ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
  122. case 0x02: sprintf(t, "cop #$%.2x ", op8); break;
  123. case 0x03: sprintf(t, "ora $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
  124. case 0x04: sprintf(t, "tsb $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  125. case 0x05: sprintf(t, "ora $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  126. case 0x06: sprintf(t, "asl $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  127. case 0x07: sprintf(t, "ora [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
  128. case 0x08: sprintf(t, "php "); break;
  129. case 0x09: if(a8)sprintf(t, "ora #$%.2x ", op8);
  130. else sprintf(t, "ora #$%.4x ", op16); break;
  131. case 0x0a: sprintf(t, "asl a "); break;
  132. case 0x0b: sprintf(t, "phd "); break;
  133. case 0x0c: sprintf(t, "tsb $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  134. case 0x0d: sprintf(t, "ora $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  135. case 0x0e: sprintf(t, "asl $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  136. case 0x0f: sprintf(t, "ora $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
  137. case 0x10: sprintf(t, "bpl $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
  138. case 0x11: sprintf(t, "ora ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
  139. case 0x12: sprintf(t, "ora ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
  140. case 0x13: sprintf(t, "ora ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
  141. case 0x14: sprintf(t, "trb $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  142. case 0x15: sprintf(t, "ora $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  143. case 0x16: sprintf(t, "asl $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  144. case 0x17: sprintf(t, "ora [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
  145. case 0x18: sprintf(t, "clc "); break;
  146. case 0x19: sprintf(t, "ora $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
  147. case 0x1a: sprintf(t, "inc "); break;
  148. case 0x1b: sprintf(t, "tcs "); break;
  149. case 0x1c: sprintf(t, "trb $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  150. case 0x1d: sprintf(t, "ora $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  151. case 0x1e: sprintf(t, "asl $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  152. case 0x1f: sprintf(t, "ora $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
  153. case 0x20: sprintf(t, "jsr $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break;
  154. case 0x21: sprintf(t, "and ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
  155. case 0x22: sprintf(t, "jsl $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
  156. case 0x23: sprintf(t, "and $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
  157. case 0x24: sprintf(t, "bit $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  158. case 0x25: sprintf(t, "and $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  159. case 0x26: sprintf(t, "rol $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  160. case 0x27: sprintf(t, "and [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
  161. case 0x28: sprintf(t, "plp "); break;
  162. case 0x29: if(a8)sprintf(t, "and #$%.2x ", op8);
  163. else sprintf(t, "and #$%.4x ", op16); break;
  164. case 0x2a: sprintf(t, "rol a "); break;
  165. case 0x2b: sprintf(t, "pld "); break;
  166. case 0x2c: sprintf(t, "bit $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  167. case 0x2d: sprintf(t, "and $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  168. case 0x2e: sprintf(t, "rol $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  169. case 0x2f: sprintf(t, "and $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
  170. case 0x30: sprintf(t, "bmi $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
  171. case 0x31: sprintf(t, "and ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
  172. case 0x32: sprintf(t, "and ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
  173. case 0x33: sprintf(t, "and ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
  174. case 0x34: sprintf(t, "bit $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  175. case 0x35: sprintf(t, "and $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  176. case 0x36: sprintf(t, "rol $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  177. case 0x37: sprintf(t, "and [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
  178. case 0x38: sprintf(t, "sec "); break;
  179. case 0x39: sprintf(t, "and $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
  180. case 0x3a: sprintf(t, "dec "); break;
  181. case 0x3b: sprintf(t, "tsc "); break;
  182. case 0x3c: sprintf(t, "bit $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  183. case 0x3d: sprintf(t, "and $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  184. case 0x3e: sprintf(t, "rol $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  185. case 0x3f: sprintf(t, "and $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
  186. case 0x40: sprintf(t, "rti "); break;
  187. case 0x41: sprintf(t, "eor ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
  188. case 0x42: sprintf(t, "wdm "); break;
  189. case 0x43: sprintf(t, "eor $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
  190. case 0x44: sprintf(t, "mvp $%.2x,$%.2x ", op1, op8); break;
  191. case 0x45: sprintf(t, "eor $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  192. case 0x46: sprintf(t, "lsr $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  193. case 0x47: sprintf(t, "eor [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
  194. case 0x48: sprintf(t, "pha "); break;
  195. case 0x49: if(a8)sprintf(t, "eor #$%.2x ", op8);
  196. else sprintf(t, "eor #$%.4x ", op16); break;
  197. case 0x4a: sprintf(t, "lsr a "); break;
  198. case 0x4b: sprintf(t, "phk "); break;
  199. case 0x4c: sprintf(t, "jmp $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break;
  200. case 0x4d: sprintf(t, "eor $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  201. case 0x4e: sprintf(t, "lsr $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  202. case 0x4f: sprintf(t, "eor $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
  203. case 0x50: sprintf(t, "bvc $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
  204. case 0x51: sprintf(t, "eor ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
  205. case 0x52: sprintf(t, "eor ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
  206. case 0x53: sprintf(t, "eor ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
  207. case 0x54: sprintf(t, "mvn $%.2x,$%.2x ", op1, op8); break;
  208. case 0x55: sprintf(t, "eor $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  209. case 0x56: sprintf(t, "lsr $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  210. case 0x57: sprintf(t, "eor [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
  211. case 0x58: sprintf(t, "cli "); break;
  212. case 0x59: sprintf(t, "eor $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
  213. case 0x5a: sprintf(t, "phy "); break;
  214. case 0x5b: sprintf(t, "tcd "); break;
  215. case 0x5c: sprintf(t, "jml $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
  216. case 0x5d: sprintf(t, "eor $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  217. case 0x5e: sprintf(t, "lsr $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  218. case 0x5f: sprintf(t, "eor $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
  219. case 0x60: sprintf(t, "rts "); break;
  220. case 0x61: sprintf(t, "adc ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
  221. case 0x62: sprintf(t, "per $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  222. case 0x63: sprintf(t, "adc $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
  223. case 0x64: sprintf(t, "stz $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  224. case 0x65: sprintf(t, "adc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  225. case 0x66: sprintf(t, "ror $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  226. case 0x67: sprintf(t, "adc [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
  227. case 0x68: sprintf(t, "pla "); break;
  228. case 0x69: if(a8)sprintf(t, "adc #$%.2x ", op8);
  229. else sprintf(t, "adc #$%.4x ", op16); break;
  230. case 0x6a: sprintf(t, "ror a "); break;
  231. case 0x6b: sprintf(t, "rtl "); break;
  232. case 0x6c: sprintf(t, "jmp ($%.4x) [$%.6x]", op16, decode(OPTYPE_IADDR_PC, op16)); break;
  233. case 0x6d: sprintf(t, "adc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  234. case 0x6e: sprintf(t, "ror $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  235. case 0x6f: sprintf(t, "adc $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
  236. case 0x70: sprintf(t, "bvs $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
  237. case 0x71: sprintf(t, "adc ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
  238. case 0x72: sprintf(t, "adc ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
  239. case 0x73: sprintf(t, "adc ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
  240. case 0x74: sprintf(t, "stz $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  241. case 0x75: sprintf(t, "adc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  242. case 0x76: sprintf(t, "ror $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  243. case 0x77: sprintf(t, "adc [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
  244. case 0x78: sprintf(t, "sei "); break;
  245. case 0x79: sprintf(t, "adc $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
  246. case 0x7a: sprintf(t, "ply "); break;
  247. case 0x7b: sprintf(t, "tdc "); break;
  248. case 0x7c: sprintf(t, "jmp ($%.4x,x) [$%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break;
  249. case 0x7d: sprintf(t, "adc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  250. case 0x7e: sprintf(t, "ror $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  251. case 0x7f: sprintf(t, "adc $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
  252. case 0x80: sprintf(t, "bra $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
  253. case 0x81: sprintf(t, "sta ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
  254. case 0x82: sprintf(t, "brl $%.4x [$%.6x]", uint16(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break;
  255. case 0x83: sprintf(t, "sta $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
  256. case 0x84: sprintf(t, "sty $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  257. case 0x85: sprintf(t, "sta $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  258. case 0x86: sprintf(t, "stx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  259. case 0x87: sprintf(t, "sta [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
  260. case 0x88: sprintf(t, "dey "); break;
  261. case 0x89: if(a8)sprintf(t, "bit #$%.2x ", op8);
  262. else sprintf(t, "bit #$%.4x ", op16); break;
  263. case 0x8a: sprintf(t, "txa "); break;
  264. case 0x8b: sprintf(t, "phb "); break;
  265. case 0x8c: sprintf(t, "sty $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  266. case 0x8d: sprintf(t, "sta $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  267. case 0x8e: sprintf(t, "stx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  268. case 0x8f: sprintf(t, "sta $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
  269. case 0x90: sprintf(t, "bcc $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
  270. case 0x91: sprintf(t, "sta ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
  271. case 0x92: sprintf(t, "sta ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
  272. case 0x93: sprintf(t, "sta ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
  273. case 0x94: sprintf(t, "sty $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  274. case 0x95: sprintf(t, "sta $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  275. case 0x96: sprintf(t, "stx $%.2x,y [$%.6x]", op8, decode(OPTYPE_DPY, op8)); break;
  276. case 0x97: sprintf(t, "sta [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
  277. case 0x98: sprintf(t, "tya "); break;
  278. case 0x99: sprintf(t, "sta $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
  279. case 0x9a: sprintf(t, "txs "); break;
  280. case 0x9b: sprintf(t, "txy "); break;
  281. case 0x9c: sprintf(t, "stz $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  282. case 0x9d: sprintf(t, "sta $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  283. case 0x9e: sprintf(t, "stz $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  284. case 0x9f: sprintf(t, "sta $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
  285. case 0xa0: if(x8)sprintf(t, "ldy #$%.2x ", op8);
  286. else sprintf(t, "ldy #$%.4x ", op16); break;
  287. case 0xa1: sprintf(t, "lda ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
  288. case 0xa2: if(x8)sprintf(t, "ldx #$%.2x ", op8);
  289. else sprintf(t, "ldx #$%.4x ", op16); break;
  290. case 0xa3: sprintf(t, "lda $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
  291. case 0xa4: sprintf(t, "ldy $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  292. case 0xa5: sprintf(t, "lda $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  293. case 0xa6: sprintf(t, "ldx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  294. case 0xa7: sprintf(t, "lda [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
  295. case 0xa8: sprintf(t, "tay "); break;
  296. case 0xa9: if(a8)sprintf(t, "lda #$%.2x ", op8);
  297. else sprintf(t, "lda #$%.4x ", op16); break;
  298. case 0xaa: sprintf(t, "tax "); break;
  299. case 0xab: sprintf(t, "plb "); break;
  300. case 0xac: sprintf(t, "ldy $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  301. case 0xad: sprintf(t, "lda $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  302. case 0xae: sprintf(t, "ldx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  303. case 0xaf: sprintf(t, "lda $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
  304. case 0xb0: sprintf(t, "bcs $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
  305. case 0xb1: sprintf(t, "lda ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
  306. case 0xb2: sprintf(t, "lda ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
  307. case 0xb3: sprintf(t, "lda ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
  308. case 0xb4: sprintf(t, "ldy $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  309. case 0xb5: sprintf(t, "lda $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  310. case 0xb6: sprintf(t, "ldx $%.2x,y [$%.6x]", op8, decode(OPTYPE_DPY, op8)); break;
  311. case 0xb7: sprintf(t, "lda [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
  312. case 0xb8: sprintf(t, "clv "); break;
  313. case 0xb9: sprintf(t, "lda $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
  314. case 0xba: sprintf(t, "tsx "); break;
  315. case 0xbb: sprintf(t, "tyx "); break;
  316. case 0xbc: sprintf(t, "ldy $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  317. case 0xbd: sprintf(t, "lda $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  318. case 0xbe: sprintf(t, "ldx $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
  319. case 0xbf: sprintf(t, "lda $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
  320. case 0xc0: if(x8)sprintf(t, "cpy #$%.2x ", op8);
  321. else sprintf(t, "cpy #$%.4x ", op16); break;
  322. case 0xc1: sprintf(t, "cmp ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
  323. case 0xc2: sprintf(t, "rep #$%.2x ", op8); break;
  324. case 0xc3: sprintf(t, "cmp $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
  325. case 0xc4: sprintf(t, "cpy $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  326. case 0xc5: sprintf(t, "cmp $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  327. case 0xc6: sprintf(t, "dec $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  328. case 0xc7: sprintf(t, "cmp [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
  329. case 0xc8: sprintf(t, "iny "); break;
  330. case 0xc9: if(a8)sprintf(t, "cmp #$%.2x ", op8);
  331. else sprintf(t, "cmp #$%.4x ", op16); break;
  332. case 0xca: sprintf(t, "dex "); break;
  333. case 0xcb: sprintf(t, "wai "); break;
  334. case 0xcc: sprintf(t, "cpy $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  335. case 0xcd: sprintf(t, "cmp $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  336. case 0xce: sprintf(t, "dec $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  337. case 0xcf: sprintf(t, "cmp $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
  338. case 0xd0: sprintf(t, "bne $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
  339. case 0xd1: sprintf(t, "cmp ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
  340. case 0xd2: sprintf(t, "cmp ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
  341. case 0xd3: sprintf(t, "cmp ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
  342. case 0xd4: sprintf(t, "pei ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
  343. case 0xd5: sprintf(t, "cmp $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  344. case 0xd6: sprintf(t, "dec $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  345. case 0xd7: sprintf(t, "cmp [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
  346. case 0xd8: sprintf(t, "cld "); break;
  347. case 0xd9: sprintf(t, "cmp $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
  348. case 0xda: sprintf(t, "phx "); break;
  349. case 0xdb: sprintf(t, "stp "); break;
  350. case 0xdc: sprintf(t, "jmp [$%.4x] [$%.6x]", op16, decode(OPTYPE_ILADDR, op16)); break;
  351. case 0xdd: sprintf(t, "cmp $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  352. case 0xde: sprintf(t, "dec $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  353. case 0xdf: sprintf(t, "cmp $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
  354. case 0xe0: if(x8)sprintf(t, "cpx #$%.2x ", op8);
  355. else sprintf(t, "cpx #$%.4x ", op16); break;
  356. case 0xe1: sprintf(t, "sbc ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
  357. case 0xe2: sprintf(t, "sep #$%.2x ", op8); break;
  358. case 0xe3: sprintf(t, "sbc $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
  359. case 0xe4: sprintf(t, "cpx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  360. case 0xe5: sprintf(t, "sbc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  361. case 0xe6: sprintf(t, "inc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
  362. case 0xe7: sprintf(t, "sbc [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
  363. case 0xe8: sprintf(t, "inx "); break;
  364. case 0xe9: if(a8)sprintf(t, "sbc #$%.2x ", op8);
  365. else sprintf(t, "sbc #$%.4x ", op16); break;
  366. case 0xea: sprintf(t, "nop "); break;
  367. case 0xeb: sprintf(t, "xba "); break;
  368. case 0xec: sprintf(t, "cpx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  369. case 0xed: sprintf(t, "sbc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  370. case 0xee: sprintf(t, "inc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  371. case 0xef: sprintf(t, "sbc $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
  372. case 0xf0: sprintf(t, "beq $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
  373. case 0xf1: sprintf(t, "sbc ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
  374. case 0xf2: sprintf(t, "sbc ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
  375. case 0xf3: sprintf(t, "sbc ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
  376. case 0xf4: sprintf(t, "pea $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
  377. case 0xf5: sprintf(t, "sbc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  378. case 0xf6: sprintf(t, "inc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
  379. case 0xf7: sprintf(t, "sbc [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
  380. case 0xf8: sprintf(t, "sed "); break;
  381. case 0xf9: sprintf(t, "sbc $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
  382. case 0xfa: sprintf(t, "plx "); break;
  383. case 0xfb: sprintf(t, "xce "); break;
  384. case 0xfc: sprintf(t, "jsr ($%.4x,x) [$%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break;
  385. case 0xfd: sprintf(t, "sbc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  386. case 0xfe: sprintf(t, "inc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
  387. case 0xff: sprintf(t, "sbc $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
  388. }
  389. #undef op8
  390. #undef op16
  391. #undef op24
  392. #undef a8
  393. #undef x8
  394. strcat(s, t);
  395. strcat(s, " ");
  396. sprintf(t, "A:%.4x X:%.4x Y:%.4x S:%.4x D:%.4x DB:%.2x ",
  397. regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, regs.db);
  398. strcat(s, t);
  399. if(regs.e) {
  400. sprintf(t, "%c%c%c%c%c%c%c%c",
  401. regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v',
  402. regs.p.m ? '1' : '0', regs.p.x ? 'B' : 'b',
  403. regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i',
  404. regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c');
  405. } else {
  406. sprintf(t, "%c%c%c%c%c%c%c%c",
  407. regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v',
  408. regs.p.m ? 'M' : 'm', regs.p.x ? 'X' : 'x',
  409. regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i',
  410. regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c');
  411. }
  412. strcat(s, t);
  413. strcat(s, " ");
  414. sprintf(t, "V:%3d H:%4d", ppu.vcounter(), ppu.hcounter());
  415. strcat(s, t);
  416. }
  417. //opcode_length() retrieves the length of the next opcode
  418. //to be executed. It is used by the debugger to step over,
  419. //disable and proceed cpu opcodes.
  420. //
  421. //5 and 6 are special cases, 5 is used for #consts based on
  422. //the A register size, 6 for the X/Y register size. the
  423. //rest are literal sizes. There's no need to test for
  424. //emulation mode, as regs.p.m/regs.p.x should *always* be
  425. //set in emulation mode.
  426. uint8 CPU::opcode_length() {
  427. uint8 op, len;
  428. static uint8 op_len_tbl[256] = {
  429. //0,1,2,3, 4,5,6,7, 8,9,a,b, c,d,e,f
  430. 2,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x0n
  431. 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x1n
  432. 3,2,4,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x2n
  433. 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x3n
  434. 1,2,2,2, 3,2,2,2, 1,5,1,1, 3,3,3,4, //0x4n
  435. 2,2,2,2, 3,2,2,2, 1,3,1,1, 4,3,3,4, //0x5n
  436. 1,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x6n
  437. 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x7n
  438. 2,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x8n
  439. 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x9n
  440. 6,2,6,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xan
  441. 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xbn
  442. 6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xcn
  443. 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xdn
  444. 6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xen
  445. 2,2,2,2, 3,2,2,2, 1,3,1,1, 3,3,3,4 //0xfn
  446. };
  447. if(in_opcode() == true) {
  448. return 0;
  449. }
  450. op = dreadb(regs.pc.d);
  451. len = op_len_tbl[op];
  452. if(len == 5) return (regs.e || regs.p.m) ? 2 : 3;
  453. if(len == 6) return (regs.e || regs.p.x) ? 2 : 3;
  454. return len;
  455. }
  456. #endif //ifdef CPU_CPP