should be all legal opcodes
This commit is contained in:
parent
57a6168646
commit
bc16c64e48
|
@ -33,6 +33,7 @@ macro_rules! abs_indexed_addr
|
|||
let fetched_addr = (hi << 8) | lo;
|
||||
self.absolute_addr = fetched_addr.wrapping_add(self.$register as u16);
|
||||
|
||||
self.additional_cycles = ((fetched_addr & 0xFF00) != (self.absolute_addr & 0xFF00)) as u8;
|
||||
|
||||
self.fetch_type = FetchType::Mem;
|
||||
|
||||
|
@ -41,6 +42,25 @@ macro_rules! abs_indexed_addr
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! zpg_indexed_addr
|
||||
{
|
||||
($name: ident, $register: ident) =>
|
||||
{
|
||||
pub fn $name(&mut self)
|
||||
{
|
||||
let bus = self.bus.upgrade().unwrap();
|
||||
|
||||
let fetched_addr = bus.borrow().read_cpu(self.pc);
|
||||
self.absolute_addr = fetched_addr.wrapping_add(self.$register) as u16;
|
||||
self.pc += instr_size!($name) - 1;
|
||||
|
||||
self.fetch_type = FetchType::Mem;
|
||||
|
||||
print!("{: <40}", format!("${:02X},{} @ ${:04X}", fetched_addr, stringify!($register).to_uppercase(), self.absolute_addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type AddrFn = fn(&mut CPU);
|
||||
|
||||
impl CPU
|
||||
|
@ -100,9 +120,7 @@ impl CPU
|
|||
let target_addr = (hi << 8) | lo;
|
||||
self.absolute_addr = target_addr.wrapping_add(self.y as u16);
|
||||
|
||||
if (target_addr & 0xFF00) != (self.absolute_addr & 0xFF00) {
|
||||
self.cycle += 1;
|
||||
}
|
||||
self.additional_cycles = ((target_addr & 0xFF00) != (self.absolute_addr & 0xFF00)) as u8;
|
||||
|
||||
self.fetch_type = FetchType::Mem;
|
||||
|
||||
|
@ -168,4 +186,8 @@ impl CPU
|
|||
|
||||
print!("{: <40}", format!("${:02X} = {:02X}", self.absolute_addr, bus.borrow().read_cpu(self.absolute_addr)))
|
||||
}
|
||||
|
||||
zpg_indexed_addr!(zpx, x);
|
||||
zpg_indexed_addr!(zpy, y);
|
||||
|
||||
}
|
|
@ -12,7 +12,8 @@ pub enum FetchType
|
|||
|
||||
pub struct CPU
|
||||
{
|
||||
pub cycle: u8,
|
||||
cycle: u8,
|
||||
pub additional_cycles: u8,
|
||||
total_cycles: u64,
|
||||
|
||||
pub absolute_addr: u16,
|
||||
|
@ -35,6 +36,7 @@ impl CPU
|
|||
{
|
||||
CPU {
|
||||
cycle: 0,
|
||||
additional_cycles: 0,
|
||||
total_cycles: 0,
|
||||
|
||||
absolute_addr: 0,
|
||||
|
@ -110,7 +112,8 @@ impl CPU
|
|||
(instr.addressing)(self);
|
||||
(instr.action)(self);
|
||||
|
||||
self.cycle += instr.cycles;
|
||||
self.cycle += instr.cycles + self.additional_cycles;
|
||||
self.additional_cycles = 0;
|
||||
|
||||
println!("A:{:02X} X:{:02X} Y:{:02X} P:{:02X} SP:{:02X} CYC:{}", self.acc, self.x, self.y, self.p, self.sp, self.total_cycles);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ pub struct Instruction
|
|||
|
||||
macro_rules! instr
|
||||
{
|
||||
($instr: ident, $addr: ident, $cyc: literal) =>
|
||||
($instr: ident, $addr: ident, $cyc: literal, $illegal: literal) =>
|
||||
{
|
||||
Option::Some(Instruction
|
||||
{
|
||||
|
@ -29,9 +29,11 @@ macro_rules! instr
|
|||
cycles: $cyc,
|
||||
length: instr_size!($addr),
|
||||
|
||||
name: Mnemonic::new(stringify!($instr), false)
|
||||
name: Mnemonic::new(stringify!($instr), $illegal)
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
($instr: ident, $addr: ident, $cyc: literal) => { instr!($instr, $addr, $cyc, false) };
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -99,10 +101,10 @@ macro_rules! branch
|
|||
{
|
||||
let branch_target = $self.pc.wrapping_add($self.relative_addr as u16);
|
||||
|
||||
$self.cycle += 1;
|
||||
$self.additional_cycles += 1;
|
||||
if (branch_target & 0xFF00) != ($self.pc & 0xFF00) // Branched to different page
|
||||
{
|
||||
$self.cycle += 1;
|
||||
$self.additional_cycles += 1;
|
||||
}
|
||||
|
||||
$self.pc = branch_target;
|
||||
|
@ -160,6 +162,8 @@ macro_rules! store_fn
|
|||
{
|
||||
let bus = self.bus.upgrade().unwrap();
|
||||
bus.borrow_mut().write_cpu(self.absolute_addr, self.$register);
|
||||
|
||||
self.additional_cycles = 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -519,7 +523,7 @@ pub static INSTRUCTION_SET: [Option<Instruction>; 256] = [
|
|||
/* 01 */ instr!(ora, idx, 6),
|
||||
/* 02 */ Option::None,
|
||||
/* 03 */ Option::None,
|
||||
/* 04 */ Option::None,
|
||||
/* 04 */ instr!(nop, zpg, 3, true),
|
||||
/* 05 */ instr!(ora, zpg, 3),
|
||||
/* 06 */ instr!(asl, zpg, 5),
|
||||
/* 07 */ Option::None,
|
||||
|
@ -527,7 +531,7 @@ pub static INSTRUCTION_SET: [Option<Instruction>; 256] = [
|
|||
/* 09 */ instr!(ora, imm, 2),
|
||||
/* 0A */ instr!(asl, acc, 2),
|
||||
/* 0B */ Option::None,
|
||||
/* 0C */ Option::None,
|
||||
/* 0C */ instr!(nop, abs, 4, true),
|
||||
/* 0D */ instr!(ora, abs, 4),
|
||||
/* 0E */ instr!(asl, abs, 6),
|
||||
/* 0F */ Option::None,
|
||||
|
@ -536,17 +540,17 @@ pub static INSTRUCTION_SET: [Option<Instruction>; 256] = [
|
|||
/* 11 */ instr!(ora, idy, 5),
|
||||
/* 12 */ Option::None,
|
||||
/* 13 */ Option::None,
|
||||
/* 14 */ Option::None,
|
||||
/* 15 */ Option::None,
|
||||
/* 16 */ Option::None,
|
||||
/* 14 */ instr!(nop, zpx, 4, true),
|
||||
/* 15 */ instr!(ora, zpx, 4),
|
||||
/* 16 */ instr!(asl, zpx, 6),
|
||||
/* 17 */ Option::None,
|
||||
/* 18 */ instr!(clc, imp, 2),
|
||||
/* 19 */ instr!(ora, aby, 4),
|
||||
/* 1A */ Option::None,
|
||||
/* 1A */ instr!(nop, imp, 2, true),
|
||||
/* 1B */ Option::None,
|
||||
/* 1C */ Option::None,
|
||||
/* 1D */ Option::None,
|
||||
/* 1E */ Option::None,
|
||||
/* 1C */ instr!(nop, abx, 4, true),
|
||||
/* 1D */ instr!(ora, abx, 4),
|
||||
/* 1E */ instr!(asl, abx, 7),
|
||||
/* 1F */ Option::None,
|
||||
|
||||
/* 20 */ instr!(jsr, abs, 6),
|
||||
|
@ -570,24 +574,24 @@ pub static INSTRUCTION_SET: [Option<Instruction>; 256] = [
|
|||
/* 31 */ instr!(and, idy, 5),
|
||||
/* 32 */ Option::None,
|
||||
/* 33 */ Option::None,
|
||||
/* 34 */ Option::None,
|
||||
/* 35 */ Option::None,
|
||||
/* 36 */ Option::None,
|
||||
/* 34 */ instr!(nop, zpx, 4, true),
|
||||
/* 35 */ instr!(and, zpx, 4),
|
||||
/* 36 */ instr!(rol, zpx, 6),
|
||||
/* 37 */ Option::None,
|
||||
/* 38 */ instr!(sec, imp, 2),
|
||||
/* 39 */ Option::None,
|
||||
/* 3A */ Option::None,
|
||||
/* 39 */ instr!(and, aby, 4),
|
||||
/* 3A */ instr!(nop, imp, 2, true),
|
||||
/* 3B */ Option::None,
|
||||
/* 3C */ Option::None,
|
||||
/* 3D */ Option::None,
|
||||
/* 3E */ Option::None,
|
||||
/* 3C */ instr!(nop, abx, 4, true),
|
||||
/* 3D */ instr!(and, abx, 4),
|
||||
/* 3E */ instr!(rol, abx, 7),
|
||||
/* 3F */ Option::None,
|
||||
|
||||
/* 40 */ instr!(rti, imp, 6),
|
||||
/* 41 */ instr!(eor, idx, 6),
|
||||
/* 42 */ Option::None,
|
||||
/* 43 */ Option::None,
|
||||
/* 44 */ Option::None,
|
||||
/* 44 */ instr!(nop, zpg, 3, true),
|
||||
/* 45 */ instr!(eor, zpg, 3),
|
||||
/* 46 */ instr!(lsr, zpg, 5),
|
||||
/* 47 */ Option::None,
|
||||
|
@ -604,24 +608,24 @@ pub static INSTRUCTION_SET: [Option<Instruction>; 256] = [
|
|||
/* 51 */ instr!(eor, idy, 5),
|
||||
/* 52 */ Option::None,
|
||||
/* 53 */ Option::None,
|
||||
/* 54 */ Option::None,
|
||||
/* 55 */ Option::None,
|
||||
/* 56 */ Option::None,
|
||||
/* 54 */ instr!(nop, zpx, 4, true),
|
||||
/* 55 */ instr!(eor, zpx, 4),
|
||||
/* 56 */ instr!(lsr, zpx, 6),
|
||||
/* 57 */ Option::None,
|
||||
/* 58 */ Option::None,
|
||||
/* 59 */ Option::None,
|
||||
/* 5A */ Option::None,
|
||||
/* 59 */ instr!(eor, aby, 4),
|
||||
/* 5A */ instr!(nop, imp, 2, true),
|
||||
/* 5B */ Option::None,
|
||||
/* 5C */ Option::None,
|
||||
/* 5D */ Option::None,
|
||||
/* 5E */ Option::None,
|
||||
/* 5C */ instr!(nop, abx, 4, true),
|
||||
/* 5D */ instr!(eor, abx, 4),
|
||||
/* 5E */ instr!(lsr, abx, 7),
|
||||
/* 5F */ Option::None,
|
||||
|
||||
/* 60 */ instr!(rts, imp, 6),
|
||||
/* 61 */ instr!(adc, idx, 6),
|
||||
/* 62 */ Option::None,
|
||||
/* 63 */ Option::None,
|
||||
/* 64 */ Option::None,
|
||||
/* 64 */ instr!(nop, zpg, 3, true),
|
||||
/* 65 */ instr!(adc, zpg, 3),
|
||||
/* 66 */ instr!(ror, zpg, 5),
|
||||
/* 67 */ Option::None,
|
||||
|
@ -638,29 +642,29 @@ pub static INSTRUCTION_SET: [Option<Instruction>; 256] = [
|
|||
/* 71 */ instr!(adc, idy, 5),
|
||||
/* 72 */ Option::None,
|
||||
/* 73 */ Option::None,
|
||||
/* 74 */ Option::None,
|
||||
/* 75 */ Option::None,
|
||||
/* 76 */ Option::None,
|
||||
/* 74 */ instr!(nop, zpx, 4, true),
|
||||
/* 75 */ instr!(adc, zpx, 4),
|
||||
/* 76 */ instr!(ror, zpx, 6),
|
||||
/* 77 */ Option::None,
|
||||
/* 78 */ instr!(sei, imp, 2),
|
||||
/* 79 */ Option::None,
|
||||
/* 7A */ Option::None,
|
||||
/* 79 */ instr!(adc, aby, 4),
|
||||
/* 7A */ instr!(nop, imp, 2, true),
|
||||
/* 7B */ Option::None,
|
||||
/* 7C */ Option::None,
|
||||
/* 7D */ Option::None,
|
||||
/* 7E */ Option::None,
|
||||
/* 7C */ instr!(nop, abx, 4, true),
|
||||
/* 7D */ instr!(adc, abx, 4),
|
||||
/* 7E */ instr!(ror, abx, 7),
|
||||
/* 7F */ Option::None,
|
||||
|
||||
/* 80 */ Option::None,
|
||||
/* 80 */ instr!(nop, imm, 2, true),
|
||||
/* 81 */ instr!(sta, idx, 6),
|
||||
/* 82 */ Option::None,
|
||||
/* 82 */ instr!(nop, imm, 2, true),
|
||||
/* 83 */ Option::None,
|
||||
/* 84 */ instr!(sty, zpg, 3),
|
||||
/* 85 */ instr!(sta, zpg, 3),
|
||||
/* 86 */ instr!(stx, zpg, 3),
|
||||
/* 87 */ Option::None,
|
||||
/* 88 */ instr!(dey, imp, 2),
|
||||
/* 89 */ Option::None,
|
||||
/* 89 */ instr!(nop, imm, 2, true),
|
||||
/* 8A */ instr!(txa, imp, 2),
|
||||
/* 8B */ Option::None,
|
||||
/* 8C */ instr!(sty, abs, 4),
|
||||
|
@ -672,16 +676,16 @@ pub static INSTRUCTION_SET: [Option<Instruction>; 256] = [
|
|||
/* 91 */ instr!(sta, idy, 6),
|
||||
/* 92 */ Option::None,
|
||||
/* 93 */ Option::None,
|
||||
/* 94 */ Option::None,
|
||||
/* 95 */ Option::None,
|
||||
/* 96 */ Option::None,
|
||||
/* 94 */ instr!(sty, zpx, 4),
|
||||
/* 95 */ instr!(sta, zpx, 4),
|
||||
/* 96 */ instr!(stx, zpy, 4),
|
||||
/* 97 */ Option::None,
|
||||
/* 98 */ instr!(tya, imp, 2),
|
||||
/* 99 */ Option::None,
|
||||
/* 99 */ instr!(sta, aby, 5),
|
||||
/* 9A */ instr!(txs, imp, 2),
|
||||
/* 9B */ Option::None,
|
||||
/* 9C */ Option::None,
|
||||
/* 9D */ Option::None,
|
||||
/* 9D */ instr!(sta, abx, 5),
|
||||
/* 9E */ Option::None,
|
||||
/* 9F */ Option::None,
|
||||
|
||||
|
@ -706,22 +710,22 @@ pub static INSTRUCTION_SET: [Option<Instruction>; 256] = [
|
|||
/* B1 */ instr!(lda, idy, 5),
|
||||
/* B2 */ Option::None,
|
||||
/* B3 */ Option::None,
|
||||
/* B4 */ Option::None,
|
||||
/* B5 */ Option::None,
|
||||
/* B6 */ Option::None,
|
||||
/* B4 */ instr!(ldy, zpx, 4),
|
||||
/* B5 */ instr!(lda, zpx, 4),
|
||||
/* B6 */ instr!(ldx, zpy, 4),
|
||||
/* B7 */ Option::None,
|
||||
/* B8 */ instr!(clv, imp, 2),
|
||||
/* B9 */ instr!(lda, aby, 4),
|
||||
/* BA */ instr!(tsx, imp, 2),
|
||||
/* BB */ Option::None,
|
||||
/* BC */ Option::None,
|
||||
/* BD */ Option::None,
|
||||
/* BE */ Option::None,
|
||||
/* BC */ instr!(ldy, abx, 4),
|
||||
/* BD */ instr!(lda, abx, 4),
|
||||
/* BE */ instr!(ldx, aby, 4),
|
||||
/* BF */ Option::None,
|
||||
|
||||
/* C0 */ instr!(cpy, imm, 2),
|
||||
/* C1 */ instr!(cmp, idx, 6),
|
||||
/* C2 */ Option::None,
|
||||
/* C2 */ instr!(nop, imm, 2, true),
|
||||
/* C3 */ Option::None,
|
||||
/* C4 */ instr!(cpy, zpg, 3),
|
||||
/* C5 */ instr!(cmp, zpg, 3),
|
||||
|
@ -740,22 +744,22 @@ pub static INSTRUCTION_SET: [Option<Instruction>; 256] = [
|
|||
/* D1 */ instr!(cmp, idy, 5),
|
||||
/* D2 */ Option::None,
|
||||
/* D3 */ Option::None,
|
||||
/* D4 */ Option::None,
|
||||
/* D5 */ Option::None,
|
||||
/* D6 */ Option::None,
|
||||
/* D4 */ instr!(nop, zpx, 4, true),
|
||||
/* D5 */ instr!(cmp, zpx, 4),
|
||||
/* D6 */ instr!(dec, zpx, 6),
|
||||
/* D7 */ Option::None,
|
||||
/* D8 */ instr!(cld, imp, 2),
|
||||
/* D9 */ Option::None,
|
||||
/* DA */ Option::None,
|
||||
/* D9 */ instr!(cmp, aby, 4),
|
||||
/* DA */ instr!(nop, imp, 2, true),
|
||||
/* DB */ Option::None,
|
||||
/* DC */ Option::None,
|
||||
/* DD */ Option::None,
|
||||
/* DE */ Option::None,
|
||||
/* DC */ instr!(nop, abx, 4, true),
|
||||
/* DD */ instr!(cmp, abx, 4),
|
||||
/* DE */ instr!(dec, abx, 7),
|
||||
/* DF */ Option::None,
|
||||
|
||||
/* E0 */ instr!(cpx, imm, 2),
|
||||
/* E1 */ instr!(sbc, idx, 6),
|
||||
/* E2 */ Option::None,
|
||||
/* E2 */ instr!(nop, imm, 2, true),
|
||||
/* E3 */ Option::None,
|
||||
/* E4 */ instr!(cpx, zpg, 3),
|
||||
/* E5 */ instr!(sbc, zpg, 3),
|
||||
|
@ -774,16 +778,16 @@ pub static INSTRUCTION_SET: [Option<Instruction>; 256] = [
|
|||
/* F1 */ instr!(sbc, idy, 5),
|
||||
/* F2 */ Option::None,
|
||||
/* F3 */ Option::None,
|
||||
/* F4 */ Option::None,
|
||||
/* F5 */ Option::None,
|
||||
/* F6 */ Option::None,
|
||||
/* F4 */ instr!(nop, zpx, 4, true),
|
||||
/* F5 */ instr!(sbc, zpx, 4),
|
||||
/* F6 */ instr!(inc, zpx, 6),
|
||||
/* F7 */ Option::None,
|
||||
/* F8 */ instr!(sed, imp, 2),
|
||||
/* F9 */ Option::None,
|
||||
/* FA */ Option::None,
|
||||
/* F9 */ instr!(sbc, aby, 4),
|
||||
/* FA */ instr!(nop, imp, 2, true),
|
||||
/* FB */ Option::None,
|
||||
/* FC */ Option::None,
|
||||
/* FD */ Option::None,
|
||||
/* FE */ Option::None,
|
||||
/* FC */ instr!(nop, abx, 4, true),
|
||||
/* FD */ instr!(sbc, abx, 4),
|
||||
/* FE */ instr!(inc, abx, 7),
|
||||
/* FF */ Option::None
|
||||
];
|
Loading…
Reference in a new issue