Enhanced INT return handling, and reorganized some disks.
This commit is contained in:
parent
c722a8ec16
commit
27359de735
140 changed files with 701 additions and 503 deletions
|
|
@ -199,8 +199,9 @@ function loadMachine(sFile)
|
|||
* do with "package.json". Also note that require() assumes the same path as that of the
|
||||
* requiring file, whereas fs.readFileSync() assumes the path reported by process.cwd().
|
||||
*
|
||||
* TODO: Actually, I removed the comments from my sample "machine.json" file, so we should
|
||||
* try to reinstate this code now.
|
||||
* TODO: I've since removed the comments from my sample "machine.json" file, so we could
|
||||
* try to reinstate this code; however, there are still hex constants, which I find *much*
|
||||
* preferable to the decimal equivalents. JSON's restrictions continue to infuriate me.
|
||||
*
|
||||
* var machine = require(lib + "../bin/" +sFile);
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1333,17 +1333,17 @@ ChipSet.prototype.getRTCCycleLimit = function(nCycles)
|
|||
if (nCyclesUpdate > 0) {
|
||||
if (nCycles > nCyclesUpdate) {
|
||||
if (DEBUG && this.messageEnabled(Messages.RTC)) {
|
||||
this.messageDebugger("getRTCCycleLimit(" + nCycles + "): reduced to " + nCyclesUpdate + " cycles", true);
|
||||
this.messagePrint("getRTCCycleLimit(" + nCycles + "): reduced to " + nCyclesUpdate + " cycles", true);
|
||||
}
|
||||
nCycles = nCyclesUpdate;
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled(Messages.RTC)) {
|
||||
this.messageDebugger("getRTCCycleLimit(" + nCycles + "): already less than " + nCyclesUpdate + " cycles", true);
|
||||
this.messagePrint("getRTCCycleLimit(" + nCycles + "): already less than " + nCyclesUpdate + " cycles", true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled(Messages.RTC)) {
|
||||
this.messageDebugger("RTC next update has passed by " + nCyclesUpdate + " cycles", true);
|
||||
this.messagePrint("RTC next update has passed by " + nCyclesUpdate + " cycles", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1402,9 +1402,9 @@ ChipSet.prototype.updateRTCTime = function()
|
|||
if (DEBUG) {
|
||||
if (nCyclesUpdate - this.nRTCCyclesNextUpdate > this.nRTCCyclesPerPeriod) {
|
||||
if (bPrev & ChipSet.CMOS.STATUSC.PF) {
|
||||
this.messageDebugger("RTC interrupt handler failed to clear STATUSC", Messages.RTC);
|
||||
this.messagePrint("RTC interrupt handler failed to clear STATUSC", Messages.RTC);
|
||||
} else {
|
||||
this.messageDebugger("CPU took too long trigger new RTC periodic interrupt", Messages.RTC);
|
||||
this.messagePrint("CPU took too long trigger new RTC periodic interrupt", Messages.RTC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2714,7 +2714,7 @@ ChipSet.prototype.requestDMA = function(iDMAChannel, done)
|
|||
|
||||
if (!channel.component || !channel.fnTransfer || !channel.obj) {
|
||||
if (DEBUG && this.messageEnabled(Messages.DMA | Messages.DATA)) {
|
||||
this.messageDebugger("requestDMA(" + iDMAChannel + "): not connected to a component", true);
|
||||
this.messagePrint("requestDMA(" + iDMAChannel + "): not connected to a component", true);
|
||||
}
|
||||
if (done) done(true);
|
||||
return;
|
||||
|
|
@ -2731,7 +2731,7 @@ ChipSet.prototype.requestDMA = function(iDMAChannel, done)
|
|||
|
||||
if (channel.masked) {
|
||||
if (DEBUG && this.messageEnabled(Messages.DMA | Messages.DATA)) {
|
||||
this.messageDebugger("requestDMA(" + iDMAChannel + "): channel masked, request queued", true);
|
||||
this.messagePrint("requestDMA(" + iDMAChannel + "): channel masked, request queued", true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -2784,7 +2784,7 @@ ChipSet.prototype.advanceDMA = function(channel, fInit)
|
|||
if (DEBUG && DEBUGGER && channel.sAddrDebug === null) {
|
||||
channel.sAddrDebug = str.toHex(addr >> 4, 4) + ":" + str.toHex(addr & 0xf, 4);
|
||||
if (this.messageEnabled(this.messageBitsDMA(iDMAChannel)) && channel.xfer != ChipSet.DMA_MODE.XFER_WRITE) {
|
||||
this.messageDebugger("advanceDMA(" + iDMAChannel + ") transferring " + channel.cbDebug + " bytes from " + channel.sAddrDebug, true);
|
||||
this.messagePrint("advanceDMA(" + iDMAChannel + ") transferring " + channel.cbDebug + " bytes from " + channel.sAddrDebug, true);
|
||||
this.dbg.doDump("db", channel.sAddrDebug, "l" + Math.floor((channel.cbDebug + 15) / 16));
|
||||
}
|
||||
}
|
||||
|
|
@ -2795,7 +2795,7 @@ ChipSet.prototype.advanceDMA = function(channel, fInit)
|
|||
if (b < 0) {
|
||||
if (!channel.fWarning) {
|
||||
if (DEBUG && obj.messageEnabled(Messages.DMA)) {
|
||||
obj.messageDebugger("advanceDMA(" + iDMAChannel + ") ran out of data, assuming 0xff", true);
|
||||
obj.messagePrint("advanceDMA(" + iDMAChannel + ") ran out of data, assuming 0xff", true);
|
||||
}
|
||||
channel.fWarning = true;
|
||||
}
|
||||
|
|
@ -2844,7 +2844,7 @@ ChipSet.prototype.advanceDMA = function(channel, fInit)
|
|||
}
|
||||
else {
|
||||
if (DEBUG && this.messageEnabled(Messages.DMA | Messages.WARN)) {
|
||||
this.messageDebugger("advanceDMA(" + iDMAChannel + ") unsupported xfer mode: " + str.toHexWord(channel.xfer), true);
|
||||
this.messagePrint("advanceDMA(" + iDMAChannel + ") unsupported xfer mode: " + str.toHexWord(channel.xfer), true);
|
||||
}
|
||||
channel.fError = true;
|
||||
}
|
||||
|
|
@ -2898,7 +2898,7 @@ ChipSet.prototype.updateDMA = function(channel)
|
|||
}
|
||||
|
||||
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, true);
|
||||
this.messagePrint("updateDMA(" + iDMAChannel + ") transferred " + channel.cbDebug + " bytes to " + channel.sAddrDebug, true);
|
||||
this.dbg.doDump("db", channel.sAddrDebug, "l" + Math.floor((channel.cbDebug + 15) / 16));
|
||||
}
|
||||
|
||||
|
|
@ -3041,22 +3041,22 @@ ChipSet.prototype.outPICLo = function(iPIC, bOut, addrFrom)
|
|||
var nIRQ = (nIRL == null? undefined : pic.nIRQBase + nIRL);
|
||||
if (pic.bISR & bIREnd) {
|
||||
if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ))) {
|
||||
this.messageDebugger("outPIC" + iPIC + "(0x" + str.toHexByte(pic.port) + "): IRQ " + nIRQ + " going out of service", true);
|
||||
this.messagePrint("outPIC" + iPIC + "(0x" + str.toHexByte(pic.port) + "): IRQ " + nIRQ + " going out of service", true);
|
||||
}
|
||||
pic.bISR &= ~bIREnd;
|
||||
this.checkIRR();
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled(Messages.PIC | Messages.WARN)) {
|
||||
this.messageDebugger("outPIC" + iPIC + "(0x" + str.toHexByte(pic.port) + "): unexpected EOI command, IRQ " + nIRQ + " not in service", true);
|
||||
this.messagePrint("outPIC" + iPIC + "(0x" + str.toHexByte(pic.port) + "): unexpected EOI command, IRQ " + nIRQ + " not in service", true);
|
||||
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(Messages.PIC | Messages.WARN)) {
|
||||
this.messageDebugger("outPIC" + iPIC + "(0x" + str.toHexByte(pic.port) + "): unsupported OCW2 rotate command: " + str.toHexByte(bOut), true);
|
||||
this.dbg.stopCPU();
|
||||
if (bOCW2 & ChipSet.PIC_LO.OCW2_SET_ROTAUTO) {
|
||||
this.notice("PIC" + iPIC + "(0x" + str.toHexByte(pic.port) + "): unsupported OCW2 rotate command: " + str.toHexByte(bOut));
|
||||
this.cpu.stopCPU();
|
||||
}
|
||||
}
|
||||
else if (bOCW2 == ChipSet.PIC_LO.OCW2_SET_PRI) {
|
||||
|
|
@ -3069,10 +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(Messages.PIC | Messages.WARN)) {
|
||||
this.messageDebugger("outPIC" + iPIC + "(0x" + str.toHexByte(pic.port) + "): unsupported OCW2 automatic EOI command: " + str.toHexByte(bOut), true);
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
this.notice("PIC" + iPIC + "(0x" + str.toHexByte(pic.port) + "): unsupported OCW2 automatic EOI command: " + str.toHexByte(bOut));
|
||||
this.cpu.stopCPU();
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -3082,9 +3080,8 @@ ChipSet.prototype.outPICLo = function(iPIC, bOut, addrFrom)
|
|||
* that's unfortunate, because I don't support them yet.
|
||||
*/
|
||||
if (bOut & (ChipSet.PIC_LO.OCW3_POLL_CMD | ChipSet.PIC_LO.OCW3_SMM_CMD)) {
|
||||
if (DEBUG && this.messageEnabled(Messages.PIC | Messages.WARN)) {
|
||||
this.messageDebugger("outPIC" + iPIC + "(0x" + str.toHexByte(pic.port) + "): unsupported OCW3 command: " + str.toHexByte(bOut), true);
|
||||
}
|
||||
this.notice("PIC" + iPIC + "(0x" + str.toHexByte(pic.port) + "): unsupported OCW3 command: " + str.toHexByte(bOut));
|
||||
this.cpu.stopCPU();
|
||||
}
|
||||
pic.bOCW3 = bOut;
|
||||
}
|
||||
|
|
@ -3179,7 +3176,7 @@ ChipSet.prototype.setIRR = function(nIRQ, nDelay)
|
|||
if (!(pic.bIRR & bIRR)) {
|
||||
pic.bIRR |= bIRR;
|
||||
if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ) | Messages.CHIPSET)) {
|
||||
this.messageDebugger("setIRR(" + nIRQ + ")", true);
|
||||
this.messagePrint("setIRR(" + nIRQ + ")", true);
|
||||
}
|
||||
pic.nDelay = nDelay || 0;
|
||||
this.checkIRR();
|
||||
|
|
@ -3201,7 +3198,7 @@ ChipSet.prototype.clearIRR = function(nIRQ)
|
|||
if (pic.bIRR & bIRR) {
|
||||
pic.bIRR &= ~bIRR;
|
||||
if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ) | Messages.CHIPSET)) {
|
||||
this.messageDebugger("clearIRR(" + nIRQ + ")", true);
|
||||
this.messagePrint("clearIRR(" + nIRQ + ")", true);
|
||||
}
|
||||
this.checkIRR();
|
||||
}
|
||||
|
|
@ -3328,7 +3325,7 @@ ChipSet.prototype.getIRRVector = function(iPIC)
|
|||
|
||||
var nIRQ = pic.nIRQBase + nIRL;
|
||||
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), true);
|
||||
this.messagePrint("getIRRVector(): IRQ " + nIRQ + " interrupting @" + str.toHexAddr(this.cpu.regIP, this.cpu.segCS.sel) + " stack=" + str.toHexAddr(this.cpu.regSP, this.cpu.segSS.sel), true);
|
||||
}
|
||||
if (MAXDEBUG && DEBUGGER) {
|
||||
this.acInterrupts[nIRQ]++;
|
||||
|
|
@ -3444,7 +3441,7 @@ ChipSet.prototype.outTimer = function(iTimer, bOut, addrFrom)
|
|||
ChipSet.prototype.inTimerCtrl = function(port, addrFrom)
|
||||
{
|
||||
this.messagePort(port, null, addrFrom, "TIMER_CTRL", null, Messages.TIMER);
|
||||
if (DEBUG) this.messageDebugger("TIMER_CTRL: Read-Back command not supported (yet)", Messages.TIMER);
|
||||
if (DEBUG) this.messagePrint("TIMER_CTRL: Read-Back command not supported (yet)", Messages.TIMER);
|
||||
return null;
|
||||
};
|
||||
|
||||
|
|
@ -3465,7 +3462,7 @@ ChipSet.prototype.outTimerCtrl = function(port, bOut, addrFrom)
|
|||
*/
|
||||
var iTimer = (bOut & ChipSet.TIMER_CTRL.SC) >> 6;
|
||||
if (iTimer == 0x3) {
|
||||
if (DEBUG) this.messageDebugger("TIMER_CTRL: Read-Back command not supported (yet)", Messages.TIMER);
|
||||
if (DEBUG) this.messagePrint("TIMER_CTRL: Read-Back command not supported (yet)", Messages.TIMER);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
|
|
@ -3517,7 +3514,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(Messages.TIMER)) {
|
||||
this.messageDebugger("TIMER0 count reset @" + timer.nCyclesStart + " cycles", true);
|
||||
this.messagePrint("TIMER0 count reset @" + timer.nCyclesStart + " cycles", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3720,7 +3717,7 @@ ChipSet.prototype.updateTimer = function(iTimer, fCycleReset)
|
|||
|
||||
if (ticksElapsed < 0) {
|
||||
if (DEBUG && this.messageEnabled(Messages.TIMER)) {
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): negative tick count (" + ticksElapsed + ")", true);
|
||||
this.messagePrint("updateTimer(" + iTimer + "): negative tick count (" + ticksElapsed + ")", true);
|
||||
}
|
||||
timer.nCyclesStart = nCycles;
|
||||
ticksElapsed = 0;
|
||||
|
|
@ -3740,7 +3737,7 @@ ChipSet.prototype.updateTimer = function(iTimer, fCycleReset)
|
|||
if (timer.mode == ChipSet.TIMER_CTRL.MODE0) {
|
||||
if (count <= 0) count = 0;
|
||||
if (DEBUG && this.messageEnabled(Messages.TIMER)) {
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): MODE0 timer count=" + count, true);
|
||||
this.messagePrint("updateTimer(" + iTimer + "): MODE0 timer count=" + count, true);
|
||||
}
|
||||
if (!count) {
|
||||
timer.fOUT = true;
|
||||
|
|
@ -3775,7 +3772,7 @@ ChipSet.prototype.updateTimer = function(iTimer, fCycleReset)
|
|||
count = countInit + count;
|
||||
if (count <= 0) {
|
||||
if (DEBUG && this.messageEnabled(Messages.TIMER)) {
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): underflow=" + count, true);
|
||||
this.messagePrint("updateTimer(" + iTimer + "): underflow=" + count, true);
|
||||
}
|
||||
count = countInit;
|
||||
}
|
||||
|
|
@ -3807,7 +3804,7 @@ ChipSet.prototype.updateTimer = function(iTimer, fCycleReset)
|
|||
count = countInit + count;
|
||||
if (count <= 0) {
|
||||
if (DEBUG && this.messageEnabled(Messages.TIMER)) {
|
||||
this.messageDebugger("updateTimer(" + iTimer + "): underflow=" + count, true);
|
||||
this.messagePrint("updateTimer(" + iTimer + "): underflow=" + count, true);
|
||||
}
|
||||
count = countInit;
|
||||
}
|
||||
|
|
@ -4290,7 +4287,7 @@ ChipSet.prototype.out8042InBuffCmd = function(port, bOut, addrFrom)
|
|||
|
||||
case ChipSet.KBC.CMD.DISABLE_KBD: // 0xAD
|
||||
this.set8042CmdData(this.b8042CmdData | ChipSet.KBC.DATA.CMD.NO_CLOCK);
|
||||
if (DEBUG) this.messageDebugger("keyboard disabled", Messages.KEYBOARD | Messages.PORT);
|
||||
if (DEBUG) this.messagePrint("keyboard disabled", Messages.KEYBOARD | Messages.PORT);
|
||||
/*
|
||||
* NOTE: The MODEL_5170 BIOS calls "KBD_RESET" (F000:17D2) while the keyboard interface is disabled,
|
||||
* yet we must still deliver the Keyboard's CMDRES.BAT_OK response code? Seems like an odd thing for
|
||||
|
|
@ -4301,13 +4298,13 @@ ChipSet.prototype.out8042InBuffCmd = function(port, bOut, addrFrom)
|
|||
case ChipSet.KBC.CMD.ENABLE_KBD: // 0xAE
|
||||
this.set8042CmdData(this.b8042CmdData & ~ChipSet.KBC.DATA.CMD.NO_CLOCK);
|
||||
if (this.kbd) this.kbd.checkScanCode();
|
||||
if (DEBUG) this.messageDebugger("keyboard re-enabled", Messages.KEYBOARD | Messages.PORT);
|
||||
if (DEBUG) this.messagePrint("keyboard re-enabled", Messages.KEYBOARD | Messages.PORT);
|
||||
break;
|
||||
|
||||
case ChipSet.KBC.CMD.SELF_TEST: // 0xAA
|
||||
if (this.kbd) this.kbd.flushScanCode();
|
||||
this.set8042CmdData(this.b8042CmdData | ChipSet.KBC.DATA.CMD.NO_CLOCK);
|
||||
if (DEBUG) this.messageDebugger("keyboard disabled on reset", Messages.KEYBOARD | Messages.PORT);
|
||||
if (DEBUG) this.messagePrint("keyboard disabled on reset", Messages.KEYBOARD | Messages.PORT);
|
||||
this.set8042OutBuff(ChipSet.KBC.DATA.SELF_TEST.OK);
|
||||
this.set8042OutPort(ChipSet.KBC.OUTPORT.NO_RESET | ChipSet.KBC.OUTPORT.A20_ON);
|
||||
break;
|
||||
|
|
@ -4329,7 +4326,7 @@ ChipSet.prototype.out8042InBuffCmd = function(port, bOut, addrFrom)
|
|||
|
||||
default:
|
||||
if (DEBUG && this.messageEnabled(Messages.C8042)) {
|
||||
this.messageDebugger("unrecognized 8042 command: " + str.toHexByte(this.b8042InBuff), true);
|
||||
this.messagePrint("unrecognized 8042 command: " + str.toHexByte(this.b8042InBuff), true);
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
break;
|
||||
|
|
@ -4382,7 +4379,7 @@ ChipSet.prototype.set8042OutBuff = function(b)
|
|||
this.b8042Status &= ~ChipSet.KBC.STATUS.OUTBUFF_FULL;
|
||||
this.b8042Status |= ChipSet.KBC.STATUS.OUTBUFF_DELAY;
|
||||
if (DEBUG && this.messageEnabled(Messages.KEYBOARD | Messages.PORT)) {
|
||||
this.messageDebugger("set8042OutBuff(0x" + str.toHexByte(b) + ")", true);
|
||||
this.messagePrint("set8042OutBuff(0x" + str.toHexByte(b) + ")", true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -4404,7 +4401,7 @@ ChipSet.prototype.set8042OutPort = function(b)
|
|||
* determine if that's what the caller intended.
|
||||
*/
|
||||
if (DEBUG && this.messageEnabled(Messages.C8042)) {
|
||||
this.messageDebugger("unexpected 8042 output port reset: " + str.toHexByte(b), true);
|
||||
this.messagePrint("unexpected 8042 output port reset: " + str.toHexByte(b), true);
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
this.cpu.resetRegs();
|
||||
|
|
@ -4514,12 +4511,12 @@ ChipSet.prototype.notifyKbdData = function(b)
|
|||
}
|
||||
else {
|
||||
if (DEBUG && this.messageEnabled(Messages.KEYBOARD | Messages.PORT)) {
|
||||
this.messageDebugger("notifyKbdData(0x" + str.toHexByte(b) + "): output buffer full", true);
|
||||
this.messagePrint("notifyKbdData(0x" + str.toHexByte(b) + "): output buffer full", true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled(Messages.KEYBOARD | Messages.PORT)) {
|
||||
this.messageDebugger("notifyKbdData(0x" + str.toHexByte(b) + "): disabled", true);
|
||||
this.messagePrint("notifyKbdData(0x" + str.toHexByte(b) + "): disabled", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4582,7 +4579,7 @@ ChipSet.prototype.inCMOSData = function(port, addrFrom)
|
|||
* occurs in a timely manner, too.
|
||||
*/
|
||||
if ((bIn & ChipSet.CMOS.STATUSC.PF) && (this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.PIE)) {
|
||||
if (DEBUG) this.messageDebugger("RTC periodic interrupt cleared", Messages.RTC);
|
||||
if (DEBUG) this.messagePrint("RTC periodic interrupt cleared", Messages.RTC);
|
||||
this.setRTCCycleLimit();
|
||||
}
|
||||
}
|
||||
|
|
@ -4608,10 +4605,10 @@ ChipSet.prototype.outCMOSData = function(port, bOut, addrFrom)
|
|||
this.abCMOSData[bAddr] = (bAddr <= ChipSet.CMOS.ADDR.STATUSD? this.setRTCByte(bAddr, bOut) : bOut);
|
||||
if (bAddr == ChipSet.CMOS.ADDR.STATUSB && (bDelta & ChipSet.CMOS.STATUSB.PIE)) {
|
||||
if (bOut & ChipSet.CMOS.STATUSB.PIE) {
|
||||
if (DEBUG) this.messageDebugger("RTC periodic interrupts enabled", Messages.RTC);
|
||||
if (DEBUG) this.messagePrint("RTC periodic interrupts enabled", Messages.RTC);
|
||||
this.setRTCCycleLimit();
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger("RTC periodic interrupts disabled", Messages.RTC);
|
||||
if (DEBUG) this.messagePrint("RTC periodic interrupts disabled", Messages.RTC);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -4791,13 +4788,13 @@ ChipSet.prototype.setSpeaker = function(fOn)
|
|||
if (fOn) {
|
||||
if (this.sourceAudio) {
|
||||
this.sourceAudio['frequency']['value'] = freq;
|
||||
if (this.messageEnabled(Messages.SPEAKER)) this.messageDebugger("speaker set to " + freq + "hz", true);
|
||||
if (this.messageEnabled(Messages.SPEAKER)) this.messagePrint("speaker set to " + freq + "hz", true);
|
||||
} else {
|
||||
this.sourceAudio = this.contextAudio['createOscillator']();
|
||||
this.sourceAudio['type'] = 1; // 0: sine wave, 1: square wave, 2: sawtooth wave, 3: triangle wave
|
||||
this.sourceAudio['connect'](this.contextAudio['destination']);
|
||||
this.sourceAudio['frequency']['value'] = freq;
|
||||
if (this.messageEnabled(Messages.SPEAKER)) this.messageDebugger("speaker on at " + freq + "hz", true);
|
||||
if (this.messageEnabled(Messages.SPEAKER)) this.messagePrint("speaker on at " + freq + "hz", true);
|
||||
this.sourceAudio['noteOn'](0); // aka start()
|
||||
}
|
||||
} else {
|
||||
|
|
@ -4805,11 +4802,11 @@ ChipSet.prototype.setSpeaker = function(fOn)
|
|||
this.sourceAudio['noteOff'](0); // aka stop()
|
||||
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(Messages.SPEAKER)) this.messageDebugger("speaker off at " + freq + "hz", true);
|
||||
if (this.messageEnabled(Messages.SPEAKER)) this.messagePrint("speaker off at " + freq + "hz", true);
|
||||
}
|
||||
}
|
||||
} else if (fOn) {
|
||||
this.messageDebugger("BEEP", Messages.SPEAKER);
|
||||
this.messagePrint("BEEP", Messages.SPEAKER);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ function Computer(parmsComputer, parmsMachine, fSuspended) {
|
|||
}
|
||||
}
|
||||
|
||||
if (DEBUG && this.messageEnabled()) this.messageDebugger("PREFETCH: " + PREFETCH + ", TYPEDARRAYS: " + TYPEDARRAYS);
|
||||
if (DEBUG && this.messageEnabled()) this.messagePrint("PREFETCH: " + PREFETCH + ", TYPEDARRAYS: " + TYPEDARRAYS);
|
||||
|
||||
/*
|
||||
* Iterate through all the components again and call their initBus() handler, if any
|
||||
|
|
@ -320,7 +320,7 @@ Computer.prototype.onLoadSetReady = function(sStateFile, sStateData, nErrorCode)
|
|||
if (!nErrorCode) {
|
||||
this.sStateData = sStateData;
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("loaded state file " + sStateFile.replace(this.sUserID || "xxx", "xxx"));
|
||||
this.messagePrint("loaded state file " + sStateFile.replace(this.sUserID || "xxx", "xxx"));
|
||||
}
|
||||
} else {
|
||||
this.sResumePath = null;
|
||||
|
|
@ -362,7 +362,7 @@ Computer.prototype.wait = function(fn, parms)
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (DEBUG && this.messageEnabled()) this.messageDebugger("Computer.wait(ready)");
|
||||
if (DEBUG && this.messageEnabled()) this.messagePrint("Computer.wait(ready)");
|
||||
fn.call(this, parms);
|
||||
};
|
||||
|
||||
|
|
@ -388,7 +388,7 @@ Computer.prototype.validateState = function(stateComputer)
|
|||
if (!stateComputer) stateValidate.clear();
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Last state: " + sTimestampComputer + " (validate: " + sTimestampValidate + ")");
|
||||
this.messagePrint("Last state: " + sTimestampComputer + " (validate: " + sTimestampValidate + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -410,7 +410,7 @@ Computer.prototype.powerOn = function(resume)
|
|||
}
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Computer.powerOn(" + (resume == Computer.RESUME_REPOWER ? "repower" : (resume ? "resume" : "")) + ")");
|
||||
this.messagePrint("Computer.powerOn(" + (resume == Computer.RESUME_REPOWER ? "repower" : (resume ? "resume" : "")) + ")");
|
||||
}
|
||||
|
||||
var fRepower = false;
|
||||
|
|
@ -649,7 +649,7 @@ Computer.prototype.donePowerOn = function(aParms)
|
|||
var fRestore = aParms[2];
|
||||
|
||||
if (DEBUG && this.aFlags.fPowered && this.messageEnabled()) {
|
||||
this.messageDebugger("Computer.donePowerOn(): redundant");
|
||||
this.messagePrint("Computer.donePowerOn(): redundant");
|
||||
}
|
||||
|
||||
this.aFlags.fPowered = true;
|
||||
|
|
@ -735,7 +735,7 @@ Computer.prototype.powerOff = function(fSave, fShutdown)
|
|||
var sState = "none";
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Computer.powerOff(" + (fSave ? "save" : "nosave") + (fShutdown ? ",shutdown" : "") + ")");
|
||||
this.messagePrint("Computer.powerOff(" + (fSave ? "save" : "nosave") + (fShutdown ? ",shutdown" : "") + ")");
|
||||
}
|
||||
|
||||
var stateComputer = new State(this, Computer.sAppVer);
|
||||
|
|
@ -842,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);
|
||||
this.messagePrint("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);
|
||||
this.messagePrint("Resetting " + component.type);
|
||||
component.reset();
|
||||
}
|
||||
}
|
||||
|
|
@ -989,7 +989,7 @@ Computer.prototype.verifyUserID = function(sUserID)
|
|||
{
|
||||
this.sUserID = null;
|
||||
var fMessages = DEBUG && this.messageEnabled();
|
||||
if (fMessages) this.messageDebugger("verifyUserID(" + sUserID + ")");
|
||||
if (fMessages) this.messagePrint("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];
|
||||
|
|
@ -999,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 (fMessages) this.messageDebugger(Computer.STATE_USERID + " updated: " + response.data);
|
||||
if (fMessages) this.messagePrint(Computer.STATE_USERID + " updated: " + response.data);
|
||||
this.sUserID = response.data;
|
||||
} else {
|
||||
if (fMessages) this.messageDebugger(response.code + ": " + response.data);
|
||||
if (fMessages) this.messagePrint(response.code + ": " + response.data);
|
||||
}
|
||||
} catch (e) {
|
||||
Component.error(e.message + " (" + sResponse + ")");
|
||||
}
|
||||
} else {
|
||||
if (fMessages) this.messageDebugger("invalid response (error " + nErrorCode + ")");
|
||||
if (fMessages) this.messagePrint("invalid response (error " + nErrorCode + ")");
|
||||
}
|
||||
return this.sUserID;
|
||||
};
|
||||
|
|
@ -1024,12 +1024,12 @@ Computer.prototype.getServerStatePath = function()
|
|||
var sStatePath = null;
|
||||
if (this.sUserID) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger(Computer.STATE_USERID + " for load: " + this.sUserID);
|
||||
this.messagePrint(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.messageEnabled()) {
|
||||
this.messageDebugger(Computer.STATE_USERID + " unavailable");
|
||||
this.messagePrint(Computer.STATE_USERID + " unavailable");
|
||||
}
|
||||
}
|
||||
return sStatePath;
|
||||
|
|
@ -1051,7 +1051,7 @@ Computer.prototype.saveServerState = function(sUserID, sState)
|
|||
*/
|
||||
if (sState) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("size of server state: " + sState.length + " bytes");
|
||||
this.messagePrint("size of server state: " + sState.length + " bytes");
|
||||
}
|
||||
var response = this.storeServerState(sUserID, sState, true);
|
||||
if (response && response[UserAPI.RES.CODE] == UserAPI.CODE.OK) {
|
||||
|
|
@ -1068,7 +1068,7 @@ Computer.prototype.saveServerState = function(sUserID, sState)
|
|||
}
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("no state to store");
|
||||
this.messagePrint("no state to store");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1085,7 +1085,7 @@ Computer.prototype.saveServerState = function(sUserID, sState)
|
|||
Computer.prototype.storeServerState = function(sUserID, sState, fSync)
|
||||
{
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger(Computer.STATE_USERID + " for store: " + sUserID);
|
||||
this.messagePrint(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,
|
||||
|
|
@ -1110,7 +1110,7 @@ Computer.prototype.storeServerState = function(sUserID, sState, fSync)
|
|||
}
|
||||
sResponse = '{"' + UserAPI.RES.CODE + '":' + response[0] + ',"' + UserAPI.RES.DATA + '":"' + sResponse + '"}';
|
||||
}
|
||||
if (DEBUG && this.messageEnabled()) this.messageDebugger(sResponse);
|
||||
if (DEBUG && this.messageEnabled()) this.messagePrint(sResponse);
|
||||
return JSON.parse(sResponse);
|
||||
}
|
||||
return null;
|
||||
|
|
@ -1219,7 +1219,7 @@ Computer.init = function()
|
|||
var computer = new Computer(parmsComputer, parmsMachine, true);
|
||||
|
||||
if (DEBUG && computer.messageEnabled()) {
|
||||
computer.messageDebugger("onInit(" + computer.aFlags.fPowered + ")");
|
||||
computer.messagePrint("onInit(" + computer.aFlags.fPowered + ")");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1251,7 +1251,7 @@ Computer.show = function()
|
|||
if (computer) {
|
||||
|
||||
if (DEBUG && computer.messageEnabled()) {
|
||||
computer.messageDebugger("onShow(" + computer.fInitialized + "," + computer.aFlags.fPowered + ")");
|
||||
computer.messagePrint("onShow(" + computer.fInitialized + "," + computer.aFlags.fPowered + ")");
|
||||
}
|
||||
|
||||
if (computer.fInitialized && !computer.aFlags.fPowered) {
|
||||
|
|
@ -1300,7 +1300,7 @@ Computer.exit = function()
|
|||
if (computer) {
|
||||
|
||||
if (DEBUG && computer.messageEnabled()) {
|
||||
computer.messageDebugger("onExit(" + computer.aFlags.fPowered + ")");
|
||||
computer.messagePrint("onExit(" + computer.aFlags.fPowered + ")");
|
||||
}
|
||||
|
||||
if (computer.aFlags.fPowered) {
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,41 @@ if (DEBUGGER) {
|
|||
this.aMessageRegs[asRegs[20]] = str.toHexWord(cpu.regIP);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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, 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)"
|
||||
|
||||
this.sMessagePrev = sMessage;
|
||||
|
||||
if (this.cpu) {
|
||||
if (this.bitsMessage & Messages.HALT) {
|
||||
this.cpu.stopCPU();
|
||||
}
|
||||
/*
|
||||
* We have no idea what the frequency of println() calls might be; all we know is that they easily
|
||||
* screw up the CPU's careful assumptions about cycles per burst. So we call yieldCPU() after every
|
||||
* message, to effectively end the current burst and start fresh.
|
||||
*
|
||||
* TODO: See CPU.calcStartTime() for a discussion of why we might want to call yieldCPU() *before*
|
||||
* we display the message.
|
||||
*/
|
||||
this.cpu.yieldCPU();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* messageInt(nInt, addr)
|
||||
*
|
||||
|
|
@ -1668,41 +1703,6 @@ if (DEBUGGER) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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, 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)"
|
||||
|
||||
this.sMessagePrev = sMessage;
|
||||
|
||||
if (this.cpu) {
|
||||
if (this.bitsMessage & Messages.HALT) {
|
||||
this.cpu.stopCPU();
|
||||
}
|
||||
/*
|
||||
* We have no idea what the frequency of println() calls might be; all we know is that they easily
|
||||
* screw up the CPU's careful assumptions about cycles per burst. So we call yieldCPU() after every
|
||||
* message, to effectively end the current burst and start fresh.
|
||||
*
|
||||
* TODO: See CPU.calcStartTime() for a discussion of why we might want to call yieldCPU() *before*
|
||||
* we display the message.
|
||||
*/
|
||||
this.cpu.yieldCPU();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* traceInit()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ Disk.prototype.create = function(mode, nCylinders, nHeads, nSectors, cbSector)
|
|||
*/
|
||||
if (this.mode != DiskAPI.MODE.PRELOAD) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("blank disk for \"" + this.sDiskName + "\": " + this.nCylinders + " cylinders, " + this.nHeads + " head(s)");
|
||||
this.messagePrint("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++) {
|
||||
|
|
@ -506,7 +506,7 @@ Disk.prototype.load = function(sDiskName, sDiskPath, file, fnNotify, controller)
|
|||
if (DEBUG) {
|
||||
var sMessage = 'Disk.load("' + sDiskName + '","' + sDiskPath + '")';
|
||||
this.controller.log(sMessage);
|
||||
this.messageDebugger(sMessage);
|
||||
this.messagePrint(sMessage);
|
||||
}
|
||||
|
||||
if (this.fnNotify) {
|
||||
|
|
@ -659,7 +659,7 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
|||
if (this.fOnDemand) {
|
||||
if (!nErrorCode) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger('Disk.doneLoad("' + sDiskFile + '","' + sDiskPath + '")');
|
||||
this.messagePrint('Disk.doneLoad("' + sDiskFile + '","' + sDiskPath + '")');
|
||||
}
|
||||
this.fRemote = true;
|
||||
disk = this;
|
||||
|
|
@ -678,7 +678,7 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
|||
this.controller.notice("Unable to load disk \"" + this.sDiskName + "\" (error " + nErrorCode + ")", fPrintOnly);
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger('Disk.doneLoad("' + sDiskFile + '","' + sDiskPath + '")');
|
||||
this.messagePrint('Disk.doneLoad("' + sDiskFile + '","' + sDiskPath + '")');
|
||||
}
|
||||
try {
|
||||
/*
|
||||
|
|
@ -776,7 +776,7 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
|||
var sHeads = nHeads + " head" + (nHeads > 1 ? "s" : "");
|
||||
var nSectorsPerTrack = aDiskData[0][0].length;
|
||||
var sSectorsPerTrack = nSectorsPerTrack + " sector" + (nSectorsPerTrack > 1 ? "s" : "") + "/track";
|
||||
this.messageDebugger(sCylinders + ", " + sHeads + ", " + sSectorsPerTrack);
|
||||
this.messagePrint(sCylinders + ", " + sHeads + ", " + sSectorsPerTrack);
|
||||
}
|
||||
/*
|
||||
* Before the image is usable, we must "normalize" all the sectors. In the past, this meant
|
||||
|
|
@ -920,7 +920,7 @@ Disk.prototype.onLoadParseSectors = function(sURLName, sURLData, nErrorCode, sec
|
|||
fAsync = sectorInfo[4];
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.onLoadParseSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + ")");
|
||||
this.messagePrint("Disk.onLoadParseSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + ")");
|
||||
}
|
||||
|
||||
var abData = JSON.parse(sURLData);
|
||||
|
|
@ -938,7 +938,7 @@ Disk.prototype.onLoadParseSectors = function(sURLName, sURLData, nErrorCode, sec
|
|||
var sector = this.seek(iCylinder, iHead, iSector, true);
|
||||
if (!sector) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.onLoadParseSectors(): seek(" + iCylinder + "," + iHead + "," + iSector + ") failed");
|
||||
this.messagePrint("Disk.onLoadParseSectors(): seek(" + iCylinder + "," + iHead + "," + iSector + ") failed");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -990,7 +990,7 @@ Disk.prototype.connectRemoteDisk = function(sDiskPath)
|
|||
Disk.prototype.readRemoteSectors = function(iCylinder, iHead, iSector, cbSector, nSectors, done)
|
||||
{
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.readRemoteSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + "," + cbSector + ")");
|
||||
this.messagePrint("Disk.readRemoteSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + "," + cbSector + ")");
|
||||
}
|
||||
|
||||
if (this.fRemote) {
|
||||
|
|
@ -1030,7 +1030,7 @@ Disk.prototype.readRemoteSectors = function(iCylinder, iHead, iSector, cbSector,
|
|||
Disk.prototype.writeRemoteSectors = function(iCylinder, iHead, iSector, nSectors, abSectors, fAsync)
|
||||
{
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.writeRemoteSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + ")");
|
||||
this.messagePrint("Disk.writeRemoteSectors(" + iCylinder + ":" + iHead + ":" + iSector + ":" + nSectors + ")");
|
||||
}
|
||||
|
||||
if (this.fRemote) {
|
||||
|
|
@ -1099,7 +1099,7 @@ Disk.prototype.queueDirtySector = function(sector, fAsync)
|
|||
this.aDirtyTimestamps.push(usr.getTime());
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.queueDirtySector(" + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + "): " + this.aDirtySectors.length + " dirty");
|
||||
this.messagePrint("Disk.queueDirtySector(" + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + "): " + this.aDirtySectors.length + " dirty");
|
||||
}
|
||||
|
||||
return fAsync && this.updateWriteTimer();
|
||||
|
|
@ -1170,7 +1170,7 @@ Disk.prototype.findDirtySectors = function(fAsync)
|
|||
var j = this.aDirtySectors.indexOf(sectorNext);
|
||||
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.messagePrint("Disk.findDirtySectors(" + iCylinder + ":" + iHead + ":" + sectorNext['sector'] + ")");
|
||||
}
|
||||
this.aDirtySectors.splice(j, 1);
|
||||
this.aDirtyTimestamps.splice(j, 1);
|
||||
|
|
@ -1207,7 +1207,7 @@ Disk.prototype.onWriteCleanSectors = function(sURLName, sURLData, nErrorCode, se
|
|||
var sector = this.aDiskData[iCylinder][iHead][i];
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.onWriteCleanSectors(" + iCylinder + ":" + iHead + ":" + sector['sector'] + ")");
|
||||
this.messagePrint("Disk.onWriteCleanSectors(" + iCylinder + ":" + iHead + ":" + sector['sector'] + ")");
|
||||
}
|
||||
|
||||
if (!nErrorCode) {
|
||||
|
|
@ -1306,7 +1306,7 @@ Disk.prototype.seek = function(iCylinder, iHead, iSector, fWrite, done)
|
|||
return null;
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger('Disk.seek("' + this.sDiskName + '"): uninitialized sector ' + iCylinder + ':' + iHead + ':' + iSector);
|
||||
this.messagePrint('Disk.seek("' + this.sDiskName + '"): uninitialized sector ' + iCylinder + ':' + iHead + ':' + iSector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1385,7 +1385,7 @@ Disk.prototype.read = function(sector, ibSector, fCompare)
|
|||
var b = -1;
|
||||
|
||||
if (DEBUG && !ibSector && !fCompare && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.read(" + this.controller.id + ":" + this.drive.iDrive + "," + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + ")");
|
||||
this.messagePrint("Disk.read(" + this.controller.id + ":" + this.drive.iDrive + "," + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + ")");
|
||||
}
|
||||
|
||||
if (ibSector < sector['length']) {
|
||||
|
|
@ -1412,7 +1412,7 @@ Disk.prototype.write = function(sector, ibSector, b)
|
|||
return false;
|
||||
|
||||
if (DEBUG && !ibSector && this.messageEnabled()) {
|
||||
this.messageDebugger("Disk.write(" + this.controller.id + ":" + this.drive.iDrive + "," + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + ")");
|
||||
this.messagePrint("Disk.write(" + this.controller.id + ":" + this.drive.iDrive + "," + sector.iCylinder + ":" + sector.iHead + ":" + sector['sector'] + ")");
|
||||
}
|
||||
|
||||
if (ibSector < sector['length']) {
|
||||
|
|
@ -1484,7 +1484,7 @@ Disk.prototype.save = function()
|
|||
}
|
||||
}
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger('Disk.save("' + this.sDiskName + '"): saved ' + (deltas.length - 1) + ' change(s)');
|
||||
this.messagePrint('Disk.save("' + this.sDiskName + '"): saved ' + (deltas.length - 1) + ' change(s)');
|
||||
}
|
||||
return deltas;
|
||||
};
|
||||
|
|
@ -1614,7 +1614,7 @@ Disk.prototype.restore = function(deltas)
|
|||
this.controller.notice("unable to restore disk '" + this.sDiskName + ": " + sReason);
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger('Disk.restore("' + this.sDiskName + '"): restored ' + nChanges + ' change(s)');
|
||||
this.messagePrint('Disk.restore("' + this.sDiskName + '"): restored ' + nChanges + ' change(s)');
|
||||
}
|
||||
}
|
||||
return nChanges;
|
||||
|
|
|
|||
|
|
@ -776,7 +776,7 @@ FDC.prototype.initController = function(data)
|
|||
this.regControl = data[i] || FDC.REG_CONTROL.RATE500K; // default to maximum data rate
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("FDC initialized for " + this.aDrives.length + " drive(s)");
|
||||
this.messagePrint("FDC initialized for " + this.aDrives.length + " drive(s)");
|
||||
}
|
||||
return fSuccess;
|
||||
};
|
||||
|
|
@ -1282,7 +1282,7 @@ FDC.prototype.loadDiskette = function(iDrive, sDisketteName, sDiskettePath, fAut
|
|||
if (fAutoMount) {
|
||||
drive.fAutoMount = true;
|
||||
this.cAutoMount++;
|
||||
if (this.messageEnabled()) this.messageDebugger("loading diskette '" + sDisketteName + "'");
|
||||
if (this.messageEnabled()) this.messagePrint("loading diskette '" + sDisketteName + "'");
|
||||
}
|
||||
drive.fLocal = !!file;
|
||||
var disk = new Disk(this, drive, DiskAPI.MODE.PRELOAD);
|
||||
|
|
@ -1531,13 +1531,13 @@ FDC.prototype.addDiskHistory = function(sDisketteName, sDiskettePath, disk)
|
|||
if (this.aDiskHistory[i][1] == sDiskettePath) {
|
||||
var nChanges = disk.restore(this.aDiskHistory[i][2]);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("disk '" + sDisketteName + "' restored from history (" + nChanges + " changes)");
|
||||
this.messagePrint("disk '" + sDisketteName + "' restored from history (" + nChanges + " changes)");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("disk '" + sDisketteName + "' added to history (nothing to restore)");
|
||||
this.messagePrint("disk '" + sDisketteName + "' added to history (nothing to restore)");
|
||||
}
|
||||
this.aDiskHistory[i] = [sDisketteName, sDiskettePath, []];
|
||||
};
|
||||
|
|
@ -1556,13 +1556,13 @@ FDC.prototype.removeDiskHistory = function(sDisketteName, sDiskettePath)
|
|||
if (this.aDiskHistory[i][1] == sDiskettePath) {
|
||||
this.aDiskHistory.splice(i, 1);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("disk '" + sDisketteName + "' removed from history");
|
||||
this.messagePrint("disk '" + sDisketteName + "' removed from history");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("unable to remove disk '" + sDisketteName + "' from history (" + sDiskettePath + ")");
|
||||
this.messagePrint("unable to remove disk '" + sDisketteName + "' from history (" + sDiskettePath + ")");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1581,7 +1581,7 @@ FDC.prototype.updateDiskHistory = function(sDisketteName, sDiskettePath, disk)
|
|||
if (this.aDiskHistory[i][1] == sDiskettePath) {
|
||||
this.aDiskHistory[i][2] = disk.save();
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("disk '" + sDisketteName + "' updated in history");
|
||||
this.messagePrint("disk '" + sDisketteName + "' updated in history");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -1593,7 +1593,7 @@ FDC.prototype.updateDiskHistory = function(sDisketteName, sDiskettePath, disk)
|
|||
* before unloading, the fact that the disk is no longer listed here can't be treated as an error.
|
||||
*/
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("unable to update disk '" + sDisketteName + "' in history (" + sDiskettePath + ")");
|
||||
this.messagePrint("unable to update disk '" + sDisketteName + "' in history (" + sDiskettePath + ")");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1719,7 +1719,7 @@ FDC.prototype.outFDCData = function(port, bOut, addrFrom)
|
|||
return;
|
||||
}
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("unsupported FDC command: " + str.toHexByte(bCmd));
|
||||
this.messagePrint("unsupported FDC command: " + str.toHexByte(bCmd));
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
};
|
||||
|
|
@ -1948,7 +1948,7 @@ FDC.prototype.doCmd = function()
|
|||
|
||||
default:
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("FDC operation unsupported (command=0x: " + str.toHexByte(bCmd) + ")");
|
||||
this.messagePrint("FDC operation unsupported (command=0x: " + str.toHexByte(bCmd) + ")");
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
break;
|
||||
|
|
@ -2029,7 +2029,7 @@ FDC.prototype.popCmd = function(name)
|
|||
if (DEBUG && this.messageEnabled(Messages.PORT | Messages.FDC)) {
|
||||
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), true);
|
||||
this.messagePrint("FDC.CMD[" + (name || this.regDataIndex) + "]: 0x" + str.toHexByte(bCmd), true);
|
||||
}
|
||||
this.regDataIndex++;
|
||||
return bCmd;
|
||||
|
|
@ -2081,7 +2081,7 @@ FDC.prototype.beginResult = function()
|
|||
FDC.prototype.pushResult = function(bResult, name)
|
||||
{
|
||||
if (DEBUG && this.messageEnabled(Messages.PORT | Messages.FDC)) {
|
||||
this.messageDebugger("FDC.RES[" + (name || this.regDataTotal) + "]: 0x" + str.toHexByte(bResult), true);
|
||||
this.messagePrint("FDC.RES[" + (name || this.regDataTotal) + "]: 0x" + str.toHexByte(bResult), true);
|
||||
}
|
||||
this.regDataArray[this.regDataTotal++] = bResult;
|
||||
};
|
||||
|
|
@ -2147,7 +2147,7 @@ FDC.prototype.dmaRead = function(drive, b, done)
|
|||
/*
|
||||
* The DMA controller should be ASKING for data, not GIVING us data; this suggests an internal DMA miscommunication
|
||||
*/
|
||||
if (DEBUG) this.messageDebugger("dmaRead(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.messagePrint("dmaRead(): invalid DMA acknowledgement");
|
||||
done(-1, false);
|
||||
};
|
||||
|
||||
|
|
@ -2166,7 +2166,7 @@ FDC.prototype.dmaWrite = function(drive, b)
|
|||
/*
|
||||
* The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication
|
||||
*/
|
||||
if (DEBUG) this.messageDebugger("dmaWrite(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.messagePrint("dmaWrite(): invalid DMA acknowledgement");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
|
@ -2185,7 +2185,7 @@ FDC.prototype.dmaFormat = function(drive, b)
|
|||
/*
|
||||
* The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication
|
||||
*/
|
||||
if (DEBUG) this.messageDebugger("dmaFormat(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.messagePrint("dmaFormat(): invalid DMA acknowledgement");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
|
@ -2205,7 +2205,7 @@ FDC.prototype.doRead = function(drive)
|
|||
drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("FDC.doRead(" + drive.bCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
this.messagePrint("FDC.doRead(" + drive.bCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
}
|
||||
|
||||
if (drive.disk) {
|
||||
|
|
@ -2229,7 +2229,7 @@ FDC.prototype.doWrite = function(drive)
|
|||
drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("FDC.doWrite(" + drive.bCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
this.messagePrint("FDC.doWrite(" + drive.bCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
}
|
||||
|
||||
if (drive.disk) {
|
||||
|
|
@ -2429,7 +2429,7 @@ FDC.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.messageEnabled()) {
|
||||
this.messageDebugger("writeFormat(head=" + str.toHexByte(drive.bHead) + ",cyl=" + str.toHexByte(drive.bCylinder) + ",sec=" + str.toHexByte(drive.bSector) + ",len=" + str.toHexWord(drive.nBytes) + ")");
|
||||
this.messagePrint("writeFormat(head=" + str.toHexByte(drive.bHead) + ",cyl=" + str.toHexByte(drive.bCylinder) + ",sec=" + str.toHexByte(drive.bSector) + ",len=" + str.toHexWord(drive.nBytes) + ")");
|
||||
}
|
||||
for (var i = 0; i < drive.nBytes; i++) {
|
||||
if (this.writeByte(drive, drive.bFiller) < 0) {
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ HDC.aDriveTypes = [
|
|||
0x00: [306, 2],
|
||||
0x01: [375, 8],
|
||||
0x02: [306, 6],
|
||||
0x03: [306, 4] // <= default 'xt' drive type (10Mb)
|
||||
0x03: [306, 4] // 10Mb (default XTC drive type)
|
||||
},
|
||||
/*
|
||||
* Sadly, drive types differ across controller models (XTC drive types don't match ATC drive types),
|
||||
|
|
@ -167,8 +167,8 @@ HDC.aDriveTypes = [
|
|||
* 15 (reserved--all zeros)
|
||||
*/
|
||||
{
|
||||
0x01: [306, 4],
|
||||
0x02: [615, 4], // <= default 'at' drive type (20Mb)
|
||||
0x01: [306, 4], // 10Mb
|
||||
0x02: [615, 4], // 20Mb (default ATC drive type)
|
||||
0x03: [615, 6],
|
||||
0x04: [940, 8],
|
||||
0x05: [940, 6],
|
||||
|
|
@ -748,7 +748,7 @@ HDC.prototype.initController = function(data, fHard)
|
|||
}
|
||||
}
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC initialized for " + this.aDrives.length + " drive(s)");
|
||||
this.messagePrint("HDC initialized for " + this.aDrives.length + " drive(s)");
|
||||
}
|
||||
return fSuccess;
|
||||
};
|
||||
|
|
@ -1149,7 +1149,7 @@ HDC.prototype.loadDisk = function(iDrive, sDiskName, sDiskPath, fAutoMount)
|
|||
if (fAutoMount) {
|
||||
drive.fAutoMount = true;
|
||||
this.cAutoMount++;
|
||||
if (this.messageEnabled()) this.messageDebugger("loading " + sDiskName);
|
||||
if (this.messageEnabled()) this.messagePrint("loading " + sDiskName);
|
||||
}
|
||||
var disk = drive.disk || new Disk(this, drive, drive.mode);
|
||||
disk.load(sDiskName, sDiskPath, null, this.doneLoadDisk);
|
||||
|
|
@ -1437,7 +1437,7 @@ HDC.prototype.inATCData = function(port, addrFrom)
|
|||
*/
|
||||
hdc.regStatus = HDC.ATC.STATUS.ERROR;
|
||||
hdc.regError = HDC.ATC.ERROR.NO_CHS;
|
||||
if (DEBUG) hdc.messageDebugger("HDC.inATCData(): read failed");
|
||||
if (DEBUG) hdc.messagePrint("HDC.inATCData(): read failed");
|
||||
}
|
||||
}, false);
|
||||
} else {
|
||||
|
|
@ -1469,7 +1469,7 @@ HDC.prototype.outATCData = function(port, bOut, addrFrom)
|
|||
this.regStatus = HDC.ATC.STATUS.ERROR;
|
||||
this.regError = HDC.ATC.ERROR.NO_CHS;
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.outATCData(" + str.toHexByte(bOut) + "): write failed");
|
||||
this.messagePrint("HDC.outATCData(" + str.toHexByte(bOut) + "): write failed");
|
||||
}
|
||||
}
|
||||
else if (this.drive.ibSector == 1) {
|
||||
|
|
@ -1503,7 +1503,7 @@ 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.messageEnabled()) {
|
||||
this.messageDebugger("HDC.outATCData(" + str.toHexByte(bOut) + "): write exceeds count (" + this.drive.nBytes + ")");
|
||||
this.messagePrint("HDC.outATCData(" + str.toHexByte(bOut) + "): write exceeds count (" + this.drive.nBytes + ")");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1511,7 +1511,7 @@ HDC.prototype.outATCData = function(port, bOut, addrFrom)
|
|||
* TODO: What to do about unexpected writes? No command was specified.
|
||||
*/
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.outATCData(" + str.toHexByte(bOut) + "): write without command");
|
||||
this.messagePrint("HDC.outATCData(" + str.toHexByte(bOut) + "): write without command");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1832,14 +1832,14 @@ HDC.prototype.doATC = function()
|
|||
}
|
||||
|
||||
if (DEBUG && this.messageEnabled(Messages.HDC)) {
|
||||
this.messageDebugger("HDC.doATC(0x" + str.toHexByte(bCmd) + "): " + HDC.aATCCommands[bCmd], true);
|
||||
this.messagePrint("HDC.doATC(0x" + str.toHexByte(bCmd) + "): " + HDC.aATCCommands[bCmd], true);
|
||||
}
|
||||
|
||||
switch (bCmd & HDC.ATC.COMMAND.MASK) {
|
||||
|
||||
case HDC.ATC.COMMAND.READ_DATA:
|
||||
if (DEBUG && this.messageEnabled(Messages.HDC)) {
|
||||
this.messageDebugger("HDC.doRead(" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + ")", true);
|
||||
this.messagePrint("HDC.doRead(" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + ")", true);
|
||||
}
|
||||
/*
|
||||
* We're using a call to readByte() that disables auto-increment, so that once we've got the first
|
||||
|
|
@ -1868,7 +1868,7 @@ HDC.prototype.doATC = function()
|
|||
|
||||
case HDC.ATC.COMMAND.WRITE_DATA:
|
||||
if (DEBUG && this.messageEnabled(Messages.HDC)) {
|
||||
this.messageDebugger("HDC.doWrite(" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + ")", true);
|
||||
this.messagePrint("HDC.doWrite(" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + ")", true);
|
||||
}
|
||||
this.regStatus = HDC.ATC.STATUS.DATA_REQ;
|
||||
break;
|
||||
|
|
@ -1917,7 +1917,7 @@ HDC.prototype.doATC = function()
|
|||
|
||||
default:
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.doATC(0x" + str.toHexByte(this.regCommand) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
this.messagePrint("HDC.doATC(0x" + str.toHexByte(this.regCommand) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
if (bCmd >= 0) this.dbg.stopCPU();
|
||||
}
|
||||
break;
|
||||
|
|
@ -1961,9 +1961,9 @@ HDC.prototype.setATCIRR = function(fWrite)
|
|||
* has a low tolerance for fast controller interrupts during multi-sector operations.
|
||||
*/
|
||||
this.chipset.setIRR(ChipSet.IRQ.ATC, 120);
|
||||
if (DEBUG) this.messageDebugger("HDC.setATCIRR(): enabled", Messages.PIC | Messages.HDC);
|
||||
if (DEBUG) this.messagePrint("HDC.setATCIRR(): enabled", Messages.PIC | Messages.HDC);
|
||||
} else {
|
||||
if (DEBUG) this.messageDebugger("HDC.setATCIRR(): disabled", Messages.PIC | Messages.HDC);
|
||||
if (DEBUG) this.messagePrint("HDC.setATCIRR(): disabled", Messages.PIC | Messages.HDC);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -2045,7 +2045,7 @@ HDC.prototype.doXTC = function()
|
|||
bDataStatus = HDC.XTC.DATA.STATUS_OK;
|
||||
if (!drive && this.iDriveAllowFail == iDrive) {
|
||||
this.iDriveAllowFail = -1;
|
||||
if (DEBUG) this.messageDebugger("HDC.doXTC(): fake failure triggered");
|
||||
if (DEBUG) this.messagePrint("HDC.doXTC(): fake failure triggered");
|
||||
bDataStatus = HDC.XTC.DATA.STATUS_ERROR;
|
||||
}
|
||||
this.beginResult(bDataStatus | bDrive);
|
||||
|
|
@ -2082,7 +2082,7 @@ HDC.prototype.doXTC = function()
|
|||
case HDC.XTC.DATA.CMD.RECALIBRATE: // 0x01
|
||||
drive.bControl = bControl;
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.doXTC(): drive " + iDrive + " control byte: 0x" + str.toHexByte(bControl));
|
||||
this.messagePrint("HDC.doXTC(): drive " + iDrive + " control byte: 0x" + str.toHexByte(bControl));
|
||||
}
|
||||
this.beginResult(HDC.XTC.DATA.STATUS_OK | bDrive);
|
||||
break;
|
||||
|
|
@ -2120,7 +2120,7 @@ HDC.prototype.doXTC = function()
|
|||
default:
|
||||
this.beginResult(HDC.XTC.DATA.STATUS_ERROR | bDrive);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.doXTC(0x" + str.toHexByte(bCmdOrig) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
this.messagePrint("HDC.doXTC(0x" + str.toHexByte(bCmdOrig) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
if (bCmd >= 0) this.dbg.stopCPU();
|
||||
}
|
||||
break;
|
||||
|
|
@ -2141,7 +2141,7 @@ HDC.prototype.popCmd = function()
|
|||
if (bCmdIndex < this.regDataTotal) {
|
||||
bCmd = this.regDataArray[this.regDataIndex++];
|
||||
if (DEBUG && this.messageEnabled((bCmdIndex > 0? Messages.PORT : 0) | Messages.HDC)) {
|
||||
this.messageDebugger("HDC.CMD[" + bCmdIndex + "]: 0x" + str.toHexByte(bCmd) + (!bCmdIndex && HDC.aXTCCommands[bCmd]? (" (" + HDC.aXTCCommands[bCmd] + ")") : ""), true);
|
||||
this.messagePrint("HDC.CMD[" + bCmdIndex + "]: 0x" + str.toHexByte(bCmd) + (!bCmdIndex && HDC.aXTCCommands[bCmd]? (" (" + HDC.aXTCCommands[bCmd] + ")") : ""), true);
|
||||
}
|
||||
}
|
||||
return bCmd;
|
||||
|
|
@ -2159,7 +2159,7 @@ HDC.prototype.beginResult = function(bResult)
|
|||
|
||||
if (bResult !== undefined) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.beginResult(0x" + str.toHexByte(bResult) + ")");
|
||||
this.messagePrint("HDC.beginResult(0x" + str.toHexByte(bResult) + ")");
|
||||
}
|
||||
this.pushResult(bResult);
|
||||
}
|
||||
|
|
@ -2181,7 +2181,7 @@ HDC.prototype.beginResult = function(bResult)
|
|||
HDC.prototype.pushResult = function(bResult)
|
||||
{
|
||||
if (DEBUG && this.messageEnabled((this.regDataTotal > 0? Messages.PORT : 0) | Messages.HDC)) {
|
||||
this.messageDebugger("HDC.RES[" + this.regDataTotal + "]: 0x" + str.toHexByte(bResult), true);
|
||||
this.messagePrint("HDC.RES[" + this.regDataTotal + "]: 0x" + str.toHexByte(bResult), true);
|
||||
}
|
||||
this.regDataArray[this.regDataTotal++] = bResult;
|
||||
};
|
||||
|
|
@ -2203,7 +2203,7 @@ HDC.prototype.dmaRead = function(drive, b, done)
|
|||
/*
|
||||
* The DMA controller should be ASKING for data, not GIVING us data; this suggests an internal DMA miscommunication
|
||||
*/
|
||||
if (DEBUG) this.messageDebugger("dmaRead(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.messagePrint("dmaRead(): invalid DMA acknowledgement");
|
||||
done(-1, false);
|
||||
};
|
||||
|
||||
|
|
@ -2222,7 +2222,7 @@ HDC.prototype.dmaWrite = function(drive, b)
|
|||
/*
|
||||
* The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication
|
||||
*/
|
||||
if (DEBUG) this.messageDebugger("dmaWrite(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.messagePrint("dmaWrite(): invalid DMA acknowledgement");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
|
@ -2241,7 +2241,7 @@ HDC.prototype.dmaWriteBuffer = function(drive, b)
|
|||
/*
|
||||
* The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication
|
||||
*/
|
||||
if (DEBUG) this.messageDebugger("dmaWriteBuffer(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.messagePrint("dmaWriteBuffer(): invalid DMA acknowledgement");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
|
@ -2260,7 +2260,7 @@ HDC.prototype.dmaWriteFormat = function(drive, b)
|
|||
/*
|
||||
* The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication
|
||||
*/
|
||||
if (DEBUG) this.messageDebugger("dmaWriteFormat(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.messagePrint("dmaWriteFormat(): invalid DMA acknowledgement");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
|
@ -2276,7 +2276,7 @@ HDC.prototype.doDMARead = function(drive, done)
|
|||
drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.doDMARead(" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + ")");
|
||||
this.messagePrint("HDC.doDMARead(" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + ")");
|
||||
}
|
||||
|
||||
if (drive.disk) {
|
||||
|
|
@ -2320,7 +2320,7 @@ HDC.prototype.doDMAWrite = function(drive, done)
|
|||
drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.doDMAWrite(" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + ")");
|
||||
this.messagePrint("HDC.doDMAWrite(" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + ")");
|
||||
}
|
||||
|
||||
if (drive.disk) {
|
||||
|
|
@ -2370,7 +2370,7 @@ HDC.prototype.doDMAWriteBuffer = function(drive, done)
|
|||
{
|
||||
drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;
|
||||
|
||||
if (DEBUG) this.messageDebugger("HDC.doDMAWriteBuffer()");
|
||||
if (DEBUG) this.messagePrint("HDC.doDMAWriteBuffer()");
|
||||
|
||||
if (!drive.abSector || drive.abSector.length != drive.nBytes) {
|
||||
drive.abSector = new Array(drive.nBytes);
|
||||
|
|
@ -2669,7 +2669,7 @@ HDC.prototype.writeFormat = function(drive, b)
|
|||
drive.cbFormat = 0;
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("HDC.writeFormat(" + drive.wCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
this.messagePrint("HDC.writeFormat(" + drive.wCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
}
|
||||
|
||||
for (var i = 0; i < drive.nBytes; i++) {
|
||||
|
|
@ -2754,7 +2754,7 @@ HDC.prototype.intBIOSDiskette = function(addr)
|
|||
{
|
||||
var AH = this.cpu.regAX >> 8;
|
||||
if ((!AH && this.chipset && this.chipset.checkIMR(ChipSet.IRQ.FDC))) {
|
||||
if (DEBUG) this.messageDebugger("HDC.intBIOSDiskette(): skipping useless INT 0x40 diskette reset");
|
||||
if (DEBUG) this.messagePrint("HDC.intBIOSDiskette(): skipping useless INT 0x40 diskette reset");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ function Keyboard(parmsKbd)
|
|||
|
||||
this.fMobile = web.isMobile();
|
||||
this.fMSIE = web.isUserAgent("MSIE");
|
||||
this.messageDebugger("mobile keyboard support: " + (this.fMobile? "true" : "false"));
|
||||
this.messagePrint("mobile keyboard support: " + (this.fMobile? "true" : "false"));
|
||||
|
||||
/*
|
||||
* This is count of the number of "soft keyboard" keys present. At the moment, its only
|
||||
|
|
@ -115,9 +115,17 @@ function Keyboard(parmsKbd)
|
|||
* nRepeat: > 0 if timer should generate more "make" scan code(s), -1 for "break" scan code(s)
|
||||
* timer: timer for next key operation, if any
|
||||
*
|
||||
* Keys are inserted into aKeysActive using splice(0, 0, key), but not before zeroing nRepeat
|
||||
* of any repeating key that already occupies index 0, so that at most only one key (ie, the most
|
||||
* recent) can ever be in a repeating state.
|
||||
* Keys are inserted at the head of aKeysActive, using splice(0, 0, key), but not before zeroing
|
||||
* nRepeat of any repeating key that already occupies the head (index 0), so that at most only one
|
||||
* key (ie, the most recent) will ever be in a repeating state.
|
||||
*
|
||||
* IBM PC keyboard repeat behavior: when pressing CTRL, then C, and then releasing CTRL while still
|
||||
* holding C, the repeated CTRL_C characters turn into 'c' characters. We emulate that behavior.
|
||||
* However, when pressing C, then CTRL, all repeating stops: not a single CTRL_C is generated, and
|
||||
* even if the CTRL is released before the C, no more more 'c' characters are generated either.
|
||||
* We do NOT fully emulate that behavior -- we DO stop the repeating, but we also generate one CTRL_C.
|
||||
* More investigation is required, because I need to confirm whether the IBM keyboard automatically
|
||||
* "breaks" all non-shift keys before it "makes" the CTRL.
|
||||
*/
|
||||
this.aKeysActive = [];
|
||||
|
||||
|
|
@ -252,7 +260,7 @@ Keyboard.KEYCODE = {
|
|||
// Technically, that makes it DCO (Decimal Coded Octal), but then again, BCD should have really
|
||||
// been called HCD (Hexadecimal Coded Decimal), so if "they" can take liberties, so can I.
|
||||
//
|
||||
// ONDOWN is a bias we add to browser keyCodes that we want to handle on "down" rather than "press".
|
||||
// ONDOWN is a bias we add to browser keyCodes that we want to handle on "down" rather than on "press".
|
||||
//
|
||||
ONDOWN: 1000,
|
||||
//
|
||||
|
|
@ -475,11 +483,16 @@ Keyboard.LOCATION = {
|
|||
* and the simulated shift-key states (in bitsStateSim). The LOCK keys are problematic in both cases: the
|
||||
* browsers give us no way to query the LOCK key states, so we can only infer them, and because they are "soft"
|
||||
* locks, the machine's notion of their state is subject to change at any time as well. Granted, the IBM PC
|
||||
* ROM BIOS will store its LOCK states in the ROM BIOS Data Area (@0040:0017), but that's purely a convention.
|
||||
* ROM BIOS will store its LOCK states in the ROM BIOS Data Area (@0040:0017), but that's just a BIOS convention.
|
||||
*
|
||||
* TODO: Consider taking notice of the ROM BIOS Data Area state anyway, although I'm not keen on the idea.
|
||||
* Also, because this is purely for internal use, don't make the mistake of thinking that these bits have any
|
||||
* connection to the ROM BIOS bits @0040:0017 (they don't). We emulate hardware, not ROMs.
|
||||
*
|
||||
* Note that right-hand state bits match the left-hand state bits shifted right 1 bit; makes sense, "right"? ;-)
|
||||
* TODO: Consider taking notice of the ROM BIOS Data Area state anyway, even though I'd rather remain ROM-agnostic;
|
||||
* at the very least, it would help us keep our LOCK LEDs in sync with the machine's LOCK states. However, the LED
|
||||
* issue will be largely moot (at least for MODEL_5170 machines) once we add support for PC AT keyboard LED commands.
|
||||
*
|
||||
* Note that right-hand state bits are equal to the left-hand bits shifted right 1 bit; makes sense, "right"? ;-)
|
||||
*
|
||||
* @enum {number}
|
||||
*/
|
||||
|
|
@ -496,7 +509,7 @@ Keyboard.STATE = {
|
|||
CMD: 0x0080, // 101-key keyboard only
|
||||
CMDS: 0x00c0,
|
||||
SHIFTS: 0x00ff, // SHIFT | RSHIFT | CTRL | RCTRL | ALT | RALT | CMD | RCMD
|
||||
INSERT: 0x0100, // TODO: Placeholder
|
||||
INSERT: 0x0100, // TODO: Placeholder (we currently have no notion of any "insert" states)
|
||||
CAPS_LOCK: 0x0200,
|
||||
NUM_LOCK: 0x0400,
|
||||
SCROLL_LOCK: 0x0800,
|
||||
|
|
@ -1006,7 +1019,7 @@ Keyboard.prototype.setBinding = function(sHTMLType, sBinding, control)
|
|||
this.bindings[id] = control;
|
||||
control.onclick = function(kbd, sKey, simCode) {
|
||||
return function onClickKeyboard(event) {
|
||||
if (!COMPILED && kbd.messageEnabled()) kbd.messageDebugger(sKey + " clicked", Messages.KEYS);
|
||||
if (!COMPILED && kbd.messageEnabled()) kbd.messagePrint(sKey + " clicked", Messages.KEYS);
|
||||
if (kbd.cpu) kbd.cpu.setFocus();
|
||||
kbd.updateShiftState(simCode, true); // future-proofing if/when any LOCK keys are added to CLICKCODES
|
||||
kbd.addActiveKey(simCode, true);
|
||||
|
|
@ -1138,7 +1151,7 @@ Keyboard.prototype.resetDevice = function(fNotify)
|
|||
/*
|
||||
* TODO: There's more to reset, like LED indicators, default type rate, and emptying the scan code buffer.
|
||||
*/
|
||||
this.messageDebugger("keyboard reset", Messages.KEYBOARD | Messages.PORT);
|
||||
this.messagePrint("keyboard reset", Messages.KEYBOARD | Messages.PORT);
|
||||
this.abScanBuffer = [Keyboard.CMDRES.BAT_OK];
|
||||
if (fNotify && this.chipset) this.chipset.notifyKbdData(this.abScanBuffer[0]);
|
||||
};
|
||||
|
|
@ -1161,7 +1174,7 @@ Keyboard.prototype.setEnable = function(fData, fClock)
|
|||
var fReset = false;
|
||||
if (this.fClock !== fClock) {
|
||||
if (!COMPILED && this.messageEnabled(Messages.KEYBOARD | Messages.PORT)) {
|
||||
this.messageDebugger("keyboard clock line changing to " + fClock, true);
|
||||
this.messagePrint("keyboard clock line changing to " + fClock, true);
|
||||
}
|
||||
/*
|
||||
* Toggling the clock line low and then high signals a "reset", which we acknowledge once the
|
||||
|
|
@ -1171,7 +1184,7 @@ Keyboard.prototype.setEnable = function(fData, fClock)
|
|||
}
|
||||
if (this.fData !== fData) {
|
||||
if (!COMPILED && this.messageEnabled(Messages.KEYBOARD | Messages.PORT)) {
|
||||
this.messageDebugger("keyboard data line changing to " + fData, true);
|
||||
this.messagePrint("keyboard data line changing to " + fData, true);
|
||||
}
|
||||
this.fData = fData;
|
||||
/*
|
||||
|
|
@ -1229,7 +1242,7 @@ Keyboard.prototype.checkScanCode = function()
|
|||
b = this.abScanBuffer[0];
|
||||
if (this.chipset) this.chipset.notifyKbdData(b);
|
||||
}
|
||||
if (this.messageEnabled()) this.messageDebugger("scan code 0x" + str.toHexByte(b) + " available");
|
||||
if (this.messageEnabled()) this.messagePrint("scan code 0x" + str.toHexByte(b) + " available");
|
||||
return b;
|
||||
};
|
||||
|
||||
|
|
@ -1247,7 +1260,7 @@ Keyboard.prototype.readScanCode = function()
|
|||
if (this.abScanBuffer.length) {
|
||||
b = this.abScanBuffer[0];
|
||||
}
|
||||
if (this.messageEnabled()) this.messageDebugger("scan code 0x" + str.toHexByte(b) + " delivered");
|
||||
if (this.messageEnabled()) this.messagePrint("scan code 0x" + str.toHexByte(b) + " delivered");
|
||||
return b;
|
||||
};
|
||||
|
||||
|
|
@ -1261,7 +1274,7 @@ Keyboard.prototype.readScanCode = function()
|
|||
Keyboard.prototype.flushScanCode = function()
|
||||
{
|
||||
this.abScanBuffer = [];
|
||||
if (this.messageEnabled()) this.messageDebugger("scan codes flushed");
|
||||
if (this.messageEnabled()) this.messagePrint("scan codes flushed");
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1288,7 +1301,7 @@ Keyboard.prototype.shiftScanCode = function(fNotify)
|
|||
this.chipset.notifyKbdData(this.abScanBuffer[0]);
|
||||
}
|
||||
}
|
||||
if (this.messageEnabled()) this.messageDebugger("scan codes shifted, notify " + (fNotify? "true" : "false"));
|
||||
if (this.messageEnabled()) this.messagePrint("scan codes shifted, notify " + (fNotify? "true" : "false"));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1455,7 +1468,7 @@ Keyboard.prototype.addScanCode = function(bScan)
|
|||
*/
|
||||
if (this.abScanBuffer) {
|
||||
if (this.abScanBuffer.length < Keyboard.LIMIT.MAX_SCANCODES) {
|
||||
if (this.messageEnabled()) this.messageDebugger("scan code 0x" + str.toHexByte(bScan) + " buffered");
|
||||
if (this.messageEnabled()) this.messagePrint("scan code 0x" + str.toHexByte(bScan) + " buffered");
|
||||
this.abScanBuffer.push(bScan);
|
||||
if (this.abScanBuffer.length == 1) {
|
||||
if (this.chipset) this.chipset.notifyKbdData(bScan);
|
||||
|
|
@ -1465,7 +1478,7 @@ Keyboard.prototype.addScanCode = function(bScan)
|
|||
if (this.abScanBuffer.length == Keyboard.LIMIT.MAX_SCANCODES) {
|
||||
this.abScanBuffer.push(Keyboard.CMDRES.BUFF_FULL);
|
||||
}
|
||||
this.messageDebugger("scan code buffer overflow");
|
||||
this.messagePrint("scan code buffer overflow");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1624,7 +1637,7 @@ Keyboard.prototype.addActiveKey = function(simCode, fPress)
|
|||
{
|
||||
if (!Keyboard.SIMCODES[simCode]) {
|
||||
if (!COMPILED && this.messageEnabled(Messages.KEYS)) {
|
||||
this.messageDebugger("addActiveKey(" + simCode + "," + (fPress? "press" : "down") + "): unrecognized", true);
|
||||
this.messagePrint("addActiveKey(" + simCode + "," + (fPress? "press" : "down") + "): unrecognized", true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -1634,6 +1647,13 @@ Keyboard.prototype.addActiveKey = function(simCode, fPress)
|
|||
*/
|
||||
if (!this.cpu || !this.cpu.isRunning()) return;
|
||||
|
||||
/*
|
||||
* If this simCode is in the KEYSTATE table, then stop all repeating.
|
||||
*/
|
||||
if (Keyboard.KEYSTATES[simCode] && this.aKeysActive.length) {
|
||||
if (this.aKeysActive[0].nRepeat > 0) this.aKeysActive[0].nRepeat = 0;
|
||||
}
|
||||
|
||||
var key;
|
||||
for (var i = 0; i < this.aKeysActive.length; i++) {
|
||||
key = this.aKeysActive[i];
|
||||
|
|
@ -1655,7 +1675,7 @@ Keyboard.prototype.addActiveKey = function(simCode, fPress)
|
|||
}
|
||||
|
||||
if (!COMPILED && this.messageEnabled(Messages.KEYS)) {
|
||||
this.messageDebugger("addActiveKey(" + simCode + "," + (fPress? "press" : "down") + "): " + (i < 0? "already active" : (i == this.aKeysActive.length? "adding" : "updating")), true);
|
||||
this.messagePrint("addActiveKey(" + simCode + "," + (fPress? "press" : "down") + "): " + (i < 0? "already active" : (i == this.aKeysActive.length? "adding" : "updating")), true);
|
||||
}
|
||||
|
||||
if (i < 0) return;
|
||||
|
|
@ -1756,7 +1776,7 @@ Keyboard.prototype.removeActiveKey = function(simCode, fFlush)
|
|||
{
|
||||
if (!Keyboard.SIMCODES[simCode]) {
|
||||
if (!COMPILED && this.messageEnabled(Messages.KEYS)) {
|
||||
this.messageDebugger("removeActiveKey(" + simCode + "): unrecognized", true);
|
||||
this.messagePrint("removeActiveKey(" + simCode + "): unrecognized", true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1770,7 +1790,6 @@ Keyboard.prototype.removeActiveKey = function(simCode, fFlush)
|
|||
for (var i = 0; i < this.aKeysActive.length; i++) {
|
||||
var key = this.aKeysActive[i];
|
||||
if (key.simCode == simCode || key.simCode == Keyboard.SHIFTED_KEYCODES[simCode]) {
|
||||
if (this.aKeysActive[0].nRepeat > 0) this.aKeysActive[0].nRepeat = 0;
|
||||
this.aKeysActive.splice(i, 1);
|
||||
if (key.timer) clearTimeout(key.timer);
|
||||
if (key.fDown && !fFlush) this.keySimulate(key.simCode, false);
|
||||
|
|
@ -1780,10 +1799,10 @@ Keyboard.prototype.removeActiveKey = function(simCode, fFlush)
|
|||
}
|
||||
}
|
||||
if (!COMPILED && !fFlush && this.messageEnabled(Messages.KEYS)) {
|
||||
this.messageDebugger("removeActiveKey(" + simCode + "): " + (fRemoved? "removed" : "not active"), true);
|
||||
this.messagePrint("removeActiveKey(" + simCode + "): " + (fRemoved? "removed" : "not active"), true);
|
||||
}
|
||||
if (!this.aKeysActive.length && this.fToggleCapsLock) {
|
||||
if (!COMPILED) this.messageDebugger("removeActiveKey(): inverting caps-lock now", Messages.KEYS);
|
||||
if (!COMPILED) this.messagePrint("removeActiveKey(): inverting caps-lock now", Messages.KEYS);
|
||||
this.updateShiftState(Keyboard.SIMCODE.CAPS_LOCK);
|
||||
this.fToggleCapsLock = false;
|
||||
}
|
||||
|
|
@ -1807,7 +1826,7 @@ Keyboard.prototype.updateActiveKey = function(key, msTimer)
|
|||
}
|
||||
|
||||
if (!COMPILED && this.messageEnabled(Messages.KEYS)) {
|
||||
this.messageDebugger((msTimer? '\n' : "") + "updateActiveKey(" + key.simCode + (msTimer? "," + msTimer + "ms" : "") + "): " + (key.fDown? "down" : "up"), true);
|
||||
this.messagePrint((msTimer? '\n' : "") + "updateActiveKey(" + key.simCode + (msTimer? "," + msTimer + "ms" : "") + "): " + (key.fDown? "down" : "up"), true);
|
||||
}
|
||||
|
||||
this.keySimulate(key.simCode, key.fDown);
|
||||
|
|
@ -1878,7 +1897,7 @@ Keyboard.prototype.getSimCode = function(keyCode, fShifted)
|
|||
Keyboard.prototype.onFocusChange = function(fFocus)
|
||||
{
|
||||
if (this.fHasFocus != fFocus && !COMPILED && this.messageEnabled(Messages.KEYS)) {
|
||||
this.messageDebugger("onFocusChange(" + (fFocus? "true" : "false") + ")", true);
|
||||
this.messagePrint("onFocusChange(" + (fFocus? "true" : "false") + ")", true);
|
||||
}
|
||||
this.fHasFocus = fFocus;
|
||||
/*
|
||||
|
|
@ -2005,7 +2024,7 @@ Keyboard.prototype.onKeyDown = function(event, fDown)
|
|||
}
|
||||
|
||||
if (!COMPILED && this.messageEnabled(Messages.KEYS)) {
|
||||
this.messageDebugger("\nonKey" + (fDown? "Down" : "Up") + "(" + keyCode + "): " + (fIgnore? "ignore" : (fPass? "true" : "false")), true);
|
||||
this.messagePrint("\nonKey" + (fDown? "Down" : "Up") + "(" + keyCode + "): " + (fIgnore? "ignore" : (fPass? "true" : "false")), true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2045,7 +2064,7 @@ Keyboard.prototype.onKeyPress = function(event)
|
|||
var simCode = this.checkActiveKey();
|
||||
if (simCode && this.isAlphaKey(simCode) && this.isAlphaKey(keyCode) && simCode != keyCode) {
|
||||
if (!COMPILED && this.messageEnabled(Messages.KEYS)) {
|
||||
this.messageDebugger("onKeyPress(" + keyCode + ") out of sync with " + simCode + ", invert caps-lock", true);
|
||||
this.messagePrint("onKeyPress(" + keyCode + ") out of sync with " + simCode + ", invert caps-lock", true);
|
||||
}
|
||||
this.fToggleCapsLock = true;
|
||||
keyCode = simCode;
|
||||
|
|
@ -2059,7 +2078,7 @@ Keyboard.prototype.onKeyPress = function(event)
|
|||
var fPass = !Keyboard.SIMCODES[keyCode] || !!(this.bitsState & Keyboard.STATE.CMD);
|
||||
|
||||
if (!COMPILED && this.messageEnabled(Messages.KEYS)) {
|
||||
this.messageDebugger("\nonKeyPress(" + keyCode + "): " + (fPass? "true" : "false"), true);
|
||||
this.messagePrint("\nonKeyPress(" + keyCode + "): " + (fPass? "true" : "false"), true);
|
||||
}
|
||||
|
||||
if (!fPass) {
|
||||
|
|
@ -2149,7 +2168,7 @@ Keyboard.prototype.keySimulate = function(simCode, fDown)
|
|||
}
|
||||
|
||||
if (!COMPILED && this.messageEnabled(Messages.KEYS)) {
|
||||
this.messageDebugger("keySimulate(" + simCode + "," + (fDown? "down" : "up") + "): " + (fSimulated? "true" : "false"), true);
|
||||
this.messagePrint("keySimulate(" + simCode + "," + (fDown? "down" : "up") + "): " + (fSimulated? "true" : "false"), true);
|
||||
}
|
||||
|
||||
return fSimulated;
|
||||
|
|
|
|||
|
|
@ -544,7 +544,7 @@ Mouse.prototype.sendPacket = function(sDiag, xDiag, yDiag)
|
|||
var b2 = this.xDelta & 0x3F;
|
||||
var b3 = this.yDelta & 0x3F;
|
||||
if (this.messageEnabled(Messages.SERIAL)) {
|
||||
this.messageDebugger((sDiag? (sDiag + ": ") : "") + (yDiag !== undefined? ("mouse (" + xDiag + "," + yDiag + "): ") : "") + "serial packet [" + str.toHexByte(b1) + "," + str.toHexByte(b2) + "," + str.toHexByte(b3) + "]", 0, true);
|
||||
this.messagePrint((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;
|
||||
|
|
@ -576,11 +576,11 @@ Mouse.prototype.notifyMCR = function(bMCR)
|
|||
var fIdentify = false;
|
||||
if (!(this.bMCR & SerialPort.MCR.RTS)) {
|
||||
this.reset();
|
||||
this.messageDebugger("serial mouse reset");
|
||||
this.messagePrint("serial mouse reset");
|
||||
fIdentify = true;
|
||||
}
|
||||
if (!(this.bMCR & SerialPort.MCR.DTR)) {
|
||||
this.messageDebugger("serial mouse ID requested");
|
||||
this.messagePrint("serial mouse ID requested");
|
||||
fIdentify = true;
|
||||
}
|
||||
if (fIdentify) {
|
||||
|
|
@ -605,7 +605,7 @@ Mouse.prototype.notifyMCR = function(bMCR)
|
|||
* I'm calling this good enough for now.
|
||||
*/
|
||||
this.componentAdapter.sendRBR([Mouse.ID_SERIAL, Mouse.ID_SERIAL]);
|
||||
this.messageDebugger("serial mouse ID sent");
|
||||
this.messagePrint("serial mouse ID sent");
|
||||
}
|
||||
this.captureMouse(this.inputScreen);
|
||||
this.setActive(fActive);
|
||||
|
|
@ -624,7 +624,7 @@ Mouse.prototype.notifyMCR = function(bMCR)
|
|||
* a mouse device that's still powered may still send event data to the serial port, and if there was software
|
||||
* polling the serial port, it might expect to see that data. Unlikely, but not impossible.
|
||||
*/
|
||||
this.messageDebugger("serial mouse inactive");
|
||||
this.messagePrint("serial mouse inactive");
|
||||
this.releaseMouse(this.inputScreen);
|
||||
this.setActive(fActive);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ State.prototype = {
|
|||
this[this.id] = s;
|
||||
this.fLoaded = true;
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("localStorage(" + this.key + "): " + s.length + " bytes loaded");
|
||||
this.messagePrint("localStorage(" + this.key + "): " + s.length + " bytes loaded");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -318,7 +318,7 @@ State.prototype = {
|
|||
var s = JSON.stringify(this[this.id]);
|
||||
if (web.setLocalStorageItem(this.key, s)) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("localStorage(" + this.key + "): " + s.length + " bytes stored");
|
||||
this.messagePrint("localStorage(" + this.key + "): " + s.length + " bytes stored");
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -378,7 +378,7 @@ State.prototype = {
|
|||
if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {
|
||||
web.removeLocalStorageItem(sKey);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("localStorage(" + sKey + ") removed");
|
||||
this.messagePrint("localStorage(" + sKey + ") removed");
|
||||
}
|
||||
aKeys.splice(i, 1);
|
||||
i = 0;
|
||||
|
|
@ -404,12 +404,12 @@ State.prototype = {
|
|||
return false;
|
||||
},
|
||||
/**
|
||||
* messageDebugger(sMessage)
|
||||
* messagePrint(sMessage)
|
||||
*
|
||||
* @this {State}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
*/
|
||||
messageDebugger: function(sMessage) {
|
||||
messagePrint: function(sMessage) {
|
||||
if (DEBUGGER && this.dbg) this.dbg.message(sMessage);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2013,7 +2013,7 @@ Video.prototype.setBinding = function(sHTMLType, sBinding, control)
|
|||
this.sLockMessage = control.textContent;
|
||||
if (this.inputScreen && this.inputScreen.lockPointer) {
|
||||
control.onclick = function onClickLockPointer() {
|
||||
if (DEBUG) video.messageDebugger("lockPointer()");
|
||||
if (DEBUG) video.messagePrint("lockPointer()");
|
||||
video.lockPointer(true);
|
||||
};
|
||||
} else {
|
||||
|
|
@ -2024,7 +2024,7 @@ Video.prototype.setBinding = function(sHTMLType, sBinding, control)
|
|||
|
||||
case "refresh":
|
||||
control.onclick = function onClickRefresh() {
|
||||
if (DEBUG) video.messageDebugger("refreshScreen()");
|
||||
if (DEBUG) video.messagePrint("refreshScreen()");
|
||||
video.updateScreen(true);
|
||||
};
|
||||
return true;
|
||||
|
|
@ -2183,7 +2183,7 @@ Video.prototype.captureTouch = function()
|
|||
Video.prototype.onFocusChange = function(fFocus)
|
||||
{
|
||||
if (this.fHasFocus != fFocus && DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("onFocusChange(" + (fFocus? "true" : "false") + ")", true);
|
||||
this.messagePrint("onFocusChange(" + (fFocus? "true" : "false") + ")", true);
|
||||
}
|
||||
/*
|
||||
* As per http://stackoverflow.com/questions/6740253/disable-scrolling-when-changing-focus-form-elements-ipad-web-app,
|
||||
|
|
@ -2216,7 +2216,7 @@ Video.prototype.releaseTouch = function()
|
|||
*/
|
||||
Video.prototype.onTouchStart = function(event)
|
||||
{
|
||||
if (DEBUG) this.messageDebugger("onTouchStart()");
|
||||
if (DEBUG) this.messagePrint("onTouchStart()");
|
||||
this.processTouchEvent(event, true);
|
||||
};
|
||||
|
||||
|
|
@ -2228,7 +2228,7 @@ Video.prototype.onTouchStart = function(event)
|
|||
*/
|
||||
Video.prototype.onTouchMove = function(event)
|
||||
{
|
||||
if (DEBUG) this.messageDebugger("onTouchMove()");
|
||||
if (DEBUG) this.messagePrint("onTouchMove()");
|
||||
this.processTouchEvent(event, false);
|
||||
};
|
||||
|
||||
|
|
@ -2240,7 +2240,7 @@ Video.prototype.onTouchMove = function(event)
|
|||
*/
|
||||
Video.prototype.onTouchEnd = function(event)
|
||||
{
|
||||
if (DEBUG) this.messageDebugger("onTouchEnd()");
|
||||
if (DEBUG) this.messagePrint("onTouchEnd()");
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2703,7 +2703,7 @@ Video.prototype.onROMLoad = function(abROM)
|
|||
* TODO: Unlike the MDA/CGA font data, we may want to hang onto this data, so that we can regenerate
|
||||
* the color font(s) whenever the foreground and/or background colors have been changed.
|
||||
*/
|
||||
if (DEBUG) this.messageDebugger("onROMLoad(): EGA fonts loaded");
|
||||
if (DEBUG) this.messagePrint("onROMLoad(): EGA fonts loaded");
|
||||
this.setFontData(abROM, [0x2230, 0x3160], 8);
|
||||
}
|
||||
this.setReady();
|
||||
|
|
@ -2886,7 +2886,7 @@ Video.prototype.buildFont = function(nFont, offData, offSplit, cxChar, cyChar, a
|
|||
var fChanges = false;
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("buildFont(" + nFont + "): building " + Video.cardSpecs[nFont][0] + " font");
|
||||
this.messagePrint("buildFont(" + nFont + "): building " + Video.cardSpecs[nFont][0] + " font");
|
||||
}
|
||||
if (this.createFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)) fChanges = true;
|
||||
|
||||
|
|
@ -2898,7 +2898,7 @@ Video.prototype.buildFont = function(nFont, offData, offSplit, cxChar, cyChar, a
|
|||
if (this.fDoubleFont) {
|
||||
nFont <<= 1;
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("buildFont(" + nFont + "): building " + Video.cardSpecs[nFont >> 1][0] + " double-size font");
|
||||
this.messagePrint("buildFont(" + nFont + "): building " + Video.cardSpecs[nFont >> 1][0] + " double-size font");
|
||||
}
|
||||
if (this.createFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)) fChanges = true;
|
||||
}
|
||||
|
|
@ -2947,7 +2947,7 @@ Video.prototype.createFont = function(nFont, offData, offSplit, cxChar, cyChar,
|
|||
var rgbColorOrig = font.aCSSColors[iColor]? font.aRGBColors[iColor] : [];
|
||||
if (rgbColor[0] !== rgbColorOrig[0] || rgbColor[1] !== rgbColorOrig[1] || rgbColor[2] !== rgbColorOrig[2]) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("creating font color " + iColor + " for font " + nFont);
|
||||
this.messagePrint("creating font color " + iColor + " for font " + nFont);
|
||||
}
|
||||
this.createFontColor(font, iColor, rgbColor, nDouble, offData, offSplit, cxChar, cyChar, abFontData);
|
||||
fChanges = true;
|
||||
|
|
@ -3179,7 +3179,7 @@ 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.messageEnabled()) {
|
||||
this.messageDebugger("checkCursor(): cursor moved from " + this.iCellCursor + " to " + iCellCursor);
|
||||
this.messagePrint("checkCursor(): cursor moved from " + this.iCellCursor + " to " + iCellCursor);
|
||||
}
|
||||
this.removeCursor();
|
||||
this.iCellCursor = iCellCursor;
|
||||
|
|
@ -3234,7 +3234,7 @@ Video.prototype.removeCursor = function()
|
|||
this.updateChar(col, row, data);
|
||||
}
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("removeCursor(): removed from " + row + "," + col);
|
||||
this.messagePrint("removeCursor(): removed from " + row + "," + col);
|
||||
}
|
||||
this.aCellCache[this.iCellCursor] = data;
|
||||
}
|
||||
|
|
@ -3301,7 +3301,7 @@ Video.prototype.getAccess = function()
|
|||
break;
|
||||
default:
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("getAccess(): invalid GRC mode (" + str.toHexByte(regGRCMode) + ")");
|
||||
this.messagePrint("getAccess(): invalid GRC mode (" + str.toHexByte(regGRCMode) + ")");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -3329,7 +3329,7 @@ Video.prototype.setAccess = function(nAccess)
|
|||
if (nAccess != null && card && nAccess != card.nAccess) {
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("setAccess(0x" + str.toHexWord(nAccess) + ")");
|
||||
this.messagePrint("setAccess(0x" + str.toHexWord(nAccess) + ")");
|
||||
}
|
||||
|
||||
card.setMemoryAccess(nAccess);
|
||||
|
|
@ -3666,7 +3666,7 @@ Video.prototype.setMode = function(nMode, fForce)
|
|||
if (nMode != null && (nMode != this.nMode || fForce)) {
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("setMode(0x" + str.toHexWord(nMode) + (fForce? ",force" : "") + ")");
|
||||
this.messagePrint("setMode(0x" + str.toHexWord(nMode) + (fForce? ",force" : "") + ")");
|
||||
}
|
||||
|
||||
this.cUpdates = 0; // count updateScreen() calls as a means of driving blink updates
|
||||
|
|
@ -3692,7 +3692,7 @@ Video.prototype.setMode = function(nMode, fForce)
|
|||
if (this.addrBuffer) {
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("setMode(" + nMode + "): removing 0x" + str.toHex(this.sizeBuffer) + " bytes from 0x" + str.toHex(this.addrBuffer));
|
||||
this.messagePrint("setMode(" + nMode + "): removing 0x" + str.toHex(this.sizeBuffer) + " bytes from 0x" + str.toHex(this.addrBuffer));
|
||||
}
|
||||
|
||||
if (!this.bus.removeMemory(this.addrBuffer, this.sizeBuffer)) {
|
||||
|
|
@ -3711,7 +3711,7 @@ Video.prototype.setMode = function(nMode, fForce)
|
|||
this.sizeBuffer = card.sizeBuffer;
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("setMode(" + nMode + "): adding 0x" + str.toHex(this.sizeBuffer) + " bytes to 0x" + str.toHex(this.addrBuffer));
|
||||
this.messagePrint("setMode(" + nMode + "): adding 0x" + str.toHex(this.sizeBuffer) + " bytes to 0x" + str.toHex(this.addrBuffer));
|
||||
}
|
||||
|
||||
var controller = (card === this.cardEGA? card : null);
|
||||
|
|
@ -4418,11 +4418,11 @@ Video.prototype.outATC = function(port, bOut, addrFrom)
|
|||
if ((bOut & Card.ATC.INDX_PAL_ENABLE) && !fPalEnabled) {
|
||||
if (!this.buildFonts()) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("outATC(" + str.toHexByte(bOut) + "): no font changes required");
|
||||
this.messagePrint("outATC(" + str.toHexByte(bOut) + "): no font changes required");
|
||||
}
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("outATC(" + str.toHexByte(bOut) + "): redraw screen for font changes");
|
||||
this.messagePrint("outATC(" + str.toHexByte(bOut) + "): redraw screen for font changes");
|
||||
}
|
||||
this.updateScreen(true);
|
||||
}
|
||||
|
|
@ -4917,7 +4917,7 @@ Video.prototype.outCRTCData = function(card, bOut, addrFrom)
|
|||
this.checkCursor();
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.messageDebugger("outCRTCData(): ignoring unexpected write to CRTC[" + str.toHexByte(card.iCRTCReg) + "]: " + str.toHexByte(bOut));
|
||||
this.messagePrint("outCRTCData(): ignoring unexpected write to CRTC[" + str.toHexByte(card.iCRTCReg) + "]: " + str.toHexByte(bOut));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -56,30 +56,29 @@ if (typeof module !== 'undefined') {
|
|||
*
|
||||
* model: a number (eg, 8088) that should match one of the X86.MODEL values
|
||||
*
|
||||
* This extends the CPU class and passes any remaining parmsCPU properties to the
|
||||
* CPU class constructor, along with a default speed (cycles per second) based on the
|
||||
* specified (or default) CPU model number.
|
||||
* This extends the CPU class and passes any remaining parmsCPU properties to the CPU class
|
||||
* constructor, along with a default speed (cycles per second) based on the specified (or default)
|
||||
* CPU model number.
|
||||
*
|
||||
* The X86CPU class was initially written to simulate a 8086/8088 microprocessor, although
|
||||
* over time it is evolving to support newer microprocessors (for example, limited
|
||||
* support for 80186/80188 instructions can already be conditionally enabled).
|
||||
* The X86CPU class was initially written to simulate a 8086/8088 microprocessor, although over time
|
||||
* it has evolved to support later microprocessors (eg, the 80186/80188 and the 80286, including
|
||||
* protected-mode support).
|
||||
*
|
||||
* This is a logical simulation, not a physical simulation, and performance is critical,
|
||||
* second only to the accuracy of the simulation when running real-world x86 software.
|
||||
* Consequently, it takes liberties that do not reflect exactly how actual hardware
|
||||
* operated, especially with regard to external components.
|
||||
* This is a logical simulation, not a physical simulation, and performance is critical, second only
|
||||
* to the accuracy of the simulation when running real-world x86 software. Consequently, it takes a
|
||||
* few liberties with the operation of the simulated hardware, especially with regard to timings,
|
||||
* little-used features, etc. We do make an effort to maintain accurate instruction cycle counts,
|
||||
* but there are many other obstacles (eg, prefetch queue, wait states) to achieving perfect timings.
|
||||
*
|
||||
* For example, our 8237 DMA controller performs all DMA transfers immediately,
|
||||
* since internally they are all memory-to-memory, and attempting to interleave DMA
|
||||
* cycles with instruction execution cycles would only hurt overall performance.
|
||||
* Similarly, the 8254 timer counters are updated only on-demand.
|
||||
* For example, our 8237 DMA controller performs all DMA transfers immediately, since internally
|
||||
* they are all memory-to-memory, and attempting to interleave DMA cycles with instruction execution
|
||||
* cycles would hurt overall performance. Similarly, 8254 timer counters are updated only on-demand.
|
||||
*
|
||||
* The 8237 and 8254, along with several "chips", are combined into a single convenient
|
||||
* "Chipset" component, to keep the number of components we must juggle to a minimum.
|
||||
* The 8237 and 8254, along with the 8259 interrupt controller and several other "chips", are combined
|
||||
* into a single "Chipset" component, to keep the number of components we juggle to a minimum.
|
||||
*
|
||||
* All that being said, this does not change the primary goal: to produce as accurate
|
||||
* a simulation as possible, within the limits of what JavaScript allows and how
|
||||
* precisely/predictably it behaves.
|
||||
* All that being said, this does not change the overall goal: to produce as accurate a simulation as
|
||||
* possible, within the limits of what JavaScript allows and how precisely/predictably it behaves.
|
||||
*
|
||||
* @constructor
|
||||
* @extends CPU
|
||||
|
|
@ -1006,8 +1005,14 @@ X86CPU.prototype.addIntReturn = function(addr, fn)
|
|||
/**
|
||||
* checkIntReturn(addr)
|
||||
*
|
||||
* It is expected (though not required) that callers will check cIntReturn and avoid calling
|
||||
* this function if the count is zero.
|
||||
* We check for possible "INT n" software interrupt returns in the cases of "IRET" (opHelpIRET), "RETF 2"
|
||||
* (opHelpRETF) and "JMPF [DWORD]" (opGrpJMPFdw).
|
||||
*
|
||||
* "JMPF [DWORD]" is an unfortunate choice that newer versions of DOS (as of at least 3.20, and probably
|
||||
* earlier) employed in their INT 0x13 hooks; I would have preferred not making this call for that opcode.
|
||||
*
|
||||
* It is expected (though not required) that callers will check cIntReturn and avoid calling this function
|
||||
* if the count is zero, for maximum performance.
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} addr is a physical (non-segmented) address
|
||||
|
|
@ -1039,7 +1044,7 @@ X86CPU.prototype.setProtMode = function(fProt)
|
|||
fProt = !!(this.regMSW & X86.MSW.PE);
|
||||
}
|
||||
if (!fProt) {
|
||||
this.messageDebugger("returning to real-mode");
|
||||
this.messagePrint("returning to real-mode");
|
||||
}
|
||||
this.aOpGrp6 = (fProt? X86Op0F.aOpGrp6Prot : X86Op0F.aOpGrp6Real);
|
||||
this.segCS.updateMode(fProt);
|
||||
|
|
@ -2083,7 +2088,7 @@ X86CPU.prototype.getBytePrefetch = function(addr)
|
|||
*/
|
||||
}
|
||||
b = this.aPrefetch[this.iPrefetchTail] & 0xff;
|
||||
if (MAXDEBUG) this.messageDebugger(" getBytePrefetch[" + this.iPrefetchTail + "]: " + str.toHex(addr) + ":" + str.toHexByte(b));
|
||||
if (MAXDEBUG) this.messagePrint(" getBytePrefetch[" + this.iPrefetchTail + "]: " + str.toHex(addr) + ":" + str.toHexByte(b));
|
||||
if (MAXDEBUG) this.assert(addr == (this.aPrefetch[this.iPrefetchTail] >> 8), "X86CPU.getBytePrefetch(" + str.toHex(addr) + "): invalid tail address (" + str.toHex(this.aPrefetch[this.iPrefetchTail] >> 8) + ")");
|
||||
this.iPrefetchTail = (this.iPrefetchTail + 1) & X86CPU.PREFETCH.MASK;
|
||||
this.cbPrefetchQueued--;
|
||||
|
|
@ -2125,7 +2130,7 @@ X86CPU.prototype.fillPrefetch = function(n)
|
|||
var addr = this.addrPrefetchHead;
|
||||
var b = this.aMemBlocks[(addr & this.addrMemMask) >> this.blockShift].readByte(addr & this.blockLimit);
|
||||
this.aPrefetch[this.iPrefetchHead] = b | (addr << 8);
|
||||
if (MAXDEBUG) this.messageDebugger(" fillPrefetch[" + this.iPrefetchHead + "]: " + str.toHex(addr) + ":" + str.toHexByte(b));
|
||||
if (MAXDEBUG) this.messagePrint(" fillPrefetch[" + this.iPrefetchHead + "]: " + str.toHex(addr) + ":" + str.toHexByte(b));
|
||||
this.addrPrefetchHead = (addr + 1) & this.addrMemMask;
|
||||
this.iPrefetchHead = (this.iPrefetchHead + 1) & X86CPU.PREFETCH.MASK;
|
||||
this.cbPrefetchQueued++;
|
||||
|
|
@ -2150,7 +2155,7 @@ X86CPU.prototype.flushPrefetch = function(addr)
|
|||
{
|
||||
this.addrPrefetchHead = addr;
|
||||
this.iPrefetchTail = this.iPrefetchHead = this.cbPrefetchQueued = this.cbPrefetchValid = 0;
|
||||
if (MAXDEBUG && addr !== undefined) this.messageDebugger(" flushPrefetch[-]: " + str.toHex(addr));
|
||||
if (MAXDEBUG && addr !== undefined) this.messagePrint(" flushPrefetch[-]: " + str.toHex(addr));
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2173,7 +2178,7 @@ X86CPU.prototype.advancePrefetch = function(inc)
|
|||
this.cbPrefetchQueued -= inc;
|
||||
} else {
|
||||
this.flushPrefetch(this.regEIP);
|
||||
if (MAXDEBUG) this.messageDebugger("advancePrefetch(" + inc + "): flushed");
|
||||
if (MAXDEBUG) this.messagePrint("advancePrefetch(" + inc + "): flushed");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1122,7 +1122,7 @@ var X86Grps = {
|
|||
* @param {number} src (null)
|
||||
* @return {number}
|
||||
*/
|
||||
opGrpCALLdw: function(dst, src) {
|
||||
opGrpCALLFdw: function(dst, src) {
|
||||
if (this.regEA < 0) {
|
||||
return X86Grps.opGrpUndefined.call(this, dst, src);
|
||||
}
|
||||
|
|
@ -1149,11 +1149,12 @@ var X86Grps = {
|
|||
* @param {number} src (null)
|
||||
* @return {number}
|
||||
*/
|
||||
opGrpJMPdw: function(dst, src) {
|
||||
opGrpJMPFdw: function(dst, src) {
|
||||
if (this.regEA < 0) {
|
||||
return X86Grps.opGrpUndefined.call(this, dst, src);
|
||||
}
|
||||
this.setCSIP(dst, this.getWord(this.regEA + 2));
|
||||
if (this.cIntReturn) this.checkIntReturn(this.regEIP);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpDM;
|
||||
if (EAFUNCS) this.setEAWord = this.setEAWordDisabled; else this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
|
|
@ -1324,8 +1325,8 @@ X86Grps.aOpGrp4b = [
|
|||
];
|
||||
|
||||
X86Grps.aOpGrp4w = [
|
||||
X86Grps.opGrpINCw, X86Grps.opGrpDECw, X86Grps.opGrpCALLw, X86Grps.opGrpCALLdw, // 0xFF(reg=0x0-0x3)
|
||||
X86Grps.opGrpJMPw, X86Grps.opGrpJMPdw, X86Grps.opGrpPUSHw, X86Grps.opGrpFault // 0xFF(reg=0x4-0x7)
|
||||
X86Grps.opGrpINCw, X86Grps.opGrpDECw, X86Grps.opGrpCALLw, X86Grps.opGrpCALLFdw, // 0xFF(reg=0x0-0x3)
|
||||
X86Grps.opGrpJMPw, X86Grps.opGrpJMPFdw, X86Grps.opGrpPUSHw, X86Grps.opGrpFault // 0xFF(reg=0x4-0x7)
|
||||
];
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -484,9 +484,6 @@ var X86Help = {
|
|||
this.segES.load(0);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We check for possible "INT n" software interrupt returns only in the cases of "IRET" and "RETF 2".
|
||||
*/
|
||||
if (n == 2 && this.cIntReturn) this.checkIntReturn(this.regEIP);
|
||||
},
|
||||
/**
|
||||
|
|
@ -576,7 +573,7 @@ var X86Help = {
|
|||
opHelpFault: function(nFault, nError, fHalt)
|
||||
{
|
||||
if (!this.aFlags.fComplete) {
|
||||
this.messageDebugger("Fault " + str.toHexByte(nFault) + " blocked by Debugger", Messages.WARN);
|
||||
this.messagePrint("Fault " + str.toHexByte(nFault) + " blocked by Debugger", Messages.WARN);
|
||||
this.setIP(this.opEA - this.segCS.base);
|
||||
return;
|
||||
}
|
||||
|
|
@ -689,22 +686,22 @@ var X86Help = {
|
|||
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) + ")";
|
||||
var fRunning = this.aFlags.fRunning;
|
||||
if (this.messageDebugger(sMessage, bitsMessage)) {
|
||||
if (this.messagePrint(sMessage, bitsMessage)) {
|
||||
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.
|
||||
*
|
||||
* Note that we had to capture fRunning before calling messageDebugger(), because if MESSAGE.HALT
|
||||
* is set, messageDebugger() will have already halted the CPU.
|
||||
* Note that we had to capture fRunning before calling messagePrint(), because if MESSAGE.HALT
|
||||
* is set, messagePrint() will have already halted the CPU.
|
||||
*/
|
||||
fHalt = fRunning;
|
||||
this.dbg.stopCPU();
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* If messageDebugger() returned false, then messageEnabled() must have returned false as well, which
|
||||
* If messagePrint() 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);
|
||||
|
|
|
|||
|
|
@ -1981,7 +1981,7 @@ var X86OpXX = {
|
|||
* op=0x9B (wait)
|
||||
*/
|
||||
opWAIT: function() {
|
||||
this.messageDebugger("WAIT not implemented", Messages.CPU);
|
||||
this.messagePrint("WAIT not implemented", Messages.CPU);
|
||||
this.nStepCycles--;
|
||||
},
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -938,7 +938,7 @@ Component.prototype = {
|
|||
* If bitsMessage is not specified, the component's MESSAGE category is used.
|
||||
*
|
||||
* @this {Component}
|
||||
* @param {number} [bitsMessage] is zero or more Debugger MESSAGE_* category flag(s)
|
||||
* @param {number} [bitsMessage] is zero or more MESSAGE_* category flag(s)
|
||||
* @return {boolean} true if all specified message enabled, false if not
|
||||
*/
|
||||
messageEnabled: function(bitsMessage) {
|
||||
|
|
@ -954,18 +954,18 @@ Component.prototype = {
|
|||
return false;
|
||||
},
|
||||
/**
|
||||
* messageDebugger(sMessage, bitsMessage, fAddress)
|
||||
* messagePrint(sMessage, bitsMessage, fAddress)
|
||||
*
|
||||
* If bitsMessage is not specified, the component's MESSAGE category is used.
|
||||
* If bitsMessage is true, the message is displayed regardless.
|
||||
*
|
||||
* @this {Component}
|
||||
* @param {string} sMessage is any caller-defined message string
|
||||
* @param {number|boolean} [bitsMessage] is zero or more Debugger MESSAGE_* category flag(s)
|
||||
* @param {number|boolean} [bitsMessage] is zero or more 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) {
|
||||
messagePrint: function(sMessage, bitsMessage, fAddress) {
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage === true || this.messageEnabled(bitsMessage | 0)) {
|
||||
this.dbg.message(sMessage, fAddress);
|
||||
|
|
@ -986,7 +986,7 @@ Component.prototype = {
|
|||
* @param {number|null} [addrFrom]
|
||||
* @param {string|null} [name] of the port, if any
|
||||
* @param {number|null} [bIn] is the input value, if known, on an input operation
|
||||
* @param {number|boolean} [bitsMessage] is zero or more Debugger MESSAGE_* category flag(s)
|
||||
* @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)
|
||||
*/
|
||||
messagePort: function(port, bOut, addrFrom, name, bIn, bitsMessage) {
|
||||
if (DEBUGGER && this.dbg) {
|
||||
|
|
|
|||
|
|
@ -393,6 +393,14 @@ web.promptUser = function(sPrompt, sDefault)
|
|||
*/
|
||||
web.fLocalStorage = null;
|
||||
|
||||
/**
|
||||
* TODO: Is there any way to get the Closure Compiler to stop inlining this string? This
|
||||
* isn't cutting it.
|
||||
*
|
||||
* @const {string}
|
||||
*/
|
||||
web.sLocalStorageTest = "PCjs.localStorage";
|
||||
|
||||
/**
|
||||
* hasLocalStorage
|
||||
*
|
||||
|
|
@ -404,11 +412,10 @@ web.hasLocalStorage = function() {
|
|||
if (web.fLocalStorage == null) {
|
||||
var f = false;
|
||||
if (window) {
|
||||
var sTest = 'PCjs.localStorage';
|
||||
try {
|
||||
window.localStorage.setItem(sTest, sTest);
|
||||
f = (window.localStorage.getItem(sTest) === sTest);
|
||||
window.localStorage.removeItem(sTest);
|
||||
window.localStorage.setItem(web.sLocalStorageTest, web.sLocalStorageTest);
|
||||
f = (window.localStorage.getItem(web.sLocalStorageTest) == web.sLocalStorageTest);
|
||||
window.localStorage.removeItem(web.sLocalStorageTest);
|
||||
} catch(e) {
|
||||
web.logLocalStorageError(e);
|
||||
f = false;
|
||||
|
|
|
|||
Loading…
Reference in a new issue