I can guarantee that syntax is fine, there are no gcc/nasm/ld errors. I can guarantee that the functions int0-int49 actually do exist. Finally, I can guarantee that the interrupts are enabled. Anyway, here's the code:
Code: Select all
[BITS 32]
[GLOBAL start]
[EXTERN _osmain]
[EXTERN _ASMdebug]
;we are currently @ 1MB physical
start:
???lgdt [gdtr] ???;load new GDT (after bootsector did its thing)
???mov ax,DATASEL???;all registers but CS are set to data
???mov ds,ax
???mov es,ax
???mov ss,ax
???mov fs,ax
???mov gs,ax
???jmp CODESEL:startagain ;cs is set to code through a jump to startagain.
???
startagain:
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;This is a beautiful chunk of code that automatically sets the offsets
;for the interrupts, this is why the the intr calls have to be in order,
;uninterrupted and why they all have to be there (or things get misplaced)
???mov ecx,(idt_end - idt) >> 3 ???;ECX = number of times to loop (number of isr stubs)
???mov edi,idt?????????;EDI = beginning of idt table
???mov esi,isr0?????????;ESI = beginning of isr stubs
do_idt:????????????;LOOP
???mov eax,esi?????????; EAX = address of current isr stub
???mov [edi],ax?????????; 1st entry = low 16bits of EAX (isr address)
???shr eax,16?????????; EAX = EAX's high 16 bits
???mov [edi + 6],ax??????; 4th entry = high 16 bits of EAX (isr address)
???add edi,8?????????; increment to the next idtr entry (8 bytes per entry)
???add esi,(isr1 - isr0)??????; increment to the next isr entry (isr1-isr0 bytes per entry)
???loop do_idt?????????;GOTO LOOP
???
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;Load the IDTR, get into the C main code, if that code returns
;(which it never should) then halt the CPU
???lidt [idt_ptr]
???call _osmain
???hlt
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;This macro defines an interrupt stub.
%macro INTR 1
isr%1:
???push byte 0???
???db 6Ah
???db %1
???push gs?????????; push segment registers
???push fs????????????
???push es????????????
???push ds????????????
???pusha?????????; push GP registers
???mov ax,DATASEL??????; put known-good values...
???mov ds,eax??????; ...in segment registers
???mov es,eax??????
???mov fs,eax??????
???mov gs,eax??????
???call _int%1???
?????????
???popa?????????; pop GP registers
???pop ds?????????; pop segment registers
???pop es
???pop fs
???pop gs
???iret?????????;return to the previous C function, just like everything
????????????;was before the interrupt (iret = interrupt return)
%endmacro????????????
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;This repetition defines all of the C funtions that handle interrupts
%macro IMPORTINT 1
???[EXTERN _int%1]
%endmacro
%assign i 0
%rep (49)???
???IMPORTINT i???
%assign i (i + 1)
%endrep
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;This repetition defines the stubs for 49 interrupts. the idtr is capable
;of holding 256 but the last 207 are undefined.
%assign i 0
%rep (49)???
???INTR i
%assign i (i + 1)
%endrep
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;GDT TABLE information
gdt:
dw 0 ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0 ; type
db 0 ; limit 19:16, flags
db 0 ; base 31:24
dd 0 ;this is the same as above, still just 8 bits of blanks
dd 0
DATASEL equ $-gdt
dw 0FFFFh
dw 0
db 0
db 92h ; present, ring 0, data, expand-up, writable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 0
CODESEL equ $-gdt
dw 0FFFFh
dw 0
db 0
db 9Ah ; present,ring 0,code,non-conforming,readable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 0
gdtend:
gdtr:
dw gdtend - gdt - 1
dd gdt
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;IDT INFORMATION
idt:
%rep 49
dw 0 ;0
dw DATASEL ;2
dw 0x8E00 ;4
dw 0 ;6
%endrep
idt_end:
idt_ptr:
dw idt_end - idt - 1
dd idt