mirror of
https://github.com/transistorfet/moa.git
synced 2024-12-03 07:49:17 +00:00
Added new Device type to replace TransmutableBox
It's mostly just sugar, but it now includes a unique ID
This commit is contained in:
parent
3db52cbef6
commit
fdca8970f2
@ -3,7 +3,7 @@ use std::io::Write;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::system::System;
|
||||
use crate::devices::{Address, Addressable, Debuggable, TransmutableBox};
|
||||
use crate::devices::{Address, Addressable, Debuggable, Device};
|
||||
|
||||
|
||||
#[derive(Default)]
|
||||
@ -19,7 +19,7 @@ impl Debugger {
|
||||
self.trace_only = false;
|
||||
}
|
||||
|
||||
pub fn run_debugger(&mut self, system: &System, target: TransmutableBox) -> Result<(), Error> {
|
||||
pub fn run_debugger(&mut self, system: &System, target: Device) -> Result<(), Error> {
|
||||
let mut target = target.borrow_mut();
|
||||
let debug_obj = target.as_debuggable().unwrap();
|
||||
println!("@ {} ns", system.clock.as_duration().as_nanos());
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{RefCell, RefMut, BorrowMutError};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::system::System;
|
||||
@ -28,6 +29,7 @@ pub trait Interruptable {
|
||||
|
||||
/// A device that can be addressed to read data from or write data to the device.
|
||||
pub trait Addressable {
|
||||
#[inline]
|
||||
fn size(&self) -> usize;
|
||||
fn read(&mut self, clock: ClockTime, addr: Address, data: &mut [u8]) -> Result<(), Error>;
|
||||
fn write(&mut self, clock: ClockTime, addr: Address, data: &[u8]) -> Result<(), Error>;
|
||||
@ -174,22 +176,27 @@ pub trait Inspectable {
|
||||
|
||||
|
||||
pub trait Transmutable {
|
||||
#[inline]
|
||||
fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_interruptable(&mut self) -> Option<&mut dyn Interruptable> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_debuggable(&mut self) -> Option<&mut dyn Debuggable> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_inspectable(&mut self) -> Option<&mut dyn Inspectable> {
|
||||
None
|
||||
}
|
||||
@ -201,12 +208,70 @@ pub fn wrap_transmutable<T: Transmutable + 'static>(value: T) -> TransmutableBox
|
||||
Rc::new(RefCell::new(Box::new(value)))
|
||||
}
|
||||
|
||||
static NEXT_ID: AtomicUsize = AtomicUsize::new(1);
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct DeviceId(usize);
|
||||
|
||||
impl DeviceId {
|
||||
pub fn new() -> Self {
|
||||
let next = NEXT_ID.load(Ordering::Acquire);
|
||||
NEXT_ID.store(next + 1, Ordering::Release);
|
||||
Self(next)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DeviceId {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Device(TransmutableBox);
|
||||
pub struct Device(DeviceId, TransmutableBox);
|
||||
|
||||
impl Device {
|
||||
pub fn new<T>(value: T) -> Self
|
||||
where
|
||||
T: Transmutable + 'static
|
||||
{
|
||||
Self(DeviceId::new(), wrap_transmutable(value))
|
||||
}
|
||||
|
||||
pub fn borrow_mut(&self) -> RefMut<'_, Box<dyn Transmutable>> {
|
||||
self.1.borrow_mut()
|
||||
}
|
||||
|
||||
pub fn try_borrow_mut(&self) -> Result<RefMut<'_, Box<dyn Transmutable>>, BorrowMutError> {
|
||||
self.1.try_borrow_mut()
|
||||
}
|
||||
|
||||
/*
|
||||
#[inline]
|
||||
pub fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
|
||||
self.1.borrow_mut().as_steppable()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_interruptable(&mut self) -> Option<&mut dyn Interruptable> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_debuggable(&mut self) -> Option<&mut dyn Debuggable> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_inspectable(&mut self) -> Option<&mut dyn Inspectable> {
|
||||
None
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ pub use log::{trace, debug, info, warn, error};
|
||||
|
||||
pub use crate::clock::{ClockTime, ClockDuration, Frequency};
|
||||
pub use crate::debugger::Debugger;
|
||||
pub use crate::devices::{Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Transmutable, TransmutableBox};
|
||||
pub use crate::devices::{Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, 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};
|
||||
pub use crate::error::{Error, ErrorType};
|
||||
pub use crate::interrupts::InterruptController;
|
||||
|
@ -8,7 +8,7 @@ use std::fmt::Write;
|
||||
use crate::info;
|
||||
use crate::error::Error;
|
||||
use crate::clock::ClockTime;
|
||||
use crate::devices::{Address, Addressable, Transmutable, TransmutableBox, read_beu16};
|
||||
use crate::devices::{Address, Addressable, Transmutable, Device, read_beu16};
|
||||
|
||||
|
||||
pub struct MemoryBlock {
|
||||
@ -78,12 +78,12 @@ impl Transmutable for MemoryBlock {
|
||||
|
||||
|
||||
pub struct AddressRightShifter {
|
||||
subdevice: TransmutableBox,
|
||||
subdevice: Device,
|
||||
shift: u8,
|
||||
}
|
||||
|
||||
impl AddressRightShifter {
|
||||
pub fn new(subdevice: TransmutableBox, shift: u8) -> Self {
|
||||
pub fn new(subdevice: Device, shift: u8) -> Self {
|
||||
Self {
|
||||
subdevice,
|
||||
shift,
|
||||
@ -114,12 +114,12 @@ impl Transmutable for AddressRightShifter {
|
||||
|
||||
|
||||
pub struct AddressRepeater {
|
||||
subdevice: TransmutableBox,
|
||||
subdevice: Device,
|
||||
range: Address,
|
||||
}
|
||||
|
||||
impl AddressRepeater {
|
||||
pub fn new(subdevice: TransmutableBox, range: Address) -> Self {
|
||||
pub fn new(subdevice: Device, range: Address) -> Self {
|
||||
Self {
|
||||
subdevice,
|
||||
range,
|
||||
@ -154,7 +154,7 @@ impl Transmutable for AddressRepeater {
|
||||
pub struct Block {
|
||||
pub base: Address,
|
||||
pub size: usize,
|
||||
pub dev: TransmutableBox,
|
||||
pub dev: Device,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
@ -174,14 +174,14 @@ impl Bus {
|
||||
self.blocks.clear();
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, base: Address, dev: TransmutableBox) {
|
||||
pub fn insert(&mut self, base: Address, dev: Device) {
|
||||
let size = dev.borrow_mut().as_addressable().unwrap().size();
|
||||
let block = Block { base, size, dev };
|
||||
let i = self.blocks.iter().position(|cur| cur.base > block.base).unwrap_or(self.blocks.len());
|
||||
self.blocks.insert(i, block);
|
||||
}
|
||||
|
||||
pub fn get_device_at(&self, addr: Address, count: usize) -> Result<(TransmutableBox, Address), Error> {
|
||||
pub fn get_device_at(&self, addr: Address, count: usize) -> Result<(Device, Address), Error> {
|
||||
for block in &self.blocks {
|
||||
if addr >= block.base && addr < (block.base + block.size as Address) {
|
||||
let relative_addr = addr - block.base;
|
||||
|
@ -9,12 +9,12 @@ use crate::signals::EdgeSignal;
|
||||
use crate::error::{Error, ErrorType};
|
||||
use crate::interrupts::InterruptController;
|
||||
use crate::clock::{ClockTime, ClockDuration};
|
||||
use crate::devices::{Address, TransmutableBox};
|
||||
use crate::devices::{Address, Device};
|
||||
|
||||
|
||||
pub struct System {
|
||||
pub clock: ClockTime,
|
||||
pub devices: HashMap<String, TransmutableBox>,
|
||||
pub devices: HashMap<String, Device>,
|
||||
pub event_queue: Vec<NextStep>,
|
||||
|
||||
pub debug_enabled: Cell<bool>,
|
||||
@ -55,28 +55,28 @@ impl System {
|
||||
self.interrupt_controller.borrow_mut()
|
||||
}
|
||||
|
||||
pub fn get_device(&self, name: &str) -> Result<TransmutableBox, Error> {
|
||||
pub fn get_device(&self, name: &str) -> Result<Device, Error> {
|
||||
self.devices.get(name).cloned().ok_or_else(|| Error::new(&format!("system: no device named {}", name)))
|
||||
}
|
||||
|
||||
pub fn add_device(&mut self, name: &str, device: TransmutableBox) -> Result<(), Error> {
|
||||
pub fn add_device(&mut self, name: &str, device: Device) -> 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> {
|
||||
pub fn add_addressable_device(&mut self, addr: Address, device: Device) -> Result<(), Error> {
|
||||
self.add_peripheral(&format!("mem{:x}", addr), addr, device)
|
||||
}
|
||||
|
||||
pub fn add_peripheral(&mut self, name: &str, addr: Address, device: TransmutableBox) -> Result<(), Error> {
|
||||
pub fn add_peripheral(&mut self, name: &str, addr: Address, device: Device) -> Result<(), Error> {
|
||||
self.bus.borrow_mut().insert(addr, device.clone());
|
||||
self.try_queue_device(device.clone());
|
||||
self.devices.insert(name.to_string(), device);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_interruptable_device(&mut self, name: &str, device: TransmutableBox) -> Result<(), Error> {
|
||||
pub fn add_interruptable_device(&mut self, name: &str, device: Device) -> Result<(), Error> {
|
||||
self.try_queue_device(device.clone());
|
||||
self.devices.insert(name.to_string(), device);
|
||||
Ok(())
|
||||
@ -172,7 +172,7 @@ impl System {
|
||||
}
|
||||
}
|
||||
|
||||
fn try_queue_device(&mut self, device: TransmutableBox) {
|
||||
fn try_queue_device(&mut self, device: Device) {
|
||||
if device.borrow_mut().as_steppable().is_some() {
|
||||
self.queue_device(NextStep::new(device));
|
||||
}
|
||||
@ -192,11 +192,11 @@ impl System {
|
||||
|
||||
pub struct NextStep {
|
||||
pub next_clock: ClockTime,
|
||||
pub device: TransmutableBox,
|
||||
pub device: Device,
|
||||
}
|
||||
|
||||
impl NextStep {
|
||||
pub fn new(device: TransmutableBox) -> Self {
|
||||
pub fn new(device: Device) -> Self {
|
||||
Self {
|
||||
next_clock: ClockTime::START,
|
||||
device,
|
||||
|
@ -7,7 +7,7 @@ use std::time::{Duration, Instant};
|
||||
use minifb::{self, Key, MouseMode, MouseButton};
|
||||
use clap::{App, Arg, ArgMatches};
|
||||
|
||||
use moa_core::{System, Error, ClockDuration, wrap_transmutable};
|
||||
use moa_core::{System, Error, ClockDuration, Device};
|
||||
use moa_core::host::{Host, Audio, KeyEvent, MouseEvent, MouseState, ControllerDevice, ControllerEvent, EventSender, PixelEncoding, Frame, FrameReceiver};
|
||||
|
||||
use moa_common::{AudioMixer, AudioSource};
|
||||
@ -216,7 +216,7 @@ impl MiniFrontend {
|
||||
|
||||
if self.mixer.borrow_mut().num_sources() != 0 && matches.occurrences_of("disable-audio") == 0 {
|
||||
if let Some(system) = system.as_mut() {
|
||||
system.add_device("mixer", wrap_transmutable(self.mixer.clone())).unwrap();
|
||||
system.add_device("mixer", Device::new(self.mixer.clone())).unwrap();
|
||||
}
|
||||
self.audio = Some(CpalAudioOutput::create_audio_output(self.mixer.borrow_mut().get_sink()));
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use web_sys::Event;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen::closure::Closure;
|
||||
|
||||
use moa_core::{ClockDuration, System, wrap_transmutable};
|
||||
use moa_core::{ClockDuration, System, Device};
|
||||
use moa_core::host::{ControllerInput, ControllerDevice, ControllerEvent, EventSender};
|
||||
|
||||
use crate::settings;
|
||||
@ -130,7 +130,7 @@ pub fn load_system(handle: &mut HostHandle, load: LoadSystemFnHandle) -> SystemH
|
||||
let mut system = load.0(&mut handle.0, settings::get().rom_data.clone()).unwrap();
|
||||
let mixer = handle.0.get_mixer();
|
||||
if mixer.borrow_mut().num_sources() > 0 {
|
||||
system.add_device("mixer", wrap_transmutable(mixer.clone())).unwrap();
|
||||
system.add_device("mixer", Device::new(mixer.clone())).unwrap();
|
||||
}
|
||||
SystemHandle(system)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
use moa_core::{System, Error, Frequency, Debuggable, MemoryBlock, BusPort, wrap_transmutable};
|
||||
use moa_core::{System, Error, Frequency, Debuggable, MemoryBlock, BusPort, Device};
|
||||
use moa_core::host::Host;
|
||||
|
||||
use moa_m68k::{M68k, M68kType};
|
||||
@ -11,20 +11,20 @@ pub fn build_computie<H: Host>(host: &H) -> Result<System, Error> {
|
||||
let mut system = System::default();
|
||||
|
||||
let monitor = MemoryBlock::load("binaries/computie/monitor.bin")?;
|
||||
system.add_addressable_device(0x00000000, wrap_transmutable(monitor))?;
|
||||
system.add_addressable_device(0x00000000, Device::new(monitor))?;
|
||||
|
||||
let mut ram = MemoryBlock::new(vec![0; 0x00100000]);
|
||||
ram.load_at(0, "binaries/computie/kernel.bin")?;
|
||||
system.add_addressable_device(0x00100000, wrap_transmutable(ram))?;
|
||||
system.add_addressable_device(0x00100000, Device::new(ram))?;
|
||||
|
||||
let mut ata = AtaDevice::default();
|
||||
ata.load("binaries/computie/disk-with-partition-table.img")?;
|
||||
system.add_addressable_device(0x00600000, wrap_transmutable(ata))?;
|
||||
system.add_addressable_device(0x00600000, Device::new(ata))?;
|
||||
|
||||
let mut serial = MC68681::default();
|
||||
launch_terminal_emulator(serial.port_a.connect(host.add_pty()?)?);
|
||||
launch_slip_connection(serial.port_b.connect(host.add_pty()?)?);
|
||||
system.add_addressable_device(0x00700000, wrap_transmutable(serial))?;
|
||||
system.add_addressable_device(0x00700000, Device::new(serial))?;
|
||||
|
||||
|
||||
let mut cpu = M68k::new(M68kType::MC68010, Frequency::from_hz(10_000_000), BusPort::new(0, 24, 16, system.bus.clone()));
|
||||
@ -40,7 +40,7 @@ pub fn build_computie<H: Host>(host: &H) -> Result<System, Error> {
|
||||
|
||||
cpu.add_breakpoint(0);
|
||||
|
||||
system.add_interruptable_device("cpu", wrap_transmutable(cpu))?;
|
||||
system.add_interruptable_device("cpu", Device::new(cpu))?;
|
||||
|
||||
Ok(system)
|
||||
}
|
||||
@ -49,20 +49,20 @@ pub fn build_computie_k30<H: Host>(host: &H) -> Result<System, Error> {
|
||||
let mut system = System::default();
|
||||
|
||||
let monitor = MemoryBlock::load("binaries/computie/monitor-68030.bin")?;
|
||||
system.add_addressable_device(0x00000000, wrap_transmutable(monitor))?;
|
||||
system.add_addressable_device(0x00000000, Device::new(monitor))?;
|
||||
|
||||
let mut ram = MemoryBlock::new(vec![0; 0x00100000]);
|
||||
ram.load_at(0, "binaries/computie/kernel-68030.bin")?;
|
||||
system.add_addressable_device(0x00100000, wrap_transmutable(ram))?;
|
||||
system.add_addressable_device(0x00100000, Device::new(ram))?;
|
||||
|
||||
let mut ata = AtaDevice::default();
|
||||
ata.load("binaries/computie/disk-with-partition-table.img")?;
|
||||
system.add_addressable_device(0x00600000, wrap_transmutable(ata))?;
|
||||
system.add_addressable_device(0x00600000, Device::new(ata))?;
|
||||
|
||||
let mut serial = MC68681::default();
|
||||
launch_terminal_emulator(serial.port_a.connect(host.add_pty()?)?);
|
||||
//launch_slip_connection(serial.port_b.connect(host.add_pty()?)?);
|
||||
system.add_addressable_device(0x00700000, wrap_transmutable(serial))?;
|
||||
system.add_addressable_device(0x00700000, Device::new(serial))?;
|
||||
|
||||
|
||||
let cpu = M68k::new(M68kType::MC68030, Frequency::from_hz(10_000_000), BusPort::new(0, 32, 32, system.bus.clone()));
|
||||
@ -76,7 +76,7 @@ pub fn build_computie_k30<H: Host>(host: &H) -> Result<System, Error> {
|
||||
//cpu.decoder.dump_disassembly(&mut system, 0x100000, 0x2000);
|
||||
//cpu.decoder.dump_disassembly(&mut system, 0x2ac, 0x200);
|
||||
|
||||
system.add_interruptable_device("cpu", wrap_transmutable(cpu))?;
|
||||
system.add_interruptable_device("cpu", Device::new(cpu))?;
|
||||
|
||||
Ok(system)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
use moa_core::{debug, warn, error};
|
||||
use moa_core::{System, Error, EdgeSignal, ClockTime, ClockDuration, Frequency, Signal, Address, Addressable, Steppable, Inspectable, Transmutable, TransmutableBox, read_beu16, dump_slice};
|
||||
use moa_core::{System, Error, EdgeSignal, ClockTime, ClockDuration, Frequency, Signal, Address, Addressable, Steppable, Inspectable, Transmutable, Device, read_beu16, dump_slice};
|
||||
use moa_core::host::{self, Host, Pixel, PixelEncoding, Frame, FrameSender};
|
||||
|
||||
|
||||
@ -709,14 +709,14 @@ impl Steppable for Ym7101 {
|
||||
pub struct Ym7101 {
|
||||
sender: FrameSender,
|
||||
state: Ym7101State,
|
||||
sn_sound: TransmutableBox,
|
||||
sn_sound: Device,
|
||||
|
||||
pub external_interrupt: Signal<bool>,
|
||||
pub frame_complete: EdgeSignal,
|
||||
}
|
||||
|
||||
impl Ym7101 {
|
||||
pub fn new<H: Host>(host: &mut H, external_interrupt: Signal<bool>, sn_sound: TransmutableBox) -> Ym7101 {
|
||||
pub fn new<H: Host>(host: &mut H, external_interrupt: Signal<bool>, sn_sound: Device) -> Ym7101 {
|
||||
let (sender, receiver) = host::frame_queue(320, 224);
|
||||
host.add_video_source(receiver).unwrap();
|
||||
|
||||
|
@ -3,7 +3,7 @@ use std::mem;
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
||||
use moa_core::{System, Error, Frequency, Signal, MemoryBlock, Bus, BusPort, Address, Addressable, Debuggable, wrap_transmutable};
|
||||
use moa_core::{System, Error, Frequency, Signal, MemoryBlock, Bus, BusPort, Address, Addressable, Debuggable, Device};
|
||||
use moa_core::host::Host;
|
||||
|
||||
use moa_m68k::{M68k, M68kType};
|
||||
@ -58,22 +58,22 @@ pub fn build_genesis<H: Host>(host: &mut H, mut options: SegaGenesisOptions) ->
|
||||
//let mut rom = MemoryBlock::load("binaries/genesis/Teenage Mutant Ninja Turtles - The Hyperstone Heist (U) [!].bin").unwrap();
|
||||
//rom.read_only();
|
||||
let rom_end = rom.size();
|
||||
system.add_addressable_device(0x00000000, wrap_transmutable(rom)).unwrap();
|
||||
system.add_addressable_device(0x00000000, Device::new(rom)).unwrap();
|
||||
|
||||
let cartridge_nvram = MemoryBlock::new(vec![0; 0x400000 - rom_end]);
|
||||
system.add_addressable_device(rom_end as Address, wrap_transmutable(cartridge_nvram)).unwrap();
|
||||
system.add_addressable_device(rom_end as Address, Device::new(cartridge_nvram)).unwrap();
|
||||
|
||||
let ram = MemoryBlock::new(vec![0; 0x00010000]);
|
||||
system.add_addressable_device(0x00ff0000, wrap_transmutable(ram)).unwrap();
|
||||
system.add_addressable_device(0x00ff0000, Device::new(ram)).unwrap();
|
||||
|
||||
|
||||
// Build the Coprocessor's Bus
|
||||
let bank_register = Signal::new(0);
|
||||
let coproc_ram = wrap_transmutable(MemoryBlock::new(vec![0; 0x00002000]));
|
||||
let coproc_ym_sound = wrap_transmutable(Ym2612::new(host, Frequency::from_hz(7_670_454))?);
|
||||
let coproc_sn_sound = wrap_transmutable(Sn76489::new(host, Frequency::from_hz(3_579_545))?);
|
||||
let coproc_register = wrap_transmutable(CoprocessorBankRegister::new(bank_register.clone()));
|
||||
let coproc_area = wrap_transmutable(CoprocessorBankArea::new(bank_register, system.bus.clone()));
|
||||
let coproc_ram = Device::new(MemoryBlock::new(vec![0; 0x00002000]));
|
||||
let coproc_ym_sound = Device::new(Ym2612::new(host, Frequency::from_hz(7_670_454))?);
|
||||
let coproc_sn_sound = Device::new(Sn76489::new(host, Frequency::from_hz(3_579_545))?);
|
||||
let coproc_register = Device::new(CoprocessorBankRegister::new(bank_register.clone()));
|
||||
let coproc_area = Device::new(CoprocessorBankArea::new(bank_register, system.bus.clone()));
|
||||
|
||||
let coproc_bus = Rc::new(RefCell::new(Bus::default()));
|
||||
coproc_bus.borrow_mut().set_ignore_unmapped(true);
|
||||
@ -95,22 +95,22 @@ pub fn build_genesis<H: Host>(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", wrap_transmutable(coproc))?;
|
||||
system.add_device("coproc", Device::new(coproc))?;
|
||||
|
||||
|
||||
let controllers = GenesisControllers::new(host)?;
|
||||
let interrupt = controllers.get_interrupt_signal();
|
||||
system.add_addressable_device(0x00a10000, wrap_transmutable(controllers)).unwrap();
|
||||
system.add_addressable_device(0x00a10000, Device::new(controllers)).unwrap();
|
||||
|
||||
let coproc = CoprocessorCoordinator::new(reset, bus_request);
|
||||
system.add_addressable_device(0x00a11000, wrap_transmutable(coproc)).unwrap();
|
||||
system.add_addressable_device(0x00a11000, Device::new(coproc)).unwrap();
|
||||
|
||||
let vdp = Ym7101::new(host, interrupt, coproc_sn_sound);
|
||||
system.break_signal = Some(vdp.frame_complete.clone());
|
||||
system.add_peripheral("vdp", 0x00c00000, wrap_transmutable(vdp)).unwrap();
|
||||
system.add_peripheral("vdp", 0x00c00000, Device::new(vdp)).unwrap();
|
||||
|
||||
let cpu = M68k::new(M68kType::MC68000, Frequency::from_hz(7_670_454), BusPort::new(0, 24, 16, system.bus.clone()));
|
||||
system.add_interruptable_device("cpu", wrap_transmutable(cpu)).unwrap();
|
||||
system.add_interruptable_device("cpu", Device::new(cpu)).unwrap();
|
||||
|
||||
Ok(system)
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
||||
use moa_core::{System, Bus, Error, Observable, ClockTime, ClockDuration, Address, Addressable, AddressRepeater, Steppable, Transmutable, TransmutableBox, wrap_transmutable};
|
||||
use moa_core::{System, Bus, Error, Observable, ClockTime, ClockDuration, Address, Addressable, AddressRepeater, Steppable, Transmutable, Device};
|
||||
|
||||
use moa_peripherals_mos::Mos6522;
|
||||
use moa_peripherals_zilog::Z8530;
|
||||
@ -22,7 +22,7 @@ pub struct Mainboard {
|
||||
}
|
||||
|
||||
impl Mainboard {
|
||||
pub fn new(ram: TransmutableBox, rom: TransmutableBox) -> Result<Self, Error> {
|
||||
pub fn new(ram: Device, rom: Device) -> Result<Self, Error> {
|
||||
let scc1 = Z8530::default();
|
||||
let scc2 = Z8530::default();
|
||||
let iwm = IWM::default();
|
||||
@ -45,16 +45,16 @@ impl Mainboard {
|
||||
if (port.data & 0x10) == 0 {
|
||||
println!("{}: overlay is 0 (normal)", DEV_NAME);
|
||||
lower_bus.borrow_mut().clear_all_bus_devices();
|
||||
lower_bus.borrow_mut().insert(0x000000, wrap_transmutable(AddressRepeater::new(ram.clone(), 0x400000)));
|
||||
lower_bus.borrow_mut().insert(0x400000, wrap_transmutable(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||
lower_bus.borrow_mut().insert(0x600000, wrap_transmutable(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||
lower_bus.borrow_mut().insert(0x000000, Device::new(AddressRepeater::new(ram.clone(), 0x400000)));
|
||||
lower_bus.borrow_mut().insert(0x400000, Device::new(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||
lower_bus.borrow_mut().insert(0x600000, Device::new(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||
} else {
|
||||
println!("{}: overlay is 1 (startup)", DEV_NAME);
|
||||
lower_bus.borrow_mut().clear_all_bus_devices();
|
||||
lower_bus.borrow_mut().insert(0x000000, wrap_transmutable(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||
lower_bus.borrow_mut().insert(0x200000, wrap_transmutable(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||
lower_bus.borrow_mut().insert(0x400000, wrap_transmutable(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||
lower_bus.borrow_mut().insert(0x600000, wrap_transmutable(AddressRepeater::new(ram.clone(), 0x200000)));
|
||||
lower_bus.borrow_mut().insert(0x000000, Device::new(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||
lower_bus.borrow_mut().insert(0x200000, Device::new(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||
lower_bus.borrow_mut().insert(0x400000, Device::new(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||
lower_bus.borrow_mut().insert(0x600000, Device::new(AddressRepeater::new(ram.clone(), 0x200000)));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
use moa_core::{System, Error, Frequency, MemoryBlock, BusPort, Debuggable, wrap_transmutable};
|
||||
use moa_core::{System, Error, Frequency, MemoryBlock, BusPort, Debuggable, Device};
|
||||
use moa_core::host::Host;
|
||||
|
||||
use moa_m68k::{M68k, M68kType};
|
||||
@ -63,10 +63,10 @@ pub fn build_macintosh_512k<H: Host>(host: &mut H) -> Result<System, Error> {
|
||||
rom.read_only();
|
||||
|
||||
let video = MacVideo::new(host)?;
|
||||
system.add_device("video", wrap_transmutable(video)).unwrap();
|
||||
system.add_device("video", Device::new(video)).unwrap();
|
||||
|
||||
let mainboard = Mainboard::new(wrap_transmutable(ram), wrap_transmutable(rom))?;
|
||||
system.add_addressable_device(0x00000000, wrap_transmutable(mainboard))?;
|
||||
let mainboard = Mainboard::new(Device::new(ram), Device::new(rom))?;
|
||||
system.add_addressable_device(0x00000000, Device::new(mainboard))?;
|
||||
|
||||
|
||||
let mut cpu = M68k::new(M68kType::MC68000, Frequency::from_hz(7_833_600), BusPort::new(0, 24, 16, system.bus.clone()));
|
||||
@ -121,7 +121,7 @@ pub fn build_macintosh_512k<H: Host>(host: &mut H) -> Result<System, Error> {
|
||||
panic!("");
|
||||
*/
|
||||
|
||||
system.add_interruptable_device("cpu", wrap_transmutable(cpu))?;
|
||||
system.add_interruptable_device("cpu", Device::new(cpu))?;
|
||||
|
||||
Ok(system)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
use moa_core::{System, Error, Frequency, MemoryBlock, BusPort, wrap_transmutable};
|
||||
use moa_core::{System, Error, Frequency, MemoryBlock, BusPort, Device};
|
||||
use moa_core::host::Host;
|
||||
|
||||
use moa_z80::{Z80, Z80Type};
|
||||
@ -32,15 +32,15 @@ pub fn build_trs80<H: Host>(host: &mut H, options: Trs80Options) -> Result<Syste
|
||||
//rom.load_at(0x0000, "binaries/trs80/level2.rom")?;
|
||||
rom.load_at(0x0000, &options.rom)?;
|
||||
rom.read_only();
|
||||
system.add_addressable_device(0x0000, wrap_transmutable(rom))?;
|
||||
system.add_addressable_device(0x0000, Device::new(rom))?;
|
||||
|
||||
let ram = MemoryBlock::new(vec![0; options.memory as usize]);
|
||||
system.add_addressable_device(0x4000, wrap_transmutable(ram))?;
|
||||
system.add_addressable_device(0x4000, Device::new(ram))?;
|
||||
|
||||
let keyboard = Model1Keyboard::new(host)?;
|
||||
system.add_addressable_device(0x37E0, wrap_transmutable(keyboard)).unwrap();
|
||||
system.add_addressable_device(0x37E0, Device::new(keyboard)).unwrap();
|
||||
let video = Model1Video::new(host)?;
|
||||
system.add_addressable_device(0x37E0 + 0x420, wrap_transmutable(video)).unwrap();
|
||||
system.add_addressable_device(0x37E0 + 0x420, Device::new(video)).unwrap();
|
||||
|
||||
// TODO the ioport needs to be hooked up
|
||||
let cpu = Z80::new(Z80Type::Z80, options.frequency, BusPort::new(0, 16, 8, system.bus.clone()), None);
|
||||
@ -68,7 +68,7 @@ pub fn build_trs80<H: Host>(host: &mut H, options: Trs80Options) -> Result<Syste
|
||||
//cpu.add_breakpoint(0x9e2);
|
||||
//cpu.add_breakpoint(0x9f9);
|
||||
|
||||
system.add_interruptable_device("cpu", wrap_transmutable(cpu))?;
|
||||
system.add_interruptable_device("cpu", Device::new(cpu))?;
|
||||
|
||||
Ok(system)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user