1 // license:BSD-3-Clause
2 // copyright-holders:AJR
3 /****************************************************************************
4
5 Skeleton driver for Micro-Term ERGO 201 terminal.
6
7 The ERGO 201 belongs to one half of a paired series of terminals. Half
8 of these terminals emulate the VT100 and support a 132 column mode; the
9 other half emulate the VT52, ADM3A and ACT-5A instead but do appear to
10 have been influenced by the VT100 in overall design.
11
12 The first members of this series, the MIME 340 (non-VT100 emulation)
13 and MIME 740 (VT100 emulation), were single units with non-detachable
14 keyboards like Micro-Term's older ACT and MIME terminals. They were
15 respectively succeeded by the ERGO 2000 and ERGO 3001 with tiltable
16 screens and similar but detached keyboards. The ERGO 201 and ERGO 301
17 appear to be low-cost redesigns of these two with keyboards even more
18 closely resembling the VT100's, with a Plot 10 graphics board as an
19 option. Also introduced around this time was the ERGO 4000, a
20 portrait-mode terminal displaying 66 lines of 80 characters.
21
22 ****************************************************************************/
23
24 #include "emu.h"
25 //#include "bus/rs232/rs232.h"
26 #include "cpu/z80/z80.h"
27 #include "machine/ay31015.h"
28 #include "machine/clock.h"
29 #include "machine/er1400.h"
30 //#include "machine/ergo201_kbd.h"
31 #include "machine/z80ctc.h"
32 #include "machine/z80sio.h"
33 #include "video/tms9927.h"
34 #include "screen.h"
35
36 class ergo201_state : public driver_device
37 {
38 public:
ergo201_state(const machine_config & mconfig,device_type type,const char * tag)39 ergo201_state(const machine_config &mconfig, device_type type, const char *tag)
40 : driver_device(mconfig, type, tag)
41 , m_maincpu(*this, "maincpu")
42 , m_earom(*this, "earom")
43 , m_kbuart(*this, "kbuart")
44 , m_vtac(*this, "vtac")
45 , m_chargen(*this, "chargen")
46 {
47 }
48
49 void ergo201(machine_config &config);
50
51 protected:
52 virtual void machine_start() override;
53
54 private:
55 u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
56
57 void earom_latch_w(u8 data);
58 u8 status_r();
59
60 void mem_map(address_map &map);
61 void io_map(address_map &map);
62
63 required_device<z80_device> m_maincpu;
64 required_device<er1400_device> m_earom;
65 required_device<ay31015_device> m_kbuart;
66 required_device<tms9927_device> m_vtac;
67 required_region_ptr<u8> m_chargen;
68 };
69
machine_start()70 void ergo201_state::machine_start()
71 {
72 m_kbuart->write_tsb(0);
73 m_kbuart->write_nb1(1);
74 m_kbuart->write_nb2(1);
75 m_kbuart->write_np(1);
76 m_kbuart->write_cs(1);
77 m_kbuart->write_swe(0);
78 }
79
screen_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)80 u32 ergo201_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
81 {
82 return 0;
83 }
84
85
earom_latch_w(u8 data)86 void ergo201_state::earom_latch_w(u8 data)
87 {
88 m_earom->c1_w(BIT(data, 0));
89 m_earom->data_w(BIT(data, 1));
90 m_earom->c3_w(BIT(data, 2));
91 m_earom->c2_w(BIT(data, 3));
92 m_earom->clock_w(BIT(data, 4));
93 }
94
status_r()95 u8 ergo201_state::status_r()
96 {
97 return (m_kbuart->dav_r() << 1) | (m_earom->data_r() << 5);
98 }
99
mem_map(address_map & map)100 void ergo201_state::mem_map(address_map &map)
101 {
102 map(0x0000, 0x5fff).rom().region("program", 0);
103 map(0x1000, 0x1000).nopw();
104 map(0x2000, 0x2000).unmapw(); // screen brightness?
105 map(0x3000, 0x300f).w(m_vtac, FUNC(tms9927_device::write));
106 map(0x4000, 0x4000).w(FUNC(ergo201_state::earom_latch_w));
107 map(0x5000, 0x5000).w(m_kbuart, FUNC(ay31015_device::transmit));
108 map(0x6000, 0x6000).r(m_kbuart, FUNC(ay31015_device::receive));
109 map(0x6001, 0x6001).r(FUNC(ergo201_state::status_r));
110 map(0x7000, 0x77ff).ram();
111 map(0x8000, 0x87ff).ram();
112 map(0xc000, 0xc7ff).ram();
113 }
114
io_map(address_map & map)115 void ergo201_state::io_map(address_map &map)
116 {
117 map.global_mask(0xff);
118 map(0xf4, 0xf7).rw("dart", FUNC(z80dart_device::cd_ba_r), FUNC(z80dart_device::cd_ba_w));
119 map(0xf8, 0xfb).rw("ctc", FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
120 }
121
122
123 static INPUT_PORTS_START(ergo201)
124 INPUT_PORTS_END
125
126 static const z80_daisy_config daisy_chain[] =
127 {
128 { "ctc" },
129 { "dart" },
130 { nullptr }
131 };
132
ergo201(machine_config & config)133 void ergo201_state::ergo201(machine_config &config)
134 {
135 Z80(config, m_maincpu, 16.313_MHz_XTAL / 4); // SGS Z8400AB1 (divider guessed)
136 m_maincpu->set_addrmap(AS_PROGRAM, &ergo201_state::mem_map);
137 m_maincpu->set_addrmap(AS_IO, &ergo201_state::io_map);
138 m_maincpu->set_daisy_config(daisy_chain);
139
140 z80ctc_device &ctc(Z80CTC(config, "ctc", 16.313_MHz_XTAL / 4)); // SGS Z8430AB1
141 ctc.set_clk<0>(16.313_MHz_XTAL / 53);
142 ctc.set_clk<1>(16.313_MHz_XTAL / 53);
143 ctc.set_clk<2>(16.313_MHz_XTAL / 53);
144 ctc.zc_callback<0>().set("dart", FUNC(z80dart_device::rxca_w));
145 ctc.zc_callback<1>().set("dart", FUNC(z80dart_device::txca_w));
146 ctc.zc_callback<2>().set("dart", FUNC(z80dart_device::rxtxcb_w));
147 ctc.intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
148
149 z80dart_device &dart(Z80DART(config, "dart", 16.313_MHz_XTAL / 4)); // Zilog Z8470A PS
150 dart.out_txda_callback().set("dart", FUNC(z80dart_device::rxa_w));
151 dart.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
152
153 AY31015(config, m_kbuart); // GI AY-3-1015D
154 m_kbuart->set_auto_rdav(true);
155
156 clock_device &kbclock(CLOCK(config, "kbclock", 10000));
157 kbclock.signal_handler().set(m_kbuart, FUNC(ay31015_device::write_rcp));
158 kbclock.signal_handler().append(m_kbuart, FUNC(ay31015_device::write_tcp));
159
160 ER1400(config, m_earom); // GI ER-1400
161
162 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
163 screen.set_raw(16.313_MHz_XTAL, 855, 0, 720, 318, 0, 300);
164 screen.set_screen_update(FUNC(ergo201_state::screen_update));
165 screen.set_color(rgb_t::green()); // P31
166
167 CRT5037(config, m_vtac, 16.313_MHz_XTAL / 9); // TI TMS9937NL
168 m_vtac->set_char_width(9);
169 m_vtac->set_screen("screen");
170 }
171
172
173 ROM_START(ergo201)
174 ROM_REGION(0x6000, "program", 0) // Checksum is off by a few bits, so at least one dump is bad
175 ROM_LOAD("201.u18", 0x0000, 0x2000, CRC(fec9fa3c) SHA1(3c1f9de9f62e74fbd1c9b67736d0959c0f6b46b1) BAD_DUMP) // M5L2764K
176 ROM_LOAD("r1.0_special_5786.u73", 0x2000, 0x2000, CRC(5a31b6bc) SHA1(6929fa8f6d481790cd43732a9a97a9110ad9fb6c)) // MBM2764-25
177 ROM_LOAD("201.u17", 0x4000, 0x2000, CRC(e7197403) SHA1(96fff6fb30eeac616d71da731b0ea79c8cd35096)) // M5L2764K
178
179 ROM_REGION(0x1000, "chargen", 0)
180 ROM_LOAD("201.u53", 0x0000, 0x1000, CRC(907dac04) SHA1(5bae6680f1ef3f5335a223bdf403e8f3ef272430)) // MBM2732A-35
181 ROM_END
182
183 COMP(1985, ergo201, 0, 0, ergo201, ergo201, ergo201_state, empty_init, "Micro-Term / Kurzweil Computer Products", "ERGO 201 (Special #9233)", MACHINE_IS_SKELETON)
184