diff --git a/frontends/moa-minifb/src/lib.rs b/frontends/moa-minifb/src/lib.rs index 528718b..084cc4f 100644 --- a/frontends/moa-minifb/src/lib.rs +++ b/frontends/moa-minifb/src/lib.rs @@ -8,7 +8,8 @@ use clap::{App, ArgMatches}; use moa::error::Error; use moa::system::System; -use moa::host::traits::{Host, JoystickDevice, JoystickUpdater, KeyboardUpdater, WindowUpdater}; +use moa::host::traits::{Host, ControllerUpdater, KeyboardUpdater, WindowUpdater}; +use moa::host::controller::{ControllerDevice, Controller}; mod keys; use crate::keys::map_key; @@ -71,7 +72,7 @@ fn wait_until_initialized(frontend: Arc>) { pub struct MiniFrontendBuilder { pub window: Option>, - pub joystick: Option>, + pub controller: Option>, pub keyboard: Option>, pub finalized: bool, } @@ -80,7 +81,7 @@ impl MiniFrontendBuilder { pub fn new() -> Self { Self { window: None, - joystick: None, + controller: None, keyboard: None, finalized: false, } @@ -92,9 +93,9 @@ impl MiniFrontendBuilder { pub fn build(&mut self) -> MiniFrontend { let window = std::mem::take(&mut self.window); - let joystick = std::mem::take(&mut self.joystick); + let controller = std::mem::take(&mut self.controller); let keyboard = std::mem::take(&mut self.keyboard); - MiniFrontend::new(window, joystick, keyboard) + MiniFrontend::new(window, controller, keyboard) } } @@ -107,15 +108,15 @@ impl Host for MiniFrontendBuilder { Ok(()) } - fn register_joystick(&mut self, device: JoystickDevice, input: Box) -> Result<(), Error> { - if device != JoystickDevice::A { + fn register_controller(&mut self, device: ControllerDevice, input: Box) -> Result<(), Error> { + if device != ControllerDevice::A { return Ok(()) } - if self.joystick.is_some() { - return Err(Error::new("A joystick updater has already been registered with the frontend")); + if self.controller.is_some() { + return Err(Error::new("A controller updater has already been registered with the frontend")); } - self.joystick = Some(input); + self.controller = Some(input); Ok(()) } @@ -132,16 +133,16 @@ impl Host for MiniFrontendBuilder { pub struct MiniFrontend { pub buffer: Vec, pub window: Option>, - pub joystick: Option>, + pub controller: Option>, pub keyboard: Option>, } impl MiniFrontend { - pub fn new(window: Option>, joystick: Option>, keyboard: Option>) -> Self { + pub fn new(window: Option>, controller: Option>, keyboard: Option>) -> Self { Self { buffer: vec![0; (WIDTH * HEIGHT) as usize], window, - joystick, + controller, keyboard, } } @@ -184,19 +185,22 @@ impl MiniFrontend { } if let Some(keys) = window.get_keys_pressed(minifb::KeyRepeat::Yes) { - let mut modifiers: u16 = 0; + let mut modifiers: u16 = 0x0000; for key in keys { if let Some(updater) = self.keyboard.as_mut() { updater.update_keyboard(map_key(key), true); } match key { - Key::Enter => { modifiers |= 0xffff; }, + Key::A => { modifiers |= 0x0040; }, + Key::B => { modifiers |= 0x0010; }, + Key::Enter => { modifiers |= 0x0080; }, Key::D => { system.as_ref().map(|s| s.enable_debugging()); }, _ => { }, } } - if let Some(updater) = self.joystick.as_mut() { - updater.update_joystick(modifiers); + if let Some(updater) = self.controller.as_mut() { + let data = Controller { bits: modifiers }; + updater.update_controller(data); } } if let Some(keys) = window.get_keys_released() { diff --git a/src/host/controller.rs b/src/host/controller.rs new file mode 100644 index 0000000..c99012f --- /dev/null +++ b/src/host/controller.rs @@ -0,0 +1,19 @@ + +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum ControllerDevice { + A, + B, + C, + D, +} + +pub struct Controller { + //pub dpad_up: bool, + //pub dpad_down: bool, + //pub dpad_left: bool, + //pub dpad_right: bool, + + // TODO this is temporary until I actually implement this properly + pub bits: u16, +} + diff --git a/src/host/mod.rs b/src/host/mod.rs index 43da817..ef4aed1 100644 --- a/src/host/mod.rs +++ b/src/host/mod.rs @@ -6,4 +6,5 @@ pub mod tty; pub mod gfx; pub mod keys; +pub mod controller; diff --git a/src/host/traits.rs b/src/host/traits.rs index 8a83868..577d2e0 100644 --- a/src/host/traits.rs +++ b/src/host/traits.rs @@ -3,19 +3,12 @@ use std::sync::{Arc, Mutex, MutexGuard}; use crate::error::Error; use crate::host::keys::Key; - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum JoystickDevice { - A, - B, - C, - D, -} +use crate::host::controller::{ControllerDevice, Controller}; pub trait Host { //fn create_pty(&self) -> Result, Error>; fn add_window(&mut self, updater: Box) -> Result<(), Error>; - fn register_joystick(&mut self, _device: JoystickDevice, _input: Box) -> Result<(), Error> { Err(Error::new("Not supported")) } + fn register_controller(&mut self, _device: ControllerDevice, _input: Box) -> Result<(), Error> { Err(Error::new("Not supported")) } fn register_keyboard(&mut self, _input: Box) -> Result<(), Error> { Err(Error::new("Not supported")) } } @@ -30,8 +23,8 @@ pub trait WindowUpdater: Send { fn update_frame(&mut self, width: u32, height: u32, bitmap: &mut [u32]); } -pub trait JoystickUpdater: Send { - fn update_joystick(&mut self, modifiers: u16); +pub trait ControllerUpdater: Send { + fn update_controller(&mut self, data: Controller); } pub trait KeyboardUpdater: Send { diff --git a/src/machines/genesis.rs b/src/machines/genesis.rs index d085151..25d99bb 100644 --- a/src/machines/genesis.rs +++ b/src/machines/genesis.rs @@ -17,8 +17,9 @@ use crate::host::traits::{Host}; pub fn build_genesis(host: &mut H) -> Result { let mut system = System::new(); - //let mut rom = MemoryBlock::load("binaries/genesis/GenTestV3.0.bin").unwrap(); - let mut rom = MemoryBlock::load("binaries/genesis/ComradeOj's tiny demo.bin").unwrap(); + let mut rom = MemoryBlock::load("binaries/genesis/GenTestV3.0.bin").unwrap(); + //let mut rom = MemoryBlock::load("binaries/genesis/HDRV_Genesis_Test_v1_4.bin").unwrap(); + //let mut rom = MemoryBlock::load("binaries/genesis/ComradeOj's tiny demo.bin").unwrap(); //let mut rom = MemoryBlock::load("binaries/genesis/Sonic The Hedgehog (W) (REV 00) [!].bin").unwrap(); //let mut rom = MemoryBlock::load("binaries/genesis/Sonic The Hedgehog (W) (REV 01) [!].bin").unwrap(); //let mut rom = MemoryBlock::load("binaries/genesis/Sonic the Hedgehog 2 (JUE) [!].bin").unwrap(); diff --git a/src/memory.rs b/src/memory.rs index 72a1b65..1a9b25d 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -75,12 +75,12 @@ impl Transmutable for MemoryBlock { } -pub struct MemoryAdapter { +pub struct AddressAdapter { pub subdevice: TransmutableBox, pub shift: u8, } -impl MemoryAdapter { +impl AddressAdapter { pub fn new(subdevice: TransmutableBox, shift: u8) -> Self { Self { subdevice, @@ -89,7 +89,7 @@ impl MemoryAdapter { } } -impl Addressable for MemoryAdapter { +impl Addressable for AddressAdapter { fn len(&self) -> usize { let len = self.subdevice.borrow_mut().as_addressable().unwrap().len(); len << self.shift @@ -104,7 +104,7 @@ impl Addressable for MemoryAdapter { } } -impl Transmutable for MemoryAdapter { +impl Transmutable for AddressAdapter { fn as_addressable(&mut self) -> Option<&mut dyn Addressable> { Some(self) } diff --git a/src/peripherals/genesis/controllers.rs b/src/peripherals/genesis/controllers.rs index 7c76520..fb743f8 100644 --- a/src/peripherals/genesis/controllers.rs +++ b/src/peripherals/genesis/controllers.rs @@ -1,7 +1,8 @@ use crate::error::Error; use crate::devices::{Address, Addressable, Transmutable}; -use crate::host::traits::{Host, JoystickDevice, JoystickUpdater, SharedData}; +use crate::host::controller::{ControllerDevice, Controller}; +use crate::host::traits::{Host, ControllerUpdater, SharedData}; const REG_VERSION: Address = 0x01; @@ -21,7 +22,7 @@ const DEV_NAME: &'static str = "genesis_controller"; 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 + /// X | Y | Z | MODE | START | A | C | B | RIGHT | LEFT | DOWN | UP pub data: SharedData, pub ctrl: u8, @@ -34,7 +35,7 @@ pub struct GenesisControllerPort { impl GenesisControllerPort { pub fn new() -> Self { Self { - data: SharedData::new(0), + data: SharedData::new(0xffff), ctrl: 0, th_count: 0, next_read: 0, @@ -73,10 +74,12 @@ impl GenesisControllerPort { pub struct GenesisControllerUpdater(SharedData, SharedData); -impl JoystickUpdater for GenesisControllerUpdater { - fn update_joystick(&mut self, modifiers: u16) { +impl ControllerUpdater for GenesisControllerUpdater { + fn update_controller(&mut self, data: Controller) { + //let modifiers = if data.bits == 0 { 0xFFFF } else { data.bits }; + let modifiers = !data.bits; self.0.set(modifiers); - if modifiers != 0 { + if data.bits != 0 { self.1.set(true); } } @@ -104,10 +107,10 @@ impl GenesisController { pub fn create(host: &mut H) -> Result { let controller = GenesisController::new(); - let joystick1 = Box::new(GenesisControllerUpdater(controller.port_1.data.clone(), controller.interrupt.clone())); - host.register_joystick(JoystickDevice::A, joystick1)?; - let joystick2 = Box::new(GenesisControllerUpdater(controller.port_2.data.clone(), controller.interrupt.clone())); - host.register_joystick(JoystickDevice::B, joystick2)?; + let controller1 = Box::new(GenesisControllerUpdater(controller.port_1.data.clone(), controller.interrupt.clone())); + host.register_controller(ControllerDevice::A, controller1)?; + let controller2 = Box::new(GenesisControllerUpdater(controller.port_2.data.clone(), controller.interrupt.clone())); + host.register_controller(ControllerDevice::B, controller2)?; Ok(controller) } diff --git a/src/peripherals/genesis/ym7101.rs b/src/peripherals/genesis/ym7101.rs index be87426..09ef6e8 100644 --- a/src/peripherals/genesis/ym7101.rs +++ b/src/peripherals/genesis/ym7101.rs @@ -702,6 +702,9 @@ impl Inspectable for Ym7101 { "vram" => { self.state.dump_vram(); }, + "vsram" => { + self.state.dump_vsram(); + }, _ => { }, } Ok(()) @@ -740,5 +743,22 @@ impl Ym7101State { println!("{}", line); } } + + pub fn dump_vsram(&self) { + let mut count = 80; + let mut addr = 0; + while count > 0 { + let mut line = format!("{:#010x}: ", addr); + + let to = if count < 16 { count / 2 } else { 8 }; + for _ in 0..to { + let word = ((self.vsram[addr] as u16) << 8) | self.vsram[addr + 1] as u16; + line += &format!("{:#06x} ", word); + addr += 2; + count -= 2; + } + println!("{}", line); + } + } } diff --git a/todo.txt b/todo.txt index 112d2ba..0698206 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,8 @@ +* should SharedData be HostData, or something else? I don't think the name is very informative +* can you make the connections between things (like memory adapters), be expressed in a way that's more similar to the electrical design? + like specifying that address pins 10-7 should be ignored/unconnected, pin 11 will connect to "chip select", etc + * movem still isn't working (for genesis) * fix movem tests