Some debugging improvements
This commit is contained in:
parent
851b077957
commit
a72d824548
7 changed files with 81 additions and 25 deletions
|
|
@ -1391,9 +1391,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", Debugger.MESSAGE.RTC | Debugger.MESSAGE.WARN);
|
||||
this.messageDebugger("RTC interrupt handler failed to clear STATUSC", Debugger.MESSAGE.RTC);
|
||||
} else {
|
||||
this.messageDebugger("CPU took too long trigger new RTC periodic interrupt", Debugger.MESSAGE.RTC | Debugger.MESSAGE.WARN);
|
||||
this.messageDebugger("CPU took too long trigger new RTC periodic interrupt", Debugger.MESSAGE.RTC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2216,7 +2216,7 @@ ChipSet.prototype.dumpPIC = function()
|
|||
sDump += " IC" + (i + 1) + "=" + str.toHexByte(b);
|
||||
}
|
||||
sDump += " IMR=" + str.toHexByte(pic.bIMR) + " IRR=" + str.toHexByte(pic.bIRR) + " ISR=" + str.toHexByte(pic.bISR);
|
||||
this.dbg.message(sDump);
|
||||
this.dbg.println(sDump);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -2240,7 +2240,7 @@ ChipSet.prototype.dumpTimer = function()
|
|||
}
|
||||
}
|
||||
sDump += " mode=" + timer.mode + " bytes=" + timer.countBytes + " count=" + str.toHexWord(count);
|
||||
this.dbg.message(sDump);
|
||||
this.dbg.println(sDump);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -2259,7 +2259,7 @@ ChipSet.prototype.dumpCMOS = function()
|
|||
if (sDump) sDump += '\n';
|
||||
sDump += "CMOS[0x" + str.toHexByte(iCMOS) + "]: 0x" + str.toHexByte(b);
|
||||
}
|
||||
this.dbg.message(sDump);
|
||||
this.dbg.println(sDump);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -2738,7 +2738,7 @@ ChipSet.prototype.advanceDMA = function(channel, fInit)
|
|||
var addr = (channel.bPage << 16) | (channel.addrCurrent[1] << 8) | channel.addrCurrent[0];
|
||||
if (DEBUG && DEBUGGER && channel.sAddrDebug === null) {
|
||||
channel.sAddrDebug = str.toHex(addr >> 4, 4) + ":" + str.toHex(addr & 0xf, 4);
|
||||
if (this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.DMA | (iDMAChannel == ChipSet.DMA_FDC? Debugger.MESSAGE.FDC : (iDMAChannel == ChipSet.DMA_HDC? Debugger.MESSAGE.HDC : Debugger.MESSAGE.LOG))) && channel.xfer != ChipSet.DMA_MODE.XFER_WRITE) {
|
||||
if (this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.DMA | (iDMAChannel == ChipSet.DMA_FDC? Debugger.MESSAGE.FDC : (iDMAChannel == ChipSet.DMA_HDC? Debugger.MESSAGE.HDC : 0))) && channel.xfer != ChipSet.DMA_MODE.XFER_WRITE) {
|
||||
this.dbg.message("advanceDMA(" + iDMAChannel + ") transferring " + channel.cbDebug + " bytes from " + channel.sAddrDebug);
|
||||
this.dbg.doDump("db", channel.sAddrDebug, "l" + Math.floor((channel.cbDebug + 15) / 16));
|
||||
}
|
||||
|
|
@ -2848,7 +2848,7 @@ ChipSet.prototype.updateDMA = function(channel)
|
|||
channel.component = channel.obj = null;
|
||||
}
|
||||
|
||||
if (DEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.DMA | (iDMAChannel == ChipSet.DMA_FDC? Debugger.MESSAGE.FDC : (iDMAChannel == ChipSet.DMA_HDC? Debugger.MESSAGE.HDC : Debugger.MESSAGE.LOG))) && channel.xfer == ChipSet.DMA_MODE.XFER_WRITE && channel.sAddrDebug) {
|
||||
if (DEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.DMA | (iDMAChannel == ChipSet.DMA_FDC? Debugger.MESSAGE.FDC : (iDMAChannel == ChipSet.DMA_HDC? Debugger.MESSAGE.HDC : 0))) && channel.xfer == ChipSet.DMA_MODE.XFER_WRITE && channel.sAddrDebug) {
|
||||
this.dbg.message("updateDMA(" + iDMAChannel + ") transferred " + channel.cbDebug + " bytes to " + channel.sAddrDebug);
|
||||
this.dbg.doDump("db", channel.sAddrDebug, "l" + Math.floor((channel.cbDebug + 15) / 16));
|
||||
}
|
||||
|
|
@ -3721,7 +3721,7 @@ ChipSet.prototype.updateTimer = function(iTimer, fCycleReset)
|
|||
}
|
||||
}
|
||||
|
||||
if (DEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.TIMER)) {
|
||||
if (DEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.TIMER | Debugger.MESSAGE.LOG)) {
|
||||
this.log("TIMER" + iTimer + " count: " + count + ", ticks: " + ticks + ", fired: " + (fFired? "true" : "false"));
|
||||
}
|
||||
|
||||
|
|
@ -4090,7 +4090,7 @@ ChipSet.prototype.in8042RWReg = function(port, addrFrom)
|
|||
* Thanks to the WAITF function, this has become a very "busy" port, so let's not generate messages
|
||||
* unless both MESSAGE_8042 *and* MESSAGE_LOG are set.
|
||||
*/
|
||||
this.messagePort(port, null, addrFrom, "8042_RWREG", Debugger.MESSAGE.C8042 | Debugger.MESSAGE.LOG, b);
|
||||
this.messagePort(port, null, addrFrom, "8042_RWREG", Debugger.MESSAGE.C8042, b);
|
||||
return b;
|
||||
};
|
||||
|
||||
|
|
@ -4670,7 +4670,7 @@ ChipSet.prototype.messageDebugger = function(sMessage, bitsMessage, nIRQ)
|
|||
bitsMessage = Debugger.MESSAGE.CHIPSET;
|
||||
}
|
||||
if (nIRQ !== undefined) {
|
||||
bitsMessage |= (nIRQ == ChipSet.IRQ.TIMER0? Debugger.MESSAGE.TIMER : (nIRQ == ChipSet.IRQ.KBD? Debugger.MESSAGE.KBD : (nIRQ == ChipSet.IRQ.FDC? Debugger.MESSAGE.FDC : Debugger.MESSAGE.PIC)));
|
||||
bitsMessage |= (nIRQ == ChipSet.IRQ.TIMER0? Debugger.MESSAGE.TIMER : (nIRQ == ChipSet.IRQ.KBD? Debugger.MESSAGE.KBD : (nIRQ == ChipSet.IRQ.FDC? Debugger.MESSAGE.FDC : 0))) | Debugger.MESSAGE.PIC;
|
||||
}
|
||||
if (this.dbg.messageEnabled(bitsMessage)) this.dbg.message(sMessage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -956,7 +956,7 @@ CPU.prototype.calcRemainingTime = function()
|
|||
this.aCounts.nCyclesRecalc += this.aCounts.nCyclesThisRun;
|
||||
|
||||
if (DEBUG && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.LOG) && msRemainsThisRun) {
|
||||
this.dbg.message("calcRemainingTime: " + msRemainsThisRun + "ms to sleep after " + this.aCounts.msEndThisRun + "ms");
|
||||
this.log("calcRemainingTime: " + msRemainsThisRun + "ms to sleep after " + this.aCounts.msEndThisRun + "ms");
|
||||
}
|
||||
|
||||
this.aCounts.msEndThisRun += msRemainsThisRun;
|
||||
|
|
|
|||
|
|
@ -1738,7 +1738,7 @@ if (DEBUGGER) {
|
|||
{
|
||||
if (this.sMessagePrev && sMessage == this.sMessagePrev) return;
|
||||
|
||||
this.println(sMessage); // + " (" + this.cpu.getCycles() + " cycles)"
|
||||
if (!SAMPLER) this.println(sMessage); // + " (" + this.cpu.getCycles() + " cycles)"
|
||||
|
||||
this.sMessagePrev = sMessage;
|
||||
|
||||
|
|
@ -1931,7 +1931,7 @@ if (DEBUGGER) {
|
|||
*/
|
||||
Debugger.prototype.stopCPU = function(s)
|
||||
{
|
||||
if (s) this.message(s);
|
||||
if (s) this.println(s);
|
||||
this.cpu.stopCPU();
|
||||
};
|
||||
|
||||
|
|
@ -4138,7 +4138,7 @@ if (DEBUGGER) {
|
|||
if (sCategory !== undefined) {
|
||||
var bitsMessage = 0;
|
||||
if (sCategory == "all") {
|
||||
bitsMessage = 0xffffffff & ~Debugger.MESSAGE.HALT;
|
||||
bitsMessage = 0xffffffff & ~(Debugger.MESSAGE.HALT | Debugger.MESSAGE.LOG);
|
||||
sCategory = null;
|
||||
} else if (sCategory == "on") {
|
||||
fCriteria = true;
|
||||
|
|
|
|||
|
|
@ -105,6 +105,13 @@ var FATARRAYS = false;
|
|||
*/
|
||||
var TYPEDARRAYS = false; // (typeof ArrayBuffer !== 'undefined');
|
||||
|
||||
/**
|
||||
* @define {boolean}
|
||||
*
|
||||
* Enable instruction sampling (work-in-progress).
|
||||
*/
|
||||
var SAMPLER = false;
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
global.PCJSCLASS = PCJSCLASS;
|
||||
global.DEBUGGER = DEBUGGER;
|
||||
|
|
|
|||
|
|
@ -2183,7 +2183,7 @@ FDC.prototype.doRead = function(drive)
|
|||
*/
|
||||
drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;
|
||||
|
||||
if (DEBUG) this.messageDebugger("FDC.doRead(" + drive.bCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
if (DEBUG) this.messageDebugger("FDC.doRead(" + drive.bCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")", Debugger.MESSAGE.OTHER);
|
||||
|
||||
if (drive.disk) {
|
||||
drive.sector = null;
|
||||
|
|
@ -2205,7 +2205,7 @@ FDC.prototype.doWrite = function(drive)
|
|||
{
|
||||
drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;
|
||||
|
||||
if (DEBUG) this.messageDebugger("FDC.doWrite(" + drive.bCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
if (DEBUG) this.messageDebugger("FDC.doWrite(" + drive.bCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")", Debugger.MESSAGE.OTHER);
|
||||
|
||||
if (drive.disk) {
|
||||
if (drive.disk.fWriteProtected) {
|
||||
|
|
|
|||
|
|
@ -1766,7 +1766,7 @@ Card.prototype.dumpCard = function()
|
|||
}
|
||||
|
||||
if (this.iCard == Video.CARDS.EGA) {
|
||||
this.dbg.message(" ATCDATA: " + this.fATCData);
|
||||
this.dbg.println(" ATCDATA: " + this.fATCData);
|
||||
this.dumpRegs(" ATC", this.iATCReg, this.aATCRegs, this.asATCRegs);
|
||||
this.dumpRegs(" GRC", this.iGRCReg, this.aGRCRegs, this.asGRCRegs);
|
||||
this.dumpRegs(" SEQ", this.iSEQReg, this.aSEQRegs, this.asSEQRegs);
|
||||
|
|
@ -1774,8 +1774,8 @@ Card.prototype.dumpCard = function()
|
|||
this.dumpRegs(" MISC", this.miscReg);
|
||||
this.dumpRegs(" STATUS0", this.status0);
|
||||
this.dumpRegs(" LATCHES", this.latches);
|
||||
this.dbg.message(" ACCESS: " + str.toHexWord(this.nAccess));
|
||||
this.dbg.message("Use 'dump video buffer' to dump video memory");
|
||||
this.dbg.println(" ACCESS: " + str.toHexWord(this.nAccess));
|
||||
this.dbg.println("Use 'dump video buffer' to dump video memory");
|
||||
/*
|
||||
* There are few more EGA regs we could dump, like GRCPos1, GRCPos2, but does anyone care?
|
||||
*/
|
||||
|
|
@ -1793,7 +1793,7 @@ Card.prototype.dumpBuffer = function(sParm)
|
|||
{
|
||||
if (DEBUGGER) {
|
||||
if (!this.adwMemory) {
|
||||
this.dbg.message("no buffer");
|
||||
this.dbg.println("no buffer");
|
||||
return;
|
||||
}
|
||||
var idw = str.parseInt(sParm);
|
||||
|
|
@ -1809,7 +1809,7 @@ Card.prototype.dumpBuffer = function(sParm)
|
|||
if (sDump) sDump += "\n";
|
||||
sDump += sData;
|
||||
}
|
||||
if (sDump) this.dbg.message(sDump);
|
||||
if (sDump) this.dbg.println(sDump);
|
||||
this.prevDump = idw;
|
||||
}
|
||||
};
|
||||
|
|
@ -1830,7 +1830,7 @@ Card.prototype.dumpRegs = function(sName, iReg, aRegs, asRegs)
|
|||
{
|
||||
if (DEBUGGER) {
|
||||
if (!aRegs) {
|
||||
this.dbg.message(sName + ": " + str.toHexByte(iReg));
|
||||
this.dbg.println(sName + ": " + str.toHexByte(iReg));
|
||||
return;
|
||||
}
|
||||
var s = "", i, cchMax = 0;
|
||||
|
|
@ -1842,7 +1842,7 @@ Card.prototype.dumpRegs = function(sName, iReg, aRegs, asRegs)
|
|||
if (s) s += '\n';
|
||||
s += sName + "[" + str.toHexByte(i) + "]: " + str.pad(asRegs[i], cchMax) + str.toHexByte(aRegs[i]) + (i === iReg? "*" : "");
|
||||
}
|
||||
this.dbg.message(s);
|
||||
this.dbg.println(s);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -4984,14 +4984,14 @@ Video.prototype.dumpVideo = function(sParm)
|
|||
{
|
||||
if (DEBUGGER) {
|
||||
if (!this.cardActive) {
|
||||
this.dbg.message("no active video card");
|
||||
this.dbg.println("no active video card");
|
||||
return;
|
||||
}
|
||||
if (sParm) {
|
||||
this.cardActive.dumpBuffer(sParm);
|
||||
return;
|
||||
}
|
||||
this.dbg.message("BIOSMODE: " + str.toHexByte(this.nMode));
|
||||
this.dbg.println("BIOSMODE: " + str.toHexByte(this.nMode));
|
||||
this.cardActive.dumpCard();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -158,6 +158,20 @@ function X86CPU(parmsCPU) {
|
|||
*/
|
||||
this.setMemoryEnabled();
|
||||
|
||||
if (SAMPLER) {
|
||||
/*
|
||||
* For now, we're just going to sample EIP values
|
||||
*/
|
||||
this.nSamples = 50000;
|
||||
this.nSampleFreq = 1;
|
||||
this.nSampleSkip = 3183300;
|
||||
this.aSamples = new Array(this.nSamples);
|
||||
for (var i = 0; i < this.nSamples; i++) this.aSamples[i] = -1;
|
||||
this.iSampleNext = 0;
|
||||
this.iSampleFreq = 0;
|
||||
this.iSampleSkip = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This initial resetRegs() call is important to create all the registers (eg, the X86Seg registers),
|
||||
* so that if/when we call restore(), it will have something to fill in.
|
||||
|
|
@ -741,6 +755,12 @@ X86CPU.prototype.reset = function()
|
|||
this.resetRegs();
|
||||
this.resetCycles();
|
||||
this.clearError(); // clear any fatal error/exception that setError() may have flagged
|
||||
|
||||
if (SAMPLER) {
|
||||
this.iSampleNext = 0;
|
||||
this.iSampleFreq = 0;
|
||||
this.iSampleSkip = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2526,6 +2546,35 @@ X86CPU.prototype.stepCPU = function(nMinCycles)
|
|||
fDebugSkip = false;
|
||||
}
|
||||
|
||||
if (SAMPLER) {
|
||||
if (++this.iSampleFreq >= this.nSampleFreq) {
|
||||
this.iSampleFreq = 0;
|
||||
if (this.iSampleSkip < this.nSampleSkip) {
|
||||
this.iSampleSkip++
|
||||
} else {
|
||||
if (this.iSampleNext == this.nSamples) {
|
||||
this.println("sample buffer full");
|
||||
this.stopCPU();
|
||||
break;
|
||||
}
|
||||
var n = this.aSamples[this.iSampleNext];
|
||||
if (n !== -1) {
|
||||
if (n !== this.regEIP) {
|
||||
this.println("sample deviation at index " + this.iSampleNext + ": current EIP=" + str.toHex(this.regEIP) + ", target EIP=" + str.toHex(n));
|
||||
this.stopCPU();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this.aSamples[this.iSampleNext] = this.regEIP;
|
||||
}
|
||||
if (this.iSampleNext == 112) {
|
||||
fDebugSkip = false; // just some no-op statement we can set a breakpoint on
|
||||
}
|
||||
this.iSampleNext++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.opFlags = 0;
|
||||
|
||||
if (DEBUG || PREFETCH) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue