Code: Select all
[bits 32]
global int32, _int32
%define INT32_BASE 0x7C00
%define REBASE(x) (((x) - reloc) + INT32_BASE)
%define GDTENTRY(x) ((x) << 3)
%define CODE32 GDTENTRY(1) ; 0x8
%define DATA32 GDTENTRY(2) ; 0x10
%define CODE16 GDTENTRY(3) ; 0x18
%define DATA16 GDTENTRY(4) ; 0x20
%define STACK16 INT32_BASE - 0x100
section .text
int32: use32
_int32:
cli
mov al, 0x80
out 0x70, al ; disable NMI
mov esi, reloc
mov edi, INT32_BASE
mov ecx, (int32_end - reloc)
cld
rep movsb
jmp INT32_BASE
reloc: use32
mov [REBASE(stack32_ptr)], esp
sidt [REBASE(idt32_ptr)]
mov esp, STACK16
jmp word CODE16:REBASE(p_mode16)
p_mode16: use16
jmp $+2
mov ax, DATA16
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov eax, cr0
and eax, 0x7ffffffe
mov cr0, eax
jmp word 0x0000:REBASE(r_mode16)
r_mode16: use16
jmp $+2
xor ax, ax
mov ds, ax
mov ss, ax
lidt [REBASE(idt16_ptr)]
mov bx, 0x0b71 ; orginal 0x0870
jmp $+2
call resetpic
jmp $+2
mov ax, 0
mov gs, ax
mov fs, ax
mov es, ax
mov ds, ax
mov si, 0x3900 ; DAP
mov al, [0x3950] ; registers
mov ah, [0x3951]
mov bl, [0x3952]
mov bh, [0x3953]
mov cl, [0x3954]
mov ch, [0x3955]
mov dl, [0x3956]
mov dh, [0x3957]
sti
jmp $+2
int 0x13
cli
mov [0x3950], al
mov [0x3951], ah
mov [0x3952], bl
mov [0x3953], bh
mov [0x3954], cl
mov [0x3955], ch
mov [0x3956], dl
mov [0x3957], dh
in al, 0x60
in al, 0x61
out 0x61, al
mov al, 0x20
out 0x20, al ;EOI
out 0xA0, al
call resetpic2
mov eax, cr0
or al,3
mov cr0, eax
jmp dword CODE32:REBASE(p_mode32)
p_mode32: use32
mov ax, DATA32
mov ds, ax
mov es, ax
mov fs, ax
mov ds, ax
mov gs, ax
mov ss, ax
lidt [REBASE(idt32_ptr)]
mov esp, [REBASE(stack32_ptr)]
mov al, 0
out 0x70, al ; enable NMI
sti
ret
resetpic:
mov al, 0x11
out 0x20, al
jmp $+2
out 0xA0, al
jmp $+2
mov al, bh
out 0x21, al
jmp $+2
mov al, bl
out 0xA1, al
jmp $+2
mov al, 0x04
out 0x21, al
jmp $+2
shr al, 1
out 0xA1, al
jmp $+2
shr al, 1
out 0x21, al
jmp $+2
out 0xA1, al
jmp $+2
ret
resetpic2:
mov al, 0x11
out 0x20, al
jmp $+2
out 0xA0, al
jmp $+2
mov al, 0x20
out 0x21, al
jmp $+2
mov al, 0x28
out 0xA1, al
jmp $+2
mov al, 0x04
out 0x21, al
jmp $+2
mov al, 0x02
out 0xA1, al
jmp $+2
mov al, 1
out 0x21, al
jmp $+2
out 0xA1, al
jmp $+2
mov al, 0xf8
out 0x21, al
jmp $+2
mov al, 0xff
out 0xA1, al
jmp $+2
in al, 0x21
jmp $+2
and al, 0xbb
out 0x21, al
jmp $+2
in al, 0xA1
jmp $+2
and al, 0x3f
out 0xA1, al
jmp $+2
ret
stack32_ptr:
dd 0x00000000
idt32_ptr:
dw 0x0000
dd 0x00000000
idt16_ptr:
dw 0x03FF
dd 0x00000000
int32_end:
.
When I don't change PIC it runs in VirtualBox, but hangs on real machines.
It must be interrupt problem - HD works fine (faster), pendrive is slower - needs interrupts.