So, bootloader loads my code to 1000h:0, then I built GDT and IDT, switch to PM. initialize PIC and try to handle IRQ.
The problem is how to put offset into gate of interrupt in IDT , cause I align PM code on the board of 10000h. egos advised me to place interrupt handles after protected mode entry. He offered to make gates like
Code: Select all
dw handler and 0FFFFh,10h,...,handler shr 16
That's the whole code, that is loaded to 1000:0.
Code: Select all
format binary
xor ax,ax
cli ;reinitialize segment registers
mov ss,ax
xor sp,sp
sti
jmp 1000h:@f
@@:
mov ax,1000h
mov ds,ax ; push cs/pop ds
mov es,ax
cli
mov al,8Fh;disable NMI
out 70h,al
in al,71h
lgdt fword [GDTR]
lidt fword [IDTR]
mov eax,cr0;enable PM
or al,1
mov cr0,eax
jmp fword 08h:Startup32;jump to 32-bit world
align 8 ;align for speed
GDT:
dq 0
db 0FFh,0FFh,0,0,0,9Ah,0CFh,0 ; desc 0,0FFFFFh,DF_CODE32
db 0FFh,0FFh,0,0,0,92h,0CFh,0 ; desc 0,0FFFFFh,DF_DATA32
label GDT_SIZE at $-GDT
GDTR:
dw GDT_SIZE-1
dd GDT+10000h
IDT:
dd 0,0 ; 0
dw int_EOI and 0FFFFh, 08h, 1000111000000000b, 0 shr 16 ; 1
dd 0,0 ; 2
dd 0,0 ; 3
dd 0,0 ; 4
dd 0,0 ; 5
dd 0,0 ; 6
dd 0,0 ; 7
dd 0,0 ; 8
dd 0,0 ; 9
dd 0,0 ; 10
dd 0,0 ; 11
dd 0,0 ; 12
dw GP_handler and 0FFFFh,08h, 1000111000000000b, 0 shr 16 ; 13 #GP
dd 0,0 ; 14
dd 0,0 ; 15
dd 0,0 ; 16
dd 0,0 ; 17
dd 0,0 ; 18
dd 0,0 ; 19
dd 0,0 ; 20
dd 0,0 ; 21
dd 0,0 ; 22
dd 0,0 ; 23
dd 0,0 ; 24
dd 0,0 ; 25
dd 0,0 ; 26
dd 0,0 ; 27
dd 0,0 ; 28
dd 0,0 ; 29
dd 0,0 ; 30
dd 0,0 ; 31
dw timer and 0FFFFh, 08h, 1000111000000000b, 0 shr 16 ; IRQ 0 timer
dw int_EOI and 0FFFFh, 08h, 1000111000000000b, 0 shr 16
label IDT_size at $-IDT
IDTR dw IDT_size-1
dd IDT+10000h
virtual
rb 10000h-$
end virtual
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;PM32 Entry;;;;;;;;;;;;;;;;;;;
use32
org $+10000h
Startup32:
mov ax,10h
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,10000h
Init_PIC:
mov al,11h;ICW1
out 20h,al
out 0A0h,al
mov al,20h;ICW2
out 21h,al
mov al,28h
out 0A1h,al
mov al,04h;ICW3
out 21h,al
mov al,02h
out 0A1h,al
mov al,11h;ICW4
out 21h,al
mov al,01h
out 0A1h,al
xor al,al ;percieve as front signals
mov dx,04D0h
out dx,al
inc dx
out dx,al
mov al,6bh
out 20h,al
out 0A0h,al
mov al,0Fh ;enable interrupts
out 70h,al
in al,71h
sti
mov al,"!"
mov ah,07h
mov word [es:0B8000h],ax
jmp $
;;;;;;;;;;;;;;;;;;;;;;;Interrupt handlers;;;;;;;;;;;;;;;;;;;;;
int_EOI:
push ax
mov al,20h
out 20h,al
out 0a0h,al
pop ax
iretd
timer:
push ax
inc byte [es:0B8000h]
pop ax
jmp int_EOI
GP_handler:
pop eax
xor eax,eax
iretd
;;;;;;;;;;;;;;;;;;;;;;;;;Data;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ascii db 0,0,'1234567890-+',0,0,'QWERTYUIOP[]',0,0,'ASDFGHJKL;',"'`",0,0,'ZXCVBNM,./',0,'*',0,' ',0,0,0,0,0,0,0,0,0,0,0,0,0,'789-456+1230.',0,0
index db 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;