// license:BSD-3-Clause // copyright-holders:AJR /**************************************************************************** Skeleton driver for Micro-Term ERGO 201 terminal. The ERGO 201 belongs to one half of a paired series of terminals. Half of these terminals emulate the VT100 and support a 132 column mode; the other half emulate the VT52, ADM3A and ACT-5A instead but do appear to have been influenced by the VT100 in overall design. The first members of this series, the MIME 340 (non-VT100 emulation) and MIME 740 (VT100 emulation), were single units with non-detachable keyboards like Micro-Term's older ACT and MIME terminals. They were respectively succeeded by the ERGO 2000 and ERGO 3001 with tiltable screens and similar but detached keyboards. The ERGO 201 and ERGO 301 appear to be low-cost redesigns of these two with keyboards even more closely resembling the VT100's, with a Plot 10 graphics board as an option. Also introduced around this time was the ERGO 4000, a portrait-mode terminal displaying 66 lines of 80 characters. ****************************************************************************/ #include "emu.h" //#include "bus/rs232/rs232.h" #include "cpu/z80/z80.h" #include "machine/ay31015.h" #include "machine/clock.h" #include "machine/er1400.h" //#include "machine/ergo201_kbd.h" #include "machine/z80ctc.h" #include "machine/z80sio.h" #include "video/tms9927.h" #include "screen.h" class ergo201_state : public driver_device { public: ergo201_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_earom(*this, "earom") , m_kbuart(*this, "kbuart") , m_vtac(*this, "vtac") , m_chargen(*this, "chargen") { } void ergo201(machine_config &config); protected: virtual void machine_start() override; private: u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void earom_latch_w(u8 data); u8 status_r(); void mem_map(address_map &map); void io_map(address_map &map); required_device m_maincpu; required_device m_earom; required_device m_kbuart; required_device m_vtac; required_region_ptr m_chargen; }; void ergo201_state::machine_start() { m_kbuart->write_tsb(0); m_kbuart->write_nb1(1); m_kbuart->write_nb2(1); m_kbuart->write_np(1); m_kbuart->write_cs(1); m_kbuart->write_swe(0); } u32 ergo201_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { return 0; } void ergo201_state::earom_latch_w(u8 data) { m_earom->c1_w(BIT(data, 0)); m_earom->data_w(BIT(data, 1)); m_earom->c3_w(BIT(data, 2)); m_earom->c2_w(BIT(data, 3)); m_earom->clock_w(BIT(data, 4)); } u8 ergo201_state::status_r() { return (m_kbuart->dav_r() << 1) | (m_earom->data_r() << 5); } void ergo201_state::mem_map(address_map &map) { map(0x0000, 0x5fff).rom().region("program", 0); map(0x1000, 0x1000).nopw(); map(0x2000, 0x2000).unmapw(); // screen brightness? map(0x3000, 0x300f).w(m_vtac, FUNC(tms9927_device::write)); map(0x4000, 0x4000).w(FUNC(ergo201_state::earom_latch_w)); map(0x5000, 0x5000).w(m_kbuart, FUNC(ay31015_device::transmit)); map(0x6000, 0x6000).r(m_kbuart, FUNC(ay31015_device::receive)); map(0x6001, 0x6001).r(FUNC(ergo201_state::status_r)); map(0x7000, 0x77ff).ram(); map(0x8000, 0x87ff).ram(); map(0xc000, 0xc7ff).ram(); } void ergo201_state::io_map(address_map &map) { map.global_mask(0xff); map(0xf4, 0xf7).rw("dart", FUNC(z80dart_device::cd_ba_r), FUNC(z80dart_device::cd_ba_w)); map(0xf8, 0xfb).rw("ctc", FUNC(z80ctc_device::read), FUNC(z80ctc_device::write)); } static INPUT_PORTS_START(ergo201) INPUT_PORTS_END static const z80_daisy_config daisy_chain[] = { { "ctc" }, { "dart" }, { nullptr } }; void ergo201_state::ergo201(machine_config &config) { Z80(config, m_maincpu, 16.313_MHz_XTAL / 4); // SGS Z8400AB1 (divider guessed) m_maincpu->set_addrmap(AS_PROGRAM, &ergo201_state::mem_map); m_maincpu->set_addrmap(AS_IO, &ergo201_state::io_map); m_maincpu->set_daisy_config(daisy_chain); z80ctc_device &ctc(Z80CTC(config, "ctc", 16.313_MHz_XTAL / 4)); // SGS Z8430AB1 ctc.set_clk<0>(16.313_MHz_XTAL / 53); ctc.set_clk<1>(16.313_MHz_XTAL / 53); ctc.set_clk<2>(16.313_MHz_XTAL / 53); ctc.zc_callback<0>().set("dart", FUNC(z80dart_device::rxca_w)); ctc.zc_callback<1>().set("dart", FUNC(z80dart_device::txca_w)); ctc.zc_callback<2>().set("dart", FUNC(z80dart_device::rxtxcb_w)); ctc.intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); z80dart_device &dart(Z80DART(config, "dart", 16.313_MHz_XTAL / 4)); // Zilog Z8470A PS dart.out_txda_callback().set("dart", FUNC(z80dart_device::rxa_w)); dart.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); AY31015(config, m_kbuart); // GI AY-3-1015D m_kbuart->set_auto_rdav(true); clock_device &kbclock(CLOCK(config, "kbclock", 10000)); kbclock.signal_handler().set(m_kbuart, FUNC(ay31015_device::write_rcp)); kbclock.signal_handler().append(m_kbuart, FUNC(ay31015_device::write_tcp)); ER1400(config, m_earom); // GI ER-1400 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_raw(16.313_MHz_XTAL, 855, 0, 720, 318, 0, 300); screen.set_screen_update(FUNC(ergo201_state::screen_update)); screen.set_color(rgb_t::green()); // P31 CRT5037(config, m_vtac, 16.313_MHz_XTAL / 9); // TI TMS9937NL m_vtac->set_char_width(9); m_vtac->set_screen("screen"); } ROM_START(ergo201) ROM_REGION(0x6000, "program", 0) // Checksum is off by a few bits, so at least one dump is bad ROM_LOAD("201.u18", 0x0000, 0x2000, CRC(fec9fa3c) SHA1(3c1f9de9f62e74fbd1c9b67736d0959c0f6b46b1) BAD_DUMP) // M5L2764K ROM_LOAD("r1.0_special_5786.u73", 0x2000, 0x2000, CRC(5a31b6bc) SHA1(6929fa8f6d481790cd43732a9a97a9110ad9fb6c)) // MBM2764-25 ROM_LOAD("201.u17", 0x4000, 0x2000, CRC(e7197403) SHA1(96fff6fb30eeac616d71da731b0ea79c8cd35096)) // M5L2764K ROM_REGION(0x1000, "chargen", 0) ROM_LOAD("201.u53", 0x0000, 0x1000, CRC(907dac04) SHA1(5bae6680f1ef3f5335a223bdf403e8f3ef272430)) // MBM2732A-35 ROM_END COMP(1985, ergo201, 0, 0, ergo201, ergo201, ergo201_state, empty_init, "Micro-Term / Kurzweil Computer Products", "ERGO 201 (Special #9233)", MACHINE_IS_SKELETON)