New icons
|
|
@ -116,8 +116,8 @@ function Debugger(parmsDbg)
|
|||
* stepCPU() and checkInstruction() calls. nCycles is updated by every stepCPU() or stop()
|
||||
* call and simply represents the number of cycles performed by the last run of instructions.
|
||||
*/
|
||||
this.nCycles = -1;
|
||||
this.cOpcodes = -1;
|
||||
this.nCycles = 0;
|
||||
this.cOpcodes = this.cOpcodesStart = 0;
|
||||
|
||||
/*
|
||||
* Default number of hex chars in a register and a linear address (ie, for real-mode);
|
||||
|
|
@ -3358,7 +3358,9 @@ if (DEBUGGER) {
|
|||
sReplace = sAddr + ' "' + this.getSZ(dbgAddr) + '"';
|
||||
s = s.replace('$' + sAddr, sReplace);
|
||||
i += sReplace.length;
|
||||
continue;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
/*
|
||||
* Replace every ^XXXX:XXXX, where XXXX:XXXX is a segmented address, with the FCB filename stored at that address.
|
||||
|
|
@ -3372,7 +3374,9 @@ if (DEBUGGER) {
|
|||
sReplace = sAddr + ' "' + this.getSZ(dbgAddr, 11) + '"';
|
||||
s = s.replace('^' + sAddr, sReplace);
|
||||
i += sReplace.length;
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return s;
|
||||
};
|
||||
|
|
@ -3757,7 +3761,7 @@ if (DEBUGGER) {
|
|||
Debugger.prototype.reset = function(fQuiet)
|
||||
{
|
||||
this.historyInit();
|
||||
this.cOpcodes = 0;
|
||||
this.cOpcodes = this.cOpcodesStart = 0;
|
||||
this.sMessagePrev = null;
|
||||
this.nCycles = 0;
|
||||
this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());
|
||||
|
|
@ -3852,7 +3856,7 @@ if (DEBUGGER) {
|
|||
sStopped += " (";
|
||||
if (this.checksEnabled()) {
|
||||
sStopped += this.cOpcodes + " opcodes, ";
|
||||
this.cOpcodes = 0; // remove this line if you want to maintain a longer total
|
||||
this.cOpcodes = this.cOpcodesStart = 0;
|
||||
}
|
||||
sStopped += this.nCycles + " cycles, " + msTotal + " ms, " + nCyclesPerSecond + " hz)";
|
||||
if (MAXDEBUG && this.chipset) {
|
||||
|
|
@ -5271,7 +5275,7 @@ if (DEBUGGER) {
|
|||
};
|
||||
|
||||
/**
|
||||
* parseReference(sValue)
|
||||
* parseReference(s)
|
||||
*
|
||||
* Returns the given string with any "{expression}" sequences replaced with the value of the expression,
|
||||
* and any "[address]" references replaced with the contents of the address. Expressions are parsed BEFORE
|
||||
|
|
@ -5279,23 +5283,50 @@ if (DEBUGGER) {
|
|||
* (define intermediate variables if needed).
|
||||
*
|
||||
* @this {Debugger}
|
||||
* @param {string} sValue
|
||||
* @param {string} s
|
||||
* @return {string}
|
||||
*/
|
||||
Debugger.prototype.parseReference = function(sValue)
|
||||
Debugger.prototype.parseReference = function(s)
|
||||
{
|
||||
var a;
|
||||
while (a = sValue.match(/\{(.*?)}/)) {
|
||||
while (a = s.match(/\{(.*?)}/)) {
|
||||
if (a[1].indexOf('{') >= 0) break; // unsupported nested brace(s)
|
||||
var value = this.parseExpression(a[1]);
|
||||
sValue = sValue.replace('{' + a[1] + '}', value != null? str.toHex(value) : "undefined");
|
||||
s = s.replace('{' + a[1] + '}', value != null? str.toHex(value) : "undefined");
|
||||
}
|
||||
while (a = sValue.match(/\[(.*?)]/)) {
|
||||
while (a = s.match(/\[(.*?)]/)) {
|
||||
if (a[1].indexOf('[') >= 0) break; // unsupported nested bracket(s)
|
||||
var dbgAddr = this.parseAddr(a[1]);
|
||||
sValue = sValue.replace('[' + a[1] + ']', dbgAddr? str.toHex(this.getWord(dbgAddr), dbgAddr.fData32? 8 : 4) : "undefined");
|
||||
s = s.replace('[' + a[1] + ']', dbgAddr? str.toHex(this.getWord(dbgAddr), dbgAddr.fData32? 8 : 4) : "undefined");
|
||||
}
|
||||
return sValue;
|
||||
return this.parseSysVars(s);
|
||||
};
|
||||
|
||||
/**
|
||||
* parseSysVars(s)
|
||||
*
|
||||
* Returns the given string with any recognized "$var" replaced with its value; eg:
|
||||
*
|
||||
* $ops: the number of opcodes executed since the last time it was displayed (or reset)
|
||||
*
|
||||
* @this {Debugger}
|
||||
* @param {string} s
|
||||
* @return {string}
|
||||
*/
|
||||
Debugger.prototype.parseSysVars = function(s)
|
||||
{
|
||||
var a;
|
||||
while (a = s.match(/\$([a-z]+)/i)) {
|
||||
var v = null;
|
||||
switch(a[1].toLowerCase()) {
|
||||
case "ops":
|
||||
v = this.cOpcodes - this.cOpcodesStart;
|
||||
break;
|
||||
}
|
||||
if (v == null) break;
|
||||
s = s.replace(a[0], v.toString());
|
||||
}
|
||||
return s;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -5339,7 +5370,7 @@ if (DEBUGGER) {
|
|||
var fDefined = false;
|
||||
if (value !== undefined) {
|
||||
fDefined = true;
|
||||
sValue = str.toHexLong(value) + " (" + value + '=' + str.toBinBytes(value) + ')';
|
||||
sValue = str.toHexLong(value) + " " + value + ". (" + str.toBinBytes(value) + ")";
|
||||
}
|
||||
sVar = (sVar != null? (sVar + ": ") : "");
|
||||
this.println(sVar + sValue);
|
||||
|
|
@ -5975,31 +6006,6 @@ if (DEBUGGER) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (sCmd == "disk") {
|
||||
/*
|
||||
* The "disk" command is an undocumented command that's useful any time we're inside an internal
|
||||
* DOS dispatch function where the registers are substantially the same as the corresponding INT 0x13;
|
||||
* "m int on; m disk on" produces the same output, but only when an actual INT 0x13 instruction is used.
|
||||
* Issuing this command at any other time should also be OK, but the results will be meaningless.
|
||||
*/
|
||||
this.messageInt(Interrupts.DISK, this.cpu.regLIP, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sCmd == "dos") {
|
||||
/*
|
||||
* The "dos" command is an undocumented command that's useful any time we're inside an internal
|
||||
* DOS dispatch function where the registers are substantially the same as the corresponding INT 0x21;
|
||||
* "m int on; m dos on" produces the same output, but only when an actual INT 0x21 instruction is used.
|
||||
* Issuing this command at any other time should also be OK, but the results will be meaningless.
|
||||
*
|
||||
* NOTE: This is different from the "d dos" command, which invokes dumpDos() to dump DOS memory blocks,
|
||||
* and is handled by one of the registered dumper functions below.
|
||||
*/
|
||||
this.messageInt(Interrupts.DOS, this.cpu.regLIP, true);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transform a "ds" command into a "d desc" command (simply as shorthand); ditto for "dg" and "dl",
|
||||
* only because that's the syntax that WDEB386 used. I'm uncertain what WDEB386 would do with an LDT
|
||||
|
|
@ -6288,6 +6294,34 @@ if (DEBUGGER) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* doInt(sInt)
|
||||
*
|
||||
* Displays information about the given software interrupt (assuming that said interrupt is in progress).
|
||||
*
|
||||
* These messages also reset the system variable $ops (by updating cOpcodesStart), to make it easier to see
|
||||
* how many opcodes were executed since the interrupt "started".
|
||||
*
|
||||
* @this {Debugger}
|
||||
* @param {string|undefined} sInt
|
||||
* @return {boolean} true if successful, false if not
|
||||
*/
|
||||
Debugger.prototype.doInt = function(sInt)
|
||||
{
|
||||
switch(this.parseValue(sInt)) {
|
||||
case 0x13:
|
||||
this.messageInt(Interrupts.DISK, this.cpu.regLIP, true);
|
||||
this.cOpcodesStart = this.cOpcodes;
|
||||
return true;
|
||||
case 0x21:
|
||||
this.messageInt(Interrupts.DOS, this.cpu.regLIP, true);
|
||||
this.cOpcodesStart = this.cOpcodes;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* doVar(sCmd)
|
||||
*
|
||||
|
|
@ -7540,6 +7574,12 @@ if (DEBUGGER) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
if (asArgs[0] == "int") {
|
||||
if (!this.doInt(asArgs[1])) {
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.doInput(asArgs[1]);
|
||||
break;
|
||||
case 'k':
|
||||
|
|
|
|||
|
|
@ -2037,7 +2037,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.printMessage(this.id + ".popCmd(" + (name || this.regDataIndex) + "): " + str.toHexByte(bCmd), true);
|
||||
this.printMessage(this.idComponent + ".popCmd(" + (name || this.regDataIndex) + "): " + str.toHexByte(bCmd), true);
|
||||
}
|
||||
this.regDataIndex++;
|
||||
return bCmd;
|
||||
|
|
@ -2089,7 +2089,7 @@ FDC.prototype.beginResult = function()
|
|||
FDC.prototype.pushResult = function(bResult, name)
|
||||
{
|
||||
if (DEBUG && this.messageEnabled(Messages.PORT | Messages.FDC)) {
|
||||
this.printMessage(this.id + ".pushResult(" + (name || this.regDataTotal) + "): " + str.toHexByte(bResult), true);
|
||||
this.printMessage(this.idComponent + ".pushResult(" + (name || this.regDataTotal) + "): " + str.toHexByte(bResult), true);
|
||||
}
|
||||
this.assert(!(bResult & ~0xff));
|
||||
this.regDataArray[this.regDataTotal++] = bResult;
|
||||
|
|
@ -2156,7 +2156,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.printMessage(this.id + ".dmaRead(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".dmaRead(): invalid DMA acknowledgement");
|
||||
done(-1, false);
|
||||
};
|
||||
|
||||
|
|
@ -2175,7 +2175,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.printMessage(this.id + ".dmaWrite(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".dmaWrite(): invalid DMA acknowledgement");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
|
@ -2194,7 +2194,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.printMessage(this.id + ".dmaFormat(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".dmaFormat(): invalid DMA acknowledgement");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
|
@ -2215,7 +2215,7 @@ FDC.prototype.doRead = function(drive)
|
|||
|
||||
if (drive.disk) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(this.id + ".doRead(CHS=" + drive.bCylinder + ':' + drive.bHead + ':' + drive.bSector + ",PBA=" + (drive.bCylinder * (drive.disk.nHeads * drive.disk.nSectors) + drive.bHead * drive.disk.nSectors + drive.bSector-1) + ')');
|
||||
this.printMessage(this.idComponent + ".doRead(CHS=" + drive.bCylinder + ':' + drive.bHead + ':' + drive.bSector + ",PBA=" + (drive.bCylinder * (drive.disk.nHeads * drive.disk.nSectors) + drive.bHead * drive.disk.nSectors + drive.bSector-1) + ')');
|
||||
}
|
||||
drive.sector = null;
|
||||
drive.resCode = FDC.REG_DATA.RES.NONE;
|
||||
|
|
@ -2238,7 +2238,7 @@ FDC.prototype.doWrite = function(drive)
|
|||
|
||||
if (drive.disk) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(this.id + ".doWrite(CHS=" + drive.bCylinder + ':' + drive.bHead + ':' + drive.bSector + ",PBA=" + (drive.bCylinder * (drive.disk.nHeads * drive.disk.nSectors) + drive.bHead * drive.disk.nSectors + drive.bSector-1) + ')');
|
||||
this.printMessage(this.idComponent + ".doWrite(CHS=" + drive.bCylinder + ':' + drive.bHead + ':' + drive.bSector + ",PBA=" + (drive.bCylinder * (drive.disk.nHeads * drive.disk.nSectors) + drive.bHead * drive.disk.nSectors + drive.bSector-1) + ')');
|
||||
}
|
||||
if (drive.disk.fWriteProtected) {
|
||||
drive.resCode = FDC.REG_DATA.RES.NOT_WRITABLE | FDC.REG_DATA.RES.INCOMPLETE;
|
||||
|
|
@ -2441,7 +2441,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.printMessage(this.id + ".writeFormat(head=" + str.toHexByte(drive.bHead) + ",cyl=" + str.toHexByte(drive.bCylinder) + ",sec=" + str.toHexByte(drive.bSector) + ",len=" + str.toHexWord(drive.nBytes) + ")");
|
||||
this.printMessage(this.idComponent + ".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.writeData(drive, drive.bFiller) < 0) {
|
||||
|
|
|
|||
|
|
@ -1459,7 +1459,7 @@ HDC.prototype.inATCByte = function(port, addrFrom)
|
|||
*/
|
||||
hdc.regStatus = HDC.ATC.STATUS.ERROR;
|
||||
hdc.regError = HDC.ATC.ERROR.NO_CHS;
|
||||
if (DEBUG) hdc.printMessage(this.id + ".inATCByte(): read failed");
|
||||
if (DEBUG) hdc.printMessage(this.idComponent + ".inATCByte(): read failed");
|
||||
}
|
||||
}, false);
|
||||
} else {
|
||||
|
|
@ -1507,7 +1507,7 @@ HDC.prototype.outATCByte = function(port, bOut, addrFrom)
|
|||
this.regStatus = HDC.ATC.STATUS.ERROR;
|
||||
this.regError = HDC.ATC.ERROR.NO_CHS;
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(this.id + ".outATCByte(" + str.toHexByte(bOut) + "): write failed");
|
||||
this.printMessage(this.idComponent + ".outATCByte(" + str.toHexByte(bOut) + "): write failed");
|
||||
}
|
||||
}
|
||||
else if (this.drive.ibSector == 1 || this.drive.ibSector == this.drive.cbSector) {
|
||||
|
|
@ -1539,7 +1539,7 @@ HDC.prototype.outATCByte = 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.printMessage(this.id + ".outATCByte(" + str.toHexByte(bOut) + "): write exceeds count (" + this.drive.nBytes + ")");
|
||||
this.printMessage(this.idComponent + ".outATCByte(" + str.toHexByte(bOut) + "): write exceeds count (" + this.drive.nBytes + ")");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1547,7 +1547,7 @@ HDC.prototype.outATCByte = function(port, bOut, addrFrom)
|
|||
* TODO: What to do about unexpected writes? No command was specified.
|
||||
*/
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(this.id + ".outATCByte(" + str.toHexByte(bOut) + "): write without command");
|
||||
this.printMessage(this.idComponent + ".outATCByte(" + str.toHexByte(bOut) + "): write without command");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1890,7 +1890,7 @@ HDC.prototype.doATC = function()
|
|||
}
|
||||
|
||||
if (DEBUG && this.messageEnabled(Messages.HDC)) {
|
||||
this.printMessage(this.id + ".doATC(" + str.toHexByte(bCmd) + "): " + HDC.aATCCommands[bCmd], true);
|
||||
this.printMessage(this.idComponent + ".doATC(" + str.toHexByte(bCmd) + "): " + HDC.aATCCommands[bCmd], true);
|
||||
}
|
||||
|
||||
switch (bCmd & HDC.ATC.COMMAND.MASK) {
|
||||
|
|
@ -1904,7 +1904,7 @@ HDC.prototype.doATC = function()
|
|||
|
||||
case HDC.ATC.COMMAND.READ_DATA: // 0x20
|
||||
if (DEBUG && this.messageEnabled(Messages.HDC)) {
|
||||
this.printMessage(this.id + ".doRead(" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + ")", true);
|
||||
this.printMessage(this.idComponent + ".doRead(" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + ")", true);
|
||||
}
|
||||
/*
|
||||
* We're using a call to readData() that disables auto-increment, so that once we've got the first
|
||||
|
|
@ -1936,7 +1936,7 @@ HDC.prototype.doATC = function()
|
|||
|
||||
case HDC.ATC.COMMAND.WRITE_DATA: // 0x30
|
||||
if (DEBUG && this.messageEnabled(Messages.HDC)) {
|
||||
this.printMessage(this.id + ".doWrite(" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + ")", true);
|
||||
this.printMessage(this.idComponent + ".doWrite(" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + ")", true);
|
||||
}
|
||||
this.regStatus = HDC.ATC.STATUS.DATA_REQ;
|
||||
break;
|
||||
|
|
@ -1987,7 +1987,7 @@ HDC.prototype.doATC = function()
|
|||
|
||||
default:
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(this.id + ".doATC(" + str.toHexByte(this.regCommand) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
this.printMessage(this.idComponent + ".doATC(" + str.toHexByte(this.regCommand) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
if (MAXDEBUG && bCmd >= 0) this.dbg.stopCPU();
|
||||
}
|
||||
break;
|
||||
|
|
@ -2031,9 +2031,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.printMessage(this.id + ".setATCIRR(): enabled", Messages.PIC | Messages.HDC);
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".setATCIRR(): enabled", Messages.PIC | Messages.HDC);
|
||||
} else {
|
||||
if (DEBUG) this.printMessage(this.id + ".setATCIRR(): disabled", Messages.PIC | Messages.HDC);
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".setATCIRR(): disabled", Messages.PIC | Messages.HDC);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -2115,7 +2115,7 @@ HDC.prototype.doXTC = function()
|
|||
bDataStatus = HDC.XTC.DATA.STATUS.OK;
|
||||
if (!drive && this.iDriveAllowFail == iDrive) {
|
||||
this.iDriveAllowFail = -1;
|
||||
if (DEBUG) this.printMessage(this.id + ".doXTC(): fake failure triggered");
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".doXTC(): fake failure triggered");
|
||||
bDataStatus = HDC.XTC.DATA.STATUS.ERROR;
|
||||
}
|
||||
this.beginResult(bDataStatus | bDrive);
|
||||
|
|
@ -2152,7 +2152,7 @@ HDC.prototype.doXTC = function()
|
|||
case HDC.XTC.DATA.CMD.RECALIBRATE: // 0x01
|
||||
drive.bControl = bControl;
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(this.id + ".doXTC(): drive " + iDrive + " control byte: " + str.toHexByte(bControl));
|
||||
this.printMessage(this.idComponent + ".doXTC(): drive " + iDrive + " control byte: " + str.toHexByte(bControl));
|
||||
}
|
||||
this.beginResult(HDC.XTC.DATA.STATUS.OK | bDrive);
|
||||
break;
|
||||
|
|
@ -2190,7 +2190,7 @@ HDC.prototype.doXTC = function()
|
|||
default:
|
||||
this.beginResult(HDC.XTC.DATA.STATUS.ERROR | bDrive);
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(this.id + ".doXTC(" + str.toHexByte(bCmdOrig) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
this.printMessage(this.idComponent + ".doXTC(" + str.toHexByte(bCmdOrig) + "): " + (bCmd < 0? ("invalid drive (" + iDrive + ")") : "unsupported operation"));
|
||||
if (MAXDEBUG && bCmd >= 0) this.dbg.stopCPU();
|
||||
}
|
||||
break;
|
||||
|
|
@ -2211,7 +2211,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.printMessage(this.id + ".popCmd(" + bCmdIndex + "): " + str.toHexByte(bCmd) + (!bCmdIndex && HDC.aXTCCommands[bCmd]? (" (" + HDC.aXTCCommands[bCmd] + ")") : ""), true);
|
||||
this.printMessage(this.idComponent + ".popCmd(" + bCmdIndex + "): " + str.toHexByte(bCmd) + (!bCmdIndex && HDC.aXTCCommands[bCmd]? (" (" + HDC.aXTCCommands[bCmd] + ")") : ""), true);
|
||||
}
|
||||
}
|
||||
return bCmd;
|
||||
|
|
@ -2226,13 +2226,7 @@ HDC.prototype.popCmd = function()
|
|||
HDC.prototype.beginResult = function(bResult)
|
||||
{
|
||||
this.regDataIndex = this.regDataTotal = 0;
|
||||
|
||||
if (bResult !== undefined) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(this.id + ".beginResult(" + str.toHexByte(bResult) + ")");
|
||||
}
|
||||
this.pushResult(bResult);
|
||||
}
|
||||
if (bResult !== undefined) this.pushResult(bResult);
|
||||
/*
|
||||
* After the Execution phase (eg, DMA Terminal Count has occurred, or the EOT sector has been read/written),
|
||||
* an interrupt is supposed to occur, signaling the beginning of the Result Phase. Once the data "status byte"
|
||||
|
|
@ -2251,7 +2245,7 @@ HDC.prototype.beginResult = function(bResult)
|
|||
HDC.prototype.pushResult = function(bResult)
|
||||
{
|
||||
if (DEBUG && this.messageEnabled((this.regDataTotal > 0? Messages.PORT : 0) | Messages.HDC)) {
|
||||
this.printMessage(this.id + ".pushResult(" + this.regDataTotal + "): " + str.toHexByte(bResult), true);
|
||||
this.printMessage(this.idComponent + ".pushResult(" + this.regDataTotal + "): " + str.toHexByte(bResult), true);
|
||||
}
|
||||
this.regDataArray[this.regDataTotal++] = bResult;
|
||||
};
|
||||
|
|
@ -2273,7 +2267,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.printMessage(this.id + ".dmaRead(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".dmaRead(): invalid DMA acknowledgement");
|
||||
done(-1, false);
|
||||
};
|
||||
|
||||
|
|
@ -2292,7 +2286,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.printMessage(this.id + ".dmaWrite(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".dmaWrite(): invalid DMA acknowledgement");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
|
@ -2311,7 +2305,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.printMessage(this.id + ".dmaWriteBuffer(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".dmaWriteBuffer(): invalid DMA acknowledgement");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
|
@ -2330,7 +2324,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.printMessage(this.id + ".dmaWriteFormat(): invalid DMA acknowledgement");
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".dmaWriteFormat(): invalid DMA acknowledgement");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
|
@ -2346,7 +2340,7 @@ HDC.prototype.doDMARead = function(drive, done)
|
|||
drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(this.id + ".doDMARead(" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + ")");
|
||||
this.printMessage(this.idComponent + ".doDMARead(" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + ")");
|
||||
}
|
||||
|
||||
if (drive.disk) {
|
||||
|
|
@ -2390,7 +2384,7 @@ HDC.prototype.doDMAWrite = function(drive, done)
|
|||
drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(this.id + ".doDMAWrite(" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + ")");
|
||||
this.printMessage(this.idComponent + ".doDMAWrite(" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + ")");
|
||||
}
|
||||
|
||||
if (drive.disk) {
|
||||
|
|
@ -2440,7 +2434,7 @@ HDC.prototype.doDMAWriteBuffer = function(drive, done)
|
|||
{
|
||||
drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;
|
||||
|
||||
if (DEBUG) this.printMessage(this.id + ".doDMAWriteBuffer()");
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".doDMAWriteBuffer()");
|
||||
|
||||
if (!drive.abSector || drive.abSector.length != drive.nBytes) {
|
||||
drive.abSector = new Array(drive.nBytes);
|
||||
|
|
@ -2743,7 +2737,7 @@ HDC.prototype.writeFormat = function(drive, b)
|
|||
drive.cbFormat = 0;
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(this.id + ".writeFormat(" + drive.wCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
this.printMessage(this.idComponent + ".writeFormat(" + drive.wCylinder + ":" + drive.bHead + ":" + drive.bSector + ":" + drive.nBytes + ")");
|
||||
}
|
||||
|
||||
for (var i = 0; i < drive.nBytes; i++) {
|
||||
|
|
@ -2828,7 +2822,7 @@ HDC.prototype.intBIOSDiskette = function(addr)
|
|||
{
|
||||
var AH = this.cpu.regEAX >> 8;
|
||||
if ((!AH && this.chipset && this.chipset.checkIMR(ChipSet.IRQ.FDC))) {
|
||||
if (DEBUG) this.printMessage(this.id + ".intBIOSDiskette(): skipping useless INT 0x40 diskette reset");
|
||||
if (DEBUG) this.printMessage(this.idComponent + ".intBIOSDiskette(): skipping useless INT 0x40 diskette reset");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -108,6 +108,71 @@ var Interrupts = {
|
|||
};
|
||||
|
||||
if (DEBUGGER) {
|
||||
Interrupts.BIOS_DATA = {
|
||||
0x400: ["RS232_BASE",8], // BASE ADDRESSES OF RS232 ADAPTERS
|
||||
0x408: ["PRINTER_BASE",8], // BASE ADDRESSES OF PRINTER ADAPTERS
|
||||
0x410: ["EQUIP_FLAG",2], // INSTALLED HARDWARE FLAGS
|
||||
0x412: ["MFG_TST",1], // INITIALIZATION FLAGS
|
||||
0x413: ["MEMORY_SIZE",2], // BASE MEMORY SIZE IN K BYTES (X 1024)
|
||||
0x415: ["MFG_ERR_FLAG",2], // SCRATCHPAD FOR MANUFACTURING ERROR CODES
|
||||
0x417: ["KB_FLAG",1], // KEYBOARD SHIFT STATE AND STATUS FLAGS
|
||||
0x418: ["KB_FLAG_1",1], // SECOND BYTE OF KEYBOARD STATUS
|
||||
0x419: ["ALT_INPUT",1], // STORAGE FOR ALTERNATE KEY PAD ENTRY
|
||||
0x41A: ["BUFFER_HEAD",2], // POINTER TO HEAD OF KEYBOARD BUFFER
|
||||
0x41C: ["BUFFER_TAIL",2], // POINTER TO TAIL OF KEYBOARD BUFFER
|
||||
0x41E: ["KB_BUFFER",32], // ROOM FOR 15 SCAN CODE ENTRIES
|
||||
0x43E: ["SEEK_STATUS",1], // DRIVE RECALIBRATION STATUS (BIT 3-0 = DRIVE 3-0 RECALIBRATION BEFORE NEXT SEEK IF BIT IS = 0)
|
||||
0x43F: ["MOTOR_STATUS",1], // MOTOR STATUS (BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING, BIT 7 = CURRENT OPERATION IS A WRITE)
|
||||
0x440: ["MOTOR_COUNT",1], // TIME OUT COUNTER FOR MOTOR(S) TURN OFF
|
||||
0x441: ["DISKETTE_STATUS",1], // RETURN CODE STATUS BYTE
|
||||
0x442: ["NEC_STATUS",7], // STATUS BYTES FROM DISKETTE OPERATION
|
||||
0x449: ["CRT_MODE",1], // CURRENT DISPLAY MODE (TYPE)
|
||||
0x44A: ["CRT_COLS",2], // NUMBER OF COLUMNS ON SCREEN
|
||||
0x44C: ["CRT_LEN",2], // LENGTH OF REGEN BUFFER IN BYTES
|
||||
0x44E: ["CRT_START",2], // STARTING ADDRESS IN REGEN BUFFER
|
||||
0x450: ["CURSOR_POSN",16], // CURSOR FOR EACH OF UP TO 8 PAGES
|
||||
0x460: ["CURSOR_MODE",2], // CURRENT CURSOR MODE SETTING
|
||||
0x462: ["ACTIVE_PAGE",1], // CURRENT PAGE BEING DISPLAYED
|
||||
0x463: ["ADDR_6845",2], // BASE ADDRESS FOR ACTIVE DISPLAY CARD
|
||||
0x465: ["CRT_MODE_SET",1], // CURRENT SETTING OF THE 3X8 REGISTER
|
||||
0x466: ["CRT_PALETTE",1], // CURRENT PALETTE SETTING - COLOR CARD
|
||||
0x467: ["IO_ROM_INIT",2], // POINTER TO ROM INITIALIZATION ROUTINE
|
||||
0x469: ["IO_ROM_SEG",2], // POINTER TO I/O ROM SEGMENT
|
||||
0x46B: ["INTR_FLAG",1], // FLAG INDICATING AN INTERRUPT HAPPENED
|
||||
0x46C: ["TIMER_LOW",2], // LOW WORD OF TIMER COUNT
|
||||
0x46E: ["TIMER_HIGH",2], // HIGH WORD OF TIMER COUNT
|
||||
0x470: ["TIMER_OFL",1], // TIMER HAS ROLLED OVER SINCE LAST READ
|
||||
0x471: ["BIOS_BREAK",1], // BIT 7=1 IF BREAK KEY HAS BEEN PRESSED
|
||||
0x472: ["RESET_FLAG",2], // WORD=1234H IF KEYBOARD RESET UNDERWAY
|
||||
0x474: ["DISK_STATUS1",1], // FIXED DISK STATUS
|
||||
0x475: ["HF_NUM",1], // COUNT OF FIXED DISK DRIVES
|
||||
0x476: ["CONTROL_BYTE",1], // HEAD CONTROL BYTE
|
||||
0x477: ["PORT_OFF",1], // RESERVED (PORT OFFSET)
|
||||
0x478: ["PRINT_TIM_OUT",4], // TIME OUT COUNTERS FOR PRINTER RESPONSE
|
||||
0x47C: ["RS232_TIM_OUT",4], // TIME OUT COUNTERS FOR RS232 RESPONSE
|
||||
0x480: ["BUFFER_START",2], // OFFSET OF KEYBOARD BUFFER START
|
||||
0x482: ["BUFFER_END",2], // OFFSET OF END OF BUFFER
|
||||
0x484: ["ROWS",1], // ROWS ON THE ACTIVE SCREEN (LESS 1)
|
||||
0x485: ["POINTS",2], // BYTES PER CHARACTER
|
||||
0x487: ["INFO",1], // MODE OPTIONS
|
||||
0x488: ["INFO_3",3], // FEATURE BIT SWITCHES
|
||||
0x48B: ["LASTRATE",1], // LAST DISKETTE DATA RATE SELECTED
|
||||
0x48C: ["HF_STATUS",1], // STATUS REGISTER
|
||||
0x48D: ["HF_ERROR",1], // ERROR REGISTER
|
||||
0x48E: ["HF_INT_FLAG",1], // FIXED DISK INTERRUPT FLAG
|
||||
0x48F: ["HF_CNTRL",1], // COMBO FIXED DISK/DISKETTE CARD BIT 0=1
|
||||
0x490: ["DSK_STATE",4], // DRIVE 0 MEDIA STATE, DRIVE 1 MEDIA STATE, DRIVE 0 OPERATION START STATE, DRIVE 1 OPERATION START STATE
|
||||
0x494: ["DSK_TRK",2], // DRIVE 0 PRESENT CYLINDER, DRIVE 1 PRESENT CYLINDER
|
||||
0x496: ["KB_FLAG_3",1], // KEYBOARD MODE STATE AND TYPE FLAGS
|
||||
0x497: ["KB_FLAG_2",1], // KEYBOARD LED FLAGS
|
||||
0x498: ["USER_FLAG",2], // OFFSET ADDRESS OF USERS WAIT FLAG
|
||||
0x49A: ["USER_FLAG_SEG",2], // SEGMENT ADDRESS OF USER WAIT FLAG
|
||||
0x49C: ["RTC_LOW",2], // LOW WORD OF USER WAIT FLAG
|
||||
0x49E: ["RTC_HIGH",2], // HIGH WORD OF USER WAIT FLAG
|
||||
0x4A0: ["RTC_WAIT_FLAG",1], // WAIT ACTIVE FLAG (01=BUSY, 80=POSTED) (00=POST ACKNOWLEDGED)
|
||||
0x4A1: ["NET",7], // RESERVED FOR NETWORK ADAPTERS
|
||||
0x4A8: ["SAVE_PTR",4] // POINTER TO EGA PARAMETER CONTROL BLOCK
|
||||
},
|
||||
/*
|
||||
* See Debugger.prototype.replaceRegs() for the rules governing how register contents are replaced in the strings below.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -9,7 +9,18 @@
|
|||
<!-- We could set content="width=device-width, initial-scale=1", but that apparently causes problems
|
||||
when rotating to landscape mode; by setting only "initial-scale", the width is apparently inferred -->
|
||||
<meta name="viewport" content="initial-scale=1">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/versions/images/current/favicon.ico">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/versions/icons/current/pc-icon-57.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/versions/icons/current/pc-icon-72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="/versions/icons/current/pc-icon-76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="/versions/icons/current/pc-icon-114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/versions/icons/current/pc-icon-120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/versions/icons/current/pc-icon-144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/versions/icons/current/pc-icon-152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/versions/icons/current/pc-icon-180.png">
|
||||
<link rel="apple-touch-icon" sizes="192x192" href="/versions/icons/current/pc-icon-192.png">
|
||||
<link rel="apple-touch-icon" href="/versions/icons/current/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/versions/icons/current/pc-icon-192.png">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/versions/icons/current/favicon.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/modules/shared/templates/common.css">
|
||||
<!-- pcjs:sockets -->
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -123,8 +123,7 @@ app.use(function(req, res, next) {
|
|||
});
|
||||
|
||||
app.use(express.static(sServerRoot));
|
||||
/* Serve favicon at site root */
|
||||
app.use('/favicon.ico', express.static(path.join(sServerRoot, "versions/images/current/favicon.ico")));
|
||||
app.use('/favicon.ico', express.static(path.join(sServerRoot, "versions/icons/current/favicon.ico")));
|
||||
app.use(slash());
|
||||
|
||||
var server = http.createServer(app).listen(app.get('port'), function() {
|
||||
|
|
|
|||
BIN
versions/icons/current/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
versions/icons/current/favicon.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
versions/icons/current/pc-favicon.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
versions/icons/current/pc-icon-114.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
versions/icons/current/pc-icon-120.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
versions/icons/current/pc-icon-144.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
versions/icons/current/pc-icon-152.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
versions/icons/current/pc-icon-180.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
versions/icons/current/pc-icon-192.png
Normal file
|
After Width: | Height: | Size: 3 KiB |
BIN
versions/icons/current/pc-icon-57.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
versions/icons/current/pc-icon-72.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
versions/icons/current/pc-icon-76.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 894 B |