mirror of
https://github.com/transistorfet/moa.git
synced 2025-02-08 20:30:40 +00:00
Added hackish H/V counter for YM7101
This commit is contained in:
parent
ba1dc78ff1
commit
c6eeed03ff
@ -90,7 +90,7 @@ pub fn build_genesis<H: Host>(host: &mut H, options: SegaGenesisOptions) -> Resu
|
||||
system.add_device("coproc", wrap_transmutable(coproc))?;
|
||||
|
||||
|
||||
let controllers = genesis::controllers::GenesisController::create(host)?;
|
||||
let controllers = genesis::controllers::GenesisControllers::create(host)?;
|
||||
let interrupt = controllers.get_interrupt_signal();
|
||||
system.add_addressable_device(0x00a10000, wrap_transmutable(controllers)).unwrap();
|
||||
|
||||
|
@ -85,9 +85,9 @@ impl GenesisControllerPort {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GenesisControllerUpdater(HostData<u16>, HostData<bool>);
|
||||
pub struct GenesisControllersUpdater(HostData<u16>, HostData<bool>);
|
||||
|
||||
impl ControllerUpdater for GenesisControllerUpdater {
|
||||
impl ControllerUpdater for GenesisControllersUpdater {
|
||||
fn update_controller(&mut self, event: ControllerEvent) {
|
||||
let (mask, state) = match event {
|
||||
ControllerEvent::ButtonA(state) => (0x0040, state),
|
||||
@ -112,7 +112,7 @@ impl ControllerUpdater for GenesisControllerUpdater {
|
||||
|
||||
|
||||
|
||||
pub struct GenesisController {
|
||||
pub struct GenesisControllers {
|
||||
port_1: GenesisControllerPort,
|
||||
port_2: GenesisControllerPort,
|
||||
expansion: GenesisControllerPort,
|
||||
@ -120,9 +120,9 @@ pub struct GenesisController {
|
||||
reset_timer: Clock,
|
||||
}
|
||||
|
||||
impl GenesisController {
|
||||
impl GenesisControllers {
|
||||
pub fn new() -> Self {
|
||||
GenesisController {
|
||||
Self {
|
||||
port_1: GenesisControllerPort::new(),
|
||||
port_2: GenesisControllerPort::new(),
|
||||
expansion: GenesisControllerPort::new(),
|
||||
@ -132,11 +132,11 @@ impl GenesisController {
|
||||
}
|
||||
|
||||
pub fn create<H: Host>(host: &mut H) -> Result<Self, Error> {
|
||||
let controller = GenesisController::new();
|
||||
let controller = GenesisControllers::new();
|
||||
|
||||
let controller1 = Box::new(GenesisControllerUpdater(controller.port_1.buttons.clone(), controller.interrupt.clone()));
|
||||
let controller1 = Box::new(GenesisControllersUpdater(controller.port_1.buttons.clone(), controller.interrupt.clone()));
|
||||
host.register_controller(ControllerDevice::A, controller1)?;
|
||||
let controller2 = Box::new(GenesisControllerUpdater(controller.port_2.buttons.clone(), controller.interrupt.clone()));
|
||||
let controller2 = Box::new(GenesisControllersUpdater(controller.port_2.buttons.clone(), controller.interrupt.clone()));
|
||||
host.register_controller(ControllerDevice::B, controller2)?;
|
||||
|
||||
Ok(controller)
|
||||
@ -147,7 +147,7 @@ impl GenesisController {
|
||||
}
|
||||
}
|
||||
|
||||
impl Addressable for GenesisController {
|
||||
impl Addressable for GenesisControllers {
|
||||
fn len(&self) -> usize {
|
||||
0x30
|
||||
}
|
||||
@ -197,7 +197,7 @@ impl Addressable for GenesisController {
|
||||
}
|
||||
}
|
||||
|
||||
impl Steppable for GenesisController {
|
||||
impl Steppable for GenesisControllers {
|
||||
fn step(&mut self, system: &System) -> Result<ClockElapsed, Error> {
|
||||
let duration = 100_00; // Update every 100us
|
||||
|
||||
@ -211,7 +211,7 @@ impl Steppable for GenesisController {
|
||||
}
|
||||
}
|
||||
|
||||
impl Transmutable for GenesisController {
|
||||
impl Transmutable for GenesisControllers {
|
||||
fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
|
||||
Some(self)
|
||||
}
|
||||
|
@ -311,9 +311,13 @@ pub struct Ym7101State {
|
||||
pub sprites_by_line: Vec<Vec<usize>>,
|
||||
|
||||
pub last_clock: Clock,
|
||||
pub p_clock: u32,
|
||||
pub h_clock: u32,
|
||||
pub v_clock: u32,
|
||||
pub h_scanlines: u8,
|
||||
|
||||
pub current_x: i32,
|
||||
pub current_y: i32,
|
||||
}
|
||||
|
||||
impl Ym7101State {
|
||||
@ -342,9 +346,13 @@ impl Ym7101State {
|
||||
sprites_by_line: vec![],
|
||||
|
||||
last_clock: 0,
|
||||
p_clock: 0,
|
||||
h_clock: 0,
|
||||
v_clock: 0,
|
||||
h_scanlines: 0,
|
||||
|
||||
current_x: 0,
|
||||
current_y: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -608,12 +616,22 @@ impl Steppable for Ym7101 {
|
||||
system.get_interrupt_controller().set(true, 2, 26)?;
|
||||
}
|
||||
|
||||
let clocks_per_pixel = 63_500 / (self.state.screen_size.0 as u32 * 8 + 88);
|
||||
self.state.p_clock += diff;
|
||||
if self.state.p_clock >= clocks_per_pixel {
|
||||
let pixels = self.state.p_clock / clocks_per_pixel;
|
||||
self.state.p_clock -= pixels * clocks_per_pixel;
|
||||
self.state.current_x += pixels as i32;
|
||||
}
|
||||
|
||||
self.state.h_clock += diff;
|
||||
if (self.state.status & STATUS_IN_HBLANK) != 0 && self.state.h_clock >= 2_340 && self.state.h_clock <= 61_160 {
|
||||
self.state.status &= !STATUS_IN_HBLANK;
|
||||
self.state.current_x = 0;
|
||||
}
|
||||
if (self.state.status & STATUS_IN_HBLANK) == 0 && self.state.h_clock >= 61_160 {
|
||||
self.state.status |= STATUS_IN_HBLANK;
|
||||
self.state.current_y += 1;
|
||||
|
||||
self.state.h_scanlines = self.state.h_scanlines.wrapping_sub(1);
|
||||
if self.state.hsync_int_enabled() && self.state.h_scanlines == 0 {
|
||||
@ -628,6 +646,7 @@ impl Steppable for Ym7101 {
|
||||
self.state.v_clock += diff;
|
||||
if (self.state.status & STATUS_IN_VBLANK) != 0 && self.state.v_clock >= 1_205_992 && self.state.v_clock <= 15_424_008 {
|
||||
self.state.status &= !STATUS_IN_VBLANK;
|
||||
self.state.current_y = 0;
|
||||
}
|
||||
if (self.state.status & STATUS_IN_VBLANK) == 0 && self.state.v_clock >= 15_424_008 {
|
||||
self.state.status |= STATUS_IN_VBLANK;
|
||||
@ -692,6 +711,7 @@ impl Ym7101 {
|
||||
REG_MODE_SET_2 => {
|
||||
self.state.mode_2 = data;
|
||||
self.state.update_screen_size();
|
||||
self.swapper.set_size(self.state.screen_size.0 as u32 * 8, self.state.screen_size.1 as u32 * 8);
|
||||
},
|
||||
REG_SCROLL_A_ADDR => { self.state.scroll_a_addr = (data as usize) << 10; },
|
||||
REG_WINDOW_ADDR => { self.state.window_addr = (data as usize) << 10; },
|
||||
@ -703,6 +723,7 @@ impl Ym7101 {
|
||||
REG_MODE_SET_4 => {
|
||||
self.state.mode_4 = data;
|
||||
self.state.update_screen_size();
|
||||
self.swapper.set_size(self.state.screen_size.0 as u32 * 8, self.state.screen_size.1 as u32 * 8);
|
||||
},
|
||||
REG_HSCROLL_ADDR => { self.state.hscroll_addr = (data as usize) << 10; },
|
||||
REG_AUTO_INCREMENT => { self.state.memory.transfer_auto_inc = data as u32; },
|
||||
@ -776,6 +797,14 @@ impl Addressable for Ym7101 {
|
||||
}
|
||||
},
|
||||
|
||||
// Read from H/V Counter
|
||||
0x08 | 0x0A => {
|
||||
data[0] = self.state.current_y as u8;
|
||||
if data.len() > 1 {
|
||||
data[1] = (self.state.current_x >> 1) as u8;
|
||||
}
|
||||
},
|
||||
|
||||
_ => { println!("{}: !!! unhandled read from {:x}", DEV_NAME, addr); },
|
||||
}
|
||||
Ok(())
|
||||
|
Loading…
x
Reference in New Issue
Block a user