use crate::alu;
use crate::cpu::Cpu;
use crate::memory::Memory;
use crate::registers::{CC_C, CC_F, CC_H, CC_I, CC_N, CC_V, CC_Z};
#[rustfmt::skip]
const PAGE0_CYCLES: [u8; 256] = [
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 6, 1, 1, 2, 2, 1, 1, 5, 9, 3, 2, 3, 2, 3, 2, 8, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 4, 5, 3, 6, 21, 11, 19, 19, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 6, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 6, 7, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 7, 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 4, 7, 3, 1, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 7, 8, 6, 6, 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 3, 1, 3, 1, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, ];
pub(super) fn cycles(opcode: u8) -> u8 {
PAGE0_CYCLES[opcode as usize]
}
pub(super) fn execute(cpu: &mut Cpu, mem: &mut impl Memory, opcode: u8) {
cpu.cycles += PAGE0_CYCLES[opcode as usize] as u64;
match opcode {
0x00 | 0x01 => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
let r = alu::neg8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x02 => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
let r = if cpu.reg.cc.carry() {
alu::com8(val, &mut cpu.reg.cc)
} else {
alu::neg8(val, &mut cpu.reg.cc)
};
mem.write(addr, r);
}
0x03 => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
let r = alu::com8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x04 | 0x05 => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
let r = alu::lsr8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x06 => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
let r = alu::ror8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x07 => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
let r = alu::asr8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x08 => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
let r = alu::asl8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x09 => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
let r = alu::rol8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x0A => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
let r = alu::dec8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x0B => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
let r = alu::dec8(val, &mut cpu.reg.cc);
cpu.reg.cc.set_carry(val != 0);
mem.write(addr, r);
}
0x0C => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
let r = alu::inc8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x0D => {
let addr = cpu.addr_direct(mem);
let val = mem.read(addr);
alu::tst8(val, &mut cpu.reg.cc);
}
0x0E => {
cpu.reg.pc = cpu.addr_direct(mem);
}
0x0F => {
let addr = cpu.addr_direct(mem);
let r = alu::clr8(&mut cpu.reg.cc);
mem.write(addr, r);
}
0x12 => {} 0x13 => {
cpu.sync = true;
}
0x14 | 0x15 => {
cpu.halted = true;
}
0x16 => {
let addr = cpu.addr_relative16(mem);
cpu.reg.pc = addr;
}
0x17 => {
let addr = cpu.addr_relative16(mem);
cpu.push_word_s(mem, cpu.reg.pc);
cpu.reg.pc = addr;
}
0x18 => {
let post = mem.read(cpu.reg.pc);
let cc = cpu.reg.cc.to_byte();
let post_cc = cc & post;
cpu.reg.cc.set_entire(post_cc & CC_F != 0);
cpu.reg.cc.set_firq_inhibit(post_cc & CC_H != 0);
cpu.reg.cc.set_half_carry(post_cc & CC_I != 0);
cpu.reg.cc.set_irq_inhibit(post_cc & CC_N != 0);
cpu.reg.cc.set_negative(post_cc & CC_Z != 0);
cpu.reg.cc.set_zero(post_cc & CC_V != 0);
cpu.reg
.cc
.set_overflow((post_cc & CC_C) | (post_cc & CC_Z) != 0);
cpu.reg.cc.set_carry(false);
}
0x19 => {
let a = cpu.reg.a();
let r = alu::daa(a, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x1A => {
let val = cpu.fetch_byte(mem);
cpu.reg.cc.or_with(val);
}
0x1B => {} 0x1C => {
let val = cpu.fetch_byte(mem);
cpu.reg.cc.and_with(val);
}
0x1D => {
let b = cpu.reg.b();
let d = alu::sex(b, &mut cpu.reg.cc);
cpu.reg.d = d;
}
0x1E => {
let post = cpu.fetch_byte(mem);
exg(cpu, post);
}
0x1F => {
let post = cpu.fetch_byte(mem);
tfr(cpu, post);
}
0x20 => {
let addr = cpu.addr_relative8(mem);
cpu.reg.pc = addr;
}
0x21 => {
let _addr = cpu.addr_relative8(mem);
}
0x22 => {
let addr = cpu.addr_relative8(mem);
if !cpu.reg.cc.carry() && !cpu.reg.cc.zero() {
cpu.reg.pc = addr;
}
}
0x23 => {
let addr = cpu.addr_relative8(mem);
if cpu.reg.cc.carry() || cpu.reg.cc.zero() {
cpu.reg.pc = addr;
}
}
0x24 => {
let addr = cpu.addr_relative8(mem);
if !cpu.reg.cc.carry() {
cpu.reg.pc = addr;
}
}
0x25 => {
let addr = cpu.addr_relative8(mem);
if cpu.reg.cc.carry() {
cpu.reg.pc = addr;
}
}
0x26 => {
let addr = cpu.addr_relative8(mem);
if !cpu.reg.cc.zero() {
cpu.reg.pc = addr;
}
}
0x27 => {
let addr = cpu.addr_relative8(mem);
if cpu.reg.cc.zero() {
cpu.reg.pc = addr;
}
}
0x28 => {
let addr = cpu.addr_relative8(mem);
if !cpu.reg.cc.overflow() {
cpu.reg.pc = addr;
}
}
0x29 => {
let addr = cpu.addr_relative8(mem);
if cpu.reg.cc.overflow() {
cpu.reg.pc = addr;
}
}
0x2A => {
let addr = cpu.addr_relative8(mem);
if !cpu.reg.cc.negative() {
cpu.reg.pc = addr;
}
}
0x2B => {
let addr = cpu.addr_relative8(mem);
if cpu.reg.cc.negative() {
cpu.reg.pc = addr;
}
}
0x2C => {
let addr = cpu.addr_relative8(mem);
if cpu.reg.cc.negative() == cpu.reg.cc.overflow() {
cpu.reg.pc = addr;
}
}
0x2D => {
let addr = cpu.addr_relative8(mem);
if cpu.reg.cc.negative() != cpu.reg.cc.overflow() {
cpu.reg.pc = addr;
}
}
0x2E => {
let addr = cpu.addr_relative8(mem);
if !cpu.reg.cc.zero() && cpu.reg.cc.negative() == cpu.reg.cc.overflow() {
cpu.reg.pc = addr;
}
}
0x2F => {
let addr = cpu.addr_relative8(mem);
if cpu.reg.cc.zero() || cpu.reg.cc.negative() != cpu.reg.cc.overflow() {
cpu.reg.pc = addr;
}
}
0x30 => {
let (ea, extra) = cpu.addr_indexed(mem);
cpu.reg.x = ea;
cpu.reg.cc.set_zero(ea == 0);
cpu.cycles += extra as u64;
}
0x31 => {
let (ea, extra) = cpu.addr_indexed(mem);
cpu.reg.y = ea;
cpu.reg.cc.set_zero(ea == 0);
cpu.cycles += extra as u64;
}
0x32 => {
let (ea, extra) = cpu.addr_indexed(mem);
cpu.reg.s = ea;
cpu.arm_nmi();
cpu.cycles += extra as u64;
}
0x33 => {
let (ea, extra) = cpu.addr_indexed(mem);
cpu.reg.u = ea;
cpu.cycles += extra as u64;
}
0x34 => {
let post = cpu.fetch_byte(mem);
pshs(cpu, mem, post);
}
0x35 => {
let post = cpu.fetch_byte(mem);
puls(cpu, mem, post);
}
0x36 => {
let post = cpu.fetch_byte(mem);
pshu(cpu, mem, post);
}
0x37 => {
let post = cpu.fetch_byte(mem);
pulu(cpu, mem, post);
}
0x38 => {
let val = cpu.fetch_byte(mem);
cpu.reg.cc.and_with(val);
}
0x39 => {
cpu.reg.pc = cpu.pull_word_s(mem);
}
0x3A => {
cpu.reg.x = cpu.reg.x.wrapping_add(cpu.reg.b() as u16);
}
0x3B => {
let cc = cpu.pull_byte_s(mem);
cpu.reg.cc = crate::registers::ConditionCodes::from_byte(cc);
if cpu.reg.cc.entire() {
let a = cpu.pull_byte_s(mem);
cpu.reg.set_a(a);
let b = cpu.pull_byte_s(mem);
cpu.reg.set_b(b);
cpu.reg.dp = cpu.pull_byte_s(mem);
cpu.reg.x = cpu.pull_word_s(mem);
cpu.reg.y = cpu.pull_word_s(mem);
cpu.reg.u = cpu.pull_word_s(mem);
cpu.cycles += 9;
}
cpu.reg.pc = cpu.pull_word_s(mem);
}
0x3C => {
let post = cpu.fetch_byte(mem);
cpu.reg.cc.and_with(post);
cpu.reg.cc.set_entire(true);
cpu.push_entire_state(mem);
cpu.cwai = true;
}
0x3D => {
let a = cpu.reg.a();
let b = cpu.reg.b();
let d = alu::mul(a, b, &mut cpu.reg.cc);
cpu.reg.d = d;
}
0x3E => {
cpu.push_entire_state(mem);
cpu.reg.pc = mem.read_word(crate::cpu::VEC_RESET);
}
0x3F => {
cpu.reg.cc.set_entire(true);
cpu.push_entire_state(mem);
cpu.reg.cc.set_irq_inhibit(true);
cpu.reg.cc.set_firq_inhibit(true);
cpu.reg.pc = mem.read_word(crate::cpu::VEC_SWI);
}
0x40 | 0x41 => {
let v = cpu.reg.a();
let r = alu::neg8(v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x42 => {
let v = cpu.reg.a();
let r = if cpu.reg.cc.carry() {
alu::com8(v, &mut cpu.reg.cc)
} else {
alu::neg8(v, &mut cpu.reg.cc)
};
cpu.reg.set_a(r);
}
0x43 => {
let v = cpu.reg.a();
let r = alu::com8(v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x44 | 0x45 => {
let v = cpu.reg.a();
let r = alu::lsr8(v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x46 => {
let v = cpu.reg.a();
let r = alu::ror8(v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x47 => {
let v = cpu.reg.a();
let r = alu::asr8(v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x48 => {
let v = cpu.reg.a();
let r = alu::asl8(v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x49 => {
let v = cpu.reg.a();
let r = alu::rol8(v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x4A => {
let v = cpu.reg.a();
let r = alu::dec8(v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x4B => {
let v = cpu.reg.a();
let r = alu::dec8(v, &mut cpu.reg.cc);
cpu.reg.cc.set_carry(v != 0);
cpu.reg.set_a(r);
}
0x4C => {
let v = cpu.reg.a();
let r = alu::inc8(v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x4D => {
let v = cpu.reg.a();
alu::tst8(v, &mut cpu.reg.cc);
}
0x4E => {
cpu.reg.cc.set_negative(false);
cpu.reg.cc.set_zero(true);
cpu.reg.cc.set_overflow(false);
cpu.reg.set_a(0);
}
0x4F => {
let r = alu::clr8(&mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x50 | 0x51 => {
let v = cpu.reg.b();
let r = alu::neg8(v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0x52 => {
let v = cpu.reg.b();
let r = if cpu.reg.cc.carry() {
alu::com8(v, &mut cpu.reg.cc)
} else {
alu::neg8(v, &mut cpu.reg.cc)
};
cpu.reg.set_b(r);
}
0x53 => {
let v = cpu.reg.b();
let r = alu::com8(v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0x54 | 0x55 => {
let v = cpu.reg.b();
let r = alu::lsr8(v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0x56 => {
let v = cpu.reg.b();
let r = alu::ror8(v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0x57 => {
let v = cpu.reg.b();
let r = alu::asr8(v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0x58 => {
let v = cpu.reg.b();
let r = alu::asl8(v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0x59 => {
let v = cpu.reg.b();
let r = alu::rol8(v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0x5A => {
let v = cpu.reg.b();
let r = alu::dec8(v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0x5B => {
let v = cpu.reg.b();
let r = alu::dec8(v, &mut cpu.reg.cc);
cpu.reg.cc.set_carry(v != 0);
cpu.reg.set_b(r);
}
0x5C => {
let v = cpu.reg.b();
let r = alu::inc8(v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0x5D => {
let v = cpu.reg.b();
alu::tst8(v, &mut cpu.reg.cc);
}
0x5E => {
cpu.reg.cc.set_negative(false);
cpu.reg.cc.set_zero(true);
cpu.reg.cc.set_overflow(false);
cpu.reg.set_b(0);
}
0x5F => {
let r = alu::clr8(&mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0x60 | 0x61 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
let r = alu::neg8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x62 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
let r = if cpu.reg.cc.carry() {
alu::com8(val, &mut cpu.reg.cc)
} else {
alu::neg8(val, &mut cpu.reg.cc)
};
mem.write(addr, r);
}
0x63 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
let r = alu::com8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x64 | 0x65 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
let r = alu::lsr8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x66 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
let r = alu::ror8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x67 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
let r = alu::asr8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x68 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
let r = alu::asl8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x69 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
let r = alu::rol8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x6A => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
let r = alu::dec8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x6B => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
let r = alu::dec8(val, &mut cpu.reg.cc);
cpu.reg.cc.set_carry(val != 0);
mem.write(addr, r);
}
0x6C => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
let r = alu::inc8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x6D => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let val = mem.read(addr);
alu::tst8(val, &mut cpu.reg.cc);
}
0x6E => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
cpu.reg.pc = addr;
}
0x6F => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let r = alu::clr8(&mut cpu.reg.cc);
mem.write(addr, r);
}
0x70 | 0x71 => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
let r = alu::neg8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x72 => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
let r = if cpu.reg.cc.carry() {
alu::com8(val, &mut cpu.reg.cc)
} else {
alu::neg8(val, &mut cpu.reg.cc)
};
mem.write(addr, r);
}
0x73 => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
let r = alu::com8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x74 | 0x75 => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
let r = alu::lsr8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x76 => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
let r = alu::ror8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x77 => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
let r = alu::asr8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x78 => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
let r = alu::asl8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x79 => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
let r = alu::rol8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x7A => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
let r = alu::dec8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x7B => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
let r = alu::dec8(val, &mut cpu.reg.cc);
cpu.reg.cc.set_carry(val != 0);
mem.write(addr, r);
}
0x7C => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
let r = alu::inc8(val, &mut cpu.reg.cc);
mem.write(addr, r);
}
0x7D => {
let addr = cpu.addr_extended(mem);
let val = mem.read(addr);
alu::tst8(val, &mut cpu.reg.cc);
}
0x7E => {
cpu.reg.pc = cpu.addr_extended(mem);
}
0x7F => {
let addr = cpu.addr_extended(mem);
let r = alu::clr8(&mut cpu.reg.cc);
mem.write(addr, r);
}
0x80 => {
let v = cpu.fetch_byte(mem);
let a = cpu.reg.a();
let r = alu::sub8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x81 => {
let v = cpu.fetch_byte(mem);
let a = cpu.reg.a();
alu::sub8(a, v, &mut cpu.reg.cc);
}
0x82 => {
let v = cpu.fetch_byte(mem);
let a = cpu.reg.a();
let r = alu::sbc8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x83 => {
let v = cpu.fetch_word(mem);
let d = cpu.reg.d;
let r = alu::sub16(d, v, &mut cpu.reg.cc);
cpu.reg.d = r;
}
0x84 => {
let v = cpu.fetch_byte(mem);
let a = cpu.reg.a();
let r = alu::and8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x85 => {
let v = cpu.fetch_byte(mem);
let a = cpu.reg.a();
alu::and8(a, v, &mut cpu.reg.cc);
}
0x86 => {
let v = cpu.fetch_byte(mem);
alu::ld8_flags(v, &mut cpu.reg.cc);
cpu.reg.set_a(v);
}
0x88 => {
let v = cpu.fetch_byte(mem);
let a = cpu.reg.a();
let r = alu::eor8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x89 => {
let v = cpu.fetch_byte(mem);
let a = cpu.reg.a();
let r = alu::adc8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x8A => {
let v = cpu.fetch_byte(mem);
let a = cpu.reg.a();
let r = alu::or8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x8B => {
let v = cpu.fetch_byte(mem);
let a = cpu.reg.a();
let r = alu::add8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x8C => {
let v = cpu.fetch_word(mem);
let x = cpu.reg.x;
alu::sub16(x, v, &mut cpu.reg.cc);
}
0x8D => {
let addr = cpu.addr_relative8(mem);
cpu.push_word_s(mem, cpu.reg.pc);
cpu.reg.pc = addr;
}
0x8E => {
let v = cpu.fetch_word(mem);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.x = v;
}
0x90 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::sub8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x91 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
alu::sub8(a, v, &mut cpu.reg.cc);
}
0x92 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::sbc8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x93 => {
let addr = cpu.addr_direct(mem);
let v = mem.read_word(addr);
let d = cpu.reg.d;
let r = alu::sub16(d, v, &mut cpu.reg.cc);
cpu.reg.d = r;
}
0x94 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::and8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x95 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
alu::and8(a, v, &mut cpu.reg.cc);
}
0x96 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
alu::ld8_flags(v, &mut cpu.reg.cc);
cpu.reg.set_a(v);
}
0x97 => {
let addr = cpu.addr_direct(mem);
let v = cpu.reg.a();
alu::ld8_flags(v, &mut cpu.reg.cc);
mem.write(addr, v);
}
0x98 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::eor8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x99 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::adc8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x9A => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::or8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x9B => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::add8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0x9C => {
let addr = cpu.addr_direct(mem);
let v = mem.read_word(addr);
let x = cpu.reg.x;
alu::sub16(x, v, &mut cpu.reg.cc);
}
0x9D => {
let addr = cpu.addr_direct(mem);
cpu.push_word_s(mem, cpu.reg.pc);
cpu.reg.pc = addr;
}
0x9E => {
let addr = cpu.addr_direct(mem);
let v = mem.read_word(addr);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.x = v;
}
0x9F => {
let addr = cpu.addr_direct(mem);
let v = cpu.reg.x;
alu::ld16_flags(v, &mut cpu.reg.cc);
mem.write_word(addr, v);
}
0xA0 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::sub8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xA1 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let a = cpu.reg.a();
alu::sub8(a, v, &mut cpu.reg.cc);
}
0xA2 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::sbc8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xA3 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read_word(addr);
let d = cpu.reg.d;
let r = alu::sub16(d, v, &mut cpu.reg.cc);
cpu.reg.d = r;
}
0xA4 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::and8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xA5 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let a = cpu.reg.a();
alu::and8(a, v, &mut cpu.reg.cc);
}
0xA6 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
alu::ld8_flags(v, &mut cpu.reg.cc);
cpu.reg.set_a(v);
}
0xA7 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = cpu.reg.a();
alu::ld8_flags(v, &mut cpu.reg.cc);
mem.write(addr, v);
}
0xA8 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::eor8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xA9 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::adc8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xAA => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::or8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xAB => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::add8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xAC => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read_word(addr);
let x = cpu.reg.x;
alu::sub16(x, v, &mut cpu.reg.cc);
}
0xAD => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
cpu.push_word_s(mem, cpu.reg.pc);
cpu.reg.pc = addr;
}
0xAE => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read_word(addr);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.x = v;
}
0xAF => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = cpu.reg.x;
alu::ld16_flags(v, &mut cpu.reg.cc);
mem.write_word(addr, v);
}
0xB0 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::sub8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xB1 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
alu::sub8(a, v, &mut cpu.reg.cc);
}
0xB2 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::sbc8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xB3 => {
let addr = cpu.addr_extended(mem);
let v = mem.read_word(addr);
let d = cpu.reg.d;
let r = alu::sub16(d, v, &mut cpu.reg.cc);
cpu.reg.d = r;
}
0xB4 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::and8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xB5 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
alu::and8(a, v, &mut cpu.reg.cc);
}
0xB6 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
alu::ld8_flags(v, &mut cpu.reg.cc);
cpu.reg.set_a(v);
}
0xB7 => {
let addr = cpu.addr_extended(mem);
let v = cpu.reg.a();
alu::ld8_flags(v, &mut cpu.reg.cc);
mem.write(addr, v);
}
0xB8 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::eor8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xB9 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::adc8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xBA => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::or8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xBB => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let a = cpu.reg.a();
let r = alu::add8(a, v, &mut cpu.reg.cc);
cpu.reg.set_a(r);
}
0xBC => {
let addr = cpu.addr_extended(mem);
let v = mem.read_word(addr);
let x = cpu.reg.x;
alu::sub16(x, v, &mut cpu.reg.cc);
}
0xBD => {
let addr = cpu.addr_extended(mem);
cpu.push_word_s(mem, cpu.reg.pc);
cpu.reg.pc = addr;
}
0xBE => {
let addr = cpu.addr_extended(mem);
let v = mem.read_word(addr);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.x = v;
}
0xBF => {
let addr = cpu.addr_extended(mem);
let v = cpu.reg.x;
alu::ld16_flags(v, &mut cpu.reg.cc);
mem.write_word(addr, v);
}
0xC0 => {
let v = cpu.fetch_byte(mem);
let b = cpu.reg.b();
let r = alu::sub8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xC1 => {
let v = cpu.fetch_byte(mem);
let b = cpu.reg.b();
alu::sub8(b, v, &mut cpu.reg.cc);
}
0xC2 => {
let v = cpu.fetch_byte(mem);
let b = cpu.reg.b();
let r = alu::sbc8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xC3 => {
let v = cpu.fetch_word(mem);
let d = cpu.reg.d;
let r = alu::add16(d, v, &mut cpu.reg.cc);
cpu.reg.d = r;
}
0xC4 => {
let v = cpu.fetch_byte(mem);
let b = cpu.reg.b();
let r = alu::and8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xC5 => {
let v = cpu.fetch_byte(mem);
let b = cpu.reg.b();
alu::and8(b, v, &mut cpu.reg.cc);
}
0xC6 => {
let v = cpu.fetch_byte(mem);
alu::ld8_flags(v, &mut cpu.reg.cc);
cpu.reg.set_b(v);
}
0xC8 => {
let v = cpu.fetch_byte(mem);
let b = cpu.reg.b();
let r = alu::eor8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xC9 => {
let v = cpu.fetch_byte(mem);
let b = cpu.reg.b();
let r = alu::adc8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xCA => {
let v = cpu.fetch_byte(mem);
let b = cpu.reg.b();
let r = alu::or8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xCB => {
let v = cpu.fetch_byte(mem);
let b = cpu.reg.b();
let r = alu::add8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xCC => {
let v = cpu.fetch_word(mem);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.d = v;
}
0xCD => {
cpu.halted = true;
}
0xCE => {
let v = cpu.fetch_word(mem);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.u = v;
}
0xD0 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::sub8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xD1 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
alu::sub8(b, v, &mut cpu.reg.cc);
}
0xD2 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::sbc8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xD3 => {
let addr = cpu.addr_direct(mem);
let v = mem.read_word(addr);
let d = cpu.reg.d;
let r = alu::add16(d, v, &mut cpu.reg.cc);
cpu.reg.d = r;
}
0xD4 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::and8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xD5 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
alu::and8(b, v, &mut cpu.reg.cc);
}
0xD6 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
alu::ld8_flags(v, &mut cpu.reg.cc);
cpu.reg.set_b(v);
}
0xD7 => {
let addr = cpu.addr_direct(mem);
let v = cpu.reg.b();
alu::ld8_flags(v, &mut cpu.reg.cc);
mem.write(addr, v);
}
0xD8 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::eor8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xD9 => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::adc8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xDA => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::or8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xDB => {
let addr = cpu.addr_direct(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::add8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xDC => {
let addr = cpu.addr_direct(mem);
let v = mem.read_word(addr);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.d = v;
}
0xDD => {
let addr = cpu.addr_direct(mem);
let v = cpu.reg.d;
alu::ld16_flags(v, &mut cpu.reg.cc);
mem.write_word(addr, v);
}
0xDE => {
let addr = cpu.addr_direct(mem);
let v = mem.read_word(addr);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.u = v;
}
0xDF => {
let addr = cpu.addr_direct(mem);
let v = cpu.reg.u;
alu::ld16_flags(v, &mut cpu.reg.cc);
mem.write_word(addr, v);
}
0xE0 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::sub8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xE1 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let b = cpu.reg.b();
alu::sub8(b, v, &mut cpu.reg.cc);
}
0xE2 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::sbc8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xE3 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read_word(addr);
let d = cpu.reg.d;
let r = alu::add16(d, v, &mut cpu.reg.cc);
cpu.reg.d = r;
}
0xE4 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::and8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xE5 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let b = cpu.reg.b();
alu::and8(b, v, &mut cpu.reg.cc);
}
0xE6 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
alu::ld8_flags(v, &mut cpu.reg.cc);
cpu.reg.set_b(v);
}
0xE7 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = cpu.reg.b();
alu::ld8_flags(v, &mut cpu.reg.cc);
mem.write(addr, v);
}
0xE8 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::eor8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xE9 => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::adc8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xEA => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::or8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xEB => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::add8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xEC => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read_word(addr);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.d = v;
}
0xED => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = cpu.reg.d;
alu::ld16_flags(v, &mut cpu.reg.cc);
mem.write_word(addr, v);
}
0xEE => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = mem.read_word(addr);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.u = v;
}
0xEF => {
let (addr, ex) = cpu.addr_indexed(mem);
cpu.cycles += ex as u64;
let v = cpu.reg.u;
alu::ld16_flags(v, &mut cpu.reg.cc);
mem.write_word(addr, v);
}
0xF0 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::sub8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xF1 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
alu::sub8(b, v, &mut cpu.reg.cc);
}
0xF2 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::sbc8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xF3 => {
let addr = cpu.addr_extended(mem);
let v = mem.read_word(addr);
let d = cpu.reg.d;
let r = alu::add16(d, v, &mut cpu.reg.cc);
cpu.reg.d = r;
}
0xF4 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::and8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xF5 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
alu::and8(b, v, &mut cpu.reg.cc);
}
0xF6 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
alu::ld8_flags(v, &mut cpu.reg.cc);
cpu.reg.set_b(v);
}
0xF7 => {
let addr = cpu.addr_extended(mem);
let v = cpu.reg.b();
alu::ld8_flags(v, &mut cpu.reg.cc);
mem.write(addr, v);
}
0xF8 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::eor8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xF9 => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::adc8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xFA => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::or8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xFB => {
let addr = cpu.addr_extended(mem);
let v = mem.read(addr);
let b = cpu.reg.b();
let r = alu::add8(b, v, &mut cpu.reg.cc);
cpu.reg.set_b(r);
}
0xFC => {
let addr = cpu.addr_extended(mem);
let v = mem.read_word(addr);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.d = v;
}
0xFD => {
let addr = cpu.addr_extended(mem);
let v = cpu.reg.d;
alu::ld16_flags(v, &mut cpu.reg.cc);
mem.write_word(addr, v);
}
0xFE => {
let addr = cpu.addr_extended(mem);
let v = mem.read_word(addr);
alu::ld16_flags(v, &mut cpu.reg.cc);
cpu.reg.u = v;
}
0xFF => {
let addr = cpu.addr_extended(mem);
let v = cpu.reg.u;
alu::ld16_flags(v, &mut cpu.reg.cc);
mem.write_word(addr, v);
}
_ => {
cpu.illegal = true;
}
}
}
fn pshs(cpu: &mut Cpu, mem: &mut impl Memory, post: u8) {
if post & 0x80 != 0 {
cpu.push_word_s(mem, cpu.reg.pc);
cpu.cycles += 2;
}
if post & 0x40 != 0 {
cpu.push_word_s(mem, cpu.reg.u);
cpu.cycles += 2;
}
if post & 0x20 != 0 {
cpu.push_word_s(mem, cpu.reg.y);
cpu.cycles += 2;
}
if post & 0x10 != 0 {
cpu.push_word_s(mem, cpu.reg.x);
cpu.cycles += 2;
}
if post & 0x08 != 0 {
cpu.push_byte_s(mem, cpu.reg.dp);
cpu.cycles += 1;
}
if post & 0x04 != 0 {
cpu.push_byte_s(mem, cpu.reg.b());
cpu.cycles += 1;
}
if post & 0x02 != 0 {
cpu.push_byte_s(mem, cpu.reg.a());
cpu.cycles += 1;
}
if post & 0x01 != 0 {
cpu.push_byte_s(mem, cpu.reg.cc.to_byte());
cpu.cycles += 1;
}
}
fn puls(cpu: &mut Cpu, mem: &mut impl Memory, post: u8) {
if post & 0x01 != 0 {
let v = cpu.pull_byte_s(mem);
cpu.reg.cc = crate::registers::ConditionCodes::from_byte(v);
cpu.cycles += 1;
}
if post & 0x02 != 0 {
let v = cpu.pull_byte_s(mem);
cpu.reg.set_a(v);
cpu.cycles += 1;
}
if post & 0x04 != 0 {
let v = cpu.pull_byte_s(mem);
cpu.reg.set_b(v);
cpu.cycles += 1;
}
if post & 0x08 != 0 {
cpu.reg.dp = cpu.pull_byte_s(mem);
cpu.cycles += 1;
}
if post & 0x10 != 0 {
cpu.reg.x = cpu.pull_word_s(mem);
cpu.cycles += 2;
}
if post & 0x20 != 0 {
cpu.reg.y = cpu.pull_word_s(mem);
cpu.cycles += 2;
}
if post & 0x40 != 0 {
cpu.reg.u = cpu.pull_word_s(mem);
cpu.cycles += 2;
}
if post & 0x80 != 0 {
cpu.reg.pc = cpu.pull_word_s(mem);
cpu.cycles += 2;
}
}
fn pshu(cpu: &mut Cpu, mem: &mut impl Memory, post: u8) {
if post & 0x80 != 0 {
cpu.push_word_u(mem, cpu.reg.pc);
cpu.cycles += 2;
}
if post & 0x40 != 0 {
cpu.push_word_u(mem, cpu.reg.s);
cpu.cycles += 2;
} if post & 0x20 != 0 {
cpu.push_word_u(mem, cpu.reg.y);
cpu.cycles += 2;
}
if post & 0x10 != 0 {
cpu.push_word_u(mem, cpu.reg.x);
cpu.cycles += 2;
}
if post & 0x08 != 0 {
cpu.push_byte_u(mem, cpu.reg.dp);
cpu.cycles += 1;
}
if post & 0x04 != 0 {
cpu.push_byte_u(mem, cpu.reg.b());
cpu.cycles += 1;
}
if post & 0x02 != 0 {
cpu.push_byte_u(mem, cpu.reg.a());
cpu.cycles += 1;
}
if post & 0x01 != 0 {
cpu.push_byte_u(mem, cpu.reg.cc.to_byte());
cpu.cycles += 1;
}
}
fn pulu(cpu: &mut Cpu, mem: &mut impl Memory, post: u8) {
if post & 0x01 != 0 {
let v = cpu.pull_byte_u(mem);
cpu.reg.cc = crate::registers::ConditionCodes::from_byte(v);
cpu.cycles += 1;
}
if post & 0x02 != 0 {
let v = cpu.pull_byte_u(mem);
cpu.reg.set_a(v);
cpu.cycles += 1;
}
if post & 0x04 != 0 {
let v = cpu.pull_byte_u(mem);
cpu.reg.set_b(v);
cpu.cycles += 1;
}
if post & 0x08 != 0 {
cpu.reg.dp = cpu.pull_byte_u(mem);
cpu.cycles += 1;
}
if post & 0x10 != 0 {
cpu.reg.x = cpu.pull_word_u(mem);
cpu.cycles += 2;
}
if post & 0x20 != 0 {
cpu.reg.y = cpu.pull_word_u(mem);
cpu.cycles += 2;
}
if post & 0x40 != 0 {
cpu.reg.s = cpu.pull_word_u(mem);
cpu.arm_nmi();
cpu.cycles += 2;
} if post & 0x80 != 0 {
cpu.reg.pc = cpu.pull_word_u(mem);
cpu.cycles += 2;
}
}
fn read_reg(cpu: &Cpu, code: u8) -> (u16, bool) {
match code {
0x0 => (cpu.reg.d, true),
0x1 => (cpu.reg.x, true),
0x2 => (cpu.reg.y, true),
0x3 => (cpu.reg.u, true),
0x4 => (cpu.reg.s, true),
0x5 => (cpu.reg.pc, true),
0x8 => (cpu.reg.a() as u16, false),
0x9 => (cpu.reg.b() as u16, false),
0xA => (cpu.reg.cc.to_byte() as u16, false),
0xB => (cpu.reg.dp as u16, false),
_ => (0xFF, false), }
}
fn write_reg(cpu: &mut Cpu, code: u8, val: u16) {
match code {
0x0 => cpu.reg.d = val,
0x1 => cpu.reg.x = val,
0x2 => cpu.reg.y = val,
0x3 => cpu.reg.u = val,
0x4 => {
cpu.reg.s = val;
cpu.arm_nmi();
}
0x5 => cpu.reg.pc = val,
0x8 => cpu.reg.set_a(val as u8),
0x9 => cpu.reg.set_b(val as u8),
0xA => cpu.reg.cc = crate::registers::ConditionCodes::from_byte(val as u8),
0xB => cpu.reg.dp = val as u8,
_ => {} }
}
fn tfr(cpu: &mut Cpu, post: u8) {
let src_code = (post >> 4) & 0x0F;
let dst_code = post & 0x0F;
let (src_val, src_16) = read_reg(cpu, src_code);
let (_, dst_16) = read_reg(cpu, dst_code);
let val = if src_16 != dst_16 {
if dst_16 { 0xFFFF } else { 0xFF }
} else {
src_val
};
write_reg(cpu, dst_code, val);
}
fn exg(cpu: &mut Cpu, post: u8) {
let src_code = (post >> 4) & 0x0F;
let dst_code = post & 0x0F;
let (src_val, src_16) = read_reg(cpu, src_code);
let (dst_val, dst_16) = read_reg(cpu, dst_code);
if src_16 != dst_16 {
let sv = if src_16 { 0xFFFF } else { 0xFF };
let dv = if dst_16 { 0xFFFF } else { 0xFF };
write_reg(cpu, src_code, sv);
write_reg(cpu, dst_code, dv);
} else {
write_reg(cpu, src_code, dst_val);
write_reg(cpu, dst_code, src_val);
}
}