summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author Robbbert <Robbbert@users.noreply.github.com>2021-04-13 21:58:48 +1000
committer Robbbert <Robbbert@users.noreply.github.com>2021-04-13 21:58:48 +1000
commit1e5e1a6376af1368daf9d7283b95936fbe2d50dd (patch)
treeb443673a598a84786518180c2f278e66cd7b37f7 /src/lib
parent8d681373f0acf580b3a7e9b583a9bd59c0d2dfb1 (diff)
jv3: fixed a data pointer bug
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/formats/trs80_dsk.cpp119
1 files 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<jv1_format>;
-#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::vector<ui
printf("Disk detected as JV3\n");fflush(stdout);
int drive_tracks, drive_sides;
image->get_maximal_geometry(drive_tracks, drive_sides);
- uint32_t image_size = io_generic_size(io);
+ std::vector<uint8_t> 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<ui
sectors[i].bad_crc = false;
sectors[i].data = 0;
}
- sect_ptr = 0;
uint32_t data_ptr = header_size;
- bool density = 0;
+ bool ddensity = false;
// Search for sectors on this track & side
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;
uint8_t size = (flags & 0x03);
if (track == 0xff)
@@ -214,24 +260,23 @@ bool jv3_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
else
size ^= 1;
uint16_t sector_size = 128 << size;
- uint8_t sector_data[1024];
- std::fill_n(sector_data,1024,0);
if ((track == curr_track) && (side == curr_side))
{
// If we would exceed the image size then ignore this sector
- if ((data_ptr + sector_size) <= image_size)
+ if ((data_ptr + sector_size) <= data.size())
{
// process the sector
- io_generic_read(io, sector_data, data_ptr, sector_size);
sectors[sector].track = curr_track;
sectors[sector].head = curr_side;
sectors[sector].sector = sector;
sectors[sector].actual_size = sector_size;
sectors[sector].size = size;
- sectors[sector].deleted = (flags & 0x20) ? true : false;
+ uint8_t dam = flags & 0xe0;
+ sectors[sector].deleted = ((dam == 0x60) || (dam == 0xa0)) ? true : false;
sectors[sector].bad_crc = (flags & 0x08) ? true : false;
- sectors[sector].data = &sector_data[0];
- density = (flags & 0x80) ? 1 : 0;
+ sectors[sector].data = &data[data_ptr];
+ if (flags & 0x80)
+ ddensity = true;
}
}
data_ptr += sector_size;
@@ -244,8 +289,8 @@ bool jv3_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return false;
}
- //printf("Side %d, Track %d, %s density\n",curr_side,curr_track,density ? "Double" : "Single");
- if (density)
+ printf("Side %d, Track %d, %s density\n",curr_side,curr_track,ddensity ? "Double" : "Single");
+ if (ddensity)
{
is_dd = true;
build_wd_track_mfm(curr_track, curr_side, image, 100000, max_sect, sectors, 32, 22, 31);