Fixed 32-bit protected-mode test code
This commit is contained in:
parent
f36b79cd25
commit
9ab1f92adc
5 changed files with 115 additions and 81 deletions
|
|
@ -972,7 +972,7 @@
|
|||
<xsl:template match="computer[not(@ref)]">
|
||||
<xsl:param name="machine" select="''"/>
|
||||
<xsl:param name="machineState" select="''"/>
|
||||
<xsl:variable name="buswidth">
|
||||
<xsl:variable name="busWidth">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@buswidth"><xsl:value-of select="@buswidth"/></xsl:when>
|
||||
<xsl:otherwise>20</xsl:otherwise>
|
||||
|
|
@ -994,7 +994,7 @@
|
|||
<xsl:call-template name="component">
|
||||
<xsl:with-param name="machine" select="$machine"/>
|
||||
<xsl:with-param name="class">computer</xsl:with-param>
|
||||
<xsl:with-param name="parms">,buswidth:<xsl:value-of select="$buswidth"/>,resume:<xsl:value-of select="$resume"/>,state:'<xsl:value-of select="$state"/>'</xsl:with-param>
|
||||
<xsl:with-param name="parms">,busWidth:<xsl:value-of select="$busWidth"/>,resume:<xsl:value-of select="$resume"/>,state:'<xsl:value-of select="$state"/>'</xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
|
|
|
|||
|
|
@ -3134,33 +3134,34 @@ if (DEBUGGER) {
|
|||
var sOperand = " ";
|
||||
var typeSize = type & Debugger.TYPE_SIZE;
|
||||
switch (typeSize) {
|
||||
case Debugger.TYPE_BYTE:
|
||||
/*
|
||||
* There's the occasional immediate byte we don't need to display (eg, the 0x0A
|
||||
* following an AAM or AAD instruction), so we suppress the byte if it lacks a TYPE_IN
|
||||
* or TYPE_OUT designation (and TYPE_BOTH, as the name implies, includes both).
|
||||
*/
|
||||
if (type & Debugger.TYPE_BOTH) {
|
||||
sOperand = str.toHex(this.getByte(aAddr, 1), 2);
|
||||
}
|
||||
case Debugger.TYPE_BYTE:
|
||||
/*
|
||||
* There's the occasional immediate byte we don't need to display (eg, the 0x0A
|
||||
* following an AAM or AAD instruction), so we suppress the byte if it lacks a TYPE_IN
|
||||
* or TYPE_OUT designation (and TYPE_BOTH, as the name implies, includes both).
|
||||
*/
|
||||
if (type & Debugger.TYPE_BOTH) {
|
||||
sOperand = str.toHex(this.getByte(aAddr, 1), 2);
|
||||
}
|
||||
break;
|
||||
case Debugger.TYPE_SBYTE:
|
||||
sOperand = str.toHex((this.getByte(aAddr, 1) << 24) >> 24, 4);
|
||||
break;
|
||||
case Debugger.TYPE_WORDV:
|
||||
if (aAddr[4]) {
|
||||
sOperand = str.toHex(this.getLong(aAddr, 4));
|
||||
break;
|
||||
case Debugger.TYPE_SBYTE:
|
||||
sOperand = str.toHex((this.getByte(aAddr, 1) << 24) >> 24, 4);
|
||||
break;
|
||||
case Debugger.TYPE_WORDV:
|
||||
if (aAddr[4]) {
|
||||
sOperand = str.toHex(this.getLong(aAddr, 4));
|
||||
break;
|
||||
}
|
||||
/* falls through */
|
||||
case Debugger.TYPE_WORD:
|
||||
sOperand = str.toHex(this.getShort(aAddr, 2), 4);
|
||||
break;
|
||||
case Debugger.TYPE_FARP:
|
||||
sOperand = this.hexAddr(this.newAddr(this.getWord(aAddr, 2), this.getShort(aAddr, 2), null, aAddr[4], aAddr[5]));
|
||||
break;
|
||||
default:
|
||||
sOperand = "imm(" + str.toHexWord(type) + ")";
|
||||
}
|
||||
/* falls through */
|
||||
case Debugger.TYPE_WORD:
|
||||
sOperand = str.toHex(this.getShort(aAddr, 2), 4);
|
||||
break;
|
||||
case Debugger.TYPE_FARP:
|
||||
sOperand = this.hexAddr(this.newAddr(this.getWord(aAddr, 2), this.getShort(aAddr, 2), null, aAddr[4], aAddr[5]));
|
||||
break;
|
||||
default:
|
||||
sOperand = "imm(" + str.toHexWord(type) + ")";
|
||||
break;
|
||||
}
|
||||
return sOperand;
|
||||
};
|
||||
|
|
@ -3345,36 +3346,36 @@ if (DEBUGGER) {
|
|||
{
|
||||
var b;
|
||||
switch (sFlag) {
|
||||
case "V":
|
||||
b = this.cpu.getOF();
|
||||
break;
|
||||
case "D":
|
||||
b = this.cpu.getDF();
|
||||
break;
|
||||
case "I":
|
||||
b = this.cpu.getIF();
|
||||
break;
|
||||
case "T":
|
||||
b = this.cpu.getTF();
|
||||
break;
|
||||
case "S":
|
||||
b = this.cpu.getSF();
|
||||
break;
|
||||
case "Z":
|
||||
b = this.cpu.getZF();
|
||||
break;
|
||||
case "A":
|
||||
b = this.cpu.getAF();
|
||||
break;
|
||||
case "P":
|
||||
b = this.cpu.getPF();
|
||||
break;
|
||||
case "C":
|
||||
b = this.cpu.getCF();
|
||||
break;
|
||||
default:
|
||||
b = 0;
|
||||
break;
|
||||
case "V":
|
||||
b = this.cpu.getOF();
|
||||
break;
|
||||
case "D":
|
||||
b = this.cpu.getDF();
|
||||
break;
|
||||
case "I":
|
||||
b = this.cpu.getIF();
|
||||
break;
|
||||
case "T":
|
||||
b = this.cpu.getTF();
|
||||
break;
|
||||
case "S":
|
||||
b = this.cpu.getSF();
|
||||
break;
|
||||
case "Z":
|
||||
b = this.cpu.getZF();
|
||||
break;
|
||||
case "A":
|
||||
b = this.cpu.getAF();
|
||||
break;
|
||||
case "P":
|
||||
b = this.cpu.getPF();
|
||||
break;
|
||||
case "C":
|
||||
b = this.cpu.getCF();
|
||||
break;
|
||||
default:
|
||||
b = 0;
|
||||
break;
|
||||
}
|
||||
return sFlag + (b? '1' : '0') + ' ';
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1592,6 +1592,7 @@ X86CPU.prototype.setProtMode = function(fProt)
|
|||
if (I386 && this.model >= X86.MODEL_80386) {
|
||||
this.segFS.updateMode(fProt);
|
||||
this.segGS.updateMode(fProt);
|
||||
this.resetSizes();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -925,7 +925,18 @@ X86Seg.prototype.updateMode = function(fProt)
|
|||
this.loadIDT = this.loadIDTReal;
|
||||
this.checkRead = this.checkReadReal;
|
||||
this.checkWrite = this.checkWriteReal;
|
||||
this.limit = 0xffff;
|
||||
/*
|
||||
* Like the base, we don't want to mess with the limit, so that features like "Unreal" mode
|
||||
* (or "Big Real" mode as it's called in the HIMEM source code) will work, at least until the
|
||||
* next explicit segment load.
|
||||
*
|
||||
* See http://www.os2museum.com/wp/himem-sys-unreal-mode-and-loadall/ for more details.
|
||||
*
|
||||
* this.limit = 0xffff;
|
||||
*
|
||||
* TODO: The checkReadReal() and checkWriteReal() functions need to generate GP faults for offsets
|
||||
* beyond the current real-mode limit.
|
||||
*/
|
||||
this.acc = this.ext = 0;
|
||||
this.cpl = this.dpl = 0;
|
||||
this.addrDesc = X86.ADDR_INVALID;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ ACC_TYPE_WRITABLE equ 0x0200
|
|||
ACC_TYPE_CODE_READABLE equ (0x1a00 | ACC_PRESENT)
|
||||
ACC_TYPE_DATA_WRITABLE equ (0x1200 | ACC_PRESENT)
|
||||
|
||||
EXT_NONE equ 0x0000
|
||||
EXT_BIG equ 0x0040
|
||||
|
||||
;
|
||||
|
|
@ -33,7 +34,7 @@ EXT_BIG equ 0x0040
|
|||
; 0x0d08-0x0d0f GDTR
|
||||
; 0x0d10-0x0fff reserved
|
||||
;
|
||||
; And in the second page (0x1000-0x1fff), let's build a page directory, followed by a single page table that
|
||||
; And in the second page (0x1000-0x1fff), we build a page directory, followed by a single page table that
|
||||
; will allow us to map up to 4Mb (although we'll only create entries for the first 1Mb).
|
||||
;
|
||||
RAM_GDT equ 0x0c00
|
||||
|
|
@ -50,8 +51,12 @@ CR0_MSW_PE equ 0x0001
|
|||
; set initializes a register to the specified value (eg, "set eax,0")
|
||||
;
|
||||
%macro set 2
|
||||
%if %2 = 0
|
||||
sub %1,%1
|
||||
%ifnum %2
|
||||
%if %2 = 0
|
||||
xor %1,%1
|
||||
%else
|
||||
mov %1,%2
|
||||
%endif
|
||||
%else
|
||||
mov %1,%2
|
||||
%endif
|
||||
|
|
@ -60,7 +65,7 @@ CR0_MSW_PE equ 0x0001
|
|||
;
|
||||
; defDesc defines a descriptor, given a base (%1), limit (%2), type (%3), dpl (%4), and ext (%5)
|
||||
;
|
||||
%macro defDesc 1-4 0,0,0,0
|
||||
%macro defDesc 1-5 0,0,0,0,0
|
||||
dw (%2 & 0x0000ffff)
|
||||
dw (%1 & 0x0000ffff)
|
||||
dw ((%1 & 0x00ff0000) >> 16) | %3 | (%4 << 13)
|
||||
|
|
@ -68,15 +73,16 @@ CR0_MSW_PE equ 0x0001
|
|||
%endmacro
|
||||
|
||||
;
|
||||
; setDesc creates a descriptor, given a base (%1), limit (%2), type (%3), dpl (%4), and ext (%5)
|
||||
; setDesc creates a descriptor, given a base (%1), limit (%2), type (%3), ext (%4), and selector (%5)
|
||||
;
|
||||
%assign selDesc 0
|
||||
%macro setDesc 1-4 0,0,0,none
|
||||
%macro setDesc 1-5 0,0,0,0,none
|
||||
set ebx,%1
|
||||
set ecx,%2
|
||||
set edx,%3
|
||||
set dx,%3
|
||||
set ax,%4
|
||||
call storeDesc
|
||||
%assign %4 selDesc
|
||||
%assign %5 selDesc
|
||||
%assign selDesc selDesc+8
|
||||
%endmacro
|
||||
|
||||
|
|
@ -99,11 +105,13 @@ start: cli ; disable all interrupts
|
|||
cmp eax,ebx
|
||||
je near initRAM ; apparently we have to tell NASM "near" because this is a forward reference
|
||||
times 32768 nop ; lots of NOPs to force a 16-bit conditional jump
|
||||
|
||||
;
|
||||
; storeDesc(EBX=base, ECX=limit, EDX=type, EDI=target)
|
||||
; storeDesc(EBX=base, ECX=limit, DX=type, AX=ext, DI=address of descriptor)
|
||||
;
|
||||
storeDesc:
|
||||
cld
|
||||
push ax
|
||||
mov ax,cx
|
||||
stosw ; store the low 16 bits of limit from ECX
|
||||
mov ax,bx
|
||||
|
|
@ -112,13 +120,17 @@ storeDesc:
|
|||
shr ebx,16
|
||||
mov al,bl
|
||||
stosw
|
||||
pop ax
|
||||
shr ecx,16
|
||||
mov al,cl
|
||||
and al,0xf
|
||||
and cl,0xf
|
||||
or al,cl
|
||||
mov ah,bh
|
||||
stosw
|
||||
ret
|
||||
|
||||
;
|
||||
; The following ROM-based data structures are obsolete, because we build these data structures in RAM now.
|
||||
;
|
||||
addrGDT:dw romGDTEnd - romGDT - 1 ; 16-bit limit of romGDT
|
||||
dw romGDT, 0xffff ; 32-bit base address of romGDT (works as long as we're aliased at 0xffff0000)
|
||||
|
||||
|
|
@ -126,13 +138,18 @@ romGDT: defDesc 0 ; the first descriptor in any descriptor table is always a d
|
|||
defDesc 0x000f0000,0x0000ffff,ACC_TYPE_CODE_READABLE
|
||||
defDesc 0x00000000,0x000fffff,ACC_TYPE_DATA_WRITABLE
|
||||
romGDTEnd:
|
||||
;
|
||||
; End of ROM-based data structures
|
||||
;
|
||||
|
||||
initRAM:
|
||||
set edi,RAM_GDT
|
||||
mov [RAM_GDTR+2],edi
|
||||
setDesc 0,0,0,NULL
|
||||
setDesc 0x000f0000,0x0000ffff,ACC_TYPE_CODE_READABLE,CSEG_PROT
|
||||
setDesc 0x00000000,0x000fffff,ACC_TYPE_DATA_WRITABLE,DSEG_PROT
|
||||
setDesc 0,0,0,0,NULL
|
||||
mov eax,cs
|
||||
shl eax,4
|
||||
setDesc eax,0x0000ffff,ACC_TYPE_CODE_READABLE,EXT_BIG,CSEG_PROT
|
||||
setDesc 0x0,0x000fffff,ACC_TYPE_DATA_WRITABLE,EXT_BIG,DSEG_PROT
|
||||
sub edi,RAM_GDT
|
||||
dec edi
|
||||
mov [RAM_GDTR],di
|
||||
|
|
@ -141,20 +158,25 @@ goProt: o32 lgdt [RAM_GDTR]
|
|||
mov eax,cr0
|
||||
or eax,CR0_MSW_PE
|
||||
mov cr0,eax
|
||||
jmp dword CSEG_PROT:inProt
|
||||
|
||||
inProt: mov ax,DSEG_PROT
|
||||
jmp CSEG_PROT:inProt
|
||||
inProt:
|
||||
bits 32
|
||||
mov ax,DSEG_PROT
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov ss,ax
|
||||
|
||||
;
|
||||
; Do some protected-mode tests...
|
||||
; Do some protected-mode tests now...
|
||||
;
|
||||
|
||||
goReal: mov eax,cr0
|
||||
and eax,~CR0_MSW_PE
|
||||
mov cr0,eax
|
||||
jmp dword CSEG_REAL:inReal
|
||||
|
||||
inReal: or eax,1
|
||||
bits 16
|
||||
jmp CSEG_REAL:inReal
|
||||
inReal:
|
||||
or ax,1
|
||||
jnz start ; apparently we do NOT have to say "near" here since this is a backward reference
|
||||
|
||||
;
|
||||
|
|
@ -163,7 +185,6 @@ inReal: or eax,1
|
|||
;
|
||||
times 0xfff0-0x100-($-$$) nop
|
||||
|
||||
bits 16
|
||||
jmp CSEG_REAL:start
|
||||
|
||||
db 0x20
|
||||
|
|
|
|||
Loading…
Reference in a new issue