Preparing web server for update to v1.15.4

This commit is contained in:
Jeff Parsons 2014-10-10 16:36:50 -07:00 committed by jeffpar
commit 1d9a5ee0df
39 changed files with 7519 additions and 1387 deletions

View file

@ -180,7 +180,7 @@ var asNonDirectories = [
* should now be removed from the project).
*/
var asFilesNonListed = [
"LICENSE",
// "LICENSE",
"index.html",
"robots.txt",
"machine.xml",
@ -196,27 +196,28 @@ var asExtsNonServed = [
"sh"
];
var asDirsNonServed = [
"bin",
"debug",
"lib",
"logs",
"my_modules",
"node_modules",
"tests",
"tmp",
"users",
"iisnode" // Azure/IISNode-specific
];
var asFilesNonServed = [
"README.md",
"Gruntfile.js",
"server.js",
"npm-shrinkwrap.json",
"package.json",
"bin",
"debug",
"lib",
"logs",
"makefile",
"my_modules",
"node_modules",
"node.log",
"src", // use this for any non-GPL'ed source code
"tests",
"todo", // where I store my own personal "to-do" lists
"tmp",
"users",
"users.log",
"iisnode", // Azure/IISNode-specific
"IISNode.yml", // Azure/IISNode-specific
"web.config" // Azure/IISNode-specific
];
@ -264,7 +265,7 @@ function HTMLOut(sDir, sFile, fRebuild, req, done)
* Note that a production server should not need the GORT_REBUILD command, so we accept
* it only if fServerDebug is true.
*/
if (fServerDebug && net.hasParm(net.GORT_COMMAND, net.GORT_REBUILD, req)) {
if (net.hasParm(net.GORT_COMMAND, net.GORT_REBUILD, req)) {
req.query[net.GORT_COMMAND] = undefined;
this.fRebuild = true;
}
@ -436,8 +437,20 @@ HTMLOut.filter = function(req, res, next)
var sBaseExt = ((i = sBaseName.lastIndexOf('.')) > 0? sBaseName.substr(i+1) : "");
var sTrailingChar = req.path.slice(-1);
if (!fServerDebug) {
if (!fServerDebug && !net.hasParm(net.GORT_COMMAND, net.GORT_DEBUG, this.req)) {
var fNonServed = false;
if (asExtsNonServed.indexOf(sBaseExt) >= 0 || asFilesNonServed.indexOf(sBaseName) >= 0) {
fNonServed = true;
} else {
var asDirs = req.path.split('/');
for (i = 0; i < asDirs.length; i++) {
if (asDirsNonServed.indexOf(asDirs[i]) >= 0) {
fNonServed = true;
break;
}
}
}
if (fNonServed) {
/*
* Mimic the error code+message that express.static() displays for non-existent files/folders.
*/

View file

@ -46,11 +46,13 @@ if (typeof module !== 'undefined') {
*
* The ChipSet component has the following component-specific (parmsChipSet) properties:
*
* model: "5150", "5160", "5170", etc (should correspond to a ChipSet.MODEL_* constant)
* scaleTimers: true to divide timer cycle counts by the CPU's cycle multiplier (default is false)
* sound: true to enable (experimental) sound support (default); false to disable
* model: 5150, 5160 or 5170 (should correspond to a ChipSet.MODEL_* constant)
* sw1: 8-character binary string representing the SW1 DIP switches (SW1[1-8])
* sw2: 8-character binary string representing the SW2 DIP switches (SW2[1-8]) (MODEL_5150 only)
* sound: true to enable (experimental) sound support (default); false to disable
* scaleTimers: true to divide timer cycle counts by the CPU's cycle multiplier (default is false)
* fdrives: 0-4 floppy drives (default is 2 if no sw1 value provided)
* monitor: none|tv|color|mono (default is mono if no sw1 value provided)
* rtcDate: optional RTC date to be used on resets; use the ISO 8601 format; eg: "2011-10-10T14:48:00"
*
* The conventions used for the sw1 and sw2 strings are that the left-most character represents DIP switch [1],
@ -63,9 +65,9 @@ if (typeof module !== 'undefined') {
*
* SW1[1] (bit 0) "0xxxxxxx" (1): IPL, "1xxxxxxx" (0): No IPL
* SW1[2] (bit 1) reserved
* SW1[3,4] (bits 3-2) "xx11xxxx" (00): 16Kb, "xx10xxxx" (01): 32Kb, "xx01xxxx" (10): 48Kb, "xx00xxxx" (11): 64Kb
* SW1[5,6] (bits 5-4) "xxxx11xx" (00): none, "xxxx10xx" (01): CGA40, "xxxx01xx" (10): CGA80, "xxxx00xx" (11): MDA80
* SW1[7,8] (bits 7-6) "xxxxxx11" (00): 1 FD, "xxxxxx10" (01): 2 FD, "xxxxxx01" (10): 3 FD, "xxxxxx00" (11): 4 FD
* SW1[3,4] (bits 3-2) "xx11xxxx" (00): 16Kb, "xx01xxxx" (01): 32Kb, "xx10xxxx" (10): 48Kb, "xx00xxxx" (11): 64Kb
* SW1[5,6] (bits 5-4) "xxxx11xx" (00): none, "xxxx01xx" (01): tv, "xxxx10xx" (10): color, "xxxx00xx" (11): mono
* SW1[7,8] (bits 7-6) "xxxxxx11" (00): 1 FD, "xxxxxx01" (01): 2 FD, "xxxxxx10" (10): 3 FD, "xxxxxx00" (11): 4 FD
*
* Note: FD refers to floppy drive, and IPL refers to an "Initial Program Load" floppy drive.
*
@ -149,14 +151,44 @@ function ChipSet(parmsChipSet)
this.model = parmsChipSet['model'];
this.model = (this.model !== undefined? parseInt(this.model, 10) : ChipSet.MODEL_5150);
/*
* SW1 describes the number of floppy drives, the amount of base memory, the primary monitor type,
* and (on the MODEL_5160) whether or not a coprocessor is installed. If no SW1 settings are provided,
* we look for individual 'fdrives' and 'monitor' settings and build a default SW1 value.
*
* TODO: Get rid of reliance on SW1 for MODEL_5170 and later; omitting it now results in a BIOS warning:
*
* ' 162-System Options Not Set-(Run SETUP)'
*
* ' (RESUME = "F1" KEY)'
*
* The defaults below select max memory, monochrome monitor (EGA monitor for MODEL_5170), and two floppies.
* Don't get too excited about "max memory" either: on a MODEL_5150, the max was 64Kb, and on a MODEL_5160,
* the max was 256Kb. However, the RAM component is free to install as much base memory as it likes,
* overriding the SW1 memory setting.
*
* Given that the ROM BIOS is hard-coded to load boot sectors @0000:7C00, the minimum amount of system RAM
* required to boot is therefore 32Kb. Whether that's actually enough to run any or all versions of PC-DOS is
* a separate question. FYI, with only 16Kb, the ROM BIOS will still try to boot, and fail miserably.
*/
this.sw1Init = this.parseSwitches(parmsChipSet['sw1'], ChipSet.PPI_SW.MEMORY.X4 | ChipSet.PPI_SW.MONITOR.MDA);
this.sw1Init = 0;
var sw1 = parmsChipSet['sw1'];
if (sw1) {
this.sw1Init = this.parseSwitches(sw1, ChipSet.PPI_SW.MEMORY.X4 | ChipSet.PPI_SW.MONITOR.MONO);
} else {
var nDrives = parmsChipSet['fdrives'] || 2;
if (nDrives) {
this.sw1Init |= ChipSet.PPI_SW.FDRIVE.IPL;
nDrives--;
this.sw1Init |= ((nDrives & 0x3) << ChipSet.PPI_SW.FDRIVE.SHIFT);
}
var sMonitor = parmsChipSet['monitor'] || (this.model < ChipSet.MODEL_5170? "mono" : "ega");
if (sMonitor && ChipSet.aMonitorSwitches[sMonitor] !== undefined) {
this.sw1Init |= (ChipSet.aMonitorSwitches[sMonitor] << ChipSet.PPI_SW.MONITOR.SHIFT);
}
}
/*
* SW2 describes the number of 32Kb blocks of I/O expansion RAM that's present in the system. The MODEL_5150 ROM BIOS
* only checked/supported the first four switches, so the maximum amount of additional RAM specifiable was 15 * 32Kb,
@ -168,11 +200,10 @@ function ChipSet(parmsChipSet)
* supported on the motherboard) is the "size" parameter of the RAM component. NOTE: If you use the "size" parameter,
* you will not be able to dynamically alter the memory configuration; the RAM component will ignore any changes to SW1.
*/
this.sw2Init = this.parseSwitches(parmsChipSet['sw2'], 0);
this.sw2Init = this.parseSwitches(parmsChipSet['sw2'] || "11110000", 0);
/*
* The SW1 memory switches specify a multiplier; the number of Kb that they multiply is model-dependent:
* 16Kb on a MODEL_5150, 64Kb otherwise.
* The SW1 memory setting is actually just a multiplier: it's multiplied by 16Kb on a MODEL_5150, 64Kb otherwise.
*/
this.kbSW = (this.model == ChipSet.MODEL_5150? 16 : 64);
@ -180,6 +211,7 @@ function ChipSet(parmsChipSet)
if (this.model >= ChipSet.MODEL_5170) {
this.cDMACs = this.cPICs = 2;
}
this.fScaleTimers = parmsChipSet['scaleTimers'] || false;
this.sRTCDate = parmsChipSet['rtcDate'];
@ -232,12 +264,24 @@ ChipSet.MODEL_5170 = 5170;
*/
ChipSet.MONITOR = {};
ChipSet.MONITOR.NONE = 0;
ChipSet.MONITOR.TV = 1; // TV (lower resolution; not currently supported)
ChipSet.MONITOR.TV = 1; // Composite monitor (lower resolution; no support)
ChipSet.MONITOR.COLOR = 2; // Color Display (5153)
ChipSet.MONITOR.MONO = 3; // Monochrome Display (5151)
ChipSet.MONITOR.EGACOLOR = 4; // Enhanced Color Display (5154) in High-Res Mode
ChipSet.MONITOR.EGAEMULATION = 5; // Enhanced Color Display (5154) in Emulation Mode
/*
* Lookup table for converting ChipSet "monitor" parameter into the corresponding SW1 switch bits
* (they must be shifted left by ChipSet.PPI_SW.MONITOR.SHIFT before OR'ing them into sw1/sw1Init).
*/
ChipSet.aMonitorSwitches = {
"none": 0x0,
"tv": 0x1,
"color":0x2,
"mono": 0x3,
"ega": 0x0
};
/*
* 8237A DMA Controller (DMAC) I/O ports
*
@ -385,6 +429,9 @@ ChipSet.PIC_HI.ICW4_MASTER = 0x04;
ChipSet.PIC_HI.ICW4_BUFFERED = 0x08;
ChipSet.PIC_HI.ICW4_FULLY_NESTED= 0x10;
/*
* Definitions for Operation Command Words (OCW1, OCW2 and OCW3)
*/
ChipSet.PIC_HI.OCW1_IMR = 0xFF;
ChipSet.PIC_LO.OCW2 = 0x00; // bit 3 (PIC_LO.OCW3) and bit 4 (ChipSet.PIC_LO.ICW1) are clear in an OCW2 command byte
@ -536,9 +583,9 @@ ChipSet.PPI_SW.MEMORY.X4 = 0x0C;
ChipSet.PPI_SW.MEMORY.MASK = 0x0C;
ChipSet.PPI_SW.MEMORY.SHIFT = 2;
ChipSet.PPI_SW.MONITOR = {};
ChipSet.PPI_SW.MONITOR.CGA40 = 0x10;
ChipSet.PPI_SW.MONITOR.CGA80 = 0x20;
ChipSet.PPI_SW.MONITOR.MDA = 0x30;
ChipSet.PPI_SW.MONITOR.TV = 0x10;
ChipSet.PPI_SW.MONITOR.COLOR = 0x20;
ChipSet.PPI_SW.MONITOR.MONO = 0x30;
ChipSet.PPI_SW.MONITOR.MASK = 0x30;
ChipSet.PPI_SW.MONITOR.SHIFT = 4;
ChipSet.PPI_SW.FDRIVE.ONE = 0x00; // 1 floppy drive attached (or 0 drives if PPI_SW.FDRIVE_IPL is not set -- MODEL_5150 only)
@ -574,84 +621,85 @@ ChipSet.PPI_SW.FDRIVE.SHIFT = 6;
* http://halicery.com/8042/8042_INTERN_TXT.htm
* http://www.os2museum.com/wp/?p=589 ("IBM PC/AT 8042 Keyboard Controller Commands")
*/
ChipSet.KBC = {};
ChipSet.KBC.DATA = { // this.b8042OutBuff (PPI_A on previous models, still referred to as "PORT A" by the MODEL_5170 BIOS)
PORT: 0x60,
SELF_TEST: { // result of ChipSet.KBC.CMD.SELF_TEST command (0xAA)
OK: 0x55
ChipSet.KBC = {
DATA: { // this.b8042OutBuff (PPI_A on previous models, still referred to as "PORT A" by the MODEL_5170 BIOS)
PORT: 0x60,
CMD: { // this.b8042CmdData (KBD_DATA.CMD "data bytes" written to port 0x60, after writing a KBD_CMD byte to port 0x64)
PC_COMPAT: 0x40, // generate IBM PC-compatible scan codes
PC_MODE: 0x20,
NO_CLOCK: 0x10, // disable keyboard by driving "clock" line low
NO_INHIBIT: 0x08, // disable inhibit function
SYS_FLAG: 0x04, // this value is propagated to ChipSet.KBC.STATUS.SYS_FLAG
INT_ENABLE: 0x01 // generate an interrupt when the controller places data in the output buffer
},
SELF_TEST: { // result of ChipSet.KBC.CMD.SELF_TEST command (0xAA)
OK: 0x55
},
INTF_TEST: { // result of ChipSet.KBC.CMD.INTF_TEST command (0xAB)
OK: 0x00, // no error
CLOCK_LO: 0x01, // keyboard clock line stuck low
CLOCK_HI: 0x02, // keyboard clock line stuck high
DATA_LO: 0x03, // keyboard data line stuck low
DATA_HI: 0x04 // keyboard data line stuck high
}
},
INTF_TEST: { // result of ChipSet.KBC.CMD.INTF_TEST command (0xAB)
OK: 0x00, // no error
CLOCK_LO: 0x01, // keyboard clock line stuck low
CLOCK_HI: 0x02, // keyboard clock line stuck high
DATA_LO: 0x03, // keyboard data line stuck low
DATA_HI: 0x04 // keyboard data line stuck high
INPORT: { // this.b8042InPort
UNDEFINED: 0x0F, // undefined
ENABLE_256KB: 0x10, // enable 2nd 256Kb of system board RAM
MFG_OFF: 0x20, // manufacturing jumper not installed
MONO: 0x40, // monochrome monitor is primary display
KBD_ON: 0x80 // keyboard not inhibited
},
OUTPORT: { // this.b8042OutPort
NO_RESET: 0x01, // set by default
A20_ON: 0x02, // set by default
OUTBUFF_FULL: 0x10, // output buffer full
INBUFF_EMPTY: 0x20, // input buffer empty
KBD_CLOCK: 0x40, // keyboard clock (output)
KBD_DATA: 0x80 // keyboard data (output)
},
TESTPORT: { // generated "on the fly"
KBD_CLOCK: 0x01, // keyboard clock (input)
KBD_DATA: 0x02 // keyboard data (input)
},
RWREG: { // this.bPPIB (since CLK_TIMER2 and SPK_TIMER2 are in both PPI_B and KBD_RWREG)
PORT: 0x61,
CLK_TIMER2: 0x01, // set to enable clock to TIMER2
SPK_TIMER2: 0x02, // set to connect output of TIMER2 to speaker
DISABLE_CHK: 0x0C, // set these bits to disable I/O and RAM parity checks, clear them to enable checks
REFRESH_BIT: 0x10, // indicates memory refresh
IO_CHK: 0x40, // indicates I/O check
PARITY_CHK: 0x80, // indicates RAM parity check
PARITY_ERR: 0xC0
},
CMD: { // this.b8042InBuff (on write to port 0x64, interpret this as a CMD)
PORT: 0x64,
READ_CMD: 0x20,
WRITE_CMD: 0x60, // followed by a command byte written to KBD_DATA.PORT (see KBD_DATA.CMD)
SELF_TEST: 0xAA, // self-test (KBD_DATA.SELF_TEST_OK is placed in the output buffer if no errors)
INTF_TEST: 0xAB, // interface test
DIAG_DUMP: 0xAC, // diagnostic dump
DISABLE_KBD: 0xAD, // disable keyboard
ENABLE_KBD: 0xAE, // enable keyboard
READ_INPORT: 0xC0, // read input port and place data in output buffer (use only if output buffer empty)
READ_OUTPORT: 0xD0, // read output port and place data in output buffer (use only if output buffer empty)
WRITE_OUTPORT: 0xD1, // next byte written to KBD_DATA.PORT (port 0x60) is placed in the output port (see KBD_DATA.OUTPUT)
READ_TEST: 0xE0,
PULSE_OUTPORT: 0xF0 // this is the 1st of 16 commands (0xF0-0xFF) that pulse bits 0-3 of the output port
},
STATUS: { // this.b8042Status (on read from port 0x64)
PORT: 0x64,
OUTBUFF_FULL: 0x01,
INBUFF_FULL: 0x02, // set if the controller has received but not yet read data written to the input buffer (not normally set)
SYS_FLAG: 0x04,
CMD_FLAG: 0x08, // set on write to KBD_CMD (port 0x64), clear on write to KBD_DATA (port 0x60)
NO_INHIBIT: 0x10,
XMT_TIMEOUT: 0x20,
RCV_TIMEOUT: 0x40,
PARITY_ERR: 0x80, // last byte of data received had EVEN parity (ODD parity is normally expected)
OUTBUFF_DELAY: 0x100
}
};
ChipSet.KBC.DATA.CMD = { // this.b8042CmdData (KBD_DATA.CMD "data bytes" written to port 0x60, after writing a KBD_CMD byte to port 0x64)
PC_COMPAT: 0x40, // generate IBM PC-compatible scan codes
PC_MODE: 0x20,
NO_CLOCK: 0x10, // disable keyboard by driving "clock" line low
NO_INHIBIT: 0x08, // disable inhibit function
SYS_FLAG: 0x04, // this value is propagated to ChipSet.KBC.STATUS.SYS_FLAG
INT_ENABLE: 0x01 // generate an interrupt when the controller places data in the output buffer
};
ChipSet.KBC.INPORT = { // this.b8042InPort
UNDEFINED: 0x0F, // undefined
ENABLE_256KB: 0x10, // enable 2nd 256Kb of system board RAM
MFG_OFF: 0x20, // manufacturing jumper not installed
MONO: 0x40, // monochrome monitor is primary display
KBD_ON: 0x80 // keyboard not inhibited
};
ChipSet.KBC.OUTPORT = { // this.b8042OutPort
NO_RESET: 0x01, // set by default
A20_ON: 0x02, // set by default
OUTBUFF_FULL: 0x10, // output buffer full
INBUFF_EMPTY: 0x20, // input buffer empty
KBD_CLOCK: 0x40, // keyboard clock (output)
KBD_DATA: 0x80 // keyboard data (output)
};
ChipSet.KBC.TESTPORT = { // generated "on the fly"
KBD_CLOCK: 0x01, // keyboard clock (input)
KBD_DATA: 0x02 // keyboard data (input)
};
ChipSet.KBC.RWREG = { // this.bPPIB (since CLK_TIMER2 and SPK_TIMER2 are in both PPI_B and KBD_RWREG)
PORT: 0x61,
CLK_TIMER2: 0x01, // set to enable clock to TIMER2
SPK_TIMER2: 0x02, // set to connect output of TIMER2 to speaker
DISABLE_CHK: 0x0C, // set these bits to disable I/O and RAM parity checks, clear them to enable checks
REFRESH_BIT: 0x10, // indicates memory refresh
IO_CHK: 0x40, // indicates I/O check
PARITY_CHK: 0x80, // indicates RAM parity check
PARITY_ERR: 0xC0
};
ChipSet.KBC.CMD = { // this.b8042InBuff (on write to port 0x64, interpret this as a CMD)
PORT: 0x64,
READ_CMD: 0x20,
WRITE_CMD: 0x60, // followed by a command byte written to KBD_DATA.PORT (see KBD_DATA.CMD)
SELF_TEST: 0xAA, // self-test (KBD_DATA.SELF_TEST_OK is placed in the output buffer if no errors)
INTF_TEST: 0xAB, // interface test
DIAG_DUMP: 0xAC, // diagnostic dump
DISABLE_KBD: 0xAD, // disable keyboard
ENABLE_KBD: 0xAE, // enable keyboard
READ_INPORT: 0xC0, // read input port and place data in output buffer (use only if output buffer empty)
READ_OUTPORT: 0xD0, // read output port and place data in output buffer (use only if output buffer empty)
WRITE_OUTPORT: 0xD1, // next byte written to KBD_DATA.PORT (port 0x60) is placed in the output port (see KBD_DATA.OUTPUT)
READ_TEST: 0xE0,
PULSE_OUTPORT: 0xF0 // this is the 1st of 16 commands (0xF0-0xFF) that pulse bits 0-3 of the output port
};
ChipSet.KBC.STATUS = { // this.b8042Status (on read from port 0x64)
PORT: 0x64,
OUTBUFF_FULL: 0x01,
INBUFF_FULL: 0x02, // set if the controller has received but not yet read data written to the input buffer (not normally set)
SYS_FLAG: 0x04,
CMD_FLAG: 0x08, // set on write to KBD_CMD (port 0x64), clear on write to KBD_DATA (port 0x60)
NO_INHIBIT: 0x10,
XMT_TIMEOUT: 0x20,
RCV_TIMEOUT: 0x40,
PARITY_ERR: 0x80, // last byte of data received had EVEN parity (ODD parity is normally expected)
OUTBUFF_DELAY: 0x100
};
/*
* MC146818A RTC/CMOS Ports (MODEL_5170)
@ -660,104 +708,104 @@ ChipSet.KBC.STATUS = { // this.b8042Status (on read from port 0x64)
*
* The ADDR port also controls NMI: write an address with bit 7 clear to enable NMI or set to disable NMI.
*/
ChipSet.CMOS = {};
ChipSet.CMOS.ADDR = {}; // this.bCMOSAddr
ChipSet.CMOS.ADDR.PORT = 0x70;
ChipSet.CMOS.ADDR.RTC_SEC = 0x00;
ChipSet.CMOS.ADDR.RTC_SEC_ALRM = 0x01;
ChipSet.CMOS.ADDR.RTC_MIN = 0x02;
ChipSet.CMOS.ADDR.RTC_MIN_ALRM = 0x03;
ChipSet.CMOS.ADDR.RTC_HOUR = 0x04;
ChipSet.CMOS.ADDR.RTC_HOUR_ALRM = 0x05;
ChipSet.CMOS.ADDR.RTC_WEEK_DAY = 0x06;
ChipSet.CMOS.ADDR.RTC_MONTH_DAY = 0x07;
ChipSet.CMOS.ADDR.RTC_MONTH = 0x08;
ChipSet.CMOS.ADDR.RTC_YEAR = 0x09;
ChipSet.CMOS.ADDR.RTC_STATUSA = 0x0A;
ChipSet.CMOS.ADDR.RTC_STATUSB = 0x0B;
ChipSet.CMOS.ADDR.RTC_STATUSC = 0x0C;
ChipSet.CMOS.ADDR.RTC_STATUSD = 0x0D;
ChipSet.CMOS.ADDR.DIAG = 0x0E;
ChipSet.CMOS.ADDR.SHUTDOWN = 0x0F;
ChipSet.CMOS.ADDR.FDRIVE = 0x10;
ChipSet.CMOS.ADDR.HDRIVE = 0x12;
ChipSet.CMOS.ADDR.EQUIP = 0x14;
ChipSet.CMOS.ADDR.BASEMEM_LO = 0x15;
ChipSet.CMOS.ADDR.BASEMEM_HI = 0x16; // the BASEMEM values indicate the total Kb of base memory, up to 0x280 (640Kb)
ChipSet.CMOS.ADDR.EXTMEM_LO = 0x17;
ChipSet.CMOS.ADDR.EXTMEM_HI = 0x18; // the EXTMEM values indicate the total Kb of extended memory, up to 0x3C00 (15Mb)
ChipSet.CMOS.ADDR.CHKSUM_HI = 0x2E;
ChipSet.CMOS.ADDR.CHKSUM_LO = 0x2F; // CMOS bytes included in the checksum calculation: 0x10-0x2D
ChipSet.CMOS.ADDR.EXTMEM2_LO = 0x30;
ChipSet.CMOS.ADDR.EXTMEM2_HI = 0x31;
ChipSet.CMOS.ADDR.CENTURY_DATE = 0x32; // BCD value for the current century (eg, 0x19 for 20th century, 0x20 for 21st century)
ChipSet.CMOS.ADDR.BOOT_INFO = 0x33; // 0x80 if 128Kb expansion memory installed, 0x40 if Setup Utility wants an initial setup message
ChipSet.CMOS.ADDR.MASK = 0x3F;
ChipSet.CMOS.ADDR.TOTAL = 0x40;
ChipSet.CMOS.ADDR.NMI_DISABLE = 0x80;
ChipSet.CMOS.DATA = {}; // this.abCMOSData
ChipSet.CMOS.DATA.PORT = 0x71;
ChipSet.CMOS.STATUSA = {}; // abCMOSData[ChipSet.CMOS.ADDR.RTC_STATUSA]
ChipSet.CMOS.STATUSA.UIP = 0x80; // bit 7: 1 indicates Update-In-Progress, 0 indicates date/time ready to read
ChipSet.CMOS.STATUSA.DV = 0x70; // bits 6-4 (DV2-DV0) are programmed to 010 to select a 32.768Khz time base
ChipSet.CMOS.STATUSA.RS = 0x0F; // bits 3-0 (RS3-RS0) are programmed to 0110 to select a 976.562us interrupt rate
ChipSet.CMOS.STATUSB = {}; // abCMOSData[ChipSet.CMOS.ADDR.RTC_STATUSB]
ChipSet.CMOS.STATUSB.SET = 0x80; // bit 7: 1 to set any/all of the 14 time-bytes
ChipSet.CMOS.STATUSB.PIE = 0x40; // bit 6: 1 for Periodic Interrupt Enable
ChipSet.CMOS.STATUSB.AIE = 0x20; // bit 5: 1 for Alarm Interrupt Enable
ChipSet.CMOS.STATUSB.UIE = 0x10; // bit 4: 1 for Update-Ended Interrupt Enable
ChipSet.CMOS.STATUSB.SQWE = 0x08; // bit 3: 1 for Square Wave Enabled (as set by the STATUSA rate selection bits)
ChipSet.CMOS.STATUSB.BINARY = 0x04; // bit 2: 1 for binary Date Mode, 0 for BCD Date Mode
ChipSet.CMOS.STATUSB.HOUR24 = 0x02; // bit 1: 1 for 24-hour mode, 0 for 12-hour mode
ChipSet.CMOS.STATUSB.DST = 0x01; // bit 0: 1 for Daylight Savings Time enabled
ChipSet.CMOS.STATUSC = {}; // abCMOSData[ChipSet.CMOS.ADDR.RTC_STATUSC] TODO: Does reading this register clear these interrupt conditions? (see F000:01C6 in the MODEL_5170 BIOS)
ChipSet.CMOS.STATUSC.IRQF = 0x80; // bit 7
ChipSet.CMOS.STATUSC.PF = 0x40; // bit 6: 1 indicates Periodic Interrupt
ChipSet.CMOS.STATUSC.AF = 0x20; // bit 5: 1 indicates Alarm Interrupt
ChipSet.CMOS.STATUSC.UF = 0x10; // bit 4: 1 indicates Update-Ended Interrupt
ChipSet.CMOS.STATUSC.RESERVED = 0x0F;
ChipSet.CMOS.STATUSD = {}; // abCMOSData[ChipSet.CMOS.ADDR.RTC_STATUSD]
ChipSet.CMOS.STATUSD.VRB = 0x80; // bit 7: 1 indicates Valid RAM Bit (0 implies power was and/or is lost)
ChipSet.CMOS.STATUSD.RESERVED = 0x7F;
ChipSet.CMOS.DIAG = {}; // abCMOSData[ChipSet.CMOS.ADDR.DIAG]
ChipSet.CMOS.DIAG.RTCFAIL = 0x80; // bit 7: 1 indicates RTC lost power
ChipSet.CMOS.DIAG.CHKSUMFAIL = 0x40; // bit 6: 1 indicates bad CMOS checksum
ChipSet.CMOS.DIAG.CONFIGFAIL = 0x20; // bit 5: 1 indicates bad CMOS configuration info
ChipSet.CMOS.DIAG.MEMSIZEFAIL = 0x10; // bit 4: 1 indicates memory size miscompare
ChipSet.CMOS.DIAG.HDRIVEFAIL = 0x08; // bit 3: 1 indicates hard drive controller or drive init failure
ChipSet.CMOS.DIAG.TIMEFAIL = 0x04; // bit 2: 1 indicates time failure
ChipSet.CMOS.DIAG.RESERVED = 0x03;
ChipSet.FDRIVE = { // abCMOSData[ChipSet.CMOS.ADDR.FDRIVE]
D0_MASK: 0xF0, // Drive 0 type in high nibble
D1_MASK: 0x0F, // Drive 1 type in lower nibble
NONE: 0, // no drive
DSDD: 1, // double-sided double-density drive (48 TPI, 40 tracks, 360Kb max)
DSHD: 2 // double-sided high-density drive (96 TPI, 80 tracks, 1.2Mb max)
};
ChipSet.CMOS.HDRIVE = { // abCMOSData[ChipSet.CMOS.ADDR.HDRIVE]
D0_MASK: 0xF0, // Drive 0 type in high nibble
D1_MASK: 0x0F // Drive 1 type in lower nibble
ChipSet.CMOS = {
ADDR: { // this.bCMOSAddr
PORT: 0x70,
RTC_SEC: 0x00,
RTC_SEC_ALRM: 0x01,
RTC_MIN: 0x02,
RTC_MIN_ALRM: 0x03,
RTC_HOUR: 0x04,
RTC_HOUR_ALRM: 0x05,
RTC_WEEK_DAY: 0x06,
RTC_MONTH_DAY: 0x07,
RTC_MONTH: 0x08,
RTC_YEAR: 0x09,
RTC_STATUSA: 0x0A,
RTC_STATUSB: 0x0B,
RTC_STATUSC: 0x0C,
RTC_STATUSD: 0x0D,
DIAG: 0x0E,
SHUTDOWN: 0x0F,
FDRIVE: 0x10,
HDRIVE: 0x12,
EQUIP: 0x14,
BASEMEM_LO: 0x15,
BASEMEM_HI: 0x16, // the BASEMEM values indicate the total Kb of base memory, up to 0x280 (640Kb)
EXTMEM_LO: 0x17,
EXTMEM_HI: 0x18, // the EXTMEM values indicate the total Kb of extended memory, up to 0x3C00 (15Mb)
CHKSUM_HI: 0x2E,
CHKSUM_LO: 0x2F, // CMOS bytes included in the checksum calculation: 0x10-0x2D
EXTMEM2_LO: 0x30,
EXTMEM2_HI: 0x31,
CENTURY_DATE: 0x32, // BCD value for the current century (eg, 0x19 for 20th century, 0x20 for 21st century)
BOOT_INFO: 0x33, // 0x80 if 128Kb expansion memory installed, 0x40 if Setup Utility wants an initial setup message
MASK: 0x3F,
TOTAL: 0x40,
NMI_DISABLE: 0x80
},
DATA: { // this.abCMOSData
PORT: 0x71
},
STATUSA: { // abCMOSData[ChipSet.CMOS.ADDR.RTC_STATUSA]
UIP: 0x80, // bit 7: 1 indicates Update-In-Progress, 0 indicates date/time ready to read
DV: 0x70, // bits 6-4 (DV2-DV0) are programmed to 010 to select a 32.768Khz time base
RS: 0x0F // bits 3-0 (RS3-RS0) are programmed to 0110 to select a 976.562us interrupt rate
},
STATUSB: { // abCMOSData[ChipSet.CMOS.ADDR.RTC_STATUSB]
SET: 0x80, // bit 7: 1 to set any/all of the 14 time-bytes
PIE: 0x40, // bit 6: 1 for Periodic Interrupt Enable
AIE: 0x20, // bit 5: 1 for Alarm Interrupt Enable
UIE: 0x10, // bit 4: 1 for Update-Ended Interrupt Enable
SQWE: 0x08, // bit 3: 1 for Square Wave Enabled (as set by the STATUSA rate selection bits)
BINARY: 0x04, // bit 2: 1 for binary Date Mode, 0 for BCD Date Mode
HOUR24: 0x02, // bit 1: 1 for 24-hour mode, 0 for 12-hour mode
DST: 0x01 // bit 0: 1 for Daylight Savings Time enabled
},
STATUSC: { // abCMOSData[ChipSet.CMOS.ADDR.RTC_STATUSC] TODO: Does reading this register clear these interrupt conditions? (see F000:01C6 in the MODEL_5170 BIOS)
IRQF: 0x80, // bit 7
PF: 0x40, // bit 6: 1 indicates Periodic Interrupt
AF: 0x20, // bit 5: 1 indicates Alarm Interrupt
UF: 0x10, // bit 4: 1 indicates Update-Ended Interrupt
RESERVED: 0x0F
},
STATUSD: { // abCMOSData[ChipSet.CMOS.ADDR.RTC_STATUSD]
VRB: 0x80, // bit 7: 1 indicates Valid RAM Bit (0 implies power was and/or is lost)
RESERVED: 0x7F
},
DIAG: { // abCMOSData[ChipSet.CMOS.ADDR.DIAG]
RTCFAIL: 0x80, // bit 7: 1 indicates RTC lost power
CHKSUMFAIL: 0x40, // bit 6: 1 indicates bad CMOS checksum
CONFIGFAIL: 0x20, // bit 5: 1 indicates bad CMOS configuration info
MEMSIZEFAIL: 0x10, // bit 4: 1 indicates memory size miscompare
HDRIVEFAIL: 0x08, // bit 3: 1 indicates hard drive controller or drive init failure
TIMEFAIL: 0x04, // bit 2: 1 indicates time failure
RESERVED: 0x03
},
FDRIVE: { // abCMOSData[ChipSet.CMOS.ADDR.FDRIVE]
D0_MASK: 0xF0, // Drive 0 type in high nibble
D1_MASK: 0x0F, // Drive 1 type in lower nibble
NONE: 0, // no drive
DSDD: 1, // double-sided double-density drive (48 TPI, 40 tracks, 360Kb max)
DSHD: 2 // double-sided high-density drive (96 TPI, 80 tracks, 1.2Mb max)
},
/*
* HDRIVE types are defined by table in the HDC component, which uses setCMOSDriveType() to update the CMOS
*/
HDRIVE: { // abCMOSData[ChipSet.CMOS.ADDR.HDRIVE]
D0_MASK: 0xF0, // Drive 0 type in high nibble
D1_MASK: 0x0F // Drive 1 type in lower nibble
},
/*
* The CMOS equipment flags use the same format as the older PPI equipment flags
*/
EQUIP: { // abCMOSData[ChipSet.CMOS.ADDR.EQUIP]
MONITOR: ChipSet.PPI_SW.MONITOR, // PPI_SW.MONITOR.MASK == 0x30
COPROC: ChipSet.PPI_SW.COPROC, // PPI_SW.COPROC == 0x02
FDRIVE: ChipSet.PPI_SW.FDRIVE // PPI_SW.FDRIVE.IPL == 0x01 and PPI_SW.FDRIVE.MASK = 0xC0
}
};
/*
* The CMOS equipment flags use the same format as the older PPI equipment flags
*/
ChipSet.CMOS.EQUIP = {}; // abCMOSData[ChipSet.CMOS.ADDR.EQUIP]
ChipSet.CMOS.EQUIP.MONITOR = ChipSet.PPI_SW.MONITOR; // PPI_SW.MONITOR.MASK == 0x30
ChipSet.CMOS.EQUIP.COPROC = ChipSet.PPI_SW.COPROC; // PPI_SW.COPROC == 0x02
ChipSet.CMOS.EQUIP.FDRIVE = ChipSet.PPI_SW.FDRIVE; // PPI_SW.FDRIVE.IPL == 0x01 and PPI_SW.FDRIVE.MASK = 0xC0
/*
* Manufacturing Test Ports (MODEL_5170)
*
@ -772,29 +820,33 @@ ChipSet.CMOS.EQUIP.FDRIVE = ChipSet.PPI_SW.FDRIVE; // PPI_SW.FDRIVE
* with manufacturing test ("MFG_TST") code which, if enabled, writes to other DMA page registers,
* perhaps treating them as scratch registers.
*/
ChipSet.MFG = {}; // this.bMFGData
ChipSet.MFG.PORT = 0x80;
ChipSet.MFG = { // this.bMFGData
PORT: 0x80
};
/*
* NMI Mask Register (MODEL_5150 and MODEL_5160 only)
*/
ChipSet.NMI = {}; // this.bNMI
ChipSet.NMI.PORT = 0xA0;
ChipSet.NMI.ENABLE = 0x80;
ChipSet.NMI.DISABLE = 0x00;
ChipSet.NMI = { // this.bNMI
PORT: 0xA0,
ENABLE: 0x80,
DISABLE: 0x00
};
/*
* Coprocessor Control Registers (MODEL_5170)
*/
ChipSet.COPROC = {}; // TODO: Define a variable for this
ChipSet.COPROC.PORT_CLEAR = 0xF0; // clear the coprocessor's "busy" state
ChipSet.COPROC.PORT_RESET = 0xF1; // reset the coprocessor
ChipSet.COPROC = { // TODO: Define a variable for this
PORT_CLEAR: 0xF0, // clear the coprocessor's "busy" state
PORT_RESET: 0xF1 // reset the coprocessor
};
/*
* ChipSet-related BIOS interrupts, functions, and other parameters
*/
ChipSet.BIOS = {};
ChipSet.BIOS.RTC = 0x1A;
ChipSet.BIOS = {
RTC_INT: 0x1A
};
/**
* @this {ChipSet}
@ -883,7 +935,7 @@ ChipSet.prototype.initBus = function(cmp, bus, cpu, dbg)
chipset.dumpCMOS();
});
}
cpu.addInterruptNotify(ChipSet.BIOS.RTC, this, this.intBIOSRTC);
cpu.addInterruptNotify(ChipSet.BIOS.RTC_INT, this, this.intBIOSRTC);
}
};
@ -897,8 +949,12 @@ ChipSet.prototype.initBus = function(cmp, bus, cpu, dbg)
*/
ChipSet.prototype.powerUp = function(data, fRepower)
{
if (!fRepower && data) {
if (!this.restore(data)) return false;
if (!fRepower) {
if (!data) {
this.reset();
} else {
if (!this.restore(data)) return false;
}
}
return true;
};
@ -923,8 +979,8 @@ ChipSet.prototype.powerDown = function(fSave)
ChipSet.prototype.reset = function()
{
/*
* We propagate the sw?Init values to sw? at reset; the user only gets
* to tweak sw?Init, which we don't want to take effect until the next reset.
* We propagate the sw1Init/sw2Init values to sw1/sw2 at reset; the user is only
* allowed to tweak sw1Init/sw2Init, which doesn't take effect until the next reset.
*/
var i;
this.sw1 = this.sw1Init;
@ -963,7 +1019,7 @@ ChipSet.prototype.reset = function()
this.bNMI = ChipSet.NMI.DISABLE;// tracks writes to the NMI Mask Register
/*
* State introduced by the MODEL_5170
* ChipSet state introduced by the MODEL_5170
*/
if (this.model >= ChipSet.MODEL_5170) {
/*
@ -988,17 +1044,25 @@ ChipSet.prototype.reset = function()
if (this.getSWVideoMonitor() == ChipSet.MONITOR.MONO) this.b8042InPort |= ChipSet.KBC.INPORT.MONO;
this.b8042OutPort = ChipSet.KBC.OUTPORT.NO_RESET | ChipSet.KBC.OUTPORT.A20_ON;
this.bCMOSAddr = 0; // NMI is enabled, since the ChipSet.CMOS.ADDR.NMI_DISABLE bit is not set in bCMOSAddr
this.abCMOSData = new Array(ChipSet.CMOS.ADDR.TOTAL);
this.initRTCDate(this.sRTCDate);
this.initCMOSData();
/*
* TODO: Data below here has not yet been added to the save/restore state; when we're done adding new data,
* make sure it all gets added.
*/
this.bMFGData = 0;
this.abDMAPageSpare = new Array(7);
this.bCMOSAddr = 0; // NMI is enabled, since the ChipSet.CMOS.ADDR.NMI_DISABLE bit is not set in bCMOSAddr
/*
* Now that we call reset() from the ChipSet constructor, enabling other components can to update
* their CMOS information, we must not allow a reset() from powerUp() to toss that information, so
* we allocate abCMOSData only if it hasn't already been allocated.
*/
if (!this.abCMOSData) this.abCMOSData = new Array(ChipSet.CMOS.ADDR.TOTAL);
this.initRTCDate(this.sRTCDate);
/*
* initCMOSData() will initialize a variety of "legacy" CMOS bytes, but it will NOT overwrite any memory
* size or hard drive type information that might have been set, via addCMOSMemory() or setCMOSDriveType().
*/
this.initCMOSData();
}
if (DEBUGGER && MAXDEBUG) {
@ -1042,6 +1106,25 @@ ChipSet.prototype.initRTCDate = function(sDate)
*/
var date = sDate? new Date(sDate) : new Date();
/*
* Example of a valid Date string:
*
* 2014-10-01T08:00:00-0700
*
* Example of an INVALID Date string:
*
* 2014-10-01T08:00:00PST
*
* In the second example, the Date object is invalid, but it wasn't obvious (to me) how to detect that.
* So here's a test from StackOverflow (http://stackoverflow.com/questions/1353684/detecting-an-invalid-date-date-instance-in-javascript).
*/
if (Object.prototype.toString.call(date) !== "[object Date]" || isNaN(date.getTime())) {
date = new Date();
this.println("CMOS date invalid (" + sDate + "), using " + date);
} else if (sDate) {
this.println("CMOS date: " + date);
}
this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC] = date.getSeconds();
this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC_ALRM] = 0;
this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN] = date.getMinutes();
@ -1171,7 +1254,7 @@ ChipSet.prototype.updateRTCDate = function()
var nCyclesUpdate = this.cpu.getCycles(this.fScaleTimers);
/*
* If nCyclesCMOSLastUpdate hasn't been properly set yet (ie, if this is our first updateRTCDate() call),
* If nCyclesCMOSLastUpdate hasn't been set yet (ie, if this is our first updateRTCDate() call),
* then do nothing except initialize nCyclesCMOSLastUpdate.
*/
if (this.nCyclesCMOSLastUpdate >= 0) {
@ -1224,36 +1307,20 @@ ChipSet.prototype.updateRTCDate = function()
ChipSet.prototype.initCMOSData = function()
{
/*
* Make sure all the "checksummed" CMOS bytes get initialized (not just the handful we set below) to ensure
* Make sure all the "checksummed" CMOS bytes are initialized (not just the handful we set below) to ensure
* that the checksum will be valid.
*/
for (var iCMOS = ChipSet.CMOS.ADDR.DIAG; iCMOS < ChipSet.CMOS.ADDR.CHKSUM_HI; iCMOS++) {
this.abCMOSData[iCMOS] = 0;
if (this.abCMOSData[iCMOS] === undefined) this.abCMOSData[iCMOS] = 0;
}
/*
* We propagate all compatible "legacy" SW1 bits to the CMOS_EQUIP byte using the old SW masks, but any further
* access to CMOS_ADDR.EQUIP should use the new CMOS_EQUIP flags (eg, CMOS_EQUIP.COPROC, CMOS_EQUIP.MONITOR.CGA80, etc).
*
* TODO: Consider more generic ChipSet parameters to specify equipment settings, so that newer models like MODEL_5170
* don't have to rely on these legacy switch settings. In fact, switch settings should NEVER be required; we should be
* setting defaults to automatically match the rest of the machine's hardware specification. However, that's probably
* incomplete; for example, does the FDC component have a way of specifying the number of drives, and do we honor that?
* I think not....
*/
this.abCMOSData[ChipSet.CMOS.ADDR.EQUIP] = this.sw1 & (ChipSet.PPI_SW.MONITOR.MASK | ChipSet.PPI_SW.COPROC | ChipSet.PPI_SW.FDRIVE.IPL | ChipSet.PPI_SW.FDRIVE.MASK);
this.abCMOSData[ChipSet.CMOS.ADDR.FDRIVE] = (this.getSWFloppyDriveType(0) << 4) | this.getSWFloppyDriveType(1);
/*
* We allow both memory totals to start at zero now, and rely on the RAM component to call addCMOSMemory()
* to update the total(s) as appropriate.
*
var wBaseMemKb = this.getSWMemorySize();
this.abCMOSData[ChipSet.CMOS.ADDR.BASEMEM_LO] = wBaseMemKb & 0xff;
this.abCMOSData[ChipSet.CMOS.ADDR.BASEMEM_HI] = wBaseMemKb >> 8;
*/
/*
* The final step is calculating the CMOS checksum, which we then store into the CMOS as a courtesy, so that the
* user doesn't get unnecessary CMOS errors.
@ -1285,7 +1352,7 @@ ChipSet.prototype.setCMOSByte = function(iCMOS, b)
/**
* addCMOSMemory(addr, size)
*
* This is ONLY for use by the RAM component, to dynamically update the CMOS memory configuration.
* For use by the RAM component, to dynamically update the CMOS memory configuration.
*
* @this {ChipSet}
* @param {number} addr (if 0, BASEMEM_LO/BASEMEM_HI is updated; if >= 0x100000, then EXTMEM_LO/EXTMEM_HI is updated)
@ -1309,7 +1376,7 @@ ChipSet.prototype.addCMOSMemory = function(addr, size)
/**
* setCMOSDriveType(iDrive, bType)
*
* This is ONLY for use by the HDC component, to update the CMOS drive configuration to match HDC's internal configuration.
* For use by the HDC component, to update the CMOS drive configuration to match HDC's internal configuration.
*
* TODO: Extend this to support FDC drive updates, so that FDC can eventually specify diskette drive types
* (ie, DSDD or DSHD) in the same way that HDC does; currently, MODEL_5170 diskette drives always default to DSHD
@ -1376,7 +1443,7 @@ ChipSet.prototype.save = function()
if (this.model >= ChipSet.MODEL_5170) {
state.set(5, [this.b8042Status, this.b8042InBuff, this.b8042CmdData,
this.b8042OutBuff, this.b8042InPort, this.b8042OutPort]);
state.set(6, [this.bCMOSAddr, this.abCMOSData, this.nCyclesCMOSLastUpdate]);
state.set(6, [this.bMFGData, this.abDMAPageSpare, this.bCMOSAddr, this.abCMOSData, this.nCyclesCMOSLastUpdate]);
}
return state.data();
};
@ -1439,9 +1506,11 @@ ChipSet.prototype.restore = function(data)
a = data[6];
if (a) {
Component.assert(this.model >= ChipSet.MODEL_5170);
this.bCMOSAddr = a[0];
this.abCMOSData = a[1];
this.nCyclesCMOSLastUpdate = a[2];
this.bMFGData = a[0];
this.abDMAPageSpare = a[1];
this.bCMOSAddr = a[2];
this.abCMOSData = a[3];
this.nCyclesCMOSLastUpdate = a[4];
}
return true;
};
@ -1914,13 +1983,10 @@ ChipSet.prototype.dumpCMOS = function()
{
if (DEBUGGER) {
var sDump = "";
for (var p in ChipSet.CMOS.ADDR) {
var iCMOS = ChipSet.CMOS.ADDR[p];
if (iCMOS >= 0 && iCMOS < ChipSet.CMOS.ADDR.MASK) {
var b = (iCMOS <= ChipSet.CMOS.ADDR.RTC_STATUSD? this.getRTCByte(iCMOS) : this.abCMOSData[iCMOS]);
if (sDump) sDump += '\n';
sDump += str.pad(p + "(" + str.toHexByte(iCMOS) + "):", 19) + str.toHexByte(b);
}
for (var iCMOS = 0; iCMOS < ChipSet.CMOS.ADDR.TOTAL; iCMOS++) {
var b = (iCMOS <= ChipSet.CMOS.ADDR.RTC_STATUSD? this.getRTCByte(iCMOS) : this.abCMOSData[iCMOS]);
if (sDump) sDump += '\n';
sDump += "CMOS[0x" + str.toHexByte(iCMOS) + "]: 0x" + str.toHexByte(b);
}
this.dbg.message(sDump);
}
@ -2137,8 +2203,8 @@ ChipSet.prototype.outDMAMode = function(iDMAC, port, bOut, addrFrom)
* @param {number} bOut
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
*
* Any write to this port simply resets the controller's "first/last flip-flop", which determines whether the even or odd byte
* of a DMA address or count register will be accessed next.
* Any write to this port simply resets the controller's "first/last flip-flop", which determines whether
* the even or odd byte of a DMA address or count register will be accessed next.
*/
ChipSet.prototype.outDMAIndex = function(iDMAC, port, bOut, addrFrom)
{

View file

@ -1003,7 +1003,7 @@ if (DEBUGGER) {
/*
* DOS interrupts, for tracing DOS operations
*/
Debugger.INT_DOS_CALL = 0x21;
Debugger.DOS_INT = 0x21;
Debugger.aDOSFuncDesc = {
0x00: "terminate program",
@ -1124,7 +1124,7 @@ if (DEBUGGER) {
}
}
this.cpu.addInterruptNotify(Debugger.INT_DOS_CALL, this, this.intDOSCall);
this.cpu.addInterruptNotify(Debugger.DOS_INT, this, this.intDOSCall);
this.setReady();

View file

@ -538,7 +538,7 @@ FDC.prototype.powerUp = function(data, fRepower)
for (iDrive = 0; iDrive < this.nDrives; iDrive++) {
var drive = this.aDrives[iDrive];
drive.bType = this.chipset.getSWFloppyDriveType(iDrive);
if (drive.bType == ChipSet.FDRIVE.DSHD) {
if (drive.bType == ChipSet.CMOS.FDRIVE.DSHD) {
drive.nCylinders = 80;
}
}
@ -826,7 +826,7 @@ FDC.prototype.initDrive = function(drive, iDrive, data)
* To simulate this, bCylinder is now treated as the "physical" cylinder (since that's how it's ALWAYS been used here),
* and bCylinderSeek will now track (pun intended) the "logical" cylinder that's programmed via SEEK commands.
*/
drive.bType = ChipSet.FDRIVE.DSDD; // default; updated later once we have the actual ChipSet object
drive.bType = ChipSet.CMOS.FDRIVE.DSDD; // default; updated later once we have the actual ChipSet object
drive.bHead = data[i++];
drive.bCylinderSeek = data[i++]; // the data[] slot where we used to store drive.nHeads (or -1)
drive.bCylinder = data[i++];

View file

@ -1050,7 +1050,7 @@ Keyboard.prototype.keyEvent = function(event, fDown)
/*
* HACK for simulating Ctrl-Break using Ctrl-Del (Mac) / Ctrl-Backspace (Windows)
*/
if (keyCode == Keyboard.KEYCODE.DELETE && (this.bitsShift & Keyboard.STATE.CTRL)) {
if (keyCode == Keyboard.KEYCODE.DELETE && (this.bitsShift & (Keyboard.STATE.CTRL|Keyboard.STATE.ALT)) == Keyboard.STATE.CTRL) {
keyCode = Keyboard.CHARCODE.CTRLBREAK;
}
/*

View file

@ -550,13 +550,13 @@
<xsl:variable name="sw1">
<xsl:choose>
<xsl:when test="@sw1"><xsl:value-of select="@sw1"/></xsl:when>
<xsl:otherwise>11110011</xsl:otherwise>
<xsl:otherwise/>
</xsl:choose>
</xsl:variable>
<xsl:variable name="sw2">
<xsl:choose>
<xsl:when test="@sw2"><xsl:value-of select="@sw2"/></xsl:when>
<xsl:otherwise>11110000</xsl:otherwise>
<xsl:otherwise/>
</xsl:choose>
</xsl:variable>
<xsl:variable name="sound">
@ -571,6 +571,18 @@
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="fdrives">
<xsl:choose>
<xsl:when test="@fdrives"><xsl:value-of select="@fdrives"/></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="monitor">
<xsl:choose>
<xsl:when test="@monitor"><xsl:value-of select="@monitor"/></xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:variable>
<xsl:variable name="rtcdate">
<xsl:choose>
<xsl:when test="@rtcdate"><xsl:value-of select="@rtcdate"/></xsl:when>
@ -580,7 +592,7 @@
<xsl:call-template name="component">
<xsl:with-param name="machine" select="$machine"/>
<xsl:with-param name="class">chipset</xsl:with-param>
<xsl:with-param name="parms">,model:'<xsl:value-of select="$model"/>',scaleTimers:<xsl:value-of select="$scaletimers"/>,sw1:'<xsl:value-of select="$sw1"/>',sw2:'<xsl:value-of select="$sw2"/>',sound:<xsl:value-of select="$sound"/>,rtcDate:'<xsl:value-of select="$rtcdate"/>'</xsl:with-param>
<xsl:with-param name="parms">,model:'<xsl:value-of select="$model"/>',scaleTimers:<xsl:value-of select="$scaletimers"/>,sw1:'<xsl:value-of select="$sw1"/>',sw2:'<xsl:value-of select="$sw2"/>',sound:<xsl:value-of select="$sound"/>,fdrives:<xsl:value-of select="$fdrives"/>,monitor:'<xsl:value-of select="$monitor"/>',rtcDate:'<xsl:value-of select="$rtcdate"/>'</xsl:with-param>
</xsl:call-template>
</xsl:template>

View file

@ -424,8 +424,8 @@ web.getURLParameters = function(sParms)
if (window) { // an alternative to "if (typeof module === 'undefined')" if require("defines") has been invoked
if (!sParms) {
/*
* Note that window.location.href returns the entire URL, whereas window.location.search returns
* only the parameters, if any (starting with the '?', which we skip over with a substr() call).
* Note that window.location.href returns the entire URL, whereas window.location.search
* returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).
*/
sParms = window.location.search.substr(1);
}