mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
news_r3k: mouse support (nw)
This commit is contained in:
parent
6ae7508bc3
commit
05c4877337
@ -8,7 +8,6 @@
|
||||
*
|
||||
* TODO
|
||||
* - sound
|
||||
* - mouse
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
@ -61,7 +60,7 @@ public:
|
||||
, m_net(*this, "net")
|
||||
, m_fdc(*this, "fdc")
|
||||
, m_lcd(*this, "lcd")
|
||||
, m_kbd(*this, "kbd")
|
||||
, m_hid(*this, "hid")
|
||||
, m_scsi(*this, "scsi:7:cxd1185")
|
||||
, m_serial(*this, "serial%u", 0U)
|
||||
, m_scsibus(*this, "scsi")
|
||||
@ -119,7 +118,6 @@ protected:
|
||||
u32 bus_error();
|
||||
void itimer_w(u8 data);
|
||||
void itimer(void *ptr, s32 param);
|
||||
void kbd_irq(int state);
|
||||
u8 debug_r() { return m_debug; }
|
||||
void debug_w(u8 data);
|
||||
|
||||
@ -135,7 +133,7 @@ protected:
|
||||
required_device<upd72067_device> m_fdc;
|
||||
|
||||
required_device<screen_device> m_lcd;
|
||||
required_device<news_hle_kbd_device> m_kbd;
|
||||
required_device<news_hid_hle_device> m_hid;
|
||||
required_device<cxd1185_device> m_scsi;
|
||||
|
||||
required_device_array<rs232_port_device, 2> m_serial;
|
||||
@ -150,7 +148,6 @@ protected:
|
||||
|
||||
u16 m_inten;
|
||||
u16 m_intst;
|
||||
u8 m_kbd_status;
|
||||
u8 m_debug;
|
||||
|
||||
static unsigned const NUM_INT = 4;
|
||||
@ -171,8 +168,6 @@ void news_r3k_state::machine_start()
|
||||
|
||||
for (bool &int_state : m_int_state)
|
||||
int_state = false;
|
||||
|
||||
m_kbd_status = 0;
|
||||
}
|
||||
|
||||
void news_r3k_state::machine_reset()
|
||||
@ -207,24 +202,28 @@ void news_r3k_state::cpu_map(address_map &map)
|
||||
// 0x18500000 lcdc?
|
||||
map(0x18600000, 0x186fffff).r(FUNC(news_r3k_state::bus_error)); // ??
|
||||
map(0x18780000, 0x18780003).r(FUNC(news_r3k_state::bus_error)); // nwb-225
|
||||
map(0x18c30000, 0x18c30003).r(FUNC(news_r3k_state::bus_error)); // second lance
|
||||
map(0x18c30000, 0x18c30003).r(FUNC(news_r3k_state::bus_error)); // second lance (ram at 18c20000, id at 18c38000)
|
||||
map(0x18c40000, 0x18c40003).r(FUNC(news_r3k_state::bus_error)); // second scc
|
||||
map(0x18c40004, 0x18c40007).r(FUNC(news_r3k_state::bus_error)); // third scc
|
||||
map(0x18c70000, 0x18c70003).r(FUNC(news_r3k_state::bus_error)); // third lance
|
||||
//map(0x18c40100, 0x18c40118); // scc #1-#4 port/status
|
||||
map(0x18c70000, 0x18c70003).r(FUNC(news_r3k_state::bus_error)); // third lance (ram at 18c60000, id at 18c78000)
|
||||
map(0x18e00000, 0x18e00003).r(FUNC(news_r3k_state::bus_error)); // nwb-252/nwb-253 crt
|
||||
map(0x18ff0000, 0x18ff0003).r(FUNC(news_r3k_state::bus_error)); // nwb-252/nwb-253 ctrl
|
||||
|
||||
map(0x1fc00000, 0x1fc1ffff).rom().region("eprom", 0);
|
||||
//map(0x1fc40004, 0x1fc40004).w().umask32(0xff); ??
|
||||
// 1fc40007 // powreb?
|
||||
map(0x1fc80000, 0x1fc80001).rw(FUNC(news_r3k_state::inten_r), FUNC(news_r3k_state::inten_w));
|
||||
map(0x1fc80002, 0x1fc80003).r(FUNC(news_r3k_state::intst_r));
|
||||
map(0x1fc80004, 0x1fc80005).w(FUNC(news_r3k_state::intclr_w));
|
||||
map(0x1fc80006, 0x1fc80006).w(FUNC(news_r3k_state::itimer_w));
|
||||
map(0x1fcc0003, 0x1fcc0003).rw(FUNC(news_r3k_state::debug_r), FUNC(news_r3k_state::debug_w));
|
||||
|
||||
map(0x1fd00000, 0x1fd00000).r(m_kbd, FUNC(news_hle_kbd_device::data_r));
|
||||
map(0x1fd00001, 0x1fd00001).lr8([this]() { return m_kbd_status; }, "kbd_status_r");
|
||||
map(0x1fd00002, 0x1fd00002).lw8([this](u8 data) { m_kbd->reset(); }, "kbd_reset_w");
|
||||
// 1fcc0000 // cstrobe?
|
||||
// 1fcc0002 // sccstatus0?
|
||||
map(0x1fcc0003, 0x1fcc0003).rw(FUNC(news_r3k_state::debug_r), FUNC(news_r3k_state::debug_w));
|
||||
// 1fcc0007 // sccvect?
|
||||
|
||||
map(0x1fd00000, 0x1fd00007).m(m_hid, FUNC(news_hid_hle_device::map));
|
||||
map(0x1fd40000, 0x1fd40003).noprw().umask32(0xffff); // FIXME: ignore buzzer for now
|
||||
|
||||
map(0x1fe00000, 0x1fe0000f).m(m_dma, FUNC(dmac_0448_device::map));
|
||||
@ -360,16 +359,6 @@ void news_r3k_state::itimer(void *ptr, s32 param)
|
||||
irq_w<TIMER>(ASSERT_LINE);
|
||||
}
|
||||
|
||||
void news_r3k_state::kbd_irq(int state)
|
||||
{
|
||||
if (state)
|
||||
m_kbd_status |= 2;
|
||||
else
|
||||
m_kbd_status &= ~2;
|
||||
|
||||
irq_w<KBD>(state);
|
||||
}
|
||||
|
||||
void news_r3k_state::debug_w(u8 data)
|
||||
{
|
||||
LOG("debug_w 0x%02x (%s)\n", data, machine().describe_context());
|
||||
@ -477,8 +466,9 @@ void news_r3k_state::common(machine_config &config)
|
||||
m_lcd->set_raw(47185920, 1024, 0, 1024, 768, 0, 768);
|
||||
m_lcd->set_screen_update(FUNC(news_r3k_state::screen_update));
|
||||
|
||||
NEWS_HLE_KBD(config, m_kbd);
|
||||
m_kbd->irq_out().set(*this, FUNC(news_r3k_state::kbd_irq));
|
||||
NEWS_HID_HLE(config, m_hid);
|
||||
m_hid->irq_out<news_hid_hle_device::KEYBOARD>().set(FUNC(news_r3k_state::irq_w<KBD>));
|
||||
m_hid->irq_out<news_hid_hle_device::MOUSE>().set(FUNC(news_r3k_state::irq_w<MOUSE>));
|
||||
}
|
||||
|
||||
void news_r3k_state::nws3260(machine_config &config)
|
||||
|
@ -2,11 +2,13 @@
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
/*
|
||||
* Sony NEWS keyboard (high-level emulation).
|
||||
* Sony NEWS keyboard and mouse (high-level emulation).
|
||||
*
|
||||
* Sources:
|
||||
*
|
||||
* https://github.com/NetBSD/src/blob/trunk/sys/dev/news/newskeymap.c
|
||||
* - https://github.com/tmk/tmk_keyboard/tree/master/converter/news_usb
|
||||
* - https://github.com/NetBSD/src/blob/trunk/sys/dev/news/newskeymap.c
|
||||
* - https://github.com/NetBSD/src/blob/trunk/sys/arch/newsmips/dev/ms_hb.c
|
||||
*
|
||||
* TODO:
|
||||
* - other languages (esp. Japanese)
|
||||
@ -22,73 +24,157 @@
|
||||
#define VERBOSE 0
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(NEWS_HLE_KBD, news_hle_kbd_device, "news_kbd_hle", "Sony NEWS Keyboard (HLE)")
|
||||
DEFINE_DEVICE_TYPE(NEWS_HID_HLE, news_hid_hle_device, "news_hid_hle", "Sony NEWS Keyboard and Mouse (HLE)")
|
||||
|
||||
news_hle_kbd_device::news_hle_kbd_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, NEWS_HLE_KBD, tag, owner, clock)
|
||||
news_hid_hle_device::news_hid_hle_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, NEWS_HID_HLE, tag, owner, clock)
|
||||
, device_matrix_keyboard_interface(mconfig, *this, "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7")
|
||||
, m_mouse_x_axis(*this, "mouse_x_axis")
|
||||
, m_mouse_y_axis(*this, "mouse_y_axis")
|
||||
, m_mouse_buttons(*this, "mouse_buttons")
|
||||
, m_irq_out_cb(*this)
|
||||
{
|
||||
}
|
||||
|
||||
void news_hle_kbd_device::device_start()
|
||||
void news_hid_hle_device::map(address_map &map)
|
||||
{
|
||||
m_irq_out_cb.resolve_safe();
|
||||
map(0x0, 0x0).r(FUNC(news_hid_hle_device::data_r<KEYBOARD>));
|
||||
map(0x1, 0x1).r(FUNC(news_hid_hle_device::status_r<KEYBOARD>));
|
||||
map(0x2, 0x2).w(FUNC(news_hid_hle_device::reset_w<KEYBOARD>));
|
||||
map(0x3, 0x3).w(FUNC(news_hid_hle_device::init_w<KEYBOARD>));
|
||||
map(0x4, 0x4).r(FUNC(news_hid_hle_device::data_r<MOUSE>));
|
||||
map(0x5, 0x5).r(FUNC(news_hid_hle_device::status_r<MOUSE>));
|
||||
map(0x6, 0x6).w(FUNC(news_hid_hle_device::reset_w<MOUSE>));
|
||||
map(0x7, 0x7).w(FUNC(news_hid_hle_device::init_w<MOUSE>));
|
||||
}
|
||||
|
||||
void news_hle_kbd_device::device_reset()
|
||||
void news_hid_hle_device::device_start()
|
||||
{
|
||||
m_fifo.clear();
|
||||
out_irq(false);
|
||||
m_irq_out_cb.resolve_all_safe();
|
||||
|
||||
//save_item(NAME(m_fifo));
|
||||
save_item(NAME(m_irq_out_state));
|
||||
|
||||
save_item(NAME(m_mouse_x));
|
||||
save_item(NAME(m_mouse_y));
|
||||
save_item(NAME(m_mouse_b));
|
||||
save_item(NAME(m_mouse_enable));
|
||||
}
|
||||
|
||||
void news_hid_hle_device::device_reset()
|
||||
{
|
||||
m_fifo[KEYBOARD].clear();
|
||||
m_fifo[MOUSE].clear();
|
||||
|
||||
out_irq<KEYBOARD>(false);
|
||||
out_irq<MOUSE>(false);
|
||||
|
||||
m_mouse_enable = false;
|
||||
|
||||
reset_key_state();
|
||||
start_processing(attotime::from_hz(1'200));
|
||||
}
|
||||
|
||||
void news_hle_kbd_device::key_make(u8 row, u8 column)
|
||||
void news_hid_hle_device::key_make(u8 row, u8 column)
|
||||
{
|
||||
LOG("key_make row %d col %d\n", row, column);
|
||||
|
||||
push_key((row << 4) | column);
|
||||
}
|
||||
|
||||
void news_hle_kbd_device::key_break(u8 row, u8 column)
|
||||
void news_hid_hle_device::key_break(u8 row, u8 column)
|
||||
{
|
||||
LOG("key_break row %d col %d\n", row, column);
|
||||
|
||||
push_key(0x80 | (row << 4) | column);
|
||||
}
|
||||
|
||||
void news_hle_kbd_device::push_key(u8 code)
|
||||
void news_hid_hle_device::push_key(u8 code)
|
||||
{
|
||||
m_fifo.enqueue(code);
|
||||
m_fifo[KEYBOARD].enqueue(code);
|
||||
|
||||
out_irq(true);
|
||||
out_irq<KEYBOARD>(true);
|
||||
}
|
||||
|
||||
void news_hle_kbd_device::out_irq(bool state)
|
||||
// HACK: abuse the keyboard row scanner to sample the mouse too
|
||||
void news_hid_hle_device::scan_complete()
|
||||
{
|
||||
if (m_irq_out_state != state)
|
||||
if (!m_mouse_enable)
|
||||
return;
|
||||
|
||||
// read mouse state
|
||||
s16 const x = m_mouse_x_axis->read();
|
||||
s16 const y = m_mouse_y_axis->read();
|
||||
u8 const b = m_mouse_buttons->read();
|
||||
|
||||
// compute delta
|
||||
s8 const dx = x - m_mouse_x;
|
||||
s8 const dy = y - m_mouse_y;
|
||||
u8 const db = b ^ m_mouse_b;
|
||||
|
||||
// report if fifo has room and position or buttons changed
|
||||
if ((m_fifo[MOUSE].queue_length() < 6) && (dx || dy || db))
|
||||
{
|
||||
m_irq_out_state = state;
|
||||
m_irq_out_cb(state);
|
||||
LOG("mouse dx %d dy %d db %d\n", dx, dy, db);
|
||||
|
||||
// compute sign
|
||||
u8 const sx = (dx < 0) ? 0x08 : 0x00;
|
||||
u8 const sy = (dy < 0) ? 0x10 : 0x00;
|
||||
|
||||
// transmit data
|
||||
m_fifo[MOUSE].enqueue(0x80 | sy | sx | b);
|
||||
m_fifo[MOUSE].enqueue(dx & 0x7f);
|
||||
m_fifo[MOUSE].enqueue(dy & 0x7f);
|
||||
|
||||
// update mouse state
|
||||
m_mouse_x = x;
|
||||
m_mouse_y = y;
|
||||
m_mouse_b = b;
|
||||
|
||||
out_irq<MOUSE>(true);
|
||||
}
|
||||
}
|
||||
|
||||
u8 news_hle_kbd_device::data_r()
|
||||
template <news_hid_hle_device::news_hid_device Device> void news_hid_hle_device::out_irq(bool state)
|
||||
{
|
||||
if (m_fifo.empty())
|
||||
if (m_irq_out_state[Device] != state)
|
||||
{
|
||||
m_irq_out_state[Device] = state;
|
||||
m_irq_out_cb[Device](state);
|
||||
}
|
||||
}
|
||||
|
||||
template <news_hid_hle_device::news_hid_device Device> u8 news_hid_hle_device::data_r()
|
||||
{
|
||||
if (m_fifo[Device].empty())
|
||||
return 0;
|
||||
|
||||
u8 const data = m_fifo.dequeue();
|
||||
u8 const data = m_fifo[Device].dequeue();
|
||||
|
||||
if (m_fifo.empty())
|
||||
out_irq(false);
|
||||
if (m_fifo[Device].empty())
|
||||
out_irq<Device>(false);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
INPUT_PORTS_START(news_hle_kbd_device)
|
||||
template <news_hid_hle_device::news_hid_device Device> void news_hid_hle_device::reset_w(u8 data)
|
||||
{
|
||||
LOG("reset_w<%d> 0x%02x\n", Device, data);
|
||||
m_fifo[Device].clear();
|
||||
|
||||
out_irq<Device>(false);
|
||||
}
|
||||
|
||||
template <news_hid_hle_device::news_hid_device Device> void news_hid_hle_device::init_w(u8 data)
|
||||
{
|
||||
LOG("init_w<%d> 0x%02x\n", Device, data);
|
||||
|
||||
// HACK: prevent unexpected mouse activity from crashing NEWS-OS
|
||||
if (Device == MOUSE)
|
||||
m_mouse_enable = bool(data);
|
||||
}
|
||||
|
||||
INPUT_PORTS_START(news_hid_hle_device)
|
||||
PORT_START("ROW0")
|
||||
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1))
|
||||
@ -232,9 +318,21 @@ INPUT_PORTS_START(news_hle_kbd_device)
|
||||
PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
|
||||
PORT_START("mouse_x_axis")
|
||||
PORT_BIT(0xffff, 0, IPT_MOUSE_X) PORT_SENSITIVITY(100)
|
||||
|
||||
PORT_START("mouse_y_axis")
|
||||
PORT_BIT(0xffff, 0, IPT_MOUSE_Y) PORT_SENSITIVITY(100)
|
||||
|
||||
PORT_START("mouse_buttons")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1) PORT_NAME("Left Button")
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CODE(MOUSECODE_BUTTON2) PORT_NAME("Right Button")
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_CODE(MOUSECODE_BUTTON3) PORT_NAME("Middle Button")
|
||||
PORT_BIT(0xf8, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
INPUT_PORTS_END
|
||||
|
||||
ioport_constructor news_hle_kbd_device::device_input_ports() const
|
||||
ioport_constructor news_hid_hle_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(news_hle_kbd_device);
|
||||
return INPUT_PORTS_NAME(news_hid_hle_device);
|
||||
}
|
||||
|
@ -8,15 +8,21 @@
|
||||
|
||||
#include "machine/keyboard.h"
|
||||
|
||||
class news_hle_kbd_device
|
||||
class news_hid_hle_device
|
||||
: public device_t
|
||||
, public device_matrix_keyboard_interface<8U>
|
||||
{
|
||||
public:
|
||||
news_hle_kbd_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0);
|
||||
news_hid_hle_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
auto irq_out() { return m_irq_out_cb.bind(); }
|
||||
u8 data_r();
|
||||
enum news_hid_device : unsigned
|
||||
{
|
||||
KEYBOARD = 0,
|
||||
MOUSE = 1,
|
||||
};
|
||||
template <news_hid_device Device> auto irq_out() { return m_irq_out_cb[Device].bind(); }
|
||||
|
||||
void map(address_map &map);
|
||||
|
||||
protected:
|
||||
// device_t overrides
|
||||
@ -27,17 +33,34 @@ protected:
|
||||
// device_matrix_keyboard_interface overrides
|
||||
virtual void key_make(u8 row, u8 column) override;
|
||||
virtual void key_break(u8 row, u8 column) override;
|
||||
virtual void scan_complete() override;
|
||||
|
||||
private:
|
||||
void push_key(u8 code);
|
||||
void out_irq(bool state);
|
||||
|
||||
devcb_write_line m_irq_out_cb;
|
||||
template <news_hid_device Device> void out_irq(bool state);
|
||||
|
||||
util::fifo<u8, 8> m_fifo;
|
||||
bool m_irq_out_state;
|
||||
template <news_hid_device Device> u8 status_r() { return (!m_fifo[Device].empty() ? 2 : 0) | (m_fifo[Device].full() ? 1 : 0); }
|
||||
template <news_hid_device Device> u8 data_r();
|
||||
template <news_hid_device Device> void reset_w(u8 data);
|
||||
template <news_hid_device Device> void init_w(u8 data);
|
||||
|
||||
required_ioport m_mouse_x_axis;
|
||||
required_ioport m_mouse_y_axis;
|
||||
required_ioport m_mouse_buttons;
|
||||
|
||||
devcb_write_line::array<2> m_irq_out_cb;
|
||||
|
||||
util::fifo<u8, 8> m_fifo[2];
|
||||
bool m_irq_out_state[2];
|
||||
|
||||
// mouse state
|
||||
s16 m_mouse_x;
|
||||
s16 m_mouse_y;
|
||||
u8 m_mouse_b;
|
||||
bool m_mouse_enable;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(NEWS_HLE_KBD, news_hle_kbd_device)
|
||||
DECLARE_DEVICE_TYPE(NEWS_HID_HLE, news_hid_hle_device)
|
||||
|
||||
#endif // MAME_MACHINE_NEWS_KBD_H
|
||||
|
Loading…
Reference in New Issue
Block a user