32 RR2_BC = RRSET2 | RR_BC,
33 RR2_DE = RRSET2 | RR_DE,
34 RR2_HL = RRSET2 | RR_HL,
35 RR2_AF = RRSET2 | RR_SP
68 uint8_t a, f, b, c, d, e, h, l;
71 uint16_t af, bc, de, hl;
80 union genregs g, shadow; /* general purpose and shadow registers */
82 uint16_t ix, iy, sp, pc;
86 static void runop_main(uint8_t op);
87 static void runop_ed(uint8_t op);
88 static void runop_cb(uint8_t op);
89 static void runop_dd(uint8_t op);
90 static void runop_fd(uint8_t op);
91 static void runop_ddcb(uint8_t op);
92 static void runop_fdcb(uint8_t op);
94 static void op_load_reg8_reg8(int rdest, int rsrc);
95 static void op_load_reg8_imm8(int rdest, uint8_t imm);
96 static void op_load_reg8_mem(int rdest, uint16_t addr);
97 static void op_store_mem_reg8(uint16_t addr, int rsrc);
98 static void op_store_mem_imm8(uint16_t addr, uint8_t imm);
99 static void op_store_mem_reg16(uint16_t addr, int rsrc);
100 static void op_load_reg16_imm16(int rdest, uint16_t imm);
101 static void op_load_reg16_reg16(int rdest, int rsrc);
102 static void op_exch_mem_reg16(uint16_t addr, int rr);
103 static void op_alu_reg8(int op, int r);
104 static void op_alu_imm8(int op, uint8_t imm);
105 static void op_incdec_reg8(int r, int adj);
106 static void op_incdec_reg16(int r, int adj);
107 static void op_incdec_mem(uint16_t addr, int adj);
108 static void op_add_reg16_reg16(int rdest, int rsrc);
109 static void op_rl_reg8(int r, int width);
110 static void op_rr_reg8(int r, int width);
111 static void op_push_reg16(int r);
112 static void op_pop_reg16(int r);
113 static void op_call(uint16_t addr);
114 static void op_ret(void);
115 static void op_input(int r, uint16_t addr);
116 static void op_output(uint16_t addr, int r);
118 static struct registers regs;
121 static void (*runop[16])(uint8_t op) = {
122 runop_main, /* 0000: no prefix */
123 runop_ed, /* 0001: ED prefix */
124 runop_cb, /* 0010: CB prefix */
125 0, /* 0011: CBED invalid */
126 runop_dd, /* 0100: DD prefix */
127 0, /* 0101: DDED invalid */
128 runop_ddcb, /* 0110: DDCB prefix */
129 0, /* 0111: DDCBED invalid */
130 runop_fd, /* 1000: FD prefix */
131 0, /* 1001: FDED invalid */
132 runop_fdcb, /* 1010: FDCB prefix */
133 0, 0, 0, 0, 0 /* all the rest combinations are invalid */
136 static uint8_t *regptr8[8] = {
137 ®s.g.r.b, ®s.g.r.c,
138 ®s.g.r.d, ®s.g.r.e,
139 ®s.g.r.h, ®s.g.r.l,
143 static uint16_t *regptr16[] = {
163 static uint8_t fetch_byte(void)
165 return emu_mem_read(regs.pc++);
168 static uint16_t fetch_imm16(void)
170 uint16_t lsb = emu_mem_read(regs.pc++);
171 uint16_t msb = emu_mem_read(regs.pc++);
172 return lsb | (msb << 8);
175 static unsigned int prefix_bit(uint8_t op)
178 case 0xed: return PREFIX_ED;
179 case 0xcb: return PREFIX_CB;
180 case 0xdd: return PREFIX_DD;
181 case 0xfd: return PREFIX_FD;
190 unsigned int pbit, prefix = 0;
196 if((pbit = prefix_bit(op))) {
200 /* only treat the next byte as another prefix if the previous was dd or fd */
201 if((pbit = prefix_bit(op)) && (prefix == 0xdd || prefix == 0xfd)) {
212 static int cond(int cc)
215 case CC_NZ: return ~regs.g.r.f & FLAGS_Z;
216 case CC_Z: return regs.g.r.f & FLAGS_Z;
217 case CC_NC: return ~regs.g.r.f & FLAGS_C;
218 case CC_C: return regs.g.r.f & FLAGS_C;
219 case CC_PO: return ~regs.g.r.f & FLAGS_PV;
220 case CC_PE: return regs.g.r.f & FLAGS_PV;
221 case CC_P: return ~regs.g.r.f & FLAGS_S;
222 case CC_M: return regs.g.r.f & FLAGS_S;
229 #define ALUOP(x) (((x) >> 3) & 7)
230 #define DEST_R(x) (((x) >> 3) & 7)
231 #define OPCOND(x) (((x) >> 3) & 7)
232 #define SRC_R(x) ((x) & 7)
233 #define OP_RR(x) (((x) >> 4) & 3)
234 #define RST_ADDR(x) ((x) & 0x38)
236 #define SWAP_RR(a, b) \
243 static void runop_main(uint8_t op)
250 /* 8-bit load group except ld r,r/ld r,imm/ld r,(hl)/ld (hl),r in default */
252 op_store_mem_imm8(regs.g.rr.hl, fetch_byte());
255 op_load_reg8_mem(R_A, regs.g.rr.bc);
258 op_load_reg8_mem(R_A, regs.g.rr.de);
261 op_load_reg8_mem(R_A, fetch_imm16());
264 op_store_mem_reg8(regs.g.rr.bc, R_A);
267 op_store_mem_reg8(regs.g.rr.de, R_A);
270 op_store_mem_reg8(fetch_imm16(), R_A);
273 /* 16-bit load group */
278 op_load_reg16_imm16(OP_RR(op), fetch_imm16());
281 op_load_reg16_imm16(RR_HL, fetch_imm16());
284 op_store_mem_reg16(fetch_imm16(), RR_HL);
287 op_load_reg16_reg16(RR_SP, RR_HL);
293 op_push_reg16(RRSET2 | OP_RR(op));
299 op_pop_reg16(RRSET2 | OP_RR(op));
302 /* exchange, block transfer, block search groups */
304 SWAP_RR(regs.g.rr.de, regs.g.rr.hl);
307 SWAP_RR(regs.g.rr.af, regs.shadow.rr.af);
310 SWAP_RR(regs.g.rr.bc, regs.shadow.rr.bc);
311 SWAP_RR(regs.g.rr.de, regs.shadow.rr.de);
312 SWAP_RR(regs.g.rr.hl, regs.shadow.rr.hl);
315 op_exch_mem_reg16(regs.sp, RR_HL);
318 /* general purpose arithmetic and cpu control groups */
320 break; /* TODO implement DAA */
321 case 0x2f: /* cpl a */
322 regs.g.r.a = ~regs.g.r.a;
323 regs.g.r.f |= FLAGS_H | FLAGS_N;
326 regs.g.r.f ^= FLAGS_C;
329 regs.g.r.f |= FLAGS_C;
332 case 0x76: /* halt */
342 /* 16-bit arithmetic group */
347 op_add_reg16_reg16(RR_HL, OP_RR(op));
353 op_incdec_reg16(OP_RR(op), 1);
359 op_incdec_reg16(OP_RR(op), -1);
362 /* rotate and shift group */
363 case 0x07: /* rlca */
369 case 0x0f: /* rrca */
376 /* jump group except jp cc, imm16 in default */
377 case 0xc3: /* jp imm16 */
378 regs.pc = fetch_imm16();
380 case 0x18: /* jr imm8 */
381 regs.pc += fetch_byte();
383 case 0x38: /* jr c, imm8 */
385 if(cond(CC_C)) regs.pc += disp;
387 case 0x30: /* jr nc, imm8 */
389 if(cond(CC_NC)) regs.pc += disp;
391 case 0x28: /* jr z, imm8 */
393 if(cond(CC_Z)) regs.pc += disp;
395 case 0x20: /* jr nz, imm8 */
397 if(cond(CC_NZ)) regs.pc += disp;
399 case 0xe9: /* jp (hl) */
400 regs.pc = regs.g.rr.hl;
402 case 0x10: /* djnz, imm8 */
404 if(--regs.g.r.b) regs.pc += disp;
407 /* call and return group except call cc,imm16/ret cc,imm16/rst */
409 op_call(fetch_imm16());
415 /* input and output group */
417 op_input(R_A, ((uint16_t)regs.g.r.a << 8) | fetch_byte());
420 op_output(((uint16_t)regs.g.r.a << 8) | fetch_byte(), R_A);
427 op_load_reg8_imm8(DEST_R(op), fetch_byte());
428 } else if(SRC_R(op) == 4 || SRC_R(op) == 5) {
429 int adj = (op & 1) ? -1 : 1;
430 if(DEST_R(op) != 6) {
431 op_incdec_reg8(DEST_R(op), adj);
433 op_incdec_mem(regs.g.rr.hl, adj);
439 if(DEST_R(op) != 6 && SRC_R(op) != 6) {
440 op_load_reg8_reg8(DEST_R(op), SRC_R(op));
443 op_load_reg8_mem(DEST_R(op), regs.g.rr.hl);
444 } else if(DEST_R(op) == 6) {
445 op_store_mem_reg8(regs.g.rr.hl, SRC_R(op));
452 op_alu_reg8(ALUOP(op), SRC_R(op));
457 if(SRC_R(op) == 6) { /* alu-op a, imm8 */
458 op_alu_imm8(ALUOP(op), fetch_byte());
460 } else if(SRC_R(op) == 2) { /* jp cc, imm16 */
461 addr = fetch_imm16();
462 if(cond(OPCOND(op))) {
466 } else if(SRC_R(op) == 4) { /* call cc, imm16 */
467 addr = fetch_imm16();
468 if(cond(OPCOND(op))) op_call(addr);
470 } else if(SRC_R(op) == 0) { /* ret cc, imm16 */
471 addr = fetch_imm16();
472 if(cond(OPCOND(op))) op_ret();
474 } else if(SRC_R(op) == 7) { /* rst */
475 op_call(RST_ADDR(op));
483 break; /* treat any unknown opcodes as nops */
487 static void runop_ed(uint8_t op)
491 static void runop_cb(uint8_t op)
495 static void runop_dd(uint8_t op)
499 static void runop_fd(uint8_t op)
503 static void runop_ddcb(uint8_t op)
507 static void runop_fdcb(uint8_t op)
511 static void set_reg8(int r, uint8_t val)
516 static void set_reg8s(int r, int8_t val)
518 *regptr8[r] = *(uint8_t*)&val;
521 static uint8_t get_reg8(int r)
526 static int8_t get_reg8s(int r)
528 return *(int8_t*)regptr8[r];
531 static void set_reg16(int r, uint16_t val)
536 static void set_reg16s(int r, int16_t val)
538 *regptr16[r] = *(uint16_t*)&val;
541 static uint16_t get_reg16(int r)
546 static int16_t get_reg16s(int r)
548 return *(int16_t*)regptr16[r];
551 static void set_flag(unsigned int flag, int val)
560 static int parity(int x)
570 static int overflow(int x)
572 return x > 127 || x < -128;
575 static int overflow16(int x)
577 return x > 32767 || x < -32768;
580 static void op_load_reg8_reg8(int rdest, int rsrc)
582 set_reg8(rdest, get_reg8(rsrc));
585 static void op_load_reg8_imm8(int rdest, uint8_t imm)
587 set_reg8(rdest, imm);
590 static void op_load_reg8_mem(int rdest, uint16_t addr)
592 set_reg8(rdest, emu_mem_read(addr));
595 static void op_store_mem_reg8(uint16_t addr, int rsrc)
597 emu_mem_write(addr, get_reg8(rsrc));
600 static void op_store_mem_imm8(uint16_t addr, uint8_t imm)
602 emu_mem_write(addr, imm);
605 static void op_store_mem_reg16(uint16_t addr, int rsrc)
607 uint16_t val = get_reg16(rsrc);
608 emu_mem_write(addr, val);
609 emu_mem_write(addr + 1, val >> 8);
612 static void op_load_reg16_imm16(int rdest, uint16_t imm)
614 set_reg16(rdest, imm);
617 static void op_load_reg16_reg16(int rdest, int rsrc)
619 set_reg16(rdest, get_reg16(rsrc));
622 static void op_exch_mem_reg16(uint16_t addr, int rr)
624 uint16_t val = get_reg16(rr);
625 uint16_t lsb = emu_mem_read(addr);
626 uint16_t msb = emu_mem_read(addr + 1);
627 set_reg16(rr, lsb | (msb << 8));
628 emu_mem_write(addr, val);
629 emu_mem_write(addr + 1, val >> 8);
632 #define CARRY (regs.g.r.f & 1)
634 static void op_alu_reg8(int op, int r)
636 op_alu_imm8(op, get_reg8(r));
639 static void op_alu_imm8(int op, uint8_t imm)
642 int acc = get_reg8s(R_A);
643 int rval = *(int8_t*)&imm;
655 h = ((acc & 0xf) + (rval + 0xf)) & 0x10;
668 h = ((acc & 0xf) + (rval + 0xf) + CARRY) & 0x10;
696 set_flag(FLAGS_S, acc & 0x80);
697 set_flag(FLAGS_Z, acc == 0);
698 set_flag(FLAGS_H, h);
699 set_flag(FLAGS_PV, pv);
700 set_flag(FLAGS_N, n);
701 set_flag(FLAGS_C, c);
708 static void op_incdec_reg8(int r, int adj)
710 int prev = get_reg8s(r);
711 int val = prev + adj;
713 set_flag(FLAGS_S, val & 0x80);
714 set_flag(FLAGS_Z, val == 0);
715 set_flag(FLAGS_H, ((prev & 0xf) + adj) & 0x10);
716 set_flag(FLAGS_PV, overflow(val));
717 set_flag(FLAGS_N, adj < 0);
722 static void op_incdec_reg16(int r, int adj)
724 set_reg16s(r, get_reg16s(r) + adj);
727 static void op_incdec_mem(uint16_t addr, int adj)
729 uint16_t lsb = emu_mem_read(addr);
730 uint16_t msb = emu_mem_read(addr + 1);
734 prev = *(int16_t*)&lsb;
737 set_flag(FLAGS_S, val & 0x8000);
738 set_flag(FLAGS_Z, val == 0);
739 set_flag(FLAGS_H, ((prev & 0xfff) + adj) & 0x1000);
740 set_flag(FLAGS_PV, overflow16(val));
741 set_flag(FLAGS_N, adj < 0);
743 lsb = *(uint16_t*)&val;
744 emu_mem_write(addr, lsb);
745 emu_mem_write(addr + 1, lsb >> 8);
748 static void op_add_reg16_reg16(int rdest, int rsrc)
752 static void op_rl_reg8(int r, int width)
756 static void op_rr_reg8(int r, int width)
760 static void op_push_reg16(int r)
764 static void op_pop_reg16(int r)
768 static void op_call(uint16_t addr)
772 static void op_ret(void)
776 static void op_input(int r, uint16_t addr)
778 set_reg8(r, emu_io_read(addr));
781 static void op_output(uint16_t addr, int r)
783 emu_io_write(addr, get_reg8(r));