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