Parcourir la source

EX; more bitwise/arithmetic ops; bugfixes.

master
Ben Kurtovic il y a 8 ans
Parent
révision
cbc1d7f02d
3 fichiers modifiés avec 87 ajouts et 18 suppressions
  1. +4
    -3
      src/z80.c
  2. +76
    -8
      src/z80_ops.inc.c
  3. +7
    -7
      src/z80_tables.inc.c

+ 4
- 3
src/z80.c Voir le fichier

@@ -306,8 +306,8 @@ static inline void trace_instruction(Z80 *z80)
return;
}
if (z80->trace.fresh) {
TRACE("PC ADDR P1 P2 OP A1 A2 INSTR\tARGS")
TRACE("------- -------------- -----\t----")
TRACE("PC ADDR P1 P2 OP A1 A2 INSTR\tARGS")
TRACE("------- -------------- -----\t----")
z80->trace.fresh = false;
}

@@ -318,7 +318,8 @@ static inline void trace_instruction(Z80 *z80)
uint8_t bytes[4] = {quad, quad >> 8, quad >> 16, quad >> 24};
DisasInstr *instr = disassemble_instruction(bytes);

TRACE("0x%04X: %-14s %s", z80->regfile.pc, instr->bytestr, instr->line)
TRACE("0x%04X: %-14s %s",
z80->regfile.pc, instr->bytestr, instr->line)
disas_instr_free(instr);
}



+ 76
- 8
src/z80_ops.inc.c Voir le fichier

@@ -267,7 +267,19 @@ static uint8_t z80_inst_pop_ixy(Z80 *z80, uint8_t opcode)
return 14;
}

// EX DE, HL
/*
EX DE, HL (0xEB):
Exchange DE with HL.
*/
static uint8_t z80_inst_ex_de_hl(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t de = get_pair(z80, REG_DE);
set_pair(z80, REG_DE, get_pair(z80, REG_HL));
set_pair(z80, REG_HL, de);
z80->regfile.pc++;
return 4;
}

// EX AF, AF′

@@ -388,6 +400,27 @@ static uint8_t z80_inst_lddr(Z80 *z80, uint8_t opcode)

// SUB s

/*
SUB n (0xD6):
Subtract n (8-bit immediate) from A.
*/
static uint8_t z80_inst_sub_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t imm = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
uint8_t orig = z80->regfile.a;
uint8_t a = z80->regfile.a -= imm;

bool c = (orig - imm) != a;
bool v = (orig - imm) != ((int8_t) a);
bool h = !!(((orig & 0x0F) - (imm & 0x0F)) & 0x10);
update_flags(z80, c, 1, v, !!(a & 0x08), h, !!(a & 0x20), a == 0,
!!(a & 0x80), 0xFF);

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

// SBC A, s

// AND s
@@ -396,12 +429,12 @@ static uint8_t z80_inst_lddr(Z80 *z80, uint8_t opcode)

/*
OR r (0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB7):
Bitwise OR a with r (8-bit register).
Bitwise OR A with r (8-bit register).
*/
static uint8_t z80_inst_or_r(Z80 *z80, uint8_t opcode)
{
uint8_t *reg = extract_reg(z80, opcode << 3);
uint8_t a = (z80->regfile.a ^= *reg);
uint8_t a = (z80->regfile.a |= *reg);

bool parity = !(__builtin_popcount(a) % 2);
update_flags(z80, 0, 0, parity, !!(a & 0x08), 0, !!(a & 0x20), a == 0,
@@ -411,11 +444,29 @@ static uint8_t z80_inst_or_r(Z80 *z80, uint8_t opcode)
return 4;
}

/*
OR n (0xF6):
Bitwise OR A with n (8-bit immediate).
*/
static uint8_t z80_inst_or_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t imm = mmu_read_byte(z80->mmu, ++z80->regfile.pc);
uint8_t a = (z80->regfile.a |= imm);

bool parity = !(__builtin_popcount(a) % 2);
update_flags(z80, 0, 0, parity, !!(a & 0x08), 0, !!(a & 0x20), a == 0,
!!(a & 0x80), 0xFF);

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

// XOR s

/*
XOR r (0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAF):
Bitwise XOR a with r (8-bit register).
Bitwise XOR A with r (8-bit register).
*/
static uint8_t z80_inst_xor_r(Z80 *z80, uint8_t opcode)
{
@@ -434,7 +485,7 @@ static uint8_t z80_inst_xor_r(Z80 *z80, uint8_t opcode)

/*
CP r (0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBF):
Set flags as if r (8-bit register) had been subtracted from a.
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)
{
@@ -453,7 +504,7 @@ static uint8_t z80_inst_cp_r(Z80 *z80, uint8_t opcode)

/*
CP n (0xFE):
Set flags as if n (8-bit immediate) had been subtracted from a.
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)
{
@@ -599,13 +650,30 @@ static uint8_t z80_inst_im(Z80 *z80, uint8_t opcode)
return 8;
}

// ADD HL, ss
/*
ADD HL, ss (0x09, 0x19, 0x29, 0x39):
Add ss to HL.
*/
static uint8_t z80_inst_add_hl_ss(Z80 *z80, uint8_t opcode)
{
uint8_t pair = extract_pair(opcode);
uint16_t lh = get_pair(z80, REG_HL), rh = get_pair(z80, pair);
uint16_t value = lh + rh;
set_pair(z80, REG_HL, value);

bool h = !!(((lh & 0x0FFF) + (rh & 0x0FFF)) & 0x1000);
update_flags(z80, (lh + rh) != value, 0, 0, !!(value & 0x0800), h,
!!(value & 0x2000), 0, 0, 0x3B);

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

// ADC HL, ss

/*
SBC HL, ss (0xED42, 0xED52, 0xED62, 0xED72):
Subtract BC with carry from HL.
Subtract ss with carry from HL.
*/
static uint8_t z80_inst_sbc_hl_ss(Z80 *z80, uint8_t opcode)
{


+ 7
- 7
src/z80_tables.inc.c Voir le fichier

@@ -11,7 +11,7 @@ static DispatchTable instruction_table = {
[0x06] = z80_inst_ld_r_n,
[0x07] = z80_inst_unimplemented, // TODO
[0x08] = z80_inst_unimplemented, // TODO
[0x09] = z80_inst_unimplemented, // TODO
[0x09] = z80_inst_add_hl_ss,
[0x0A] = z80_inst_unimplemented, // TODO
[0x0B] = z80_inst_dec_ss,
[0x0C] = z80_inst_inc_r,
@@ -27,7 +27,7 @@ static DispatchTable instruction_table = {
[0x16] = z80_inst_ld_r_n,
[0x17] = z80_inst_unimplemented, // TODO
[0x18] = z80_inst_jr_e,
[0x19] = z80_inst_unimplemented, // TODO
[0x19] = z80_inst_add_hl_ss,
[0x1A] = z80_inst_unimplemented, // TODO
[0x1B] = z80_inst_dec_ss,
[0x1C] = z80_inst_inc_r,
@@ -43,7 +43,7 @@ static DispatchTable instruction_table = {
[0x26] = z80_inst_ld_r_n,
[0x27] = z80_inst_unimplemented, // TODO
[0x28] = z80_inst_jr_cc_e,
[0x29] = z80_inst_unimplemented, // TODO
[0x29] = z80_inst_add_hl_ss,
[0x2A] = z80_inst_unimplemented, // TODO
[0x2B] = z80_inst_dec_ss,
[0x2C] = z80_inst_inc_r,
@@ -59,7 +59,7 @@ static DispatchTable instruction_table = {
[0x36] = z80_inst_ld_hl_n,
[0x37] = z80_inst_unimplemented, // TODO
[0x38] = z80_inst_jr_cc_e,
[0x39] = z80_inst_unimplemented, // TODO
[0x39] = z80_inst_add_hl_ss,
[0x3A] = z80_inst_ld_a_nn,
[0x3B] = z80_inst_dec_ss,
[0x3C] = z80_inst_inc_r,
@@ -216,7 +216,7 @@ static DispatchTable instruction_table = {
[0xD3] = z80_inst_out_n_a,
[0xD4] = z80_inst_call_cc_nn,
[0xD5] = z80_inst_push_qq,
[0xD6] = z80_inst_unimplemented, // TODO
[0xD6] = z80_inst_sub_n,
[0xD7] = z80_inst_rst_p,
[0xD8] = z80_inst_ret_cc,
[0xD9] = z80_inst_exx,
@@ -237,7 +237,7 @@ static DispatchTable instruction_table = {
[0xE8] = z80_inst_ret_cc,
[0xE9] = z80_inst_unimplemented, // TODO
[0xEA] = z80_inst_jp_cc_nn,
[0xEB] = z80_inst_unimplemented, // TODO
[0xEB] = z80_inst_ex_de_hl,
[0xEC] = z80_inst_call_cc_nn,
[0xED] = z80_prefix_extended,
[0xEE] = z80_inst_unimplemented, // TODO
@@ -248,7 +248,7 @@ static DispatchTable instruction_table = {
[0xF3] = z80_inst_di,
[0xF4] = z80_inst_call_cc_nn,
[0xF5] = z80_inst_push_qq,
[0xF6] = z80_inst_unimplemented, // TODO
[0xF6] = z80_inst_or_n,
[0xF7] = z80_inst_rst_p,
[0xF8] = z80_inst_ret_cc,
[0xF9] = z80_inst_unimplemented, // TODO


Chargement…
Annuler
Enregistrer