From 5511ce41e2b5a23394c75b0e743c3bcafdb87b15 Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Sun, 10 Mar 2019 17:23:39 +0000 Subject: 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. --- scripts/src/bus.lua | 15 ++ scripts/src/formats.lua | 12 ++ scripts/target/mame/mess.lua | 2 + src/devices/bus/mtx/exp.cpp | 126 +++++++++++++ src/devices/bus/mtx/exp.h | 92 ++++++++++ src/devices/bus/mtx/sdx.cpp | 425 +++++++++++++++++++++++++++++++++++++++++++ src/devices/bus/mtx/sdx.h | 105 +++++++++++ src/lib/formats/mtx_dsk.cpp | 53 ++++++ src/lib/formats/mtx_dsk.h | 33 ++++ src/mame/drivers/mtx.cpp | 98 +++++----- src/mame/includes/mtx.h | 31 ++-- src/mame/machine/mtx.cpp | 157 ++++++++++------ 12 files changed, 1023 insertions(+), 126 deletions(-) create mode 100644 src/devices/bus/mtx/exp.cpp create mode 100644 src/devices/bus/mtx/exp.h create mode 100644 src/devices/bus/mtx/sdx.cpp create mode 100644 src/devices/bus/mtx/sdx.h create mode 100644 src/lib/formats/mtx_dsk.cpp create mode 100644 src/lib/formats/mtx_dsk.h 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 @@ -1404,6 +1404,21 @@ if (BUSES["MSX_SLOT"]~=null) then 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 @@ -1145,6 +1145,18 @@ if (FORMATS["MSX_DSK"]~=null or _OPTIONS["with-tools"]) then } 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(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(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(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 + 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 m_fdc; + required_device m_floppy0; + required_device 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 m_screen; + required_device m_palette; + required_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; 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 ¢_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 m_maincpu; required_device m_sn; @@ -59,6 +57,7 @@ private: required_device m_cassette; required_device m_centronics; required_device m_ram; + required_device m_exp; required_device m_extrom; required_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); } -- cgit v1.2.3