abc1600: Implement Luxor R8 mouse. [Curt Coder]

This commit is contained in:
Curt Coder 2023-03-07 12:28:40 +02:00
parent 3fe6977878
commit 3b8c1569cf
5 changed files with 250 additions and 35 deletions

View File

@ -4141,6 +4141,8 @@ if (BUSES["ABCKB"]~=null) then
MAME_DIR .. "src/devices/bus/abckb/abc99.h",
MAME_DIR .. "src/devices/bus/abckb/abc800kb.cpp",
MAME_DIR .. "src/devices/bus/abckb/abc800kb.h",
MAME_DIR .. "src/devices/bus/abckb/r8.cpp",
MAME_DIR .. "src/devices/bus/abckb/r8.h",
}
end

View File

@ -2,7 +2,7 @@
// copyright-holders:Curt Coder
/**********************************************************************
Luxor ABC-99 keyboard and mouse emulation
Luxor ABC-99 keyboard emulation
*********************************************************************/
@ -45,7 +45,6 @@ Notes:
- watchdog
- language DIP
- mouse
*/
@ -162,7 +161,7 @@ void abc99_device::device_add_mconfig(machine_config &config)
m_maincpu->set_addrmap(AS_IO, &abc99_device::abc99_z2_io);
m_maincpu->p1_out_cb().set(FUNC(abc99_device::z2_p1_w));
m_maincpu->p2_in_cb().set(FUNC(abc99_device::z2_p2_r));
m_maincpu->t0_in_cb().set(FUNC(abc99_device::z2_t0_r));
m_maincpu->t0_in_cb().set_constant(0); // mouse connected
m_maincpu->t1_in_cb().set(FUNC(abc99_device::z2_t1_r));
// mouse CPU
@ -173,6 +172,9 @@ void abc99_device::device_add_mconfig(machine_config &config)
m_mousecpu->set_t0_clk_cb(I8035_Z2_TAG, FUNC(device_t::set_unscaled_clock_int));
m_mousecpu->t1_in_cb().set(FUNC(abc99_device::z5_t1_r));
// mouse
R8(config, m_mouse, 0);
// sound hardware
SPEAKER(config, "mono").front_center();
SPEAKER_SOUND(config, m_speaker, 0).add_route(ALL_OUTPUTS, "mono", 0.25);
@ -417,17 +419,6 @@ INPUT_PORTS_START( abc99 )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
PORT_START("MOUSEB")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Left Mouse Button") PORT_CODE(MOUSECODE_BUTTON1)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Middle Mouse Button") PORT_CODE(MOUSECODE_BUTTON3)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Right Mouse Button") PORT_CODE(MOUSECODE_BUTTON2)
PORT_START("MOUSEX")
PORT_BIT( 0xff, 0x00, IPT_MOUSE_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_PLAYER(1)
PORT_START("MOUSEY")
PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_PLAYER(1)
PORT_START("J4")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Keyboard Reset") PORT_CHANGED_MEMBER(DEVICE_SELF, abc99_device, keyboard_reset, 0)
INPUT_PORTS_END
@ -466,16 +457,6 @@ TIMER_CALLBACK_MEMBER(abc99_device::serial_clock)
}
//-------------------------------------------------
// scan_mouse -
//-------------------------------------------------
TIMER_CALLBACK_MEMBER(abc99_device::scan_mouse)
{
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
@ -488,13 +469,12 @@ abc99_device::abc99_device(const machine_config &mconfig, const char *tag, devic
device_t(mconfig, ABC99, tag, owner, clock),
abc_keyboard_interface(mconfig, *this),
m_serial_timer(nullptr),
m_mouse_timer(nullptr),
m_maincpu(*this, I8035_Z2_TAG),
m_mousecpu(*this, I8035_Z5_TAG),
m_speaker(*this, "speaker"),
m_mouse(*this, R8_TAG),
m_z14(*this, "Z14"),
m_cursor(*this, "CURSOR"),
m_mouseb(*this, "MOUSEB"),
m_leds(*this, "led%u", 0U),
m_si(1),
m_si_en(1),
@ -520,8 +500,6 @@ void abc99_device::device_start()
m_serial_timer = timer_alloc(FUNC(abc99_device::serial_clock), this);
m_serial_timer->adjust(MCS48_ALE_CLOCK(XTAL(6'000'000)/3), 0, MCS48_ALE_CLOCK(XTAL(6'000'000)/3));
m_mouse_timer = timer_alloc(FUNC(abc99_device::scan_mouse), this);
// state saving
save_item(NAME(m_si));
save_item(NAME(m_si_en));
@ -675,8 +653,8 @@ uint8_t abc99_device::z5_p1_r()
uint8_t data = 0;
// mouse buttons
data |= (m_mouseb->read() & 0x07) << 4;
// mouse
data |= m_mouse->read() & 0x7f;
// serial input
data |= m_si << 7;

View File

@ -2,7 +2,7 @@
// copyright-holders:Curt Coder
/**********************************************************************
Luxor ABC-99 keyboard and mouse emulation
Luxor ABC-99 keyboard emulation
*********************************************************************/
@ -13,6 +13,7 @@
#include "abckb.h"
#include "bus/abckb/r8.h"
#include "cpu/mcs48/mcs48.h"
#include "sound/spkrdev.h"
@ -67,11 +68,9 @@ private:
void serial_input();
TIMER_CALLBACK_MEMBER(serial_clock);
TIMER_CALLBACK_MEMBER(scan_mouse);
void z2_p1_w(uint8_t data);
uint8_t z2_p2_r();
DECLARE_READ_LINE_MEMBER( z2_t0_r ) { return 1; /* 0=mouse connected, 1=no mouse */ }
DECLARE_READ_LINE_MEMBER( z2_t1_r ) { return m_t1_z2; }
void z2_led_w(uint8_t data);
@ -84,14 +83,13 @@ private:
void abc99_z5_mem(address_map &map);
emu_timer *m_serial_timer;
emu_timer *m_mouse_timer;
required_device<i8035_device> m_maincpu;
required_device<i8035_device> m_mousecpu;
required_device<speaker_sound_device> m_speaker;
required_device<r8_device> m_mouse;
required_ioport m_z14;
required_ioport m_cursor;
required_ioport m_mouseb;
output_finder<11> m_leds;
int m_si;

View File

@ -0,0 +1,160 @@
// copyright-holders:Curt Coder
/**********************************************************************
Luxor R8 mouse emulation
*********************************************************************/
#include "emu.h"
#include "r8.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(R8, r8_device, "r8", "Luxor R8")
//-------------------------------------------------
// INPUT_PORTS( r8 )
//-------------------------------------------------
INPUT_PORTS_START( r8 )
PORT_START("MOUSEB")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Left Mouse Button") PORT_CODE(MOUSECODE_BUTTON1)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Middle Mouse Button") PORT_CODE(MOUSECODE_BUTTON3)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Right Mouse Button") PORT_CODE(MOUSECODE_BUTTON2)
PORT_START("MOUSEX")
PORT_BIT( 0xfff, 0x000, IPT_MOUSE_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(0)
PORT_START("MOUSEY")
PORT_BIT( 0xfff, 0x000, IPT_MOUSE_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(0)
INPUT_PORTS_END
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
ioport_constructor r8_device::device_input_ports() const
{
return INPUT_PORTS_NAME( r8 );
}
//-------------------------------------------------
// scan_mouse -
//-------------------------------------------------
TIMER_CALLBACK_MEMBER(r8_device::scan_mouse)
{
switch(m_mouse.phase)
{
case 0:
m_mouse.xa = m_mouse.x > m_mouse.prev_x ? CLEAR_LINE : ASSERT_LINE;
m_mouse.xb = m_mouse.x < m_mouse.prev_x ? CLEAR_LINE : ASSERT_LINE;
m_mouse.ya = m_mouse.y > m_mouse.prev_y ? CLEAR_LINE : ASSERT_LINE;
m_mouse.yb = m_mouse.y < m_mouse.prev_y ? CLEAR_LINE : ASSERT_LINE;
break;
case 1:
m_mouse.xa = m_mouse.xb = m_mouse.x != m_mouse.prev_x ? CLEAR_LINE : ASSERT_LINE;
m_mouse.ya = m_mouse.yb = m_mouse.y != m_mouse.prev_y ? CLEAR_LINE : ASSERT_LINE;
break;
case 2:
m_mouse.xa = m_mouse.x < m_mouse.prev_x ? CLEAR_LINE : ASSERT_LINE;
m_mouse.xb = m_mouse.x > m_mouse.prev_x ? CLEAR_LINE : ASSERT_LINE;
m_mouse.ya = m_mouse.y < m_mouse.prev_y ? CLEAR_LINE : ASSERT_LINE;
m_mouse.yb = m_mouse.y > m_mouse.prev_y ? CLEAR_LINE : ASSERT_LINE;
break;
case 3:
m_mouse.xa = m_mouse.xb = ASSERT_LINE;
m_mouse.ya = m_mouse.yb = ASSERT_LINE;
m_mouse.prev_x = m_mouse.x;
m_mouse.prev_y = m_mouse.y;
m_mouse.x = m_mouse_x->read();
m_mouse.y = m_mouse_y->read();
break;
}
m_mouse.phase = (m_mouse.phase + 1) & 3;
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// r8_device - constructor
//-------------------------------------------------
r8_device::r8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, R8, tag, owner, clock),
m_mouse_timer(nullptr),
m_mouse_b(*this, "MOUSEB"),
m_mouse_x(*this, "MOUSEX"),
m_mouse_y(*this, "MOUSEY")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void r8_device::device_start()
{
// allocate timers
m_mouse_timer = timer_alloc(FUNC(r8_device::scan_mouse), this);
m_mouse_timer->adjust(attotime::from_hz(1000), 0, attotime::from_hz(1000));
// state saving
save_item(NAME(m_mouse.phase));
save_item(NAME(m_mouse.x));
save_item(NAME(m_mouse.y));
save_item(NAME(m_mouse.prev_x));
save_item(NAME(m_mouse.prev_y));
save_item(NAME(m_mouse.xa));
save_item(NAME(m_mouse.xb));
save_item(NAME(m_mouse.ya));
save_item(NAME(m_mouse.yb));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void r8_device::device_reset()
{
m_mouse.phase = 0;
m_mouse.xa = m_mouse.xb = ASSERT_LINE;
m_mouse.ya = m_mouse.yb = ASSERT_LINE;
m_mouse.x = m_mouse.y = 0;
m_mouse.prev_x = m_mouse.prev_y = 0;
}
//-------------------------------------------------
// read -
//-------------------------------------------------
u8 r8_device::read()
{
u8 data = 0;
// mouse movement
data |= m_mouse.xa;
data |= m_mouse.xb << 1;
data |= m_mouse.ya << 2;
data |= m_mouse.yb << 3;
// mouse buttons
data |= (m_mouse_b->read() & 0x07) << 4;
return data;
}

View File

@ -0,0 +1,77 @@
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************
Luxor R8 mouse emulation
*********************************************************************/
#ifndef MAME_BUS_ABCKB_R8_H
#define MAME_BUS_ABCKB_R8_H
#pragma once
#include "emu.h"
//**************************************************************************
// MACROS / CONSTANTS
//**************************************************************************
#define R8_TAG "r8"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> r8_device
class r8_device : public device_t
{
public:
// construction/destruction
r8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
u8 read();
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
private:
TIMER_CALLBACK_MEMBER(scan_mouse);
emu_timer *m_mouse_timer;
required_ioport m_mouse_b;
required_ioport m_mouse_x;
required_ioport m_mouse_y;
struct
{
int phase;
int x;
int y;
int prev_x;
int prev_y;
int xa;
int xb;
int ya;
int yb;
} m_mouse;
};
// device type definition
DECLARE_DEVICE_TYPE(R8, r8_device)
#endif // MAME_BUS_ABCKB_R8_H