diff --git a/src/chip.rs b/src/chip.rs index 72f7ef7..342cd99 100644 --- a/src/chip.rs +++ b/src/chip.rs @@ -14,7 +14,7 @@ impl Chip { pub fn new(log: slog::Logger, rom: Box<[u8]>) -> Chip { Self { log: log.clone(), - cpu: CPU::new(log.clone()), + cpu: CPU::new(log), rom: rom, ram: Box::new([0u8; 0x4000]), } diff --git a/src/cpu.rs b/src/cpu.rs index f81d386..02feeec 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -74,8 +74,8 @@ impl CPU { } pub fn get_sp(&self, mem: &[u8]) -> u16 { - mem[chip_definitions::IOAdress::SPL as usize] as u16 - | ((mem[chip_definitions::IOAdress::SPH as usize] as u16) << 8) + u16::from(mem[chip_definitions::IOAdress::SPL as usize]) + | (u16::from(mem[chip_definitions::IOAdress::SPH as usize]) << 8) } fn set_sp(&self, mem: &mut [u8], val: u16) { @@ -105,7 +105,7 @@ impl CPU { } fn get_register_pair(&self, r: &GeneralPurposeRegisterPair) -> u16 { - ((self.registers[r.high()] as u16) << 8) | self.registers[r.low()] as u16 + (u16::from(self.registers[r.high()]) << 8) | u16::from(self.registers[r.low()]) } fn set_register_pair(&mut self, r: &GeneralPurposeRegisterPair, v: u16) { @@ -268,14 +268,14 @@ impl CPU { } fn push(&mut self, ram: &mut [u8], val: u8) -> Result<(), CPUError> { - let sp = self.get_sp(&ram); + let sp = self.get_sp(ram); self.ram_write(ram, sp, val)?; self.set_sp(ram, sp.wrapping_sub(1)); Ok(()) } fn pop(&mut self, ram: &mut [u8]) -> Result { - let sp = self.get_sp(&ram); + let sp = self.get_sp(ram); self.set_sp(ram, sp.wrapping_add(1)); self.ram_read(ram, sp.wrapping_add(1)) } @@ -402,7 +402,7 @@ impl CPU { Instruction::SER(ref r) => self.set_register(r, 0xFF), Instruction::RJMP(v) => { self.pc = self.pc.wrapping_add(v as _); - if v == -1 && self.test_flag(StatusFlag::GlobalInterruptEnable) == false { + if v == -1 && !self.test_flag(StatusFlag::GlobalInterruptEnable) { info!(self.logger, "HALTED "); return Err(CPUError::Exit); } @@ -447,7 +447,7 @@ impl CPU { self.set_register_pair(ptr, base.wrapping_add(1)); base } - IncrementMode::ConstantOffset(o) => base.wrapping_add(o as _), + IncrementMode::ConstantOffset(o) => base.wrapping_add(u16::from(o)), }; self.ram_write(ram, addr, self.get_register(src_reg))?; } @@ -470,7 +470,7 @@ impl CPU { self.set_register_pair(ptr, base.wrapping_add(1)); base } - IncrementMode::ConstantOffset(o) => base.wrapping_add(o as _), + IncrementMode::ConstantOffset(o) => base.wrapping_add(u16::from(o)), }; let v = self.ram_read(ram, addr)?; self.set_register(dst_reg, v); @@ -537,12 +537,12 @@ impl CPU { self.push(ram, ((ret_to >> 16) & 0xFF) as u8)?; self.push(ram, ((ret_to >> 8) & 0xFF) as u8)?; self.push(ram, (ret_to & 0xFF) as u8)?; - self.pc = (self.pc as i32 + *addr as i32) as u32; + self.pc = ((self.pc as i32) + i32::from(*addr)) as u32; } Instruction::RET => { - let mut ret_to = self.pop(ram)? as u32; - ret_to += (self.pop(ram)? as u32) << 8; - ret_to += (self.pop(ram)? as u32) << 16; + let mut ret_to = u32::from(self.pop(ram)?); + ret_to += u32::from(self.pop(ram)?) << 8; + ret_to += u32::from(self.pop(ram)?) << 16; self.pc = ret_to as _; } Instruction::POP(ref reg) => { @@ -675,17 +675,17 @@ impl CPU { self.update_flags_zns_8(res); } Instruction::STS16(ref addr, ref r) => { - let rampd = ram[chip_definitions::IOAdress::RAMPD as usize] as u32; + let rampd = u32::from(ram[chip_definitions::IOAdress::RAMPD as usize]); if rampd != 0 { panic!("This is unexpected (for now)"); } self.ram_write(ram, *addr, self.get_register(r))?; } Instruction::STS8(ref addr, ref r) => { - self.ram_write(ram, *addr as u16, self.get_register(r))?; + self.ram_write(ram, u16::from(*addr), self.get_register(r))?; } Instruction::LDS16(ref r, ref addr) => { - let rampd = ram[chip_definitions::IOAdress::RAMPD as usize] as u32; + let rampd = u32::from(ram[chip_definitions::IOAdress::RAMPD as usize]); if rampd != 0 { panic!("This is unexpected (for now)"); } @@ -693,7 +693,7 @@ impl CPU { self.set_register(r, v); } Instruction::LDS8(ref r, ref addr) => { - let v = self.ram_read(ram, *addr as u16)?; + let v = self.ram_read(ram, u16::from(*addr))?; self.set_register(r, v); } Instruction::LSL(ref r) => { @@ -772,8 +772,8 @@ impl CPU { } Instruction::MUL(ref r, ref d) => { // R1:R0 ← Rd × Rr(unsigned ← unsigned × unsigned) - let r = self.get_register(r) as u16; - let d = self.get_register(d) as u16; + let r = u16::from(self.get_register(r)); + let d = u16::from(self.get_register(d)); let v = r * d; self.registers[0] = (v & 0xFF) as u8; self.registers[1] = ((v >> 8) & 0xFF) as u8; diff --git a/src/decoder.rs b/src/decoder.rs index d4dded0..ec958c0 100644 --- a/src/decoder.rs +++ b/src/decoder.rs @@ -206,7 +206,7 @@ impl Instruction { // LDS32 STS32 pub fn size(&self) -> usize { match *self { - Instruction::JMP(_) | Instruction::CALL(_) => 4, + Instruction::JMP(_) | Instruction::CALL(_) | Instruction::STS16(_, _) | Instruction::LDS16(_, _) => 4, _ => 2, } @@ -223,11 +223,11 @@ pub fn decode(data: &[u8]) -> Result { return Err(DecodingError::TruncatedInstruction); } // Try to match 2b instructions without any parameters first. - let v: u16 = ((data[1] as u16) << 8) | (data[0] as u16); + let v: u16 = (u16::from(data[1]) << 8) | u16::from(data[0]); // Load second u16 as well if possible let v2: Option = if data.len() >= 4 { - Some(((data[3] as u16) << 8) | (data[2] as u16)) + Some((u16::from(data[3]) << 8) | u16::from(data[2])) } else { None }; @@ -277,21 +277,18 @@ pub fn decode(data: &[u8]) -> Result { 0000_0011_1: 0000_0011_0: */ - match v & 0b1111_1111_0000_0000 { - 0b0000_0011_0000_0000 => { - // FMUL/FMULS/FMULSU/MULSU - let d = ((v & 0b0111_0000) >> 4) as u8; - let r = ((v & 0b0111)) as u8; - let mode = v & 0b1000_1000; - match mode { - 0b0000_0000 => return Ok(Instruction::MULSU((d + 16).into(), (r + 16).into())), - 0b0000_1000 => return Ok(Instruction::FMUL((d + 16).into(), (r + 16).into())), - 0b1000_0000 => return Ok(Instruction::FMULS((d + 16).into(), (r + 16).into())), - 0b1000_1000 => return Ok(Instruction::FMULSU((d + 16).into(), (r + 16).into())), - _ => unreachable!(), - } + if v & 0b1111_1111_0000_0000 == 0b0000_0011_0000_0000 { + // FMUL/FMULS/FMULSU/MULSU + let d = ((v & 0b0111_0000) >> 4) as u8; + let r = ((v & 0b0111)) as u8; + let mode = v & 0b1000_1000; + match mode { + 0b0000_0000 => return Ok(Instruction::MULSU((d + 16).into(), (r + 16).into())), + 0b0000_1000 => return Ok(Instruction::FMUL((d + 16).into(), (r + 16).into())), + 0b1000_0000 => return Ok(Instruction::FMULS((d + 16).into(), (r + 16).into())), + 0b1000_1000 => return Ok(Instruction::FMULSU((d + 16).into(), (r + 16).into())), + _ => unreachable!(), } - _ => {} } /* @@ -309,16 +306,16 @@ pub fn decode(data: &[u8]) -> Result { let K = (((v & 0b1100_0000) >> 2) | (v & 0b1111)) as u8; let d = ((v & 0b1111_0000) >> 4) as u8; let r = (v & 0b1111) as u8; - let A = ((v & 0b1111_1000) >> 3) as u16; + let A = u16::from((v & 0b1111_1000) >> 3); let b = (v & 0b0111) as u8; match v & 0b1111_1111_0000_0000 { 0b1001_0110_0000_0000 => { - return Ok(Instruction::ADIW(((d & 0b11) * 2 + 24).into(), K as u16)) + return Ok(Instruction::ADIW(((d & 0b11) * 2 + 24).into(), u16::from(K))) } 0b0000_0001_0000_0000 => return Ok(Instruction::MOVW((d * 2).into(), (r * 2).into())), 0b0000_0010_0000_0000 => return Ok(Instruction::MULS((d + 16).into(), (r + 16).into())), 0b1001_0111_0000_0000 => { - return Ok(Instruction::SBIW(((d & 0b11) * 2 + 24).into(), K as u16)) + return Ok(Instruction::SBIW(((d & 0b11) * 2 + 24).into(), u16::from(K))) } 0b1110_1111_0000_0000 => if r == 0b1111 { return Ok(Instruction::SER((d + 16).into())); @@ -491,7 +488,7 @@ pub fn decode(data: &[u8]) -> Result { let d = (((v >> 4) & 0b1_1111) as u8).into(); let b = (v & 0b111) as u8; if (v & 0b1000) == 0 { - if ((v >> 9) & 1) == 9 { + if ((v >> 9) & 1) == 1 { return Ok(Instruction::BLD(d, b)); } else { return Ok(Instruction::BST(d, b)); @@ -528,7 +525,7 @@ pub fn decode(data: &[u8]) -> Result { match v2 { None => return Err(DecodingError::TruncatedInstruction), Some(kl) => { - let k = (((v & 0b1111_0000) as u32) << 12) | (kl as u32); + let k = (u32::from(v & 0b1111_0000) << 12) | (u32::from(kl)); if v & 0b10 == 0 { return Ok(Instruction::JMP(k)); } else { diff --git a/src/gdbstub.rs b/src/gdbstub.rs index baf11f4..b077887 100644 --- a/src/gdbstub.rs +++ b/src/gdbstub.rs @@ -26,7 +26,7 @@ pub enum GDBPacketError { } impl GDBPacket { - pub fn from_packet(data: &Vec) -> Result { + pub fn from_packet(data: &[u8]) -> Result { let mut is_escaped = false; let mut in_checksum = false; let mut decoded_data = Vec::new(); @@ -77,7 +77,7 @@ impl GDBPacket { fn escaped_data(&self) -> Vec { let mut r = Vec::new(); - for e in self.raw_data.iter() { + for e in &self.raw_data { match *e { b'$' | b'#' | b'}' | b'*' => { r.push(b'}'); @@ -101,8 +101,8 @@ impl GDBPacket { fn split_definitions(pkg: &str) -> Vec<(String, String)> { let mut res = Vec::new(); - for definition in pkg.split(";") { - let mut v = definition.split(":"); + for definition in pkg.split(';') { + let mut v = definition.split(':'); let first = v.nth(0).unwrap().to_string(); res.push((first, v.collect::())); } @@ -139,7 +139,7 @@ impl<'a> GDBStub<'a> { panic!("Connection closed?") } // Wait for beginning of pkg. - if buf.len() == 0 && s[0] != b'$' { + if buf.is_empty() && s[0] != b'$' { continue; } buf.push(s[0]); @@ -169,7 +169,7 @@ impl<'a> GDBStub<'a> { // Split it into command and values. if response.chars().nth(0).ok_or(())? == 'v' { // Multibyte word, up to the first ; (or others?). - let word_payload = response.split(";").collect::>(); + let word_payload = response.split(';').collect::>(); Ok(( word_payload[0].to_string(), word_payload[1..].join(";").to_string(), @@ -202,7 +202,7 @@ impl<'a> GDBStub<'a> { let response: Cow; info!(self.log, "<- {} {}", cmd, payload); // Send ACK. - conn.write_all(&"+".as_bytes()).unwrap(); + conn.write_all(b"+").unwrap(); match &*cmd { "q" => { let query_data = split_definitions(&payload); @@ -282,7 +282,7 @@ impl<'a> GDBStub<'a> { } "m" => { // Read memory. - let parts = payload.split(",").collect::>(); + let parts = payload.split(',').collect::>(); let mem_addr = usize::from_str_radix(parts[0], 16).unwrap_or(0); let len = usize::from_str_radix(parts[1], 16).unwrap_or(0); let mut data = Vec::new(); @@ -294,7 +294,7 @@ impl<'a> GDBStub<'a> { let addr_i = addr & 0xFFFFF; if addr_i >= self.chip.ram.len() { // Partial read case. - if data.len() == 0 { + if data.is_empty() { err = true; } break; @@ -304,7 +304,7 @@ impl<'a> GDBStub<'a> { // ROM if addr >= self.chip.rom.len() { // Partial read case. - if data.len() == 0 { + if data.is_empty() { err = true; } break; @@ -320,8 +320,8 @@ impl<'a> GDBStub<'a> { } "M" => { // Write memory. - let addrlen_content = payload.split(":").collect::>(); - let parts = addrlen_content[0].split(",").collect::>(); + let addrlen_content = payload.split(':').collect::>(); + let parts = addrlen_content[0].split(',').collect::>(); let value = addrlen_content[1]; let mem_addr = usize::from_str_radix(parts[0], 16).unwrap(); let len = usize::from_str_radix(parts[1], 16).unwrap(); @@ -355,9 +355,9 @@ impl<'a> GDBStub<'a> { } "z" | "Z" => { // insert(Z)/remove(z) breakpoint. - let values = payload.split(",").collect::>(); + let values = payload.split(',').collect::>(); let bp_type = values[0]; - let bp_addr = u32::from_str_radix(&values[1], 16).unwrap(); + let bp_addr = u32::from_str_radix(values[1], 16).unwrap(); let _bp_length = values[2]; if bp_type == "0" || bp_type == "1" && bp_addr & 1 == 0 { let cpu_addr = bp_addr >> 1; diff --git a/src/main.rs b/src/main.rs index 7bc4e06..c9f9536 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,7 +29,7 @@ fn main() { ); info!(log, "AVREmu starting up"); - let rom = read_file(std::env::args().nth(1).unwrap_or("rom.bin".to_string())).unwrap(); + let rom = read_file(std::env::args().nth(1).unwrap_or_else(|| "rom.bin".to_string())).unwrap(); let mut chip = chip::Chip::new(log.clone(), rom); @@ -49,6 +49,6 @@ pub fn read_file>(rom_path: P) -> Result, io::Error> { pub fn write_file>(path: P, data: &[u8]) -> Result<(), io::Error> { let mut file = try!(fs::File::create(path)); - try!(file.write_all(&data)); + try!(file.write_all(data)); Ok(()) }