summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/8042kbdc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/8042kbdc.cpp')
-rw-r--r--src/devices/machine/8042kbdc.cpp299
1 files changed, 118 insertions, 181 deletions
diff --git a/src/devices/machine/8042kbdc.cpp b/src/devices/machine/8042kbdc.cpp
index 44927c1433c..649be5f2529 100644
--- a/src/devices/machine/8042kbdc.cpp
+++ b/src/devices/machine/8042kbdc.cpp
@@ -2,175 +2,9 @@
// copyright-holders:Peter Trauner
/*********************************************************************
- 8042kbdc.c
-
- Code specific to fun IBM AT stuff
-
-
- PeT's notes about various Power On Self Tests (POSTs)
-
- at post
- -------
- f81d2 01
- f82e6 05
- f8356 07
- f83e5 0a
- f847e 0e
- f8e7c 10
- f8f3a 13
- f9058 1a
- f913a 1e
- fa8ba 30
- fa96c 36
- fa9d3 3c
- fa9f4 3e
- ff122 50
- ff226 5b
- ff29f 5f
- f9228 70
- f92b2 74 ide?
-
- ibm at bios
- -----------
- f0101 after switch to real mode jump back!!!!!!!!!!
- jumping table
- f0123
- f098e memory tests
- f10b4 ???
- not reached
- f1050
- f1617
- f0119
- f10d8
- f10b7 system board error
-
- f019f
- f025b
- f02e6
- f0323
- f03b3 0e
- f03d7 0f
- f058d
- at8042 signal timing test
- sets errorcode!
-
- f0655
- f06a3 postcode 15
- f06ba 16
- f0747 18
- f0763 enter pm! (0x81, 0x85)
- f0766 1a
- f07b3 first 640kb memory test
- f084c 1c
- f086e extended memory test
- f0928 1f
- f097d 20
- ???
- f0ff4 34
- ???
- f1675 f0
- f16cb f2
- illegal access trap test!!!!
- f16fe f3
- task descriptor test!!!!
- f174a f4
- f17af f5
- f1800 f6 writing to non write segment
- f1852 f7 arpl
- f1880 f8 lar, lsl
- f18ca fa
- f10d8
- f10ec 35
- f1106 36
- f1137 !!!!!!!keyboard test fails
-
- f11aa 3a
- f1240 3c harddisk controller test!!!
- f13f3 3b
- f1a6d xthdd bios init
- f1429
- f1462
- f1493 40
- f1532
- keyboard lock
- f1 to unlock
- f155c
- jumps to f0050 (reset) without enabling of the a20 gate --> hangs
- 0412 bit 5 must be set to reach f1579
- f1579
- f15c3 41
- f1621 43
-
- routines
- f1945 read cmos ram
- f195f write to cmos al value ah
- f1a3a poll 0x61 bit 4
- f1a49 sets something in cmos ram
- f1d30 switch to protected mode
-
- neat
- ----
- f80b9
-
- at386
- -----
- fd28c fd
- fd2c3 fc
- f40dc
- fd949
- fd8e3
- fd982
- f4219 01
- f4296 03
- f42f3 04
- f4377 05
- f43ec 06
- f4430 08
- f6017 switches to PM
- f4456 09
- f55a2
- f44ec 0d
- f4557 20
- f462d 27 my special friend, the keyboard controller once more
- ed0a1
- f4679 28
- fa16a
- f46d6
- f4768 2c
- f47f0 2e
- f5081
- fa16a
- f9a83
- Message: "Checksum Error on Extended CMOS"
- f4840 34
- f488c 35
- reset
- f48ee
- f493e 3a
- f49cd
- f4fc7
- fe842
- f4a5a
- f4b01 38
- (Memory Test)
- f4b41 3b
- f4c0f
- Message: "Invalid configuration information - please run SETUP program"
- f4c5c
- f86fc
- f8838
- f4c80
- f4ca2
- f4d4c
- f4e15 (int 19h)
-
- [f9a83 output text at return address!, return after text]
-
-
- at486
- -----
- f81a5 03
- f1096 0f 09 wbinvd i486 instruction
+ 8042kbdc.cpp
+
+ 8042-based keyboard/mouse controller simulation
*********************************************************************/
@@ -191,7 +25,7 @@
#define LOG_KEYBOARD 0
#define LOG_ACCESSES 0
-DEFINE_DEVICE_TYPE(KBDC8042, kbdc8042_device, "kbdc8042", "8042 Keyboard Controller")
+DEFINE_DEVICE_TYPE(KBDC8042, kbdc8042_device, "kbdc8042", "8042 Keyboard/Mouse Controller")
//-------------------------------------------------
// kbdc8042_device - constructor
@@ -200,6 +34,9 @@ DEFINE_DEVICE_TYPE(KBDC8042, kbdc8042_device, "kbdc8042", "8042 Keyboard Control
kbdc8042_device::kbdc8042_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, KBDC8042, tag, owner, clock)
, m_keyboard_dev(*this, "at_keyboard")
+ , m_mousex_port(*this, "MOUSEX")
+ , m_mousey_port(*this, "MOUSEY")
+ , m_mousebtn_port(*this, "MOUSEBTN")
, m_system_reset_cb(*this)
, m_gate_a20_cb(*this)
, m_input_buffer_full_cb(*this)
@@ -228,6 +65,7 @@ void kbdc8042_device::device_start()
m_operation_write_state = 0; /* first write to 0x60 might occur before anything can set this */
memset(&m_keyboard, 0x00, sizeof(m_keyboard));
memset(&m_mouse, 0x00, sizeof(m_mouse));
+ m_mouse.sample_rate = 100;
m_sending = 0;
m_last_write_to_control = 0;
m_status_read_mode = 0;
@@ -244,12 +82,15 @@ void kbdc8042_device::device_reset()
/* ibmat bios wants 0x20 set! (keyboard locked when not set) 0x80 */
m_inport = 0xa0;
at_8042_set_outport(0xfe, 1);
+
+ m_mouse_x = 0;
+ m_mouse_y = 0;
+ m_mouse_btn = 0;
}
void kbdc8042_device::at_8042_set_outport(uint8_t data, int initial)
{
- uint8_t change;
- change = initial ? 0xFF : (m_outport ^ data);
+ uint8_t change = initial ? 0xFF : (m_outport ^ data);
m_outport = data;
if (change & 0x02)
{
@@ -264,15 +105,18 @@ WRITE_LINE_MEMBER( kbdc8042_device::keyboard_w )
at_8042_check_keyboard();
}
-void kbdc8042_device::at_8042_receive(uint8_t data)
+void kbdc8042_device::at_8042_receive(uint8_t data, bool mouse)
{
if (LOG_KEYBOARD)
logerror("at_8042_receive Received 0x%02x\n", data);
m_data = data;
- if(!(m_speaker & 0x80))
+ if(!(m_speaker & 0x80) || mouse)
{
- m_keyboard.received = 1;
+ if (mouse)
+ m_mouse.received = 1;
+ else
+ m_keyboard.received = 1;
if (!m_input_buffer_full_cb.isnull())
m_input_buffer_full_cb(1);
@@ -281,15 +125,62 @@ void kbdc8042_device::at_8042_receive(uint8_t data)
void kbdc8042_device::at_8042_check_keyboard()
{
- int data;
-
if (!m_keyboard.received && !m_mouse.received)
{
- if((data = m_keyboard_dev->read(machine().dummy_space(), 0)))
+ int data = m_keyboard_dev->read(machine().dummy_space(), 0);
+ if (data)
at_8042_receive(data);
}
}
+void kbdc8042_device::at_8042_check_mouse()
+{
+ if (!m_keyboard.received && !m_mouse.received)
+ {
+ if (m_mouse.to_transmit == 0)
+ {
+ uint16_t x = m_mousex_port->read();
+ uint16_t y = m_mousey_port->read();
+ uint8_t buttons = m_mousebtn_port->read();
+
+ uint16_t old_mouse_x = m_mouse_x;
+ uint16_t old_mouse_y = m_mouse_y;
+ uint16_t old_mouse_btn = m_mouse_btn;
+
+ if(m_mouse_x == 0xffff)
+ {
+ old_mouse_x = x & 0x3ff;
+ old_mouse_y = y & 0x3ff;
+ old_mouse_btn = buttons;
+ }
+
+ m_mouse_x = x & 0x3ff;
+ m_mouse_y = y & 0x3ff;
+ m_mouse_btn = buttons;
+
+ uint16_t dx = m_mouse_x - old_mouse_x;
+ uint16_t dy = old_mouse_y - m_mouse_y;
+
+ if (dx != 0 || dy != 0 || buttons != old_mouse_btn)
+ {
+ m_mouse.to_transmit = 3;
+ m_mouse.transmit_buf[0] = buttons | 0x08 | (BIT(dx, 8) << 4) | (BIT(dy, 8) << 5);
+ m_mouse.transmit_buf[1] = dx & 0xff;
+ m_mouse.transmit_buf[2] = dy & 0xff;
+ }
+ }
+
+ if (m_mouse.to_transmit)
+ {
+ at_8042_receive(m_mouse.transmit_buf[0], true);
+ m_mouse.to_transmit--;
+ for (int i = 0; i < m_mouse.to_transmit; i++)
+ {
+ m_mouse.transmit_buf[i] = m_mouse.transmit_buf[i + 1];
+ }
+ }
+ }
+}
void kbdc8042_device::at_8042_clear_keyboard_received()
{
@@ -370,6 +261,7 @@ READ8_MEMBER(kbdc8042_device::data_r)
case 4:
at_8042_check_keyboard();
+ at_8042_check_mouse();
if (m_keyboard.received || m_mouse.received)
data |= 1;
@@ -444,6 +336,29 @@ WRITE8_MEMBER(kbdc8042_device::data_w)
case 4:
/* preceded by writing 0xD4 to port 60h */
m_data = data;
+ if (m_mouse.receiving_sample_rate)
+ {
+ m_mouse.received = 1;
+ m_mouse.sample_rate = data;
+ m_data = 0xfa;
+ break;
+ }
+
+ switch (m_data)
+ {
+ case 0xf6:
+ m_mouse.received = 1;
+ m_data = 0xfa;
+ break;
+ case 0xf3:
+ m_mouse.received = 1;
+ m_data = 0xfa;
+ m_mouse.receiving_sample_rate = true;
+ break;
+ default:
+ logerror("%s: Unknown mouse command: %02x\n", machine().describe_context(), m_data);
+ break;
+ }
break;
case 5:
@@ -463,7 +378,7 @@ WRITE8_MEMBER(kbdc8042_device::data_w)
}
m_speaker &= ~0x80;
if (!m_speaker_cb.isnull())
- m_speaker_cb((offs_t)0, m_speaker);
+ m_speaker_cb((offs_t)0, m_speaker);
break;
@@ -473,7 +388,7 @@ WRITE8_MEMBER(kbdc8042_device::data_w)
/* switch based on the command */
switch(data) {
case 0x20: /* current 8042 command byte is placed on port 60h */
- m_data = m_command;
+ at_8042_receive(m_command);
break;
case 0x60: /* next data byte is placed in 8042 command byte */
m_operation_write_state = 5;
@@ -548,12 +463,16 @@ WRITE8_MEMBER(kbdc8042_device::data_w)
* written to input register a port at 60h is sent to the
* auxiliary device */
m_operation_write_state = 4;
+ m_send_to_mouse = 1;
break;
case 0xe0:
/* read test inputs; read T1/T0 test inputs into bit 1/0 */
at_8042_receive(0x00);
break;
-
+ case 0xed:
+ /* set/unset keyboard LEDs */
+ at_8042_receive(0xfa);
+ break;
case 0xf0:
case 0xf2:
case 0xf4:
@@ -581,3 +500,21 @@ WRITE_LINE_MEMBER(kbdc8042_device::write_out2)
{
m_out2 = state;
}
+
+INPUT_PORTS_START( kbdc8042_mouse )
+ PORT_START("MOUSEX")
+ PORT_BIT(0x3ff, 0x000, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0x3ff) PORT_KEYDELTA(2)
+
+ PORT_START("MOUSEY")
+ PORT_BIT(0x3ff, 0x000, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0x3ff) PORT_KEYDELTA(2)
+
+ PORT_START("MOUSEBTN")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1) PORT_NAME("Mouse Button 1")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CODE(MOUSECODE_BUTTON2) PORT_NAME("Mouse Button 2")
+ PORT_BIT(0xfc, IP_ACTIVE_HIGH, IPT_UNUSED)
+INPUT_PORTS_END
+
+ioport_constructor kbdc8042_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(kbdc8042_mouse);
+}