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

@ -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