summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2013-12-25 04:18:47 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2013-12-25 04:18:47 +0000
commit9c03593b09938be83736b9ee26cb5b2323e68e6b (patch)
tree290eb2fae1b2ee08c61a0dde9eba435efe3e2bae /src
parentb92f94d643573565c66fb602ad5de87faa13b60a (diff)
(MESS) DEC Rainbow updates: [M. Burke, R. Belmont]
- LK201 keyboard matrix hooked up and working - LK201 serial I/O first pass (nw part) diserial is currently misframing the input bits so the LK201 doesn't get the proper commands from the Rainbow. If someone with experience in this area is bored, I won't be able to look at this again for about a week. The LK201 also needs a devcb2 hookup for the send back to the system once things are resolved.
Diffstat (limited to 'src')
-rw-r--r--src/mess/drivers/rainbow.c3
-rw-r--r--src/mess/machine/dec_lk201.c465
-rw-r--r--src/mess/machine/dec_lk201.h47
3 files changed, 462 insertions, 53 deletions
diff --git a/src/mess/drivers/rainbow.c b/src/mess/drivers/rainbow.c
index c93ad4eff9e..f675364062b 100644
--- a/src/mess/drivers/rainbow.c
+++ b/src/mess/drivers/rainbow.c
@@ -1134,6 +1134,7 @@ void rainbow_state::update_kbd_irq()
WRITE_LINE_MEMBER(rainbow_state::kbd_tx)
{
// printf("%02x to keyboard\n", state);
+ m_lk201->rx_w(state);
}
WRITE_LINE_MEMBER(rainbow_state::kbd_rxready_w)
@@ -1277,7 +1278,7 @@ static MACHINE_CONFIG_START( rainbow, rainbow_state )
MCFG_SOFTWARE_LIST_ADD("flop_list","rainbow")
MCFG_I8251_ADD("kbdser", i8251_intf)
- MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard", rainbow_state, keyboard_tick, attotime::from_hz(4800))
+ MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard", rainbow_state, keyboard_tick, attotime::from_hz(4800*16)) // 8251 is set to /16 on the clock input
MCFG_LK201_ADD()
MCFG_NVRAM_ADD_0FILL("nvram")
diff --git a/src/mess/machine/dec_lk201.c b/src/mess/machine/dec_lk201.c
index 1aa7749cd01..4aff8f347db 100644
--- a/src/mess/machine/dec_lk201.c
+++ b/src/mess/machine/dec_lk201.c
@@ -1,6 +1,6 @@
/*
DEC LK-201 keyboard
- Emulation by R. Belmont
+ Emulation by R. Belmont & M. Burke
This is the later "cost-reduced" 6805 version; there's also an 8048 version.
*/
@@ -108,7 +108,65 @@ ________|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0
// MACROS / CONSTANTS
//**************************************************************************
-#define LK201_CPU_TAG "lk201"
+#define LK201_CPU_TAG "lk201_cpu"
+#define LK201_SPK_TAG "beeper"
+
+//-------------------------------------------------
+// SERIAL COMMUNICATIONS INTERFACE
+//-------------------------------------------------
+
+#define SCI_BAUD 0 // Baud rate register
+#define BAUD_SCR 0x07 // SCI baud rate select
+#define BAUD_SCP 0x30 // SCI prescaler select
+
+#define SCI_SCCR1 1 // Control register 1
+#define SCCR1_WAKE 0x08 // Wakeup method
+#define SCCR1_M 0x10 // Character length
+#define SCCR1_T8 0x40 // Transmit bit 8
+#define SCCR1_R8 0x80 // Receive bit 8
+
+#define SCI_SCCR2 2 // Control register 2
+#define SCCR2_SBK 0x01 // Send break
+#define SCCR2_RWU 0x02 // Receiver wakeup enable
+#define SCCR2_RE 0x04 // Receiver enable
+#define SCCR2_TE 0x08 // Transmitter enable
+#define SCCR2_ILIE 0x10 // Idle line interrupt enable
+#define SCCR2_RIE 0x20 // Receiver interrupt enable
+#define SCCR2_TCIE 0x40 // Transmit complete interrupt enable
+#define SCCR2_TIE 0x80 // Transmit interrupt enable
+
+#define SCI_SCSR 3 // Status register
+#define SCSR_FE 0x02 // Receiver framing error
+#define SCSR_NF 0x04 // Receiver noise
+#define SCSR_OR 0x08 // Receiver overrun
+#define SCSR_IDLE 0x10 // Receiver idle
+#define SCSR_RDRF 0x20 // Receive data register full
+#define SCSR_TC 0x40 // Transmit complete
+#define SCSR_TDRE 0x80 // Transmit data register empty
+#define SCSR_INT (SCSR_IDLE | SCSR_RDRF| \
+ SCSR_TC | SCSR_TDRE) // Interrupt sources
+
+#define SCI_SCDR 4 // Data register
+
+//-------------------------------------------------
+// SERIAL PERIPHERAL INTERFACE
+//-------------------------------------------------
+
+#define SPI_SPCR 0 // Control register
+#define SPCR_SPR 0x03 // SPI clock rate select
+#define SPCR_CPHA 0x04 // Clock phase
+#define SPCR_CPOL 0x08 // Clock polarity
+#define SPCR_MSTR 0x10 // Master mode select
+#define SPCR_DWOM 0x20 // Port D wire-or mode option
+#define SPCR_SPE 0x40 // Serial peripheral system enable
+#define SPCR_SPIE 0x80 // Serial peripheral interrupt enable
+
+#define SPI_SPSR 1 // Status register
+#define SPSR_MODF 0x10 // Mode fault flag
+#define SPSR_WCOL 0x40 // Write collision
+#define SPSR_SPIF 0x80 // SPI transfer complete
+
+#define SPI_SPDR 2 // Data I/O Register
//**************************************************************************
// DEVICE DEFINITIONS
@@ -141,6 +199,10 @@ ADDRESS_MAP_END
static MACHINE_CONFIG_FRAGMENT( lk201 )
MCFG_CPU_ADD(LK201_CPU_TAG, M68HC05EG, 2000000) // actually 68HC05C4
MCFG_CPU_PROGRAM_MAP(lk201_map)
+
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD(LK201_SPK_TAG, BEEP, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
MACHINE_CONFIG_END
@@ -159,6 +221,202 @@ const rom_entry *lk201_device::device_rom_region() const
return ROM_NAME( lk201 );
}
+//-------------------------------------------------
+// INPUT_PORTS( lk201 )
+//-------------------------------------------------
+
+INPUT_PORTS_START( lk201 )
+ PORT_START("KBD0")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT)
+
+ PORT_START("KBD1")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Compose") PORT_CODE(KEYCODE_LALT)
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_CAPSLOCK)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL)
+
+ PORT_START("KBD2")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Z") PORT_CODE(KEYCODE_Z)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("A") PORT_CODE(KEYCODE_A)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Q") PORT_CODE(KEYCODE_Q)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1") PORT_CODE(KEYCODE_1)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Esc") PORT_CODE(KEYCODE_TILDE)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("KBD3")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("<")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("X") PORT_CODE(KEYCODE_X)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("S") PORT_CODE(KEYCODE_S)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("W") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Z") PORT_CODE(KEYCODE_2)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Hold Screen") PORT_CODE(KEYCODE_F1)
+
+ PORT_START("KBD4")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("C") PORT_CODE(KEYCODE_C)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("D") PORT_CODE(KEYCODE_D)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("E") PORT_CODE(KEYCODE_E)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3") PORT_CODE(KEYCODE_3)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Setup") PORT_CODE(KEYCODE_F3)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Print Screen") PORT_CODE(KEYCODE_F2)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("KBD5")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("V") PORT_CODE(KEYCODE_V)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F") PORT_CODE(KEYCODE_F)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("R") PORT_CODE(KEYCODE_R)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4") PORT_CODE(KEYCODE_4)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Break") PORT_CODE(KEYCODE_F5)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4)
+
+ PORT_START("KBD6")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("B") PORT_CODE(KEYCODE_B)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("G") PORT_CODE(KEYCODE_G)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("T") PORT_CODE(KEYCODE_T)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5") PORT_CODE(KEYCODE_5)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Interrupt") PORT_CODE(KEYCODE_F6)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("KBD7")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("N") PORT_CODE(KEYCODE_N)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("H") PORT_CODE(KEYCODE_H)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Y") PORT_CODE(KEYCODE_Y)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6") PORT_CODE(KEYCODE_6)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Resume") PORT_CODE(KEYCODE_F7)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Cancel") PORT_CODE(KEYCODE_F8)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("KBD8")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("M") PORT_CODE(KEYCODE_M)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("J") PORT_CODE(KEYCODE_J)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("U") PORT_CODE(KEYCODE_U)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7") PORT_CODE(KEYCODE_7)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Exit") PORT_CODE(KEYCODE_F10)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Main Screen") PORT_CODE(KEYCODE_F9)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("KBD9")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("K") PORT_CODE(KEYCODE_K)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("I") PORT_CODE(KEYCODE_I)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8") PORT_CODE(KEYCODE_8)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F11") PORT_CODE(KEYCODE_F11)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("KBD10")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(".") PORT_CODE(KEYCODE_STOP)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("L") PORT_CODE(KEYCODE_L)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("O") PORT_CODE(KEYCODE_O)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9") PORT_CODE(KEYCODE_9)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F13")
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F12") PORT_CODE(KEYCODE_F12)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("KBD11")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(";")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) // FIXME - duplicate "Return"
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("P") PORT_CODE(KEYCODE_P)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0") PORT_CODE(KEYCODE_0)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Delete") PORT_CODE(KEYCODE_BACKSPACE)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Additional Options")
+
+ PORT_START("KBD12")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Select") PORT_CODE(KEYCODE_DEL)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Help")
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("=") PORT_CODE(KEYCODE_EQUALS)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Find") PORT_CODE(KEYCODE_INSERT)
+
+ PORT_START("KBD13")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("'") PORT_CODE(KEYCODE_QUOTE)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Previous") PORT_CODE(KEYCODE_END)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS)
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD )
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Insert Here") PORT_CODE(KEYCODE_HOME)
+
+ PORT_START("KBD14")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 0") PORT_CODE(KEYCODE_0_PAD)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 1") PORT_CODE(KEYCODE_1_PAD)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 4") PORT_CODE(KEYCODE_4_PAD)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 7") PORT_CODE(KEYCODE_7_PAD)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Up") PORT_CODE(KEYCODE_UP)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Remove") PORT_CODE(KEYCODE_PGUP)
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Next") PORT_CODE(KEYCODE_PGDN)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF1") PORT_CODE(KEYCODE_NUMLOCK)
+
+ PORT_START("KBD15")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) // FIXME - duplicate "Num 0"
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 2") PORT_CODE(KEYCODE_2_PAD)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 5") PORT_CODE(KEYCODE_5_PAD)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 8") PORT_CODE(KEYCODE_8_PAD)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF2") PORT_CODE(KEYCODE_SLASH_PAD)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F17")
+
+ PORT_START("KBD16")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 3") PORT_CODE(KEYCODE_3_PAD)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 6") PORT_CODE(KEYCODE_6_PAD)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 9") PORT_CODE(KEYCODE_9_PAD)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF3") PORT_CODE(KEYCODE_ASTERISK)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F18")
+
+ PORT_START("KBD17")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER_PAD)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num ,") PORT_CODE(KEYCODE_PLUS_PAD)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num -")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF4") PORT_CODE(KEYCODE_MINUS_PAD)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F20")
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F19")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor lk201_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( lk201 );
+}
+
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
@@ -169,7 +427,27 @@ const rom_entry *lk201_device::device_rom_region() const
lk201_device::lk201_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, LK201, "DEC LK201 keyboard", tag, owner, clock, "lk201", __FILE__),
- m_maincpu(*this, LK201_CPU_TAG)
+ device_serial_interface(mconfig, *this),
+ m_maincpu(*this, LK201_CPU_TAG),
+ m_speaker(*this, LK201_SPK_TAG),
+ m_kbd0(*this, "KBD0"),
+ m_kbd1(*this, "KBD1"),
+ m_kbd2(*this, "KBD2"),
+ m_kbd3(*this, "KBD3"),
+ m_kbd4(*this, "KBD4"),
+ m_kbd5(*this, "KBD5"),
+ m_kbd6(*this, "KBD6"),
+ m_kbd7(*this, "KBD7"),
+ m_kbd8(*this, "KBD8"),
+ m_kbd9(*this, "KBD9"),
+ m_kbd10(*this, "KBD10"),
+ m_kbd11(*this, "KBD11"),
+ m_kbd12(*this, "KBD12"),
+ m_kbd13(*this, "KBD13"),
+ m_kbd14(*this, "KBD14"),
+ m_kbd15(*this, "KBD15"),
+ m_kbd16(*this, "KBD16"),
+ m_kbd17(*this, "KBD17")
{
}
@@ -188,6 +466,59 @@ void lk201_device::device_start()
void lk201_device::device_reset()
{
+ set_rate(4800);
+ set_data_frame(8, 1, PARITY_NONE, false);
+
+ sci_status = (SCSR_TC | SCSR_TDRE);
+
+ spi_status = 0;
+ spi_data = 0;
+
+ kbd_data = 0;
+ led_data = 0;
+
+ transmit_register_reset();
+ receive_register_reset();
+}
+
+void lk201_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ device_serial_interface::device_timer(timer, id, param, ptr);
+}
+
+void lk201_device::rcv_complete()
+{
+ printf("lk201 got %02x\n", get_received_char());
+ sci_status |= SCSR_RDRF;
+ update_interrupts();
+ receive_register_extract();
+}
+
+void lk201_device::tra_complete()
+{
+ sci_status |= (SCSR_TC | SCSR_TDRE);
+ update_interrupts();
+}
+
+void lk201_device::tra_callback()
+{
+ transmit_register_send_bit();
+}
+
+void lk201_device::input_callback(UINT8 state)
+{
+}
+
+void lk201_device::update_interrupts()
+{
+ if (sci_ctl2 & sci_status & SCSR_INT)
+ {
+ m_maincpu->set_input_line(M68HC05EG_INT_CPI, 1);
+ }
+ else
+ {
+ m_maincpu->set_input_line(M68HC05EG_INT_CPI, 0);
+ }
}
READ8_MEMBER( lk201_device::ddr_r )
@@ -197,7 +528,7 @@ READ8_MEMBER( lk201_device::ddr_r )
WRITE8_MEMBER( lk201_device::ddr_w )
{
-// printf("%02x to PORT %c DDR (PC=%x)\n", data, 'A' + offset, m_maincpu->pc());
+// printf("%02x to PORT %c DDR (PC=%x)\n", data, 'A' + offset, m_maincpu->pc());
send_port(space, offset, ports[offset] & data);
@@ -208,24 +539,12 @@ READ8_MEMBER( lk201_device::ports_r )
{
UINT8 incoming = 0;
- switch (offset)
- {
- case 0: // port A
- break;
-
- case 1: // port B
- break;
-
- case 2: // port C
- break;
- }
-
// apply data direction registers
incoming &= (ddrs[offset] ^ 0xff);
// add in ddr-masked version of port writes
incoming |= (ports[offset] & ddrs[offset]);
-// printf("PORT %c read = %02x (DDR = %02x latch = %02x) (PC=%x)\n", 'A' + offset, ports[offset], ddrs[offset], ports[offset], m_maincpu->pc());
+// printf("PORT %c read = %02x (DDR = %02x latch = %02x) (PC=%x)\n", 'A' + offset, ports[offset], ddrs[offset], ports[offset], m_maincpu->pc());
return incoming;
}
@@ -239,7 +558,7 @@ WRITE8_MEMBER( lk201_device::ports_w )
void lk201_device::send_port(address_space &space, UINT8 offset, UINT8 data)
{
-// printf("PORT %c write %02x (DDR = %02x) (PC=%x)\n", 'A' + offset, data, ddrs[offset], m_maincpu->pc());
+// printf("PORT %c write %02x (DDR = %02x) (PC=%x)\n", 'A' + offset, data, ddrs[offset], m_maincpu->pc());
switch (offset)
{
@@ -250,6 +569,37 @@ void lk201_device::send_port(address_space &space, UINT8 offset, UINT8 data)
break;
case 2: // port C
+ // Check for keyboard read strobe
+ if (((data & 0x40) == 0) && (ports[offset] & 0x40))
+ {
+ if (ports[0] & 0x1) kbd_data = m_kbd0->read();
+ if (ports[0] & 0x2) kbd_data = m_kbd1->read();
+ if (ports[0] & 0x4) kbd_data = m_kbd2->read();
+ if (ports[0] & 0x8) kbd_data = m_kbd3->read();
+ if (ports[0] & 0x10) kbd_data = m_kbd4->read();
+ if (ports[0] & 0x20) kbd_data = m_kbd5->read();
+ if (ports[0] & 0x40) kbd_data = m_kbd6->read();
+ if (ports[0] & 0x80) kbd_data = m_kbd7->read();
+ if (ports[1] & 0x1) kbd_data = m_kbd8->read();
+ if (ports[1] & 0x2) kbd_data = m_kbd9->read();
+ if (ports[1] & 0x4) kbd_data = m_kbd10->read();
+ if (ports[1] & 0x8) kbd_data = m_kbd11->read();
+ if (ports[1] & 0x10) kbd_data = m_kbd12->read();
+ if (ports[1] & 0x20) kbd_data = m_kbd13->read();
+ if (ports[1] & 0x40) kbd_data = m_kbd14->read();
+ if (ports[1] & 0x80) kbd_data = m_kbd15->read();
+ if (ports[2] & 0x1) kbd_data = m_kbd16->read();
+ if (ports[2] & 0x2) kbd_data = m_kbd17->read();
+ }
+ // Check for LED update strobe
+ if (((data & 0x80) == 0) && (ports[offset] & 0x80))
+ {
+ // Lower nibble contains the LED values (1 = on, 0 = off)
+ output_set_value("led_wait", (led_data & 0x1) == 0);
+ output_set_value("led_comp", (led_data & 0x2) == 0);
+ output_set_value("led_hold", (led_data & 0x4) == 0);
+ output_set_value("led_lock", (led_data & 0x8) == 0);
+ }
break;
}
}
@@ -260,24 +610,29 @@ READ8_MEMBER( lk201_device::sci_r )
switch (offset)
{
- case 0: // baud rate
+ case SCI_BAUD: // Baud rate
break;
- case 1: // control 1
+ case SCI_SCCR1: // Control 1
break;
- case 2: // control 2
+ case SCI_SCCR2: // Control 2
+ incoming = sci_ctl2;
break;
- case 3: // status
- incoming |= 0x40; // indicate transmit ready
+ case SCI_SCSR: // Status
+ incoming = sci_status;
break;
- case 4: // data
+ case SCI_SCDR: // Data
+ incoming = get_received_char();
+ sci_status &= ~SCSR_RDRF;
+ m_maincpu->set_input_line(M68HC05EG_INT_CPI, 0);
+ update_interrupts();
break;
}
-// printf("SCI read @ %x = %02x (PC=%x)\n", offset, incoming, m_maincpu->pc());
+// printf("SCI read @ %x = %02x (PC=%x)\n", offset, incoming, m_maincpu->pc());
return incoming;
}
@@ -286,23 +641,29 @@ WRITE8_MEMBER( lk201_device::sci_w )
{
switch (offset)
{
- case 0: // baud rate
+ case SCI_BAUD: // Baud rate
break;
- case 1: // control 1
+ case SCI_SCCR1: // Control 1
break;
- case 2: // control 2
+ case SCI_SCCR2: // Control 2
+ sci_ctl2 = data;
+ update_interrupts();
break;
- case 3: // status
+ case SCI_SCSR: // Status
break;
- case 4: // data
+ case SCI_SCDR: // Data
+ transmit_register_setup(data);
+ sci_status &= ~(SCSR_TC | SCSR_TDRE);
+ m_maincpu->set_input_line(M68HC05EG_INT_CPI, 0);
+ update_interrupts();
break;
}
-// printf("SCI %02x to %x (PC=%x)\n", data, offset, m_maincpu->pc());
+// printf("SCI %02x to %x (PC=%x)\n", data, offset, m_maincpu->pc());
}
READ8_MEMBER( lk201_device::spi_r )
@@ -311,18 +672,20 @@ READ8_MEMBER( lk201_device::spi_r )
switch (offset)
{
- case 0: // control
+ case SPI_SPCR: // Control
break;
- case 1: // status
- incoming |= 0x80;
+ case SPI_SPSR: // Status
+ incoming = spi_status;
+ spi_status &= ~SPSR_SPIF;
break;
- case 2: // data
+ case SPI_SPDR: // Data I/O
+ incoming = spi_data;
break;
}
-// printf("SPI read @ %x = %02x (PC=%x)\n", offset, incoming, m_maincpu->pc());
+// printf("SPI read @ %x = %02x (PC=%x)\n", offset, incoming, m_maincpu->pc());
return incoming;
}
@@ -331,24 +694,30 @@ WRITE8_MEMBER( lk201_device::spi_w )
{
switch (offset)
{
- case 0: // control
+ case SPI_SPCR: // Control
break;
- case 1: // status
+ case SPI_SPSR: // Status (read only)
break;
- case 2: // data
+ case SPI_SPDR: // Data I/O
+ spi_data = data;
+
+ // Transfer only allowed if transfer complete flag has been acknowleged
+ if ((spi_status & SPSR_SPIF) == 0)
+ {
+ // Data out
+ led_data = data;
+
+ // Data in
+ spi_data = kbd_data;
+
+ // Indicate transfer complete
+ spi_status |= SPSR_SPIF;
+ }
break;
}
-// printf("SPI %02x to %x (PC=%x)\n", data, offset, m_maincpu->pc());
+// printf("SPI %02x to %x (PC=%x)\n", data, offset, m_maincpu->pc());
}
-/*
-
-SCI 01 to 4 (PC=24b) firmware ID
-SCI 00 to 4 (PC=cb2) hardware jumpers ID (port C & 0x30)
-SCI 00 to 4 (PC=cb2) self-test result OK
-SCI 00 to 4 (PC=cb2) keycode if there was a self-test error
-
-*/
diff --git a/src/mess/machine/dec_lk201.h b/src/mess/machine/dec_lk201.h
index 96f1c187cd8..fb3151d9c8e 100644
--- a/src/mess/machine/dec_lk201.h
+++ b/src/mess/machine/dec_lk201.h
@@ -4,6 +4,7 @@
#define __LK201_H__
#include "emu.h"
+#include "sound/beep.h"
//**************************************************************************
// MACROS / CONSTANTS
@@ -44,7 +45,7 @@
// ======================> lk201_device
-class lk201_device : public device_t
+class lk201_device : public device_t, public device_serial_interface
{
public:
// construction/destruction
@@ -61,18 +62,56 @@ public:
protected:
// device-level overrides
- virtual void device_start();
- virtual void device_reset();
virtual machine_config_constructor device_mconfig_additions() const;
virtual const rom_entry *device_rom_region() const;
+ virtual ioport_constructor device_input_ports() const;
+ virtual void device_start();
+ virtual void device_reset();
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
- required_device<cpu_device> m_maincpu;
+ // device_serial overrides
+ virtual void rcv_complete(); // Rx completed receiving byte
+ virtual void tra_complete(); // Tx completed sending byte
+ virtual void tra_callback(); // Tx send bit
+ void input_callback(UINT8 state);
private:
UINT8 ddrs[3];
UINT8 ports[3];
+ UINT8 led_data;
+ UINT8 kbd_data;
+
+ UINT8 sci_ctl2;
+ UINT8 sci_status;
+ UINT8 sci_data;
+
+ UINT8 spi_status;
+ UINT8 spi_data;
+
+ required_device<cpu_device> m_maincpu;
+ required_device<beep_device> m_speaker;
+
+ required_ioport m_kbd0;
+ required_ioport m_kbd1;
+ required_ioport m_kbd2;
+ required_ioport m_kbd3;
+ required_ioport m_kbd4;
+ required_ioport m_kbd5;
+ required_ioport m_kbd6;
+ required_ioport m_kbd7;
+ required_ioport m_kbd8;
+ required_ioport m_kbd9;
+ required_ioport m_kbd10;
+ required_ioport m_kbd11;
+ required_ioport m_kbd12;
+ required_ioport m_kbd13;
+ required_ioport m_kbd14;
+ required_ioport m_kbd15;
+ required_ioport m_kbd16;
+ required_ioport m_kbd17;
void send_port(address_space &space, UINT8 offset, UINT8 data);
+ void update_interrupts();
};
// device type definition