Skip to content

Improve UDI disk image support#57

Open
morozov wants to merge 4 commits into
masterfrom
udi
Open

Improve UDI disk image support#57
morozov wants to merge 4 commits into
masterfrom
udi

Conversation

@morozov

@morozov morozov commented Jun 17, 2026

Copy link
Copy Markdown
Member

Open .udi from Finder

master doesn't register .udi as a document type, so it can't be opened from Finder. This PR adds the registration and an icon, mirroring fdi (#43); no controller change is needed, since UDI already routes through the shared DISK_GENERIC open path.

Description block rejected on load

A UDI may set header byte 11 bit 0 to flag a NUL-terminated description stored after its last track1. master's open_udi scans tracks to EOF, so it reads the first description byte as a track-type byte, fails the check, and returns DISK_UNSUP:

for( i = 0; buffer->index < eof; i++ ) {

Both scan loops are bounded to sides × cylinders tracks, leaving the description unparsed. Spectrofon #09 (SP9_O.udi, header byte 11 = 0x01) is rejected on master and loads with this change.

More than 85 cylinders rejected

The shared GEOM_CHECK macro rejects any image over 85 cylinders as DISK_GEOM:

#define GEOM_CHECK \
if( d->sides < 1 || d->sides > 2 || \
d->cylinders < 1 || d->cylinders > 85 ) return d->status = DISK_GEOM

The UDI max-cylinder field is one byte (0x00–0xFF, up to 256 cylinders)1, and the drive reaches FDD_MAX_TRACK (99), so 85 was below both limits. The cap is raised to 86. GEOM_CHECK is shared by every disk loader and track storage is allocated from d->cylinders, so the wider cap is safe across formats.

Spectrum Expert (SP_EXP1O.UDI) is an 86-cylinder example: its CRC is valid and it has no description block, so master rejects it only at GEOM_CHECK, and raising the cap admits it.

Sectors with imperfect MFM sync don't read

read_id and read_datamark require textbook MFM sync: three 0xffa1 marks before the address mark, and in read_datamark a 0x00 data sync and a gap of only 0x4e/0x00. Any stray gap byte errors the read:

for( i = 40; i > 0; i-- ) {
fdd_read_data( d );
if( d->data == 0x4e ) /* read next */
continue;
if( d->data == 0x00 ) /* go to PLL sync */
break;
return 1; /* something wrong... */

Disks imaged from protected or marginal originals violate this — stray gap bytes, or one or two 0xffa1 marks with no 0x00 sync. A real WD1793 reads them; master does not.

The fix scans the gap for the A1 run within the datasheet's data-mark window — 43 byte-times in MFM, 30 in FM2 — then locks onto the A1 and the following mark byte. It presets the address-mark CRC to 0xcdb4, the value after three A1 bytes, and resumes from the mark byte. The surviving A1 count therefore never affects validation: a standard three-A1 disk validates identically, and the datasheet's detector keys on a single missing-clock A1 regardless2.

This lives in shared WD1793 core, so it also covers +D; the FM path is untouched.

Unsupported CRC algorithms

A UDI whose stored CRC32 was computed with a standard algorithm instead of the format's signed-accumulator variant1 is rejected on load; this PR doesn't relax that. Возрождение (VOZRAZH1.udi) is such an image — its stored CRC matches the textbook algorithm, not the format's.

Footnotes

  1. UDI format specification — Alex Makeev, 2002 (Sinclair Wiki transcription). 2 3

  2. WD179X / FD179X datasheet — 1986 Western Digital Storage Management Products Handbook. 2

morozov added 4 commits June 17, 2026 12:49
Register the .udi extension as a document type so Finder
double-click and Open With route it to FuseX.
open_udi scanned to end of file, so the optional description
block after the last track was parsed as a track descriptor
and failed the type check. Bounding both track loops to the
header geometry leaves the description unparsed.
Extended-format TR-DOS disks use 86 cylinders. Accept them as
valid geometry.
Disks imaged from protected or marginal originals may present an
MFM address mark with only one or two A1 sync marks and no
data-field sync, or carry stray bytes in the data-mark gap. Such
sectors must read.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant