diff options
| author | 2026-04-15 18:13:27 +0200 | |
|---|---|---|
| committer | 2026-04-16 02:13:27 +1000 | |
| commit | 0ff8ec15a3bef83a8e4a725f3e124e5e4601e0b6 (patch) | |
| tree | 304775e1c8723e49c144c86d9aee22ad5832ea18 | |
| parent | e10d4dee14ffbaffc3b0f8abc49837df8c778133 (diff) | |
bus/ieee488/grid2102.cpp: Fixed geometry disk and support formatting. (#15192)
* Support ddFormat, ddInitialize; fix ddWrite(mode=1).
* Rewrite 2101 and 2102 status blobs.
* Add disk status struct, fill geometry properly.
* Disable gpib state logs by default.
* Fixes MS-DOS 2.11A loading, GitHub #10209 and GitHub #10210.
* ieee488/grid2102.cpp:
* ieee488/grid2102.cpp:
* ieee488/grid2102.cpp:
Fix #10209
* ieee488/grid2102.cpp: fixes after code review
| -rw-r--r-- | src/devices/bus/ieee488/grid2102.cpp | 168 | ||||
| -rw-r--r-- | src/devices/bus/ieee488/grid2102.h | 41 |
2 files changed, 160 insertions, 49 deletions
diff --git a/src/devices/bus/ieee488/grid2102.cpp b/src/devices/bus/ieee488/grid2102.cpp index 4e6bc92c391..8da7c44e8a9 100644 --- a/src/devices/bus/ieee488/grid2102.cpp +++ b/src/devices/bus/ieee488/grid2102.cpp @@ -12,6 +12,43 @@ #include "emu.h" #include "grid2102.h" +#include "harddisk.h" +#include "multibyte.h" + +#include <algorithm> + +static const grid210x_device::disk_status fdd_status +{ + 512, + 504, + 360 * 1024 / 512, // 360KiB, 5.25 DS/DD + 1, // ok + 0x120, + 0x121, + 1, + 0, + "48 TPI DS DD FLOPPY 30237-00", + 512, + 9, + 2, +}; + +static const grid210x_device::disk_status hdd_status +{ + 512, + 504, + (10 * 1024 * 1024) / 512, // 10 MB by default + 1, // ok + 0x2400, + 0x2420, + 10, + 0, + "MAME HARD DISK DRIVE", + 512, + 10, + 4, +}; + // device type definition DEFINE_DEVICE_TYPE(GRID2102, grid2102_device, "grid2102", "GRID2102") DEFINE_DEVICE_TYPE(GRID2101_FLOPPY, grid2101_floppy_device, "grid2101_floppy", "GRID2101_FLOPPY") @@ -19,6 +56,10 @@ DEFINE_DEVICE_TYPE(GRID2101_HDD, grid2101_hdd_device, "grid2101_hdd", "GRID2101_ #define LOG_BYTES_MASK (LOG_GENERAL << 1) #define LOG_BYTES(...) LOGMASKED(LOG_BYTES_MASK, __VA_ARGS__) + +#define LOG_GPIB_STATE_MASK (LOG_GENERAL << 2) +#define LOG_GPIB_STATE(...) LOGMASKED(LOG_GPIB_STATE_MASK, __VA_ARGS__) + #define VERBOSE (LOG_GENERAL) #include "logmacro.h" @@ -46,26 +87,28 @@ DEFINE_DEVICE_TYPE(GRID2101_HDD, grid2101_hdd_device, "grid2101_hdd", "GRID2101_ #define GRID210X_STATE_READING_DATA 1 #define GRID210X_STATE_WRITING_DATA 2 #define GRID210X_STATE_WRITING_DATA_WAIT 3 +#define GRID210X_STATE_FORMATTING 4 -uint8_t grid2102_device::identify_response[56] = {0x00, 0x02, 0xf8, 0x01, 0xD0, 0x02, 0x01, 0x20, 0x01, 0x21, 0x01, 0x01, 0x00, 0x00, - 0x34, 0x38, 0x20, 0x54, 0x50, 0x49, 0x20, 0x44, 0x53, 0x20, 0x44, 0x44, 0x20, 0x46, - 0x4c, 0x4f, 0x50, 0x50, 0x59, 0x20, 0x20, 0x20, 0x20, 0x33, 0x30, 0x32, 0x33, 0x37, - 0x2d, 0x30, 0x30, 0x00, 0x02, 0x09, 0x00}; - -uint8_t grid2101_floppy_device::identify_response[56] = {0x00, 0x02, 0xf8, 0x01, 0xD0, 0x02, 0x01, 0x20, 0x01, 0x21, 0x01, 0x01, 0x00, 0x00, - 0x34, 0x38, 0x20, 0x54, 0x50, 0x49, 0x20, 0x44, 0x53, 0x20, 0x44, 0x44, 0x20, 0x46, - 0x4c, 0x4f, 0x50, 0x50, 0x59, 0x20, 0x20, 0x20, 0x20, 0x33, 0x30, 0x32, 0x33, 0x37, - 0x2d, 0x30, 0x30, 0x00, 0x02, 0x09, 0x00}; - -uint8_t grid2101_hdd_device::identify_response[56] = { - 0x00, 0x02, 0xF8, 0x01, 0x8C, 0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4D, 0x41, - 0x4D, 0x45, 0x20, 0x48, 0x41, 0x52, 0x44, 0x44, 0x49, 0x53, 0x4B, 0x20, 0x44, 0x52, 0x49, 0x56, - 0x45, 0x20, 0x20, 0x20, 0x20, 0x20, 0x47, 0x52, 0x49, 0x44, 0x32, 0x31, 0x30, 0x31, 0x00, 0x02, - 0x11, 0x00, 0x33, 0x01, 0x00, 0x00, 0x04, 0x00 -}; - +std::array<uint8_t, 52> grid210x_device::disk_status::serialize() const +{ + std::array<uint8_t, 52> out{}; + put_u16le(&out[0], sector_size); + put_u16le(&out[2], logical_sector_size); + put_u16le(&out[4], sector_count); + out[6] = drive_status; + put_u16le(&out[7], bitmap_fid); + put_u16le(&out[9], superblock_fid); + put_u16le(&out[11], min_dir_pages); + out[13] = flush; + std::fill_n(std::begin(out) + 14, 32, ' '); + std::copy_n(name.data(), std::min<size_t>(name.length(), 32), &out[14]); + put_u16le(&out[46], bytes_per_sector); + put_u16le(&out[48], sectors_per_track); + put_u16le(&out[50], tracks_per_cylinder); + return out; +} -grid210x_device::grid210x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int bus_addr, uint8_t *identify_response, attotime read_delay) +grid210x_device::grid210x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int bus_addr, attotime read_delay) : device_t(mconfig, type, tag, owner, clock), device_ieee488_interface(mconfig, *this), device_image_interface(mconfig, *this), @@ -77,7 +120,6 @@ grid210x_device::grid210x_device(const machine_config &mconfig, device_type type has_srq(false), serial_poll_byte(0), bus_addr(bus_addr), - identify_response_ptr(identify_response), read_delay(read_delay) { @@ -97,20 +139,33 @@ TIMER_CALLBACK_MEMBER(grid210x_device::delay_tick) { for (int i = 0; i < io_size; i++) { m_output_data_buffer.push(data[i]); } - serial_poll_byte = 0x0F; - has_srq = true; - m_bus->srq_w(this, 0); - m_floppy_loop_state = GRID210X_STATE_IDLE; + } else if (m_floppy_loop_state == GRID210X_STATE_FORMATTING) { + const uint32_t sector_total = get_status().sector_count; + + uint8_t buf[512]; + std::fill(std::begin(buf), std::end(buf), 0xe5); + std::fill_n(std::begin(buf), 8, 0xff); + + for (uint32_t sec = 0; sec < sector_total; sec++) { + fseek(s64(sec) * 512, SEEK_SET); + fwrite(buf, 512); + } + + for (int i = 0; i < 7; i++) { + m_output_data_buffer.push(0); + } } else if (m_floppy_loop_state == GRID210X_STATE_WRITING_DATA_WAIT) { - // send an srq as success flag - for (int i = 0; i < 7; i++) { // FIXME: + for (int i = 0; i < 7; i++) { m_output_data_buffer.push(0); } - serial_poll_byte = 0x0F; - has_srq = true; - m_bus->srq_w(this, 0); - m_floppy_loop_state = GRID210X_STATE_IDLE; + } else { + return; } + + serial_poll_byte = 0x0F; + has_srq = true; + m_bus->srq_w(this, 0); + m_floppy_loop_state = GRID210X_STATE_IDLE; } void grid210x_device::ieee488_eoi(int state) { @@ -125,9 +180,13 @@ void grid210x_device::accept_transfer() { uint16_t data_size = GRID2102_FETCH16(m_data_buffer, 7); LOG("grid210x_device command %u, data size %u, sector no %u\n", (unsigned)command, (unsigned)data_size, (unsigned)sector_number); (void)(sector_number); - if (command == 0x1) { // ddGetStatus - for (int i = 0; i < 56 && i < data_size; i++) { - m_output_data_buffer.push(identify_response_ptr[i]); + if (command == 0x0) { // ddInitialize + for (int i = 0; i < 7; i++) { // just OK + m_output_data_buffer.push(0); + } + } else if (command == 0x1) { // ddGetStatus + for (uint8_t b : get_status().serialize()) { + m_output_data_buffer.push(b); } } else if (command == 0x4) { // ddRead floppy_sector_number = sector_number; @@ -138,11 +197,14 @@ void grid210x_device::accept_transfer() { floppy_sector_number = sector_number; io_size = data_size; m_floppy_loop_state = GRID210X_STATE_WRITING_DATA; + } else if (command == 0x11) { // ddFormat + m_floppy_loop_state = GRID210X_STATE_FORMATTING; + m_delay_timer->adjust(read_delay); } } // else something is wrong, ignore } else if (m_floppy_loop_state == GRID210X_STATE_WRITING_DATA) { // write - if (floppy_sector_number != 0xFFFFFFFF) { + if (floppy_sector_number < 0xFFFF) { fseek(floppy_sector_number * 512, SEEK_SET); fwrite(m_data_buffer.data(), m_data_buffer.size()); } else { @@ -180,21 +242,21 @@ void grid210x_device::ieee488_dav(int state) { if ((m_last_recv_byte & 0x1F) == bus_addr) { // dev-id = 5 listening = true; - LOG("grid210x_device now listening\n"); + LOG_GPIB_STATE("grid210x_device now listening\n"); } else if((m_last_recv_byte & 0x1F) == 0x1F) { // reset listen listening = false; - LOG("grid210x_device now not listening\n"); + LOG_GPIB_STATE("grid210x_device now not listening\n"); } } else if ((m_last_recv_byte & 0xE0) == 0x40) { if ((m_last_recv_byte & 0x1F) == bus_addr) { // dev-id = 5 talking = true; - LOG("grid210x_device now talking\n"); + LOG_GPIB_STATE("grid210x_device now talking\n"); } else { // reset talk talking = false; - LOG("grid210x_device now not talking\n"); + LOG_GPIB_STATE("grid210x_device now not talking\n"); } } else if (m_last_recv_byte == 0x18) { // serial poll enable @@ -299,17 +361,43 @@ void grid210x_device::ieee488_ren(int state) { } grid2101_hdd_device::grid2101_hdd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : grid210x_device(mconfig, GRID2101_HDD, tag, owner, clock, 4, identify_response, attotime::from_usec(150)) + : grid210x_device(mconfig, GRID2101_HDD, tag, owner, clock, 4, attotime::from_usec(150)) +{ + +} + +grid2101_floppy_device::grid2101_floppy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : grid210x_device(mconfig, GRID2101_FLOPPY, tag, owner, clock, 5) { } -grid2101_floppy_device::grid2101_floppy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : grid210x_device(mconfig, GRID2101_FLOPPY, tag, owner, clock, 5, identify_response) +grid2102_device::grid2102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : grid210x_device(mconfig, GRID2102, tag, owner, clock, 6) { } -grid2102_device::grid2102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : grid210x_device(mconfig, GRID2102, tag, owner, clock, 6, identify_response) +grid210x_device::disk_status grid2101_hdd_device::get_status() { + grid210x_device::disk_status status = hdd_status; + if (is_open()) { + hard_disk_file hd(image_core_file(), 0); + const hard_disk_file::info &info = hd.get_info(); + + status.sector_count = u16(std::min<u64>(length() / u64(status.sector_size), 0xffffU)); + status.sectors_per_track = u16(std::min<u32>(info.sectors, 0xffffU)); + status.tracks_per_cylinder = u16(std::min<u32>(info.heads, 0xffffU)); + } + + return status; +} + +grid210x_device::disk_status grid2101_floppy_device::get_status() +{ + return fdd_status; +} + +grid210x_device::disk_status grid2102_device::get_status() +{ + return fdd_status; } diff --git a/src/devices/bus/ieee488/grid2102.h b/src/devices/bus/ieee488/grid2102.h index 437bae8fb97..6f0dc2b6364 100644 --- a/src/devices/bus/ieee488/grid2102.h +++ b/src/devices/bus/ieee488/grid2102.h @@ -13,7 +13,9 @@ #include "ieee488.h" +#include <array> #include <queue> +#include <string_view> #include <vector> @@ -22,13 +24,31 @@ //************************************************************************** // ======================> grid210x_device -class grid210x_device : public device_t, +class grid210x_device : public device_t, public device_ieee488_interface, public device_image_interface { public: + struct disk_status + { + uint16_t sector_size; + uint16_t logical_sector_size; + uint16_t sector_count; + uint8_t drive_status; + uint16_t bitmap_fid; + uint16_t superblock_fid; + uint16_t min_dir_pages; + uint8_t flush; + std::string_view name; + uint16_t bytes_per_sector; + uint16_t sectors_per_track; + uint16_t tracks_per_cylinder; + + std::array<uint8_t, 52> serialize() const; + }; + // construction/destruction - grid210x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int bus_addr, uint8_t *identify_response, attotime read_delay = attotime::from_msec(5)); + grid210x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int bus_addr, attotime read_delay = attotime::from_msec(5)); protected: // device-level overrides @@ -56,6 +76,8 @@ protected: void accept_transfer(); void update_ndac(int atn); + virtual disk_status get_status() = 0; + private: TIMER_CALLBACK_MEMBER(delay_tick); @@ -71,7 +93,6 @@ private: uint8_t serial_poll_byte; uint32_t floppy_sector_number; int bus_addr; - uint8_t *identify_response_ptr; std::vector<uint8_t> m_data_buffer; std::queue<uint8_t> m_output_data_buffer; uint16_t io_size; @@ -85,16 +106,18 @@ class grid2102_device : public grid210x_device { public: // construction/destruction grid2102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); -private: - static uint8_t identify_response[]; + +protected: + virtual disk_status get_status() override; }; class grid2101_floppy_device : public grid210x_device { public: // construction/destruction grid2101_floppy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); -private: - static uint8_t identify_response[]; + +protected: + virtual disk_status get_status() override; }; class grid2101_hdd_device : public grid210x_device { @@ -106,8 +129,8 @@ public: virtual const char *image_type_name() const noexcept override { return "harddisk"; } virtual const char *image_brief_type_name() const noexcept override { return "hard"; } -private: - static uint8_t identify_response[]; +protected: + virtual disk_status get_status() override; }; // device type definition |
