From 62419d27b52bedf832af9db6c5cc58c2a8577c04 Mon Sep 17 00:00:00 2001 From: Robin Sergeant Date: Thu, 25 Jan 2024 22:03:30 +0000 Subject: rm/rmnimbus.cpp: Allow choice of HLE mouse processing (#11890) --- src/mame/rm/rmnimbus.cpp | 5 ++ src/mame/rm/rmnimbus.h | 11 +++++ src/mame/rm/rmnimbus_m.cpp | 113 +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 116 insertions(+), 13 deletions(-) diff --git a/src/mame/rm/rmnimbus.cpp b/src/mame/rm/rmnimbus.cpp index a8cc0a480f2..a795cd9249d 100644 --- a/src/mame/rm/rmnimbus.cpp +++ b/src/mame/rm/rmnimbus.cpp @@ -68,6 +68,11 @@ void rmnimbus_state::nimbus_io(address_map &map) static INPUT_PORTS_START( nimbus ) + PORT_START("config") + PORT_CONFNAME( 0x01, 0x00, "Mouse emulation mode" ) + PORT_CONFSETTING( 0x00, "Real" ) + PORT_CONFSETTING( 0x01, "HLE" ) + PORT_START(JOYSTICK0_TAG) PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY diff --git a/src/mame/rm/rmnimbus.h b/src/mame/rm/rmnimbus.h index d6e21f56fc0..4fdaa599626 100644 --- a/src/mame/rm/rmnimbus.h +++ b/src/mame/rm/rmnimbus.h @@ -77,6 +77,7 @@ public: m_fdc(*this, FDC_TAG), m_z80sio(*this, Z80SIO_TAG), m_screen(*this, "screen"), + m_io_config(*this, "config"), m_io_joysticks(*this, JOYSTICK_TAG_BASE "%u", 0), m_io_mouse_button(*this, MOUSE_BUTTON_TAG), m_io_mousex(*this, MOUSEX_TAG), @@ -104,6 +105,7 @@ private: required_device m_fdc; required_device m_z80sio; required_device m_screen; + required_ioport m_io_config; required_ioport_array<2> m_io_joysticks; required_ioport m_io_mouse_button; required_ioport m_io_mousex; @@ -227,6 +229,13 @@ private: /* Mouse */ struct { + uint16_t xpos_loc = 0; + uint16_t ypos_loc = 0; + uint16_t xmin_loc = 0; + uint16_t ymin_loc = 0; + uint16_t xmax_loc = 0; + uint16_t ymax_loc = 0; + uint8_t m_mouse_x = 0; uint8_t m_mouse_y = 0; @@ -263,6 +272,8 @@ private: offs_t dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms); TIMER_CALLBACK_MEMBER(do_mouse); + void do_mouse_real(int8_t xdiff, int8_t ydiff); + void do_mouse_hle(int8_t xdiff, int8_t ydiff); }; #endif // MAME_RM_RMNIMBUS_H diff --git a/src/mame/rm/rmnimbus_m.cpp b/src/mame/rm/rmnimbus_m.cpp index 2a721a3b4f5..d7e53f9a5c5 100644 --- a/src/mame/rm/rmnimbus_m.cpp +++ b/src/mame/rm/rmnimbus_m.cpp @@ -980,6 +980,29 @@ TIMER_CALLBACK_MEMBER(rmnimbus_state::do_mouse) int8_t xdiff; // Difference from previous X and Y int8_t ydiff; + // Read mose positions and calculate difference from previous value + mouse_x = m_io_mousex->read(); + mouse_y = m_io_mousey->read(); + + xdiff = m_nimbus_mouse.m_mouse_x - mouse_x; + ydiff = m_nimbus_mouse.m_mouse_y - mouse_y; + + if (m_io_config->read() & 0x01) + { + do_mouse_hle(xdiff, ydiff); + } + else + { + do_mouse_real(xdiff, ydiff); + } + + // Update current mouse position + m_nimbus_mouse.m_mouse_x = mouse_x; + m_nimbus_mouse.m_mouse_y = mouse_y; +} + +void rmnimbus_state::do_mouse_real(int8_t xdiff, int8_t ydiff) +{ uint8_t intstate_x; // Used to calculate if we should trigger interrupt uint8_t intstate_y; int xint; // X and Y interrupts to trigger @@ -990,13 +1013,6 @@ TIMER_CALLBACK_MEMBER(rmnimbus_state::do_mouse) uint8_t mya; uint8_t myb; - // Read mose positions and calculate difference from previous value - mouse_x = m_io_mousex->read(); - mouse_y = m_io_mousey->read(); - - xdiff = m_nimbus_mouse.m_mouse_x - mouse_x; - ydiff = m_nimbus_mouse.m_mouse_y - mouse_y; - // convert movement into emulated movement of quadrature encoder in mouse. if (xdiff < 0) m_nimbus_mouse.m_mouse_pcx++; @@ -1049,17 +1065,78 @@ TIMER_CALLBACK_MEMBER(rmnimbus_state::do_mouse) m_nimbus_mouse.m_reg0a4 |= ( myb & 0x01) << 0; // YB } - // Update current mouse position - m_nimbus_mouse.m_mouse_x = mouse_x; - m_nimbus_mouse.m_mouse_y = mouse_y; - // and interrupt state m_nimbus_mouse.m_intstate_x=intstate_x; m_nimbus_mouse.m_intstate_y=intstate_y; } +void rmnimbus_state::do_mouse_hle(int8_t xdiff, int8_t ydiff) +{ + if (MOUSE_INT_ENABLED(this)) + { + // bypass bios ISR and update mouse cursor position locations directly + address_space &space = m_maincpu->space(AS_PROGRAM); + + if (xdiff) + { + uint16_t x = space.read_word_unaligned(m_nimbus_mouse.xpos_loc); + if ((xdiff < 0) && (x != space.read_word_unaligned(m_nimbus_mouse.xmax_loc))) + { + x++; + } + else if (x != space.read_word_unaligned(m_nimbus_mouse.xmin_loc)) + { + x--; + } + space.write_word_unaligned(m_nimbus_mouse.xpos_loc, x); + } + + if (ydiff) + { + uint16_t y = space.read_word_unaligned(m_nimbus_mouse.ypos_loc); + if ((ydiff < 0) && (y != space.read_word_unaligned(m_nimbus_mouse.ymin_loc))) + { + y--; + } + else if (y != space.read_word_unaligned(m_nimbus_mouse.ymax_loc)) + { + y++; + } + space.write_word_unaligned(m_nimbus_mouse.ypos_loc, y); + } + } + else + { + // store status to support polling operation of mouse + // (not tested as no software seems to use this method!) + if (xdiff || ydiff) + { + m_nimbus_mouse.m_reg0a4 = 0; + } + if (xdiff < 0) + { + m_nimbus_mouse.m_reg0a4 |= CONTROLLER_RIGHT; + } + else if (xdiff > 0) + { + m_nimbus_mouse.m_reg0a4 |= CONTROLLER_LEFT; + } + if (ydiff < 0) + { + m_nimbus_mouse.m_reg0a4 |= CONTROLLER_DOWN; + } + else if (ydiff > 0) + { + m_nimbus_mouse.m_reg0a4 |= CONTROLLER_UP; + } + + } +} + void rmnimbus_state::mouse_js_reset() { + constexpr uint16_t bios_addresses[] = { 0x18cd, 0x196d, 0x196d, 0x1a6d, 0x1a6d, 0x1a77 }; + m_nimbus_mouse.m_mouse_x=128; m_nimbus_mouse.m_mouse_y=128; m_nimbus_mouse.m_mouse_pcx=0; @@ -1068,6 +1145,15 @@ void rmnimbus_state::mouse_js_reset() m_nimbus_mouse.m_intstate_y=0; m_nimbus_mouse.m_reg0a4=0xC0; + // calculate addresses for mouse related variable used by the bios mouse ISR + auto bios_base = bios_addresses[system_bios() - 1]; + m_nimbus_mouse.xpos_loc = bios_base + 8; + m_nimbus_mouse.ypos_loc = bios_base + 10; + m_nimbus_mouse.xmin_loc = bios_base; + m_nimbus_mouse.ymin_loc = bios_base + 4; + m_nimbus_mouse.xmax_loc = bios_base + 2; + m_nimbus_mouse.ymax_loc = bios_base + 6; + // Setup timer to poll the mouse m_nimbus_mouse.m_mouse_timer->adjust(attotime::zero, 0, attotime::from_hz(MOUSE_POLL_FREQUENCY)); @@ -1078,8 +1164,9 @@ uint8_t rmnimbus_state::nimbus_joystick_r() { /* Only the joystick drection data is read from this port (which corresponds to the the low nibble of the selected joystick port). - The joystick buttons are read from the mouse data port instead. */ - uint8_t result = m_io_joysticks[m_selected_js_idx]->read() & 0x0f; + The joystick buttons are read from the mouse data port instead. + Unused bits are set to 1. */ + uint8_t result = m_io_joysticks[m_selected_js_idx]->read() | 0xf0; if (result & CONTROLLER_RIGHT) { -- cgit v1.2.3