diff --git a/Cargo.lock b/Cargo.lock index c8201a5..be66a2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1247,9 +1247,10 @@ name = "rad-tests" version = "0.1.0" dependencies = [ "clap 3.2.25", + "emulator-hal", + "emulator-hal-memory", "femtos", "flate2", - "moa-core", "moa-z80", "serde", "serde_derive", diff --git a/emulator/core/src/devices.rs b/emulator/core/src/devices.rs index 6ffae86..3f46c4c 100644 --- a/emulator/core/src/devices.rs +++ b/emulator/core/src/devices.rs @@ -171,6 +171,16 @@ pub trait Inspectable { fn inspect(&mut self, system: &System, args: &[&str]) -> Result<(), Error>; } +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum Signal { + Reset, + BusRequest, +} + +pub trait Signalable { + fn set_signal(&mut self, signal: Signal, flag: bool) -> Result<(), Error>; + fn signal(&mut self, signal: Signal) -> Option; +} pub trait Transmutable { #[inline] @@ -197,6 +207,11 @@ pub trait Transmutable { fn as_inspectable(&mut self) -> Option<&mut dyn Inspectable> { None } + + #[inline] + fn as_signalable(&mut self) -> Option<&mut dyn Signalable> { + None + } } pub type TransmutableBox = Rc>>; diff --git a/emulator/core/src/lib.rs b/emulator/core/src/lib.rs index c0c332f..a13dc08 100644 --- a/emulator/core/src/lib.rs +++ b/emulator/core/src/lib.rs @@ -7,7 +7,8 @@ mod memory; mod system; pub use crate::devices::{ - Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Transmutable, TransmutableBox, Device, + Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Signalable, Signal, Transmutable, TransmutableBox, + Device, }; pub use crate::devices::{ read_beu16, read_beu32, read_leu16, read_leu32, write_beu16, write_beu32, write_leu16, write_leu32, wrap_transmutable, @@ -17,4 +18,4 @@ pub use crate::interrupts::InterruptController; pub use crate::memory::{MemoryBlock, AddressTranslator, AddressRepeater, Bus, BusPort, dump_slice, dump_memory}; pub use crate::system::System; -pub use emulator_hal::bus::{BusAccess}; +pub use emulator_hal::BusAccess; diff --git a/emulator/core/src/memory.rs b/emulator/core/src/memory.rs index b5e545b..fd5d38d 100644 --- a/emulator/core/src/memory.rs +++ b/emulator/core/src/memory.rs @@ -4,6 +4,7 @@ use std::rc::Rc; use std::cell::RefCell; use std::fmt::Write; use femtos::Instant; +use emulator_hal::{self, BusAccess, Error as EmuError}; use crate::error::Error; use crate::devices::{Address, Addressable, Transmutable, Device, read_beu16}; @@ -236,7 +237,7 @@ impl Bus { let to = if count < 16 { count / 2 } else { 8 }; for _ in 0..to { - let word = self.read_beu16(clock, addr); + let word = Addressable::read_beu16(self, clock, addr); if word.is_err() { println!("{}", line); return; @@ -353,7 +354,7 @@ impl Addressable for BusPort { for i in (0..data.len()).step_by(self.data_width as usize) { let addr_index = (addr + i as Address) & self.address_mask; let end = cmp::min(i + self.data_width as usize, data.len()); - subdevice.read(clock, addr_index, &mut data[i..end])?; + Addressable::read(&mut *subdevice, clock, addr_index, &mut data[i..end])?; } Ok(()) } @@ -364,7 +365,7 @@ impl Addressable for BusPort { for i in (0..data.len()).step_by(self.data_width as usize) { let addr_index = (addr + i as Address) & self.address_mask; let end = cmp::min(i + self.data_width as usize, data.len()); - subdevice.write(clock, addr_index, &data[i..end])?; + Addressable::write(&mut *subdevice, clock, addr_index, &data[i..end])?; } Ok(()) } @@ -412,9 +413,7 @@ where } } -use emulator_hal::bus::{self, BusAccess}; - -impl bus::Error for Error {} +impl EmuError for Error {} impl BusAccess for &mut dyn Addressable { type Instant = Instant; @@ -430,3 +429,18 @@ impl BusAccess for &mut dyn Addressable { Ok(data.len()) } } + +impl BusAccess for Bus { + type Instant = Instant; + type Error = Error; + + fn read(&mut self, now: Instant, addr: Address, data: &mut [u8]) -> Result { + Addressable::read(self, now, addr, data)?; + Ok(data.len()) + } + + fn write(&mut self, now: Instant, addr: Address, data: &[u8]) -> Result { + Addressable::write(self, now, addr, data)?; + Ok(data.len()) + } +} diff --git a/emulator/cpus/z80/src/decode.rs b/emulator/cpus/z80/src/decode.rs index 8dde2b1..330ed77 100644 --- a/emulator/cpus/z80/src/decode.rs +++ b/emulator/cpus/z80/src/decode.rs @@ -1,7 +1,7 @@ use core::fmt::Write; use emulator_hal::{BusAccess, Instant as EmuInstant}; -use crate::state::{Z80Error, Z80Address} ; +use crate::state::{Z80Error, Z80Address}; use crate::instructions::{ Direction, Condition, Register, RegisterPair, IndexRegister, IndexRegisterHalf, SpecialRegister, InterruptMode, Target, LoadTarget, UndocumentedCopy, Instruction, @@ -55,27 +55,16 @@ impl Z80Decoder { Ok(decoder.decoder) } - /* - pub fn format_instruction_bytes(&mut self) -> String { - let mut ins_data = String::new(); - for offset in 0..self.decoder.end.saturating_sub(self.decoder.start) { - write!(ins_data, "{:02x} ", self.bus.read_u8(self.clock, self.decoder.start + offset).unwrap()).unwrap() - } - ins_data - } - - pub fn dump_decoded(&mut self) { - let ins_data = self.format_instruction_bytes(); - println!("{:#06x}: {}\n\t{:?}\n", self.decoder.start, ins_data, self.decoder.instruction); - } - - pub fn dump_disassembly(&mut self, start: Z80Address, length: Z80Address) { + pub fn dump_disassembly(bus: &mut Bus, start: Z80Address, length: Z80Address) + where + Bus: BusAccess, + { let mut next = start; while next < (start + length) { - match self.decode_at(self.clock, next) { - Ok(()) => { - self.dump_decoded(); - next = self.decoder.end; + match Z80Decoder::decode_at(bus, Bus::Instant::START, next) { + Ok(mut decoder) => { + decoder.dump_decoded(bus); + next = decoder.end; }, Err(err) => { println!("{:?}", err); @@ -84,7 +73,25 @@ impl Z80Decoder { } } } - */ + + pub fn dump_decoded(&mut self, bus: &mut Bus) + where + Bus: BusAccess, + { + let ins_data = self.format_instruction_bytes(bus); + println!("{:#06x}: {}\n\t{:?}\n", self.start, ins_data, self.instruction); + } + + pub fn format_instruction_bytes(&mut self, bus: &mut Bus) -> String + where + Bus: BusAccess, + { + let mut ins_data = String::new(); + for offset in 0..self.end.saturating_sub(self.start) { + write!(ins_data, "{:02x} ", bus.read_u8(Bus::Instant::START, self.start + offset).unwrap()).unwrap() + } + ins_data + } } pub struct DecodeNext<'a, Bus, Instant> @@ -107,11 +114,7 @@ where Ok(()) } - pub fn decode_bare( - &mut self, - ins: u8, - extra_instruction_bytes: u16, - ) -> Result { + pub fn decode_bare(&mut self, ins: u8, extra_instruction_bytes: u16) -> Result { self.decoder.extra_instruction_bytes = extra_instruction_bytes; match get_ins_x(ins) { 0 => match get_ins_z(ins) { @@ -559,11 +562,7 @@ where } } - fn decode_index_target( - &mut self, - index_reg: IndexRegister, - z: u8, - ) -> Result, Z80Error> { + fn decode_index_target(&mut self, index_reg: IndexRegister, z: u8) -> Result, Z80Error> { let result = match z { 4 => Some(Target::DirectRegHalf(get_index_register_half(index_reg, 0))), 5 => Some(Target::DirectRegHalf(get_index_register_half(index_reg, 1))), @@ -578,7 +577,9 @@ where fn read_instruction_byte(&mut self) -> Result { - let byte = self.bus.read_u8(self.clock, self.decoder.end) + let byte = self + .bus + .read_u8(self.clock, self.decoder.end) .map_err(|err| Z80Error::BusError(format!("{:?}", err)))?; self.decoder.end = self.decoder.end.wrapping_add(1); Ok(byte) @@ -587,7 +588,9 @@ where fn read_instruction_word(&mut self) -> Result { let mut bytes = [0; 2]; for byte in bytes.iter_mut() { - *byte = self.bus.read_u8(self.clock, self.decoder.end & 0xFFFF) + *byte = self + .bus + .read_u8(self.clock, self.decoder.end & 0xFFFF) .map_err(|err| Z80Error::BusError(format!("{:?}", err)))?; self.decoder.end = self.decoder.end.wrapping_add(1); } diff --git a/emulator/cpus/z80/src/emuhal.rs b/emulator/cpus/z80/src/emuhal.rs index 82154f1..1651ee2 100644 --- a/emulator/cpus/z80/src/emuhal.rs +++ b/emulator/cpus/z80/src/emuhal.rs @@ -1,4 +1,3 @@ - use emulator_hal::{BusAccess, Instant as EmuInstant, Error as EmuError, Step, Inspect, Debug, IntoAddress}; use crate::state::{Z80, Z80Error, Z80Address, Status}; @@ -23,10 +22,9 @@ where fn step(&mut self, now: Self::Instant, bus: &mut Bus) -> Result { let mut executor = self.begin(now, bus)?; - executor.step_one()?; + let clocks = executor.step_one()?; self.previous_cycle = executor.end(); - // TODO fix this - Ok(now) + Ok(now + Instant::hertz_to_duration(self.frequency.as_hz() as u64) * clocks as u32) } } @@ -51,11 +49,9 @@ where fn step(&mut self, now: Self::Instant, bus: (&mut MemBus, &mut IoBus)) -> Result { let executor = self.begin(now, bus)?; - executor.step_one()?; + let clocks = executor.step_one()?; self.previous_cycle = executor.end(); - // TODO fix this - Ok(now) + Ok(now + Instant::hertz_to_duration(self.frequency.as_hz() as u64) * clocks as u32) } } */ - diff --git a/emulator/cpus/z80/src/execute.rs b/emulator/cpus/z80/src/execute.rs index 171705d..7475ed5 100644 --- a/emulator/cpus/z80/src/execute.rs +++ b/emulator/cpus/z80/src/execute.rs @@ -5,7 +5,7 @@ use crate::instructions::{ Condition, Instruction, LoadTarget, Target, Register, InterruptMode, RegisterPair, IndexRegister, SpecialRegister, IndexRegisterHalf, Size, Direction, UndocumentedCopy, }; -use crate::state::{Z80, Z80Error, Z80State, Z80Address, Status, Flags}; +use crate::state::{Z80, Z80Error, Z80State, Z80Signals, Z80Address, Status, Flags}; use crate::timing::Z80InstructionCycles; use crate::debugger::Z80Debugger; @@ -41,12 +41,17 @@ impl Z80 where Instant: EmuInstant, { - pub(crate) fn begin<'a, Bus>(&'a mut self, clock: Instant, bus: &'a mut Bus) -> Result, Z80Error> + pub(crate) fn begin<'a, Bus>( + &'a mut self, + clock: Instant, + bus: &'a mut Bus, + ) -> Result, Z80Error> where Bus: BusAccess, { let executor = ExecuteNext { state: &mut self.state, + signals: &mut self.signals, debugger: &mut self.debugger, cycle: Z80Cycle::at_time(clock), bus, @@ -61,6 +66,7 @@ where Bus: BusAccess, { state: &'a mut Z80State, + signals: &'a mut Z80Signals, debugger: &'a mut Z80Debugger, cycle: Z80Cycle, bus: Bus, @@ -71,28 +77,22 @@ where Bus: BusAccess, Instant: EmuInstant, { - pub(crate) fn end(mut self) -> Z80Cycle { + pub(crate) fn end(self) -> Z80Cycle { self.cycle } pub(crate) fn step_one(&mut self) -> Result { - // TODO restore the reset and bus request signals - //let clocks = if self.reset.get() { - // self.reset()? - //} else if self.bus_request.get() { - // 4 - //} else { - // self.step_internal(self.cycle.current_clock)? - //}; - - //Ok(self.frequency.period_duration() * clocks as u64) - - // TODO remove this when done - let clocks = self.step_internal(self.cycle.current_clock)?; + let clocks = if self.signals.reset { + self.reset()? + } else if self.signals.bus_request { + 4 + } else { + self.step_internal()? + }; Ok(clocks) } - fn step_internal(&mut self, clock: Instant) -> Result { + fn step_internal(&mut self) -> Result { match self.state.status { Status::Init => self.init(), Status::Halted => Err(Z80Error::Halted), @@ -630,7 +630,9 @@ where let parity = if count != 0 { Flags::Parity as u8 } else { 0 }; self.set_flags(mask, parity); - if (self.cycle.decoder.instruction == Instruction::LDIR || self.cycle.decoder.instruction == Instruction::LDDR) && count != 0 { + if (self.cycle.decoder.instruction == Instruction::LDIR || self.cycle.decoder.instruction == Instruction::LDDR) + && count != 0 + { self.cycle.took_branch = true; self.state.pc -= 2; } @@ -1126,13 +1128,17 @@ where fn read_port_u8(&mut self, addr: u16) -> Result { self.increment_refresh(1); - Ok(self.bus.read_u8(self.cycle.current_clock, addr as Z80Address) + Ok(self + .bus + .read_u8(self.cycle.current_clock, addr as Z80Address) .map_err(|err| Z80Error::BusError(format!("{:?}", err)))?) } fn write_port_u8(&mut self, addr: u16, value: u8) -> Result<(), Z80Error> { self.increment_refresh(1); - Ok(self.bus.write_u8(self.cycle.current_clock, addr as Z80Address, value) + Ok(self + .bus + .write_u8(self.cycle.current_clock, addr as Z80Address, value) .map_err(|err| Z80Error::BusError(format!("{:?}", err)))?) } @@ -1144,7 +1150,9 @@ where let mut bytes = [0; 2]; for byte in bytes.iter_mut() { self.increment_refresh(1); - *byte = self.bus.read_u8(self.cycle.current_clock, addr & 0xFFFF) + *byte = self + .bus + .read_u8(self.cycle.current_clock, addr & 0xFFFF) .map_err(|err| Z80Error::BusError(format!("{:?}", err)))?; addr = addr.wrapping_add(1); } @@ -1159,7 +1167,8 @@ where let mut bytes = value.to_le_bytes(); for byte in bytes.iter_mut() { self.increment_refresh(1); - self.bus.write_u8(self.cycle.current_clock, addr & 0xFFFF, *byte) + self.bus + .write_u8(self.cycle.current_clock, addr & 0xFFFF, *byte) .map_err(|err| Z80Error::BusError(format!("{:?}", err)))?; addr = addr.wrapping_add(1); } @@ -1172,7 +1181,7 @@ where //if let Some(io) = self.ioport.as_mut() { // Ok(io.read_u8(self.cycle.current_clock, addr)?) //} else { - Ok(0) + Ok(0) //} } diff --git a/emulator/cpus/z80/src/lib.rs b/emulator/cpus/z80/src/lib.rs index f7e857d..bbaa30f 100644 --- a/emulator/cpus/z80/src/lib.rs +++ b/emulator/cpus/z80/src/lib.rs @@ -1,11 +1,11 @@ mod debugger; mod decode; +mod emuhal; mod execute; mod instructions; +mod moa; mod state; mod timing; -mod moa; -mod emuhal; pub use crate::state::{Z80, Z80Type, Z80Error, Z80State, Status, Flags}; pub use crate::decode::Z80Decoder; diff --git a/emulator/cpus/z80/src/moa.rs b/emulator/cpus/z80/src/moa.rs index d8e573f..ef99dca 100644 --- a/emulator/cpus/z80/src/moa.rs +++ b/emulator/cpus/z80/src/moa.rs @@ -1,8 +1,8 @@ - +use std::any::Any; use femtos::{Instant, Duration}; use emulator_hal::{BusAdapter, Instant as EmuInstant}; -use moa_core::{System, Error, Address, Steppable, Addressable, Interruptable, Debuggable, Transmutable}; +use moa_core::{System, Error, Address, Steppable, Addressable, Interruptable, Signalable, Signal, Debuggable, Transmutable}; use crate::{Z80, Z80Error, Z80Decoder}; use crate::instructions::Register; @@ -22,13 +22,32 @@ where } fn on_error(&mut self, system: &System) { - self.dump_state(system.clock); + let bus = &mut *system.bus.borrow_mut(); + let mut adapter = BusAdapter::new(bus, |addr| addr as u64, |err| Z80Error::BusError(format!("{:?}", err))); + self.dump_state(system.clock, &mut adapter); } } impl Interruptable for Z80 {} +impl Signalable for Z80 { + fn set_signal(&mut self, signal: Signal, flag: bool) -> Result<(), Error> { + match signal { + Signal::Reset => self.signals.reset = flag, + Signal::BusRequest => self.signals.bus_request = flag, + } + Ok(()) + } + + fn signal(&mut self, signal: Signal) -> Option { + match signal { + Signal::Reset => Some(self.signals.reset), + Signal::BusRequest => Some(self.signals.bus_request), + } + } +} + impl Transmutable for Z80 { fn as_steppable(&mut self) -> Option<&mut dyn Steppable> { Some(self) @@ -41,6 +60,11 @@ impl Transmutable for Z80 { fn as_debuggable(&mut self) -> Option<&mut dyn Debuggable> { Some(self) } + + #[inline] + fn as_signalable(&mut self) -> Option<&mut dyn Signalable> { + Some(self) + } } impl From for Error { @@ -80,16 +104,16 @@ impl Debuggable for Z80 { let mut adapter = BusAdapter::new(bus, |addr| addr as u64, |err| Z80Error::BusError(format!("{:?}", err))); let decoder = Z80Decoder::decode_at(&mut adapter, system.clock, self.state.pc)?; - // TODO disabled until decoder is fixed - //self.decoder.dump_decoded(&mut self.port); - self.dump_state(system.clock); + self.previous_cycle.decoder.dump_decoded(&mut adapter); + self.dump_state(system.clock, &mut adapter); Ok(()) } - fn print_disassembly(&mut self, _system: &System, addr: Address, count: usize) { - // TODO disabled until decoder is fixed - //let mut decoder = Z80Decoder::default(); - //decoder.dump_disassembly(&mut self.port, addr as u16, count as u16); + fn print_disassembly(&mut self, system: &System, addr: Address, count: usize) { + let bus = &mut *system.bus.borrow_mut(); + let mut adapter = BusAdapter::new(bus, |addr| addr as u64, |err| Z80Error::BusError(format!("{:?}", err))); + + Z80Decoder::dump_disassembly(&mut adapter, addr as u16, count as u16); } fn run_command(&mut self, _system: &System, args: &[&str]) -> Result { @@ -102,5 +126,3 @@ impl Debuggable for Z80 { Ok(false) } } - - diff --git a/emulator/cpus/z80/src/state.rs b/emulator/cpus/z80/src/state.rs index 6091980..614c9e2 100644 --- a/emulator/cpus/z80/src/state.rs +++ b/emulator/cpus/z80/src/state.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use std::cell::RefCell; use femtos::{Instant, Frequency}; -use emulator_hal::Instant as EmuInstant; +use emulator_hal::{Instant as EmuInstant, BusAccess}; use moa_core::{Address, Bus, BusPort}; use moa_signals::Signal; @@ -92,6 +92,12 @@ impl Z80State { } } +#[derive(Clone, Debug, Default)] +pub struct Z80Signals { + pub reset: bool, + pub bus_request: bool, +} + #[derive(Clone, Debug, thiserror::Error)] pub enum Z80Error /* */ { #[error("cpu halted")] @@ -120,8 +126,7 @@ pub struct Z80 { pub state: Z80State, pub debugger: Z80Debugger, pub previous_cycle: Z80Cycle, - //pub port: BusPort, - //pub ioport: Option, + pub signals: Z80Signals, // TODO activate later //pub reset: Signal, //pub bus_request: Signal, @@ -131,34 +136,22 @@ impl Z80 where Instant: EmuInstant, { - pub fn new(cputype: Z80Type, frequency: Frequency /*, port: BusPort, ioport: Option*/) -> Self { + pub fn new(cputype: Z80Type, frequency: Frequency) -> Self { Self { cputype, frequency, state: Z80State::default(), debugger: Z80Debugger::default(), previous_cycle: Z80Cycle::at_time(Instant::START), - //port, - //ioport, + signals: Z80Signals::default(), //reset: Signal::new(false), //bus_request: Signal::new(false), } } - pub fn from_type( - cputype: Z80Type, - frequency: Frequency, - bus: Rc>, - addr_offset: Address, - io_bus: Option<(Rc>, Address)>, - ) -> Self { + pub fn from_type(cputype: Z80Type, frequency: Frequency) -> Self { match cputype { - Z80Type::Z80 => Self::new( - cputype, - frequency, - //BusPort::new(addr_offset, 16, 8, bus), - //io_bus.map(|(io_bus, io_offset)| BusPort::new(io_offset, 16, 8, io_bus)), - ), + Z80Type::Z80 => Self::new(cputype, frequency), } } @@ -168,7 +161,10 @@ where self.debugger = Z80Debugger::default(); } - pub fn dump_state(&mut self, clock: Instant) { + pub fn dump_state(&mut self, clock: Instant, bus: &mut Bus) + where + Bus: BusAccess, + { println!("Status: {:?}", self.state.status); println!("PC: {:#06x}", self.state.pc); println!("SP: {:#06x}", self.state.sp); @@ -207,12 +203,11 @@ where println!("I: {:#04x} R: {:#04x}", self.state.i, self.state.r); println!("IM: {:?} IFF1: {:?} IFF2: {:?}", self.state.im, self.state.iff1, self.state.iff2); - // TODO disabled until function is reimplemented - //println!( - // "Current Instruction: {} {:?}", - // self.decoder.format_instruction_bytes(&mut self.port), - // self.decoder.instruction - //); + println!( + "Current Instruction: {} {:?}", + self.previous_cycle.decoder.format_instruction_bytes(bus), + self.previous_cycle.decoder.instruction + ); println!("Previous Instruction: {:?}", self.previous_cycle.decoder.instruction); println!(); // TODO disabled until function is reimplemented diff --git a/emulator/systems/genesis/src/peripherals/coprocessor.rs b/emulator/systems/genesis/src/peripherals/coprocessor.rs index ab3cf8a..89a2986 100644 --- a/emulator/systems/genesis/src/peripherals/coprocessor.rs +++ b/emulator/systems/genesis/src/peripherals/coprocessor.rs @@ -1,23 +1,27 @@ use std::rc::Rc; use std::cell::{Cell, RefCell}; +use std::any::Any; use femtos::Instant; -use moa_core::{Bus, Error, Address, Addressable, Transmutable}; -use moa_signals::Signal; +use moa_core::{Bus, Device, Error, Address, Addressable, Signal, Transmutable}; +//use moa_signals::Signal; +use moa_z80::Z80; const DEV_NAME: &str = "coprocessor"; pub struct CoprocessorCoordinator { - bus_request: Signal, - reset: Signal, + z80: Device, + //bus_request: Signal, + //reset: Signal, } impl CoprocessorCoordinator { - pub fn new(reset: Signal, bus_request: Signal) -> Self { + pub fn new(z80: Device) -> Self { Self { - bus_request, - reset, + z80, + //bus_request, + //reset, } } } @@ -30,7 +34,9 @@ impl Addressable for CoprocessorCoordinator { fn read(&mut self, _clock: Instant, addr: Address, data: &mut [u8]) -> Result<(), Error> { match addr { 0x100 => { - data[0] = if self.bus_request.get() && self.reset.get() { + let mut device = self.z80.borrow_mut(); + let z80 = device.as_signalable().unwrap(); + data[0] = if z80.signal(Signal::BusRequest).unwrap_or(false) && z80.signal(Signal::Reset).unwrap_or(false) { 0x01 } else { 0x00 @@ -49,10 +55,14 @@ impl Addressable for CoprocessorCoordinator { match addr { 0x000 => { /* ROM vs DRAM mode */ }, 0x100 => { - self.bus_request.set(data[0] != 0); + let mut device = self.z80.borrow_mut(); + let z80 = device.as_signalable().unwrap(); + z80.set_signal(Signal::BusRequest, data[0] == 0)?; }, 0x200 => { - self.reset.set(data[0] == 0); + let mut device = self.z80.borrow_mut(); + let z80 = device.as_signalable().unwrap(); + z80.set_signal(Signal::Reset, data[0] == 0)?; }, _ => { log::warn!("{}: !!! unhandled write {:0x} to {:0x}", DEV_NAME, data[0], addr); diff --git a/emulator/systems/genesis/src/system.rs b/emulator/systems/genesis/src/system.rs index d57e2e5..e9cffec 100644 --- a/emulator/systems/genesis/src/system.rs +++ b/emulator/systems/genesis/src/system.rs @@ -2,7 +2,7 @@ use std::mem; use std::rc::Rc; use std::cell::RefCell; -use femtos::Frequency; +use femtos::{Instant, Frequency}; use moa_core::{System, Error, MemoryBlock, Bus, Address, Addressable, Device}; use moa_host::Host; @@ -68,11 +68,13 @@ pub fn build_genesis(host: &mut H, mut options: SegaGenesisOptions) -> coproc_bus.borrow_mut().insert(0x6000, coproc_register.clone()); coproc_bus.borrow_mut().insert(0x7f11, coproc_sn_sound.clone()); coproc_bus.borrow_mut().insert(0x8000, coproc_area); - let coproc = Z80::from_type(Z80Type::Z80, Frequency::from_hz(3_579_545), coproc_bus, 0, None); - let mut reset = coproc.reset.clone(); - let mut bus_request = coproc.bus_request.clone(); - reset.set(true); - bus_request.set(true); + let coproc = Z80::from_type(Z80Type::Z80, Frequency::from_hz(3_579_545)); + //let mut reset = coproc.reset.clone(); + //let mut bus_request = coproc.bus_request.clone(); + //reset.set(true); + //bus_request.set(true); + let coproc = Device::new(coproc); + // Add coprocessor devices to the system bus so the 68000 can access them too system.add_addressable_device(0x00a00000, coproc_ram)?; @@ -80,14 +82,14 @@ pub fn build_genesis(host: &mut H, mut options: SegaGenesisOptions) -> system.add_addressable_device(0x00a06000, coproc_register)?; //system.add_addressable_device(0x00c00010, coproc_sn_sound)?; system.add_device("sn_sound", coproc_sn_sound.clone())?; - system.add_device("coproc", Device::new(coproc))?; + system.add_device("coproc", coproc.clone())?; let controllers = GenesisControllers::new(host)?; let interrupt = controllers.get_interrupt_signal(); system.add_addressable_device(0x00a10000, Device::new(controllers))?; - let coproc = CoprocessorCoordinator::new(reset, bus_request); + let coproc = CoprocessorCoordinator::new(coproc); system.add_addressable_device(0x00a11000, Device::new(coproc))?; let vdp = Ym7101::new(host, interrupt, coproc_sn_sound)?; diff --git a/emulator/systems/trs80/src/system.rs b/emulator/systems/trs80/src/system.rs index d692853..fd4c9ce 100644 --- a/emulator/systems/trs80/src/system.rs +++ b/emulator/systems/trs80/src/system.rs @@ -44,7 +44,7 @@ pub fn build_trs80(host: &mut H, options: Trs80Options) -> Result Result<(Z80, MemoryBlock, MemoryBlock), Error> { +fn init_execute_test( + cputype: Z80Type, + state: &TestState, + ports: &[TestPort], +) -> Result<(Z80, MemoryBlock, MemoryBlock), Error> { // Insert basic initialization let len = 0x1_0000; let mut data = Vec::with_capacity(len); @@ -220,7 +224,8 @@ fn load_state( // Load data bytes into memory for (addr, byte) in initial.ram.iter() { - memory.write_u8(Instant::START, *addr, *byte) + memory + .write_u8(Instant::START, *addr, *byte) .map_err(|err| Error::Bus(format!("{:?}", err)))?; } @@ -281,7 +286,8 @@ fn assert_state( // Load data bytes into memory for (addr, byte) in expected.ram.iter() { - let actual = memory.read_u8(Instant::START, *addr) + let actual = memory + .read_u8(Instant::START, *addr) .map_err(|err| Error::Bus(format!("{:?}", err)))?; assert_value(actual, *byte, &format!("ram at {:x}", addr))?; } @@ -289,7 +295,8 @@ fn assert_state( // Load data bytes into io space for port in ports.iter() { if port.atype == "w" { - let actual = io.read_u8(Instant::START, port.addr) + let actual = io + .read_u8(Instant::START, port.addr) .map_err(|err| Error::Bus(format!("{:?}", err)))?; assert_value(actual, port.value, &format!("port value at {:x}", port.addr))?; } @@ -306,7 +313,8 @@ fn step_cpu_and_assert( args: &Args, ) -> Result<(), Error> { //let clock_elapsed = cpu.step((memory, io))?; - let clock_elapsed = cpu.step(Instant::START, memory) + let clock_elapsed = cpu + .step(Instant::START, memory) .map_err(|err| Error::Step(format!("{:?}", err)))?; assert_state(cpu, memory, io, &case.final_state, args.check_extra_flags, &case.ports)?; @@ -338,8 +346,8 @@ fn run_test(case: &TestCase, args: &Args) -> Result<(), Error> { if args.debug { case.dump(); println!(); - initial_cpu.dump_state(Instant::START); - cpu.dump_state(Instant::START); + initial_cpu.dump_state(Instant::START, &mut memory); + cpu.dump_state(Instant::START, &mut memory); } println!("FAILED: {:?}", err); }