diff --git a/src/gbemu/cpu.c b/src/gbemu/cpu.c index f2f2f55..89c1d22 100644 --- a/src/gbemu/cpu.c +++ b/src/gbemu/cpu.c @@ -170,25 +170,25 @@ static const unsigned int cb_extra_cycles[256] = { 0 }; (cpu)->zf = (dst) == 0; \ } while (0) -#define ADD_16(cpu, dst, src) \ - do { \ - uint16_t _src = src; \ - (cpu)->nf = 0; \ +#define ADD_16(cpu, dst, src) \ + do { \ + uint16_t _src = src; \ + (cpu)->nf = 0; \ (cpu)->hf = (dst & 0xfff) + (_src & 0xfff) > 0xfff; \ - (cpu)->cf = CALC_C_ADD_16(dst, _src); \ - (dst) = _src + dst; \ - } while (0) \ + (cpu)->cf = CALC_C_ADD_16(dst, _src); \ + (dst) = _src + dst; \ + } while (0) \ -#define ADC_8(cpu, dst, src) \ - do { \ - uint16_t _tmp; \ - uint16_t _reg = src; \ - _tmp = _reg + dst + cpu->cf; \ - cpu->nf = 0; \ - cpu->hf = _reg + dst + cpu->cf > 0xff; \ - cpu->cf = !(_tmp & 0xff); \ - (dst) = _tmp; \ - cpu->zf = !(dst); \ +#define ADC_8(cpu, dst, src) \ + do { \ + uint16_t _dst = dst; \ + uint16_t _src = src; \ + cpu->nf = 0; \ + cpu->hf = ((_src & 0xf) + (_dst & 0xf) + cpu->cf) > 0xf; \ + _dst = _src + _dst + cpu->cf; \ + cpu->cf = _dst > 0xff; \ + cpu->zf = !(_dst & 0xff); \ + (dst) = _dst; \ } while (0) #define SUB_8(cpu, dst, src) \ @@ -199,20 +199,21 @@ static const unsigned int cb_extra_cycles[256] = { 0 }; (cpu)->cf = _reg > dst; \ (cpu)->nf = 1; \ (cpu)->hf = CALC_H_SUB(dst, _reg); \ - (cpu)->zf = tmp == 0; \ + (cpu)->zf = !tmp; \ dst = tmp; \ } while (0) -#define SBC_8(cpu, dst, src) \ - do { \ - int tmp; \ - uint8_t _reg = src; \ - tmp = (dst) - (_reg) - (cpu->cf); \ - (cpu)->cf = _reg + (cpu->cf) > dst; \ - (cpu)->nf = 1; \ - (cpu)->hf = CALC_H_ADD(_reg, dst); \ - (cpu)->zf = tmp == 0; \ - (dst) = (tmp); \ +#define SBC_8(cpu, dst, src) \ + do { \ + int tmp; \ + uint8_t _reg = src; \ + uint8_t cf = cpu->cf; \ + tmp = (dst) - (_reg) - (cpu->cf); \ + (cpu)->cf = tmp < 0; \ + (cpu)->nf = 1; \ + (cpu)->hf = ((dst & 0xf) - (_reg & 0xf) - cf) < 0 ; \ + (dst) = (tmp); \ + (cpu)->zf = dst == 0; \ } while (0) #define AND_8(cpu, dst, src) \ @@ -330,6 +331,37 @@ static const unsigned int cb_extra_cycles[256] = { 0 }; reg = tmp; \ } while (0) +#define RLC(cpu, reg) \ + do { \ + uint8_t tmp = reg; \ + (cpu)->nf = 0; \ + (cpu)->hf = 0; \ + (cpu)->cf = GET_BIT(tmp, 7); \ + tmp = tmp << 1; \ + tmp |= (cpu)->cf; \ + (cpu)->zf = (tmp) == 0; \ + reg = tmp; \ + } while (0) + +#define RRC(cpu, reg) \ + do { \ + cpu->cf = GET_BIT(reg, 0); \ + cpu->nf = 0; \ + cpu->hf = 0; \ + (reg) >>= 1; \ + WRITE_BIT(reg, 7, cpu->cf); \ + cpu->zf = (reg == 0); \ + } while (0) + +#define SLA(cpu, reg) \ + do { \ + cpu->cf = GET_BIT(reg, 7); \ + reg <<= 1; \ + cpu->nf = 0; \ + cpu->zf = !reg; \ + cpu->hf = 0; \ + } while (0) + #define SRL(cpu, reg) \ do { \ cpu->cf = GET_BIT(reg, 0); \ @@ -350,6 +382,16 @@ static const unsigned int cb_extra_cycles[256] = { 0 }; cpu->hf = 0; \ } while (0) +#define SRA(cpu, reg) \ + do { \ + uint8_t val = GET_BIT(reg, 7); \ + cpu->cf = GET_BIT(reg, 0); \ + cpu->nf = 0; \ + cpu->hf = 0; \ + reg = (val << 7) | (reg >> 1); \ + cpu->zf = !reg; \ + } while (0) \ + #define SWAP(cpu, reg) \ do { \ uint8_t tmp = reg << 4; \ @@ -428,12 +470,8 @@ int lr35902_cycle(struct lr35902_state *cpu) LD_D8(cpu, cpu->c); break; case 0x0f: /* RRCA */ - cpu->cf = GET_BIT(cpu->a, 0); - cpu->nf = 0; + RRC(cpu, cpu->a); cpu->zf = 0; - cpu->hf = 0; - cpu->a >>= 1; - WRITE_BIT(cpu->a, 7, cpu->cf); break; case 0x10: /* STOP */ ASSERT(0); //TODO: Implement me @@ -473,8 +511,8 @@ int lr35902_cycle(struct lr35902_state *cpu) case 0x1a: /* LD A, (DE) */ cpu->a = gb_mem_read(cpu->memory, cpu->de); break; - case 0x1b: /* DEC BC */ - cpu->bc--; + case 0x1b: /* DEC DE */ + cpu->de--; break; case 0x1c: /* INC E */ INC_8(cpu, cpu->e); @@ -585,7 +623,7 @@ int lr35902_cycle(struct lr35902_state *cpu) break; case 0x36: /* LD (HL), d8 */ val = gb_mem_read(cpu->memory, cpu->pc++); - gb_mem_write(cpu->memory, cpu->hl++, val); + gb_mem_write(cpu->memory, cpu->hl, val); break; case 0x37: /* SCF */ cpu->nf = 0; @@ -618,6 +656,8 @@ int lr35902_cycle(struct lr35902_state *cpu) LD_D8(cpu, cpu->a); break; case 0x3f: /* CCF */ + cpu->nf = 0; + cpu->hf = 0; cpu->cf = !cpu->cf; break; case 0x40: /* LD B,B */ @@ -830,7 +870,7 @@ int lr35902_cycle(struct lr35902_state *cpu) ADD_8(cpu, cpu->a, cpu->a); break; case 0x88: /* ADC A,B */ - ADC_8(cpu, cpu->a, cpu->a); + ADC_8(cpu, cpu->a, cpu->b); break; case 0x89: /* ADC A,C */ ADC_8(cpu, cpu->a, cpu->c); @@ -1054,22 +1094,57 @@ int lr35902_cycle(struct lr35902_state *cpu) cycles = cb_extra_cycles[inst]; switch (inst) { case 0x00: + RLC(cpu, cpu->b); + break; case 0x01: + RLC(cpu, cpu->c); + break; case 0x02: + RLC(cpu, cpu->d); + break; case 0x03: + RLC(cpu, cpu->e); + break; case 0x04: + RLC(cpu, cpu->h); + break; case 0x05: + RLC(cpu, cpu->l); + break; case 0x06: + val = gb_mem_read(cpu->memory, cpu->hl); + RLC(cpu, val); + gb_mem_write(cpu->memory, cpu->hl, val); + break; case 0x07: + RLC(cpu, cpu->a); + break; case 0x08: + RRC(cpu, cpu->b); + break; case 0x09: + RRC(cpu, cpu->c); + break; case 0x0a: + RRC(cpu, cpu->d); + break; case 0x0b: + RRC(cpu, cpu->e); + break; case 0x0c: + RRC(cpu, cpu->h); + break; case 0x0d: + RRC(cpu, cpu->l); + break; case 0x0e: + val = gb_mem_read(cpu->memory, cpu->hl); + RLC(cpu, val); + gb_mem_write(cpu->memory, cpu->hl, val); + break; case 0x0f: - ASSERT(0); + RRC(cpu, cpu->a); + break; case 0x10: RL(cpu, cpu->b); break; @@ -1119,21 +1194,57 @@ int lr35902_cycle(struct lr35902_state *cpu) RR(cpu, cpu->a); break; case 0x20: + SLA(cpu, cpu->b); + break; case 0x21: + SLA(cpu, cpu->c); + break; case 0x22: + SLA(cpu, cpu->d); + break; case 0x23: + SLA(cpu, cpu->e); + break; case 0x24: + SLA(cpu, cpu->h); + break; case 0x25: + SLA(cpu, cpu->l); + break; case 0x26: + val = gb_mem_read(cpu->memory, cpu->hl); + SLA(cpu, val); + gb_mem_write(cpu->memory, cpu->hl, val); + break; case 0x27: + SLA(cpu, cpu->a); + break; case 0x28: + SRA(cpu, cpu->b); + break; case 0x29: + SRA(cpu, cpu->c); + break; case 0x2a: + SRA(cpu, cpu->d); + break; case 0x2b: + SRA(cpu, cpu->e); + break; case 0x2c: + SRA(cpu, cpu->h); + break; case 0x2d: + SRA(cpu, cpu->l); + break; case 0x2e: + val = gb_mem_read(cpu->memory, cpu->hl); + SRA(cpu, val); + gb_mem_write(cpu->memory, cpu->hl, val); + break; case 0x2f: + SRA(cpu, cpu->a); + break; case 0x30: SWAP(cpu, cpu->b); break; @@ -1442,7 +1553,7 @@ int lr35902_cycle(struct lr35902_state *cpu) case 0xcd: /* CALL */ CALL(cpu); break; - case 0xce: + case 0xce: /* ADC A, d8 */ val = gb_mem_read(cpu->memory, cpu->pc++); ADC_8(cpu, cpu->a, val); break; diff --git a/src/gbemu/video.c b/src/gbemu/video.c index 84c248b..3b42767 100644 --- a/src/gbemu/video.c +++ b/src/gbemu/video.c @@ -66,7 +66,7 @@ static void gb_video_screenshot(struct gb_video *video) uint8_t tile; int log = id == 30; - snprintf(filename, sizeof(filename), "screenshot-%d.bmp", id++); + snprintf(filename, sizeof(filename), "screenshot-%05d.bmp", id++); if (!(video->lcdcont & 1)) { goto out;