Corrected timing for many instructions
This commit is contained in:
parent
8dd5462525
commit
4a50000e83
158
Core/z80_cpu.c
158
Core/z80_cpu.c
@ -51,10 +51,13 @@ static void ld_rr_d16(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
{
|
{
|
||||||
uint8_t register_id;
|
uint8_t register_id;
|
||||||
uint16_t value;
|
uint16_t value;
|
||||||
GB_advance_cycles(gb, 12);
|
GB_advance_cycles(gb, 4);
|
||||||
register_id = (GB_read_memory(gb, gb->pc++) >> 4) + 1;
|
register_id = (opcode >> 4) + 1;
|
||||||
|
gb->pc++;
|
||||||
value = GB_read_memory(gb, gb->pc++);
|
value = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
value |= GB_read_memory(gb, gb->pc++) << 8;
|
value |= GB_read_memory(gb, gb->pc++) << 8;
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
gb->registers[register_id] = value;
|
gb->registers[register_id] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +75,8 @@ static void inc_rr(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
{
|
{
|
||||||
uint8_t register_id;
|
uint8_t register_id;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 8);
|
||||||
register_id = (GB_read_memory(gb, gb->pc++) >> 4) + 1;
|
register_id = (opcode >> 4) + 1;
|
||||||
|
gb->pc++;
|
||||||
gb->registers[register_id]++;
|
gb->registers[register_id]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,11 +119,12 @@ static void dec_hr(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void ld_hr_d8(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_hr_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t register_id;
|
uint8_t register_id;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
register_id = ((opcode >> 4) + 1) & 0x03;
|
register_id = ((opcode >> 4) + 1) & 0x03;
|
||||||
gb->registers[register_id] &= 0xFF;
|
gb->registers[register_id] &= 0xFF;
|
||||||
gb->registers[register_id] |= GB_read_memory(gb, gb->pc++) << 8;
|
gb->registers[register_id] |= GB_read_memory(gb, gb->pc++) << 8;
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rlca(GB_gameboy_t *gb, uint8_t opcode)
|
static void rlca(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
@ -150,14 +155,20 @@ static void rla(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ld_da16_sp(GB_gameboy_t *gb, uint8_t opcode){
|
static void ld_da16_sp(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
|
{
|
||||||
|
/* Todo: Verify order is correct */
|
||||||
uint16_t addr;
|
uint16_t addr;
|
||||||
GB_advance_cycles(gb, 20);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
addr = GB_read_memory(gb, gb->pc++);
|
addr = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
addr |= GB_read_memory(gb, gb->pc++) << 8;
|
addr |= GB_read_memory(gb, gb->pc++) << 8;
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
GB_write_memory(gb, addr, gb->registers[GB_REGISTER_SP] & 0xFF);
|
GB_write_memory(gb, addr, gb->registers[GB_REGISTER_SP] & 0xFF);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
GB_write_memory(gb, addr+1, gb->registers[GB_REGISTER_SP] >> 8);
|
GB_write_memory(gb, addr+1, gb->registers[GB_REGISTER_SP] >> 8);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_hl_rr(GB_gameboy_t *gb, uint8_t opcode)
|
static void add_hl_rr(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
@ -197,7 +208,8 @@ static void dec_rr(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
{
|
{
|
||||||
uint8_t register_id;
|
uint8_t register_id;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 8);
|
||||||
register_id = (GB_read_memory(gb, gb->pc++) >> 4) + 1;
|
register_id = (opcode >> 4) + 1;
|
||||||
|
gb->pc++;
|
||||||
gb->registers[register_id]--;
|
gb->registers[register_id]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +218,8 @@ static void inc_lr(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
uint8_t register_id;
|
uint8_t register_id;
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
GB_advance_cycles(gb, 4);
|
GB_advance_cycles(gb, 4);
|
||||||
register_id = (GB_read_memory(gb, gb->pc++) >> 4) + 1;
|
register_id = (opcode >> 4) + 1;
|
||||||
|
gb->pc++;
|
||||||
|
|
||||||
value = (gb->registers[register_id] & 0xFF) + 1;
|
value = (gb->registers[register_id] & 0xFF) + 1;
|
||||||
gb->registers[register_id] = (gb->registers[register_id] & 0xFF00) | value;
|
gb->registers[register_id] = (gb->registers[register_id] & 0xFF00) | value;
|
||||||
@ -226,7 +239,8 @@ static void dec_lr(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
uint8_t register_id;
|
uint8_t register_id;
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
GB_advance_cycles(gb, 4);
|
GB_advance_cycles(gb, 4);
|
||||||
register_id = (GB_read_memory(gb, gb->pc++) >> 4) + 1;
|
register_id = (opcode >> 4) + 1;
|
||||||
|
gb->pc++;
|
||||||
|
|
||||||
value = (gb->registers[register_id] & 0xFF) - 1;
|
value = (gb->registers[register_id] & 0xFF) - 1;
|
||||||
gb->registers[register_id] = (gb->registers[register_id] & 0xFF00) | value;
|
gb->registers[register_id] = (gb->registers[register_id] & 0xFF00) | value;
|
||||||
@ -246,10 +260,12 @@ static void dec_lr(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void ld_lr_d8(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_lr_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t register_id;
|
uint8_t register_id;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
register_id = (GB_read_memory(gb, gb->pc++) >> 4) + 1;
|
register_id = (opcode >> 4) + 1;
|
||||||
|
gb->pc++;
|
||||||
gb->registers[register_id] &= 0xFF00;
|
gb->registers[register_id] &= 0xFF00;
|
||||||
gb->registers[register_id] |= GB_read_memory(gb, gb->pc++);
|
gb->registers[register_id] |= GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rrca(GB_gameboy_t *gb, uint8_t opcode)
|
static void rrca(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
@ -282,9 +298,11 @@ static void rra(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
|
|
||||||
static void jr_r8(GB_gameboy_t *gb, uint8_t opcode)
|
static void jr_r8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
GB_advance_cycles(gb, 12);
|
/* Todo: Verify cycles are not 8 and 4 instead */
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
gb->pc += (int8_t) GB_read_memory(gb, gb->pc++);
|
gb->pc += (int8_t) GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool condition_code(GB_gameboy_t *gb, uint8_t opcode)
|
static bool condition_code(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
@ -305,9 +323,11 @@ static bool condition_code(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
|
|
||||||
static void jr_cc_r8(GB_gameboy_t *gb, uint8_t opcode)
|
static void jr_cc_r8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
if (condition_code(gb, GB_read_memory(gb, gb->pc++))) {
|
gb->pc++;
|
||||||
GB_advance_cycles(gb, 12);
|
if (condition_code(gb, opcode)) {
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc += (int8_t)GB_read_memory(gb, gb->pc++);
|
gb->pc += (int8_t)GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 8);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 8);
|
||||||
@ -395,42 +415,47 @@ static void ccf(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
|
|
||||||
static void ld_dhli_a(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_dhli_a(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
GB_write_memory(gb, gb->registers[GB_REGISTER_HL]++, gb->registers[GB_REGISTER_AF] >> 8);
|
GB_write_memory(gb, gb->registers[GB_REGISTER_HL]++, gb->registers[GB_REGISTER_AF] >> 8);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ld_dhld_a(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_dhld_a(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
GB_write_memory(gb, gb->registers[GB_REGISTER_HL]--, gb->registers[GB_REGISTER_AF] >> 8);
|
GB_write_memory(gb, gb->registers[GB_REGISTER_HL]--, gb->registers[GB_REGISTER_AF] >> 8);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ld_a_dhli(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_a_dhli(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
||||||
gb->registers[GB_REGISTER_AF] |= GB_read_memory(gb, gb->registers[GB_REGISTER_HL]++) << 8;
|
gb->registers[GB_REGISTER_AF] |= GB_read_memory(gb, gb->registers[GB_REGISTER_HL]++) << 8;
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ld_a_dhld(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_a_dhld(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
||||||
gb->registers[GB_REGISTER_AF] |= GB_read_memory(gb, gb->registers[GB_REGISTER_HL]--) << 8;
|
gb->registers[GB_REGISTER_AF] |= GB_read_memory(gb, gb->registers[GB_REGISTER_HL]--) << 8;
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inc_dhl(GB_gameboy_t *gb, uint8_t opcode)
|
static void inc_dhl(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = GB_read_memory(gb, gb->registers[GB_REGISTER_HL]) + 1;
|
value = GB_read_memory(gb, gb->registers[GB_REGISTER_HL]) + 1;
|
||||||
GB_advance_cycles(gb, 4);
|
GB_advance_cycles(gb, 4);
|
||||||
GB_write_memory(gb, gb->registers[GB_REGISTER_HL], value);
|
GB_write_memory(gb, gb->registers[GB_REGISTER_HL], value);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
|
|
||||||
gb->registers[GB_REGISTER_AF] &= ~(GB_SUBSTRACT_FLAG | GB_ZERO_FLAG | GB_HALF_CARRY_FLAG);
|
gb->registers[GB_REGISTER_AF] &= ~(GB_SUBSTRACT_FLAG | GB_ZERO_FLAG | GB_HALF_CARRY_FLAG);
|
||||||
if ((value & 0x0F) == 0) {
|
if ((value & 0x0F) == 0) {
|
||||||
@ -445,11 +470,12 @@ static void inc_dhl(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void dec_dhl(GB_gameboy_t *gb, uint8_t opcode)
|
static void dec_dhl(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = GB_read_memory(gb, gb->registers[GB_REGISTER_HL]) - 1;
|
value = GB_read_memory(gb, gb->registers[GB_REGISTER_HL]) - 1;
|
||||||
GB_advance_cycles(gb, 4);
|
GB_advance_cycles(gb, 4);
|
||||||
GB_write_memory(gb, gb->registers[GB_REGISTER_HL], value);
|
GB_write_memory(gb, gb->registers[GB_REGISTER_HL], value);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
|
|
||||||
gb->registers[GB_REGISTER_AF] &= ~( GB_ZERO_FLAG | GB_HALF_CARRY_FLAG);
|
gb->registers[GB_REGISTER_AF] &= ~( GB_ZERO_FLAG | GB_HALF_CARRY_FLAG);
|
||||||
gb->registers[GB_REGISTER_AF] |= GB_SUBSTRACT_FLAG;
|
gb->registers[GB_REGISTER_AF] |= GB_SUBSTRACT_FLAG;
|
||||||
@ -464,9 +490,12 @@ static void dec_dhl(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
|
|
||||||
static void ld_dhl_d8(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_dhl_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
GB_advance_cycles(gb, 12);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
GB_write_memory(gb, gb->registers[GB_REGISTER_HL], GB_read_memory(gb, gb->pc++));
|
uint8_t data = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
|
GB_write_memory(gb, gb->registers[GB_REGISTER_HL], data);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t get_src_value(GB_gameboy_t *gb, uint8_t opcode)
|
uint8_t get_src_value(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
@ -479,8 +508,9 @@ uint8_t get_src_value(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
if (src_low) {
|
if (src_low) {
|
||||||
return gb->registers[GB_REGISTER_AF] >> 8;
|
return gb->registers[GB_REGISTER_AF] >> 8;
|
||||||
}
|
}
|
||||||
|
uint8_t ret = GB_read_memory(gb, gb->registers[GB_REGISTER_HL]);
|
||||||
GB_advance_cycles(gb, 4);
|
GB_advance_cycles(gb, 4);
|
||||||
return GB_read_memory(gb, gb->registers[GB_REGISTER_HL]);
|
return ret;
|
||||||
}
|
}
|
||||||
if (src_low) {
|
if (src_low) {
|
||||||
return gb->registers[src_register_id] & 0xFF;
|
return gb->registers[src_register_id] & 0xFF;
|
||||||
@ -501,8 +531,8 @@ static void set_src_value(GB_gameboy_t *gb, uint8_t opcode, uint8_t value)
|
|||||||
gb->registers[GB_REGISTER_AF] |= value << 8;
|
gb->registers[GB_REGISTER_AF] |= value << 8;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GB_advance_cycles(gb, 4);
|
|
||||||
GB_write_memory(gb, gb->registers[GB_REGISTER_HL], value);
|
GB_write_memory(gb, gb->registers[GB_REGISTER_HL], value);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -529,16 +559,14 @@ static void ld_r_r(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
dst_low = opcode & 8;
|
dst_low = opcode & 8;
|
||||||
value = get_src_value(gb, opcode);
|
value = get_src_value(gb, opcode);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (dst_register_id == GB_REGISTER_AF) {
|
if (dst_register_id == GB_REGISTER_AF) {
|
||||||
if (dst_low) {
|
if (dst_low) {
|
||||||
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
||||||
gb->registers[GB_REGISTER_AF] |= value << 8;
|
gb->registers[GB_REGISTER_AF] |= value << 8;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GB_advance_cycles(gb, 4);
|
|
||||||
GB_write_memory(gb, gb->registers[GB_REGISTER_HL], value);
|
GB_write_memory(gb, gb->registers[GB_REGISTER_HL], value);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -702,11 +730,14 @@ static void halt(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
|
|
||||||
static void ret_cc(GB_gameboy_t *gb, uint8_t opcode)
|
static void ret_cc(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
|
/* Todo: Verify timing */
|
||||||
if (condition_code(gb, GB_read_memory(gb, gb->pc++))) {
|
if (condition_code(gb, GB_read_memory(gb, gb->pc++))) {
|
||||||
GB_debugger_ret_hook(gb);
|
GB_debugger_ret_hook(gb);
|
||||||
GB_advance_cycles(gb, 20);
|
GB_advance_cycles(gb, 8);
|
||||||
gb->pc = GB_read_memory(gb, gb->registers[GB_REGISTER_SP]) |
|
gb->pc = GB_read_memory(gb, gb->registers[GB_REGISTER_SP]);
|
||||||
(GB_read_memory(gb, gb->registers[GB_REGISTER_SP] + 1) << 8);
|
GB_advance_cycles(gb, 4);
|
||||||
|
gb->pc |= GB_read_memory(gb, gb->registers[GB_REGISTER_SP] + 1) << 8;
|
||||||
|
GB_advance_cycles(gb, 8);
|
||||||
gb->registers[GB_REGISTER_SP] += 2;
|
gb->registers[GB_REGISTER_SP] += 2;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -720,10 +751,10 @@ static void pop_rr(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
GB_advance_cycles(gb, 4);
|
GB_advance_cycles(gb, 4);
|
||||||
register_id = ((opcode >> 4) + 1) & 3;
|
register_id = ((opcode >> 4) + 1) & 3;
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
GB_advance_cycles(gb, 4);
|
|
||||||
gb->registers[register_id] = GB_read_memory(gb, gb->registers[GB_REGISTER_SP]);
|
gb->registers[register_id] = GB_read_memory(gb, gb->registers[GB_REGISTER_SP]);
|
||||||
GB_advance_cycles(gb, 4);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->registers[register_id] |= GB_read_memory(gb, gb->registers[GB_REGISTER_SP] + 1) << 8;
|
gb->registers[register_id] |= GB_read_memory(gb, gb->registers[GB_REGISTER_SP] + 1) << 8;
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
gb->registers[GB_REGISTER_AF] &= 0xFFF0; // Make sure we don't set impossible flags on F! See Blargg's PUSH AF test.
|
gb->registers[GB_REGISTER_AF] &= 0xFFF0; // Make sure we don't set impossible flags on F! See Blargg's PUSH AF test.
|
||||||
gb->registers[GB_REGISTER_SP] += 2;
|
gb->registers[GB_REGISTER_SP] += 2;
|
||||||
}
|
}
|
||||||
@ -796,9 +827,10 @@ static void push_rr(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void add_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
static void add_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value, a;
|
uint8_t value, a;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = GB_read_memory(gb, gb->pc++);
|
value = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
a = gb->registers[GB_REGISTER_AF] >> 8;
|
a = gb->registers[GB_REGISTER_AF] >> 8;
|
||||||
gb->registers[GB_REGISTER_AF] = (a + value) << 8;
|
gb->registers[GB_REGISTER_AF] = (a + value) << 8;
|
||||||
if ((uint8_t) (a + value) == 0) {
|
if ((uint8_t) (a + value) == 0) {
|
||||||
@ -815,9 +847,10 @@ static void add_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void adc_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
static void adc_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value, a, carry;
|
uint8_t value, a, carry;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = GB_read_memory(gb, gb->pc++);
|
value = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
a = gb->registers[GB_REGISTER_AF] >> 8;
|
a = gb->registers[GB_REGISTER_AF] >> 8;
|
||||||
carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0;
|
carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0;
|
||||||
gb->registers[GB_REGISTER_AF] = (a + value + carry) << 8;
|
gb->registers[GB_REGISTER_AF] = (a + value + carry) << 8;
|
||||||
@ -836,9 +869,10 @@ static void adc_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void sub_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
static void sub_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value, a;
|
uint8_t value, a;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = GB_read_memory(gb, gb->pc++);
|
value = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
a = gb->registers[GB_REGISTER_AF] >> 8;
|
a = gb->registers[GB_REGISTER_AF] >> 8;
|
||||||
gb->registers[GB_REGISTER_AF] = ((a - value) << 8) | GB_SUBSTRACT_FLAG;
|
gb->registers[GB_REGISTER_AF] = ((a - value) << 8) | GB_SUBSTRACT_FLAG;
|
||||||
if (a == value) {
|
if (a == value) {
|
||||||
@ -855,9 +889,10 @@ static void sub_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void sbc_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
static void sbc_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value, a, carry;
|
uint8_t value, a, carry;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = GB_read_memory(gb, gb->pc++);
|
value = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
a = gb->registers[GB_REGISTER_AF] >> 8;
|
a = gb->registers[GB_REGISTER_AF] >> 8;
|
||||||
carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0;
|
carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0;
|
||||||
gb->registers[GB_REGISTER_AF] = ((a - value - carry) << 8) | GB_SUBSTRACT_FLAG;
|
gb->registers[GB_REGISTER_AF] = ((a - value - carry) << 8) | GB_SUBSTRACT_FLAG;
|
||||||
@ -876,9 +911,10 @@ static void sbc_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void and_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
static void and_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value, a;
|
uint8_t value, a;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = GB_read_memory(gb, gb->pc++);
|
value = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
a = gb->registers[GB_REGISTER_AF] >> 8;
|
a = gb->registers[GB_REGISTER_AF] >> 8;
|
||||||
gb->registers[GB_REGISTER_AF] = ((a & value) << 8) | GB_HALF_CARRY_FLAG;
|
gb->registers[GB_REGISTER_AF] = ((a & value) << 8) | GB_HALF_CARRY_FLAG;
|
||||||
if ((a & value) == 0) {
|
if ((a & value) == 0) {
|
||||||
@ -889,9 +925,10 @@ static void and_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void xor_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
static void xor_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value, a;
|
uint8_t value, a;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = GB_read_memory(gb, gb->pc++);
|
value = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
a = gb->registers[GB_REGISTER_AF] >> 8;
|
a = gb->registers[GB_REGISTER_AF] >> 8;
|
||||||
gb->registers[GB_REGISTER_AF] = (a ^ value) << 8;
|
gb->registers[GB_REGISTER_AF] = (a ^ value) << 8;
|
||||||
if ((a ^ value) == 0) {
|
if ((a ^ value) == 0) {
|
||||||
@ -902,9 +939,10 @@ static void xor_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void or_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
static void or_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value, a;
|
uint8_t value, a;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = GB_read_memory(gb, gb->pc++);
|
value = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
a = gb->registers[GB_REGISTER_AF] >> 8;
|
a = gb->registers[GB_REGISTER_AF] >> 8;
|
||||||
gb->registers[GB_REGISTER_AF] = (a | value) << 8;
|
gb->registers[GB_REGISTER_AF] = (a | value) << 8;
|
||||||
if ((a | value) == 0) {
|
if ((a | value) == 0) {
|
||||||
@ -915,9 +953,10 @@ static void or_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void cp_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
static void cp_a_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value, a;
|
uint8_t value, a;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = GB_read_memory(gb, gb->pc++);
|
value = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
a = gb->registers[GB_REGISTER_AF] >> 8;
|
a = gb->registers[GB_REGISTER_AF] >> 8;
|
||||||
gb->registers[GB_REGISTER_AF] &= 0xFF00;
|
gb->registers[GB_REGISTER_AF] &= 0xFF00;
|
||||||
gb->registers[GB_REGISTER_AF] |= GB_SUBSTRACT_FLAG;
|
gb->registers[GB_REGISTER_AF] |= GB_SUBSTRACT_FLAG;
|
||||||
@ -980,36 +1019,40 @@ static void call_a16(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
|
|
||||||
static void ld_da8_a(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_da8_a(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
uint8_t temp = GB_read_memory(gb, gb->pc++);
|
uint8_t temp = GB_read_memory(gb, gb->pc++);
|
||||||
GB_advance_cycles(gb, 4);
|
GB_advance_cycles(gb, 4);
|
||||||
GB_write_memory(gb, 0xFF00 + temp, gb->registers[GB_REGISTER_AF] >> 8);
|
GB_write_memory(gb, 0xFF00 + temp, gb->registers[GB_REGISTER_AF] >> 8);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ld_a_da8(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_a_da8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
uint8_t temp = GB_read_memory(gb, gb->pc++);
|
uint8_t temp = GB_read_memory(gb, gb->pc++);
|
||||||
GB_advance_cycles(gb, 4);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->registers[GB_REGISTER_AF] |= GB_read_memory(gb, 0xFF00 + temp) << 8;
|
gb->registers[GB_REGISTER_AF] |= GB_read_memory(gb, 0xFF00 + temp) << 8;
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ld_dc_a(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_dc_a(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
GB_write_memory(gb, 0xFF00 + (gb->registers[GB_REGISTER_BC] & 0xFF), gb->registers[GB_REGISTER_AF] >> 8);
|
GB_write_memory(gb, 0xFF00 + (gb->registers[GB_REGISTER_BC] & 0xFF), gb->registers[GB_REGISTER_AF] >> 8);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ld_a_dc(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_a_dc(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
gb->registers[GB_REGISTER_AF] |= GB_read_memory(gb, 0xFF00 + (gb->registers[GB_REGISTER_BC] & 0xFF)) << 8;
|
gb->registers[GB_REGISTER_AF] |= GB_read_memory(gb, 0xFF00 + (gb->registers[GB_REGISTER_BC] & 0xFF)) << 8;
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_sp_r8(GB_gameboy_t *gb, uint8_t opcode)
|
static void add_sp_r8(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
@ -1043,22 +1086,28 @@ static void jp_hl(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void ld_da16_a(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_da16_a(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint16_t addr;
|
uint16_t addr;
|
||||||
GB_advance_cycles(gb, 16);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
addr = GB_read_memory(gb, gb->pc++);
|
addr = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
addr |= GB_read_memory(gb, gb->pc++) << 8;
|
addr |= GB_read_memory(gb, gb->pc++) << 8;
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
GB_write_memory(gb, addr, gb->registers[GB_REGISTER_AF] >> 8);
|
GB_write_memory(gb, addr, gb->registers[GB_REGISTER_AF] >> 8);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ld_a_da16(GB_gameboy_t *gb, uint8_t opcode)
|
static void ld_a_da16(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint16_t addr;
|
uint16_t addr;
|
||||||
GB_advance_cycles(gb, 16);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
gb->registers[GB_REGISTER_AF] &= 0xFF;
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
addr = GB_read_memory(gb, gb->pc++);
|
addr = GB_read_memory(gb, gb->pc++);
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
addr |= GB_read_memory(gb, gb->pc++) << 8 ;
|
addr |= GB_read_memory(gb, gb->pc++) << 8 ;
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
gb->registers[GB_REGISTER_AF] |= GB_read_memory(gb, addr) << 8;
|
gb->registers[GB_REGISTER_AF] |= GB_read_memory(gb, addr) << 8;
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void di(GB_gameboy_t *gb, uint8_t opcode)
|
static void di(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
@ -1111,7 +1160,7 @@ static void rlc_r(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
{
|
{
|
||||||
bool carry;
|
bool carry;
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = get_src_value(gb, opcode);
|
value = get_src_value(gb, opcode);
|
||||||
carry = (value & 0x80) != 0;
|
carry = (value & 0x80) != 0;
|
||||||
@ -1129,7 +1178,7 @@ static void rrc_r(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
{
|
{
|
||||||
bool carry;
|
bool carry;
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = get_src_value(gb, opcode);
|
value = get_src_value(gb, opcode);
|
||||||
carry = (value & 0x01) != 0;
|
carry = (value & 0x01) != 0;
|
||||||
@ -1149,7 +1198,7 @@ static void rl_r(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
bool carry;
|
bool carry;
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
bool bit7;
|
bool bit7;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = get_src_value(gb, opcode);
|
value = get_src_value(gb, opcode);
|
||||||
carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0;
|
carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0;
|
||||||
@ -1172,7 +1221,7 @@ static void rr_r(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
uint8_t value;
|
uint8_t value;
|
||||||
bool bit1;
|
bool bit1;
|
||||||
|
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = get_src_value(gb, opcode);
|
value = get_src_value(gb, opcode);
|
||||||
carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0;
|
carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0;
|
||||||
@ -1193,7 +1242,7 @@ static void sla_r(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
{
|
{
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
bool carry;
|
bool carry;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = get_src_value(gb, opcode);
|
value = get_src_value(gb, opcode);
|
||||||
carry = (value & 0x80) != 0;
|
carry = (value & 0x80) != 0;
|
||||||
@ -1211,7 +1260,7 @@ static void sra_r(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
{
|
{
|
||||||
uint8_t bit7;
|
uint8_t bit7;
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = get_src_value(gb, opcode);
|
value = get_src_value(gb, opcode);
|
||||||
bit7 = value & 0x80;
|
bit7 = value & 0x80;
|
||||||
@ -1229,7 +1278,7 @@ static void sra_r(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void srl_r(GB_gameboy_t *gb, uint8_t opcode)
|
static void srl_r(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = get_src_value(gb, opcode);
|
value = get_src_value(gb, opcode);
|
||||||
gb->registers[GB_REGISTER_AF] &= 0xFF00;
|
gb->registers[GB_REGISTER_AF] &= 0xFF00;
|
||||||
@ -1245,7 +1294,7 @@ static void srl_r(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
static void swap_r(GB_gameboy_t *gb, uint8_t opcode)
|
static void swap_r(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = get_src_value(gb, opcode);
|
value = get_src_value(gb, opcode);
|
||||||
gb->registers[GB_REGISTER_AF] &= 0xFF00;
|
gb->registers[GB_REGISTER_AF] &= 0xFF00;
|
||||||
@ -1259,7 +1308,7 @@ static void bit_r(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
{
|
{
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
uint8_t bit;
|
uint8_t bit;
|
||||||
GB_advance_cycles(gb, 8);
|
GB_advance_cycles(gb, 4);
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
value = get_src_value(gb, opcode);
|
value = get_src_value(gb, opcode);
|
||||||
bit = 1 << ((opcode >> 3) & 7);
|
bit = 1 << ((opcode >> 3) & 7);
|
||||||
@ -1280,6 +1329,7 @@ static void bit_r(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
|
|
||||||
static void cb_prefix(GB_gameboy_t *gb, uint8_t opcode)
|
static void cb_prefix(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
|
GB_advance_cycles(gb, 4);
|
||||||
opcode = GB_read_memory(gb, ++gb->pc);
|
opcode = GB_read_memory(gb, ++gb->pc);
|
||||||
switch (opcode >> 3) {
|
switch (opcode >> 3) {
|
||||||
case 0:
|
case 0:
|
||||||
|
Loading…
Reference in New Issue
Block a user