diff --git a/src/cartridge/mbc0.rs b/src/cartridge/mbc0.rs index bed215d..b0fb556 100644 --- a/src/cartridge/mbc0.rs +++ b/src/cartridge/mbc0.rs @@ -15,7 +15,5 @@ impl MBC for MBC0 { self.rom[addr as usize] } - fn write_byte(&mut self, _addr: u16, _value: u8) { - (); - } + fn write_byte(&mut self, _addr: u16, _value: u8) {} } diff --git a/src/cartridge/mbc1.rs b/src/cartridge/mbc1.rs index 3152c9f..4f9409e 100644 --- a/src/cartridge/mbc1.rs +++ b/src/cartridge/mbc1.rs @@ -27,9 +27,9 @@ impl MBC for MBC1 { self.rom_bank as u16 }; - let idx = bank * 0x4000 | (addr & 0x3FFF); + let idx = (bank * 0x4000) | (addr & 0x3FFF); - return self.rom[idx as usize]; + self.rom[idx as usize] } 0xA000..=0xBFFF => self.ram[addr as usize - 0xA000], _ => { diff --git a/src/cpu/execution/bit.rs b/src/cpu/execution/bit.rs index c680907..8f16128 100644 --- a/src/cpu/execution/bit.rs +++ b/src/cpu/execution/bit.rs @@ -31,7 +31,7 @@ impl CPU { */ pub(in crate::cpu) fn swap(&mut self, mmu: &mut MMU, r: R8) { let register_value = self.get_r8_byte(mmu, r); - let result = (register_value >> 4) | (register_value << 4); + let result = register_value.rotate_left(4); self.set_r8_byte(mmu, r, result); self.registers.f.zero = result == 0; self.registers.f.carry = false; @@ -56,7 +56,7 @@ impl CPU { pub(in crate::cpu) fn rlc(&mut self, mmu: &mut MMU, r: R8) { let value = self.get_r8_byte(mmu, r); - let result = (value << 1) | (value >> 7); + let result = value.rotate_left(1); self.set_r8_byte(mmu, r, result); self.registers.f.zero = result == 0; self.registers.f.subtract = false; @@ -137,7 +137,7 @@ impl CPU { pub(in crate::cpu) fn rrc(&mut self, mmu: &mut MMU, r: R8) { let value = self.get_r8_byte(mmu, r); - let result = value >> 1 | (value << 7); + let result = value.rotate_right(1); self.registers.f.carry = value & 1 > 0; self.registers.f.half_carry = false; self.registers.f.subtract = false; diff --git a/src/cpu/flag_register.rs b/src/cpu/flag_register.rs index 47cf33f..ab8d6b1 100644 --- a/src/cpu/flag_register.rs +++ b/src/cpu/flag_register.rs @@ -26,10 +26,10 @@ impl FlagsRegister { } pub fn as_byte(&self) -> u8 { - return ((self.zero as u8) << ZERO_FLAG_BYTE_POSITION) + ((self.zero as u8) << ZERO_FLAG_BYTE_POSITION) | ((self.subtract as u8) << SUBTRACT_FLAG_BYTE_POSITION) | ((self.half_carry as u8) << HALF_CARRY_FLAG_BYTE_POSITION) - | ((self.carry as u8) << CARRY_FLAG_BYTE_POSITION); + | ((self.carry as u8) << CARRY_FLAG_BYTE_POSITION) } } diff --git a/src/cpu/mod.rs b/src/cpu/mod.rs index 6e3a9ec..0bbe792 100644 --- a/src/cpu/mod.rs +++ b/src/cpu/mod.rs @@ -17,6 +17,12 @@ pub struct CPU { pub ime: bool, } +impl Default for CPU { + fn default() -> Self { + Self::new() + } +} + impl CPU { pub fn new() -> CPU { CPU { @@ -227,6 +233,6 @@ impl CPU { pub fn get_memory_word(&mut self, memory: &MMU, addr: u16) -> u16 { let little = memory.read_byte(addr) as u16; let big = memory.read_byte(addr + 1) as u16; - return (big << 8) | little; + (big << 8) | little } } diff --git a/src/cpu/registers.rs b/src/cpu/registers.rs index 16a43e9..8a13b7b 100644 --- a/src/cpu/registers.rs +++ b/src/cpu/registers.rs @@ -20,6 +20,12 @@ pub struct Registers { pub pc: u16, } +impl Default for Registers { + fn default() -> Self { + Self::new() + } +} + impl Registers { pub fn new() -> Registers { if is_gameboy_doctor() { diff --git a/src/gameboy/debugger.rs b/src/gameboy/debugger.rs index 3c76970..0cdf21a 100644 --- a/src/gameboy/debugger.rs +++ b/src/gameboy/debugger.rs @@ -15,7 +15,7 @@ fn parse_number(s: &str) -> Option { } else if s.to_lowercase().starts_with("0b") { u16::from_str_radix(&s[2..], 2).ok() } else { - u16::from_str_radix(s, 10).ok() + s.parse::().ok() } } @@ -127,7 +127,7 @@ impl GameBoy { .map(|o| { format!( "{:02x}", - self.mmu.read_byte(self.cpu.registers.pc + o as u16) + self.mmu.read_byte(self.cpu.registers.pc + o) ) }) .collect::>() @@ -144,17 +144,14 @@ impl GameBoy { fn print_memory_range(&self, args: Vec<&str>) { const BYTES_PER_ROW: u16 = 16; - let parsed_args = args.iter().map(|s| parse_number(s)).fold( - Some(vec![] as Vec), - |acc, curr| match (acc, curr) { - (None, _) => None, - (_, None) => None, - (Some(mut v), Some(n)) => { - v.push(n); - Some(v.to_vec()) - } - }, - ); + let parsed_args: Option> = args.iter() + .map(|s| parse_number(s)) + .try_fold(Vec::new(), |mut acc, curr| { + curr.map(|n| { + acc.push(n); + acc + }) + }); let (start, end) = match parsed_args { Some(nums) => match nums.as_slice() { @@ -200,13 +197,13 @@ impl GameBoy { if b { return "true ".green().to_string(); } - return "false".red().to_string(); + "false".red().to_string() } println!("======== interrupts ========"); println!(" enabled flagged"); println!("IME: {}", colored_bool(self.cpu.ime)); - println!(""); + println!(); println!( "VBlank: {:5} {}", colored_bool(self.mmu.ie & 0x1 > 0), @@ -233,7 +230,7 @@ impl GameBoy { colored_bool(self.mmu.read_byte(0xFF0F) & 0x10 > 0) ); - println!(""); + println!(); } fn print_help(&self) { @@ -251,7 +248,7 @@ impl GameBoy { println!("[ro]m display gameboy rom"); println!("[ins]tructions last cpu operations"); println!("============================================="); - println!(""); + println!(); } } diff --git a/src/gameboy/mod.rs b/src/gameboy/mod.rs index d3ebb29..5bc6bc0 100644 --- a/src/gameboy/mod.rs +++ b/src/gameboy/mod.rs @@ -53,10 +53,9 @@ impl GameBoy { let opcode = self.mmu.read_byte(self.cpu.registers.pc); let arg_1 = self.mmu.read_byte(self.cpu.registers.pc + 1); let arg_2 = self.mmu.read_byte(self.cpu.registers.pc + 2); + let (ins, _, _) = parse(opcode, arg_1, arg_2); - match parse(opcode, arg_1, arg_2) { - (ins, _, _) => ins, - } + ins } fn print_gameboy_doctor(&self) { diff --git a/src/instructions/display.rs b/src/instructions/display.rs index 3122ef4..d8a0a22 100644 --- a/src/instructions/display.rs +++ b/src/instructions/display.rs @@ -37,7 +37,6 @@ impl fmt::Display for Instruction { let args: &mut Vec = match buffer.find('(') { Some(index) => &mut buffer[index + 1..buffer.len() - 1] .split(',') - .into_iter() .map(|s| s.trim()) .map(|s| { s.parse::() @@ -63,7 +62,7 @@ impl fmt::Display for Instruction { "a" => "a".cyan().to_string(), // Memory address - "r16mem" => format!("{}", args.pop().unwrap()).blue().to_string(), + "r16mem" => args.pop().unwrap().to_string().blue().to_string(), "imm8mem" => format!("[{}]", args.pop().unwrap()).blue().to_string(), "imm16mem" => format!("[{}]", args.pop().unwrap()).blue().to_string(), "cmem" => format!("[{}]", args.pop().unwrap()).blue().to_string(), @@ -77,7 +76,7 @@ impl fmt::Display for Instruction { .join(" "); // Process the captured string (example: convert to uppercase) - let processed = format!("{}", instruction_formatted); + let processed = instruction_formatted.to_string(); // Write the processed string to the actual formatter write!(f, "{}", processed.to_lowercase()) diff --git a/src/instructions/mod.rs b/src/instructions/mod.rs index c0c0f1f..76115b4 100644 --- a/src/instructions/mod.rs +++ b/src/instructions/mod.rs @@ -15,7 +15,7 @@ pub fn parse(opcode: u8, arg1: u8, arg2: u8) -> (Instruction, u16, u8) { let imm16: u16 = (arg2 as u16) << 8 | arg1 as u16; let imm8: u8 = arg1; - return match opcode { + match opcode { // Block 0 0x00 => (Instruction::Nop, 1, 4), 0x01 => (Instruction::LdR16Imm16(R16::BC, imm16), 3, 12), @@ -99,7 +99,7 @@ pub fn parse(opcode: u8, arg1: u8, arg2: u8) -> (Instruction, u16, u8) { _ => 4, }; - return match (opcode >> 3) & 0x7 { + match (opcode >> 3) & 0x7 { 0 => (Instruction::AddAR8(operand), 1, cycle_count), 1 => (Instruction::AdcAR8(operand), 1, cycle_count), 2 => (Instruction::SubAR8(operand), 1, cycle_count), @@ -108,7 +108,7 @@ pub fn parse(opcode: u8, arg1: u8, arg2: u8) -> (Instruction, u16, u8) { 5 => (Instruction::XorAR8(operand), 1, cycle_count), 6 => (Instruction::OrAR8(operand), 1, cycle_count), _ => (Instruction::CpAR8(operand), 1, cycle_count), - }; + } } // Block 3 @@ -178,7 +178,7 @@ pub fn parse(opcode: u8, arg1: u8, arg2: u8) -> (Instruction, u16, u8) { 0xF4 => (Instruction::ILLEGAL, 1, 4), 0xFC => (Instruction::ILLEGAL, 1, 4), 0xFD => (Instruction::ILLEGAL, 1, 4), - }; + } } fn parse_prefixed(opcode: u8) -> (Instruction, u16, u8) { @@ -208,7 +208,7 @@ fn parse_prefixed(opcode: u8) -> (Instruction, u16, u8) { } }; - return match instruction { + match instruction { Instruction::BitB3R8(_, R8::HL) => (instruction, 2, 12), Instruction::RlcR8(R8::HL) => (instruction, 2, 16), Instruction::RlR8(R8::HL) => (instruction, 2, 16), @@ -221,7 +221,7 @@ fn parse_prefixed(opcode: u8) -> (Instruction, u16, u8) { Instruction::ResB3R8(_, R8::HL) => (instruction, 2, 16), Instruction::SetB3R8(_, R8::HL) => (instruction, 2, 16), ins => (ins, 2, 8), - }; + } } #[derive(Debug)] @@ -335,7 +335,7 @@ mod test { let error_message = format!( "{} (opcode: {:#04X} {:#04X})", - json["mnemonic"].to_string(), + json["mnemonic"], opcode, imm8 ); diff --git a/src/mmu/joypad.rs b/src/mmu/joypad.rs index c7fc2cf..a0c1df8 100644 --- a/src/mmu/joypad.rs +++ b/src/mmu/joypad.rs @@ -7,6 +7,12 @@ pub struct Joypad { dulr: u8, } +impl Default for Joypad { + fn default() -> Self { + Self::new() + } +} + impl Joypad { pub fn new() -> Joypad { Joypad { @@ -58,7 +64,7 @@ impl Joypad { match addr { // Joy pad 0xFF00 => { - return match (self.joypad >> 4) & 0x3 { + match (self.joypad >> 4) & 0x3 { // Return both 0x0 => 0xC0 | (self.dulr & self.ssba), @@ -72,7 +78,7 @@ impl Joypad { 0x3 => 0xFF, _ => unreachable!(), - }; + } } _ => unreachable!(), diff --git a/src/mmu/mod.rs b/src/mmu/mod.rs index 89f7cba..a919b2a 100644 --- a/src/mmu/mod.rs +++ b/src/mmu/mod.rs @@ -117,7 +117,7 @@ impl MMU { // Interrupt 0xFF0F => { - self.ppu.vblank_irq = value & 0x1 == 0x2; + self.ppu.vblank_irq = value & 0x1 == 0x1; self.ppu.stat_irq = value & 0x2 == 0x2; self.timer.timer_irq = value & 0x4 == 0x4; self.joypad.joypad_irq = value & 0x8 == 0x8; diff --git a/src/mmu/ppu.rs b/src/mmu/ppu.rs index bae9525..5c7d142 100644 --- a/src/mmu/ppu.rs +++ b/src/mmu/ppu.rs @@ -45,6 +45,12 @@ pub struct PPU { pub stat: u8, } +impl Default for PPU { + fn default() -> Self { + Self::new() + } +} + impl PPU { pub fn new() -> PPU { PPU { @@ -127,7 +133,7 @@ impl PPU { 0x8000..=0x9FFF => self.vram[(addr - 0x8000) as usize], // Sound. - 0xFF10..=0xFF3F => return 0, + 0xFF10..=0xFF3F => 0, 0xFF40 => self.lcdc, 0xFF41 => { @@ -138,7 +144,7 @@ impl PPU { // just put it into mode 3... - return ret; + ret } 0xFF42 => self.scy, 0xFF43 => self.scx, @@ -190,7 +196,7 @@ impl PPU { 0xFF4B => self.wx = value, 0xFF4D => (), - 0xFe00..=0xFE9F => self.voam[(addr - 0xFE00) as usize] = value, + 0xFE00..=0xFE9F => self.voam[(addr - 0xFE00) as usize] = value, 0xFF7F => (), @@ -204,7 +210,7 @@ impl PPU { pub fn get_and_reset_frame_available(&mut self) -> bool { let result = self.frame_available; self.frame_available = false; - return result; + result } pub fn get_tile_pixel( @@ -215,7 +221,7 @@ impl PPU { use_8000: bool, ) -> u8 { let start_address = if self.lcdc & 0x10 > 0 || use_8000 { - 0x8000 + ((tile_index as u16) * 16) as u16 + 0x8000 + ((tile_index as u16) * 16) } else { let offset = ((tile_index as i8) as i16) * 16; 0x9000_u16.wrapping_add(offset as u16) @@ -224,14 +230,14 @@ impl PPU { let byte_a = self.get_byte(start_address + (2 * line_index)); let byte_b = self.get_byte(start_address + (2 * line_index) + 1); - let bit1 = (byte_a >> 7 - col_index) & 1; - let bit2 = (byte_b >> 7 - col_index) & 1; + let bit1 = (byte_a >> (7 - col_index)) & 1; + let bit2 = (byte_b >> (7 - col_index)) & 1; - return ((bit2 << 1) | bit1) as u8; + (bit2 << 1) | bit1 } pub fn get_object(&self, tile_index: u8) -> Tile { - let start_address = 0x8000 + ((tile_index as u16) * 16) as u16; + let start_address = 0x8000 + ((tile_index as u16) * 16); let mut ret = [[0u8; 8]; 8]; for i in 0..8 { @@ -239,10 +245,10 @@ impl PPU { let byte_b = self.get_byte(start_address + (2 * i) + 1); for j in 0..8 { - let bit1 = (byte_a >> 7 - j) & 1; - let bit2 = (byte_b >> 7 - j) & 1; + let bit1 = (byte_a >> (7 - j)) & 1; + let bit2 = (byte_b >> (7 - j)) & 1; - ret[j as usize][i as usize] = ((bit2 << 1) | bit1) as u8; + ret[j as usize][i as usize] = (bit2 << 1) | bit1; } } @@ -372,11 +378,11 @@ impl PPU { }; let window_y = (line as usize).wrapping_sub(self.wy as usize); - if window_y as usize >= SCREEN_HEIGHT { + if window_y >= SCREEN_HEIGHT { continue; }; - let tile_map_index = ((window_y / 8) as usize * 32) + (window_x / 8); + let tile_map_index = ((window_y / 8) * 32) + (window_x / 8); let tile_map_data_area = if self.lcdc & 0x40 == 0x40 { 0x9C00 } else { diff --git a/src/mmu/timer.rs b/src/mmu/timer.rs index dc70da7..379016c 100644 --- a/src/mmu/timer.rs +++ b/src/mmu/timer.rs @@ -10,6 +10,12 @@ pub struct Timer { step: u32, } +impl Default for Timer { + fn default() -> Self { + Self::new() + } +} + impl Timer { pub fn new() -> Timer { Timer { diff --git a/src/renderer.rs b/src/renderer.rs index 654d20b..d0d931d 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -6,8 +6,8 @@ use crate::mmu::ppu::{SCREEN_HEIGHT, SCREEN_WIDTH}; pub fn window_loop(rx: Receiver>, tx: Sender<(bool, Key)>, game_title: &String) { let mut window = Window::new( format!("Cowboy Emulator - {}", game_title).as_str(), - SCREEN_WIDTH as usize, - SCREEN_HEIGHT as usize, + SCREEN_WIDTH, + SCREEN_HEIGHT, WindowOptions { scale: Scale::X4, ..WindowOptions::default() @@ -18,7 +18,7 @@ pub fn window_loop(rx: Receiver>, tx: Sender<(bool, Key)>, game_title: while window.is_open() && !window.is_key_down(Key::Escape) { if let Some(frame_buffer) = most_recent_frame(&rx) { window - .update_with_buffer(&frame_buffer, SCREEN_WIDTH as usize, SCREEN_HEIGHT as usize) + .update_with_buffer(&frame_buffer, SCREEN_WIDTH, SCREEN_HEIGHT) .unwrap(); }