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
This commit is contained in:
transistor 2021-12-03 15:32:59 -08:00
parent 75e4a760eb
commit b540e53ea1
3 changed files with 37 additions and 28 deletions

View File

@ -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()); },
_ => { },
}

View File

@ -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<u16>, SharedData<bool>);
@ -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; },

View File

@ -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);
}
}