Browse Source

Refactor flag setting code; implement more instructions.

master
Ben Kurtovic 8 years ago
parent
commit
fdda540d26
5 changed files with 619 additions and 229 deletions
  1. +11
    -0
      src/vdp.c
  2. +11
    -6
      src/z80.c
  3. +100
    -0
      src/z80_flags.inc.c
  4. +443
    -169
      src/z80_ops.inc.c
  5. +54
    -54
      src/z80_tables.inc.c

+ 11
- 0
src/vdp.c View File

@@ -266,4 +266,15 @@ void vdp_dump_registers(const VDP *vdp)
DEBUG("- $08: 0x%02X (HS)", regs[0x08])
DEBUG("- $09: 0x%02X (VS)", regs[0x09])
DEBUG("- $0A: 0x%02X (LC)", regs[0x0A])

// TODO: remove me!
DEBUG("Dumping CRAM:")
for (uint8_t i = 0x00; i < 0x40; i += 0x10) {
uint16_t w[8];
for (uint8_t j = 0; j < 8; j++)
w[j] = vdp->cram[i + j * 2] + (vdp->cram[i + j * 2 + 1] << 8);

DEBUG("- %04X %04X %04X %04X %04X %04X %04X %04X",
w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7])
}
}

+ 11
- 6
src/z80.c View File

@@ -90,10 +90,11 @@ static inline bool get_shadow_flag(const Z80 *z80, uint8_t flag)
/*
Update the F register flags according to the set bits in the mask.
*/
static inline void update_flags(Z80 *z80, bool c, bool n, bool pv, bool f3,
bool h, bool f5, bool z, bool s, uint8_t mask)
static inline void set_flags(Z80 *z80,
bool c, bool n, bool pv, bool f3, bool h, bool f5, bool z, bool s,
uint8_t mask)
{
z80->regs.f = (~mask & z80->regs.f) | (mask & (
uint8_t new = (
c << FLAG_CARRY |
n << FLAG_SUBTRACT |
pv << FLAG_PARITY |
@@ -101,9 +102,13 @@ static inline void update_flags(Z80 *z80, bool c, bool n, bool pv, bool f3,
h << FLAG_HALFCARRY |
f5 << FLAG_UNDOC_5 |
z << FLAG_ZERO |
s << FLAG_SIGN));
s << FLAG_SIGN
);
z80->regs.f = (~mask & z80->regs.f) | (mask & new);
}

#include "z80_flags.inc.c"

/*
Push a two-byte value onto the stack.
*/
@@ -138,7 +143,7 @@ static void handle_io_errors(Z80 *z80)
/*
Read and return a byte from the given port, and check for errors.
*/
static uint8_t read_port(Z80 *z80, uint8_t port)
static inline uint8_t read_port(Z80 *z80, uint8_t port)
{
uint8_t value = io_port_read(z80->io, port);
handle_io_errors(z80);
@@ -148,7 +153,7 @@ static uint8_t read_port(Z80 *z80, uint8_t port)
/*
Write a byte to the given port, and check for errors.
*/
static void write_port(Z80 *z80, uint8_t port, uint8_t value)
static inline void write_port(Z80 *z80, uint8_t port, uint8_t value)
{
io_port_write(z80->io, port, value);
handle_io_errors(z80);


+ 100
- 0
src/z80_flags.inc.c View File

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

#define POS(x) (!((x) & 0x80))
#define NEG(x) ((x) & 0x80)

#define CARRY(lh, op, rh) (((lh) op (rh)) & 0x100)
#define HALF(lh, op, rh) ((((lh) & 0x0F) op ((rh) & 0x0F)) & 0x10)
#define ZERO(x) ((x) == 0)
#define SIGN(x) NEG(x)
#define SUB 1

#define OV_ADD(lh, rh, res) \
(POS(lh) && POS(rh) && NEG(res) || NEG(lh) && NEG(rh) && POS(res))
#define OV_SUB(lh, rh, res) \
(POS(lh) && NEG(rh) && NEG(res) || NEG(lh) && POS(rh) && POS(res))

#define PARITY(x) (!(__builtin_popcount(x) % 2))

#define F3(x) ((x) & 0x08)
#define F5(x) ((x) & 0x20)

/*
Set the flags for an 8-bit ADD or ADC instruction.
*/
static inline void set_flags_add8(Z80 *z80, uint16_t rh)
{
uint8_t lh = z80->regs.a;
uint8_t res = lh + rh;
set_flags(z80, CARRY(lh, +, rh), !SUB, OV_ADD(lh, rh, res), F3(res),
HALF(lh, +, rh), F5(res), ZERO(res), SIGN(res), 0xFF);
}

/*
Set the flags for an 8-bit SUB or SBC instruction.
*/
static inline void set_flags_sub8(Z80 *z80, uint16_t rh)
{
uint8_t lh = z80->regs.a;
uint8_t res = lh - rh;
set_flags(z80, CARRY(lh, -, rh), SUB, OV_SUB(lh, rh, res), F3(res),
HALF(lh, -, rh), F5(res), ZERO(res), SIGN(res), 0xFF);
}

/*
Set the flags for a CP instruction.
*/
static inline void set_flags_cp(Z80 *z80, uint16_t rh)
{
uint8_t lh = z80->regs.a;
uint8_t res = lh - rh;
set_flags(z80, CARRY(lh, -, rh), SUB, OV_SUB(lh, rh, res), F3(rh),
HALF(lh, -, rh), F5(rh), ZERO(res), SIGN(res), 0xFF);
}

/*
Set the flags for an AND, XOR, or OR instruction.
*/
static inline void set_flags_bitwise(Z80 *z80, uint8_t res, bool is_and)
{
set_flags(z80, 0, 0, PARITY(res), F3(res), is_and, F5(res), ZERO(res),
SIGN(res), 0xFF);
}

/*
Set the flags for an 8-bit INC instruction.
*/
static inline void set_flags_inc(Z80 *z80, uint8_t val)
{
uint8_t res = val + 1;
set_flags(z80, 0, !SUB, OV_ADD(val, 1, res), F3(res), HALF(val, +, 1),
F5(res), ZERO(res), SIGN(res), 0xFE);
}

/*
Set the flags for an 8-bit DEC instruction.
*/
static inline void set_flags_dec(Z80 *z80, uint8_t val)
{
uint8_t res = val - 1;
set_flags(z80, 0, SUB, OV_SUB(val, 1, res), F3(res), HALF(val, -, 1),
F5(res), ZERO(res), SIGN(res), 0xFE);
}

// set_flags(Z80 *z80,
// bool c, bool n, bool pv, bool f3, bool h, bool f5, bool z, bool s,
// uint8_t mask)

#undef POS
#undef NEG
#undef CARRY
#undef HALF
#undef ZERO
#undef SIGN
#undef SUB
#undef OV_ADD
#undef OV_SUB
#undef PARITY
#undef F3
#undef F5

+ 443
- 169
src/z80_ops.inc.c View File

@@ -484,7 +484,7 @@ static uint8_t z80_inst_ldi(Z80 *z80, uint8_t opcode)
z80->regs.de++;
z80->regs.bc--;

update_flags(z80, 0, 0, z80->regs.bc == 0, 0, 0, 0, 0, 0, 0x16);
set_flags(z80, 0, 0, z80->regs.bc == 0, 0, 0, 0, 0, 0, 0x16);
z80->regs.pc++;
return 16;
}
@@ -516,7 +516,7 @@ static uint8_t z80_inst_ldd(Z80 *z80, uint8_t opcode)
z80->regs.de--;
z80->regs.bc--;

update_flags(z80, 0, 0, z80->regs.bc == 0, 0, 0, 0, 0, 0, 0x16);
set_flags(z80, 0, 0, z80->regs.bc == 0, 0, 0, 0, 0, 0, 0x16);
z80->regs.pc++;
return 16;
}
@@ -534,31 +534,151 @@ static uint8_t z80_inst_lddr(Z80 *z80, uint8_t opcode)
return 21;
}

// CPI
// TODO; CPI

// CPIR
// TODO: CPIR

// CPD
// TODO: CPD

// CPDR
// TODO: CPDR

// ADD A, r
/*
ADD A, r (0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87):
TODO
*/
static uint8_t z80_inst_add_a_r(Z80 *z80, uint8_t opcode)
{
uint8_t value = *extract_reg(z80, opcode << 3);

// ADD A, n
set_flags_add8(z80, value);
z80->regs.a += value;
z80->regs.pc++;
return 4;
}

// ADD A, (HL)
/*
ADD A, n (0xC6):
TODO
*/
static uint8_t z80_inst_add_a_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t value = mmu_read_byte(z80->mmu, ++z80->regs.pc);

// ADD A, (IXY+d)
set_flags_add8(z80, value);
z80->regs.a += value;
z80->regs.pc++;
return 7;
}

// ADC A, r
/*
ADD A, (HL) (0x86):
TODO
*/
static uint8_t z80_inst_add_a_hl(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t value = mmu_read_byte(z80->mmu, z80->regs.hl);

// ADC A, n
set_flags_add8(z80, value);
z80->regs.a += value;
z80->regs.pc++;
return 7;
}

// ADC A, (HL)
/*
ADD A, (IXY+d) (0xDD86, 0xFD86):
TODO
*/
static uint8_t z80_inst_add_a_ixy(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t addr = get_index_addr(z80, ++z80->regs.pc);
uint8_t value = mmu_read_byte(z80->mmu, addr);

// ADC A, (IXY+d)
set_flags_add8(z80, value);
z80->regs.a += value;
z80->regs.pc++;
return 19;
}

/*
ADC A, r (0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8F):
TODO
*/
static uint8_t z80_inst_adc_a_r(Z80 *z80, uint8_t opcode)
{
uint16_t value = *extract_reg(z80, opcode << 3);
value += get_flag(z80, FLAG_CARRY);

set_flags_add8(z80, value);
z80->regs.a += value;
z80->regs.pc++;
return 4;
}

/*
ADC A, n (0xCE):
TODO
*/
static uint8_t z80_inst_adc_a_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t value = mmu_read_byte(z80->mmu, ++z80->regs.pc);
value += get_flag(z80, FLAG_CARRY);

// SUB r
set_flags_add8(z80, value);
z80->regs.a += value;
z80->regs.pc++;
return 7;
}

/*
ADC A, (HL) (0x8E):
TODO
*/
static uint8_t z80_inst_adc_a_hl(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t value = mmu_read_byte(z80->mmu, z80->regs.hl);
value += get_flag(z80, FLAG_CARRY);

set_flags_add8(z80, value);
z80->regs.a += value;
z80->regs.pc++;
return 7;
}

/*
ADC A, (IXY+d) (0xDD8E, 0xFD8E):
TODO
*/
static uint8_t z80_inst_adc_a_ixy(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t addr = get_index_addr(z80, ++z80->regs.pc);
uint16_t value = mmu_read_byte(z80->mmu, addr);
value += get_flag(z80, FLAG_CARRY);

set_flags_add8(z80, value);
z80->regs.a += value;
z80->regs.pc++;
return 19;
}

/*
SUB, r (0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x97):
TODO
*/
static uint8_t z80_inst_sub_r(Z80 *z80, uint8_t opcode)
{
uint8_t value = *extract_reg(z80, opcode << 3);

set_flags_sub8(z80, value);
z80->regs.a -= value;
z80->regs.pc++;
return 4;
}

/*
SUB n (0xD6):
@@ -567,33 +687,122 @@ static uint8_t z80_inst_lddr(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_sub_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t imm = mmu_read_byte(z80->mmu, ++z80->regs.pc);
uint8_t orig = z80->regs.a;
uint8_t a = z80->regs.a -= imm;
uint8_t value = mmu_read_byte(z80->mmu, ++z80->regs.pc);

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);
set_flags_sub8(z80, value);
z80->regs.a -= value;
z80->regs.pc++;
return 7;
}

/*
SUB (HL)
TODO
*/
static uint8_t z80_inst_sub_hl(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t value = mmu_read_byte(z80->mmu, z80->regs.hl);

set_flags_sub8(z80, value);
z80->regs.a -= value;
z80->regs.pc++;
return 7;
}

// SUB (HL)
/*
SUB (IXY+d)
TODO
*/
static uint8_t z80_inst_sub_ixy(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t addr = get_index_addr(z80, ++z80->regs.pc);
uint8_t value = mmu_read_byte(z80->mmu, addr);

// SUB (IXY+d)
set_flags_sub8(z80, value);
z80->regs.a -= value;
z80->regs.pc++;
return 19;
}

// SBC A, r
/*
SBC A, r (...):
TODO
*/
static uint8_t z80_inst_sbc_a_r(Z80 *z80, uint8_t opcode)
{
uint8_t value = *extract_reg(z80, opcode << 3);
value += get_flag(z80, FLAG_CARRY);

// SBC A, n
set_flags_sub8(z80, value);
z80->regs.a -= value;
z80->regs.pc++;
return 4;
}

// SBC A, (HL)
/*
SBC A, n (...):
TODO
*/
static uint8_t z80_inst_sbc_a_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t value = mmu_read_byte(z80->mmu, ++z80->regs.pc);
value += get_flag(z80, FLAG_CARRY);

// SBC A, (IXY+d)
set_flags_sub8(z80, value);
z80->regs.a -= value;
z80->regs.pc++;
return 7;
}

// AND r
/*
SBC A, (HL)
TODO
*/
static uint8_t z80_inst_sbc_a_hl(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t value = mmu_read_byte(z80->mmu, z80->regs.hl);
value += get_flag(z80, FLAG_CARRY);

set_flags_sub8(z80, value);
z80->regs.a -= value;
z80->regs.pc++;
return 7;
}

/*
SBC A, (IXY+d)
TODO
*/
static uint8_t z80_inst_sbc_a_ixy(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t addr = get_index_addr(z80, ++z80->regs.pc);
uint8_t value = mmu_read_byte(z80->mmu, addr);
value += get_flag(z80, FLAG_CARRY);

set_flags_sub8(z80, value);
z80->regs.a -= value;
z80->regs.pc++;
return 19;
}

/*
AND r
TODO
*/
static uint8_t z80_inst_and_r(Z80 *z80, uint8_t opcode)
{
uint8_t value = *extract_reg(z80, opcode << 3);
uint8_t res = z80->regs.a &= value;

set_flags_bitwise(z80, res, true);
z80->regs.pc++;
return 4;
}

/*
AND n (0xE6):
@@ -602,20 +811,44 @@ static uint8_t z80_inst_sub_n(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_and_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t imm = mmu_read_byte(z80->mmu, ++z80->regs.pc);
uint8_t a = (z80->regs.a &= imm);
uint8_t value = mmu_read_byte(z80->mmu, ++z80->regs.pc);
uint8_t res = z80->regs.a &= value;

bool parity = !(__builtin_popcount(a) % 2);
update_flags(z80, 0, 0, parity, !!(a & 0x08), 1, !!(a & 0x20), a == 0,
!!(a & 0x80), 0xFF);
set_flags_bitwise(z80, res, true);
z80->regs.pc++;
return 7;
}

/*
AND (HL)
TODO
*/
static uint8_t z80_inst_and_hl(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t value = mmu_read_byte(z80->mmu, z80->regs.hl);
uint8_t res = z80->regs.a &= value;

set_flags_bitwise(z80, res, true);
z80->regs.pc++;
return 7;
}

// AND (HL)
/*
AND (IXY+d)
TODO
*/
static uint8_t z80_inst_and_ixy(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t addr = get_index_addr(z80, ++z80->regs.pc);
uint8_t value = mmu_read_byte(z80->mmu, addr);
uint8_t res = z80->regs.a &= value;

// AND (IXY+d)
set_flags_bitwise(z80, res, true);
z80->regs.pc++;
return 19;
}

/*
OR r (0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB7):
@@ -623,13 +856,10 @@ static uint8_t z80_inst_and_n(Z80 *z80, uint8_t opcode)
*/
static uint8_t z80_inst_or_r(Z80 *z80, uint8_t opcode)
{
uint8_t *reg = extract_reg(z80, opcode << 3);
uint8_t a = (z80->regs.a |= *reg);

bool parity = !(__builtin_popcount(a) % 2);
update_flags(z80, 0, 0, parity, !!(a & 0x08), 0, !!(a & 0x20), a == 0,
!!(a & 0x80), 0xFF);
uint8_t value = *extract_reg(z80, opcode << 3);
uint8_t res = z80->regs.a |= value;

set_flags_bitwise(z80, res, false);
z80->regs.pc++;
return 4;
}
@@ -641,18 +871,28 @@ static uint8_t z80_inst_or_r(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_or_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t imm = mmu_read_byte(z80->mmu, ++z80->regs.pc);
uint8_t a = (z80->regs.a |= imm);

bool parity = !(__builtin_popcount(a) % 2);
update_flags(z80, 0, 0, parity, !!(a & 0x08), 0, !!(a & 0x20), a == 0,
!!(a & 0x80), 0xFF);
uint8_t value = mmu_read_byte(z80->mmu, ++z80->regs.pc);
uint8_t res = z80->regs.a |= value;

set_flags_bitwise(z80, res, false);
z80->regs.pc++;
return 7;
}

// OR (HL)
/*
OR (HL)
TODO
*/
static uint8_t z80_inst_or_hl(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t value = mmu_read_byte(z80->mmu, z80->regs.hl);
uint8_t res = z80->regs.a |= value;

set_flags_bitwise(z80, res, false);
z80->regs.pc++;
return 7;
}

/*
OR (IXY+d) (0xDDB6, 0xFDB6):
@@ -661,16 +901,13 @@ static uint8_t z80_inst_or_n(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_or_ixy(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t addr = get_index_addr(z80, ++z80->regs.pc);
uint8_t val = mmu_read_byte(z80->mmu, addr);
uint8_t a = (z80->regs.a |= val);

bool parity = !(__builtin_popcount(a) % 2);
update_flags(z80, 0, 0, parity, !!(a & 0x08), 0, !!(a & 0x20), a == 0,
!!(a & 0x80), 0xFF);
uint16_t addr = get_index_addr(z80, ++z80->regs.pc);
uint8_t value = mmu_read_byte(z80->mmu, addr);
uint8_t res = z80->regs.a |= value;

set_flags_bitwise(z80, res, false);
z80->regs.pc++;
return 7;
return 19;
}

/*
@@ -679,13 +916,10 @@ static uint8_t z80_inst_or_ixy(Z80 *z80, uint8_t opcode)
*/
static uint8_t z80_inst_xor_r(Z80 *z80, uint8_t opcode)
{
uint8_t *reg = extract_reg(z80, opcode << 3);
uint8_t a = (z80->regs.a ^= *reg);

bool parity = !(__builtin_popcount(a) % 2);
update_flags(z80, 0, 0, parity, !!(a & 0x08), 0, !!(a & 0x20), a == 0,
!!(a & 0x80), 0xFF);
uint8_t value = *extract_reg(z80, opcode << 3);
uint8_t res = z80->regs.a ^= value;

set_flags_bitwise(z80, res, false);
z80->regs.pc++;
return 4;
}
@@ -697,20 +931,43 @@ static uint8_t z80_inst_xor_r(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_xor_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t imm = mmu_read_byte(z80->mmu, ++z80->regs.pc);
uint8_t a = (z80->regs.a ^= imm);

bool parity = !(__builtin_popcount(a) % 2);
update_flags(z80, 0, 0, parity, !!(a & 0x08), 0, !!(a & 0x20), a == 0,
!!(a & 0x80), 0xFF);
uint8_t value = mmu_read_byte(z80->mmu, ++z80->regs.pc);
uint8_t res = z80->regs.a ^= value;

set_flags_bitwise(z80, res, false);
z80->regs.pc++;
return 7;
}

// XOR (HL)
/*
XOR (HL)
TODO
*/
static uint8_t z80_inst_xor_hl(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t value = mmu_read_byte(z80->mmu, z80->regs.hl);
uint8_t res = z80->regs.a ^= value;

set_flags_bitwise(z80, res, false);
z80->regs.pc++;
return 7;
}
/*
XOR (IXY+d)
TODO
*/
static uint8_t z80_inst_xor_ixy(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t addr = get_index_addr(z80, ++z80->regs.pc);
uint8_t value = mmu_read_byte(z80->mmu, addr);
uint8_t res = z80->regs.a ^= value;

// XOR (IXY+d)
set_flags_bitwise(z80, res, false);
z80->regs.pc++;
return 19;
}

/*
CP r (0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBF):
@@ -718,15 +975,9 @@ static uint8_t z80_inst_xor_n(Z80 *z80, uint8_t opcode)
*/
static uint8_t z80_inst_cp_r(Z80 *z80, uint8_t opcode)
{
uint8_t *reg = extract_reg(z80, opcode << 3);
uint8_t d = z80->regs.a - *reg;

bool c = (z80->regs.a - *reg) != d;
bool v = (z80->regs.a - *reg) != ((int8_t) d);
bool h = !!(((z80->regs.a & 0x0F) - (*reg & 0x0F)) & 0x10);
update_flags(z80, c, 1, v, !!(*reg & 0x08), h, !!(*reg & 0x20), d == 0,
!!(d & 0x80), 0xFF);
uint8_t value = *extract_reg(z80, opcode << 3);

set_flags_cp(z80, value);
z80->regs.pc++;
return 4;
}
@@ -738,15 +989,9 @@ static uint8_t z80_inst_cp_r(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_cp_n(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t n = mmu_read_byte(z80->mmu, ++z80->regs.pc);
uint8_t d = z80->regs.a - n;

bool c = (z80->regs.a - n) != d;
bool v = (z80->regs.a - n) != ((int8_t) d);
bool h = !!(((z80->regs.a & 0x0F) - (n & 0x0F)) & 0x10);
update_flags(z80, c, 1, v, !!(n & 0x08), h, !!(n & 0x20), d == 0,
!!(d & 0x80), 0xFF);
uint8_t value = mmu_read_byte(z80->mmu, ++z80->regs.pc);

set_flags_cp(z80, value);
z80->regs.pc++;
return 7;
}
@@ -758,20 +1003,27 @@ static uint8_t z80_inst_cp_n(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_cp_hl(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t n = mmu_read_byte(z80->mmu, z80->regs.hl);
uint8_t d = z80->regs.a - n;

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

set_flags_cp(z80, value);
z80->regs.pc++;
return 7;
}

// CP (IXY+d)
/*
CP (IXY+d)
TODO
*/
static uint8_t z80_inst_cp_ixy(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t addr = get_index_addr(z80, ++z80->regs.pc);
uint8_t value = mmu_read_byte(z80->mmu, addr);

set_flags_cp(z80, value);
z80->regs.pc++;
return 19;
}

/*
INC r (0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x3C):
@@ -780,11 +1032,9 @@ static uint8_t z80_inst_cp_hl(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_inc_r(Z80 *z80, uint8_t opcode)
{
uint8_t *reg = extract_reg(z80, opcode);
bool halfcarry = !!(((*reg & 0x0F) + 1) & 0x10);
(*reg)++;
update_flags(z80, 0, 0, *reg == 0x80, !!(*reg & 0x08), halfcarry,
!!(*reg & 0x20), *reg == 0, !!(*reg & 0x80), 0xFE);

set_flags_inc(z80, *reg);
(*reg)++;
z80->regs.pc++;
return 4;
}
@@ -797,16 +1047,28 @@ static uint8_t z80_inst_inc_hl(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t byte = mmu_read_byte(z80->mmu, z80->regs.hl);
bool halfcarry = !!(((byte & 0x0F) + 1) & 0x10);
mmu_write_byte(z80->mmu, z80->regs.hl, ++byte);
update_flags(z80, 0, 0, byte == 0x80, !!(byte & 0x08), halfcarry,
!!(byte & 0x20), byte == 0, !!(byte & 0x80), 0xFE);

set_flags_inc(z80, byte);
mmu_write_byte(z80->mmu, z80->regs.hl, ++byte);
z80->regs.pc++;
return 11;
}

// INC (IXY+d)
/*
INC (IXY+d)
TODO
*/
static uint8_t z80_inst_inc_ixy(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t addr = get_index_addr(z80, ++z80->regs.pc);
uint8_t byte = mmu_read_byte(z80->mmu, addr);

set_flags_inc(z80, byte);
mmu_write_byte(z80->mmu, addr, ++byte);
z80->regs.pc++;
return 23;
}

/*
DEC r (0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, 0x3D):
@@ -815,11 +1077,9 @@ static uint8_t z80_inst_inc_hl(Z80 *z80, uint8_t opcode)
static uint8_t z80_inst_dec_r(Z80 *z80, uint8_t opcode)
{
uint8_t *reg = extract_reg(z80, opcode);
bool halfcarry = !!(((*reg & 0x0F) - 1) & 0x10);
(*reg)--;
update_flags(z80, 0, 1, *reg == 0x7F, !!(*reg & 0x08), halfcarry,
!!(*reg & 0x20), *reg == 0, !!(*reg & 0x80), 0xFE);

set_flags_dec(z80, *reg);
(*reg)--;
z80->regs.pc++;
return 4;
}
@@ -832,26 +1092,40 @@ static uint8_t z80_inst_dec_hl(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint8_t byte = mmu_read_byte(z80->mmu, z80->regs.hl);
bool halfcarry = !!(((byte & 0x0F) + 1) & 0x10);
mmu_write_byte(z80->mmu, z80->regs.hl, --byte);
update_flags(z80, 0, 1, byte == 0x7F, !!(byte & 0x08), halfcarry,
!!(byte & 0x20), byte == 0, !!(byte & 0x80), 0xFE);

set_flags_dec(z80, byte);
mmu_write_byte(z80->mmu, z80->regs.hl, --byte);
z80->regs.pc++;
return 11;
}

// DEC (IXY+d)
/*
DEC (IXY+d)
TODO
*/
static uint8_t z80_inst_dec_ixy(Z80 *z80, uint8_t opcode)
{
(void) opcode;
uint16_t addr = get_index_addr(z80, ++z80->regs.pc);
uint8_t byte = mmu_read_byte(z80->mmu, addr);

set_flags_dec(z80, byte);
mmu_write_byte(z80->mmu, addr, --byte);
z80->regs.pc++;
return 23;
}

// ----------------------------------------------------------------------------

// DAA
// TODO: DAA

// CPL
// TODO: CPL

// NEG
// TODO: NEG

// CCF
// TODO: CCF

// SCF
// TODO: SCF

/*
NOP (0x00):
@@ -942,14 +1216,14 @@ static uint8_t z80_inst_add_hl_ss(Z80 *z80, uint8_t opcode)
z80->regs.hl = value;

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

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

// ADC HL, ss
// TODO: ADC HL, ss

/*
SBC HL, ss (0xED42, 0xED52, 0xED62, 0xED72):
@@ -966,14 +1240,14 @@ static uint8_t z80_inst_sbc_hl_ss(Z80 *z80, uint8_t opcode)
bool ov = (minu - subtra) != ((int16_t) value);
bool hc = !!(((minu & 0x0FFF) - (subtra & 0x0FFF)) & 0x1000);

update_flags(z80, c, 1, ov, !!(value & 0x0800), hc,
set_flags(z80, c, 1, ov, !!(value & 0x0800), hc,
!!(value & 0x2000), value == 0, !!(value & 0x8000), 0xFF);

z80->regs.pc++;
return 15;
}

// ADD IXY, pp
// TODO: ADD IXY, pp

/*
INC ss (0x03, 0x13, 0x23, 0x33):
@@ -986,7 +1260,7 @@ static uint8_t z80_inst_inc_ss(Z80 *z80, uint8_t opcode)
return 6;
}

// INC IXY
// TODO: INC IXY

/*
DEC ss (0x0B, 0x1B, 0x2B, 0x3B):
@@ -999,61 +1273,61 @@ static uint8_t z80_inst_dec_ss(Z80 *z80, uint8_t opcode)
return 6;
}

// DEC IXY
// TODO: DEC IXY

// RLCA
// TODO: RLCA

// RLA
// TODO: RLA

// RRCA
// TODO: RRCA

// RRA
// TODO: RRA

// RLC r
// TODO: RLC r

// RLC (HL)
// TODO: RLC (HL)

// RLC (IXY+d)
// TODO: RLC (IXY+d)

// RL r
// TODO: RL r

// RL (HL)
// TODO: RL (HL)

// RL (IXY+d)
// TODO: RL (IXY+d)

// RRC r
// TODO: RRC r

// RRC (HL)
// TODO: RRC (HL)

// RRC (IXY+d)
// TODO: RRC (IXY+d)

// RR r
// TODO: RR r

// RR (HL)
// TODO: RR (HL)

// RR (IXY+d)
// TODO: RR (IXY+d)

// SLA r
// TODO: SLA r

// SLA (HL)
// TODO: SLA (HL)

// SLA (IXY+d)
// TODO: SLA (IXY+d)

// SRA r
// TODO: SRA r

// SRA (HL)
// TODO: SRA (HL)

// SRA (IXY+d)
// TODO: SRA (IXY+d)

// SRL r
// TODO: SRL r

// SRL (HL)
// TODO: SRL (HL)

// SRL (IXY+d)
// TODO: SRL (IXY+d)

// RLD
// TODO: RLD

// RRD
// TODO: RRD

/*
BIT b, r (0xCB40, 0xCB41, 0xCB42, 0xCB43, 0xCB44, 0xCB45, 0xCB47, 0xCB48,
@@ -1071,9 +1345,9 @@ static uint8_t z80_inst_bit_b_r(Z80 *z80, uint8_t opcode)
uint8_t bit = (opcode >> 3) & 0x07;
bool z = (((*reg) >> bit) & 1) == 0;
if (z)
update_flags(z80, 0, 0, 1, 0, 1, 0, 1, 0, 0xFE);
set_flags(z80, 0, 0, 1, 0, 1, 0, 1, 0, 0xFE);
else
update_flags(z80, 0, 0, 0, bit == 3, 1, bit == 5, 0, bit == 7, 0xFE);
set_flags(z80, 0, 0, 0, bit == 3, 1, bit == 5, 0, bit == 7, 0xFE);
z80->regs.pc++;
return 8;
}
@@ -1089,9 +1363,9 @@ static uint8_t z80_inst_bit_b_hl(Z80 *z80, uint8_t opcode)
uint8_t bit = (opcode >> 3) & 0x07;
bool z = ((val >> bit) & 1) == 0;
if (z)
update_flags(z80, 0, 0, 1, 0, 1, 0, 1, 0, 0xFE);
set_flags(z80, 0, 0, 1, 0, 1, 0, 1, 0, 0xFE);
else
update_flags(z80, 0, 0, 0, bit == 3, 1, bit == 5, 0, bit == 7, 0xFE);
set_flags(z80, 0, 0, 0, bit == 3, 1, bit == 5, 0, bit == 7, 0xFE);
z80->regs.pc++;
return 8;
}
@@ -1107,20 +1381,20 @@ static uint8_t z80_inst_bit_b_ixy(Z80 *z80, uint8_t opcode)
uint8_t bit = (opcode >> 3) & 0x07;
bool z = ((val >> bit) & 1) == 0;
if (z)
update_flags(z80, 0, 0, 1, 0, 1, 0, 1, 0, 0xFE);
set_flags(z80, 0, 0, 1, 0, 1, 0, 1, 0, 0xFE);
else
update_flags(z80, 0, 0, 0, bit == 3, 1, bit == 5, 0, bit == 7, 0xFE);
set_flags(z80, 0, 0, 0, bit == 3, 1, bit == 5, 0, bit == 7, 0xFE);
z80->regs.pc++;
return 8;
}

// SET b, r
// TODO: SET b, r

// SET b, (HL)
// TODO: SET b, (HL)

// SET b, (IXY+d)
// TODO: SET b, (IXY+d)

// RES b, r
// TODO: RES b, r

/*
RES b, (HL) (0xCB86, 0xCB8E, 0xCB96, 0xCB9E, 0xCBA6, 0xCBAE, 0xCBB6,
@@ -1137,7 +1411,7 @@ static uint8_t z80_inst_res_b_hl(Z80 *z80, uint8_t opcode)
return 8;
}

// RES b, (IXY+d)
// TODO: RES b, (IXY+d)

/*
JP nn (0xC3):
@@ -1344,7 +1618,7 @@ static uint8_t z80_inst_in_r_c(Z80 *z80, uint8_t opcode)

if (opcode != 0x70)
*extract_reg(z80, opcode) = data;
update_flags(z80, 0, 0, parity, !!(data & 0x08), 0, !!(data & 0x20),
set_flags(z80, 0, 0, parity, !!(data & 0x08), 0, !!(data & 0x20),
data == 0, !!(data & 0x80), 0xFE);
z80->regs.pc++;
return 12;
@@ -1364,7 +1638,7 @@ static uint8_t z80_inst_ini(Z80 *z80, uint8_t opcode)
z80->regs.hl++;
(*b)--;

update_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
set_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
*b == 0, !!(*b & 0x80), 0xFE);
z80->regs.pc++;
return 16;
@@ -1397,7 +1671,7 @@ static uint8_t z80_inst_ind(Z80 *z80, uint8_t opcode)
z80->regs.hl--;
(*b)--;

update_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
set_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
*b == 0, !!(*b & 0x80), 0xFE);
z80->regs.pc++;
return 16;
@@ -1456,7 +1730,7 @@ static uint8_t z80_inst_outi(Z80 *z80, uint8_t opcode)
z80->regs.hl++;
(*b)--;

update_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
set_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
*b == 0, !!(*b & 0x80), 0xFE);
z80->regs.pc++;
return 16;
@@ -1489,7 +1763,7 @@ static uint8_t z80_inst_outd(Z80 *z80, uint8_t opcode)
z80->regs.hl--;
(*b)--;

update_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
set_flags(z80, 0, 1, *b == 0x7F, !!(*b & 0x08), h, !!(*b & 0x20),
*b == 0, !!(*b & 0x80), 0xFE);
z80->regs.pc++;
return 16;


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

@@ -130,53 +130,53 @@ static DispatchTable instruction_table = {
[0x7D] = z80_inst_ld_r_r,
[0x7E] = z80_inst_ld_r_hl,
[0x7F] = z80_inst_ld_r_r,
[0x80] = z80_inst_unimplemented, // TODO
[0x81] = z80_inst_unimplemented, // TODO
[0x82] = z80_inst_unimplemented, // TODO
[0x83] = z80_inst_unimplemented, // TODO
[0x84] = z80_inst_unimplemented, // TODO
[0x85] = z80_inst_unimplemented, // TODO
[0x86] = z80_inst_unimplemented, // TODO
[0x87] = z80_inst_unimplemented, // TODO
[0x88] = z80_inst_unimplemented, // TODO
[0x89] = z80_inst_unimplemented, // TODO
[0x8A] = z80_inst_unimplemented, // TODO
[0x8B] = z80_inst_unimplemented, // TODO
[0x8C] = z80_inst_unimplemented, // TODO
[0x8D] = z80_inst_unimplemented, // TODO
[0x8E] = z80_inst_unimplemented, // TODO
[0x8F] = z80_inst_unimplemented, // TODO
[0x90] = z80_inst_unimplemented, // TODO
[0x91] = z80_inst_unimplemented, // TODO
[0x92] = z80_inst_unimplemented, // TODO
[0x93] = z80_inst_unimplemented, // TODO
[0x94] = z80_inst_unimplemented, // TODO
[0x95] = z80_inst_unimplemented, // TODO
[0x96] = z80_inst_unimplemented, // TODO
[0x97] = z80_inst_unimplemented, // TODO
[0x98] = z80_inst_unimplemented, // TODO
[0x99] = z80_inst_unimplemented, // TODO
[0x9A] = z80_inst_unimplemented, // TODO
[0x9B] = z80_inst_unimplemented, // TODO
[0x9C] = z80_inst_unimplemented, // TODO
[0x9D] = z80_inst_unimplemented, // TODO
[0x9E] = z80_inst_unimplemented, // TODO
[0x9F] = z80_inst_unimplemented, // TODO
[0xA0] = z80_inst_unimplemented, // TODO
[0xA1] = z80_inst_unimplemented, // TODO
[0xA2] = z80_inst_unimplemented, // TODO
[0xA3] = z80_inst_unimplemented, // TODO
[0xA4] = z80_inst_unimplemented, // TODO
[0xA5] = z80_inst_unimplemented, // TODO
[0xA6] = z80_inst_unimplemented, // TODO
[0xA7] = z80_inst_unimplemented, // TODO
[0x80] = z80_inst_add_a_r,
[0x81] = z80_inst_add_a_r,
[0x82] = z80_inst_add_a_r,
[0x83] = z80_inst_add_a_r,
[0x84] = z80_inst_add_a_r,
[0x85] = z80_inst_add_a_r,
[0x86] = z80_inst_add_a_hl,
[0x87] = z80_inst_add_a_r,
[0x88] = z80_inst_adc_a_r,
[0x89] = z80_inst_adc_a_r,
[0x8A] = z80_inst_adc_a_r,
[0x8B] = z80_inst_adc_a_r,
[0x8C] = z80_inst_adc_a_r,
[0x8D] = z80_inst_adc_a_r,
[0x8E] = z80_inst_adc_a_hl,
[0x8F] = z80_inst_adc_a_r,
[0x90] = z80_inst_sub_r,
[0x91] = z80_inst_sub_r,
[0x92] = z80_inst_sub_r,
[0x93] = z80_inst_sub_r,
[0x94] = z80_inst_sub_r,
[0x95] = z80_inst_sub_r,
[0x96] = z80_inst_sub_hl,
[0x97] = z80_inst_sub_r,
[0x98] = z80_inst_sbc_a_r,
[0x99] = z80_inst_sbc_a_r,
[0x9A] = z80_inst_sbc_a_r,
[0x9B] = z80_inst_sbc_a_r,
[0x9C] = z80_inst_sbc_a_r,
[0x9D] = z80_inst_sbc_a_r,
[0x9E] = z80_inst_sbc_a_hl,
[0x9F] = z80_inst_sbc_a_r,
[0xA0] = z80_inst_and_r,
[0xA1] = z80_inst_and_r,
[0xA2] = z80_inst_and_r,
[0xA3] = z80_inst_and_r,
[0xA4] = z80_inst_and_r,
[0xA5] = z80_inst_and_r,
[0xA6] = z80_inst_and_hl,
[0xA7] = z80_inst_and_r,
[0xA8] = z80_inst_xor_r,
[0xA9] = z80_inst_xor_r,
[0xAA] = z80_inst_xor_r,
[0xAB] = z80_inst_xor_r,
[0xAC] = z80_inst_xor_r,
[0xAD] = z80_inst_xor_r,
[0xAE] = z80_inst_unimplemented, // TODO
[0xAE] = z80_inst_xor_hl,
[0xAF] = z80_inst_xor_r,
[0xB0] = z80_inst_or_r,
[0xB1] = z80_inst_or_r,
@@ -184,7 +184,7 @@ static DispatchTable instruction_table = {
[0xB3] = z80_inst_or_r,
[0xB4] = z80_inst_or_r,
[0xB5] = z80_inst_or_r,
[0xB6] = z80_inst_unimplemented, // TODO
[0xB6] = z80_inst_or_hl,
[0xB7] = z80_inst_or_r,
[0xB8] = z80_inst_cp_r,
[0xB9] = z80_inst_cp_r,
@@ -200,7 +200,7 @@ static DispatchTable instruction_table = {
[0xC3] = z80_inst_jp_nn,
[0xC4] = z80_inst_call_cc_nn,
[0xC5] = z80_inst_push_qq,
[0xC6] = z80_inst_unimplemented, // TODO
[0xC6] = z80_inst_add_a_n,
[0xC7] = z80_inst_rst_p,
[0xC8] = z80_inst_ret_cc,
[0xC9] = z80_inst_ret,
@@ -208,7 +208,7 @@ static DispatchTable instruction_table = {
[0xCB] = z80_prefix_bits,
[0xCC] = z80_inst_call_cc_nn,
[0xCD] = z80_inst_call_nn,
[0xCE] = z80_inst_unimplemented, // TODO
[0xCE] = z80_inst_adc_a_n,
[0xCF] = z80_inst_rst_p,
[0xD0] = z80_inst_ret_cc,
[0xD1] = z80_inst_pop_qq,
@@ -224,7 +224,7 @@ static DispatchTable instruction_table = {
[0xDB] = z80_inst_in_a_n,
[0xDC] = z80_inst_call_cc_nn,
[0xDD] = z80_prefix_index,
[0xDE] = z80_inst_unimplemented, // TODO
[0xDE] = z80_inst_sbc_a_n,
[0xDF] = z80_inst_rst_p,
[0xE0] = z80_inst_ret_cc,
[0xE1] = z80_inst_pop_qq,
@@ -831,8 +831,8 @@ static DispatchTable instruction_table_index = {
[0x31] = z80_inst_nop2,
[0x32] = z80_inst_nop2,
[0x33] = z80_inst_nop2,
[0x34] = z80_inst_unimplemented, // TODO
[0x35] = z80_inst_unimplemented, // TODO
[0x34] = z80_inst_inc_ixy,
[0x35] = z80_inst_dec_ixy,
[0x36] = z80_inst_ld_ixy_n,
[0x37] = z80_inst_nop2,
[0x38] = z80_inst_nop2,
@@ -913,7 +913,7 @@ static DispatchTable instruction_table_index = {
[0x83] = z80_inst_nop2,
[0x84] = z80_inst_unimplemented, // TODO
[0x85] = z80_inst_unimplemented, // TODO
[0x86] = z80_inst_unimplemented, // TODO
[0x86] = z80_inst_add_a_ixy,
[0x87] = z80_inst_nop2,
[0x88] = z80_inst_nop2,
[0x89] = z80_inst_nop2,
@@ -921,7 +921,7 @@ static DispatchTable instruction_table_index = {
[0x8B] = z80_inst_nop2,
[0x8C] = z80_inst_unimplemented, // TODO
[0x8D] = z80_inst_unimplemented, // TODO
[0x8E] = z80_inst_unimplemented, // TODO
[0x8E] = z80_inst_adc_a_ixy,
[0x8F] = z80_inst_nop2,
[0x90] = z80_inst_nop2,
[0x91] = z80_inst_nop2,
@@ -929,7 +929,7 @@ static DispatchTable instruction_table_index = {
[0x93] = z80_inst_nop2,
[0x94] = z80_inst_unimplemented, // TODO
[0x95] = z80_inst_unimplemented, // TODO
[0x96] = z80_inst_unimplemented, // TODO
[0x96] = z80_inst_sub_ixy,
[0x97] = z80_inst_nop2,
[0x98] = z80_inst_nop2,
[0x99] = z80_inst_nop2,
@@ -937,7 +937,7 @@ static DispatchTable instruction_table_index = {
[0x9B] = z80_inst_nop2,
[0x9C] = z80_inst_unimplemented, // TODO
[0x9D] = z80_inst_unimplemented, // TODO
[0x9E] = z80_inst_unimplemented, // TODO
[0x9E] = z80_inst_sbc_a_ixy,
[0x9F] = z80_inst_nop2,
[0xA0] = z80_inst_nop2,
[0xA1] = z80_inst_nop2,
@@ -945,7 +945,7 @@ static DispatchTable instruction_table_index = {
[0xA3] = z80_inst_nop2,
[0xA4] = z80_inst_unimplemented, // TODO
[0xA5] = z80_inst_unimplemented, // TODO
[0xA6] = z80_inst_unimplemented, // TODO
[0xA6] = z80_inst_and_ixy,
[0xA7] = z80_inst_nop2,
[0xA8] = z80_inst_nop2,
[0xA9] = z80_inst_nop2,
@@ -953,7 +953,7 @@ static DispatchTable instruction_table_index = {
[0xAB] = z80_inst_nop2,
[0xAC] = z80_inst_unimplemented, // TODO
[0xAD] = z80_inst_unimplemented, // TODO
[0xAE] = z80_inst_unimplemented, // TODO
[0xAE] = z80_inst_xor_ixy,
[0xAF] = z80_inst_nop2,
[0xB0] = z80_inst_nop2,
[0xB1] = z80_inst_nop2,
@@ -969,7 +969,7 @@ static DispatchTable instruction_table_index = {
[0xBB] = z80_inst_nop2,
[0xBC] = z80_inst_unimplemented, // TODO
[0xBD] = z80_inst_unimplemented, // TODO
[0xBE] = z80_inst_unimplemented, // TODO
[0xBE] = z80_inst_cp_ixy,
[0xBF] = z80_inst_nop2,
[0xC0] = z80_inst_nop2,
[0xC1] = z80_inst_nop2,


Loading…
Cancel
Save