Improved separation of FDC media parameters from drive parameters
This commit is contained in:
parent
2ce025aa78
commit
1809543577
32 changed files with 1915 additions and 1887 deletions
|
|
@ -16,7 +16,7 @@ when the keyboard's "clock" line is toggled (see *set8042CmdData()* in [chipset.
|
|||
a 40-track diskette).
|
||||
+ The BIOS Diskette Reset function does something odd after resetting the Floppy Disk Controller: it
|
||||
issues not one but *four* "SENSE INTERRUPT STATUS" commands to the FDC, and expects each response to
|
||||
return an incrementally larger drive number. I found this a bit mystifying, considering that the IBM's
|
||||
return an incrementally larger drive number. I found this a bit mystifying, considering that IBM's
|
||||
own FDC/HDC "combo card" supports a maximum of *two* diskette drives. But, there's no point in arguing
|
||||
with a BIOS that's almost 30 years old.
|
||||
+ The BIOS attempts to detect what its authors must have considered a common problem: failure to run SETUP
|
||||
|
|
@ -28,22 +28,22 @@ to discover that the ATC had this behavior, and now I'm wondering how many other
|
|||
immediate "STATUS" register updates.
|
||||
|
||||
This PCjs release also fixes a problem reported by a user: if you disable **localStorage** support in your
|
||||
browser, previous versions would fault. I knew that every browser that supports PCjs also supports
|
||||
**localStorage**, but I didn't consider what might happen if a user had decided to turn it off.
|
||||
browser, previous versions of PCjs would fault. While every browser that supports PCjs also supports
|
||||
**localStorage**, I didn't consider what might happen if a user decided to turn it off.
|
||||
|
||||
The only downside to turning off **localStorage** is that none of your PCjs machines will be able save/restore
|
||||
their state when you leave/return to the page, so they will always reboot.
|
||||
their state when you leave/return to the page; they will always reboot.
|
||||
|
||||
Browser's don't always refer to the **localStorage** feature by its actual name, either. For example, in
|
||||
Chrome, the setting that enables/disables **localStorage** is hidden under "Advanced Settings" => "Privacy" =>
|
||||
"Content Settings" => "Cookies" => "Allow local data to be set (recommended)". Which is a little misleading
|
||||
and annoying, because **localStorage** != **cookie**.
|
||||
"Content Settings" => "Cookies" => "Allow local data to be set (recommended)". Which is somewhat misleading
|
||||
and a little annoying, because **localStorage** is *not* a **cookie**.
|
||||
|
||||
PCjs *never* sets any cookies. Cookies are bits of data that your browser saves and then automatically sends
|
||||
off to the server every time you make a request. **localStorage** is nothing more than local storage. Granted,
|
||||
a JavaScript application could certainly abuse it and send it around like a cookie, but PCjs doesn't do that.
|
||||
The only exception is when PCjs detects a problem, and even then, you must first agree to submit your machine's
|
||||
state as part of the bug report.
|
||||
off to the server every time you make a request. **localStorage** is nothing more than local storage; it is
|
||||
*not* automatically sent anywhere. Granted, a JavaScript application could abuse it and send it around like a
|
||||
cookie, but PCjs does *not* do that; the only exception is when PCjs detects a problem, and even then, you must
|
||||
first agree to submit your machine's state as part of the bug report.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*October 17, 2014*
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ The following features are targeted for version 1.16:
|
|||
|
||||
### History
|
||||
|
||||
+ v1.15 introduced PC AT (Model 5170) emulation, as discussed on our [Blog](/blog/2014/09/13/).
|
||||
+ v1.14 introduced limited EGA emulation, as discussed on our [Blog](/blog/2014/07/30/).
|
||||
+ v1.15 introduced PC AT (Model 5170) emulation, as discussed in the [blog](/blog/2014/09/13/).
|
||||
+ v1.14 introduced limited EGA emulation, as discussed in the [blog](/blog/2014/07/30/).
|
||||
+ v1.13 introduced manifest files that describe software packages that can be used with PCjs.
|
||||
More information on software manifests is available [here](/apps/).
|
||||
+ v1.12.1 coincided with the first release of the new PCjs web server running on [Node.js](http://nodejs.org).
|
||||
|
|
|
|||
|
|
@ -43,13 +43,13 @@ var mkdirp = require("mkdirp");
|
|||
|
||||
var DiskAPI = require("../../shared/lib/diskapi");
|
||||
var DumpAPI = require("../../shared/lib/dumpapi");
|
||||
var DiskDump = require("../../diskdump");
|
||||
var FileDump = require("../../filedump");
|
||||
var UserAPI = require("../../shared/lib/userapi");
|
||||
var ReportAPI = require("../../shared/lib/reportapi");
|
||||
var net = require("../../shared/lib/netlib");
|
||||
var str = require("../../shared/lib/strlib");
|
||||
var usr = require("../../shared/lib/usrlib");
|
||||
var DiskDump = require("../../diskdump");
|
||||
var FileDump = require("../../filedump");
|
||||
|
||||
/**
|
||||
* @type {HTMLOut}
|
||||
|
|
|
|||
|
|
@ -926,7 +926,7 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock)
|
|||
var sMachineFunc = "embed" + sMachine;
|
||||
var sMachineClass = sMachine.toLowerCase();
|
||||
var aMachineParms = aMatch[4].split(':');
|
||||
var sMachineMessage = "(If you see this message, " + sMachine + "js may still be loading)";
|
||||
var sMachineMessage = "(If you see this message, " + sMachine + "js is still loading, or JavaScript has been disabled)";
|
||||
|
||||
var sMachineID = aMachineParms[0];
|
||||
var sMachineXSLFile = aMachineParms[1] || "";
|
||||
|
|
|
|||
|
|
@ -738,6 +738,13 @@ FDC.prototype.initController = function(data)
|
|||
for (iDrive = 0; iDrive < this.aDrives.length; iDrive++) {
|
||||
var drive = this.aDrives[iDrive];
|
||||
if (drive === undefined) {
|
||||
/*
|
||||
* The first time each drive is initialized, obtain its type (from switches or CMOS) and the physical limits
|
||||
* of the drive (ie, max tracks and max sectors/track). As for max heads, initDrive() assumes that all drives
|
||||
* have two heads, and in any case, there's no way to configure/specify a single-sided floppy drive.
|
||||
*
|
||||
* TODO: Provide a configuration option for single-sided drives, in case someone really wants to simulate that.
|
||||
*/
|
||||
drive = this.aDrives[iDrive] = {};
|
||||
drive.bType = this.chipset.getSWFloppyDriveType(iDrive);
|
||||
drive.nCylinders = 40;
|
||||
|
|
@ -823,7 +830,7 @@ FDC.prototype.initDrive = function(drive, iDrive, data)
|
|||
/*
|
||||
* Note that when no data is provided (eg, when the controller is being reinitialized), we now take
|
||||
* care to preserve any drive defaults that initController() already obtained for us, falling back to
|
||||
* bare minimums only when all else has failed.
|
||||
* bare minimums only when all else fails.
|
||||
*/
|
||||
data[1] = [FDC.DEFAULT_DRIVE_NAME, drive.nCylinders || 40, drive.nHeads || data[3], drive.nSectors || 9, drive.cbSector || 512, data[1]];
|
||||
}
|
||||
|
|
@ -845,6 +852,18 @@ FDC.prototype.initDrive = function(drive, iDrive, data)
|
|||
drive.nSectors = data[i][3]; // sectors/track
|
||||
drive.cbSector = data[i][4]; // bytes/sector
|
||||
drive.fRemovable = data[i][5];
|
||||
/*
|
||||
* If we have current media parameters, restore them; otherwise, default to the drive's physical parameters.
|
||||
*/
|
||||
if (drive.nDiskCylinders = data[i][6]) {
|
||||
drive.nDiskHeads = data[i][7];
|
||||
drive.nDiskSectors = data[i][8];
|
||||
} else {
|
||||
drive.nDiskCylinders = drive.nCylinders;
|
||||
drive.nDiskHeads = drive.nHeads;
|
||||
drive.nDiskSectors = drive.nSectors;
|
||||
|
||||
}
|
||||
i++;
|
||||
|
||||
/*
|
||||
|
|
@ -888,11 +907,7 @@ FDC.prototype.initDrive = function(drive, iDrive, data)
|
|||
drive.nBytes = data[i++];
|
||||
|
||||
/*
|
||||
* The next group of properties are set by user requests to load/unload diskette images.
|
||||
*
|
||||
* NOTE: I now avoid reinitializing drive.disk in order to retain any previously mounted diskette across resets.
|
||||
*
|
||||
* drive.disk = null; // when a "disk" is "inserted" into the "drive", this is a Disk object
|
||||
* We no longer reinitialize drive.disk, in order to retain previously mounted diskette across resets.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
@ -971,7 +986,7 @@ FDC.prototype.saveDrive = function(drive)
|
|||
var i = 0;
|
||||
var data = [];
|
||||
data[i++] = drive.resCode;
|
||||
data[i++] = [drive.name, drive.nCylinders, drive.nHeads, drive.nSectors, drive.cbSector, drive.fRemovable];
|
||||
data[i++] = [drive.name, drive.nCylinders, drive.nHeads, drive.nSectors, drive.cbSector, drive.fRemovable, drive.nDiskCylinders, drive.nDiskHeads, drive.nDiskSectors];
|
||||
data[i++] = drive.bHead;
|
||||
/*
|
||||
* We used to store drive.nHeads in the next slot, but now we store bCylinderSeek,
|
||||
|
|
@ -1170,16 +1185,21 @@ FDC.prototype.loadDiskette = function(iDrive, sDisketteName, sDiskettePath, fAut
|
|||
*/
|
||||
FDC.prototype.mountDiskette = function(drive, disk, sDisketteName, sDiskettePath)
|
||||
{
|
||||
var aDiskInfo;
|
||||
|
||||
drive.fBusy = false;
|
||||
|
||||
if (disk) {
|
||||
/*
|
||||
* We shouldn't mount the diskette unless the drive is able to handle it; for example, DSDD (40-track)
|
||||
* drives cannot read DSHD (80-track) diskettes.
|
||||
*/
|
||||
if (disk && disk.aDiskData.length > drive.nCylinders) {
|
||||
aDiskInfo = disk.info();
|
||||
if (disk && aDiskInfo[0] > drive.nCylinders || aDiskInfo[1] > drive.nHeads || aDiskInfo[2] > drive.nSectors) {
|
||||
this.notice("Diskette \"" + sDisketteName + "\" too large for drive " + String.fromCharCode(0x41 + drive.iDrive));
|
||||
disk = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (disk) {
|
||||
drive.disk = disk;
|
||||
|
|
@ -1205,6 +1225,13 @@ FDC.prototype.mountDiskette = function(drive, disk, sDisketteName, sDiskettePath
|
|||
* and will not match the drive mappings that DOS ultimately uses (ie, for drives beyond B:).
|
||||
*/
|
||||
this.notice("Mounted diskette \"" + sDisketteName + "\" in drive " + String.fromCharCode(0x41 + drive.iDrive), drive.fAutoMount);
|
||||
|
||||
/*
|
||||
* Update the drive's current media parameters to match the disk's.
|
||||
*/
|
||||
drive.nDiskCylinders = aDiskInfo[0];
|
||||
drive.nDiskHeads = aDiskInfo[1];
|
||||
drive.nDiskSectors = aDiskInfo[2];
|
||||
}
|
||||
|
||||
if (drive.fAutoMount) {
|
||||
|
|
@ -2141,8 +2168,8 @@ FDC.prototype.writeByte = function(drive, b)
|
|||
/**
|
||||
* advanceSector(drive)
|
||||
*
|
||||
* This increments the sector number; when the sector number reaches drive.nSectors on the current track, we
|
||||
* increment drive.bHead and reset drive.bSector, and when drive.bHead reaches drive.nHeads, we reset drive.bHead
|
||||
* This increments the sector number; when the sector number reaches drive.nDiskSectors on the current track, we
|
||||
* increment drive.bHead and reset drive.bSector, and when drive.bHead reaches drive.nDiskHeads, we reset drive.bHead
|
||||
* and increment drive.bCylinder.
|
||||
*
|
||||
* @this {FDC}
|
||||
|
|
@ -2150,13 +2177,13 @@ FDC.prototype.writeByte = function(drive, b)
|
|||
*/
|
||||
FDC.prototype.advanceSector = function(drive)
|
||||
{
|
||||
Component.assert(drive.bCylinder < drive.nCylinders);
|
||||
Component.assert(drive.bCylinder < drive.nDiskCylinders);
|
||||
drive.bSector++;
|
||||
var bSectorStart = 1;
|
||||
if (drive.bSector >= drive.nSectors + bSectorStart) {
|
||||
if (drive.bSector >= drive.nDiskSectors + bSectorStart) {
|
||||
drive.bSector = bSectorStart;
|
||||
drive.bHead++;
|
||||
if (drive.bHead >= drive.nHeads) {
|
||||
if (drive.bHead >= drive.nDiskHeads) {
|
||||
drive.bHead = 0;
|
||||
drive.bCylinder++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -865,7 +865,7 @@ HDC.prototype.initDrive = function(iDrive, drive, driveConfig, data, fReset)
|
|||
/*
|
||||
* The next group of properties are set by user requests to load/unload disk images.
|
||||
*
|
||||
* NOTE: I now avoid reinitializing drive.disk in order to retain any previously mounted disk across resets.
|
||||
* We no longer reinitialize drive.disk, in order to retain previously mounted disk across resets.
|
||||
*/
|
||||
if (drive.disk === undefined) {
|
||||
drive.disk = null;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue