An emulator, assembler, and disassembler for the Sega Game Gear
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

942 lines
19 KiB

  1. /* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. Released under the terms of the MIT License. See LICENSE for details. */
  3. /*
  4. This file contains code to implement the Z80 instruction set. Since there
  5. are a lot of functions, it is kept separate from the main z80.c file. It is
  6. included in the middle of z80.c and should not be compiled separately.
  7. Most of this information can be found in the Z80 User Manual, Revision 06.
  8. Undocumented opcodes, flags, and some additional details come from:
  9. - http://clrhome.org/table/
  10. - http://www.z80.info/z80sflag.htm
  11. */
  12. typedef uint8_t (*DispatchTable[256])(Z80*, uint8_t);
  13. static DispatchTable instruction_table;
  14. static DispatchTable instruction_table_extended;
  15. static DispatchTable instruction_table_bits;
  16. static DispatchTable instruction_table_index;
  17. static DispatchTable instruction_table_index_bits;
  18. /*
  19. Unimplemented opcode handler.
  20. */
  21. static uint8_t z80_inst_unimplemented(Z80 *z80, uint8_t opcode)
  22. {
  23. z80->except = true;
  24. z80->exc_code = Z80_EXC_UNIMPLEMENTED_OPCODE;
  25. z80->exc_data = opcode;
  26. return 4;
  27. }
  28. /*
  29. LD r, r' (0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4A, 0x4B,
  30. 0x4C, 0x4D, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x57, 0x58, 0x59,
  31. 0x5A, 0x5B, 0x5C, 0x5D, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67,
  32. 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6F, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
  33. 0x7D, 0x7F):
  34. Load r' (8-bit register) into r (8-bit register).
  35. */
  36. static uint8_t z80_inst_ld_r_r(Z80 *z80, uint8_t opcode)
  37. {
  38. uint8_t *dst = extract_reg(z80, opcode),
  39. *src = extract_reg(z80, opcode << 3);
  40. *dst = *src;
  41. z80->regfile.pc++;
  42. return 4;
  43. }
  44. /*
  45. LD r, n (0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, 0x3E):
  46. Load n (8-bit immediate) into r (8-bit register).
  47. */
  48. static uint8_t z80_inst_ld_r_n(Z80 *z80, uint8_t opcode)
  49. {
  50. uint8_t *reg = extract_reg(z80, opcode);
  51. *reg = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
  52. z80->regfile.pc++;
  53. return 7;
  54. }
  55. /*
  56. LD r, (HL) (0x46, 0x4E, 0x56, 0x5E, 0x66, 0x6E, 0x7E):
  57. Load the contents of HL into r (8-bit register).
  58. */
  59. static uint8_t z80_inst_ld_r_hl(Z80 *z80, uint8_t opcode)
  60. {
  61. uint8_t *reg = extract_reg(z80, opcode);
  62. *reg = mmu_read_byte(z80->mmu, get_pair(z80, REG_HL));
  63. z80->regfile.pc++;
  64. return 7;
  65. }
  66. /*
  67. LD r, (IX+d)
  68. */
  69. // static uint8_t z80_inst_ld_r_ix(Z80 *z80, uint8_t opcode)
  70. /*
  71. LD r, (IY+d)
  72. */
  73. // static uint8_t z80_inst_ld_r_iy(Z80 *z80, uint8_t opcode)
  74. /*
  75. LD (HL), r
  76. */
  77. // static uint8_t z80_inst_ld_hl_r(Z80 *z80, uint8_t opcode)
  78. /*
  79. LD (IX+d), r
  80. */
  81. // static uint8_t z80_inst_ld_ix_r(Z80 *z80, uint8_t opcode)
  82. /*
  83. LD (IY+d), r
  84. */
  85. // static uint8_t z80_inst_ld_iy_r(Z80 *z80, uint8_t opcode)
  86. /*
  87. LD (HL), n (0x36):
  88. Load n (8-bit immediate) into the memory address pointed to by HL.
  89. */
  90. static uint8_t z80_inst_ld_hl_n(Z80 *z80, uint8_t opcode)
  91. {
  92. (void) opcode;
  93. uint16_t addr = get_pair(z80, REG_HL);
  94. uint8_t byte = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
  95. mmu_write_byte(z80->mmu, addr, byte);
  96. z80->regfile.pc++;
  97. return 10;
  98. }
  99. /*
  100. LD (IX+d), n
  101. */
  102. // static uint8_t z80_inst_ld_ix_n(Z80 *z80, uint8_t opcode)
  103. /*
  104. LD (IY+d), n
  105. */
  106. // static uint8_t z80_inst_ld_iy_n(Z80 *z80, uint8_t opcode)
  107. /*
  108. LD A, (BC)
  109. */
  110. // static uint8_t z80_inst_ld_a_bc(Z80 *z80, uint8_t opcode)
  111. /*
  112. LD A, (DE)
  113. */
  114. // static uint8_t z80_inst_ld_a_de(Z80 *z80, uint8_t opcode)
  115. /*
  116. LD A, (nn)
  117. */
  118. // static uint8_t z80_inst_ld_a_nn(Z80 *z80, uint8_t opcode)
  119. /*
  120. LD (BC), A
  121. */
  122. // static uint8_t z80_inst_ld_bc_a(Z80 *z80, uint8_t opcode)
  123. /*
  124. LD (DE), A
  125. */
  126. // static uint8_t z80_inst_ld_de_a(Z80 *z80, uint8_t opcode)
  127. /*
  128. LD (nn), A (0x32):
  129. Load a into memory address nn.
  130. */
  131. static uint8_t z80_inst_ld_nn_a(Z80 *z80, uint8_t opcode)
  132. {
  133. (void) opcode;
  134. uint16_t addr = mmu_read_double(z80->mmu, ++z80->regfile.pc);
  135. mmu_write_byte(z80->mmu, addr, z80->regfile.a);
  136. z80->regfile.pc += 2;
  137. return 13;
  138. }
  139. /*
  140. LD A, I
  141. */
  142. // static uint8_t z80_inst_ld_a_i(Z80 *z80, uint8_t opcode)
  143. /*
  144. LD A, R
  145. */
  146. // static uint8_t z80_inst_ld_a_r(Z80 *z80, uint8_t opcode)
  147. /*
  148. LD I,A
  149. */
  150. // static uint8_t z80_inst_ld_i_a(Z80 *z80, uint8_t opcode)
  151. /*
  152. LD R, A
  153. */
  154. // static uint8_t z80_inst_ld_r_a(Z80 *z80, uint8_t opcode)
  155. /*
  156. LD dd, nn (0x01, 0x11, 0x21, 0x31):
  157. Load nn (16-bit immediate) into dd (16-bit register).
  158. */
  159. static uint8_t z80_inst_ld_dd_nn(Z80 *z80, uint8_t opcode)
  160. {
  161. uint8_t pair = extract_pair(opcode);
  162. set_pair(z80, pair, mmu_read_double(z80->mmu, ++z80->regfile.pc));
  163. z80->regfile.pc += 2;
  164. return 10;
  165. }
  166. // LD IX, nn
  167. // LD IY, nn
  168. // LD HL, (nn)
  169. // LD dd, (nn)
  170. // LD IX, (nn)
  171. // LD IY, (nn)
  172. // LD (nn), HL
  173. // LD (nn), dd
  174. // LD (nn), IX
  175. // LD (nn), IY
  176. // LD SP, HL
  177. // LD SP, IX
  178. // LD SP, IY
  179. /*
  180. PUSH qq (0xC5, 0xD5, 0xE5, 0xF5):
  181. Push qq onto the stack, and decrement SP by two.
  182. */
  183. static uint8_t z80_inst_push_qq(Z80 *z80, uint8_t opcode)
  184. {
  185. uint8_t pair = extract_pair(opcode);
  186. stack_push(z80, get_pair(z80, pair));
  187. z80->regfile.pc++;
  188. return 11;
  189. }
  190. // PUSH IX
  191. // PUSH IY
  192. /*
  193. POP qq (0xC1, 0xD1, 0xE1, 0xF1):
  194. Pop qq from the stack, and increment SP by two.
  195. */
  196. static uint8_t z80_inst_pop_qq(Z80 *z80, uint8_t opcode)
  197. {
  198. uint8_t pair = extract_pair(opcode);
  199. set_pair(z80, pair, stack_pop(z80));
  200. z80->regfile.pc++;
  201. return 10;
  202. }
  203. // POP IX
  204. // POP IY
  205. // EX DE, HL
  206. // EX AF, AF′
  207. /*
  208. EXX (0xD9):
  209. Exchange the 16-bit registers with their shadows
  210. (BC <=> BC', DE <=> DE', HL <=> HL').
  211. */
  212. static uint8_t z80_inst_exx(Z80 *z80, uint8_t opcode)
  213. {
  214. (void) opcode;
  215. uint16_t bc = get_pair(z80, REG_BC),
  216. de = get_pair(z80, REG_DE),
  217. hl = get_pair(z80, REG_HL);
  218. set_pair(z80, REG_BC, get_pair(z80, REG_BC_));
  219. set_pair(z80, REG_DE, get_pair(z80, REG_DE_));
  220. set_pair(z80, REG_HL, get_pair(z80, REG_HL_));
  221. set_pair(z80, REG_BC_, bc);
  222. set_pair(z80, REG_DE_, de);
  223. set_pair(z80, REG_HL_, hl);
  224. z80->regfile.pc++;
  225. return 4;
  226. }
  227. // EX (SP), HL
  228. // EX (SP), IX
  229. // EX (SP), IY
  230. // LDI
  231. // LDIR
  232. // LDD
  233. // LDDR
  234. // CPI
  235. // CPIR
  236. // CPD
  237. // CPDR
  238. // ADD A, r
  239. // ADD A, n
  240. // ADD A, (HL)
  241. // ADD A, (IX + d)
  242. // ADD A, (IY + d)
  243. // ADC A, s
  244. // SUB s
  245. // SBC A, s
  246. // AND s
  247. // OR s
  248. // XOR s
  249. /*
  250. XOR r (0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAF):
  251. Bitwise XOR a with r (8-bit register).
  252. */
  253. static uint8_t z80_inst_xor_r(Z80 *z80, uint8_t opcode)
  254. {
  255. uint8_t *reg = extract_reg(z80, opcode);
  256. uint8_t a = (z80->regfile.a ^= *reg);
  257. bool parity = !(__builtin_popcount(a) % 2);
  258. update_flags(z80, 0, 0, parity, !!(a & 0x08), 0, !!(a & 0x20), a == 0,
  259. !!(a & 0x80), 0xFF);
  260. z80->regfile.pc++;
  261. return 4;
  262. }
  263. // CP s
  264. /*
  265. CP r (0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBF):
  266. Set flags as if r (8-bit register) had been subtracted from a.
  267. */
  268. static uint8_t z80_inst_cp_r(Z80 *z80, uint8_t opcode)
  269. {
  270. uint8_t *reg = extract_reg(z80, opcode);
  271. uint8_t d = z80->regfile.a - *reg;
  272. bool c = (z80->regfile.a - *reg) != d;
  273. bool v = (z80->regfile.a - *reg) != ((int8_t) d);
  274. bool h = !!(((z80->regfile.a & 0x0F) - (*reg & 0x0F)) & 0x10);
  275. update_flags(z80, c, 1, v, !!(*reg & 0x08), h, !!(*reg & 0x20), d == 0,
  276. !!(d & 0x80), 0xFF);
  277. z80->regfile.pc++;
  278. return 4;
  279. }
  280. /*
  281. CP n (0xFE):
  282. Set flags as if n (8-bit immediate) had been subtracted from a.
  283. */
  284. static uint8_t z80_inst_cp_n(Z80 *z80, uint8_t opcode)
  285. {
  286. (void) opcode;
  287. uint8_t n = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
  288. uint8_t d = z80->regfile.a - n;
  289. bool c = (z80->regfile.a - n) != d;
  290. bool v = (z80->regfile.a - n) != ((int8_t) d);
  291. bool h = !!(((z80->regfile.a & 0x0F) - (n & 0x0F)) & 0x10);
  292. update_flags(z80, c, 1, v, !!(n & 0x08), h, !!(n & 0x20), d == 0,
  293. !!(d & 0x80), 0xFF);
  294. z80->regfile.pc++;
  295. return 7;
  296. }
  297. /*
  298. INC r (0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x3C):
  299. Increment r (8-bit register).
  300. */
  301. static uint8_t z80_inst_inc_r(Z80 *z80, uint8_t opcode)
  302. {
  303. uint8_t *reg = extract_reg(z80, opcode);
  304. bool halfcarry = !!(((*reg & 0x0F) + 1) & 0x10);
  305. (*reg)++;
  306. update_flags(z80, 0, 0, *reg == 0x80, !!(*reg & 0x08), halfcarry,
  307. !!(*reg & 0x20), *reg == 0, !!(*reg & 0x80), 0xFE);
  308. z80->regfile.pc++;
  309. return 4;
  310. }
  311. // INC (HL)
  312. // INC (IX+d)
  313. // INC (IY+d)
  314. // DEC m
  315. // DAA
  316. // CPL
  317. // NEG
  318. // CCF
  319. // SCF
  320. /*
  321. NOP (0x00):
  322. No operation is performed.
  323. */
  324. static uint8_t z80_inst_nop(Z80 *z80, uint8_t opcode)
  325. {
  326. (void) opcode;
  327. z80->regfile.pc++;
  328. return 4;
  329. }
  330. /*
  331. HALT (0x76):
  332. Suspend CPU operation: execute NOPs until an interrupt or reset.
  333. */
  334. static uint8_t z80_inst_halt(Z80 *z80, uint8_t opcode)
  335. {
  336. (void) z80;
  337. (void) opcode;
  338. return 4;
  339. }
  340. /*
  341. DI (0xF3):
  342. Disable maskable interrupts by resetting both flip-flops.
  343. */
  344. static uint8_t z80_inst_di(Z80 *z80, uint8_t opcode)
  345. {
  346. (void) opcode;
  347. z80->regfile.iff1 = false;
  348. z80->regfile.iff2 = false;
  349. z80->regfile.pc++;
  350. return 4;
  351. }
  352. /*
  353. EI (0xFB):
  354. Enable maskable interrupts by setting both flip-flops.
  355. */
  356. static uint8_t z80_inst_ei(Z80 *z80, uint8_t opcode)
  357. {
  358. (void) opcode;
  359. z80->regfile.iff1 = true;
  360. z80->regfile.iff2 = true;
  361. z80->regfile.pc++;
  362. return 4;
  363. }
  364. /*
  365. IM (0xED46, 0xED4E, 0xED56, 0xED5E, 0xED66, 0xED6E, 0xED76, 0xED7E):
  366. Set the interrupt mode.
  367. */
  368. static uint8_t z80_inst_im(Z80 *z80, uint8_t opcode)
  369. {
  370. switch (opcode) {
  371. case 0x46:
  372. case 0x4E:
  373. case 0x66:
  374. case 0x6E:
  375. z80->regfile.im_a = false; // Interrupt mode 0
  376. z80->regfile.im_b = false;
  377. break;
  378. case 0x56:
  379. case 0x76:
  380. z80->regfile.im_a = true; // Interrupt mode 1
  381. z80->regfile.im_b = false;
  382. break;
  383. case 0x5E:
  384. case 0x7E:
  385. z80->regfile.im_a = true; // Interrupt mode 2
  386. z80->regfile.im_b = true;
  387. break;
  388. }
  389. z80->regfile.pc++;
  390. return 8;
  391. }
  392. // ADD HL, ss
  393. // ADC HL, ss
  394. // SBC HL, ss
  395. // ADD IX, pp
  396. // ADD IY, rr
  397. /*
  398. INC ss (0x03, 0x13, 0x23, 0x33):
  399. Increment ss (16-bit register).
  400. */
  401. static uint8_t z80_inst_inc_ss(Z80 *z80, uint8_t opcode)
  402. {
  403. uint8_t pair = extract_pair(opcode);
  404. set_pair(z80, pair, get_pair(z80, pair) + 1);
  405. z80->regfile.pc++;
  406. return 6;
  407. }
  408. // INC IX
  409. // INC IY
  410. // DEC ss
  411. // DEC IX
  412. // DEC IY
  413. // RLCA
  414. // RLA
  415. // RRCA
  416. // RRA
  417. // RLC r
  418. // RLC (HL)
  419. // RLC (IX+d)
  420. // RLC (IY+d)
  421. // RL m
  422. // RRC m
  423. // RR m
  424. // SLA m
  425. // SRA m
  426. // SRL m
  427. // RLD
  428. // RRD
  429. // BIT b, r
  430. // BIT b, (HL)
  431. // BIT b, (IX+d)
  432. // BIT b, (IY+d)
  433. // SET b, r
  434. // SET b, (HL)
  435. // SET b, (IX+d)
  436. // SET b, (IY+d)
  437. // RES b, m
  438. /*
  439. JP nn (0xC3):
  440. Jump to nn (16-bit immediate).
  441. */
  442. static uint8_t z80_inst_jp_nn(Z80 *z80, uint8_t opcode)
  443. {
  444. (void) opcode;
  445. z80->regfile.pc = mmu_read_double(z80->mmu, ++z80->regfile.pc);
  446. return 10;
  447. }
  448. /*
  449. JP cc, nn (0xC2, 0xCA, 0xD2, 0xDA, 0xE2, 0xEA, 0xF2, 0xFA):
  450. Jump to nn (16-bit immediate) if cc (condition) is true.
  451. */
  452. static uint8_t z80_inst_jp_cc_nn(Z80 *z80, uint8_t opcode)
  453. {
  454. if (extract_cond(z80, opcode))
  455. z80->regfile.pc = mmu_read_double(z80->mmu, ++z80->regfile.pc);
  456. else
  457. z80->regfile.pc += 3;
  458. return 10;
  459. }
  460. /*
  461. JR e (0x18):
  462. Relative jump e (signed 8-bit immediate) bytes.
  463. */
  464. static uint8_t z80_inst_jr_e(Z80 *z80, uint8_t opcode)
  465. {
  466. (void) opcode;
  467. int8_t jump = mmu_read_byte(z80->mmu, z80->regfile.pc + 1);
  468. z80->regfile.pc += jump + 2;
  469. return 12;
  470. }
  471. /*
  472. JR cc, e (0x20, 0x28, 0x30, 0x38):
  473. Relative jump e (signed 8-bit immediate) bytes if cc (condition) is true.
  474. */
  475. static uint8_t z80_inst_jr_cc_e(Z80 *z80, uint8_t opcode)
  476. {
  477. if (extract_cond(z80, opcode - 0x20)) {
  478. int8_t jump = mmu_read_byte(z80->mmu, z80->regfile.pc + 1);
  479. z80->regfile.pc += jump + 2;
  480. return 12;
  481. } else {
  482. z80->regfile.pc += 2;
  483. return 7;
  484. }
  485. }
  486. // JP (HL)
  487. // JP (IX)
  488. // JP (IY)
  489. // DJNZ, e
  490. /*
  491. CALL nn (0xCD):
  492. Push PC+3 onto the stack and jump to nn (16-bit immediate).
  493. */
  494. static uint8_t z80_inst_call_nn(Z80 *z80, uint8_t opcode)
  495. {
  496. (void) opcode;
  497. stack_push(z80, z80->regfile.pc + 3);
  498. z80->regfile.pc = mmu_read_double(z80->mmu, ++z80->regfile.pc);
  499. return 17;
  500. }
  501. /*
  502. CALL cc, nn (0xC4, 0xCC, 0xD4, 0xDC, 0xE4, 0xEC, 0xF4, 0xFC):
  503. Push PC+3 onto the stack and jump to nn (16-bit immediate) if cc is true.
  504. */
  505. static uint8_t z80_inst_call_cc_nn(Z80 *z80, uint8_t opcode)
  506. {
  507. if (extract_cond(z80, opcode)) {
  508. stack_push(z80, z80->regfile.pc + 3);
  509. z80->regfile.pc = mmu_read_double(z80->mmu, ++z80->regfile.pc);
  510. return 17;
  511. } else {
  512. z80->regfile.pc += 3;
  513. return 10;
  514. }
  515. }
  516. /*
  517. RET (0xC9):
  518. Pop PC from the stack.
  519. */
  520. static uint8_t z80_inst_ret(Z80 *z80, uint8_t opcode)
  521. {
  522. (void) opcode;
  523. z80->regfile.pc = stack_pop(z80);
  524. return 10;
  525. }
  526. /*
  527. RET cc (0xC0, 0xC8, 0xD0, 0xD8, 0xE0, 0xE8, 0xF0, 0xF8):
  528. Pop PC from the stack if cc is true.
  529. */
  530. static uint8_t z80_inst_ret_cc(Z80 *z80, uint8_t opcode)
  531. {
  532. if (extract_cond(z80, opcode)) {
  533. z80->regfile.pc = stack_pop(z80);
  534. return 11;
  535. } else {
  536. z80->regfile.pc++;
  537. return 5;
  538. }
  539. }
  540. // RETI
  541. // RETN
  542. // RST p
  543. /*
  544. IN A, (n) (0xDB):
  545. Read a byte from port n into a.
  546. */
  547. static uint8_t z80_inst_in_a_n(Z80 *z80, uint8_t opcode)
  548. {
  549. (void) opcode;
  550. uint8_t port = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
  551. z80->regfile.a = read_port(z80, port);
  552. z80->regfile.pc++;
  553. return 11;
  554. }
  555. /*
  556. IN r, (C) (0xED40, 0xED48, 0xED50, 0xED58, 0xED60, 0xED68, 0xED70, 0xED78):
  557. Read a byte from port C into r, or affect flags only if 0xED70.
  558. */
  559. static uint8_t z80_inst_in_r_c(Z80 *z80, uint8_t opcode)
  560. {
  561. uint8_t data = read_port(z80, z80->regfile.c);
  562. bool parity = !(__builtin_popcount(data) % 2);
  563. if (opcode != 0x70)
  564. *extract_reg(z80, opcode) = data;
  565. update_flags(z80, 0, 0, parity, !!(data & 0x08), 0, !!(data & 0x20),
  566. data == 0, !!(data & 0x80), 0xFE);
  567. z80->regfile.pc++;
  568. return 12;
  569. }
  570. /*
  571. INI (0xEDA2):
  572. IN (HL), (C); INC HL; DEC B
  573. */
  574. static uint8_t z80_inst_ini(Z80 *z80, uint8_t opcode)
  575. {
  576. (void) opcode;
  577. uint8_t data = read_port(z80, z80->regfile.c), *b = &z80->regfile.b;
  578. uint16_t hl = get_pair(z80, REG_HL);
  579. bool h = !!(((*b & 0x0F) - 1) & 0x10);
  580. mmu_write_byte(z80->mmu, hl, data);
  581. set_pair(z80, REG_HL, hl + 1);
  582. (*b)--;
  583. update_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
  584. *b == 0, !!(*b & 0x80), 0xFE);
  585. z80->regfile.pc++;
  586. return 16;
  587. }
  588. /*
  589. INIR (0xEDB2):
  590. INI; JR NZ, -1
  591. */
  592. static uint8_t z80_inst_inir(Z80 *z80, uint8_t opcode)
  593. {
  594. z80_inst_ini(z80, opcode);
  595. if (z80->regfile.b == 0)
  596. return 16;
  597. z80->regfile.pc -= 2;
  598. return 21;
  599. }
  600. /*
  601. IND (0xEDAA):
  602. IN (HL), (C); DEC HL; DEC B
  603. */
  604. static uint8_t z80_inst_ind(Z80 *z80, uint8_t opcode)
  605. {
  606. (void) opcode;
  607. uint8_t data = read_port(z80, z80->regfile.c), *b = &z80->regfile.b;
  608. uint16_t hl = get_pair(z80, REG_HL);
  609. bool h = !!(((*b & 0x0F) - 1) & 0x10);
  610. mmu_write_byte(z80->mmu, hl, data);
  611. set_pair(z80, REG_HL, hl - 1);
  612. (*b)--;
  613. update_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
  614. *b == 0, !!(*b & 0x80), 0xFE);
  615. z80->regfile.pc++;
  616. return 16;
  617. }
  618. /*
  619. INDR (0xEDBA):
  620. IND; JR NZ, -1
  621. */
  622. static uint8_t z80_inst_indr(Z80 *z80, uint8_t opcode)
  623. {
  624. z80_inst_ind(z80, opcode);
  625. if (z80->regfile.b == 0)
  626. return 16;
  627. z80->regfile.pc -= 2;
  628. return 21;
  629. }
  630. /*
  631. OUT (n), A (0xD3):
  632. Write a byte from a into port n.
  633. */
  634. static uint8_t z80_inst_out_n_a(Z80 *z80, uint8_t opcode)
  635. {
  636. (void) opcode;
  637. uint8_t port = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
  638. write_port(z80, port, z80->regfile.a);
  639. z80->regfile.pc++;
  640. return 11;
  641. }
  642. /*
  643. OUT (C), r (0xED41, 0xED49, 0xED51, 0xED59, 0xED61, 0xED69, 0xED71,
  644. 0xED79):
  645. Write a byte from r (8-bit reg, or 0 if 0xED71) into port C.
  646. */
  647. static uint8_t z80_inst_out_c_r(Z80 *z80, uint8_t opcode)
  648. {
  649. uint8_t value = opcode != 0x71 ? *extract_reg(z80, opcode) : 0;
  650. write_port(z80, z80->regfile.c, value);
  651. z80->regfile.pc++;
  652. return 12;
  653. }
  654. /*
  655. OUTI (0xEDA3):
  656. OUT (C), (HL); INC HL; DEC B
  657. */
  658. static uint8_t z80_inst_outi(Z80 *z80, uint8_t opcode)
  659. {
  660. (void) opcode;
  661. uint16_t hl = get_pair(z80, REG_HL);
  662. uint8_t *b = &z80->regfile.b;
  663. bool h = !!(((*b & 0x0F) - 1) & 0x10);
  664. write_port(z80, z80->regfile.c, mmu_read_byte(z80->mmu, hl));
  665. set_pair(z80, REG_HL, hl + 1);
  666. (*b)--;
  667. update_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
  668. *b == 0, !!(*b & 0x80), 0xFE);
  669. z80->regfile.pc++;
  670. return 16;
  671. }
  672. /*
  673. OTIR (0xEDB3):
  674. OUTI; JR NZ, -1
  675. */
  676. static uint8_t z80_inst_otir(Z80 *z80, uint8_t opcode)
  677. {
  678. z80_inst_outi(z80, opcode);
  679. if (z80->regfile.b == 0)
  680. return 16;
  681. z80->regfile.pc -= 2;
  682. return 21;
  683. }
  684. /*
  685. OUTD (0xEDAB):
  686. OUT (C), (HL); DEC HL; DEC B
  687. */
  688. static uint8_t z80_inst_outd(Z80 *z80, uint8_t opcode)
  689. {
  690. (void) opcode;
  691. uint16_t hl = get_pair(z80, REG_HL);
  692. uint8_t *b = &z80->regfile.b;
  693. bool h = !!(((*b & 0x0F) - 1) & 0x10);
  694. write_port(z80, z80->regfile.c, mmu_read_byte(z80->mmu, hl));
  695. set_pair(z80, REG_HL, hl - 1);
  696. (*b)--;
  697. update_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
  698. *b == 0, !!(*b & 0x80), 0xFE);
  699. z80->regfile.pc++;
  700. return 16;
  701. }
  702. /*
  703. OTDR (0xEDBB):
  704. OUTD; JR NZ, -1
  705. */
  706. static uint8_t z80_inst_otdr(Z80 *z80, uint8_t opcode)
  707. {
  708. z80_inst_outd(z80, opcode);
  709. if (z80->regfile.b == 0)
  710. return 16;
  711. z80->regfile.pc -= 2;
  712. return 21;
  713. }
  714. /*
  715. NOP2:
  716. No operation is performed twice; i.e., 2 NOPs-worth of cycles are spent.
  717. Used for unimplemented extended and index instructions.
  718. */
  719. static uint8_t z80_inst_nop2(Z80 *z80, uint8_t opcode)
  720. {
  721. (void) opcode;
  722. z80->regfile.pc++;
  723. return 8;
  724. }
  725. /*
  726. 0xED:
  727. Handle an extended instruction.
  728. */
  729. static uint8_t z80_prefix_extended(Z80 *z80, uint8_t opcode)
  730. {
  731. opcode = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
  732. return (*instruction_table_extended[opcode])(z80, opcode);
  733. }
  734. /*
  735. 0xED:
  736. Handle a bit instruction.
  737. */
  738. static uint8_t z80_prefix_bits(Z80 *z80, uint8_t opcode)
  739. {
  740. opcode = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
  741. return (*instruction_table_bits[opcode])(z80, opcode);
  742. }
  743. /*
  744. 0xDD, 0xFD:
  745. Handle an index instruction.
  746. */
  747. static uint8_t z80_prefix_index(Z80 *z80, uint8_t opcode)
  748. {
  749. opcode = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
  750. return (*instruction_table_index[opcode])(z80, opcode);
  751. }
  752. /*
  753. 0xDDCB, 0xFDCB:
  754. Handle an index-bit instruction.
  755. */
  756. static uint8_t z80_prefix_index_bits(Z80 *z80, uint8_t opcode)
  757. {
  758. opcode = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
  759. return (*instruction_table_index_bits[opcode])(z80, opcode);
  760. }
  761. #include "z80_tables.inc.c"