diff options
Diffstat (limited to 'src/mess/machine/kc_keyb.c')
-rw-r--r-- | src/mess/machine/kc_keyb.c | 614 |
1 files changed, 0 insertions, 614 deletions
diff --git a/src/mess/machine/kc_keyb.c b/src/mess/machine/kc_keyb.c deleted file mode 100644 index 740d0dc7fce..00000000000 --- a/src/mess/machine/kc_keyb.c +++ /dev/null @@ -1,614 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Kevin Thacker,Sandro Ronco -/********************************************************************* - - kc_keyb.c - - KC85_2/3/4/5 Keyboard emulation - -********************************************************************** - - E-mail from Torsten Paul about the keyboard: - - Torsten.Paul@gmx.de - -"> I hope that you will be able to help me so I can add keyboard -> emulation to it. -> -Oh yes the keyboard caused me a lot of trouble too. I still don't -understand it completely. -A first dirty but working keyboard support is quite easy because -of the good and modular system rom. Most programs use the supplied -routines to read keyboard input so patching the right memory address -with the keycode that is originally supplied by the interrupt -routines for keyboard input will work. So if you first want to -have a simple start to get other things to work you can try this. - - * write keycode (ascii) to address IX+0dh (0x1fd) - * set bit 0 at address IX+08h (0x1f8) - simply writing 01h - worked for me but some other bits are used too - this bit is reset if the key is read by the system - -> From the schematics I see that the keyboard is linked to the CTC and PIO, -> but I don't understand it fully. -> Please can you tell me more about how the keyboard is scanned? -> -The full emulation is quite tricky and I still have some programs that -behave odd. (A good hint for a correct keyboard emulation is Digger ;-). - -Ok, now the technical things: - -The keyboard of the KC is driven by a remote control circuit that is -originally designed for infrared remote control. This one was named -U807 and I learned there should be a similar chip called SAB 3021 -available but I never found the specs on the web. The SAB 3021 was -produced by Valvo which doesn't exist anymore (bought by Phillips -if I remember correctly). If you have more luck finding the specs -I'm still interested. -There also was a complementary chip for the recieving side but that -was not used in the KC unfortunately. They choosed to measure the -pulses sent by the U807 via PIO and CTC. - -Anyway here is what I know about the protocol: - -The U807 sends impulses with equal length. The information is -given by the time between two impulses. Short time means bit is 1 -long time mean bit is 0. The impulses are modulated by a 62.5 kHz -Signal but that's not interesting for the emulator. -The timing comes from a base clock of 4 MHz that is divided -multiple times: - -4 MHz / 64 - 62.5 kHz -> used for filtered amplification -62.5 kHz / 64 - 976 Hz -> 1.024 ms -976 / 7 - 140 Hz -> 7.2 ms -976 / 5 - 195 Hz -> 5.1 ms - -short - 5.12 ms - 1 bit -long - 7.168 ms - 0 bit - - +-+ +-+ +-+ +-+ - | | | | | | | | - +--+ +-----+ +-------+ +-----+ +--.... - - | | |---0---| |--1--| - ^ - | - Startbit = shift key - -The keyboard can have 64 keys with an additional key that is used by -the KC as shift key. This additional key is directly connected to the -chip and changes the startbit. All other keys are arranged in a matrix. - -The chip sends full words of 7 bits (including the startbit) at least -twice for each keypress with a spacing of 14 * 1.024 ms. If the key -is still pressed the double word is repeated after 19 * 1.024 ms. - -The impulses trigger the pio interrupt line for channel B that -triggers the time measurement by the CTC channel 3." - - -********************************************************************** - - - The CTC timer 3 count is initialised at 0x08f and counts down. - - The pulses are connected into PIO /BSTB and generate a interrupt - on a positive edge. A pulse will not get through if BRDY from PIO is - not true! - - Then the interrupt occurs, the CTC count is read. The time between - pulses is therefore measured by the CTC. - - The time is checked and depending on the value the KC detects - a 1 or 0 bit sent from the keyboard. - - Summary From code below: - - 0x065<=count<0x078 -> 0 bit "short pulse" - 0x042<=count<0x065 -> 1 bit "long pulse" - count<0x014 -> ignore - count>=0x078 -> ignore - 0x014<=count<0x042 -> signal end of code "very long pulse" - - codes are sent bit 0, bit 1, bit 2...bit 7. bit 0 is the state - of the shift key. - - Torsten's e-mail indicates "short pulse" for 1 bit, and "long - pulse" for 0 bit, but I found this to be incorrect. However, - the timings are correct. - - - Keyboard reading procedure extracted from KC85/4 system rom: - -0345 f5 push af -0346 db8f in a,(#8f) ; get CTC timer 3 count -0348 f5 push af -0349 3ea7 ld a,#a7 ; channel 3, enable int, select counter mode, control word - ; write, software reset, time constant follows -034b d38f out (#8f),a -034d 3e8f ld a,#8f ; time constant -034f d38f out (#8f),a -0351 f1 pop af - -0352 fb ei -0353 b7 or a ; count is over -0354 284d jr z,#03a3 ; - - ;; check count is in range -0356 fe14 cp #14 -0358 3849 jr c,#03a3 ; -035a fe78 cp #78 -035c 3045 jr nc,#03a3 ; - - ;; at this point, time must be between #14 and #77 to be valid - - ;; if >=#65, then carry=0, and a 0 bit has been detected - -035e fe65 cp #65 -0360 303d jr nc,#039f ; (61) - - ;; if <#65, then a 1 bit has been detected. carry is set with the addition below. - ;; a carry will be generated if the count is >#42 - - ;; therefore for a 1 bit to be generated, then #42<=time<#65 - ;; must be true. - -0362 c6be add a,#be -0364 3839 jr c,#039f ; (57) - - ;; this code appears to take the transmitted scan-code - ;; and converts it into a useable code by the os??? -0366 e5 push hl -0367 d5 push de - ;; convert hardware scan-code into os code -0368 dd7e0c ld a,(ix+#0c) -036b 1f rra -036c ee01 xor #01 -036e dd6e0e ld l,(ix+#0e) -0371 dd660f ld h,(ix+#0f) -0374 1600 ld d,#00 -0376 5f ld e,a -0377 19 add hl,de -0378 7e ld a,(hl) -0379 d1 pop de -037a e1 pop hl - - ;; shift lock pressed? -037b ddcb087e bit 7,(ix+#08) -037f 200a jr nz,#038b - ;; no. - - ;; alpha char? -0381 fe40 cp #40 -0383 3806 jr c,#038b -0385 fe80 cp #80 -0387 3002 jr nc,#038b - ;; yes, it is a alpha char - ;; force to lower case -0389 ee20 xor #20 - -038b ddbe0d cp (ix+#0d) ;; same as stored? -038e 201d jr nz,#03ad - - ;; yes - must be held for a certain time before it can repeat? -0390 f5 push af -0391 3ae0b7 ld a,(#b7e0) -0394 ddbe0a cp (ix+#0a) -0397 3811 jr c,#03aa -0399 f1 pop af - -039a dd340a inc (ix+#0a) ;; incremenent repeat count? -039d 1804 jr #03a3 - - ;; update scan-code received so far - -039f ddcb0c1e rr (ix+#0c) ; shift in 0 or 1 bit depending on what has been selected - -03a3 db89 in a,(#89) ; used to clear brdy -03a5 d389 out (#89),a -03a7 f1 pop af -03a8 ed4d reti - -03aa f1 pop af -03ab 1808 jr #03b5 - -;; clear count -03ad dd360a00 ld (ix+#0a),#00 - -;; shift lock? -03b1 fe16 cp #16 -03b3 2809 jr z,#03be - -;; store char -03b5 dd770d ld (ix+#0d),a -03b8 ddcb08c6 set 0,(ix+#08) -03bc 18e5 jr #03a3 - -;; toggle shift lock on/off -03be dd7e08 ld a,(ix+#08) -03c1 ee80 xor #80 -03c3 dd7708 ld (ix+#08),a -;; shift/lock was last key pressed -03c6 3e16 ld a,#16 -03c8 18eb jr #03b5 - -03ca b7 or a -03cb ddcb0846 bit 0,(ix+#08) -03cf c8 ret z -03d0 dd7e0d ld a,(ix+#0d) -03d3 37 scf -03d4 c9 ret -03d5 cdcae3 call #e3ca -03d8 d0 ret nc -03d9 ddcb0886 res 0,(ix+#08) -03dd c9 ret -03de cdcae3 call #e3ca -03e1 d0 ret nc -03e2 fe03 cp #03 -03e4 37 scf -03e5 c8 ret z -03e6 a7 and a -03e7 c9 ret - - - Keyboard reading procedure extracted from KC85/3 rom: - - -019a f5 push af -019b db8f in a,(#8f) -019d f5 push af -019e 3ea7 ld a,#a7 -01a0 d38f out (#8f),a -01a2 3e8f ld a,#8f -01a4 d38f out (#8f),a -01a6 f1 pop af -01a7 ddcb085e bit 3,(ix+#08) -01ab ddcb089e res 3,(ix+#08) -01af 2055 jr nz,#0206 ; (85) - -01b1 fe65 cp #65 -01b3 3054 jr nc,#0209 - - - ;; count>=#65 = 0 bit - ;; #44<=count<#65 = 1 bit - ;; count<#44 = end of code - -01b5 fe44 cp #44 -01b7 3053 jr nc,#020c -01b9 e5 push hl -01ba d5 push de -01bb ddcb0c3e srl (ix+#0c) -01bf dd7e08 ld a,(ix+#08) -01c2 e680 and #80 -01c4 07 rlca -01c5 ddae0c xor (ix+#0c) -01c8 2600 ld h,#00 -01ca dd5e0e ld e,(ix+#0e) -01cd dd560f ld d,(ix+#0f) -01d0 6f ld l,a -01d1 19 add hl,de -01d2 7e ld a,(hl) -01d3 d1 pop de -01d4 e1 pop hl -01d5 ddbe0d cp (ix+#0d) -01d8 2811 jr z,#01eb ; (17) -01da dd770d ld (ix+#0d),a -01dd ddcb08a6 res 4,(ix+#08) -01e1 ddcb08c6 set 0,(ix+#08) -01e5 dd360a00 ld (ix+#0a),#00 -01e9 181b jr #0206 ; (27) -01eb dd340a inc (ix+#0a) -01ee ddcb0866 bit 4,(ix+#08) -01f2 200c jr nz,#0200 ; (12) -01f4 ddcb0a66 bit 4,(ix+#0a) -01f8 280c jr z,#0206 ; (12) -01fa ddcb08e6 set 4,(ix+#08) -01fe 18e1 jr #01e1 ; (-31) -0200 ddcb0a4e bit 1,(ix+#0a) -0204 20db jr nz,#01e1 ; (-37) -0206 f1 pop af -0207 ed4d reti -0209 b7 or a -020a 1801 jr #020d ; (1) -020c 37 scf -020d ddcb0c1e rr (ix+#0c) -0211 18f3 jr #0206 ; (-13) - -*********************************************************************/ - - -#include "emu.h" -#include "kc_keyb.h" - -#define VERBOSE 0 -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) - -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** - -const device_type KC_KEYBOARD = &device_creator<kc_keyboard_device>; - -//************************************************************************** -// Input Ports -//************************************************************************** - -// this is a fake keyboard layout. The keys are converted into codes -// which are transmitted by the keyboard to the base-unit. key code can -// be calculated as (line*8)+bit_index - -static INPUT_PORTS_START( kc_keyboard ) - // start of keyboard scan-codes - // codes 0-7 - PORT_START("KEY0") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) - PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) - PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') PORT_CHAR('=') - PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) - PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') - // codes 8-15 - PORT_START("KEY1") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('^') PORT_CHAR(0x00AC) - PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Clr") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) - PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*') - PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) - PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') - // codes 16-23 - PORT_START("KEY2") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') - PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Del") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL)) - PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('@') - PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) - PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') - // codes 24-31 - PORT_START("KEY3") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') - PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Ins") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) - PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') - PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Brk") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) - PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') - // codes 32-39 - PORT_START("KEY4") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') - PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Stop") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(PAUSE)) - PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') - // codes 40-47 - PORT_START("KEY5") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') - PORT_BIT(0x08, 0x00, IPT_UNUSED) - PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') - PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) - PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') - // codes 48-56 - PORT_START("KEY6") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('-') PORT_CHAR('|') - PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR('+') PORT_CHAR(';') - PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) - PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') - // codes 56-63 - PORT_START("KEY7") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Shift Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) - PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) - PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) - PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) - // end of keyboard scan-codes - PORT_START("SHIFT") - // has a single shift key. Mapped here to left and right shift. - // shift is connected to the MOC pin of the U807 - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) -INPUT_PORTS_END - - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// kc_keyboard_device - constructor -//------------------------------------------------- -kc_keyboard_device::kc_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - device_t(mconfig, KC_KEYBOARD, "KC Keyboard", tag, owner, clock, "kc_keyboard", __FILE__), - m_write_out(*this) -{ -} - -//------------------------------------------------- -// kc_keyboard_device - destructor -//------------------------------------------------- - -kc_keyboard_device::~kc_keyboard_device() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void kc_keyboard_device::device_start() -{ - // resolve callbacks - m_write_out.resolve_safe(); - - m_timer_transmit_pulse = timer_alloc(TIMER_TRANSMIT_PULSE); - - m_timer_transmit_pulse->adjust(attotime::from_usec(1024), 0, attotime::from_usec(1024)); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void kc_keyboard_device::device_reset() -{ - // set initial state - m_write_out(CLEAR_LINE); - - m_transmit_buffer.pulse_sent = 0; - m_transmit_buffer.pulse_count = 0; - - memset(&m_transmit_buffer, 0, sizeof(m_transmit_buffer)); -} - -//------------------------------------------------- -// input_ports - device-specific input ports -//------------------------------------------------- - -ioport_constructor kc_keyboard_device::device_input_ports() const -{ - return INPUT_PORTS_NAME( kc_keyboard ); -} - -//------------------------------------------------- -// device_timer - handler timer events -//------------------------------------------------- - -void kc_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch(id) - { - case TIMER_TRANSMIT_PULSE: - if (m_transmit_buffer.pulse_sent < m_transmit_buffer.pulse_count) - { - // byte containing pulse state - int pulse_byte_count = m_transmit_buffer.pulse_sent>>3; - // bit within byte containing pulse state - int pulse_bit_count = 7 - (m_transmit_buffer.pulse_sent & 0x07); - - // get current pulse state - int pulse_state = (m_transmit_buffer.data[pulse_byte_count]>>pulse_bit_count) & 0x01; - - LOG(("KC keyboard sending pulse: %02x\n", pulse_state)); - - // send pulse - m_write_out(pulse_state ? ASSERT_LINE : CLEAR_LINE); - - // update counts - m_transmit_buffer.pulse_sent++; - } - else - { - // if there is nothing to send, rescan the keyboard - static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5", "KEY6", "KEY7" }; - - m_transmit_buffer.pulse_sent = 0; - m_transmit_buffer.pulse_count = 0; - - // scan all lines (excluding shift) - for (int i=0; i<8; i++) - { - UINT8 keyboard_line_data = ioport(keynames[i])->read(); - - // scan through each bit - for (int b=0; b<8; b++) - { - // is pressed? - if ((keyboard_line_data & (1<<b)) != 0) - { - // generate fake code - UINT8 code = (i<<3) | b; - LOG(("Code: %02x\n",code)); - - transmit_scancode(code); - } - } - } - } - break; - } -} - - -//------------------------------------------------- -// add a pulse -//------------------------------------------------- - -void kc_keyboard_device::add_pulse_to_transmit_buffer(int pulse_state, int pulse_number) -{ - if (m_transmit_buffer.pulse_count + 1 < KC_TRANSMIT_BUFFER_LENGTH) - { - for (int i=0; i<pulse_number; i++) - { - int pulse_byte_count = m_transmit_buffer.pulse_count>>3; - int pulse_bit_count = 7-(m_transmit_buffer.pulse_count & 0x07); - - if (pulse_state) - m_transmit_buffer.data[pulse_byte_count] |= (1<<pulse_bit_count); - else - m_transmit_buffer.data[pulse_byte_count] &= ~(1<<pulse_bit_count); - - m_transmit_buffer.pulse_count++; - } - } -} - -//------------------------------------------------- -// fill transmit buffer with pulse for 0 or 1 bit -//------------------------------------------------- - -void kc_keyboard_device::add_bit(int bit) -{ - if (bit) - add_pulse_to_transmit_buffer(0, 7); - else - add_pulse_to_transmit_buffer(0, 5); - - // "end of bit" pulse -> end of time for bit - add_pulse_to_transmit_buffer(1); -} - - -//------------------------------------------------- -// begin pulse transmit -//------------------------------------------------- - -void kc_keyboard_device::transmit_scancode(UINT8 scan_code) -{ - // initial pulse -> start of code - add_pulse_to_transmit_buffer(1); - - // state of shift key - add_bit((ioport("SHIFT")->read() & 0x01)^0x01); - - for (int i=0; i<6; i++) - { - // each bit in turn - add_bit(scan_code & (1<<i)); - } - - // signal end of scan-code - add_pulse_to_transmit_buffer(0, 14); - - add_pulse_to_transmit_buffer(1); - - // back to original state - add_pulse_to_transmit_buffer(0); -} |