@@ -170,6 +170,16 @@ static inline void stack_push(Z80 *z80, uint16_t value) | |||||
} | } | ||||
/* | /* | ||||
Pop a two-byte value from the stack. | |||||
*/ | |||||
static inline uint16_t stack_pop(Z80 *z80) | |||||
{ | |||||
uint16_t value = mmu_read_double(z80->mmu, z80->regfile.sp); | |||||
z80->regfile.sp += 2; | |||||
return value; | |||||
} | |||||
/* | |||||
Read and return a byte from the given port. | Read and return a byte from the given port. | ||||
*/ | */ | ||||
static uint8_t read_port(Z80 *z80, uint8_t port) | static uint8_t read_port(Z80 *z80, uint8_t port) | ||||
@@ -225,7 +225,7 @@ static uint8_t z80_inst_ld_dd_nn(Z80 *z80, uint8_t opcode) | |||||
static uint8_t z80_inst_push_qq(Z80 *z80, uint8_t opcode) | static uint8_t z80_inst_push_qq(Z80 *z80, uint8_t opcode) | ||||
{ | { | ||||
uint8_t pair = extract_pair(opcode); | uint8_t pair = extract_pair(opcode); | ||||
stack_push(z80, pair); | |||||
stack_push(z80, get_pair(z80, pair)); | |||||
z80->regfile.pc++; | z80->regfile.pc++; | ||||
return 11; | return 11; | ||||
} | } | ||||
@@ -234,7 +234,17 @@ static uint8_t z80_inst_push_qq(Z80 *z80, uint8_t opcode) | |||||
// PUSH IY | // PUSH IY | ||||
// POP qq | |||||
/* | |||||
POP qq (0xC1, 0xD1, 0xE1, 0xF1): | |||||
Pop qq from the stack, and increment SP by two. | |||||
*/ | |||||
static uint8_t z80_inst_pop_qq(Z80 *z80, uint8_t opcode) | |||||
{ | |||||
uint8_t pair = extract_pair(opcode); | |||||
set_pair(z80, pair, stack_pop(z80)); | |||||
z80->regfile.pc++; | |||||
return 10; | |||||
} | |||||
// POP IX | // POP IX | ||||
@@ -594,7 +604,7 @@ static uint8_t z80_inst_jp_cc_nn(Z80 *z80, uint8_t opcode) | |||||
static uint8_t z80_inst_jr_e(Z80 *z80, uint8_t opcode) | static uint8_t z80_inst_jr_e(Z80 *z80, uint8_t opcode) | ||||
{ | { | ||||
(void) opcode; | (void) opcode; | ||||
int8_t jump = mmu_read_byte(z80->mmu, ++z80->regfile.pc); | |||||
int8_t jump = mmu_read_byte(z80->mmu, z80->regfile.pc + 1); | |||||
z80->regfile.pc += jump + 2; | z80->regfile.pc += jump + 2; | ||||
return 12; | return 12; | ||||
} | } | ||||
@@ -607,7 +617,7 @@ static uint8_t z80_inst_jr_e(Z80 *z80, uint8_t opcode) | |||||
static uint8_t z80_inst_jr_cc_e(Z80 *z80, uint8_t opcode) | static uint8_t z80_inst_jr_cc_e(Z80 *z80, uint8_t opcode) | ||||
{ | { | ||||
if (extract_cond(z80, opcode - 0x20)) { | if (extract_cond(z80, opcode - 0x20)) { | ||||
int8_t jump = mmu_read_byte(z80->mmu, ++z80->regfile.pc); | |||||
int8_t jump = mmu_read_byte(z80->mmu, z80->regfile.pc + 1); | |||||
z80->regfile.pc += jump + 2; | z80->regfile.pc += jump + 2; | ||||
return 12; | return 12; | ||||
} else { | } else { | ||||
@@ -195,7 +195,7 @@ static DispatchTable instruction_table = { | |||||
[0xBE] = z80_inst_unimplemented, // TODO | [0xBE] = z80_inst_unimplemented, // TODO | ||||
[0xBF] = z80_inst_cp_r, | [0xBF] = z80_inst_cp_r, | ||||
[0xC0] = z80_inst_unimplemented, // TODO | [0xC0] = z80_inst_unimplemented, // TODO | ||||
[0xC1] = z80_inst_unimplemented, // TODO | |||||
[0xC1] = z80_inst_pop_qq, | |||||
[0xC2] = z80_inst_jp_cc_nn, | [0xC2] = z80_inst_jp_cc_nn, | ||||
[0xC3] = z80_inst_jp_nn, | [0xC3] = z80_inst_jp_nn, | ||||
[0xC4] = z80_inst_call_cc_nn, | [0xC4] = z80_inst_call_cc_nn, | ||||
@@ -211,7 +211,7 @@ static DispatchTable instruction_table = { | |||||
[0xCE] = z80_inst_unimplemented, // TODO | [0xCE] = z80_inst_unimplemented, // TODO | ||||
[0xCF] = z80_inst_unimplemented, // TODO | [0xCF] = z80_inst_unimplemented, // TODO | ||||
[0xD0] = z80_inst_unimplemented, // TODO | [0xD0] = z80_inst_unimplemented, // TODO | ||||
[0xD1] = z80_inst_unimplemented, // TODO | |||||
[0xD1] = z80_inst_pop_qq, | |||||
[0xD2] = z80_inst_jp_cc_nn, | [0xD2] = z80_inst_jp_cc_nn, | ||||
[0xD3] = z80_inst_out_n_a, | [0xD3] = z80_inst_out_n_a, | ||||
[0xD4] = z80_inst_call_cc_nn, | [0xD4] = z80_inst_call_cc_nn, | ||||
@@ -227,7 +227,7 @@ static DispatchTable instruction_table = { | |||||
[0xDE] = z80_inst_unimplemented, // TODO | [0xDE] = z80_inst_unimplemented, // TODO | ||||
[0xDF] = z80_inst_unimplemented, // TODO | [0xDF] = z80_inst_unimplemented, // TODO | ||||
[0xE0] = z80_inst_unimplemented, // TODO | [0xE0] = z80_inst_unimplemented, // TODO | ||||
[0xE1] = z80_inst_unimplemented, // TODO | |||||
[0xE1] = z80_inst_pop_qq, | |||||
[0xE2] = z80_inst_jp_cc_nn, | [0xE2] = z80_inst_jp_cc_nn, | ||||
[0xE3] = z80_inst_unimplemented, // TODO | [0xE3] = z80_inst_unimplemented, // TODO | ||||
[0xE4] = z80_inst_call_cc_nn, | [0xE4] = z80_inst_call_cc_nn, | ||||
@@ -243,7 +243,7 @@ static DispatchTable instruction_table = { | |||||
[0xEE] = z80_inst_unimplemented, // TODO | [0xEE] = z80_inst_unimplemented, // TODO | ||||
[0xEF] = z80_inst_unimplemented, // TODO | [0xEF] = z80_inst_unimplemented, // TODO | ||||
[0xF0] = z80_inst_unimplemented, // TODO | [0xF0] = z80_inst_unimplemented, // TODO | ||||
[0xF1] = z80_inst_unimplemented, // TODO | |||||
[0xF1] = z80_inst_pop_qq, | |||||
[0xF2] = z80_inst_jp_cc_nn, | [0xF2] = z80_inst_jp_cc_nn, | ||||
[0xF3] = z80_inst_di, | [0xF3] = z80_inst_di, | ||||
[0xF4] = z80_inst_call_cc_nn, | [0xF4] = z80_inst_call_cc_nn, | ||||