diff --git a/src/gbemu/cpu.c b/src/gbemu/cpu.c index f92dd00..282d3f9 100644 --- a/src/gbemu/cpu.c +++ b/src/gbemu/cpu.c @@ -150,7 +150,6 @@ static const unsigned int cb_op_cycles[256] = { 0 }; #define LD_D16(cpu, reg) \ do { \ - printf("LD_D16 " #reg "\n"); \ (reg) = (cpu)->mem_read((cpu), (cpu)->pc++); \ (reg) |= (uint16_t) (cpu)->mem_read((cpu), (cpu)->pc++) << 8; \ } while (0) @@ -233,17 +232,18 @@ static const unsigned int cb_op_cycles[256] = { 0 }; #define CP_8(cpu, dst, src) \ do { \ uint8_t _tmp; \ + uint8_t _dst = dst; \ + uint8_t _src = src; \ (cpu)->nf = 1; \ - (cpu)->hf = CALC_H_SUB((dst), (src)); \ - (cpu)->cf = CALC_C_SUB((dst), (src)); \ - _tmp = (dst) - (src); \ + (cpu)->hf = CALC_H_SUB((_dst), (_src)); \ + (cpu)->cf = CALC_C_SUB((_dst), (_src)); \ + _tmp = (_dst) - (_src); \ (cpu)->zf = ((_tmp) == 0); \ } while (0) - #define JR_8(cpu) \ do { \ - val_16 = cpu->mem_read(cpu, cpu->pc); \ + val_16 = cpu->mem_read(cpu, cpu->pc++); \ /* sign-extend */ \ val_16 |= GET_BIT(val_16, 7) ? 0xff00 : 0; \ cpu->pc += val_16; \ @@ -253,7 +253,7 @@ static const unsigned int cb_op_cycles[256] = { 0 }; #define POP_16(cpu, dst) \ do { \ (dst) = (cpu)->mem_read((cpu), (cpu)->sp++); \ - (dst) = (uint16_t) (cpu)->mem_read((cpu), (cpu)->sp++) << 8; \ + (dst) |= (uint16_t) (cpu)->mem_read((cpu), (cpu)->sp++) << 8; \ } while (0) #define PUSH_16(cpu, src) \ @@ -264,18 +264,20 @@ static const unsigned int cb_op_cycles[256] = { 0 }; #define CALL(cpu) \ do { \ + uint16_t pc_base; \ cpu->mem_write(cpu, --cpu->sp, cpu->pc); \ cpu->mem_write(cpu, --cpu->sp, cpu->pc >> 8); \ - cpu->pc = cpu->mem_read(cpu, cpu->pc++); \ - cpu->pc |= (uint16_t) cpu->mem_read(cpu, cpu->pc) << 8; \ - cpu->pc++; \ + pc_base = cpu->mem_read(cpu, cpu->pc++); \ + pc_base |= (uint16_t) cpu->mem_read(cpu, cpu->pc) << 8; \ + cpu->pc = pc_base; \ } while (0) #define RET(cpu) \ do { \ (cpu)->pc = 0; \ - (cpu)->pc |= (uint16_t) (cpu)->mem_read((cpu), (cpu)->sp--) << 8; \ - (cpu)->pc |= (cpu)->mem_read((cpu), (cpu)->sp--); \ + (cpu)->pc |= (uint16_t) (cpu)->mem_read((cpu), (cpu)->sp++) << 8; \ + (cpu)->pc |= (cpu)->mem_read((cpu), (cpu)->sp++); \ + (cpu)->pc += 2; \ } while (0) #define RST(cpu, n) \ @@ -283,7 +285,26 @@ static const unsigned int cb_op_cycles[256] = { 0 }; (cpu)->mem_write((cpu), (cpu)->sp++, (cpu)->pc >> 8); \ (cpu)->mem_write((cpu), (cpu)->sp++, (cpu)->pc); \ (cpu)->pc = (n); \ - } while (0); + } while (0) + +#define BIT(cpu, reg, bit) \ + do { \ + (cpu)->zf = !GET_BIT(reg, bit); \ + (cpu)->nf = 0; \ + (cpu)->hf = 1; \ + } while (0) + +#define RL(cpu, reg) \ + do { \ + uint8_t ci = (cpu)->cf; \ + uint8_t tmp = reg; \ + (cpu)->nf = 0; \ + (cpu)->hf = 0; \ + (cpu)->cf = GET_BIT(tmp, 7); \ + tmp = tmp << 1; \ + (tmp) |= ci; \ + (cpu)->zf = (tmp) == 0; \ + } while (0) void lr35902_cycle(struct lr35902_state *cpu) { @@ -292,16 +313,19 @@ void lr35902_cycle(struct lr35902_state *cpu) uint8_t val; uint16_t val_16; + cpu->metrics.cycles++; + if (cpu->stall_cycles > 0) { cpu->stall_cycles--; + if (cpu->stall_cycles == 0) { + cpu->metrics.retired_instrs++; + } return; } inst = cpu->mem_read(cpu, cpu->pc++); cycles = op_cycles[inst]; - printf("running command\n"); - switch (inst) { case 0x00: /* NOP */ break; @@ -948,7 +972,9 @@ void lr35902_cycle(struct lr35902_state *cpu) cpu->pc += 2; } break; - case 0xc5: + case 0xc5: /* PUSH BC */ + PUSH_16(cpu, cpu->bc); + break; case 0xc6: case 0xc7: /* RST 00 */ RST(cpu, 0); @@ -983,13 +1009,29 @@ void lr35902_cycle(struct lr35902_state *cpu) case 0x0e: case 0x0f: case 0x10: + RL(cpu, cpu->b); + break; case 0x11: + RL(cpu, cpu->c); + break; case 0x12: + RL(cpu, cpu->d); + break; case 0x13: + RL(cpu, cpu->e); + break; case 0x14: + RL(cpu, cpu->h); + break; case 0x15: + RL(cpu, cpu->l); + break; case 0x16: + ASSERT(0); + break; case 0x17: + RL(cpu, cpu->a); + break; case 0x18: case 0x19: case 0x1a: @@ -1090,10 +1132,16 @@ void lr35902_cycle(struct lr35902_state *cpu) case 0x79: case 0x7a: case 0x7b: + assert(0); case 0x7c: + BIT(cpu, cpu->h, 7); + break; case 0x7d: case 0x7e: + assert(0); case 0x7f: + BIT(cpu, cpu->a, 7); + break; case 0x80: case 0x81: case 0x82: @@ -1258,7 +1306,9 @@ void lr35902_cycle(struct lr35902_state *cpu) cpu->pc += 2; } break; - case 0xd5: + case 0xd5:/* PUSH DE */ + PUSH_16(cpu, cpu->de); + break; case 0xd6: case 0xd7: /* RST 0x10 */ RST(cpu, 0x10); @@ -1297,14 +1347,20 @@ void lr35902_cycle(struct lr35902_state *cpu) break; case 0xe4: /* UNDEF */ break; - case 0xe5: + case 0xe5: /* PUSH HL */ + PUSH_16(cpu, cpu->hl); + break; case 0xe6: case 0xe7: /* RST 0x20 */ RST(cpu, 0x20); break; case 0xe8: case 0xe9: - case 0xea: + case 0xea: /* LD (a16), A */ + val_16 = cpu->mem_read(cpu, cpu->pc++); + val_16 |= cpu->mem_read(cpu, cpu->pc++) << 8; + cpu->mem_write(cpu, val_16, cpu->a); + break; case 0xeb: /* UNDEF */ break; case 0xec: /* UNDEF */ @@ -1328,7 +1384,9 @@ void lr35902_cycle(struct lr35902_state *cpu) case 0xf3: case 0xf4: /* UNDEF */ break; - case 0xf5: + case 0xf5: /* PUSH AF */ + PUSH_16(cpu, cpu->af); + break; case 0xf6: case 0xf7: /* RST 0x30 */ RST(cpu, 0x30); @@ -1341,7 +1399,9 @@ void lr35902_cycle(struct lr35902_state *cpu) break; case 0xfd: /* UNDEF */ break; - case 0xfe: + case 0xfe: /* CP d8 */ + CP_8(cpu, cpu->a, cpu->mem_read(cpu, cpu->pc++)); + break; case 0xff: /* RST 0x38 */ RST(cpu, 0x38); break; diff --git a/src/gbemu/cpu.h b/src/gbemu/cpu.h index 2187349..c2676d0 100644 --- a/src/gbemu/cpu.h +++ b/src/gbemu/cpu.h @@ -80,7 +80,7 @@ struct lr35902_state { uint8_t regs_8[NUM_LR35902_REGS_8]; struct { - uint8_t b, c, d, e, h, l, a, f_dummy; + uint8_t c, b, e, d, l, h, f_dummy, a; }; };