mirror of
https://github.com/holub/mame
synced 2025-06-29 23:48:56 +03:00
rm/rmnimbus.cpp: Allow choice of HLE mouse processing (#11890)
This commit is contained in:
parent
9bbc99137f
commit
62419d27b5
@ -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
|
||||
|
@ -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<wd2793_device> m_fdc;
|
||||
required_device<z80sio_device> m_z80sio;
|
||||
required_device<screen_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
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user