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

Last change on this file since 33 was 33, checked in by aitotat, 14 years ago

Interrupt controllers are now unmasked during drive reset.

File size: 8.5 KB
Line 
1; File name     :   Interrupts.asm
2; Project name  :   IDE BIOS
3; Created date  :   23.8.2010
4; Last update   :   23.8.2010
5; Author        :   Tomi Tilli
6; Description   :   Functions for initializing the BIOS.
7
8; Section containing code
9SECTION .text
10
11;--------------------------------------------------------------------
12; Interrupts_InitializeInterruptVectors
13;   Parameters:
14;       DS:     RAMVARS segment
15;       ES:     BDA and Interrupt Vector segment (zero)
16;   Returns:
17;       Nothing
18;   Corrupts registers:
19;       All except segments
20;--------------------------------------------------------------------   
21ALIGN JUMP_ALIGN
22Interrupts_InitializeInterruptVectors:
23    call    Interrupts_InitializeInt13hAnd40h
24    call    Interrupts_InitializeInt19h
25    jmp     SHORT Interrupts_InitializeHardwareIrqHandlers
26
27
28;--------------------------------------------------------------------
29; Interrupts_Int13hAnd40h
30;   Parameters:
31;       DS:     RAMVARS segment
32;       ES:     BDA and Interrupt Vector segment (zero)
33;   Returns:
34;       Nothing
35;   Corrupts registers:
36;       AX, BX, CX, DX, SI, DI
37;--------------------------------------------------------------------   
38ALIGN JUMP_ALIGN
39Interrupts_InitializeInt13hAnd40h:
40    mov     ax, [es:INTV_DISK_FUNC*4]           ; Load old INT 13h offset
41    mov     dx, [es:INTV_DISK_FUNC*4+2]         ; Load old INT 13h segment
42    mov     [RAMVARS.fpOldI13h], ax             ; Store old INT 13h offset
43    mov     [RAMVARS.fpOldI13h+2], dx           ; Store old INT 13h segment
44    mov     bx, INTV_DISK_FUNC                  ; INT 13h interrupt vector offset
45    mov     si, Int13h_DiskFunctions            ; Interrupt handler offset
46    call    Interrupts_InstallHandlerToVectorInBXFromCSSI
47
48    ; Only store INT 13h handler to 40h if 40h is not already installed.
49    ; At least AMI BIOS for 286 stores 40h handler by itself and calls
50    ; 40h from 13h. That system locks to infinite loop if we copy 13h to 40h.
51    call    FloppyDrive_IsInt40hInstalled
52    jnc     SHORT .InitializeInt40h
53    ret
54
55;--------------------------------------------------------------------
56; .InitializeInt40h
57;   Parameters:
58;       DX:AX:  Ptr to old INT 13h handler
59;       ES:     BDA and Interrupt Vector segment (zero)
60;   Returns:
61;       Nothing
62;   Corrupts registers:
63;       Nothing
64;--------------------------------------------------------------------   
65ALIGN JUMP_ALIGN
66.InitializeInt40h:
67    mov     [es:INTV_FLOPPY_FUNC*4], ax     ; Store offset
68    mov     [es:INTV_FLOPPY_FUNC*4+2], dx   ; Store segment
69    ret
70
71
72;--------------------------------------------------------------------
73; Interrupts_InitializeInt19h
74;   Parameters:
75;       DS:     RAMVARS segment
76;       ES:     BDA and Interrupt Vector segment (zero)
77;   Returns:
78;       Nothing
79;   Corrupts registers:
80;       BX, SI
81;--------------------------------------------------------------------   
82ALIGN JUMP_ALIGN
83Interrupts_InitializeInt19h:
84    eMOVZX  bx, [cs:ROMVARS.bBootLdrType]   ; Load boot loader type
85    mov     si, INTV_BOOTSTRAP              ; 19h
86    xchg    bx, si                          ; SI=Loader type, BX=19h
87    jmp     [cs:si+.rgwSetupBootLoader]     ; Jump to install selected loader
88ALIGN WORD_ALIGN
89.rgwSetupBootLoader:
90    dw      .SetupBootMenuLoader        ; BOOTLOADER_TYPE_MENU
91    dw      .SetupSimpleLoader          ; BOOTLOADER_TYPE_SIMPLE
92    dw      .SetupBootMenuLoader        ; reserved
93    dw      .NoBootLoader               ; BOOTLOADER_TYPE_NONE
94
95ALIGN JUMP_ALIGN
96.NoBootLoader:
97    test    BYTE [cs:ROMVARS.wFlags], FLG_ROMVARS_LATE
98    jnz     SHORT .SetupSimpleLoader    ; Boot loader required for late initialization
99    ret
100ALIGN JUMP_ALIGN
101.SetupSimpleLoader:
102    mov     si, Int19h_SimpleBootLoader
103    jmp     Interrupts_InstallHandlerToVectorInBXFromCSSI
104ALIGN JUMP_ALIGN
105.SetupBootMenuLoader:
106    mov     si, Int19hMenu_BootLoader
107    jmp     Interrupts_InstallHandlerToVectorInBXFromCSSI
108
109
110;--------------------------------------------------------------------
111; Interrupts_InitializeHardwareIrqHandlers
112;   Parameters:
113;       ES:     BDA and Interrupt Vector segment (zero)
114;   Returns:
115;       Nothing
116;   Corrupts registers:
117;       BX, CX, DX, SI, DI
118;--------------------------------------------------------------------       
119ALIGN JUMP_ALIGN
120Interrupts_InitializeHardwareIrqHandlers:
121    call    RamVars_GetIdeControllerCountToCX
122    mov     di, ROMVARS.ideVars0            ; CS:SI points to first IDEVARS
123ALIGN JUMP_ALIGN
124.IdeControllerLoop:
125    eMOVZX  bx, BYTE [cs:di+IDEVARS.bIRQ]
126    add     di, BYTE IDEVARS_size           ; Increment to next controller
127    call    .InstallLowOrHighIrqHandler
128    loop    .IdeControllerLoop
129    ret
130
131;--------------------------------------------------------------------
132; .InstallLowOrHighIrqHandler
133;   Parameters:
134;       BX:     IRQ number, 0 if IRQ disabled
135;       ES:     BDA and Interrupt Vector segment (zero)
136;   Returns:
137;       Nothing
138;   Corrupts registers:
139;       BX, SI
140;--------------------------------------------------------------------       
141ALIGN JUMP_ALIGN
142.InstallLowOrHighIrqHandler:
143    cmp     bl, 8
144    jae     SHORT .InstallHighIrqHandler
145    test    bl, bl
146    jnz     SHORT .InstallLowIrqHandler
147    ret     ; IRQ not used
148
149;--------------------------------------------------------------------
150; .InstallHighIrqHandler
151;   Parameters:
152;       BX:     IRQ number (8...15)
153;       ES:     BDA and Interrupt Vector segment (zero)
154;   Returns:
155;       Nothing
156;   Corrupts registers:
157;       BX, SI
158;--------------------------------------------------------------------       
159ALIGN JUMP_ALIGN
160.InstallHighIrqHandler:
161    add     bx, BYTE INTV_IRQ8 - 8          ; Interrupt vector number
162    mov     si, HIRQ_InterruptServiceRoutineForIrqs8to15
163    jmp     SHORT Interrupts_InstallHandlerToVectorInBXFromCSSI
164
165;--------------------------------------------------------------------
166; .InstallLowIrqHandler
167;   Parameters:
168;       BX:     IRQ number (0...7)
169;       ES:     BDA and Interrupt Vector segment (zero)
170;   Returns:
171;       Nothing
172;   Corrupts registers:
173;       BX, SI
174;--------------------------------------------------------------------       
175ALIGN JUMP_ALIGN
176.InstallLowIrqHandler:
177    add     bx, BYTE INTV_IRQ0              ; Interrupt vector number
178    mov     si, HIRQ_InterruptServiceRoutineForIrqs2to7
179    ; Fall to Interrupts_InstallHandlerToVectorInBXFromCSSI
180
181
182;--------------------------------------------------------------------
183; Interrupts_InstallHandlerToVectorInBXFromCSSI
184;   Parameters:
185;       BX:     Interrupt vector number (for example 13h)
186;       ES:     BDA and Interrupt Vector segment (zero)
187;       CS:SI:  Ptr to interrupt handler
188;   Returns:
189;       Nothing
190;   Corrupts registers:
191;       BX
192;--------------------------------------------------------------------   
193ALIGN JUMP_ALIGN
194Interrupts_InstallHandlerToVectorInBXFromCSSI:
195    eSHL_IM bx, 2                   ; Shift for DWORD offset
196    mov     [es:bx], si             ; Store offset
197    mov     [es:bx+2], cs           ; Store segment
198    ret
199
200
201;--------------------------------------------------------------------
202; Interrupts_UnmaskInterruptControllerForDriveInDSDI
203;   Parameters:
204;       DS:DI:  Ptr to DPT
205;   Returns:
206;       Nothing
207;   Corrupts registers:
208;       AX, BX, DX
209;--------------------------------------------------------------------
210ALIGN JUMP_ALIGN
211Interrupts_UnmaskInterruptControllerForDriveInDSDI:
212    eMOVZX  bx, BYTE [di+DPT.bIdeOff]
213    mov     al, [cs:bx+IDEVARS.bIRQ]
214    cmp     al, 8
215    jae     SHORT .UnmaskHighIrqController
216    test    al, al
217    jnz     SHORT .UnmaskLowIrqController
218    ret     ; Interrupts disabled
219
220;--------------------------------------------------------------------
221; .UnmaskHighIrqController
222;   Parameters:
223;       AL:     IRQ number (8...15)
224;   Returns:
225;       Nothing
226;   Corrupts registers:
227;       AX, DX
228;--------------------------------------------------------------------
229ALIGN JUMP_ALIGN
230.UnmaskHighIrqController:
231    sub     al, 8               ; Slave interrupt number
232    mov     dx, PORT_8259SL_IMR ; Load Slave Mask Register address
233    call    .ClearBitFrom8259MaskRegister
234    mov     al, 2               ; Master IRQ 2 to allow slave IRQs
235    ; Fall to .UnmaskLowIrqController
236
237;--------------------------------------------------------------------
238; .UnmaskLowIrqController
239;   Parameters:
240;       AL:     IRQ number (0...7)
241;   Returns:
242;       Nothing
243;   Corrupts registers:
244;       AX, DX
245;--------------------------------------------------------------------
246ALIGN JUMP_ALIGN
247.UnmaskLowIrqController:
248    mov     dx, PORT_8259MA_IMR ; Load Mask Register address
249    ; Fall to .ClearBitFrom8259MaskRegister
250
251;--------------------------------------------------------------------
252; .ClearBitFrom8259MaskRegister
253;   Parameters:
254;       AL:     8259 interrupt index (0...7)
255;       DX:     Port address to Interrupt Mask Register
256;   Returns:
257;       Nothing
258;   Corrupts registers:
259;       AX
260;--------------------------------------------------------------------
261;ALIGN JUMP_ALIGN
262.ClearBitFrom8259MaskRegister:
263    push    cx
264    xchg    ax, cx              ; IRQ index to CL
265    mov     ch, 1               ; Load 1 to be shifted
266    shl     ch, cl              ; Shift bit to correct position
267    not     ch                  ; Invert to create bit mask for clearing
268    in      al, dx              ; Read Interrupt Mask Register
269    and     al, ch              ; Clear wanted bit
270    out     dx, al              ; Write modified Interrupt Mask Register
271    pop     cx
272    ret
Note: See TracBrowser for help on using the repository browser.