Browse Source

CP, IN, OUT, JP cc; stub out port functions.

master
Ben Kurtovic 8 years ago
parent
commit
c2a52194a8
3 changed files with 133 additions and 21 deletions
  1. +40
    -0
      src/z80.c
  2. +75
    -3
      src/z80_ops.inc.c
  3. +18
    -18
      src/z80_tables.inc.c

+ 40
- 0
src/z80.c View File

@@ -161,6 +161,28 @@ static inline void update_flags(Z80 *z80, bool c, bool n, bool pv, bool f3,
}

/*
Read and return a byte from the given port.
*/
static uint8_t read_port(Z80 *z80, uint8_t port)
{
// TODO
(void) z80;
(void) port;
return 0x00;
}

/*
Write a byte to the given port.
*/
static void write_port(Z80 *z80, uint8_t port, uint8_t value)
{
// TODO
(void) z80;
(void) port;
(void) value;
}

/*
Extract an 8-bit register from the given opcode and return a pointer to it.
*/
static inline uint8_t* extract_reg(Z80 *z80, uint8_t opcode)
@@ -192,6 +214,24 @@ static inline uint8_t extract_pair(uint8_t opcode)
}

/*
Extract a condition from the given opcode.
*/
static inline bool extract_cond(const Z80 *z80, uint8_t opcode)
{
switch (opcode & 0x38) {
case 0x00: return !get_flag(z80, FLAG_ZERO);
case 0x08: return get_flag(z80, FLAG_ZERO);
case 0x10: return !get_flag(z80, FLAG_CARRY);
case 0x18: return get_flag(z80, FLAG_CARRY);
case 0x20: return !get_flag(z80, FLAG_PARITY);
case 0x28: return get_flag(z80, FLAG_PARITY);
case 0x30: return !get_flag(z80, FLAG_SIGN);
case 0x38: return get_flag(z80, FLAG_SIGN);
}
FATAL("invalid call: extract_cond(z80, 0x%02X)", opcode)
}

/*
Return the CPU's current interrupt mode.
*/
static inline uint8_t get_interrupt_mode(const Z80 *z80)


+ 75
- 3
src/z80_ops.inc.c View File

@@ -312,6 +312,45 @@ static uint8_t z80_inst_xor_r(Z80 *z80, uint8_t opcode)
// CP s

/*
CP r (0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBF):
Set flags as if r (8-bit register) had been subtracted from a.
*/
static uint8_t z80_inst_cp_r(Z80 *z80, uint8_t opcode)
{
uint8_t *reg = extract_reg(z80, opcode);
uint8_t d = z80->regfile.a - *reg;

bool c = (z80->regfile.a - *reg) != d;
bool v = (z80->regfile.a - *reg) != ((int8_t) d);
bool h = !!(((z80->regfile.a & 0x0F) - (*reg & 0x0F)) & 0x10);
update_flags(z80, c, 1, v, !!(*reg & 0x08), h, !!(*reg & 0x20), d == 0,
!!(d & 0x80), 0xFF);

z80->regfile.pc++;
return 4;
}

/*
CP n (0xFE):
Set flags as if n (8-bit immediate) had been subtracted from a.
*/
static uint8_t z80_inst_cp_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t n = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
uint8_t d = z80->regfile.a - n;

bool c = (z80->regfile.a - n) != d;
bool v = (z80->regfile.a - n) != ((int8_t) d);
bool h = !!(((z80->regfile.a & 0x0F) - (n & 0x0F)) & 0x10);
update_flags(z80, c, 1, v, !!(n & 0x08), h, !!(n & 0x20), d == 0,
!!(d & 0x80), 0xFF);

z80->regfile.pc++;
return 7;
}

/*
INC r (0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x3C):
Increment r (8-bit register).
*/
@@ -516,7 +555,18 @@ static uint8_t z80_inst_jp_nn(Z80 *z80, uint8_t opcode)
return 10;
}

// JP cc, nn
/*
JP cc, nn (0xC2, 0xCA, 0xD2, 0xDA, 0xE2, 0xEA, 0xF2, 0xFA):
Jump to nn (16-bit immediate) if cc (condition) is true.
*/
static uint8_t z80_inst_jp_cc_nn(Z80 *z80, uint8_t opcode)
{
if (extract_cond(z80, opcode))
z80->regfile.pc = mmu_read_double(z80->mmu, ++z80->regfile.pc);
else
z80->regfile.pc += 2;
return 10;
}

// JR e

@@ -550,7 +600,18 @@ static uint8_t z80_inst_jp_nn(Z80 *z80, uint8_t opcode)

// RST p

// IN A, (n)
/*
IN A, (n): (0xDB):
Read a byte from port n into a.
*/
static uint8_t z80_inst_in_a_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t port = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
z80->regfile.a = read_port(z80, port);
z80->regfile.pc++;
return 11;
}

// IN r (C)

@@ -562,7 +623,18 @@ static uint8_t z80_inst_jp_nn(Z80 *z80, uint8_t opcode)

// INDR

// OUT (n), A
/*
OUT (n), A: (0xD3):
Write a byte from a into port n.
*/
static uint8_t z80_inst_out_n_a(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t port = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
write_port(z80, port, z80->regfile.a);
z80->regfile.pc++;
return 11;
}

// OUT (C), r



+ 18
- 18
src/z80_tables.inc.c View File

@@ -186,17 +186,17 @@ static DispatchTable instruction_table = {
[0xB5] = z80_inst_unimplemented, // TODO
[0xB6] = z80_inst_unimplemented, // TODO
[0xB7] = z80_inst_unimplemented, // TODO
[0xB8] = z80_inst_unimplemented, // TODO
[0xB9] = z80_inst_unimplemented, // TODO
[0xBA] = z80_inst_unimplemented, // TODO
[0xBB] = z80_inst_unimplemented, // TODO
[0xBC] = z80_inst_unimplemented, // TODO
[0xBD] = z80_inst_unimplemented, // TODO
[0xB8] = z80_inst_cp_r,
[0xB9] = z80_inst_cp_r,
[0xBA] = z80_inst_cp_r,
[0xBB] = z80_inst_cp_r,
[0xBC] = z80_inst_cp_r,
[0xBD] = z80_inst_cp_r,
[0xBE] = z80_inst_unimplemented, // TODO
[0xBF] = z80_inst_unimplemented, // TODO
[0xBF] = z80_inst_cp_r,
[0xC0] = z80_inst_unimplemented, // TODO
[0xC1] = z80_inst_unimplemented, // TODO
[0xC2] = z80_inst_unimplemented, // TODO
[0xC2] = z80_inst_jp_cc_nn,
[0xC3] = z80_inst_jp_nn,
[0xC4] = z80_inst_unimplemented, // TODO
[0xC5] = z80_inst_unimplemented, // TODO
@@ -204,7 +204,7 @@ static DispatchTable instruction_table = {
[0xC7] = z80_inst_unimplemented, // TODO
[0xC8] = z80_inst_unimplemented, // TODO
[0xC9] = z80_inst_unimplemented, // TODO
[0xCA] = z80_inst_unimplemented, // TODO
[0xCA] = z80_inst_jp_cc_nn,
[0xCB] = z80_prefix_bits,
[0xCC] = z80_inst_unimplemented, // TODO
[0xCD] = z80_inst_unimplemented, // TODO
@@ -212,23 +212,23 @@ static DispatchTable instruction_table = {
[0xCF] = z80_inst_unimplemented, // TODO
[0xD0] = z80_inst_unimplemented, // TODO
[0xD1] = z80_inst_unimplemented, // TODO
[0xD2] = z80_inst_unimplemented, // TODO
[0xD3] = z80_inst_unimplemented, // TODO
[0xD2] = z80_inst_jp_cc_nn,
[0xD3] = z80_inst_out_n_a,
[0xD4] = z80_inst_unimplemented, // TODO
[0xD5] = z80_inst_unimplemented, // TODO
[0xD6] = z80_inst_unimplemented, // TODO
[0xD7] = z80_inst_unimplemented, // TODO
[0xD8] = z80_inst_unimplemented, // TODO
[0xD9] = z80_inst_exx,
[0xDA] = z80_inst_unimplemented, // TODO
[0xDB] = z80_inst_unimplemented, // TODO
[0xDA] = z80_inst_jp_cc_nn,
[0xDB] = z80_inst_in_a_n,
[0xDC] = z80_inst_unimplemented, // TODO
[0xDD] = z80_prefix_index,
[0xDE] = z80_inst_unimplemented, // TODO
[0xDF] = z80_inst_unimplemented, // TODO
[0xE0] = z80_inst_unimplemented, // TODO
[0xE1] = z80_inst_unimplemented, // TODO
[0xE2] = z80_inst_unimplemented, // TODO
[0xE2] = z80_inst_jp_cc_nn,
[0xE3] = z80_inst_unimplemented, // TODO
[0xE4] = z80_inst_unimplemented, // TODO
[0xE5] = z80_inst_unimplemented, // TODO
@@ -236,7 +236,7 @@ static DispatchTable instruction_table = {
[0xE7] = z80_inst_unimplemented, // TODO
[0xE8] = z80_inst_unimplemented, // TODO
[0xE9] = z80_inst_unimplemented, // TODO
[0xEA] = z80_inst_unimplemented, // TODO
[0xEA] = z80_inst_jp_cc_nn,
[0xEB] = z80_inst_unimplemented, // TODO
[0xEC] = z80_inst_unimplemented, // TODO
[0xED] = z80_prefix_extended,
@@ -244,7 +244,7 @@ static DispatchTable instruction_table = {
[0xEF] = z80_inst_unimplemented, // TODO
[0xF0] = z80_inst_unimplemented, // TODO
[0xF1] = z80_inst_unimplemented, // TODO
[0xF2] = z80_inst_unimplemented, // TODO
[0xF2] = z80_inst_jp_cc_nn,
[0xF3] = z80_inst_di,
[0xF4] = z80_inst_unimplemented, // TODO
[0xF5] = z80_inst_unimplemented, // TODO
@@ -252,11 +252,11 @@ static DispatchTable instruction_table = {
[0xF7] = z80_inst_unimplemented, // TODO
[0xF8] = z80_inst_unimplemented, // TODO
[0xF9] = z80_inst_unimplemented, // TODO
[0xFA] = z80_inst_unimplemented, // TODO
[0xFA] = z80_inst_jp_cc_nn,
[0xFB] = z80_inst_ei,
[0xFC] = z80_inst_unimplemented, // TODO
[0xFD] = z80_prefix_index,
[0xFE] = z80_inst_unimplemented, // TODO
[0xFE] = z80_inst_cp_n,
[0xFF] = z80_inst_unimplemented // TODO
};



Loading…
Cancel
Save