From b540e53ea157c3aa24caeea601fa98e04d0337fe Mon Sep 17 00:00:00 2001 From: transistor Date: Fri, 3 Dec 2021 15:32:59 -0800 Subject: [PATCH] Fixed issues with Genesis controllers and sprite rendering The controller th count was starting at 1 instead of 0 which caused inputs to be read incorrectly, as well as the fact that inputs are inverted. The sprite fix now draws them in the right order so that ComradeOj's sprite test renders correctly, but games still render them broken because of some other bug yet to be found --- frontends/moa-minifb/src/lib.rs | 6 +++ src/peripherals/genesis/controllers.rs | 53 ++++++++++++++------------ src/peripherals/genesis/ym7101.rs | 6 +-- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/frontends/moa-minifb/src/lib.rs b/frontends/moa-minifb/src/lib.rs index 084cc4f..30e94e6 100644 --- a/frontends/moa-minifb/src/lib.rs +++ b/frontends/moa-minifb/src/lib.rs @@ -193,7 +193,13 @@ impl MiniFrontend { match key { Key::A => { modifiers |= 0x0040; }, Key::B => { modifiers |= 0x0010; }, + Key::C => { modifiers |= 0x0020; }, + Key::Up => { modifiers |= 0x0001; }, + Key::Down => { modifiers |= 0x0002; }, + Key::Left => { modifiers |= 0x0004; }, + Key::Right => { modifiers |= 0x0008; }, Key::Enter => { modifiers |= 0x0080; }, + Key::M => { modifiers |= 0x0100; }, Key::D => { system.as_ref().map(|s| s.enable_debugging()); }, _ => { }, } diff --git a/src/peripherals/genesis/controllers.rs b/src/peripherals/genesis/controllers.rs index fb743f8..e713a32 100644 --- a/src/peripherals/genesis/controllers.rs +++ b/src/peripherals/genesis/controllers.rs @@ -43,33 +43,36 @@ impl GenesisControllerPort { } } - pub fn set_data(&mut self, data: u8) { + pub fn set_data(&mut self, outputs: u8) { let prev_th = self.next_read & 0x40; - self.next_read = data & self.ctrl; + self.next_read = outputs & self.ctrl; - if (self.next_read ^ prev_th) != 0 { + if ((self.next_read & 0x40) ^ prev_th) != 0 { // TH bit was toggled - self.th_count += 1; - let data = self.data.get(); + let inputs = self.data.get(); self.next_read = match self.th_count { - 0 => self.next_read | ((data & 0x003F) as u8), - 1 => self.next_read | (((data & 0x00C0) >> 2) as u8) | ((data & 0x0003) as u8), - 2 => self.next_read | ((data & 0x003F) as u8), - 3 => self.next_read | (((data & 0x00C0) >> 2) as u8), - 4 => self.next_read | ((data & 0x0030) as u8) | (((data & 0x0F00) >> 8) as u8), - 5 => self.next_read | (((data & 0x00C0) >> 2) as u8) | 0x0F, - 6 => self.next_read | ((data & 0x003F) as u8), - 7 => { - self.th_count = 0; - self.next_read | (((data & 0x00C0) >> 2) as u8) | ((data & 0x0003) as u8) - }, - _ => { - self.th_count = 0; - 0 - }, + 0 => self.next_read | ((inputs & 0x003F) as u8), + 1 => self.next_read | (((inputs & 0x00C0) >> 2) as u8) | ((inputs & 0x0003) as u8), + 2 => self.next_read | ((inputs & 0x003F) as u8), + 3 => self.next_read | (((inputs & 0x00C0) >> 2) as u8), + 4 => self.next_read | ((inputs & 0x0030) as u8) | (((inputs & 0x0F00) >> 8) as u8), + 5 => self.next_read | (((inputs & 0x00C0) >> 2) as u8) | 0x0F, + 6 => self.next_read | ((inputs & 0x003F) as u8), + 7 => self.next_read | (((inputs & 0x00C0) >> 2) as u8) | ((inputs & 0x0003) as u8), + _ => 0, }; + + self.th_count += 1; + if self.th_count > 7 { + self.th_count = 0; + } } } + + pub fn set_ctrl(&mut self, ctrl: u8) { + self.ctrl = ctrl; + self.th_count = 0; + } } pub struct GenesisControllerUpdater(SharedData, SharedData); @@ -146,19 +149,19 @@ impl Addressable for GenesisController { REG_S_CTRL3 => { data[i] = self.expansion.s_ctrl | 0x02; }, _ => { warning!("{}: !!! unhandled reading from {:0x}", DEV_NAME, addr); }, } - info!("{}: read from register {:x} the value {:x}", DEV_NAME, addr, data[0]); + debug!("{}: read from register {:x} the value {:x}", DEV_NAME, addr, data[0]); Ok(()) } fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> { - info!("{}: write to register {:x} with {:x}", DEV_NAME, addr, data[0]); + debug!("{}: write to register {:x} with {:x}", DEV_NAME, addr, data[0]); match addr { REG_DATA1 => { self.port_1.set_data(data[0]); } REG_DATA2 => { self.port_2.set_data(data[0]); }, REG_DATA3 => { self.expansion.set_data(data[0]); }, - REG_CTRL1 => { self.port_1.ctrl = data[0]; }, - REG_CTRL2 => { self.port_2.ctrl = data[0]; }, - REG_CTRL3 => { self.expansion.ctrl = data[0]; }, + REG_CTRL1 => { self.port_1.set_ctrl(data[0]); }, + REG_CTRL2 => { self.port_2.set_ctrl(data[0]); }, + REG_CTRL3 => { self.expansion.set_ctrl(data[0]); }, REG_S_CTRL1 => { self.port_1.s_ctrl = data[0] & 0xF8; }, REG_S_CTRL2 => { self.port_2.s_ctrl = data[0] & 0xF8; }, REG_S_CTRL3 => { self.expansion.s_ctrl = data[0] & 0xF8; }, diff --git a/src/peripherals/genesis/ym7101.rs b/src/peripherals/genesis/ym7101.rs index 09ef6e8..6240b24 100644 --- a/src/peripherals/genesis/ym7101.rs +++ b/src/peripherals/genesis/ym7101.rs @@ -336,12 +336,12 @@ impl Ym7101State { for ih in 0..size_h { for iv in 0..size_v { - let (h, v) = (if !h_rev { ih } else { size_h - ih }, if !v_rev { iv } else { size_v - iv }); - let (x, y) = (h_pos + h * 8, v_pos + v * 8); + let (h, v) = (if !h_rev { ih } else { size_h - 1 - ih }, if !v_rev { iv } else { size_v - 1 - iv }); + let (x, y) = (h_pos + ih * 8, v_pos + iv * 8); if x > 128 && x < pos_limit_h && y > 128 && y < pos_limit_v { let iter = self.get_pattern_iter(((pattern_name & 0x07FF) + (h * size_v) + v) | (pattern_name & 0xF800)); - println!("{}: ({} {}), {:x}", i, x, y, ((pattern_name & 0x07FF) + (h * size_v) + v)); +//println!("{}: ({} {}), {:x}", i, x, y, ((pattern_name & 0x07FF) + (h * size_v) + v)); frame.blit(x as u32 - 128, y as u32 - 128, iter, 8, 8); } }