Assorted 80386 and Debugger fixes

This commit is contained in:
Jeff Parsons 2015-05-01 14:21:23 -07:00 • committed by jeffpar
commit 73e52134ac
20 changed files with 1409 additions and 1372 deletions

View file

@ -20,6 +20,6 @@
<item ref="/apps/c1p/BASIC/OSI/SAMPLE6.BAS">PRESIDENTS</item> <item ref="/apps/c1p/BASIC/OSI/SAMPLE6.BAS">PRESIDENTS</item>
<item ref="/sites/www.osiweb.org/programs/basic/OsiBas/spacewar.bas">SPACEWAR</item> <item ref="/sites/www.osiweb.org/programs/basic/OsiBas/spacewar.bas">SPACEWAR</item>
</control> </control>
<control type="button" binding="loadSerial">Download</control> <control type="button" binding="loadSerial">Load</control>
<control type="file" binding="mountSerial" style="padding-left:16px"/> <control type="file" binding="mountSerial" style="padding-left:16px"/>
</serial> </serial>

View file

@ -9,6 +9,6 @@
<item ref="/apps/c1p/BASIC/OSI/SAMPLE5.BAS">COUNTER</item> <item ref="/apps/c1p/BASIC/OSI/SAMPLE5.BAS">COUNTER</item>
<item ref="/apps/c1p/BASIC/OSI/SAMPLE6.BAS">PRESIDENTS</item> <item ref="/apps/c1p/BASIC/OSI/SAMPLE6.BAS">PRESIDENTS</item>
</control> </control>
<control type="button" binding="loadSerial">Download</control> <control type="button" binding="loadSerial">Load</control>
<control type="file" binding="mountSerial" style="padding-left:16px"/> <control type="file" binding="mountSerial" style="padding-left:16px"/>
</serial> </serial>

View file

@ -45,8 +45,8 @@ Similarly, [1989-04-14.json](1989-04-14/1989-04-14.json) was generated by first
from the two 16Kb BIN files provided by [Al Kossow](http://www.vintage-computer.com/vcforum/member.php?2256-Al-Kossow): from the two 16Kb BIN files provided by [Al Kossow](http://www.vintage-computer.com/vcforum/member.php?2256-Al-Kossow):
cd 1989-04-14 cd 1989-04-14
filedump --file=private/109592-005.U11.bin --merge=private/109591-005.U13.bin --output=private/1989-04-14.rom --format=rom filedump --file=static/109592-005.U11.bin --merge=static/109591-005.U13.bin --output=static/1989-04-14.rom --format=rom
filedump --file=private/1989-04-14.rom --output=1989-04-14.json filedump --file=static/1989-04-14.rom --output=1989-04-14.json
Dumping the ROMs Dumping the ROMs
--- ---

View file

@ -23,7 +23,7 @@
<manifest ref="/apps/pc/1981/visicalc/manifest.xml" disk="*"/> <manifest ref="/apps/pc/1981/visicalc/manifest.xml" disk="*"/>
<manifest ref="/apps/pc/1982/esuite/manifest.xml" disk="*"/> <manifest ref="/apps/pc/1982/esuite/manifest.xml" disk="*"/>
</control> </control>
<control type="button" binding="loadDrive">Download</control> <control type="button" binding="loadDrive">Load</control>
<control type="description" binding="descDisk" padleft="8px"/> <control type="description" binding="descDisk" padleft="8px"/>
<control type="file" binding="mountDrive" padtop="8px"/> <control type="file" binding="mountDrive" padtop="8px"/>
</fdc> </fdc>

View file

@ -23,7 +23,7 @@
<manifest ref="/apps/pc/1981/visicalc/manifest.xml" disk="*"/> <manifest ref="/apps/pc/1981/visicalc/manifest.xml" disk="*"/>
<manifest ref="/apps/pc/1982/esuite/manifest.xml" disk="*"/> <manifest ref="/apps/pc/1982/esuite/manifest.xml" disk="*"/>
</control> </control>
<control type="button" binding="loadDrive" padright="8px">Download</control> <control type="button" binding="loadDrive" padright="8px">Load</control>
<control type="description" binding="descDisk" padright="8px"/> <control type="description" binding="descDisk" padright="8px"/>
<control type="file" binding="mountDrive"/> <control type="file" binding="mountDrive"/>
</fdc> </fdc>

View file

@ -9,6 +9,6 @@
<manifest ref="/disks/pc/games/infocom/zork2/manifest.xml" disk="*"/> <manifest ref="/disks/pc/games/infocom/zork2/manifest.xml" disk="*"/>
<manifest ref="/disks/pc/games/infocom/zork3/manifest.xml" disk="*"/> <manifest ref="/disks/pc/games/infocom/zork3/manifest.xml" disk="*"/>
</control> </control>
<control type="button" binding="loadDrive" padright="8px">Download</control> <control type="button" binding="loadDrive" padright="8px">Load</control>
<control type="description" binding="descDisk" padright="8px"/> <control type="description" binding="descDisk" padright="8px"/>
</fdc> </fdc>

View file

@ -299,7 +299,7 @@ function genSIB(sib) {
sMod = "((this.segData = this.segStack), " + sMod + ")"; sMod = "((this.segData = this.segStack), " + sMod + ")";
} }
} }
var sBase = (base == 5? "(mod? " + sMod + " : this.getIPWord())" : "this.reg" + aBase[base]); var sBase = (base == 5? "(mod? " + sMod + " : this.getIPAddr())" : "this.reg" + aBase[base]);
if (index != 4) sBase += " + " + (scale? ("(this.reg" + aIndex[index] + " << " + scale + ")") : ("this.reg" + aIndex[index])); if (index != 4) sBase += " + " + (scale? ("(this.reg" + aIndex[index] + " << " + scale + ")") : ("this.reg" + aIndex[index]));
print(" return " + sBase + ";"); print(" return " + sBase + ";");
print(" }" + (sib < 255? "," : "")); print(" }" + (sib < 255? "," : ""));
@ -473,7 +473,7 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
nCycles = "this.cycleCounts.nEACyclesBase"; // 8086: 5 nCycles = "this.cycleCounts.nEACyclesBase"; // 8086: 5
break; break;
case 6: case 6:
sModAddr = "this.getIPWord()"; sModAddr = "this.getIPAddr()";
sModFunc = "D16"; sModFunc = "D16";
nCycles = "this.cycleCounts.nEACyclesDisp"; // 8086: 6 nCycles = "this.cycleCounts.nEACyclesDisp"; // 8086: 6
break; break;
@ -540,45 +540,45 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
case 2: case 2:
switch (r_m) { switch (r_m) {
case 0: case 0:
sModAddr = "this.regEBX + this.regESI + this.getIPWord()"; sModAddr = "this.regEBX + this.regESI + this.getIPAddr()";
sModFunc = "BXSID16"; sModFunc = "BXSID16";
nCycles = "this.cycleCounts.nEACyclesBaseIndexDisp"; // 8086: 11 nCycles = "this.cycleCounts.nEACyclesBaseIndexDisp"; // 8086: 11
break; break;
case 1: case 1:
sModAddr = "this.regEBX + this.regEDI + this.getIPWord()"; sModAddr = "this.regEBX + this.regEDI + this.getIPAddr()";
sModFunc = "BXDID16"; sModFunc = "BXDID16";
nCycles = "this.cycleCounts.nEACyclesBaseIndexDispExtra"; // 8086: 12 nCycles = "this.cycleCounts.nEACyclesBaseIndexDispExtra"; // 8086: 12
break; break;
case 2: case 2:
sModAddr = "this.regEBP + this.regESI + this.getIPWord()"; sModAddr = "this.regEBP + this.regESI + this.getIPAddr()";
sModFunc = "BPSID16"; sModFunc = "BPSID16";
sModRegSeg = "Stack"; sModRegSeg = "Stack";
nCycles = "this.cycleCounts.nEACyclesBaseIndexDispExtra"; // 8086: 12 nCycles = "this.cycleCounts.nEACyclesBaseIndexDispExtra"; // 8086: 12
break; break;
case 3: case 3:
sModAddr = "this.regEBP + this.regEDI + this.getIPWord()"; sModAddr = "this.regEBP + this.regEDI + this.getIPAddr()";
sModFunc = "BPDID16"; sModFunc = "BPDID16";
sModRegSeg = "Stack"; sModRegSeg = "Stack";
nCycles = "this.cycleCounts.nEACyclesBaseIndexDisp"; // 8086: 11 nCycles = "this.cycleCounts.nEACyclesBaseIndexDisp"; // 8086: 11
break; break;
case 4: case 4:
sModAddr = "this.regESI + this.getIPWord()"; sModAddr = "this.regESI + this.getIPAddr()";
sModFunc = "SID16"; sModFunc = "SID16";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; // 8086: 9 nCycles = "this.cycleCounts.nEACyclesBaseDisp"; // 8086: 9
break; break;
case 5: case 5:
sModAddr = "this.regEDI + this.getIPWord()"; sModAddr = "this.regEDI + this.getIPAddr()";
sModFunc = "DID16"; sModFunc = "DID16";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; // 8086: 9 nCycles = "this.cycleCounts.nEACyclesBaseDisp"; // 8086: 9
break; break;
case 6: case 6:
sModAddr = "this.regEBP + this.getIPWord()"; sModAddr = "this.regEBP + this.getIPAddr()";
sModFunc = "BPD16"; sModFunc = "BPD16";
sModRegSeg = "Stack"; sModRegSeg = "Stack";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; // 8086: 9 nCycles = "this.cycleCounts.nEACyclesBaseDisp"; // 8086: 9
break; break;
case 7: case 7:
sModAddr = "this.regEBX + this.getIPWord()"; sModAddr = "this.regEBX + this.getIPAddr()";
sModFunc = "BXD16"; sModFunc = "BXD16";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; // 8086: 9 nCycles = "this.cycleCounts.nEACyclesBaseDisp"; // 8086: 9
break; break;
@ -729,7 +729,7 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
nCycles = "this.cycleCounts.nEACyclesBase"; nCycles = "this.cycleCounts.nEACyclesBase";
break; break;
case 5: case 5:
sModAddr = "this.getIPWord()"; sModAddr = "this.getIPAddr()";
sModFunc = "D32"; sModFunc = "D32";
nCycles = "this.cycleCounts.nEACyclesDisp"; nCycles = "this.cycleCounts.nEACyclesDisp";
break; break;
@ -799,43 +799,43 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
case 2: case 2:
switch (r_m) { switch (r_m) {
case 0: case 0:
sModAddr = "this.regEAX + this.getIPWord()"; sModAddr = "this.regEAX + this.getIPAddr()";
sModFunc = "EAXD32"; sModFunc = "EAXD32";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; nCycles = "this.cycleCounts.nEACyclesBaseDisp";
break; break;
case 1: case 1:
sModAddr = "this.regECX + this.getIPWord()"; sModAddr = "this.regECX + this.getIPAddr()";
sModFunc = "ECXD32"; sModFunc = "ECXD32";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; nCycles = "this.cycleCounts.nEACyclesBaseDisp";
break; break;
case 2: case 2:
sModAddr = "this.regEDX + this.getIPWord()"; sModAddr = "this.regEDX + this.getIPAddr()";
sModFunc = "EDXD32"; sModFunc = "EDXD32";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; nCycles = "this.cycleCounts.nEACyclesBaseDisp";
break; break;
case 3: case 3:
sModAddr = "this.regEBX + this.getIPWord()"; sModAddr = "this.regEBX + this.getIPAddr()";
sModFunc = "EBXD32"; sModFunc = "EBXD32";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; nCycles = "this.cycleCounts.nEACyclesBaseDisp";
break; break;
case 4: case 4:
sModAddr = "this.getSIBAddr(2) + this.getIPWord()"; sModAddr = "this.getSIBAddr(2) + this.getIPAddr()";
sModFunc = "SIBD32"; sModFunc = "SIBD32";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; nCycles = "this.cycleCounts.nEACyclesBaseDisp";
break; break;
case 5: case 5:
sModAddr = "this.regEBP + this.getIPWord()"; sModAddr = "this.regEBP + this.getIPAddr()";
sModFunc = "EBPD32"; sModFunc = "EBPD32";
sModRegSeg = "Stack"; sModRegSeg = "Stack";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; nCycles = "this.cycleCounts.nEACyclesBaseDisp";
break; break;
case 6: case 6:
sModAddr = "this.regESI + this.getIPWord()"; sModAddr = "this.regESI + this.getIPAddr()";
sModFunc = "ESID32"; sModFunc = "ESID32";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; nCycles = "this.cycleCounts.nEACyclesBaseDisp";
break; break;
case 7: case 7:
sModAddr = "this.regEDI + this.getIPWord()"; sModAddr = "this.regEDI + this.getIPAddr()";
sModFunc = "EDID32"; sModFunc = "EDID32";
nCycles = "this.cycleCounts.nEACyclesBaseDisp"; nCycles = "this.cycleCounts.nEACyclesBaseDisp";
break; break;

View file

@ -1373,9 +1373,28 @@ if (DEBUGGER) {
*/ */
Debugger.prototype.newAddr = function(off, seg, addr, fData32, fAddr32) Debugger.prototype.newAddr = function(off, seg, addr, fData32, fAddr32)
{ {
if (fData32 === undefined) fData32 = (this.cpu.segCS.dataSize == 4);
if (fAddr32 === undefined) fAddr32 = (this.cpu.segCS.addrSize == 4);
return [off, seg, addr, false, fData32, fAddr32]; return [off, seg, addr, false, fData32, fAddr32];
}; };
/**
* checkLimit(aAddr)
*
* @this {Debugger}
* @param {Array} aAddr containing [off, seg, addr]
*/
Debugger.prototype.checkLimit = function(aAddr)
{
if (aAddr[1] != null) {
var limit = this.getSegment(aAddr[1]).limit;
if (aAddr[0] > limit) {
aAddr[0] = 0;
aAddr[2] = null;
}
}
};
/** /**
* incAddr(aAddr, inc) * incAddr(aAddr, inc)
* *
@ -1391,11 +1410,7 @@ if (DEBUGGER) {
} }
if (aAddr[1] != null) { if (aAddr[1] != null) {
aAddr[0] += inc; aAddr[0] += inc;
var limit = this.getSegment(aAddr[1]).limit; this.checkLimit(aAddr);
if (aAddr[0] > limit) {
aAddr[0] = 0;
aAddr[2] = null;
}
} }
}; };
@ -1408,22 +1423,22 @@ if (DEBUGGER) {
*/ */
Debugger.prototype.hexAddr = function(aAddr) Debugger.prototype.hexAddr = function(aAddr)
{ {
return aAddr[1] == null? ("%" + str.toHex(aAddr[2])) : this.hexOffset(aAddr[0], aAddr[1], aAddr[4]); return aAddr[1] == null? ("%" + str.toHex(aAddr[2])) : this.hexOffset(aAddr[0], aAddr[1], aAddr[5]);
}; };
/** /**
* hexOffset(off, sel) * hexOffset(off, sel, fAddr32)
* *
* @this {Debugger} * @this {Debugger}
* @param {number} off * @param {number} off
* @param {number} [sel] * @param {number} [sel]
* @param {boolean} [fData32] is true if 32-bit OPERAND size in effect * @param {boolean} [fAddr32] is true to force 32-bit ADDRESS size
* @return {string} the hex representation of off (or sel:off) * @return {string} the hex representation of off (or sel:off)
*/ */
Debugger.prototype.hexOffset = function(off, sel, fData32) Debugger.prototype.hexOffset = function(off, sel, fAddr32)
{ {
if (sel !== undefined) { if (sel !== undefined) {
return str.toHex(sel, 4) + ":" + str.toHex(off, fData32? 8 : 4); return str.toHex(sel, 4) + ":" + str.toHex(off, (off & (0xffff0000|0)) || fAddr32? 8 : 4);
} }
return str.toHex(off); return str.toHex(off);
}; };
@ -2958,14 +2973,16 @@ if (DEBUGGER) {
*/ */
Debugger.prototype.getInstruction = function(aAddr, sComment, nSequence) Debugger.prototype.getInstruction = function(aAddr, sComment, nSequence)
{ {
var aAddrIns = this.newAddr(aAddr[0], aAddr[1], aAddr[2], this.cpu.segCS.addrSize == 4); var aAddrIns = this.newAddr(aAddr[0], aAddr[1], aAddr[2]);
var bOpcode = this.getByte(aAddr, 1); var bOpcode = this.getByte(aAddr, 1);
/* /*
* Incorporate the following prefixes into the current instruction's byte stream * Incorporate the following prefixes into the current instruction byte stream.
* TODO: Determine the actual effect of multiple OS (and/or multiple AS) prefixes.
*/ */
if (bOpcode == X86.OPCODE.OS || bOpcode == X86.OPCODE.AS) { var cMax = 2; // let's make sure unfortunate memory contents don't screw us
while ((bOpcode == X86.OPCODE.OS || bOpcode == X86.OPCODE.AS) && cMax--) {
if (bOpcode == X86.OPCODE.OS) { if (bOpcode == X86.OPCODE.OS) {
aAddr[4] = !aAddr[4]; aAddr[4] = !aAddr[4];
} else { } else {
@ -3134,7 +3151,7 @@ if (DEBUGGER) {
sOperand = str.toHex(this.getShort(aAddr, 2), 4); sOperand = str.toHex(this.getShort(aAddr, 2), 4);
break; break;
case Debugger.TYPE_FARP: case Debugger.TYPE_FARP:
sOperand = this.hexAddr(this.newAddr(this.getWord(aAddr, 2), this.getShort(aAddr, 2), null, aAddr[4])); sOperand = this.hexAddr(this.newAddr(this.getWord(aAddr, 2), this.getShort(aAddr, 2), null, aAddr[4], aAddr[5]));
break; break;
default: default:
sOperand = "imm(" + str.toHexWord(type) + ")"; sOperand = "imm(" + str.toHexWord(type) + ")";
@ -3550,7 +3567,9 @@ if (DEBUGGER) {
addr = null; addr = null;
} }
} }
return [off, seg, addr]; var aAddr = [off, seg, addr];
this.checkLimit(aAddr);
return aAddr;
}; };
/** /**
@ -4021,14 +4040,13 @@ if (DEBUGGER) {
* because we always display whole lines. If sLen is omitted/undefined, then we default to 8 lines, regardless * because we always display whole lines. If sLen is omitted/undefined, then we default to 8 lines, regardless
* whether dumping bytes or words. * whether dumping bytes or words.
* *
* Also, unlike sAddr, sLen is interpreted as a decimal number, unless a radix specifier in included (eg, "0x100"). * Also, unlike sAddr, sLen is interpreted as a decimal number, unless a radix specifier is included (eg, "0x100");
* * sLen also supports the DEBUG.COM-style syntax of a preceding "l" (eg, "l16").
* And finally, sLen also support the DEBUG.COM-style syntax of a preceding "l" (eg, "l16").
* *
* @this {Debugger} * @this {Debugger}
* @param {string} sCmd * @param {string} sCmd
* @param {string|undefined} sAddr * @param {string|undefined} sAddr
* @param {string|undefined} sLen (if present, it can be preceded by an "l", which we simply ignore; this is purely for historical reasons) * @param {string|undefined} sLen (if present, it can be preceded by an "l", which we simply ignore)
*/ */
Debugger.prototype.doDump = function(sCmd, sAddr, sLen) Debugger.prototype.doDump = function(sCmd, sAddr, sLen)
{ {
@ -4046,6 +4064,7 @@ if (DEBUGGER) {
this.println("\tdb [a] [#] dump # bytes at address a"); this.println("\tdb [a] [#] dump # bytes at address a");
if (BACKTRACK) this.println("\tdi [a] dump backtrack info at address a"); if (BACKTRACK) this.println("\tdi [a] dump backtrack info at address a");
this.println("\tdw [a] [#] dump # words at address a"); this.println("\tdw [a] [#] dump # words at address a");
this.println("\tdd [a] [#] dump # dwords at address a");
if (sDumpers.length) this.println("dump extensions:\n\t" + sDumpers); if (sDumpers.length) this.println("dump extensions:\n\t" + sDumpers);
return; return;
} }
@ -4085,32 +4104,30 @@ if (DEBUGGER) {
} }
else { else {
var cLines = 0; var cLines = 0;
var fWords = (sCmd == "dw"); var cBytes = (sCmd == "dd"? 4 : (sCmd == "dw"? 2 : 1));
if (sLen !== undefined) { var cNumbers = (16 / cBytes)|0;
if (sLen) {
if (sLen.charAt(0) == "l") sLen = sLen.substr(1); if (sLen.charAt(0) == "l") sLen = sLen.substr(1);
cLines = +sLen; cLines = +sLen;
if (cLines) cLines = fWords? ((cLines + 7) >> 3) : ((cLines + 15) >> 4); if (cLines) cLines = ((cLines + cNumbers - 1) / cNumbers)|0;
} }
if (!cLines) cLines = 8; if (!cLines) cLines = 8;
for (var iLine = 0; iLine < cLines; iLine++) { for (var iLine = 0; iLine < cLines; iLine++) {
var bPrev = 0; var data = 0, iByte = 0;
var sBytes = "", sChars = ""; var sData = "", sChars = "";
sAddr = this.hexAddr(aAddr); sAddr = this.hexAddr(aAddr);
for (var i = 0; i < 16; i++) { for (var i = 0; i < 16; i++) {
var b = this.getByte(aAddr, 1); var b = this.getByte(aAddr, 1);
if (fWords) { data |= (b << (iByte++ << 3));
if (i & 0x1) { if (iByte == cBytes) {
sBytes += str.toHex(bPrev | (b << 8), 4) + (i == 7? " - " : " "); sData += str.toHex(data, cBytes * 2);
} sData += (cBytes == 1? (i == 7? '-' : ' ') : " ");
} data = iByte = 0;
else {
sBytes += str.toHex(b, 2) + (i == 7? "-" : " ");
} }
sChars += (b >= 32 && b < 128? String.fromCharCode(b) : "."); sChars += (b >= 32 && b < 128? String.fromCharCode(b) : ".");
bPrev = b;
} }
if (sDump) sDump += "\n"; if (sDump) sDump += "\n";
sDump += sAddr + " " + sBytes + " " + sChars; sDump += sAddr + " " + sData + " " + sChars;
} }
} }
if (sDump) this.println(sDump); if (sDump) this.println(sDump);

View file

@ -289,7 +289,7 @@ function CompaqController(ram)
this.aBlocksDst = null; this.aBlocksDst = null;
} }
CompaqController.ADDR = 0x80C00000; CompaqController.ADDR =(0x80C00000|0);
CompaqController.MAP_SRC = 0x00FE0000; CompaqController.MAP_SRC = 0x00FE0000;
CompaqController.MAP_DST = 0x000E0000; CompaqController.MAP_DST = 0x000E0000;
CompaqController.MAP_SIZE = 0x00020000; CompaqController.MAP_SIZE = 0x00020000;

View file

@ -173,7 +173,7 @@ var X86 = {
}, },
LADDR: { // linear address LADDR: { // linear address
PDE: { // index of page directory entry PDE: { // index of page directory entry
MASK: 0xffc00000, MASK: 0xffc00000|0,
SHIFT: 20 // (addr & DIR.MASK) >>> DIR.SHIFT yields a page directory offset (ie, index * 4) SHIFT: 20 // (addr & DIR.MASK) >>> DIR.SHIFT yields a page directory offset (ie, index * 4)
}, },
PTE: { // index of page table entry PTE: { // index of page table entry
@ -183,7 +183,7 @@ var X86 = {
OFFSET: 0x00000fff OFFSET: 0x00000fff
}, },
PTE: { PTE: {
FRAME: 0xfffff000, FRAME: 0xfffff000|0,
DIRTY: 0x00000040, // page has been modified DIRTY: 0x00000040, // page has been modified
ACCESSED: 0x00000020, // page has been accessed ACCESSED: 0x00000020, // page has been accessed
USER: 0x00000004, // set for user level (CPL 3), clear for supervisor level (CPL 0-2) USER: 0x00000004, // set for user level (CPL 3), clear for supervisor level (CPL 0-2)

View file

@ -2522,7 +2522,7 @@ X86CPU.prototype.setBinding = function(sHTMLType, sBinding, control)
* @param {number} addr is a physical (non-segmented) address * @param {number} addr is a physical (non-segmented) address
* @return {number} byte (8-bit) value at that address * @return {number} byte (8-bit) value at that address
*/ */
X86CPU.prototype.getByte = function(addr) X86CPU.prototype.getByte = function getByte(addr)
{ {
if (BACKTRACK) this.backTrack.btiMemLo = this.bus.readBackTrack(addr); if (BACKTRACK) this.backTrack.btiMemLo = this.bus.readBackTrack(addr);
return this.aMemBlocks[(addr & this.busMask) >>> this.blockShift].readByte(addr & this.blockLimit, addr); return this.aMemBlocks[(addr & this.busMask) >>> this.blockShift].readByte(addr & this.blockLimit, addr);
@ -2535,7 +2535,7 @@ X86CPU.prototype.getByte = function(addr)
* @param {number} addr is a physical (non-segmented) address * @param {number} addr is a physical (non-segmented) address
* @return {number} word (16-bit) value at that address * @return {number} word (16-bit) value at that address
*/ */
X86CPU.prototype.getShort = function(addr) X86CPU.prototype.getShort = function getShort(addr)
{ {
var off = addr & this.blockLimit; var off = addr & this.blockLimit;
var iBlock = (addr & this.busMask) >>> this.blockShift; var iBlock = (addr & this.busMask) >>> this.blockShift;
@ -2562,7 +2562,7 @@ X86CPU.prototype.getShort = function(addr)
* @param {number} addr is a physical (non-segmented) address * @param {number} addr is a physical (non-segmented) address
* @return {number} long (32-bit) value at that address * @return {number} long (32-bit) value at that address
*/ */
X86CPU.prototype.getLong = function(addr) X86CPU.prototype.getLong = function getLong(addr)
{ {
var off = addr & this.blockLimit; var off = addr & this.blockLimit;
var iBlock = (addr & this.busMask) >>> this.blockShift; var iBlock = (addr & this.busMask) >>> this.blockShift;
@ -2584,7 +2584,7 @@ X86CPU.prototype.getLong = function(addr)
* @param {number} addr is a physical (non-segmented) address * @param {number} addr is a physical (non-segmented) address
* @param {number} b is the byte (8-bit) value to write (which we truncate to 8 bits; required by opSTOSb) * @param {number} b is the byte (8-bit) value to write (which we truncate to 8 bits; required by opSTOSb)
*/ */
X86CPU.prototype.setByte = function(addr, b) X86CPU.prototype.setByte = function setByte(addr, b)
{ {
if (BACKTRACK) this.bus.writeBackTrack(addr, this.backTrack.btiMemLo); if (BACKTRACK) this.bus.writeBackTrack(addr, this.backTrack.btiMemLo);
this.aMemBlocks[(addr & this.busMask) >>> this.blockShift].writeByte(addr & this.blockLimit, b & 0xff, addr); this.aMemBlocks[(addr & this.busMask) >>> this.blockShift].writeByte(addr & this.blockLimit, b & 0xff, addr);
@ -2597,7 +2597,7 @@ X86CPU.prototype.setByte = function(addr, b)
* @param {number} addr is a physical (non-segmented) address * @param {number} addr is a physical (non-segmented) address
* @param {number} w is the word (16-bit) value to write (which we truncate to 16 bits to be safe) * @param {number} w is the word (16-bit) value to write (which we truncate to 16 bits to be safe)
*/ */
X86CPU.prototype.setShort = function(addr, w) X86CPU.prototype.setShort = function setShort(addr, w)
{ {
var off = addr & this.blockLimit; var off = addr & this.blockLimit;
var iBlock = (addr & this.busMask) >>> this.blockShift; var iBlock = (addr & this.busMask) >>> this.blockShift;
@ -2626,7 +2626,7 @@ X86CPU.prototype.setShort = function(addr, w)
* @param {number} addr is a physical (non-segmented) address * @param {number} addr is a physical (non-segmented) address
* @param {number} l is the long (32-bit) value to write * @param {number} l is the long (32-bit) value to write
*/ */
X86CPU.prototype.setLong = function(addr, l) X86CPU.prototype.setLong = function setLong(addr, l)
{ {
var off = addr & this.blockLimit; var off = addr & this.blockLimit;
var iBlock = (addr & this.busMask) >>> this.blockShift; var iBlock = (addr & this.busMask) >>> this.blockShift;

View file

@ -2629,7 +2629,7 @@ X86.fnSGDT = function SGDT(dst, src)
* *
* This code is expecting SGDT on an 80286 to set the 6th "undefined" byte to 0xFF. * This code is expecting SGDT on an 80286 to set the 6th "undefined" byte to 0xFF.
*/ */
var addr = this.addrGDT | (this.model == X86.MODEL_80286? 0xff000000 : 0); var addr = this.addrGDT | (this.model == X86.MODEL_80286? (0xff000000|0) : 0);
this.setLong(this.regEA + 2, addr); this.setLong(this.regEA + 2, addr);
this.nStepCycles -= 11; this.nStepCycles -= 11;
} }
@ -2981,7 +2981,7 @@ X86.fnSIDT = function SIDT(dst, src)
* As with SGDT, the 6th byte is technically "undefined" on an 80286, but we now set it to 0xFF, for the * As with SGDT, the 6th byte is technically "undefined" on an 80286, but we now set it to 0xFF, for the
* same reasons discussed in SGDT (above). * same reasons discussed in SGDT (above).
*/ */
var addr = this.addrIDT | (this.model == X86.MODEL_80286? 0xff000000 : 0); var addr = this.addrIDT | (this.model == X86.MODEL_80286? (0xff000000|0) : 0);
this.setLong(this.regEA + 2, addr); this.setLong(this.regEA + 2, addr);
this.nStepCycles -= 12; this.nStepCycles -= 12;
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -288,7 +288,11 @@ X86Seg.prototype.checkWriteReal = function checkWriteReal(off, cb, fSuppress)
*/ */
X86Seg.prototype.checkReadProt = function checkReadProt(off, cb, fSuppress) X86Seg.prototype.checkReadProt = function checkReadProt(off, cb, fSuppress)
{ {
if (off + cb - 1 <= this.limit) { /*
* Since "off" could be a 32-bit value with the sign bit (bit 31) set, we must convert
* it to an unsigned value using ">>>"; limit was already converted at segment load time.
*/
if ((off >>> 0) + cb - 1 <= this.limit) {
return (this.base + off)|0; return (this.base + off)|0;
} }
return this.checkReadProtDisallowed(off, cb, fSuppress); return this.checkReadProtDisallowed(off, cb, fSuppress);
@ -305,7 +309,11 @@ X86Seg.prototype.checkReadProt = function checkReadProt(off, cb, fSuppress)
*/ */
X86Seg.prototype.checkReadProtDown = function checkReadProtDown(off, cb, fSuppress) X86Seg.prototype.checkReadProtDown = function checkReadProtDown(off, cb, fSuppress)
{ {
if (off + cb - 1 > this.limit) { /*
* Since "off" could be a 32-bit value with the sign bit (bit 31) set, we must convert
* it to an unsigned value using ">>>"; limit was already converted at segment load time.
*/
if ((off >>> 0) + cb - 1 > this.limit) {
return (this.base + off)|0; return (this.base + off)|0;
} }
return this.checkReadProtDisallowed(off, cb, fSuppress); return this.checkReadProtDisallowed(off, cb, fSuppress);
@ -339,7 +347,11 @@ X86Seg.prototype.checkReadProtDisallowed = function checkReadProtDisallowed(off,
*/ */
X86Seg.prototype.checkWriteProt = function checkWriteProt(off, cb, fSuppress) X86Seg.prototype.checkWriteProt = function checkWriteProt(off, cb, fSuppress)
{ {
if (off + cb - 1 <= this.limit) { /*
* Since "off" could be a 32-bit value with the sign bit (bit 31) set, we must convert
* it to an unsigned value using ">>>"; limit was already converted at segment load time.
*/
if ((off >>> 0) + cb - 1 <= this.limit) {
return (this.base + off)|0; return (this.base + off)|0;
} }
return this.checkWriteProtDisallowed(off, cb, fSuppress); return this.checkWriteProtDisallowed(off, cb, fSuppress);
@ -356,7 +368,11 @@ X86Seg.prototype.checkWriteProt = function checkWriteProt(off, cb, fSuppress)
*/ */
X86Seg.prototype.checkWriteProtDown = function checkWriteProtDown(off, cb, fSuppress) X86Seg.prototype.checkWriteProtDown = function checkWriteProtDown(off, cb, fSuppress)
{ {
if (off + cb - 1 > this.limit) { /*
* Since "off" could be a 32-bit value with the sign bit (bit 31) set, we must convert
* it to an unsigned value using ">>>"; limit was already converted at segment load time.
*/
if ((off >>> 0) + cb - 1 > this.limit) {
return (this.base + off)|0; return (this.base + off)|0;
} }
return this.checkWriteProtDisallowed(off, cb, fSuppress); return this.checkWriteProtDisallowed(off, cb, fSuppress);
@ -748,7 +764,11 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
} }
this.sel = sel; this.sel = sel;
this.base = base; this.base = base;
this.limit = limit; /*
* Since limit could be a 32-bit value with the sign bit (bit 31) set, we convert
* it to an unsigned value now, using ">>>", so that the limit checks won't have to.
*/
this.limit = (limit >>> 0);
this.acc = acc; this.acc = acc;
this.type = type; this.type = type;
this.ext = ext; this.ext = ext;

View file

@ -10,7 +10,7 @@
<manifest ref="/apps/pc/1981/visicalc/manifest.xml" disk="*"/> <manifest ref="/apps/pc/1981/visicalc/manifest.xml" disk="*"/>
<disk path="/api/v1/dump?dir=/pubs/pc/programming/Graphics_for_the_IBM_PC/programs">BASIC Programs</disk> <disk path="/api/v1/dump?dir=/pubs/pc/programming/Graphics_for_the_IBM_PC/programs">BASIC Programs</disk>
</control> </control>
<control type="button" binding="loadDrive" padright="8px">Download</control> <control type="button" binding="loadDrive" padright="8px">Load</control>
<control type="description" binding="descDisk" padright="8px"/> <control type="description" binding="descDisk" padright="8px"/>
<control type="file" binding="mountDrive"/> <control type="file" binding="mountDrive"/>
</fdc> </fdc>