mirror of
https://github.com/holub/mame
synced 2025-07-05 18:08:04 +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 )
|
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_START(JOYSTICK0_TAG)
|
||||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY
|
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
|
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_fdc(*this, FDC_TAG),
|
||||||
m_z80sio(*this, Z80SIO_TAG),
|
m_z80sio(*this, Z80SIO_TAG),
|
||||||
m_screen(*this, "screen"),
|
m_screen(*this, "screen"),
|
||||||
|
m_io_config(*this, "config"),
|
||||||
m_io_joysticks(*this, JOYSTICK_TAG_BASE "%u", 0),
|
m_io_joysticks(*this, JOYSTICK_TAG_BASE "%u", 0),
|
||||||
m_io_mouse_button(*this, MOUSE_BUTTON_TAG),
|
m_io_mouse_button(*this, MOUSE_BUTTON_TAG),
|
||||||
m_io_mousex(*this, MOUSEX_TAG),
|
m_io_mousex(*this, MOUSEX_TAG),
|
||||||
@ -104,6 +105,7 @@ private:
|
|||||||
required_device<wd2793_device> m_fdc;
|
required_device<wd2793_device> m_fdc;
|
||||||
required_device<z80sio_device> m_z80sio;
|
required_device<z80sio_device> m_z80sio;
|
||||||
required_device<screen_device> m_screen;
|
required_device<screen_device> m_screen;
|
||||||
|
required_ioport m_io_config;
|
||||||
required_ioport_array<2> m_io_joysticks;
|
required_ioport_array<2> m_io_joysticks;
|
||||||
required_ioport m_io_mouse_button;
|
required_ioport m_io_mouse_button;
|
||||||
required_ioport m_io_mousex;
|
required_ioport m_io_mousex;
|
||||||
@ -227,6 +229,13 @@ private:
|
|||||||
/* Mouse */
|
/* Mouse */
|
||||||
struct
|
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_x = 0;
|
||||||
uint8_t m_mouse_y = 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);
|
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);
|
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
|
#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 xdiff; // Difference from previous X and Y
|
||||||
int8_t ydiff;
|
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_x; // Used to calculate if we should trigger interrupt
|
||||||
uint8_t intstate_y;
|
uint8_t intstate_y;
|
||||||
int xint; // X and Y interrupts to trigger
|
int xint; // X and Y interrupts to trigger
|
||||||
@ -990,13 +1013,6 @@ TIMER_CALLBACK_MEMBER(rmnimbus_state::do_mouse)
|
|||||||
uint8_t mya;
|
uint8_t mya;
|
||||||
uint8_t myb;
|
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.
|
// convert movement into emulated movement of quadrature encoder in mouse.
|
||||||
if (xdiff < 0)
|
if (xdiff < 0)
|
||||||
m_nimbus_mouse.m_mouse_pcx++;
|
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
|
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
|
// and interrupt state
|
||||||
m_nimbus_mouse.m_intstate_x=intstate_x;
|
m_nimbus_mouse.m_intstate_x=intstate_x;
|
||||||
m_nimbus_mouse.m_intstate_y=intstate_y;
|
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()
|
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_x=128;
|
||||||
m_nimbus_mouse.m_mouse_y=128;
|
m_nimbus_mouse.m_mouse_y=128;
|
||||||
m_nimbus_mouse.m_mouse_pcx=0;
|
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_intstate_y=0;
|
||||||
m_nimbus_mouse.m_reg0a4=0xC0;
|
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
|
// Setup timer to poll the mouse
|
||||||
m_nimbus_mouse.m_mouse_timer->adjust(attotime::zero, 0, attotime::from_hz(MOUSE_POLL_FREQUENCY));
|
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
|
/* Only the joystick drection data is read from this port
|
||||||
(which corresponds to the the low nibble of the selected joystick port).
|
(which corresponds to the the low nibble of the selected joystick port).
|
||||||
The joystick buttons are read from the mouse data port instead. */
|
The joystick buttons are read from the mouse data port instead.
|
||||||
uint8_t result = m_io_joysticks[m_selected_js_idx]->read() & 0x0f;
|
Unused bits are set to 1. */
|
||||||
|
uint8_t result = m_io_joysticks[m_selected_js_idx]->read() | 0xf0;
|
||||||
|
|
||||||
if (result & CONTROLLER_RIGHT)
|
if (result & CONTROLLER_RIGHT)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user