New machines added as WORKING

New machines added as WORKING
---
Motorola EXORterm 155 [68bit]
This commit is contained in:
68bit 2020-07-11 05:41:52 +10:00 committed by GitHub
parent 47e32437cd
commit 5972474a21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1358 additions and 0 deletions

View File

@ -2528,6 +2528,8 @@ if (BUSES["RS232"]~=null) then
MAME_DIR .. "src/devices/bus/rs232/ie15.h",
MAME_DIR .. "src/devices/bus/rs232/swtpc8212.cpp",
MAME_DIR .. "src/devices/bus/rs232/swtpc8212.h",
MAME_DIR .. "src/devices/bus/rs232/exorterm.cpp",
MAME_DIR .. "src/devices/bus/rs232/exorterm.h",
}
end

View File

@ -1239,6 +1239,26 @@ if (MACHINES["ER2055"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/machine/exorterm.h,MACHINES["EXORTERM"] = true
---------------------------------------------------
if (MACHINES["EXORTERM"]~=null) then
files {
MAME_DIR .. "src/devices/machine/exorterm.cpp",
MAME_DIR .. "src/devices/machine/exorterm.h",
}
dependency {
{ MAME_DIR .. "src/devices/machine/exorterm.cpp", GEN_DIR .. "emu/layout/exorterm155.lh" },
}
custombuildtask {
layoutbuildtask("emu/layout", "exorterm155"),
}
end
---------------------------------------------------
--
--@src/devices/machine/f3853.h,MACHINES["F3853"] = true

View File

@ -497,6 +497,7 @@ MACHINES["E05A30"] = true
MACHINES["EEPROMDEV"] = true
MACHINES["ER1400"] = true
MACHINES["ER2055"] = true
MACHINES["EXORTERM"] = true
MACHINES["F3853"] = true
MACHINES["HD63450"] = true
MACHINES["HD64610"] = true
@ -1185,6 +1186,7 @@ function linkProjects_mame_mess(_target, _subtarget)
"epson",
"ericsson",
"exidy",
"exorterm",
"fairch",
"fairlight",
"fidelity",
@ -2319,6 +2321,11 @@ files {
MAME_DIR .. "src/mame/machine/micropolis.h",
}
createMESSProjects(_target, _subtarget, "exorterm")
files {
MAME_DIR .. "src/mame/drivers/exorterm.cpp",
}
createMESSProjects(_target, _subtarget, "fairch")
files {
MAME_DIR .. "src/mame/drivers/channelf.cpp",

View File

@ -0,0 +1,87 @@
// license:BSD-3-Clause
// copyright-holders:68bit
#include "emu.h"
#include "exorterm.h"
exorterm155_terminal_device::exorterm155_terminal_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, SERIAL_TERMINAL_EXORTERM155, tag, owner, clock)
, device_rs232_port_interface(mconfig, *this)
, m_exorterm155(*this, "exorterm155")
, m_flow_control(*this, "FLOW_CONTROL")
{
}
void exorterm155_terminal_device::device_add_mconfig(machine_config &config)
{
EXORTERM155(config, m_exorterm155, 0);
m_exorterm155->rs232_conn_txd_handler().set(FUNC(exorterm155_terminal_device::output_rxd));
m_exorterm155->rs232_conn_rts_handler().set(FUNC(exorterm155_terminal_device::route_term_rts));
m_exorterm155->rs232_conn_dtr_handler().set(FUNC(exorterm155_terminal_device::route_term_dtr));
}
INPUT_PORTS_START(exorterm155_terminal)
PORT_START("FLOW_CONTROL")
PORT_CONFNAME(0x1, 1, "Flow Control") PORT_CHANGED_MEMBER(DEVICE_SELF, exorterm155_terminal_device, flow_control, 0)
PORT_CONFSETTING(0x00, "None")
PORT_CONFSETTING(0x01, "Terminal DTR to remote CTS")
INPUT_PORTS_END
ioport_constructor exorterm155_terminal_device::device_input_ports() const
{
return INPUT_PORTS_NAME(exorterm155_terminal);
}
WRITE_LINE_MEMBER(exorterm155_terminal_device::input_txd)
{
m_exorterm155->rs232_conn_rxd_w(state);
}
WRITE_LINE_MEMBER(exorterm155_terminal_device::route_term_rts)
{
// Loop the terminal RTS output to the terminal CTS input.
m_exorterm155->rs232_conn_cts_w(state);
}
// This terminal uses DTR for hardware flow control.
WRITE_LINE_MEMBER(exorterm155_terminal_device::route_term_dtr)
{
if (m_flow_control->read())
{
// Connect the terminal DTR output to CTS at the other end.
output_cts(state);
}
// Cache the state, in case the ioport setting changes.
m_dtr = state;
}
INPUT_CHANGED_MEMBER(exorterm155_terminal_device::flow_control)
{
if (newval)
output_cts(m_dtr);
else
output_cts(0);
}
void exorterm155_terminal_device::device_start()
{
save_item(NAME(m_dtr));
}
void exorterm155_terminal_device::device_reset()
{
// To the terminal
m_exorterm155->rs232_conn_cts_w(0);
// To the computer
output_rxd(1);
output_dcd(0);
output_dsr(0);
if (!m_flow_control->read())
output_cts(0);
}
DEFINE_DEVICE_TYPE(SERIAL_TERMINAL_EXORTERM155, exorterm155_terminal_device, "exorterm155_terminal", "EXORterm 155 Terminal")

View File

@ -0,0 +1,40 @@
// license:BSD-3-Clause
// copyright-holders:68bit
#ifndef MAME_BUS_RS232_EXORTERM_H
#define MAME_BUS_RS232_EXORTERM_H
#pragma once
#include "rs232.h"
#include "machine/exorterm.h"
class exorterm155_terminal_device : public device_t, public device_rs232_port_interface
{
public:
exorterm155_terminal_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual DECLARE_WRITE_LINE_MEMBER(input_txd) override;
DECLARE_INPUT_CHANGED_MEMBER(flow_control);
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
private:
required_device<exorterm155_device> m_exorterm155;
required_ioport m_flow_control;
DECLARE_WRITE_LINE_MEMBER(route_term_rts);
DECLARE_WRITE_LINE_MEMBER(route_term_dtr);
int m_dtr;
};
DECLARE_DEVICE_TYPE(SERIAL_TERMINAL_EXORTERM155, exorterm155_terminal_device)
#endif // MAME_BUS_RS232_EXORTERM_H

View File

@ -0,0 +1,906 @@
// license:BSD-3-Clause
// copyright-holders: 68bit
/****************************************************************************
Motorola EXORterm 155 (M68SDS)
The terminfo database has an entry for this terminal named 'ex155'.
TODO
- Keyboard layout. All the codes appear to have been implemented following
the manual but have not been checked with hardware. The key repetition
rate and delay need to be checked.
- Video character ROM needs dumping. An apparently close Motorola published
7x9 character set has been substituted for now, but three of the codes
(0x1a, 0x1b, and 0x1c) do not match the characters listed in the manual.
****************************************************************************/
#include "emu.h"
#include "machine/exorterm.h"
#include "speaker.h"
#include "exorterm155.lh"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
exorterm155_device::exorterm155_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, type, tag, owner, clock)
, m_maincpu(*this, "maincpu")
, m_irqs(*this, "irqs")
, m_acia(*this, "acia")
, m_brg(*this, "brg")
, m_rs232_baud(*this, "RS232_BAUD")
, m_disable_fac(*this, "DISABLE_FAC")
, m_display_fac(*this, "DISPLAY_FAC")
, m_pia_kbd(*this, "pia_kbd")
, m_pia_cfg(*this, "pia_cfg")
, m_pia_disp(*this, "pia_disp")
, m_screen(*this, "screen")
, m_palette(*this, "palette")
, m_sys_timer_clock(*this, "sys_timer_clock")
, m_vram(*this, "videoram")
, m_chargen(*this, "chargen")
, m_beeper(*this, "beeper")
, m_online_led(*this, "online_led")
, m_auto_lf_led(*this, "auto_lf_led")
, m_page_mode_led(*this, "page_mode_led")
, m_insert_char_led(*this, "insert_char_led")
, m_rs232_conn_txd_handler(*this)
, m_rs232_conn_dtr_handler(*this)
, m_rs232_conn_rts_handler(*this)
// Keyboard
, m_kbd_scan_timer(nullptr)
, m_kbd_repeat_timer(nullptr)
, m_kbd_modifiers(*this, "KBD_MOD")
, m_kbd_rows(*this, "KBD_ROW%u", 0)
, m_kbd_next_row(0)
, m_kbd_processing(0)
, m_kbd_repeat_row(0)
, m_kbd_repeat_column(0)
, m_kbd_last_modifiers(0)
{
}
exorterm155_device::exorterm155_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: exorterm155_device(mconfig, EXORTERM155, tag, owner, clock)
{
}
//**************************************************************************
// ADDRESS MAPS
//**************************************************************************
void exorterm155_device::mem_map(address_map &map)
{
// 2 x 1Kx4 static RAM.
map(0x0000, 0x03ff).ram(); // Scratch RAM
map(0xa000, 0xa7ff).rom(); // U89 68K edit mode
//map(0xa800, 0xafff).rom(); // U70 (reserved)
//map(0xb000, 0xb7ff).rom(); // U59 (reserved)
map(0xc000, 0xc7ff).rom(); // U49 Extended display
map(0xc800, 0xcfff).rom(); // U104 Basic display #1
map(0xd000, 0xd7ff).rom(); // U98 Basic display #2
// Appears to mirror to ff00-ffff for the reset vectors.
map(0xd800, 0xdfff).rom().mirror(0x2000); // U78 Terminal control
// 4 x 1Kx4 static RAM.
map(0xe000, 0xe7ff).ram().share(m_vram);
map(0xef00, 0xef01).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write));
map(0xef04, 0xef07).rw(m_pia_kbd, FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0xef08, 0xef0b).rw(m_pia_cfg, FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0xef0c, 0xef0f).rw(m_pia_disp, FUNC(pia6821_device::read), FUNC(pia6821_device::write));
}
//**************************************************************************
// INPUT PORT DEFINITIONS
//**************************************************************************
INPUT_PORTS_START( exorterm155 )
PORT_START("DISABLE_FAC")
PORT_DIPNAME(0x01, 0x01, "Disable FAC codes") PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING(0x00, "On")
PORT_DIPSETTING(0x01, "Off")
PORT_START("DISPLAY_FAC")
PORT_DIPNAME(0x01, 0x01, "Display FAC codes") PORT_DIPLOCATION("SW1:2")
PORT_DIPSETTING(0x00, "On")
PORT_DIPSETTING(0x01, "Off")
PORT_START("DIP_SWITCHES_A")
PORT_DIPNAME(0x01, 0x01, "Stop bits") PORT_DIPLOCATION("SW2:5")
PORT_DIPSETTING(0x00, "2")
PORT_DIPSETTING(0x01, "1")
PORT_DIPNAME(0x02, 0x02, "Duplex") PORT_DIPLOCATION("SW2:1")
PORT_DIPSETTING(0x00, "Half")
PORT_DIPSETTING(0x02, "Full")
PORT_DIPNAME(0x04, 0x04, "Parity") PORT_DIPLOCATION("SW2:2")
PORT_DIPSETTING(0x00, "Yes")
PORT_DIPSETTING(0x04, "No")
PORT_DIPNAME(0x08, 0x08, "Parity") PORT_DIPLOCATION("SW2:3")
PORT_DIPSETTING(0x00, "Odd")
PORT_DIPSETTING(0x08, "Even")
PORT_DIPNAME(0x10, 0x00, "Word size") PORT_DIPLOCATION("SW2:4")
PORT_DIPSETTING(0x00, "8-bit")
PORT_DIPSETTING(0x10, "7-bit")
PORT_DIPNAME(0x20, 0x00, "Connection") PORT_DIPLOCATION("SW2:6")
PORT_DIPSETTING(0x00, "Direct")
PORT_DIPSETTING(0x20, "Modem")
PORT_DIPNAME(0x40, 0x40, "Modem Type") PORT_DIPLOCATION("SW2:7")
PORT_DIPSETTING(0x00, "202")
PORT_DIPSETTING(0x40, "103")
PORT_DIPNAME(0x80, 0x80, "Turnaround") PORT_DIPLOCATION("SW2:8")
PORT_DIPSETTING(0x00, "Code")
PORT_DIPSETTING(0x80, "S-chan")
PORT_START("DIP_SWITCHES_B")
PORT_DIPNAME(0x01, 0x01, "Code") PORT_DIPLOCATION("SW2:9")
PORT_DIPSETTING(0x00, "ETX")
PORT_DIPSETTING(0x01, "EOT")
PORT_DIPNAME(0x02, 0x02, "Spare 1") PORT_DIPLOCATION("SW1:5")
PORT_DIPSETTING(0x00, "On")
PORT_DIPSETTING(0x02, "Off")
PORT_DIPNAME(0x04, 0x04, "Spare 2") PORT_DIPLOCATION("SW1:6")
PORT_DIPSETTING(0x00, "On")
PORT_DIPSETTING(0x04, "Off")
PORT_DIPNAME(0x08, 0x08, "Spare 3") PORT_DIPLOCATION("SW1:7")
PORT_DIPSETTING(0x00, "On")
PORT_DIPSETTING(0x08, "Off")
PORT_DIPNAME(0x10, 0x10, "Display special characters") PORT_DIPLOCATION("SW1:8")
PORT_DIPSETTING(0x00, "On")
PORT_DIPSETTING(0x10, "Off")
PORT_DIPNAME(0x40, 0x40, "Transparent mode") PORT_DIPLOCATION("SW1:3")
PORT_DIPSETTING(0x00, "On")
PORT_DIPSETTING(0x40, "Off")
PORT_DIPNAME(0x80, 0x80, "Video invert") PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING(0x00, "Invert")
PORT_DIPSETTING(0x80, "Normal")
PORT_START("RS232_BAUD")
PORT_DIPNAME(0x1ff, 0x01, "RS232 Baud Rate")
PORT_DIPSETTING(0x100, "110") PORT_DIPLOCATION("SW3:1,2,3,4,5,6,7,8,9")
PORT_DIPSETTING(0x080, "150") PORT_DIPLOCATION("SW3:1,2,3,4,5,6,7,8,9")
PORT_DIPSETTING(0x040, "300") PORT_DIPLOCATION("SW3:1,2,3,4,5,6,7,8,9")
PORT_DIPSETTING(0x020, "600") PORT_DIPLOCATION("SW3:1,2,3,4,5,6,7,8,9")
PORT_DIPSETTING(0x010, "1200") PORT_DIPLOCATION("SW3:1,2,3,4,5,6,7,8,9")
PORT_DIPSETTING(0x008, "1800") PORT_DIPLOCATION("SW3:1,2,3,4,5,6,7,8,9")
PORT_DIPSETTING(0x004, "2400") PORT_DIPLOCATION("SW3:1,2,3,4,5,6,7,8,9")
PORT_DIPSETTING(0x002, "4800") PORT_DIPLOCATION("SW3:1,2,3,4,5,6,7,8,9")
PORT_DIPSETTING(0x001, "9600") PORT_DIPLOCATION("SW3:1,2,3,4,5,6,7,8,9")
// Keyboard
PORT_START("KBD_MOD")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL))
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("All Caps") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK))
PORT_START("KBD_ROW0")
PORT_BIT( 0x00001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1))
PORT_BIT( 0x00002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2))
PORT_BIT( 0x00004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3))
PORT_BIT( 0x00008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4))
PORT_BIT( 0x00010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5))
PORT_BIT( 0x00020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6))
PORT_BIT( 0x00040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7))
PORT_BIT( 0x00080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8))
PORT_BIT( 0x00100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9))
PORT_BIT( 0x00200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10))
PORT_BIT( 0x00400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11))
PORT_BIT( 0x00800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12))
PORT_BIT( 0x01000, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x02000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH_PAD) PORT_NAME("Auto LF")
PORT_BIT( 0x04000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ASTERISK) PORT_NAME("Online")
PORT_BIT( 0x08000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("Page Mode")
PORT_BIT( 0x10000, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START("KBD_ROW1")
PORT_BIT( 0x00001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
PORT_BIT( 0x00002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@')
PORT_BIT( 0x00004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
PORT_BIT( 0x00008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
PORT_BIT( 0x00010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
PORT_BIT( 0x00020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')
PORT_BIT( 0x00040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')
PORT_BIT( 0x00080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
PORT_BIT( 0x00100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
PORT_BIT( 0x00200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
PORT_BIT( 0x00400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~')
PORT_BIT( 0x00800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
PORT_BIT( 0x01000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
PORT_BIT( 0x02000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PAUSE) PORT_NAME("Break") PORT_CHAR(UCHAR_MAMEKEY(CANCEL))
PORT_BIT( 0x04000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_INSERT) PORT_NAME("Insert Character") PORT_CHAR(UCHAR_MAMEKEY(INSERT))
PORT_BIT( 0x08000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL) PORT_NAME("Delete Character") PORT_CHAR(UCHAR_MAMEKEY(DEL))
PORT_BIT( 0x10000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("Set Tabs")
PORT_START("KBD_ROW2")
PORT_BIT( 0x00001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_NAME("Escape") PORT_CHAR(UCHAR_MAMEKEY(ESC))
PORT_BIT( 0x00002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
PORT_BIT( 0x00004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
PORT_BIT( 0x00008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
PORT_BIT( 0x00010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
PORT_BIT( 0x00020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
PORT_BIT( 0x00040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
PORT_BIT( 0x00080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
PORT_BIT( 0x00100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
PORT_BIT( 0x00200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
PORT_BIT( 0x00400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
PORT_BIT( 0x00800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|')
PORT_BIT( 0x01000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_END) PORT_NAME("Linefeed")
PORT_BIT( 0x02000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Return") PORT_CHAR(0x0dU)
PORT_BIT( 0x04000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_NAME("Forward Tab") PORT_CHAR('\t')
PORT_BIT( 0x08000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Back Tab")
PORT_BIT( 0x10000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("Line Delete")
PORT_START("KBD_ROW3")
PORT_BIT( 0x00001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
PORT_BIT( 0x00002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
PORT_BIT( 0x00004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
PORT_BIT( 0x00008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
PORT_BIT( 0x00010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
PORT_BIT( 0x00020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
PORT_BIT( 0x00040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
PORT_BIT( 0x00080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
PORT_BIT( 0x00100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
PORT_BIT( 0x00200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')
PORT_BIT( 0x00400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"')
PORT_BIT( 0x00800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{')
PORT_BIT( 0x01000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')
PORT_BIT( 0x02000, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x04000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_NAME("Cursor Up") PORT_CHAR(UCHAR_MAMEKEY(UP))
PORT_BIT( 0x08000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Cursor Down") PORT_CHAR(UCHAR_MAMEKEY(DOWN))
PORT_BIT( 0x10000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Line Insert")
PORT_START("KBD_ROW4")
PORT_BIT( 0x00001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_HOME) PORT_NAME("Home / Clear")
PORT_BIT( 0x00002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
PORT_BIT( 0x00004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
PORT_BIT( 0x00008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
PORT_BIT( 0x00010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
PORT_BIT( 0x00020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
PORT_BIT( 0x00040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
PORT_BIT( 0x00080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
PORT_BIT( 0x00100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
PORT_BIT( 0x00200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
PORT_BIT( 0x00400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
PORT_BIT( 0x00800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Page Send / Line Send")
PORT_BIT( 0x01000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
PORT_BIT( 0x02000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("Backspace") PORT_CHAR(0x08U)
PORT_BIT( 0x04000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Cursor Left") PORT_CHAR(UCHAR_MAMEKEY(LEFT))
PORT_BIT( 0x08000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Cursor Right") PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
PORT_BIT( 0x10000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PGDN) PORT_NAME("Page Erase / Line Erase")
INPUT_PORTS_END
// PA0 to PA6 - Keyboard data.
u8 exorterm155_device::pia_kbd_pa_r()
{
u8 ret = m_term_data;
m_term_data = 0;
return ret;
}
u8 exorterm155_device::pia_kbd_pb_r()
{
// PB7 is a 'keyboard attached' signal, low when a keyboard is attached.
return 0x00;
}
void exorterm155_device::pia_kbd_pb_w(u8 data)
{
m_online_led = BIT(data, 0) ? 0 : 1;
m_auto_lf_led = BIT(data, 1) ? 0 : 1;
m_page_mode_led = BIT(data, 2) ? 0 : 1;
m_insert_char_led = BIT(data, 5) ? 0 : 1;
// Bit 3 is AUX ON, and bit 4 is AUX EN, but it is not clear
// if the firmware uses these?
}
WRITE_LINE_MEMBER(exorterm155_device::pia_cfg_cb2_w)
{
m_beeper->set_state(!state);
}
void exorterm155_device::pia_disp_pa_w(u8 data)
{
m_cursor_addr = (m_cursor_addr & 0x700) | data;
}
u8 exorterm155_device::pia_disp_pb_r()
{
u8 ret = 0;
if (m_dsr)
ret |= 0x20;
return ret;
}
void exorterm155_device::pia_disp_pb_w(u8 data)
{
m_cursor_addr = (m_cursor_addr & 0x0ff) | ((data & 0x7) << 8);
m_inv_video = BIT(data, 3);
m_special_char_disp = BIT(data, 4);
m_rs232_conn_dtr_handler(BIT(data, 7));
}
READ_LINE_MEMBER(exorterm155_device::pia_disp_ca2_r)
{
return m_ring;
}
//**************************************************************************
// VIDEO EMULATION
//**************************************************************************
u32 exorterm155_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
u16 sy = 0, ma = 0;
u8 disable_fac = m_disable_fac->read() == 0;
u8 display_fac = m_display_fac->read() == 0;
const rgb_t *palette = m_palette->palette()->entry_list_raw();
m_framecnt++;
for (u8 y = 0; y < 24; y++)
{
for (u8 ra = 0; ra < 12; ra++)
{
u32 *p = &bitmap.pix32(sy++);
// FAC codes are cleared on horizontal sync.
u8 underline1 = 0;
u8 underline2 = 0;
u8 non_display = 0;
u8 invert = 0;
u8 half_bright = 0;
u8 blink = 0;
for (u16 x = ma; x < ma + 80; x++)
{
u8 code = m_vram[x + 0x80];
u16 gfx = 0;
if (BIT(code, 7) && !disable_fac)
{
underline1 = BIT(code, 4);
non_display = BIT(code, 3);
invert = BIT(code, 2);
half_bright = BIT(code, 1);
blink = BIT(code, 0);
}
// Copying the circuit logic for loading from
// the character generator which occurs when:
//
// 1. Special character display is enabled or
// it is not a special character 0x00 to 0x1f.
//
// AND
//
// 2. Not 'non display'
//
// AND
//
// 3. Not 'blink' and blinked off.
//
// AND
//
// 4. Not FAC code or Display FAC enabled.
//
if ((m_special_char_disp || (code & 0xe0)) &&
!non_display &&
!(blink && (m_framecnt & 8)) &&
(!BIT(code, 7) || display_fac))
{
offs_t address = ((code & 0x7f) << 4) | (ra & 0x0f);
gfx = m_chargen[address];
}
if (underline1 && underline2 && ra == 10)
gfx |= 0x1ff;
u8 cursor_display = x + 0x80 == m_cursor_addr;
cursor_display = cursor_display && (m_framecnt & 4);
if (m_inv_video ^ invert ^ cursor_display)
gfx ^= 0x1ff; // invert
u32 font_color = palette[2 - half_bright];
/* Display a scanline of a character */
*p++ = (BIT(gfx, 7)) ? font_color : 0;
*p++ = (BIT(gfx, 6)) ? font_color : 0;
*p++ = (BIT(gfx, 5)) ? font_color : 0;
*p++ = (BIT(gfx, 4)) ? font_color : 0;
*p++ = (BIT(gfx, 3)) ? font_color : 0;
*p++ = (BIT(gfx, 2)) ? font_color : 0;
*p++ = (BIT(gfx, 1)) ? font_color : 0;
*p++ = (BIT(gfx, 0)) ? font_color : 0;
*p++ = (BIT(gfx, 8)) ? font_color : 0;
// The circuit has logic to delay underlining
// but not for the other attributes.
underline2 = underline1;
}
}
ma += 80;
}
return 0;
}
static const gfx_layout char_layout =
{
8,12,
RGN_FRAC(1,1),
1,
{ 0 },
{ 0, 1, 2, 3, 4, 5, 6, 7 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8 },
8*16
};
static GFXDECODE_START(chars)
GFXDECODE_ENTRY("chargen", 0, char_layout, 0, 1)
GFXDECODE_END
//**************************************************************************
// MACHINE EMULATION
//**************************************************************************
WRITE_LINE_MEMBER(exorterm155_device::sys_timer_w)
{
// 3.4ms
m_pia_disp->cb1_w(state);
// Divide by 16, giving 27.5ms.
if (state == 1) m_sys_timer_count++;
m_pia_disp->ca1_w((m_sys_timer_count & 8) != 0);
// The terminal firmware does not initialize properly if a key
// interrupt is received too soon after reset, so a hold off period is
// implemented and measured in terms of these timer interrupts.
if (m_kbd_start_holdoff > 0)
{
if (m_kbd_start_holdoff == 1)
kbd_start_processing();
m_kbd_start_holdoff--;
}
}
WRITE_LINE_MEMBER(exorterm155_device::write_f1_clock)
{
if (BIT(m_rs232_baud->read(), 0))
{
m_acia->write_txc(state);
m_acia->write_rxc(state);
}
}
WRITE_LINE_MEMBER(exorterm155_device::write_f3_clock)
{
if (BIT(m_rs232_baud->read(), 1))
{
m_acia->write_txc(state);
m_acia->write_rxc(state);
}
}
WRITE_LINE_MEMBER(exorterm155_device::write_f5_clock)
{
if (BIT(m_rs232_baud->read(), 2))
{
m_acia->write_txc(state);
m_acia->write_rxc(state);
}
}
WRITE_LINE_MEMBER(exorterm155_device::write_f6_clock)
{
if (BIT(m_rs232_baud->read(), 3))
{
m_acia->write_txc(state);
m_acia->write_rxc(state);
}
}
WRITE_LINE_MEMBER(exorterm155_device::write_f7_clock)
{
if (BIT(m_rs232_baud->read(), 4))
{
m_acia->write_txc(state);
m_acia->write_rxc(state);
}
}
WRITE_LINE_MEMBER(exorterm155_device::write_f8_clock)
{
if (BIT(m_rs232_baud->read(), 5))
{
m_acia->write_txc(state);
m_acia->write_rxc(state);
}
}
WRITE_LINE_MEMBER(exorterm155_device::write_f9_clock)
{
if (BIT(m_rs232_baud->read(), 6))
{
m_acia->write_txc(state);
m_acia->write_rxc(state);
}
}
WRITE_LINE_MEMBER(exorterm155_device::write_f11_clock)
{
if (BIT(m_rs232_baud->read(), 7))
{
m_acia->write_txc(state);
m_acia->write_rxc(state);
}
}
WRITE_LINE_MEMBER(exorterm155_device::write_f13_clock)
{
if (BIT(m_rs232_baud->read(), 8))
{
m_acia->write_txc(state);
m_acia->write_rxc(state);
}
}
WRITE_LINE_MEMBER(exorterm155_device::acia_txd_w)
{
m_rs232_conn_txd_handler(state);
}
WRITE_LINE_MEMBER(exorterm155_device::acia_rts_w)
{
m_rs232_conn_rts_handler(state);
}
WRITE_LINE_MEMBER(exorterm155_device::rs232_conn_dcd_w)
{
m_acia->write_dcd(state);
}
WRITE_LINE_MEMBER(exorterm155_device::rs232_conn_dsr_w)
{
// Input of Display PIA PB5, pulled high.
m_dsr = state;
}
WRITE_LINE_MEMBER(exorterm155_device::rs232_conn_ri_w)
{
m_ring = state;
}
WRITE_LINE_MEMBER(exorterm155_device::rs232_conn_cts_w)
{
m_acia->write_cts(state);
}
WRITE_LINE_MEMBER(exorterm155_device::rs232_conn_rxd_w)
{
m_acia->write_rxd(state);
}
// Keyboard
u8 const exorterm155_device::translation_table[][5][17] = {
{ // Standard
{ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xff, 0xf7, 0xf8, 0xc7, 0xff },
{ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '`', '-', '=', 0x8c, 0xd0, 0xd1, 0xdc },
{ 0x1b, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '\\', 0x0a, 0x0d, 0xda, 0xdb, 0xd7 },
{ 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '[', ']', 0xff, 0xc1, 0xc2, 0xd6 },
{ 0xc0, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0xd9, ' ', 0x08, 0xc3, 0xc4, 0xd4 }
},
{ // Shift
{ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff },
{ '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '~', '_', '+', 0xff, 0xd6, 0xd7, 0xff },
{ 0x1b , 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '|', 0x0a, 0x0d, 0xdb, 0xff, 0xff },
{ 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '{', '}', 0xff, 0xff, 0xff, 0xff },
{ 0xd8, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0xdf, ' ', 0x08, 0xff, 0xff, 0xd5 }
},
{ // Ctrl
{ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff, 0xff },
{ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0x00, 0x1f, 0x1e, 0xff, 0xff, 0xff, 0xff },
{ 0x1b, 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, 0x0f, 0x10, 0x1c, 0x0a, 0x0d, 0x09, 0xff, 0xff },
{ 0x01, 0x13, 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, ';', '\'', 0x1b, 0x1d, 0xff, 0xff, 0xff, 0xff },
{ 0xff, 0x1a, 0x18, 0x03, 0x16, 0x02, 0x0e, 0x0d, ',', '.', 0x1f, 0xff, 0x00, 0x08, 0xff, 0xff, 0xff }
}
};
bool const exorterm155_device::caps_table[5][17] = {
{ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false },
{ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false },
{ false, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false },
{ true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false },
{ false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false }
};
void exorterm155_device::kbd_start_processing()
{
attotime period = attotime::from_hz(2'400);
m_kbd_processing = 1;
m_kbd_scan_timer->adjust(period, 0, period);
}
void exorterm155_device::kbd_reset_state()
{
std::fill(std::begin(m_kbd_states), std::end(m_kbd_states), ioport_value(0));
m_kbd_next_row = 0;
}
void exorterm155_device::kbd_repeat_start(uint8_t row, uint8_t column)
{
attotime delay = attotime::from_msec(750);
attotime interval = attotime::from_msec(100);
m_kbd_repeat_row = row;
m_kbd_repeat_column = column;
m_kbd_repeat_timer->adjust(delay, 0, interval);
}
void exorterm155_device::kbd_repeat_restart()
{
attotime delay = attotime::from_msec(750);
attotime interval = attotime::from_msec(100);
if ((m_kbd_repeat_row != 0xff) || (m_kbd_repeat_column != 0xff))
m_kbd_repeat_timer->adjust(delay, 0, interval);
}
void exorterm155_device::kbd_repeat_stop()
{
m_kbd_repeat_row = 0xff;
m_kbd_repeat_column = 0xff;
m_kbd_repeat_timer->reset();
}
void exorterm155_device::kbd_send_translated(u8 code)
{
unsigned row = (code >> 5) & 0x07;
unsigned col = (code >> 0) & 0x1f;
u16 modifiers = m_kbd_modifiers->read();
bool shift = BIT(modifiers, 1) != ((modifiers & 4) && caps_table[row][col]);
bool ctrl = BIT(modifiers, 0);
unsigned map = ctrl ? 2 : shift ? 1 : 0;
u8 result = translation_table[map][row][col];
if (result == 0xff)
return;
m_term_data = result;
// Triggers on the falling edge.
m_pia_kbd->ca1_w(ASSERT_LINE);
m_pia_kbd->ca1_w(CLEAR_LINE);
m_pia_kbd->ca1_w(ASSERT_LINE);
}
TIMER_CALLBACK_MEMBER(exorterm155_device::kbd_scan_row)
{
u16 const modifiers(m_kbd_modifiers->read());
if (modifiers != m_kbd_last_modifiers)
kbd_repeat_restart();
m_kbd_last_modifiers = modifiers;
ioport_value &state(m_kbd_states[m_kbd_next_row]);
ioport_value const keys(m_kbd_rows[m_kbd_next_row]->read());
ioport_value const change(state ^ keys);
ioport_value mask(1U);
for (uint8_t column = 0U; m_kbd_processing && (state != keys); ++column, mask <<= 1)
{
if (change & mask)
{
state ^= mask;
if (keys & mask)
{
kbd_send_translated((m_kbd_next_row << 5) | column);
kbd_repeat_start(m_kbd_next_row, column);
}
else
{
if (m_kbd_repeat_row == m_kbd_next_row && m_kbd_repeat_column == column)
kbd_repeat_stop();
}
}
}
m_kbd_next_row = (m_kbd_next_row + 1) % 5;
}
TIMER_CALLBACK_MEMBER(exorterm155_device::kbd_repeat)
{
assert((m_kbd_repeat_row != 0xff) || (m_kbd_repeat_column != 0xff));
kbd_send_translated((m_kbd_repeat_row << 5) | m_kbd_repeat_column);
}
void exorterm155_device::device_resolve_objects()
{
m_rs232_conn_dtr_handler.resolve_safe();
m_rs232_conn_rts_handler.resolve_safe();
m_rs232_conn_txd_handler.resolve_safe();
}
void exorterm155_device::device_start()
{
m_online_led.resolve();
m_auto_lf_led.resolve();
m_page_mode_led.resolve();
m_insert_char_led.resolve();
// register for save states
save_item(NAME(m_term_data));
save_item(NAME(m_framecnt));
save_item(NAME(m_cursor_addr));
save_item(NAME(m_inv_video));
save_item(NAME(m_special_char_disp));
save_item(NAME(m_sys_timer_count));
save_item(NAME(m_dsr));
save_item(NAME(m_ring));
save_item(NAME(m_kbd_start_holdoff));
// Keyboard
if (!m_kbd_scan_timer)
m_kbd_scan_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(exorterm155_device::kbd_scan_row), this));
if (!m_kbd_repeat_timer)
m_kbd_repeat_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(exorterm155_device::kbd_repeat), this));
kbd_reset_state();
kbd_repeat_stop();
save_item(NAME(m_kbd_states));
save_item(NAME(m_kbd_next_row));
save_item(NAME(m_kbd_processing));
save_item(NAME(m_kbd_repeat_row));
save_item(NAME(m_kbd_repeat_column));
save_item(NAME(m_kbd_last_modifiers));
}
void exorterm155_device::device_reset()
{
m_brg->rsa_w(CLEAR_LINE);
m_brg->rsb_w(ASSERT_LINE);
m_online_led = 0;
m_auto_lf_led = 0;
m_page_mode_led = 0;
m_insert_char_led = 0;
m_framecnt = 0;
m_cursor_addr = 0;
m_inv_video = 0;
m_special_char_disp = 0;
m_sys_timer_count = 0;
m_dsr = 1;
m_ring = 0;
m_beeper->set_state(0);
// Keyboard
kbd_reset_state();
kbd_repeat_stop();
m_kbd_start_holdoff = 180;
m_kbd_last_modifiers = 0;
}
//**************************************************************************
// ROM DEFINITIONS
//**************************************************************************
ROM_START( exorterm155 )
ROM_REGION(0x10000, "maincpu", 0)
ROM_LOAD("51aw1018b25.bin", 0xa000, 0x0800, CRC(5f9352ba) SHA1(9fb52992bd3f3409fa8ec1002e2ebdf61318d260))
ROM_LOAD("51aw1018b22.bin", 0xc000, 0x0800, CRC(b6bb9df0) SHA1(5c0bda69d94fd58c21f07c810525043cd22a9d7d))
ROM_LOAD("51aw1018b27.bin", 0xc800, 0x0800, CRC(15f77b53) SHA1(1f73098ebf83d7255efcf2b509d12e559001ca5b))
ROM_LOAD("51aw1018b26.bin", 0xd000, 0x0800, CRC(f5b204bc) SHA1(9815fd7d7ba617ebb3f55e595e4931d75942b6a9))
ROM_LOAD("51aw1018b24.bin", 0xd800, 0x0800, CRC(18a0ed66) SHA1(5fa6e4b3c27969c1d7e27c79fc2993e4cc9262cf))
ROM_REGION(0x0800, "chargen", 0)
ROM_LOAD("chargen.rom", 0x0000, 0x0800, CRC(0087cbad) SHA1(a6d3dd0512db4c459944c60d728536755a570964))
ROM_END
//**************************************************************************
// MACHINE DEFINTIONS
//**************************************************************************
void exorterm155_device::device_add_mconfig(machine_config &config)
{
M6800(config, m_maincpu, 16.6698_MHz_XTAL / 18);
m_maincpu->set_addrmap(AS_PROGRAM, &exorterm155_device::mem_map);
INPUT_MERGER_ANY_HIGH(config, m_irqs).output_handler().set_inputline(m_maincpu, M6800_IRQ_LINE);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(50);
m_screen->set_size(80*9, 24*12);
m_screen->set_visarea(0, 80*9-1, 0, 24*12-1);
m_screen->set_screen_update(FUNC(exorterm155_device::screen_update));
PALETTE(config, m_palette, palette_device::MONOCHROME_HIGHLIGHT);
GFXDECODE(config, "gfxdecode", m_palette, chars);
config.set_default_layout(layout_exorterm155);
ACIA6850(config, m_acia, 0);
m_acia->txd_handler().set(FUNC(exorterm155_device::acia_txd_w));
m_acia->rts_handler().set(FUNC(exorterm155_device::acia_rts_w));
m_acia->irq_handler().set(m_irqs, FUNC(input_merger_device::in_w<0>));
MC14411(config, m_brg, XTAL(1'843'200));
m_brg->out_f<1>().set(FUNC(exorterm155_device::write_f1_clock));
m_brg->out_f<3>().set(FUNC(exorterm155_device::write_f3_clock));
m_brg->out_f<5>().set(FUNC(exorterm155_device::write_f5_clock));
m_brg->out_f<6>().set(FUNC(exorterm155_device::write_f6_clock));
m_brg->out_f<7>().set(FUNC(exorterm155_device::write_f7_clock));
m_brg->out_f<8>().set(FUNC(exorterm155_device::write_f8_clock));
m_brg->out_f<9>().set(FUNC(exorterm155_device::write_f9_clock));
m_brg->out_f<11>().set(FUNC(exorterm155_device::write_f11_clock));
m_brg->out_f<13>().set(FUNC(exorterm155_device::write_f13_clock));
PIA6821(config, m_pia_kbd);
m_pia_kbd->readpa_handler().set(FUNC(exorterm155_device::pia_kbd_pa_r));
m_pia_kbd->readpb_handler().set(FUNC(exorterm155_device::pia_kbd_pb_r));
m_pia_kbd->writepb_handler().set(FUNC(exorterm155_device::pia_kbd_pb_w));
m_pia_kbd->irqa_handler().set(m_irqs, FUNC(input_merger_device::in_w<1>));
m_pia_kbd->irqb_handler().set(m_irqs, FUNC(input_merger_device::in_w<2>));
PIA6821(config, m_pia_cfg);
m_pia_cfg->readpa_handler().set_ioport("DIP_SWITCHES_A");
m_pia_cfg->readpb_handler().set_ioport("DIP_SWITCHES_B");
m_pia_cfg->cb2_handler().set(FUNC(exorterm155_device::pia_cfg_cb2_w));
m_pia_cfg->irqa_handler().set(m_irqs, FUNC(input_merger_device::in_w<3>));
m_pia_cfg->irqb_handler().set(m_irqs, FUNC(input_merger_device::in_w<4>));
PIA6821(config, m_pia_disp);
m_pia_disp->writepa_handler().set(FUNC(exorterm155_device::pia_disp_pa_w));
m_pia_disp->readpb_handler().set(FUNC(exorterm155_device::pia_disp_pb_r));
m_pia_disp->writepb_handler().set(FUNC(exorterm155_device::pia_disp_pb_w));
m_pia_disp->readca2_handler().set(FUNC(exorterm155_device::pia_disp_ca2_r));
m_pia_disp->irqa_handler().set(m_irqs, FUNC(input_merger_device::in_w<5>));
m_pia_disp->irqb_handler().set(m_irqs, FUNC(input_merger_device::in_w<6>));
// Derived from the horizontal blanking, 3.4ms.
CLOCK(config, m_sys_timer_clock, 4706 / 16);
m_sys_timer_clock->signal_handler().set(FUNC(exorterm155_device::sys_timer_w));
SPEAKER(config, "bell").front_center();
BEEP(config, m_beeper, 2000);
m_beeper->add_route(ALL_OUTPUTS, "bell", 0.25);
}
ioport_constructor exorterm155_device::device_input_ports() const
{
return INPUT_PORTS_NAME(exorterm155);
}
const tiny_rom_entry *exorterm155_device::device_rom_region() const
{
return ROM_NAME(exorterm155);
}
DEFINE_DEVICE_TYPE(EXORTERM155, exorterm155_device, "exorterm155_device", "EXORTERM155")

View File

@ -0,0 +1,154 @@
// license:BSD-3-Clause
// copyright-holders: 68bit
/****************************************************************************
Motorola EXORterm 155 (M68SDS)
****************************************************************************/
#ifndef MAME_MACHINE_EXORTERM_H
#define MAME_MACHINE_EXORTERM_H
#pragma once
#include "cpu/m6800/m6800.h"
#include "machine/clock.h"
#include "machine/input_merger.h"
#include "machine/mc14411.h"
#include "machine/6850acia.h"
#include "machine/6821pia.h"
#include "sound/spkrdev.h"
#include "bus/rs232/rs232.h"
#include "emupal.h"
#include "screen.h"
#include "machine/terminal.h"
INPUT_PORTS_EXTERN(exorterm155);
class exorterm155_device : public device_t
{
public:
exorterm155_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// Interface to a RS232 connection.
auto rs232_conn_txd_handler() { return m_rs232_conn_txd_handler.bind(); }
auto rs232_conn_dtr_handler() { return m_rs232_conn_dtr_handler.bind(); }
auto rs232_conn_rts_handler() { return m_rs232_conn_rts_handler.bind(); }
DECLARE_WRITE_LINE_MEMBER(rs232_conn_dcd_w);
DECLARE_WRITE_LINE_MEMBER(rs232_conn_dsr_w);
DECLARE_WRITE_LINE_MEMBER(rs232_conn_ri_w);
DECLARE_WRITE_LINE_MEMBER(rs232_conn_cts_w);
DECLARE_WRITE_LINE_MEMBER(rs232_conn_rxd_w);
protected:
exorterm155_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
virtual void device_resolve_objects() override;
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
virtual const tiny_rom_entry *device_rom_region() const override;
private:
required_device<m6800_cpu_device> m_maincpu;
required_device<input_merger_device> m_irqs;
required_device<acia6850_device> m_acia;
required_device<mc14411_device> m_brg;
required_ioport m_rs232_baud;
required_ioport m_disable_fac;
required_ioport m_display_fac;
required_device<pia6821_device> m_pia_kbd;
required_device<pia6821_device> m_pia_cfg;
required_device<pia6821_device> m_pia_disp;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_device<clock_device> m_sys_timer_clock;
required_shared_ptr<u8> m_vram;
required_region_ptr<u8> m_chargen;
required_device<beep_device> m_beeper;
output_finder<> m_online_led;
output_finder<> m_auto_lf_led;
output_finder<> m_page_mode_led;
output_finder<> m_insert_char_led;
void mem_map(address_map &map);
DECLARE_WRITE_LINE_MEMBER(acia_txd_w);
DECLARE_WRITE_LINE_MEMBER(acia_rts_w);
// Clocks
DECLARE_WRITE_LINE_MEMBER(write_f1_clock);
DECLARE_WRITE_LINE_MEMBER(write_f3_clock);
DECLARE_WRITE_LINE_MEMBER(write_f5_clock);
DECLARE_WRITE_LINE_MEMBER(write_f6_clock);
DECLARE_WRITE_LINE_MEMBER(write_f7_clock);
DECLARE_WRITE_LINE_MEMBER(write_f8_clock);
DECLARE_WRITE_LINE_MEMBER(write_f9_clock);
DECLARE_WRITE_LINE_MEMBER(write_f11_clock);
DECLARE_WRITE_LINE_MEMBER(write_f13_clock);
u8 m_dsr;
u8 m_ring;
devcb_write_line m_rs232_conn_txd_handler;
devcb_write_line m_rs232_conn_dtr_handler;
devcb_write_line m_rs232_conn_rts_handler;
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
u8 m_framecnt;
u16 m_cursor_addr;
u8 m_inv_video;
u8 m_special_char_disp;
DECLARE_WRITE_LINE_MEMBER(sys_timer_w);
u8 m_sys_timer_count;
DECLARE_WRITE_LINE_MEMBER(pia_cfg_cb2_w);
u8 pia_kbd_pa_r();
u8 pia_kbd_pb_r();
void pia_kbd_pb_w(u8 data);
u8 m_term_data;
u8 pia_disp_pb_r();
void pia_disp_pa_w(u8 data);
void pia_disp_pb_w(u8 data);
DECLARE_READ_LINE_MEMBER(pia_disp_ca2_r);
u8 m_kbd_start_holdoff;
// Keyboard
static u8 const translation_table[][5][17];
static bool const caps_table[5][17];
void kbd_start_processing();
void kbd_reset_state();
void kbd_repeat_start(u8 row, u8 column);
void kbd_repeat_restart();
void kbd_repeat_stop();
void kbd_repeat();
void kbd_send_translated(u8 code);
TIMER_CALLBACK_MEMBER(kbd_scan_row);
TIMER_CALLBACK_MEMBER(kbd_repeat);
emu_timer *m_kbd_scan_timer;
emu_timer *m_kbd_repeat_timer;
required_ioport m_kbd_modifiers;
required_ioport_array<5> m_kbd_rows;
ioport_value m_kbd_states[5];
u8 m_kbd_next_row;
u8 m_kbd_processing;
u8 m_kbd_repeat_row;
u8 m_kbd_repeat_column;
u16 m_kbd_last_modifiers;
};
DECLARE_DEVICE_TYPE(EXORTERM155, exorterm155_device)
#endif // MAME_MACHINE_EXORTERM_H

View File

@ -0,0 +1,80 @@
<?xml version="1.0"?>
<!--
license:CC0
LEDs for the Motorola EXORterm 155
-->
<mamelayout version="2">
<element name="red_led">
<disk>
<color red="1.0" green="0.0" blue="0.0" />
</disk>
</element>
<element name="ON_LINE">
<text string="ON LINE">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="AUTO_LF">
<text string="AUTO LF">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="PAGE_MODE">
<text string="PAGE MODE">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="INS_CHAR">
<text string="INS CHAR">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="background">
<rect>
<bounds left="0" top="0" right="1" bottom="1" />
<color red="0.0" green="0.0" blue="0.0" />
</rect>
</element>
<view name="Keyboard LEDs">
<bezel name="auto_lf_txt" element="AUTO_LF">
<bounds left="0" right="70" top="296" bottom="304" />
</bezel>
<bezel name="auto_lf_led" element="red_led">
<bounds left="31" right="39" top="308" bottom="316" />
</bezel>
<bezel name="online_txt" element="ON_LINE">
<bounds left="70" right="140" top="296" bottom="304" />
</bezel>
<bezel name="online_led" element="red_led">
<bounds left="101" right="109" top="308" bottom="316" />
</bezel>
<bezel name="page_mode_txt" element="PAGE_MODE">
<bounds left="140" right="210" top="296" bottom="304" />
</bezel>
<bezel name="page_mode_led" element="red_led">
<bounds left="171" right="179" top="308" bottom="316" />
</bezel>
<bezel name="insert_char_txt" element="INS_CHAR">
<bounds left="281" right="351" top="296" bottom="304" />
</bezel>
<bezel name="insert_char_led" element="red_led">
<bounds left="312" right="320" top="308" bottom="316" />
</bezel>
<bezel element="background">
<bounds left="0" top="316" right="720" bottom="320" />
</bezel>
<screen index="0">
<bounds x="0" y="0" width="720" height="288" />
</screen>
</view>
</mamelayout>

View File

@ -0,0 +1,58 @@
// license:BSD-3-Clause
// copyright-holders: 68bit
/****************************************************************************
Stand alone front end for the Motorola EXORterm 155 (M68SDS)
****************************************************************************/
#include "emu.h"
#include "machine/exorterm.h"
#include "bus/rs232/rs232.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class exorterm155_state : public driver_device
{
public:
exorterm155_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_exorterm155(*this, "exorterm155")
, m_host(*this, "host")
{ }
void exorterm155(machine_config &config);
private:
required_device<exorterm155_device> m_exorterm155;
required_device<rs232_port_device> m_host;
};
void exorterm155_state::exorterm155(machine_config &config)
{
EXORTERM155(config, m_exorterm155, 0);
RS232_PORT(config, m_host, default_rs232_devices, nullptr);
m_host->dcd_handler().set(m_exorterm155, FUNC(exorterm155_device::rs232_conn_dcd_w));
m_host->dsr_handler().set(m_exorterm155, FUNC(exorterm155_device::rs232_conn_dsr_w));
m_host->ri_handler().set(m_exorterm155, FUNC(exorterm155_device::rs232_conn_ri_w));
m_host->cts_handler().set(m_exorterm155, FUNC(exorterm155_device::rs232_conn_cts_w));
m_host->rxd_handler().set(m_exorterm155, FUNC(exorterm155_device::rs232_conn_rxd_w));
m_exorterm155->rs232_conn_txd_handler().set(m_host, FUNC(rs232_port_device::write_txd));
m_exorterm155->rs232_conn_dtr_handler().set(m_host, FUNC(rs232_port_device::write_dtr));
m_exorterm155->rs232_conn_rts_handler().set(m_host, FUNC(rs232_port_device::write_rts));
}
ROM_START(exorterm155)
ROM_END
//**************************************************************************
// SYSTEM DRIVERS
//**************************************************************************
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
COMP( 1979, exorterm155, 0, 0, exorterm155, 0, exorterm155_state, empty_init, "Motorola", "EXORterm 155", MACHINE_SUPPORTS_SAVE )

View File

@ -13314,6 +13314,9 @@ deathrac // (c) 1976 Exidy
destdrby // (c) 1976 Exidy
rhunting // bootleg of deathrac
@source:exorterm.cpp
exorterm155 // (c) 1979 Motorola
@source:exp85.cpp
exp85 //

View File

@ -277,6 +277,7 @@ eva.cpp
evmbug.cpp
excali64.cpp
exelv.cpp
exorterm.cpp
exp85.cpp
facit4440.cpp
falco5220.cpp