From 0581346b2c4600a00ab6bab70502e9ffb2a63e87 Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 16 Sep 2018 11:58:54 -0400 Subject: facit4440: Create new skeleton driver; burn-in tests all seem to pass now (nw) --- scripts/target/mame/mess.lua | 1 + src/devices/machine/er1400.cpp | 10 +- src/devices/machine/er1400.h | 2 +- src/mame/drivers/facit4440.cpp | 265 +++++++++++++++++++++++++++++++++++++++++ src/mame/drivers/terminal.cpp | 15 --- src/mame/mame.lst | 4 +- src/mame/mess.flt | 1 + 7 files changed, 280 insertions(+), 18 deletions(-) create mode 100644 src/mame/drivers/facit4440.cpp diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 127e7c91071..9e4799dca7f 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -3678,6 +3678,7 @@ files { MAME_DIR .. "src/mame/includes/eti660.h", MAME_DIR .. "src/mame/drivers/eurocom2.cpp", MAME_DIR .. "src/mame/drivers/excali64.cpp", + MAME_DIR .. "src/mame/drivers/facit4440.cpp", MAME_DIR .. "src/mame/drivers/fanucs15.cpp", MAME_DIR .. "src/mame/drivers/fanucspmg.cpp", MAME_DIR .. "src/mame/drivers/fc100.cpp", diff --git a/src/devices/machine/er1400.cpp b/src/devices/machine/er1400.cpp index 763e80af58f..dec90501855 100644 --- a/src/devices/machine/er1400.cpp +++ b/src/devices/machine/er1400.cpp @@ -291,7 +291,13 @@ void er1400_device::device_timer(emu_timer &timer, device_timer_id id, int param switch (id) { case PROPAGATION_TIMER: - m_data_output = (m_code_input == 5) ? BIT(m_data_register, 13) : false; + if (m_code_input == 5) + { + m_data_output = BIT(m_data_register, 13); + LOG("Data output %d bit\n", m_data_output); + } + else + m_data_output = false; break; } } @@ -345,6 +351,7 @@ WRITE_LINE_MEMBER(er1400_device::clock_w) break; case 3: // accept address + LOG("Accepting address %d bit\n", m_data_input); m_address_register = (m_address_register << 1) | m_data_input; m_address_register &= 0xfffff; break; @@ -367,6 +374,7 @@ WRITE_LINE_MEMBER(er1400_device::clock_w) break; case 7: // accept data + LOG("Accepting data %d bit\n", m_data_input); m_data_register = (m_data_register & 0x1fff) << 1; m_data_register |= m_data_input; break; diff --git a/src/devices/machine/er1400.h b/src/devices/machine/er1400.h index df95cc226e2..6093a29d60c 100644 --- a/src/devices/machine/er1400.h +++ b/src/devices/machine/er1400.h @@ -32,7 +32,7 @@ class er1400_device : public device_t, public device_nvram_interface { public: // construction/destruction - er1400_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + er1400_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); // line handlers DECLARE_WRITE_LINE_MEMBER(data_w); diff --git a/src/mame/drivers/facit4440.cpp b/src/mame/drivers/facit4440.cpp new file mode 100644 index 00000000000..c5cb37d6819 --- /dev/null +++ b/src/mame/drivers/facit4440.cpp @@ -0,0 +1,265 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/**************************************************************************** + + Skeleton driver for Facit 4440 Twist terminal. + + The “Twist” sobriquet refers to the adjustable orientation of the + monitor, whose normally black-on-white display has the dimensions of a + sheet of A4 paper. It displays 24 lines of 80 characters in landscape + mode and 72 lines of rather smaller characters in portrait mode. + + No user manual for this terminal has been found. The layout of the + keyboard is also unclear, not to mention the serial protocol. + + Nonvolatile settings are configured through VT100-style setup screens. + Several non-ANSI emulation modes are also available. + + An OEM customized version was sold by Norsk Data AS as the ND 319 Twist. + + The timing of the display circuit seems a bit uncertain. Promotional + information claims that it has a 40 MHz bandwidth, but this may be only + a nominal maximum rating since the only high-frequency oscillator seen + on the PCB is 32 MHz. It is unclear how the CRTC parameters and this + value can produce the documented 65 Hz refresh rate. The actual circuit + also generates alarming levels of electromagnetic radiation. + +****************************************************************************/ + +#include "emu.h" +//#include "bus/rs232/rs232.h" +#include "cpu/z80/z80.h" +#include "machine/clock.h" +#include "machine/er1400.h" +#include "machine/z80ctc.h" +#include "machine/z80dart.h" +#include "video/mc6845.h" +#include "screen.h" + +class facit4440_state : public driver_device +{ +public: + facit4440_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_earom(*this, "earom%u", 0U) + , m_crtc(*this, "crtc") + , m_test(*this, "TEST") + , m_chargen(*this, "chargen") + , m_vidprom(*this, "vidprom") + { + } + + void facit4440(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + void earom_latch_w(u8 data); + void control_2000_w(u8 data); + u8 misc_status_r(); + void control_6000_w(u8 data); + void control_a000_w(u8 data); + + DECLARE_WRITE_LINE_MEMBER(vsync_w); + + MC6845_UPDATE_ROW(update_row); + + void mem_map(address_map &map); + void io_map(address_map &map); + + required_device m_maincpu; + required_device_array m_earom; + required_device m_crtc; + + required_ioport m_test; + + required_region_ptr m_chargen; + required_region_ptr m_vidprom; + + u8 m_control_latch[3]; +}; + +void facit4440_state::earom_latch_w(u8 data) +{ + // SN74LS174 latch + SN7406 inverter + + // Prevent outputs from interfering with data reads + if (!BIT(data, 2)) + data &= 0xfc; + + // FIXME: clock must be written first here due to data/control setup time + m_earom[0]->clock_w(BIT(data, 5)); + m_earom[1]->clock_w(BIT(data, 5)); + + m_earom[0]->data_w(BIT(data, 1)); + m_earom[1]->data_w(BIT(data, 0)); + + for (auto &earom : m_earom) + { + earom->c2_w(BIT(data, 2)); + earom->c1_w(BIT(data, 3)); + earom->c3_w(BIT(data, 4)); + } +} + +void facit4440_state::control_2000_w(u8 data) +{ + m_control_latch[0] = data; + + if (!BIT(m_control_latch[0], 5)) + m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); +} + +void facit4440_state::control_6000_w(u8 data) +{ + m_control_latch[1] = data; +} + +void facit4440_state::control_a000_w(u8 data) +{ + m_control_latch[2] = data; +} + +u8 facit4440_state::misc_status_r() +{ + u8 status = m_test->read() << 6; + + status |= m_earom[0]->data_r() << 4; + status |= m_earom[1]->data_r() << 3; + + status |= m_crtc->vsync_r() << 1; + // TODO: what should bit 0 be? + + return status; +} + +WRITE_LINE_MEMBER(facit4440_state::vsync_w) +{ + if (BIT(m_control_latch[0], 5)) + m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); +} + +MC6845_UPDATE_ROW(facit4440_state::update_row) +{ +} + +void facit4440_state::mem_map(address_map &map) +{ + map(0x0000, 0x7fff).rom().region("mainprg", 0); + map(0x0000, 0x0000).w(FUNC(facit4440_state::earom_latch_w)); + map(0x2000, 0x2000).w(FUNC(facit4440_state::control_2000_w)); + map(0x4000, 0x4000).mirror(0x1ffe).w("crtc", FUNC(mc6845_device::address_w)); + map(0x4001, 0x4001).mirror(0x1ffe).w("crtc", FUNC(mc6845_device::register_w)); + map(0x6000, 0x6000).w(FUNC(facit4440_state::control_6000_w)); + map(0x8000, 0x8000).r(FUNC(facit4440_state::misc_status_r)); + map(0x8000, 0x8050).nopw(); + map(0xa000, 0xbfff).rom().region("testprg", 0); + map(0xa000, 0xa000).w(FUNC(facit4440_state::control_a000_w)); + map(0xc000, 0xdfff).ram(); // 4x TMM2016AP-90 + map(0xe000, 0xffff).ram(); // 4x TMM2016AP-90 +} + +void facit4440_state::io_map(address_map &map) +{ + map.global_mask(0xff); + map(0xec, 0xef).rw("dart2", FUNC(z80dart_device::cd_ba_r), FUNC(z80dart_device::cd_ba_w)); + map(0xf4, 0xf7).rw("dart1", 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)); +} + +void facit4440_state::machine_start() +{ + m_control_latch[0] = m_control_latch[1] = m_control_latch[2] = 0; + + save_item(NAME(m_control_latch)); +} + +static INPUT_PORTS_START(facit4440) + PORT_START("TEST") + PORT_CONFNAME(3, 0, "Test Mode") + PORT_CONFSETTING(0, DEF_STR(Off)) + PORT_CONFSETTING(3, DEF_STR(On)) + PORT_CONFSETTING(2, "Burn In") +INPUT_PORTS_END + +static const z80_daisy_config daisy_chain[] = +{ + { "ctc" }, + { "dart1" }, + { "dart2" }, + { nullptr } +}; + +void facit4440_state::facit4440(machine_config &config) +{ + constexpr u32 CHAR_WIDTH = 8; + constexpr u32 FAKE_DOT_CLOCK = 65 * 103 * 621 * CHAR_WIDTH; + + Z80(config, m_maincpu, 32_MHz_XTAL / 8); // clock unknown + m_maincpu->set_addrmap(AS_PROGRAM, &facit4440_state::mem_map); + m_maincpu->set_addrmap(AS_IO, &facit4440_state::io_map); + m_maincpu->set_daisy_config(daisy_chain); + + ER1400(config, m_earom[0]); // M5G1400P + ER1400(config, m_earom[1]); // M5G1400P + + z80ctc_device &ctc(Z80CTC(config, "ctc", 32_MHz_XTAL / 8)); + ctc.intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + ctc.zc_callback<0>().set("dart1", FUNC(z80dart_device::txca_w)); + ctc.zc_callback<1>().set("dart1", FUNC(z80dart_device::rxca_w)); + ctc.zc_callback<2>().set("dart1", FUNC(z80dart_device::txcb_w)); + ctc.zc_callback<2>().append("dart1", FUNC(z80dart_device::rxcb_w)); + + clock_device &baudclk(CLOCK(config, "baudclk", 2.4576_MHz_XTAL / 4)); + baudclk.signal_handler().set("ctc", FUNC(z80ctc_device::trg0)); + baudclk.signal_handler().append("ctc", FUNC(z80ctc_device::trg1)); + baudclk.signal_handler().append("ctc", FUNC(z80ctc_device::trg2)); + + clock_device &keybclk(CLOCK(config, "keybclk", 2.4576_MHz_XTAL / 32)); // unclear + keybclk.signal_handler().set("dart2", FUNC(z80dart_device::txca_w)); + keybclk.signal_handler().append("dart2", FUNC(z80dart_device::rxca_w)); + + z80dart_device &dart1(Z80DART(config, "dart1", 32_MHz_XTAL / 8)); // Z80ADART + dart1.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + dart1.out_txda_callback().set("dart1", FUNC(z80dart_device::rxa_w)); // temporary loopback for testing + dart1.out_rtsa_callback().set("dart1", FUNC(z80dart_device::ctsa_w)); // temporary loopback for testing + dart1.out_dtra_callback().set("dart1", FUNC(z80dart_device::dcdb_w)); // temporary loopback for testing + dart1.out_txdb_callback().set("dart1", FUNC(z80dart_device::rxb_w)); // temporary loopback for testing + + z80dart_device &dart2(Z80DART(config, "dart2", 32_MHz_XTAL / 8)); // Z80ADART + dart2.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + dart2.out_txda_callback().set("dart2", FUNC(z80dart_device::rxa_w)); // FIXME: serial keyboard needed here + // Channel B is not used + + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(FAKE_DOT_CLOCK, 103 * CHAR_WIDTH, 0, 80 * CHAR_WIDTH, 621, 0, 592); + screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); + + MC6845(config, m_crtc, FAKE_DOT_CLOCK / CHAR_WIDTH); // HD46505SP-2 + m_crtc->set_char_width(CHAR_WIDTH); + m_crtc->set_update_row_callback(FUNC(facit4440_state::update_row), this); + m_crtc->out_hsync_callback().set("ctc", FUNC(z80ctc_device::trg3)); + m_crtc->out_vsync_callback().set(FUNC(facit4440_state::vsync_w)); +} + + +ROM_START(facit4440) + ROM_REGION(0x8000, "mainprg", 0) + ROM_LOAD("rom7.bin", 0x0000, 0x4000, CRC(a8da2b11) SHA1(4436ef14c29ae299f7bc338748158771c02d02a9)) + ROM_LOAD("rom6.bin", 0x4000, 0x4000, CRC(790b7642) SHA1(688a80cbf011e5c14f501e11fe0e3bf64a85bbd7)) + + ROM_REGION(0x2000, "testprg", 0) + ROM_LOAD("rom5.bin", 0x0000, 0x2000, CRC(715d02b6) SHA1(e304718dbdc8867ac01909fd2d027e5014a8c4f9)) + + ROM_REGION(0x3000, "chargen", 0) // order unknown + ROM_LOAD("rom1.bin", 0x0000, 0x1000, CRC(b503c173) SHA1(209bf59e2e9953179d04c4e768fc41574e039d36)) + ROM_LOAD("rom3.bin", 0x1000, 0x1000, CRC(a55a25d9) SHA1(c0d321e65f214adee01bf5f8c495b2518fa31b7b)) + ROM_LOAD("rom4.bin", 0x2000, 0x1000, CRC(52004ef8) SHA1(50d6e2eb48f60db3a3c9d206fc40d3294b6adc0e)) + + ROM_REGION(0x0800, "vidprom", 0) + ROM_LOAD("rom2.bin", 0x0000, 0x0800, CRC(9e1a190c) SHA1(fb08ee806f1056bcdfb5b08ea85995e1d3d01298)) +ROM_END + +COMP(1984, facit4440, 0, 0, facit4440, facit4440, facit4440_state, empty_init, "Facit", "4440 Twist (30M-F1)", MACHINE_IS_SKELETON) diff --git a/src/mame/drivers/terminal.cpp b/src/mame/drivers/terminal.cpp index 5e5149469ba..e6d424f87c9 100644 --- a/src/mame/drivers/terminal.cpp +++ b/src/mame/drivers/terminal.cpp @@ -74,20 +74,6 @@ ROM_START( alcat7100 ) // Z80 // 256k ram // b&w // looks like it needs a boot ROM_END -ROM_START( facit4440 ) // Z80 (+HD46505SP, 2x Z80ADART // 16k ram // b&w - ROM_REGION( 0x10000, "maincpu", 0 ) - ROM_LOAD( "rom7.bin", 0x0000, 0x4000, CRC(a8da2b11) SHA1(4436ef14c29ae299f7bc338748158771c02d02a9) ) - ROM_LOAD( "rom5.bin", 0xa000, 0x2000, CRC(715d02b6) SHA1(e304718dbdc8867ac01909fd2d027e5014a8c4f9) ) - - ROM_REGION( 0x8000, "chargen", 0 ) // order unknown - ROM_LOAD( "rom2.bin", 0x0000, 0x0800, CRC(9e1a190c) SHA1(fb08ee806f1056bcdfb5b08ea85995e1d3d01298) ) - ROM_LOAD( "rom1.bin", 0x0800, 0x1000, CRC(b503c173) SHA1(209bf59e2e9953179d04c4e768fc41574e039d36) ) - ROM_LOAD( "rom3.bin", 0x1800, 0x1000, CRC(a55a25d9) SHA1(c0d321e65f214adee01bf5f8c495b2518fa31b7b) ) - ROM_LOAD( "rom4.bin", 0x2800, 0x1000, CRC(52004ef8) SHA1(50d6e2eb48f60db3a3c9d206fc40d3294b6adc0e) ) - ROM_LOAD( "rom6.bin", 0x3800, 0x4000, CRC(790b7642) SHA1(688a80cbf011e5c14f501e11fe0e3bf64a85bbd7) ) -ROM_END - - ROM_START( itt9216 ) // MC68008P8, (+beeper, 701188-001, xtal 38.080)// 64k ram // colour ROM_REGION( 0x10000, "maincpu", 0 ) ROM_LOAD( "174054-007.u52", 0x0000, 0x2000, CRC(be1f85c8) SHA1(8c44ff6166c43b524f41133053fa82f5c48047d8) ) @@ -158,7 +144,6 @@ ROM_END /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ COMP( 1991, alcat258, 0, 0, terminal, terminal, terminal_state, empty_init, "Alcatel", "Terminatel 258", MACHINE_IS_SKELETON ) COMP( 1984, alcat7100, 0, 0, terminal, terminal, terminal_state, empty_init, "Alcatel", "Terminal 7100", MACHINE_IS_SKELETON ) -COMP( 1986, facit4440, 0, 0, terminal, terminal, terminal_state, empty_init, "Facit", "Terminal 4440 (30M-F1)", MACHINE_IS_SKELETON ) COMP( 1986, itt9216, 0, 0, terminal, terminal, terminal_state, empty_init, "ITT", "Courier 9216-X", MACHINE_IS_SKELETON ) COMP( 1992, loewed, 0, 0, terminal, terminal, terminal_state, empty_init, "Loewe", "Multitel D", MACHINE_IS_SKELETON ) COMP( 1988, loewe715, 0, 0, terminal, terminal, terminal_state, empty_init, "Loewe", "Multicom 715L", MACHINE_IS_SKELETON ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index a30230ac16e..7983b3e4a69 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -12639,6 +12639,9 @@ f1gpb // bootleg mosaicf2 // (c) 1999 F2 System royalpk2 // +@source:facit.cpp +facit4440 // 1984 + @source:famibox.cpp famibox // 1986 @@ -36955,7 +36958,6 @@ t4490 // Terco 4490 Mill CNC Control (c) 1986 7951om // alcat258 // alcat7100 // -facit4440 // feap90 // ikt5a // itt9216 // diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 9be36b04838..4ffad605533 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -220,6 +220,7 @@ evmbug.cpp excali64.cpp exelv.cpp exp85.cpp +facit4440.cpp fanucs15.cpp fanucspmg.cpp fb01.cpp -- cgit v1.2.3