Browse Source

Implement LD A, I/R; CPI/CPIR/CPD/CPDR

develop
Ben Kurtovic 4 years ago
parent
commit
526c33f24b
3 changed files with 103 additions and 17 deletions
  1. +23
    -1
      src/z80_flags.inc.c
  2. +73
    -9
      src/z80_ops.inc.c
  3. +7
    -7
      src/z80_tables.inc.c

+ 23
- 1
src/z80_flags.inc.c View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2019 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#define POS(x) (!((x) & 0x80))
@@ -211,6 +211,15 @@ static inline void set_flags_scf(Z80 *z80)
}

/*
Set the flags for a LD A, I/R instruction.
*/
static inline void set_flags_ld_a_ir(Z80 *z80)
{
uint8_t val = z80->regs.a;
set_flags(z80, 0, 0, z80->regs.iff2, F3(val), 0, F5(val), ZERO(val), SIGN(val), 0xFE);
}

/*
Set the flags for a LDI/LDIR/LDD/LDDR instruction.
*/
static inline void set_flags_blockxfer(Z80 *z80, uint8_t val)
@@ -221,6 +230,19 @@ static inline void set_flags_blockxfer(Z80 *z80, uint8_t val)
}

/*
Set the flags for a CPI/CPIR/CPD/CPDR instruction.
*/
static inline void set_flags_blockcp(Z80 *z80, uint16_t rh)
{
uint8_t lh = z80->regs.a;
bool pv = z80->regs.bc != 0;
bool h = HALF(lh, -, rh);
uint8_t res = lh - rh;
uint8_t resh = res - h;
set_flags(z80, 0, 1, pv, F3(resh), h, F5(resh), ZERO(res), SIGN(res), 0xFE);
}

/*
Set the flags for an IN instruction.
*/
static inline void set_flags_in(Z80 *z80, uint8_t val)


+ 73
- 9
src/z80_ops.inc.c View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2019 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

/*
@@ -193,16 +193,28 @@ static uint8_t z80_inst_ld_nn_a(Z80 *z80, uint8_t opcode)
/*
LD A, I (0xED57):
Load I into A.
TODO
*/
// static uint8_t z80_inst_ld_a_i(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_ld_a_i(Z80 *z80, uint8_t opcode)
{
(void) opcode;
z80->regs.a = z80->regs.i;
set_flags_ld_a_ir(z80);
z80->regs.pc++;
return 9;
}

/*
LD A, R (0xED5F):
Load R into A.
TODO
*/
// static uint8_t z80_inst_ld_a_r(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_ld_a_r(Z80 *z80, uint8_t opcode)
{
(void) opcode;
z80->regs.a = z80->regs.r;
set_flags_ld_a_ir(z80);
z80->regs.pc++;
return 9;
}

/*
LD I, A (0xED47):
@@ -536,13 +548,65 @@ static uint8_t z80_inst_lddr(Z80 *z80, uint8_t opcode)
return 21;
}

// TODO: CPI
/*
CPI (0xEDA1):
CP (HL); INC HL; DEC BL
*/
static uint8_t z80_inst_cpi(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t value = mmu_read_byte(z80->mmu, z80->regs.hl);

z80->regs.hl++;
z80->regs.bc--;

set_flags_blockcp(z80, value);
z80->regs.pc++;
return 16;
}

/*
CPIR (0xEDB1):
CPI; JR PV; -2
*/
static uint8_t z80_inst_cpir(Z80 *z80, uint8_t opcode)
{
z80_inst_cpi(z80, opcode);
if (z80->regs.bc == 0)
return 16;
z80->regs.pc -= 2;
return 21;
}

/*
CPD (0xEDA9):
CP (HL); DEC HL; DEC BL
*/
static uint8_t z80_inst_cpd(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t value = mmu_read_byte(z80->mmu, z80->regs.hl);

// TODO: CPIR
z80->regs.hl--;
z80->regs.bc--;

// TODO: CPD
set_flags_blockcp(z80, value);
z80->regs.pc++;
return 16;
}

// TODO: CPDR
/*
CPDR (0xEDB9):
CPD; JR PV; -2
*/
static uint8_t z80_inst_cpdr(Z80 *z80, uint8_t opcode)
{
z80_inst_cpd(z80, opcode);
if (z80->regs.bc == 0)
return 16;
z80->regs.pc -= 2;
return 21;
}

/*
ADD A, r (0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87):


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

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2019 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

static DispatchTable instruction_table = {
@@ -348,7 +348,7 @@ static DispatchTable instruction_table_extended = {
[0x54] = z80_inst_neg,
[0x55] = z80_inst_retn,
[0x56] = z80_inst_im,
[0x57] = z80_inst_unimplemented, // TODO
[0x57] = z80_inst_ld_a_i,
[0x58] = z80_inst_in_r_c,
[0x59] = z80_inst_out_c_r,
[0x5A] = z80_inst_adc_hl_ss,
@@ -356,7 +356,7 @@ static DispatchTable instruction_table_extended = {
[0x5C] = z80_inst_neg,
[0x5D] = z80_inst_retn,
[0x5E] = z80_inst_im,
[0x5F] = z80_inst_unimplemented, // TODO
[0x5F] = z80_inst_ld_a_r,
[0x60] = z80_inst_in_r_c,
[0x61] = z80_inst_out_c_r,
[0x62] = z80_inst_sbc_hl_ss,
@@ -422,7 +422,7 @@ static DispatchTable instruction_table_extended = {
[0x9E] = z80_inst_nop2,
[0x9F] = z80_inst_nop2,
[0xA0] = z80_inst_ldi,
[0xA1] = z80_inst_unimplemented, // TODO
[0xA1] = z80_inst_cpi,
[0xA2] = z80_inst_ini,
[0xA3] = z80_inst_outi,
[0xA4] = z80_inst_nop2,
@@ -430,7 +430,7 @@ static DispatchTable instruction_table_extended = {
[0xA6] = z80_inst_nop2,
[0xA7] = z80_inst_nop2,
[0xA8] = z80_inst_ldd,
[0xA9] = z80_inst_unimplemented, // TODO
[0xA9] = z80_inst_cpd,
[0xAA] = z80_inst_ind,
[0xAB] = z80_inst_outd,
[0xAC] = z80_inst_nop2,
@@ -438,7 +438,7 @@ static DispatchTable instruction_table_extended = {
[0xAE] = z80_inst_nop2,
[0xAF] = z80_inst_nop2,
[0xB0] = z80_inst_ldir,
[0xB1] = z80_inst_unimplemented, // TODO
[0xB1] = z80_inst_cpir,
[0xB2] = z80_inst_inir,
[0xB3] = z80_inst_otir,
[0xB4] = z80_inst_nop2,
@@ -446,7 +446,7 @@ static DispatchTable instruction_table_extended = {
[0xB6] = z80_inst_nop2,
[0xB7] = z80_inst_nop2,
[0xB8] = z80_inst_lddr,
[0xB9] = z80_inst_unimplemented, // TODO
[0xB9] = z80_inst_cpdr,
[0xBA] = z80_inst_indr,
[0xBB] = z80_inst_otdr,
[0xBC] = z80_inst_nop2,


Loading…
Cancel
Save