From 1e5e1a6376af1368daf9d7283b95936fbe2d50dd Mon Sep 17 00:00:00 2001 From: Robbbert Date: Tue, 13 Apr 2021 21:58:48 +1000 Subject: jv3: fixed a data pointer bug --- src/lib/formats/trs80_dsk.cpp | 119 +++++++++++++++++++++++++++++------------- 1 file changed, 82 insertions(+), 37 deletions(-) diff --git a/src/lib/formats/trs80_dsk.cpp b/src/lib/formats/trs80_dsk.cpp index d3f92fedf41..a45e5a5e7b9 100644 --- a/src/lib/formats/trs80_dsk.cpp +++ b/src/lib/formats/trs80_dsk.cpp @@ -2,19 +2,65 @@ // copyright-holders:Dirk Best /*************************************************************************** - TRS-80 - - JV1/3 disk image formats - - Used by Jeff Vavasour's TRS-80 Emulators - - TODO: - - Gap sizes unverified. - - JV3: not working. Disk can be loaded, but it's unreadable. - - JV3: cannot create. - - JV1: if you try to create, MAME will crash. - - all: if the disk image contains more tracks than the drive, - then MAME could crash. +TRS-80 + +JV1/3 disk image formats + +Used by Jeff Vavasour's TRS-80 Emulators + +Description of JV1: + This format has no header or identifying characteristics. It is + simply a string of sectors one after the other in order. There's + no DAM or inter-sector bytes. The expected format is 10 sectors + per track, 256 bytes per sector, single-sided, single-density. + There's no limit on the number of tracks. It's up to the emulation + to decide how to represent things. This format is intended only + for the TRS-80 Model 1 with Level 2 basic. As it happens, the + format is readable by the Model 3, but it's probably not a good + idea to attempt writing on it. + BUGS: If you try to create a JV1 disk, MAME will crash. + +Description of JV3: + There's no header, but the format is obvious to the practised eye. + Firstly there's a 3 byte descriptor per sector, occurs 2901 times. + This is followed by a byte to indicate if the disk is read-only. The + total size of this area is 0x2200 bytes. The sector descriptors can + be in any order. Unused descriptors are FF FF (FC | size). These + can be intermixed with valid descriptors. + Byte 1 - track number (0xFF indicates unused entry). + Byte 2 - sector number. + Byte 3 - flag byte. The bits are assigned as follows: + Bits 0,1 - size in multiples of 128 bytes xor 1 for used tracks, or + xor 2 for unused tracks. + 128 bytes: 1 (used), 2 (unused) + 256 bytes: 0 (used), 3 (unused) + 512 bytes: 3 (used), 0 (unused) + 1024 bytes: 2 (used), 1 (unused) + bit 2: non-ibm flag. Some FDCs, such as the 1771, can have sector + sizes from 16 to 1024 in any multiple of 16. MAME doesn't + support this, and the format itself gives no indication of the + size. So, it's impossible to support it. + bit 3: sector has a CRC error. + bit 4: side (0 = side 0, 1 = side 1) + bits 5,6: DAM code: + 0xF8 (deleted): 0x60 (single-density), 0x20 (double-density) + 0xF9 (undefined): 0x40 (single-density), invalid/unused (double-density) + 0xFA (undefined): 0x20 (single-density), invalid/unused (double-density) + 0xFB (normal) : 0x00 (single and double-density) + bit 7: density (1 = dden/MFM). MAME doesn't support different densities in + a track, so it's defaulted to single-density unless at least 1 sector is + marked as double-density. + After 0x2200 comes the data. There's no DAM bytes or inter-sector bytes + included. If the last part of the descriptors is all unused, there's no + need for those sectors to be in the image. If 2901 entries is not enough, + the format allows another set of descriptors and data. However no TRS-80 + disks need this extra area, so it's unsupported. This format is intended + only for the TRS-80 Models 3 and 4. Save/Create is currently unsupported. + + What we support: up to 2 sides, 96 tracks, 18 sectors per track. + We support all the flags except the non-ibm flag. + We do not support multiple sets of descriptors and data. + We do not support multiple densities per track. ***************************************************************************/ @@ -64,7 +110,8 @@ const jv1_format::format jv1_format::formats[] = const floppy_format_type FLOPPY_JV1_FORMAT = &floppy_image_format_creator; -#define MAX_SECTORS 20 +#define MAX_SECTORS 18 +#define MAX_TRACKS 96 jv3_format::jv3_format() { @@ -122,8 +169,10 @@ int jv3_format::identify(io_generic *io, uint32_t form_factor, const std::vector uint8_t sector = header[sect_ptr++]; uint8_t flags = header[sect_ptr++]; - if (track > 0x7f) + if (track == 0xff) break; + if (track >= MAX_TRACKS) + return 0; if (sector >= MAX_SECTORS) return 0; if ((flags & 0xfc) == 0xfc) @@ -143,25 +192,23 @@ bool jv3_format::load(io_generic *io, uint32_t form_factor, const std::vectorget_maximal_geometry(drive_tracks, drive_sides); - uint32_t image_size = io_generic_size(io); + std::vector data(io_generic_size(io)); + io_generic_read(io, data.data(), 0, data.size()); const uint32_t entries = 2901; const uint32_t header_size = entries *3 +1; - uint8_t header[0x2200]; - io_generic_read(io, header, 0, header_size); bool is_dd = false, is_ds = false; for (uint8_t curr_side = 0; curr_side < 2; curr_side++) { - for (uint8_t curr_track = 0; curr_track < 0x80; curr_track++) + for (uint8_t curr_track = 0; curr_track < MAX_TRACKS; curr_track++) { // Find out how many sectors are in this track uint8_t max_sect = 0, min_sect = 0xff; - uint32_t sect_ptr = 0; for (uint32_t sect = 0; sect < entries; sect++) { - uint8_t track = header[sect_ptr++]; - uint8_t sector = header[sect_ptr++]; - uint8_t flags = header[sect_ptr++]; + uint8_t track = data[sect*3]; + uint8_t sector = data[sect*3+1]; + uint8_t flags = data[sect*3+2]; uint8_t side = (flags & 0x10) ? 1 : 0; if ((track == curr_track) && (side == curr_side)) { @@ -198,15 +245,14 @@ bool jv3_format::load(io_generic *io, uint32_t form_factor, const std::vector