diff --git a/emulator/core/Cargo.toml b/emulator/core/Cargo.toml index ec434d7..fa3cda6 100644 --- a/emulator/core/Cargo.toml +++ b/emulator/core/Cargo.toml @@ -8,4 +8,4 @@ log = "0.4" femtos = "0.1" thiserror = "1.0" moa-host = { path = "../libraries/host" } -emulator-hal = { path = "../libraries/emulator-hal/emulator-hal" } +emulator-hal = { path = "../libraries/emulator-hal/emulator-hal", features = ["femtos"] } diff --git a/emulator/cpus/z80/src/execute.rs b/emulator/cpus/z80/src/execute.rs index 7475ed5..630233e 100644 --- a/emulator/cpus/z80/src/execute.rs +++ b/emulator/cpus/z80/src/execute.rs @@ -82,9 +82,9 @@ where } pub(crate) fn step_one(&mut self) -> Result { - let clocks = if self.signals.reset { + let clocks = if self.signals.reset.get() { self.reset()? - } else if self.signals.bus_request { + } else if self.signals.bus_request.get() { 4 } else { self.step_internal()? diff --git a/emulator/cpus/z80/src/lib.rs b/emulator/cpus/z80/src/lib.rs index bbaa30f..00e053b 100644 --- a/emulator/cpus/z80/src/lib.rs +++ b/emulator/cpus/z80/src/lib.rs @@ -3,10 +3,13 @@ mod decode; mod emuhal; mod execute; mod instructions; -mod moa; mod state; mod timing; +//#[cfg(feature = "moa")] +pub mod moa; +pub use crate::moa::MoaZ80; + pub use crate::state::{Z80, Z80Type, Z80Error, Z80State, Status, Flags}; pub use crate::decode::Z80Decoder; pub use crate::execute::Z80Cycle; diff --git a/emulator/cpus/z80/src/moa.rs b/emulator/cpus/z80/src/moa.rs index ef99dca..ea12221 100644 --- a/emulator/cpus/z80/src/moa.rs +++ b/emulator/cpus/z80/src/moa.rs @@ -1,36 +1,45 @@ -use std::any::Any; +use std::rc::Rc; +use std::cell::RefCell; use femtos::{Instant, Duration}; use emulator_hal::{BusAdapter, Instant as EmuInstant}; -use moa_core::{System, Error, Address, Steppable, Addressable, Interruptable, Signalable, Signal, Debuggable, Transmutable}; +use moa_core::{System, Error, Bus, Address, Steppable, Addressable, Interruptable, Signalable, Signal, Debuggable, Transmutable}; use crate::{Z80, Z80Error, Z80Decoder}; use crate::instructions::Register; -impl Steppable for Z80 +pub struct MoaZ80 +where + Instant: EmuInstant, +{ + pub bus: Rc>, + pub cpu: Z80, +} + +impl Steppable for MoaZ80 where Instant: EmuInstant, { fn step(&mut self, system: &System) -> Result { - let bus = &mut *system.bus.borrow_mut(); + let mut bus = &mut *self.bus.borrow_mut(); let mut adapter = BusAdapter::new(bus, |addr| addr as u64, |err| Z80Error::BusError(format!("{:?}", err))); - let mut executor = self.begin(system.clock, &mut adapter)?; + let mut executor = self.cpu.begin(system.clock, &mut adapter)?; let clocks = executor.step_one()?; - self.previous_cycle = executor.end(); - Ok(Instant::hertz_to_duration(self.frequency.as_hz() as u64) * clocks as u32) + self.cpu.previous_cycle = executor.end(); + Ok(Instant::hertz_to_duration(self.cpu.frequency.as_hz() as u64) * clocks as u32) } fn on_error(&mut self, system: &System) { 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); + self.cpu.dump_state(system.clock, &mut adapter); } } -impl Interruptable for Z80 {} - +impl Interruptable for MoaZ80 {} +/* impl Signalable for Z80 { fn set_signal(&mut self, signal: Signal, flag: bool) -> Result<(), Error> { match signal { @@ -47,8 +56,9 @@ impl Signalable for Z80 { } } } +*/ -impl Transmutable for Z80 { +impl Transmutable for MoaZ80 { fn as_steppable(&mut self) -> Option<&mut dyn Steppable> { Some(self) } @@ -61,10 +71,10 @@ impl Transmutable for Z80 { Some(self) } - #[inline] - fn as_signalable(&mut self) -> Option<&mut dyn Signalable> { - Some(self) - } + //#[inline] + //fn as_signalable(&mut self) -> Option<&mut dyn Signalable> { + // Some(self) + //} } impl From for Error { @@ -88,14 +98,14 @@ impl From for Z80Error { } } -impl Debuggable for Z80 { +impl Debuggable for MoaZ80 { fn add_breakpoint(&mut self, addr: Address) { - self.debugger.breakpoints.push(addr as u16); + self.cpu.debugger.breakpoints.push(addr as u16); } fn remove_breakpoint(&mut self, addr: Address) { - if let Some(index) = self.debugger.breakpoints.iter().position(|a| *a == addr as u16) { - self.debugger.breakpoints.remove(index); + if let Some(index) = self.cpu.debugger.breakpoints.iter().position(|a| *a == addr as u16) { + self.cpu.debugger.breakpoints.remove(index); } } @@ -103,9 +113,9 @@ impl Debuggable for Z80 { let bus = &mut *system.bus.borrow_mut(); 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)?; - self.previous_cycle.decoder.dump_decoded(&mut adapter); - self.dump_state(system.clock, &mut adapter); + let decoder = Z80Decoder::decode_at(&mut adapter, system.clock, self.cpu.state.pc)?; + self.cpu.previous_cycle.decoder.dump_decoded(&mut adapter); + self.cpu.dump_state(system.clock, &mut adapter); Ok(()) } @@ -118,7 +128,7 @@ impl Debuggable for Z80 { fn run_command(&mut self, _system: &System, args: &[&str]) -> Result { match args[0] { - "l" => self.state.reg[Register::L as usize] = 0x05, + "l" => self.cpu.state.reg[Register::L as usize] = 0x05, _ => { return Ok(true); }, diff --git a/emulator/cpus/z80/src/state.rs b/emulator/cpus/z80/src/state.rs index 614c9e2..7a6be75 100644 --- a/emulator/cpus/z80/src/state.rs +++ b/emulator/cpus/z80/src/state.rs @@ -94,8 +94,10 @@ impl Z80State { #[derive(Clone, Debug, Default)] pub struct Z80Signals { - pub reset: bool, - pub bus_request: bool, + //pub reset: bool, + //pub bus_request: bool, + pub reset: Signal, + pub bus_request: Signal, } #[derive(Clone, Debug, thiserror::Error)] diff --git a/emulator/libraries/signals/src/lib.rs b/emulator/libraries/signals/src/lib.rs index 7c9f331..a79e495 100644 --- a/emulator/libraries/signals/src/lib.rs +++ b/emulator/libraries/signals/src/lib.rs @@ -19,7 +19,7 @@ type Input = Signal; #[allow(dead_code)] type TriState = Signal; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct Signal(Rc>); impl Signal { diff --git a/emulator/systems/genesis/src/peripherals/coprocessor.rs b/emulator/systems/genesis/src/peripherals/coprocessor.rs index 89a2986..ab3cf8a 100644 --- a/emulator/systems/genesis/src/peripherals/coprocessor.rs +++ b/emulator/systems/genesis/src/peripherals/coprocessor.rs @@ -1,27 +1,23 @@ use std::rc::Rc; use std::cell::{Cell, RefCell}; -use std::any::Any; use femtos::Instant; -use moa_core::{Bus, Device, Error, Address, Addressable, Signal, Transmutable}; -//use moa_signals::Signal; -use moa_z80::Z80; +use moa_core::{Bus, Error, Address, Addressable, Transmutable}; +use moa_signals::Signal; const DEV_NAME: &str = "coprocessor"; pub struct CoprocessorCoordinator { - z80: Device, - //bus_request: Signal, - //reset: Signal, + bus_request: Signal, + reset: Signal, } impl CoprocessorCoordinator { - pub fn new(z80: Device) -> Self { + pub fn new(reset: Signal, bus_request: Signal) -> Self { Self { - z80, - //bus_request, - //reset, + bus_request, + reset, } } } @@ -34,9 +30,7 @@ impl Addressable for CoprocessorCoordinator { fn read(&mut self, _clock: Instant, addr: Address, data: &mut [u8]) -> Result<(), Error> { match addr { 0x100 => { - 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) { + data[0] = if self.bus_request.get() && self.reset.get() { 0x01 } else { 0x00 @@ -55,14 +49,10 @@ impl Addressable for CoprocessorCoordinator { match addr { 0x000 => { /* ROM vs DRAM mode */ }, 0x100 => { - let mut device = self.z80.borrow_mut(); - let z80 = device.as_signalable().unwrap(); - z80.set_signal(Signal::BusRequest, data[0] == 0)?; + self.bus_request.set(data[0] != 0); }, 0x200 => { - let mut device = self.z80.borrow_mut(); - let z80 = device.as_signalable().unwrap(); - z80.set_signal(Signal::Reset, data[0] == 0)?; + self.reset.set(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 e9cffec..bcc4b5c 100644 --- a/emulator/systems/genesis/src/system.rs +++ b/emulator/systems/genesis/src/system.rs @@ -8,7 +8,7 @@ use moa_core::{System, Error, MemoryBlock, Bus, Address, Addressable, Device}; use moa_host::Host; use moa_m68k::{M68k, M68kType}; -use moa_z80::{Z80, Z80Type}; +use moa_z80::{MoaZ80, Z80, Z80Type}; use moa_peripherals_yamaha::Ym2612; use moa_peripherals_yamaha::Sn76489; @@ -69,13 +69,16 @@ pub fn build_genesis(host: &mut H, mut options: SegaGenesisOptions) -> 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)); - //let mut reset = coproc.reset.clone(); - //let mut bus_request = coproc.bus_request.clone(); - //reset.set(true); - //bus_request.set(true); + let coproc = MoaZ80 { + bus: coproc_bus, + cpu: coproc, + }; + let mut reset = coproc.cpu.signals.reset.clone(); + let mut bus_request = coproc.cpu.signals.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)?; system.add_addressable_device(0x00a04000, coproc_ym_sound)?; @@ -89,7 +92,7 @@ pub fn build_genesis(host: &mut H, mut options: SegaGenesisOptions) -> let interrupt = controllers.get_interrupt_signal(); system.add_addressable_device(0x00a10000, Device::new(controllers))?; - let coproc = CoprocessorCoordinator::new(coproc); + let coproc = CoprocessorCoordinator::new(reset, bus_request); 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 fd4c9ce..8e4cdee 100644 --- a/emulator/systems/trs80/src/system.rs +++ b/emulator/systems/trs80/src/system.rs @@ -3,7 +3,7 @@ use femtos::Frequency; use moa_core::{System, Error, MemoryBlock, Device}; use moa_host::Host; -use moa_z80::{Z80, Z80Type}; +use moa_z80::{MoaZ80, Z80, Z80Type}; use crate::peripherals::model1::{Model1Keyboard, Model1Video}; @@ -45,6 +45,10 @@ pub fn build_trs80(host: &mut H, options: Trs80Options) -> Result