rdos/kernel/intr.asm

102 lines
1.9 KiB
NASM

; Data table for interrupts
; cs:word for service routine
intr_table:
dw iret ; 0 Divide by Zero
dw iret ; 1 Single Step
dw iret ; 2 Parity error routine (NMI)
dw debug_reg_ir ; 3 Break
dw iret ; 4 Overflow
dw iret ; 5 Print Screen
dw iret ; 6 Mouse button control
dw iret ; 7 Reserved
dw irq0 ; 8 System Clock interrupt
dw irq1 ; 9 Keyboard interrupt
dw irq2 ; 10 RTC interrupt
dw irq3 ; 11 COMMS
dw irq4 ; 12 COMMS
dw irq5 ; 13 Hard Disk
dw irq6 ; 14 Floppy Disk interrupt routine
dw irq7 ; 15 Printer interrupt
; LSB is IRQ0, MSB is IRQ16
; A IRQ will set their bit to 1, so userspace may poll it via wait_irq
intr_flip:
dw 0
intr_init:
push ds
push es
; backup intr 0x0n to 0x4n
xor ax, ax
mov ds, ax ; read from IVT
mov es, ax ; write to IVT
mov si, ax ; read from start of IVT table
mov di, 0x0100 ; write to offset of int 0x40 address
mov cx, 0x0020 ; 0x10 vectors, segment:offset each
repe movsw
; now setup our own handlers
mov ax, cs
mov ds, ax ; read from local segment
mov si, intr_table ; read from intr_table
mov di, 0x0000 ; write to start of IVT table
mov cx, 0x0010 ; 0x10 vectors, one offset each
.loop:
movsw ; read offset, write offset
mov ax,cs
stosw ; write segment
loop .loop
pop es
pop ds
ret
irq0:
int 0x48
or byte [intr_flip], 0x01
jmp irqret
irq1:
int 0x49
or byte [intr_flip], 0x02
push ax
mov ax, [intr_flip]
call kprint8
mov word [intr_flip], 0x0000
pop ax
jmp irqret
irq2:
int 0x4A
or byte [intr_flip], 0x04
jmp irqret
irq3:
int 0x4B
or byte [intr_flip], 0x08
jmp irqret
irq4:
int 0x4C
or byte [intr_flip], 0x10
jmp irqret
irq5:
int 0x4D
or byte [intr_flip], 0x20
jmp irqret
irq6:
int 0x4E
or byte [intr_flip], 0x40
jmp irqret
irq7:
int 0x4F
or byte [intr_flip], 0x80
jmp irqret
hwiret:
mov al,20h
out 20h,al
irqret:
iret:
iret