source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Initialization/Interrupts.asm @ 294

Last change on this file since 294 was 294, checked in by krille_n_@…, 12 years ago

Commit 2/2 (BIOS):

  • Fixed a bug in AH1h_HStatus.asm.
  • Minor optimizations.
  • Fixed spelling and did some cleaning.
File size: 6.8 KB
RevLine 
[90]1; Project name  :   XTIDE Universal BIOS
[33]2; Description   :   Functions for initializing the BIOS.
3
4; Section containing code
5SECTION .text
6
7;--------------------------------------------------------------------
8; Interrupts_InitializeInterruptVectors
9;   Parameters:
10;       DS:     RAMVARS segment
11;       ES:     BDA and Interrupt Vector segment (zero)
12;   Returns:
13;       Nothing
14;   Corrupts registers:
15;       All except segments
[86]16;--------------------------------------------------------------------
[33]17Interrupts_InitializeInterruptVectors:
[97]18    ; Fall to .InitializeInt13hAnd40h
[33]19
20;--------------------------------------------------------------------
[97]21; .InitializeInt13hAnd40h
[33]22;   Parameters:
23;       DS:     RAMVARS segment
24;       ES:     BDA and Interrupt Vector segment (zero)
25;   Returns:
26;       Nothing
27;   Corrupts registers:
28;       AX, BX, CX, DX, SI, DI
[86]29;--------------------------------------------------------------------
[97]30.InitializeInt13hAnd40h:
[181]31    mov     ax, [es:BIOS_DISK_INTERRUPT_13h*4+2]; Load old INT 13h segment
32    mov     [RAMVARS.fpOldI13h+2], ax           ; Store old INT 13h segment
33    xchg    dx, ax
[152]34    mov     ax, [es:BIOS_DISK_INTERRUPT_13h*4]  ; Load old INT 13h offset
[33]35    mov     [RAMVARS.fpOldI13h], ax             ; Store old INT 13h offset
[181]36
[33]37    ; Only store INT 13h handler to 40h if 40h is not already installed.
38    ; At least AMI BIOS for 286 stores 40h handler by itself and calls
39    ; 40h from 13h. That system locks to infinite loop if we copy 13h to 40h.
40    call    FloppyDrive_IsInt40hInstalled
[243]41    jc      SHORT .Int40hAlreadyInstalled
[152]42    mov     [es:BIOS_DISKETTE_INTERRUPT_40h*4], ax      ; Store old INT 13h offset
43    mov     [es:BIOS_DISKETTE_INTERRUPT_40h*4+2], dx    ; Store old INT 13h segment
[243]44.Int40hAlreadyInstalled:
[258]45
46    mov     al, BIOS_DISK_INTERRUPT_13h         ; INT 13h interrupt vector offset
47    mov     si, Int13h_DiskFunctionsHandler     ; Interrupt handler offset
48    call    Interrupts_InstallHandlerToVectorInALFromCSSI
[97]49    ; Fall to .InitializeHardwareIrqHandlers
[33]50
51;--------------------------------------------------------------------
[97]52; .InitializeHardwareIrqHandlers
[33]53;   Parameters:
54;       ES:     BDA and Interrupt Vector segment (zero)
55;   Returns:
56;       Nothing
57;   Corrupts registers:
[258]58;       BX, CX, DX, SI, DI, AX
[86]59;--------------------------------------------------------------------
[97]60.InitializeHardwareIrqHandlers:
[33]61    call    RamVars_GetIdeControllerCountToCX
62    mov     di, ROMVARS.ideVars0            ; CS:SI points to first IDEVARS
63.IdeControllerLoop:
[294]64    mov     al, [cs:di+IDEVARS.bIRQ]
[33]65    add     di, BYTE IDEVARS_size           ; Increment to next controller
66    call    .InstallLowOrHighIrqHandler
67    loop    .IdeControllerLoop
[86]68.Return:
69    ret     ; This ret is shared with .InstallLowOrHighIrqHandler
[33]70
71;--------------------------------------------------------------------
72; .InstallLowOrHighIrqHandler
73;   Parameters:
[258]74;       AL:     IRQ number, 0 if IRQ disabled
[33]75;       ES:     BDA and Interrupt Vector segment (zero)
76;   Returns:
77;       Nothing
78;   Corrupts registers:
79;       BX, SI
[86]80;--------------------------------------------------------------------
[33]81.InstallLowOrHighIrqHandler:
[258]82    test    al, al
[86]83    jz      SHORT .Return   ; IRQ not used
[258]84    cmp     al, 8
[86]85    jb      SHORT .InstallLowIrqHandler
[162]86    ; Fall to .InstallHighIrqHandler
[33]87
88;--------------------------------------------------------------------
89; .InstallHighIrqHandler
90;   Parameters:
91;       BX:     IRQ number (8...15)
92;       ES:     BDA and Interrupt Vector segment (zero)
93;   Returns:
94;       Nothing
95;   Corrupts registers:
[258]96;       AL, BX, SI
[86]97;--------------------------------------------------------------------
[97]98.InstallHighIrqHandler:
[258]99    add     al, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8   ; Interrupt vector number
[150]100    mov     si, IdeIrq_InterruptServiceRoutineForIrqs8to15
[258]101    jmp     SHORT Interrupts_InstallHandlerToVectorInALFromCSSI
[33]102
103;--------------------------------------------------------------------
104; .InstallLowIrqHandler
105;   Parameters:
[258]106;       AL:     IRQ number (0...7)
[33]107;       ES:     BDA and Interrupt Vector segment (zero)
108;   Returns:
109;       Nothing
110;   Corrupts registers:
[258]111;       AL, BX, SI
[86]112;--------------------------------------------------------------------
[33]113.InstallLowIrqHandler:
[258]114    add     al, BYTE HARDWARE_IRQ_0_INTERRUPT_08h       ; Interrupt vector number
[150]115    mov     si, IdeIrq_InterruptServiceRoutineForIrqs2to7
[258]116    ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
[33]117
118
119;--------------------------------------------------------------------
[258]120; Interrupts_InstallHandlerToVectorInALFromCSSI
[33]121;   Parameters:
[258]122;       AL:     Interrupt vector number (for example 13h)
[33]123;       ES:     BDA and Interrupt Vector segment (zero)
124;       CS:SI:  Ptr to interrupt handler
125;   Returns:
126;       Nothing
127;   Corrupts registers:
[258]128;       AX, BX
[86]129;--------------------------------------------------------------------
[258]130Interrupts_InstallHandlerToVectorInALFromCSSI:
131    mov     bl, 4                   ; Shift for DWORD offset, MUL smaller than other alternatives
132    mul     bl
133    xchg    ax, bx
[33]134    mov     [es:bx], si             ; Store offset
135    mov     [es:bx+2], cs           ; Store segment
136    ret
137
138
139;--------------------------------------------------------------------
140; Interrupts_UnmaskInterruptControllerForDriveInDSDI
141;   Parameters:
142;       DS:DI:  Ptr to DPT
143;   Returns:
144;       Nothing
145;   Corrupts registers:
146;       AX, BX, DX
147;--------------------------------------------------------------------
148Interrupts_UnmaskInterruptControllerForDriveInDSDI:
[294]149    eMOVZX  bx, [di+DPT.bIdevarsOffset]
[33]150    mov     al, [cs:bx+IDEVARS.bIRQ]
[86]151    test    al, al
152    jz      SHORT .Return   ; Interrupts disabled
[33]153    cmp     al, 8
[86]154    jb      SHORT .UnmaskLowIrqController
[162]155    ; Fall to .UnmaskHighIrqController
[33]156
157;--------------------------------------------------------------------
158; .UnmaskHighIrqController
159;   Parameters:
160;       AL:     IRQ number (8...15)
161;   Returns:
162;       Nothing
163;   Corrupts registers:
164;       AX, DX
165;--------------------------------------------------------------------
[97]166.UnmaskHighIrqController:
[33]167    sub     al, 8               ; Slave interrupt number
[152]168    mov     dx, SLAVE_8259_IMR
[33]169    call    .ClearBitFrom8259MaskRegister
170    mov     al, 2               ; Master IRQ 2 to allow slave IRQs
171    ; Fall to .UnmaskLowIrqController
172
173;--------------------------------------------------------------------
174; .UnmaskLowIrqController
175;   Parameters:
176;       AL:     IRQ number (0...7)
177;   Returns:
178;       Nothing
179;   Corrupts registers:
180;       AX, DX
181;--------------------------------------------------------------------
182.UnmaskLowIrqController:
[152]183    mov     dx, MASTER_8259_IMR
[33]184    ; Fall to .ClearBitFrom8259MaskRegister
185
186;--------------------------------------------------------------------
187; .ClearBitFrom8259MaskRegister
188;   Parameters:
189;       AL:     8259 interrupt index (0...7)
190;       DX:     Port address to Interrupt Mask Register
191;   Returns:
192;       Nothing
193;   Corrupts registers:
194;       AX
195;--------------------------------------------------------------------
196.ClearBitFrom8259MaskRegister:
197    push    cx
198    xchg    ax, cx              ; IRQ index to CL
199    mov     ch, 1               ; Load 1 to be shifted
200    shl     ch, cl              ; Shift bit to correct position
201    not     ch                  ; Invert to create bit mask for clearing
202    in      al, dx              ; Read Interrupt Mask Register
203    and     al, ch              ; Clear wanted bit
204    out     dx, al              ; Write modified Interrupt Mask Register
205    pop     cx
[86]206.Return:
[33]207    ret
Note: See TracBrowser for help on using the repository browser.