;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
[org 7c00h]
[bits 16]
%define KADDR 4000h
start:
mov ax, cs
mov ds, ax
mov es, ax
mov gs, ax
mov bx, 9000h ;
mov ss, bx
xor sp, sp
mov [boot_drv], dl
call load_prog ;
call enable_a20 ;
mov si, msg_pmode
call print_cstr
;
lidt [idt_ptr]
lgdt [gdt_ptr]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp super_code_sel:.pmode
[bits 32]
.pmode:
mov ax, super_data_sel
mov ss, ax
mov es, ax
mov ds, ax
mov gs, ax
mov fs, ax
mov esp, 9000h
jmp word KADDR
[bits 16]
msg_pmode db 'Switching to protected mode...',0
;
msg_load_str db 'Loading OSP...',13,10,0
load_prog
mov si, msg_load_str
call print_cstr
.reset:
xor ax, ax
mov dl, [boot_drv]
int 13h
jc .reset
.read:
mov ax, 0
mov es, ax
mov ebx, KADDR
mov ah, 2 ;
mov al, [ksize] ;
mov ch, [kcyl] ;
mov cl, [ksec] ;
mov dh, [khead] ;
mov dl, [boot_drv] ;
int 13h ;
jnc .donerd
push ax ;
mov si, err_msg1
call print_cstr
pop ax
shr ax, 8 ;
add al, 48 ;
call putchar
jmp .read
.donerd
cli ;
ret
;
msg_a20 db 'Enabling A20 line...',0
msg_ok db 'OK',13,10,0
;
;
empty_8042:
push ecx
mov ecx, 100000
.loop:
dec ecx
jz .end_loop
call delay
in al, 64h ;
test al, 1 ;
jz .no_output
call delay
in al, 60h ;
jmp .loop
.no_output:
test al, 2
jnz .loop
.end_loop:
pop ecx
ret
;
;
delay:
out 80h, al
ret
;
;
;
%define A20_TEST_LOOPS 32
a20_tries db 255
enable_a20:
mov si, msg_a20
call print_cstr
.try_loop:
.none:
call a20_test
jnz .done
.bios:
mov ax, 2401h
int 15h
call a20_test
jnz .done
.kbc:
call empty_8042
call a20_test ;
jnz .done
mov al, 0d1h
out 64h, al
call empty_8042
mov al, 0dfh
out 60h, al
call empty_8042
.kbc_wait:
xor cx, cx
.wait_loop:
call a20_test
jnz .done
loop .wait_loop
.fast:
in al, 92h ;
or al, 2 ;
and al, 0feh ;
out 92h, al
.wait_fast:
xor cx, cx
.wait_fast_loop:
call a20_test
jnz .done
loop .wait_fast_loop
;
dec byte [a20_tries]
jnz .try_loop
call panic16
.done:
mov si, msg_ok
call print_cstr
ret
;
;
%define A20_TEST_ADDR 4*80h
a20_test:
push cx
push ax
xor cx, cx
mov fs, cx ;
dec cx
mov gs, cx ;
mov cx, A20_TEST_LOOPS
mov ax, [fs:A20_TEST_ADDR]
push ax
.wait:
inc ax
mov [fs:A20_TEST_ADDR], ax
call delay
cmp ax, [gs:A20_TEST_ADDR+10h]
loope .wait
pop word [fs:A20_TEST_ADDR]
pop ax
pop cx
ret
;
putchar
push bx
mov ah, 0eh
mov bl, 4
int 10h
pop bx
ret
;
print_cstr
mov al, [si]
mov ah, 0eh
mov bl, 4
int 10h
inc si
cmp byte [si], 0
jnz print_cstr
ret
msg_panic_std db 'Aaarrggghhh!',0
panic16
mov si, msg_panic_std
call print_cstr
hlt
;
ksize db 20
kcyl db 0
ksec db 2
khead db 0
boot_drv db 0
;
err_msg1 db 13,10,'read error: ',0
gdt_ptr:
dw gdt_end - gdt - 1
;
dd gdt
idt_ptr:
dw 7ffh
dd 09000h
gdt:
;
times 8 db 0
;
super_code_sel equ $-gdt
dw 0ffffh ;
dw 0000h ;
db 00h ;
db 10011010b ;
db 11001111b ;
db 00h ;
;
super_data_sel equ $-gdt
dw 0ffffh ;
dw 0000h ;
db 00h ;
db 10010010b ;
db 11001111b ;
db 00h ;
;
tss_desc_dummy equ $-gdt
dd 0
dd 0
gdt_end:
times 510-($-$$) db 0
dw 0aa55h