Tightened up tests for selector types not yet supported
This commit is contained in:
parent
f9fa88b3c5
commit
208f5af4bc
3 changed files with 120 additions and 19 deletions
|
|
@ -227,6 +227,7 @@ if (DEBUGGER) {
|
|||
*/
|
||||
Debugger.INT = {
|
||||
VIDEO: 0x10,
|
||||
DISK: 0x13,
|
||||
CASSETTE: 0x15,
|
||||
KBD: 0x16,
|
||||
RTC: 0x1a,
|
||||
|
|
@ -237,8 +238,10 @@ if (DEBUGGER) {
|
|||
|
||||
Debugger.INT_MESSAGE = {
|
||||
0x10: Debugger.MESSAGE.VIDEO,
|
||||
0x13: Debugger.MESSAGE.FDC,
|
||||
0x15: Debugger.MESSAGE.CHIPSET,
|
||||
0x16: Debugger.MESSAGE.KBD,
|
||||
// 0x1a: Debugger.MESSAGE.RTC, // ChipSet contains its own specialized messageInt() handler for the RTC
|
||||
// 0x1a: Debugger.MESSAGE.RTC, // ChipSet contains its own specialized messageInt() handler for the RTC
|
||||
0x1c: Debugger.MESSAGE.TIMER,
|
||||
0x21: Debugger.MESSAGE.DOS,
|
||||
0x33: Debugger.MESSAGE.MOUSE
|
||||
|
|
@ -1218,8 +1221,9 @@ if (DEBUGGER) {
|
|||
}
|
||||
}
|
||||
|
||||
this.messageDump(Debugger.MESSAGE.TSS, function onDumpTSS(s) { dbg.dumpTSS(s); });
|
||||
this.messageDump(Debugger.MESSAGE.DOS, function onDumpDOS(s) { dbg.dumpDOS(s); });
|
||||
this.messageDump(Debugger.MESSAGE.DESC, function onDumpDesc(s) { dbg.dumpDesc(s); });
|
||||
this.messageDump(Debugger.MESSAGE.TSS, function onDumpTSS(s) { dbg.dumpTSS(s); });
|
||||
this.messageDump(Debugger.MESSAGE.DOS, function onDumpDOS(s) { dbg.dumpDOS(s); });
|
||||
|
||||
this.setReady();
|
||||
|
||||
|
|
@ -1346,7 +1350,7 @@ if (DEBUGGER) {
|
|||
* If s is provided and str.parseInt(s) succeeds, then we assume it represents a starting
|
||||
* MCB (Memory Control Block) segment, and we dump the corresponding blocks.
|
||||
*/
|
||||
var seg = str.parseInt(s);
|
||||
var seg = this.parseValue(s);
|
||||
while (seg) {
|
||||
var aAddr = this.newAddr(0, seg);
|
||||
var bSig = this.getByte(aAddr, 1);
|
||||
|
|
@ -1383,6 +1387,78 @@ if (DEBUGGER) {
|
|||
"TASK_LDT": 0x2a
|
||||
};
|
||||
|
||||
/**
|
||||
* dumpDesc(s)
|
||||
*
|
||||
* This dumps a descriptor for the given selector.
|
||||
*
|
||||
* @this {Debugger}
|
||||
* @param {string} [s]
|
||||
*/
|
||||
Debugger.prototype.dumpDesc = function(s)
|
||||
{
|
||||
if (!s) {
|
||||
this.println("no selector");
|
||||
return;
|
||||
}
|
||||
|
||||
var sel = this.parseValue(s);
|
||||
if (sel === undefined) {
|
||||
this.println("invalid selector: " + s);
|
||||
return;
|
||||
}
|
||||
|
||||
var seg = this.getSegment(sel);
|
||||
|
||||
this.println("dumpDesc(" + str.toHexWord(seg.sel) + "): %" + str.toHex(seg.addrDesc, this.cchAddr));
|
||||
|
||||
var sType;
|
||||
if (seg.type & X86.DESC.ACC.TYPE.SEG) {
|
||||
if (seg.type & X86.DESC.ACC.TYPE.CODE) {
|
||||
sType = "code";
|
||||
if (seg.type & X86.DESC.ACC.TYPE.READABLE) sType += ",readable";
|
||||
if (seg.type & X86.DESC.ACC.TYPE.CONFORMING) sType += ",conforming";
|
||||
}
|
||||
else {
|
||||
sType = "data";
|
||||
if (seg.type & X86.DESC.ACC.TYPE.WRITABLE) sType += ",writable";
|
||||
if (seg.type & X86.DESC.ACC.TYPE.EXPDOWN) sType += ",expdown";
|
||||
}
|
||||
if (seg.type & X86.DESC.ACC.TYPE.ACCESSED) sType += ",accessed";
|
||||
}
|
||||
else {
|
||||
switch(seg.type) {
|
||||
case X86.DESC.ACC.TYPE.TSS:
|
||||
sType = "tss";
|
||||
break;
|
||||
case X86.DESC.ACC.TYPE.LDT:
|
||||
sType = "ldt";
|
||||
break;
|
||||
case X86.DESC.ACC.TYPE.TSS_BUSY:
|
||||
sType = "busy tss";
|
||||
break;
|
||||
case X86.DESC.ACC.TYPE.GATE_CALL:
|
||||
sType = "call gate";
|
||||
break;
|
||||
case X86.DESC.ACC.TYPE.GATE_TASK:
|
||||
sType = "task gate";
|
||||
break;
|
||||
case X86.DESC.ACC.TYPE.GATE_INT:
|
||||
sType = "int gate";
|
||||
break;
|
||||
case X86.DESC.ACC.TYPE.GATE_TRAP:
|
||||
sType = "trap gate";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sType && !(seg.acc & X86.DESC.ACC.PRESENT)) sType += ",not present";
|
||||
|
||||
this.println("base=" + str.toHex(seg.base, this.cchAddr) + " limit=" + str.toHexWord(seg.limit) + " dpl=" + str.toHexByte(seg.dpl) + " type=" + str.toHexByte(seg.acc >>> 8) + " (" + sType + ")");
|
||||
};
|
||||
|
||||
/**
|
||||
* dumpTSS(s)
|
||||
*
|
||||
|
|
@ -1397,7 +1473,7 @@ if (DEBUGGER) {
|
|||
if (!s) {
|
||||
seg = this.cpu.segTSS;
|
||||
} else {
|
||||
var sel = str.parseInt(s);
|
||||
var sel = this.parseValue(s);
|
||||
if (sel === undefined) {
|
||||
this.println("invalid task selector: " + s);
|
||||
return;
|
||||
|
|
@ -3120,7 +3196,7 @@ if (DEBUGGER) {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
this.println("missing " + (sName? sName : "value"));
|
||||
this.println("missing " + (sName || "value"));
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
|
@ -3563,19 +3639,19 @@ if (DEBUGGER) {
|
|||
{
|
||||
var m;
|
||||
if (sAddr == "?") {
|
||||
var sDumpers = "symbols";
|
||||
var sDumpers = "";
|
||||
for (m in Debugger.MESSAGES) {
|
||||
if (this.afnDumpers[m]) {
|
||||
if (sDumpers.length) sDumpers += ",";
|
||||
if (sDumpers) sDumpers += ",";
|
||||
sDumpers = sDumpers + m;
|
||||
}
|
||||
}
|
||||
sDumpers += ",state";
|
||||
sDumpers += ",state,symbols";
|
||||
this.println("\ndump commands:");
|
||||
this.println("\tdb [a] [#] dump bytes at address a");
|
||||
this.println("\tdw [a] [#] dump words at address a");
|
||||
this.println("\tds [s] dump descriptor for selector s");
|
||||
if (sDumpers.length) this.println("dumps are also available for: " + sDumpers);
|
||||
if (sDumpers.length) this.println("dump extensions:\n\t" + sDumpers);
|
||||
return;
|
||||
}
|
||||
if (sAddr == "state") {
|
||||
|
|
@ -3926,6 +4002,7 @@ if (DEBUGGER) {
|
|||
Debugger.prototype.doList = function(sSymbol)
|
||||
{
|
||||
var aAddr = this.parseAddr(sSymbol, Debugger.ADDR_CODE);
|
||||
|
||||
if (aAddr[0] == null && aAddr[2] == null) return;
|
||||
|
||||
var addr = this.getAddr(aAddr);
|
||||
|
|
|
|||
|
|
@ -2010,7 +2010,7 @@ FDC.prototype.popCmd = function(name)
|
|||
if (DEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Debugger.MESSAGE.FDC)) {
|
||||
var bCmdMasked = bCmd & FDC.REG_DATA.CMD.MASK;
|
||||
if (!name && !this.regDataIndex && FDC.aCmdInfo[bCmdMasked]) name = FDC.aCmdInfo[bCmdMasked].name;
|
||||
this.dbg.message("FDC.CMD[" + (name || this.regDataIndex) + "]: 0x" + str.toHexByte(bCmd));
|
||||
this.messageDebugger("FDC.CMD[" + (name || this.regDataIndex) + "]: 0x" + str.toHexByte(bCmd), Debugger.MESSAGE.PORT);
|
||||
}
|
||||
this.regDataIndex++;
|
||||
return bCmd;
|
||||
|
|
@ -2061,7 +2061,7 @@ FDC.prototype.beginResult = function()
|
|||
*/
|
||||
FDC.prototype.pushResult = function(bResult, name)
|
||||
{
|
||||
if (DEBUG) this.messageDebugger("FDC.RES[" + (name || this.regDataTotal) + "]: 0x" + str.toHexByte(bResult), Debugger.MESSAGE.FDC);
|
||||
if (DEBUG) this.messageDebugger("FDC.RES[" + (name || this.regDataTotal) + "]: 0x" + str.toHexByte(bResult), Debugger.MESSAGE.PORT);
|
||||
this.regDataArray[this.regDataTotal++] = bResult;
|
||||
};
|
||||
|
||||
|
|
@ -2427,7 +2427,11 @@ FDC.prototype.writeFormat = function(drive, b)
|
|||
FDC.prototype.messageDebugger = function(sMessage, bitsMessage)
|
||||
{
|
||||
if (DEBUGGER && this.dbg) {
|
||||
if (bitsMessage == null) bitsMessage = Debugger.MESSAGE.FDC;
|
||||
if (bitsMessage == null) {
|
||||
bitsMessage = Debugger.MESSAGE.FDC;
|
||||
} else {
|
||||
bitsMessage |= Debugger.MESSAGE.FDC;
|
||||
}
|
||||
if (this.dbg.messageEnabled(bitsMessage)) this.dbg.message(sMessage);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -310,11 +310,31 @@ X86Seg.prototype.loadDesc8 = function(sel, addrDesc)
|
|||
base = null;
|
||||
break;
|
||||
}
|
||||
if (this.id == X86Seg.ID.TSS) {
|
||||
if (type != X86.DESC.ACC.TYPE.TSS && type != X86.DESC.ACC.TYPE.TSS_BUSY) {
|
||||
X86Help.opHelpFault.call(this.cpu, X86.EXCEPTION.TS_FAULT, sel, true);
|
||||
base = null;
|
||||
break;
|
||||
if (sel) {
|
||||
/*
|
||||
* TODO: These tests are far from complete; the main purpose right now is to
|
||||
* catch cases (eg, call gates) that we need to add support for.
|
||||
*/
|
||||
if (this.id == X86Seg.ID.CODE) {
|
||||
if (type < X86.DESC.ACC.TYPE.CODE_EXECONLY) {
|
||||
X86Help.opHelpFault.call(this.cpu, X86.EXCEPTION.GP_FAULT, sel, true);
|
||||
base = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (this.id == X86Seg.ID.DATA || this.id == X86Seg.ID.STACK) {
|
||||
if (type < X86.DESC.ACC.TYPE.DATA_READONLY || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.READABLE)) == X86.DESC.ACC.TYPE.CODE) {
|
||||
X86Help.opHelpFault.call(this.cpu, X86.EXCEPTION.GP_FAULT, sel, true);
|
||||
base = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (this.id == X86Seg.ID.TSS) {
|
||||
if (type != X86.DESC.ACC.TYPE.TSS && type != X86.DESC.ACC.TYPE.TSS_BUSY) {
|
||||
X86Help.opHelpFault.call(this.cpu, X86.EXCEPTION.TS_FAULT, sel, true);
|
||||
base = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.sel = sel;
|
||||
|
|
@ -448,7 +468,7 @@ X86Seg.prototype.messageDebugger = function(base, limit, acc, ext)
|
|||
if (this.id == X86Seg.ID.CODE) sDPL += " cpl=" + this.cpl;
|
||||
this.cpu.messageDebugger("loadSeg(" + this.sName + "):" + ch + " base=" + str.toHex(base) + " limit=" + str.toHexWord(limit) + " acc=" + str.toHexWord(acc) + sDPL, Debugger.MESSAGE.SEG);
|
||||
}
|
||||
this.cpu.assert(!ext || ext == X86.DESC.EXT.AVAIL);
|
||||
this.cpu.assert(base != null && (!ext || ext == X86.DESC.EXT.AVAIL));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue