From 7aa1490a7e920be58d73344e20af67f36f7a9a2f Mon Sep 17 00:00:00 2001 From: 68bit <53298758+68bit@users.noreply.github.com> Date: Wed, 30 Oct 2019 13:02:31 +1100 Subject: swtpc8212: get it running, and on the rs232 bus (#5729) This patch gets it running, and splits it into two front ends, one being a rs232 bus slot so that is can be used as a terminal option. It adds the MCM66750 character generator, and implements the MC6845 row update function. Most of the I/O has been worked out with help from the CT-82 user manual. The various screen formats and the graphics modes appear to be working and plausible. Printer support has been added, and a beeper. --- scripts/src/bus.lua | 2 + scripts/src/machine.lua | 12 + scripts/target/mame/mess.lua | 1 + src/devices/bus/rs232/swtpc8212.cpp | 87 ++++++ src/devices/bus/rs232/swtpc8212.h | 40 +++ src/devices/bus/ss50/mps.cpp | 47 ++- src/devices/bus/ss50/mps2.cpp | 3 + src/devices/machine/swtpc8212.cpp | 582 ++++++++++++++++++++++++++++++++++++ src/devices/machine/swtpc8212.h | 102 +++++++ src/mame/drivers/swtpc8212.cpp | 131 ++------ src/mame/mame.lst | 2 +- 11 files changed, 893 insertions(+), 116 deletions(-) create mode 100644 src/devices/bus/rs232/swtpc8212.cpp create mode 100644 src/devices/bus/rs232/swtpc8212.h create mode 100644 src/devices/machine/swtpc8212.cpp create mode 100644 src/devices/machine/swtpc8212.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index d5e47d68f1f..53623267c55 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -2353,6 +2353,8 @@ if (BUSES["RS232"]~=null) then MAME_DIR .. "src/devices/bus/rs232/xvd701.h", MAME_DIR .. "src/devices/bus/rs232/ie15.cpp", MAME_DIR .. "src/devices/bus/rs232/ie15.h", + MAME_DIR .. "src/devices/bus/rs232/swtpc8212.cpp", + MAME_DIR .. "src/devices/bus/rs232/swtpc8212.h", } end diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 3c574fe3762..e9a58631883 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -2811,6 +2811,18 @@ if (MACHINES["STVCD"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/swtpc8212.h,MACHINES["SWTPC8212"] = true +--------------------------------------------------- + +if (MACHINES["SWTPC8212"]~=null) then + files { + MAME_DIR .. "src/devices/machine/swtpc8212.cpp", + MAME_DIR .. "src/devices/machine/swtpc8212.h", + } +end + --------------------------------------------------- -- -- diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index f09ec3d999d..031c563ad4c 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -621,6 +621,7 @@ MACHINES["SMPC"] = true MACHINES["SPG2XX"] = true MACHINES["STVCD"] = true MACHINES["SUN4C_MMU"] = true +MACHINES["SWTPC8212"] = true MACHINES["TC0091LVC"] = true MACHINES["TDC1008"] = true --MACHINES["TE7750"] = true diff --git a/src/devices/bus/rs232/swtpc8212.cpp b/src/devices/bus/rs232/swtpc8212.cpp new file mode 100644 index 00000000000..ea48a2cecf8 --- /dev/null +++ b/src/devices/bus/rs232/swtpc8212.cpp @@ -0,0 +1,87 @@ +// license:BSD-3-Clause +// copyright-holders:68bit + +#include "emu.h" +#include "swtpc8212.h" + +swtpc8212_terminal_device::swtpc8212_terminal_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SERIAL_TERMINAL_SWTPC8212, tag, owner, clock) + , device_rs232_port_interface(mconfig, *this) + , m_swtpc8212(*this, "swtpc8212") + , m_flow_control(*this, "FLOW_CONTROL") +{ +} + +void swtpc8212_terminal_device::device_add_mconfig(machine_config &config) +{ + SWTPC8212(config, m_swtpc8212, 0); + m_swtpc8212->rs232_conn_txd_handler().set(FUNC(swtpc8212_terminal_device::output_rxd)); + m_swtpc8212->rs232_conn_rts_handler().set(FUNC(swtpc8212_terminal_device::route_term_rts)); + m_swtpc8212->rs232_conn_dtr_handler().set(FUNC(swtpc8212_terminal_device::route_term_dtr)); +} + +INPUT_PORTS_START(swtpc8212_terminal) + + PORT_START("FLOW_CONTROL") + PORT_CONFNAME(0x1, 1, "Flow control") + PORT_CONFSETTING(0x00, "None") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_terminal_device, flow_control, 0) + PORT_CONFSETTING(0x01, "Terminal DTR to remote CTS") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_terminal_device, flow_control, 0) + +INPUT_PORTS_END + +ioport_constructor swtpc8212_terminal_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(swtpc8212_terminal); +} + +WRITE_LINE_MEMBER(swtpc8212_terminal_device::input_txd) +{ + m_swtpc8212->rs232_conn_rxd_w(state); +} + +WRITE_LINE_MEMBER(swtpc8212_terminal_device::route_term_rts) +{ + // Loop the terminal RTS output to the terminal CTS input. + m_swtpc8212->rs232_conn_cts_w(state); +} + +// This terminal uses DTR for hardware flow control. +WRITE_LINE_MEMBER(swtpc8212_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(swtpc8212_terminal_device::flow_control) +{ + if (newval) + output_cts(m_dtr); + else + output_cts(0); +} + +void swtpc8212_terminal_device::device_start() +{ + save_item(NAME(m_dtr)); +} + +void swtpc8212_terminal_device::device_reset() +{ + // To the terminal + m_swtpc8212->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_SWTPC8212, swtpc8212_terminal_device, "swtpc8212_terminal", "SWTPC8212 Terminal") diff --git a/src/devices/bus/rs232/swtpc8212.h b/src/devices/bus/rs232/swtpc8212.h new file mode 100644 index 00000000000..2af82fa3215 --- /dev/null +++ b/src/devices/bus/rs232/swtpc8212.h @@ -0,0 +1,40 @@ +// license:BSD-3-Clause +// copyright-holders:68bit + +#ifndef MAME_BUS_RS232_SWTPC8212_H +#define MAME_BUS_RS232_SWTPC8212_H + +#pragma once + +#include "rs232.h" +#include "machine/swtpc8212.h" + + +class swtpc8212_terminal_device : public device_t, public device_rs232_port_interface +{ +public: + swtpc8212_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 m_swtpc8212; + 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_SWTPC8212, swtpc8212_terminal_device) + +#endif // MAME_BUS_RS232_SWTPC8212_H diff --git a/src/devices/bus/ss50/mps.cpp b/src/devices/bus/ss50/mps.cpp index 15d7d160e31..30e2a534615 100644 --- a/src/devices/bus/ss50/mps.cpp +++ b/src/devices/bus/ss50/mps.cpp @@ -10,6 +10,7 @@ #include "mps.h" #include "bus/rs232/rs232.h" +#include "bus/rs232/swtpc8212.h" #include "machine/6850acia.h" //************************************************************************** @@ -23,11 +24,12 @@ class ss50_mps_device : public device_t, public ss50_card_interface public: // construction/destruction ss50_mps_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : device_t(mconfig, SS50_MPS, tag, owner, clock), - ss50_card_interface(mconfig, *this), - m_acia(*this, "acia"), - m_irq_jumper(*this, "IRQ"), - m_rate_jumper(*this, "BAUD") + : device_t(mconfig, SS50_MPS, tag, owner, clock) + , ss50_card_interface(mconfig, *this) + , m_acia(*this, "acia") + , m_irq_jumper(*this, "IRQ") + , m_rate_jumper(*this, "BAUD") + , m_cts_route(*this, "CTS_ROUTE") { } @@ -48,26 +50,34 @@ protected: private: DECLARE_WRITE_LINE_MEMBER(acia_irq_w); + DECLARE_WRITE_LINE_MEMBER(route_cts_r); required_device m_acia; required_ioport m_irq_jumper; required_ioport m_rate_jumper; + required_ioport m_cts_route; }; static INPUT_PORTS_START( mps ) PORT_START("IRQ") - PORT_DIPNAME(1, 0, "IRQ") - PORT_DIPSETTING(1, DEF_STR(Off)) - PORT_DIPSETTING(0, DEF_STR(On)) + PORT_CONFNAME(1, 0, "IRQ") + PORT_CONFSETTING(1, DEF_STR(Off)) + PORT_CONFSETTING(0, DEF_STR(On)) PORT_START("BAUD") - PORT_DIPNAME(0x1f, 0x1d, "Baud Rate") - PORT_DIPSETTING(0x1e, "110") - PORT_DIPSETTING(0x1d, "150 / 9600") - PORT_DIPSETTING(0x1b, "300") - PORT_DIPSETTING(0x17, "600") - PORT_DIPSETTING(0x0f, "1200") + PORT_CONFNAME(0x1f, 0x1d, "Baud Rate") + PORT_CONFSETTING(0x1e, "110") + PORT_CONFSETTING(0x1d, "150 / 9600") + PORT_CONFSETTING(0x1b, "300") + PORT_CONFSETTING(0x17, "600") + PORT_CONFSETTING(0x0f, "1200") + + PORT_START("CTS_ROUTE") + PORT_CONFNAME(1, 0, "CTS route") + PORT_CONFSETTING(0, "Wired low (standard)") + PORT_CONFSETTING(1, "Connected through (modified)") + INPUT_PORTS_END @@ -105,6 +115,8 @@ void ss50_mps_device::device_add_mconfig(machine_config &config) rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal")); rs232.rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd)); + rs232.cts_handler().set(FUNC(ss50_mps_device::route_cts_r)); + rs232.option_add("swtpc8212", SERIAL_TERMINAL_SWTPC8212); rs232.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal)); } @@ -178,6 +190,13 @@ WRITE_LINE_MEMBER(ss50_mps_device::acia_irq_w) write_irq(state); } +WRITE_LINE_MEMBER(ss50_mps_device::route_cts_r) +{ + if (m_cts_route->read()) + { + m_acia->write_cts(state); + } +} // device type definition DEFINE_DEVICE_TYPE_PRIVATE(SS50_MPS, ss50_card_interface, ss50_mps_device, "ss50_mps", "MP-S Serial Interface") diff --git a/src/devices/bus/ss50/mps2.cpp b/src/devices/bus/ss50/mps2.cpp index 30bdd9e5a64..f2c6c8c1f77 100644 --- a/src/devices/bus/ss50/mps2.cpp +++ b/src/devices/bus/ss50/mps2.cpp @@ -11,6 +11,7 @@ #include "mps2.h" #include "bus/rs232/rs232.h" +#include "bus/rs232/swtpc8212.h" #include "machine/6850acia.h" #include "machine/input_merger.h" @@ -141,6 +142,7 @@ void ss50_mps2_device::device_add_mconfig(machine_config &config) rs232_upper.rxd_handler().set(m_acia_upper, FUNC(acia6850_device::write_rxd)); rs232_upper.cts_handler().set(m_acia_upper, FUNC(acia6850_device::write_cts)); rs232_upper.dcd_handler().set(m_acia_upper, FUNC(acia6850_device::write_dcd)); + rs232_upper.option_add("swtpc8212", SERIAL_TERMINAL_SWTPC8212); rs232_upper.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal_upper)); ACIA6850(config, m_acia_lower, 0); @@ -152,6 +154,7 @@ void ss50_mps2_device::device_add_mconfig(machine_config &config) rs232_lower.rxd_handler().set(m_acia_lower, FUNC(acia6850_device::write_rxd)); rs232_lower.cts_handler().set(m_acia_lower, FUNC(acia6850_device::write_cts)); rs232_lower.dcd_handler().set(m_acia_lower, FUNC(acia6850_device::write_dcd)); + rs232_lower.option_add("swtpc8212", SERIAL_TERMINAL_SWTPC8212); rs232_lower.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal_lower)); INPUT_MERGER_ANY_HIGH(config, "irq").output_handler().set(FUNC(ss50_mps2_device::write_irq)); diff --git a/src/devices/machine/swtpc8212.cpp b/src/devices/machine/swtpc8212.cpp new file mode 100644 index 00000000000..db7feb6e037 --- /dev/null +++ b/src/devices/machine/swtpc8212.cpp @@ -0,0 +1,582 @@ +// license:BSD-3-Clause +// copyright-holders:AJR,68bit +/**************************************************************************** + +Driver for Southwest Technical Products video terminal 8210. + +MC6802P, 2xMC6821P, INS8250N, MCM66750, MC6845P, bank of 8 dips, crystals +17.0748 (video), 1.8432 (cpu/uart). On the back is a 25-pin RS-232 port, and a +25-pin printer port. + +The 8212 terminal appears similar in design to the CT-82 terminal for which +there is some documentation and a user guide. In particular it appears closest +to the 'Version B1'. There was also a 8209 terminal with an 9 inch CRT versus +the 12 inch CRT in the 8212. This terminal has also been labeled at the +CT8200. http://www.swtpc.com/mholley/CT_82/CT82_Index.htm + +The 8212 has three CRT controller configurations: + 1. 82 x 20 characters, with a height of 14 scan lines. + 2. 82 x 24 characters, with a height of 12 scan lines. + 3. 92 x 22 characters, with a height of 12 scan lines. + +There are two character generators: +1. The MCM66750 with 7x9 sized characters with some descending by 3 lines +giving an effective 7x12 sized character set. +2. An EPROM defining 8x16 sized characters for which only 12 scan lines are +used, and this is used for the graphics mode. + +These appear to map onto the CT-82 screen formats options as follows: +Format I: 82 by 20, MCM66750 character set. Ctrl-\ crtl-Q +Format II: 82 by 24, MCM66750 character set. Ctrl-\ crtl-R +Format III: 82 by 20, EPROM character set. Ctrl-\ crtl-S +Format IV: 82 by 24, EPROM character set. Ctrl-\ crtl-T +Graphics: 92 by 22, EPROM character set. Ctrl-] crtl-V + +The semi-graphics character set is defined in an EPROM, and that EPROM defines +these characters but here is a brief description of the graphics codes. It +includes graphics characters that support a two by three pixel array per +character. The codes 0x20 to 0x5f remain ASCII characters. The codes 0x00 to +0x1f have the following graphics encoding: + + 000xxxxx + ---------- + | D0 | D3 | + ----------- + | D1 | D4 | + ----------- + | D2 | 0 | + ----------- + +The codes 0x60 to 0x7f have the following graphics encoding: + + 011xxxxx + ----------- + | D0 | D3 | + ----------- + | D1 | D4 | + ----------- + | D2 | 1 | + ----------- + +The terminal includes a parallel printer output and Ctrl-] Ctrl-K enables +printer pass-through and Ctrl-] Ctrl-G disables pass-through. + +The terminal appears to include light pen support, and the positions is read +via Ctrl-] Ctrl-B, TODO. + +The numeric keypad is separte to the keyboard, returning a separate 4 bit code +and strobe. The CT-82 documentation suggests that the order of the bits on the +keypad bus is reversed. Photos of the 8212 show a 16 key keypad. The ROM has a +table starting at 0xb8e4 that maps the keypad code read from PIA 0 Port A bits +4 to 7 into a character code. This table has two vectors of 16 bytes, and the +first 16 are used when in the 'cursor' mode and the later 16 are uses when in +the 'numeric' keypad mode. In the 'cursor' mode, four of the keys are +underfined. TODO the labels of all the keypad keys could not be read from the +photo found, so could use a better photo of the keypad and an update here. + +The keypad codes in the ROM appear consistent with the CT-82 +documentation. However the codes for the left and right cursor keys are not +consistent with a UniFlex termcap entry for the 'ct8200' which has the right +cursor code being 0x1d and the left cursor code being 0x1e. The standard CT-82 +codes of Ctrl-D and Ctrl-I for these keys are not good choices for a 'Unix' +like terminal and it appears likely that there is either a ROM revision making +this trivial change to better work with UniFlex or that people did patch the +keypad codes. The keypad codes are single character codes so there is very +limit room to add more, and some of keys were not even assigned a code, +history! A ROM patch assigning code friendlier to Unix is included in this +emulator. + +A glitch in the interaction of the keyboard and the keypad has been noted. When +typing fast on the keyboard a character may not be sent. Then if another key is +typed on the keyboard the unsent code is lost. But if another key is typed on +the keypad then the unsent keyboard code is then sent and the keypad code is +lost. The firmware has a one character send buffer. TODO This might be a +firmware issue, or might be a problem with the emulation of the PIA or UART or +the keyboard or keypad strobes etc. + +TODO A generic keyboard is used. Might need some work to get a better keyboard +emulation. The CT-82 documentation mentions a 'Break' key. + +TODO A generic 'beep' is used. Might want to compare this with the actual 8212 +to better emulate the sound. + +TODO the CB2 input of 'pia0' at address 0x0080 is polled by the firmware, and +it is the first input checked in the ISR. On a CB2 interrupt the ISR checks +for a 'break' condition on the UART and if not then it clears the UART OUT1 +output. There are other suggestions in the firmware that the OUT1 and OUT2 +UART lines are being driven. The operation here is unknown? + +TODO Confirm the CPU XTAL. The terminal emulation appears slugish compared +with the documented claims, the hardware flow control is needed even at 9600 +and it does not operate at 38400 as documented. The CT82 manual mentions an +optional 4MHz crystal and that would run the CPU at 1MHz which is the rated +speed for the CPU and perhaps the 8212 uses that 4MHz XTAL or at least +something faster the current 1.8432MHz XTAL? + +The terminfo database does not appear to have an entry for this terminal, and +the following is offered that attempts to use the features of the terminal that +map to ncurses and this helped testing and it appears to run the ncurses tests +and some utilities ok. The cursor keys are set for the patched ROM option. Keep +in mind that it is an ASCII terminal so try an ISO-8859-1 locale, and also that +it has no tabs so it needs tab to space translation. + +swtp|ct8212|southwest technical products ct8212, + cols#82, lines#24, + bel=^G, civis=^E, clear=^L, cnorm=^U, cr=\r, + cub=^\^D%p1%c, cub1=^D, cud=^\^B%p1%c, cud1=^B, + cuf1=^R, cup=^K%p2%{32}%+%c%p1%{32}%+%c, + cuu=^\^A%p1%c, cuu1=^A, dch1=^\^H, dl1=^Z, ed=^V, el=^F, + el1=^\^F, home=^P, hpa=^\^W%p1%{32}%+%c, ich1=^\^X, + il1=^\^Y, ind=^N, + is2=^_^A$<250>^\^R$<50>^^^D^^^T^_^J\040^^^G^^^O^^^Z^]^W^I^R, + kbs=^H, kcub1=^B, kcud1=^N, kcuf1=^F, kcuu1=^P, khome=^A, + ll=^C, mc4=^]^G, mc5=^]^K, nel=\r\n, ri=^O, rmir=, rmso=^^^F, + smir=, smso=^^^V, vpa=^\^G%p1%{32}%+%c, + +****************************************************************************/ + +#include "emu.h" +#include "machine/swtpc8212.h" +#include "machine/input_merger.h" +#include "screen.h" +#include "speaker.h" + +swtpc8212_device::swtpc8212_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , m_maincpu(*this, "maincpu") + , m_pia0(*this, "pia0") + , m_pia1(*this, "pia1") + , m_uart(*this, "uart") + , m_crtc(*this, "crtc") + , m_chargen1(*this, "chargen1") + , m_chargen2(*this, "chargen2") + , m_video_ram(*this, "videoram") + , m_config(*this, "CONFIG") + , m_keypad(*this, "KEYPAD") + , m_one_stop_bit(*this, "ONE_STOP_BIT") + , m_bell_timer(nullptr) + , m_beeper(*this, "beeper") + , m_printer(*this, "printer") + , m_rs232_conn_txd_handler(*this) + , m_rs232_conn_dtr_handler(*this) + , m_rs232_conn_rts_handler(*this) +{ +} + +swtpc8212_device::swtpc8212_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : swtpc8212_device(mconfig, SWTPC8212, tag, owner, clock) +{ +} + +WRITE8_MEMBER(swtpc8212_device::latch_w) +{ + // Bits 0 to 3 control outputs that are intended to control and tape + // 'read' and 'punch' operations. These are strobes, about 10usec, and + // intended to trigger on the falling edge. + // + // Bit 0 - Read on output + // Bit 1 - Read off output + // Bit 2 - Punch on output + // Bit 3 - Punch off output + + // Bit 4 - ?? usually high + // Bit 5 - ?? usually low + + // Bits 6 and 7 change with the screen format. + // + // Bit 6 is zero for formats I and II, and one for formats III and IV + // and for the graphics format. Assume this selects between the + // characters sets, so formats III and IV might use an alternative + // custom text character set. + // + // Bit 6 - character set: 0 - standard; 1 - alternate/graphics. + // + // Bit 7 is zero in formats I, II, III, and IV, and one for the + // graphics format. Assume this controls the horizontal + // inter-character gap, eliminating the gap for the graphics format. + // + // Bit 7 - character width: 0 - 9 dots; 1 - 8 dots. + // + if (BIT(data, 7) == 0) + m_crtc->set_char_width(9); + else + m_crtc->set_char_width(8); + + m_latch_data = data; +} + + +READ8_MEMBER(swtpc8212_device::pia0_pa_r) +{ + // PA0 controls the 'duplex' mode, the echoing back of characters, and + // appears to connect to a switch on the outer casing. + // + // PA1 On the CT-82 this enabled or disabled use of an optional ROM, + // but that function is disabled in the 8212, and this is probably + // unused. + // + // PA2 is Jumper B, and PA3 is Jumper A. + uint8_t config = m_config->read(); + + return (m_keypad_data << 4) | config; +} + +READ8_MEMBER(swtpc8212_device::pia0_pb_r) +{ + return m_keyboard_data; +} + +void swtpc8212_device::keyboard_put(uint8_t data) +{ + m_keyboard_data = data; + // Triggers on the falling edge. + m_pia0->cb1_w(ASSERT_LINE); + m_pia0->cb1_w(CLEAR_LINE); + m_pia0->cb1_w(ASSERT_LINE); +} + +INPUT_CHANGED_MEMBER(swtpc8212_device::keypad_changed) +{ + uint16_t keys = m_keypad->read(); + uint8_t n; + + for (n = 0; n < 16; n++) + { + if (BIT(keys, n)) + break; + } + + m_keypad_data = n; + + if (newval) + { + m_pia0->ca1_w(ASSERT_LINE); + m_pia0->ca1_w(CLEAR_LINE); + m_pia0->ca1_w(ASSERT_LINE); + } +} + +WRITE_LINE_MEMBER(swtpc8212_device::pia0_ca2_w) +{ + if (state == 0) + { + m_beeper->set_state(1); + m_bell_timer->reset(attotime::from_msec(250)); + } +} + +WRITE8_MEMBER(swtpc8212_device::pia1_pa_w) +{ + // External parallel printer data output. + m_printer_data = data; +} + +READ_LINE_MEMBER(swtpc8212_device::pia1_ca1_r) +{ + // External parallel printer busy input. + return 0; +} + +WRITE_LINE_MEMBER(swtpc8212_device::pia1_ca2_w) +{ + // External parallel printer data ready. + + // Trigger on the falling edge. + if (m_printer_data_ready == 1 && state == 0) + { + m_printer->output(m_printer_data); + // Toggle the printer busy line as the software waits for a + // falling edge. + m_pia1->ca1_w(CLEAR_LINE); + m_pia1->ca1_w(ASSERT_LINE); + m_pia1->ca1_w(CLEAR_LINE); + } + m_printer_data_ready = state; +} + +MC6845_UPDATE_ROW(swtpc8212_device::update_row) +{ + int x = 0; + uint8_t *chargen = BIT(m_latch_data, 6) == 0 ? m_chargen1 : m_chargen2; + + for (int column = 0; column < x_count; column++) + { + uint8_t code = m_video_ram[(ma + column) & 0x07ff]; + int dcursor = (column == cursor_x); + + offs_t address = ra < 16 ? (code & 0x7f) | (ra & 0x0f) << 7 : 0; + uint8_t data = chargen[address]; + uint8_t intensity = BIT(code, 7); + + for (int bit = 0; bit < 8; bit++) + { + int dout = BIT(data, 7); + uint32_t font_color = 0; + if ((dcursor ^ dout) && de) + { + if (intensity) + font_color = rgb_t(0x10, 0xff, 0x10); + else + font_color = rgb_t(0x00, 0xd0, 0x00); + } + bitmap.pix32(y, x++) = font_color; + data <<= 1; + } + + // Gap between characters + if (BIT(m_latch_data, 7) == 0) + x++; + } +} + +void swtpc8212_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case BELL_TIMER_ID: + m_beeper->set_state(0); + break; + } +} + +WRITE_LINE_MEMBER(swtpc8212_device::rs232_conn_dcd_w) +{ + m_uart->dcd_w(state); +} + +WRITE_LINE_MEMBER(swtpc8212_device::rs232_conn_dsr_w) +{ + m_uart->dsr_w(state); +} + +WRITE_LINE_MEMBER(swtpc8212_device::rs232_conn_ri_w) +{ + m_uart->ri_w(state); +} + +WRITE_LINE_MEMBER(swtpc8212_device::rs232_conn_cts_w) +{ + m_uart->cts_w(state); +} + +WRITE_LINE_MEMBER(swtpc8212_device::rs232_conn_rxd_w) +{ + m_uart->rx_w(state); +} + +WRITE_LINE_MEMBER(swtpc8212_device::write_txd) +{ + m_rs232_conn_txd_handler(state); +} + +WRITE_LINE_MEMBER(swtpc8212_device::write_dtr) +{ + m_rs232_conn_dtr_handler(state); +} + +WRITE_LINE_MEMBER(swtpc8212_device::write_rts) +{ + m_rs232_conn_rts_handler(state); +} + +void swtpc8212_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 swtpc8212_device::device_start() +{ + m_bell_timer = timer_alloc(BELL_TIMER_ID); + + save_item(NAME(m_latch_data)); + save_item(NAME(m_keyboard_data)); + save_item(NAME(m_printer_data)); + save_item(NAME(m_printer_data_ready)); +} + +void swtpc8212_device::device_reset() +{ + m_keyboard_data = 0; + m_pia0->cb1_w(ASSERT_LINE); + m_keypad_data = 0; + m_pia0->ca1_w(ASSERT_LINE); + + m_latch_data = 0x1f; + + m_beeper->set_state(0); + + m_printer_data = 0; + m_printer_data_ready = 1; + m_pia1->ca1_w(CLEAR_LINE); + + if (m_one_stop_bit->read()) + { + // Patch the firmware to use one stop bit. + uint8_t* program = memregion("program")->base(); + program[0x01ad] = 0x02; + } +} + +void swtpc8212_device::mem_map(address_map &map) +{ + map(0x0000, 0x007f).ram(); + map(0x0080, 0x0083).rw("pia0", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0x0088, 0x0088).w("crtc", FUNC(mc6845_device::address_w)); + map(0x0089, 0x0089).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); + map(0x008c, 0x008c).w(FUNC(swtpc8212_device::latch_w)); + map(0x0090, 0x0097).rw("uart", FUNC(ins8250_device::ins8250_r), FUNC(ins8250_device::ins8250_w)); + map(0x0098, 0x009b).rw("pia1", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0x4000, 0x47ff).mirror(0x1800).ram().share(m_video_ram); + map(0xb800, 0xbfff).rom().region("program", 0); + map(0xc000, 0xc7ff).mirror(0x3800).rom().region("program", 0x800); +} + + + + +INPUT_PORTS_START(swtpc8212) + + PORT_START("KEYPAD") + PORT_BIT(0x0002U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("7 / Form") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x0004U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("8 / Xmit") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x0001U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("9 / ??") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x0008U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("\xC3\xB7 / ??") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x0200U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("4 / Scroll Up") PORT_CODE(KEYCODE_PGDN) PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x0400U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("5 / \xE2\x86\x91") PORT_CODE(KEYCODE_UP) PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x0100U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("6 / Insert") PORT_CODE(KEYCODE_0_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x0800U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("\xC3\x97 / ??") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x0020U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("1 / \xE2\x86\x90") PORT_CODE(KEYCODE_LEFT) PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x0040U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("2 / Home") PORT_CODE(KEYCODE_HOME) PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x0010U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("3 / \xE2\x86\x92") PORT_CODE(KEYCODE_RIGHT) PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x0080U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("- / LF") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x2000U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("0 / Scroll Down") PORT_CODE(KEYCODE_PGUP) PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x4000U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("0 / \xE2\x86\x93") PORT_CODE(KEYCODE_DOWN) PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x1000U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME(". / Delete") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + PORT_BIT(0x8000U, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("+ / CR") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc8212_device, keypad_changed, 0) + + PORT_START("DIP_SWITCHES") + PORT_DIPNAME(0x1f, 0x19, "Baud Rate") PORT_DIPLOCATION("DIP:4,3,2,1,0") + PORT_DIPSETTING(0x04, "110") + PORT_DIPSETTING(0x0a, "300") + PORT_DIPSETTING(0x0d, "600") + PORT_DIPSETTING(0x0f, "1200") + PORT_DIPSETTING(0x12, "2400") + PORT_DIPSETTING(0x16, "4800") + PORT_DIPSETTING(0x18, "7200") + PORT_DIPSETTING(0x19, "9600") + PORT_DIPSETTING(0x1c, "19200") + PORT_DIPSETTING(0x1f, "38400") + PORT_DIPNAME(0x20, 0x00, "Mode switch") PORT_DIPLOCATION("DIP:5") + PORT_DIPSETTING(0x00, "Conversational") + PORT_DIPSETTING(0x20, "Page edit") + PORT_DIPNAME(0x40, 0x00, "No Parity") PORT_DIPLOCATION("DIP:6") + PORT_DIPSETTING(0x00, "No Parity") + PORT_DIPSETTING(0x40, "Parity") + PORT_DIPNAME(0x80, 0x00, "Parity Select") PORT_DIPLOCATION("DIP:7") + PORT_DIPSETTING(0x00, "Odd or Mark") + PORT_DIPSETTING(0x80, "Even or Space") + + PORT_START("CONFIG") + PORT_CONFNAME(0x01, 0x01, "Duplex") + PORT_CONFSETTING(0x00, "Full duplex") + PORT_CONFSETTING(0x01, "Half duplex") + PORT_CONFNAME(0x02, 0x00, "Option ROM (Not used)") + PORT_CONFSETTING(0x00, DEF_STR(On)) + PORT_CONFSETTING(0x02, DEF_STR(Off)) + PORT_CONFNAME(0x04, 0x04, "Parity Select (Jumper B)") + PORT_CONFSETTING(0x00, "Odd or Even (On)") + PORT_CONFSETTING(0x04, "Mark or Space (Off)") + PORT_CONFNAME(0x08, 0x08, "Data bits (Jumper A)") + PORT_CONFSETTING(0x00, "7 bit data (On)") + PORT_CONFSETTING(0x08, "8 bit data (Off)") + + PORT_START("ONE_STOP_BIT") + PORT_CONFNAME(1, 1, "One stop bit patch") + PORT_CONFSETTING(0, "No") + PORT_CONFSETTING(1, "Yes - apply patch") + +INPUT_PORTS_END + + +ROM_START( swtpc8212 ) + ROM_REGION( 0x1000, "program", 0 ) + ROM_LOAD( "8224g_ver.1.1_6oct80.ic1", 0x0000, 0x0800, CRC(7d7f3c21) SHA1(f7e6e20b36a1c724a4e348bc784d0b7b5fb462a3) ) + ROM_LOAD( "8224g_ver.1.1_6oct80.ic2", 0x0800, 0x0800, CRC(2b118c22) SHA1(5fa031c834c7c582d5715764941499fcef51f477) ) + + ROM_REGION( 0x0800, "chargen1", 0 ) + ROM_LOAD( "mcm66750.rom", 0x0000, 0x0800, CRC(aedc2830) SHA1(49ce17d5b5cefb24e89ed3fd59887a652501b919) ) + ROM_REGION( 0x0800, "chargen2", 0 ) + ROM_LOAD( "grafix_8x12_22aug80.bin", 0x0000, 0x0800, CRC(a525ed65) SHA1(813d2e85ddb258c5b032b959e695ad33200cbcc4) ) +ROM_END + +void swtpc8212_device::device_add_mconfig(machine_config &config) +{ + M6802(config, m_maincpu, 1.8432_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &swtpc8212_device::mem_map); + + INPUT_MERGER_ANY_HIGH(config, "mainirq").output_handler().set_inputline(m_maincpu, M6802_IRQ_LINE); + + // PA - various jumpers and keypad inputs. + // PB - parallel keyboard data input. + // CA1 - parallel keypad input strobe. + // CA2 - output, bell. + // CB1 - parallel keyboard input strobe. + // CB2 ?? + PIA6821(config, m_pia0); + m_pia0->readpa_handler().set(FUNC(swtpc8212_device::pia0_pa_r)); + m_pia0->readpb_handler().set(FUNC(swtpc8212_device::pia0_pb_r)); + m_pia0->ca2_handler().set(FUNC(swtpc8212_device::pia0_ca2_w)); + m_pia0->irqa_handler().set("mainirq", FUNC(input_merger_device::in_w<0>)); + m_pia0->irqb_handler().set("mainirq", FUNC(input_merger_device::in_w<1>)); + + // PA - parallel printer data outputs. + // PB - various config inputs. + // CA1 - parallel printer, 'busy' input. + // CA2 - parallel printer, 'data ready' output. + // CB1 - Handshake input? + // CB2 - Handshake output? + PIA6821(config, m_pia1); + m_pia1->writepa_handler().set(FUNC(swtpc8212_device::pia1_pa_w)); + m_pia1->readca1_handler().set(FUNC(swtpc8212_device::pia1_ca1_r)); + m_pia1->ca2_handler().set(FUNC(swtpc8212_device::pia1_ca2_w)); + m_pia1->readpb_handler().set_ioport("DIP_SWITCHES"); + + INS8250(config, m_uart, 1.8432_MHz_XTAL); + m_uart->out_tx_callback().set(FUNC(swtpc8212_device::write_txd)); + m_uart->out_dtr_callback().set(FUNC(swtpc8212_device::write_dtr)); + m_uart->out_rts_callback().set(FUNC(swtpc8212_device::write_rts)); + m_uart->out_int_callback().set("mainirq", FUNC(input_merger_device::in_w<2>)); + + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(17.0748_MHz_XTAL, 918, 0, 738, 310, 0, 280); + screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); + + MC6845(config, m_crtc, 17.0748_MHz_XTAL / 9); + m_crtc->set_char_width(9); + m_crtc->set_screen("screen"); + m_crtc->set_show_border_area(false); + m_crtc->set_update_row_callback(FUNC(swtpc8212_device::update_row)); + + generic_keyboard_device &keyboard(GENERIC_KEYBOARD(config, "keyboard", 0)); + keyboard.set_keyboard_callback(FUNC(swtpc8212_device::keyboard_put)); + + SPEAKER(config, "bell").front_center(); + BEEP(config, m_beeper, 2000); + m_beeper->add_route(ALL_OUTPUTS, "bell", 0.25); + + PRINTER(config, m_printer, 0); +} + +ioport_constructor swtpc8212_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(swtpc8212); +} + +const tiny_rom_entry *swtpc8212_device::device_rom_region() const +{ + return ROM_NAME(swtpc8212); +} + +DEFINE_DEVICE_TYPE(SWTPC8212, swtpc8212_device, "swtpc8212_device", "SWTPC8212") diff --git a/src/devices/machine/swtpc8212.h b/src/devices/machine/swtpc8212.h new file mode 100644 index 00000000000..7f2ed05ad68 --- /dev/null +++ b/src/devices/machine/swtpc8212.h @@ -0,0 +1,102 @@ +// license:BSD-3-Clause +// copyright-holders:AJR,68bit + +#ifndef MAME_MACHINE_SWTPC8212_H +#define MAME_MACHINE_SWTPC8212_H + +#pragma once + +#include "cpu/m6800/m6800.h" +#include "imagedev/printer.h" +#include "machine/6821pia.h" +#include "machine/ins8250.h" +#include "machine/terminal.h" +#include "video/mc6845.h" + +INPUT_PORTS_EXTERN(swtpc8212); + + +class swtpc8212_device : public device_t +{ +public: + swtpc8212_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_INPUT_CHANGED_MEMBER(keypad_changed); + + // 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: + swtpc8212_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) 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: + enum + { + BELL_TIMER_ID = 1 + }; + + void mem_map(address_map &map); + + required_device m_maincpu; + required_device m_pia0; + required_device m_pia1; + required_device m_uart; + required_device m_crtc; + required_region_ptr m_chargen1; + required_region_ptr m_chargen2; + required_shared_ptr m_video_ram; + required_ioport m_config; + required_ioport m_keypad; + required_ioport m_one_stop_bit; + emu_timer *m_bell_timer; + required_device m_beeper; + required_device m_printer; + + devcb_write_line m_rs232_conn_txd_handler; + devcb_write_line m_rs232_conn_dtr_handler; + devcb_write_line m_rs232_conn_rts_handler; + + MC6845_UPDATE_ROW(update_row); + + DECLARE_WRITE8_MEMBER(latch_w); + uint8_t m_latch_data; + + DECLARE_READ8_MEMBER(pia0_pa_r); + DECLARE_READ8_MEMBER(pia0_pb_r); + DECLARE_WRITE_LINE_MEMBER(pia0_ca2_w); + + DECLARE_WRITE8_MEMBER(pia1_pa_w); + DECLARE_READ_LINE_MEMBER(pia1_ca1_r); + DECLARE_WRITE_LINE_MEMBER(pia1_ca2_w); + + uint8_t m_keyboard_data; + uint8_t m_keypad_data; + uint8_t m_printer_data; + uint8_t m_printer_data_ready; + + void keyboard_put(uint8_t data); + + DECLARE_WRITE_LINE_MEMBER(write_txd); + DECLARE_WRITE_LINE_MEMBER(write_dtr); + DECLARE_WRITE_LINE_MEMBER(write_rts); +}; + +DECLARE_DEVICE_TYPE(SWTPC8212, swtpc8212_device) + +#endif // MAME_MACHINE_SWTPC8212_H diff --git a/src/mame/drivers/swtpc8212.cpp b/src/mame/drivers/swtpc8212.cpp index 1191198b431..d6b38d27e01 100644 --- a/src/mame/drivers/swtpc8212.cpp +++ b/src/mame/drivers/swtpc8212.cpp @@ -1,124 +1,53 @@ // license:BSD-3-Clause -// copyright-holders:AJR -/**************************************************************************** +// copyright-holders:68bit +/*************************************************************************** - Skeleton driver for Southwest Technical Products video terminal. +SWTPC 8212 Video Terminal + +Front end interfacing the terminal device to a MAME RS232 port. ****************************************************************************/ #include "emu.h" -//#include "bus/rs232/rs232.h" -#include "cpu/m6800/m6800.h" -#include "machine/6821pia.h" -#include "machine/input_merger.h" -#include "machine/ins8250.h" -#include "video/mc6845.h" -#include "screen.h" - +#include "machine/swtpc8212.h" +#include "bus/rs232/rs232.h" class swtpc8212_state : public driver_device { public: - swtpc8212_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_chargen(*this, "chargen") - { - } + swtpc8212_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag) + , m_swtpc8212(*this, "swtpc8212") + , m_rs232(*this, "rs232") + { } - void swtpc8212(machine_config &mconfig); + void swtpc8212(machine_config &config); private: - MC6845_UPDATE_ROW(update_row); - - void mem_map(address_map &map); - - required_device m_maincpu; - required_region_ptr m_chargen; + required_device m_swtpc8212; + required_device m_rs232; }; -MC6845_UPDATE_ROW(swtpc8212_state::update_row) -{ -} - - -void swtpc8212_state::mem_map(address_map &map) -{ - map(0x0000, 0x007f).ram(); - map(0x0080, 0x0083).rw("pia0", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x0088, 0x0088).w("crtc", FUNC(mc6845_device::address_w)); - map(0x0089, 0x0089).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); - map(0x0090, 0x0097).rw("uart", FUNC(ins8250_device::ins8250_r), FUNC(ins8250_device::ins8250_w)); - map(0x0098, 0x009b).rw("pia1", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x4800, 0x4fff).ram(); - map(0xb800, 0xbfff).rom().region("program", 0); - map(0xc000, 0xc7ff).mirror(0x3800).rom().region("program", 0x800); -} - - -static INPUT_PORTS_START(swtpc8212) - PORT_START("DSW") - PORT_DIPNAME(0x01, 0x00, DEF_STR(Unknown)) - PORT_DIPSETTING(0x01, DEF_STR(Off)) - PORT_DIPSETTING(0x00, DEF_STR(On)) - PORT_DIPNAME(0x02, 0x00, DEF_STR(Unknown)) - PORT_DIPSETTING(0x02, DEF_STR(Off)) - PORT_DIPSETTING(0x00, DEF_STR(On)) - PORT_DIPNAME(0x04, 0x00, DEF_STR(Unknown)) - PORT_DIPSETTING(0x04, DEF_STR(Off)) - PORT_DIPSETTING(0x00, DEF_STR(On)) - PORT_DIPNAME(0x08, 0x00, DEF_STR(Unknown)) - PORT_DIPSETTING(0x08, DEF_STR(Off)) - PORT_DIPSETTING(0x00, DEF_STR(On)) - PORT_DIPNAME(0x10, 0x00, DEF_STR(Unknown)) - PORT_DIPSETTING(0x10, DEF_STR(Off)) - PORT_DIPSETTING(0x00, DEF_STR(On)) - PORT_DIPNAME(0x20, 0x00, DEF_STR(Unknown)) - PORT_DIPSETTING(0x20, DEF_STR(Off)) - PORT_DIPSETTING(0x00, DEF_STR(On)) - PORT_DIPNAME(0x40, 0x00, DEF_STR(Unknown)) - PORT_DIPSETTING(0x40, DEF_STR(Off)) - PORT_DIPSETTING(0x00, DEF_STR(On)) - PORT_DIPNAME(0x80, 0x00, DEF_STR(Unknown)) - PORT_DIPSETTING(0x80, DEF_STR(Off)) - PORT_DIPSETTING(0x00, DEF_STR(On)) -INPUT_PORTS_END void swtpc8212_state::swtpc8212(machine_config &config) { - M6802(config, m_maincpu, 1.8432_MHz_XTAL); - m_maincpu->set_addrmap(AS_PROGRAM, &swtpc8212_state::mem_map); - - INPUT_MERGER_ANY_HIGH(config, "mainirq").output_handler().set_inputline(m_maincpu, M6802_IRQ_LINE); - - pia6821_device &pia0(PIA6821(config, "pia0")); - pia0.irqa_handler().set("mainirq", FUNC(input_merger_device::in_w<0>)); - pia0.irqb_handler().set("mainirq", FUNC(input_merger_device::in_w<1>)); - - PIA6821(config, "pia1"); - - ins8250_device &uart(INS8250(config, "uart", 1.8432_MHz_XTAL)); - uart.out_int_callback().set("mainirq", FUNC(input_merger_device::in_w<2>)); - - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(17.0748_MHz_XTAL, 918, 0, 738, 310, 0, 280); - screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); - - mc6845_device &crtc(MC6845(config, "crtc", 17.0748_MHz_XTAL / 9)); - crtc.set_char_width(9); - crtc.set_screen("screen"); - crtc.set_show_border_area(false); - crtc.set_update_row_callback(FUNC(swtpc8212_state::update_row)); + SWTPC8212(config, m_swtpc8212, 0); + + RS232_PORT(config, m_rs232, default_rs232_devices, nullptr); + m_rs232->dcd_handler().set(m_swtpc8212, FUNC(swtpc8212_device::rs232_conn_dcd_w)); + m_rs232->dsr_handler().set(m_swtpc8212, FUNC(swtpc8212_device::rs232_conn_dsr_w)); + m_rs232->ri_handler().set(m_swtpc8212, FUNC(swtpc8212_device::rs232_conn_ri_w)); + m_rs232->cts_handler().set(m_swtpc8212, FUNC(swtpc8212_device::rs232_conn_cts_w)); + m_rs232->rxd_handler().set(m_swtpc8212, FUNC(swtpc8212_device::rs232_conn_rxd_w)); + + m_swtpc8212->rs232_conn_txd_handler().set(m_rs232, FUNC(rs232_port_device::write_txd)); + m_swtpc8212->rs232_conn_dtr_handler().set(m_rs232, FUNC(rs232_port_device::write_dtr)); + m_swtpc8212->rs232_conn_rts_handler().set(m_rs232, FUNC(rs232_port_device::write_rts)); } -ROM_START( swtpc8212 ) // MC6802P, 2xMC6821P, INS8250N, MCM66750, MC6845P, bank of 8 dips, crystals 17.0748 (video), 1.8432 (cpu/uart). On the back is a 25-pin RS-232 port, and a 25-pin printer port. - ROM_REGION( 0x1000, "program", 0 ) - ROM_LOAD( "8224g_ver.1.1_6oct80.ic1", 0x0000, 0x0800, CRC(7d7f3c21) SHA1(f7e6e20b36a1c724a4e348bc784d0b7b5fb462a3) ) - ROM_LOAD( "8224g_ver.1.1_6oct80.ic2", 0x0800, 0x0800, CRC(2b118c22) SHA1(5fa031c834c7c582d5715764941499fcef51f477) ) - - ROM_REGION( 0x0800, "chargen", 0 ) - ROM_LOAD( "grafix_8x12_22aug80.bin", 0x0000, 0x0800, CRC(a525ed65) SHA1(813d2e85ddb258c5b032b959e695ad33200cbcc4) ) +ROM_START(swtpc8212) ROM_END -COMP(1980, swtpc8212, 0, 0, swtpc8212, swtpc8212, swtpc8212_state, empty_init, "Southwest Technical Products", "SWTPC 8212 Video Terminal", MACHINE_IS_SKELETON) +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP(1980, swtpc8212, 0, 0, swtpc8212, 0, swtpc8212_state, empty_init, "Southwest Technical Products", "SWTPC 8212 Video Terminal", 0 ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index ec5227d906d..432325ca517 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -37298,7 +37298,7 @@ swtpc09i // S09, DC4 Floppy + PIA IDE SBUG rom - FLEX swtpc09u // S09, DMF2 Floppy UNIBUG rom - UniFLEX @source:swtpc8212.cpp -swtpc8212 // +swtpc8212 // Terminal @source:swyft.cpp swyft // -- cgit v1.2.3