Fixed 32-bit protected-mode test code

This commit is contained in:
Jeff Parsons 2015-05-05 18:26:19 -07:00 committed by jeffpar
commit 9ab1f92adc
5 changed files with 115 additions and 81 deletions

View file

@ -972,7 +972,7 @@
<xsl:template match="computer[not(@ref)]"> <xsl:template match="computer[not(@ref)]">
<xsl:param name="machine" select="''"/> <xsl:param name="machine" select="''"/>
<xsl:param name="machineState" select="''"/> <xsl:param name="machineState" select="''"/>
<xsl:variable name="buswidth"> <xsl:variable name="busWidth">
<xsl:choose> <xsl:choose>
<xsl:when test="@buswidth"><xsl:value-of select="@buswidth"/></xsl:when> <xsl:when test="@buswidth"><xsl:value-of select="@buswidth"/></xsl:when>
<xsl:otherwise>20</xsl:otherwise> <xsl:otherwise>20</xsl:otherwise>
@ -994,7 +994,7 @@
<xsl:call-template name="component"> <xsl:call-template name="component">
<xsl:with-param name="machine" select="$machine"/> <xsl:with-param name="machine" select="$machine"/>
<xsl:with-param name="class">computer</xsl:with-param> <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:call-template>
</xsl:template> </xsl:template>

View file

@ -3134,33 +3134,34 @@ if (DEBUGGER) {
var sOperand = " "; var sOperand = " ";
var typeSize = type & Debugger.TYPE_SIZE; var typeSize = type & Debugger.TYPE_SIZE;
switch (typeSize) { switch (typeSize) {
case Debugger.TYPE_BYTE: case Debugger.TYPE_BYTE:
/* /*
* There's the occasional immediate byte we don't need to display (eg, the 0x0A * 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 * 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). * or TYPE_OUT designation (and TYPE_BOTH, as the name implies, includes both).
*/ */
if (type & Debugger.TYPE_BOTH) { if (type & Debugger.TYPE_BOTH) {
sOperand = str.toHex(this.getByte(aAddr, 1), 2); 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; break;
case Debugger.TYPE_SBYTE: }
sOperand = str.toHex((this.getByte(aAddr, 1) << 24) >> 24, 4); /* falls through */
break; case Debugger.TYPE_WORD:
case Debugger.TYPE_WORDV: sOperand = str.toHex(this.getShort(aAddr, 2), 4);
if (aAddr[4]) { break;
sOperand = str.toHex(this.getLong(aAddr, 4)); case Debugger.TYPE_FARP:
break; sOperand = this.hexAddr(this.newAddr(this.getWord(aAddr, 2), this.getShort(aAddr, 2), null, aAddr[4], aAddr[5]));
} break;
/* falls through */ default:
case Debugger.TYPE_WORD: sOperand = "imm(" + str.toHexWord(type) + ")";
sOperand = str.toHex(this.getShort(aAddr, 2), 4); break;
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) + ")";
} }
return sOperand; return sOperand;
}; };
@ -3345,36 +3346,36 @@ if (DEBUGGER) {
{ {
var b; var b;
switch (sFlag) { switch (sFlag) {
case "V": case "V":
b = this.cpu.getOF(); b = this.cpu.getOF();
break; break;
case "D": case "D":
b = this.cpu.getDF(); b = this.cpu.getDF();
break; break;
case "I": case "I":
b = this.cpu.getIF(); b = this.cpu.getIF();
break; break;
case "T": case "T":
b = this.cpu.getTF(); b = this.cpu.getTF();
break; break;
case "S": case "S":
b = this.cpu.getSF(); b = this.cpu.getSF();
break; break;
case "Z": case "Z":
b = this.cpu.getZF(); b = this.cpu.getZF();
break; break;
case "A": case "A":
b = this.cpu.getAF(); b = this.cpu.getAF();
break; break;
case "P": case "P":
b = this.cpu.getPF(); b = this.cpu.getPF();
break; break;
case "C": case "C":
b = this.cpu.getCF(); b = this.cpu.getCF();
break; break;
default: default:
b = 0; b = 0;
break; break;
} }
return sFlag + (b? '1' : '0') + ' '; return sFlag + (b? '1' : '0') + ' ';
}; };

View file

@ -1592,6 +1592,7 @@ X86CPU.prototype.setProtMode = function(fProt)
if (I386 && this.model >= X86.MODEL_80386) { if (I386 && this.model >= X86.MODEL_80386) {
this.segFS.updateMode(fProt); this.segFS.updateMode(fProt);
this.segGS.updateMode(fProt); this.segGS.updateMode(fProt);
this.resetSizes();
} }
}; };

View file

@ -925,7 +925,18 @@ X86Seg.prototype.updateMode = function(fProt)
this.loadIDT = this.loadIDTReal; this.loadIDT = this.loadIDTReal;
this.checkRead = this.checkReadReal; this.checkRead = this.checkReadReal;
this.checkWrite = this.checkWriteReal; 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.acc = this.ext = 0;
this.cpl = this.dpl = 0; this.cpl = this.dpl = 0;
this.addrDesc = X86.ADDR_INVALID; this.addrDesc = X86.ADDR_INVALID;

View file

@ -21,6 +21,7 @@ ACC_TYPE_WRITABLE equ 0x0200
ACC_TYPE_CODE_READABLE equ (0x1a00 | ACC_PRESENT) ACC_TYPE_CODE_READABLE equ (0x1a00 | ACC_PRESENT)
ACC_TYPE_DATA_WRITABLE equ (0x1200 | ACC_PRESENT) ACC_TYPE_DATA_WRITABLE equ (0x1200 | ACC_PRESENT)
EXT_NONE equ 0x0000
EXT_BIG equ 0x0040 EXT_BIG equ 0x0040
; ;
@ -33,7 +34,7 @@ EXT_BIG equ 0x0040
; 0x0d08-0x0d0f GDTR ; 0x0d08-0x0d0f GDTR
; 0x0d10-0x0fff reserved ; 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). ; will allow us to map up to 4Mb (although we'll only create entries for the first 1Mb).
; ;
RAM_GDT equ 0x0c00 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") ; set initializes a register to the specified value (eg, "set eax,0")
; ;
%macro set 2 %macro set 2
%if %2 = 0 %ifnum %2
sub %1,%1 %if %2 = 0
xor %1,%1
%else
mov %1,%2
%endif
%else %else
mov %1,%2 mov %1,%2
%endif %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) ; 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 (%2 & 0x0000ffff)
dw (%1 & 0x0000ffff) dw (%1 & 0x0000ffff)
dw ((%1 & 0x00ff0000) >> 16) | %3 | (%4 << 13) dw ((%1 & 0x00ff0000) >> 16) | %3 | (%4 << 13)
@ -68,15 +73,16 @@ CR0_MSW_PE equ 0x0001
%endmacro %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 %assign selDesc 0
%macro setDesc 1-4 0,0,0,none %macro setDesc 1-5 0,0,0,0,none
set ebx,%1 set ebx,%1
set ecx,%2 set ecx,%2
set edx,%3 set dx,%3
set ax,%4
call storeDesc call storeDesc
%assign %4 selDesc %assign %5 selDesc
%assign selDesc selDesc+8 %assign selDesc selDesc+8
%endmacro %endmacro
@ -99,11 +105,13 @@ start: cli ; disable all interrupts
cmp eax,ebx cmp eax,ebx
je near initRAM ; apparently we have to tell NASM "near" because this is a forward reference 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 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: storeDesc:
cld cld
push ax
mov ax,cx mov ax,cx
stosw ; store the low 16 bits of limit from ECX stosw ; store the low 16 bits of limit from ECX
mov ax,bx mov ax,bx
@ -112,13 +120,17 @@ storeDesc:
shr ebx,16 shr ebx,16
mov al,bl mov al,bl
stosw stosw
pop ax
shr ecx,16 shr ecx,16
mov al,cl and cl,0xf
and al,0xf or al,cl
mov ah,bh mov ah,bh
stosw stosw
ret 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 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) 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 0x000f0000,0x0000ffff,ACC_TYPE_CODE_READABLE
defDesc 0x00000000,0x000fffff,ACC_TYPE_DATA_WRITABLE defDesc 0x00000000,0x000fffff,ACC_TYPE_DATA_WRITABLE
romGDTEnd: romGDTEnd:
;
; End of ROM-based data structures
;
initRAM: initRAM:
set edi,RAM_GDT set edi,RAM_GDT
mov [RAM_GDTR+2],edi mov [RAM_GDTR+2],edi
setDesc 0,0,0,NULL setDesc 0,0,0,0,NULL
setDesc 0x000f0000,0x0000ffff,ACC_TYPE_CODE_READABLE,CSEG_PROT mov eax,cs
setDesc 0x00000000,0x000fffff,ACC_TYPE_DATA_WRITABLE,DSEG_PROT 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 sub edi,RAM_GDT
dec edi dec edi
mov [RAM_GDTR],di mov [RAM_GDTR],di
@ -141,20 +158,25 @@ goProt: o32 lgdt [RAM_GDTR]
mov eax,cr0 mov eax,cr0
or eax,CR0_MSW_PE or eax,CR0_MSW_PE
mov cr0,eax mov cr0,eax
jmp dword CSEG_PROT:inProt jmp CSEG_PROT:inProt
inProt:
inProt: mov ax,DSEG_PROT bits 32
mov ax,DSEG_PROT
mov ds,ax mov ds,ax
mov es,ax
mov ss,ax
; ;
; Do some protected-mode tests... ; Do some protected-mode tests now...
; ;
goReal: mov eax,cr0 goReal: mov eax,cr0
and eax,~CR0_MSW_PE and eax,~CR0_MSW_PE
mov cr0,eax mov cr0,eax
jmp dword CSEG_REAL:inReal bits 16
jmp CSEG_REAL:inReal
inReal: or eax,1 inReal:
or ax,1
jnz start ; apparently we do NOT have to say "near" here since this is a backward reference 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 times 0xfff0-0x100-($-$$) nop
bits 16
jmp CSEG_REAL:start jmp CSEG_REAL:start
db 0x20 db 0x20