Compare commits

...

2 Commits

Author SHA1 Message Date
transistor fet b34588d73a
Merge 90e617c5de into 6e7e315808 2024-04-13 18:36:08 +00:00
transistor 90e617c5de Fixed genesis Z80 bus issue 2024-04-13 11:35:43 -07:00
9 changed files with 70 additions and 58 deletions

View File

@ -8,4 +8,4 @@ log = "0.4"
femtos = "0.1" femtos = "0.1"
thiserror = "1.0" thiserror = "1.0"
moa-host = { path = "../libraries/host" } moa-host = { path = "../libraries/host" }
emulator-hal = { path = "../libraries/emulator-hal/emulator-hal" } emulator-hal = { path = "../libraries/emulator-hal/emulator-hal", features = ["femtos"] }

View File

@ -82,9 +82,9 @@ where
} }
pub(crate) fn step_one(&mut self) -> Result<u16, Z80Error> { pub(crate) fn step_one(&mut self) -> Result<u16, Z80Error> {
let clocks = if self.signals.reset { let clocks = if self.signals.reset.get() {
self.reset()? self.reset()?
} else if self.signals.bus_request { } else if self.signals.bus_request.get() {
4 4
} else { } else {
self.step_internal()? self.step_internal()?

View File

@ -3,10 +3,13 @@ mod decode;
mod emuhal; mod emuhal;
mod execute; mod execute;
mod instructions; mod instructions;
mod moa;
mod state; mod state;
mod timing; 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::state::{Z80, Z80Type, Z80Error, Z80State, Status, Flags};
pub use crate::decode::Z80Decoder; pub use crate::decode::Z80Decoder;
pub use crate::execute::Z80Cycle; pub use crate::execute::Z80Cycle;

View File

@ -1,36 +1,45 @@
use std::any::Any; use std::rc::Rc;
use std::cell::RefCell;
use femtos::{Instant, Duration}; use femtos::{Instant, Duration};
use emulator_hal::{BusAdapter, Instant as EmuInstant}; 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::{Z80, Z80Error, Z80Decoder};
use crate::instructions::Register; use crate::instructions::Register;
impl Steppable for Z80<Instant> pub struct MoaZ80<Instant>
where
Instant: EmuInstant,
{
pub bus: Rc<RefCell<Bus>>,
pub cpu: Z80<Instant>,
}
impl Steppable for MoaZ80<Instant>
where where
Instant: EmuInstant, Instant: EmuInstant,
{ {
fn step(&mut self, system: &System) -> Result<Duration, Error> { fn step(&mut self, system: &System) -> Result<Duration, Error> {
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 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()?; let clocks = executor.step_one()?;
self.previous_cycle = executor.end(); self.cpu.previous_cycle = executor.end();
Ok(Instant::hertz_to_duration(self.frequency.as_hz() as u64) * clocks as u32) Ok(Instant::hertz_to_duration(self.cpu.frequency.as_hz() as u64) * clocks as u32)
} }
fn on_error(&mut self, system: &System) { fn on_error(&mut self, system: &System) {
let bus = &mut *system.bus.borrow_mut(); let bus = &mut *system.bus.borrow_mut();
let mut adapter = BusAdapter::new(bus, |addr| addr as u64, |err| Z80Error::BusError(format!("{:?}", err))); 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<Instant> {} impl Interruptable for MoaZ80<Instant> {}
/*
impl Signalable for Z80<Instant> { impl Signalable for Z80<Instant> {
fn set_signal(&mut self, signal: Signal, flag: bool) -> Result<(), Error> { fn set_signal(&mut self, signal: Signal, flag: bool) -> Result<(), Error> {
match signal { match signal {
@ -47,8 +56,9 @@ impl Signalable for Z80<Instant> {
} }
} }
} }
*/
impl Transmutable for Z80<Instant> { impl Transmutable for MoaZ80<Instant> {
fn as_steppable(&mut self) -> Option<&mut dyn Steppable> { fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
Some(self) Some(self)
} }
@ -61,10 +71,10 @@ impl Transmutable for Z80<Instant> {
Some(self) Some(self)
} }
#[inline] //#[inline]
fn as_signalable(&mut self) -> Option<&mut dyn Signalable> { //fn as_signalable(&mut self) -> Option<&mut dyn Signalable> {
Some(self) // Some(self)
} //}
} }
impl From<Z80Error> for Error { impl From<Z80Error> for Error {
@ -88,14 +98,14 @@ impl From<Error> for Z80Error {
} }
} }
impl Debuggable for Z80<Instant> { impl Debuggable for MoaZ80<Instant> {
fn add_breakpoint(&mut self, addr: Address) { 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) { fn remove_breakpoint(&mut self, addr: Address) {
if let Some(index) = self.debugger.breakpoints.iter().position(|a| *a == addr as u16) { if let Some(index) = self.cpu.debugger.breakpoints.iter().position(|a| *a == addr as u16) {
self.debugger.breakpoints.remove(index); self.cpu.debugger.breakpoints.remove(index);
} }
} }
@ -103,9 +113,9 @@ impl Debuggable for Z80<Instant> {
let bus = &mut *system.bus.borrow_mut(); let bus = &mut *system.bus.borrow_mut();
let mut adapter = BusAdapter::new(bus, |addr| addr as u64, |err| Z80Error::BusError(format!("{:?}", err))); 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)?; let decoder = Z80Decoder::decode_at(&mut adapter, system.clock, self.cpu.state.pc)?;
self.previous_cycle.decoder.dump_decoded(&mut adapter); self.cpu.previous_cycle.decoder.dump_decoded(&mut adapter);
self.dump_state(system.clock, &mut adapter); self.cpu.dump_state(system.clock, &mut adapter);
Ok(()) Ok(())
} }
@ -118,7 +128,7 @@ impl Debuggable for Z80<Instant> {
fn run_command(&mut self, _system: &System, args: &[&str]) -> Result<bool, Error> { fn run_command(&mut self, _system: &System, args: &[&str]) -> Result<bool, Error> {
match args[0] { 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); return Ok(true);
}, },

View File

@ -94,8 +94,10 @@ impl Z80State {
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct Z80Signals { pub struct Z80Signals {
pub reset: bool, //pub reset: bool,
pub bus_request: bool, //pub bus_request: bool,
pub reset: Signal<bool>,
pub bus_request: Signal<bool>,
} }
#[derive(Clone, Debug, thiserror::Error)] #[derive(Clone, Debug, thiserror::Error)]

View File

@ -19,7 +19,7 @@ type Input<T> = Signal<T>;
#[allow(dead_code)] #[allow(dead_code)]
type TriState<T> = Signal<T>; type TriState<T> = Signal<T>;
#[derive(Clone, Debug)] #[derive(Clone, Debug, Default)]
pub struct Signal<T: Copy>(Rc<Cell<T>>); pub struct Signal<T: Copy>(Rc<Cell<T>>);
impl<T: Copy> Signal<T> { impl<T: Copy> Signal<T> {

View File

@ -1,27 +1,23 @@
use std::rc::Rc; use std::rc::Rc;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::any::Any;
use femtos::Instant; use femtos::Instant;
use moa_core::{Bus, Device, Error, Address, Addressable, Signal, Transmutable}; use moa_core::{Bus, Error, Address, Addressable, Transmutable};
//use moa_signals::Signal; use moa_signals::Signal;
use moa_z80::Z80;
const DEV_NAME: &str = "coprocessor"; const DEV_NAME: &str = "coprocessor";
pub struct CoprocessorCoordinator { pub struct CoprocessorCoordinator {
z80: Device, bus_request: Signal<bool>,
//bus_request: Signal<bool>, reset: Signal<bool>,
//reset: Signal<bool>,
} }
impl CoprocessorCoordinator { impl CoprocessorCoordinator {
pub fn new(z80: Device) -> Self { pub fn new(reset: Signal<bool>, bus_request: Signal<bool>) -> Self {
Self { Self {
z80, bus_request,
//bus_request, reset,
//reset,
} }
} }
} }
@ -34,9 +30,7 @@ impl Addressable for CoprocessorCoordinator {
fn read(&mut self, _clock: Instant, addr: Address, data: &mut [u8]) -> Result<(), Error> { fn read(&mut self, _clock: Instant, addr: Address, data: &mut [u8]) -> Result<(), Error> {
match addr { match addr {
0x100 => { 0x100 => {
let mut device = self.z80.borrow_mut(); data[0] = if self.bus_request.get() && self.reset.get() {
let z80 = device.as_signalable().unwrap();
data[0] = if z80.signal(Signal::BusRequest).unwrap_or(false) && z80.signal(Signal::Reset).unwrap_or(false) {
0x01 0x01
} else { } else {
0x00 0x00
@ -55,14 +49,10 @@ impl Addressable for CoprocessorCoordinator {
match addr { match addr {
0x000 => { /* ROM vs DRAM mode */ }, 0x000 => { /* ROM vs DRAM mode */ },
0x100 => { 0x100 => {
let mut device = self.z80.borrow_mut(); self.bus_request.set(data[0] != 0);
let z80 = device.as_signalable().unwrap();
z80.set_signal(Signal::BusRequest, data[0] == 0)?;
}, },
0x200 => { 0x200 => {
let mut device = self.z80.borrow_mut(); self.reset.set(data[0] == 0);
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); log::warn!("{}: !!! unhandled write {:0x} to {:0x}", DEV_NAME, data[0], addr);

View File

@ -8,7 +8,7 @@ use moa_core::{System, Error, MemoryBlock, Bus, Address, Addressable, Device};
use moa_host::Host; use moa_host::Host;
use moa_m68k::{M68k, M68kType}; 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::Ym2612;
use moa_peripherals_yamaha::Sn76489; use moa_peripherals_yamaha::Sn76489;
@ -69,13 +69,16 @@ pub fn build_genesis<H: Host>(host: &mut H, mut options: SegaGenesisOptions) ->
coproc_bus.borrow_mut().insert(0x7f11, coproc_sn_sound.clone()); coproc_bus.borrow_mut().insert(0x7f11, coproc_sn_sound.clone());
coproc_bus.borrow_mut().insert(0x8000, coproc_area); coproc_bus.borrow_mut().insert(0x8000, coproc_area);
let coproc = Z80::from_type(Z80Type::Z80, Frequency::from_hz(3_579_545)); let coproc = Z80::from_type(Z80Type::Z80, Frequency::from_hz(3_579_545));
//let mut reset = coproc.reset.clone(); let coproc = MoaZ80 {
//let mut bus_request = coproc.bus_request.clone(); bus: coproc_bus,
//reset.set(true); cpu: coproc,
//bus_request.set(true); };
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); let coproc = Device::new(coproc);
// Add coprocessor devices to the system bus so the 68000 can access them too // 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(0x00a00000, coproc_ram)?;
system.add_addressable_device(0x00a04000, coproc_ym_sound)?; system.add_addressable_device(0x00a04000, coproc_ym_sound)?;
@ -89,7 +92,7 @@ pub fn build_genesis<H: Host>(host: &mut H, mut options: SegaGenesisOptions) ->
let interrupt = controllers.get_interrupt_signal(); let interrupt = controllers.get_interrupt_signal();
system.add_addressable_device(0x00a10000, Device::new(controllers))?; 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))?; system.add_addressable_device(0x00a11000, Device::new(coproc))?;
let vdp = Ym7101::new(host, interrupt, coproc_sn_sound)?; let vdp = Ym7101::new(host, interrupt, coproc_sn_sound)?;

View File

@ -3,7 +3,7 @@ use femtos::Frequency;
use moa_core::{System, Error, MemoryBlock, Device}; use moa_core::{System, Error, MemoryBlock, Device};
use moa_host::Host; use moa_host::Host;
use moa_z80::{Z80, Z80Type}; use moa_z80::{MoaZ80, Z80, Z80Type};
use crate::peripherals::model1::{Model1Keyboard, Model1Video}; use crate::peripherals::model1::{Model1Keyboard, Model1Video};
@ -45,6 +45,10 @@ pub fn build_trs80<H: Host>(host: &mut H, options: Trs80Options) -> Result<Syste
// TODO the ioport needs to be hooked up // TODO the ioport needs to be hooked up
let cpu = Z80::from_type(Z80Type::Z80, options.frequency); let cpu = Z80::from_type(Z80Type::Z80, options.frequency);
let cpu = MoaZ80 {
bus: system.bus.clone(),
cpu,
};
system.add_interruptable_device("cpu", Device::new(cpu))?; system.add_interruptable_device("cpu", Device::new(cpu))?;