source: xtideuniversalbios/tags/XTIDE_Universal_BIOS_v1.1.5/Src/Initialization/Interrupts.asm@ 539

Last change on this file since 539 was 33, checked in by Tomi Tilli, 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.