From 61dd52cf6072a4621380a47d5cdb092fb84c29b1 Mon Sep 17 00:00:00 2001 From: AJR Date: Mon, 25 Oct 2021 11:05:52 -0400 Subject: facit4440: Updates based on schematics --- src/mame/drivers/facit4440.cpp | 101 ++++++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 32 deletions(-) diff --git a/src/mame/drivers/facit4440.cpp b/src/mame/drivers/facit4440.cpp index 84c6d8cc8db..d203d085319 100644 --- a/src/mame/drivers/facit4440.cpp +++ b/src/mame/drivers/facit4440.cpp @@ -16,25 +16,31 @@ Several non-ANSI emulation modes are also available. An OEM customized version was sold by Norsk Data AS as the ND 319 Twist. + Micro-Term apparently distributed this terminal in the US. 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. + on the PCB is 32 MHz, and schematics label this as 30 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 "bus/rs232/rs232.h" #include "cpu/z80/z80.h" +#include "cpu/m6800/m6801.h" #include "machine/clock.h" #include "machine/er1400.h" +#include "machine/ripple_counter.h" #include "machine/z80ctc.h" #include "machine/z80sio.h" +#include "sound/spkrdev.h" #include "video/mc6845.h" #include "screen.h" +#include "speaker.h" class facit4440_state : public driver_device { @@ -42,8 +48,11 @@ 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_earom(*this, "earom%u", 1U) , m_crtc(*this, "crtc") + , m_bellctr(*this, "bellctr") + , m_rs232(*this, "rs232") + , m_printer(*this, "printer") , m_test(*this, "TEST") , m_orientation(*this, "ORIENTATION") , m_chargen(*this, "chargen") @@ -74,6 +83,9 @@ private: required_device m_maincpu; required_device_array m_earom; required_device m_crtc; + required_device m_bellctr; + required_device m_rs232; + required_device m_printer; required_ioport m_test; required_ioport m_orientation; @@ -97,8 +109,8 @@ void facit4440_state::earom_latch_w(u8 data) 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)); + m_earom[0]->data_w(BIT(data, 0)); + m_earom[1]->data_w(BIT(data, 1)); for (auto &earom : m_earom) { @@ -112,7 +124,8 @@ void facit4440_state::control_2000_w(u8 data) { m_control_latch[0] = data; - if (!BIT(m_control_latch[0], 5)) + m_bellctr->reset_w(BIT(data, 5)); + if (!BIT(m_control_latch[0], 6)) m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); } @@ -130,9 +143,10 @@ 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_earom[1]->data_r() << 4; + status |= m_earom[0]->data_r() << 3; + status |= m_crtc->hsync_r() << 2; status |= m_crtc->vsync_r() << 1; status |= m_orientation->read(); @@ -147,6 +161,7 @@ WRITE_LINE_MEMBER(facit4440_state::vsync_w) MC6845_UPDATE_ROW(facit4440_state::update_row) { + // FIXME: MA does not determine video addressing at all here offs_t base = ma / 5 * 6; u32 *px = &bitmap.pix(y); @@ -191,6 +206,8 @@ void facit4440_state::io_map(address_map &map) void facit4440_state::machine_start() { + subdevice("kbdart")->rxb_w(0); + m_control_latch[0] = m_control_latch[1] = m_control_latch[2] = 0; save_item(NAME(m_control_latch)); @@ -198,10 +215,10 @@ void facit4440_state::machine_start() 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") + PORT_DIPNAME(3, 0, "Test Mode") PORT_DIPLOCATION("W7/W4:1,2") + PORT_DIPSETTING(0, DEF_STR(Off)) + PORT_DIPSETTING(3, DEF_STR(On)) + PORT_DIPSETTING(2, "Burn In") PORT_START("ORIENTATION") PORT_CONFNAME(1, 1, "Orientation") @@ -219,16 +236,15 @@ static const z80_daisy_config daisy_chain[] = void facit4440_state::facit4440(machine_config &config) { - constexpr u32 CH_WIDTH = 8; - constexpr u32 FAKE_DOT_CLOCK = 65 * 103 * 621 * CH_WIDTH; + constexpr XTAL DOT_CLOCK = 32_MHz_XTAL; // XTAL is 30 MHz according to schematics - Z80(config, m_maincpu, 32_MHz_XTAL / 8); // clock unknown + Z80(config, m_maincpu, 32_MHz_XTAL / 8); // divider confirmed from schematics 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 + ER1400(config, m_earom[0]); // M5G1400P @ D65 + ER1400(config, m_earom[1]); // M5G1400P @ D64 z80ctc_device &ctc(Z80CTC(config, "ctc", 32_MHz_XTAL / 8)); ctc.intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); @@ -240,33 +256,51 @@ void facit4440_state::facit4440(machine_config &config) ctc.zc_callback<2>().set("iodart", FUNC(z80dart_device::txcb_w)); ctc.zc_callback<2>().append("iodart", FUNC(z80dart_device::rxcb_w)); - clock_device &keybclk(CLOCK(config, "keybclk", 2.4576_MHz_XTAL / 32)); // unclear + clock_device &keybclk(CLOCK(config, "kbdclk", 2.4576_MHz_XTAL / 32)); // divider confirmed from schematics keybclk.signal_handler().set("kbdart", FUNC(z80dart_device::txca_w)); keybclk.signal_handler().append("kbdart", FUNC(z80dart_device::rxca_w)); - z80dart_device &iodart(Z80DART(config, "iodart", 32_MHz_XTAL / 8)); // Z80ADART + z80dart_device &iodart(Z80DART(config, "iodart", 32_MHz_XTAL / 8)); // Z80ADART @ D83 iodart.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - iodart.out_txda_callback().set("iodart", FUNC(z80dart_device::rxa_w)); // temporary loopback for testing - iodart.out_rtsa_callback().set("iodart", FUNC(z80dart_device::ctsa_w)); // temporary loopback for testing - iodart.out_dtra_callback().set("iodart", FUNC(z80dart_device::dcdb_w)); // temporary loopback for testing - iodart.out_txdb_callback().set("iodart", FUNC(z80dart_device::rxb_w)); // temporary loopback for testing + iodart.out_txda_callback().set(m_rs232, FUNC(rs232_port_device::write_txd)); + iodart.out_rtsa_callback().set(m_rs232, FUNC(rs232_port_device::write_rts)); + iodart.out_dtra_callback().set(m_printer, FUNC(rs232_port_device::write_dtr)); // not correct according to schematics, but needed to pass burn-in test + iodart.out_txdb_callback().set(m_printer, FUNC(rs232_port_device::write_txd)); - z80dart_device &kbdart(Z80DART(config, "kbdart", 32_MHz_XTAL / 8)); // Z80ADART + z80dart_device &kbdart(Z80DART(config, "kbdart", 32_MHz_XTAL / 8)); // Z80ADART @ D82 kbdart.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); kbdart.out_txda_callback().set("kbdart", FUNC(z80dart_device::rxa_w)); // FIXME: serial keyboard needed here - // Channel B is not used + // Channel B is not used (though schematics show 307.2 kHz provided for RxTxCB) + + M6801(config, "kbdmcu", 2.4576_MHz_XTAL).set_disable(); // exact type unknown screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(FAKE_DOT_CLOCK, 103 * CH_WIDTH, 0, 80 * CH_WIDTH, 621, 0, 500); - //screen.set_raw(FAKE_DOT_CLOCK, 103 * CH_WIDTH, 0, 80 * CH_WIDTH, 621, 0, 560); + screen.set_raw(DOT_CLOCK, 103 * 8, 0, 80 * 8, 621, 0, 500); + //screen.set_raw(DOT_CLOCK, 103 * 8, 0, 80 * 8, 621, 0, 560); screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); - MC6845(config, m_crtc, FAKE_DOT_CLOCK / CH_WIDTH); // HD46505SP-2 - m_crtc->set_char_width(CH_WIDTH); + MC6845(config, m_crtc, DOT_CLOCK / 8); // HD46505SP-2 + m_crtc->set_char_width(8); m_crtc->set_show_border_area(false); m_crtc->set_update_row_callback(FUNC(facit4440_state::update_row)); m_crtc->out_hsync_callback().set("ctc", FUNC(z80ctc_device::trg3)); + m_crtc->out_hsync_callback().append(m_bellctr, FUNC(ripple_counter_device::clock_w)); m_crtc->out_vsync_callback().set(FUNC(facit4440_state::vsync_w)); + + RIPPLE_COUNTER(config, m_bellctr).set_stages(12); // HEF4040BP + m_bellctr->count_out_cb().set("speaker", FUNC(speaker_sound_device::level_w)).bit(5); + + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.5); + + RS232_PORT(config, m_rs232, default_rs232_devices, "loopback"); // temporary loopback for testing + m_rs232->rxd_handler().set("iodart", FUNC(z80dart_device::rxa_w)); + m_rs232->cts_handler().set("iodart", FUNC(z80dart_device::ctsa_w)); + m_rs232->dcd_handler().set("iodart", FUNC(z80dart_device::dcda_w)); + + RS232_PORT(config, m_printer, default_rs232_devices, "loopback"); // temporary loopback for testing + m_printer->rxd_handler().set("iodart", FUNC(z80dart_device::rxb_w)); + m_printer->dcd_handler().set("iodart", FUNC(z80dart_device::dcdb_w)); } @@ -275,6 +309,9 @@ ROM_START(facit4440) ROM_LOAD("rom7.bin", 0x0000, 0x4000, CRC(a8da2b11) SHA1(4436ef14c29ae299f7bc338748158771c02d02a9)) ROM_LOAD("rom6.bin", 0x4000, 0x4000, CRC(790b7642) SHA1(688a80cbf011e5c14f501e11fe0e3bf64a85bbd7)) + ROM_REGION(0x1000, "kbdmcu", 0) + ROM_LOAD("6801.bin", 0x0000, 0x1000, NO_DUMP) + ROM_REGION(0x2000, "testprg", 0) ROM_LOAD("rom5.bin", 0x0000, 0x2000, CRC(715d02b6) SHA1(e304718dbdc8867ac01909fd2d027e5014a8c4f9)) @@ -287,4 +324,4 @@ ROM_START(facit4440) 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_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND) +COMP(1984, facit4440, 0, 0, facit4440, facit4440, facit4440_state, empty_init, "Facit", "4440 Twist (30M-F1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS) -- cgit v1.2.3