Cleaned up debugger message handling
This commit is contained in:
parent
6248972684
commit
2ff339f190
31 changed files with 640 additions and 735 deletions
|
|
@ -171,7 +171,7 @@ module.exports = function(grunt) {
|
|||
banner: '"use strict";\n\n',
|
||||
process: function(src, filepath) {
|
||||
return "// " + filepath + "\n\n" +
|
||||
src.replace(/(^|\n)[ \t]*(['"])use strict\2;?\s*/g, '$1').replace(/[ \t]*if\s*\(typeof\s+(module|APP_PCJS)\s*!==\s*(['"])undefined\2\)\s*(\{[^}]*}|[^\n]*)(\n|$)/gm, '');
|
||||
src.replace(/(^|\n)[ \t]*(['"])use strict\2;?\s*/g, '$1').replace(/[ \t]*if\s*\(typeof\s+(module|APP_PCJS)\s*!==\s*(['"])undefined\2\)\s*(\{[^}]*}|[^\n]*)(\n|$)/gm, '').replace(/[ \t]*[A-Za-z_][A-Za-z0-9_\.]*\.assert\(.*\);[^\n]*(\n|$)/g, '');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -182,7 +182,7 @@ module.exports = function(grunt) {
|
|||
banner: '"use strict";\n\n',
|
||||
process: function(src, filepath) {
|
||||
return "// " + filepath + "\n\n" +
|
||||
src.replace(/(^|\n)[ \t]*(['"])use strict\2;?\s*/g, '$1').replace(/[ \t]*if\s*\(typeof\s+(module|APP_PCJS)\s*!==\s*(['"])undefined\2\)\s*(\{[^}]*}|[^\n]*)(\n|$)/gm, '');
|
||||
src.replace(/(^|\n)[ \t]*(['"])use strict\2;?\s*/g, '$1').replace(/[ \t]*if\s*\(typeof\s+(module|APP_PCJS)\s*!==\s*(['"])undefined\2\)\s*(\{[^}]*}|[^\n]*)(\n|$)/gm, '').replace(/[ \t]*[A-Za-z_][A-Za-z0-9_\.]*\.assert\(.*\);[^\n]*(\n|$)/g, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,10 @@
|
|||
"global": true,
|
||||
"module": true,
|
||||
"require": true,
|
||||
"FileReader": false,
|
||||
"setTimeout": false,
|
||||
"clearTimeout": false,
|
||||
"Image": false
|
||||
"Image": false,
|
||||
"DumpAPI": false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ function C1PDebugger(parmsDbg)
|
|||
|
||||
Component.call(this, "C1PDebugger", parmsDbg);
|
||||
|
||||
this.dbg = this;
|
||||
/*
|
||||
* This keeps track of instruction activity, but only when tracing or when
|
||||
* Debugger checks have been enabled (eg, one or more breakpoints have been set).
|
||||
|
|
@ -122,7 +123,7 @@ function C1PDebugger(parmsDbg)
|
|||
this.MESSAGE_SERIAL = 0x80;
|
||||
this.MESSAGE_NONE = 0x00;
|
||||
// this.MESSAGE_ALL = 0xff;
|
||||
this.bMessages = this.MESSAGE_NONE;
|
||||
this.bitsMessage = this.MESSAGE_NONE;
|
||||
this.aMessageCategories = {
|
||||
'port': this.MESSAGE_PORT,
|
||||
'kbd': this.MESSAGE_KBD,
|
||||
|
|
@ -694,7 +695,7 @@ if (DEBUGGER) {
|
|||
];
|
||||
for (iMode=0; iMode < this.aOpModes.length; iMode++) {
|
||||
sMode = this.aOpModes[iMode];
|
||||
sRegEx += "(" + sMode.replace(/\[/g, "\\[").replace(/\]/g, "\\]").replace(/nnnn/g, "[0-9A-F][0-9A-F][0-9A-F][0-9A-F]?").replace(/nn/g, "[0-9A-F][0-9A-F]?").replace(/\+/g, "\\+") + "|)";
|
||||
sRegEx += "(" + sMode.replace(/\[/g, "\\[").replace(/]/g, "\\]").replace(/nnnn/g, "[0-9A-F][0-9A-F][0-9A-F][0-9A-F]?").replace(/nn/g, "[0-9A-F][0-9A-F]?").replace(/\+/g, "\\+") + "|)";
|
||||
}
|
||||
this.regexOpModes = new RegExp(sRegEx);
|
||||
}
|
||||
|
|
@ -732,31 +733,18 @@ if (DEBUGGER) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @this {C1PDebugger}
|
||||
* @param {number} bMessage is one or more Debugger MESSAGE_* category flag(s)
|
||||
* @return {boolean} true if message category is enabled, false if not
|
||||
*
|
||||
* NOTE: If the caller specifies MULTIPLE category flags, then ALL the corresponding flags
|
||||
* in the Debugger's bMessages variable must be enabled as well, else the result will be false
|
||||
*/
|
||||
C1PDebugger.prototype.messageEnabled = function(bMessage)
|
||||
{
|
||||
return ((this.bMessages & bMessage) === bMessage);
|
||||
};
|
||||
|
||||
/**
|
||||
* @this {C1PDebugger}
|
||||
* @param {Component} component
|
||||
* @param {number} addr
|
||||
* @param {number|undefined} addrFrom
|
||||
* @param {boolean} bMessage is a Debugger MESSAGE_* category flag
|
||||
* @param {boolean} bitsMessage is a Debugger MESSAGE_* category flag
|
||||
* @param {boolean|undefined} [fWrite] is true if this was a write, false (or undefined) if read
|
||||
* @param {string|undefined} [name] of the port, if any
|
||||
*/
|
||||
C1PDebugger.prototype.messagePort = function(component, addr, addrFrom, bMessage, fWrite, name)
|
||||
C1PDebugger.prototype.messageIO = function(component, addr, addrFrom, bitsMessage, fWrite, name)
|
||||
{
|
||||
if ((this.bMessages & bMessage) == bMessage) {
|
||||
if ((this.bitsMessage & bitsMessage) == bitsMessage) {
|
||||
var b = this.cpu.getByte(addr);
|
||||
this.message(component.id + "." + (fWrite? "setByte":"getByte") + "(" + str.toHexWord(addr) + ")" + (addrFrom !== undefined? (" @" + str.toHexWord(addrFrom)) : "") + ": " + (name? (name + "=") : "") + str.toHexByte(b));
|
||||
}
|
||||
|
|
@ -1947,25 +1935,25 @@ if (DEBUGGER) {
|
|||
this.println("modern syntax enabled");
|
||||
break;
|
||||
case "msg":
|
||||
var bMessage = 0;
|
||||
var bitsMessage = 0;
|
||||
if (asArgs[2] !== undefined) {
|
||||
if (asArgs[2] == "all")
|
||||
bMessage = 0xff;
|
||||
bitsMessage = 0xff;
|
||||
else if (this.aMessageCategories[asArgs[2]] !== undefined)
|
||||
bMessage = this.aMessageCategories[asArgs[2]];
|
||||
if (bMessage) {
|
||||
bitsMessage = this.aMessageCategories[asArgs[2]];
|
||||
if (bitsMessage) {
|
||||
if (asArgs[3] == "on") {
|
||||
this.bMessages |= bMessage;
|
||||
this.bitsMessage |= bitsMessage;
|
||||
}
|
||||
else if (asArgs[3] == "off") {
|
||||
this.bMessages &= ~bMessage;
|
||||
this.bitsMessage &= ~bitsMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var sCategory in this.aMessageCategories) {
|
||||
if (asArgs[2] !== undefined && (asArgs[2] != "all" && asArgs[2] != sCategory)) continue;
|
||||
bMessage = this.aMessageCategories[sCategory];
|
||||
this.println(sCategory + " messages: " + ((this.bMessages & bMessage)? "on" : "off"));
|
||||
bitsMessage = this.aMessageCategories[sCategory];
|
||||
this.println(sCategory + " messages: " + ((this.bitsMessage & bitsMessage)? "on" : "off"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -970,7 +970,7 @@ C1PDiskController.prototype.getByte = function(addr, addrFrom)
|
|||
if (addrFrom !== undefined) {
|
||||
var port = addr - this.addrController;
|
||||
var reg = this.getReg(port, false);
|
||||
if (DEBUGGER && this.dbg) this.dbg.messagePort(this, addr, addrFrom, this.dbg.MESSAGE_DISK, false, reg.sName);
|
||||
if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_DISK, false, reg.sName);
|
||||
reg.read();
|
||||
}
|
||||
};
|
||||
|
|
@ -991,7 +991,7 @@ C1PDiskController.prototype.setByte = function(addr, addrFrom)
|
|||
var port = addr - this.addrController;
|
||||
var reg = this.getReg(port, true);
|
||||
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_DISK | this.dbg.MESSAGE_PORT)) {
|
||||
this.dbg.messagePort(this, addr, addrFrom, this.dbg.MESSAGE_DISK, true, reg.sName);
|
||||
this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_DISK, true, reg.sName);
|
||||
if (reg.aBitIDs) {
|
||||
var bTest = 0x80;
|
||||
var bChanged = reg.bits ^ b;
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ C1PROM.prototype.setByte = function(addr, addrFrom)
|
|||
* we need to allow the Debugger to modify ROM contents).
|
||||
*/
|
||||
if (addrFrom !== undefined) {
|
||||
if (DEBUGGER && this.dbg) this.dbg.messagePort(this, addr, addrFrom, this.dbg.MESSAGE_PORT, true);
|
||||
if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_PORT, true);
|
||||
var offset = (addr - this.offROM);
|
||||
Component.assert(offset >= 0 && offset < this.cbROM);
|
||||
if (!this.abImage)
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ C1PSerialPort.prototype.setBinding = function(sHTMLType, sBinding, control)
|
|||
var fieldset = control.children[0];
|
||||
var files = fieldset.children[0].files;
|
||||
var submit = fieldset.children[1];
|
||||
submit.disabled = (files.length == 0);
|
||||
submit.disabled = !files.length;
|
||||
});
|
||||
|
||||
control.onsubmit = function(event) {
|
||||
|
|
@ -321,7 +321,7 @@ C1PSerialPort.prototype.setByte = function(addr, addrFrom)
|
|||
* the Debugger performed this write (need a special Debugger I/O command if/when you really want to do that).
|
||||
*/
|
||||
if (addrFrom !== undefined) {
|
||||
if (DEBUGGER && this.dbg) this.dbg.messagePort(this, addr, addrFrom, this.dbg.MESSAGE_SERIAL, true);
|
||||
if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_SERIAL, true);
|
||||
/*
|
||||
* WARNING: I don't yet care what state the CPU puts the port into. When it's time to support serial output,
|
||||
* obviously that will become an issue.
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ C1PVideo.prototype.getByte = function(addr, addrFrom)
|
|||
{
|
||||
var b = this.cpu.getByte(addr);
|
||||
if (addrFrom !== undefined) {
|
||||
if (DEBUGGER && this.dbg) this.dbg.messagePort(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO);
|
||||
if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO);
|
||||
}
|
||||
/*
|
||||
* The only documented READ bit in addrVideoPort is bit 7, which is supposed to alternate between
|
||||
|
|
@ -388,7 +388,7 @@ C1PVideo.prototype.getByte = function(addr, addrFrom)
|
|||
C1PVideo.prototype.setByte = function(addr, addrFrom)
|
||||
{
|
||||
if (addrFrom !== undefined) {
|
||||
if (DEBUGGER && this.dbg) this.dbg.messagePort(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO);
|
||||
if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -404,7 +404,7 @@ C1PVideo.prototype.tripGuard = function(addr, addrFrom)
|
|||
* the Debugger performed this read (need a special Debugger I/O command if/when you really want to do that).
|
||||
*/
|
||||
if (addrFrom !== undefined) {
|
||||
if (DEBUGGER && this.dbg) this.dbg.messagePort(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO, true);
|
||||
if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO, true);
|
||||
/*
|
||||
* The CPU has just written to the guard address we established just beyond the video buffer's 1K boundary,
|
||||
* implying that the system thinks we have a 2K buffer instead. So we bump our model to 540, bump the
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
"APPNAME": false,
|
||||
"APPVERSION": false,
|
||||
"SITEHOST": false,
|
||||
"COMPILED": true,
|
||||
"DEBUG": true,
|
||||
"MAXDEBUG": false,
|
||||
"PCJSCLASS": true,
|
||||
|
|
@ -18,6 +19,7 @@
|
|||
"EAFUNCS": true,
|
||||
"FATARRAYS": true,
|
||||
"TYPEDARRAYS": true,
|
||||
"SAMPLER": true,
|
||||
"Component": true,
|
||||
"State": true,
|
||||
"Bus": true,
|
||||
|
|
@ -47,9 +49,14 @@
|
|||
"str": true,
|
||||
"usr": true,
|
||||
"web": true,
|
||||
"document": true,
|
||||
"global": true,
|
||||
"module": true,
|
||||
"require": true,
|
||||
"ArrayBuffer": false,
|
||||
"DataView": false,
|
||||
"FileReader": false,
|
||||
"Uint8Array": false,
|
||||
"setTimeout": false,
|
||||
"clearTimeout": false,
|
||||
"webkitAudioContext": false,
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ Bus.prototype.getA20 = function()
|
|||
*/
|
||||
Bus.prototype.setA20 = function(fEnable)
|
||||
{
|
||||
if (DEBUG) this.assert(fEnable !== undefined);
|
||||
this.assert(fEnable !== undefined);
|
||||
if (fEnable !== undefined) {
|
||||
if (this.nBusWidth > 20) {
|
||||
var addrMask = (this.addrMask & ~0x100000) | (fEnable? 0x100000 : 0);
|
||||
|
|
@ -643,7 +643,7 @@ Bus.prototype.checkPortInputNotify = function(port, addrFrom)
|
|||
}
|
||||
else {
|
||||
if (DEBUGGER && this.dbg) {
|
||||
this.dbg.messagePort(this, port, null, addrFrom);
|
||||
this.dbg.messageIO(this, port, null, addrFrom);
|
||||
if (this.fPortInputBreakAll) this.dbg.checkPortInput(port, bIn);
|
||||
}
|
||||
}
|
||||
|
|
@ -759,7 +759,7 @@ Bus.prototype.checkPortOutputNotify = function(port, bOut, addrFrom)
|
|||
}
|
||||
else {
|
||||
if (DEBUGGER && this.dbg) {
|
||||
this.dbg.messagePort(this, port, bOut, addrFrom);
|
||||
this.dbg.messageIO(this, port, bOut, addrFrom);
|
||||
if (this.fPortOutputBreakAll) this.dbg.checkPortOutput(port, bOut);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ if (typeof module !== 'undefined') {
|
|||
* be programmed to return it (which we support), but its purpose remains unclear to me (see PPI_B.ENABLE_SW2).
|
||||
*
|
||||
* For example, sw1="01110011" indicates that all SW1 DIP switches are ON, except for SW1[1], SW1[5] and SW1[6],
|
||||
* which are OFF. Internally, the order of these bits must reversed (to 11001110) and then inverted (to 00110001)
|
||||
* which are OFF. Internally, the order of these bits must reversed (to 11001110) and then inverted (to 00110001)
|
||||
* to yield the value that the 8255A PPI returns. Reading the final value right-to-left, 00110001 indicates an
|
||||
* IPL floppy drive, 1X of RAM (where X is 16Kb on a MODEL_5150 and 64Kb on a MODEL_5160), MDA, and 1 floppy drive.
|
||||
*
|
||||
|
|
@ -88,7 +88,7 @@ if (typeof module !== 'undefined') {
|
|||
* a valid stack causes the system to crash after the next IRET. The BIOS should have either halted or modified
|
||||
* the actual memory size to match the results of the memory test.
|
||||
*
|
||||
* This component provides support for many of the following components (except where a separate component is noted).
|
||||
* This module provides support for many of the following components (except where a separate component is noted).
|
||||
* This list is taken from p.1-8 ("System Unit") of the IBM 5160 (PC XT) Technical Reference Manual (as revised
|
||||
* April 1983), only because I didn't see a similar listing in the original 5150 TechRef.
|
||||
*
|
||||
|
|
@ -147,7 +147,7 @@ if (typeof module !== 'undefined') {
|
|||
*/
|
||||
function ChipSet(parmsChipSet)
|
||||
{
|
||||
Component.call(this, "ChipSet", parmsChipSet, ChipSet);
|
||||
Component.call(this, "ChipSet", parmsChipSet, ChipSet, Debugger.MESSAGE.CHIPSET);
|
||||
|
||||
this.model = parmsChipSet['model'];
|
||||
this.model = (this.model? parseInt(this.model, 10) : ChipSet.MODEL_5150);
|
||||
|
|
@ -187,15 +187,18 @@ function ChipSet(parmsChipSet)
|
|||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
* or 480Kb. With a maximum of 64Kb on the motherboard, the MODEL_5150 ROM BIOS could support a grand total of 544Kb.
|
||||
* 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, or 480Kb. With a maximum of 64Kb on the motherboard, the MODEL_5150 ROM BIOS could support
|
||||
* a grand total of 544Kb.
|
||||
*
|
||||
* For MODEL_5160 (PC XT) and up, memory expansion cards had their own configuration switches, and the motherboard SW2
|
||||
* switches for I/O expansion RAM were eliminated. Instead, the ROM BIOS scans the entire address space (up to 0xA0000)
|
||||
* looking for additional memory. As a result, the only mechanism we provide for adding RAM (above the maximum of 256Kb
|
||||
* 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.
|
||||
* For MODEL_5160 (PC XT) and up, memory expansion cards had their own configuration switches, and the motherboard
|
||||
* SW2 switches for I/O expansion RAM were eliminated. Instead, the ROM BIOS scans the entire address space
|
||||
* (up to 0xA0000) looking for additional memory. As a result, the only mechanism we provide for adding RAM
|
||||
* (above the maximum of 256Kb 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'] || "11110000", 0);
|
||||
|
||||
|
|
@ -214,7 +217,7 @@ function ChipSet(parmsChipSet)
|
|||
|
||||
/*
|
||||
* Here, I'm finally getting around to trying the Web Audio API. Fortunately, based on what little I know about
|
||||
* sound generation, using the API to make the same noises as the IBM PC speaker should be straightforward.
|
||||
* sound generation, using the API to make the same noises as the IBM PC speaker seems straightforward.
|
||||
*
|
||||
* To start, we create an audio context, unless the 'sound' parameter has been explicitly set to false.
|
||||
*
|
||||
|
|
@ -426,8 +429,8 @@ ChipSet.DMA_HDC = 0x03; // DMA channel assigned to the Hard Drive Contro
|
|||
*
|
||||
* ICW4 is typically set to 0x09, indicating 8086 mode, non-automatic EOI, buffered/slave mode.
|
||||
*
|
||||
* QUESTION: Why did the original ROM BIOS choose buffered/slave over buffered/master? Did it simply
|
||||
* not matter in pre-AT systems with only one PIC, or am I misreading something?
|
||||
* TODO: Determine why the original ROM BIOS chose buffered/slave over buffered/master.
|
||||
* Did it simply not matter in pre-AT systems with only one PIC, or am I misreading something?
|
||||
*
|
||||
* TODO: Consider support for level-triggered PIC interrupts, even though the original IBM PCs
|
||||
* (up through MODEL_5170) used only edge-triggered interrupts.
|
||||
|
|
@ -643,6 +646,7 @@ ChipSet.PPI_SW = {
|
|||
*
|
||||
* Similarly, port 0x61 is designated KBC.RWREG rather than PPI_B; the BIOS also refers to it as "PORT_B: 8042
|
||||
* READ WRITE REGISTER", but it is not otherwise discussed in the MODEL_5170 TechRef's 8042 documentation.
|
||||
*
|
||||
* There are brief references to bits 0 and 1 (KBC.RWREG.CLK_TIMER2 and KBC.RWREG.SPK_TIMER2), and the BIOS sets
|
||||
* bits 2-7 to "DISABLE PARITY CHECKERS" (principally KBC.RWREG.DISABLE_CHK, which are bits 2 and 3); why the BIOS
|
||||
* also sets bits 4-7 (or if those bits are even settable) is unclear, since it uses 11111100B rather than defined
|
||||
|
|
@ -655,7 +659,7 @@ ChipSet.PPI_SW = {
|
|||
* PPI_C and PPI_CTRL don't seem to be documented or used by the MODEL_5170 BIOS, so I'm assuming they're obsolete.
|
||||
*
|
||||
* NOTE: For more information on the 8042 Controller, including information on undocumented commands, refer to the
|
||||
* documents in /devices/pc/keyboard/, as well as the following websites:
|
||||
* documents in /devices/pc/keyboard, as well as the following websites:
|
||||
*
|
||||
* http://halicery.com/8042/8042_INTERN_TXT.htm
|
||||
* http://www.os2museum.com/wp/?p=589 ("IBM PC/AT 8042 Keyboard Controller Commands")
|
||||
|
|
@ -863,9 +867,9 @@ ChipSet.CMOS = {
|
|||
* This port corresponds to a read/write register in the DMA page register (74LS6I2)."
|
||||
*
|
||||
* 0x80 is the neighborhood, but that particular port is not documented as a DMA page register.
|
||||
* We'll refer to it as manufacturing port (see bMFGData). Be aware that the MODEL_5170 BIOS is littered
|
||||
* with manufacturing test ("MFG_TST") code which, if enabled, writes to other DMA page registers,
|
||||
* perhaps treating them as scratch registers.
|
||||
* We'll refer to it as a "manufacturing port" (see bMFGData). Be aware that the MODEL_5170 BIOS is
|
||||
* littered with manufacturing test ("MFG_TST") code which, if enabled, writes to other DMA page
|
||||
* registers, presumably treating them as scratch registers.
|
||||
*/
|
||||
ChipSet.MFG = { // this.bMFGData
|
||||
PORT: 0x80
|
||||
|
|
@ -1130,11 +1134,11 @@ ChipSet.prototype.reset = function(fHard)
|
|||
*
|
||||
* NOTE: There are two approaches we could take here: always store the RTC bytes in binary, and convert them
|
||||
* to/from BCD on-demand (ie, as the simulation reads/writes the CMOS RTC registers); or init/update them in the
|
||||
* format specified by CMOS_STATUSB.BINARY (1 for binary, 0 for BCD). Both approaches require BCD conversion
|
||||
* format specified by CMOS.STATUSB.BINARY (1 for binary, 0 for BCD). Both approaches require BCD conversion
|
||||
* functions, but the former seems more efficient, in part because the periodic calls to updateRTCTime() won't
|
||||
* require any conversions.
|
||||
*
|
||||
* We take the same approach with the CMOS_STATUSB.HOUR24 setting: internally, we always operate in 24-hour mode,
|
||||
* We take the same approach with the CMOS.STATUSB.HOUR24 setting: internally, we always operate in 24-hour mode,
|
||||
* but externally, we convert the RTC hour values to the 12-hour format as needed.
|
||||
*
|
||||
* Thus, all I/O to the RTC bytes must be routed through the getRTCByte() and setRTCByte() functions, to ensure
|
||||
|
|
@ -1206,7 +1210,7 @@ ChipSet.prototype.initRTCTime = function(sDate)
|
|||
*/
|
||||
ChipSet.prototype.getRTCByte = function(iRTC)
|
||||
{
|
||||
if (DEBUG) this.assert(iRTC >= 0 && iRTC <= ChipSet.CMOS.ADDR.STATUSD);
|
||||
this.assert(iRTC >= 0 && iRTC <= ChipSet.CMOS.ADDR.STATUSD);
|
||||
|
||||
var b = this.abCMOSData[iRTC];
|
||||
|
||||
|
|
@ -1258,7 +1262,7 @@ ChipSet.prototype.getRTCByte = function(iRTC)
|
|||
*/
|
||||
ChipSet.prototype.setRTCByte = function(iRTC, b)
|
||||
{
|
||||
if (DEBUG) this.assert(iRTC >= 0 && iRTC <= ChipSet.CMOS.ADDR.STATUSD);
|
||||
this.assert(iRTC >= 0 && iRTC <= ChipSet.CMOS.ADDR.STATUSD);
|
||||
|
||||
if (iRTC < ChipSet.CMOS.ADDR.STATUSA) {
|
||||
var fBCD = false;
|
||||
|
|
@ -1276,8 +1280,8 @@ ChipSet.prototype.setRTCByte = function(iRTC, b)
|
|||
* If the original BCD hour was 0x81-0x92, then the previous BINARY-to-BCD conversion
|
||||
* transformed it to 0x51-0x5C, so we must add 0x30.
|
||||
*/
|
||||
if (b > 12) {
|
||||
if (DEBUG) this.assert(b >= 0x51 && b <= 0x5c);
|
||||
if (b > 23) {
|
||||
this.assert(b >= 0x51 && b <= 0x5c);
|
||||
b += 0x30;
|
||||
}
|
||||
}
|
||||
|
|
@ -1328,17 +1332,17 @@ ChipSet.prototype.getRTCCycleLimit = function(nCycles)
|
|||
if (nCyclesUpdate > 0) {
|
||||
if (nCycles > nCyclesUpdate) {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.RTC)) {
|
||||
this.messageDebugger("getRTCCycleLimit(" + nCycles + "): reduced to " + nCyclesUpdate + " cycles", Debugger.MESSAGE.RTC);
|
||||
this.messageDebugger("getRTCCycleLimit(" + nCycles + "): reduced to " + nCyclesUpdate + " cycles");
|
||||
}
|
||||
nCycles = nCyclesUpdate;
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.RTC)) {
|
||||
this.messageDebugger("getRTCCycleLimit(" + nCycles + "): already less than " + nCyclesUpdate + " cycles", Debugger.MESSAGE.RTC);
|
||||
this.messageDebugger("getRTCCycleLimit(" + nCycles + "): already less than " + nCyclesUpdate + " cycles");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.RTC)) {
|
||||
this.messageDebugger("RTC next update has passed by " + nCyclesUpdate + " cycles", Debugger.MESSAGE.RTC);
|
||||
this.messageDebugger("RTC next update has passed by " + nCyclesUpdate + " cycles");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1434,7 +1438,7 @@ ChipSet.prototype.updateRTCTime = function()
|
|||
* Step 3: Update the RTC date/time and deal with Update Interrupts
|
||||
*/
|
||||
var nCyclesDelta = nCyclesUpdate - this.nRTCCyclesLastUpdate;
|
||||
if (DEBUG) this.assert(nCyclesDelta >= 0);
|
||||
this.assert(nCyclesDelta >= 0);
|
||||
var nSecondsDelta = Math.floor(nCyclesDelta / nCyclesPerSecond);
|
||||
|
||||
/*
|
||||
|
|
@ -1444,7 +1448,7 @@ ChipSet.prototype.updateRTCTime = function()
|
|||
* (nCyclesDelta % nCyclesPerSecond) back into nRTCCyclesLastUpdate, so that we will eventually
|
||||
* see a one-second delta.
|
||||
*/
|
||||
if (DEBUG) this.assert(nSecondsDelta <= 1);
|
||||
this.assert(nSecondsDelta <= 1);
|
||||
|
||||
/*
|
||||
* Make sure that CMOS.STATUSB.SET isn't set; if it is, then the once-per-second RTC updates must be
|
||||
|
|
@ -1512,8 +1516,8 @@ ChipSet.prototype.initCMOSData = function()
|
|||
}
|
||||
|
||||
/*
|
||||
* 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).
|
||||
* 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).
|
||||
*/
|
||||
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);
|
||||
|
|
@ -1538,7 +1542,7 @@ ChipSet.prototype.initCMOSData = function()
|
|||
ChipSet.prototype.setCMOSByte = function(iCMOS, b)
|
||||
{
|
||||
if (this.abCMOSData) {
|
||||
if (DEBUG) this.assert(iCMOS >= ChipSet.CMOS.ADDR.FDRIVE && iCMOS < ChipSet.CMOS.ADDR.CHKSUM_HI);
|
||||
this.assert(iCMOS >= ChipSet.CMOS.ADDR.FDRIVE && iCMOS < ChipSet.CMOS.ADDR.CHKSUM_HI);
|
||||
this.abCMOSData[iCMOS] = b;
|
||||
this.updateCMOSChecksum();
|
||||
return true;
|
||||
|
|
@ -1590,7 +1594,7 @@ ChipSet.prototype.setCMOSDriveType = function(iDrive, bType)
|
|||
{
|
||||
if (this.abCMOSData) {
|
||||
var b = this.abCMOSData[ChipSet.CMOS.ADDR.HDRIVE];
|
||||
if (DEBUG) this.assert(bType > 0 && bType < 0xf);
|
||||
this.assert(bType > 0 && bType < 0xf);
|
||||
if (iDrive) {
|
||||
b = (b & ChipSet.CMOS.HDRIVE.D0_MASK) | bType;
|
||||
} else {
|
||||
|
|
@ -1690,7 +1694,7 @@ ChipSet.prototype.restore = function(data)
|
|||
|
||||
a = data[5];
|
||||
if (a) {
|
||||
if (DEBUG) this.assert(this.model >= ChipSet.MODEL_5170);
|
||||
this.assert(this.model >= ChipSet.MODEL_5170);
|
||||
this.b8042Status = a[0];
|
||||
this.b8042InBuff = a[1];
|
||||
this.b8042CmdData = a[2];
|
||||
|
|
@ -1701,7 +1705,7 @@ ChipSet.prototype.restore = function(data)
|
|||
|
||||
a = data[6];
|
||||
if (a) {
|
||||
if (DEBUG) this.assert(this.model >= ChipSet.MODEL_5170);
|
||||
this.assert(this.model >= ChipSet.MODEL_5170);
|
||||
this.bMFGData = a[0];
|
||||
this.abDMAPageSpare = a[1];
|
||||
this.bCMOSAddr = a[2];
|
||||
|
|
@ -1734,7 +1738,7 @@ ChipSet.prototype.initDMAController = function(iDMAC, aState)
|
|||
{
|
||||
var controller = this.aDMACs[iDMAC];
|
||||
if (!controller) {
|
||||
if (DEBUG) this.assert(!aState);
|
||||
this.assert(!aState);
|
||||
controller = {
|
||||
aChannels: new Array(4)
|
||||
};
|
||||
|
|
@ -1765,7 +1769,7 @@ ChipSet.prototype.initDMAChannel = function(controller, iChannel, aState)
|
|||
{
|
||||
var channel = controller.aChannels[iChannel];
|
||||
if (!channel) {
|
||||
if (DEBUG) this.assert(!aState);
|
||||
this.assert(!aState);
|
||||
channel = {
|
||||
addrInit: [0,0],
|
||||
countInit: [0,0],
|
||||
|
|
@ -2041,7 +2045,7 @@ ChipSet.prototype.getSWFloppyDriveType = function(iDrive)
|
|||
return ChipSet.CMOS.FDRIVE.FD1440;
|
||||
}
|
||||
}
|
||||
if (DEBUG) this.assert(false); // we should never get here (else something is out of out sync)
|
||||
this.assert(false); // we should never get here (else something is out of out sync)
|
||||
}
|
||||
return ChipSet.CMOS.FDRIVE.NONE;
|
||||
};
|
||||
|
|
@ -2062,7 +2066,7 @@ ChipSet.prototype.getSWFloppyDriveSize = function(iDrive)
|
|||
if (iDrive < this.aFloppyDrives.length) {
|
||||
return this.aFloppyDrives[iDrive];
|
||||
}
|
||||
if (DEBUG) this.assert(false); // we should never get here (else something is out of out sync)
|
||||
this.assert(false); // we should never get here (else something is out of out sync)
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
|
@ -2285,7 +2289,7 @@ ChipSet.prototype.inDMAChannelAddr = function(iDMAC, iChannel, port, addrFrom)
|
|||
var channel = controller.aChannels[iChannel];
|
||||
var b = channel.addrCurrent[controller.bIndex];
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, null, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".ADDR[" + controller.bIndex + "]", Debugger.MESSAGE.DMA, b);
|
||||
this.messagePort(port, null, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".ADDR[" + controller.bIndex + "]", 0, b);
|
||||
}
|
||||
controller.bIndex ^= 0x1;
|
||||
/*
|
||||
|
|
@ -2322,7 +2326,7 @@ ChipSet.prototype.outDMAChannelAddr = function outDMAChannelAddr(iDMAC, iChannel
|
|||
{
|
||||
var controller = this.aDMACs[iDMAC];
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".ADDR[" + controller.bIndex + "]", Debugger.MESSAGE.DMA);
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".ADDR[" + controller.bIndex + "]");
|
||||
}
|
||||
var channel = controller.aChannels[iChannel];
|
||||
channel.addrCurrent[controller.bIndex] = channel.addrInit[controller.bIndex] = bOut;
|
||||
|
|
@ -2345,7 +2349,7 @@ ChipSet.prototype.inDMAChannelCount = function(iDMAC, iChannel, port, addrFrom)
|
|||
var channel = controller.aChannels[iChannel];
|
||||
var b = channel.countCurrent[controller.bIndex];
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, null, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".COUNT[" + controller.bIndex + "]", Debugger.MESSAGE.DMA, b);
|
||||
this.messagePort(port, null, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".COUNT[" + controller.bIndex + "]", 0, b);
|
||||
}
|
||||
controller.bIndex ^= 0x1;
|
||||
/*
|
||||
|
|
@ -2386,7 +2390,7 @@ ChipSet.prototype.outDMAChannelCount = function(iDMAC, iChannel, port, bOut, add
|
|||
{
|
||||
var controller = this.aDMACs[iDMAC];
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".COUNT[" + controller.bIndex + "]", Debugger.MESSAGE.DMA);
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".COUNT[" + controller.bIndex + "]");
|
||||
}
|
||||
var channel = controller.aChannels[iChannel];
|
||||
channel.countCurrent[controller.bIndex] = channel.countInit[controller.bIndex] = bOut;
|
||||
|
|
@ -2429,7 +2433,7 @@ ChipSet.prototype.inDMAStatus = function(iDMAC, port, addrFrom)
|
|||
var b = controller.bStatus | ChipSet.DMA_STATUS.CH0_TC;
|
||||
controller.bStatus &= ~ChipSet.DMA_STATUS.ALL_TC;
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, null, addrFrom, "DMA" + iDMAC + ".STATUS", Debugger.MESSAGE.DMA, b);
|
||||
this.messagePort(port, null, addrFrom, "DMA" + iDMAC + ".STATUS", 0, b);
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
|
@ -2446,7 +2450,7 @@ ChipSet.prototype.inDMAStatus = function(iDMAC, port, addrFrom)
|
|||
ChipSet.prototype.outDMACmd = function(iDMAC, port, bOut, addrFrom)
|
||||
{
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".CMD", Debugger.MESSAGE.DMA);
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".CMD");
|
||||
}
|
||||
this.aDMACs[iDMAC].bCmd = bOut;
|
||||
};
|
||||
|
|
@ -2474,7 +2478,7 @@ ChipSet.prototype.outDMAReq = function(iDMAC, port, bOut, addrFrom)
|
|||
{
|
||||
var controller = this.aDMACs[iDMAC];
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".REQ", Debugger.MESSAGE.DMA);
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".REQ");
|
||||
}
|
||||
/*
|
||||
* Bits 0-1 contain the channel number
|
||||
|
|
@ -2501,7 +2505,7 @@ ChipSet.prototype.outDMAMask = function(iDMAC, port, bOut, addrFrom)
|
|||
{
|
||||
var controller = this.aDMACs[iDMAC];
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".MASK", Debugger.MESSAGE.DMA);
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".MASK");
|
||||
}
|
||||
var iChannel = bOut & ChipSet.DMA_MASK.CHANNEL;
|
||||
var channel = controller.aChannels[iChannel];
|
||||
|
|
@ -2521,7 +2525,7 @@ ChipSet.prototype.outDMAMask = function(iDMAC, port, bOut, addrFrom)
|
|||
ChipSet.prototype.outDMAMode = function(iDMAC, port, bOut, addrFrom)
|
||||
{
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".MODE", Debugger.MESSAGE.DMA);
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".MODE");
|
||||
}
|
||||
var iChannel = bOut & ChipSet.DMA_MODE.CHANNEL;
|
||||
this.aDMACs[iDMAC].aChannels[iChannel].mode = bOut;
|
||||
|
|
@ -2542,7 +2546,7 @@ ChipSet.prototype.outDMAMode = function(iDMAC, port, bOut, addrFrom)
|
|||
ChipSet.prototype.outDMAResetFF = function(iDMAC, port, bOut, addrFrom)
|
||||
{
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".RESET_FF", Debugger.MESSAGE.DMA);
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".RESET_FF");
|
||||
}
|
||||
this.aDMACs[iDMAC].bIndex = 0;
|
||||
};
|
||||
|
|
@ -2559,7 +2563,7 @@ ChipSet.prototype.outDMAResetFF = function(iDMAC, port, bOut, addrFrom)
|
|||
ChipSet.prototype.outDMAMasterClear = function(iDMAC, port, bOut, addrFrom)
|
||||
{
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".MASTER_CLEAR", Debugger.MESSAGE.DMA);
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".MASTER_CLEAR");
|
||||
}
|
||||
/*
|
||||
* The value written to this port doesn't matter; any write triggers a "master clear" operation
|
||||
|
|
@ -2586,7 +2590,7 @@ ChipSet.prototype.inDMAPageReg = function(iDMAC, iChannel, port, addrFrom)
|
|||
{
|
||||
var bIn = this.aDMACs[iDMAC].aChannels[iChannel].bPage;
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, null, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".PAGE", Debugger.MESSAGE.DMA, bIn);
|
||||
this.messagePort(port, null, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".PAGE", 0, bIn);
|
||||
}
|
||||
return bIn;
|
||||
};
|
||||
|
|
@ -2604,7 +2608,7 @@ ChipSet.prototype.inDMAPageReg = function(iDMAC, iChannel, port, addrFrom)
|
|||
ChipSet.prototype.outDMAPageReg = function(iDMAC, iChannel, port, bOut, addrFrom)
|
||||
{
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".PAGE", Debugger.MESSAGE.DMA);
|
||||
this.messagePort(port, bOut, addrFrom, "DMA" + iDMAC + ".CHANNEL" + iChannel + ".PAGE");
|
||||
}
|
||||
this.aDMACs[iDMAC].aChannels[iChannel].bPage = bOut;
|
||||
};
|
||||
|
|
@ -2622,7 +2626,7 @@ ChipSet.prototype.inDMAPageSpare = function(iSpare, port, addrFrom)
|
|||
{
|
||||
var bIn = this.abDMAPageSpare[iSpare];
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, null, addrFrom, "DMA.SPARE" + iSpare + ".PAGE", Debugger.MESSAGE.DMA, bIn);
|
||||
this.messagePort(port, null, addrFrom, "DMA.SPARE" + iSpare + ".PAGE", 0, bIn);
|
||||
}
|
||||
return bIn;
|
||||
};
|
||||
|
|
@ -2639,7 +2643,7 @@ ChipSet.prototype.inDMAPageSpare = function(iSpare, port, addrFrom)
|
|||
ChipSet.prototype.outDMAPageSpare = function(iSpare, port, bOut, addrFrom)
|
||||
{
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, bOut, addrFrom, "DMA.SPARE" + iSpare + ".PAGE", Debugger.MESSAGE.DMA);
|
||||
this.messagePort(port, bOut, addrFrom, "DMA.SPARE" + iSpare + ".PAGE");
|
||||
}
|
||||
this.abDMAPageSpare[iSpare] = bOut;
|
||||
};
|
||||
|
|
@ -2709,7 +2713,7 @@ ChipSet.prototype.requestDMA = function(iDMAChannel, done)
|
|||
|
||||
if (!channel.component || !channel.fnTransfer || !channel.obj) {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.OTHER)) {
|
||||
this.messageDebugger("requestDMA(" + iDMAChannel + "): not connected to a component", Debugger.MESSAGE.DMA | Debugger.MESSAGE.OTHER);
|
||||
this.messageDebugger("requestDMA(" + iDMAChannel + "): not connected to a component");
|
||||
}
|
||||
if (done) done(true);
|
||||
return;
|
||||
|
|
@ -2726,7 +2730,7 @@ ChipSet.prototype.requestDMA = function(iDMAChannel, done)
|
|||
|
||||
if (channel.masked) {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.OTHER)) {
|
||||
this.messageDebugger("requestDMA(" + iDMAChannel + "): channel masked, request queued", Debugger.MESSAGE.DMA | Debugger.MESSAGE.OTHER);
|
||||
this.messageDebugger("requestDMA(" + iDMAChannel + "): channel masked, request queued");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -2778,8 +2782,8 @@ ChipSet.prototype.advanceDMA = function(channel, fInit)
|
|||
var addr = (channel.bPage << 16) | (channel.addrCurrent[1] << 8) | channel.addrCurrent[0];
|
||||
if (DEBUG && DEBUGGER && channel.sAddrDebug === null) {
|
||||
channel.sAddrDebug = str.toHex(addr >> 4, 4) + ":" + str.toHex(addr & 0xf, 4);
|
||||
if (this.messageEnabled(Debugger.MESSAGE.DMA | (iDMAChannel == ChipSet.DMA_FDC? Debugger.MESSAGE.FDC : (iDMAChannel == ChipSet.DMA_HDC? Debugger.MESSAGE.HDC : 0))) && channel.xfer != ChipSet.DMA_MODE.XFER_WRITE) {
|
||||
this.dbg.message("advanceDMA(" + iDMAChannel + ") transferring " + channel.cbDebug + " bytes from " + channel.sAddrDebug);
|
||||
if (this.messageEnabled(this.messageBitsDMA(iDMAChannel)) && channel.xfer != ChipSet.DMA_MODE.XFER_WRITE) {
|
||||
this.messageDebugger("advanceDMA(" + iDMAChannel + ") transferring " + channel.cbDebug + " bytes from " + channel.sAddrDebug);
|
||||
this.dbg.doDump("db", channel.sAddrDebug, "l" + Math.floor((channel.cbDebug + 15) / 16));
|
||||
}
|
||||
}
|
||||
|
|
@ -2790,7 +2794,7 @@ ChipSet.prototype.advanceDMA = function(channel, fInit)
|
|||
if (b < 0) {
|
||||
if (!channel.fWarning) {
|
||||
if (DEBUG && obj.messageEnabled(Debugger.MESSAGE.DMA)) {
|
||||
obj.messageDebugger("advanceDMA(" + iDMAChannel + ") ran out of data, assuming 0xff", Debugger.MESSAGE.DMA);
|
||||
obj.messageDebugger("advanceDMA(" + iDMAChannel + ") ran out of data, assuming 0xff");
|
||||
}
|
||||
channel.fWarning = true;
|
||||
}
|
||||
|
|
@ -2839,7 +2843,7 @@ ChipSet.prototype.advanceDMA = function(channel, fInit)
|
|||
}
|
||||
else {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.DMA | Debugger.MESSAGE.WARN)) {
|
||||
this.messageDebugger("advanceDMA(" + iDMAChannel + ") unsupported xfer mode: " + str.toHexWord(channel.xfer), Debugger.MESSAGE.DMA | Debugger.MESSAGE.WARN);
|
||||
this.messageDebugger("advanceDMA(" + iDMAChannel + ") unsupported xfer mode: " + str.toHexWord(channel.xfer));
|
||||
}
|
||||
channel.fError = true;
|
||||
}
|
||||
|
|
@ -2892,8 +2896,8 @@ ChipSet.prototype.updateDMA = function(channel)
|
|||
channel.component = channel.obj = null;
|
||||
}
|
||||
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.DMA | (iDMAChannel == ChipSet.DMA_FDC? Debugger.MESSAGE.FDC : (iDMAChannel == ChipSet.DMA_HDC? Debugger.MESSAGE.HDC : 0))) && channel.xfer == ChipSet.DMA_MODE.XFER_WRITE && channel.sAddrDebug) {
|
||||
this.dbg.message("updateDMA(" + iDMAChannel + ") transferred " + channel.cbDebug + " bytes to " + channel.sAddrDebug);
|
||||
if (DEBUG && this.messageEnabled(this.messageBitsDMA(iDMAChannel)) && channel.xfer == ChipSet.DMA_MODE.XFER_WRITE && channel.sAddrDebug) {
|
||||
this.messageDebugger("updateDMA(" + iDMAChannel + ") transferred " + channel.cbDebug + " bytes to " + channel.sAddrDebug);
|
||||
this.dbg.doDump("db", channel.sAddrDebug, "l" + Math.floor((channel.cbDebug + 15) / 16));
|
||||
}
|
||||
|
||||
|
|
@ -2935,7 +2939,7 @@ ChipSet.prototype.inPICLo = function(iPIC, addrFrom)
|
|||
}
|
||||
}
|
||||
if (this.messageEnabled(Debugger.MESSAGE.PIC | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(pic.port, null, addrFrom, "PIC" + iPIC, Debugger.MESSAGE.PIC, b);
|
||||
this.messagePort(pic.port, null, addrFrom, "PIC" + iPIC, 0, b);
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
|
@ -2952,7 +2956,7 @@ ChipSet.prototype.outPICLo = function(iPIC, bOut, addrFrom)
|
|||
{
|
||||
var pic = this.aPICs[iPIC];
|
||||
if (this.messageEnabled(Debugger.MESSAGE.PIC | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(pic.port, bOut, addrFrom, "PIC" + iPIC, Debugger.MESSAGE.PIC);
|
||||
this.messagePort(pic.port, bOut, addrFrom, "PIC" + iPIC);
|
||||
}
|
||||
if (bOut & ChipSet.PIC_LO.ICW1) {
|
||||
/*
|
||||
|
|
@ -3035,23 +3039,23 @@ ChipSet.prototype.outPICLo = function(iPIC, bOut, addrFrom)
|
|||
}
|
||||
var nIRQ = (nIRL == null? undefined : pic.nIRQBase + nIRL);
|
||||
if (pic.bISR & bIREnd) {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.PIC, nIRQ)) {
|
||||
this.messageDebugger("outPIC" + iPIC + "(" + str.toHexByte(pic.port) + "): IRQ " + nIRQ + " going out of service", Debugger.MESSAGE.PIC, nIRQ);
|
||||
if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ))) {
|
||||
this.messageDebugger("outPIC" + iPIC + "(" + str.toHexByte(pic.port) + "): IRQ " + nIRQ + " going out of service");
|
||||
}
|
||||
pic.bISR &= ~bIREnd;
|
||||
this.checkIRR(iPIC);
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.PIC | Debugger.MESSAGE.WARN)) {
|
||||
this.messageDebugger("outPIC" + iPIC + "(" + str.toHexByte(pic.port) + "): unexpected EOI command, IRQ " + nIRQ + " not in service", Debugger.MESSAGE.PIC | Debugger.MESSAGE.WARN);
|
||||
if (this.dbg && !SAMPLER && MAXDEBUG) this.dbg.stopCPU();
|
||||
this.messageDebugger("outPIC" + iPIC + "(" + str.toHexByte(pic.port) + "): unexpected EOI command, IRQ " + nIRQ + " not in service");
|
||||
if (!SAMPLER && MAXDEBUG) this.dbg.stopCPU();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* TODO: Support EOI commands with automatic rotation (eg, ChipSet.PIC_LO.OCW2_EOI_ROT and ChipSet.PIC_LO.OCW2_EOI_ROTSPEC)
|
||||
*/
|
||||
if (DEBUG && (bOCW2 & ChipSet.PIC_LO.OCW2_SET_ROTAUTO) && this.messageEnabled(Debugger.MESSAGE.PIC | Debugger.MESSAGE.WARN)) {
|
||||
this.messageDebugger("outPIC" + iPIC + "(" + str.toHexByte(pic.port) + "): unsupported OCW2 rotate command: " + str.toHexByte(bOut), Debugger.MESSAGE.PIC | Debugger.MESSAGE.WARN);
|
||||
if (this.dbg) this.dbg.stopCPU();
|
||||
this.messageDebugger("outPIC" + iPIC + "(" + str.toHexByte(pic.port) + "): unsupported OCW2 rotate command: " + str.toHexByte(bOut));
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
}
|
||||
else if (bOCW2 == ChipSet.PIC_LO.OCW2_SET_PRI) {
|
||||
|
|
@ -3065,8 +3069,8 @@ ChipSet.prototype.outPICLo = function(iPIC, bOut, addrFrom)
|
|||
* TODO: Remaining commands to support: ChipSet.PIC_LO.OCW2_SET_ROTAUTO and ChipSet.PIC_LO.OCW2_CLR_ROTAUTO
|
||||
*/
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.PIC | Debugger.MESSAGE.WARN)) {
|
||||
this.messageDebugger("outPIC" + iPIC + "(" + str.toHexByte(pic.port) + "): unsupported OCW2 automatic EOI command: " + str.toHexByte(bOut), Debugger.MESSAGE.PIC | Debugger.MESSAGE.WARN);
|
||||
if (this.dbg) this.dbg.stopCPU();
|
||||
this.messageDebugger("outPIC" + iPIC + "(" + str.toHexByte(pic.port) + "): unsupported OCW2 automatic EOI command: " + str.toHexByte(bOut));
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -3078,7 +3082,7 @@ ChipSet.prototype.outPICLo = function(iPIC, bOut, addrFrom)
|
|||
*/
|
||||
if (bOut & (ChipSet.PIC_LO.OCW3_POLL_CMD | ChipSet.PIC_LO.OCW3_SMM_CMD)) {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.PIC | Debugger.MESSAGE.WARN)) {
|
||||
this.messageDebugger("outPIC" + iPIC + "(" + str.toHexByte(pic.port) + "): unsupported OCW3 command: " + str.toHexByte(bOut), Debugger.MESSAGE.PIC | Debugger.MESSAGE.WARN);
|
||||
this.messageDebugger("outPIC" + iPIC + "(" + str.toHexByte(pic.port) + "): unsupported OCW3 command: " + str.toHexByte(bOut));
|
||||
}
|
||||
}
|
||||
pic.bOCW3 = bOut;
|
||||
|
|
@ -3098,7 +3102,7 @@ ChipSet.prototype.inPICHi = function(iPIC, addrFrom)
|
|||
var pic = this.aPICs[iPIC];
|
||||
var b = pic.bIMR;
|
||||
if (this.messageEnabled(Debugger.MESSAGE.PIC | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(pic.port+1, null, addrFrom, "PIC" + iPIC, Debugger.MESSAGE.PIC, b);
|
||||
this.messagePort(pic.port+1, null, addrFrom, "PIC" + iPIC, 0, b);
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
|
@ -3115,7 +3119,7 @@ ChipSet.prototype.outPICHi = function(iPIC, bOut, addrFrom)
|
|||
{
|
||||
var pic = this.aPICs[iPIC];
|
||||
if (this.messageEnabled(Debugger.MESSAGE.PIC | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(pic.port+1, bOut, addrFrom, "PIC" + iPIC, Debugger.MESSAGE.PIC);
|
||||
this.messagePort(pic.port+1, bOut, addrFrom, "PIC" + iPIC);
|
||||
}
|
||||
if (pic.nICW < pic.aICW.length) {
|
||||
pic.aICW[pic.nICW++] = bOut;
|
||||
|
|
@ -3174,8 +3178,8 @@ ChipSet.prototype.setIRR = function(nIRQ, nDelay)
|
|||
var nIRL = nIRQ & 0x7;
|
||||
var pic = this.aPICs[iPIC];
|
||||
pic.bIRR |= 1 << nIRL;
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.PIC, nIRQ)) {
|
||||
this.messageDebugger("setIRR(" + nIRQ + ")", Debugger.MESSAGE.PIC, nIRQ);
|
||||
if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ))) {
|
||||
this.messageDebugger("setIRR(" + nIRQ + ")");
|
||||
}
|
||||
pic.nDelay = nDelay || 0;
|
||||
/*
|
||||
|
|
@ -3199,8 +3203,8 @@ ChipSet.prototype.clearIRR = function(nIRQ)
|
|||
var bIRR = (1 << nIRL);
|
||||
if (pic.bIRR & bIRR) {
|
||||
pic.bIRR &= ~bIRR;
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.PIC, nIRQ)) {
|
||||
this.messageDebugger("clearIRR(" + nIRQ + ")", Debugger.MESSAGE.PIC, nIRQ);
|
||||
if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ))) {
|
||||
this.messageDebugger("clearIRR(" + nIRQ + ")");
|
||||
}
|
||||
/*
|
||||
* When all slave IRRs go low, I'm assuming that the master's slave IRR line should go low as well
|
||||
|
|
@ -3297,8 +3301,8 @@ ChipSet.prototype.getIRRVector = function(iPIC)
|
|||
}
|
||||
|
||||
var nIRQ = pic.nIRQBase + nIRL;
|
||||
if (DEBUG && this.messageEnabled(0, nIRQ)) {
|
||||
this.messageDebugger("getIRRVector(): IRQ " + nIRQ + " interrupting @" + str.toHexAddr(this.cpu.regIP, this.cpu.segCS.sel) + " stack=" + str.toHexAddr(this.cpu.regSP, this.cpu.segSS.sel), 0, nIRQ);
|
||||
if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ))) {
|
||||
this.messageDebugger("getIRRVector(): IRQ " + nIRQ + " interrupting @" + str.toHexAddr(this.cpu.regIP, this.cpu.segCS.sel) + " stack=" + str.toHexAddr(this.cpu.regSP, this.cpu.segSS.sel));
|
||||
}
|
||||
if (MAXDEBUG && DEBUGGER) {
|
||||
this.acInterrupts[nIRQ]++;
|
||||
|
|
@ -3334,7 +3338,7 @@ ChipSet.prototype.inTimer = function(iTimer, addrFrom)
|
|||
this.updateTimer(iTimer);
|
||||
b = timer.countCurrent[timer.countIndex++];
|
||||
if (this.messageEnabled(Debugger.MESSAGE.TIMER | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(ChipSet.TIMER0.PORT + iTimer, null, addrFrom, "TIMER" + iTimer, Debugger.MESSAGE.TIMER, b);
|
||||
this.messagePort(ChipSet.TIMER0.PORT + iTimer, null, addrFrom, "TIMER" + iTimer, 0, b);
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
|
@ -3359,7 +3363,7 @@ ChipSet.prototype.inTimer = function(iTimer, addrFrom)
|
|||
ChipSet.prototype.outTimer = function(iTimer, bOut, addrFrom)
|
||||
{
|
||||
if (this.messageEnabled(Debugger.MESSAGE.TIMER | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(ChipSet.TIMER0.PORT + iTimer, bOut, addrFrom, "TIMER" + iTimer, Debugger.MESSAGE.TIMER);
|
||||
this.messagePort(ChipSet.TIMER0.PORT + iTimer, bOut, addrFrom, "TIMER" + iTimer);
|
||||
}
|
||||
var timer = this.aTimers[iTimer];
|
||||
if (timer.countIndex == timer.countBytes) this.resetTimerIndex(iTimer);
|
||||
|
|
@ -3486,7 +3490,7 @@ ChipSet.prototype.outTimerCtrl = function(port, bOut, addrFrom)
|
|||
timer.countStart[1] = timer.countInit[1];
|
||||
timer.nCyclesStart = this.cpu.getCycles(this.fScaleTimers);
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.TIMER)) {
|
||||
this.messageDebugger("TIMER0 count reset @" + timer.nCyclesStart + " cycles", Debugger.MESSAGE.TIMER);
|
||||
this.messageDebugger("TIMER0 count reset @" + timer.nCyclesStart + " cycles");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3540,11 +3544,11 @@ ChipSet.prototype.getTimerCycleLimit = function(iTimer, nCycles)
|
|||
if (timer.fCounting) {
|
||||
var nCyclesUpdate = this.cpu.getCycles(this.fScaleTimers);
|
||||
var ticksElapsed = ((nCyclesUpdate - timer.nCyclesStart) / this.nTicksDivisor) | 0;
|
||||
if (DEBUG) this.assert(ticksElapsed >= 0);
|
||||
this.assert(ticksElapsed >= 0);
|
||||
var countStart = this.getTimerStart(iTimer);
|
||||
var count = countStart - ticksElapsed;
|
||||
if (timer.mode == ChipSet.TIMER_CTRL.MODE3) count -= ticksElapsed;
|
||||
if (DEBUG) this.assert(count > 0);
|
||||
this.assert(count > 0);
|
||||
var nCyclesRemain = (count * this.nTicksDivisor) | 0;
|
||||
if (timer.mode == ChipSet.TIMER_CTRL.MODE3) nCyclesRemain >>= 1;
|
||||
if (nCycles > nCyclesRemain) nCycles = nCyclesRemain;
|
||||
|
|
@ -3689,7 +3693,7 @@ ChipSet.prototype.updateTimer = function(iTimer, fCycleReset)
|
|||
|
||||
if (ticksElapsed < 0) {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.TIMER)) {
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): negative tick count (" + ticksElapsed + ")", Debugger.MESSAGE.TIMER);
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): negative tick count (" + ticksElapsed + ")");
|
||||
}
|
||||
timer.nCyclesStart = nCycles;
|
||||
ticksElapsed = 0;
|
||||
|
|
@ -3709,7 +3713,7 @@ ChipSet.prototype.updateTimer = function(iTimer, fCycleReset)
|
|||
if (timer.mode == ChipSet.TIMER_CTRL.MODE0) {
|
||||
if (count <= 0) count = 0;
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.TIMER)) {
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): MODE0 timer count=" + count, Debugger.MESSAGE.TIMER);
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): MODE0 timer count=" + count);
|
||||
}
|
||||
if (!count) {
|
||||
timer.fOUT = true;
|
||||
|
|
@ -3744,7 +3748,7 @@ ChipSet.prototype.updateTimer = function(iTimer, fCycleReset)
|
|||
count = countInit + count;
|
||||
if (count <= 0) {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.TIMER)) {
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): underflow=" + count, Debugger.MESSAGE.TIMER);
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): underflow=" + count);
|
||||
}
|
||||
count = countInit;
|
||||
}
|
||||
|
|
@ -3776,7 +3780,7 @@ ChipSet.prototype.updateTimer = function(iTimer, fCycleReset)
|
|||
count = countInit + count;
|
||||
if (count <= 0) {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.TIMER)) {
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): underflow=" + count, Debugger.MESSAGE.TIMER);
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): underflow=" + count);
|
||||
}
|
||||
count = countInit;
|
||||
}
|
||||
|
|
@ -4232,7 +4236,7 @@ ChipSet.prototype.in8042Status = function(port, addrFrom)
|
|||
ChipSet.prototype.out8042InBuffCmd = function(port, bOut, addrFrom)
|
||||
{
|
||||
this.messagePort(port, bOut, addrFrom, "8042_INBUFF.CMD", Debugger.MESSAGE.C8042);
|
||||
if (DEBUG) this.assert(!(this.b8042Status & ChipSet.KBC.STATUS.INBUFF_FULL));
|
||||
this.assert(!(this.b8042Status & ChipSet.KBC.STATUS.INBUFF_FULL));
|
||||
this.b8042InBuff = bOut;
|
||||
|
||||
this.b8042Status |= ChipSet.KBC.STATUS.CMD_FLAG;
|
||||
|
|
@ -4298,8 +4302,8 @@ ChipSet.prototype.out8042InBuffCmd = function(port, bOut, addrFrom)
|
|||
|
||||
default:
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.C8042)) {
|
||||
this.messageDebugger("unrecognized 8042 command: " + str.toHexByte(this.b8042InBuff), Debugger.MESSAGE.C8042);
|
||||
if (this.dbg) this.dbg.stopCPU();
|
||||
this.messageDebugger("unrecognized 8042 command: " + str.toHexByte(this.b8042InBuff));
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -4315,7 +4319,7 @@ ChipSet.prototype.set8042CmdData = function(b)
|
|||
{
|
||||
var bClockWasEnabled = !(this.b8042CmdData & ChipSet.KBC.DATA.CMD.NO_CLOCK);
|
||||
this.b8042CmdData = b;
|
||||
if (DEBUG) this.assert(ChipSet.KBC.DATA.CMD.SYS_FLAG === ChipSet.KBC.STATUS.SYS_FLAG);
|
||||
this.assert(ChipSet.KBC.DATA.CMD.SYS_FLAG === ChipSet.KBC.STATUS.SYS_FLAG);
|
||||
this.b8042Status = (this.b8042Status & ~ChipSet.KBC.STATUS.SYS_FLAG) | (b & ChipSet.KBC.DATA.CMD.SYS_FLAG);
|
||||
if (this.kbd) {
|
||||
/*
|
||||
|
|
@ -4374,9 +4378,9 @@ ChipSet.prototype.set8042OutPort = function(b)
|
|||
* KBC.CMD.PULSE_OUTPORT command, so if a RESET is detected via this command, we should try to
|
||||
* determine if that's what the caller intended.
|
||||
*/
|
||||
if (DEBUG) {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.C8042)) {
|
||||
this.messageDebugger("unexpected 8042 output port reset: " + str.toHexByte(b));
|
||||
if (this.dbg) this.dbg.stopCPU();
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
this.cpu.resetRegs();
|
||||
}
|
||||
|
|
@ -4489,7 +4493,7 @@ ChipSet.prototype.notifyKbdData = function(fAvail)
|
|||
*/
|
||||
ChipSet.prototype.inCMOSAddr = function(port, addrFrom)
|
||||
{
|
||||
this.messagePort(port, null, addrFrom, "CMOS_ADDR", Debugger.MESSAGE.CMOS, this.bCMOSAddr);
|
||||
this.messagePort(port, null, addrFrom, "CMOS.ADDR", Debugger.MESSAGE.CMOS, this.bCMOSAddr);
|
||||
return this.bCMOSAddr;
|
||||
};
|
||||
|
||||
|
|
@ -4503,7 +4507,7 @@ ChipSet.prototype.inCMOSAddr = function(port, addrFrom)
|
|||
*/
|
||||
ChipSet.prototype.outCMOSAddr = function(port, bOut, addrFrom)
|
||||
{
|
||||
this.messagePort(port, bOut, addrFrom, "CMOS_ADDR", Debugger.MESSAGE.CMOS);
|
||||
this.messagePort(port, bOut, addrFrom, "CMOS.ADDR", Debugger.MESSAGE.CMOS);
|
||||
this.bCMOSAddr = bOut;
|
||||
this.bNMI = (bOut & ChipSet.CMOS.ADDR.NMI_DISABLE)? ChipSet.NMI.DISABLE : ChipSet.NMI.ENABLE;
|
||||
};
|
||||
|
|
@ -4521,7 +4525,7 @@ ChipSet.prototype.inCMOSData = function(port, addrFrom)
|
|||
var bAddr = this.bCMOSAddr & ChipSet.CMOS.ADDR.MASK;
|
||||
var bIn = (bAddr <= ChipSet.CMOS.ADDR.STATUSD? this.getRTCByte(bAddr) : this.abCMOSData[bAddr]);
|
||||
if (this.messageEnabled(Debugger.MESSAGE.CMOS | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, null, addrFrom, "CMOS_DATA[" + str.toHexByte(bAddr) + "]", Debugger.MESSAGE.CMOS, bIn);
|
||||
this.messagePort(port, null, addrFrom, "CMOS.DATA[" + str.toHexByte(bAddr) + "]", 0, bIn);
|
||||
}
|
||||
if (addrFrom != null) {
|
||||
if (bAddr == ChipSet.CMOS.ADDR.STATUSC) {
|
||||
|
|
@ -4556,7 +4560,7 @@ ChipSet.prototype.outCMOSData = function(port, bOut, addrFrom)
|
|||
{
|
||||
var bAddr = this.bCMOSAddr & ChipSet.CMOS.ADDR.MASK;
|
||||
if (this.messageEnabled(Debugger.MESSAGE.CMOS | Debugger.MESSAGE.PORT)) {
|
||||
this.messagePort(port, bOut, addrFrom, "CMOS_DATA[" + str.toHexByte(bAddr) + "]", Debugger.MESSAGE.CMOS);
|
||||
this.messagePort(port, bOut, addrFrom, "CMOS.DATA[" + str.toHexByte(bAddr) + "]");
|
||||
}
|
||||
var bDelta = bOut ^ this.abCMOSData[bAddr];
|
||||
this.abCMOSData[bAddr] = (bAddr <= ChipSet.CMOS.ADDR.STATUSD? this.setRTCByte(bAddr, bOut) : bOut);
|
||||
|
|
@ -4708,7 +4712,7 @@ ChipSet.prototype.setSpeaker = function(fOn)
|
|||
if (this.sourceAudio) {
|
||||
this.sourceAudio['frequency']['value'] = freq;
|
||||
if (this.messageEnabled(Debugger.MESSAGE.SPEAKER)) {
|
||||
this.messageDebugger("speaker set to " + freq + "hz", Debugger.MESSAGE.SPEAKER);
|
||||
this.messageDebugger("speaker set to " + freq + "hz");
|
||||
}
|
||||
} else {
|
||||
this.sourceAudio = this.contextAudio['createOscillator']();
|
||||
|
|
@ -4716,7 +4720,7 @@ ChipSet.prototype.setSpeaker = function(fOn)
|
|||
this.sourceAudio['connect'](this.contextAudio['destination']);
|
||||
this.sourceAudio['frequency']['value'] = freq;
|
||||
if (this.messageEnabled(Debugger.MESSAGE.SPEAKER)) {
|
||||
this.messageDebugger("speaker on at " + freq + "hz", Debugger.MESSAGE.SPEAKER);
|
||||
this.messageDebugger("speaker on at " + freq + "hz");
|
||||
}
|
||||
this.sourceAudio['noteOn'](0); // aka start()
|
||||
}
|
||||
|
|
@ -4726,7 +4730,7 @@ ChipSet.prototype.setSpeaker = function(fOn)
|
|||
this.sourceAudio['disconnect'](); // QUESTION: is this automatic following a stop(), since this particular source cannot be started again?
|
||||
delete this.sourceAudio; // QUESTION: ditto?
|
||||
if (this.messageEnabled(Debugger.MESSAGE.SPEAKER)) {
|
||||
this.messageDebugger("speaker off at " + freq + "hz", Debugger.MESSAGE.SPEAKER);
|
||||
this.messageDebugger("speaker off at " + freq + "hz");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4736,69 +4740,41 @@ ChipSet.prototype.setSpeaker = function(fOn)
|
|||
};
|
||||
|
||||
/**
|
||||
* messageEnabled(bitsMessage, nIRQ)
|
||||
* messageBitsDMA(iChannel)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @param {number} [iChannel] if the message is associated with a particular IRQ #
|
||||
* @return {number}
|
||||
*/
|
||||
ChipSet.prototype.messageBitsDMA = function(iChannel)
|
||||
{
|
||||
var bitsMessage = Debugger.MESSAGE.DMA;
|
||||
if (iChannel == ChipSet.DMA_FDC) {
|
||||
bitsMessage |= Debugger.MESSAGE.FDC;
|
||||
} else if (iChannel == ChipSet.DMA_HDC) {
|
||||
bitsMessage |= Debugger.MESSAGE.HDC;
|
||||
}
|
||||
return bitsMessage;
|
||||
};
|
||||
|
||||
/**
|
||||
* messageBitsIRQ(nIRQ)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
* @param {number|undefined} [nIRQ] if the message is associated with a particular IRQ #
|
||||
* @return {boolean}
|
||||
* @return {number}
|
||||
*/
|
||||
ChipSet.prototype.messageEnabled = function(bitsMessage, nIRQ)
|
||||
ChipSet.prototype.messageBitsIRQ = function(nIRQ)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage == null) {
|
||||
bitsMessage = Debugger.MESSAGE.CHIPSET;
|
||||
}
|
||||
if (nIRQ !== undefined) {
|
||||
bitsMessage |= (nIRQ == ChipSet.IRQ.TIMER0? Debugger.MESSAGE.TIMER : (nIRQ == ChipSet.IRQ.KBD? Debugger.MESSAGE.KBD : (nIRQ == ChipSet.IRQ.FDC? Debugger.MESSAGE.FDC : 0))) | Debugger.MESSAGE.PIC;
|
||||
}
|
||||
return this.dbg.messageEnabled(bitsMessage);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* messageDebugger(sMessage, bitsMessage, nIRQ)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
* @param {number} [nIRQ] if the message is associated with a particular IRQ #
|
||||
*
|
||||
* This is a combination of the Debugger's messageEnabled() and message() functions, for convenience.
|
||||
*
|
||||
* NOTE: If the caller specifies multiple MESSAGE category flags, then ALL the corresponding message
|
||||
* categories in the Debugger must be enabled as well, else the message will not be displayed.
|
||||
*/
|
||||
ChipSet.prototype.messageDebugger = function(sMessage, bitsMessage, nIRQ)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (this.messageEnabled(bitsMessage, nIRQ)) this.dbg.message(sMessage);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* messagePort(port, bOut, addrFrom, name, bitsMessage, bIn)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @param {number} port
|
||||
* @param {number|null} bOut if an output operation
|
||||
* @param {number|null} [addrFrom]
|
||||
* @param {string|null} [name] of the port, if any
|
||||
* @param {number|null} [bitsMessage] is one or more a Debugger MESSAGE_* category flag(s)
|
||||
* @param {number} [bIn] is the input value, if known, on an input operation
|
||||
*
|
||||
* This is an internal version of the Debugger's messagePort() function, for convenience.
|
||||
*
|
||||
* NOTE: If the caller specifies multiple MESSAGE category flags, then ALL the corresponding message
|
||||
* categories in the Debugger must be enabled as well, else the message will not be displayed.
|
||||
*/
|
||||
ChipSet.prototype.messagePort = function(port, bOut, addrFrom, name, bitsMessage, bIn)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage == null) bitsMessage = Debugger.MESSAGE.CHIPSET;
|
||||
this.dbg.messagePort(this, port, bOut, addrFrom, name, bitsMessage, bIn);
|
||||
var bitsMessage = Debugger.MESSAGE.PIC;
|
||||
if (nIRQ == ChipSet.IRQ.TIMER0) {
|
||||
bitsMessage |= Debugger.MESSAGE.TIMER;
|
||||
} else if (nIRQ == ChipSet.IRQ.KBD) {
|
||||
bitsMessage |= Debugger.MESSAGE.KBD;
|
||||
} else if (nIRQ == ChipSet.IRQ.FDC) {
|
||||
bitsMessage |= Debugger.MESSAGE.FDC;
|
||||
}
|
||||
return bitsMessage;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ if (typeof module !== 'undefined') {
|
|||
*/
|
||||
function Computer(parmsComputer, parmsMachine, fSuspended) {
|
||||
|
||||
Component.call(this, "Computer", parmsComputer, Computer);
|
||||
Component.call(this, "Computer", parmsComputer, Computer, Debugger.MESSAGE.COMPUTER);
|
||||
|
||||
this.bitField.fPowered = false;
|
||||
this.nBusWidth = parmsComputer['buswidth'];
|
||||
|
|
@ -174,7 +174,7 @@ function Computer(parmsComputer, parmsMachine, fSuspended) {
|
|||
}
|
||||
}
|
||||
|
||||
if (DEBUG) this.messageDebugger("PREFETCH: " + PREFETCH + ", TYPEDARRAYS: " + TYPEDARRAYS);
|
||||
if (DEBUG && this.messageEnabled()) this.messageDebugger("PREFETCH: " + PREFETCH + ", TYPEDARRAYS: " + TYPEDARRAYS);
|
||||
|
||||
/*
|
||||
* Iterate through all the components again and call their initBus() handler, if any
|
||||
|
|
@ -319,7 +319,9 @@ Computer.prototype.onLoadSetReady = function(sStateFile, sStateData, nErrorCode)
|
|||
{
|
||||
if (!nErrorCode) {
|
||||
this.sStateData = sStateData;
|
||||
if (DEBUG) this.messageDebugger("loaded state file " + sStateFile.replace(this.sUserID || "xxx", "xxx"));
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("loaded state file " + sStateFile.replace(this.sUserID || "xxx", "xxx"));
|
||||
}
|
||||
} else {
|
||||
this.sResumePath = null;
|
||||
this.fServerState = false;
|
||||
|
|
@ -360,7 +362,7 @@ Computer.prototype.wait = function(fn, parms)
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (DEBUG) this.messageDebugger("Computer.wait(ready)");
|
||||
if (DEBUG && this.messageEnabled()) this.messageDebugger("Computer.wait(ready)");
|
||||
fn.call(this, parms);
|
||||
};
|
||||
|
||||
|
|
@ -385,7 +387,9 @@ Computer.prototype.validateState = function(stateComputer)
|
|||
fValid = false;
|
||||
if (!stateComputer) stateValidate.clear();
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger("Last state: " + sTimestampComputer + " (validate: " + sTimestampValidate + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Last state: " + sTimestampComputer + " (validate: " + sTimestampValidate + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
return fValid;
|
||||
|
|
@ -405,7 +409,9 @@ Computer.prototype.powerOn = function(resume)
|
|||
resume = this.resume || (this.sStateData? Computer.RESUME_AUTO : Computer.RESUME_NONE);
|
||||
}
|
||||
|
||||
if (DEBUG) this.messageDebugger("Computer.powerOn(" + (resume == Computer.RESUME_REPOWER ? "repower" : (resume ? "resume" : "")) + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Computer.powerOn(" + (resume == Computer.RESUME_REPOWER ? "repower" : (resume ? "resume" : "")) + ")");
|
||||
}
|
||||
|
||||
var fRepower = false;
|
||||
var fRestore = false;
|
||||
|
|
@ -642,7 +648,9 @@ Computer.prototype.donePowerOn = function(aParms)
|
|||
var fRepower = (aParms[1] < 0);
|
||||
var fRestore = aParms[2];
|
||||
|
||||
if (DEBUG && this.bitField.fPowered) this.messageDebugger("Computer.donePowerOn(): redundant");
|
||||
if (DEBUG && this.bitField.fPowered && this.messageEnabled()) {
|
||||
this.messageDebugger("Computer.donePowerOn(): redundant");
|
||||
}
|
||||
|
||||
this.bitField.fPowered = true;
|
||||
|
||||
|
|
@ -726,7 +734,9 @@ Computer.prototype.powerOff = function(fSave, fShutdown)
|
|||
var data;
|
||||
var sState = "none";
|
||||
|
||||
if (DEBUG) this.messageDebugger("Computer.powerOff(" + (fSave ? "save" : "nosave") + (fShutdown ? ",shutdown" : "") + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Computer.powerOff(" + (fSave ? "save" : "nosave") + (fShutdown ? ",shutdown" : "") + ")");
|
||||
}
|
||||
|
||||
var stateComputer = new State(this, Computer.sAppVer);
|
||||
var stateValidate = new State(this, Computer.sAppVer, Computer.STATE_VALIDATE);
|
||||
|
|
@ -832,14 +842,14 @@ Computer.prototype.powerOff = function(fSave, fShutdown)
|
|||
Computer.prototype.reset = function()
|
||||
{
|
||||
if (this.bus && this.bus.reset) {
|
||||
this.messageDebugger("Resetting " + this.bus.type, true);
|
||||
this.messageDebugger("Resetting " + this.bus.type);
|
||||
this.bus.reset();
|
||||
}
|
||||
var aComponents = Component.getComponents(this.id);
|
||||
for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {
|
||||
var component = aComponents[iComponent];
|
||||
if (component !== this && component !== this.bus && component.reset) {
|
||||
this.messageDebugger("Resetting " + component.type, true);
|
||||
this.messageDebugger("Resetting " + component.type);
|
||||
component.reset();
|
||||
}
|
||||
}
|
||||
|
|
@ -978,7 +988,8 @@ Computer.prototype.queryUserID = function(fPrompt)
|
|||
Computer.prototype.verifyUserID = function(sUserID)
|
||||
{
|
||||
this.sUserID = null;
|
||||
if (DEBUG) this.messageDebugger("verifyUserID(" + sUserID + ")");
|
||||
var fMessages = DEBUG && this.messageEnabled();
|
||||
if (fMessages) this.messageDebugger("verifyUserID(" + sUserID + ")");
|
||||
var sRequest = web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUserID;
|
||||
var response = web.loadResource(sRequest);
|
||||
var nErrorCode = response[0];
|
||||
|
|
@ -988,16 +999,16 @@ Computer.prototype.verifyUserID = function(sUserID)
|
|||
response = eval("(" + sResponse + ")");
|
||||
if (response.code && response.code == UserAPI.CODE.OK) {
|
||||
web.setLocalStorageItem(Computer.STATE_USERID, response.data);
|
||||
if (DEBUG) this.messageDebugger(Computer.STATE_USERID + " updated: " + response.data);
|
||||
if (fMessages) this.messageDebugger(Computer.STATE_USERID + " updated: " + response.data);
|
||||
this.sUserID = response.data;
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger(response.code + ": " + response.data);
|
||||
if (fMessages) this.messageDebugger(response.code + ": " + response.data);
|
||||
}
|
||||
} catch (e) {
|
||||
Component.error(e.message + " (" + sResponse + ")");
|
||||
}
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger("invalid response (error " + nErrorCode + ")");
|
||||
if (fMessages) this.messageDebugger("invalid response (error " + nErrorCode + ")");
|
||||
}
|
||||
return this.sUserID;
|
||||
};
|
||||
|
|
@ -1012,10 +1023,14 @@ Computer.prototype.getServerStatePath = function()
|
|||
{
|
||||
var sStatePath = null;
|
||||
if (this.sUserID) {
|
||||
if (DEBUG) this.messageDebugger(Computer.STATE_USERID + " for load: " + this.sUserID);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger(Computer.STATE_USERID + " for load: " + this.sUserID);
|
||||
}
|
||||
sStatePath = web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.LOAD + '&' + UserAPI.QUERY.USER + '=' + this.sUserID + '&' + UserAPI.QUERY.STATE + '=' + State.key(this, Computer.sAppVer);
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger(Computer.STATE_USERID + " unavailable");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger(Computer.STATE_USERID + " unavailable");
|
||||
}
|
||||
}
|
||||
return sStatePath;
|
||||
};
|
||||
|
|
@ -1035,7 +1050,9 @@ Computer.prototype.saveServerState = function(sUserID, sState)
|
|||
* tend to blow off alerts() and the like when closing down.
|
||||
*/
|
||||
if (sState) {
|
||||
if (DEBUG) this.messageDebugger("size of server state: " + sState.length + " bytes");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("size of server state: " + sState.length + " bytes");
|
||||
}
|
||||
var response = this.storeServerState(sUserID, sState, true);
|
||||
if (response && response[UserAPI.RES.CODE] == UserAPI.CODE.OK) {
|
||||
this.notice("Machine state saved to server");
|
||||
|
|
@ -1050,7 +1067,9 @@ Computer.prototype.saveServerState = function(sUserID, sState)
|
|||
this.resetUserID();
|
||||
}
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger("no state to store");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("no state to store");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1065,7 +1084,9 @@ Computer.prototype.saveServerState = function(sUserID, sState)
|
|||
*/
|
||||
Computer.prototype.storeServerState = function(sUserID, sState, fSync)
|
||||
{
|
||||
if (DEBUG) this.messageDebugger(Computer.STATE_USERID + " for store: " + sUserID);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger(Computer.STATE_USERID + " for store: " + sUserID);
|
||||
}
|
||||
/*
|
||||
* TODO: Determine whether or not any browsers cancel our request if we're called during a browser "shutdown" event,
|
||||
* and whether or not it matters if we do an async request (currently, we're not, to try to ensure the request goes through).
|
||||
|
|
@ -1089,7 +1110,7 @@ Computer.prototype.storeServerState = function(sUserID, sState, fSync)
|
|||
}
|
||||
sResponse = '{"' + UserAPI.RES.CODE + '":' + response[0] + ',"' + UserAPI.RES.DATA + '":"' + sResponse + '"}';
|
||||
}
|
||||
if (DEBUG) this.messageDebugger(sResponse);
|
||||
if (DEBUG && this.messageEnabled()) this.messageDebugger(sResponse);
|
||||
return JSON.parse(sResponse);
|
||||
}
|
||||
return null;
|
||||
|
|
@ -1165,22 +1186,6 @@ Computer.prototype.getComponentByType = function(sType, componentPrev)
|
|||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* messageDebugger(sMessage, fForce)
|
||||
*
|
||||
* This is a combination of the Debugger's messageEnabled(MESSAGE_COMPUTER) and message() functions, for convenience.
|
||||
*
|
||||
* @this {Computer}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
* @param {boolean} [fForce] is true to force display of the message
|
||||
*/
|
||||
Computer.prototype.messageDebugger = function(sMessage, fForce)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (fForce || this.dbg.messageEnabled(Debugger.MESSAGE.COMPUTER)) this.dbg.message(sMessage);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Computer.init()
|
||||
*
|
||||
|
|
@ -1213,7 +1218,9 @@ Computer.init = function()
|
|||
*/
|
||||
var computer = new Computer(parmsComputer, parmsMachine, true);
|
||||
|
||||
if (DEBUG) computer.messageDebugger("onInit(" + computer.bitField.fPowered + ")");
|
||||
if (DEBUG && computer.messageEnabled()) {
|
||||
computer.messageDebugger("onInit(" + computer.bitField.fPowered + ")");
|
||||
}
|
||||
|
||||
/*
|
||||
* For now, all we support are "reset" and "save" buttons. We may eventually add a "power"
|
||||
|
|
@ -1243,7 +1250,9 @@ Computer.show = function()
|
|||
var computer = Component.getComponentByType("Computer", parmsComputer['id']);
|
||||
if (computer) {
|
||||
|
||||
if (DEBUG) computer.messageDebugger("onShow(" + computer.fInitialized + "," + computer.bitField.fPowered + ")");
|
||||
if (DEBUG && computer.messageEnabled()) {
|
||||
computer.messageDebugger("onShow(" + computer.fInitialized + "," + computer.bitField.fPowered + ")");
|
||||
}
|
||||
|
||||
if (computer.fInitialized && !computer.bitField.fPowered) {
|
||||
/**
|
||||
|
|
@ -1290,7 +1299,9 @@ Computer.exit = function()
|
|||
var computer = Component.getComponentByType("Computer", parmsComputer['id']);
|
||||
if (computer) {
|
||||
|
||||
if (DEBUG) computer.messageDebugger("onExit(" + computer.bitField.fPowered + ")");
|
||||
if (DEBUG && computer.messageEnabled()) {
|
||||
computer.messageDebugger("onExit(" + computer.bitField.fPowered + ")");
|
||||
}
|
||||
|
||||
if (computer.bitField.fPowered) {
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ if (typeof module !== 'undefined') {
|
|||
*/
|
||||
function CPU(parmsCPU, nCyclesDefault)
|
||||
{
|
||||
Component.call(this, "CPU", parmsCPU, CPU);
|
||||
Component.call(this, "CPU", parmsCPU, CPU, Debugger.MESSAGE.CPU);
|
||||
|
||||
var nCycles = parmsCPU['cycles'] || nCyclesDefault;
|
||||
|
||||
|
|
@ -865,7 +865,7 @@ CPU.prototype.calcStartTime = function()
|
|||
* in case, I make absolutely sure it cannot happen, since doing so could result in negative
|
||||
* speed calculations.
|
||||
*/
|
||||
if (DEBUG) this.assert(this.aCounts.msStartRun <= this.aCounts.msStartThisRun);
|
||||
this.assert(this.aCounts.msStartRun <= this.aCounts.msStartThisRun);
|
||||
if (this.aCounts.msStartRun > this.aCounts.msStartThisRun) {
|
||||
this.aCounts.msStartRun = this.aCounts.msStartThisRun;
|
||||
}
|
||||
|
|
@ -936,7 +936,7 @@ CPU.prototype.calcRemainingTime = function()
|
|||
*/
|
||||
this.aCounts.nCyclesRecalc += this.aCounts.nCyclesThisRun;
|
||||
|
||||
if (DEBUG && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.LOG) && msRemainsThisRun) {
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.LOG) && msRemainsThisRun) {
|
||||
this.log("calcRemainingTime: " + msRemainsThisRun + "ms to sleep after " + this.aCounts.msEndThisRun + "ms");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1558,14 +1558,15 @@ if (DEBUGGER) {
|
|||
*/
|
||||
Debugger.prototype.initMessages = function(sEnable)
|
||||
{
|
||||
this.afnDumpers = [];
|
||||
this.bitsMessageEnabled = Debugger.MESSAGE.WARN;
|
||||
this.dbg = this;
|
||||
this.bitsMessage = this.bitsWarning = Debugger.MESSAGE.WARN;
|
||||
this.sMessagePrev = null;
|
||||
this.afnDumpers = [];
|
||||
var aEnable = this.parseCommand(sEnable);
|
||||
if (aEnable.length) {
|
||||
for (var m in Debugger.MESSAGES) {
|
||||
if (aEnable.indexOf(m) >= 0) {
|
||||
this.bitsMessageEnabled |= Debugger.MESSAGES[m];
|
||||
this.bitsMessage |= Debugger.MESSAGES[m];
|
||||
this.println(m + " messages enabled");
|
||||
}
|
||||
}
|
||||
|
|
@ -1591,24 +1592,6 @@ if (DEBUGGER) {
|
|||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* messageEnabled(bitsMessage)
|
||||
*
|
||||
* NOTE: If the caller specifies multiple MESSAGE category flags, then ALL the corresponding flags
|
||||
* in the Debugger's bitsMessageEnabled variable must be enabled as well, else the result will be false.
|
||||
*
|
||||
* One wrinkle is MESSAGE.WARN: if that category is enabled, then ANY value with that bit will return true.
|
||||
*
|
||||
* @this {Debugger}
|
||||
* @param {number} bitsMessage is one or more Debugger MESSAGE_* category flag(s)
|
||||
* @return {boolean} true if message category is enabled, false if not
|
||||
*/
|
||||
Debugger.prototype.messageEnabled = function(bitsMessage)
|
||||
{
|
||||
var bitsEnabled = this.bitsMessageEnabled & bitsMessage;
|
||||
return (bitsEnabled === bitsMessage || !!(bitsEnabled & Debugger.MESSAGE.WARN));
|
||||
};
|
||||
|
||||
/**
|
||||
* messageRegs()
|
||||
*
|
||||
|
|
@ -1652,8 +1635,8 @@ if (DEBUGGER) {
|
|||
{
|
||||
var nCategory = Debugger.INT_MESSAGE[nInt];
|
||||
var fMessage = nCategory && this.messageEnabled(nCategory);
|
||||
var AH = this.cpu.regAX >> 8;
|
||||
if (fMessage) {
|
||||
var AH = this.cpu.regAX >> 8;
|
||||
var DL = this.cpu.regDX & 0xff;
|
||||
if (nInt == Debugger.INT.DOS && AH == 0x0b ||
|
||||
nCategory == Debugger.MESSAGE.FDC && DL >= 0x80 || nCategory == Debugger.MESSAGE.HDC && DL < 0x80) {
|
||||
|
|
@ -1693,31 +1676,7 @@ if (DEBUGGER) {
|
|||
};
|
||||
|
||||
/**
|
||||
* messageMem(component, addr, fWrite, addrFrom, name, bitsMessage)
|
||||
*
|
||||
* NOTE: Not currently used
|
||||
*
|
||||
* @this {Debugger}
|
||||
* @param {Component} component
|
||||
* @param {number} addr
|
||||
* @param {boolean} fWrite is true if this was a write, false if read
|
||||
* @param {number|null} [addrFrom]
|
||||
* @param {string|null} [name] of the memory address, if any
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
*
|
||||
Debugger.prototype.messageMem = function(component, addr, fWrite, addrFrom, name, bitsMessage)
|
||||
{
|
||||
if (!bitsMessage) bitsMessage = 0;
|
||||
bitsMessage |= Debugger.MESSAGES_MEM;
|
||||
if (addrFrom == null || (this.bitsMessageEnabled & bitsMessage) == bitsMessage) {
|
||||
var b = this.bus.getByteDirect(addr);
|
||||
this.message(component.idComponent + "." + (fWrite? "setByte" : "getByte") + "(0x" + str.toHexAddr(addr) + ")" + (addrFrom != null? (" at " + str.toHexAddr(addrFrom)) : "") + ": " + (name? (name + "=") : "") + str.toHexByte(b));
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
/**
|
||||
* messagePort(component, port, bOut, addrFrom, name, bitsMessage, bIn)
|
||||
* messageIO(component, port, bOut, addrFrom, name, bIn, bitsMessage)
|
||||
*
|
||||
* @this {Debugger}
|
||||
* @param {Component} component
|
||||
|
|
@ -1725,14 +1684,14 @@ if (DEBUGGER) {
|
|||
* @param {number|null} bOut if an output operation
|
||||
* @param {number|null} [addrFrom]
|
||||
* @param {string|null} [name] of the port, if any
|
||||
* @param {number|null} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
* @param {number} [bIn] is the input value, if known, on an input operation
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
*/
|
||||
Debugger.prototype.messagePort = function(component, port, bOut, addrFrom, name, bitsMessage, bIn)
|
||||
Debugger.prototype.messageIO = function(component, port, bOut, addrFrom, name, bIn, bitsMessage)
|
||||
{
|
||||
if (!bitsMessage) bitsMessage = 0;
|
||||
bitsMessage |= Debugger.MESSAGE.PORT;
|
||||
if (addrFrom == null || (this.bitsMessageEnabled & bitsMessage) == bitsMessage) {
|
||||
if (addrFrom == null || (this.bitsMessage & bitsMessage) == bitsMessage) {
|
||||
var segFrom = null;
|
||||
if (addrFrom != null) {
|
||||
segFrom = this.cpu.segCS.sel;
|
||||
|
|
@ -1743,13 +1702,18 @@ if (DEBUGGER) {
|
|||
};
|
||||
|
||||
/**
|
||||
* message(sMessage)
|
||||
* message(sMessage, fAddress)
|
||||
*
|
||||
* @this {Debugger}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
* @param {boolean} [fAddress] is true to display the current CS:IP
|
||||
*/
|
||||
Debugger.prototype.message = function(sMessage)
|
||||
Debugger.prototype.message = function(sMessage, fAddress)
|
||||
{
|
||||
if (fAddress) {
|
||||
sMessage += " @" + str.toHexAddr(this.cpu.regIP, this.cpu.segCS.sel);
|
||||
}
|
||||
|
||||
if (this.sMessagePrev && sMessage == this.sMessagePrev) return;
|
||||
|
||||
if (!SAMPLER) this.println(sMessage); // + " (" + this.cpu.getCycles() + " cycles)"
|
||||
|
|
@ -1757,7 +1721,7 @@ if (DEBUGGER) {
|
|||
this.sMessagePrev = sMessage;
|
||||
|
||||
if (this.cpu) {
|
||||
if (this.bitsMessageEnabled & Debugger.MESSAGE.HALT) {
|
||||
if (this.bitsMessage & Debugger.MESSAGE.HALT) {
|
||||
this.cpu.stopCPU();
|
||||
}
|
||||
/*
|
||||
|
|
@ -2073,7 +2037,7 @@ if (DEBUGGER) {
|
|||
var state = new State(this);
|
||||
state.set(0, this.aAddrNextCode);
|
||||
state.set(1, this.aAddrAssemble);
|
||||
state.set(2, [this.aPrevCmds, this.fAssemble, this.bitsMessageEnabled]);
|
||||
state.set(2, [this.aPrevCmds, this.fAssemble, this.bitsMessage]);
|
||||
return state.data();
|
||||
};
|
||||
|
||||
|
|
@ -2095,16 +2059,16 @@ if (DEBUGGER) {
|
|||
this.aPrevCmds = data[i][0];
|
||||
if (typeof this.aPrevCmds == "string") this.aPrevCmds = [this.aPrevCmds];
|
||||
this.fAssemble = data[i][1];
|
||||
if (!this.bitsMessageEnabled) {
|
||||
if (!this.bitsMessage) {
|
||||
/*
|
||||
* It's actually kinda annoying that a restored (or predefined) state will trump my initial state,
|
||||
* It's actually kind of annoying that a restored (or predefined) state will trump my initial state,
|
||||
* at least in situations where I've changed the initial state, if I want to diagnose something.
|
||||
* Perhaps I should save/restore both the initial and current bitsMessageEnabled, and if the initial
|
||||
* values don't agree, then leave the current value alone.
|
||||
*
|
||||
* But, it's much easier to just leave bitsMessageEnabled alone whenever it already contains set bits.
|
||||
*/
|
||||
this.bitsMessageEnabled = data[i][2];
|
||||
this.bitsMessage = data[i][2];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -2213,12 +2177,8 @@ if (DEBUGGER) {
|
|||
*/
|
||||
Debugger.prototype.checkInstruction = function(addr, fSkipBP)
|
||||
{
|
||||
/*
|
||||
* Assert that general-purpose register contents remain within their respective ranges;
|
||||
* this isn't intended to be complete, just a spot-check.
|
||||
*/
|
||||
if (DEBUG) {
|
||||
this.assert(!(this.cpu.regAX & ~0xffff) && !(this.cpu.regBX & ~0xffff) && !(this.cpu.regCX & ~0xffff) && !(this.cpu.regDX & ~0xffff), "register out of bounds");
|
||||
if (!fSkipBP && this.cpu.segCS.cpl == 3 && !(this.cpu.regPS & X86.PS.IF)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!fSkipBP && this.checkBreakpoint(addr, this.aBreakExec)) {
|
||||
|
|
@ -2410,7 +2370,7 @@ if (DEBUGGER) {
|
|||
var addr = this.getAddr(aAddr, false, 0);
|
||||
if (addr >= 0) {
|
||||
b = this.bus.getByteDirect(addr);
|
||||
if (DEBUG) this.assert((b == (b & 0xff)), "invalid byte (" + b + ") at address: " + this.hexAddr(aAddr));
|
||||
this.assert((b == (b & 0xff)), "invalid byte (" + b + ") at address: " + this.hexAddr(aAddr));
|
||||
if (inc !== undefined) this.incAddr(aAddr, inc);
|
||||
}
|
||||
return b;
|
||||
|
|
@ -2430,7 +2390,7 @@ if (DEBUGGER) {
|
|||
var addr = this.getAddr(aAddr, false, 1);
|
||||
if (addr >= 0) {
|
||||
w = this.bus.getWordDirect(addr);
|
||||
if (DEBUG) this.assert((w == (w & 0xffff)), "invalid word (" + w + ") at address: " + this.hexAddr(aAddr));
|
||||
this.assert((w == (w & 0xffff)), "invalid word (" + w + ") at address: " + this.hexAddr(aAddr));
|
||||
if (inc !== undefined) this.incAddr(aAddr, inc);
|
||||
}
|
||||
return w;
|
||||
|
|
@ -4181,7 +4141,7 @@ if (DEBUGGER) {
|
|||
for (m in Debugger.MESSAGES) {
|
||||
if (sCategory == m) {
|
||||
bitsMessage = Debugger.MESSAGES[m];
|
||||
fCriteria = !!(this.bitsMessageEnabled & bitsMessage);
|
||||
fCriteria = !!(this.bitsMessage & bitsMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -4192,11 +4152,11 @@ if (DEBUGGER) {
|
|||
}
|
||||
if (bitsMessage) {
|
||||
if (asArgs[2] == "on") {
|
||||
this.bitsMessageEnabled |= bitsMessage;
|
||||
this.bitsMessage |= bitsMessage;
|
||||
fCriteria = true;
|
||||
}
|
||||
else if (asArgs[2] == "off") {
|
||||
this.bitsMessageEnabled &= ~bitsMessage;
|
||||
this.bitsMessage &= ~bitsMessage;
|
||||
fCriteria = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -4210,7 +4170,7 @@ if (DEBUGGER) {
|
|||
for (m in Debugger.MESSAGES) {
|
||||
if (!sCategory || sCategory == m) {
|
||||
var bitMessage = Debugger.MESSAGES[m];
|
||||
var fEnabled = !!(this.bitsMessageEnabled & bitMessage);
|
||||
var fEnabled = !!(this.bitsMessage & bitMessage);
|
||||
if (fCriteria !== null && fCriteria != fEnabled) continue;
|
||||
if (sCategories) sCategories += ",";
|
||||
if (!(++n % 10)) sCategories += "\n\t"; // jshint ignore:line
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ if (typeof module !== 'undefined') {
|
|||
*/
|
||||
function Disk(controller, drive, mode)
|
||||
{
|
||||
Component.call(this, "Disk", {'id': controller.idMachine + ".disk" + Disk.nDisks++}, Disk);
|
||||
Component.call(this, "Disk", {'id': controller.idMachine + ".disk" + Disk.nDisks++}, Disk, Debugger.MESSAGE.DISK);
|
||||
|
||||
/*
|
||||
* Route all non-Debugger messages (eg, notice() and println() calls) through
|
||||
|
|
@ -444,7 +444,9 @@ Disk.prototype.create = function(mode, nCylinders, nHeads, nSectors, cbSector)
|
|||
* it wouldn't hurt to let create() do its thing, too, but it's a waste of time.
|
||||
*/
|
||||
if (this.mode != DiskAPI.MODE.PRELOAD) {
|
||||
if (DEBUG) this.messageDebugger("blank disk for \"" + this.sDiskName + "\": " + this.nCylinders + " cylinders, " + this.nHeads + " head(s)");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("blank disk for \"" + this.sDiskName + "\": " + this.nCylinders + " cylinders, " + this.nHeads + " head(s)");
|
||||
}
|
||||
var aCylinders = new Array(this.nCylinders);
|
||||
for (var iCylinder = 0; iCylinder < aCylinders.length; iCylinder++) {
|
||||
var aHeads = new Array(this.nHeads);
|
||||
|
|
@ -656,7 +658,9 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
|||
|
||||
if (this.fOnDemand) {
|
||||
if (!nErrorCode) {
|
||||
if (DEBUG) this.messageDebugger('Disk.doneLoad("' + sDiskFile + '","' + sDiskPath + '")');
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger('Disk.doneLoad("' + sDiskFile + '","' + sDiskPath + '")');
|
||||
}
|
||||
this.fRemote = true;
|
||||
disk = this;
|
||||
} else {
|
||||
|
|
@ -673,7 +677,9 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
|||
*/
|
||||
this.controller.notice("Unable to load disk \"" + this.sDiskName + "\" (error " + nErrorCode + ")", fPrintOnly);
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger('Disk.doneLoad("' + sDiskFile + '","' + sDiskPath + '")');
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger('Disk.doneLoad("' + sDiskFile + '","' + sDiskPath + '")');
|
||||
}
|
||||
try {
|
||||
/*
|
||||
* The following code was a hack to turn on write-protection for a disk image if there was
|
||||
|
|
@ -764,13 +770,13 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
|||
* conversion to a forward-compatible 'data' array.
|
||||
*/
|
||||
else {
|
||||
if (MAXDEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.DISK)) {
|
||||
if (MAXDEBUG && this.messageEnabled()) {
|
||||
var sCylinders = aDiskData.length + " track" + (aDiskData.length > 1 ? "s" : "");
|
||||
var nHeads = aDiskData[0].length;
|
||||
var sHeads = nHeads + " head" + (nHeads > 1 ? "s" : "");
|
||||
var nSectorsPerTrack = aDiskData[0][0].length;
|
||||
var sSectorsPerTrack = nSectorsPerTrack + " sector" + (nSectorsPerTrack > 1 ? "s" : "") + "/track";
|
||||
this.dbg.message(sCylinders + ", " + sHeads + ", " + sSectorsPerTrack);
|
||||
this.messageDebugger(sCylinders + ", " + sHeads + ", " + sSectorsPerTrack);
|
||||
}
|
||||
/*
|
||||
* Before the image is usable, we must "normalize" all the sectors. In the past, this meant
|
||||
|
|
@ -811,7 +817,7 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
|||
* pattern, if any, into a dword pattern.
|
||||
*/
|
||||
adw = [];
|
||||
if (DEBUG) this.assert((dwPattern & 0xff) == dwPattern);
|
||||
this.assert((dwPattern & 0xff) == dwPattern);
|
||||
dwPattern = sector['pattern'] = (dwPattern | (dwPattern << 8) | (dwPattern << 16) | (dwPattern << 24));
|
||||
sector['data'] = adw;
|
||||
} else {
|
||||
|
|
@ -913,7 +919,9 @@ Disk.prototype.onLoadParseSectors = function(sURLName, sURLData, nErrorCode, sec
|
|||
var nSectors = sectorInfo[3];
|
||||
fAsync = sectorInfo[4];
|
||||
|
||||
if (DEBUG) this.messageDebugger("Disk.onLoadParseSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.onLoadParseSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + ")");
|
||||
}
|
||||
|
||||
var abData = JSON.parse(sURLData);
|
||||
var offData = 0;
|
||||
|
|
@ -929,7 +937,9 @@ Disk.prototype.onLoadParseSectors = function(sURLName, sURLData, nErrorCode, sec
|
|||
*/
|
||||
var sector = this.seek(iCylinder, iHead, iSector, true);
|
||||
if (!sector) {
|
||||
if (DEBUG) this.messageDebugger("Disk.onLoadParseSectors(): seek(" + iCylinder + "," + iHead + "," + iSector + ") failed");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.onLoadParseSectors(): seek(" + iCylinder + "," + iHead + "," + iSector + ") failed");
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.fill(sector, abData, offData);
|
||||
|
|
@ -979,7 +989,9 @@ Disk.prototype.connectRemoteDisk = function(sDiskPath)
|
|||
*/
|
||||
Disk.prototype.readRemoteSectors = function(iCylinder, iHead, iSector, cbSector, nSectors, done)
|
||||
{
|
||||
if (DEBUG) this.messageDebugger("Disk.readRemoteSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + "," + cbSector + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.readRemoteSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + "," + cbSector + ")");
|
||||
}
|
||||
|
||||
if (this.fRemote) {
|
||||
var sParms = DiskAPI.QUERY.ACTION + '=' + DiskAPI.ACTION.READ;
|
||||
|
|
@ -1017,7 +1029,9 @@ Disk.prototype.readRemoteSectors = function(iCylinder, iHead, iSector, cbSector,
|
|||
*/
|
||||
Disk.prototype.writeRemoteSectors = function(iCylinder, iHead, iSector, nSectors, abSectors, fAsync)
|
||||
{
|
||||
if (DEBUG) this.messageDebugger("Disk.writeRemoteSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.writeRemoteSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + ")");
|
||||
}
|
||||
|
||||
if (this.fRemote) {
|
||||
var data = {};
|
||||
|
|
@ -1084,7 +1098,9 @@ Disk.prototype.queueDirtySector = function(sector, fAsync)
|
|||
this.aDirtySectors.push(sector);
|
||||
this.aDirtyTimestamps.push(usr.getTime());
|
||||
|
||||
if (DEBUG) this.messageDebugger("Disk.queueDirtySector(" + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + "): " + this.aDirtySectors.length + " dirty");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.queueDirtySector(" + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + "): " + this.aDirtySectors.length + " dirty");
|
||||
}
|
||||
|
||||
return fAsync && this.updateWriteTimer();
|
||||
};
|
||||
|
|
@ -1152,15 +1168,17 @@ Disk.prototype.findDirtySectors = function(fAsync)
|
|||
var sectorNext = this.aDiskData[iCylinder][iHead][i];
|
||||
if (!sectorNext.fDirty) break;
|
||||
var j = this.aDirtySectors.indexOf(sectorNext);
|
||||
if (DEBUG) this.assert(j >= 0, "dirty sector (" + iCylinder + ":" + iHead + ":" + sectorNext['sector'] + ") missing from aDirtySectors");
|
||||
if (DEBUG) this.messageDebugger("Disk.findDirtySectors(" + iCylinder + ":" + iHead + ":" + sectorNext['sector'] + ")");
|
||||
this.assert(j >= 0, "dirty sector (" + iCylinder + ":" + iHead + ":" + sectorNext['sector'] + ") missing from aDirtySectors");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.findDirtySectors(" + iCylinder + ":" + iHead + ":" + sectorNext['sector'] + ")");
|
||||
}
|
||||
this.aDirtySectors.splice(j, 1);
|
||||
this.aDirtyTimestamps.splice(j, 1);
|
||||
abSectors = abSectors.concat(this.toBytes(sectorNext));
|
||||
sectorNext.fDirty = false;
|
||||
nSectors++;
|
||||
}
|
||||
if (DEBUG) this.assert(!!abSectors.length, "no data for dirty sector (" + iCylinder + ":" + iHead + ":" + sector['sector'] + ")");
|
||||
this.assert(!!abSectors.length, "no data for dirty sector (" + iCylinder + ":" + iHead + ":" + sector['sector'] + ")");
|
||||
var response = this.writeRemoteSectors(iCylinder, iHead, iSector, nSectors, abSectors, fAsync);
|
||||
return fAsync || response;
|
||||
}
|
||||
|
|
@ -1188,7 +1206,9 @@ Disk.prototype.onWriteCleanSectors = function(sURLName, sURLData, nErrorCode, se
|
|||
for (var i = iSector - 1; nSectors-- > 0 && i >= 0 && i < this.aDiskData[iCylinder][iHead].length; i++) {
|
||||
var sector = this.aDiskData[iCylinder][iHead][i];
|
||||
|
||||
if (DEBUG) this.messageDebugger("Disk.onWriteCleanSectors(" + iCylinder + ":" + iHead + ":" + sector['sector'] + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.onWriteCleanSectors(" + iCylinder + ":" + iHead + ":" + sector['sector'] + ")");
|
||||
}
|
||||
|
||||
if (!nErrorCode) {
|
||||
if (!sector.fDirty) {
|
||||
|
|
@ -1318,7 +1338,9 @@ Disk.prototype.seek = function(iCylinder, iHead, iSector, fWrite, done)
|
|||
});
|
||||
return null;
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger('Disk.seek("' + this.sDiskName + '"): uninitialized sector ' + iCylinder + ':' + iHead + ':' + iSector);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger('Disk.seek("' + this.sDiskName + '"): uninitialized sector ' + iCylinder + ':' + iHead + ':' + iSector);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -1395,7 +1417,9 @@ Disk.prototype.read = function(sector, ibSector, fCompare)
|
|||
{
|
||||
var b = -1;
|
||||
|
||||
if (DEBUG && !ibSector && !fCompare) this.messageDebugger("Disk.read(" + this.controller.id + ":" + this.drive.iDrive + "," + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + ")");
|
||||
if (DEBUG && !ibSector && !fCompare && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.read(" + this.controller.id + ":" + this.drive.iDrive + "," + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + ")");
|
||||
}
|
||||
|
||||
if (ibSector < sector['length']) {
|
||||
var adw = sector['data'];
|
||||
|
|
@ -1420,7 +1444,9 @@ Disk.prototype.write = function(sector, ibSector, b)
|
|||
if (this.fWriteProtected)
|
||||
return false;
|
||||
|
||||
if (DEBUG && !ibSector) this.messageDebugger("Disk.write(" + this.controller.id + ":" + this.drive.iDrive + "," + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + ")");
|
||||
if (DEBUG && !ibSector && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.write(" + this.controller.id + ":" + this.drive.iDrive + "," + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + ")");
|
||||
}
|
||||
|
||||
if (ibSector < sector['length']) {
|
||||
if (b != this.read(sector, ibSector, true)) {
|
||||
|
|
@ -1490,7 +1516,9 @@ Disk.prototype.save = function()
|
|||
}
|
||||
}
|
||||
}
|
||||
if (DEBUG) this.messageDebugger('Disk.save("' + this.sDiskName + '"): saved ' + (deltas.length - 1) + ' change(s)');
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger('Disk.save("' + this.sDiskName + '"): saved ' + (deltas.length - 1) + ' change(s)');
|
||||
}
|
||||
return deltas;
|
||||
};
|
||||
|
||||
|
|
@ -1618,26 +1646,11 @@ Disk.prototype.restore = function(deltas)
|
|||
if (nChanges < 0) {
|
||||
this.controller.notice("unable to restore disk '" + this.sDiskName + ": " + sReason);
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger('Disk.restore("' + this.sDiskName + '"): restored ' + nChanges + ' change(s)');
|
||||
}
|
||||
return nChanges;
|
||||
};
|
||||
|
||||
/**
|
||||
* messageDebugger(sMessage)
|
||||
*
|
||||
* This is a combination of the Debugger's messageEnabled(MESSAGE_DISK) and message() functions, for convenience.
|
||||
*
|
||||
* @this {Disk}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
*/
|
||||
Disk.prototype.messageDebugger = function(sMessage)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (this.dbg.messageEnabled(Debugger.MESSAGE.DISK)) {
|
||||
this.dbg.message(sMessage);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger('Disk.restore("' + this.sDiskName + '"): restored ' + nChanges + ' change(s)');
|
||||
}
|
||||
}
|
||||
return nChanges;
|
||||
};
|
||||
|
||||
if (typeof APP_PCJS !== 'undefined') APP_PCJS.Disk = Disk;
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ function FDC(parmsFDC) {
|
|||
* TODO: Indicate the type of diskette image being loaded (this might help folks understand what's going
|
||||
* on when they try to load a diskette image that's larger than what the selected operating system supports).
|
||||
*/
|
||||
Component.call(this, "FDC", parmsFDC, FDC);
|
||||
Component.call(this, "FDC", parmsFDC, FDC, Debugger.MESSAGE.FDC);
|
||||
|
||||
this['dmaRead'] = this.dmaRead;
|
||||
this['dmaWrite'] = this.dmaWrite;
|
||||
|
|
@ -211,7 +211,7 @@ if (DEBUG) {
|
|||
ST1: "ST1", // Status Register 1
|
||||
ST2: "ST2", // Status Register 2
|
||||
ST3: "ST3" // Status Register 3
|
||||
}
|
||||
};
|
||||
} else {
|
||||
FDC.TERMS = {};
|
||||
}
|
||||
|
|
@ -390,7 +390,7 @@ if (DEBUG) {
|
|||
READ_ID: "READ ID",
|
||||
FORMAT: "FORMAT",
|
||||
SEEK: "SEEK"
|
||||
}
|
||||
};
|
||||
} else {
|
||||
FDC.CMDS = {};
|
||||
}
|
||||
|
|
@ -483,7 +483,7 @@ FDC.prototype.setBinding = function(sHTMLType, sBinding, control)
|
|||
var fieldset = control.children[0];
|
||||
var files = fieldset.children[0].files;
|
||||
var submit = fieldset.children[1];
|
||||
submit.disabled = (files.length == 0);
|
||||
submit.disabled = !files.length;
|
||||
});
|
||||
|
||||
control.onsubmit = function(event) {
|
||||
|
|
@ -740,6 +740,7 @@ FDC.prototype.initController = function(data)
|
|||
/* falls through */
|
||||
case 320:
|
||||
case 360:
|
||||
/* falls through */
|
||||
default: // drives that don't have a recognized capacity default to 360
|
||||
drive.nCylinders = 40;
|
||||
drive.nSectors = 9; // drives capable of writing 8 sectors/track can also write 9 sectors/track
|
||||
|
|
@ -1525,7 +1526,7 @@ FDC.prototype.unloadAllDrives = function(fDiscard)
|
|||
FDC.prototype.addDiskHistory = function(sDisketteName, sDiskettePath, disk)
|
||||
{
|
||||
var i;
|
||||
if (DEBUG) this.assert(!!sDiskettePath);
|
||||
this.assert(!!sDiskettePath);
|
||||
for (i = 0; i < this.aDiskHistory.length; i++) {
|
||||
if (this.aDiskHistory[i][1] == sDiskettePath) {
|
||||
var nChanges = disk.restore(this.aDiskHistory[i][2]);
|
||||
|
|
@ -1719,7 +1720,7 @@ FDC.prototype.outFDCData = function(port, bOut, addrFrom)
|
|||
}
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("unsupported FDC command: " + str.toHexByte(bCmd));
|
||||
if (DEBUGGER) this.cpu.stopCPU();
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1814,7 +1815,7 @@ FDC.prototype.doCmd = function()
|
|||
* Controller docs say that H should always match HD, so I assert that, but what if someone
|
||||
* made a mistake and didn't program them identically -- what would happen? Which should we honor?
|
||||
*/
|
||||
if (DEBUG) this.assert(h == bHead);
|
||||
this.assert(h == bHead);
|
||||
r = drive.bSector = this.popCmd(FDC.TERMS.R); // R
|
||||
n = this.popCmd(FDC.TERMS.N); // N
|
||||
drive.nBytes = 128 << n; // 0 => 128, 1 => 256, 2 => 512, 3 => 1024
|
||||
|
|
@ -1938,7 +1939,7 @@ FDC.prototype.doCmd = function()
|
|||
* update() function that all FDC commands can use. This code is merely sufficient to get us
|
||||
* through the "DSKETTE_SETUP" gauntlet in the MODEL_5170 BIOS.
|
||||
*/
|
||||
if (drive.bCylinder == 0) {
|
||||
if (!drive.bCylinder) {
|
||||
drive.resCode |= FDC.REG_DATA.RES.TRACK0;
|
||||
}
|
||||
this.beginResult(); // like FDC.REG_DATA.CMD.RECALIBRATE, no results are provided
|
||||
|
|
@ -1948,7 +1949,7 @@ FDC.prototype.doCmd = function()
|
|||
default:
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("FDC operation unsupported (command=0x: " + str.toHexByte(bCmd) + ")");
|
||||
if (DEBUGGER) this.cpu.stopCPU();
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2023,12 +2024,12 @@ FDC.prototype.pushResults = function(drive, bCmd, bHead, c, h, r, n)
|
|||
*/
|
||||
FDC.prototype.popCmd = function(name)
|
||||
{
|
||||
if (DEBUG) this.assert((!this.regDataIndex || name !== undefined) && this.regDataIndex < this.regDataTotal);
|
||||
this.assert((!this.regDataIndex || name !== undefined) && this.regDataIndex < this.regDataTotal);
|
||||
var bCmd = this.regDataArray[this.regDataIndex];
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.PORT)) {
|
||||
var bCmdMasked = bCmd & FDC.REG_DATA.CMD.MASK;
|
||||
if (!name && !this.regDataIndex && FDC.aCmdInfo[bCmdMasked]) name = FDC.aCmdInfo[bCmdMasked].name;
|
||||
this.messageDebugger("FDC.CMD[" + (name || this.regDataIndex) + "]: 0x" + str.toHexByte(bCmd), Debugger.MESSAGE.PORT);
|
||||
this.messageDebugger("FDC.CMD[" + (name || this.regDataIndex) + "]: 0x" + str.toHexByte(bCmd));
|
||||
}
|
||||
this.regDataIndex++;
|
||||
return bCmd;
|
||||
|
|
@ -2080,7 +2081,7 @@ FDC.prototype.beginResult = function()
|
|||
FDC.prototype.pushResult = function(bResult, name)
|
||||
{
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.PORT)) {
|
||||
this.messageDebugger("FDC.RES[" + (name || this.regDataTotal) + "]: 0x" + str.toHexByte(bResult), Debugger.MESSAGE.PORT);
|
||||
this.messageDebugger("FDC.RES[" + (name || this.regDataTotal) + "]: 0x" + str.toHexByte(bResult));
|
||||
}
|
||||
this.regDataArray[this.regDataTotal++] = bResult;
|
||||
};
|
||||
|
|
@ -2396,7 +2397,7 @@ FDC.prototype.writeByte = function(drive, b)
|
|||
*/
|
||||
FDC.prototype.advanceSector = function(drive)
|
||||
{
|
||||
if (DEBUG) this.assert(drive.bCylinder < drive.nDiskCylinders);
|
||||
this.assert(drive.bCylinder < drive.nDiskCylinders);
|
||||
drive.bSector++;
|
||||
var bSectorStart = 1;
|
||||
if (drive.bSector >= drive.nDiskSectors + bSectorStart) {
|
||||
|
|
@ -2441,64 +2442,6 @@ FDC.prototype.writeFormat = function(drive, b)
|
|||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
* messageEnabled(bitsMessage)
|
||||
*
|
||||
* @this {FDC}
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
* @return {boolean}
|
||||
*/
|
||||
FDC.prototype.messageEnabled = function(bitsMessage)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage == null) {
|
||||
bitsMessage = Debugger.MESSAGE.FDC;
|
||||
} else {
|
||||
bitsMessage |= Debugger.MESSAGE.FDC;
|
||||
}
|
||||
return this.dbg.messageEnabled(bitsMessage);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* messageDebugger(sMessage, bitsMessage)
|
||||
*
|
||||
* This is a combination of the Debugger's messageEnabled(MESSAGE_FDC) and message() functions, for convenience.
|
||||
*
|
||||
* @this {FDC}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
*/
|
||||
FDC.prototype.messageDebugger = function(sMessage, bitsMessage)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage == null) {
|
||||
bitsMessage = Debugger.MESSAGE.FDC;
|
||||
} else {
|
||||
bitsMessage |= Debugger.MESSAGE.FDC;
|
||||
}
|
||||
if (this.dbg.messageEnabled(bitsMessage)) this.dbg.message(sMessage);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* messagePort(port, bOut, addrFrom, name, bIn)
|
||||
*
|
||||
* This is an internal version of the Debugger's messagePort() function, for convenience.
|
||||
*
|
||||
* @this {FDC}
|
||||
* @param {number} port
|
||||
* @param {number|null} bOut if an output operation
|
||||
* @param {number|null} [addrFrom]
|
||||
* @param {string|null} [name] of the port, if any
|
||||
* @param {number} [bIn] is the input value, if known, on an input operation
|
||||
*/
|
||||
FDC.prototype.messagePort = function(port, bOut, addrFrom, name, bIn)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) this.dbg.messagePort(this, port, bOut, addrFrom, name, Debugger.MESSAGE.FDC, bIn);
|
||||
};
|
||||
|
||||
/*
|
||||
* Port input notification table
|
||||
*
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ if (typeof module !== 'undefined') {
|
|||
*/
|
||||
function HDC(parmsHDC) {
|
||||
|
||||
Component.call(this, "HDC", parmsHDC, HDC);
|
||||
Component.call(this, "HDC", parmsHDC, HDC, Debugger.MESSAGE.HDC);
|
||||
|
||||
this['dmaRead'] = this.dmaRead;
|
||||
this['dmaWrite'] = this.dmaWrite;
|
||||
|
|
@ -747,7 +747,9 @@ HDC.prototype.initController = function(data, fHard)
|
|||
this.regConfig |= (drive.type & 0x3) << ((1 - iDrive) << 1);
|
||||
}
|
||||
}
|
||||
if (DEBUG) this.messageDebugger("HDC initialized for " + this.aDrives.length + " drive(s)");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC initialized for " + this.aDrives.length + " drive(s)");
|
||||
}
|
||||
return fSuccess;
|
||||
};
|
||||
|
||||
|
|
@ -1147,7 +1149,7 @@ HDC.prototype.loadDisk = function(iDrive, sDiskName, sDiskPath, fAutoMount)
|
|||
if (fAutoMount) {
|
||||
drive.fAutoMount = true;
|
||||
this.cAutoMount++;
|
||||
this.messageDebugger("loading " + sDiskName);
|
||||
if (this.messageEnabled()) this.messageDebugger("loading " + sDiskName);
|
||||
}
|
||||
var disk = drive.disk || new Disk(this, drive, drive.mode);
|
||||
disk.load(sDiskName, sDiskPath, null, this.doneLoadDisk);
|
||||
|
|
@ -1399,7 +1401,7 @@ HDC.prototype.inATCData = function(port, addrFrom)
|
|||
* well, then the caller will get 0xff.
|
||||
*/
|
||||
bIn = this.readByte(this.drive);
|
||||
if (DEBUG) this.assert(bIn >= 0);
|
||||
this.assert(bIn >= 0);
|
||||
|
||||
/*
|
||||
* Now that we've supplied a full sector of data, see if the caller's expecting additional sectors;
|
||||
|
|
@ -1420,7 +1422,7 @@ HDC.prototype.inATCData = function(port, addrFrom)
|
|||
/*
|
||||
* I shouldn't have to set BUSY (or DATA_REQ) again, because it should still be set, no?
|
||||
*/
|
||||
if (DEBUG) hdc.assert(!!(hdc.regStatus & HDC.ATC.STATUS.BUSY));
|
||||
hdc.assert(!!(hdc.regStatus & HDC.ATC.STATUS.BUSY));
|
||||
} else {
|
||||
/*
|
||||
* TODO: It would be nice to be a bit more specific about the error (if any) that just occurred.
|
||||
|
|
@ -1432,7 +1434,7 @@ HDC.prototype.inATCData = function(port, addrFrom)
|
|||
}
|
||||
}, false);
|
||||
} else {
|
||||
if (DEBUG) this.assert(this.drive.nBytes == 0);
|
||||
this.assert(!this.drive.nBytes);
|
||||
this.regStatus = HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK;
|
||||
}
|
||||
}
|
||||
|
|
@ -1454,7 +1456,7 @@ HDC.prototype.outATCData = function(port, bOut, addrFrom)
|
|||
/*
|
||||
* messagePort() calls, if enabled, can be overwhelming for this port, so limit them to the first byte.
|
||||
*/
|
||||
if (!this.drive || this.drive.ibSector == 0) this.messagePort(port, bOut, addrFrom, "DATA");
|
||||
if (!this.drive || !this.drive.ibSector) this.messagePort(port, bOut, addrFrom, "DATA");
|
||||
|
||||
if (this.drive) {
|
||||
if (this.drive.nBytes >= this.drive.cbSector) {
|
||||
|
|
@ -1465,7 +1467,9 @@ HDC.prototype.outATCData = function(port, bOut, addrFrom)
|
|||
*/
|
||||
this.regStatus = HDC.ATC.STATUS.ERROR;
|
||||
this.regError = HDC.ATC.ERROR.NO_CHS;
|
||||
if (DEBUG) this.messageDebugger("HDC.outATCData(" + str.toHexByte(bOut) + "): write failed");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.outATCData(" + str.toHexByte(bOut) + "): write failed");
|
||||
}
|
||||
}
|
||||
else if (this.drive.ibSector == this.drive.cbSector) {
|
||||
this.drive.nBytes -= this.drive.cbSector;
|
||||
|
|
@ -1475,9 +1479,9 @@ HDC.prototype.outATCData = function(port, bOut, addrFrom)
|
|||
/*
|
||||
* I shouldn't have to set BUSY (or DATA_REQ) again, because it should still be set, no?
|
||||
*/
|
||||
if (DEBUG) this.assert(!!(this.regStatus & HDC.ATC.STATUS.BUSY));
|
||||
this.assert(!!(this.regStatus & HDC.ATC.STATUS.BUSY));
|
||||
} else {
|
||||
if (DEBUG) this.assert(this.drive.nBytes == 0);
|
||||
this.assert(!this.drive.nBytes);
|
||||
this.regStatus = HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK;
|
||||
}
|
||||
}
|
||||
|
|
@ -1485,13 +1489,17 @@ HDC.prototype.outATCData = function(port, bOut, addrFrom)
|
|||
/*
|
||||
* TODO: What to do about unexpected writes? The number of bytes has exceeded what the command specified.
|
||||
*/
|
||||
if (DEBUG) this.messageDebugger("HDC.outATCData(" + str.toHexByte(bOut) + "): write exceeds count (" + this.drive.nBytes + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.outATCData(" + str.toHexByte(bOut) + "): write exceeds count (" + this.drive.nBytes + ")");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* TODO: What to do about unexpected writes? The number of bytes has exceeded what the command specified.
|
||||
*/
|
||||
if (DEBUG) this.messageDebugger("HDC.outATCData(" + str.toHexByte(bOut) + "): write without command");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.outATCData(" + str.toHexByte(bOut) + "): write without command");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1791,7 +1799,9 @@ HDC.prototype.doATCommand = function()
|
|||
this.drive = drive;
|
||||
}
|
||||
|
||||
if (DEBUG) this.messageDebugger("HDC.doATCommand(" + str.toHexByte(bCmd) + "): " + HDC.aATCCommands[bCmd], Debugger.MESSAGE.PORT | Debugger.MESSAGE.HDC);
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.PORT | Debugger.MESSAGE.HDC)) {
|
||||
this.messageDebugger("HDC.doATCommand(" + str.toHexByte(bCmd) + "): " + HDC.aATCCommands[bCmd]);
|
||||
}
|
||||
|
||||
switch (bCmd & HDC.ATC.COMMAND.MASK) {
|
||||
|
||||
|
|
@ -1868,16 +1878,18 @@ HDC.prototype.doATCommand = function()
|
|||
* The importance of SECCNT (nSectors) and DRVHD (nHeads) is controlling how multi-sector operations
|
||||
* advance to the next sector; see advanceSector().
|
||||
*/
|
||||
if (DEBUG) this.assert(drive.nHeads == nHead + 1);
|
||||
if (DEBUG) this.assert(drive.nSectors == nSectors);
|
||||
this.assert(drive.nHeads == nHead + 1);
|
||||
this.assert(drive.nSectors == nSectors);
|
||||
drive.nHeads = nHead + 1;
|
||||
drive.nSectors = nSectors;
|
||||
fInterrupt = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DEBUG) this.messageDebugger("HDC.doATCommand(" + str.toHexByte(this.regCommand) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
if (DEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.HDC) && bCmd >= 0) this.cpu.stopCPU();
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.doATCommand(" + str.toHexByte(this.regCommand) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
if (bCmd >= 0) this.dbg.stopCPU();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2009,7 +2021,9 @@ HDC.prototype.doXTCommand = function()
|
|||
|
||||
case HDC.XTC.DATA.CMD.RECALIBRATE: // 0x01
|
||||
drive.bControl = bControl;
|
||||
if (DEBUG) this.messageDebugger("HDC.doXTCommand(): drive " + iDrive + " control byte: 0x" + str.toHexByte(bControl));
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.doXTCommand(): drive " + iDrive + " control byte: 0x" + str.toHexByte(bControl));
|
||||
}
|
||||
this.beginResult(HDC.XTC.DATA.STATUS_OK | bDrive);
|
||||
break;
|
||||
|
||||
|
|
@ -2044,9 +2058,11 @@ HDC.prototype.doXTCommand = function()
|
|||
break;
|
||||
|
||||
default:
|
||||
if (DEBUG) this.messageDebugger("HDC.doXTCommand(" + str.toHexByte(bCmdOrig) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
this.beginResult(HDC.XTC.DATA.STATUS_ERROR | bDrive);
|
||||
if (DEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.HDC) && bCmd >= 0) this.cpu.stopCPU();
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.doXTCommand(" + str.toHexByte(bCmdOrig) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
if (bCmd >= 0) this.dbg.stopCPU();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -2064,7 +2080,9 @@ HDC.prototype.popCmd = function()
|
|||
var bCmdIndex = this.regDataIndex;
|
||||
if (bCmdIndex < this.regDataTotal) {
|
||||
bCmd = this.regDataArray[this.regDataIndex++];
|
||||
if (DEBUG) this.messageDebugger("HDC.CMD[" + bCmdIndex + "]: 0x" + str.toHexByte(bCmd) + (!bCmdIndex && HDC.aXTCCommands[bCmd]? (" (" + HDC.aXTCCommands[bCmd] + ")") : ""), (bCmdIndex > 0? Debugger.MESSAGE.PORT : 0) | Debugger.MESSAGE.HDC);
|
||||
if (DEBUG && this.messageEnabled((bCmdIndex > 0? Debugger.MESSAGE.PORT : 0) | Debugger.MESSAGE.HDC)) {
|
||||
this.messageDebugger("HDC.CMD[" + bCmdIndex + "]: 0x" + str.toHexByte(bCmd) + (!bCmdIndex && HDC.aXTCCommands[bCmd]? (" (" + HDC.aXTCCommands[bCmd] + ")") : ""));
|
||||
}
|
||||
}
|
||||
return bCmd;
|
||||
};
|
||||
|
|
@ -2080,7 +2098,9 @@ HDC.prototype.beginResult = function(bResult)
|
|||
this.regDataIndex = this.regDataTotal = 0;
|
||||
|
||||
if (bResult !== undefined) {
|
||||
if (DEBUG) this.messageDebugger("HDC.beginResult(0x" + str.toHexByte(bResult) + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.beginResult(0x" + str.toHexByte(bResult) + ")");
|
||||
}
|
||||
this.pushResult(bResult);
|
||||
}
|
||||
/*
|
||||
|
|
@ -2100,7 +2120,9 @@ HDC.prototype.beginResult = function(bResult)
|
|||
*/
|
||||
HDC.prototype.pushResult = function(bResult)
|
||||
{
|
||||
if (DEBUG) this.messageDebugger("HDC.RES[" + this.regDataTotal + "]: 0x" + str.toHexByte(bResult), (this.regDataTotal > 0? Debugger.MESSAGE.PORT : 0) | Debugger.MESSAGE.HDC);
|
||||
if (DEBUG && this.messageEnabled((this.regDataTotal > 0? Debugger.MESSAGE.PORT : 0) | Debugger.MESSAGE.HDC)) {
|
||||
this.messageDebugger("HDC.RES[" + this.regDataTotal + "]: 0x" + str.toHexByte(bResult));
|
||||
}
|
||||
this.regDataArray[this.regDataTotal++] = bResult;
|
||||
};
|
||||
|
||||
|
|
@ -2193,9 +2215,9 @@ HDC.prototype.doRead = function(drive, done)
|
|||
{
|
||||
drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;
|
||||
|
||||
if (DEBUG) this.messageDebugger("HDC.doRead(" + drive.wCylinder + ":" + drive.bHead + ":" + drive.bSector + ")");
|
||||
|
||||
// if (DEBUG) this.messageDebugger("HDC.doRead(head=" + str.toHexByte(drive.bHead) + ",cyl=" + str.toHexWord(drive.wCylinder) + ",sec=" + str.toHexByte(drive.bSector) + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.doRead(" + drive.wCylinder + ":" + drive.bHead + ":" + drive.bSector + ")");
|
||||
}
|
||||
|
||||
if (drive.disk) {
|
||||
drive.sector = null;
|
||||
|
|
@ -2237,9 +2259,9 @@ HDC.prototype.doWrite = function(drive, done)
|
|||
{
|
||||
drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;
|
||||
|
||||
if (DEBUG) this.messageDebugger("HDC.doWrite(" + drive.wCylinder + ":" + drive.bHead + ":" + drive.bSector + ")");
|
||||
|
||||
// if (DEBUG) this.messageDebugger("HDC.doWrite(head=" + str.toHexByte(drive.bHead) + ",cyl=" + str.toHexWord(drive.wCylinder) + ",sec=" + str.toHexByte(drive.bSector) + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.doWrite(" + drive.wCylinder + ":" + drive.bHead + ":" + drive.bSector + ")");
|
||||
}
|
||||
|
||||
if (drive.disk) {
|
||||
drive.sector = null;
|
||||
|
|
@ -2340,8 +2362,6 @@ HDC.prototype.doFormat = function(drive, done)
|
|||
{
|
||||
drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;
|
||||
|
||||
// if (DEBUG) this.messageDebugger("HDC.doFormat()");
|
||||
|
||||
if (drive.disk) {
|
||||
drive.sector = null;
|
||||
if (this.chipset) {
|
||||
|
|
@ -2525,7 +2545,7 @@ HDC.prototype.writeByte = function(drive, b)
|
|||
*/
|
||||
HDC.prototype.advanceSector = function(drive)
|
||||
{
|
||||
if (DEBUG) this.assert(drive.wCylinder < drive.nCylinders);
|
||||
this.assert(drive.wCylinder < drive.nCylinders);
|
||||
drive.bSector++;
|
||||
var bSectorStart = (1 - drive.bSectorBias);
|
||||
if (drive.bSector >= drive.nSectors + bSectorStart) {
|
||||
|
|
@ -2585,9 +2605,9 @@ HDC.prototype.writeFormat = function(drive, b)
|
|||
drive.nBytes = 128 << drive.abFormat[3];// N (0 => 128, 1 => 256, 2 => 512, 3 => 1024)
|
||||
drive.cbFormat = 0;
|
||||
|
||||
if (DEBUG) this.messageDebugger("HDC.writeFormat(" + drive.wCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
|
||||
// if (DEBUG) this.messageDebugger("HDC.writeFormat(head=" + str.toHexByte(drive.bHead) + ",cyl=" + str.toHexWord(drive.wCylinder) + ",sec=" + str.toHexByte(drive.bSector) + ",len=" + str.toHexWord(drive.nBytes) + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.writeFormat(" + drive.wCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
}
|
||||
|
||||
for (var i = 0; i < drive.nBytes; i++) {
|
||||
if (this.writeByte(drive, drive.bFiller) < 0) {
|
||||
|
|
@ -2677,40 +2697,6 @@ HDC.prototype.intBIOSDiskette = function(addr)
|
|||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* messageDebugger(sMessage, bitsMessage)
|
||||
*
|
||||
* This is a combination of the Debugger's messageEnabled(MESSAGE_HDC) and message() functions, for convenience.
|
||||
*
|
||||
* @this {HDC}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
*/
|
||||
HDC.prototype.messageDebugger = function(sMessage, bitsMessage)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage == null) bitsMessage = Debugger.MESSAGE.HDC;
|
||||
if (this.dbg.messageEnabled(bitsMessage)) this.dbg.message(sMessage);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* messagePort(port, bOut, addrFrom, name, bIn)
|
||||
*
|
||||
* This is an internal version of the Debugger's messagePort() function, for convenience.
|
||||
*
|
||||
* @this {HDC}
|
||||
* @param {number} port
|
||||
* @param {number|null} bOut if an output operation
|
||||
* @param {number|null} [addrFrom]
|
||||
* @param {string|null} [name] of the port, if any
|
||||
* @param {number} [bIn] is the input value, if known, on an input operation
|
||||
*/
|
||||
HDC.prototype.messagePort = function(port, bOut, addrFrom, name, bIn)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) this.dbg.messagePort(this, port, bOut, addrFrom, name, Debugger.MESSAGE.HDC, bIn);
|
||||
};
|
||||
|
||||
/*
|
||||
* Port input notification tables
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -60,9 +60,9 @@ if (typeof module !== 'undefined') {
|
|||
* @extends Component
|
||||
* @param {Object} parmsKbd
|
||||
*/
|
||||
function Keyboard(parmsKbd) {
|
||||
|
||||
Component.call(this, "Keyboard", parmsKbd, Keyboard);
|
||||
function Keyboard(parmsKbd)
|
||||
{
|
||||
Component.call(this, "Keyboard", parmsKbd, Keyboard, Debugger.MESSAGE.KBD);
|
||||
|
||||
this.nDefaultModel = parmsKbd['model'];
|
||||
this.fEscapeDisabled = false;
|
||||
|
|
@ -842,7 +842,7 @@ Keyboard.prototype.setBinding = function(sHTMLType, sBinding, control)
|
|||
this.bindings[id] = control;
|
||||
control.onclick = function(kbd, sKey, keyCode) {
|
||||
return function onClickKeyboard(event) {
|
||||
if (DEBUG) kbd.messageDebugger(sKey + " clicked", Debugger.MESSAGE.KEYS);
|
||||
if (DEBUG && kbd.messageEnabled()) kbd.messageDebugger(sKey + " clicked", Debugger.MESSAGE.KEYS);
|
||||
if (kbd.cpu) kbd.cpu.setFocus();
|
||||
kbd.checkShiftState(keyCode);
|
||||
return !kbd.keySimulatePress(keyCode);
|
||||
|
|
@ -989,7 +989,9 @@ Keyboard.prototype.setEnable = function(fData, fClock)
|
|||
{
|
||||
var fReset = false;
|
||||
if (this.fClock !== fClock) {
|
||||
if (DEBUG) this.messageDebugger("keyboard clock line changing to " + fClock, Debugger.MESSAGE.PORT);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("keyboard clock line changing to " + fClock, Debugger.MESSAGE.PORT);
|
||||
}
|
||||
/*
|
||||
* Toggling the clock line low and then high signals a "reset", which we acknowledge once the
|
||||
* data line is high as well.
|
||||
|
|
@ -997,7 +999,9 @@ Keyboard.prototype.setEnable = function(fData, fClock)
|
|||
this.fClock = this.fResetOnEnable = fClock;
|
||||
}
|
||||
if (this.fData !== fData) {
|
||||
if (DEBUG) this.messageDebugger("keyboard data line changing to " + fData, Debugger.MESSAGE.PORT);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("keyboard data line changing to " + fData, Debugger.MESSAGE.PORT);
|
||||
}
|
||||
this.fData = fData;
|
||||
/*
|
||||
* TODO: Review this code; it was added during the early days of MODEL_5150 testing and may not be
|
||||
|
|
@ -1054,7 +1058,7 @@ Keyboard.prototype.readScanCode = function(fShift)
|
|||
var b = 0;
|
||||
if (this.abScanBuffer.length) {
|
||||
b = this.abScanBuffer[0];
|
||||
this.messageDebugger("scan code 0x" + str.toHexByte(b) + " delivered");
|
||||
if (this.messageEnabled()) this.messageDebugger("scan code 0x" + str.toHexByte(b) + " delivered");
|
||||
if (fShift) this.shiftScanCode();
|
||||
}
|
||||
return b;
|
||||
|
|
@ -1274,11 +1278,11 @@ Keyboard.prototype.addScanCode = function(bScan, fRepeat)
|
|||
if (this.abScanBuffer) {
|
||||
if (this.abScanBuffer.length < Keyboard.LIMIT.MAX_SCANCODES) {
|
||||
if (!fDown && !this.aScanCodesActive[bKey] || fDown && this.aScanCodesActive[bKey] && !fRepeat) {
|
||||
if (MAXDEBUG) this.messageDebugger("scan code 0x" + str.toHexByte(bScan) + " redundant");
|
||||
if (MAXDEBUG && this.messageEnabled()) this.messageDebugger("scan code 0x" + str.toHexByte(bScan) + " redundant");
|
||||
return;
|
||||
}
|
||||
this.aScanCodesActive[bKey] = fDown;
|
||||
this.messageDebugger("scan code 0x" + str.toHexByte(bScan) + " buffered");
|
||||
if (this.messageEnabled()) this.messageDebugger("scan code 0x" + str.toHexByte(bScan) + " buffered");
|
||||
this.abScanBuffer.push(bScan);
|
||||
if (this.abScanBuffer.length == 1) {
|
||||
if (this.chipset) this.chipset.notifyKbdData(true);
|
||||
|
|
@ -1333,7 +1337,7 @@ Keyboard.prototype.autoClear = function(notKeyCode)
|
|||
{
|
||||
if (this.prevCharDown && (notKeyCode === undefined || notKeyCode != this.prevCharDown)) {
|
||||
if (DEBUG) {
|
||||
this.messageDebugger("autoClear(" + this.prevCharDown + ")");
|
||||
if (this.messageEnabled()) this.messageDebugger("autoClear(" + this.prevCharDown + ")");
|
||||
this.assert(this.aKeyTimers[this.prevCharDown]);
|
||||
}
|
||||
clearTimeout(this.aKeyTimers[this.prevCharDown]);
|
||||
|
|
@ -1632,7 +1636,9 @@ Keyboard.prototype.keyUpDown = function(event, fDown)
|
|||
fPass = !this.keySimulateUpOrDown(keyCodeSim, fDown, Keyboard.SIMCODE.KEYUPDOWN);
|
||||
}
|
||||
|
||||
if (DEBUG) this.messageDebugger(/*(fDown?"\n":"") +*/ "key" + (fDown? "Down" : "Up") + "(" + keyCode + "): " + (fPass? "pass" : "consume"), Debugger.MESSAGE.KEYS);
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.KEYS)) {
|
||||
this.messageDebugger(/*(fDown?"\n":"") +*/ "key" + (fDown? "Down" : "Up") + "(" + keyCode + "): " + (fPass? "pass" : "consume"));
|
||||
}
|
||||
return fPass;
|
||||
};
|
||||
|
||||
|
|
@ -1680,7 +1686,9 @@ Keyboard.prototype.keyPress = function(event)
|
|||
}
|
||||
}
|
||||
|
||||
if (DEBUG) this.messageDebugger("keyPress(" + keyCode + "): " + (fPass? "pass" : "consume"), Debugger.MESSAGE.KEYS);
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.KEYS)) {
|
||||
this.messageDebugger("keyPress(" + keyCode + "): " + (fPass? "pass" : "consume"));
|
||||
}
|
||||
return fPass;
|
||||
};
|
||||
|
||||
|
|
@ -1734,11 +1742,15 @@ Keyboard.prototype.keySimulatePress = function(keyCode, fCheckShift, fQuickRelea
|
|||
kbd.keySimulateUpOrDown(keyCode, false, Keyboard.SIMCODE.KEYTIMEOUT);
|
||||
};
|
||||
}(this), msDelay);
|
||||
if (DEBUG) this.messageDebugger("keySimulatePress(" + keyCode + "): setTimeout()");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("keySimulatePress(" + keyCode + "): setTimeout()");
|
||||
}
|
||||
}
|
||||
fSimulated = true;
|
||||
}
|
||||
if (DEBUG) this.messageDebugger("keySimulatePress(" + keyCode + "): " + (fSimulated? "true" : "false"), Debugger.MESSAGE.KEYS);
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.KEYS)) {
|
||||
this.messageDebugger("keySimulatePress(" + keyCode + "): " + (fSimulated? "true" : "false"));
|
||||
}
|
||||
return fSimulated;
|
||||
};
|
||||
|
||||
|
|
@ -1823,29 +1835,10 @@ Keyboard.prototype.keySimulateUpOrDown = function(keyCode, fDown, simCode)
|
|||
|
||||
fSimulated = true;
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.messageDebugger("keySimulateUpOrDown(" + keyCode + "," + (fDown? "down" : "up") + "," + Keyboard.aSimCodeDescs[simCode] + "): " + (fSimulated? "true" : "false"), Debugger.MESSAGE.KEYS);
|
||||
return fSimulated;
|
||||
};
|
||||
|
||||
/**
|
||||
* messageDebugger(sMessage, bitsMessage)
|
||||
*
|
||||
* This is a combination of the Debugger's messageEnabled(MESSAGE_KBD) and message() functions, for convenience.
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
*/
|
||||
Keyboard.prototype.messageDebugger = function(sMessage, bitsMessage)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage == null) {
|
||||
bitsMessage = Debugger.MESSAGE.KBD;
|
||||
} else {
|
||||
bitsMessage |= Debugger.MESSAGE.KBD;
|
||||
}
|
||||
if (this.dbg.messageEnabled(bitsMessage)) this.dbg.message(sMessage);
|
||||
if (DEBUG && this.messageEnabled(Debugger.MESSAGE.KEYS)) {
|
||||
this.messageDebugger("keySimulateUpOrDown(" + keyCode + "," + (fDown? "down" : "up") + "," + Keyboard.aSimCodeDescs[simCode] + "): " + (fSimulated? "true" : "false"));
|
||||
}
|
||||
return fSimulated;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ Memory.prototype = {
|
|||
*/
|
||||
writeNone: function(off, v) {
|
||||
if (DEBUGGER && this.dbg.messageEnabled(Debugger.MESSAGE.MEM) && !off) {
|
||||
this.dbg.message("attempt to write 0x" + str.toHexWord(v) + " to invalid block %" + str.toHex(this.addr) + " from " + str.toHexAddr(this.cpu.regIP, this.cpu.segCS.sel));
|
||||
this.dbg.message("attempt to write 0x" + str.toHexWord(v) + " to invalid block %" + str.toHex(this.addr), true);
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ if (typeof module !== 'undefined') {
|
|||
*/
|
||||
function Mouse(parmsMouse)
|
||||
{
|
||||
Component.call(this, "Mouse", parmsMouse, Mouse);
|
||||
Component.call(this, "Mouse", parmsMouse, Mouse, Debugger.MESSAGE.MOUSE);
|
||||
|
||||
this.idAdapter = parmsMouse['serial'];
|
||||
if (this.idAdapter) {
|
||||
|
|
@ -543,7 +543,9 @@ Mouse.prototype.sendPacket = function(sDiag, xDiag, yDiag)
|
|||
var b1 = 0x40 | (this.fButton1? 0x20 : 0) | (this.fButton2? 0x10 : 0) | ((this.yDelta & 0xC0) >> 4) | ((this.xDelta & 0xC0) >> 6);
|
||||
var b2 = this.xDelta & 0x3F;
|
||||
var b3 = this.yDelta & 0x3F;
|
||||
this.messageDebugger((sDiag? (sDiag + ": ") : "") + (yDiag !== undefined? ("mouse (" + xDiag + "," + yDiag + "): ") : "") + "serial packet [" + str.toHexByte(b1) + "," + str.toHexByte(b2) + "," + str.toHexByte(b3) + "]", Debugger.MESSAGE.SERIAL);
|
||||
if (this.messageEnabled(Debugger.MESSAGE.SERIAL)) {
|
||||
this.messageDebugger((sDiag? (sDiag + ": ") : "") + (yDiag !== undefined? ("mouse (" + xDiag + "," + yDiag + "): ") : "") + "serial packet [" + str.toHexByte(b1) + "," + str.toHexByte(b2) + "," + str.toHexByte(b3) + "]", 0, true);
|
||||
}
|
||||
this.componentAdapter.sendRBR([b1, b2, b3]);
|
||||
this.xDelta = this.yDelta = 0;
|
||||
};
|
||||
|
|
@ -630,29 +632,6 @@ Mouse.prototype.notifyMCR = function(bMCR)
|
|||
this.bMCR = bMCR;
|
||||
};
|
||||
|
||||
/**
|
||||
* messageDebugger(sMessage)
|
||||
*
|
||||
* This is a combination of the Debugger's messageEnabled(MESSAGE_MOUSE) and message() functions, for convenience.
|
||||
*
|
||||
* @this {Mouse}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
*/
|
||||
Mouse.prototype.messageDebugger = function(sMessage, bitsMessage)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage == null) {
|
||||
bitsMessage = Debugger.MESSAGE.MOUSE;
|
||||
} else {
|
||||
bitsMessage |= Debugger.MESSAGE.MOUSE;
|
||||
}
|
||||
if (this.dbg.messageEnabled(bitsMessage)) {
|
||||
this.dbg.message(sMessage + " @" + str.toHexAddr(this.cpu.regIP, this.cpu.segCS.sel));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mouse.init()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@
|
|||
* debugger.js from the compilation process altogether.
|
||||
*
|
||||
* However, when we're in "development mode" and running uncompiled code in debugger-less configurations,
|
||||
* I would still like to skip loading debugger.js altogether. To do that, we must arrange for an additional file,
|
||||
* nodebugger.js, to be loaded as early as possible, which must explicitly UPDATE the value of DEBUGGER to *false*.
|
||||
* I would still like to skip loading debugger.js altogether. To do that, we must arrange for this additional file,
|
||||
* nodebugger.js, to be loaded as early as possible, which explicitly UPDATES the value of DEBUGGER to false.
|
||||
*/
|
||||
DEBUGGER = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ function SerialPort(parmsSerial) {
|
|||
*/
|
||||
this.controlIOBuffer = null;
|
||||
|
||||
Component.call(this, "SerialPort", parmsSerial, SerialPort);
|
||||
Component.call(this, "SerialPort", parmsSerial, SerialPort, Debugger.MESSAGE.SERIAL);
|
||||
|
||||
Component.bindExternalControl(this, parmsSerial['binding'], SerialPort.sIOBuffer);
|
||||
}
|
||||
|
|
@ -715,40 +715,6 @@ SerialPort.prototype.echoByte = function(b) {
|
|||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* messageDebugger(sMessage)
|
||||
*
|
||||
* This is a combination of the Debugger's messageEnabled(MESSAGE_SERIAL) and message() functions, for convenience.
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
*/
|
||||
SerialPort.prototype.messageDebugger = function(sMessage) {
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (this.dbg.messageEnabled(Debugger.MESSAGE.SERIAL)) {
|
||||
this.dbg.message(sMessage);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* messagePort(port, bOut, addrFrom, name, bIn)
|
||||
*
|
||||
* This is an internal version of the Debugger's messagePort() function, for convenience.
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @param {number} port
|
||||
* @param {number|null} bOut if an output operation
|
||||
* @param {number|null} [addrFrom]
|
||||
* @param {string|null} [name] of the port, if any
|
||||
* @param {number} [bIn] is the input value, if known, on an input operation
|
||||
*/
|
||||
SerialPort.prototype.messagePort = function(port, bOut, addrFrom, name, bIn) {
|
||||
if (DEBUGGER && this.dbg) {
|
||||
this.dbg.messagePort(this, port, bOut, addrFrom, name, Debugger.MESSAGE.SERIAL, bIn);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Port input notification table
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ if (typeof module !== 'undefined') {
|
|||
*
|
||||
* WARNING: Since State objects are low-level objects that have no UI requirements,
|
||||
* they do not inherit from the Component class, so you should only use class methods
|
||||
* of Component, such as Component.assert(), or Debugger methods if the Debugger is available.
|
||||
* of Component, such as Component.assert(), or Debugger methods if the Debugger
|
||||
* is available.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Component} component
|
||||
|
|
@ -136,12 +137,14 @@ State.decompress = function(aComp, nLength) {
|
|||
/**
|
||||
* State.compressEvenOdd(aSrc)
|
||||
*
|
||||
* This is a very simple variation on compress() that compresses all the EVEN elements of aSrc first, followed by all the ODD
|
||||
* elements. This tends to work better on EGA video memory, because when odd/even addressing is enabled (eg, for text
|
||||
* modes), the DWORD values tend to alternate, which is the worst case for compress(), but the best case for compressEvenOdd().
|
||||
* This is a very simple variation on compress() that compresses all the EVEN elements of aSrc first,
|
||||
* followed by all the ODD elements. This tends to work better on EGA video memory, because when odd/even
|
||||
* addressing is enabled (eg, for text modes), the DWORD values tend to alternate, which is the worst case
|
||||
* for compress(), but the best case for compressEvenOdd().
|
||||
*
|
||||
* One wrinkle we support: if the first element is uninitialized, then we assume the entire array is undefined, and return an
|
||||
* empty compressed array. Conversely, decompressEvenOdd() will take an empty compressed array and return an uninitialized array.
|
||||
* One wrinkle we support: if the first element is uninitialized, then we assume the entire array is undefined,
|
||||
* and return an empty compressed array. Conversely, decompressEvenOdd() will take an empty compressed array
|
||||
* and return an uninitialized array.
|
||||
*
|
||||
* @param {Array.<number>|null} aSrc
|
||||
* @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of "count, value" pairs (aComp)
|
||||
|
|
@ -170,9 +173,9 @@ State.compressEvenOdd = function(aSrc) {
|
|||
/**
|
||||
* State.decompressEvenOdd(aComp, nLength)
|
||||
*
|
||||
* This is the counterpart to compressEvenOdd(). Note that because there's nothing in the compressed sequence that differentiates
|
||||
* a compress() sequence from a compressEvenOdd() sequence, you simply have to be consistent -- if you used even/odd compression, then
|
||||
* you must use even/odd decompression.
|
||||
* This is the counterpart to compressEvenOdd(). Note that because there's nothing in the compressed sequence
|
||||
* that differentiates a compress() sequence from a compressEvenOdd() sequence, you simply have to be consistent:
|
||||
* if you used even/odd compression, then you must use even/odd decompression.
|
||||
*
|
||||
* @param {Array.<number>} aComp
|
||||
* @param {number} nLength is expected length of decompressed data
|
||||
|
|
@ -214,7 +217,7 @@ State.prototype = {
|
|||
try {
|
||||
this[this.id][id] = data;
|
||||
} catch(e) {
|
||||
Component.log(e.message)
|
||||
Component.log(e.message);
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
|
@ -274,7 +277,9 @@ State.prototype = {
|
|||
if (s) {
|
||||
this[this.id] = s;
|
||||
this.fLoaded = true;
|
||||
if (DEBUG) this.messageDebugger("localStorage(" + this.key + "): " + s.length + " bytes loaded");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("localStorage(" + this.key + "): " + s.length + " bytes loaded");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -311,7 +316,9 @@ State.prototype = {
|
|||
if (web.hasLocalStorage()) {
|
||||
var s = JSON.stringify(this[this.id]);
|
||||
if (web.setLocalStorageItem(this.key, s)) {
|
||||
if (DEBUG) this.messageDebugger("localStorage(" + this.key + "): " + s.length + " bytes stored");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("localStorage(" + this.key + "): " + s.length + " bytes stored");
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* WARNING: Because browsers tend to disable all alerts() during an "unload" operation,
|
||||
|
|
@ -369,24 +376,40 @@ State.prototype = {
|
|||
var sKey = aKeys[i];
|
||||
if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {
|
||||
web.removeLocalStorageItem(sKey);
|
||||
if (DEBUG) this.messageDebugger("localStorage(" + sKey + ") removed");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("localStorage(" + sKey + ") removed");
|
||||
}
|
||||
aKeys.splice(i, 1);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* messageDebugger(sMessage)
|
||||
* messageEnabled(bitsMessage)
|
||||
*
|
||||
* This is a combination of the Debugger's messageEnabled(MESSAGE_STATE) and message() functions, for convenience.
|
||||
* @this {State}
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
* @return {boolean}
|
||||
*/
|
||||
messageEnabled: function(bitsMessage) {
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage == null) {
|
||||
bitsMessage = Debugger.MESSAGE.STATE;
|
||||
} else {
|
||||
bitsMessage |= Debugger.MESSAGE.STATE;
|
||||
}
|
||||
return this.dbg.messageEnabled(bitsMessage);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
/**
|
||||
* messageDebugger(sMessage)
|
||||
*
|
||||
* @this {State}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
*/
|
||||
messageDebugger: function(sMessage) {
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (this.dbg.messageEnabled(Debugger.MESSAGE.STATE)) this.dbg.message(sMessage);
|
||||
}
|
||||
if (DEBUGGER && this.dbg) this.dbg.message(sMessage);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ if (typeof module !== 'undefined') {
|
|||
*/
|
||||
function Video(parmsVideo, canvas, context, textarea)
|
||||
{
|
||||
Component.call(this, "Video", parmsVideo, Video);
|
||||
Component.call(this, "Video", parmsVideo, Video, Debugger.MESSAGE.VIDEO);
|
||||
|
||||
/*
|
||||
* This records the model specified (eg, "mda", "cga", "ega" or "" if none specified);
|
||||
|
|
@ -2189,7 +2189,9 @@ Video.prototype.captureTouch = function()
|
|||
*/
|
||||
Video.prototype.onFocusChange = function(fFocus)
|
||||
{
|
||||
if (this.fHasFocus != fFocus && DEBUG) this.messageDebugger("onFocusChange(): focus is now " + fFocus);
|
||||
if (this.fHasFocus != fFocus && DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("onFocusChange(): focus is now " + fFocus);
|
||||
}
|
||||
this.fHasFocus = fFocus;
|
||||
};
|
||||
|
||||
|
|
@ -2748,7 +2750,7 @@ Video.prototype.getCardColors = function(nBitsPerPixel)
|
|||
return Video.aCGAColors;
|
||||
}
|
||||
|
||||
if (DEBUG) this.assert(this.cardColor === this.cardEGA);
|
||||
this.assert(this.cardColor === this.cardEGA);
|
||||
|
||||
var aRegs = (this.cardEGA.aATCRegs[15] != null? this.cardEGA.aATCRegs : Video.aEGAPalDef);
|
||||
for (var i = 0; i < this.aRGB.length; i++) {
|
||||
|
|
@ -2867,7 +2869,10 @@ Video.prototype.buildFonts = function()
|
|||
Video.prototype.buildFont = function(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)
|
||||
{
|
||||
var fChanges = false;
|
||||
if (DEBUG) this.messageDebugger("buildFont(" + nFont + "): building " + Video.cardSpecs[nFont][0] + " font");
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("buildFont(" + nFont + "): building " + Video.cardSpecs[nFont][0] + " font");
|
||||
}
|
||||
if (this.createFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)) fChanges = true;
|
||||
|
||||
/*
|
||||
|
|
@ -2877,7 +2882,9 @@ Video.prototype.buildFont = function(nFont, offData, offSplit, cxChar, cyChar, a
|
|||
*/
|
||||
if (this.fDoubleFont) {
|
||||
nFont <<= 1;
|
||||
if (DEBUG) this.messageDebugger("buildFont(" + nFont + "): building " + Video.cardSpecs[nFont >> 1][0] + " double-size font");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("buildFont(" + nFont + "): building " + Video.cardSpecs[nFont >> 1][0] + " double-size font");
|
||||
}
|
||||
if (this.createFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)) fChanges = true;
|
||||
}
|
||||
return fChanges;
|
||||
|
|
@ -2924,7 +2931,9 @@ Video.prototype.createFont = function(nFont, offData, offSplit, cxChar, cyChar,
|
|||
var rgbColor = aRGBColors[iColor];
|
||||
var rgbColorOrig = font.aCSSColors[iColor]? font.aRGBColors[iColor] : [];
|
||||
if (rgbColor[0] !== rgbColorOrig[0] || rgbColor[1] !== rgbColorOrig[1] || rgbColor[2] !== rgbColorOrig[2]) {
|
||||
if (DEBUG) this.messageDebugger("creating font color " + iColor + " for font " + nFont);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("creating font color " + iColor + " for font " + nFont);
|
||||
}
|
||||
this.createFontColor(font, iColor, rgbColor, nDouble, offData, offSplit, cxChar, cyChar, abFontData);
|
||||
fChanges = true;
|
||||
}
|
||||
|
|
@ -3154,7 +3163,9 @@ Video.prototype.checkCursor = function()
|
|||
*/
|
||||
var iCellCursor = (this.cardActive.aCRTCRegs[Card.CRTC.CURSOR_ADDR_LO] + ((this.cardActive.aCRTCRegs[Card.CRTC.CURSOR_ADDR_HI] & Card.CRTC.ADDR_HI_MASK) << 8));
|
||||
if (this.iCellCursor != iCellCursor) {
|
||||
if (DEBUG) this.messageDebugger("checkCursor(): cursor moved from " + this.iCellCursor + " to " + iCellCursor);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("checkCursor(): cursor moved from " + this.iCellCursor + " to " + iCellCursor);
|
||||
}
|
||||
this.removeCursor();
|
||||
this.iCellCursor = iCellCursor;
|
||||
}
|
||||
|
|
@ -3207,7 +3218,9 @@ Video.prototype.removeCursor = function()
|
|||
*/
|
||||
this.updateChar(col, row, data);
|
||||
}
|
||||
if (DEBUG) this.messageDebugger("removeCursor(): removed from " + row + "," + col);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("removeCursor(): removed from " + row + "," + col);
|
||||
}
|
||||
this.aCellCache[this.iCellCursor] = data;
|
||||
}
|
||||
}
|
||||
|
|
@ -3272,7 +3285,9 @@ Video.prototype.getAccess = function()
|
|||
}
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) this.messageDebugger("getAccess(): invalid GRC mode (" + str.toHexByte(regGRCMode) + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("getAccess(): invalid GRC mode (" + str.toHexByte(regGRCMode) + ")");
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (regGRCMode & Card.GRC.MODE.READ_MODE1) {
|
||||
|
|
@ -3298,7 +3313,9 @@ Video.prototype.setAccess = function(nAccess)
|
|||
var card = this.cardActive;
|
||||
if (nAccess != null && card && nAccess != card.nAccess) {
|
||||
|
||||
if (DEBUG) this.messageDebugger("setAccess(0x" + str.toHexWord(nAccess) + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("setAccess(0x" + str.toHexWord(nAccess) + ")");
|
||||
}
|
||||
|
||||
card.setMemoryAccess(nAccess);
|
||||
|
||||
|
|
@ -3633,7 +3650,9 @@ Video.prototype.setMode = function(nMode, fForce)
|
|||
{
|
||||
if (nMode != null && (nMode != this.nMode || fForce)) {
|
||||
|
||||
if (DEBUG) this.messageDebugger("setMode(0x" + str.toHexWord(nMode) + (fForce? ",force" : "") + ")");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("setMode(0x" + str.toHexWord(nMode) + (fForce? ",force" : "") + ")");
|
||||
}
|
||||
|
||||
this.cUpdates = 0; // count updateScreen() calls as a means of driving blink updates
|
||||
this.nMode = nMode;
|
||||
|
|
@ -3657,7 +3676,9 @@ Video.prototype.setMode = function(nMode, fForce)
|
|||
|
||||
if (this.addrBuffer) {
|
||||
|
||||
if (DEBUG) this.messageDebugger("setMode(" + nMode + "): removing 0x" + str.toHex(this.sizeBuffer) + " bytes from 0x" + str.toHex(this.addrBuffer));
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("setMode(" + nMode + "): removing 0x" + str.toHex(this.sizeBuffer) + " bytes from 0x" + str.toHex(this.addrBuffer));
|
||||
}
|
||||
|
||||
if (!this.bus.removeMemory(this.addrBuffer, this.sizeBuffer)) {
|
||||
/*
|
||||
|
|
@ -3674,7 +3695,9 @@ Video.prototype.setMode = function(nMode, fForce)
|
|||
this.addrBuffer = card.addrBuffer;
|
||||
this.sizeBuffer = card.sizeBuffer;
|
||||
|
||||
if (DEBUG) this.messageDebugger("setMode(" + nMode + "): adding 0x" + str.toHex(this.sizeBuffer) + " bytes to 0x" + str.toHex(this.addrBuffer));
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("setMode(" + nMode + "): adding 0x" + str.toHex(this.sizeBuffer) + " bytes to 0x" + str.toHex(this.addrBuffer));
|
||||
}
|
||||
|
||||
var controller = (card === this.cardEGA? card : null);
|
||||
|
||||
|
|
@ -3824,7 +3847,7 @@ Video.prototype.updateChar = function(col, row, data, context)
|
|||
this.contextScreen.fillRect(xDst, yDst, this.cxScreenCell, this.cyScreenCell);
|
||||
}
|
||||
|
||||
if (MAXDEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.VIDEO | Debugger.MESSAGE.LOG)) {
|
||||
if (MAXDEBUG && this.messageEnabled(Debugger.MESSAGE.VIDEO | Debugger.MESSAGE.LOG)) {
|
||||
this.log("updateCharBgnd(" + col + "," + row + "," + bChar + "): filled " + xDst + "," + yDst);
|
||||
}
|
||||
|
||||
|
|
@ -3835,7 +3858,7 @@ Video.prototype.updateChar = function(col, row, data, context)
|
|||
var xSrcFgnd = (bChar & 0xf) * font.cxCell;
|
||||
var ySrcFgnd = (bChar >> 4) * font.cyCell;
|
||||
|
||||
if (MAXDEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.VIDEO | Debugger.MESSAGE.LOG)) {
|
||||
if (MAXDEBUG && this.messageEnabled(Debugger.MESSAGE.VIDEO | Debugger.MESSAGE.LOG)) {
|
||||
this.log("updateCharFgnd(" + col + "," + row + "," + bChar + "): draw from " + xSrcFgnd + "," + ySrcFgnd + " (" + font.cxCell + "," + font.cyCell + ") to " + xDst + "," + yDst);
|
||||
}
|
||||
|
||||
|
|
@ -4064,7 +4087,7 @@ Video.prototype.updateScreenText = function(addrScreen, addrScreenLimit, iCell,
|
|||
if (iCell == this.iCellCursor) {
|
||||
data |= ((this.cBlinks & 0x1)? (Video.ATTRS.DRAW_CURSOR << 8) : 0);
|
||||
}
|
||||
if (DEBUG) this.assert(iCell < this.aCellCache.length);
|
||||
this.assert(iCell < this.aCellCache.length);
|
||||
dataCache = this.aCellCache[iCell];
|
||||
if (dataCache != data) {
|
||||
var col = iCell % this.nCols;
|
||||
|
|
@ -4105,7 +4128,7 @@ Video.prototype.updateScreenGraphicsCGA = function(addrScreen, addrScreenLimit)
|
|||
var xDirty = this.nCols, xMaxDirty = 0, yDirty = this.nRows, yMaxDirty = 0;
|
||||
while (addr < addrScreenLimit) {
|
||||
data = this.bus.getWordDirect(addr);
|
||||
if (DEBUG) this.assert(iCell < this.aCellCache.length);
|
||||
this.assert(iCell < this.aCellCache.length);
|
||||
dataCache = this.aCellCache[iCell];
|
||||
if (dataCache === data) {
|
||||
x += nPixelsPerCell;
|
||||
|
|
@ -4183,9 +4206,9 @@ Video.prototype.updateScreenGraphicsEGA = function(addrScreen, addrScreenLimit)
|
|||
var xDirty = this.nCols, xMaxDirty = 0, yDirty = this.nRows, yMaxDirty = 0;
|
||||
while (addr < addrScreenLimit) {
|
||||
var idw = addr++ - this.addrBuffer;
|
||||
if (DEBUG) this.assert(idw >= 0 && idw < adwMemory.length);
|
||||
this.assert(idw >= 0 && idw < adwMemory.length);
|
||||
data = adwMemory[idw];
|
||||
if (DEBUG) this.assert(iCell < this.aCellCache.length);
|
||||
this.assert(iCell < this.aCellCache.length);
|
||||
dataCache = this.aCellCache[iCell];
|
||||
if (dataCache === data) {
|
||||
x += nPixelsPerCell;
|
||||
|
|
@ -4211,7 +4234,7 @@ Video.prototype.updateScreenGraphicsEGA = function(addrScreen, addrScreenLimit)
|
|||
* Since assertions don't fix problems (only catch them, and only in DEBUG builds), I'm also ensuring
|
||||
* that bPixel will always default to 0 if an undefined value ever slips through again.
|
||||
*/
|
||||
if (DEBUG) this.assert(Video.aEGADWToByte[dwPixel] !== undefined);
|
||||
this.assert(Video.aEGADWToByte[dwPixel] !== undefined);
|
||||
var bPixel = Video.aEGADWToByte[dwPixel] || 0;
|
||||
this.setPixel(this.imageScreenBuffer, x++, y, aPixelColors[bPixel]);
|
||||
data <<= 1;
|
||||
|
|
@ -4355,7 +4378,9 @@ Video.prototype.outFeat = function(port, bOut, addrFrom)
|
|||
Video.prototype.inATC = function(port, addrFrom)
|
||||
{
|
||||
var b = this.cardEGA.fATCData? this.cardEGA.aATCRegs[this.cardEGA.iATCReg & Card.ATC.INDX_MASK] : this.cardEGA.iATCReg;
|
||||
this.messagePort(Card.ATC.PORT, null, addrFrom, "ATC." + (this.cardEGA.fATCData? this.cardEGA.asATCRegs[this.cardEGA.iATCReg & Card.ATC.INDX_MASK] : "INDX"), b);
|
||||
if (this.messageEnabled()) {
|
||||
this.messagePort(Card.ATC.PORT, null, addrFrom, "ATC." + (this.cardEGA.fATCData? this.cardEGA.asATCRegs[this.cardEGA.iATCReg & Card.ATC.INDX_MASK] : "INDX"), b);
|
||||
}
|
||||
this.cardEGA.fATCData = !this.cardEGA.fATCData;
|
||||
return b;
|
||||
};
|
||||
|
|
@ -4377,9 +4402,13 @@ Video.prototype.outATC = function(port, bOut, addrFrom)
|
|||
this.cardEGA.fATCData = true;
|
||||
if ((bOut & Card.ATC.INDX_PAL_ENABLE) && !fPalEnabled) {
|
||||
if (!this.buildFonts()) {
|
||||
if (DEBUG) this.messageDebugger("outATC(" + str.toHexByte(bOut) + "): no font changes required");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("outATC(" + str.toHexByte(bOut) + "): no font changes required");
|
||||
}
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger("outATC(" + str.toHexByte(bOut) + "): redraw screen for font changes");
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("outATC(" + str.toHexByte(bOut) + "): redraw screen for font changes");
|
||||
}
|
||||
this.updateScreen(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -4387,7 +4416,9 @@ Video.prototype.outATC = function(port, bOut, addrFrom)
|
|||
var iReg = this.cardEGA.iATCReg & Card.ATC.INDX_MASK;
|
||||
if (iReg >= Card.ATC.PALETTE_REGS || !fPalEnabled) {
|
||||
if (Video.TRAPALL || this.cardEGA.aATCRegs[iReg] !== bOut) {
|
||||
this.messagePort(port, bOut, addrFrom, "ATC." + this.cardEGA.asATCRegs[iReg]);
|
||||
if (this.messageEnabled()) {
|
||||
this.messagePort(port, bOut, addrFrom, "ATC." + this.cardEGA.asATCRegs[iReg]);
|
||||
}
|
||||
this.cardEGA.aATCRegs[iReg] = bOut;
|
||||
}
|
||||
}
|
||||
|
|
@ -4469,7 +4500,9 @@ Video.prototype.outSEQIndx = function(port, bOut, addrFrom)
|
|||
Video.prototype.inSEQData = function(port, addrFrom)
|
||||
{
|
||||
var b = this.cardEGA.aSEQRegs[this.cardEGA.iSEQReg];
|
||||
this.messagePort(Card.SEQ.DATA.PORT, null, addrFrom, "SEQ" + this.cardEGA.asSEQRegs[this.cardEGA.iSEQReg], b);
|
||||
if (this.messageEnabled()) {
|
||||
this.messagePort(Card.SEQ.DATA.PORT, null, addrFrom, "SEQ" + this.cardEGA.asSEQRegs[this.cardEGA.iSEQReg], b);
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
||||
|
|
@ -4484,7 +4517,9 @@ Video.prototype.inSEQData = function(port, addrFrom)
|
|||
Video.prototype.outSEQData = function(port, bOut, addrFrom)
|
||||
{
|
||||
if (Video.TRAPALL || this.cardEGA.aSEQRegs[this.cardEGA.iSEQReg] !== bOut) {
|
||||
this.messagePort(Card.SEQ.DATA.PORT, bOut, addrFrom, "SEQ." + this.cardEGA.asSEQRegs[this.cardEGA.iSEQReg]);
|
||||
if (this.messageEnabled()) {
|
||||
this.messagePort(Card.SEQ.DATA.PORT, bOut, addrFrom, "SEQ." + this.cardEGA.asSEQRegs[this.cardEGA.iSEQReg]);
|
||||
}
|
||||
this.cardEGA.aSEQRegs[this.cardEGA.iSEQReg] = bOut;
|
||||
}
|
||||
if (this.cardEGA.iSEQReg == Card.SEQ.MAPMASK.INDX) {
|
||||
|
|
@ -4601,7 +4636,9 @@ Video.prototype.outGRCIndx = function(port, bOut, addrFrom)
|
|||
Video.prototype.inGRCData = function(port, addrFrom)
|
||||
{
|
||||
var b = this.cardEGA.aGRCRegs[this.cardEGA.iGRCReg];
|
||||
this.messagePort(Card.GRC.DATA.PORT, null, addrFrom, "GRC." + this.cardEGA.asGRCRegs[this.cardEGA.iGRCReg], b);
|
||||
if (this.messageEnabled()) {
|
||||
this.messagePort(Card.GRC.DATA.PORT, null, addrFrom, "GRC." + this.cardEGA.asGRCRegs[this.cardEGA.iGRCReg], b);
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
||||
|
|
@ -4616,7 +4653,9 @@ Video.prototype.inGRCData = function(port, addrFrom)
|
|||
Video.prototype.outGRCData = function(port, bOut, addrFrom)
|
||||
{
|
||||
if (Video.TRAPALL || this.cardEGA.aGRCRegs[this.cardEGA.iGRCReg] !== bOut) {
|
||||
this.messagePort(Card.GRC.DATA.PORT, bOut, addrFrom, "GRC." + this.cardEGA.asGRCRegs[this.cardEGA.iGRCReg]);
|
||||
if (this.messageEnabled()) {
|
||||
this.messagePort(Card.GRC.DATA.PORT, bOut, addrFrom, "GRC." + this.cardEGA.asGRCRegs[this.cardEGA.iGRCReg]);
|
||||
}
|
||||
this.cardEGA.aGRCRegs[this.cardEGA.iGRCReg] = bOut;
|
||||
}
|
||||
switch(this.cardEGA.iGRCReg) {
|
||||
|
|
@ -4741,7 +4780,9 @@ Video.prototype.outCGAMode = function(port, bOut, addrFrom)
|
|||
Video.prototype.inCGAColor = function(port, addrFrom)
|
||||
{
|
||||
var b = this.cardColor.colorReg;
|
||||
this.messagePort(this.cardColor.port + 5, null, addrFrom, this.cardColor.type + ".COLOR", b);
|
||||
if (this.messageEnabled()) {
|
||||
this.messagePort(this.cardColor.port + 5, null, addrFrom, this.cardColor.type + ".COLOR", b);
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
||||
|
|
@ -4755,7 +4796,9 @@ Video.prototype.inCGAColor = function(port, addrFrom)
|
|||
*/
|
||||
Video.prototype.outCGAColor = function(port, bOut, addrFrom)
|
||||
{
|
||||
this.messagePort(this.cardColor.port + 5, bOut, addrFrom, this.cardColor.type + ".COLOR");
|
||||
if (this.messageEnabled()) {
|
||||
this.messagePort(this.cardColor.port + 5, bOut, addrFrom, this.cardColor.type + ".COLOR");
|
||||
}
|
||||
if (this.cardColor.colorReg !== bOut) {
|
||||
this.cardColor.colorReg = bOut;
|
||||
/*
|
||||
|
|
@ -4821,7 +4864,9 @@ Video.prototype.inCRTCData = function(card, addrFrom)
|
|||
{
|
||||
var b;
|
||||
if (card.iCRTCReg < card.nCRTCRegs) b = card.aCRTCRegs[card.iCRTCReg];
|
||||
this.messagePort(card.port + 1, null, addrFrom, "CRTC." + card.asCRTCRegs[card.iCRTCReg], b);
|
||||
if (this.messageEnabled()) {
|
||||
this.messagePort(card.port + 1, null, addrFrom, "CRTC." + card.asCRTCRegs[card.iCRTCReg], b);
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
||||
|
|
@ -4837,7 +4882,9 @@ Video.prototype.outCRTCData = function(card, bOut, addrFrom)
|
|||
{
|
||||
if (card.iCRTCReg < card.nCRTCRegs) {
|
||||
if (Video.TRAPALL || card.aCRTCRegs[card.iCRTCReg] !== bOut) {
|
||||
this.messagePort(card.port + 1, bOut, addrFrom, "CRTC." + card.asCRTCRegs[card.iCRTCReg]);
|
||||
if (this.messageEnabled()) {
|
||||
this.messagePort(card.port + 1, bOut, addrFrom, "CRTC." + card.asCRTCRegs[card.iCRTCReg]);
|
||||
}
|
||||
card.aCRTCRegs[card.iCRTCReg] = bOut;
|
||||
}
|
||||
/*
|
||||
|
|
@ -4854,7 +4901,9 @@ Video.prototype.outCRTCData = function(card, bOut, addrFrom)
|
|||
}
|
||||
this.checkCursor();
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger("outCRTCData(): ignoring unexpected write to CRTC[" + str.toHexByte(card.iCRTCReg) + "]: " + str.toHexByte(bOut));
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("outCRTCData(): ignoring unexpected write to CRTC[" + str.toHexByte(card.iCRTCReg) + "]: " + str.toHexByte(bOut));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -4996,43 +5045,6 @@ Video.prototype.dumpVideo = function(sParm)
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* messageDebugger(sMessage)
|
||||
*
|
||||
* This is a combination of the Debugger's messageEnabled(MESSAGE_VIDEO) and message() functions, for convenience.
|
||||
*
|
||||
* @this {Video}
|
||||
* @param {boolean} [fForce] to display the message regardless of the MESSAGE_VIDEO setting, provided the Debugger is loaded
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
*/
|
||||
Video.prototype.messageDebugger = function(sMessage, fForce)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (fForce || this.dbg.messageEnabled(Debugger.MESSAGE.VIDEO)) {
|
||||
this.dbg.message(sMessage);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* messagePort(port, bOut, addrFrom, name, bIn)
|
||||
*
|
||||
* This is an internal version of the Debugger's messagePort() function, for convenience.
|
||||
*
|
||||
* @this {Video}
|
||||
* @param {number} port
|
||||
* @param {number|null} bOut if an output operation
|
||||
* @param {number|null} [addrFrom]
|
||||
* @param {string|null} [name] of the port, if any
|
||||
* @param {number} [bIn] is the input value, if known, on an input operation
|
||||
*/
|
||||
Video.prototype.messagePort = function(port, bOut, addrFrom, name, bIn)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
this.dbg.messagePort(this, port, bOut, addrFrom, name, Debugger.MESSAGE.VIDEO, bIn);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Port input/output notification tables
|
||||
*
|
||||
|
|
|
|||
|
|
@ -966,7 +966,7 @@ X86CPU.prototype.checkIntNotify = function(nInt)
|
|||
* checksEnabled() function, and therefore in fDebugCheck, so for maximum speed, we check fDebugCheck first.
|
||||
*/
|
||||
if (DEBUGGER && this.bitField.fDebugCheck) {
|
||||
if (this.dbg.messageEnabled(Debugger.MESSAGE.INT) && this.dbg.messageInt(nInt, this.regEIP)) {
|
||||
if (this.messageEnabled(Debugger.MESSAGE.INT) && this.dbg.messageInt(nInt, this.regEIP)) {
|
||||
this.addIntReturn(this.regEIP, function(cpu, nCycles) {
|
||||
return function onIntReturn(nLevel) {
|
||||
cpu.dbg.messageIntReturn(nInt, nLevel, cpu.getCycles() - nCycles);
|
||||
|
|
@ -1210,7 +1210,7 @@ X86CPU.prototype.getSeg = function(sName)
|
|||
* HACK: We return a fake segment register object in which only the base physical address is valid,
|
||||
* because that's all the caller provided (ie, we must be restoring from an older state).
|
||||
*/
|
||||
if (DEBUG) this.assert(typeof sName == "number");
|
||||
this.assert(typeof sName == "number");
|
||||
return [0, sName, 0, 0, ""];
|
||||
}
|
||||
};
|
||||
|
|
@ -1311,7 +1311,7 @@ X86CPU.prototype.setIP = function(off)
|
|||
*/
|
||||
X86CPU.prototype.setCSIP = function(off, sel, fCall)
|
||||
{
|
||||
if (DEBUG) this.assert((off & 0xffff) == off);
|
||||
this.assert((off & 0xffff) == off);
|
||||
this.segCS.fCall = fCall;
|
||||
/*
|
||||
* We break this operation into the following discrete steps (eg, set IP, load CS, and then update EIP)
|
||||
|
|
@ -1668,7 +1668,7 @@ X86CPU.prototype.setPS = function(regPS)
|
|||
/*
|
||||
* Assert that all requested flag bits now agree with our simulated (PS_INDIRECT) bits
|
||||
*/
|
||||
if (DEBUG) this.assert((regPS & X86.PS.INDIRECT) == (this.getPS() & X86.PS.INDIRECT));
|
||||
this.assert((regPS & X86.PS.INDIRECT) == (this.getPS() & X86.PS.INDIRECT));
|
||||
|
||||
if (this.regPS & X86.PS.TF) {
|
||||
this.intFlags |= X86.INTFLAG.TRAP;
|
||||
|
|
@ -2233,7 +2233,7 @@ X86CPU.prototype.popWord = function()
|
|||
*/
|
||||
X86CPU.prototype.pushWord = function(w)
|
||||
{
|
||||
if (DEBUG) this.assert((w & 0xffff) == w);
|
||||
this.assert((w & 0xffff) == w);
|
||||
this.setSOWord(this.segSS, (this.regSP = (this.regSP - 2) & 0xffff), w);
|
||||
};
|
||||
|
||||
|
|
@ -2308,7 +2308,7 @@ X86CPU.prototype.pushWord = function(w)
|
|||
*/
|
||||
X86CPU.prototype.checkINTR = function()
|
||||
{
|
||||
if (DEBUG) this.assert(this.intFlags);
|
||||
this.assert(this.intFlags);
|
||||
if (!(this.opFlags & X86.OPFLAG.NOINTR)) {
|
||||
if ((this.intFlags & X86.INTFLAG.INTR) && (this.regPS & X86.PS.IF)) {
|
||||
var nIDT = this.chipset.getIRRVector();
|
||||
|
|
@ -2495,7 +2495,7 @@ X86CPU.prototype.stepCPU = function(nMinCycles)
|
|||
* One exception I make here is when you've asked the Debugger to display PIC messages, the idea being that
|
||||
* if you're watching the PIC that closely, then you want to hardware interrupts to occur regardless.
|
||||
*/
|
||||
if (!nMinCycles && this.dbg && !this.dbg.messageEnabled(Debugger.MESSAGE.PIC)) this.opFlags |= X86.OPFLAG.NOINTR;
|
||||
if (!nMinCycles && !this.messageEnabled(Debugger.MESSAGE.PIC)) this.opFlags |= X86.OPFLAG.NOINTR;
|
||||
|
||||
do {
|
||||
var opPrefixes = this.opFlags & X86.OPFLAG.PREFIXES;
|
||||
|
|
@ -2553,7 +2553,7 @@ X86CPU.prototype.stepCPU = function(nMinCycles)
|
|||
if (++this.iSampleFreq >= this.nSampleFreq) {
|
||||
this.iSampleFreq = 0;
|
||||
if (this.iSampleSkip < this.nSampleSkip) {
|
||||
this.iSampleSkip++
|
||||
this.iSampleSkip++;
|
||||
} else {
|
||||
if (this.iSampleNext == this.nSamples) {
|
||||
this.println("sample buffer full");
|
||||
|
|
@ -2621,25 +2621,6 @@ X86CPU.prototype.stepCPU = function(nMinCycles)
|
|||
return (this.bitField.fComplete? this.nBurstCycles - this.nStepCycles : (this.bitField.fComplete === undefined? 0 : -1));
|
||||
};
|
||||
|
||||
/**
|
||||
* messageDebugger(sMessage, bitsMessage)
|
||||
*
|
||||
* This is a combination of the Debugger's messageEnabled(MESSAGE_CPU) and message() functions, for convenience.
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
*/
|
||||
X86CPU.prototype.messageDebugger = function(sMessage, bitsMessage)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage == null) {
|
||||
bitsMessage = Debugger.MESSAGE.CPU;
|
||||
}
|
||||
if (this.dbg.messageEnabled(bitsMessage)) this.dbg.message(sMessage);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* X86CPU.init()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -571,10 +571,10 @@ var X86Help = {
|
|||
* JavaScript exception), and since we don't want that instruction to perform any writes that might
|
||||
* be destructive, we should shut off all further reads/writes for the current instruction.
|
||||
*
|
||||
* As long as we're not using EAFUNCS, this is easy for any EA-based memory accesses: simply set
|
||||
* As long as we're not using EAFUNCS, that's easy for any EA-based memory accesses: simply set both
|
||||
* the NOREAD and NOWRITE flags. However, there may still be direct, non-EA-based memory accesses that
|
||||
* could cause us grief. TODO: Implement the ultimate solution, which will involve setting a special
|
||||
* flag and throwing an exception that the CPU must intercept and then quietly ignore.
|
||||
* could cause us grief. TODO: Implement the ultimate solution, which will involve throwing a special
|
||||
* JavaScript exception that cpu.js must intercept and quietly ignore.
|
||||
*/
|
||||
if (!EAFUNCS) {
|
||||
this.opFlags &= ~(X86.OPFLAG.NOREAD | X86.OPFLAG.NOWRITE);
|
||||
|
|
@ -588,24 +588,20 @@ var X86Help = {
|
|||
*
|
||||
* TODO: Provide the Debugger with some UI to control its "interference" with fault dispatching, and to
|
||||
* continue the dispatch after it has interfered. At the moment, your only option is to single-step over
|
||||
* the offending instruction to allow the fault to be dispatched.
|
||||
* the offending instruction, which will allow the fault to be dispatched, and then continue execution.
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} nFault
|
||||
* @param {number} [nError]
|
||||
* @param {boolean} [fHalt] will halt the CPU if true *and* a Debugger is loaded
|
||||
* @return {boolean|undefined} true to block the fault, otherwise dispatch it
|
||||
* @param {boolean} [fHalt] true if the CPU should always be halted, false if "it depends"
|
||||
* @return {boolean|undefined} true to block the fault (often desirable when fHalt is true), otherwise dispatch it
|
||||
*/
|
||||
opHelpFaultMessage: function(nFault, nError, fHalt)
|
||||
{
|
||||
var bitsMessage = Debugger.MESSAGE.FAULT;
|
||||
var bOpcode = this.bus.getByteDirect(this.regEIP);
|
||||
|
||||
var fDebugger = false;
|
||||
if (DEBUGGER && this.dbg) {
|
||||
fDebugger = true;
|
||||
if (nFault == X86.EXCEPTION.GP_FAULT) fHalt = true;
|
||||
}
|
||||
if (this.messageEnabled(bitsMessage)) fHalt = true;
|
||||
|
||||
/*
|
||||
* OS/2 1.0 uses an INT3 (0xCC) opcode in conjunction with an invalid IDT to trigger a triple-fault
|
||||
|
|
@ -633,15 +629,24 @@ var X86Help = {
|
|||
fHalt = false;
|
||||
}
|
||||
|
||||
if (fDebugger && this.dbg.messageEnabled(bitsMessage) || !fDebugger && fHalt) {
|
||||
if (this.messageEnabled(bitsMessage) || fHalt) {
|
||||
var sMessage = (fHalt? '\n' : '') + "Fault " + str.toHexByte(nFault) + (nError != null? " (" + str.toHexWord(nError) + ")" : "") + " on opcode 0x" + str.toHexByte(bOpcode) + " at " + str.toHexAddr(this.regIP, this.segCS.sel) + " (%" + str.toHex(this.regEIP, 6) + ")";
|
||||
if (fDebugger) {
|
||||
this.messageDebugger(sMessage, bitsMessage);
|
||||
if (this.messageDebugger(sMessage)) {
|
||||
if (fHalt) {
|
||||
/*
|
||||
* By setting fHalt to fRunning (which is true while running but false while single-stepping),
|
||||
* this allows a fault to be dispatched when you single-step over a faulting instruction; you can
|
||||
* then continue single-stepping into the fault handler, or start running again.
|
||||
*/
|
||||
fHalt = this.bitField.fRunning;
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
} else if (fHalt) {
|
||||
} else {
|
||||
/*
|
||||
* If messageDebugger() returned false, then messageEnabled() must have returned false as well, which
|
||||
* means that fHalt must be true. Which means we should shut the machine down.
|
||||
*/
|
||||
this.assert(fHalt);
|
||||
this.notice(sMessage);
|
||||
this.stopCPU();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,6 +126,9 @@ var X86Op0F = {
|
|||
*/
|
||||
opLOADALL: function() {
|
||||
if (this.segCS.cpl) {
|
||||
/*
|
||||
* You're not allowed to use LOADALL at any privilege level other than zero
|
||||
*/
|
||||
X86Help.opHelpFault.call(this, X86.EXCEPTION.GP_FAULT, 0, true);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1980,7 +1980,7 @@ var X86OpXX = {
|
|||
* op=0x9B (wait)
|
||||
*/
|
||||
opWAIT: function() {
|
||||
this.messageDebugger("WAIT not implemented");
|
||||
this.messageDebugger("WAIT not implemented", Debugger.MESSAGE.CPU);
|
||||
this.nStepCycles--;
|
||||
},
|
||||
/**
|
||||
|
|
@ -2026,7 +2026,7 @@ var X86OpXX = {
|
|||
if (ah & X86.PS.ZF) this.setZF(); else this.clearZF();
|
||||
if (ah & X86.PS.SF) this.setSF(); else this.clearSF();
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesLAHF;
|
||||
if (DEBUG) this.assert((this.getPS() & X86.PS.SAHF) == (ah & X86.PS.SAHF));
|
||||
this.assert((this.getPS() & X86.PS.SAHF) == (ah & X86.PS.SAHF));
|
||||
},
|
||||
/**
|
||||
* @this {X86CPU}
|
||||
|
|
|
|||
|
|
@ -193,9 +193,7 @@ X86Seg.loadProt = function loadProt(sel, fSuppress)
|
|||
X86Seg.loadRealIDT = function loadRealIDT(nIDT)
|
||||
{
|
||||
var cpu = this.cpu;
|
||||
if (DEBUG) {
|
||||
cpu.assert(nIDT >= 0 && nIDT < 256 && !cpu.addrIDT && cpu.addrIDTLimit == 0x03FF);
|
||||
}
|
||||
cpu.assert(nIDT >= 0 && nIDT < 256 && !cpu.addrIDT && cpu.addrIDTLimit == 0x03FF);
|
||||
/*
|
||||
* Intel documentation for INT/INTO under "REAL ADDRESS MODE EXCEPTIONS" says:
|
||||
*
|
||||
|
|
@ -220,7 +218,7 @@ X86Seg.loadRealIDT = function loadRealIDT(nIDT)
|
|||
X86Seg.loadProtIDT = function loadProtIDT(nIDT)
|
||||
{
|
||||
var cpu = this.cpu;
|
||||
if (DEBUG) cpu.assert(nIDT >= 0 && nIDT < 256);
|
||||
cpu.assert(nIDT >= 0 && nIDT < 256);
|
||||
|
||||
nIDT <<= 3;
|
||||
var addrDesc = cpu.addrIDT + nIDT;
|
||||
|
|
@ -380,7 +378,7 @@ X86Seg.checkWriteProtDisallowed = function checkWriteProtDisallowed(off, cb, fSu
|
|||
X86Seg.switchTSS = function switchTSS(selNew, fNest)
|
||||
{
|
||||
var cpu = this.cpu;
|
||||
if (DEBUG) cpu.assert(this === cpu.segCS);
|
||||
cpu.assert(this === cpu.segCS);
|
||||
|
||||
var addrOld = cpu.segTSS.base;
|
||||
var cplOld = this.cpl;
|
||||
|
|
@ -424,7 +422,7 @@ X86Seg.switchTSS = function switchTSS(selNew, fNest)
|
|||
var offSS = X86.TSS.TASK_SS;
|
||||
var offSP = X86.TSS.TASK_SP;
|
||||
cpu.setPS(cpu.getWord(addrNew + X86.TSS.TASK_PS) | (fNest? X86.PS.NT : 0));
|
||||
if (DEBUG) cpu.assert(!fNest || !!(cpu.regPS & X86.PS.NT));
|
||||
cpu.assert(!fNest || !!(cpu.regPS & X86.PS.NT));
|
||||
cpu.regAX = cpu.getWord(addrNew + X86.TSS.TASK_AX);
|
||||
cpu.regCX = cpu.getWord(addrNew + X86.TSS.TASK_CX);
|
||||
cpu.regDX = cpu.getWord(addrNew + X86.TSS.TASK_DX);
|
||||
|
|
@ -581,14 +579,14 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
|
|||
if (rpl <= dpl) {
|
||||
cplPrev = this.cpl;
|
||||
if (this.load(selCode, true) == null) {
|
||||
if (DEBUG) cpu.assert(false);
|
||||
cpu.assert(false);
|
||||
base = null;
|
||||
break;
|
||||
}
|
||||
cpu.regIP = limit;
|
||||
if (this.cpl < cplPrev) {
|
||||
if (fCall !== true) {
|
||||
if (DEBUG) cpu.assert(false);
|
||||
cpu.assert(false);
|
||||
base = null;
|
||||
break;
|
||||
}
|
||||
|
|
@ -612,7 +610,7 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
|
|||
}
|
||||
return this.base;
|
||||
}
|
||||
if (DEBUG) cpu.assert(false);
|
||||
cpu.assert(false);
|
||||
if (!fSuppress) X86Help.opHelpFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel, true);
|
||||
base = null;
|
||||
break;
|
||||
|
|
@ -628,7 +626,7 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
|
|||
if (dpl <= this.cpl) {
|
||||
cplPrev = this.cpl;
|
||||
if (this.load(selCode, true) == null) {
|
||||
if (DEBUG) cpu.assert(false);
|
||||
cpu.assert(false);
|
||||
base = null;
|
||||
break;
|
||||
}
|
||||
|
|
@ -657,7 +655,7 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
|
|||
}
|
||||
return this.base;
|
||||
}
|
||||
if (DEBUG) cpu.assert(false);
|
||||
cpu.assert(false);
|
||||
if (!fSuppress) X86Help.opHelpFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel | X86.ERRCODE.EXT, true);
|
||||
base = null;
|
||||
break;
|
||||
|
|
@ -674,7 +672,7 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
|
|||
base = null;
|
||||
break;
|
||||
}
|
||||
if (DEBUG) cpu.assert(!!selMasked); // a null CS selector should be caught by the final preceding check
|
||||
cpu.assert(!!selMasked); // a null CS selector should be caught by the final preceding check
|
||||
}
|
||||
else if (this.id == X86Seg.ID.DATA) {
|
||||
if (selMasked) {
|
||||
|
|
@ -726,8 +724,8 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
|
|||
*
|
||||
* This is used in unusual situations where the base must be set independently; normally, the base
|
||||
* is set according to the selector provided to load(), but there are a few cases where setBase() is
|
||||
* required (eg, in resetRegs() where the 80286 wants the real-mode CS selector to be 0xF000 but the
|
||||
* CS base must be 0xFF0000, and possibly LOADALL).
|
||||
* required (eg, in resetRegs(), where the 80286 wants the real-mode CS selector to be 0xF000 but the
|
||||
* CS base must be 0xFF0000).
|
||||
*
|
||||
* @this {X86Seg}
|
||||
* @param {number} addr
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ if (typeof module !== 'undefined') {
|
|||
}
|
||||
|
||||
/**
|
||||
* Component(type, parms, constructor)
|
||||
* Component(type, parms, constructor, bitsMessage)
|
||||
*
|
||||
* A Component object requires:
|
||||
*
|
||||
|
|
@ -79,8 +79,9 @@ if (typeof module !== 'undefined') {
|
|||
* @param {string} type
|
||||
* @param {Object} [parms]
|
||||
* @param {Object} [constructor]
|
||||
* @param {number} [bitsMessage]
|
||||
*/
|
||||
function Component(type, parms, constructor)
|
||||
function Component(type, parms, constructor, bitsMessage)
|
||||
{
|
||||
this.type = type;
|
||||
|
||||
|
|
@ -125,6 +126,7 @@ function Component(type, parms, constructor)
|
|||
this.clearError();
|
||||
this.bindings = {};
|
||||
this.dbg = null; // by default, no connection to a Debugger
|
||||
this.bitsMessage = bitsMessage || -1;
|
||||
|
||||
Component.add(this);
|
||||
}
|
||||
|
|
@ -729,7 +731,7 @@ Component.prototype = {
|
|||
* $('h')
|
||||
* ...
|
||||
*
|
||||
* If you have no desire to stop on assertions, then yes, consider this a giant no-op.
|
||||
* If you have no desire to stop on assertions, consider this a no-op.
|
||||
*/
|
||||
try {
|
||||
throw new Error(s);
|
||||
|
|
@ -929,6 +931,63 @@ Component.prototype = {
|
|||
powerDown: function(fSave, fShutdown) {
|
||||
if (fShutdown) this.bitField.fPowered = false;
|
||||
return true;
|
||||
},
|
||||
/**
|
||||
* messageEnabled(bitsMessage, fOnly)
|
||||
*
|
||||
* @this {Component}
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
* @return {boolean} true if all specified message enabled, false if not
|
||||
*/
|
||||
messageEnabled: function(bitsMessage) {
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (this === this.dbg) {
|
||||
bitsMessage = bitsMessage || 0;
|
||||
} else {
|
||||
if (!bitsMessage) {
|
||||
bitsMessage = this.bitsMessage;
|
||||
}
|
||||
}
|
||||
var bitsEnabled = this.dbg.bitsMessage & bitsMessage;
|
||||
return (bitsEnabled === bitsMessage || !!(bitsEnabled & this.dbg.bitsWarning));
|
||||
}
|
||||
return false;
|
||||
},
|
||||
/**
|
||||
* messageDebugger(sMessage, bitsMessage, fAddress)
|
||||
*
|
||||
* @this {Component}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
* @param {boolean} [fAddress] is true to display the current address
|
||||
* @return {boolean} true if Debugger available, false if not
|
||||
*/
|
||||
messageDebugger: function(sMessage, bitsMessage, fAddress) {
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage == null || this.messageEnabled(bitsMessage)) {
|
||||
this.dbg.message(sMessage, fAddress);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
/**
|
||||
* messagePort(port, bOut, addrFrom, name, bIn, bitsMessage)
|
||||
*
|
||||
* This is an internal version of the Debugger's messagePort() function, for convenience.
|
||||
*
|
||||
* @this {Component}
|
||||
* @param {number} port
|
||||
* @param {number|null} bOut if an output operation
|
||||
* @param {number|null} [addrFrom]
|
||||
* @param {string|null} [name] of the port, if any
|
||||
* @param {number} [bIn] is the input value, if known, on an input operation
|
||||
* @param {number} [bitsMessage] is one or more Debugger MESSAGE_* category flag(s)
|
||||
*/
|
||||
messagePort: function(port, bOut, addrFrom, name, bIn, bitsMessage) {
|
||||
if (DEBUGGER && this.dbg) {
|
||||
this.dbg.messageIO(this, port, bOut, addrFrom, name, bIn, bitsMessage || this.bitsMessage);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ function embedMachine(sName, sVersion, idElement, sXMLFile, sXSLFile, sStateFile
|
|||
|
||||
var doneMachine = function() {
|
||||
Component.assert(cMachines > 0);
|
||||
if (--cMachines == 0) {
|
||||
if (!--cMachines) {
|
||||
if (fAsync) web.enablePageEvents(true);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -389,9 +389,9 @@ web.promptUser = function(sPrompt, sDefault)
|
|||
*
|
||||
* true if localStorage support exists, is enabled, and works; "falsey" otherwise
|
||||
*
|
||||
* @type {boolean|undefined}
|
||||
* @type {boolean|null}
|
||||
*/
|
||||
web.fLocalStorage;
|
||||
web.fLocalStorage = null;
|
||||
|
||||
/**
|
||||
* hasLocalStorage
|
||||
|
|
@ -401,7 +401,7 @@ web.fLocalStorage;
|
|||
* @return {boolean}
|
||||
*/
|
||||
web.hasLocalStorage = function() {
|
||||
if (web.fLocalStorage === undefined) {
|
||||
if (web.fLocalStorage == null) {
|
||||
var f;
|
||||
var sTest = 'PCjs.localStorage';
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in a new issue