diff --git a/src/cpus/m68k/tests.rs b/src/cpus/m68k/tests.rs index 0219a00..dae067d 100644 --- a/src/cpus/m68k/tests.rs +++ b/src/cpus/m68k/tests.rs @@ -703,8 +703,8 @@ mod execute_tests { ins: Instruction::MOVEA(Target::DirectDReg(0), 0, Size::Long), data: &[ 0x2040 ], cputype: M68kType::MC68010, - init: TestState { pc: 0x00000000, msp: 0x00000000, usp: 0x00000000, d0: 0xFEDCBA98, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700 }, - fini: TestState { pc: 0x00000002, msp: 0x00000000, usp: 0x00000000, d0: 0xFEDCBA98, d1: 0x00000000, a0: 0xFEDCBA98, a1: 0x00000000, sr: 0x2700 }, + init: TestState { pc: 0x00000000, msp: 0x00000000, usp: 0x00000000, d0: 0xFEDCBA98, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x27FF }, + fini: TestState { pc: 0x00000002, msp: 0x00000000, usp: 0x00000000, d0: 0xFEDCBA98, d1: 0x00000000, a0: 0xFEDCBA98, a1: 0x00000000, sr: 0x27FF }, }, TestCase { name: "neg", diff --git a/src/host/traits.rs b/src/host/traits.rs index f7144fa..8a83868 100644 --- a/src/host/traits.rs +++ b/src/host/traits.rs @@ -1,4 +1,6 @@ +use std::sync::{Arc, Mutex, MutexGuard}; + use crate::error::Error; use crate::host::keys::Key; @@ -43,3 +45,26 @@ pub trait BlitableSurface { } +#[derive(Clone, Debug)] +pub struct SharedData(Arc>); + +impl SharedData { + pub fn new(init: T) -> SharedData { + SharedData(Arc::new(Mutex::new(init))) + } + + pub fn lock(&self) -> MutexGuard<'_, T> { + self.0.lock().unwrap() + } +} + +impl SharedData { + pub fn set(&mut self, value: T) { + *(self.0.lock().unwrap()) = value; + } + + pub fn get(&mut self) -> T { + *(self.0.lock().unwrap()) + } +} + diff --git a/src/memory.rs b/src/memory.rs index 00aad05..6349232 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -130,13 +130,8 @@ impl Bus { pub fn insert(&mut self, base: Address, length: usize, dev: TransmutableBox) { let block = Block { base, length, dev }; - for i in 0..self.blocks.len() { - if self.blocks[i].base > block.base { - self.blocks.insert(i, block); - return; - } - } - self.blocks.insert(0, block); + let i = self.blocks.iter().position(|cur| cur.base > block.base).unwrap_or(0); + self.blocks.insert(i, block); } pub fn get_device_at(&self, addr: Address, count: usize) -> Result<(TransmutableBox, Address), Error> { diff --git a/src/peripherals/genesis/controllers.rs b/src/peripherals/genesis/controllers.rs index e160c04..7c76520 100644 --- a/src/peripherals/genesis/controllers.rs +++ b/src/peripherals/genesis/controllers.rs @@ -1,8 +1,7 @@ use crate::error::Error; -use crate::signals::SyncSignal; use crate::devices::{Address, Addressable, Transmutable}; -use crate::host::traits::{Host, JoystickDevice, JoystickUpdater}; +use crate::host::traits::{Host, JoystickDevice, JoystickUpdater, SharedData}; const REG_VERSION: Address = 0x01; @@ -23,7 +22,7 @@ pub struct GenesisControllerPort { /// Data contains bits: /// 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 /// X | Y | Z | MODE | START | A | B | C | RIGHT | LEFT | DOWN | UP - pub data: SyncSignal, + pub data: SharedData, pub ctrl: u8, pub th_count: u8, @@ -35,7 +34,7 @@ pub struct GenesisControllerPort { impl GenesisControllerPort { pub fn new() -> Self { Self { - data: SyncSignal::new(0), + data: SharedData::new(0), ctrl: 0, th_count: 0, next_read: 0, @@ -72,7 +71,7 @@ impl GenesisControllerPort { } } -pub struct GenesisControllerUpdater(SyncSignal, SyncSignal); +pub struct GenesisControllerUpdater(SharedData, SharedData); impl JoystickUpdater for GenesisControllerUpdater { fn update_joystick(&mut self, modifiers: u16) { @@ -89,7 +88,7 @@ pub struct GenesisController { pub port_1: GenesisControllerPort, pub port_2: GenesisControllerPort, pub expansion: GenesisControllerPort, - pub interrupt: SyncSignal, + pub interrupt: SharedData, } impl GenesisController { @@ -98,7 +97,7 @@ impl GenesisController { port_1: GenesisControllerPort::new(), port_2: GenesisControllerPort::new(), expansion: GenesisControllerPort::new(), - interrupt: SyncSignal::new(false), + interrupt: SharedData::new(false), } } @@ -113,7 +112,7 @@ impl GenesisController { Ok(controller) } - pub fn get_interrupt_signal(&self) -> SyncSignal { + pub fn get_interrupt_signal(&self) -> SharedData { self.interrupt.clone() } } diff --git a/src/peripherals/genesis/ym7101.rs b/src/peripherals/genesis/ym7101.rs index 458c43e..37707b9 100644 --- a/src/peripherals/genesis/ym7101.rs +++ b/src/peripherals/genesis/ym7101.rs @@ -4,9 +4,8 @@ use std::sync::{Arc, Mutex}; use crate::error::Error; use crate::system::System; -use crate::signals::SyncSignal; use crate::devices::{Clock, ClockElapsed, Address, Addressable, Steppable, Transmutable, read_beu16, read_beu32, write_beu16}; -use crate::host::traits::{Host, BlitableSurface}; +use crate::host::traits::{Host, BlitableSurface, SharedData}; use crate::host::gfx::{Frame, FrameSwapper}; @@ -410,11 +409,11 @@ impl<'a> Iterator for PatternIterator<'a> { pub struct Ym7101 { pub swapper: Arc>, pub state: Ym7101State, - pub external_interrupt: SyncSignal, + pub external_interrupt: SharedData, } impl Ym7101 { - pub fn new(host: &mut H, external_interrupt: SyncSignal) -> Ym7101 { + pub fn new(host: &mut H, external_interrupt: SharedData) -> Ym7101 { let swapper = FrameSwapper::new_shared(320, 224); host.add_window(FrameSwapper::to_boxed(swapper.clone())).unwrap(); diff --git a/src/peripherals/mc68681.rs b/src/peripherals/mc68681.rs index e92db0d..0b1c64c 100644 --- a/src/peripherals/mc68681.rs +++ b/src/peripherals/mc68681.rs @@ -252,7 +252,7 @@ impl Steppable for MC68681 { self.set_interrupt_flag(ISR_CH_B_TX_READY, true); } - Ok(1_000_000_000 / 3_646_800) + Ok(1_000_000_000 / 3_686_400) } } diff --git a/src/signals.rs b/src/signals.rs index cbceb58..9a63395 100644 --- a/src/signals.rs +++ b/src/signals.rs @@ -1,7 +1,6 @@ use std::rc::Rc; -use std::cell::Cell; -use std::sync::{Arc, Mutex}; +use std::cell::{Cell, RefCell, RefMut}; #[derive(Clone, Debug)] pub struct Signal(Rc>); @@ -20,22 +19,16 @@ impl Signal { } } - #[derive(Clone, Debug)] -pub struct SyncSignal(Arc>); +pub struct Latch(Rc>); -impl SyncSignal { - pub fn new(init: T) -> SyncSignal { - SyncSignal(Arc::new(Mutex::new(init))) +impl Latch { + pub fn new(init: T) -> Latch { + Latch(Rc::new(RefCell::new(init))) } - pub fn set(&mut self, value: T) { - *(self.0.lock().unwrap()) = value; - } - - pub fn get(&mut self) -> T { - *(self.0.lock().unwrap()) + pub fn borrow_mut(&self) -> RefMut<'_, T> { + self.0.borrow_mut() } } - diff --git a/todo.txt b/todo.txt index f5bfbc1..c0406be 100644 --- a/todo.txt +++ b/todo.txt @@ -30,7 +30,7 @@ Genesis/Mega Drive: * make tests for each instruction * check all instructions in the docs - * unimplemented: ABCD, ADDX, BFFFO, BFINS, BKPT, CHK, EXG, ILLEGAL, MOVEfromCCR, MOVEP, RTR, RTD, SBCD, SUBX + * unimplemented: ABCD, ADDX, BFFFO, BFINS, BKPT, CHK, ILLEGAL, MOVEfromCCR,, RTR, RTD, SBCD, SUBX * >=MC68020 undecoded & unimplemented: CALLM, CAS, CAS2, CHK2, CMP2, RTM, PACK, TRAPcc, UNPK * add support for MMU