This commit is contained in:
Kevin Hamacher 2018-02-17 00:37:15 +01:00
parent d96f4b9ad5
commit 107b901c27
5 changed files with 54 additions and 57 deletions

View File

@ -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]),
}

View File

@ -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<u8, CPUError> {
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;

View File

@ -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<Instruction, DecodingError> {
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<u16> = 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,8 +277,7 @@ pub fn decode(data: &[u8]) -> Result<Instruction, DecodingError> {
0000_0011_1: <class 'FMULS'> <class 'FMULSU'>
0000_0011_0: <class 'FMUL'> <class 'MULSU'>
*/
match v & 0b1111_1111_0000_0000 {
0b0000_0011_0000_0000 => {
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;
@ -291,8 +290,6 @@ pub fn decode(data: &[u8]) -> Result<Instruction, DecodingError> {
_ => unreachable!(),
}
}
_ => {}
}
/*
10010110: <class 'ADIW'> '1001 0110 KKdd KKKK'
@ -309,16 +306,16 @@ pub fn decode(data: &[u8]) -> Result<Instruction, DecodingError> {
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<Instruction, DecodingError> {
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<Instruction, DecodingError> {
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 {

View File

@ -26,7 +26,7 @@ pub enum GDBPacketError {
}
impl GDBPacket {
pub fn from_packet(data: &Vec<u8>) -> Result<GDBPacket, GDBPacketError> {
pub fn from_packet(data: &[u8]) -> Result<GDBPacket, GDBPacketError> {
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<u8> {
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::<String>()));
}
@ -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::<Vec<_>>();
let word_payload = response.split(';').collect::<Vec<_>>();
Ok((
word_payload[0].to_string(),
word_payload[1..].join(";").to_string(),
@ -202,7 +202,7 @@ impl<'a> GDBStub<'a> {
let response: Cow<str>;
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::<Vec<_>>();
let parts = payload.split(',').collect::<Vec<_>>();
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::<Vec<_>>();
let parts = addrlen_content[0].split(",").collect::<Vec<_>>();
let addrlen_content = payload.split(':').collect::<Vec<_>>();
let parts = addrlen_content[0].split(',').collect::<Vec<_>>();
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::<Vec<_>>();
let values = payload.split(',').collect::<Vec<_>>();
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;

View File

@ -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<P: AsRef<Path>>(rom_path: P) -> Result<Box<[u8]>, io::Error> {
pub fn write_file<P: AsRef<Path>>(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(())
}