mirror of
https://github.com/holub/mame
synced 2025-04-26 02:07:14 +03:00
ec1841: mouse emulation (Logitech bus mouse protocol) (#3623)
* ec1841: mouse emulation (Logitech bus mouse protocol) * follow-up to PR#3623
This commit is contained in:
parent
0aa81fc184
commit
02197ab4ca
@ -744,6 +744,18 @@ if (MACHINES["BANKDEV"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/busmouse.h,MACHINES["BUSMOUSE"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (MACHINES["BUSMOUSE"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/busmouse.cpp",
|
||||
MAME_DIR .. "src/devices/machine/busmouse.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/cdp1852.h,MACHINES["CDP1852"] = true
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "fdc.h"
|
||||
#include "machine/busmouse.h"
|
||||
#include "machine/pc_fdc.h"
|
||||
#include "imagedev/flopdrv.h"
|
||||
#include "formats/pc_dsk.h"
|
||||
@ -139,8 +140,37 @@ MACHINE_CONFIG_START(isa8_fdc_superio_device::device_add_mconfig)
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:1", pc_hd_floppies, "35hd", isa8_fdc_device::floppy_formats)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
isa8_ec1841_0003_device::isa8_ec1841_0003_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: isa8_fdc_device(mconfig, ISA8_EC1841_0003, tag, owner, clock)
|
||||
, m_bus_mouse(*this, "bus_mouse")
|
||||
{
|
||||
}
|
||||
|
||||
void isa8_ec1841_0003_device::device_start()
|
||||
{
|
||||
isa8_fdc_device::device_start();
|
||||
m_isa->install_device(0x023c, 0x023f, *m_bus_mouse, &bus_mouse_device::map);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( isa8_ec1841_0003_device::aux_irq_w )
|
||||
{
|
||||
m_isa->irq4_w(state ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
MACHINE_CONFIG_START( isa8_ec1841_0003_device::device_add_mconfig )
|
||||
MCFG_PC_FDC_XT_ADD("fdc")
|
||||
MCFG_PC_FDC_INTRQ_CALLBACK(WRITELINE(*this, isa8_fdc_device, irq_w))
|
||||
MCFG_PC_FDC_DRQ_CALLBACK(WRITELINE(*this, isa8_fdc_device, drq_w))
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:0", pc_dd_floppies, "525dd", isa8_fdc_device::floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:1", pc_dd_floppies, "525dd", isa8_fdc_device::floppy_formats)
|
||||
|
||||
MCFG_DEVICE_ADD("bus_mouse", BUS_MOUSE, 0)
|
||||
MCFG_BUS_MOUSE_EXTINT_CALLBACK(WRITELINE(*this, isa8_ec1841_0003_device, aux_irq_w))
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
DEFINE_DEVICE_TYPE(ISA8_FDC_XT, isa8_fdc_xt_device, "isa8_fdc_xt", "ISA 8bits XT FDC hookup")
|
||||
DEFINE_DEVICE_TYPE(ISA8_FDC_AT, isa8_fdc_at_device, "isa8_fdc_at", "ISA 8bits AT FDC hookup")
|
||||
DEFINE_DEVICE_TYPE(ISA8_FDC_SMC, isa8_fdc_smc_device, "isa8_fdc_smc", "ISA 8bits SMC FDC hookup")
|
||||
DEFINE_DEVICE_TYPE(ISA8_FDC_PS2, isa8_fdc_ps2_device, "isa8_fdc_ps2", "ISA 8bits PS/2 FDC hookup")
|
||||
DEFINE_DEVICE_TYPE(ISA8_FDC_SUPERIO, isa8_fdc_superio_device, "isa8_fdc_superio", "ISA 8bits SUPERIO FDC hookup")
|
||||
DEFINE_DEVICE_TYPE(ISA8_EC1841_0003, isa8_ec1841_0003_device, "isa8_ec1841_0003", "ISA 8bits EC1841.0003 FDC hookup")
|
||||
|
@ -11,6 +11,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "isa.h"
|
||||
#include "machine/busmouse.h"
|
||||
#include "machine/upd765.h"
|
||||
|
||||
//**************************************************************************
|
||||
@ -83,11 +84,25 @@ protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
};
|
||||
|
||||
class isa8_ec1841_0003_device : public isa8_fdc_device {
|
||||
public:
|
||||
isa8_ec1841_0003_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( aux_irq_w );
|
||||
|
||||
required_device<bus_mouse_device> m_bus_mouse;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(ISA8_FDC_XT, isa8_fdc_xt_device)
|
||||
DECLARE_DEVICE_TYPE(ISA8_FDC_AT, isa8_fdc_at_device)
|
||||
DECLARE_DEVICE_TYPE(ISA8_FDC_SMC, isa8_fdc_smc_device)
|
||||
DECLARE_DEVICE_TYPE(ISA8_FDC_PS2, isa8_fdc_ps2_device)
|
||||
DECLARE_DEVICE_TYPE(ISA8_FDC_SUPERIO, isa8_fdc_superio_device)
|
||||
DECLARE_DEVICE_TYPE(ISA8_EC1841_0003, isa8_ec1841_0003_device)
|
||||
|
||||
#endif // MAME_BUS_ISA_FDC_H
|
||||
|
@ -64,17 +64,17 @@ void mc1502_isa8_cards(device_slot_interface &device)
|
||||
void ec184x_isa8_cards(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("ec1840.0002", ISA8_EC1840_0002); // MDA with downloadable font
|
||||
device.option_add("ec1840.0003", ISA8_FDC_XT);
|
||||
device.option_add("ec1841.0002", ISA8_EC1841_0002); // CGA with downloadable font
|
||||
device.option_add("ec1841.0003", ISA8_FDC_XT);
|
||||
/*
|
||||
device.option_add("ec1841.0010", ISA8_EC1841_0010); // 8089-based HDC
|
||||
device.option_add("ec1841.0003", ISA8_EC1841_0003); // FDC + mouse port
|
||||
device.option_add("ec1841.0004", ISA8_LPT);
|
||||
/*
|
||||
device.option_add("ec1841.0004", ISA8_EC1841_0004); // BSC-like serial ports + parallel port
|
||||
device.option_add("ec1841.0010", ISA8_EC1841_0010); // 8089-based HDC
|
||||
*/
|
||||
device.option_add("mda", ISA8_MDA);
|
||||
device.option_add("hdc", ISA8_HDC_EC1841);
|
||||
device.option_add("pccom", ISA8_COM);
|
||||
device.option_add("pclpt", ISA8_LPT);
|
||||
device.option_add("xtide", ISA8_XTIDE);
|
||||
}
|
||||
|
||||
|
221
src/devices/machine/busmouse.cpp
Normal file
221
src/devices/machine/busmouse.cpp
Normal file
@ -0,0 +1,221 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/**********************************************************************
|
||||
|
||||
Logitech bus mouse interface emulation
|
||||
|
||||
References:
|
||||
- ec1841 technical manual
|
||||
- https://github.com/OBattler/86Box/blob/master/src/mouse_bus.c
|
||||
- https://communities.intel.com/docs/DOC-22714
|
||||
- http://toastytech.com/guis/msmouse.html
|
||||
|
||||
To do:
|
||||
- selectable IRQ level
|
||||
- Microsoft protocol
|
||||
- ec1841.0003 clone: diag mode
|
||||
- ec1841.0003 clone: fix detection by m86v32 driver
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "busmouse.h"
|
||||
|
||||
#include "machine/i8255.h"
|
||||
|
||||
|
||||
#define LOG_GENERAL (1U << 0)
|
||||
|
||||
//#define VERBOSE (LOG_GENERAL)
|
||||
//#define LOG_OUTPUT_FUNC printf
|
||||
#include "logmacro.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(BUS_MOUSE, bus_mouse_device, "bus_mouse", "Bus Mouse Interface")
|
||||
|
||||
void bus_mouse_device::map(address_map &map)
|
||||
{
|
||||
map(0x0, 0x3).rw("ppi", FUNC(i8255_device::read), FUNC(i8255_device::write));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// INPUT_CHANGED_MEMBER( mouse_x_changed )
|
||||
//-------------------------------------------------
|
||||
|
||||
INPUT_CHANGED_MEMBER(bus_mouse_device::mouse_x_changed)
|
||||
{
|
||||
m_x += newval - oldval;
|
||||
LOG("m_x_c: irqdis %d; %d = %d - %d\n", irq_disabled, m_x, newval, oldval);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// INPUT_CHANGED_MEMBER( mouse_y_changed )
|
||||
//-------------------------------------------------
|
||||
|
||||
INPUT_CHANGED_MEMBER(bus_mouse_device::mouse_y_changed)
|
||||
{
|
||||
m_y += newval - oldval;
|
||||
LOG("m_y_c: irqdis %d; %d = %d - %d\n", irq_disabled, m_y, newval, oldval);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// INPUT_PORTS( bus_mouse )
|
||||
//-------------------------------------------------
|
||||
|
||||
INPUT_PORTS_START( bus_mouse )
|
||||
PORT_START("mouse_x")
|
||||
PORT_BIT( 0xff, 0x00, IPT_MOUSE_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_CHANGED_MEMBER(DEVICE_SELF, bus_mouse_device, mouse_x_changed, 0)
|
||||
|
||||
PORT_START("mouse_y")
|
||||
PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_CHANGED_MEMBER(DEVICE_SELF, bus_mouse_device, mouse_y_changed, 0)
|
||||
|
||||
PORT_START("mouse_buttons")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Left Mouse Button") PORT_CODE(MOUSECODE_BUTTON1)
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Right Mouse Button") PORT_CODE(MOUSECODE_BUTTON3)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Middle Mouse Button") PORT_CODE(MOUSECODE_BUTTON2)
|
||||
PORT_BIT( 0x1f, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
|
||||
PORT_START("irq_rate")
|
||||
PORT_DIPNAME(0x0f, 0x02, "IRQ rate")
|
||||
PORT_DIPSETTING(0x01, "15 hz")
|
||||
PORT_DIPSETTING(0x02, "30 hz")
|
||||
PORT_DIPSETTING(0x04, "60 hz")
|
||||
PORT_DIPSETTING(0x08, "120 hz")
|
||||
|
||||
PORT_START("irq_line")
|
||||
PORT_DIPNAME(0x0f, 0x02, "IRQ line")
|
||||
PORT_DIPSETTING(0x02, "IRQ4")
|
||||
#if 0
|
||||
PORT_DIPSETTING(0x08, "IRQ2")
|
||||
PORT_DIPSETTING(0x04, "IRQ3")
|
||||
PORT_DIPSETTING(0x01, "IRQ5")
|
||||
#endif
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// input_ports - device-specific input ports
|
||||
//-------------------------------------------------
|
||||
|
||||
ioport_constructor bus_mouse_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(bus_mouse);
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// bus_mouse_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
bus_mouse_device::bus_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, BUS_MOUSE, tag, owner, clock)
|
||||
, m_write_extint(*this)
|
||||
, m_buttons(*this, "mouse_buttons")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MACHINE_CONFIG_START(bus_mouse_device::device_add_mconfig)
|
||||
MCFG_DEVICE_ADD("ppi", I8255, 0)
|
||||
MCFG_I8255_IN_PORTA_CB(READ8(*this, bus_mouse_device, ppi_a_r))
|
||||
MCFG_I8255_OUT_PORTC_CB(WRITE8(*this, bus_mouse_device, ppi_c_w))
|
||||
MCFG_I8255_IN_PORTC_CB(READ8(*this, bus_mouse_device, ppi_c_r))
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void bus_mouse_device::device_start()
|
||||
{
|
||||
// resolve callbacks
|
||||
m_write_extint.resolve_safe();
|
||||
|
||||
m_irq_timer = timer_alloc(0);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void bus_mouse_device::device_reset()
|
||||
{
|
||||
int hz = 2 * 15 * ioport("irq_rate")->read();
|
||||
|
||||
m_irq_timer->adjust(attotime::from_hz(hz), 0, attotime::from_hz(hz));
|
||||
|
||||
irq = 0;
|
||||
irq_disabled = 1;
|
||||
irq_line = ioport("irq_line")->read();
|
||||
|
||||
LOG("irq rate: %d Hz\n", hz);
|
||||
}
|
||||
|
||||
void bus_mouse_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
irq = !irq;
|
||||
|
||||
if (!irq_disabled && irq)
|
||||
{
|
||||
m_write_extint(irq);
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(bus_mouse_device::ppi_a_r)
|
||||
{
|
||||
return m_pa;
|
||||
}
|
||||
|
||||
READ8_MEMBER(bus_mouse_device::ppi_c_r)
|
||||
{
|
||||
return irq ? irq_line : 0;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(bus_mouse_device::ppi_c_w)
|
||||
{
|
||||
irq_disabled = BIT(data, 4);
|
||||
|
||||
switch (data & 0xe0)
|
||||
{
|
||||
case 0:
|
||||
m_write_extint(CLEAR_LINE);
|
||||
m_pa = 0;
|
||||
break;
|
||||
|
||||
case 0x80: // LSB X
|
||||
m_pa = m_x & 0xf;
|
||||
break;
|
||||
|
||||
case 0xa0: // MSB X
|
||||
m_pa = (m_x >> 4) & 0xf;
|
||||
if (m_x < 0) m_pa |= 8;
|
||||
m_pa |= m_buttons->read() & 0xe0;
|
||||
m_x = 0;
|
||||
break;
|
||||
|
||||
case 0xc0: // LSB Y
|
||||
m_pa = m_y & 0xf;
|
||||
break;
|
||||
|
||||
case 0xe0: // MSB Y
|
||||
m_pa = (m_y >> 4) & 0xf;
|
||||
if (m_y < 0) m_pa |= 8;
|
||||
m_pa |= m_buttons->read() & 0xe0;
|
||||
m_y = 0;
|
||||
break;
|
||||
}
|
||||
LOG("c_w: data %02x m_pa %02x\n", data, m_pa);
|
||||
}
|
74
src/devices/machine/busmouse.h
Normal file
74
src/devices/machine/busmouse.h
Normal file
@ -0,0 +1,74 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/**********************************************************************
|
||||
|
||||
Logitech bus mouse interface emulation
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_BUSMOUSE_H
|
||||
#define MAME_MACHINE_BUSMOUSE_H
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_BUS_MOUSE_EXTINT_CALLBACK(_write) \
|
||||
devcb = &bus_mouse_device::set_extint_wr_callback(*device, DEVCB_##_write);
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> bus_mouse_device
|
||||
|
||||
class bus_mouse_device : public device_t
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
bus_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
template <class Object> static devcb_base &set_extint_wr_callback(device_t &device, Object &&cb) { return downcast<bus_mouse_device &>(device).m_write_extint.set_callback(std::forward<Object>(cb)); }
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(mouse_x_changed);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(mouse_y_changed);
|
||||
|
||||
void map(address_map &map);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
|
||||
// optional information overrides
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
|
||||
DECLARE_READ8_MEMBER(ppi_a_r);
|
||||
DECLARE_READ8_MEMBER(ppi_c_r);
|
||||
DECLARE_WRITE8_MEMBER(ppi_c_w);
|
||||
|
||||
private:
|
||||
emu_timer *m_irq_timer;
|
||||
bool irq, irq_disabled;
|
||||
int irq_line;
|
||||
|
||||
devcb_write_line m_write_extint;
|
||||
|
||||
required_ioport m_buttons;
|
||||
|
||||
uint8_t m_pa;
|
||||
int8_t m_x, m_y;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(BUS_MOUSE, bus_mouse_device)
|
||||
|
||||
|
||||
#endif // MAME_MACHINE_BUSMOUSE_H
|
@ -233,7 +233,7 @@ MACHINE_CONFIG_START(ec184x_state::ec1840)
|
||||
|
||||
// FIXME: determine ISA bus clock
|
||||
MCFG_DEVICE_ADD("isa1", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, "ec1840.0002", false)
|
||||
MCFG_DEVICE_ADD("isa2", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, "ec1841.0003", false) // actually ec1840.0003 -- w/o mouse port
|
||||
MCFG_DEVICE_ADD("isa2", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, "ec1840.0003", false)
|
||||
MCFG_DEVICE_ADD("isa3", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, nullptr, false)
|
||||
MCFG_DEVICE_ADD("isa4", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, nullptr, false)
|
||||
MCFG_DEVICE_ADD("isa5", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, nullptr, false)
|
||||
@ -259,9 +259,9 @@ MACHINE_CONFIG_START(ec184x_state::ec1841)
|
||||
|
||||
// FIXME: determine ISA bus clock
|
||||
MCFG_DEVICE_ADD("isa1", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, "ec1841.0002", false) // cga
|
||||
MCFG_DEVICE_ADD("isa2", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, "ec1841.0003", false) // fdc + mouse port
|
||||
MCFG_DEVICE_ADD("isa3", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, "hdc", false)
|
||||
MCFG_DEVICE_ADD("isa4", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, nullptr, false)
|
||||
MCFG_DEVICE_ADD("isa2", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, "ec1841.0003", false) // fdc (IRQ6) + mouse port (IRQ2..5)
|
||||
MCFG_DEVICE_ADD("isa3", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, "ec1841.0004", false) // lpt (IRQ7||5) [+ serial (IRQx)]
|
||||
MCFG_DEVICE_ADD("isa4", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, "hdc", false)
|
||||
MCFG_DEVICE_ADD("isa5", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, nullptr, false)
|
||||
MCFG_DEVICE_ADD("isa6", ISA8_SLOT, 0, "mb:isa", ec184x_isa8_cards, nullptr, false)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user