From b562991b8dd43a492de9e420440747dedbb1e3c3 Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Thu, 7 Sep 2023 16:34:59 -0700 Subject: [PATCH 1/4] Changed how the pc.js --hidden option works --- .vscode/launch.json | 6 ++--- machines/pcx86/modules/v3/diskinfo.js | 38 ++++++++++++++++++--------- tools/diskimage/README.md | 4 +++ tools/pc/pc.js | 26 +++++++++--------- 4 files changed, 45 insertions(+), 29 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 8567baa90..c7fcd5a07 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -478,10 +478,10 @@ "request": "launch", "program": "${workspaceFolder}/tools/pc/pc.js", "args": [ - "--start=ibm5160", - "--floppy" + "--sys=pcdos:2", + "--halt" ], - "cwd": "${workspaceFolder}/tools/pc/disks/empty", + "cwd": "${workspaceFolder}/tools/pc/empty", "stopOnEntry": false, "console": "integratedTerminal", "outFiles": [ diff --git a/machines/pcx86/modules/v3/diskinfo.js b/machines/pcx86/modules/v3/diskinfo.js index bd1b9ea7f..05d295c79 100644 --- a/machines/pcx86/modules/v3/diskinfo.js +++ b/machines/pcx86/modules/v3/diskinfo.js @@ -1495,7 +1495,7 @@ export default class DiskInfo { if (driveInfo.partitioned) { bMediaID = 0xF8; - cHiddenSectors = 1 + (driveInfo.hiddenSectors || 0); + cHiddenSectors = driveInfo.hiddenSectors || 1; cDiagnosticSectors = cHeads * cSectorsPerTrack; } @@ -1747,32 +1747,44 @@ export default class DiskInfo { * for the implication that a contemporaneous disk using only 17 sectors per track was safe (it was not). * * To make matters *slightly* worse, the affected boot sectors didn't accurately calculate the sector size - * of the system file correctly; in keeping with the overall "sloppy" approach, it simply divides the file - * size by the sector size and then *always* adds 1 (it should have added 1 only if there was a remainder). - * However, unless IO.SYS or IBMBIO.COM was an *exact* multiple of 512, this calculation would generally - * end up with the correct answer. + * of the system file correctly; in keeping with the overall "sloppy" approach, they simply divide the file + * size by the sector size and then *always* adds 1 (they should have added 1 only if there was a remainder). + * This affects any version of IO.SYS or IBMBIO.COM that is an exact multiple of 512 (such as IBMBIO.COM + * from PC DOS 2.00, which is 4608 bytes or 9 sectors; the boot sector will read 10 sectors instead). * * Having perfect hindsight, we can help the boot sector avoid running into trouble by performing the same * sloppy sector size calculation ourselves, dividing it by sectors per track, and ensuring that the remainder * matches the number of free sectors in the first data track (and adjusting volume sector usage until it does). * As a result, the system file will end at the end of a track, and the boot sector never risks reading too * much data. + * + * Finally, a note about disks with a cluster size of 2 or more sectors: on such disks, the final *cluster* + * of IO.SYS/IBMBIO.COM may not end on a track boundary, but that's OK, because the boot sector is only + * reading sectors, not clusters. Any "overhang" is merely wasted cluster space and does not affect us here. */ let cFileSectors = 0; if (aFileData[0]) { let maxAdjustments = driveInfo.hiddenSectors? 0 : cSectorsPerTrack; - cFileSectors = Math.ceil(aFileData[0].size / cbSector); + /* + * This next calculation should have just used Math.ceil(), but we have to be as "broken" as DOS. + */ + cFileSectors = Math.trunc(aFileData[0].size / cbSector) + 1; while (maxAdjustments--) { let cInitSectors = cHiddenSectors + cReservedSectors + cFATs * cFATSectors + cRootSectors; - let cFreeSectors = cSectorsPerTrack - (cInitSectors % cSectorsPerTrack); /* - * I used to ALSO break whenever cFileSectors - cFreeSectors < 0, because that meant the file was - * contained entirely within a single track, but that's not sufficient, because if the disk is using - * a large number of sectors/track (eg, 63) AND the file happens to be at the start of the track, - * then a full track (31.5K) will be read, which will trash the boot sector. We REALLY need to push - * the file to the END of the track, even if it's fully contained within the track. + * I used to calculate the number of free sectors in the first track with free sectors: + * + * let cFreeSectors = cSectorsPerTrack - (cInitSectors % cSectorsPerTrack); + * + * and break when cFreeSectors >= cFileSectors, because that meant the file was contained + * entirely within that track, but that's not sufficient, because if the disk is using a large + * number of sectors/track (eg, 63) AND the file happens to be at the start of the track, then + * a full track (31.5K) will be read, which will trash the boot sector. We REALLY need to push + * the file to the END of the track, even if it's already fully contained within the track. */ - if ((cFileSectors - cFreeSectors) % cSectorsPerTrack == 0) break; + if ((cInitSectors + cFileSectors) % cSectorsPerTrack == 0) { + break; + } /* * I used to increase root directory sectors, since we were at least getting some benefit from the * adjustment: diff --git a/tools/diskimage/README.md b/tools/diskimage/README.md index 96d168a34..49ec4cb49 100644 --- a/tools/diskimage/README.md +++ b/tools/diskimage/README.md @@ -230,6 +230,10 @@ To extract a specific file from a disk image: diskimage.js /diskettes/pcx86/sys/dos/ibm/2.00/PCDOS200-DISK1.json --extract=COMMAND.COM +To display the contents of a specific file in a disk image: + + diskimage.js /diskettes/pcx86/sys/dos/ibm/3.00/PCDOS300-DISK2.json --type=VDISK.LST + To extract files from a disk image into a specific directory (eg, tmp): diskimage.js /diskettes/pcx86/sys/dos/ibm/2.00/PCDOS200-DISK1.json --extract --extdir=tmp diff --git a/tools/pc/pc.js b/tools/pc/pc.js index 57c0999e7..c8422a72b 100755 --- a/tools/pc/pc.js +++ b/tools/pc/pc.js @@ -819,8 +819,8 @@ function sendSerial(b) /** * checkMachine(sFile) * - * We now allow a machine file to be specified with or without the --load option, with or without a path, and - * with or without an extension. If you don't use --load, then it must be the first non-option argument. If you + * We now allow a machine file to be specified with or without the --start option, with or without a path, and + * with or without an extension. If you don't use --start, then it must be the first non-option argument. If you * don't specify a path, then it must either be in the current directory or the pc.js directory (ie, /tools/pc), * and if you don't specify an extension, we'll try ".json", ".json5", and ".xml", in that order. * @@ -2807,19 +2807,19 @@ function main(argc, argv) "--start=[machine]": "start machine configuration file", }; let optionsDisk = { - "--dir=[directory]": "drive directory (default is " + localDir + ")", - "--disk=[image]": "\tdrive disk image (instead of directory)", - "--drive=[controller]": "drive controller (XT, AT, COMPAQ, or PCJS)", - "--drivetype=[value]": "drive type or C:H:S (eg, 306:4:17)", - "--fat=[number]": "\thard disk FAT type (12 or 16)", - "--hidden=[number]": "additional hidden sectors (default is 0)", - "--label=[label]": "\tvolume label of disk image", - "--maxfiles=[number]": "maximum local files (default is " + maxFiles + ")", + "--dir=[directory]": "use drive directory (default is " + localDir + ")", + "--disk=[image]": "\tuse drive disk image (instead of directory)", + "--drive=[controller]": "set drive controller (XT, AT, COMPAQ, or PCJS)", + "--drivetype=[value]": "set drive type or C:H:S (eg, 306:4:17)", + "--fat=[number]": "\tset hard disk FAT type (12 or 16)", + "--hidden=[number]": "set hidden sectors (default is 1)", + "--label=[label]": "\tset volume label of disk image", + "--maxfiles=[number]": "set maximum local files (default is " + maxFiles + ")", "--normalize=[boolean]": "convert text file encoding (default is " + fNormalize + ")", "--save=[image]": "\tsave drive disk image and exit", - "--sys=[string]": "\toperating system type (default is " + systemType + ")", - "--target=[nK|nM]": "target disk size (default is " + ((kbTarget / 1024)|0) + "M)", - "--ver=[#.##]": "\toperating system version (default is " + systemVersion + ")" + "--sys=[string]": "\tset operating system type (default is " + systemType + ")", + "--target=[nK|nM]": "set target disk size (default is " + ((kbTarget / 1024)|0) + "M)", + "--ver=[#.##]": "\tset operating system version (default is " + systemVersion + ")" }; let optionsOther = { "--bare (-b)": "\tomit helper binaries from disk", From 5e75b295cd64a7303e8da5e3a88a9e78cd42bf4e Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Thu, 7 Sep 2023 17:21:38 -0700 Subject: [PATCH 2/4] Updated boot sector notes in diskinfo.js --- machines/pcx86/modules/v3/diskinfo.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/machines/pcx86/modules/v3/diskinfo.js b/machines/pcx86/modules/v3/diskinfo.js index 05d295c79..eac0b5a94 100644 --- a/machines/pcx86/modules/v3/diskinfo.js +++ b/machines/pcx86/modules/v3/diskinfo.js @@ -1747,10 +1747,14 @@ export default class DiskInfo { * for the implication that a contemporaneous disk using only 17 sectors per track was safe (it was not). * * To make matters *slightly* worse, the affected boot sectors didn't accurately calculate the sector size - * of the system file correctly; in keeping with the overall "sloppy" approach, they simply divide the file - * size by the sector size and then *always* adds 1 (they should have added 1 only if there was a remainder). + * of the system file correctly; in keeping with the overall "sloppy" approach, they simply divided the file + * size by the sector size and then *always* added 1 (they should have added 1 only if there was a remainder). + * * This affects any version of IO.SYS or IBMBIO.COM that is an exact multiple of 512 (such as IBMBIO.COM - * from PC DOS 2.00, which is 4608 bytes or 9 sectors; the boot sector will read 10 sectors instead). + * from PC DOS 2.00, which is 4608 bytes or 9 sectors; the boot sector will read 10 sectors instead). Although + * interestingly, DOS 2.x "precalculates" that number and stores it in the BPB at offset 0x20, whereas DOS 3.x + * actually reads the file size from the directory entry and performs the calculation at runtime. In both + * cases though, the calculation is "sloppy". * * Having perfect hindsight, we can help the boot sector avoid running into trouble by performing the same * sloppy sector size calculation ourselves, dividing it by sectors per track, and ensuring that the remainder From 38a140031985090e4e6c9f6ca6ca6bc18fd26d26 Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Fri, 8 Sep 2023 00:35:38 -0700 Subject: [PATCH 3/4] pc.js now recalculates FAT sectors if hidden sectors had to be adjusted --- .vscode/launch.json | 3 + machines/pcx86/modules/v3/diskinfo.js | 173 ++++++++++++++------------ tools/pc/pc.js | 7 +- 3 files changed, 96 insertions(+), 87 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c7fcd5a07..9cb177042 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -478,7 +478,10 @@ "request": "launch", "program": "${workspaceFolder}/tools/pc/pc.js", "args": [ + "load info", "--sys=pcdos:2", + "--drivetype=100:3:23", + "--test", "--halt" ], "cwd": "${workspaceFolder}/tools/pc/empty", diff --git a/machines/pcx86/modules/v3/diskinfo.js b/machines/pcx86/modules/v3/diskinfo.js index eac0b5a94..05f47a8ba 100644 --- a/machines/pcx86/modules/v3/diskinfo.js +++ b/machines/pcx86/modules/v3/diskinfo.js @@ -1550,7 +1550,6 @@ export default class DiskInfo { * DOS that performs these same tests using the total sectors value from the partition table, then it may be * using a slightly different value and therefore arriving at different defaults. */ - let cRecalcs = 2; if (!driveInfo.clusterSize) { if (cTotalSectors <= 512) { // 0x0200 (256Kb) cSectorsPerCluster = 1; @@ -1593,6 +1592,88 @@ export default class DiskInfo { } cRootSectors = Math.ceil((rootEntries * 32) / cbSector); + /* + * This is our code to ensure that the the last sector of the BIOS (IO.SYS or IBMBIO.COM) falls on the + * last sector of a track. + * + * This weird requirement is due to how PC DOS and MS-DOS 2.x/3.x boot sectors read the first system file + * into memory: they read the file one track at a time; the first track read may be partial, because it + * starts with whatever the file's first sector is, but every subsequent read is a whole track, even if the + * file doesn't occupy the entire track. + * + * This would be OK if there was ample memory, but the boot sector doesn't relocate itself from 0:7C00, + * and with its stack sitting just below that address, there's room for only about 28K of file data. For + * reference, IO.SYS in MS-DOS 3.30 is about 22K, so there's enough room, but if the final sector is near + * the start of a track, then the final full track read (8.5K for a track with 17 sectors) runs the risk + * of overwriting the stack and/or the boot sector itself. + * + * See https://www.os2museum.com/wp/hang-with-early-dos-boot-sector/ for more details; it's accurate except + * for the implication that a contemporaneous disk using only 17 sectors per track was safe (it was not). + * + * To make matters *slightly* worse, the affected boot sectors didn't accurately calculate the sector size + * of the system file correctly; in keeping with the overall "sloppy" approach, they simply divided the file + * size by the sector size and then *always* added 1 (they should have added 1 only if there was a remainder). + * + * This affects any version of IO.SYS or IBMBIO.COM that is an exact multiple of 512 (such as IBMBIO.COM + * from PC DOS 2.00, which is 4608 bytes or 9 sectors; the boot sector will read 10 sectors instead). Although + * interestingly, DOS 2.x "precalculates" that number and stores it in the BPB at offset 0x20, whereas DOS 3.x + * actually reads the file size from the directory entry and performs the calculation at runtime. In both + * cases though, the calculation is "sloppy". + * + * Having perfect hindsight, we can help the boot sector avoid running into trouble by performing the same + * sloppy sector size calculation ourselves, dividing it by sectors per track, and ensuring that the remainder + * matches the number of free sectors in the first data track (and adjusting volume sector usage until it does). + * As a result, the system file will end at the end of a track, and the boot sector never risks reading too + * much data. + * + * Finally, a note about disks with a cluster size of 2 or more sectors: on such disks, the final *cluster* + * of IO.SYS/IBMBIO.COM may not end on a track boundary, but that's OK, because the boot sector is only + * reading sectors, not clusters. Any "overhang" is merely wasted cluster space and does not affect us here. + */ + let cFileSectors = aFileData[0]? Math.trunc(aFileData[0].size / cbSector) + 1 : 0; + let adjustTotalSectors = function() { + let fAdjusted = false; + if (cFileSectors) { + let maxAdjustments = driveInfo.hiddenSectors? 0 : cSectorsPerTrack; + while (maxAdjustments--) { + let cInitSectors = cHiddenSectors + cReservedSectors + cFATs * cFATSectors + cRootSectors; + /* + * I used to calculate the number of free sectors in the first track with free sectors: + * + * let cFreeSectors = cSectorsPerTrack - (cInitSectors % cSectorsPerTrack); + * + * and break when cFreeSectors >= cFileSectors, because that meant the file was contained + * entirely within that track, but that's not sufficient, because if the disk is using a large + * number of sectors/track (eg, 63) AND the file happens to be at the start of the track, then + * a full track (31.5K) will be read, which will trash the boot sector. We REALLY need to push + * the file to the END of the track, even if it's already fully contained within the track. + */ + if ((cInitSectors + cFileSectors) % cSectorsPerTrack == 0) { + break; + } + /* + * I used to increase root directory sectors, since we were at least getting some benefit from the + * adjustment: + * + * cRootSectors++; + * rootEntries += (cbSector >> 5); + * + * However, that created compatibility issues (see the verDOS code above for specific thresholds we + * need to honor). Next, I tried tweaking reserved sectors, but guess what? Few if any versions of DOS + * actually honor reserved sectors (they assume it's 1 and crash if it isn't): + * + * cReservedSectors++; + * + * So we're left with adjusting hidden sectors, which requires a corresponding adjustment to total sectors: + */ + cHiddenSectors++; + cTotalSectors--; + fAdjusted = true; + } + } + return fAdjusted; + }; + /* * Now we get to a thornier matter: when calculating how many clusters will fit on a disk, the calculation * SHOULD begin with total DATA sectors, not total DISK sectors. But that presents a chicken-and-egg problem, @@ -1607,6 +1688,7 @@ export default class DiskInfo { * I learned about the latter by watching IO.SYS from MS-DOS 3.30 read the entire FAT into memory (at 0000:7DC6): * if it reads more than 32K of FAT data, it will start trashing memory. */ + let cRecalcs = 4; let grossClusters, minClusters, maxClusters, initSectors = cSectorsPerCluster; do { minClusters = (typeFAT == 12)? 0 : DiskInfo.FAT12.MAX_CLUSTERS + 1; @@ -1674,7 +1756,13 @@ export default class DiskInfo { continue; } if (grossClusters <= maxClusters) { - if (cFATSectors * cbSector <= 32 * 1024) break; + if (cFATSectors * cbSector <= 32 * 1024) { + if (adjustTotalSectors()) { + if (!cRecalcs--) break; + continue; + } + break; + } } if (cSectorsPerCluster == maxSectorsPerCluster) { if (typeFAT == 12) { @@ -1728,87 +1816,6 @@ export default class DiskInfo { setBoot(DiskInfo.BPB.TRACKSECS, 2, cSectorsPerTrack); setBoot(DiskInfo.BPB.DRIVEHEADS, 2, cHeads); - /* - * We're now at the point where we ensure that the the last sector of the BIOS (IO.SYS or IBMBIO.COM) - * falls on the last sector of a track. - * - * This weird requirement is due to how PC DOS and MS-DOS 2.x/3.x boot sectors read the first system file - * into memory: they read the file one track at a time; the first track read may be partial, because it - * starts with whatever the file's first sector is, but every subsequent read is a whole track, even if the - * file doesn't occupy the entire track. - * - * This would be OK if there was ample memory, but the boot sector doesn't relocate itself from 0:7C00, - * and with its stack sitting just below that address, there's room for only about 28K of file data. For - * reference, IO.SYS in MS-DOS 3.30 is about 22K, so there's enough room, but if the final sector is near - * the start of a track, then the final full track read (8.5K for a track with 17 sectors) runs the risk - * of overwriting the stack and/or the boot sector itself. - * - * See https://www.os2museum.com/wp/hang-with-early-dos-boot-sector/ for more details; it's accurate except - * for the implication that a contemporaneous disk using only 17 sectors per track was safe (it was not). - * - * To make matters *slightly* worse, the affected boot sectors didn't accurately calculate the sector size - * of the system file correctly; in keeping with the overall "sloppy" approach, they simply divided the file - * size by the sector size and then *always* added 1 (they should have added 1 only if there was a remainder). - * - * This affects any version of IO.SYS or IBMBIO.COM that is an exact multiple of 512 (such as IBMBIO.COM - * from PC DOS 2.00, which is 4608 bytes or 9 sectors; the boot sector will read 10 sectors instead). Although - * interestingly, DOS 2.x "precalculates" that number and stores it in the BPB at offset 0x20, whereas DOS 3.x - * actually reads the file size from the directory entry and performs the calculation at runtime. In both - * cases though, the calculation is "sloppy". - * - * Having perfect hindsight, we can help the boot sector avoid running into trouble by performing the same - * sloppy sector size calculation ourselves, dividing it by sectors per track, and ensuring that the remainder - * matches the number of free sectors in the first data track (and adjusting volume sector usage until it does). - * As a result, the system file will end at the end of a track, and the boot sector never risks reading too - * much data. - * - * Finally, a note about disks with a cluster size of 2 or more sectors: on such disks, the final *cluster* - * of IO.SYS/IBMBIO.COM may not end on a track boundary, but that's OK, because the boot sector is only - * reading sectors, not clusters. Any "overhang" is merely wasted cluster space and does not affect us here. - */ - let cFileSectors = 0; - if (aFileData[0]) { - let maxAdjustments = driveInfo.hiddenSectors? 0 : cSectorsPerTrack; - /* - * This next calculation should have just used Math.ceil(), but we have to be as "broken" as DOS. - */ - cFileSectors = Math.trunc(aFileData[0].size / cbSector) + 1; - while (maxAdjustments--) { - let cInitSectors = cHiddenSectors + cReservedSectors + cFATs * cFATSectors + cRootSectors; - /* - * I used to calculate the number of free sectors in the first track with free sectors: - * - * let cFreeSectors = cSectorsPerTrack - (cInitSectors % cSectorsPerTrack); - * - * and break when cFreeSectors >= cFileSectors, because that meant the file was contained - * entirely within that track, but that's not sufficient, because if the disk is using a large - * number of sectors/track (eg, 63) AND the file happens to be at the start of the track, then - * a full track (31.5K) will be read, which will trash the boot sector. We REALLY need to push - * the file to the END of the track, even if it's already fully contained within the track. - */ - if ((cInitSectors + cFileSectors) % cSectorsPerTrack == 0) { - break; - } - /* - * I used to increase root directory sectors, since we were at least getting some benefit from the - * adjustment: - * - * cRootSectors++; - * rootEntries += (cbSector >> 5); - * - * However, that created compatibility issues (see the verDOS code above for specific thresholds we - * need to honor). Next, I tried tweaking reserved sectors, but guess what? Few if any versions of DOS - * actually honor reserved sectors (they assume it's 1 and crash if it isn't): - * - * cReservedSectors++; - * - * So we're left with adjusting hidden sectors, which requires a corresponding adjustment to total sectors: - */ - cHiddenSectors++; - cTotalSectors--; - } - } - if (cTotalSectors <= 0xffff) { setBoot(DiskInfo.BPB.DISKSECS, 2, cTotalSectors); } else { diff --git a/tools/pc/pc.js b/tools/pc/pc.js index c8422a72b..1ca542c33 100755 --- a/tools/pc/pc.js +++ b/tools/pc/pc.js @@ -111,7 +111,6 @@ function setDebugMode(nEvent) } debugMode = nEvent; if (debugMode == DbgLib.EVENTS.READY && prevMode != DbgLib.EVENTS.READY) { - if (fTest) exit(); command = ""; printf('[' + (commandPrev? "Press CTRL-A to repeat last command" : "Type help for list of commands") + ", CTRL-C to terminate]\n"); printf("%s> ", prompt); @@ -775,11 +774,11 @@ function getDriveInfo() info.bytesFree = vol.clusFree * vol.clusSecs * vol.cbSector; info.usageFinalFAT = (vol.cbSector - (Math.ceil(vol.clusTotal * info.typeFAT / 8) % vol.cbSector)) / vol.cbSector * 100; text += sprintf(" %d-bit FAT, %d-byte clusters, %d clusters\n", info.typeFAT, info.clusterSize, info.clustersTotal); - text += sprintf(" %d FAT sectors (x%d), %d root sectors (%d entries)\n", info.sectorsFAT, info.totalFATs, info.sectorsRoot, info.sizeRoot); - text += sprintf(" %d total sectors, %d data sectors, %d data bytes\n", info.sectorsTotal, info.sectorsData, info.bytesTotal); if (fTest) { - text += sprintf(" %3.2f% usage of final FAT sector\n", info.usageFinalFAT); + text += sprintf(" %d hidden sectors, %d reserved sectors\n", info.sectorsHidden, info.sectorsReserved); } + text += sprintf(" %d FAT sectors (x%d), %d root sectors (%d entries)\n", info.sectorsFAT, info.totalFATs, info.sectorsRoot, info.sizeRoot); + text += sprintf(" %d total sectors, %d data sectors, %d data bytes\n", info.sectorsTotal, info.sectorsData, info.bytesTotal); } } return text; From f3d2dcc14ade90e55530b8ed4b5ae4ce8e22a012 Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Fri, 8 Sep 2023 08:20:29 -0700 Subject: [PATCH 4/4] Added undocumented '--trim' option to pc.js --- blog/_posts/2023/2023-09-05-wrapping-up-support-for-fat.md | 4 ++-- tools/pc/pc.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/blog/_posts/2023/2023-09-05-wrapping-up-support-for-fat.md b/blog/_posts/2023/2023-09-05-wrapping-up-support-for-fat.md index a1d0b0a33..7a4b952c1 100644 --- a/blog/_posts/2023/2023-09-05-wrapping-up-support-for-fat.md +++ b/blog/_posts/2023/2023-09-05-wrapping-up-support-for-fat.md @@ -242,9 +242,9 @@ To confirm this, I tested a drive configuration (162 cylinders, 4 heads, and 17 Here's how I built it using `pc.js`: - % pc.js --sys=pcdos --ver=2.00 --drivetype=162:4:17 --test --save=test.img + % pc.js --sys=pcdos --ver=2.00 --drivetype=162:4:17 --trim --save=test.img -The undocumented `--test` flag tells `pc.js` to bypass its normal DOS-compatibility rules and build/format the disk with an "optimized" 12-bit FAT, and the `--save` option saves the disk image without starting a machine. And although DOS 2.00 didn't like it, `test.img` was an otherwise perfectly valid and usable disk image, and `fsck_msdos` on macOS reported no problems. +The undocumented `--trim` flag tells `pc.js` to bypass its normal DOS-compatibility rules and build/format the disk with an "optimized" 12-bit FAT, and the `--save` option saves the disk image without starting a machine. And although DOS 2.00 didn't like it, `test.img` was an otherwise perfectly valid and usable disk image, and `fsck_msdos` on macOS reported no problems. It's understandable that DOS 2.00 would be skeptical of its own BPBs, in part because BPBs were a new feature that probably evolved during the development of DOS 2.00, so they would have been dealing with disks with no BPBs, out-dated BPBs, or even invalid BPBs. However, perhaps the biggest problem was FDISK, because whenever FDISK created a DOS partition, it would simply update the partition table in the Master Boot Record and then reboot, leaving the partition's boot sector and any BPB it previously contained in place. And that old BPB might be completely inappropriate. diff --git a/tools/pc/pc.js b/tools/pc/pc.js index 1ca542c33..b36205f1a 100755 --- a/tools/pc/pc.js +++ b/tools/pc/pc.js @@ -2668,7 +2668,7 @@ function main(argc, argv) fDebug = removeFlag('debug') || fDebug; fVerbose = removeFlag('verbose') || fVerbose; fTest = removeFlag('test') || fTest; - if (fTest) driveInfo.trimFAT = true; + if (removeFlag('trim')) driveInfo.trimFAT = true; device.setDebug(fDebug); device.setMessages(MESSAGE.DISK + MESSAGE.WARN + MESSAGE.ERROR + (fDebug && fVerbose? MESSAGE.DEBUG : 0) + (fVerbose? MESSAGE.INFO : 0), true);