From 4d78f96cad7b077f057e2171f9a6400d8465515a Mon Sep 17 00:00:00 2001 From: David Derler Date: Sun, 22 Mar 2026 06:42:11 +0100 Subject: [PATCH 1/2] Clippy --- rs/chip_emulator/src/chip8/cursive_display.rs | 4 +- rs/chip_emulator/src/chip8/mod.rs | 10 ++-- .../src/chip8/opcodes/arithmetic_and_logic.rs | 52 +++++++++---------- rs/chip_emulator/src/chip8/opcodes/mod.rs | 4 +- .../src/chip8/opcodes/program_flow.rs | 32 ++++++------ rs/chip_emulator/src/chip8/opcodes/system.rs | 6 +-- rs/chip_emulator/src/chip8/tests.rs | 42 +++++++-------- rs/text-ui/mod.rs | 2 +- 8 files changed, 75 insertions(+), 77 deletions(-) diff --git a/rs/chip_emulator/src/chip8/cursive_display.rs b/rs/chip_emulator/src/chip8/cursive_display.rs index e61e926..e57b841 100644 --- a/rs/chip_emulator/src/chip8/cursive_display.rs +++ b/rs/chip_emulator/src/chip8/cursive_display.rs @@ -18,7 +18,7 @@ impl Display { pub fn new(pixels: &[bool]) -> Self { assert_eq!(pixels.len(), 64 * 32); let mut tmp = [false; 64 * 32]; - tmp.copy_from_slice(&pixels[..]); + tmp.copy_from_slice(pixels); Display { pixels: tmp } } } @@ -69,7 +69,7 @@ impl ChipWithCursiveDisplay for Chip8 { if !self.draw { return; } - let display = get_display(&self); + let display = get_display(self); gfx_sink .send(Box::new(Box::new(move |s: &mut cursive::Cursive| { s.pop_layer(); diff --git a/rs/chip_emulator/src/chip8/mod.rs b/rs/chip_emulator/src/chip8/mod.rs index 2fdff8c..7eac57d 100644 --- a/rs/chip_emulator/src/chip8/mod.rs +++ b/rs/chip_emulator/src/chip8/mod.rs @@ -84,8 +84,8 @@ impl Chip for Chip8 { return Err(LoadProgramError::ProgramTooLarge(program.len())); } - for i in 0..program.len() { - self.set_memory_byte(program[i], (0x200 + i) as u16); + for (i, instruction) in program.iter().enumerate() { + self.set_memory_byte(*instruction, (0x200 + i) as u16); } Ok(()) @@ -93,12 +93,12 @@ impl Chip for Chip8 { fn cycle(&mut self) { let opcode = self.next_instruction(); - let mut state = self; - opcode.execute(&mut state); + let state = self; + opcode.execute(state); state.cycles_since_timer_dec += 1; - if state.cycles_since_timer_dec % CHIP8_TIMER_RESOLUTION == 0 { + if state.cycles_since_timer_dec.is_multiple_of(CHIP8_TIMER_RESOLUTION) { if state.delay_timer > 0 { state.delay_timer -= 1; } diff --git a/rs/chip_emulator/src/chip8/opcodes/arithmetic_and_logic.rs b/rs/chip_emulator/src/chip8/opcodes/arithmetic_and_logic.rs index d2b27ef..1e2112c 100644 --- a/rs/chip_emulator/src/chip8/opcodes/arithmetic_and_logic.rs +++ b/rs/chip_emulator/src/chip8/opcodes/arithmetic_and_logic.rs @@ -10,19 +10,19 @@ use crate::chip8::{ define_instruction!(LdrInstruction, RegAndValue, 0x6); impl Executable for LdrInstruction { /// Opcode of the form `0x6XYZ` (LDR). Load a value `YZ` into `state.registers[X]`. - fn execute(&self, mut state: &mut Chip8) { + fn execute(&self, state: &mut Chip8) { state.registers[self.reg() as usize] = self.value(); - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } define_instruction!(AddInstruction, RegAndValue, 0x7); impl Executable for AddInstruction { /// Opcode of the form `0x7XYZ` (ADD). Add value `YZ` into `state.registers[X]`. - fn execute(&self, mut state: &mut Chip8) { + fn execute(&self, state: &mut Chip8) { state.registers[self.reg() as usize] = state.registers[self.reg() as usize].wrapping_add(self.value()); - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } @@ -54,7 +54,7 @@ impl Executable for RegInstruction { /// - If `Z == 0xE`, it sets `state.registers[X] = state.registers[X] << 1`; `state.registers[0xF]` /// is set to `1` if the shifted out bit is set, and to `0` otherwise. /// - fn execute(&self, mut state: &mut Chip8) { + fn execute(&self, state: &mut Chip8) { fn modify_registers( state: &mut Chip8, r1: u8, @@ -71,40 +71,40 @@ impl Executable for RegInstruction { } match self.op3() { - 0x0 => modify_registers(&mut state, self.op1(), self.op2(), |_, v2| (v2, None)), - 0x1 => modify_registers(&mut state, self.op1(), self.op2(), |v1, v2| (v1 | v2, None)), - 0x2 => modify_registers(&mut state, self.op1(), self.op2(), |v1, v2| (v1 & v2, None)), - 0x3 => modify_registers(&mut state, self.op1(), self.op2(), |v1, v2| (v1 ^ v2, None)), - 0x4 => modify_registers(&mut state, self.op1(), self.op2(), |v1, v2| { + 0x0 => modify_registers(state, self.op1(), self.op2(), |_, v2| (v2, None)), + 0x1 => modify_registers(state, self.op1(), self.op2(), |v1, v2| (v1 | v2, None)), + 0x2 => modify_registers(state, self.op1(), self.op2(), |v1, v2| (v1 & v2, None)), + 0x3 => modify_registers(state, self.op1(), self.op2(), |v1, v2| (v1 ^ v2, None)), + 0x4 => modify_registers(state, self.op1(), self.op2(), |v1, v2| { let (result, overflow) = v1.overflowing_add(v2); (result, Some(overflow)) }), - 0x5 => modify_registers(&mut state, self.op1(), self.op2(), |v1, v2| { + 0x5 => modify_registers(state, self.op1(), self.op2(), |v1, v2| { let (result, overflow) = v1.overflowing_sub(v2); (result, Some(!overflow)) }), - 0x6 => modify_registers(&mut state, self.op1(), self.op2(), |v1, _| { + 0x6 => modify_registers(state, self.op1(), self.op2(), |v1, _| { (v1 >> 1, Some(v1 & 1 != 0)) }), - 0x7 => modify_registers(&mut state, self.op1(), self.op2(), |v1, v2| { + 0x7 => modify_registers(state, self.op1(), self.op2(), |v1, v2| { let (result, overflow) = v2.overflowing_sub(v1); (result, Some(!overflow)) }), - 0xE => modify_registers(&mut state, self.op1(), self.op2(), |v1, _| { + 0xE => modify_registers(state, self.op1(), self.op2(), |v1, _| { (v1 << 1, Some(v1 & 0x80 != 0)) }), _ => panic!("Unsupported opcode"), }; - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } define_instruction!(LdInstruction, Address, 0xA); impl Executable for LdInstruction { /// Opcode of the form `0xAXYZ` (LD). Loads `XYZ` into `state.index`. - fn execute(&self, mut state: &mut Chip8) { + fn execute(&self, state: &mut Chip8) { state.index = self.address(); - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } @@ -112,13 +112,13 @@ define_instruction!(RndInstruction, RegAndValue, 0xC); impl Executable for RndInstruction { /// Opcode of the form `0xCXYZ` (RND). Generates a random value `v`, and sets /// `state.registers[X] = v & YZ. - fn execute(&self, mut state: &mut Chip8) { + fn execute(&self, state: &mut Chip8) { let mut rng = rng(); let sample = rng.random_range(0..=255); state.registers[self.reg() as usize] = sample as u8 & self.value(); - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } @@ -133,7 +133,7 @@ impl Executable for DrwInstruction { /// given in the index register. /// - `state.registers[0xF]` is set to `1` if any pixel is flipped to `0`, and /// to `0` otherwise. - fn execute(&self, mut state: &mut Chip8) { + fn execute(&self, state: &mut Chip8) { fn translate_gfx(x: u16, y: u16) -> usize { ((x % 64) + ((y % 32) * 64)) as usize } @@ -169,7 +169,7 @@ impl Executable for DrwInstruction { pixel_mask >>= 1; } } - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } @@ -201,7 +201,7 @@ impl Executable for LduInstruction { /// - If `YZ == 0x65`, load `state.registers[0]` to `state.registers[X]` from memory starting /// at `state.index`. /// - fn execute(&self, mut state: &mut Chip8) { + fn execute(&self, state: &mut Chip8) { match self.value() { 0x07 => { state.registers[self.reg() as usize] = state.delay_timer; @@ -240,13 +240,13 @@ impl Executable for LduInstruction { } 0x33 => { let mut a: u8 = state.registers[self.reg() as usize]; - state.memory[(state.index + 2) as usize] = (a % 10) as u8; + state.memory[(state.index + 2) as usize] = a % 10; a /= 10; - state.memory[(state.index + 1) as usize] = (a % 10) as u8; + state.memory[(state.index + 1) as usize] = a % 10; a /= 10; - state.memory[state.index as usize] = (a % 10) as u8; + state.memory[state.index as usize] = a % 10; } 0x55 => { for reg in 0x0..=self.reg() { @@ -262,6 +262,6 @@ impl Executable for LduInstruction { } _ => unimplemented!("Unsupported opcode"), } - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } diff --git a/rs/chip_emulator/src/chip8/opcodes/mod.rs b/rs/chip_emulator/src/chip8/opcodes/mod.rs index 8af5bca..f4e3faf 100644 --- a/rs/chip_emulator/src/chip8/opcodes/mod.rs +++ b/rs/chip_emulator/src/chip8/opcodes/mod.rs @@ -48,9 +48,9 @@ impl Opcode { } } - pub(super) fn execute(self, mut state: &mut Chip8) { + pub(super) fn execute(self, state: &mut Chip8) { let executable_opcode: Box> = self.into(); - executable_opcode.execute(&mut state); + executable_opcode.execute(state); } } diff --git a/rs/chip_emulator/src/chip8/opcodes/program_flow.rs b/rs/chip_emulator/src/chip8/opcodes/program_flow.rs index b22f44c..3804938 100644 --- a/rs/chip_emulator/src/chip8/opcodes/program_flow.rs +++ b/rs/chip_emulator/src/chip8/opcodes/program_flow.rs @@ -18,7 +18,7 @@ impl Executable for CallInstruction { fn execute(&self, state: &mut Chip8) { assert!(state.stack_pointer < 16, "Stack overflow"); state.stack[state.stack_pointer as usize] = state.program_counter; - state.stack_pointer = state.stack_pointer + 1; + state.stack_pointer += 1; state.program_counter = self.address(); } } @@ -26,48 +26,48 @@ impl Executable for CallInstruction { define_instruction!(SeInstruction, RegAndValue, 0x3); impl Executable for SeInstruction { /// Opcode of the form `0x3XYZ` (SE). Skip the next instruction if `state.registers[X] == YZ`. - fn execute(&self, mut state: &mut Chip8) { - util::conditional_skip(&self, &mut state, |instruction, state| { + fn execute(&self, state: &mut Chip8) { + util::conditional_skip(&self, state, |instruction, state| { state.registers[instruction.reg() as usize] == instruction.value() }); - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } define_instruction!(SneInstruction, RegAndValue, 0x4); impl Executable for SneInstruction { /// Opcode of the form `0x4XYZ` (SNE). Skip the next instruction if `state.registers[X] != YZ`. - fn execute(&self, mut state: &mut Chip8) { - util::conditional_skip(&self, &mut state, |instruction, state| { + fn execute(&self, state: &mut Chip8) { + util::conditional_skip(&self, state, |instruction, state| { state.registers[instruction.reg() as usize] != instruction.value() }); - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } define_instruction!(SreInstruction, Operands, 0x5); impl Executable for SreInstruction { /// Opcode of the form `0x5XY0` (SRE). Skip the next instruction if `state.registers[X] == state.registers[y]`. - fn execute(&self, mut state: &mut Chip8) { - util::conditional_skip(&self, &mut state, |instruction, state| { + fn execute(&self, state: &mut Chip8) { + util::conditional_skip(&self, state, |instruction, state| { assert_eq!(instruction.op3(), 0, "Unsupported opcode"); state.registers[instruction.op1() as usize] == state.registers[instruction.op2() as usize] }); - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } define_instruction!(SrneInstruction, Operands, 0x9); impl Executable for SrneInstruction { /// Opcode of the form `0x9XY0` (SRNE). Skip the next instruction if `state.registers[X] != state.registers[Y]`. - fn execute(&self, mut state: &mut Chip8) { - util::conditional_skip(&self, &mut state, |instruction, state| { + fn execute(&self, state: &mut Chip8) { + util::conditional_skip(&self, state, |instruction, state| { assert_eq!(instruction.op3(), 0, "Unsupported opcode"); state.registers[instruction.op1() as usize] != state.registers[instruction.op2() as usize] }); - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } @@ -89,15 +89,15 @@ impl Executable for SkInstruction { /// /// - If `YZ == A1`, it skips the next instruction if the key stored in `state.registers[X]` /// is not pressed. - fn execute(&self, mut state: &mut Chip8) { + fn execute(&self, state: &mut Chip8) { let skip = match self.value() { 0x9E => state.input_pins[state.registers[self.reg() as usize] as usize], 0xA1 => !state.input_pins[state.registers[self.reg() as usize] as usize], _ => unimplemented!("Unsupported opcode"), }; if skip { - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } - util::increment_program_counter(&mut state); + util::increment_program_counter(state); } } diff --git a/rs/chip_emulator/src/chip8/opcodes/system.rs b/rs/chip_emulator/src/chip8/opcodes/system.rs index 851546a..15b812f 100644 --- a/rs/chip_emulator/src/chip8/opcodes/system.rs +++ b/rs/chip_emulator/src/chip8/opcodes/system.rs @@ -12,7 +12,7 @@ impl Executable for SysInstruction { /// /// - If `XYZ == 0x0EE`, it returns from the current subroutine. /// - fn execute(&self, mut state: &mut Chip8) { + fn execute(&self, state: &mut Chip8) { match self.address() { 0x0E0 => { state.output_pins = [false; 64 * 32]; @@ -21,8 +21,8 @@ impl Executable for SysInstruction { 0x0EE => { assert!(state.stack_pointer > 0, "Stack underflow"); state.program_counter = state.stack[(state.stack_pointer - 1) as usize]; - state.stack_pointer = state.stack_pointer - 1; - util::increment_program_counter(&mut state); + state.stack_pointer -= 1; + util::increment_program_counter(state); } _ => panic!("Opcode not supported"), }; diff --git a/rs/chip_emulator/src/chip8/tests.rs b/rs/chip_emulator/src/chip8/tests.rs index 831efdb..6fe3766 100644 --- a/rs/chip_emulator/src/chip8/tests.rs +++ b/rs/chip_emulator/src/chip8/tests.rs @@ -113,9 +113,9 @@ fn test_skip_if_equal() { instruction |= reg << 8; test_skip_if( instruction, - reg.try_into().unwrap(), + reg.into(), cmp.try_into().unwrap(), - ((cmp as u8).wrapping_add(1)).try_into().unwrap(), + (cmp as u8).wrapping_add(1), Condition::Equal, ); } @@ -131,9 +131,9 @@ fn test_skip_if_not_equal() { instruction |= register << 8; test_skip_if( instruction, - register.try_into().unwrap(), + register.into(), cmp.try_into().unwrap(), - ((cmp as u8).wrapping_add(1)).try_into().unwrap(), + (cmp as u8).wrapping_add(1), Condition::NotEqual, ); } @@ -297,7 +297,7 @@ fn test_skip_if_reg_not_equal() { #[test] fn test_set_index() { for value in 0x0..=0xFFF { - let instruction = 0xA000 as u16 | value as u16; + let instruction = 0xA000_u16 | value; do_cycle( instruction, |state| { @@ -314,7 +314,7 @@ fn test_set_index() { #[test] fn test_set_program_counter() { for value in 0x0..=0xFFF { - let instruction = 0xB000 as u16 | value as u16; + let instruction = 0xB000_u16 | value; do_cycle( instruction, |state| { @@ -322,7 +322,7 @@ fn test_set_program_counter() { state.registers[0] = 0xA; }, |state| { - assert_eq!(state.program_counter, (0xA as u16).wrapping_add(value)); + assert_eq!(state.program_counter, (0xA_u16).wrapping_add(value)); }, ); } @@ -495,7 +495,7 @@ fn test_inc_index_by_reg() { state.registers[reg as usize] = 0xAB; }, |state| { - assert_eq!(state.index, (0xAB as u16).wrapping_add(index)); + assert_eq!(state.index, 0xAB_u16.wrapping_add(index)); assert_eq!(state.program_counter, 0x202); }, ); @@ -507,7 +507,7 @@ fn test_inc_index_by_reg() { fn test_load_sprite() { for reg in 0x0..=0xF { for character in 0x0..=0xF { - let instruction = 0xF029 as u16 | (reg << 8) as u16; + let instruction = 0xF029_u16 | (reg << 8) as u16; do_cycle( instruction, |state| { @@ -526,7 +526,7 @@ fn test_load_sprite() { #[test] fn test_bcd() { for reg in 0x0..=0xF { - let instruction = 0xF033 as u16 | (reg << 8) as u16; + let instruction = 0xF033_u16 | (reg << 8) as u16; do_cycle( instruction, |state| { @@ -535,7 +535,7 @@ fn test_bcd() { }, |state| { assert_eq!(state.program_counter, 0x202); - assert_eq!(state.memory[(state.index + 0) as usize], 1); + assert_eq!(state.memory[state.index as usize], 1); assert_eq!(state.memory[(state.index + 1) as usize], 2); assert_eq!(state.memory[(state.index + 2) as usize], 3); }, @@ -547,8 +547,8 @@ fn test_bcd() { fn test_reg_dump_load() { let mut register_values = [0; 16]; let mut rng = rng(); - for i in 0x0..=0xF { - register_values[i] = rng.random_range(0..=255); + for value in &mut register_values { + *value = rng.random_range(0..=255); } for reg in 0x0..=0xF { let instruction = 0xF055 | (reg << 8) as u16; @@ -556,17 +556,15 @@ fn test_reg_dump_load() { instruction, |state| { assert_eq!(state.program_counter, 0x200); - for r in 0x0..=reg { - state.registers[r] = register_values[r] - } + state.registers[0x0..=reg].copy_from_slice(®ister_values[0x0..=reg]); state.index = 0x400; }, |state| { - for r in 0x0..=0xF { + for (r, value) in register_values.iter().enumerate() { if r <= reg { assert_eq!( state.memory[((state.index + r as u16) % 4096) as usize], - register_values[r] + *value ); } else { assert_eq!(state.memory[((state.index + r as u16) % 4096) as usize], 0); @@ -582,14 +580,14 @@ fn test_reg_dump_load() { |state| { assert_eq!(state.program_counter, 0x200); state.index = 0x400; - for r in 0x0..=0xF { - state.memory[((state.index + r as u16) % 4096) as usize] = register_values[r]; + for (r, value) in register_values.iter().enumerate() { + state.memory[((state.index + r as u16) % 4096) as usize] = *value; } }, |state| { - for r in 0x0..=0xF { + for (r, value) in register_values.iter().enumerate() { if r <= reg { - assert_eq!(state.registers[r], register_values[r]); + assert_eq!(state.registers[r], *value); } else { assert_eq!(state.registers[r], 0); } diff --git a/rs/text-ui/mod.rs b/rs/text-ui/mod.rs index 40ae43e..79c1597 100644 --- a/rs/text-ui/mod.rs +++ b/rs/text-ui/mod.rs @@ -138,7 +138,7 @@ fn main() { chip8, EventLoopChannels { gfx_sender: cb_sink, - key_receiver: key_receiver, + key_receiver, }, ); }); From a7d535046ce578ebd496834f4b65d6bd52002635 Mon Sep 17 00:00:00 2001 From: David Derler Date: Sun, 22 Mar 2026 06:49:48 +0100 Subject: [PATCH 2/2] cargo fmt --- rs/chip_emulator/src/chip8/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rs/chip_emulator/src/chip8/mod.rs b/rs/chip_emulator/src/chip8/mod.rs index 7eac57d..0fe01e9 100644 --- a/rs/chip_emulator/src/chip8/mod.rs +++ b/rs/chip_emulator/src/chip8/mod.rs @@ -98,7 +98,10 @@ impl Chip for Chip8 { state.cycles_since_timer_dec += 1; - if state.cycles_since_timer_dec.is_multiple_of(CHIP8_TIMER_RESOLUTION) { + if state + .cycles_since_timer_dec + .is_multiple_of(CHIP8_TIMER_RESOLUTION) + { if state.delay_timer > 0 { state.delay_timer -= 1; }