diff --git a/src/sim6502.rs b/src/sim6502.rs index 303c2ed..9c9e546 100644 --- a/src/sim6502.rs +++ b/src/sim6502.rs @@ -21,7 +21,7 @@ pub enum Addressing { Relative, } -#[derive(Debug, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum InstructionName { ADC, AHX, ALR, AND, ANC, ARR, ASL, AXS, BCC, BCS, BEQ, BIT, BMI, BNE, BPL, BRK, BVC, BVS, CLC, CLD, CLI, CLV, CMP, CPX, CPY, DCP, DEC, DEX, DEY, EOR, ISC, INC, @@ -30,7 +30,7 @@ pub enum InstructionName { STA, STX, STY, TAS, TAX, TAY, TSX, TXA, TXS, TYA, XAA, } -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub enum AddressingShort { Imp, Acc, Imm, ZPg, ZPX, ZPY, Abs, AbX, AbY, InX, @@ -43,7 +43,7 @@ pub struct InstructionDefinition { addressing: AddressingShort, } -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub enum Register { A, X, @@ -97,13 +97,13 @@ pub struct Cpu { } #[derive(Debug)] -pub struct Instruction { +pub struct Instruction<'a> { opcode: u8, name: InstructionName, src_opr: Operand, dst_opr: Operand, bytes_read: i32, - raw_data: Vec, + raw_data: &'a [u8], } impl Cpu { @@ -156,21 +156,17 @@ impl Cpu { self.status_flags[Carry] = bit > 0x0; } - pub fn branch(mut self, offset: i8) { - self.program_counter += 2 + offset as i16; + pub fn branch_on_flag(&mut self, inst: &Instruction, flag: Flag, not: bool) { + let offset = self.load(&inst.src_opr) as i8; + if not ^ !self.status_flags[flag] { + self.program_counter += 2 + offset as i16; + } } } macro_rules! instruction_defs { ($({$name:ident, $addr:ident}),* $(,)?) => { - [ - $( - InstructionDefinition { - name: $name, - addressing: $addr - }, - )* - ] + [$(InstructionDefinition {name: $name, addressing: $addr},)*] }; } @@ -245,7 +241,8 @@ fn execute(cpu: &mut Cpu, inst: &Instruction) { cpu.registers[reg] = result as u8 - carry_val; } - cpu.status_flags[Carry] = result < 0; + // TODO: This is wrong because it's a u16, it can't be below 0 + // cpu.status_flags[Carry] = if result < 0 { true } else { false }; let reg_a = cpu.registers[A]; let res = result as u8; @@ -273,18 +270,18 @@ fn execute(cpu: &mut Cpu, inst: &Instruction) { cpu.check_z_n_flags(cpu.registers[A]); }, EOR => { - cpu.registers[A] != cpu.load(&inst.src_opr); + cpu.registers[A] ^= cpu.load(&inst.src_opr); cpu.check_z_n_flags(cpu.registers[A]); }, // Branching - BCC => if !cpu.status_flags[Carry] { cpu.branch(cpu.load(&inst.src_opr) as i8) }, - BCS => if cpu.status_flags[Carry] { cpu.branch(cpu.load(&inst.src_opr) as i8) }, - BNE => if !cpu.status_flags[Zero] { cpu.branch(cpu.load(&inst.src_opr) as i8) }, - BEQ => if cpu.status_flags[Zero] { cpu.branch(cpu.load(&inst.src_opr) as i8) }, - BPL => if !cpu.status_flags[Negative] { cpu.branch(cpu.load(&inst.src_opr) as i8) }, - BMI => if cpu.status_flags[Negative] { cpu.branch(cpu.load(&inst.src_opr) as i8) }, - BVC => if !cpu.status_flags[Overflow] { cpu.branch(cpu.load(&inst.src_opr) as i8) }, - BVS => if cpu.status_flags[Overflow] { cpu.branch(cpu.load(&inst.src_opr) as i8) }, + BCC => cpu.branch_on_flag(&inst, Carry, true), + BCS => cpu.branch_on_flag(&inst, Carry, false), + BNE => cpu.branch_on_flag(&inst, Zero, true), + BEQ => cpu.branch_on_flag(&inst, Zero, false), + BPL => cpu.branch_on_flag(&inst, Negative, true), + BMI => cpu.branch_on_flag(&inst, Negative, false), + BVC => cpu.branch_on_flag(&inst, Overflow, true), + BVS => cpu.branch_on_flag(&inst, Overflow, false), // Jump JMP => cpu.program_counter = cpu.load_u16(&inst.src_opr) as i16, JSR => {