Переглянути джерело

CCF, SCF, DAA; bugfixes.

master
Ben Kurtovic 8 роки тому
джерело
коміт
51258e724f
4 змінених файлів з 103 додано та 13 видалено
  1. +14
    -0
      src/z80.c
  2. +35
    -0
      src/z80_flags.inc.c
  3. +47
    -6
      src/z80_ops.inc.c
  4. +7
    -7
      src/z80_tables.inc.c

+ 14
- 0
src/z80.c Переглянути файл

@@ -161,6 +161,20 @@ static inline uint16_t* extract_pair(Z80 *z80, uint8_t opcode)
}

/*
Extract a pp register pair from the given opcode and return a pointer.
*/
static inline uint16_t* extract_pair_pp(Z80 *z80, uint8_t opcode)
{
switch (opcode & 0x30) {
case 0x00: return &z80->regs.bc;
case 0x10: return &z80->regs.de;
case 0x20: return z80->regs.ixy;
case 0x30: return &z80->regs.sp;
}
FATAL("invalid call: extract_pair_pp(z80, 0x%02X)", opcode)
}

/*
Extract a qq register pair from the given opcode and return a pointer.
*/
static inline uint16_t* extract_pair_qq(Z80 *z80, uint8_t opcode)


+ 35
- 0
src/z80_flags.inc.c Переглянути файл

@@ -147,6 +147,22 @@ static inline void set_flags_bitshift(Z80 *z80, uint8_t res, uint8_t bit)
}

/*
Set the flags for a DAA instruction.
*/
static inline void set_flags_daa(Z80 *z80, uint8_t old, uint8_t adjust)
{
uint8_t res = z80->regs.a;

bool c = adjust >= 0x60;
bool h = get_flag(z80, FLAG_SUBTRACT) ?
(get_flag(z80, FLAG_HALFCARRY) && (old & 0x0F) < 0x06) :
((old & 0x0F) > 0x09);

set_flags(z80, c, 0, PARITY(res), F3(res), h, F5(res), ZERO(res),
SIGN(res), 0xFD);
}

/*
Set the flags for a CPL instruction.
*/
static inline void set_flags_cpl(Z80 *z80)
@@ -167,6 +183,25 @@ static inline void set_flags_neg(Z80 *z80)
}

/*
Set the flags for a CCF instruction.
*/
static inline void set_flags_ccf(Z80 *z80)
{
uint8_t val = z80->regs.a;
bool c = get_flag(z80, FLAG_CARRY);
set_flags(z80, 1 - c, 0, 0, F3(val), c, F5(val), 0, 0, 0x3B);
}

/*
Set the flags for a SCF instruction.
*/
static inline void set_flags_scf(Z80 *z80)
{
uint8_t val = z80->regs.a;
set_flags(z80, 1, 0, 0, F3(val), 0, F5(val), 0, 0, 0x3B);
}

/*
Set the flags for a LDI/LDIR/LDD/LDDR instruction.
*/
static inline void set_flags_blockxfer(Z80 *z80, uint8_t val)


+ 47
- 6
src/z80_ops.inc.c Переглянути файл

@@ -1118,7 +1118,28 @@ static uint8_t z80_inst_dec_ixy(Z80 *z80, uint8_t opcode)
return 23;
}

// TODO: DAA
/*
DAA (0x27):
Adjust A for BCD addition and subtraction.
*/
static uint8_t z80_inst_daa(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t a = z80->regs.a, adjust = 0x00;
bool n = get_flag(z80, FLAG_SUBTRACT);

if ((a & 0x0F) > 0x09 || get_flag(z80, FLAG_HALFCARRY))
adjust += 0x06;

uint8_t temp = n ? (a - adjust) : (a + adjust);
if ((temp >> 4) > 0x09 || get_flag(z80, FLAG_CARRY))
adjust += 0x60;

z80->regs.a += n ? -adjust : adjust;
set_flags_daa(z80, a, adjust);
z80->regs.pc++;
return 4;
}

/*
CPL (0x2F):
@@ -1130,7 +1151,7 @@ static uint8_t z80_inst_cpl(Z80 *z80, uint8_t opcode)
z80->regs.a = ~z80->regs.a;
set_flags_cpl(z80);
z80->regs.pc++;
return 8;
return 4;
}

/*
@@ -1146,9 +1167,29 @@ static uint8_t z80_inst_neg(Z80 *z80, uint8_t opcode)
return 8;
}

// TODO: CCF
/*
CCF (0x3F):
Invert the carry flag.
*/
static uint8_t z80_inst_ccf(Z80 *z80, uint8_t opcode)
{
(void) opcode;
set_flags_ccf(z80);
z80->regs.pc++;
return 4;
}

// TODO: SCF
/*
SCF (0x37):
Set the carry flag.
*/
static uint8_t z80_inst_scf(Z80 *z80, uint8_t opcode)
{
(void) opcode;
set_flags_scf(z80);
z80->regs.pc++;
return 4;
}

/*
NOP (0x00):
@@ -1278,9 +1319,9 @@ static uint8_t z80_inst_sbc_hl_ss(Z80 *z80, uint8_t opcode)
0xFD39):
Add pp to IX or IY.
*/
static uint8_t z80_inst_add_ixy_ss(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_add_ixy_pp(Z80 *z80, uint8_t opcode)
{
uint16_t lh = *z80->regs.ixy, rh = *extract_pair(z80, opcode);
uint16_t lh = *z80->regs.ixy, rh = *extract_pair_pp(z80, opcode);
*z80->regs.ixy += rh;

set_flags_add16(z80, lh, rh);


+ 7
- 7
src/z80_tables.inc.c Переглянути файл

@@ -41,7 +41,7 @@ static DispatchTable instruction_table = {
[0x24] = z80_inst_inc_r,
[0x25] = z80_inst_dec_r,
[0x26] = z80_inst_ld_r_n,
[0x27] = z80_inst_unimplemented, // TODO
[0x27] = z80_inst_daa,
[0x28] = z80_inst_jr_cc_e,
[0x29] = z80_inst_add_hl_ss,
[0x2A] = z80_inst_ld_hl_inn,
@@ -57,7 +57,7 @@ static DispatchTable instruction_table = {
[0x34] = z80_inst_inc_hl,
[0x35] = z80_inst_dec_hl,
[0x36] = z80_inst_ld_hl_n,
[0x37] = z80_inst_unimplemented, // TODO
[0x37] = z80_inst_scf,
[0x38] = z80_inst_jr_cc_e,
[0x39] = z80_inst_add_hl_ss,
[0x3A] = z80_inst_ld_a_nn,
@@ -65,7 +65,7 @@ static DispatchTable instruction_table = {
[0x3C] = z80_inst_inc_r,
[0x3D] = z80_inst_dec_r,
[0x3E] = z80_inst_ld_r_n,
[0x3F] = z80_inst_unimplemented, // TODO
[0x3F] = z80_inst_ccf,
[0x40] = z80_inst_ld_r_r,
[0x41] = z80_inst_ld_r_r,
[0x42] = z80_inst_ld_r_r,
@@ -788,7 +788,7 @@ static DispatchTable instruction_table_index = {
[0x06] = z80_inst_nop2,
[0x07] = z80_inst_nop2,
[0x08] = z80_inst_nop2,
[0x09] = z80_inst_add_ixy_ss,
[0x09] = z80_inst_add_ixy_pp,
[0x0A] = z80_inst_nop2,
[0x0B] = z80_inst_nop2,
[0x0C] = z80_inst_nop2,
@@ -804,7 +804,7 @@ static DispatchTable instruction_table_index = {
[0x16] = z80_inst_nop2,
[0x17] = z80_inst_nop2,
[0x18] = z80_inst_nop2,
[0x19] = z80_inst_add_ixy_ss,
[0x19] = z80_inst_add_ixy_pp,
[0x1A] = z80_inst_nop2,
[0x1B] = z80_inst_nop2,
[0x1C] = z80_inst_nop2,
@@ -820,7 +820,7 @@ static DispatchTable instruction_table_index = {
[0x26] = z80_inst_unimplemented, // TODO
[0x27] = z80_inst_nop2,
[0x28] = z80_inst_nop2,
[0x29] = z80_inst_add_ixy_ss,
[0x29] = z80_inst_add_ixy_pp,
[0x2A] = z80_inst_ld_ixy_inn,
[0x2B] = z80_inst_dec_xy,
[0x2C] = z80_inst_unimplemented, // TODO
@@ -836,7 +836,7 @@ static DispatchTable instruction_table_index = {
[0x36] = z80_inst_ld_ixy_n,
[0x37] = z80_inst_nop2,
[0x38] = z80_inst_nop2,
[0x39] = z80_inst_add_ixy_ss,
[0x39] = z80_inst_add_ixy_pp,
[0x3A] = z80_inst_nop2,
[0x3B] = z80_inst_nop2,
[0x3C] = z80_inst_nop2,


Завантаження…
Відмінити
Зберегти