Ready to debug Windows/386 (see /disks/pc/windows/2.01/)
This commit is contained in:
parent
d052b114c0
commit
8d1031c8b2
7 changed files with 80403 additions and 14 deletions
|
|
@ -9,7 +9,7 @@
|
||||||
<ram id="ramExt" addr="0x100000" size="0x100000" comment="Extended memory at 0x100000"/>
|
<ram id="ramExt" addr="0x100000" size="0x100000" comment="Extended memory at 0x100000"/>
|
||||||
<rom id="romBIOS" addr="0xf8000" size="0x8000" alias="[0xf0000,0xffff0000,0xffff8000]" file="/devices/pc/rom/compaq/bios/deskpro386/1988-01-28/1988-01-28.json"/>
|
<rom id="romBIOS" addr="0xf8000" size="0x8000" alias="[0xf0000,0xffff0000,0xffff8000]" file="/devices/pc/rom/compaq/bios/deskpro386/1988-01-28/1988-01-28.json"/>
|
||||||
<video ref="/devices/pc/video/ibm/vga/1986-10-27/256kb-autolockfs.xml"/>
|
<video ref="/devices/pc/video/ibm/vga/1986-10-27/256kb-autolockfs.xml"/>
|
||||||
<fdc ref="/disks/pc/compiled/library.xml" automount='{A: {name: "PC-DOS 3.30 (Disk 1)", path: "/disks/pc/dos/ibm/3.30/PCDOS330-DISK1.json"}, B: {name: "VGA Tests (Black Book)", path: "/tests/pc/vga/VGABIN.json"}}'/>
|
<fdc ref="/disks/pc/compiled/library.xml" automount='{A: {name: "COMPAQ MS-DOS 3.10 (Disk 1)", path: "/disks/pc/dos/compaq/3.10/COMPAQ-DOS310-DISK1.json"}, B: {name: "COMPAQ MS-DOS 3.10 (Disk 2)", path: "/disks/pc/dos/compaq/3.10/COMPAQ-DOS310-DISK2.json"}}'/>
|
||||||
<keyboard ref="/devices/pc/keyboard/us84-buttons-functions.xml"/>
|
<keyboard ref="/devices/pc/keyboard/us84-buttons-functions.xml"/>
|
||||||
<debugger id="debugger" messages="fault|int" commands=""/>
|
<debugger id="debugger" messages="fault|int" commands=""/>
|
||||||
<panel ref="/devices/pc/panel/wide386.xml"/>
|
<panel ref="/devices/pc/panel/wide386.xml"/>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<video id="videoVGA" model="vga" screenwidth="1280" screenheight="960" scale="true" autolock="true" pos="center" padding="8px">
|
<video id="videoVGA" model="vga" screenwidth="1280" screenheight="960" scale="true" autolock="true" pos="center" padding="8px">
|
||||||
<menu>
|
<menu>
|
||||||
<title>VGA Color Display</title>
|
<title>COMPAQ VGA Color Display</title>
|
||||||
<control type="container" pos="right">
|
<control type="container" pos="right">
|
||||||
<control type="led" label="Caps" binding="caps-lock" padleft="8px"/>
|
<control type="led" label="Caps" binding="caps-lock" padleft="8px"/>
|
||||||
<control type="led" label="Num" binding="num-lock" padleft="8px"/>
|
<control type="led" label="Num" binding="num-lock" padleft="8px"/>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<video id="videoVGA" model="vga" screenwidth="1280" screenheight="960" scale="true" touchscreen="mouse" autolock="true" pos="center" padding="8px">
|
<video id="videoVGA" model="vga" screenwidth="1280" screenheight="960" scale="true" touchscreen="mouse" autolock="true" pos="center" padding="8px">
|
||||||
<menu>
|
<menu>
|
||||||
<title>VGA Color Display</title>
|
<title>IBM VGA Color Display</title>
|
||||||
<control type="container" pos="right">
|
<control type="container" pos="right">
|
||||||
<control type="led" label="Caps" binding="caps-lock" padleft="8px"/>
|
<control type="led" label="Caps" binding="caps-lock" padleft="8px"/>
|
||||||
<control type="led" label="Num" binding="num-lock" padleft="8px"/>
|
<control type="led" label="Num" binding="num-lock" padleft="8px"/>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<video id="videoVGA" model="vga" screenwidth="1280" screenheight="960" scale="true" touchscreen="mouse" pos="center" padding="8px">
|
<video id="videoVGA" model="vga" screenwidth="1280" screenheight="960" scale="true" touchscreen="mouse" pos="center" padding="8px">
|
||||||
<menu>
|
<menu>
|
||||||
<title>VGA Color Display</title>
|
<title>IBM VGA Color Display</title>
|
||||||
<control type="container" pos="right">
|
<control type="container" pos="right">
|
||||||
<control type="led" label="Caps" binding="caps-lock" padleft="8px"/>
|
<control type="led" label="Caps" binding="caps-lock" padleft="8px"/>
|
||||||
<control type="led" label="Num" binding="num-lock" padleft="8px"/>
|
<control type="led" label="Num" binding="num-lock" padleft="8px"/>
|
||||||
|
|
|
||||||
80326
disks/pc/fixed/20mb/COMPAQ310-WIN386201-VGA.json
Normal file
80326
disks/pc/fixed/20mb/COMPAQ310-WIN386201-VGA.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -2,6 +2,13 @@
|
||||||
layout: page
|
layout: page
|
||||||
title: Microsoft Windows/386 2.01
|
title: Microsoft Windows/386 2.01
|
||||||
permalink: /disks/pc/windows/2.01/
|
permalink: /disks/pc/windows/2.01/
|
||||||
|
machines:
|
||||||
|
- type: pc
|
||||||
|
id: deskpro386
|
||||||
|
debugger: true
|
||||||
|
config: /devices/pc/machine/compaq/deskpro386/vga/2048kb/machine.xml
|
||||||
|
drives: '[{name:"20Mb Hard Disk",type:2,path:"/disks/pc/fixed/20mb/COMPAQ310-WIN386201-VGA.json"}]'
|
||||||
|
autoMount: ''
|
||||||
---
|
---
|
||||||
|
|
||||||
Microsoft Windows 2.0 existed only as "point releases":
|
Microsoft Windows 2.0 existed only as "point releases":
|
||||||
|
|
@ -18,6 +25,8 @@ by several months.
|
||||||
|
|
||||||
Directory listings of the three 1.2Mb distribution diskettes are provided below.
|
Directory listings of the three 1.2Mb distribution diskettes are provided below.
|
||||||
|
|
||||||
|
{% include machine.html id="deskpro386" %}
|
||||||
|
|
||||||
### Directory of Windows/386 2.01 (Disk 1)
|
### Directory of Windows/386 2.01 (Disk 1)
|
||||||
|
|
||||||
Volume in drive A has no label
|
Volume in drive A has no label
|
||||||
|
|
|
||||||
|
|
@ -757,7 +757,7 @@ FileInfo.prototype.getSymbol = function(off, fNearest)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every Sector object (once loaded and fully parsed) should have ALL of the following named properties:
|
* Every Sector object (once loaded, parsed, and "normalized") should have ALL of the following named properties:
|
||||||
*
|
*
|
||||||
* 'sector': sector number
|
* 'sector': sector number
|
||||||
* 'length': size of the sector, in bytes
|
* 'length': size of the sector, in bytes
|
||||||
|
|
@ -939,6 +939,7 @@ Disk.prototype.powerDown = function(fSave, fShutdown)
|
||||||
/**
|
/**
|
||||||
* create()
|
* create()
|
||||||
*
|
*
|
||||||
|
* @this {Disk}
|
||||||
* @param {string} mode
|
* @param {string} mode
|
||||||
* @param {number} nCylinders
|
* @param {number} nCylinders
|
||||||
* @param {number} nHeads
|
* @param {number} nHeads
|
||||||
|
|
@ -1968,6 +1969,7 @@ Disk.prototype.updateSector = function(file, pba, off)
|
||||||
* cModify: number of modified dwords in sector
|
* cModify: number of modified dwords in sector
|
||||||
* fDirty: true if sector is dirty, false if clean (or cleaning in progress)
|
* fDirty: true if sector is dirty, false if clean (or cleaning in progress)
|
||||||
*
|
*
|
||||||
|
* @this {Disk}
|
||||||
* @param {Object} sector
|
* @param {Object} sector
|
||||||
* @param {number} iCylinder
|
* @param {number} iCylinder
|
||||||
* @param {number} iHead
|
* @param {number} iHead
|
||||||
|
|
@ -2013,6 +2015,7 @@ Disk.prototype.connectRemoteDisk = function(sDiskPath)
|
||||||
/**
|
/**
|
||||||
* readRemoteSectors(iCylinder, iHead, iSector, nSectors, fAsync, done)
|
* readRemoteSectors(iCylinder, iHead, iSector, nSectors, fAsync, done)
|
||||||
*
|
*
|
||||||
|
* @this {Disk}
|
||||||
* @param {number} iCylinder
|
* @param {number} iCylinder
|
||||||
* @param {number} iHead
|
* @param {number} iHead
|
||||||
* @param {number} iSector
|
* @param {number} iSector
|
||||||
|
|
@ -2046,6 +2049,7 @@ Disk.prototype.readRemoteSectors = function(iCylinder, iHead, iSector, nSectors,
|
||||||
/**
|
/**
|
||||||
* doneReadRemoteSectors(sURLName, sURLData, nErrorCode, sectorInfo)
|
* doneReadRemoteSectors(sURLName, sURLData, nErrorCode, sectorInfo)
|
||||||
*
|
*
|
||||||
|
* @this {Disk}
|
||||||
* @param {string} sURLName
|
* @param {string} sURLName
|
||||||
* @param {string} sURLData
|
* @param {string} sURLData
|
||||||
* @param {number} nErrorCode
|
* @param {number} nErrorCode
|
||||||
|
|
@ -2110,6 +2114,7 @@ Disk.prototype.doneReadRemoteSectors = function(sURLName, sURLData, nErrorCode,
|
||||||
* clean -- unless one or more writes to the sector occurred in the meantime, which we track through a per-sector
|
* clean -- unless one or more writes to the sector occurred in the meantime, which we track through a per-sector
|
||||||
* fDirty flag.
|
* fDirty flag.
|
||||||
*
|
*
|
||||||
|
* @this {Disk}
|
||||||
* @param {number} iCylinder
|
* @param {number} iCylinder
|
||||||
* @param {number} iHead
|
* @param {number} iHead
|
||||||
* @param {number} iSector
|
* @param {number} iSector
|
||||||
|
|
@ -2146,6 +2151,7 @@ Disk.prototype.writeRemoteSectors = function(iCylinder, iHead, iSector, nSectors
|
||||||
/**
|
/**
|
||||||
* doneWriteRemoteSectors(sURLName, sURLData, nErrorCode, sectorInfo)
|
* doneWriteRemoteSectors(sURLName, sURLData, nErrorCode, sectorInfo)
|
||||||
*
|
*
|
||||||
|
* @this {Disk}
|
||||||
* @param {string} sURLName
|
* @param {string} sURLName
|
||||||
* @param {string} sURLData
|
* @param {string} sURLData
|
||||||
* @param {number} nErrorCode
|
* @param {number} nErrorCode
|
||||||
|
|
@ -2212,6 +2218,7 @@ Disk.prototype.disconnectRemoteDisk = function()
|
||||||
* is finally written, we want to take advantage of the write request to write any additional dirty
|
* is finally written, we want to take advantage of the write request to write any additional dirty
|
||||||
* sectors that follow it, even if those additional sectors were written less than 2 seconds ago.
|
* sectors that follow it, even if those additional sectors were written less than 2 seconds ago.
|
||||||
*
|
*
|
||||||
|
* @this {Disk}
|
||||||
* @param {Object} sector
|
* @param {Object} sector
|
||||||
* @param {boolean} fAsync (true to update write timer, false to not)
|
* @param {boolean} fAsync (true to update write timer, false to not)
|
||||||
* @return {boolean} true if write timer set, false if not
|
* @return {boolean} true if write timer set, false if not
|
||||||
|
|
@ -2241,6 +2248,7 @@ Disk.prototype.queueDirtySector = function(sector, fAsync)
|
||||||
* If a timer is already active, make sure it's still valid (ie, the time the timer is scheduled to fire is
|
* If a timer is already active, make sure it's still valid (ie, the time the timer is scheduled to fire is
|
||||||
* >= the timestamp of the next dirty sector + REMOTE_WRITE_DELAY); if not, cancel the timer and start a new one.
|
* >= the timestamp of the next dirty sector + REMOTE_WRITE_DELAY); if not, cancel the timer and start a new one.
|
||||||
*
|
*
|
||||||
|
* @this {Disk}
|
||||||
* @return {boolean} true if write timer set, false if not
|
* @return {boolean} true if write timer set, false if not
|
||||||
*/
|
*/
|
||||||
Disk.prototype.updateWriteTimer = function()
|
Disk.prototype.updateWriteTimer = function()
|
||||||
|
|
@ -2276,11 +2284,12 @@ Disk.prototype.updateWriteTimer = function()
|
||||||
/**
|
/**
|
||||||
* findDirtySectors(fAsync)
|
* findDirtySectors(fAsync)
|
||||||
*
|
*
|
||||||
* @param {boolean} fAsync is true if this function is being called asynchronously, false otherwise
|
|
||||||
* @return {boolean|Array} false if no dirty sectors, otherwise true (or a response array if not fAsync)
|
|
||||||
*
|
|
||||||
* Starting with the oldest dirty sector in the queue (aDirtySectors), determine the longest contiguous stretch of
|
* Starting with the oldest dirty sector in the queue (aDirtySectors), determine the longest contiguous stretch of
|
||||||
* dirty sectors (currently limited to the same track), mark them all as not dirty, and then call writeRemoteSectors().
|
* dirty sectors (currently limited to the same track), mark them all as not dirty, and then call writeRemoteSectors().
|
||||||
|
*
|
||||||
|
* @this {Disk}
|
||||||
|
* @param {boolean} fAsync is true if this function is being called asynchronously, false otherwise
|
||||||
|
* @return {boolean|Array} false if no dirty sectors, otherwise true (or a response array if not fAsync)
|
||||||
*/
|
*/
|
||||||
Disk.prototype.findDirtySectors = function(fAsync)
|
Disk.prototype.findDirtySectors = function(fAsync)
|
||||||
{
|
{
|
||||||
|
|
@ -2418,6 +2427,7 @@ Disk.prototype.seek = function(iCylinder, iHead, iSector, fWrite, done)
|
||||||
/**
|
/**
|
||||||
* fill(sector, ab, off)
|
* fill(sector, ab, off)
|
||||||
*
|
*
|
||||||
|
* @this {Disk}
|
||||||
* @param {Object} sector
|
* @param {Object} sector
|
||||||
* @param {*} ab (technically, this should be typed as Array.<number> but I'm having trouble coercing JSON.parse() to that)
|
* @param {*} ab (technically, this should be typed as Array.<number> but I'm having trouble coercing JSON.parse() to that)
|
||||||
* @param {number} off
|
* @param {number} off
|
||||||
|
|
@ -2440,6 +2450,7 @@ Disk.prototype.fill = function(sector, ab, off)
|
||||||
/**
|
/**
|
||||||
* toBytes(sector)
|
* toBytes(sector)
|
||||||
*
|
*
|
||||||
|
* @this {Disk}
|
||||||
* @param {Object} sector
|
* @param {Object} sector
|
||||||
* @return {Array.<number>} is an array of bytes
|
* @return {Array.<number>} is an array of bytes
|
||||||
*/
|
*/
|
||||||
|
|
@ -2704,8 +2715,9 @@ Disk.prototype.restore = function(deltas)
|
||||||
var sector = this.aDiskData[iCylinder][iHead][iSector];
|
var sector = this.aDiskData[iCylinder][iHead][iSector];
|
||||||
if (!sector) continue;
|
if (!sector) continue;
|
||||||
/*
|
/*
|
||||||
* Since write() now deals with empty/partial sectors, we no longer need to completely "inflate" the sector prior
|
* Since write() now deals with empty/partial sectors, we no longer need to completely "inflate"
|
||||||
* to applying modifications. So let's just make sure that the sector is "inflated" up to iModify.
|
* the sector prior to applying modifications. So let's just make sure that the sector is "inflated"
|
||||||
|
* up to iModify.
|
||||||
*/
|
*/
|
||||||
var idw = sector['data'].length;
|
var idw = sector['data'].length;
|
||||||
while (idw < iModify) {
|
while (idw < iModify) {
|
||||||
|
|
@ -2744,17 +2756,25 @@ Disk.prototype.restore = function(deltas)
|
||||||
* toJSON()
|
* toJSON()
|
||||||
*
|
*
|
||||||
* We perform some RegExp massaging on the JSON data to eliminate unnecessary properties
|
* We perform some RegExp massaging on the JSON data to eliminate unnecessary properties
|
||||||
* (eg, 'length' values of 512, 'pattern' values of 0, quotes around the property names, etc).
|
* (eg, 'length' values of 512, 'pattern' values of 0, since those are defaults).
|
||||||
* Sectors that were initially compressed should remain compressed unless/until they were modified.
|
|
||||||
*
|
*
|
||||||
* TODO: Check sectors (or at least modified sectors) to see if they can be recompressed.
|
* In addition, we first check every sector to see if it can be "deflated". Sectors that were
|
||||||
|
* initially "deflated" should remain that way unless/until they were modified, so technically,
|
||||||
|
* we could call deflateSector() just for modified sectors, but this isn't a common operation,
|
||||||
|
* so it doesn't hurt to check every sector.
|
||||||
*
|
*
|
||||||
* @this {Disk}
|
* @this {Disk}
|
||||||
* @return {string} containing the entire disk image as JSON-encoded data
|
* @return {string} containing the entire disk image as JSON-encoded data
|
||||||
*/
|
*/
|
||||||
Disk.prototype.toJSON = function()
|
Disk.prototype.toJSON = function()
|
||||||
{
|
{
|
||||||
var s = JSON.stringify(this.aDiskData, function(key, value) {
|
var s, pba = 0, sector, sectorLast;
|
||||||
|
|
||||||
|
while ((sector = this.getSector(pba++))) {
|
||||||
|
this.deflateSector(sector);
|
||||||
|
}
|
||||||
|
|
||||||
|
s = JSON.stringify(this.aDiskData, function(key, value) {
|
||||||
/*
|
/*
|
||||||
* If BACKTRACK support is enabled, we have to filter out any 'file' properties that may
|
* If BACKTRACK support is enabled, we have to filter out any 'file' properties that may
|
||||||
* be attached to the sector objects, lest we risk blowing the stack due to circular references.
|
* be attached to the sector objects, lest we risk blowing the stack due to circular references.
|
||||||
|
|
@ -2764,7 +2784,12 @@ Disk.prototype.toJSON = function()
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Eliminate unnecessary default properties (eg, 'length' values of 512, 'pattern' values of 0).
|
||||||
|
*/
|
||||||
s = s.replace(/,"length":512/gm, "").replace(/,"pattern":0/gm, "");
|
s = s.replace(/,"length":512/gm, "").replace(/,"pattern":0/gm, "");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I don't really want to strip quotes from disk image property names, since I would have to put them
|
* I don't really want to strip quotes from disk image property names, since I would have to put them
|
||||||
* back again during mount() -- or whenever JSON.parse() is used instead of eval(). But I still remove
|
* back again during mount() -- or whenever JSON.parse() is used instead of eval(). But I still remove
|
||||||
|
|
@ -2773,12 +2798,14 @@ Disk.prototype.toJSON = function()
|
||||||
* all the property names that remain.
|
* all the property names that remain.
|
||||||
*/
|
*/
|
||||||
s = s.replace(/"(sector|length|data|pattern)":/gm, "$1:");
|
s = s.replace(/"(sector|length|data|pattern)":/gm, "$1:");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The next line will remove any other numeric or boolean properties that were added at runtime, although
|
* The next line will remove any other numeric or boolean properties that were added at runtime, although
|
||||||
* they may have completely different ("minified") names if the code has been compiled.
|
* they may have completely different ("minified") names if the code has been compiled.
|
||||||
*/
|
*/
|
||||||
s = s.replace(/,"[^"]*":([0-9]+|true|false)/gm, "");
|
s = s.replace(/,"[^"]*":([0-9]+|true|false)/gm, "");
|
||||||
s = s.replace(/(sector|length|data|pattern):/gm, "\"$1\":");
|
s = s.replace(/(sector|length|data|pattern):/gm, "\"$1\":");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Last but not least, insert line breaks after every object definition, to ease the pain on text editors.
|
* Last but not least, insert line breaks after every object definition, to ease the pain on text editors.
|
||||||
*/
|
*/
|
||||||
|
|
@ -2786,9 +2813,36 @@ Disk.prototype.toJSON = function()
|
||||||
return s;
|
return s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deflateSector(sector)
|
||||||
|
*
|
||||||
|
* This is just the first revision: it currently looks only at fully inflated sectors.
|
||||||
|
*
|
||||||
|
* @this {Disk}
|
||||||
|
* @param {Object} sector
|
||||||
|
*/
|
||||||
|
Disk.prototype.deflateSector = function(sector)
|
||||||
|
{
|
||||||
|
var adw = sector['data'];
|
||||||
|
var cdw = adw.length;
|
||||||
|
if ((cdw << 2) == sector['length']) {
|
||||||
|
var idw = cdw - 1;
|
||||||
|
var dwPattern = adw[idw], cDupes = 0;
|
||||||
|
while (idw--) {
|
||||||
|
if (adw[idw] !== dwPattern) break;
|
||||||
|
cDupes++;
|
||||||
|
}
|
||||||
|
if (cDupes++) {
|
||||||
|
adw.length = cdw - cDupes;
|
||||||
|
sector['pattern'] = dwPattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dumpSector(sector, pba, sDesc)
|
* dumpSector(sector, pba, sDesc)
|
||||||
*
|
*
|
||||||
|
* @this {Disk}
|
||||||
* @param {Object} sector (returned from a previous seek)
|
* @param {Object} sector (returned from a previous seek)
|
||||||
* @param {number} [pba]
|
* @param {number} [pba]
|
||||||
* @param {string} [sDesc]
|
* @param {string} [sDesc]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue