Switch to PMode not working
Posted: Sat Sep 18, 2004 9:15 am
When I try this on my test computer it just hangs. I'm in the process of getting Bochs running so I can get some debug info.
Code: Select all
ORG 00000h
BITS 16
main:
mov ax, 07C00h
mov ds, ax
mov ax, 08000h
mov ss, ax
mov ax, 09000h
mov sp, ax
; Enable the A20 line.
call .enable_a20
; Reprogram the PIC.
; call .reprogPIC
; Re-enable the keyboard (if it's off)
mov al, 0AEh
mov dx, 064h
out dx, al
cli
lgdt [gdt_main]
lidt [idt_main]
mov eax, 000000011h
mov cr0, eax
jmp dword 008h:main32
; Candy's A20 Code:
.a20_tries db 00FFh
.empty_8042:
push cx
mov cx, 65535
.empty_8042_loop:
dec cx
jz .empty_8042_end_loop
mov dx, 064h
in al, dx
test al, 01h
jz .no_output
mov dx, 064h
in al, dx
jmp .empty_8042_loop
.no_output:
test al, 02h
jnz .empty_8042_loop
.empty_8042_end_loop:
pop cx
ret
.enable_a20:
.a20_none:
call .a20_test
jnz .a20_done
.a20_bios:
mov ax, 02401h
pushf
int 015h
popf
call .a20_test
jnz .a20_done
.a20_kbc:
call .empty_8042
call .a20_test
jnz .a20_done
mov al, 0D1h
mov dx, 064h
out dx, al
call .empty_8042
mov al, 0DFh
mov dx, 060h
out dx, al
call .empty_8042
mov dx, 092h
in al, dx
or al, 02h
and al, 0FEh
out dx, al
.a20_wait:
xor cx, cx
.a20_wait_loop:
call .a20_test
jnz .a20_done
loop .a20_wait_loop
mov bx, .a20_tries
dec byte [bx]
jnz .enable_a20
mov si, .a20_not_working
; call print_message_16
.crash:
hlt
jmp .crash
.crash:
hlt
jmp .crash
.a20_done:
ret
.a20_not_working db "Unable to enable A20 gate, booting failed."
.a20_test:
push cx
push ax
xor cx, cx
mov fs, cx
dec cx
mov gs, cx
mov cx, 020h
mov ax, [fs:600h]
push ax
.a20_test_wait:
inc ax
mov [fs:600h], ax
wbinvd
cmp ax, [gs:610h]
je .a20_test_wait
pop ax
mov [fs:600h], ax
pop ax
pop cx
ret
loc dw 0
gdt
; Null descriptor.
dw 00000h
; Here we cheat a bit, using a portion of our null descriptor as the GDT
; data loaded into GDTR, saving some bytes.
gdt_main
dw 007FFh
dw 01800h
; CPL0 code segment.
dw 0FFFFh
dw 00000h
dw 09A00h
dw 000CFh
; CPL0 data/stack segment.
dw 0FFFFh
dw 00000h
dw 09200h
dw 000CFh
; Alignement
dw 00000h
idt_main
dw 007FFh
dw 01000h
BITS 32
main32:
; Reload segment registers with our CPL0 data/stack segment.
mov ax, 010h
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov eax, 0B8000h
mov [eax], byte 'X'
mov [eax + 1], byte 007h
jmp $
times 512 - ($ - $$) - 2 db 0
dw 0AA55h