mirror of
https://github.com/holub/mame
synced 2025-06-22 12:28:33 +03:00
SPARC keyboard: remove transmit delay hack, emulate keyclick [Vas Crabb]
This commit is contained in:
parent
4477e5d4b0
commit
9711a68c54
@ -6,9 +6,8 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: implement keyclick
|
|
||||||
TODO: determine default keyclick state on real keyboard
|
TODO: determine default keyclick state on real keyboard
|
||||||
TODO: use 1,200 Baud properly once we work out what's going on with the SCC
|
TODO: scancodes for extra key on international layout
|
||||||
|
|
||||||
HLE SPARC serial keyboard compatible with Sun Type 4/5/6
|
HLE SPARC serial keyboard compatible with Sun Type 4/5/6
|
||||||
|
|
||||||
@ -16,7 +15,7 @@
|
|||||||
0000 0001 reset (keyboard responds with self test pass/fail)
|
0000 0001 reset (keyboard responds with self test pass/fail)
|
||||||
0000 0010 bell on (480us period)
|
0000 0010 bell on (480us period)
|
||||||
0000 0011 bell off
|
0000 0011 bell off
|
||||||
0000 1010 enable keyclick (5us duration 480us period on make)
|
0000 1010 enable keyclick (5ms duration 480us period on make)
|
||||||
0000 1011 disable keyclick
|
0000 1011 disable keyclick
|
||||||
0000 1110 ---- lscn LED (1 = on, l = caps lock, s = scroll lock, c = compose, n = num lock)
|
0000 1110 ---- lscn LED (1 = on, l = caps lock, s = scroll lock, c = compose, n = num lock)
|
||||||
0000 1111 layout request (keyboard responds with layout response)
|
0000 1111 layout request (keyboard responds with layout response)
|
||||||
@ -299,7 +298,7 @@ sparc_keyboard_device::sparc_keyboard_device(
|
|||||||
, device_serial_interface(mconfig, *this)
|
, device_serial_interface(mconfig, *this)
|
||||||
, device_rs232_port_interface(mconfig, *this)
|
, device_rs232_port_interface(mconfig, *this)
|
||||||
, m_scan_timer(nullptr)
|
, m_scan_timer(nullptr)
|
||||||
, m_tx_delay_timer(nullptr)
|
, m_click_timer(nullptr)
|
||||||
, m_dips(*this, "DIP")
|
, m_dips(*this, "DIP")
|
||||||
, m_key_inputs{
|
, m_key_inputs{
|
||||||
{ *this, "ROW0" }, { *this, "ROW1" },
|
{ *this, "ROW0" }, { *this, "ROW1" },
|
||||||
@ -314,6 +313,7 @@ sparc_keyboard_device::sparc_keyboard_device(
|
|||||||
, m_tail(0)
|
, m_tail(0)
|
||||||
, m_empty(0)
|
, m_empty(0)
|
||||||
, m_rx_state(RX_IDLE)
|
, m_rx_state(RX_IDLE)
|
||||||
|
, m_keyclick(0)
|
||||||
, m_beeper_state(0)
|
, m_beeper_state(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -340,7 +340,7 @@ void sparc_keyboard_device::device_start()
|
|||||||
device_serial_interface::register_save_state(machine().save(), this);
|
device_serial_interface::register_save_state(machine().save(), this);
|
||||||
|
|
||||||
m_scan_timer = timer_alloc(SCAN_TIMER_ID);
|
m_scan_timer = timer_alloc(SCAN_TIMER_ID);
|
||||||
m_tx_delay_timer = timer_alloc(TX_DELAY_TIMER_ID);
|
m_click_timer = timer_alloc(CLICK_TIMER_ID);
|
||||||
|
|
||||||
save_item(NAME(m_current_keys));
|
save_item(NAME(m_current_keys));
|
||||||
save_item(NAME(m_next_row));
|
save_item(NAME(m_next_row));
|
||||||
@ -349,6 +349,7 @@ void sparc_keyboard_device::device_start()
|
|||||||
save_item(NAME(m_tail));
|
save_item(NAME(m_tail));
|
||||||
save_item(NAME(m_empty));
|
save_item(NAME(m_empty));
|
||||||
save_item(NAME(m_rx_state));
|
save_item(NAME(m_rx_state));
|
||||||
|
save_item(NAME(m_keyclick));
|
||||||
save_item(NAME(m_beeper_state));
|
save_item(NAME(m_beeper_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,11 +363,12 @@ void sparc_keyboard_device::device_reset()
|
|||||||
m_head = m_tail = 0;
|
m_head = m_tail = 0;
|
||||||
m_empty = 1;
|
m_empty = 1;
|
||||||
m_rx_state = RX_IDLE;
|
m_rx_state = RX_IDLE;
|
||||||
|
m_keyclick = 0;
|
||||||
m_beeper_state = 0;
|
m_beeper_state = 0;
|
||||||
|
|
||||||
// configure device_serial_interface
|
// configure device_serial_interface
|
||||||
set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1);
|
set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1);
|
||||||
set_rate(1200);
|
set_rate(1'200);
|
||||||
receive_register_reset();
|
receive_register_reset();
|
||||||
transmit_register_reset();
|
transmit_register_reset();
|
||||||
|
|
||||||
@ -391,7 +393,7 @@ void sparc_keyboard_device::device_reset()
|
|||||||
|
|
||||||
// kick the scan timer
|
// kick the scan timer
|
||||||
m_scan_timer->adjust(attotime::from_hz(1'200), 0, attotime::from_hz(1'200));
|
m_scan_timer->adjust(attotime::from_hz(1'200), 0, attotime::from_hz(1'200));
|
||||||
m_tx_delay_timer->reset();
|
m_click_timer->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -403,20 +405,9 @@ void sparc_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, i
|
|||||||
scan_row();
|
scan_row();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TX_DELAY_TIMER_ID:
|
case CLICK_TIMER_ID:
|
||||||
assert(is_transmit_register_empty());
|
m_beeper_state &= ~UINT8(BEEPER_CLICK);
|
||||||
assert(!m_empty || (m_head == m_tail));
|
m_beeper->set_state(m_beeper_state ? 1 : 0);
|
||||||
assert(m_head < ARRAY_LENGTH(m_fifo));
|
|
||||||
assert(m_tail < ARRAY_LENGTH(m_fifo));
|
|
||||||
|
|
||||||
if (!m_empty)
|
|
||||||
{
|
|
||||||
printf("SPARC keyboard: send queued: %02x\n", m_fifo[m_head]);
|
|
||||||
fflush(stdout);
|
|
||||||
transmit_register_setup(m_fifo[m_head]);
|
|
||||||
m_head = (m_head + 1) & 0x0fU;
|
|
||||||
m_empty = (m_head == m_tail) ? 1 : 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -433,7 +424,18 @@ void sparc_keyboard_device::tra_callback()
|
|||||||
|
|
||||||
void sparc_keyboard_device::tra_complete()
|
void sparc_keyboard_device::tra_complete()
|
||||||
{
|
{
|
||||||
m_tx_delay_timer->reset(attotime::from_hz(1'200 / 10));
|
assert(!m_empty || (m_head == m_tail));
|
||||||
|
assert(m_head < ARRAY_LENGTH(m_fifo));
|
||||||
|
assert(m_tail < ARRAY_LENGTH(m_fifo));
|
||||||
|
|
||||||
|
if (!m_empty)
|
||||||
|
{
|
||||||
|
printf("SPARC keyboard: send queued: %02x\n", m_fifo[m_head]);
|
||||||
|
fflush(stdout);
|
||||||
|
transmit_register_setup(m_fifo[m_head]);
|
||||||
|
m_head = (m_head + 1) & 0x0fU;
|
||||||
|
m_empty = (m_head == m_tail) ? 1 : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -489,7 +491,7 @@ void sparc_keyboard_device::rcv_complete()
|
|||||||
case 0x0aU:
|
case 0x0aU:
|
||||||
printf("SPARC keyboard: keyclick on\n");
|
printf("SPARC keyboard: keyclick on\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
logerror("Keyclick on");
|
m_keyclick = 1;
|
||||||
m_rx_state = RX_IDLE;
|
m_rx_state = RX_IDLE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -497,7 +499,10 @@ void sparc_keyboard_device::rcv_complete()
|
|||||||
case 0x0bU:
|
case 0x0bU:
|
||||||
printf("SPARC keyboard: keyclick off\n");
|
printf("SPARC keyboard: keyclick off\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
logerror("Keyclick off");
|
m_keyclick = 0;
|
||||||
|
m_click_timer->reset();
|
||||||
|
m_beeper_state &= ~UINT8(BEEPER_CLICK);
|
||||||
|
m_beeper->set_state(m_beeper_state ? 1 : 0);
|
||||||
m_rx_state = RX_IDLE;
|
m_rx_state = RX_IDLE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -531,7 +536,7 @@ void sparc_keyboard_device::scan_row()
|
|||||||
|
|
||||||
UINT16 const row(m_key_inputs[m_next_row]->read());
|
UINT16 const row(m_key_inputs[m_next_row]->read());
|
||||||
UINT16 ¤t(m_current_keys[m_next_row]);
|
UINT16 ¤t(m_current_keys[m_next_row]);
|
||||||
bool keyup(false);
|
bool keydown(false), keyup(false);
|
||||||
|
|
||||||
for (UINT8 bit = 0; (bit < 16) && (m_empty || (m_head != m_tail)); ++bit)
|
for (UINT8 bit = 0; (bit < 16) && (m_empty || (m_head != m_tail)); ++bit)
|
||||||
{
|
{
|
||||||
@ -539,12 +544,20 @@ void sparc_keyboard_device::scan_row()
|
|||||||
if ((row ^ current) & mask)
|
if ((row ^ current) & mask)
|
||||||
{
|
{
|
||||||
UINT8 const make_break((row & mask) ? 0x00U : 0x80U);
|
UINT8 const make_break((row & mask) ? 0x00U : 0x80U);
|
||||||
|
keydown = keydown || !bool(make_break);
|
||||||
keyup = keyup || bool(make_break);
|
keyup = keyup || bool(make_break);
|
||||||
current = (current & ~mask) | (row & mask);
|
current = (current & ~mask) | (row & mask);
|
||||||
send_byte(make_break | (m_next_row << 4) | bit);
|
send_byte(make_break | (m_next_row << 4) | bit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keydown && m_keyclick)
|
||||||
|
{
|
||||||
|
m_beeper_state |= UINT8(BEEPER_CLICK);
|
||||||
|
m_beeper->set_state(m_beeper_state ? 1 : 0);
|
||||||
|
m_click_timer->reset(attotime::from_msec(5));
|
||||||
|
}
|
||||||
|
|
||||||
if (keyup)
|
if (keyup)
|
||||||
{
|
{
|
||||||
UINT16 const acc(
|
UINT16 const acc(
|
||||||
@ -567,7 +580,7 @@ void sparc_keyboard_device::send_byte(UINT8 code)
|
|||||||
assert(m_head < ARRAY_LENGTH(m_fifo));
|
assert(m_head < ARRAY_LENGTH(m_fifo));
|
||||||
assert(m_tail < ARRAY_LENGTH(m_fifo));
|
assert(m_tail < ARRAY_LENGTH(m_fifo));
|
||||||
|
|
||||||
if (m_empty && is_transmit_register_empty() && (m_tx_delay_timer->remaining() == attotime::never))
|
if (m_empty && is_transmit_register_empty())
|
||||||
{
|
{
|
||||||
printf("SPARC keyboard: send immediately: %02x\n", code);
|
printf("SPARC keyboard: send immediately: %02x\n", code);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -35,7 +35,7 @@ private:
|
|||||||
// device_serial_interface uses 10'000 range
|
// device_serial_interface uses 10'000 range
|
||||||
enum {
|
enum {
|
||||||
SCAN_TIMER_ID = 20'000,
|
SCAN_TIMER_ID = 20'000,
|
||||||
TX_DELAY_TIMER_ID
|
CLICK_TIMER_ID
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: ensure these don't clash with diagnostic LEDs on host computer
|
// TODO: ensure these don't clash with diagnostic LEDs on host computer
|
||||||
@ -60,7 +60,7 @@ private:
|
|||||||
void send_byte(UINT8 code);
|
void send_byte(UINT8 code);
|
||||||
|
|
||||||
emu_timer *m_scan_timer;
|
emu_timer *m_scan_timer;
|
||||||
emu_timer *m_tx_delay_timer;
|
emu_timer *m_click_timer;
|
||||||
required_ioport m_dips;
|
required_ioport m_dips;
|
||||||
required_ioport m_key_inputs[8];
|
required_ioport m_key_inputs[8];
|
||||||
required_device<beep_device> m_beeper;
|
required_device<beep_device> m_beeper;
|
||||||
@ -74,6 +74,7 @@ private:
|
|||||||
|
|
||||||
UINT8 m_rx_state;
|
UINT8 m_rx_state;
|
||||||
|
|
||||||
|
UINT8 m_keyclick;
|
||||||
UINT8 m_beeper_state;
|
UINT8 m_beeper_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user