summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Nigel Barnes <Pernod70@users.noreply.github.com>2019-03-10 17:23:39 +0000
committer Nigel Barnes <Pernod70@users.noreply.github.com>2019-03-10 17:23:39 +0000
commit5511ce41e2b5a23394c75b0e743c3bcafdb87b15 (patch)
tree5d2cb4dc1642094abb6816f9da86509fd07530d0
parentf9ae1fd4080bad4870247c4fc21fee3ba8b7af1f (diff)
mtx: Added expansion bus with SDX floppy controller.
- 80 column card with SDX in CP/M mode. - ROM/RAM banking fixed for CP/M, and MTX500 now correctly detected. - Support for Type 03 and Type 07 .mfloppy images. - Added alternate MTX2 romset (German). - Keyboard ROM now selected in Configuration. - Quickload .RUN files.
-rw-r--r--scripts/src/bus.lua15
-rw-r--r--scripts/src/formats.lua12
-rw-r--r--scripts/target/mame/mess.lua2
-rw-r--r--src/devices/bus/mtx/exp.cpp126
-rw-r--r--src/devices/bus/mtx/exp.h92
-rw-r--r--src/devices/bus/mtx/sdx.cpp425
-rw-r--r--src/devices/bus/mtx/sdx.h105
-rw-r--r--src/lib/formats/mtx_dsk.cpp53
-rw-r--r--src/lib/formats/mtx_dsk.h33
-rw-r--r--src/mame/drivers/mtx.cpp98
-rw-r--r--src/mame/includes/mtx.h31
-rw-r--r--src/mame/machine/mtx.cpp157
12 files changed, 1023 insertions, 126 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 30465695536..ee55202bb88 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -1406,6 +1406,21 @@ end
---------------------------------------------------
--
+--@src/devices/bus/mtx/exp.h,BUSES["MTX"] = true
+---------------------------------------------------
+
+if (BUSES["MTX"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/bus/mtx/exp.cpp",
+ MAME_DIR .. "src/devices/bus/mtx/exp.h",
+ MAME_DIR .. "src/devices/bus/mtx/sdx.cpp",
+ MAME_DIR .. "src/devices/bus/mtx/sdx.h",
+ }
+end
+
+
+---------------------------------------------------
+--
--@src/devices/bus/kc/kc.h,BUSES["KC"] = true
---------------------------------------------------
diff --git a/scripts/src/formats.lua b/scripts/src/formats.lua
index b25909dbb3a..071982e83fe 100644
--- a/scripts/src/formats.lua
+++ b/scripts/src/formats.lua
@@ -1147,6 +1147,18 @@ end
--------------------------------------------------
--
+--@src/lib/formats/mtx_dsk.h,FORMATS["MTX_DSK"] = true
+--------------------------------------------------
+
+if (FORMATS["MTX_DSK"]~=null or _OPTIONS["with-tools"]) then
+ files {
+ MAME_DIR.. "src/lib/formats/mtx_dsk.cpp",
+ MAME_DIR.. "src/lib/formats/mtx_dsk.h",
+ }
+end
+
+--------------------------------------------------
+--
--@src/lib/formats/mz_cas.h,FORMATS["MZ_CAS"] = true
--------------------------------------------------
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index ee9eb3117d2..52cb428d421 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -772,6 +772,7 @@ BUSES["MACPDS"] = true
BUSES["MIDI"] = true
BUSES["MEGADRIVE"] = true
BUSES["MSX_SLOT"] = true
+BUSES["MTX"] = true
BUSES["NASBUS"] = true
BUSES["NEOGEO"] = true
BUSES["NEOGEO_CTRL"] = true
@@ -933,6 +934,7 @@ FORMATS["MFM_HD"] = true
FORMATS["MM_DSK"] = true
FORMATS["MS0515_DSK"] = true
FORMATS["MSX_DSK"] = true
+FORMATS["MTX_DSK"] = true
FORMATS["MZ_CAS"] = true
FORMATS["NANOS_DSK"] = true
FORMATS["NASCOM_DSK"] = true
diff --git a/src/devices/bus/mtx/exp.cpp b/src/devices/bus/mtx/exp.cpp
new file mode 100644
index 00000000000..d08827f8caa
--- /dev/null
+++ b/src/devices/bus/mtx/exp.cpp
@@ -0,0 +1,126 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/**********************************************************************
+
+ MTX expansion emulation
+
+**********************************************************************/
+
+#include "emu.h"
+#include "exp.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(MTX_EXP_SLOT, mtx_exp_slot_device, "mtx_exp_slot", "MTX expansion slot")
+
+
+//**************************************************************************
+// DEVICE MTX_BUS PORT INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_mtx_exp_interface - constructor
+//-------------------------------------------------
+
+device_mtx_exp_interface::device_mtx_exp_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device)
+{
+ m_slot = dynamic_cast<mtx_exp_slot_device *>(device.owner());
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// mtx_exp_slot_device - constructor
+//-------------------------------------------------
+
+mtx_exp_slot_device::mtx_exp_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, MTX_EXP_SLOT, tag, owner, clock)
+ , device_slot_interface(mconfig, *this)
+ , m_io(nullptr)
+ , m_card(nullptr)
+ , m_busreq_handler(*this)
+ , m_int_handler(*this)
+ , m_nmi_handler(*this)
+{
+}
+
+
+//-------------------------------------------------
+// device_validity_check -
+//-------------------------------------------------
+
+void mtx_exp_slot_device::device_validity_check(validity_checker &valid) const
+{
+ device_t *const carddev = get_card_device();
+ if (carddev && !dynamic_cast<device_mtx_exp_interface *>(carddev))
+ osd_printf_error("Card device %s (%s) does not implement device_mtx_exp_interface\n", carddev->tag(), carddev->name());
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void mtx_exp_slot_device::device_start()
+{
+ device_t *const carddev = get_card_device();
+ if (carddev && !dynamic_cast<device_mtx_exp_interface *>(carddev))
+ osd_printf_error("Card device %s (%s) does not implement device_mtx_exp_interface\n", carddev->tag(), carddev->name());
+
+ // resolve callbacks
+ m_busreq_handler.resolve_safe();
+ m_int_handler.resolve_safe();
+ m_nmi_handler.resolve_safe();
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void mtx_exp_slot_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// set_program_space - set address space we are attached to
+//-------------------------------------------------
+
+void mtx_exp_slot_device::set_program_space(address_space *program)
+{
+ m_program = program;
+}
+
+//-------------------------------------------------
+// set_io_space - set address space we are attached to
+//-------------------------------------------------
+
+void mtx_exp_slot_device::set_io_space(address_space *io)
+{
+ m_io = io;
+}
+
+//-------------------------------------------------
+// SLOT_INTERFACE( mtx_exp_devices )
+//-------------------------------------------------
+
+
+// slot devices
+//#include "fdx.h"
+#include "sdx.h"
+
+
+void mtx_expansion_devices(device_slot_interface &device)
+{
+ //device.option_add("fdx", MTX_FDX); /* FDX Floppy Disc System */
+ device.option_add("sdxbas", MTX_SDXBAS); /* SDX Floppy Disc System (SDX ROM)*/
+ device.option_add("sdxcpm", MTX_SDXCPM); /* SDX Floppy Disc System (CP/M ROM and 80 column card) */
+}
diff --git a/src/devices/bus/mtx/exp.h b/src/devices/bus/mtx/exp.h
new file mode 100644
index 00000000000..21cb4e80c9d
--- /dev/null
+++ b/src/devices/bus/mtx/exp.h
@@ -0,0 +1,92 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/**********************************************************************
+
+ MTX expansion emulation
+
+**********************************************************************/
+
+
+#ifndef MAME_BUS_MTX_EXP_H
+#define MAME_BUS_MTX_EXP_H
+
+#pragma once
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> mtx_exp_slot_device
+
+class device_mtx_exp_interface;
+
+class mtx_exp_slot_device : public device_t, public device_slot_interface
+{
+public:
+ // construction/destruction
+ template <typename T>
+ mtx_exp_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&slot_options, const char *default_option)
+ : mtx_exp_slot_device(mconfig, tag, owner)
+ {
+ option_reset();
+ slot_options(*this);
+ set_default_option(default_option);
+ set_fixed(false);
+ }
+
+ mtx_exp_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0);
+
+ void set_program_space(address_space *program);
+ void set_io_space(address_space *io);
+
+ // callbacks
+ auto busreq_handler() { return m_busreq_handler.bind(); }
+ auto int_handler() { return m_int_handler.bind(); }
+ auto nmi_handler() { return m_nmi_handler.bind(); }
+
+ DECLARE_WRITE_LINE_MEMBER( busreq_w ) { m_busreq_handler(state); }
+ DECLARE_WRITE_LINE_MEMBER( int_w ) { m_int_handler(state); }
+ DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_nmi_handler(state); }
+
+ address_space *m_program;
+ address_space *m_io;
+
+protected:
+ // device-level overrides
+ virtual void device_validity_check(validity_checker &valid) const override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ device_mtx_exp_interface *m_card;
+
+private:
+ devcb_write_line m_busreq_handler;
+ devcb_write_line m_int_handler;
+ devcb_write_line m_nmi_handler;
+};
+
+
+// ======================> device_mtx_exp_interface
+
+class device_mtx_exp_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_mtx_exp_interface(const machine_config &mconfig, device_t &device);
+
+protected:
+ address_space &program_space() { return *m_slot->m_program; }
+ address_space &io_space() { return *m_slot->m_io; }
+
+ mtx_exp_slot_device *m_slot;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(MTX_EXP_SLOT, mtx_exp_slot_device)
+
+void mtx_expansion_devices(device_slot_interface &device);
+
+
+#endif // MAME_BUS_MTX_EXP_H
diff --git a/src/devices/bus/mtx/sdx.cpp b/src/devices/bus/mtx/sdx.cpp
new file mode 100644
index 00000000000..27f7285d6d2
--- /dev/null
+++ b/src/devices/bus/mtx/sdx.cpp
@@ -0,0 +1,425 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/**********************************************************************
+
+ MTX SDX Controller
+
+**********************************************************************/
+
+
+#include "emu.h"
+#include "sdx.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(MTX_SDXBAS, mtx_sdxbas_device, "mtx_sdxbas", "MTX SDX Controller (BASIC)")
+DEFINE_DEVICE_TYPE(MTX_SDXCPM, mtx_sdxcpm_device, "mtx_sdxcpm", "MTX SDX Controller (CP/M)")
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( sdx_floppies )
+//-------------------------------------------------
+
+static void sdx_floppies(device_slot_interface &device)
+{
+ device.option_add("35dd", FLOPPY_35_DD);
+ device.option_add("525qd", FLOPPY_525_QD);
+}
+
+FLOPPY_FORMATS_MEMBER(mtx_sdx_device::floppy_formats)
+ FLOPPY_MTX_FORMAT
+FLOPPY_FORMATS_END
+
+//-------------------------------------------------
+// ROM( sdx )
+//-------------------------------------------------
+
+ROM_START( sdxbas )
+ ROM_REGION(0x2000, "sdx_rom", ROMREGION_ERASE00)
+ ROM_DEFAULT_BIOS("sdx07")
+ ROM_SYSTEM_BIOS(0, "sdx07", "Type 07")
+ ROMX_LOAD("sdxbas07.rom", 0x0000, 0x2000, CRC(db88b245) SHA1(05c89db8e39ec3165b4620432f48e1d59abe10dd), ROM_BIOS(0))
+ ROM_SYSTEM_BIOS(1, "sdx03", "Type 03")
+ ROMX_LOAD("sdxbas03.rom", 0x0000, 0x2000, CRC(2fc46a46) SHA1(f08e6a8cffbb3ca39633be6e9958bec85d1e5981), ROM_BIOS(1))
+ROM_END
+
+ROM_START( sdxcpm )
+ ROM_REGION(0x2000, "sdx_rom", ROMREGION_ERASE00)
+ ROM_DEFAULT_BIOS("sdx07")
+ ROM_SYSTEM_BIOS(0, "sdx07", "SDX07 CP/M")
+ ROMX_LOAD("sdxcpm07.rom", 0x0000, 0x2000, CRC(622a04ea) SHA1(c633ce1054b45afda53116e0c6e272a1ae6a2155), ROM_BIOS(0))
+
+ ROM_REGION(0x2000, "chargen", 0)
+ ROM_LOAD("80z_7a.bin", 0x0000, 0x1000, CRC(ea6fe865) SHA1(f84883f79bed34501e5828336894fad929bddbb5)) // alpha
+ ROM_LOAD("80z_9a.bin", 0x1000, 0x1000, NO_DUMP) // graphic
+ROM_END
+
+//-------------------------------------------------
+// INPUT_PORTS( sdx )
+//-------------------------------------------------
+
+INPUT_PORTS_START( sdx )
+ PORT_START("DSW0")
+ PORT_DIPNAME(0x01, 0x00, "Drive A: Head-load solenoid present") PORT_DIPLOCATION("SW1:1")
+ PORT_DIPSETTING(0x00, DEF_STR(Yes))
+ PORT_DIPSETTING(0x01, DEF_STR(No))
+ PORT_DIPNAME(0x02, 0x00, "Drive A: Double-sided drive") PORT_DIPLOCATION("SW1:2")
+ PORT_DIPSETTING(0x00, DEF_STR(Yes))
+ PORT_DIPSETTING(0x02, DEF_STR(No))
+ PORT_DIPNAME(0x04, 0x00, "Drive A: 96 TPI drive") PORT_DIPLOCATION("SW1:3")
+ PORT_DIPSETTING(0x00, DEF_STR(Yes))
+ PORT_DIPSETTING(0x04, DEF_STR(No))
+ PORT_DIPNAME(0x08, 0x00, "Drive A: Stepping rate") PORT_DIPLOCATION("SW1:4")
+ PORT_DIPSETTING(0x00, "Stepping rate 6ms")
+ PORT_DIPSETTING(0x08, "Stepping rate 12ms")
+
+ PORT_START("DSW1")
+ PORT_DIPNAME(0x01, 0x00, "Drive B: Head-load solenoid present") PORT_DIPLOCATION("SW2:1")
+ PORT_DIPSETTING(0x00, DEF_STR(Yes))
+ PORT_DIPSETTING(0x01, DEF_STR(No))
+ PORT_DIPNAME(0x02, 0x00, "Drive B: Double-sided drive") PORT_DIPLOCATION("SW2:2")
+ PORT_DIPSETTING(0x00, DEF_STR(Yes))
+ PORT_DIPSETTING(0x02, DEF_STR(No))
+ PORT_DIPNAME(0x04, 0x00, "Drive B: 96 TPI drive") PORT_DIPLOCATION("SW2:3")
+ PORT_DIPSETTING(0x00, DEF_STR(Yes))
+ PORT_DIPSETTING(0x04, DEF_STR(No))
+ PORT_DIPNAME(0x08, 0x00, "Drive B: Stepping rate") PORT_DIPLOCATION("SW2:4")
+ PORT_DIPSETTING(0x00, "Stepping rate 6ms")
+ PORT_DIPSETTING(0x08, "Stepping rate 12ms")
+INPUT_PORTS_END
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor mtx_sdx_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(sdx);
+}
+
+//-------------------------------------------------
+// gfx_layout mtx_sdx_charlayout
+//-------------------------------------------------
+
+static const gfx_layout mtx_sdx_charlayout =
+{
+ 8, 10, /* 8 x 10 characters */
+ 256, /* 256 characters */
+ 1, /* 1 bits per pixel */
+ { 0 }, /* no bitplanes */
+ /* x offsets */
+ { 0, 1, 2, 3, 4, 5, 6, 7 },
+ /* y offsets */
+ { 0 * 8, 1 * 8, 2 * 8, 3 * 8, 4 * 8, 5 * 8, 6 * 8, 7 * 8, 8 * 8, 9 * 8 },
+ 8 * 16 /* every char takes 16 bytes */
+};
+
+//-------------------------------------------------
+// GFXDECODE( gfx_mtx_sdx )
+//-------------------------------------------------
+
+static GFXDECODE_START(gfx_mtx_sdx)
+ GFXDECODE_ENTRY("chargen", 0, mtx_sdx_charlayout, 0, 8)
+GFXDECODE_END
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void mtx_sdxbas_device::device_add_mconfig(machine_config &config)
+{
+ /* fdc */
+ MB8877(config, m_fdc, 8_MHz_XTAL / 8);
+ m_fdc->hld_wr_callback().set(FUNC(mtx_sdx_device::motor_w));
+
+ FLOPPY_CONNECTOR(config, "fdc:0", sdx_floppies, "525qd", mtx_sdx_device::floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, "fdc:1", sdx_floppies, "525qd", mtx_sdx_device::floppy_formats).enable_sound(true);
+}
+
+void mtx_sdxcpm_device::device_add_mconfig(machine_config &config)
+{
+ /* fdc */
+ MB8877(config, m_fdc, 8_MHz_XTAL / 8);
+ m_fdc->hld_wr_callback().set(FUNC(mtx_sdx_device::motor_w));
+
+ FLOPPY_CONNECTOR(config, "fdc:0", sdx_floppies, "525qd", mtx_sdx_device::floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, "fdc:1", sdx_floppies, "525qd", mtx_sdx_device::floppy_formats).enable_sound(true);
+
+ /* 80 column video card - required to be installed in MTX internally */
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
+ m_screen->set_refresh_hz(50);
+ m_screen->set_size(960, 313);
+ m_screen->set_visarea(00, 640 - 1, 0, 240 - 1);
+ m_screen->set_screen_update("crtc", FUNC(hd6845_device::screen_update));
+
+ GFXDECODE(config, "gfxdecode", "palette", gfx_mtx_sdx);
+ PALETTE(config, "palette", palette_device::RGB_3BIT);
+
+ HD6845(config, m_crtc, 15_MHz_XTAL / 8);
+ m_crtc->set_screen("screen");
+ m_crtc->set_show_border_area(false);
+ m_crtc->set_char_width(8);
+ m_crtc->set_update_row_callback(FUNC(mtx_sdxcpm_device::crtc_update_row), this);
+}
+
+
+const tiny_rom_entry *mtx_sdxbas_device::device_rom_region() const
+{
+ return ROM_NAME( sdxbas );
+}
+
+const tiny_rom_entry *mtx_sdxcpm_device::device_rom_region() const
+{
+ return ROM_NAME( sdxcpm );
+}
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// mtx_sdx_device - constructor
+//-------------------------------------------------
+
+mtx_sdx_device::mtx_sdx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_mtx_exp_interface(mconfig, *this)
+ , m_sdx_rom(*this, "sdx_rom")
+ , m_fdc(*this, "fdc")
+ , m_floppy0(*this, "fdc:0")
+ , m_floppy1(*this, "fdc:1")
+ , m_dsw(*this, "DSW%u", 0)
+{
+}
+
+mtx_sdxbas_device::mtx_sdxbas_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mtx_sdx_device(mconfig, MTX_SDXBAS, tag, owner, clock)
+{
+}
+
+mtx_sdxcpm_device::mtx_sdxcpm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mtx_sdx_device(mconfig, MTX_SDXCPM, tag, owner, clock)
+ , m_screen(*this, "screen")
+ , m_palette(*this, "palette")
+ , m_crtc(*this, "crtc")
+ , m_char_rom(*this, "chargen")
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void mtx_sdxbas_device::device_start()
+{
+ save_item(NAME(m_control));
+}
+
+void mtx_sdxcpm_device::device_start()
+{
+ save_item(NAME(m_control));
+ save_item(NAME(m_80col_ascii));
+ save_item(NAME(m_80col_attr));
+ save_item(NAME(m_80col_addr));
+ save_item(NAME(m_80col_char_ram));
+ save_item(NAME(m_80col_attr_ram));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void mtx_sdxbas_device::device_reset()
+{
+ machine().root_device().membank("rommap_bank1")->configure_entry(3, m_sdx_rom->base());
+
+ /* SDX FDC */
+ io_space().install_readwrite_handler(0x10, 0x13, read8sm_delegate(FUNC(mb8877_device::read), m_fdc.target()), write8sm_delegate(FUNC(mb8877_device::write), m_fdc.target()));
+ io_space().install_readwrite_handler(0x14, 0x14, read8_delegate(FUNC(mtx_sdx_device::sdx_status_r), this), write8_delegate(FUNC(mtx_sdx_device::sdx_control_w), this));
+}
+
+void mtx_sdxcpm_device::device_reset()
+{
+ machine().root_device().membank("rommap_bank1")->configure_entry(3, m_sdx_rom->base());
+
+ /* SDX FDC */
+ io_space().install_readwrite_handler(0x10, 0x13, read8sm_delegate(FUNC(mb8877_device::read), m_fdc.target()), write8sm_delegate(FUNC(mb8877_device::write), m_fdc.target()));
+ io_space().install_readwrite_handler(0x14, 0x14, read8_delegate(FUNC(mtx_sdx_device::sdx_status_r), this), write8_delegate(FUNC(mtx_sdx_device::sdx_control_w), this));
+
+ /* 80 column */
+ io_space().install_readwrite_handler(0x30, 0x33, read8_delegate(FUNC(mtx_sdxcpm_device::mtx_80col_r), this), write8_delegate(FUNC(mtx_sdxcpm_device::mtx_80col_w), this));
+ io_space().install_readwrite_handler(0x38, 0x38, read8smo_delegate(FUNC(mc6845_device::status_r), m_crtc.target()), write8smo_delegate(FUNC(mc6845_device::address_w), m_crtc.target()));
+ io_space().install_readwrite_handler(0x39, 0x39, read8smo_delegate(FUNC(mc6845_device::register_r), m_crtc.target()), write8smo_delegate(FUNC(mc6845_device::register_w), m_crtc.target()));
+
+ memset(m_80col_char_ram, 0, sizeof(m_80col_char_ram));
+ memset(m_80col_attr_ram, 0, sizeof(m_80col_attr_ram));
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+READ8_MEMBER(mtx_sdx_device::sdx_status_r)
+{
+ /*
+ bit description
+ 0 Head load: 1 - head load on drive
+ 1 Double-sided: 1 if drive double-sided
+ 2 TPI: 0 - 48 TPI drive. 1 - 96 TPI drive
+ 3 Track stepping rate: 0 - 12ms, 1 - 6ms
+ 4 No. of drives: 0 - 1 drive, 1 - 2 drives
+ 5 Ready: 1 - drive ready
+ 6 Interrupt: 1 - FDC interrupt request
+ 7 Data request: 1 - FDC data request
+ */
+
+ uint8_t data = 0x00;
+
+ data |= m_dsw[BIT(m_control, 0)].read_safe(0x0f) & 0x0f;
+
+ data |= (m_floppy0->get_device() && m_floppy1->get_device()) ? 0x10 : 0x00;
+
+ if (m_floppy)
+ data |= m_floppy->ready_r() ? 0x00 : 0x20;
+
+ data |= m_fdc->intrq_r() ? 0x40 : 0x00;
+ data |= m_fdc->drq_r() ? 0x80 : 0x00;
+
+ return data;
+}
+
+WRITE8_MEMBER(mtx_sdx_device::sdx_control_w)
+{
+ /*
+ bit description
+ 0 Drive select: 0 - drive A, 1 - drive B
+ 1 Side select: 0 - side 0, 1 - side 1
+ 2 Motor on: 1 - turns drive motor on
+ 3 Motor ready: 1 - drive motor ready
+ 4 Density: 0 - FM, 1 - MFM
+ */
+
+ m_control = data;
+
+ /* bit 0: drive select */
+ m_floppy = BIT(data, 0) ? m_floppy1->get_device() : m_floppy0->get_device();
+
+ m_fdc->set_floppy(m_floppy);
+
+ if (m_floppy)
+ {
+ /* bit 1: side select */
+ m_floppy->ss_w(BIT(data, 1));
+ logerror("motor on %d\n", BIT(data, 2));
+ /* bit 2: motor on */
+ m_floppy->mon_w(!(BIT(data, 2) || m_fdc->hld_r()));
+ logerror("head load %d\n", m_fdc->hld_r());
+ /* bit 3: motor ready */
+ //if (BIT(data, 3))
+ //m_floppy->mon_w(!BIT(data, 2));
+ //m_floppy->mon_w(!BIT(data, 3));
+ logerror("motor ready %d\n", BIT(data, 3));
+ }
+
+ /* bit 4: density */
+ m_fdc->dden_w(!BIT(data, 4));
+}
+
+WRITE_LINE_MEMBER(mtx_sdx_device::motor_w)
+{
+ if (m_floppy0->get_device()) m_floppy0->get_device()->mon_w(0);
+ if (m_floppy1->get_device()) m_floppy1->get_device()->mon_w(0);
+}
+
+//-------------------------------------------------
+// 80 column video board
+//-------------------------------------------------
+
+READ8_MEMBER(mtx_sdxcpm_device::mtx_80col_r)
+{
+ uint8_t data = 0xff;
+
+ switch (offset)
+ {
+ case 0:
+ /* ring the bell */
+ break;
+ case 2:
+ if (!BIT(m_80col_addr, 15))
+ data = m_80col_char_ram[m_80col_addr & 0x07ff];
+ break;
+ case 3:
+ if (!BIT(m_80col_addr, 15))
+ data = m_80col_attr_ram[m_80col_addr & 0x07ff];
+ break;
+ }
+ return data;
+}
+
+WRITE8_MEMBER(mtx_sdxcpm_device::mtx_80col_w)
+{
+ switch (offset)
+ {
+ case 0:
+ m_80col_addr = (m_80col_addr & 0xff00) | data;
+ /* write to ram */
+ if (BIT(m_80col_addr, 15))
+ {
+ /* write enable ascii ram */
+ if (BIT(m_80col_addr, 14))
+ m_80col_char_ram[m_80col_addr & 0x07ff] = m_80col_ascii;
+
+ /* write enable attribute ram */
+ if (BIT(m_80col_addr, 13))
+ m_80col_attr_ram[m_80col_addr & 0x07ff] = m_80col_attr;
+ }
+ break;
+ case 1:
+ m_80col_addr = (data << 8) | (m_80col_addr & 0x00ff);
+ break;
+ case 2:
+ m_80col_ascii = data;
+ break;
+ case 3:
+ m_80col_attr = data;
+ break;
+ }
+}
+
+MC6845_UPDATE_ROW(mtx_sdxcpm_device::crtc_update_row)
+{
+ const pen_t *pen = m_palette->pens();
+
+ for (int column = 0; column < x_count; column++)
+ {
+ uint8_t code = m_80col_char_ram[(ma + column) & 0x7ff];
+ uint8_t attr = m_80col_attr_ram[(ma + column) & 0x7ff];
+ offs_t addr = (code << 4) | (ra & 0x0f);
+ uint8_t data = m_char_rom->base()[addr];
+
+ if (column == cursor_x)
+ {
+ data = 0xff;
+ attr = 0x07;
+ }
+
+ for (int bit = 0; bit < 8; bit++)
+ {
+ int x = (column * 8) + bit;
+ int fg = attr & 0x07;
+ int bg = attr & 0x38;
+
+ int color = BIT(data, 7) ? fg : bg;
+
+ bitmap.pix32(y, x) = pen[de ? color : 0];
+
+ data <<= 1;
+ }
+ }
+}
diff --git a/src/devices/bus/mtx/sdx.h b/src/devices/bus/mtx/sdx.h
new file mode 100644
index 00000000000..dff83358dd4
--- /dev/null
+++ b/src/devices/bus/mtx/sdx.h
@@ -0,0 +1,105 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/**********************************************************************
+
+ MTX SDX Controller
+
+**********************************************************************/
+
+
+#ifndef MAME_BUS_MTX_EXP_SDX_H
+#define MAME_BUS_MTX_EXP_SDX_H
+
+#include "exp.h"
+#include "imagedev/floppy.h"
+#include "machine/wd_fdc.h"
+#include "video/mc6845.h"
+#include "formats/mtx_dsk.h"
+#include "emupal.h"
+#include "screen.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class mtx_sdx_device :
+ public device_t,
+ public device_mtx_exp_interface
+{
+public:
+ DECLARE_FLOPPY_FORMATS(floppy_formats);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override;
+
+ DECLARE_READ8_MEMBER(sdx_status_r);
+ DECLARE_WRITE8_MEMBER(sdx_control_w);
+ DECLARE_WRITE_LINE_MEMBER(motor_w);
+
+protected:
+ // construction/destruction
+ mtx_sdx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ required_memory_region m_sdx_rom;
+ required_device<mb8877_device> m_fdc;
+ required_device<floppy_connector> m_floppy0;
+ required_device<floppy_connector> m_floppy1;
+ required_ioport_array<2> m_dsw;
+ floppy_image_device *m_floppy;
+ uint8_t m_control;
+};
+
+class mtx_sdxbas_device : public mtx_sdx_device
+{
+public:
+ // construction/destruction
+ mtx_sdxbas_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+};
+
+class mtx_sdxcpm_device : public mtx_sdx_device
+{
+public:
+ // construction/destruction
+ mtx_sdxcpm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ DECLARE_READ8_MEMBER(mtx_80col_r);
+ DECLARE_WRITE8_MEMBER(mtx_80col_w);
+ MC6845_UPDATE_ROW(crtc_update_row);
+
+ required_device<screen_device> m_screen;
+ required_device<palette_device> m_palette;
+ required_device<mc6845_device> m_crtc;
+ required_memory_region m_char_rom;
+ uint8_t m_80col_char_ram[0x800];
+ uint8_t m_80col_attr_ram[0x800];
+ uint8_t m_80col_ascii, m_80col_attr;
+ uint16_t m_80col_addr;
+};
+
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(MTX_SDXBAS, mtx_sdxbas_device)
+DECLARE_DEVICE_TYPE(MTX_SDXCPM, mtx_sdxcpm_device)
+
+
+#endif // MAME_BUS_MTX_EXP_SDX_H
diff --git a/src/lib/formats/mtx_dsk.cpp b/src/lib/formats/mtx_dsk.cpp
new file mode 100644
index 00000000000..95420f40aab
--- /dev/null
+++ b/src/lib/formats/mtx_dsk.cpp
@@ -0,0 +1,53 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/***************************************************************************
+
+ Memotech MTX
+
+ Disk image format
+
+***************************************************************************/
+
+#include "mtx_dsk.h"
+
+mtx_format::mtx_format() : wd177x_format(formats)
+{
+}
+
+const char *mtx_format::name() const
+{
+ return "mtx";
+}
+
+const char *mtx_format::description() const
+{
+ return "Memotech MTX disk image";
+}
+
+const char *mtx_format::extensions() const
+{
+ return "mfloppy";
+}
+
+const mtx_format::format mtx_format::formats[] =
+{
+ { // 320k 5 1/4 inch double density single sided (Type 03)
+ floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
+ 2000, 16, 40, 2, 256, {}, 1, {}, 32, 22, 54
+ },
+ { // 640k 5 1/4 inch double density double sided (Type 07)
+ floppy_image::FF_525, floppy_image::DSQD, floppy_image::MFM,
+ 2000, 16, 80, 2, 256, {}, 1, {}, 32, 22, 54
+ },
+ { // 320k 3 1/2 inch double density single sided (Type 03)
+ floppy_image::FF_35, floppy_image::DSDD, floppy_image::MFM,
+ 2000, 16, 40, 2, 256, {}, 1, {}, 32, 22, 54
+ },
+ { // 640k 3 1/2 inch double density double sided (Type 07)
+ floppy_image::FF_35, floppy_image::DSQD, floppy_image::MFM,
+ 2000, 16, 80, 2, 256, {}, 1, {}, 32, 22, 54
+ },
+ {}
+};
+
+const floppy_format_type FLOPPY_MTX_FORMAT = &floppy_image_format_creator<mtx_format>;
diff --git a/src/lib/formats/mtx_dsk.h b/src/lib/formats/mtx_dsk.h
new file mode 100644
index 00000000000..86f74bccfc5
--- /dev/null
+++ b/src/lib/formats/mtx_dsk.h
@@ -0,0 +1,33 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/***************************************************************************
+
+ Memotech MTX
+
+ Disk image format
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __MTX_DSK_H__
+#define __MTX_DSK_H__
+
+#include "wd177x_dsk.h"
+
+class mtx_format : public wd177x_format
+{
+public:
+ mtx_format();
+
+ virtual const char *name() const override;
+ virtual const char *description() const override;
+ virtual const char *extensions() const override;
+
+private:
+ static const format formats[];
+};
+
+extern const floppy_format_type FLOPPY_MTX_FORMAT;
+
+#endif // __MTX_DSK_H__
diff --git a/src/mame/drivers/mtx.cpp b/src/mame/drivers/mtx.cpp
index da32536facc..1ca48a8e2f3 100644
--- a/src/mame/drivers/mtx.cpp
+++ b/src/mame/drivers/mtx.cpp
@@ -11,8 +11,7 @@
TODO:
- cassette
- - cartridges
- - SDX/FDX floppy
+ - FDX floppy
- HDX hard disk
- HRX high resolution graphics
- "Silicon" disks
@@ -24,14 +23,8 @@
#include "includes/mtx.h"
#include "bus/centronics/ctronics.h"
-#include "cpu/z80/z80.h"
-#include "machine/z80daisy.h"
#include "imagedev/cassette.h"
#include "imagedev/snapquik.h"
-#include "machine/ram.h"
-#include "machine/z80ctc.h"
-#include "machine/z80dart.h"
-#include "sound/sn76496.h"
#include "video/tms9928a.h"
#include "softlist.h"
@@ -64,7 +57,7 @@ void mtx_state::mtx_io(address_map &map)
map(0x04, 0x04).r(FUNC(mtx_state::mtx_prt_r)).w("cent_data_out", FUNC(output_latch_device::bus_w));
map(0x05, 0x05).rw(FUNC(mtx_state::mtx_key_lo_r), FUNC(mtx_state::mtx_sense_w));
map(0x06, 0x06).rw(FUNC(mtx_state::mtx_key_hi_r), FUNC(mtx_state::mtx_sound_latch_w));
-// map(0x07, 0x07) PIO
+ // map(0x07, 0x07) PIO
map(0x08, 0x0b).rw(m_z80ctc, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
map(0x1f, 0x1f).w(FUNC(mtx_state::mtx_cst_motor_w));
map(0x30, 0x31).w(FUNC(mtx_state::hrx_address_w));
@@ -202,6 +195,12 @@ static INPUT_PORTS_START( mtx512 )
PORT_DIPSETTING(0x08, DEF_STR(Off) )
PORT_DIPSETTING(0x00, DEF_STR(On) )
PORT_BIT( 0xf3, IP_ACTIVE_LOW, IPT_UNUSED)
+
+ PORT_START("keyboard_rom")
+ PORT_CONFNAME(0x03, 0x00, "Keyboard ROM")
+ PORT_CONFSETTING(0x00, "None")
+ PORT_CONFSETTING(0x01, "Denmark")
+ PORT_CONFSETTING(0x02, "Finland")
INPUT_PORTS_END
/***************************************************************************
@@ -243,7 +242,7 @@ WRITE_LINE_MEMBER(mtx_state::ctc_trg2_w)
static const z80_daisy_config mtx_daisy_chain[] =
{
- { Z80CTC_TAG },
+ { "z80ctc" },
{ nullptr }
};
@@ -253,8 +252,8 @@ static const z80_daisy_config mtx_daisy_chain[] =
static const z80_daisy_config rs128_daisy_chain[] =
{
- { Z80CTC_TAG },
- { Z80DART_TAG },
+ { "z80ctc" },
+ { "z80dart" },
{ nullptr }
};
@@ -283,19 +282,16 @@ WRITE_LINE_MEMBER(mtx_state::mtx_tms9929a_interrupt)
machine_config( mtx512 )
-------------------------------------------------*/
-MACHINE_CONFIG_START(mtx_state::mtx512)
-
+void mtx_state::mtx512(machine_config &config)
+{
/* basic machine hardware */
- Z80(config, m_maincpu, XTAL(4'000'000));
+ Z80(config, m_maincpu, 4_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &mtx_state::mtx_mem);
m_maincpu->set_addrmap(AS_IO, &mtx_state::mtx_io);
m_maincpu->set_daisy_config(mtx_daisy_chain);
- MCFG_MACHINE_START_OVERRIDE(mtx_state,mtx512)
- MCFG_MACHINE_RESET_OVERRIDE(mtx_state,mtx512)
-
/* video hardware */
- tms9929a_device &vdp(TMS9929A(config, "tms9929a", XTAL(10'738'635)));
+ tms9929a_device &vdp(TMS9929A(config, "tms9929a", 10.6875_MHz_XTAL));
vdp.set_screen("screen");
vdp.set_vram_size(0x4000);
vdp.int_callback().set(FUNC(mtx_state::mtx_tms9929a_interrupt));
@@ -303,15 +299,15 @@ MACHINE_CONFIG_START(mtx_state::mtx512)
/* sound hardware */
SPEAKER(config, "mono").front_center();
- SN76489A(config, SN76489A_TAG, XTAL(4'000'000)).add_route(ALL_OUTPUTS, "mono", 1.00);
+ SN76489A(config, m_sn, 4_MHz_XTAL).add_route(ALL_OUTPUTS, "mono", 1.00);
/* devices */
- Z80CTC(config, m_z80ctc, XTAL(4'000'000));
+ Z80CTC(config, m_z80ctc, 4_MHz_XTAL);
m_z80ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_z80ctc->zc_callback<1>().set(FUNC(mtx_state::ctc_trg1_w));
m_z80ctc->zc_callback<2>().set(FUNC(mtx_state::ctc_trg2_w));
- TIMER(config, "z80ctc_timer").configure_periodic(FUNC(mtx_state::ctc_tick), attotime::from_hz(XTAL(4'000'000)/13));
+ TIMER(config, "z80ctc_timer").configure_periodic(FUNC(mtx_state::ctc_tick), attotime::from_hz(4_MHz_XTAL/13));
CENTRONICS(config, m_centronics, centronics_devices, "printer");
m_centronics->busy_handler().set(FUNC(mtx_state::write_centronics_busy));
@@ -322,7 +318,11 @@ MACHINE_CONFIG_START(mtx_state::mtx512)
output_latch_device &cent_data_out(OUTPUT_LATCH(config, "cent_data_out"));
m_centronics->set_output_latch(cent_data_out);
- MCFG_SNAPSHOT_ADD("snapshot", mtx_state, mtx, "mtx", attotime::from_seconds(1))
+ snapshot_image_device &snapshot(SNAPSHOT(config, "snapshot"));
+ snapshot.set_handler(snapquick_load_delegate(&SNAPSHOT_LOAD_NAME(mtx_state, mtx), this), "mtx", attotime::from_seconds(1));
+ quickload_image_device &quickload(QUICKLOAD(config, "quickload"));
+ quickload.set_handler(snapquick_load_delegate(&QUICKLOAD_LOAD_NAME(mtx_state, mtx), this), "run", attotime::from_seconds(1));
+
CASSETTE(config, m_cassette);
m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_MUTED);
m_cassette->set_interface("mtx_cass");
@@ -333,20 +333,25 @@ MACHINE_CONFIG_START(mtx_state::mtx512)
RAM(config, m_ram).set_default_size("64K").set_extra_options("96K,128K,192K,320K,448K,512K");
/* rom extension board */
- MCFG_GENERIC_SOCKET_ADD("extrom", generic_plain_slot, "mtx_rom")
- MCFG_GENERIC_EXTENSIONS("bin,rom")
- MCFG_GENERIC_LOAD(mtx_state, extrom_load)
+ GENERIC_SOCKET(config, m_extrom, generic_plain_slot, "mtx_rom", "bin,rom");
+ m_extrom->set_device_load(device_image_load_delegate(&mtx_state::device_image_load_extrom_load, this));
+
+ /* rs232 board with disk drive bus */
+ MTX_EXP_SLOT(config, m_exp, mtx_expansion_devices, nullptr);
+ m_exp->int_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
+ m_exp->nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI);
+ m_exp->busreq_handler().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
/* cartridge slot */
- MCFG_GENERIC_SOCKET_ADD("rompak", generic_plain_slot, "mtx_cart")
- MCFG_GENERIC_EXTENSIONS("bin,rom")
- MCFG_GENERIC_LOAD(mtx_state, rompak_load)
+ GENERIC_CARTSLOT(config, m_rompak, generic_plain_slot, "mtx_cart", "bin,rom");
+ m_rompak->set_device_load(device_image_load_delegate(&mtx_state::device_image_load_rompak_load, this));
/* software lists */
SOFTWARE_LIST(config, "cass_list").set_original("mtx_cass");
+ SOFTWARE_LIST(config, "flop_list").set_original("mtx_flop");
SOFTWARE_LIST(config, "cart_list").set_original("mtx_cart");
SOFTWARE_LIST(config, "rom_list").set_original("mtx_rom");
-MACHINE_CONFIG_END
+}
void mtx_state::mtx500(machine_config &config)
{
@@ -369,7 +374,7 @@ void mtx_state::rs128(machine_config &config)
m_maincpu->set_daisy_config(rs128_daisy_chain);
/* devices */
- Z80DART(config, m_z80dart, XTAL(4'000'000));
+ Z80DART(config, m_z80dart, 4_MHz_XTAL);
m_z80dart->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
/* internal ram */
@@ -382,30 +387,23 @@ void mtx_state::rs128(machine_config &config)
ROM_START( mtx512 )
ROM_REGION( 0x02000, "user1", 0 )
- ROM_LOAD( "osrom", 0x0000, 0x2000, CRC(9ca858cc) SHA1(3804503a58f0bcdea96bb6488833782ebd03976d) )
+ ROM_SYSTEM_BIOS( 0, "uk", "UK" )
+ ROMX_LOAD( "mtx1a.9h", 0x0000, 0x2000, CRC(9ca858cc) SHA1(3804503a58f0bcdea96bb6488833782ebd03976d), ROM_BIOS(0) ) /* OS */
+ ROM_SYSTEM_BIOS( 1, "de", "German" )
+ ROMX_LOAD( "mtx2a.9h", 0x0000, 0x2000, CRC(1c7bbe98) SHA1(8c950051b830e5e0c41072d6bd893151acd3839d), ROM_BIOS(1) ) /* OS */
ROM_REGION( 0x10000, "user2", ROMREGION_ERASEFF )
- ROM_LOAD( "basicrom", 0x0000, 0x2000, CRC(87b4e59c) SHA1(c49782a82a7f068c1195cd967882ba9edd546eaf) )
- ROM_LOAD( "assemrom", 0x2000, 0x2000, CRC(9d7538c3) SHA1(d1882c4ea61a68b1715bd634ded5603e18a99c5f) )
+ ROMX_LOAD( "mtx1b.8h", 0x0000, 0x2000, CRC(87b4e59c) SHA1(c49782a82a7f068c1195cd967882ba9edd546eaf), ROM_BIOS(0) ) /* BASIC */
+ ROMX_LOAD( "mtx1c.10h", 0x2000, 0x2000, CRC(9d7538c3) SHA1(d1882c4ea61a68b1715bd634ded5603e18a99c5f), ROM_BIOS(0) ) /* ASSEM */
+ ROMX_LOAD( "mtx2b.8h", 0x0000, 0x2000, CRC(599d5b6b) SHA1(3ec1f7f476a21ca3206012ded22198c020b47f7d), ROM_BIOS(1) ) /* BASIC */
+ ROMX_LOAD( "mtx1c.10h", 0x2000, 0x2000, CRC(9d7538c3) SHA1(d1882c4ea61a68b1715bd634ded5603e18a99c5f), ROM_BIOS(1) ) /* ASSEM */
- /* Keyboard ROMs are piggy-backed on top of the OS ROM, wired to be selected as ROM 7 */
+ /* Keyboard PROMs (N82S181N) are piggy-backed on top of the OS ROM, wired to be selected as ROM 7 */
/* Country character sets documented in the Operators Manual are:
U.S.A, France, Germany, England, Denmark, Sweden, Italy, Spain */
- ROM_DEFAULT_BIOS("us")
- ROM_SYSTEM_BIOS( 0, "us", "U.S.A." )
- ROM_SYSTEM_BIOS( 1, "dk", "Denmark" )
- ROMX_LOAD( "danish.rom", 0xe000, 0x2000, CRC(9c1b3fae) SHA1(82bc021660d88eebcf0c4d3856558ee9acc1c348), ROM_BIOS(1) )
- ROM_SYSTEM_BIOS( 2, "fi", "Finland" )
- ROMX_LOAD( "finnish.rom", 0xe000, 0x2000, CRC(9b96cf72) SHA1(b46d1a733e0e635ccdaf4752cc370d793c3b5c55), ROM_BIOS(2) )
-
- ROM_REGION( 0x2000, "sdx", 0 )
- ROM_LOAD( "sdx", 0x0000, 0x2000, NO_DUMP )
-
- ROM_REGION( 0x2000, "mtx", 0 )
- ROM_LOAD( "sm2 fdcx1 v03", 0x0000, 0x2000, NO_DUMP )
-
- ROM_REGION( 0x1000, MC6845_TAG, 0 )
- ROM_LOAD( "80z.bin", 0x0000, 0x1000, CRC(ea6fe865) SHA1(f84883f79bed34501e5828336894fad929bddbb5) )
+ ROM_REGION( 0x4000, "keyboard_rom", 0 )
+ ROM_LOAD( "danish.rom", 0x0000, 0x2000, CRC(9c1b3fae) SHA1(82bc021660d88eebcf0c4d3856558ee9acc1c348) )
+ ROM_LOAD( "finnish.rom", 0x2000, 0x2000, CRC(9b96cf72) SHA1(b46d1a733e0e635ccdaf4752cc370d793c3b5c55) )
/* Device GAL16V8 converted from PAL14L4 JEDEC map */
ROM_REGION( 0x117, "plds", 0 )
diff --git a/src/mame/includes/mtx.h b/src/mame/includes/mtx.h
index 959780228f3..111ac5931f3 100644
--- a/src/mame/includes/mtx.h
+++ b/src/mame/includes/mtx.h
@@ -14,35 +14,29 @@
#include "bus/centronics/ctronics.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
+#include "bus/mtx/exp.h"
#include "cpu/z80/z80.h"
+#include "machine/z80daisy.h"
#include "machine/z80dart.h"
#include "machine/z80ctc.h"
#include "sound/sn76496.h"
#include "machine/ram.h"
#include "machine/timer.h"
-#define Z80_TAG "z80"
-#define Z80CTC_TAG "z80ctc"
-#define Z80DART_TAG "z80dart"
-#define FD1793_TAG "fd1793" // SDX
-#define FD1791_TAG "fd1791" // FDX
-#define SN76489A_TAG "sn76489a"
-#define MC6845_TAG "mc6845"
-#define SCREEN_TAG "screen"
-#define CENTRONICS_TAG "centronics"
class mtx_state : public driver_device
{
public:
mtx_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
- , m_maincpu(*this, Z80_TAG)
- , m_sn(*this, SN76489A_TAG)
- , m_z80ctc(*this, Z80CTC_TAG)
- , m_z80dart(*this, Z80DART_TAG)
+ , m_maincpu(*this, "z80")
+ , m_sn(*this, "sn76489a")
+ , m_z80ctc(*this, "z80ctc")
+ , m_z80dart(*this, "z80dart")
, m_cassette(*this, "cassette")
- , m_centronics(*this, CENTRONICS_TAG)
+ , m_centronics(*this, "centronics")
, m_ram(*this, RAM_TAG)
+ , m_exp(*this, "exp")
, m_extrom(*this, "extrom")
, m_rompak(*this, "rompak")
{ }
@@ -51,6 +45,10 @@ public:
void mtx500(machine_config &config);
void mtx512(machine_config &config);
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
private:
required_device<z80_device> m_maincpu;
required_device<sn76489a_device> m_sn;
@@ -59,6 +57,7 @@ private:
required_device<cassette_image_device> m_cassette;
required_device<centronics_device> m_centronics;
required_device<ram_device> m_ram;
+ required_device<mtx_exp_slot_device> m_exp;
required_device<generic_slot_device> m_extrom;
required_device<generic_slot_device> m_rompak;
@@ -91,8 +90,6 @@ private:
DECLARE_WRITE8_MEMBER(hrx_data_w);
DECLARE_READ8_MEMBER(hrx_attr_r);
DECLARE_WRITE8_MEMBER(hrx_attr_w);
- DECLARE_MACHINE_START(mtx512);
- DECLARE_MACHINE_RESET(mtx512);
TIMER_DEVICE_CALLBACK_MEMBER(ctc_tick);
TIMER_DEVICE_CALLBACK_MEMBER(cassette_tick);
DECLARE_WRITE_LINE_MEMBER(ctc_trg1_w);
@@ -110,7 +107,9 @@ private:
void bankswitch(uint8_t data);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(extrom_load);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rompak_load);
+ DECLARE_QUICKLOAD_LOAD_MEMBER(mtx);
DECLARE_SNAPSHOT_LOAD_MEMBER(mtx);
+
void mtx_io(address_map &map);
void mtx_mem(address_map &map);
void rs128_io(address_map &map);
diff --git a/src/mame/machine/mtx.cpp b/src/mame/machine/mtx.cpp
index 846648b30e8..41960e45398 100644
--- a/src/mame/machine/mtx.cpp
+++ b/src/mame/machine/mtx.cpp
@@ -111,38 +111,20 @@ void mtx_state::bankswitch(uint8_t data)
program.install_readwrite_bank(0x8000, 0xbfff, "rammap_bank3");
/* set ram bank, for invalid pages a nop-handler will be installed */
- switch (ram_page)
- {
- case 0:
- if (ram_page * 0xc000 + 0x10000 <= m_ram->size())
- membank("rammap_bank1")->set_entry(ram_page);
- else
- program.nop_readwrite(0x0000, 0x3fff);
- if (ram_page * 0xc000 + 0xc000 <= m_ram->size())
- membank("rammap_bank2")->set_entry(ram_page);
- else
- program.nop_readwrite(0x4000, 0x7fff);
- if (ram_page * 0xc000 + 0x8000 <= m_ram->size())
- membank("rammap_bank3")->set_entry(ram_page);
- else
- program.nop_readwrite(0x8000, 0xbfff);
- break;
-
- default:
- if (ram_page * 0xc000 + 0x8000 <= m_ram->size())
- membank("rammap_bank1")->set_entry(ram_page);
- else
- program.nop_readwrite(0x0000, 0x3fff);
- if (ram_page * 0xc000 + 0xc000 <= m_ram->size())
- membank("rammap_bank2")->set_entry(ram_page);
- else
- program.nop_readwrite(0x4000, 0x7fff);
- if (ram_page * 0xc000 + 0x10000 <= m_ram->size())
- membank("rammap_bank3")->set_entry(ram_page);
- else
- program.nop_readwrite(0x8000, 0xbfff);
- break;
- }
+ if ((ram_page == 0 && m_ram->size() > 0xc000) || (ram_page > 0 && m_ram->size() > 0x10000 + ram_page * 0xc000))
+ membank("rammap_bank1")->set_entry(ram_page);
+ else
+ program.nop_readwrite(0x0000, 0x3fff);
+ if ((ram_page == 0 && m_ram->size() > 0x8000) || (ram_page > 0 && m_ram->size() > 0x14000 + ram_page * 0xc000))
+
+ membank("rammap_bank2")->set_entry(ram_page);
+ else
+ program.nop_readwrite(0x4000, 0x7fff);
+ if ((ram_page == 0 && m_ram->size() > 0x4000) || (ram_page > 0 && m_ram->size() > 0x18000 + ram_page * 0xc000))
+
+ membank("rammap_bank3")->set_entry(ram_page);
+ else
+ program.nop_readwrite(0x8000, 0xbfff);
}
else
{
@@ -158,11 +140,11 @@ void mtx_state::bankswitch(uint8_t data)
membank("rommap_bank1")->set_entry(rom_page);
/* set ram bank, for invalid pages a nop-handler will be installed */
- if (ram_page * 0x8000 + 0xc000 <= m_ram->size())
+ if ((ram_page == 0 && m_ram->size() > 0x8000) || (ram_page > 0 && m_ram->size() > 0x10000 + ram_page * 0x8000))
membank("rommap_bank2")->set_entry(ram_page);
else
program.nop_readwrite(0x4000, 0x7fff);
- if (ram_page * 0x8000 + 0x8000 <= m_ram->size())
+ if ((ram_page == 0 && m_ram->size() > 0x4000) || (ram_page == 1 && m_ram->size() > 0xc000) || (ram_page > 1 && m_ram->size() > 0x14000 + ram_page * 0x8000))
membank("rommap_bank3")->set_entry(ram_page);
else
program.nop_readwrite(0x8000, 0xbfff);
@@ -208,7 +190,16 @@ WRITE8_MEMBER(mtx_state::mtx_cst_w)
WRITE8_MEMBER(mtx_state::mtx_cst_motor_w)
{
- m_cassette->change_state(data ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
+ /* supported in the MTX ROM */
+ switch (data)
+ {
+ case 0xaa:
+ m_cassette->change_state(CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR);
+ break;
+ case 0x55:
+ m_cassette->change_state(CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
+ break;
+ }
}
/*-------------------------------------------------
@@ -453,14 +444,10 @@ DEVICE_IMAGE_LOAD_MEMBER( mtx_state, rompak_load )
SNAPSHOT_LOAD_MEMBER( mtx_state, mtx )
{
address_space &program = m_maincpu->space(AS_PROGRAM);
- void *ptr;
- uint8_t header[18];
-
- // read header
- image.fread(&header, sizeof(header));
+ uint8_t *data = (uint8_t*)image.ptr();
// verify first byte
- if (header[0] != 0xff)
+ if (data[0] != 0xff)
{
image.seterror(IMAGE_ERROR_INVALIDIMAGE, nullptr);
return image_init_result::FAIL;
@@ -468,37 +455,74 @@ SNAPSHOT_LOAD_MEMBER( mtx_state, mtx )
// get tape name
char tape_name[16];
- memcpy(&tape_name, &header[1], 15);
+ memcpy(&tape_name, &data[1], 15);
tape_name[15] = '\0';
image.message("Loading '%s'", tape_name);
+ // reset memory map
+ bankswitch(0);
+
// start of system variables area
- uint16_t system_variables_base = pick_integer_le(header, 16, 2);
+ uint16_t system_variables_base = pick_integer_le(data, 16, 2);
// write system variables
uint16_t system_variables_size = 0;
if (system_variables_base != 0)
{
- ptr = program.get_write_ptr(system_variables_base);
system_variables_size = 0xfb4b - system_variables_base;
- image.fread(ptr, system_variables_size);
+ for (int i = 0; i < system_variables_size; i++)
+ program.write_byte(system_variables_base + i, data[18 + i]);
}
// write actual image data
uint16_t data_size = snapshot_size - 18 - system_variables_size;
+ for (int i = 0; i < data_size; i++)
+ program.write_byte(0x4000 + i, data[18 + system_variables_size + i]);
+
+ logerror("snapshot name = '%s', system_size = 0x%04x, data_size = 0x%04x\n", tape_name, system_variables_size, data_size);
+
+ return image_init_result::PASS;
+}
+
+/***************************************************************************
+ QUICKLOAD
+***************************************************************************/
+
+QUICKLOAD_LOAD_MEMBER(mtx_state, mtx)
+{
+ address_space &program = m_maincpu->space(AS_PROGRAM);
+ uint8_t *data = (uint8_t*)image.ptr();
- ptr = program.get_write_ptr(0x4000);
- image.fread(ptr, 0x4000);
+ if (quickload_size < 4)
+ {
+ image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ return image_init_result::FAIL;
+ }
- // if we cross the page boundary, get a new write pointer and write the rest
- if (data_size > 0x4000)
+ uint16_t code_base = pick_integer_le(data, 0, 2);
+ uint16_t code_length = pick_integer_le(data, 2, 2);
+
+ if (quickload_size < code_length)
{
- ptr = program.get_write_ptr(0x8000);
- image.fread(ptr, 0x4000);
+ image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ return image_init_result::FAIL;
}
- logerror("snapshot name = '%s', system_size = 0x%04x, data_size = 0x%04x\n", tape_name, system_variables_size, data_size);
+ if (code_base < 0x4000 || (code_base + code_length) >= 0x10000)
+ {
+ image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid code base and length");
+ return image_init_result::FAIL;
+ }
+
+ // reset memory map
+ bankswitch(0);
+
+ // write image data
+ for (int i = 0; i < code_length; i++)
+ program.write_byte(code_base + i, data[4 + i]);
+
+ m_maincpu->set_pc(code_base);
return image_init_result::PASS;
}
@@ -511,7 +535,7 @@ SNAPSHOT_LOAD_MEMBER( mtx_state, mtx )
MACHINE_START( mtx512 )
-------------------------------------------------*/
-MACHINE_START_MEMBER(mtx_state, mtx512)
+void mtx_state::machine_start()
{
address_space &program = m_maincpu->space(AS_PROGRAM);
@@ -521,12 +545,11 @@ MACHINE_START_MEMBER(mtx_state, mtx512)
program.install_readwrite_bank(0x8000, 0xbfff, "rommap_bank3");
membank("rommap_bank1")->configure_entries(0, 8, memregion("user2")->base(), 0x2000);
- if (m_extrom->exists())
- membank("rommap_bank1")->configure_entry(2, m_extrom->get_rom_base());
- if (m_rompak->exists())
- membank("rommap_bank1")->configure_entry(7, m_rompak->get_rom_base());
- membank("rommap_bank2")->configure_entries(0, 16, m_ram->pointer() + 0x8000, 0x8000);
- membank("rommap_bank3")->configure_entries(0, 16, m_ram->pointer() + 0x4000, 0x8000);
+ membank("rommap_bank2")->configure_entry(0, m_ram->pointer() + 0x8000);
+ membank("rommap_bank2")->configure_entries(1, 15, m_ram->pointer() + 0x10000, 0x8000);
+ membank("rommap_bank3")->configure_entry(0, m_ram->pointer() + 0x4000);
+ membank("rommap_bank3")->configure_entry(1, m_ram->pointer() + 0xc000);
+ membank("rommap_bank3")->configure_entries(2, 14, m_ram->pointer() + 0x14000, 0x8000);
/* setup banks for ram based memory map */
program.install_readwrite_bank(0x0000, 0x3fff, "rammap_bank1");
@@ -542,10 +565,24 @@ MACHINE_START_MEMBER(mtx_state, mtx512)
/* install 4000h bytes common block */
program.install_ram(0xc000, 0xffff, m_ram->pointer());
+
+ /* setup expansion slot */
+ m_exp->set_program_space(&m_maincpu->space(AS_PROGRAM));
+ m_exp->set_io_space(&m_maincpu->space(AS_IO));
}
-MACHINE_RESET_MEMBER(mtx_state, mtx512)
+void mtx_state::machine_reset()
{
+ /* extension board ROMs */
+ if (m_extrom->exists())
+ membank("rommap_bank1")->configure_entry(2, m_extrom->get_rom_base());
+ /* keyboard ROMs */
+ if (ioport("keyboard_rom")->read())
+ membank("rommap_bank1")->configure_entry(7, memregion("keyboard_rom")->base() + (ioport("keyboard_rom")->read() - 1) * 0x2000);
+ /* rompak ROMs */
+ if (m_rompak->exists())
+ membank("rommap_bank1")->configure_entry(7, m_rompak->get_rom_base());
+
/* bank switching */
bankswitch(0);
}