Fixed PC-DOS 7.00 CPU detection logic (see SGDT)
This commit is contained in:
parent
3bbbd4e9b1
commit
0173492ef2
12 changed files with 198 additions and 93 deletions
|
|
@ -1346,7 +1346,7 @@ Disk.prototype.save = function()
|
|||
for (var iHead = 0; iHead < aDiskData[iCylinder].length; iHead++) {
|
||||
for (var iSector = 0; iSector < aDiskData[iCylinder][iHead].length; iSector++) {
|
||||
var sector = aDiskData[iCylinder][iHead][iSector];
|
||||
if (sector.cModify) {
|
||||
if (sector && sector.cModify) {
|
||||
var mods = [], n = 0;
|
||||
var iModify = sector.iModify, iModifyLimit = sector.iModify + sector.cModify;
|
||||
while (iModify < iModifyLimit) {
|
||||
|
|
@ -1443,6 +1443,7 @@ Disk.prototype.restore = function(deltas)
|
|||
var mods = mod[m++];
|
||||
var iModifyLimit = iModify + mods.length;
|
||||
var sector = this.aDiskData[iCylinder][iHead][iSector];
|
||||
if (!sector) continue;
|
||||
/*
|
||||
* Since write() now deals with empty/partial sectors, we no longer need to completely "inflate" the sector prior
|
||||
* to applying modifications. So let's just make sure that the sector is "inflated" up to iModify.
|
||||
|
|
|
|||
|
|
@ -812,7 +812,10 @@ X86CPU.prototype.resetRegs = function()
|
|||
* at both 0x0F0000 and 0xFF0000; see the ROM component's "alias" parameter).
|
||||
*/
|
||||
if (this.model >= X86.MODEL_80286) {
|
||||
this.addrGDT = this.addrGDTLimit = 0; // GDTR
|
||||
/*
|
||||
* TODO: Verify what the 80286 actually sets addrGDT and addrGDTLimit to on reset (or if it leaves them alone).
|
||||
*/
|
||||
this.addrGDT = 0; this.addrGDTLimit = 0xFFFF; // GDTR
|
||||
this.segLDT = new X86Seg(this, "LDT", true); // LDTR
|
||||
this.segTSS = new X86Seg(this, "TSS", true); // TR
|
||||
this.segVER = new X86Seg(this, "VER", true); // a scratch segment register for VERR and VERW instructions
|
||||
|
|
|
|||
|
|
@ -210,9 +210,44 @@ var X86Op0F = {
|
|||
if (this.regEA < 0) {
|
||||
X86Help.opInvalid.call(this);
|
||||
} else {
|
||||
this.setWord(this.regEA + 2, this.addrGDT);
|
||||
this.setByte(this.regEA + 4, this.addrGDT >> 16);
|
||||
/*
|
||||
* We don't need to setWord() the first word of the operand, because the ModRM group decoder that calls
|
||||
* us does that automatically with the value we return (dst).
|
||||
*/
|
||||
dst = this.addrGDTLimit - this.addrGDT;
|
||||
this.setWord(this.regEA + 2, this.addrGDT);
|
||||
/*
|
||||
* We previously left the 6th byte of the target operand "undefined". But it turns out we have to set
|
||||
* it to *something*, because there's processor detection in PC-DOS 7.0 (at least in the SETUP portion)
|
||||
* that looks like this:
|
||||
*
|
||||
* 145E:4B84 9C PUSHF
|
||||
* 145E:4B85 55 PUSH BP
|
||||
* 145E:4B86 8BEC MOV BP,SP
|
||||
* 145E:4B88 B80000 MOV AX,0000
|
||||
* 145E:4B8B 50 PUSH AX
|
||||
* 145E:4B8C 9D POPF
|
||||
* 145E:4B8D 9C PUSHF
|
||||
* 145E:4B8E 58 POP AX
|
||||
* 145E:4B8F 2500F0 AND AX,F000
|
||||
* 145E:4B92 3D00F0 CMP AX,F000
|
||||
* 145E:4B95 7511 JNZ 4BA8
|
||||
* 145E:4BA8 C8060000 ENTER 0006,00
|
||||
* 145E:4BAC 0F0146FA SGDT [BP-06]
|
||||
* 145E:4BB0 807EFFFF CMP [BP-01],FF
|
||||
* 145E:4BB4 C9 LEAVE
|
||||
* 145E:4BB5 BA8603 MOV DX,0386
|
||||
* 145E:4BB8 7503 JNZ 4BBD
|
||||
* 145E:4BBA BA8602 MOV DX,0286
|
||||
* 145E:4BBD 89163004 MOV [0430],DX
|
||||
* 145E:4BC1 5D POP BP
|
||||
* 145E:4BC2 9D POPF
|
||||
* 145E:4BC3 CB RETF
|
||||
*
|
||||
* This code is expecting SGDT on an 80286 to set the 6th "undefined" byte to 0xFF. So we use setWord()
|
||||
* instead of setByte() and force the upper byte to 0xFF. TODO: Remove the 0xFF00 on post-80286 processors.
|
||||
*/
|
||||
this.setWord(this.regEA + 4, 0xFF00 | (this.addrGDT >> 16));
|
||||
this.nStepCycles -= 11;
|
||||
}
|
||||
return dst;
|
||||
|
|
@ -227,9 +262,17 @@ var X86Op0F = {
|
|||
if (this.regEA < 0) {
|
||||
X86Help.opInvalid.call(this);
|
||||
} else {
|
||||
this.setWord(this.regEA + 2, this.addrIDT);
|
||||
this.setByte(this.regEA + 4, this.addrIDT >> 16);
|
||||
/*
|
||||
* We don't need to setWord() the first word of the operand, because the ModRM group decoder that calls
|
||||
* us does that automatically with the value we return (dst).
|
||||
*/
|
||||
dst = this.addrIDTLimit - this.addrIDT;
|
||||
this.setWord(this.regEA + 2, this.addrIDT);
|
||||
/*
|
||||
* As with SGDT, the 6th byte is technically "undefined" on an 80286, but given that SGDT now sets it to 0xFF,
|
||||
* we mimic SGDT.
|
||||
*/
|
||||
this.setWord(this.regEA + 4, 0xFF00 | (this.addrIDT >> 16));
|
||||
this.nStepCycles -= 12;
|
||||
}
|
||||
return dst;
|
||||
|
|
|
|||
Loading…
Reference in a new issue