Fixed I/O port handling
This commit is contained in:
parent
6295c112fe
commit
e76655a48f
3 changed files with 438 additions and 20 deletions
|
|
@ -1241,13 +1241,13 @@ if (DEBUGGER) {
|
|||
0x3A: "remove subdirectory $%DS:%DX",
|
||||
0x3B: "set current directory $%DS:%DX",
|
||||
0x3C: "create or truncate file $%DS:%DX with attributes %CX",
|
||||
0x3D: "open existing file $%DS:%DX with mode %AL",
|
||||
0x3D: "open file $%DS:%DX with mode %AL",
|
||||
0x3E: "close file %BX",
|
||||
0x3F: "read %CX bytes from file %BX into buffer %DS:%DX",
|
||||
0x40: "write %CX bytes to file %BX from buffer %DS:%DX",
|
||||
0x41: "delete file $%DS:%DX",
|
||||
0x42: "set position %CX:%DX of file %BX relative to %AL",
|
||||
0x43: "get(0)/set(1) attributes %CX of file %DS:%DX (%AL)",
|
||||
0x43: "get(0)/set(1) attributes %CX of file $%DS:%DX (%AL)",
|
||||
0x44: "get device information (IOCTL)",
|
||||
0x45: "duplicate file handle %BX",
|
||||
0x46: "force file handle %CX to duplicate file handle %BX",
|
||||
|
|
@ -1267,12 +1267,16 @@ if (DEBUGGER) {
|
|||
0x54: "get verify flag (AL)",
|
||||
0x55: "create child PSP at segment %DX",
|
||||
0x56: "rename file $%DS:%DX to $%ES:%DI",
|
||||
0x57: "get(0)/set(1) file date %DX and time %CX (%AL)",
|
||||
0x57: "get(0)/set(1) file %BX date %DX and time %CX (%AL)",
|
||||
0x58: "get(0)/set(1) memory allocation strategy (%AL)", // DOS 2.11+
|
||||
0x59: "get extended error information", // DOS 3.00+
|
||||
0x5A: "create temporary file $%DS:%DX with attributes %CX", // DOS 3.00+
|
||||
0x5B: "create file $%DS:%DX with attributes %CX", // DOS 3.00+ (doesn't truncate existing files like 0x3C)
|
||||
0x5C: "lock(0)/unlock(1) file %BX region %CX:%DX length %SI:%DI (%AL)" // DOS 3.00+
|
||||
0x5C: "lock(0)/unlock(1) file %BX region %CX:%DX length %SI:%DI (%AL)", // DOS 3.00+
|
||||
0x5D: "critical error information (%AL)", // DOS 3.00+ (undocumented)
|
||||
0x60: "get fully-qualified filename from $%DS:%SI", // DOS 3.00+ (undocumented)
|
||||
0x63: "get lead byte table (%AL)", // DOS 2.25 and 3.20+
|
||||
0x6C: "extended open file $%DS:%SI" // DOS 4.00+
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -2226,7 +2230,7 @@ if (DEBUGGER) {
|
|||
sChar = s.substr(i+1, 2);
|
||||
b = str.parseInt(sChar, 16);
|
||||
if (b != null && b >= 32 && b < 128) {
|
||||
sReplace = '#' + sChar + " '" + String.fromCharCode(b) + "'";
|
||||
sReplace = sChar + " '" + String.fromCharCode(b) + "'";
|
||||
s = s.replace('#' + sChar, sReplace);
|
||||
i += sReplace.length;
|
||||
continue;
|
||||
|
|
@ -2833,10 +2837,10 @@ if (DEBUGGER) {
|
|||
return true;
|
||||
}
|
||||
/*
|
||||
* Halt whenever ring 3 code is running with interrupts disabled, because that's likely an
|
||||
* error (TODO: we should also check the IOPL, too, because if IOPL is 3, then this is OK).
|
||||
* Halt if running with interrupts disabled and IOPL < CPL, because that's likely an error
|
||||
*/
|
||||
if (this.cpu.segCS.cpl == 3 && !(this.cpu.regPS & X86.PS.IF)) {
|
||||
if (!(this.cpu.regPS & X86.PS.IF) && this.cpu.nIOPL < this.cpu.segCS.cpl) {
|
||||
this.printMessage("interrupts disabled at IOPL " + this.cpu.nIOPL + " and CPL " + this.cpu.segCS.cpl, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1347,7 +1347,6 @@ X86.opFS = function FS()
|
|||
this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;
|
||||
this.segData = this.segStack = this.segFS;
|
||||
this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;
|
||||
this.stopCPU();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1364,7 +1363,6 @@ X86.opGS = function GS()
|
|||
this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;
|
||||
this.segData = this.segStack = this.segGS;
|
||||
this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;
|
||||
this.stopCPU();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1475,7 +1473,7 @@ X86.opINSb = function INSb()
|
|||
}
|
||||
|
||||
if (nReps--) {
|
||||
var b = this.bus.checkPortInputNotify(this.regEDX, this.regLIP - nDelta - 1);
|
||||
var b = this.bus.checkPortInputNotify(this.regEDX & 0xffff, this.regLIP - nDelta - 1);
|
||||
if (BACKTRACK) this.backTrack.btiMemLo = this.backTrack.btiIO;
|
||||
this.setSOByte(this.segES, this.regEDI & this.addrMask, b);
|
||||
this.regEDI = (this.regEDI & ~this.addrMask) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -1 : 1)) & this.addrMask);
|
||||
|
|
@ -1524,7 +1522,7 @@ X86.opINSw = function INSw()
|
|||
var addrFrom = this.regLIP - nDelta - 1;
|
||||
var w = 0, shift = 0;
|
||||
for (var n = 0; n < this.dataSize; n++) {
|
||||
w |= this.bus.checkPortInputNotify(this.regEDX, addrFrom) << shift;
|
||||
w |= this.bus.checkPortInputNotify(this.regEDX & 0xffff, addrFrom) << shift;
|
||||
shift += 8;
|
||||
if (BACKTRACK) {
|
||||
if (!n) {
|
||||
|
|
@ -1581,7 +1579,7 @@ X86.opOUTSb = function OUTSb()
|
|||
this.regESI = (this.regESI & ~this.addrMask) | ((this.regESI + ((this.regPS & X86.PS.DF)? -1 : 1)) & this.addrMask);
|
||||
this.nStepCycles -= nCycles;
|
||||
if (BACKTRACK) this.backTrack.btiIO = this.backTrack.btiMemLo;
|
||||
this.bus.checkPortOutputNotify(this.regEDX, b, this.regLIP - nDelta - 1);
|
||||
this.bus.checkPortOutputNotify(this.regEDX & 0xffff, b, this.regLIP - nDelta - 1);
|
||||
this.regECX = (this.regECX & ~this.addrMask) | ((this.regECX - nDelta) & this.addrMask);
|
||||
if (nReps) {
|
||||
if (BUGS_8086) {
|
||||
|
|
@ -1634,7 +1632,7 @@ X86.opOUTSw = function OUTSw()
|
|||
this.backTrack.btiIO = this.backTrack.btiMemHi;
|
||||
}
|
||||
}
|
||||
this.bus.checkPortOutputNotify(this.regEDX, (w >> shift) & 0xff, addrFrom);
|
||||
this.bus.checkPortOutputNotify(this.regEDX & 0xffff, (w >> shift) & 0xff, addrFrom);
|
||||
shift += 8;
|
||||
}
|
||||
this.regECX = (this.regECX & ~this.addrMask) | ((this.regECX - nDelta) & this.addrMask);
|
||||
|
|
@ -3623,7 +3621,12 @@ X86.opINw = function INw()
|
|||
var port = this.getIPByte();
|
||||
this.regEAX = this.bus.checkPortInputNotify(port, this.regLIP - 2);
|
||||
if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiIO;
|
||||
this.regEAX |= (this.bus.checkPortInputNotify((port + 1) & 0xffff, this.regLIP - 2) << 8);
|
||||
/*
|
||||
* TODO: Specs are clear that bits 8-15 of the port address for the FIRST byte of I/O will be zero, but
|
||||
* what about the SECOND byte? If the port is 0xff, will the SECOND byte of I/O use port 0x00 or 0x100?
|
||||
* Our code (below) assumes the latter. Mask (port + 1) with 0xff if it turns out the former is true.
|
||||
*/
|
||||
this.regEAX |= (this.bus.checkPortInputNotify(port + 1, this.regLIP - 2) << 8);
|
||||
if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiIO;
|
||||
this.nStepCycles -= this.cycleCounts.nOpCyclesInP;
|
||||
};
|
||||
|
|
@ -3649,7 +3652,12 @@ X86.opOUTw = function OUTw()
|
|||
{
|
||||
var port = this.getIPByte();
|
||||
this.bus.checkPortOutputNotify(port, this.regEAX & 0xff, this.regLIP - 2);
|
||||
this.bus.checkPortOutputNotify((port + 1) & 0xffff, this.regEAX >> 8, this.regLIP - 2);
|
||||
/*
|
||||
* TODO: Specs are clear that bits 8-15 of the port address for the FIRST byte of I/O will be zero, but
|
||||
* what about the SECOND byte? If the port is 0xff, will the SECOND byte of I/O use port 0x00 or 0x100?
|
||||
* Our code (below) assumes the latter. Mask (port + 1) with 0xff if it turns out the former is true.
|
||||
*/
|
||||
this.bus.checkPortOutputNotify(port + 1, this.regEAX >> 8, this.regLIP - 2);
|
||||
this.nStepCycles -= this.cycleCounts.nOpCyclesOutP;
|
||||
};
|
||||
|
||||
|
|
@ -3711,7 +3719,7 @@ X86.opJMPs = function JMPs()
|
|||
*/
|
||||
X86.opINDXb = function INDXb()
|
||||
{
|
||||
this.regEAX = (this.regEAX & ~0xff) | this.bus.checkPortInputNotify(this.regEDX, this.regLIP - 1);
|
||||
this.regEAX = (this.regEAX & ~0xff) | this.bus.checkPortInputNotify(this.regEDX & 0xffff, this.regLIP - 1);
|
||||
if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiIO;
|
||||
this.nStepCycles -= this.cycleCounts.nOpCyclesInDX;
|
||||
};
|
||||
|
|
@ -3723,7 +3731,7 @@ X86.opINDXb = function INDXb()
|
|||
*/
|
||||
X86.opINDXw = function INDXw()
|
||||
{
|
||||
this.regEAX = this.bus.checkPortInputNotify(this.regEDX, this.regLIP - 1);
|
||||
this.regEAX = this.bus.checkPortInputNotify(this.regEDX & 0xffff, this.regLIP - 1);
|
||||
if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiIO;
|
||||
this.regEAX |= (this.bus.checkPortInputNotify((this.regEDX + 1) & 0xffff, this.regLIP - 1) << 8);
|
||||
if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiIO;
|
||||
|
|
@ -3738,7 +3746,7 @@ X86.opINDXw = function INDXw()
|
|||
X86.opOUTDXb = function OUTDXb()
|
||||
{
|
||||
if (BACKTRACK) this.backTrack.btiIO = this.backTrack.btiAL;
|
||||
this.bus.checkPortOutputNotify(this.regEDX, this.regEAX & 0xff, this.regLIP - 1);
|
||||
this.bus.checkPortOutputNotify(this.regEDX & 0xffff, this.regEAX & 0xff, this.regLIP - 1);
|
||||
this.nStepCycles -= this.cycleCounts.nOpCyclesOutDX;
|
||||
};
|
||||
|
||||
|
|
@ -3750,7 +3758,7 @@ X86.opOUTDXb = function OUTDXb()
|
|||
X86.opOUTDXw = function OUTDXw()
|
||||
{
|
||||
if (BACKTRACK) this.backTrack.btiIO = this.backTrack.btiAL;
|
||||
this.bus.checkPortOutputNotify(this.regEDX, this.regEAX & 0xff, this.regLIP - 1);
|
||||
this.bus.checkPortOutputNotify(this.regEDX & 0xffff, this.regEAX & 0xff, this.regLIP - 1);
|
||||
if (BACKTRACK) this.backTrack.btiIO = this.backTrack.btiAH;
|
||||
this.bus.checkPortOutputNotify((this.regEDX + 1) & 0xffff, this.regEAX >> 8, this.regLIP - 1);
|
||||
this.nStepCycles -= this.cycleCounts.nOpCyclesOutDX;
|
||||
|
|
|
|||
Loading…
Reference in a new issue