diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/bus/rs232/sparckbd.cpp | 65 | ||||
-rw-r--r-- | src/devices/bus/rs232/sparckbd.h | 5 |
2 files changed, 42 insertions, 28 deletions
diff --git a/src/devices/bus/rs232/sparckbd.cpp b/src/devices/bus/rs232/sparckbd.cpp index 3df48ba3d61..21e570cb189 100644 --- a/src/devices/bus/rs232/sparckbd.cpp +++ b/src/devices/bus/rs232/sparckbd.cpp @@ -6,9 +6,8 @@ /* - TODO: implement keyclick 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 @@ -16,7 +15,7 @@ 0000 0001 reset (keyboard responds with self test pass/fail) 0000 0010 bell on (480us period) 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 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) @@ -299,7 +298,7 @@ sparc_keyboard_device::sparc_keyboard_device( , device_serial_interface(mconfig, *this) , device_rs232_port_interface(mconfig, *this) , m_scan_timer(nullptr) - , m_tx_delay_timer(nullptr) + , m_click_timer(nullptr) , m_dips(*this, "DIP") , m_key_inputs{ { *this, "ROW0" }, { *this, "ROW1" }, @@ -314,6 +313,7 @@ sparc_keyboard_device::sparc_keyboard_device( , m_tail(0) , m_empty(0) , m_rx_state(RX_IDLE) + , m_keyclick(0) , m_beeper_state(0) { } @@ -340,7 +340,7 @@ void sparc_keyboard_device::device_start() device_serial_interface::register_save_state(machine().save(), this); 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_next_row)); @@ -349,6 +349,7 @@ void sparc_keyboard_device::device_start() save_item(NAME(m_tail)); save_item(NAME(m_empty)); save_item(NAME(m_rx_state)); + save_item(NAME(m_keyclick)); save_item(NAME(m_beeper_state)); } @@ -362,11 +363,12 @@ void sparc_keyboard_device::device_reset() m_head = m_tail = 0; m_empty = 1; m_rx_state = RX_IDLE; + m_keyclick = 0; m_beeper_state = 0; // configure device_serial_interface set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1); - set_rate(1200); + set_rate(1'200); receive_register_reset(); transmit_register_reset(); @@ -391,7 +393,7 @@ void sparc_keyboard_device::device_reset() // kick the scan timer 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(); break; - case TX_DELAY_TIMER_ID: - assert(is_transmit_register_empty()); - 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; - } + case CLICK_TIMER_ID: + m_beeper_state &= ~UINT8(BEEPER_CLICK); + m_beeper->set_state(m_beeper_state ? 1 : 0); break; default: @@ -433,7 +424,18 @@ void sparc_keyboard_device::tra_callback() 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: printf("SPARC keyboard: keyclick on\n"); fflush(stdout); - logerror("Keyclick on"); + m_keyclick = 1; m_rx_state = RX_IDLE; break; @@ -497,7 +499,10 @@ void sparc_keyboard_device::rcv_complete() case 0x0bU: printf("SPARC keyboard: keyclick off\n"); 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; break; @@ -531,7 +536,7 @@ void sparc_keyboard_device::scan_row() UINT16 const row(m_key_inputs[m_next_row]->read()); 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) { @@ -539,12 +544,20 @@ void sparc_keyboard_device::scan_row() if ((row ^ current) & mask) { UINT8 const make_break((row & mask) ? 0x00U : 0x80U); + keydown = keydown || !bool(make_break); keyup = keyup || bool(make_break); current = (current & ~mask) | (row & mask); 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) { UINT16 const acc( @@ -567,7 +580,7 @@ void sparc_keyboard_device::send_byte(UINT8 code) assert(m_head < 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); fflush(stdout); diff --git a/src/devices/bus/rs232/sparckbd.h b/src/devices/bus/rs232/sparckbd.h index a5444415e4f..cbe22d941f0 100644 --- a/src/devices/bus/rs232/sparckbd.h +++ b/src/devices/bus/rs232/sparckbd.h @@ -35,7 +35,7 @@ private: // device_serial_interface uses 10'000 range enum { SCAN_TIMER_ID = 20'000, - TX_DELAY_TIMER_ID + CLICK_TIMER_ID }; // TODO: ensure these don't clash with diagnostic LEDs on host computer @@ -60,7 +60,7 @@ private: void send_byte(UINT8 code); emu_timer *m_scan_timer; - emu_timer *m_tx_delay_timer; + emu_timer *m_click_timer; required_ioport m_dips; required_ioport m_key_inputs[8]; required_device<beep_device> m_beeper; @@ -74,6 +74,7 @@ private: UINT8 m_rx_state; + UINT8 m_keyclick; UINT8 m_beeper_state; }; |