summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/dec_lk201.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/machine/dec_lk201.c')
-rw-r--r--src/mess/machine/dec_lk201.c465
1 files changed, 417 insertions, 48 deletions
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
-
-*/