mirror of
https://github.com/transistorfet/moa.git
synced 2024-12-04 14:49:16 +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::error::Error;
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::devices::{Address, Addressable, Debuggable, TransmutableBox};
|
use crate::devices::{Address, Addressable, Debuggable, Device};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -19,7 +19,7 @@ impl Debugger {
|
|||||||
self.trace_only = false;
|
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 mut target = target.borrow_mut();
|
||||||
let debug_obj = target.as_debuggable().unwrap();
|
let debug_obj = target.as_debuggable().unwrap();
|
||||||
println!("@ {} ns", system.clock.as_duration().as_nanos());
|
println!("@ {} ns", system.clock.as_duration().as_nanos());
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
use std::rc::Rc;
|
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::error::Error;
|
||||||
use crate::system::System;
|
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.
|
/// A device that can be addressed to read data from or write data to the device.
|
||||||
pub trait Addressable {
|
pub trait Addressable {
|
||||||
|
#[inline]
|
||||||
fn size(&self) -> usize;
|
fn size(&self) -> usize;
|
||||||
fn read(&mut self, clock: ClockTime, addr: Address, data: &mut [u8]) -> Result<(), Error>;
|
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>;
|
fn write(&mut self, clock: ClockTime, addr: Address, data: &[u8]) -> Result<(), Error>;
|
||||||
@ -174,22 +176,27 @@ pub trait Inspectable {
|
|||||||
|
|
||||||
|
|
||||||
pub trait Transmutable {
|
pub trait Transmutable {
|
||||||
|
#[inline]
|
||||||
fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
|
fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
|
fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn as_interruptable(&mut self) -> Option<&mut dyn Interruptable> {
|
fn as_interruptable(&mut self) -> Option<&mut dyn Interruptable> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn as_debuggable(&mut self) -> Option<&mut dyn Debuggable> {
|
fn as_debuggable(&mut self) -> Option<&mut dyn Debuggable> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn as_inspectable(&mut self) -> Option<&mut dyn Inspectable> {
|
fn as_inspectable(&mut self) -> Option<&mut dyn Inspectable> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -201,12 +208,70 @@ pub fn wrap_transmutable<T: Transmutable + 'static>(value: T) -> TransmutableBox
|
|||||||
Rc::new(RefCell::new(Box::new(value)))
|
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)]
|
#[derive(Clone)]
|
||||||
pub struct Device(TransmutableBox);
|
pub struct Device(DeviceId, TransmutableBox);
|
||||||
|
|
||||||
impl Device {
|
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::clock::{ClockTime, ClockDuration, Frequency};
|
||||||
pub use crate::debugger::Debugger;
|
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::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::error::{Error, ErrorType};
|
||||||
pub use crate::interrupts::InterruptController;
|
pub use crate::interrupts::InterruptController;
|
||||||
|
@ -8,7 +8,7 @@ use std::fmt::Write;
|
|||||||
use crate::info;
|
use crate::info;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::clock::ClockTime;
|
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 {
|
pub struct MemoryBlock {
|
||||||
@ -78,12 +78,12 @@ impl Transmutable for MemoryBlock {
|
|||||||
|
|
||||||
|
|
||||||
pub struct AddressRightShifter {
|
pub struct AddressRightShifter {
|
||||||
subdevice: TransmutableBox,
|
subdevice: Device,
|
||||||
shift: u8,
|
shift: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AddressRightShifter {
|
impl AddressRightShifter {
|
||||||
pub fn new(subdevice: TransmutableBox, shift: u8) -> Self {
|
pub fn new(subdevice: Device, shift: u8) -> Self {
|
||||||
Self {
|
Self {
|
||||||
subdevice,
|
subdevice,
|
||||||
shift,
|
shift,
|
||||||
@ -114,12 +114,12 @@ impl Transmutable for AddressRightShifter {
|
|||||||
|
|
||||||
|
|
||||||
pub struct AddressRepeater {
|
pub struct AddressRepeater {
|
||||||
subdevice: TransmutableBox,
|
subdevice: Device,
|
||||||
range: Address,
|
range: Address,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AddressRepeater {
|
impl AddressRepeater {
|
||||||
pub fn new(subdevice: TransmutableBox, range: Address) -> Self {
|
pub fn new(subdevice: Device, range: Address) -> Self {
|
||||||
Self {
|
Self {
|
||||||
subdevice,
|
subdevice,
|
||||||
range,
|
range,
|
||||||
@ -154,7 +154,7 @@ impl Transmutable for AddressRepeater {
|
|||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub base: Address,
|
pub base: Address,
|
||||||
pub size: usize,
|
pub size: usize,
|
||||||
pub dev: TransmutableBox,
|
pub dev: Device,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
@ -174,14 +174,14 @@ impl Bus {
|
|||||||
self.blocks.clear();
|
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 size = dev.borrow_mut().as_addressable().unwrap().size();
|
||||||
let block = Block { base, size, dev };
|
let block = Block { base, size, dev };
|
||||||
let i = self.blocks.iter().position(|cur| cur.base > block.base).unwrap_or(self.blocks.len());
|
let i = self.blocks.iter().position(|cur| cur.base > block.base).unwrap_or(self.blocks.len());
|
||||||
self.blocks.insert(i, block);
|
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 {
|
for block in &self.blocks {
|
||||||
if addr >= block.base && addr < (block.base + block.size as Address) {
|
if addr >= block.base && addr < (block.base + block.size as Address) {
|
||||||
let relative_addr = addr - block.base;
|
let relative_addr = addr - block.base;
|
||||||
|
@ -9,12 +9,12 @@ use crate::signals::EdgeSignal;
|
|||||||
use crate::error::{Error, ErrorType};
|
use crate::error::{Error, ErrorType};
|
||||||
use crate::interrupts::InterruptController;
|
use crate::interrupts::InterruptController;
|
||||||
use crate::clock::{ClockTime, ClockDuration};
|
use crate::clock::{ClockTime, ClockDuration};
|
||||||
use crate::devices::{Address, TransmutableBox};
|
use crate::devices::{Address, Device};
|
||||||
|
|
||||||
|
|
||||||
pub struct System {
|
pub struct System {
|
||||||
pub clock: ClockTime,
|
pub clock: ClockTime,
|
||||||
pub devices: HashMap<String, TransmutableBox>,
|
pub devices: HashMap<String, Device>,
|
||||||
pub event_queue: Vec<NextStep>,
|
pub event_queue: Vec<NextStep>,
|
||||||
|
|
||||||
pub debug_enabled: Cell<bool>,
|
pub debug_enabled: Cell<bool>,
|
||||||
@ -55,28 +55,28 @@ impl System {
|
|||||||
self.interrupt_controller.borrow_mut()
|
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)))
|
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.try_queue_device(device.clone());
|
||||||
self.devices.insert(name.to_string(), device);
|
self.devices.insert(name.to_string(), device);
|
||||||
Ok(())
|
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)
|
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.bus.borrow_mut().insert(addr, device.clone());
|
||||||
self.try_queue_device(device.clone());
|
self.try_queue_device(device.clone());
|
||||||
self.devices.insert(name.to_string(), device);
|
self.devices.insert(name.to_string(), device);
|
||||||
Ok(())
|
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.try_queue_device(device.clone());
|
||||||
self.devices.insert(name.to_string(), device);
|
self.devices.insert(name.to_string(), device);
|
||||||
Ok(())
|
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() {
|
if device.borrow_mut().as_steppable().is_some() {
|
||||||
self.queue_device(NextStep::new(device));
|
self.queue_device(NextStep::new(device));
|
||||||
}
|
}
|
||||||
@ -192,11 +192,11 @@ impl System {
|
|||||||
|
|
||||||
pub struct NextStep {
|
pub struct NextStep {
|
||||||
pub next_clock: ClockTime,
|
pub next_clock: ClockTime,
|
||||||
pub device: TransmutableBox,
|
pub device: Device,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NextStep {
|
impl NextStep {
|
||||||
pub fn new(device: TransmutableBox) -> Self {
|
pub fn new(device: Device) -> Self {
|
||||||
Self {
|
Self {
|
||||||
next_clock: ClockTime::START,
|
next_clock: ClockTime::START,
|
||||||
device,
|
device,
|
||||||
|
@ -7,7 +7,7 @@ use std::time::{Duration, Instant};
|
|||||||
use minifb::{self, Key, MouseMode, MouseButton};
|
use minifb::{self, Key, MouseMode, MouseButton};
|
||||||
use clap::{App, Arg, ArgMatches};
|
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_core::host::{Host, Audio, KeyEvent, MouseEvent, MouseState, ControllerDevice, ControllerEvent, EventSender, PixelEncoding, Frame, FrameReceiver};
|
||||||
|
|
||||||
use moa_common::{AudioMixer, AudioSource};
|
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 self.mixer.borrow_mut().num_sources() != 0 && matches.occurrences_of("disable-audio") == 0 {
|
||||||
if let Some(system) = system.as_mut() {
|
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()));
|
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::JsCast;
|
||||||
use wasm_bindgen::closure::Closure;
|
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 moa_core::host::{ControllerInput, ControllerDevice, ControllerEvent, EventSender};
|
||||||
|
|
||||||
use crate::settings;
|
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 mut system = load.0(&mut handle.0, settings::get().rom_data.clone()).unwrap();
|
||||||
let mixer = handle.0.get_mixer();
|
let mixer = handle.0.get_mixer();
|
||||||
if mixer.borrow_mut().num_sources() > 0 {
|
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)
|
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_core::host::Host;
|
||||||
|
|
||||||
use moa_m68k::{M68k, M68kType};
|
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 mut system = System::default();
|
||||||
|
|
||||||
let monitor = MemoryBlock::load("binaries/computie/monitor.bin")?;
|
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]);
|
let mut ram = MemoryBlock::new(vec![0; 0x00100000]);
|
||||||
ram.load_at(0, "binaries/computie/kernel.bin")?;
|
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();
|
let mut ata = AtaDevice::default();
|
||||||
ata.load("binaries/computie/disk-with-partition-table.img")?;
|
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();
|
let mut serial = MC68681::default();
|
||||||
launch_terminal_emulator(serial.port_a.connect(host.add_pty()?)?);
|
launch_terminal_emulator(serial.port_a.connect(host.add_pty()?)?);
|
||||||
launch_slip_connection(serial.port_b.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()));
|
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);
|
cpu.add_breakpoint(0);
|
||||||
|
|
||||||
system.add_interruptable_device("cpu", wrap_transmutable(cpu))?;
|
system.add_interruptable_device("cpu", Device::new(cpu))?;
|
||||||
|
|
||||||
Ok(system)
|
Ok(system)
|
||||||
}
|
}
|
||||||
@ -49,20 +49,20 @@ pub fn build_computie_k30<H: Host>(host: &H) -> Result<System, Error> {
|
|||||||
let mut system = System::default();
|
let mut system = System::default();
|
||||||
|
|
||||||
let monitor = MemoryBlock::load("binaries/computie/monitor-68030.bin")?;
|
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]);
|
let mut ram = MemoryBlock::new(vec![0; 0x00100000]);
|
||||||
ram.load_at(0, "binaries/computie/kernel-68030.bin")?;
|
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();
|
let mut ata = AtaDevice::default();
|
||||||
ata.load("binaries/computie/disk-with-partition-table.img")?;
|
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();
|
let mut serial = MC68681::default();
|
||||||
launch_terminal_emulator(serial.port_a.connect(host.add_pty()?)?);
|
launch_terminal_emulator(serial.port_a.connect(host.add_pty()?)?);
|
||||||
//launch_slip_connection(serial.port_b.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()));
|
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, 0x100000, 0x2000);
|
||||||
//cpu.decoder.dump_disassembly(&mut system, 0x2ac, 0x200);
|
//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)
|
Ok(system)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
use moa_core::{debug, warn, error};
|
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};
|
use moa_core::host::{self, Host, Pixel, PixelEncoding, Frame, FrameSender};
|
||||||
|
|
||||||
|
|
||||||
@ -709,14 +709,14 @@ impl Steppable for Ym7101 {
|
|||||||
pub struct Ym7101 {
|
pub struct Ym7101 {
|
||||||
sender: FrameSender,
|
sender: FrameSender,
|
||||||
state: Ym7101State,
|
state: Ym7101State,
|
||||||
sn_sound: TransmutableBox,
|
sn_sound: Device,
|
||||||
|
|
||||||
pub external_interrupt: Signal<bool>,
|
pub external_interrupt: Signal<bool>,
|
||||||
pub frame_complete: EdgeSignal,
|
pub frame_complete: EdgeSignal,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ym7101 {
|
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);
|
let (sender, receiver) = host::frame_queue(320, 224);
|
||||||
host.add_video_source(receiver).unwrap();
|
host.add_video_source(receiver).unwrap();
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ use std::mem;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
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_core::host::Host;
|
||||||
|
|
||||||
use moa_m68k::{M68k, M68kType};
|
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();
|
//let mut rom = MemoryBlock::load("binaries/genesis/Teenage Mutant Ninja Turtles - The Hyperstone Heist (U) [!].bin").unwrap();
|
||||||
//rom.read_only();
|
//rom.read_only();
|
||||||
let rom_end = rom.size();
|
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]);
|
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]);
|
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
|
// Build the Coprocessor's Bus
|
||||||
let bank_register = Signal::new(0);
|
let bank_register = Signal::new(0);
|
||||||
let coproc_ram = wrap_transmutable(MemoryBlock::new(vec![0; 0x00002000]));
|
let coproc_ram = Device::new(MemoryBlock::new(vec![0; 0x00002000]));
|
||||||
let coproc_ym_sound = wrap_transmutable(Ym2612::new(host, Frequency::from_hz(7_670_454))?);
|
let coproc_ym_sound = Device::new(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_sn_sound = Device::new(Sn76489::new(host, Frequency::from_hz(3_579_545))?);
|
||||||
let coproc_register = wrap_transmutable(CoprocessorBankRegister::new(bank_register.clone()));
|
let coproc_register = Device::new(CoprocessorBankRegister::new(bank_register.clone()));
|
||||||
let coproc_area = wrap_transmutable(CoprocessorBankArea::new(bank_register, system.bus.clone()));
|
let coproc_area = Device::new(CoprocessorBankArea::new(bank_register, system.bus.clone()));
|
||||||
|
|
||||||
let coproc_bus = Rc::new(RefCell::new(Bus::default()));
|
let coproc_bus = Rc::new(RefCell::new(Bus::default()));
|
||||||
coproc_bus.borrow_mut().set_ignore_unmapped(true);
|
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(0x00a06000, coproc_register)?;
|
||||||
//system.add_addressable_device(0x00c00010, coproc_sn_sound)?;
|
//system.add_addressable_device(0x00c00010, coproc_sn_sound)?;
|
||||||
system.add_device("sn_sound", coproc_sn_sound.clone())?;
|
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 controllers = GenesisControllers::new(host)?;
|
||||||
let interrupt = controllers.get_interrupt_signal();
|
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);
|
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);
|
let vdp = Ym7101::new(host, interrupt, coproc_sn_sound);
|
||||||
system.break_signal = Some(vdp.frame_complete.clone());
|
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()));
|
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)
|
Ok(system)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
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_mos::Mos6522;
|
||||||
use moa_peripherals_zilog::Z8530;
|
use moa_peripherals_zilog::Z8530;
|
||||||
@ -22,7 +22,7 @@ pub struct Mainboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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 scc1 = Z8530::default();
|
||||||
let scc2 = Z8530::default();
|
let scc2 = Z8530::default();
|
||||||
let iwm = IWM::default();
|
let iwm = IWM::default();
|
||||||
@ -45,16 +45,16 @@ impl Mainboard {
|
|||||||
if (port.data & 0x10) == 0 {
|
if (port.data & 0x10) == 0 {
|
||||||
println!("{}: overlay is 0 (normal)", DEV_NAME);
|
println!("{}: overlay is 0 (normal)", DEV_NAME);
|
||||||
lower_bus.borrow_mut().clear_all_bus_devices();
|
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(0x000000, Device::new(AddressRepeater::new(ram.clone(), 0x400000)));
|
||||||
lower_bus.borrow_mut().insert(0x400000, wrap_transmutable(AddressRepeater::new(rom.clone(), 0x100000)));
|
lower_bus.borrow_mut().insert(0x400000, Device::new(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||||
lower_bus.borrow_mut().insert(0x600000, wrap_transmutable(AddressRepeater::new(rom.clone(), 0x100000)));
|
lower_bus.borrow_mut().insert(0x600000, Device::new(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||||
} else {
|
} else {
|
||||||
println!("{}: overlay is 1 (startup)", DEV_NAME);
|
println!("{}: overlay is 1 (startup)", DEV_NAME);
|
||||||
lower_bus.borrow_mut().clear_all_bus_devices();
|
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(0x000000, Device::new(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||||
lower_bus.borrow_mut().insert(0x200000, wrap_transmutable(AddressRepeater::new(rom.clone(), 0x100000)));
|
lower_bus.borrow_mut().insert(0x200000, Device::new(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||||
lower_bus.borrow_mut().insert(0x400000, wrap_transmutable(AddressRepeater::new(rom.clone(), 0x100000)));
|
lower_bus.borrow_mut().insert(0x400000, Device::new(AddressRepeater::new(rom.clone(), 0x100000)));
|
||||||
lower_bus.borrow_mut().insert(0x600000, wrap_transmutable(AddressRepeater::new(ram.clone(), 0x200000)));
|
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_core::host::Host;
|
||||||
|
|
||||||
use moa_m68k::{M68k, M68kType};
|
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();
|
rom.read_only();
|
||||||
|
|
||||||
let video = MacVideo::new(host)?;
|
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))?;
|
let mainboard = Mainboard::new(Device::new(ram), Device::new(rom))?;
|
||||||
system.add_addressable_device(0x00000000, wrap_transmutable(mainboard))?;
|
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()));
|
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!("");
|
panic!("");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
system.add_interruptable_device("cpu", wrap_transmutable(cpu))?;
|
system.add_interruptable_device("cpu", Device::new(cpu))?;
|
||||||
|
|
||||||
Ok(system)
|
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_core::host::Host;
|
||||||
|
|
||||||
use moa_z80::{Z80, Z80Type};
|
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, "binaries/trs80/level2.rom")?;
|
||||||
rom.load_at(0x0000, &options.rom)?;
|
rom.load_at(0x0000, &options.rom)?;
|
||||||
rom.read_only();
|
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]);
|
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)?;
|
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)?;
|
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
|
// 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);
|
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(0x9e2);
|
||||||
//cpu.add_breakpoint(0x9f9);
|
//cpu.add_breakpoint(0x9f9);
|
||||||
|
|
||||||
system.add_interruptable_device("cpu", wrap_transmutable(cpu))?;
|
system.add_interruptable_device("cpu", Device::new(cpu))?;
|
||||||
|
|
||||||
Ok(system)
|
Ok(system)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user