diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 4a3805bf029..396ed5572b6 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -4177,6 +4177,7 @@ files { createMESSProjects(_target, _subtarget, "zenith") files { + MAME_DIR .. "src/mame/drivers/mdt60.cpp", MAME_DIR .. "src/mame/drivers/z100.cpp", MAME_DIR .. "src/mame/drivers/z29.cpp", } diff --git a/src/devices/cpu/m6502/m6502.cpp b/src/devices/cpu/m6502/m6502.cpp index 18e8b57cd79..3d89735dda5 100644 --- a/src/devices/cpu/m6502/m6502.cpp +++ b/src/devices/cpu/m6502/m6502.cpp @@ -14,12 +14,18 @@ #include "m6502d.h" DEFINE_DEVICE_TYPE(M6502, m6502_device, "m6502", "MOS Technology M6502") +DEFINE_DEVICE_TYPE(M6512, m6512_device, "m6512", "MOS Technology M6512") m6502_device::m6502_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : m6502_device(mconfig, M6502, tag, owner, clock) { } +m6512_device::m6512_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + m6502_device(mconfig, M6512, tag, owner, clock) +{ +} + m6502_device::m6502_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, type, tag, owner, clock), sync_w(*this), diff --git a/src/devices/cpu/m6502/m6502.h b/src/devices/cpu/m6502/m6502.h index 4e9e71b2eed..3637b088eea 100644 --- a/src/devices/cpu/m6502/m6502.h +++ b/src/devices/cpu/m6502/m6502.h @@ -269,6 +269,11 @@ protected: virtual void execute_run() override; }; +class m6512_device : public m6502_device { +public: + m6512_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + enum { M6502_PC = 1, M6502_A, @@ -286,5 +291,6 @@ enum { }; DECLARE_DEVICE_TYPE(M6502, m6502_device) +DECLARE_DEVICE_TYPE(M6512, m6512_device) #endif // MAME_CPU_M6502_M6502_H diff --git a/src/mame/drivers/mdt60.cpp b/src/mame/drivers/mdt60.cpp new file mode 100644 index 00000000000..f77249fd288 --- /dev/null +++ b/src/mame/drivers/mdt60.cpp @@ -0,0 +1,273 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/************************************************************************** + + Skeleton driver for MDT 60 and related Zenith terminals. + + MDT 60 was designed by Zenith for use with Morrow's Micro-Decision + computers as a low-cost terminal with limited features. It appears + to be a stripped-down version of some previously designed terminal, + with the auxiliary port omitted from the Morrow version even though + the schematics published by Morrow include it. Morrow's schematics + also include the same keyboard used by the Z-29, though the actual + keyboard found with one unit was different. + +**************************************************************************/ + +#include "emu.h" +#include "bus/rs232/rs232.h" +#include "cpu/m6502/m6502.h" +//#include "machine/eepromser.h" +#include "machine/i8251.h" +#include "machine/pit8253.h" +#include "video/mc6845.h" +#include "screen.h" + +class mdt60_state : public driver_device +{ +public: + mdt60_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_crtc(*this, "crtc") + , m_uart(*this, "uart%u", 0U) + , m_charrom(*this, "charrom") + , m_charram(*this, "charram") + , m_attrram(*this, "attrram") + , m_dip0(*this, "DIP0") + , m_keyin(false) + { + } + + void mdt60(machine_config &mconfig); + void z22(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + MC6845_UPDATE_ROW(update_row); + MC6845_ON_UPDATE_ADDR_CHANGED(update_cb); + + DECLARE_WRITE_LINE_MEMBER(keyin_w); + u8 dip0_r(offs_t offset); + void reg_w(u8 data); + u8 z22_status_r(); + + void mdt60_map(address_map &map); + void z22_map(address_map &map); + + required_device m_maincpu; + required_device m_crtc; + optional_device_array m_uart; + required_region_ptr m_charrom; + required_shared_ptr m_charram; + required_shared_ptr m_attrram; + optional_ioport m_dip0; + + bool m_keyin; + bool m_reverse; +}; + +void mdt60_state::machine_start() +{ + save_item(NAME(m_keyin)); + save_item(NAME(m_reverse)); +} + +void mdt60_state::machine_reset() +{ + reg_w(0); +} + + +MC6845_UPDATE_ROW(mdt60_state::update_row) +{ + u32 *pix = &bitmap.pix32(y); + + for (unsigned x = 0; x < x_count; x++) + { + u8 cdata = m_charram[(ma + x) & 0x7ff]; + u8 adata = m_attrram[(ma + x) & 0x3ff] >> (BIT(ma + x, 10) ? 4 : 0); + u16 dots = m_charrom[cdata << 4 | ra] << 1 | BIT(adata, 3); + + if (x == cursor_x) + dots = ~dots; + if (BIT(adata, 2)) + dots = ~dots; + if (BIT(adata, 0) && (ra & 0xb) == 0xa) + dots = ~dots; + + rgb_t fg = BIT(adata, 1) ? rgb_t::white() : rgb_t(0xc0, 0xc0, 0xc0); + rgb_t bg = rgb_t::black(); + if (m_reverse) + std::swap(fg, bg); + + for (int n = 8; n >= 0; n--) + *pix++ = BIT(dots, n) ? fg : bg; + } +} + +MC6845_ON_UPDATE_ADDR_CHANGED(mdt60_state::update_cb) +{ +} + + +WRITE_LINE_MEMBER(mdt60_state::keyin_w) +{ + m_keyin = state; + m_maincpu->set_input_line(m6502_device::IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE); +} + +u8 mdt60_state::dip0_r(offs_t offset) +{ + u8 buffer = 0xff; + if (!BIT(offset, 0)) + buffer &= m_dip0->read() | 0x80; + if (!BIT(offset, 1)) + buffer &= m_dip0->read() >> 7 | 0xfe; + if (!m_keyin) + buffer &= 0x7f; + return buffer; +} + +void mdt60_state::reg_w(u8 data) +{ + //m_keyboard->keyout_w(BIT(data, 0)); + m_reverse = BIT(data, 5); +} + +u8 mdt60_state::z22_status_r() +{ + return m_crtc->hsync_r() ? 0x02 : 0x00; // total guess +} + +void mdt60_state::mdt60_map(address_map &map) +{ + map(0x0000, 0x03ff).mirror(0x1800).ram(); + map(0x0400, 0x07ff).mirror(0x1800).ram().share("attrram"); + map(0x2000, 0x27ff).mirror(0x1800).ram().share("charram"); + map(0x4000, 0x4000).mirror(0x1ffe).rw(m_crtc, FUNC(r6545_1_device::status_r), FUNC(r6545_1_device::address_w)); + map(0x4001, 0x4001).mirror(0x1ffe).rw(m_crtc, FUNC(r6545_1_device::register_r), FUNC(r6545_1_device::register_w)); + map(0x6000, 0x6001).mirror(0x1ffe).rw(m_uart[0], FUNC(i8251_device::read), FUNC(i8251_device::write)); + //map(0x8000, 0x8001).mirror(0x1ffe).rw(m_uart[1], FUNC(i8251_device::read), FUNC(i8251_device::write)); + map(0xa000, 0xa003).mirror(0x1ffc).r(FUNC(mdt60_state::dip0_r)); + map(0xa000, 0xa000).mirror(0x1fff).w(FUNC(mdt60_state::reg_w)); + //map(0xc000, 0xc000).mirror(0x1fff).portr("DIP1"); + map(0xe000, 0xefff).mirror(0x1000).rom().region("coderom", 0); +} + +void mdt60_state::z22_map(address_map &map) +{ + map(0x0000, 0x07ff).ram(); + map(0x2000, 0x27ff).ram().share("charram"); + map(0x4000, 0x4001).rw(m_uart[0], FUNC(i8251_device::read), FUNC(i8251_device::write)); + map(0x6000, 0x67ff).ram().share("attrram"); + map(0x8000, 0x8001).rw(m_uart[1], FUNC(i8251_device::read), FUNC(i8251_device::write)); + map(0x8800, 0x8800).rw(m_crtc, FUNC(r6545_1_device::status_r), FUNC(r6545_1_device::address_w)); + map(0x8801, 0x8801).rw(m_crtc, FUNC(r6545_1_device::register_r), FUNC(r6545_1_device::register_w)); + map(0x9000, 0x9003).w("pit", FUNC(pit8254_device::write)); + map(0xa000, 0xa000).r(FUNC(mdt60_state::z22_status_r)); + map(0xc000, 0xdfff).rom().region("charrom", 0); + map(0xe000, 0xffff).rom().region("coderom", 0); +} + + +static INPUT_PORTS_START(mdt60) + PORT_START("DIP0") // TODO: verify bit assignments + PORT_DIPNAME(0x03, 0x01, "Baud Rate") PORT_DIPLOCATION("SW1:1,2") + PORT_DIPSETTING(0x03, "300") + PORT_DIPSETTING(0x02, "1200") + PORT_DIPSETTING(0x01, "9600") + PORT_DIPSETTING(0x00, "19200") + PORT_DIPNAME(0x0c, 0x00, "Parity") PORT_DIPLOCATION("SW1:3,4") + PORT_DIPSETTING(0x04, "Odd") + PORT_DIPSETTING(0x0c, "Even") + PORT_DIPSETTING(0x00, "Mark") + PORT_DIPSETTING(0x08, "Space") + PORT_DIPNAME(0x70, 0x00, "Character Set") PORT_DIPLOCATION("SW1:5,6,7") + PORT_DIPSETTING(0x00, "U.S.") + PORT_DIPSETTING(0x10, "U.K.") + PORT_DIPSETTING(0x20, "French") + PORT_DIPSETTING(0x30, "German") + PORT_DIPSETTING(0x40, "Spanish") + PORT_DIPSETTING(0x50, "Danish/Norwegian") + PORT_DIPSETTING(0x60, "Swedish/Finnish") + PORT_DIPSETTING(0x70, "Italian") + PORT_DIPNAME(0x80, 0x80, "Function Key Sequence Type") PORT_DIPLOCATION("SW1:8") + PORT_DIPSETTING(0x80, "Morrow (FS)") + PORT_DIPSETTING(0x00, "TeleVideo (SOH...CR)") + + PORT_START("DIP1") + PORT_BIT(0xff, 0xff, IPT_UNUSED) // SW2 is unpopulated +INPUT_PORTS_END + +static INPUT_PORTS_START(z22) +INPUT_PORTS_END + +// XTAL frequency is specified as 16.589 MHz on actual parts as well as in MDT 60 schematics. +// This has been assumed to be a lower-precision specification of the common 16.5888 MHz value. + +void mdt60_state::mdt60(machine_config &config) +{ + M6512(config, m_maincpu, 16.5888_MHz_XTAL / 9); // R6512AP + m_maincpu->set_addrmap(AS_PROGRAM, &mdt60_state::mdt60_map); + + I8251(config, m_uart[0], 16.5888_MHz_XTAL / 9); // TMP8251AP (U19) + m_uart[0]->rxrdy_handler().set_inputline(m_maincpu, m6512_device::NMI_LINE); + m_uart[0]->txd_handler().set("computer", FUNC(rs232_port_device::write_txd)); + m_uart[0]->dtr_handler().set("computer", FUNC(rs232_port_device::write_dtr)); + m_uart[0]->rts_handler().set("computer", FUNC(rs232_port_device::write_rts)); + + // UART 1 (at U28) is unpopulated and not used by code + + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_color(rgb_t::amber()); + screen.set_raw(16.5888_MHz_XTAL, 918, 0, 720, 301, 0, 288); + screen.set_screen_update(m_crtc, FUNC(r6545_1_device::screen_update)); + + R6545_1(config, m_crtc, 16.5888_MHz_XTAL / 9); // R6545-1AP + m_crtc->set_screen("screen"); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(9); + m_crtc->set_update_row_callback(FUNC(mdt60_state::update_row)); + m_crtc->set_on_update_addr_change_callback(FUNC(mdt60_state::update_cb)); + + rs232_port_device &computer(RS232_PORT(config, "computer", default_rs232_devices, nullptr)); + computer.rxd_handler().set(m_uart[0], FUNC(i8251_device::write_rxd)); + computer.dsr_handler().set(m_uart[0], FUNC(i8251_device::write_dsr)); + computer.cts_handler().set(m_uart[0], FUNC(i8251_device::write_cts)); +} + +void mdt60_state::z22(machine_config &config) +{ + mdt60(config); + m_maincpu->set_addrmap(AS_PROGRAM, &mdt60_state::z22_map); + + I8251(config, m_uart[1], 16.5888_MHz_XTAL / 9); + + PIT8254(config, "pit"); + + subdevice("screen")->set_raw(16.5888_MHz_XTAL, 873, 0, 720, 317, 0, 300); +} + + +ROM_START(mdt60) + ROM_REGION(0x1000, "coderom", 0) + ROM_LOAD("vb-rom_1.7_bcfd.u9", 0x0000, 0x1000, CRC(3902f7b3) SHA1(ee0ce7f68efe20efe1ab8a44888e276f08fe2d07)) + + ROM_REGION(0x1000, "charrom", 0) + ROM_LOAD("char_gen_b207.u6", 0x0000, 0x1000, CRC(b19432da) SHA1(fa73641c08b778f19a17676a7f4074f69b7b55dd)) +ROM_END + +ROM_START(z22) + ROM_REGION(0x2000, "coderom", 0) + ROM_LOAD("u38.bin", 0x0000, 0x2000, CRC(f0bfe9b5) SHA1(8807841b28549d0ddf30275fc6035a66093f8768)) // D2764A-3 + + ROM_REGION(0x2000, "charrom", 0) + ROM_LOAD("u39.bin", 0x0000, 0x2000, CRC(2f62c1f8) SHA1(448581d987fee6b4303e481e78f46d3255baccbb)) // D2764A-3 +ROM_END + +SYST(1983, mdt60, 0, 0, mdt60, mdt60, mdt60_state, empty_init, "Morrow", "MDT 60 Video Display Terminal", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) +SYST(1984, z22, 0, 0, z22, z22, mdt60_state, empty_init, "Zenith Data Systems", "Z-22 Terminal", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index ca35e085fa1..b444dcb3ffa 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -21870,6 +21870,10 @@ xenophob // (c) 1987 mdisk // (c) 198? mupid Computer Ges.m.b.H. fl100 // (c) 198? Grundig +@source:mdt60.cpp +mdt60 // +z22 // + @source:meadows.cpp bowl3d // [1978?] deadeye // [1978?] diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 6fb838c7d8f..147370eecfa 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -504,6 +504,7 @@ mc8030.cpp mcb216.cpp mccpm.cpp mdisk.cpp +mdt60.cpp megadriv.cpp megadriv_rad.cpp mekd1.cpp