mirror of
https://github.com/transistorfet/moa.git
synced 2024-09-26 09:55:26 +00:00
Compare commits
1 Commits
b34588d73a
...
4bc1794d0f
Author | SHA1 | Date | |
---|---|---|---|
|
4bc1794d0f |
@ -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", features = ["femtos"] }
|
||||
emulator-hal = { path = "../libraries/emulator-hal/emulator-hal" }
|
||||
|
@ -82,9 +82,9 @@ where
|
||||
}
|
||||
|
||||
pub(crate) fn step_one(&mut self) -> Result<u16, Z80Error> {
|
||||
let clocks = if self.signals.reset.get() {
|
||||
let clocks = if self.signals.reset {
|
||||
self.reset()?
|
||||
} else if self.signals.bus_request.get() {
|
||||
} else if self.signals.bus_request {
|
||||
4
|
||||
} else {
|
||||
self.step_internal()?
|
||||
|
@ -3,13 +3,10 @@ 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;
|
||||
|
@ -1,45 +1,36 @@
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use std::any::Any;
|
||||
use femtos::{Instant, Duration};
|
||||
use emulator_hal::{BusAdapter, Instant as EmuInstant};
|
||||
|
||||
use moa_core::{System, Error, Bus, Address, Steppable, Addressable, Interruptable, Signalable, Signal, Debuggable, Transmutable};
|
||||
use moa_core::{System, Error, Address, Steppable, Addressable, Interruptable, Signalable, Signal, Debuggable, Transmutable};
|
||||
|
||||
use crate::{Z80, Z80Error, Z80Decoder};
|
||||
use crate::instructions::Register;
|
||||
|
||||
pub struct MoaZ80<Instant>
|
||||
where
|
||||
Instant: EmuInstant,
|
||||
{
|
||||
pub bus: Rc<RefCell<Bus>>,
|
||||
pub cpu: Z80<Instant>,
|
||||
}
|
||||
|
||||
impl Steppable for MoaZ80<Instant>
|
||||
impl Steppable for Z80<Instant>
|
||||
where
|
||||
Instant: EmuInstant,
|
||||
{
|
||||
fn step(&mut self, system: &System) -> Result<Duration, Error> {
|
||||
let mut bus = &mut *self.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 executor = self.cpu.begin(system.clock, &mut adapter)?;
|
||||
let mut executor = self.begin(system.clock, &mut adapter)?;
|
||||
let clocks = executor.step_one()?;
|
||||
self.cpu.previous_cycle = executor.end();
|
||||
Ok(Instant::hertz_to_duration(self.cpu.frequency.as_hz() as u64) * clocks as u32)
|
||||
self.previous_cycle = executor.end();
|
||||
Ok(Instant::hertz_to_duration(self.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.cpu.dump_state(system.clock, &mut adapter);
|
||||
self.dump_state(system.clock, &mut adapter);
|
||||
}
|
||||
}
|
||||
|
||||
impl Interruptable for MoaZ80<Instant> {}
|
||||
impl Interruptable for Z80<Instant> {}
|
||||
|
||||
|
||||
/*
|
||||
impl Signalable for Z80<Instant> {
|
||||
fn set_signal(&mut self, signal: Signal, flag: bool) -> Result<(), Error> {
|
||||
match signal {
|
||||
@ -56,9 +47,8 @@ impl Signalable for Z80<Instant> {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl Transmutable for MoaZ80<Instant> {
|
||||
impl Transmutable for Z80<Instant> {
|
||||
fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
|
||||
Some(self)
|
||||
}
|
||||
@ -71,10 +61,10 @@ impl Transmutable for MoaZ80<Instant> {
|
||||
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<Z80Error> for Error {
|
||||
@ -98,14 +88,14 @@ impl From<Error> for Z80Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl Debuggable for MoaZ80<Instant> {
|
||||
impl Debuggable for Z80<Instant> {
|
||||
fn add_breakpoint(&mut self, addr: Address) {
|
||||
self.cpu.debugger.breakpoints.push(addr as u16);
|
||||
self.debugger.breakpoints.push(addr as u16);
|
||||
}
|
||||
|
||||
fn remove_breakpoint(&mut self, addr: Address) {
|
||||
if let Some(index) = self.cpu.debugger.breakpoints.iter().position(|a| *a == addr as u16) {
|
||||
self.cpu.debugger.breakpoints.remove(index);
|
||||
if let Some(index) = self.debugger.breakpoints.iter().position(|a| *a == addr as u16) {
|
||||
self.debugger.breakpoints.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,9 +103,9 @@ impl Debuggable for MoaZ80<Instant> {
|
||||
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.cpu.state.pc)?;
|
||||
self.cpu.previous_cycle.decoder.dump_decoded(&mut adapter);
|
||||
self.cpu.dump_state(system.clock, &mut adapter);
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -128,7 +118,7 @@ impl Debuggable for MoaZ80<Instant> {
|
||||
|
||||
fn run_command(&mut self, _system: &System, args: &[&str]) -> Result<bool, Error> {
|
||||
match args[0] {
|
||||
"l" => self.cpu.state.reg[Register::L as usize] = 0x05,
|
||||
"l" => self.state.reg[Register::L as usize] = 0x05,
|
||||
_ => {
|
||||
return Ok(true);
|
||||
},
|
||||
|
@ -94,10 +94,8 @@ impl Z80State {
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Z80Signals {
|
||||
//pub reset: bool,
|
||||
//pub bus_request: bool,
|
||||
pub reset: Signal<bool>,
|
||||
pub bus_request: Signal<bool>,
|
||||
pub reset: bool,
|
||||
pub bus_request: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, thiserror::Error)]
|
||||
|
@ -19,7 +19,7 @@ type Input<T> = Signal<T>;
|
||||
#[allow(dead_code)]
|
||||
type TriState<T> = Signal<T>;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Signal<T: Copy>(Rc<Cell<T>>);
|
||||
|
||||
impl<T: Copy> Signal<T> {
|
||||
|
@ -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<bool>,
|
||||
reset: Signal<bool>,
|
||||
z80: Device,
|
||||
//bus_request: Signal<bool>,
|
||||
//reset: Signal<bool>,
|
||||
}
|
||||
|
||||
|
||||
impl CoprocessorCoordinator {
|
||||
pub fn new(reset: Signal<bool>, bus_request: Signal<bool>) -> 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);
|
||||
|
@ -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::{MoaZ80, Z80, Z80Type};
|
||||
use moa_z80::{Z80, Z80Type};
|
||||
use moa_peripherals_yamaha::Ym2612;
|
||||
use moa_peripherals_yamaha::Sn76489;
|
||||
|
||||
@ -69,16 +69,13 @@ 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(0x8000, coproc_area);
|
||||
let coproc = Z80::from_type(Z80Type::Z80, Frequency::from_hz(3_579_545));
|
||||
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 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)?;
|
||||
system.add_addressable_device(0x00a04000, coproc_ym_sound)?;
|
||||
@ -92,7 +89,7 @@ pub fn build_genesis<H: Host>(host: &mut H, mut options: SegaGenesisOptions) ->
|
||||
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)?;
|
||||
|
@ -3,7 +3,7 @@ use femtos::Frequency;
|
||||
use moa_core::{System, Error, MemoryBlock, Device};
|
||||
use moa_host::Host;
|
||||
|
||||
use moa_z80::{MoaZ80, Z80, Z80Type};
|
||||
use moa_z80::{Z80, Z80Type};
|
||||
|
||||
use crate::peripherals::model1::{Model1Keyboard, Model1Video};
|
||||
|
||||
@ -45,10 +45,6 @@ pub fn build_trs80<H: Host>(host: &mut H, options: Trs80Options) -> Result<Syste
|
||||
|
||||
// TODO the ioport needs to be hooked up
|
||||
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))?;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user