Nasm's version of start32.asm
dufrp@oricom.ca
dufrp@oricom.ca
Thu, 24 Apr 1997 06:59:55 -0400
; Paul Dufresne (dufrp@oricom.ca) note:
; I have translated this code from TASM to NASM.
; Every bug is caused by me, not TRAN. :)
; In fact I just discovered that it crash after writing the registers
; to screen when an error happens. I don't feel like searching the bug,
; so I post to tunes-lll@ens.fr mailing list anyway. Please don't spread
; too much in this bad state.
; to assemble write: nasm -f bin ex0.asm -o ex0.com [lowercase!]
; example0.inc is DIRECTLY included at the end of this file.
; 386 Protected mode control program header.
; By Tran.
; Feel free to use this code in your own programs.
LOWMIN equ 0 ; minimum low memory needed to run (in K)
EXTMIN equ 0 ; minimum extended memory needed to run (in
TSTAK equ 400h ; total stack size (in bytes)
ISTAK equ 80h ; hardware IRQ safe stack size (in bytes)
[ABSOLUTE 0]
lml resw 1
bsl resw 1
bsm resb 1
acc resb 1
lmh resb 1
bsh resb 1
descr_len
[ABSOLUTE 0]
back resd 1
esp0 resd 1
sp0 resd 1 ; should be 10h
esp1 resd 1
sp1 resd 1
esp2 resd 1
sp2 resd 1
ocr3 resd 1
oeip resd 1
oeflags resd 1
oeax resd 1
oecx resd 1
oedx resd 1
oebx resd 1
oesp resd 1
oebp resd 1
oesi resd 1
oedi resd 1
oes resd 1
ocs resd 1
oss resd 1
ods resd 1
ofs resd 1
ogs resd 1
oldtr resd 1
iomap resd 1 ; should be 104 shl 16
task_len
[segment .text]
[org 0x100] ; was 0 in genuine code
[BITS 16]
jmp start16
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
; 16 bit basic system data
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
stak16 times 100h db 0
stak16e
oldint1b dd 0 ; ?
old_cs dw 0 ; ?
nullint db 0cfh ; I think it is iret
errmsg0 db 'You must have a 386 or better to run this program!!
,7,'$'
errmsg1 db 'This system is already in V86 mode!!!',7,'$'
errmsg2 db 'You must have 640k low memory to run this program!!
,7,'$'
errmsg3 db 'Not enough extended memory to run this program!!!',
'$'
errmsg4 db 'You must have VGA to run this program!!!',7,'$'
errmsg5 db 'Not enough low memory to run this program!!!',7,'$'
defidt dw 3ffh, 0,0
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
; 16 bit basic system code
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
chek_VGA: ; Detect VGA or MCGA card
xor bx,bx
mov ax,01a00h
int 10h
cmp bl,7
jb short detectvgano
cmp bl,0ch
ja short detectvgano
ret
detectvgano:
mov dx,errmsg4
jmp exit16err
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
chek_processor: ; Detect if current processor 386
pushf
xor ah,ah
push ax
popf
pushf
pop ax
and ah,0f0h
cmp ah,0f0h
je short detectno386
mov ah,0f0h
push ax
popf
pushf
pop ax
and ah,0f0h
jz short detectno386
popf
ret
detectno386:
mov dx,errmsg0
jmp short exit16err
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
chek_virtual: ; Chek if already running in V86 mod
smsw ax
test al,1
jnz short detected_virtual86
ret
detected_virtual86:
mov dx,errmsg1
jmp short exit16err
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
chek_memory: ; Chek and get info on memory
int 12h
cmp ax,638
jb short notenoughlowmem
movzx eax,ax
shl eax,10
sub eax,[ds:_code32a]
mov [ds:_lomemtop],eax
sub eax,[ds:_lomembase]
shr eax,10
cmp eax,LOWMIN
jb short notenoughlowmem2
mov ah,88h
int 15h
cmp ax,EXTMIN
jb short notenoughhighmem
mov [ds:_totalextmem],ax
movzx eax,ax
shl eax,10
add eax,[ds:_himembase]
mov [ds:_himemtop],eax
ret
notenoughlowmem:
mov dx,errmsg2
jmp short exit16err
notenoughlowmem2:
mov dx,errmsg5
jmp short exit16err
notenoughhighmem:
mov dx,errmsg3
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
exit16err: ; Exit program with message
mov ah,9
int 21h
mov ax,4cffh
int 21h
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
init_vm86_task
mov dword [ds:v86task+sp0],10h
mov eax,104
shl eax,16
mov [ds:v86task+iomap],eax
ret
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
start16: ; Program begins here
cli
mov sp,stak16e
mov ax,cs
mov ds,ax
call chek_VGA
call chek_processor
call chek_virtual
mov ax,cs ; Calc misc memory pointers (was code16)
mov [cs:old_cs],ax
movzx eax,ax
shl eax,4
mov [ds:_code16a],eax
mov ax,cs ; was code32
movzx eax,ax
shl eax,4
mov [ds:_code32a],eax
mov ebx,codeend
shl ebx,4
sub ebx,eax
add [ds:v86task+esp0],ebx
add ebx,TSTAK
mov [ds:_lomembase],ebx
mov ebx,100000h
sub ebx,eax
mov [ds:_himembase],ebx
call chek_memory
xor ax,ax ; Disable CTRL+BREAK
mov es,ax
mov eax,[es:1bh*4]
mov [oldint1b],eax
mov word [es:1bh*4],nullint
mov word [es:1bh*4+2],cs
mov eax,[ds:_code32a] ; Set up protected mode adresses
add dword [ds:gdt32a+2],eax
add dword [ds:idt32a+2],eax
mov [ds:code32dsc+bsl],ax
mov [ds:data32dsc+bsl],ax
add [ds:v86taskdsc+bsl],ax
shr eax,8
mov [ds:code32dsc+bsm],ah
mov [ds:data32dsc+bsm],ah
add [ds:v86taskdsc+bsm],ah
mov eax,[ds:_code16a]
mov [ds:retrealc+bsl],ax
mov [ds:retreald+bsl],ax
shr eax,8
mov [ds:retrealc+bsm],ah
mov [ds:retreald+bsm],ah
call init_vm86_task
lgdt [ds:gdt32a] ; Init protected mode
mov eax,cr0
or al,1
mov cr0,eax
db 0eah
dw start32,8
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
v86sys: ; V86 interrupt
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
xor esi,esi
xor edi,edi
xor ebp,ebp
mov ax,[cs:v86r_ax]
mov bx,[cs:v86r_bx]
mov cx,[cs:v86r_cx]
mov dx,[cs:v86r_dx]
mov si,[cs:v86r_si]
mov di,[cs:v86r_di]
mov bp,[cs:v86r_bp]
db 0cdh
v86sysintnum db 0
mov [cs:v86r_ax],ax
mov [cs:v86r_bx],bx
mov [cs:v86r_cx],cx
mov [cs:v86r_dx],dx
mov [cs:v86r_si],si
mov [cs:v86r_di],di
mov [cs:v86r_bp],bp
mov [cs:v86r_ds],ds
mov [cs:v86r_es],es
pushf
pop ax
mov [cs:v86r_flags],ax
int 0fdh
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
prerealmode: ; 16 bit protected mode to real mode
lidt [defidt]
mov ax,[old_cs]
mov [new_seg],ax
mov eax,cr0
and al,0feh
mov cr0,eax
db 0eah
dw realmode
new_seg dw 0
realmode: ; Back in real mode
xor ax,ax ; Reenable CTRL+BREAK
mov es,ax
mov eax,[cs:oldint1b]
mov [es:1bh*4],eax
mov ax,cs ; Fix up regs and quit to DOS
mov ds,ax
mov es,ax
mov ss,ax
xor eax,eax
mov fs,ax
mov gs,ax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
xor esi,esi
xor edi,edi
xor ebp,ebp
mov esp,stak16e+200h
mov ax,4c00h
int 21h
dw 0,0,0
;===========================================================================
==
;------- org 0
[BITS 32]
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
; 32 bit basic system data
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
v86task times task_len db 0 ; ?
times 2000h db 0
gdt32 db 0x00,0x00, 0x00,0x00, 0x00, 00000000b, 00000000b, 0
code32dsc db 0xff,0xff, 0x00,0x00, 0x00, 10011010b, 11001111b, 0
data32dsc db 0xff,0xff, 0x00,0x00, 0x00, 10010010b, 11001111b, 0
zerodsc db 0xff,0xff, 0x00,0x00, 0x00, 10010010b, 11001111b, 0
v86taskdsc db 0xff,0xff
dw v86task
db 0x00, 10001001b, 0, 0
retrealc db 0xff,0xff, 0x00,0x00, 0x00, 10011010b, 0, 0
retreald db 0xff,0xff, 0x00,0x00, 0x00, 10010010b, 0, 0
idt32 dw exc0, 8, 08e00h, 0
dw exc1, 8, 08e00h, 0
dw exc2, 8, 08e00h, 0
dw exc3, 8, 08e00h, 0
dw exc4, 8, 08e00h, 0
dw exc5, 8, 08e00h, 0
dw exc6, 8, 08e00h, 0
dw exc7, 8, 08e00h, 0
dw exc8, 8, 08e00h, 0
dw exc9, 8, 08e00h, 0
dw exca, 8, 08e00h, 0
dw excb, 8, 08e00h, 0
dw excc, 8, 08e00h, 0
dw v86gen, 8, 08e00h, 0
dw exce, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw unexp, 8, 08e00h, 0
dw irq0, 8, 08e00h, 0
dw irq1, 8, 08e00h, 0
dw irq2, 8, 08e00h, 0
dw irq3, 8, 08e00h, 0
dw irq4, 8, 08e00h, 0
dw irq5, 8, 08e00h, 0
dw irq6, 8, 08e00h, 0
dw irq7, 8, 08e00h, 0
dw irq8, 8, 08e00h, 0
dw irq9, 8, 08e00h, 0
dw irqa, 8, 08e00h, 0
dw irqb, 8, 08e00h, 0
dw irqc, 8, 08e00h, 0
dw irqd, 8, 08e00h, 0
dw irqe, 8, 08e00h, 0
dw irqf, 8, 08e00h, 0
dw callv86sys, 8, 8e00h, 0
gdt32a dw 037h, gdt32,0
idt32a dw 187h, idt32,0
v86irqnum db 0 ; num of IRQ that ocurred in V86 mod
v86r_ax ; Virtual regs for virtual ints
v86r_al db 0
v86r_ah db 0
v86r_bx
v86r_bl db 0
v86r_bh db 0
v86r_cx
v86r_cl db 0
v86r_ch db 0
v86r_dx
v86r_dl db 0
v86r_dh db 0
v86r_si dw 0
v86r_di dw 0
v86r_bp dw 0
v86r_ds dw 0
v86r_es dw 0
v86r_flags dw 0
oirqm21 db 0 ; old low IRQ mask
oirqma1 db 0 ; old high IRQ mask
_totalextmem dw 0 ; total extended memory present
_code16a dd 0 ; offset of start of program from 0
_code32a dd 0 ; offset of start of 32bit code from
_lomembase dd 0 ; low mem base for allocation
_lomemtop dd 0 ; top of low mem
_himembase dd 0 ; high mem base for allocation
_himemtop dd 0 ; top of high mem
_hextbl db '0123456789ABCDEF'
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
; 32 bit basic system code
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
callv86sys: ; V86 INT AL
pushad
push es
push fs
push gs
mov bx,18h
mov es,bx
mov ebx,[_code16a]
mov [es:v86sysintnum+ebx],al
push dword [v86task+esp0]
mov ecx,esp
sub esp,ISTAK
mov [v86task+esp0],esp
xor eax,eax
push eax
push eax
mov ax,[v86r_ds]
push eax
mov ax,[v86r_es]
push eax
mov eax,codeend
push eax
shl eax,4
sub eax,[_code32a]
sub ecx,eax
push ecx
pushfd
pop eax
or eax,20000h
push eax
mov ax, word [cs:old_cs] ; ????????????????????????????????????
movzx eax,ax
push eax
mov eax,v86sys
push eax
iretd
retfromv86:
mov ax,10h
mov ds,ax
mov esp,[v86task+esp0]
add esp,ISTAK
pop dword [v86task+esp0]
pop gs
pop fs
pop es
popad
iretd
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
v86gen: ; General protection violation handl
test byte [esp+14],2
jnz short v86genv86
pushad
mov dl,13
jmp exc
v86genv86:
add esp,4
pushad
mov ax,18h
mov ds,ax
movzx ebx,word [esp+36]
shl ebx,4
add ebx,[esp+32]
inc word [esp+32]
mov al,[ebx]
mov dl,3
cmp al,0cch
je short v86int
cmp al,0ceh
jna .L1
jmp exc
.L1
je short v86genv86ni
inc word [esp+32]
mov dl,[ebx+1]
cmp dl,0fdh
jne short v86int
jmp retfromv86
v86genv86ni:
mov dl,4
v86int: ; Do interrupt for V86 task
mov ax,18h
mov ds,ax
movzx ebx,dl
shl ebx,2
movzx edx,word [esp+48]
shl edx,4
sub word [esp+44],6
add edx,[esp+44]
mov ax,[esp+40]
mov [edx+4],ax
mov ax,[esp+36]
mov [edx+2],ax
mov ax,[esp+32]
mov [edx],ax
and word [esp+40],0fcffh
mov eax,[ds:ebx]
mov [esp+32],ax
shr eax,16
mov [esp+36],ax
popad
iretd
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
exc0: ; Exceptions
push ax
mov al,0
jmp irq
exc1:
push ax
mov al,1
jmp irq
exc2:
push ax
mov al,2
jmp irq
exc3:
push ax
mov al,3
jmp irq
exc4:
push ax
mov al,4
jmp irq
exc5:
push ax
mov al,5
jmp irq
exc6:
pushad
mov dl,6
jmp short exc
exc7:
push ax
mov al,7
jmp irq
exc8:
pushad
mov dl,8
jmp short exc
exc9:
pushad
mov dl,9
jmp short exc
exca:
pushad
mov dl,10
jmp short exc
excb:
pushad
mov dl,11
jmp short exc
excc:
pushad
mov dl,12
jmp short exc
exce:
pushad
mov dl,14
jmp short exc
unexp: ; Unexpected interrupt
pushad
mov dl,0ffh
exc:
cld ; Dump data
mov ax,10h
mov ds,ax
mov es,ax
mov fs,ax
mov ax,18h
mov gs,ax
mov al,0ffh
out 21h,al
out 0a1h,al
mov al,10h
mov word [v86r_ax],3 ; set video mode 3
int 30h
mov edi,0b8000h+2*160
sub edi,[_code32a]
mov ebx,_hextbl
mov ecx,2
shl edx,24
mov ah,0fh ; color
call excput
add edi,152
mov ah,0ah
mov ebp,8
excl0:
pop edx
mov cl,8
call excput
dec ebp
jnz excl0
mov ebp,codeend
shl ebp,4
sub ebp,[_code32a]
add ebp,TSTAK
excf0:
mov ah,0ch
excl1:
pop edx
mov cl,8
call excput
cmp esp,ebp
jbe excf0
jmp _exit
excput:
rol edx,4
mov al,dl
and al,0fh
xlatb
stosw
loop excput
mov al,' '
stosw
stosw
ret
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
irq0: ; Do IRQs
push ax
mov al,8
jmp short irq
irq1:
push ax
mov al,9
jmp short irq
irq2:
push ax
mov al,0ah
jmp short irq
irq3:
push ax
mov al,0bh
jmp short irq
irq4:
push ax
mov al,0ch
jmp short irq
irq5:
push ax
mov al,0dh
jmp short irq
irq6:
push ax
mov al,0eh
jmp short irq
irq7:
push ax
mov al,0fh
jmp short irq
irq8:
push ax
mov al,70h
jmp short irq
irq9:
push ax
mov al,71h
jmp short irq
irqa:
push ax
mov al,72h
jmp short irq
irqb:
push ax
mov al,73h
jmp short irq
irqc:
push ax
mov al,74h
jmp short irq
irqd:
push ax
mov al,75h
jmp short irq
irqe:
push ax
mov al,76h
jmp short irq
irqf:
push ax
mov al,77h
irq:
test byte [esp+12],2
jnz short v86irq
push ds ; A real mode IRQ in protected mode
push ss
pop ds
int 30h
pop ds
pop ax
iretd
v86irq: ; An IRQ from V86 mode
mov [ss:v86irqnum],al
pop ax
pushad
mov dl,[ss:v86irqnum]
jmp v86int
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
set8529vektorz: ; Set new IRQ vektor numbers
mov al,11h ; BL - low vektor base #
out 20h,al ; BH - high vektor base #
jmp short $+2
mov al,bl
out 21h,al
jmp short $+2
mov al,4h
out 21h,al
jmp short $+2
mov al,1h
out 21h,al
jmp short $+2
mov al,11h
out 0a0h,al
jmp short $+2
mov al,bh
out 0a1h,al
jmp short $+2
mov al,2h
out 0a1h,al
jmp short $+2
mov al,1h
out 0a1h,al
ret
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
enableA20: ; Enable gate A20
call enableA20o1
jnz short enableA20done
mov al,0d1h
out 64h,al
call enableA20o1
jnz short enableA20done
mov al,0dfh
out 60h,al
enableA20o1:
mov ecx,20000h
enableA20o1l:
jmp short $+2
in al,64h
test al,2
loopnz enableA20o1l
enableA20done:
ret
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
start32: ; 32bit code begins here
lidt [cs:idt32a]
mov ax,10h
mov ds,ax
mov es,ax
mov fs,ax
mov ss,ax
mov ax,18h
mov gs,ax
mov esp,[_lomembase]
mov ax,20h
ltr ax
pushfd
pop eax
or ah,30h
and ah,10111111b
push eax
popfd
in al,21h
mov [oirqm21],al
or al,3
out 21h,al
in al,0a1h
mov [oirqma1],al
mov bx,2820h
call set8529vektorz
call enableA20
sti ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
jmp _main
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
; Some 'system' services
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
; Exit to real mode
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
_exit:
cli
mov bx,7008h
call set8529vektorz
mov al,[oirqm21]
out 21h,al
mov al,[oirqma1]
out 0a1h,al
mov ax,30h
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
db 0eah
dw prerealmode,0,28h
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
; Get interrupt vektor (0-30h)
; In:
; BL - interrupt number
; Out:
; EAX - 32 bit offset in code
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
_getvect:
push ebx
movzx ebx,bl
mov ax,[idt32+ebx*8+6]
shl eax,16
mov ax,[idt32+ebx*8]
pop ebx
_ret: ; Generic RET for all procedures
ret
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
; Set interrupt vektor (0-30h)
; In:
; BL - interrupt number
; EAX - 32 bit offset in code
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
_setvect:
pushf
cli
push eax
push ebx
movzx ebx,bl
mov [idt32+ebx*8],ax
shr eax,16
mov [idt32+ebx*8+6],ax
pop ebx
pop eax
popf
ret
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
; Allocate any mem, (first cheks low, then high)
; In:
; EAX - size requested
; Out:
; CF=1 - not enough mem
; EAX - ?
; CF=0 - memory allocated
; EAX - linear pointer to mem
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
_getmem:
push eax
call _getlomem
jnc short getmemd
pop eax
jmp short _gethimem
getmemd:
add esp,4
ret
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
; Allocate some low mem
; In:
; EAX - size requested
; Out:
; CF=1 - not enough mem
; EAX - ?
; CF=0 - memory allocated
; EAX - linear pointer to mem
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
_getlomem:
add eax,[_lomembase]
cmp eax,[_lomemtop]
ja short getmemerr
xchg eax,[_lomembase]
clc
ret
getmemerr:
stc
ret
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
; Allocate some high mem
; In:
; EAX - size requested
; Out:
; CF=1 - not enough mem
; EAX - ?
; CF=0 - memory allocated
; EAX - linear pointer to mem
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
_gethimem:
add eax,[_himembase]
cmp eax,[_himemtop]
ja short getmemerr
xchg eax,[_himembase]
clc
ret
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
; Get amount of free low mem
; Out:
; EAX - number of bytes free
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
_lomemsize:
mov eax,[_lomemtop]
sub eax,[_lomembase]
ret
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
; Get amount of free high mem
; Out:
; EAX - number of bytes free
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
_himemsize:
mov eax,[_himemtop]
sub eax,[_himembase]
ret
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
; Put '$' terminated message to DOS
; In:
; EDX -> message in low mem
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
_putdosmsg:
push ax
push edx
add edx,[_code32a]
mov al,dl
and ax,0fh
shr edx,4
mov [v86r_ds],dx
mov [v86r_dx],ax
mov byte [v86r_ah],9
mov al,21h
int 30h
pop edx
pop ax
ret
;===========================================================================
;===========================================================================
;===========================================================================
; Included part
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
; DATA
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
msg0 db 'Free low mem: '
msg0len equ $-msg0
msg1 db 'Free high mem: '
msg1len equ $-msg1
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
; CODE
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
_main:
;db 0x0f,0x50 ; What happens on an invalid opcode?
;@rlp edi,0b8000h ; fill text screen with stuff
mov edi,0b8000h
sub edi,[_code32a]
mov ecx,80*25
mov al,'±'
mov ah,78h
rep stosw
mov ah,0fh ; put amount of free low mem
;@rlp edi,0b8000h+2*160+4
mov edi,0b8000h+2*160+4
sub edi,[_code32a]
mov esi,msg0
mov ecx,msg0len
mainl0:
lodsb
stosw
loop mainl0
call _lomemsize
call putnum
;@rlp edi,0b8000h+3*160+4 ; put amount of free high mem
mov edi,0b8000h+3*160+4
sub edi,[_code32a]
mov esi,msg1
mov ecx,msg1len
mainl1:
lodsb
stosw
loop mainl1
call _himemsize
call putnum
; Uncomment this and the next piece of code if you have a mouse driver loade
; and want to test the handling of real-mode IRQs.
; mov v86r_ax,0 ; Enable and unhide mouse cursor
; mov al,33h
; int 30h
; mov v86r_ax,1
; int 30h
mov byte [v86r_ah],0 ; INT 16h, AH=0, wait for keypress
mov al,16h
int 30h
; mov v86r_ax,0 ; Disable mouse
; mov al,33h
; int 30h
jmp _exit ; return to real mode
;---------------------------------------------------------------------------
putnum: ; put EAX to EDI
mov edx,eax
mov ecx,8
mov ebx,_hextbl
mov ah,0fh
putnuml0:
rol edx,4
mov al,dl
and al,0fh
xlatb
stosw
loop putnuml0
ret
; End of included code
;==========================================================================
; The following should stay at the end of all, (I think)
stak32
codeend
Net-Tamer V 1.08X - Test Drive