jeffpar / pcjs

The original IBM PC and other machine emulations in JavaScript
https://www.pcjs.org
Other
853 stars 131 forks source link

MINIX 1.1 for PC ATs boots but fails to load the "Root" diskette #57

Closed jeffpar closed 1 year ago

jeffpar commented 1 year ago

There is a similar problem with MINIX 1.1 for PCs and PC XTs using the 360K diskette images, but let's start by debugging the PC AT version here. The test machine has 640K of RAM, which is more than the 512K stated minimum.

jeffpar commented 1 year ago

There were at least 3 separate issues with the floppy disk controller that MINIX 1.1 for PC ATs didn't like:

  1. When the FDC Output Register (0x3F2) is reset, an interrupt is supposed to be generated; PCjs was failing to do that because an internal register hadn't been updated yet.
  2. Since MINIX is using the MT (multi-track) version of the READ command, it expects the FDC command results (specifically, the C, H, and R bytes) to advance past the last sector read; PCjs wasn't updating the R byte as expected.
  3. The MINIX floppy driver was using the wrong number of sectors-per-track (EOT) for the 1.2M MINIX disks (9 instead of 15); this happened because MINIX cycles through 4 sets of drive/disk parameter combos (for DATA RATE, STEPS, EOT, GAP, etc) on every READ, and it will only settle on the correct set (especially the correct EOT) if every incorrect combo fails. PCjs tends to be very forgiving in this regard, in order to make it easy to use non-standard disk formats like XDF, but alas, for the MINIX 1.2M diskettes to work on a PC AT, PCjs must be unforgiving.

The first 2 issues were easy to fix without too much risk of breaking things, but I may just add a special FDC compatibility setting for the "MINIX for PC AT" machine in order to resolve the 3rd issue.

jeffpar commented 1 year ago

I rolled the dice and put in a generic work-around for the 3rd MINIX issue after all. The bare minimum required was adding a couple of lines to the FDC's doCmd() function, right before it calls pushResult():

    if (drive.disk.nSectors >= 15 && this.regControl != FDC.REG_CONTROL.RATE500K) {
        drive.resCode = FDC.REG_DATA.RES.INCOMPLETE;
    }

This will cause ST0 (the first byte of the results data) to indicate an INCOMPLETE error if the diskette is deemed a "high density" diskette (ie, one with 15 or more sectors per track) and MINIX has not yet programmed the CONTROL register for 500kbps transfers (the normal transfer speed for high density diskettes).

jeffpar commented 1 year ago

Fixed as of 271b650de91dc26ed6a5fdd2255d87de84b8b635.