From 7ab57109f16cc58c1b281b7b3042f28a11d1e47e Mon Sep 17 00:00:00 2001 From: lyrakisk <24938740+lyrakisk@users.noreply.github.com> Date: Mon, 22 Jul 2024 22:07:11 +0200 Subject: [PATCH] Refactor execute() --- src/cpu/mod.rs | 63 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/src/cpu/mod.rs b/src/cpu/mod.rs index b28712c..6ee0049 100644 --- a/src/cpu/mod.rs +++ b/src/cpu/mod.rs @@ -15,8 +15,12 @@ enum FlagStates { SET = 1, } +enum InstructionExecutionError { + INTERRUPT_HANDLING_NOT_IMPLEMENTED, +} + #[derive(Debug)] -pub struct CPU { +struct CPU { pub register_a: u8, pub register_x: u8, pub register_y: u8, @@ -57,87 +61,91 @@ impl CPU { let instruction = &INSTRUCTIONS[&opcode]; - if let Some(_) = self.execute(&instruction) { - return; + match self.execute(&instruction) { + Ok(()) => (), + Err(InstructionExecutionError::INTERRUPT_HANDLING_NOT_IMPLEMENTED) => { + return; + } } + self.program_counter += (instruction.bytes as u16) - 1; } } - fn execute(&mut self, instruction: &Instruction) -> Option { + fn execute(&mut self, instruction: &Instruction) -> Result<(), InstructionExecutionError> { match instruction.name { "ADC" => { self.adc(&instruction.addressing_mode); - None + Ok(()) } "AND" => { self.and(&instruction.addressing_mode); - None + Ok(()) } "ASL" => { self.asl(&instruction.addressing_mode); - None + Ok(()) } "BCC" => { self.bcc(); - None + Ok(()) } "BCS" => { self.bcs(); - None + Ok(()) } "BEQ" => { self.beq(); - None + Ok(()) } "BMI" => { self.bmi(); - None + Ok(()) } "BNE" => { self.bne(); - None + Ok(()) } "BPL" => { self.bpl(); - None + Ok(()) } "BVC" => { self.bvc(); - None + Ok(()) } "BVS" => { self.bvs(); - None + Ok(()) } "CLC" => { self.clc(); - None + Ok(()) } "CLV" => { self.clv(); - None + Ok(()) } "CMP" => { self.cmp(&instruction.addressing_mode); - None + Ok(()) } - "BRK" => Some(0), + "BRK" => Err(InstructionExecutionError::INTERRUPT_HANDLING_NOT_IMPLEMENTED), "LDA" => { self.lda(&instruction.addressing_mode); - None + Ok(()) } "TAX" => { self.tax(); - None + Ok(()) } "INX" => { self.inx(); - None + Ok(()) } "SBC" => { self.sbc(&instruction.addressing_mode); - None + Ok(()) } _ => { todo!(); @@ -514,6 +522,8 @@ mod test_cpu { assert_eq!(cpu.status, expected); } + // TODO: test that illegal opcodes are ignored + #[test] fn lda_correctly_sets_negative_flag() { let program = vec![0xa9, 0x05, 0x00]; @@ -948,4 +958,11 @@ mod test_cpu { let result = cpu.get_operand(&AddressingMode::Accumulator); assert_eq!(result, 0x80); } + + #[test] + fn run_test_from_json() { + // init cpu + // update state + // while next instruction, execute() + } }