diff --git a/src/cpus/m68k/debugger.rs b/src/cpus/m68k/debugger.rs index 2be25c8..f0d1e05 100644 --- a/src/cpus/m68k/debugger.rs +++ b/src/cpus/m68k/debugger.rs @@ -68,7 +68,7 @@ impl Debuggable for M68k { decoder.dump_disassembly(&mut self.port, addr as u32, count as u32); } - fn execute_command(&mut self, system: &System, args: &[&str]) -> Result { + fn execute_command(&mut self, _system: &System, args: &[&str]) -> Result { match args[0] { "ds" | "stack" | "dumpstack" => { println!("Stack:"); diff --git a/src/cpus/m68k/decode.rs b/src/cpus/m68k/decode.rs index b0aef4f..4480203 100644 --- a/src/cpus/m68k/decode.rs +++ b/src/cpus/m68k/decode.rs @@ -1,6 +1,5 @@ use crate::error::Error; -use crate::system::System; use crate::devices::{Address, Addressable}; use super::state::{M68kType, Exceptions}; diff --git a/src/cpus/m68k/execute.rs b/src/cpus/m68k/execute.rs index 246c032..0ab3002 100644 --- a/src/cpus/m68k/execute.rs +++ b/src/cpus/m68k/execute.rs @@ -62,7 +62,7 @@ impl M68k { pub fn step_internal(&mut self, system: &System) -> Result<(), Error> { match self.state.status { - Status::Init => self.init(system), + Status::Init => self.init(), Status::Stopped => Err(Error::new("CPU stopped")), Status::Running => { match self.cycle_one(system) { @@ -70,7 +70,7 @@ impl M68k { //Err(Error { err: ErrorType::Processor, native, .. }) => { // TODO match arm conditional is temporary: illegal instructions generate a top level error in order to debug and fix issues with decode Err(Error { err: ErrorType::Processor, native, .. }) if native != Exceptions::IllegalInstruction as u32 => { - self.exception(system, native as u8, false)?; + self.exception(native as u8, false)?; Ok(()) }, Err(err) => Err(err), @@ -79,7 +79,7 @@ impl M68k { } } - pub fn init(&mut self, system: &System) -> Result<(), Error> { + pub fn init(&mut self) -> Result<(), Error> { self.state.msp = self.port.read_beu32(0)?; self.state.pc = self.port.read_beu32(4)?; self.state.status = Status::Running; @@ -88,8 +88,8 @@ impl M68k { pub fn cycle_one(&mut self, system: &System) -> Result<(), Error> { self.timer.cycle.start(); - self.decode_next(system)?; - self.execute_current(system)?; + self.decode_next()?; + self.execute_current()?; self.timer.cycle.end(); //if (self.timer.cycle.events % 500) == 0 { @@ -117,7 +117,7 @@ impl M68k { debug!("{} interrupt: {} {}", DEV_NAME, pending_ipl, priority_mask); self.state.current_ipl = self.state.pending_ipl; let ack_num = system.get_interrupt_controller().acknowledge(self.state.current_ipl as u8)?; - self.exception(system, ack_num, true)?; + self.exception(ack_num, true)?; return Ok(()); } } @@ -129,14 +129,14 @@ impl M68k { Ok(()) } - pub fn exception(&mut self, system: &System, number: u8, is_interrupt: bool) -> Result<(), Error> { + pub fn exception(&mut self, number: u8, is_interrupt: bool) -> Result<(), Error> { debug!("{}: raising exception {}", DEV_NAME, number); let offset = (number as u16) << 2; if self.cputype >= M68kType::MC68010 { - self.push_word(system, offset)?; + self.push_word(offset)?; } - self.push_long(system, self.state.pc)?; - self.push_word(system, self.state.sr)?; + self.push_long(self.state.pc)?; + self.push_word(self.state.sr)?; // Changes to the flags must happen after the previous value has been pushed to the stack self.set_flag(Flags::Supervisor, true); @@ -150,7 +150,7 @@ impl M68k { Ok(()) } - pub fn decode_next(&mut self, system: &System) -> Result<(), Error> { + pub fn decode_next(&mut self) -> Result<(), Error> { self.timer.decode.start(); self.decoder.decode_at(&mut self.port, self.state.pc)?; self.timer.decode.end(); @@ -164,22 +164,22 @@ impl M68k { Ok(()) } - pub fn execute_current(&mut self, system: &System) -> Result<(), Error> { + pub fn execute_current(&mut self) -> Result<(), Error> { self.timer.execute.start(); match self.decoder.instruction { //Instruction::ABCD(Target) => { //}, Instruction::ADD(src, dest, size) => { - let value = self.get_target_value(system, src, size)?; - let existing = self.get_target_value(system, dest, size)?; + let value = self.get_target_value(src, size)?; + let existing = self.get_target_value(dest, size)?; let (result, carry) = overflowing_add_sized(existing, value, size); let overflow = get_add_overflow(existing, value, result, size); self.set_compare_flags(result, size, carry, overflow); self.set_flag(Flags::Extend, carry); - self.set_target_value(system, dest, result, size)?; + self.set_target_value(dest, result, size)?; }, Instruction::ADDA(src, dest, size) => { - let value = sign_extend_to_long(self.get_target_value(system, src, size)?, size) as u32; + let value = sign_extend_to_long(self.get_target_value(src, size)?, size) as u32; let existing = *self.get_a_reg_mut(dest); let (result, _) = overflowing_add_sized(existing, value, Size::Long); *self.get_a_reg_mut(dest) = result; @@ -187,10 +187,10 @@ impl M68k { //Instruction::ADDX(Target) => { //}, Instruction::AND(src, dest, size) => { - let value = self.get_target_value(system, src, size)?; - let existing = self.get_target_value(system, dest, size)?; + let value = self.get_target_value(src, size)?; + let existing = self.get_target_value(dest, size)?; let result = get_value_sized(existing & value, size); - self.set_target_value(system, dest, result, size)?; + self.set_target_value(dest, result, size)?; self.set_logic_flags(result, size); }, Instruction::ANDtoCCR(value) => { @@ -201,8 +201,8 @@ impl M68k { self.state.sr = self.state.sr & value; }, Instruction::ASd(count, target, size, shift_dir) => { - let count = self.get_target_value(system, count, size)? % 64; - let mut pair = (self.get_target_value(system, target, size)?, false); + let count = self.get_target_value(count, size)? % 64; + let mut pair = (self.get_target_value(target, size)?, false); let original = pair.0; for _ in 0..count { pair = shift_operation(pair.0, size, shift_dir, true); @@ -215,7 +215,7 @@ impl M68k { if get_msb(pair.0, size) != get_msb(original, size) { self.set_flag(Flags::Overflow, true); } - self.set_target_value(system, target, pair.0, size)?; + self.set_target_value(target, pair.0, size)?; }, Instruction::Bcc(cond, offset) => { let should_branch = self.get_current_condition(cond); @@ -227,57 +227,57 @@ impl M68k { self.state.pc = (self.decoder.start + 2).wrapping_add(offset as u32); }, Instruction::BSR(offset) => { - self.push_long(system, self.state.pc)?; + self.push_long(self.state.pc)?; let sp = *self.get_stack_pointer_mut(); self.debugger.stack_tracer.push_return(sp); self.state.pc = (self.decoder.start + 2).wrapping_add(offset as u32); }, Instruction::BCHG(bitnum, target, size) => { - let bitnum = self.get_target_value(system, bitnum, Size::Byte)?; - let mut value = self.get_target_value(system, target, size)?; + let bitnum = self.get_target_value(bitnum, Size::Byte)?; + let mut value = self.get_target_value(target, size)?; let mask = self.set_bit_test_flags(value, bitnum, size); value = (value & !mask) | (!(value & mask) & mask); - self.set_target_value(system, target, value, size)?; + self.set_target_value(target, value, size)?; }, Instruction::BCLR(bitnum, target, size) => { - let bitnum = self.get_target_value(system, bitnum, Size::Byte)?; - let mut value = self.get_target_value(system, target, size)?; + let bitnum = self.get_target_value(bitnum, Size::Byte)?; + let mut value = self.get_target_value(target, size)?; let mask = self.set_bit_test_flags(value, bitnum, size); value = value & !mask; - self.set_target_value(system, target, value, size)?; + self.set_target_value(target, value, size)?; }, Instruction::BSET(bitnum, target, size) => { - let bitnum = self.get_target_value(system, bitnum, Size::Byte)?; - let mut value = self.get_target_value(system, target, size)?; + let bitnum = self.get_target_value(bitnum, Size::Byte)?; + let mut value = self.get_target_value(target, size)?; let mask = self.set_bit_test_flags(value, bitnum, size); value = value | mask; - self.set_target_value(system, target, value, size)?; + self.set_target_value(target, value, size)?; }, Instruction::BTST(bitnum, target, size) => { - let bitnum = self.get_target_value(system, bitnum, Size::Byte)?; - let value = self.get_target_value(system, target, size)?; + let bitnum = self.get_target_value(bitnum, Size::Byte)?; + let value = self.get_target_value(target, size)?; self.set_bit_test_flags(value, bitnum, size); }, Instruction::BFCHG(target, offset, width) => { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); - let value = self.get_target_value(system, target, Size::Long)?; + let value = self.get_target_value(target, Size::Long)?; let field = value & mask; self.set_bit_field_test_flags(field, get_bit_field_msb(offset)); - self.set_target_value(system, target, (value & !mask) | (!field & mask), Size::Long)?; + self.set_target_value(target, (value & !mask) | (!field & mask), Size::Long)?; }, Instruction::BFCLR(target, offset, width) => { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); - let value = self.get_target_value(system, target, Size::Long)?; + let value = self.get_target_value(target, Size::Long)?; let field = value & mask; self.set_bit_field_test_flags(field, get_bit_field_msb(offset)); - self.set_target_value(system, target, value & !mask, Size::Long)?; + self.set_target_value(target, value & !mask, Size::Long)?; }, Instruction::BFEXTS(target, offset, width, reg) => { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); - let value = self.get_target_value(system, target, Size::Long)?; + let value = self.get_target_value(target, Size::Long)?; let field = value & mask; self.set_bit_field_test_flags(field, get_bit_field_msb(offset)); @@ -291,7 +291,7 @@ impl M68k { Instruction::BFEXTU(target, offset, width, reg) => { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); - let value = self.get_target_value(system, target, Size::Long)?; + let value = self.get_target_value(target, Size::Long)?; let field = value & mask; self.set_bit_field_test_flags(field, get_bit_field_msb(offset)); self.state.d_reg[reg as usize] = field >> (32 - offset - width); @@ -303,15 +303,15 @@ impl M68k { Instruction::BFSET(target, offset, width) => { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); - let value = self.get_target_value(system, target, Size::Long)?; + let value = self.get_target_value(target, Size::Long)?; let field = value & mask; self.set_bit_field_test_flags(field, get_bit_field_msb(offset)); - self.set_target_value(system, target, value | mask, Size::Long)?; + self.set_target_value(target, value | mask, Size::Long)?; }, Instruction::BFTST(target, offset, width) => { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); - let value = self.get_target_value(system, target, Size::Long)?; + let value = self.get_target_value(target, Size::Long)?; let field = value & mask; self.set_bit_field_test_flags(field, get_bit_field_msb(offset)); }, @@ -320,19 +320,19 @@ impl M68k { //Instruction::CHK(Target, Size) => { //}, Instruction::CLR(target, size) => { - self.set_target_value(system, target, 0, size)?; + self.set_target_value(target, 0, size)?; // Clear flags except Zero flag self.state.sr = (self.state.sr & 0xFFF0) | (Flags::Zero as u16); }, Instruction::CMP(src, dest, size) => { - let value = self.get_target_value(system, src, size)?; - let existing = self.get_target_value(system, dest, size)?; + let value = self.get_target_value(src, size)?; + let existing = self.get_target_value(dest, size)?; let (result, carry) = overflowing_sub_sized(existing, value, size); let overflow = get_sub_overflow(existing, value, result, size); self.set_compare_flags(result, size, carry, overflow); }, Instruction::CMPA(src, reg, size) => { - let value = sign_extend_to_long(self.get_target_value(system, src, size)?, size) as u32; + let value = sign_extend_to_long(self.get_target_value(src, size)?, size) as u32; let existing = *self.get_a_reg_mut(reg); let (result, carry) = overflowing_sub_sized(existing, value, Size::Long); let overflow = get_sub_overflow(existing, value, result, size); @@ -349,9 +349,9 @@ impl M68k { } }, Instruction::DIVW(src, dest, sign) => { - let value = self.get_target_value(system, src, Size::Word)?; + let value = self.get_target_value(src, Size::Word)?; if value == 0 { - self.exception(system, Exceptions::ZeroDivide as u8, false)?; + self.exception(Exceptions::ZeroDivide as u8, false)?; return Ok(()); } @@ -368,9 +368,9 @@ impl M68k { self.state.d_reg[dest as usize] = (remainder << 16) | (0xFFFF & quotient); }, Instruction::DIVL(src, dest_h, dest_l, sign) => { - let value = self.get_target_value(system, src, Size::Long)?; + let value = self.get_target_value(src, Size::Long)?; if value == 0 { - self.exception(system, Exceptions::ZeroDivide as u8, false)?; + self.exception(Exceptions::ZeroDivide as u8, false)?; return Ok(()); } @@ -399,10 +399,10 @@ impl M68k { self.state.d_reg[dest_l as usize] = quotient as u32; }, Instruction::EOR(src, dest, size) => { - let value = self.get_target_value(system, src, size)?; - let existing = self.get_target_value(system, dest, size)?; + let value = self.get_target_value(src, size)?; + let existing = self.get_target_value(dest, size)?; let result = get_value_sized(existing ^ value, size); - self.set_target_value(system, dest, result, size)?; + self.set_target_value(dest, result, size)?; self.set_logic_flags(result, size); }, Instruction::EORtoCCR(value) => { @@ -413,10 +413,10 @@ impl M68k { self.state.sr = self.state.sr ^ value; }, Instruction::EXG(target1, target2) => { - let value1 = self.get_target_value(system, target1, Size::Long)?; - let value2 = self.get_target_value(system, target2, Size::Long)?; - self.set_target_value(system, target1, value2, Size::Long)?; - self.set_target_value(system, target2, value1, Size::Long)?; + let value1 = self.get_target_value(target1, Size::Long)?; + let value2 = self.get_target_value(target2, Size::Long)?; + self.set_target_value(target1, value2, Size::Long)?; + self.set_target_value(target2, value1, Size::Long)?; }, Instruction::EXT(reg, from_size, to_size) => { let input = get_value_sized(self.state.d_reg[reg as usize], from_size); @@ -432,30 +432,30 @@ impl M68k { //Instruction::ILLEGAL => { //}, Instruction::JMP(target) => { - self.state.pc = self.get_target_address(system, target)?; + self.state.pc = self.get_target_address(target)?; }, Instruction::JSR(target) => { - self.push_long(system, self.state.pc)?; + self.push_long(self.state.pc)?; let sp = *self.get_stack_pointer_mut(); self.debugger.stack_tracer.push_return(sp); - self.state.pc = self.get_target_address(system, target)?; + self.state.pc = self.get_target_address(target)?; }, Instruction::LEA(target, reg) => { - let value = self.get_target_address(system, target)?; + let value = self.get_target_address(target)?; let addr = self.get_a_reg_mut(reg); *addr = value; }, Instruction::LINK(reg, offset) => { let value = *self.get_a_reg_mut(reg); - self.push_long(system, value)?; + self.push_long(value)?; let sp = *self.get_stack_pointer_mut(); let addr = self.get_a_reg_mut(reg); *addr = sp; *self.get_stack_pointer_mut() = sp.wrapping_add((offset as i32) as u32); }, Instruction::LSd(count, target, size, shift_dir) => { - let count = self.get_target_value(system, count, size)? % 64; - let mut pair = (self.get_target_value(system, target, size)?, false); + let count = self.get_target_value(count, size)? % 64; + let mut pair = (self.get_target_value(target, size)?, false); for _ in 0..count { pair = shift_operation(pair.0, size, shift_dir, false); } @@ -464,48 +464,48 @@ impl M68k { self.set_flag(Flags::Carry, true); self.set_flag(Flags::Extend, true); } - self.set_target_value(system, target, pair.0, size)?; + self.set_target_value(target, pair.0, size)?; }, Instruction::MOVE(src, dest, size) => { - let value = self.get_target_value(system, src, size)?; + let value = self.get_target_value(src, size)?; self.set_logic_flags(value, size); - self.set_target_value(system, dest, value, size)?; + self.set_target_value(dest, value, size)?; }, Instruction::MOVEA(src, reg, size) => { - let value = self.get_target_value(system, src, size)?; + let value = self.get_target_value(src, size)?; let value = sign_extend_to_long(value, size) as u32; let addr = self.get_a_reg_mut(reg); *addr = value; }, Instruction::MOVEfromSR(target) => { self.require_supervisor()?; - self.set_target_value(system, target, self.state.sr as u32, Size::Word)?; + self.set_target_value(target, self.state.sr as u32, Size::Word)?; }, Instruction::MOVEtoSR(target) => { self.require_supervisor()?; - self.state.sr = self.get_target_value(system, target, Size::Word)? as u16; + self.state.sr = self.get_target_value(target, Size::Word)? as u16; }, Instruction::MOVEtoCCR(target) => { - let value = self.get_target_value(system, target, Size::Word)? as u16; + let value = self.get_target_value(target, Size::Word)? as u16; self.state.sr = (self.state.sr & 0xFF00) | (value & 0x00FF); }, Instruction::MOVEC(target, control_reg, dir) => { self.require_supervisor()?; match dir { Direction::FromTarget => { - let value = self.get_target_value(system, target, Size::Long)?; + let value = self.get_target_value(target, Size::Long)?; let addr = self.get_control_reg_mut(control_reg); *addr = value; }, Direction::ToTarget => { let addr = self.get_control_reg_mut(control_reg); let value = *addr; - self.set_target_value(system, target, value, Size::Long)?; + self.set_target_value(target, value, Size::Long)?; }, } }, Instruction::MOVEM(target, size, dir, mask) => { - self.execute_movem(system, target, size, dir, mask)?; + self.execute_movem(target, size, dir, mask)?; }, //Instruction::MOVEP(reg, target, size, dir) => { //}, @@ -517,12 +517,12 @@ impl M68k { Instruction::MOVEUSP(target, dir) => { self.require_supervisor()?; match dir { - Direction::ToTarget => self.set_target_value(system, target, self.state.usp, Size::Long)?, - Direction::FromTarget => { self.state.usp = self.get_target_value(system, target, Size::Long)?; }, + Direction::ToTarget => self.set_target_value(target, self.state.usp, Size::Long)?, + Direction::FromTarget => { self.state.usp = self.get_target_value(target, Size::Long)?; }, } }, Instruction::MULW(src, dest, sign) => { - let value = self.get_target_value(system, src, Size::Word)?; + let value = self.get_target_value(src, Size::Word)?; let existing = get_value_sized(self.state.d_reg[dest as usize], Size::Word); let result = match sign { Sign::Signed => ((((existing as u16) as i16) as i64) * (((value as u16) as i16) as i64)) as u64, @@ -533,7 +533,7 @@ impl M68k { self.state.d_reg[dest as usize] = result as u32; }, Instruction::MULL(src, dest_h, dest_l, sign) => { - let value = self.get_target_value(system, src, Size::Long)?; + let value = self.get_target_value(src, Size::Long)?; let existing = get_value_sized(self.state.d_reg[dest_l as usize], Size::Long); let result = match sign { Sign::Signed => (((existing as i32) as i64) * ((value as i32) as i64)) as u64, @@ -549,10 +549,10 @@ impl M68k { //Instruction::NBCD(Target) => { //}, Instruction::NEG(target, size) => { - let original = self.get_target_value(system, target, size)?; + let original = self.get_target_value(target, size)?; let (result, overflow) = overflowing_sub_signed_sized(0, original, size); let carry = result != 0; - self.set_target_value(system, target, result, size)?; + self.set_target_value(target, result, size)?; self.set_compare_flags(result, size, carry, overflow); self.set_flag(Flags::Extend, carry); }, @@ -560,16 +560,16 @@ impl M68k { //}, Instruction::NOP => { }, Instruction::NOT(target, size) => { - let mut value = self.get_target_value(system, target, size)?; + let mut value = self.get_target_value(target, size)?; value = get_value_sized(!value, size); - self.set_target_value(system, target, value, size)?; + self.set_target_value(target, value, size)?; self.set_logic_flags(value, size); }, Instruction::OR(src, dest, size) => { - let value = self.get_target_value(system, src, size)?; - let existing = self.get_target_value(system, dest, size)?; + let value = self.get_target_value(src, size)?; + let existing = self.get_target_value(dest, size)?; let result = get_value_sized(existing | value, size); - self.set_target_value(system, dest, result, size)?; + self.set_target_value(dest, result, size)?; self.set_logic_flags(result, size); }, Instruction::ORtoCCR(value) => { @@ -580,15 +580,15 @@ impl M68k { self.state.sr = self.state.sr | value; }, Instruction::PEA(target) => { - let value = self.get_target_address(system, target)?; - self.push_long(system, value)?; + let value = self.get_target_address(target)?; + self.push_long(value)?; }, //Instruction::RESET => { // self.require_supervisor()?; //}, Instruction::ROd(count, target, size, shift_dir) => { - let count = self.get_target_value(system, count, size)? % 64; - let mut pair = (self.get_target_value(system, target, size)?, false); + let count = self.get_target_value(count, size)? % 64; + let mut pair = (self.get_target_value(target, size)?, false); for _ in 0..count { pair = rotate_operation(pair.0, size, shift_dir, None); } @@ -596,11 +596,11 @@ impl M68k { if pair.1 { self.set_flag(Flags::Carry, true); } - self.set_target_value(system, target, pair.0, size)?; + self.set_target_value(target, pair.0, size)?; }, Instruction::ROXd(count, target, size, shift_dir) => { - let count = self.get_target_value(system, count, size)? % 64; - let mut pair = (self.get_target_value(system, target, size)?, false); + let count = self.get_target_value(count, size)? % 64; + let mut pair = (self.get_target_value(target, size)?, false); for _ in 0..count { pair = rotate_operation(pair.0, size, shift_dir, Some(self.get_flag(Flags::Extend))); self.set_flag(Flags::Extend, pair.1); @@ -609,30 +609,30 @@ impl M68k { if pair.1 { self.set_flag(Flags::Carry, true); } - self.set_target_value(system, target, pair.0, size)?; + self.set_target_value(target, pair.0, size)?; }, Instruction::RTE => { self.require_supervisor()?; - self.state.sr = self.pop_word(system)?; - self.state.pc = self.pop_long(system)?; + self.state.sr = self.pop_word()?; + self.state.pc = self.pop_long()?; if self.cputype >= M68kType::MC68010 { - let _ = self.pop_word(system)?; + let _ = self.pop_word()?; } }, //Instruction::RTR => { //}, Instruction::RTS => { self.debugger.stack_tracer.pop_return(); - self.state.pc = self.pop_long(system)?; + self.state.pc = self.pop_long()?; }, //Instruction::RTD(i16) => { //}, Instruction::Scc(cond, target) => { let condition_true = self.get_current_condition(cond); if condition_true { - self.set_target_value(system, target, 0xFF, Size::Byte)?; + self.set_target_value(target, 0xFF, Size::Byte)?; } else { - self.set_target_value(system, target, 0x00, Size::Byte)?; + self.set_target_value(target, 0x00, Size::Byte)?; } }, Instruction::STOP(flags) => { @@ -643,16 +643,16 @@ impl M68k { //Instruction::SBCD(Target) => { //}, Instruction::SUB(src, dest, size) => { - let value = self.get_target_value(system, src, size)?; - let existing = self.get_target_value(system, dest, size)?; + let value = self.get_target_value(src, size)?; + let existing = self.get_target_value(dest, size)?; let (result, carry) = overflowing_sub_sized(existing, value, size); let overflow = get_sub_overflow(existing, value, result, size); self.set_compare_flags(result, size, carry, overflow); self.set_flag(Flags::Extend, carry); - self.set_target_value(system, dest, result, size)?; + self.set_target_value(dest, result, size)?; }, Instruction::SUBA(src, dest, size) => { - let value = sign_extend_to_long(self.get_target_value(system, src, size)?, size) as u32; + let value = sign_extend_to_long(self.get_target_value(src, size)?, size) as u32; let existing = *self.get_a_reg_mut(dest); let (result, _) = overflowing_sub_sized(existing, value, Size::Long); *self.get_a_reg_mut(dest) = result; @@ -666,21 +666,21 @@ impl M68k { //Instruction::TAS(Target) => { //}, Instruction::TST(target, size) => { - let value = self.get_target_value(system, target, size)?; + let value = self.get_target_value(target, size)?; self.set_logic_flags(value, size); }, Instruction::TRAP(number) => { - self.exception(system, 32 + number, false)?; + self.exception(32 + number, false)?; }, Instruction::TRAPV => { if self.get_flag(Flags::Overflow) { - self.exception(system, Exceptions::TrapvInstruction as u8, false)?; + self.exception(Exceptions::TrapvInstruction as u8, false)?; } }, Instruction::UNLK(reg) => { let value = *self.get_a_reg_mut(reg); *self.get_stack_pointer_mut() = value; - let new_value = self.pop_long(system)?; + let new_value = self.pop_long()?; let addr = self.get_a_reg_mut(reg); *addr = new_value; }, @@ -691,8 +691,8 @@ impl M68k { Ok(()) } - fn execute_movem(&mut self, system: &System, target: Target, size: Size, dir: Direction, mut mask: u16) -> Result<(), Error> { - let mut addr = self.get_target_address(system, target)?; + fn execute_movem(&mut self, target: Target, size: Size, dir: Direction, mut mask: u16) -> Result<(), Error> { + let mut addr = self.get_target_address(target)?; // If we're using a MC68020 or higher, and it was Post-Inc/Pre-Dec target, then update the value before it's stored if self.cputype >= M68kType::MC68020 { @@ -751,33 +751,33 @@ impl M68k { Ok(()) } - fn push_word(&mut self, system: &System, value: u16) -> Result<(), Error> { + fn push_word(&mut self, value: u16) -> Result<(), Error> { *self.get_stack_pointer_mut() -= 2; let addr = *self.get_stack_pointer_mut(); self.port.write_beu16(addr as Address, value) } - fn pop_word(&mut self, system: &System) -> Result { + fn pop_word(&mut self) -> Result { let addr = *self.get_stack_pointer_mut(); let value = self.port.read_beu16(addr as Address)?; *self.get_stack_pointer_mut() += 2; Ok(value) } - fn push_long(&mut self, system: &System, value: u32) -> Result<(), Error> { + fn push_long(&mut self, value: u32) -> Result<(), Error> { *self.get_stack_pointer_mut() -= 4; let addr = *self.get_stack_pointer_mut(); self.port.write_beu32(addr as Address, value) } - fn pop_long(&mut self, system: &System) -> Result { + fn pop_long(&mut self) -> Result { let addr = *self.get_stack_pointer_mut(); let value = self.port.read_beu32(addr as Address)?; *self.get_stack_pointer_mut() += 4; Ok(value) } - pub fn get_target_value(&mut self, system: &System, target: Target, size: Size) -> Result { + pub fn get_target_value(&mut self, target: Target, size: Size) -> Result { match target { Target::Immediate(value) => Ok(value), Target::DirectDReg(reg) => Ok(get_value_sized(self.state.d_reg[reg as usize], size)), @@ -820,7 +820,7 @@ impl M68k { } } - pub fn set_target_value(&mut self, system: &System, target: Target, value: u32, size: Size) -> Result<(), Error> { + pub fn set_target_value(&mut self, target: Target, value: u32, size: Size) -> Result<(), Error> { match target { Target::DirectDReg(reg) => { set_value_sized(&mut self.state.d_reg[reg as usize], value, size); @@ -869,7 +869,7 @@ impl M68k { Ok(()) } - pub fn get_target_address(&mut self, system: &System, target: Target) -> Result { + pub fn get_target_address(&mut self, target: Target) -> Result { let addr = match target { Target::IndirectAReg(reg) | Target::IndirectARegInc(reg) | Target::IndirectARegDec(reg) => *self.get_a_reg_mut(reg), Target::IndirectRegOffset(base_reg, index_reg, displacement) => { @@ -1187,10 +1187,6 @@ fn get_sub_overflow(operand1: u32, operand2: u32, result: u32, size: Size) -> bo (msb1 && msb2 && !msb_res) || (!msb1 && !msb2 && msb_res) } -fn get_twos_complement(value: u32, size: Size) -> u32 { - get_value_sized(!value + 1, size) -} - #[inline(always)] fn get_msb(value: u32, size: Size) -> bool { match size { diff --git a/src/cpus/m68k/state.rs b/src/cpus/m68k/state.rs index 17ae157..b8802d1 100644 --- a/src/cpus/m68k/state.rs +++ b/src/cpus/m68k/state.rs @@ -148,7 +148,7 @@ impl M68k { self.debugger = M68kDebugger::new(); } - pub fn dump_state(&mut self, system: &System) { + pub fn dump_state(&mut self, _system: &System) { println!("Status: {:?}", self.state.status); println!("PC: {:#010x}", self.state.pc); println!("SR: {:#06x}", self.state.sr); diff --git a/src/cpus/m68k/tests.rs b/src/cpus/m68k/tests.rs index fca6c09..e39ba86 100644 --- a/src/cpus/m68k/tests.rs +++ b/src/cpus/m68k/tests.rs @@ -70,7 +70,7 @@ mod decode_tests { BusPort::new(0, 24, 16, system.bus.clone()) }; let mut cpu = M68k::new(cputype, 10_000_000, port); - cpu.init(&system).unwrap(); + cpu.init().unwrap(); assert_eq!(cpu.state.pc, INIT_ADDR as u32); assert_eq!(cpu.state.msp, INIT_STACK as u32); @@ -93,11 +93,11 @@ mod decode_tests { load_memory(&system, case.data); match &case.ins { Some(ins) => { - cpu.decode_next(&system).unwrap(); + cpu.decode_next().unwrap(); assert_eq!(cpu.decoder.instruction, ins.clone()); }, None => { - assert_eq!(cpu.decode_next(&system).is_err(), true); + assert_eq!(cpu.decode_next().is_err(), true); }, } } @@ -119,7 +119,6 @@ mod decode_tests { let (mut cpu, system) = init_decode_test(M68kType::MC68010); let size = Size::Word; - let expected = 0x1234; let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b000, 0b001, Some(size)).unwrap(); assert_eq!(target, Target::DirectDReg(1)); @@ -130,7 +129,6 @@ mod decode_tests { let (mut cpu, system) = init_decode_test(M68kType::MC68010); let size = Size::Word; - let expected = 0x1234; let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b001, 0b010, Some(size)).unwrap(); assert_eq!(target, Target::DirectAReg(2)); @@ -141,7 +139,6 @@ mod decode_tests { let (mut cpu, system) = init_decode_test(M68kType::MC68010); let size = Size::Long; - let expected_addr = INIT_ADDR; let expected = 0x12345678; system.get_bus().write_beu32(INIT_ADDR, expected).unwrap(); @@ -155,7 +152,6 @@ mod decode_tests { let (mut cpu, system) = init_decode_test(M68kType::MC68010); let size = Size::Long; - let expected_addr = INIT_ADDR; let expected = 0x12345678; system.get_bus().write_beu32(INIT_ADDR, expected).unwrap(); @@ -169,7 +165,6 @@ mod decode_tests { let (mut cpu, system) = init_decode_test(M68kType::MC68010); let size = Size::Long; - let expected_addr = INIT_ADDR + 4; let expected = 0x12345678; system.get_bus().write_beu32(INIT_ADDR, expected).unwrap(); @@ -433,15 +428,15 @@ mod execute_tests { let (mut cpu, system) = init_execute_test(case.cputype); let init_state = build_state(&case.init); - let mut expected_state = build_state(&case.fini); + let expected_state = build_state(&case.fini); load_memory(&system, case.data); cpu.state = init_state; - cpu.decode_next(&system).unwrap(); + cpu.decode_next().unwrap(); assert_eq!(cpu.decoder.instruction, case.ins); - cpu.execute_current(&system).unwrap(); + cpu.execute_current().unwrap(); assert_eq!(cpu.state, expected_state); } @@ -709,73 +704,70 @@ mod execute_tests { #[test] fn target_value_direct_d() { - let (mut cpu, system) = init_execute_test(M68kType::MC68010); + let (mut cpu, _) = init_execute_test(M68kType::MC68010); let size = Size::Word; let expected = 0x1234; let target = Target::DirectDReg(1); cpu.state.d_reg[1] = expected; - let result = cpu.get_target_value(&system, target, size).unwrap(); + let result = cpu.get_target_value(target, size).unwrap(); assert_eq!(result, expected); } #[test] fn target_value_direct_a() { - let (mut cpu, system) = init_execute_test(M68kType::MC68010); + let (mut cpu, _) = init_execute_test(M68kType::MC68010); let size = Size::Word; let expected = 0x1234; let target = Target::DirectAReg(2); cpu.state.a_reg[2] = expected; - let result = cpu.get_target_value(&system, target, size).unwrap(); + let result = cpu.get_target_value(target, size).unwrap(); assert_eq!(result, expected); } #[test] fn target_value_indirect_a() { - let (mut cpu, system) = init_execute_test(M68kType::MC68010); + let (mut cpu, _) = init_execute_test(M68kType::MC68010); let size = Size::Long; - let expected_addr = INIT_ADDR; let expected = 0x12345678; let target = Target::IndirectAReg(2); - system.get_bus().write_beu32(INIT_ADDR, expected).unwrap(); + cpu.port.write_beu32(INIT_ADDR, expected).unwrap(); cpu.state.a_reg[2] = INIT_ADDR as u32; - let result = cpu.get_target_value(&system, target, size).unwrap(); + let result = cpu.get_target_value(target, size).unwrap(); assert_eq!(result, expected); } #[test] fn target_value_indirect_a_inc() { - let (mut cpu, system) = init_execute_test(M68kType::MC68010); + let (mut cpu, _) = init_execute_test(M68kType::MC68010); let size = Size::Long; - let expected_addr = INIT_ADDR; let expected = 0x12345678; let target = Target::IndirectARegInc(2); - system.get_bus().write_beu32(INIT_ADDR, expected).unwrap(); + cpu.port.write_beu32(INIT_ADDR, expected).unwrap(); cpu.state.a_reg[2] = INIT_ADDR as u32; - let result = cpu.get_target_value(&system, target, size).unwrap(); + let result = cpu.get_target_value(target, size).unwrap(); assert_eq!(result, expected); assert_eq!(cpu.state.a_reg[2], (INIT_ADDR as u32) + 4); } #[test] fn target_value_indirect_a_dec() { - let (mut cpu, system) = init_execute_test(M68kType::MC68010); + let (mut cpu, _) = init_execute_test(M68kType::MC68010); let size = Size::Long; - let expected_addr = INIT_ADDR + 4; let expected = 0x12345678; let target = Target::IndirectARegDec(2); - system.get_bus().write_beu32(INIT_ADDR, expected).unwrap(); + cpu.port.write_beu32(INIT_ADDR, expected).unwrap(); cpu.state.a_reg[2] = (INIT_ADDR as u32) + 4; - let result = cpu.get_target_value(&system, target, size).unwrap(); + let result = cpu.get_target_value(target, size).unwrap(); assert_eq!(result, expected); assert_eq!(cpu.state.a_reg[2], INIT_ADDR as u32); } @@ -783,14 +775,14 @@ mod execute_tests { #[test] fn target_value_immediate() { - let (mut cpu, system) = init_execute_test(M68kType::MC68010); + let (mut cpu, _) = init_execute_test(M68kType::MC68010); let size = Size::Word; let expected = 0x1234; let target = Target::Immediate(expected); - let result = cpu.get_target_value(&system, target, size).unwrap(); + let result = cpu.get_target_value(target, size).unwrap(); assert_eq!(result, expected); } } diff --git a/src/cpus/z80/debugger.rs b/src/cpus/z80/debugger.rs index 5739b86..86becbf 100644 --- a/src/cpus/z80/debugger.rs +++ b/src/cpus/z80/debugger.rs @@ -30,10 +30,10 @@ impl Debuggable for Z80 { } } - fn print_current_step(&mut self, system: &System) -> Result<(), Error> { + fn print_current_step(&mut self, _system: &System) -> Result<(), Error> { self.decoder.decode_at(&mut self.port, self.state.pc)?; self.decoder.dump_decoded(&mut self.port); - self.dump_state(system); + self.dump_state(); Ok(()) } @@ -42,7 +42,7 @@ impl Debuggable for Z80 { decoder.dump_disassembly(&mut self.port, addr as u16, count as u16); } - fn execute_command(&mut self, system: &System, args: &[&str]) -> Result { + fn execute_command(&mut self, _system: &System, args: &[&str]) -> Result { match args[0] { "l" => { use super::state::Register; diff --git a/src/cpus/z80/decode.rs b/src/cpus/z80/decode.rs index 853d88f..f8d8d59 100644 --- a/src/cpus/z80/decode.rs +++ b/src/cpus/z80/decode.rs @@ -2,7 +2,7 @@ use crate::error::Error; use crate::devices::{Address, Addressable}; -use super::state::{Z80, Z80Type, Register}; +use super::state::Register; #[derive(Copy, Clone, Debug, PartialEq)] diff --git a/src/cpus/z80/execute.rs b/src/cpus/z80/execute.rs index cc8fbcc..00436df 100644 --- a/src/cpus/z80/execute.rs +++ b/src/cpus/z80/execute.rs @@ -3,14 +3,12 @@ use crate::system::System; use crate::error::{ErrorType, Error}; use crate::devices::{ClockElapsed, Address, Steppable, Addressable, Interruptable, Debuggable, Transmutable, read_beu16, write_beu16}; -use super::decode::{Condition, Instruction, LoadTarget, Target, RegisterPair, IndexRegister, IndexRegisterHalf, Size, Direction, UndocumentedCopy}; +use super::decode::{Condition, Instruction, LoadTarget, Target, RegisterPair, IndexRegister, IndexRegisterHalf, Size}; use super::state::{Z80, Status, Flags, Register}; const DEV_NAME: &'static str = "z80-cpu"; -const FLAGS_ALL: u8 = 0xFF; -const FLAGS_ALL_BUT_CARRY: u8 = 0xFE; const FLAGS_NUMERIC: u8 = 0xC0; const FLAGS_ARITHMETIC: u8 = 0x17; const FLAGS_CARRY_HALF_CARRY: u8 = 0x11; @@ -28,8 +26,8 @@ impl Steppable for Z80 { Ok((1_000_000_000 / self.frequency as u64) * 4) } - fn on_error(&mut self, system: &System) { - self.dump_state(system); + fn on_error(&mut self, _system: &System) { + self.dump_state(); } } @@ -55,13 +53,13 @@ impl Transmutable for Z80 { impl Z80 { pub fn step_internal(&mut self, system: &System) -> Result<(), Error> { match self.state.status { - Status::Init => self.init(system), + Status::Init => self.init(), Status::Halted => Err(Error::new("CPU stopped")), Status::Running => { match self.cycle_one(system) { Ok(()) => Ok(()), //Err(Error { err: ErrorType::Processor, native, .. }) => { - Err(Error { err: ErrorType::Processor, native, .. }) => { + Err(Error { err: ErrorType::Processor, .. }) => { //self.exception(system, native as u8, false)?; Ok(()) }, @@ -71,17 +69,16 @@ impl Z80 { } } - pub fn init(&mut self, system: &System) -> Result<(), Error> { - //self.state.msp = self.port.read_beu32(0)?; - //self.state.pc = self.port.read_beu32(4)?; + pub fn init(&mut self) -> Result<(), Error> { + self.state.pc = 0; self.state.status = Status::Running; Ok(()) } pub fn cycle_one(&mut self, system: &System) -> Result<(), Error> { //self.timer.cycle.start(); - self.decode_next(system)?; - self.execute_current(system)?; + self.decode_next()?; + self.execute_current()?; //self.timer.cycle.end(); //if (self.timer.cycle.events % 500) == 0 { @@ -93,21 +90,21 @@ impl Z80 { Ok(()) } - pub fn decode_next(&mut self, system: &System) -> Result<(), Error> { + pub fn decode_next(&mut self) -> Result<(), Error> { //self.timer.decode.start(); self.decoder.decode_at(&mut self.port, self.state.pc)?; //self.timer.decode.end(); //if self.debugger.use_tracing { //self.decoder.dump_decoded(&mut self.port); - //self.dump_state(system); + //self.dump_state(); //} self.state.pc = self.decoder.end; Ok(()) } - pub fn execute_current(&mut self, system: &System) -> Result<(), Error> { + pub fn execute_current(&mut self) -> Result<(), Error> { match self.decoder.instruction { Instruction::ADCa(target) => { let src = self.get_target_value(target)?; @@ -204,14 +201,14 @@ impl Z80 { Instruction::DEC16(regpair) => { let value = self.get_register_pair_value(regpair); - let (result, carry, overflow) = sub_words(value, 1); + let (result, _, _) = sub_words(value, 1); self.set_register_pair_value(regpair, result); }, Instruction::DEC8(target) => { let value = self.get_target_value(target)?; - let (result, carry, overflow) = sub_bytes(value, 1); + let (result, _, overflow) = sub_bytes(value, 1); let carry = self.get_flag(Flags::Carry); // Preserve the carry bit, according to Z80 reference self.set_arithmetic_op_flags(result as u16, Size::Byte, true, carry, overflow, (result & 0x10) != 0); @@ -620,7 +617,7 @@ impl Z80 { } fn pop_word(&mut self) -> Result { - let mut value = 0; + let mut value; value = self.port.read_u8(self.state.sp as Address)? as u16; self.state.sp = self.state.sp.wrapping_add(1); value |= (self.port.read_u8(self.state.sp as Address)? as u16) << 8; diff --git a/src/cpus/z80/state.rs b/src/cpus/z80/state.rs index 8d4beb4..a252ffc 100644 --- a/src/cpus/z80/state.rs +++ b/src/cpus/z80/state.rs @@ -1,5 +1,4 @@ -use crate::system::System; use crate::devices::Address; use crate::memory::BusPort; @@ -122,7 +121,7 @@ impl Z80 { self.debugger = Z80Debugger::new(); } - pub fn dump_state(&mut self, system: &System) { + pub fn dump_state(&mut self) { println!("Status: {:?}", self.state.status); println!("PC: {:#06x}", self.state.pc); println!("SP: {:#06x}", self.state.sp); diff --git a/src/cpus/z80/tests.rs b/src/cpus/z80/tests.rs index 17351e7..e66227d 100644 --- a/src/cpus/z80/tests.rs +++ b/src/cpus/z80/tests.rs @@ -19,7 +19,7 @@ mod decode_tests { // Initialize the CPU and make sure it's in the expected state let mut cpu = Z80::new(Z80Type::Z80, 4_000_000, BusPort::new(0, 16, 8, system.bus.clone())); - cpu.init(&system).unwrap(); + cpu.init().unwrap(); (cpu, system) } @@ -33,7 +33,7 @@ mod decode_tests { fn run_decode_test(data: &[u8]) -> Instruction { let (mut cpu, system) = init_decode_test(); load_memory(&system, data); - cpu.decode_next(&system).unwrap(); + cpu.decode_next().unwrap(); cpu.decoder.instruction } @@ -84,7 +84,7 @@ mod execute_tests { use super::super::{Z80, Z80Type}; use super::super::state::{Z80State, Register}; - use super::super::decode::{Instruction, LoadTarget, Target, RegisterPair, IndexRegister, IndexRegisterHalf, Condition}; + use super::super::decode::{Instruction, LoadTarget, Target, RegisterPair, Condition}; struct TestState { pc: u16, @@ -571,7 +571,7 @@ mod execute_tests { // Initialize the CPU and make sure it's in the expected state let mut cpu = Z80::new(Z80Type::Z80, 4_000_000, BusPort::new(0, 16, 8, system.bus.clone())); - cpu.init(&system).unwrap(); + cpu.init().unwrap(); (cpu, system) } @@ -608,10 +608,10 @@ mod execute_tests { load_memory(&system, case.data); cpu.state = init_state; - cpu.decode_next(&system).unwrap(); + cpu.decode_next().unwrap(); assert_eq!(cpu.decoder.instruction, case.ins); - cpu.execute_current(&system).unwrap(); + cpu.execute_current().unwrap(); // TODO this is a hack to ignore the functioning of the F5, F3 flags for now cpu.state.reg[Register::F as usize] &= 0xD7; diff --git a/src/debugger.rs b/src/debugger.rs index 7c757fd..612cbbe 100644 --- a/src/debugger.rs +++ b/src/debugger.rs @@ -67,7 +67,7 @@ impl Debugger { loop { let mut buffer = String::new(); - std::io::stdout().write_all(b"> "); + std::io::stdout().write_all(b"> ").unwrap(); std::io::stdin().read_line(&mut buffer).unwrap(); let args: Vec<&str> = buffer.split_whitespace().collect(); match self.run_debugger_command(system, debug_obj, &args) { diff --git a/src/devices.rs b/src/devices.rs index c4b464d..3b1cf65 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -6,8 +6,6 @@ use crate::error::Error; use crate::system::System; -pub const MAX_READ: usize = 4; - /// The time in nanoseconds that have elapsed since the start of the simulation pub type Clock = u64; diff --git a/src/host/gfx.rs b/src/host/gfx.rs index b780671..3bf5d6e 100644 --- a/src/host/gfx.rs +++ b/src/host/gfx.rs @@ -65,7 +65,7 @@ impl WindowUpdater for FrameSwapper { (self.current.width, self.current.height) } - fn update_frame(&mut self, width: u32, height: u32, bitmap: &mut [u32]) { + fn update_frame(&mut self, width: u32, _height: u32, bitmap: &mut [u32]) { std::mem::swap(&mut self.current, &mut self.previous); for y in 0..self.current.height { @@ -84,7 +84,9 @@ impl WindowUpdater for FrameSwapperWrapper { } fn update_frame(&mut self, width: u32, height: u32, bitmap: &mut [u32]) { - self.0.lock().map(|mut swapper| swapper.update_frame(width, height, bitmap)); + if let Ok(mut swapper) = self.0.lock() { + swapper.update_frame(width, height, bitmap); + } } } diff --git a/src/host/traits.rs b/src/host/traits.rs index 6905940..f7144fa 100644 --- a/src/host/traits.rs +++ b/src/host/traits.rs @@ -1,6 +1,4 @@ -use std::sync::{Arc, Mutex}; - use crate::error::Error; use crate::host::keys::Key; @@ -15,8 +13,8 @@ pub enum JoystickDevice { pub trait Host { //fn create_pty(&self) -> Result, Error>; fn add_window(&mut self, updater: Box) -> Result<(), Error>; - fn register_joystick(&mut self, device: JoystickDevice, input: Box) -> Result<(), Error> { Err(Error::new("Not supported")) } - fn register_keyboard(&mut self, input: Box) -> Result<(), Error> { Err(Error::new("Not supported")) } + fn register_joystick(&mut self, _device: JoystickDevice, _input: Box) -> Result<(), Error> { Err(Error::new("Not supported")) } + fn register_keyboard(&mut self, _input: Box) -> Result<(), Error> { Err(Error::new("Not supported")) } } pub trait Tty { diff --git a/src/host/tty.rs b/src/host/tty.rs index 17cac5d..1e997fa 100644 --- a/src/host/tty.rs +++ b/src/host/tty.rs @@ -3,7 +3,6 @@ use std::thread; use std::sync::mpsc; use std::time::Duration; use std::io::{Read, Write}; -use std::sync::{Arc, Mutex}; use std::os::unix::io::AsRawFd; use nix::fcntl::OFlag; @@ -55,7 +54,7 @@ impl SimplePty { loop { match pty.read(&mut buf) { Ok(_) => { - input_tx.send(buf[0]); + input_tx.send(buf[0]).unwrap(); }, Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => { }, Err(err) => { println!("ERROR: {:?}", err); } @@ -84,7 +83,7 @@ impl Tty for SimplePty { } fn write(&mut self, output: u8) -> bool { - self.output.send(output); + self.output.send(output).unwrap(); true } } diff --git a/src/interrupts.rs b/src/interrupts.rs index d94e9bd..6a66f45 100644 --- a/src/interrupts.rs +++ b/src/interrupts.rs @@ -1,6 +1,4 @@ -use std::iter; - use crate::error::Error; use crate::devices::TransmutableBox; diff --git a/src/machines/genesis.rs b/src/machines/genesis.rs index eaa37ed..3ebc409 100644 --- a/src/machines/genesis.rs +++ b/src/machines/genesis.rs @@ -1,13 +1,17 @@ +use std::rc::Rc; +use std::cell::RefCell; + use crate::error::Error; use crate::system::System; -use crate::memory::{MemoryBlock, BusPort}; +use crate::memory::{MemoryBlock, Bus, BusPort}; use crate::devices::{wrap_transmutable, Debuggable}; use crate::cpus::m68k::{M68k, M68kType}; +use crate::cpus::z80::{Z80, Z80Type}; use crate::peripherals::genesis; -use crate::host::traits::{Host, WindowUpdater}; +use crate::host::traits::{Host}; pub fn build_genesis(host: &mut H) -> Result { @@ -28,12 +32,17 @@ pub fn build_genesis(host: &mut H) -> Result { system.add_addressable_device(0x00000000, wrap_transmutable(rom)).unwrap(); let ram = MemoryBlock::new(vec![0; 0x00010000]); - system.add_addressable_device(0x00FF0000, wrap_transmutable(ram)).unwrap(); + system.add_addressable_device(0x00ff0000, wrap_transmutable(ram)).unwrap(); + let coproc_bus = Rc::new(RefCell::new(Bus::new())); + let coproc_shared_mem = wrap_transmutable(MemoryBlock::new(vec![0; 0x00010000])); + coproc_bus.borrow_mut().insert(0x0000, coproc_shared_mem.borrow_mut().as_addressable().unwrap().len(), coproc_shared_mem.clone()); + let mut coproc = Z80::new(Z80Type::Z80, 3_579_545, BusPort::new(0, 16, 8, coproc_bus.clone())); + + system.add_addressable_device(0x00a00000, coproc_shared_mem)?; + //system.add_device("coproc", wrap_transmutable(coproc))?; - let coproc_shared_mem = MemoryBlock::new(vec![0; 0x00010000]); - system.add_addressable_device(0x00A00000, wrap_transmutable(coproc_shared_mem)).unwrap(); let controllers = genesis::controllers::GenesisController::create(host)?; diff --git a/src/memory.rs b/src/memory.rs index d9d67db..00aad05 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -4,7 +4,7 @@ use std::rc::Rc; use std::cell::RefCell; use crate::error::Error; -use crate::devices::{Address, Addressable, Transmutable, TransmutableBox, MAX_READ}; +use crate::devices::{Address, Addressable, Transmutable, TransmutableBox}; pub struct MemoryBlock { @@ -75,6 +75,41 @@ impl Transmutable for MemoryBlock { } +pub struct MemoryAdapter { + pub subdevice: TransmutableBox, + pub shift: u8, +} + +impl MemoryAdapter { + pub fn new(subdevice: TransmutableBox, shift: u8) -> Self { + Self { + subdevice, + shift, + } + } +} + +impl Addressable for MemoryAdapter { + fn len(&self) -> usize { + let len = self.subdevice.borrow_mut().as_addressable().unwrap().len(); + len << self.shift + } + + fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> { + self.subdevice.borrow_mut().as_addressable().unwrap().read(addr >> self.shift, data) + } + + fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> { + self.subdevice.borrow_mut().as_addressable().unwrap().write(addr >> self.shift, data) + } +} + +impl Transmutable for MemoryAdapter { + fn as_addressable(&mut self) -> Option<&mut dyn Addressable> { + Some(self) + } +} + pub struct Block { pub base: Address, diff --git a/src/peripherals/ata.rs b/src/peripherals/ata.rs index 6e2a826..4eba0a3 100644 --- a/src/peripherals/ata.rs +++ b/src/peripherals/ata.rs @@ -2,7 +2,7 @@ use std::fs; use crate::error::Error; -use crate::devices::{Address, Addressable, Transmutable, MAX_READ}; +use crate::devices::{Address, Addressable, Transmutable}; const ATA_REG_DATA_WORD: Address = 0x20; diff --git a/src/peripherals/genesis/controllers.rs b/src/peripherals/genesis/controllers.rs index 8b6350c..e160c04 100644 --- a/src/peripherals/genesis/controllers.rs +++ b/src/peripherals/genesis/controllers.rs @@ -1,9 +1,7 @@ -use std::sync::{Arc, Mutex}; - use crate::error::Error; -use crate::signals::{Signal, SyncSignal}; -use crate::devices::{Address, Addressable, Transmutable, MAX_READ}; +use crate::signals::SyncSignal; +use crate::devices::{Address, Addressable, Transmutable}; use crate::host::traits::{Host, JoystickDevice, JoystickUpdater}; diff --git a/src/peripherals/genesis/coproc_memory.rs b/src/peripherals/genesis/coproc_memory.rs index 8d52a21..b5f3442 100644 --- a/src/peripherals/genesis/coproc_memory.rs +++ b/src/peripherals/genesis/coproc_memory.rs @@ -1,6 +1,6 @@ use crate::error::Error; -use crate::devices::{Address, Addressable, Transmutable, MAX_READ}; +use crate::devices::{Address, Addressable, Transmutable}; const DEV_NAME: &'static str = "coprocessor"; diff --git a/src/peripherals/genesis/ym7101.rs b/src/peripherals/genesis/ym7101.rs index 1c9eb52..cf1104e 100644 --- a/src/peripherals/genesis/ym7101.rs +++ b/src/peripherals/genesis/ym7101.rs @@ -5,7 +5,7 @@ use std::sync::{Arc, Mutex}; use crate::error::Error; use crate::system::System; use crate::signals::SyncSignal; -use crate::devices::{Clock, ClockElapsed, Address, Addressable, Steppable, Transmutable, MAX_READ, read_beu16, read_beu32, write_beu16}; +use crate::devices::{Clock, ClockElapsed, Address, Addressable, Steppable, Transmutable, read_beu16, read_beu32, write_beu16}; use crate::host::traits::{Host, BlitableSurface}; use crate::host::gfx::{Frame, FrameSwapper}; @@ -251,17 +251,20 @@ impl Ym7101State { } pub fn draw_frame(&mut self, frame: &mut Frame) { - let bg_colour = self.get_palette_colour((self.regs[REG_BACKGROUND] & 0x30) >> 4, self.regs[REG_BACKGROUND] & 0x0f); - for i in 0..(frame.width as usize * frame.height as usize) { - frame.bitmap[i] = bg_colour; - } - + self.draw_background(frame); self.draw_cell_table(frame, self.get_vram_scroll_b_addr()); self.draw_cell_table(frame, self.get_vram_scroll_a_addr()); //self.draw_window(frame); self.draw_sprites(frame); } + pub fn draw_background(&mut self, frame: &mut Frame) { + let bg_colour = self.get_palette_colour((self.regs[REG_BACKGROUND] & 0x30) >> 4, self.regs[REG_BACKGROUND] & 0x0f); + for i in 0..(frame.width as usize * frame.height as usize) { + frame.bitmap[i] = bg_colour; + } + } + pub fn draw_cell_table(&mut self, frame: &mut Frame, cell_table: u32) { let (scroll_h, scroll_v) = self.get_scroll_size(); let (cells_h, cells_v) = self.get_screen_size(); @@ -411,14 +414,10 @@ pub struct Ym7101 { } impl Ym7101 { - pub fn new(host: &H, external_interrupt: SyncSignal) -> Ym7101 { - let swapper = FrameSwapper::new_shared(); - swapper.lock().map(|mut swapper| { - swapper.current.set_size(320, 224); - swapper.previous.set_size(320, 224); - }); + pub fn new(host: &mut H, external_interrupt: SyncSignal) -> Ym7101 { + let swapper = FrameSwapper::new_shared(320, 224); - host.add_window(FrameSwapper::to_boxed(swapper.clone())); + host.add_window(FrameSwapper::to_boxed(swapper.clone())).unwrap(); Ym7101 { swapper, @@ -490,16 +489,48 @@ impl Steppable for Ym7101 { /* // Print Pattern Table let mut swapper = self.swapper.lock().unwrap(); - let coords = self.state.get_window_coords(); - for cell_y in coords.0.1..coords.1.1 { - for cell_x in coords.0.0..coords.1.0 { - let pattern_addr = (cell_x + (cell_y * 40)) * 32; - let iter = PatternIterator::new(&self.state, pattern_addr as u32, 0); + let (cells_h, cells_v) = self.state.get_screen_size(); + for cell_y in 0..cells_v { + for cell_x in 0..cells_h { + let pattern_addr = (cell_x + (cell_y * cells_h)) * 32; + let iter = PatternIterator::new(&self.state, pattern_addr as u32, 0, false, false); swapper.current.blit((cell_x << 3) as u32, (cell_y << 3) as u32, iter, 8, 8); } } */ + + /* + // Print Sprite + let mut swapper = self.swapper.lock().unwrap(); + self.state.draw_background(&mut swapper.current); + let sprite_table = (self.state.regs[REG_SPRITES_ADDR] as usize) << 9; + let (cells_h, cells_v) = self.state.get_screen_size(); + let sprite = 0; + println!("{:?}", &self.state.vram[(sprite_table + (sprite * 8))..(sprite_table + (sprite * 8) + 8)].iter().map(|byte| format!("{:02x}", byte)).collect::>()); + let size = self.state.vram[sprite_table + (sprite * 8) + 2]; + let (size_h, size_v) = (((size >> 2) & 0x03) as u16 + 1, (size & 0x03) as u16 + 1); + let pattern_name = ((self.state.vram[sprite_table + (sprite * 8) + 4] as u16) << 8) | (self.state.vram[sprite_table + (sprite * 8) + 5] as u16); + let pattern_gen = pattern_name & 0x7FF; + println!("{:x}", pattern_name); + + for cell_y in 0..size_v { + for cell_x in 0..size_h { + let pattern_addr = (pattern_gen + (cell_y * size_h) + cell_x) as u32; + println!("pattern: ({}, {}) {:x}", cell_x, cell_y, pattern_addr); + let iter = PatternIterator::new(&self.state, pattern_addr * 32, 3, true, true); + swapper.current.blit((cell_x << 3) as u32, (cell_y << 3) as u32, iter, 8, 8); + } + } + */ + + //let mut swapper = self.swapper.lock().unwrap(); + //swapper.current.blit(0, 0, PatternIterator::new(&self.state, 0x408 * 32, 3, false, false), 8, 8); + //swapper.current.blit(0, 8, PatternIterator::new(&self.state, 0x409 * 32, 3, false, false), 8, 8); + //swapper.current.blit(8, 0, PatternIterator::new(&self.state, 0x402 * 32, 3, false, false), 8, 8); + //swapper.current.blit(8, 8, PatternIterator::new(&self.state, 0x403 * 32, 3, false, false), 8, 8); + //swapper.current.blit(16, 0, PatternIterator::new(&self.state, 0x404 * 32, 3, false, false), 8, 8); + //swapper.current.blit(16, 8, PatternIterator::new(&self.state, 0x405 * 32, 3, false, false), 8, 8); } if self.state.transfer_run != DmaType::None { @@ -525,7 +556,7 @@ impl Steppable for Ym7101 { { let addr = self.state.transfer_addr; - let mut target = self.state.get_transfer_target_mut(); + let target = self.state.get_transfer_target_mut(); target[addr as usize] = data[0]; target[addr as usize + 1] = data[1]; } diff --git a/src/peripherals/mc68681.rs b/src/peripherals/mc68681.rs index a665152..e92db0d 100644 --- a/src/peripherals/mc68681.rs +++ b/src/peripherals/mc68681.rs @@ -1,7 +1,7 @@ use crate::error::Error; use crate::system::System; -use crate::devices::{ClockElapsed, Address, Steppable, Addressable, Transmutable, MAX_READ}; +use crate::devices::{ClockElapsed, Address, Steppable, Addressable, Transmutable}; use crate::host::traits::Tty; diff --git a/src/peripherals/trs80/model1.rs b/src/peripherals/trs80/model1.rs index 6f49dd8..75c7664 100644 --- a/src/peripherals/trs80/model1.rs +++ b/src/peripherals/trs80/model1.rs @@ -1,5 +1,4 @@ -use std::slice::Iter; use std::sync::{Arc, Mutex}; use crate::error::Error; @@ -7,7 +6,7 @@ use crate::system::System; use crate::devices::{ClockElapsed, Address, Addressable, Steppable, Transmutable}; use crate::host::keys::Key; -use crate::host::gfx::{Frame, FrameSwapper}; +use crate::host::gfx::{FrameSwapper}; use crate::host::traits::{Host, BlitableSurface, KeyboardUpdater}; use super::keymap; @@ -48,7 +47,7 @@ impl KeyboardUpdater for Model1KeyboardUpdater { } impl Steppable for Model1Peripherals { - fn step(&mut self, system: &System) -> Result { + fn step(&mut self, _system: &System) -> Result { let mut swapper = self.swapper.lock().unwrap(); swapper.current.clear(0); for y in 0..16 { diff --git a/src/system.rs b/src/system.rs index b51f599..d7fa399 100644 --- a/src/system.rs +++ b/src/system.rs @@ -7,7 +7,7 @@ use crate::memory::Bus; use crate::debugger::Debugger; use crate::error::{Error, ErrorType}; use crate::interrupts::InterruptController; -use crate::devices::{Clock, ClockElapsed, Address, TransmutableBox}; +use crate::devices::{Clock, Address, TransmutableBox}; pub struct System { @@ -45,11 +45,17 @@ impl System { self.interrupt_controller.borrow_mut() } + pub fn add_device(&mut self, name: &str, device: TransmutableBox) -> Result<(), Error> { + self.try_queue_device(device.clone()); + self.devices.insert(name.to_string(), device); + Ok(()) + } + pub fn add_addressable_device(&mut self, addr: Address, device: TransmutableBox) -> Result<(), Error> { let length = device.borrow_mut().as_addressable().unwrap().len(); self.bus.borrow_mut().insert(addr, length, device.clone()); self.try_queue_device(device.clone()); - self.devices.insert(format!("ram{:x}", addr), device); + self.devices.insert(format!("mem{:x}", addr), device); Ok(()) } @@ -108,7 +114,7 @@ impl System { } pub fn run_loop(&mut self) { - self.run_for(u64::MAX); + self.run_for(u64::MAX).unwrap(); } pub fn exit_error(&mut self) { diff --git a/todo.txt b/todo.txt index 3d4c6fa..0701f19 100644 --- a/todo.txt +++ b/todo.txt @@ -1,25 +1,19 @@ * the overflow bit is only correct for addition but not subtraction... in subtraction, two positives can result in a negative and vice versa +* we need better m68k tests. Can we do what we did for Z80, with maybe a reduced test state and/or different states for different types of tests +* maybe see about a Mac 128k or something - - -* could have a remapper device, which takes a big swath of addresses in and maps them to another set of addresses (for Mac VIA generic to bus-hookup-in-mac adapter) -* how can you do devices that change their address map during operation, like mac which puts rom at 0 and ram at 600000 temporarily -* i need a better way of handling disperate reads/writes to I/O spaces, rather than having multiple devices or having a massive chunk of address space allocated, continuously -* should you modify Addressable to also take the absolute address as input? I'm thinking of how the same device could be mapped to multiple addresses in memory instead - of taking up a whole range of addresses -* could you use a generic sharable signal thing for sharing data, such as the VIA in mac128 where a single output bit determines the video mode (which would be a separate device) - So both could share the same Signal, one setting it and the other reading it, but how would you actually configure/build that? - - -* make it possible to specify the rom on the command line. Would this be machine specific? -* make the frontend resize its window based on the frame swapper -* make it possible to set the frame sizes when creating the frame swapper * should you rename devices.rs traits.rs? -* maybe see about a Mac 128k or something +* how can you do devices that change their address map during operation, like mac which puts rom at 0 and ram at 600000 temporarily +* i need a better way of handling disperate reads/writes to I/O spaces, rather than having multiple devices or having a massive chunk of address space allocated, continuously +* should you modify Addressable to also take the absolute address as input? I'm thinking of how the same device could be mapped to multiple addresses in memory instead + of taking up a whole range of addresses +* could have a remapper device, which takes a big swath of addresses in and maps them to another set of addresses (for Mac VIA generic to bus-hookup-in-mac adapter) +* could you use a generic sharable signal thing for sharing data, such as the VIA in mac128 where a single output bit determines the video mode (which would be a separate device) + So both could share the same Signal, one setting it and the other reading it, but how would you actually configure/build that? * you could modify read()/write() in Addressable to return the number of bytes read or written for dynamic bus sizing used by the MC68020+ @@ -50,6 +44,5 @@ Z80: * how can you have multiple CPUs -* each device that can make a bus request should have a BusPort which is used to access the bus * can you eventually make the system connections all configurable via a config file?