Files
oldlinux-files/study/sabre/os/files/ProtectedMode/voodoo.asm
2024-02-19 00:25:23 -05:00

164 lines
3.4 KiB
NASM

;VooDoo init!
;This will setup the system into a special mode. This code will crash if
; EMM386, Windoze and other PMODE software is loaded. You must also
; enable the a20 thru XMS if himem.sys is loaded.
; once complete the following will happen in real mode.
; - mov ax,[ebx] is legal now
; - code will still have a 64K limit range (IP still used not EIP)
;This is presented to learn from - I really suggest not using this technique
;as it's old and crappy. Gamez to use this : Ultima 7. This was the day
;I hated the PC, but things got better as DPMI and VCPI were introduced
.386p
vd_desc struc
lmt dw 0
bsl dw 0
bsm db 0
typel db 0
typeh db 0
bsh db 0
vd_desc ENDS
.code
cli ;No ints
xor eax,eax
mov ax,cs
mov ds,ax
shl eax,4
mov ds:[oldcs.bsl],ax
mov ds:[oldds.bsl],ax
shr eax,16
mov ds:[oldcs.bsm],al
mov ds:[oldds.bsm],al
mov eax,code32
shl eax,4
add dword ptr ds:gdt32[2],eax
add dword ptr ds:idt32[2],eax
mov ds:[scode32.bsl],ax
mov ds:[sdata32.bsl],ax
shr eax,16
mov ds:[scode32.bsm],al
mov ds:[sdata32.bsm],al
mov ds:[scode32.bsh],ah
mov ds:[sdata32.bsh],ah ;All mem ptr are calculated
lgdt fword ptr ds:gdt32 ;Load the GDT
mov eax,cr0
or al,1
mov cr0,eax ;Hop to Prot. mode
db 0eah
dw main32,8 ;far jmp 08:main
realmode16:
lidt fword ptr ds:defidt ;load the IDT
mov eax,cr0
and al,0feh
mov cr0,eax ;Kill the P-mode bit
db 0eah
dw realmode,Code_start ;Another far jmp
realmode:
mov ebx,10000h ;
mov ax,[ebx] ;Oh my god this shit works !!
;Jmp here to your own code !!! VERY IMPORTANT !
mov ax,4c00h
int 21h
defidt dw 3ffh,0,0 ;The normal IDT
ENDS
code32 segment para public use32
assume cs:code32,ds:code32
main32:
lidt fword ptr cs:idt32 ;The PROT MODE IDT
mov ax,10h
mov ds,ax
mov es,ax
mov fs,ax
mov ss,ax ;Just loading some segs
mov ax,30h
mov gs,ax ;This is the videoseg
xor esp,esp
mov esp,offset stackend ;What could that be ???
call enablea20
; jmp gone ;Testing exc6
exit:
mov ax,20h
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax ;Loading the segs back
db 0eah
dw realmode16,0,18h ;Far jmp 18:realmode16
gone:
db 10 dup(0feh)
idt32 dw 187h,idt,0
gdt32 dw 224,dummy,0
dummy vd_desc <>
scode32 vd_desc <0ffffh,0,0,10011010b,11001111b,0>
sdata32 vd_desc <0ffffh,0,0,10010010b,11001111b,0>
oldcs vd_desc <0ffffh,0,0,10011010b,10000000b,0>
oldds vd_desc <0ffffh,0,0,10010010b,10000000b,0>
bios vd_desc <0ffffh,0,0,10010010b,11001111b,0>
vseg vd_desc <0ffffh,8000h,0bh,10010010b,11001111b,0>
idt dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
dw inter,8,8e00h,0
inter:
jmp exit
enablea20:
call enablea201
jnz short enablea20done
mov al,0d1h
out 64h,al
call enablea201
jnz short enablea20done
mov al,0dfh
out 60h,al
enablea201:
mov ecx,20000h
enablea201l:
jmp short $+2
in al,64h
test al,2
loopnz enablea201l
enablea20done:
ret
pile db 400 dup(?)
stackend:
ENDS
END