diff --git a/src/arm7tdmi/arm/exec.rs b/src/arm7tdmi/arm/exec.rs index 811ebf2..2100654 100644 --- a/src/arm7tdmi/arm/exec.rs +++ b/src/arm7tdmi/arm/exec.rs @@ -1,6 +1,6 @@ use crate::bit::BitIndex; -use crate::arm7tdmi::bus::{Bus, MemoryAccessType::*, MemoryAccessWidth::*}; +use crate::arm7tdmi::bus::Bus; use crate::arm7tdmi::cpu::{Core, CpuExecResult, CpuPipelineAction}; use crate::arm7tdmi::exception::Exception; use crate::arm7tdmi::psr::RegPSR; @@ -31,7 +31,7 @@ impl Core { } /// Cycles 2S+1N - fn exec_b_bl(&mut self, bus: &mut Bus, insn: ArmInstruction) -> CpuResult { + fn exec_b_bl(&mut self, _bus: &mut Bus, insn: ArmInstruction) -> CpuResult { if insn.link_flag() { self.set_reg(14, (insn.pc + (self.word_size() as u32)) & !0b1); } @@ -42,7 +42,7 @@ impl Core { } /// Cycles 2S+1N - fn exec_bx(&mut self, bus: &mut Bus, insn: ArmInstruction) -> CpuResult { + fn exec_bx(&mut self, _bus: &mut Bus, insn: ArmInstruction) -> CpuResult { let rn = self.get_reg(insn.rn()); if rn.bit(0) { self.cpsr.set_state(CpuState::THUMB); @@ -62,7 +62,7 @@ impl Core { fn exec_msr_reg( &mut self, - bus: &mut Bus, + _bus: &mut Bus, insn: ArmInstruction, ) -> CpuResult { let new_psr = RegPSR::new(self.get_reg(insn.rm())); @@ -119,6 +119,7 @@ impl Core { res } + #[allow(non_snake_case)] pub fn alu( &mut self, opcode: ArmOpCode, @@ -129,7 +130,7 @@ impl Core { let C = self.cpsr.C() as i32; let mut carry = self.cpsr.C(); - let mut overflow = self.cpsr.V(); + let overflow = self.cpsr.V(); let result = match opcode { ArmOpCode::AND | ArmOpCode::TST => op1 & op2, @@ -165,7 +166,7 @@ impl Core { /// Add x=1I cycles if Op2 shifted-by-register. Add y=1S+1N cycles if Rd=R15. fn exec_data_processing( &mut self, - bus: &mut Bus, + _bus: &mut Bus, insn: ArmInstruction, ) -> CpuResult { // TODO handle carry flag @@ -251,7 +252,6 @@ impl Core { if insn.rn() == REG_PC { addr = insn.pc + 8; // prefetching } - let dest = self.get_reg(insn.rd()); let offset = self.get_rn_offset(&insn); diff --git a/src/arm7tdmi/mod.rs b/src/arm7tdmi/mod.rs index 9ffc6ea..99f3ac8 100644 --- a/src/arm7tdmi/mod.rs +++ b/src/arm7tdmi/mod.rs @@ -198,12 +198,6 @@ impl fmt::Display for CpuError { pub type CpuResult = Result; -pub struct CpuModeContext { - // r8-r14 - banked_gpr: [u32; 7], - spsr: u32, -} - #[cfg(test)] mod tests { #[test] diff --git a/src/arm7tdmi/thumb/display.rs b/src/arm7tdmi/thumb/display.rs index 5b08f54..f0f25f8 100644 --- a/src/arm7tdmi/thumb/display.rs +++ b/src/arm7tdmi/thumb/display.rs @@ -3,7 +3,7 @@ use std::fmt; use crate::bit::BitIndex; use super::*; -use crate::arm7tdmi::reg_string; +use crate::arm7tdmi::*; impl ThumbInstruction { fn fmt_thumb_move_shifted_reg(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -158,6 +158,17 @@ impl ThumbInstruction { } ) } + + fn fmt_thumb_branch_long_with_link(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "bl\t#0x{:08x}", { + let offset11 = self.offset11(); + if self.flag(ThumbInstruction::FLAG_LOW_OFFSET) { + (offset11 << 1) as i32 + } else { + ((offset11 << 21) >> 9) as i32 + } + }) + } } impl fmt::Display for ThumbInstruction { @@ -175,6 +186,7 @@ impl fmt::Display for ThumbInstruction { ThumbFormat::AddSp => self.fmt_thumb_add_sp(f), ThumbFormat::PushPop => self.fmt_thumb_push_pop(f), ThumbFormat::BranchConditional => self.fmt_thumb_branch_with_cond(f), + ThumbFormat::BranchLongWithLink => self.fmt_thumb_branch_long_with_link(f), _ => write!(f, "({:?})", self), } } diff --git a/src/arm7tdmi/thumb/exec.rs b/src/arm7tdmi/thumb/exec.rs index cfc0558..7d950af 100644 --- a/src/arm7tdmi/thumb/exec.rs +++ b/src/arm7tdmi/thumb/exec.rs @@ -1,7 +1,7 @@ use crate::arm7tdmi::arm::*; -use crate::arm7tdmi::bus::{Bus, MemoryAccessType::*, MemoryAccessWidth::*}; +use crate::arm7tdmi::bus::Bus; use crate::arm7tdmi::cpu::{Core, CpuExecResult, CpuPipelineAction}; -use crate::arm7tdmi::{reg_string, Addr, CpuState, REG_LR, REG_PC, REG_SP}; +use crate::arm7tdmi::*; use super::*; fn push(cpu: &mut Core, bus: &mut Bus, r: usize) { @@ -19,7 +19,7 @@ fn pop(cpu: &mut Core, bus: &mut Bus, r: usize) { impl Core { fn exec_thumb_move_shifted_reg( &mut self, - bus: &mut Bus, + _bus: &mut Bus, insn: ThumbInstruction, ) -> CpuExecResult { let result = self @@ -33,7 +33,7 @@ impl Core { Ok(CpuPipelineAction::IncPC) } - fn exec_thumb_add_sub(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { + fn exec_thumb_add_sub(&mut self, _bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { let op1 = self.get_reg(insn.rs()) as i32; let op2 = if insn.is_immediate_operand() { insn.rn() as u32 as i32 @@ -56,7 +56,7 @@ impl Core { fn exec_thumb_data_process_imm( &mut self, - bus: &mut Bus, + _bus: &mut Bus, insn: ThumbInstruction, ) -> CpuExecResult { let arm_alu_op: ArmOpCode = insn.format3_op().into(); @@ -70,18 +70,18 @@ impl Core { Ok(CpuPipelineAction::IncPC) } - fn exec_thumb_mul(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { + fn exec_thumb_mul(&mut self, _bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { let op1 = self.get_reg(insn.rd()) as i32; let op2 = self.get_reg(insn.rs()) as i32; let m = self.get_required_multipiler_array_cycles(op2); - for i in 0..m { + for _ in 0..m { self.add_cycle(); } self.gpr[insn.rd()] = (op1 * op2) as u32; Ok(CpuPipelineAction::IncPC) } - fn exec_thumb_alu_ops(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { + fn exec_thumb_alu_ops(&mut self, _bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { let arm_alu_op: ArmOpCode = insn.alu_opcode(); let op1 = self.get_reg(insn.rd()) as i32; let op2 = self.get_reg(insn.rs()) as i32; @@ -94,7 +94,7 @@ impl Core { } /// Cycles 2S+1N - fn exec_thumb_bx(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { + fn exec_thumb_bx(&mut self, _bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { let src_reg = if insn.flag(ThumbInstruction::FLAG_H2) { insn.rs() + 8 } else { @@ -180,7 +180,7 @@ impl Core { Ok(CpuPipelineAction::IncPC) } - fn exec_thumb_add_sp(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { + fn exec_thumb_add_sp(&mut self, _bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { let op1 = self.gpr[REG_SP] as i32; let op2 = insn.sword7(); let arm_alu_op = ArmOpCode::ADD; @@ -230,12 +230,33 @@ impl Core { if !self.check_arm_cond(insn.cond()) { Ok(CpuPipelineAction::IncPC) } else { - let offset = insn.offset8() as u8 as i32; + let offset = insn.offset8() as i8 as i32; self.pc = (insn.pc as i32).wrapping_add(offset) as u32; Ok(CpuPipelineAction::Flush) } } + fn exec_thumb_branch_long_with_link( + &mut self, + _bus: &mut Bus, + insn: ThumbInstruction, + ) -> CpuExecResult { + let mut off = insn.offset11(); + if insn.flag(ThumbInstruction::FLAG_LOW_OFFSET) { + off = off << 1; + let next_pc = (self.pc - 2) | 1; + self.pc = (self.gpr[REG_LR] as i32).wrapping_add(off) as u32; + self.gpr[REG_LR] = next_pc; + + Ok(CpuPipelineAction::Flush) + } else { + off = (off << 21) >> 9; + self.gpr[REG_LR] = (self.pc as i32).wrapping_add(off) as u32; + + Ok(CpuPipelineAction::IncPC) + } + } + pub fn exec_thumb(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { match insn.fmt { ThumbFormat::MoveShiftedReg => self.exec_thumb_move_shifted_reg(bus, insn), @@ -250,6 +271,7 @@ impl Core { ThumbFormat::AddSp => self.exec_thumb_add_sp(bus, insn), ThumbFormat::PushPop => self.exec_thumb_push_pop(bus, insn), ThumbFormat::BranchConditional => self.exec_thumb_branch_with_cond(bus, insn), + ThumbFormat::BranchLongWithLink => self.exec_thumb_branch_long_with_link(bus, insn), _ => unimplemented!("thumb not implemented {:#x?}", insn), } } diff --git a/src/arm7tdmi/thumb/mod.rs b/src/arm7tdmi/thumb/mod.rs index 8f96df9..1355b38 100644 --- a/src/arm7tdmi/thumb/mod.rs +++ b/src/arm7tdmi/thumb/mod.rs @@ -198,6 +198,7 @@ impl ThumbInstruction { const FLAG_H2: usize = 6; const FLAG_R: usize = 8; const FLAG_S: usize = 7; + const FLAG_LOW_OFFSET: usize = 11; pub fn rd(&self) -> usize { match self.fmt { @@ -252,6 +253,10 @@ impl ThumbInstruction { self.raw.bit_range(0..8) as i8 } + pub fn offset11(&self) -> i32 { + (self.raw & 0x7FF) as i32 + } + pub fn word8(&self) -> u16 { self.raw.bit_range(0..8) << 2 } diff --git a/src/cartridge.rs b/src/cartridge.rs index 65c5e27..5b16c60 100644 --- a/src/cartridge.rs +++ b/src/cartridge.rs @@ -1,9 +1,7 @@ use std::str::from_utf8; -use nom::number::streaming::le_u32; - use crate::arm7tdmi::{ - bus::{Bus, MemoryAccess, MemoryAccessType, MemoryAccessWidth}, + bus::{Bus, MemoryAccess, MemoryAccessWidth}, Addr, }; use crate::sysbus::WaitState; diff --git a/src/debugger/parser.rs b/src/debugger/parser.rs index 0ef87e1..f992135 100644 --- a/src/debugger/parser.rs +++ b/src/debugger/parser.rs @@ -1,7 +1,3 @@ -use std::fmt; - -use crate::arm7tdmi::Addr; - use nom; use nom::branch::alt; use nom::bytes::complete::{tag, take_while1, take_while_m_n}; diff --git a/src/disass.rs b/src/disass.rs index 70e799d..eef3477 100644 --- a/src/disass.rs +++ b/src/disass.rs @@ -1,8 +1,6 @@ -use std::convert::TryFrom; use std::marker::PhantomData; use super::arm7tdmi::{Addr, InstructionDecoder, InstructionDecoderError}; -use std::io; use std::io::ErrorKind; pub struct Disassembler<'a, D> diff --git a/src/sysbus.rs b/src/sysbus.rs index b257370..dfbef43 100644 --- a/src/sysbus.rs +++ b/src/sysbus.rs @@ -69,38 +69,38 @@ impl Bus for BoxedMemory { struct DummyBus([u8; 4]); impl Bus for DummyBus { - fn read_32(&self, addr: Addr) -> u32 { + fn read_32(&self, _addr: Addr) -> u32 { 0 } - fn read_16(&self, addr: Addr) -> u16 { + fn read_16(&self, _addr: Addr) -> u16 { 0 } - fn read_8(&self, addr: Addr) -> u8 { + fn read_8(&self, _addr: Addr) -> u8 { 0 } - fn write_32(&mut self, addr: Addr, value: u32) -> Result<(), io::Error> { + fn write_32(&mut self, _addr: Addr, _value: u32) -> Result<(), io::Error> { Ok(()) } - fn write_16(&mut self, addr: Addr, value: u16) -> Result<(), io::Error> { + fn write_16(&mut self, _addr: Addr, _value: u16) -> Result<(), io::Error> { Ok(()) } - fn write_8(&mut self, addr: Addr, value: u8) -> Result<(), io::Error> { + fn write_8(&mut self, _addr: Addr, _value: u8) -> Result<(), io::Error> { Ok(()) } - fn get_bytes(&self, addr: Addr) -> &[u8] { + fn get_bytes(&self, _addr: Addr) -> &[u8] { &self.0 } - fn get_bytes_mut(&mut self, addr: Addr) -> &mut [u8] { + fn get_bytes_mut(&mut self, _addr: Addr) -> &mut [u8] { &mut self.0 } - fn get_cycles(&self, addr: Addr, access: MemoryAccess) -> usize { + fn get_cycles(&self, _addr: Addr, _access: MemoryAccess) -> usize { 1 } }