From 3cbf1d39b6e6f4b49115f248e8b66207c7517e8f Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 17 Sep 2023 22:36:22 -0400 Subject: trs80, trs80m3: Quickload updates - Move /CMD quickload implementation to its own source file again, this time as a device - Rewrite file I/O code to use more modern methods (somewhat clumsily) --- src/mame/trs/lnw80.cpp | 6 +- src/mame/trs/meritum.cpp | 6 +- src/mame/trs/radionic.cpp | 11 ++-- src/mame/trs/trs80.cpp | 6 +- src/mame/trs/trs80.h | 2 - src/mame/trs/trs80_m.cpp | 90 -------------------------- src/mame/trs/trs80_quik.cpp | 149 ++++++++++++++++++++++++++++++++++++++++++++ src/mame/trs/trs80_quik.h | 39 ++++++++++++ src/mame/trs/trs80m3.cpp | 6 +- src/mame/trs/trs80m3_m.cpp | 89 -------------------------- 10 files changed, 206 insertions(+), 198 deletions(-) create mode 100644 src/mame/trs/trs80_quik.cpp create mode 100644 src/mame/trs/trs80_quik.h diff --git a/src/mame/trs/lnw80.cpp b/src/mame/trs/lnw80.cpp index 42beaec46f7..747c77fce67 100644 --- a/src/mame/trs/lnw80.cpp +++ b/src/mame/trs/lnw80.cpp @@ -74,8 +74,10 @@ To Do / Status: - none of my collection of lnw80-specific floppies will work; some crash MAME *******************************************************************************************************/ + #include "emu.h" #include "trs80.h" +#include "trs80_quik.h" #include "machine/input_merger.h" #include "formats/td0_dsk.h" #include "softlist_dev.h" @@ -609,9 +611,7 @@ void lnw80_state::lnw80(machine_config &config) m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); m_cassette->set_interface("trs80_cass"); - quickload_image_device &quickload(QUICKLOAD(config, "quickload", "cmd", attotime::from_seconds(1))); - quickload.set_load_callback(FUNC(lnw80_state::quickload_cb)); - quickload.set_interface("trs80_quik"); + TRS80_QUICKLOAD(config, "quickload", m_maincpu, attotime::from_seconds(1)); FD1771(config, m_fdc, 4_MHz_XTAL / 4); m_fdc->intrq_wr_callback().set(FUNC(lnw80_state::intrq_w)); diff --git a/src/mame/trs/meritum.cpp b/src/mame/trs/meritum.cpp index 8ccecdf780b..b55c4725172 100644 --- a/src/mame/trs/meritum.cpp +++ b/src/mame/trs/meritum.cpp @@ -57,6 +57,8 @@ For Model III: #include "emu.h" #include "trs80.h" +#include "trs80_quik.h" + #include "bus/centronics/ctronics.h" #include "machine/input_merger.h" #include "machine/i8251.h" @@ -397,9 +399,7 @@ void meritum_state::meritum1(machine_config &config) m_cassette->set_default_state(CASSETTE_PLAY); m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); - quickload_image_device &quickload(QUICKLOAD(config, "quickload", "cmd", attotime::from_seconds(1))); - quickload.set_load_callback(FUNC(meritum_state::quickload_cb)); - quickload.set_interface("trs80_quik"); + TRS80_QUICKLOAD(config, "quickload", m_maincpu, attotime::from_seconds(1)); SOFTWARE_LIST(config, "quik_list").set_original("trs80_quik").set_filter("M1"); } diff --git a/src/mame/trs/radionic.cpp b/src/mame/trs/radionic.cpp index 385c053234c..83d0f38960d 100644 --- a/src/mame/trs/radionic.cpp +++ b/src/mame/trs/radionic.cpp @@ -109,10 +109,13 @@ To Do / Status: #include "emu.h" #include "trs80.h" +#include "trs80_quik.h" + +#include "bus/rs232/rs232.h" +#include "machine/clock.h" #include "machine/i8251.h" #include "machine/i8255.h" -#include "machine/clock.h" -#include "bus/rs232/rs232.h" + #include "softlist_dev.h" #include "utf8.h" @@ -511,9 +514,7 @@ void radionic_state::radionic(machine_config &config) m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); m_cassette->set_interface("trs80_cass"); - quickload_image_device &quickload(QUICKLOAD(config, "quickload", "cmd", attotime::from_seconds(1))); - quickload.set_load_callback(FUNC(radionic_state::quickload_cb)); - quickload.set_interface("trs80_quik"); + TRS80_QUICKLOAD(config, "quickload", m_maincpu, attotime::from_seconds(1)); FD1771(config, m_fdc, 16_MHz_XTAL / 16); m_fdc->intrq_wr_callback().set(FUNC(radionic_state::intrq_w)); diff --git a/src/mame/trs/trs80.cpp b/src/mame/trs/trs80.cpp index 99b94969a35..fb579cea944 100644 --- a/src/mame/trs/trs80.cpp +++ b/src/mame/trs/trs80.cpp @@ -155,6 +155,8 @@ ht1080z works #include "emu.h" #include "trs80.h" +#include "trs80_quik.h" + #include "machine/input_merger.h" #include "sound/ay8910.h" @@ -478,9 +480,7 @@ void trs80_state::level2(machine_config &config) // model I, level II /* devices */ m_cassette->set_formats(trs80l2_cassette_formats); - quickload_image_device &quickload(QUICKLOAD(config, "quickload", "cmd", attotime::from_seconds(1))); - quickload.set_load_callback(FUNC(trs80_state::quickload_cb)); - quickload.set_interface("trs80_quik"); + TRS80_QUICKLOAD(config, "quickload", m_maincpu, attotime::from_seconds(1)); FD1771(config, m_fdc, 4_MHz_XTAL / 4); m_fdc->intrq_wr_callback().set(FUNC(trs80_state::intrq_w)); diff --git a/src/mame/trs/trs80.h b/src/mame/trs/trs80.h index e74b021acc4..3d34b2d8901 100644 --- a/src/mame/trs/trs80.h +++ b/src/mame/trs/trs80.h @@ -11,7 +11,6 @@ #include "cpu/z80/z80.h" #include "imagedev/cassette.h" #include "imagedev/floppy.h" -#include "imagedev/snapquik.h" #include "machine/ay31015.h" #include "machine/clock.h" #include "machine/com8116.h" @@ -83,7 +82,6 @@ protected: INTERRUPT_GEN_MEMBER(fdc_interrupt); TIMER_CALLBACK_MEMBER(cassette_data_callback); void intrq_w(int state); - DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); u8 m_irq = 0U; u8 m_mask = 0U; diff --git a/src/mame/trs/trs80_m.cpp b/src/mame/trs/trs80_m.cpp index fc1d1743e64..e93f2c7c9c0 100644 --- a/src/mame/trs/trs80_m.cpp +++ b/src/mame/trs/trs80_m.cpp @@ -349,93 +349,3 @@ void trs80_state::machine_reset() m_uart_clock->set_unscaled_clock(s_clock); } } - - -/*************************************************************************** - PARAMETERS -***************************************************************************/ - -#define LOG 1 - -#define CMD_TYPE_OBJECT_CODE 0x01 -#define CMD_TYPE_TRANSFER_ADDRESS 0x02 -#define CMD_TYPE_END_OF_PARTITIONED_DATA_SET_MEMBER 0x04 -#define CMD_TYPE_LOAD_MODULE_HEADER 0x05 -#define CMD_TYPE_PARTITIONED_DATA_SET_HEADER 0x06 -#define CMD_TYPE_PATCH_NAME_HEADER 0x07 -#define CMD_TYPE_ISAM_DIRECTORY_ENTRY 0x08 -#define CMD_TYPE_END_OF_ISAM_DIRECTORY_ENTRY 0x0a -#define CMD_TYPE_PDS_DIRECTORY_ENTRY 0x0c -#define CMD_TYPE_END_OF_PDS_DIRECTORY_ENTRY 0x0e -#define CMD_TYPE_YANKED_LOAD_BLOCK 0x10 -#define CMD_TYPE_COPYRIGHT_BLOCK 0x1f - -/*************************************************************************** - IMPLEMENTATION -***************************************************************************/ - -// TODO: If you get "Attempting to write outside of RAM" enough times in succession, MAME will exit unexpectedly (no error). -QUICKLOAD_LOAD_MEMBER(trs80_state::quickload_cb) -{ - address_space &program = m_maincpu->space(AS_PROGRAM); - - u8 type, length; - u8 data[0x100]; - u8 addr[2]; - void *ptr; - - while (!image.image_feof()) - { - image.fread(&type, 1); - image.fread(&length, 1); - - switch (type) - { - case CMD_TYPE_OBJECT_CODE: // 01 - block of data - { - length -= 2; - u16 block_length = length ? length : 256; - image.fread(&addr, 2); - u16 address = (addr[1] << 8) | addr[0]; - if (LOG) logerror("/CMD object code block: address %04x length %u\n", address, block_length); - ptr = program.get_write_ptr(address); - if (!ptr) - { - return std::make_pair( - image_error::INVALIDIMAGE, - util::string_format("Object code block at address %04x is outside RAM", address)); - } - image.fread( ptr, block_length); - } - break; - - case CMD_TYPE_TRANSFER_ADDRESS: // 02 - go address - { - image.fread(&addr, 2); - u16 address = (addr[1] << 8) | addr[0]; - if (LOG) logerror("/CMD transfer address %04x\n", address); - m_maincpu->set_state_int(Z80_PC, address); - } - return std::make_pair(std::error_condition(), std::string()); - - case CMD_TYPE_LOAD_MODULE_HEADER: // 05 - name - image.fread(&data, length); - if (LOG) logerror("/CMD load module header '%s'\n", data); - break; - - case CMD_TYPE_COPYRIGHT_BLOCK: // 1F - copyright info - image.fread(&data, length); - if (LOG) logerror("/CMD copyright block '%s'\n", data); - break; - - default: - image.fread(&data, length); - logerror("/CMD unsupported block type %u!\n", type); - return std::make_pair( - image_error::INVALIDIMAGE, - util::string_format("Unsupported or invalid block type %u", type)); - } - } - - return std::make_pair(std::error_condition(), std::string()); -} diff --git a/src/mame/trs/trs80_quik.cpp b/src/mame/trs/trs80_quik.cpp new file mode 100644 index 00000000000..df8ed104e51 --- /dev/null +++ b/src/mame/trs/trs80_quik.cpp @@ -0,0 +1,149 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** + + Quickload code for TRS-80 /CMD files + +***************************************************************************/ + +#include "emu.h" +#include "trs80_quik.h" + +#include "cpu/z80/z80.h" + + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +#define VERBOSE 1 +#include "logmacro.h" + +#define CMD_TYPE_OBJECT_CODE 0x01 +#define CMD_TYPE_TRANSFER_ADDRESS 0x02 +#define CMD_TYPE_END_OF_PARTITIONED_DATA_SET_MEMBER 0x04 +#define CMD_TYPE_LOAD_MODULE_HEADER 0x05 +#define CMD_TYPE_PARTITIONED_DATA_SET_HEADER 0x06 +#define CMD_TYPE_PATCH_NAME_HEADER 0x07 +#define CMD_TYPE_ISAM_DIRECTORY_ENTRY 0x08 +#define CMD_TYPE_END_OF_ISAM_DIRECTORY_ENTRY 0x0a +#define CMD_TYPE_PDS_DIRECTORY_ENTRY 0x0c +#define CMD_TYPE_END_OF_PDS_DIRECTORY_ENTRY 0x0e +#define CMD_TYPE_YANKED_LOAD_BLOCK 0x10 +#define CMD_TYPE_COPYRIGHT_BLOCK 0x1f + +/*************************************************************************** + IMPLEMENTATION +***************************************************************************/ + +DEFINE_DEVICE_TYPE(TRS80_QUICKLOAD, trs80_quickload_device, "trs80_quickload", "TRS-80 /CMD quickload") + +trs80_quickload_device::trs80_quickload_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : snapshot_image_device(mconfig, TRS80_QUICKLOAD, tag, owner, clock) + , m_maincpu(*this, finder_base::DUMMY_TAG) +{ + set_load_callback(load_delegate(*this, FUNC(trs80_quickload_device::quickload_cb))); +} + + +// TODO: If you get "Attempting to write outside of RAM" enough times in succession, MAME will exit unexpectedly (no error). +QUICKLOAD_LOAD_MEMBER(trs80_quickload_device::quickload_cb) +{ + util::core_file &file = image_core_file(); + address_space &program = m_maincpu->space(AS_PROGRAM); + + uint8_t type, length; + uint8_t data[0x100]; + uint8_t addr[2]; + void *ptr; + + std::error_condition err; + size_t actual; + while (true) + { + err = file.read(&type, 1, actual); + if (actual != 1) + break; + err = file.read(&length, 1, actual); + if (actual != 1) + break; + + switch (type) + { + case CMD_TYPE_OBJECT_CODE: // 01 - block of data + { + length -= 2; + u16 block_length = length ? length : 256; + err = file.read(&addr, 2, actual); + if (actual != 2) + { + logerror("/CMD error reading address of data block\n"); + return std::make_pair(err ? err : image_error::INVALIDLENGTH, std::string()); + } + u16 address = (addr[1] << 8) | addr[0]; + LOG("/CMD object code block: address %04x length %u\n", address, block_length); + ptr = program.get_write_ptr(address); + if (!ptr) + { + return std::make_pair( + image_error::INVALIDIMAGE, + util::string_format("Object code block at address %04x is outside RAM", address)); + } + err = file.read(ptr, block_length, actual); + if (actual != block_length) + { + logerror("/CMD error reading data block at address %04x\n", address); + return std::make_pair(err ? err : image_error::INVALIDLENGTH, std::string()); + } + } + break; + + case CMD_TYPE_TRANSFER_ADDRESS: // 02 - go address + { + err = file.read(&addr, 2, actual); + if (actual != 2) + { + logerror("/CMD error reading transfer address\n"); + return std::make_pair(err ? err : image_error::INVALIDLENGTH, std::string()); + } + u16 address = (addr[1] << 8) | addr[0]; + LOG("/CMD transfer address %04x\n", address); + m_maincpu->set_state_int(Z80_PC, address); + } + return std::make_pair(std::error_condition(), std::string()); + + case CMD_TYPE_LOAD_MODULE_HEADER: // 05 - name + err = file.read(&data, length, actual); + if (actual != length) + { + logerror("/CMD error reading block type %02x\n", type); + return std::make_pair(err ? err : image_error::INVALIDLENGTH, std::string()); + } + LOG("/CMD load module header '%s'\n", data); + break; + + case CMD_TYPE_COPYRIGHT_BLOCK: // 1F - copyright info err = file.read(&data, length, actual); + if (actual != length) + { + logerror("/CMD error reading block type %02x\n", type); + return std::make_pair(err ? err : image_error::INVALIDLENGTH, std::string()); + } + LOG("/CMD copyright block '%s'\n", data); + break; + + default: + err = file.read(&data, length, actual); + if (actual != length) + { + logerror("/CMD error reading block type %02x\n", type); + return std::make_pair(err ? err : image_error::INVALIDLENGTH, std::string()); + } + logerror("/CMD unsupported block type %u!\n", type); + return std::make_pair( + image_error::INVALIDIMAGE, + util::string_format("Unsupported or invalid block type %u", type)); + } + } + + return std::make_pair(err, std::string()); +} diff --git a/src/mame/trs/trs80_quik.h b/src/mame/trs/trs80_quik.h new file mode 100644 index 00000000000..bbca4d80dfe --- /dev/null +++ b/src/mame/trs/trs80_quik.h @@ -0,0 +1,39 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert + +#ifndef MAME_TRS_TRS80_QUIK_H +#define MAME_TRS_TRS80_QUIK_H + +#pragma once + +#include "imagedev/snapquik.h" + +class trs80_quickload_device : public snapshot_image_device +{ +public: + template + trs80_quickload_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cputag, attotime delay = attotime::zero) + : trs80_quickload_device(mconfig, tag, owner, 0U) + { + set_cpu(cputag); + set_delay(delay); + } + trs80_quickload_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U); + + template void set_cpu(T &&tag) { m_maincpu.set_tag(std::forward(tag)); } + +protected: + virtual const char *image_interface() const noexcept override { return "trs80_quik"; } + virtual const char *file_extensions() const noexcept override { return "cmd"; } + virtual const char *image_type_name() const noexcept override { return "quickload"; } + virtual const char *image_brief_type_name() const noexcept override { return "quik"; } + +private: + DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); + + required_device m_maincpu; +}; + +DECLARE_DEVICE_TYPE(TRS80_QUICKLOAD, trs80_quickload_device) + +#endif // MAME_TRS_TRS80_QUIK_H diff --git a/src/mame/trs/trs80m3.cpp b/src/mame/trs/trs80m3.cpp index 21f1e9852d5..0f41544052e 100644 --- a/src/mame/trs/trs80m3.cpp +++ b/src/mame/trs/trs80m3.cpp @@ -74,6 +74,8 @@ trs80m4p: Floppy not working, so machine is useless. #include "emu.h" #include "trs80m3.h" +#include "trs80_quik.h" + #include "screen.h" #include "softlist_dev.h" #include "speaker.h" @@ -381,9 +383,7 @@ void trs80m3_state::model3(machine_config &config) m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); m_cassette->set_interface("trs80_cass"); - quickload_image_device &quickload(QUICKLOAD(config, "quickload", "cmd", attotime::from_seconds(1))); - quickload.set_load_callback(FUNC(trs80m3_state::quickload_cb)); - quickload.set_interface("trs80_quik"); + TRS80_QUICKLOAD(config, "quickload", m_maincpu, attotime::from_seconds(1)); FD1793(config, m_fdc, 4_MHz_XTAL / 4); m_fdc->intrq_wr_callback().set(FUNC(trs80m3_state::intrq_w)); diff --git a/src/mame/trs/trs80m3_m.cpp b/src/mame/trs/trs80m3_m.cpp index 5711d1c5a38..8636f3f8d7d 100644 --- a/src/mame/trs/trs80m3_m.cpp +++ b/src/mame/trs/trs80m3_m.cpp @@ -639,92 +639,3 @@ void trs80m3_state::machine_reset() m_fdd = nullptr; } - - -/*************************************************************************** - PARAMETERS -***************************************************************************/ - -#define LOG 1 - -#define CMD_TYPE_OBJECT_CODE 0x01 -#define CMD_TYPE_TRANSFER_ADDRESS 0x02 -#define CMD_TYPE_END_OF_PARTITIONED_DATA_SET_MEMBER 0x04 -#define CMD_TYPE_LOAD_MODULE_HEADER 0x05 -#define CMD_TYPE_PARTITIONED_DATA_SET_HEADER 0x06 -#define CMD_TYPE_PATCH_NAME_HEADER 0x07 -#define CMD_TYPE_ISAM_DIRECTORY_ENTRY 0x08 -#define CMD_TYPE_END_OF_ISAM_DIRECTORY_ENTRY 0x0a -#define CMD_TYPE_PDS_DIRECTORY_ENTRY 0x0c -#define CMD_TYPE_END_OF_PDS_DIRECTORY_ENTRY 0x0e -#define CMD_TYPE_YANKED_LOAD_BLOCK 0x10 -#define CMD_TYPE_COPYRIGHT_BLOCK 0x1f - -/*************************************************************************** - IMPLEMENTATION -***************************************************************************/ - -QUICKLOAD_LOAD_MEMBER(trs80m3_state::quickload_cb) -{ - address_space &program = m_maincpu->space(AS_PROGRAM); - - uint8_t type, length; - uint8_t data[0x100]; - uint8_t addr[2]; - void *ptr; - - while (!image.image_feof()) - { - image.fread(&type, 1); - image.fread(&length, 1); - - switch (type) - { - case CMD_TYPE_OBJECT_CODE: // 01 - block of data - { - length -= 2; - u16 block_length = length ? length : 256; - image.fread( &addr, 2); - u16 address = (addr[1] << 8) | addr[0]; - if (LOG) logerror("/CMD object code block: address %04x length %u\n", address, block_length); - ptr = program.get_write_ptr(address); - if (!ptr) - { - return std::make_pair( - image_error::INVALIDIMAGE, - util::string_format("Object code block at address %04x is outside RAM", address)); - } - image.fread(ptr, block_length); - } - break; - - case CMD_TYPE_TRANSFER_ADDRESS: // 02 - go address - { - image.fread( &addr, 2); - u16 address = (addr[1] << 8) | addr[0]; - if (LOG) logerror("/CMD transfer address %04x\n", address); - m_maincpu->set_state_int(Z80_PC, address); - } - return std::make_pair(std::error_condition(), std::string()); - - case CMD_TYPE_LOAD_MODULE_HEADER: // 05 - name - image.fread( &data, length); - if (LOG) logerror("/CMD load module header '%s'\n", data); - break; - - case CMD_TYPE_COPYRIGHT_BLOCK: // 1F - copyright info - image.fread( &data, length); - if (LOG) logerror("/CMD copyright block '%s'\n", data); - break; - - default: - image.fread(&data, length); - logerror("/CMD unsupported block type %u!\n", type); - return std::make_pair( - image_error::INVALIDIMAGE, - util::string_format("Unsupported or invalid block type %u", type)); - } - } - - return std::make_pair(std::error_condition(), std::string()); -} -- cgit v1.2.3