summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/kc_keyb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/machine/kc_keyb.c')
-rw-r--r--src/mess/machine/kc_keyb.c614
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);
-}