User:Johnburger/Demo/Exec/PICs

From OSDev Wiki
Jump to navigation Jump to search

Revectoring the hardware Interrupt ReQuests (IRQs) from their legacy position to a more sensible one is something that nearly every x86-based system should do. The code is well understood, and most everyone does it the same way - and often with the same new values of 20h and 28h too!

But this time, with symbols!

You'll note that the last thing this code does is to re-disable interrupts. I really wish that initialising the PICs would have them by default leave all interrupts disabled. Unfortunately, it does the exact opposite. Ah well: I need to enable the Cascade interrupt on the Master anyway...

Demo/Exec/PICs.inc

;
; Exec/PICs.inc
;

; To service hardware Interrupt ReQuests, the PICs need to be changed from their
; arbitrary BIOS-set Real Mode values to more rational settings. Other modules
; can then install IRQ handlers for their particular devices.
;
; To program a PIC, you first give it the Init Cmd, then you program the Mask
; register a few times in a prescribed order. The details change depending on
; whether the PIC is a Master or a Slave.

Exec.PICs:
                MOV             AL,Dev.PIC.Cmd.Init     ; Initialise PICs
                OUT             Dev.PIC.A.Cmd,AL
                OUT             Dev.PIC.B.Cmd,AL

                MOV             AL,PIC.A.Base           ; Set PIC.A's Base
                OUT             Dev.PIC.A.Mask,AL
                MOV             AL,PIC.B.Base           ; Set PIC.B's Base
                OUT             Dev.PIC.B.Mask,AL

                MOV             AL,Dev.PIC.A.Cascade    ; Tell PIC.A where Slave is
                OUT             Dev.PIC.A.Mask,AL

                MOV             AL,Dev.PIC.B.Cascade    ; Tell PIC.B where it is Slave
                OUT             Dev.PIC.B.Mask,AL

                MOV             AL,Dev.PIC.Init.8086    ; 80x86 mode
                OUT             Dev.PIC.A.Mask,AL
                OUT             Dev.PIC.B.Mask,AL

                MOV             AL,~Dev.PIC.A.Cascade   ; Allow Cascade interrupts through
                OUT             Dev.PIC.A.Mask,AL
                MOV             AL,0FFh                 ; Mask all interrupts
                OUT             Dev.PIC.B.Mask,AL

                RET