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

Last change on this file since 525 was 524, checked in by aitotat@…, 12 years ago

Changes to XTIDE Universal BIOS:

  • Min time to display hotkeys finally work correctly.
  • AT builds do not copy existing INT 13h handler to 40h by default, XT builds do.
  • Interrupts are enabled for Primary and Secondary controller by default on AT builds.
File size: 8.3 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : Functions for initializing the BIOS.
3
4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2012 by XTIDE Universal BIOS Team.
7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
12;
13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16; GNU General Public License for more details.
17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
19
20; Section containing code
21SECTION .text
22
23;--------------------------------------------------------------------
24; Drives must be detected before this function is called!
25;
26; Interrupts_InitializeInterruptVectors
27; Parameters:
28; DS: RAMVARS segment
29; ES: BDA and Interrupt Vector segment (zero)
30; Returns:
31; Nothing
32; Corrupts registers:
33; All except segments
34;--------------------------------------------------------------------
35Interrupts_InitializeInterruptVectors:
36 ; Install INT 19h handler to properly reset the system
37 mov al, BIOS_BOOT_LOADER_INTERRUPT_19h ; INT 19h interrupt vector offset
38 mov si, Int19hReset_Handler ; INT 19h handler to reboot the system
39 call Interrupts_InstallHandlerToVectorInALFromCSSI
40
41 ; If no drives detected, leave system INT 13h and 40h handlers
42 ; in place. We need our INT 13h handler to swap drive letters.
43%ifndef MODULE_DRIVEXLATE
44 cmp BYTE [RAMVARS.bDrvCnt], 0
45 je SHORT Interrupts_InstallHandlerToVectorInALFromCSSI.Interrupts_Return
46%endif
47 ; Fall to .InitializeInt13hAnd40h
48
49;--------------------------------------------------------------------
50; .InitializeInt13hAnd40h
51; Parameters:
52; DS: RAMVARS segment
53; ES: BDA and Interrupt Vector segment (zero)
54; Returns:
55; Nothing
56; Corrupts registers:
57; AX, BX, CX, DX, SI, DI
58;--------------------------------------------------------------------
59.InitializeInt13hAnd40h:
60 mov ax, [es:BIOS_DISK_INTERRUPT_13h*4+2]; Load old INT 13h segment
61 mov [RAMVARS.fpOldI13h+2], ax ; Store old INT 13h segment
62 xchg dx, ax
63 mov ax, [es:BIOS_DISK_INTERRUPT_13h*4] ; Load old INT 13h offset
64 mov [RAMVARS.fpOldI13h], ax ; Store old INT 13h offset
65
66%ifdef COPY_13H_HANDLER_TO_40H
67 ; Only store INT 13h handler to 40h if 40h is not already installed.
68 ; At least AMI BIOS for 286 stores 40h handler by itself and calls
69 ; 40h from 13h. That system locks to infinite loop if we copy 13h to 40h.
70 call FloppyDrive_IsInt40hInstalled
71 jc SHORT .Int40hAlreadyInstalled
72 mov [es:BIOS_DISKETTE_INTERRUPT_40h*4], ax ; Store old INT 13h offset
73 mov [es:BIOS_DISKETTE_INTERRUPT_40h*4+2], dx ; Store old INT 13h segment
74.Int40hAlreadyInstalled:
75%endif ; COPY_13H_HANDLER_TO_40H
76
77 mov al, BIOS_DISK_INTERRUPT_13h ; INT 13h interrupt vector offset
78%ifdef RELOCATE_INT13H_STACK
79 mov si, Int13h_DiskFunctionsHandlerWithStackChange
80%else
81 mov si, Int13h_DiskFunctionsHandler
82%endif
83
84%ifndef MODULE_IRQ
85 ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
86%else
87 call Interrupts_InstallHandlerToVectorInALFromCSSI
88 ; Fall to .InitializeHardwareIrqHandlers
89
90;--------------------------------------------------------------------
91; .InitializeHardwareIrqHandlers
92; Parameters:
93; ES: BDA and Interrupt Vector segment (zero)
94; Returns:
95; Nothing
96; Corrupts registers:
97; BX, CX, DX, SI, DI, AX
98;--------------------------------------------------------------------
99.InitializeHardwareIrqHandlers:
100 call RamVars_GetIdeControllerCountToCX
101 mov di, ROMVARS.ideVars0+IDEVARS.bIRQ ; CS:SI points to first IDEVARS
102.IdeControllerLoop:
103 mov al, [cs:di]
104 add di, BYTE IDEVARS_size ; Increment to next controller
105 call .InstallLowOrHighIrqHandler
106 loop .IdeControllerLoop
107.Return:
108 ret ; This ret is shared with .InstallLowOrHighIrqHandler
109
110;--------------------------------------------------------------------
111; .InstallLowOrHighIrqHandler
112; Parameters:
113; AL: IRQ number, 0 if IRQ disabled
114; ES: BDA and Interrupt Vector segment (zero)
115; Returns:
116; Nothing
117; Corrupts registers:
118; BX, SI
119;--------------------------------------------------------------------
120.InstallLowOrHighIrqHandler:
121 test al, al
122 jz SHORT .Return ; IRQ not used
123 cmp al, 8
124 jb SHORT .InstallLowIrqHandler
125 ; Fall to .InstallHighIrqHandler
126
127;--------------------------------------------------------------------
128; .InstallHighIrqHandler
129; Parameters:
130; BX: IRQ number (8...15)
131; ES: BDA and Interrupt Vector segment (zero)
132; Returns:
133; Nothing
134; Corrupts registers:
135; AL, BX, SI
136;--------------------------------------------------------------------
137.InstallHighIrqHandler:
138 add al, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8 ; Interrupt vector number
139 mov si, IdeIrq_InterruptServiceRoutineForIrqs8to15
140 jmp SHORT Interrupts_InstallHandlerToVectorInALFromCSSI
141
142;--------------------------------------------------------------------
143; .InstallLowIrqHandler
144; Parameters:
145; AL: IRQ number (0...7)
146; ES: BDA and Interrupt Vector segment (zero)
147; Returns:
148; Nothing
149; Corrupts registers:
150; AL, BX, SI
151;--------------------------------------------------------------------
152.InstallLowIrqHandler:
153 add al, BYTE HARDWARE_IRQ_0_INTERRUPT_08h ; Interrupt vector number
154 mov si, IdeIrq_InterruptServiceRoutineForIrqs2to7
155 ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
156%endif ; MODULE_IRQ
157
158
159;--------------------------------------------------------------------
160; Interrupts_InstallHandlerToVectorInALFromCSSI
161; Parameters:
162; AL: Interrupt vector number (for example 13h)
163; ES: BDA and Interrupt Vector segment (zero)
164; CS:SI: Ptr to interrupt handler
165; Returns:
166; Nothing
167; Corrupts registers:
168; AX, BX
169;--------------------------------------------------------------------
170Interrupts_InstallHandlerToVectorInALFromCSSI:
171 mov bl, 4 ; Shift for DWORD offset, MUL smaller than other alternatives
172 mul bl
173 xchg ax, bx
174 mov [es:bx], si ; Store offset
175 mov [es:bx+2], cs ; Store segment
176.Interrupts_Return:
177 ret
178
179
180%ifdef MODULE_IRQ
181;--------------------------------------------------------------------
182; Interrupts_UnmaskInterruptControllerForDriveInDSDI
183; Parameters:
184; DS:DI: Ptr to DPT
185; Returns:
186; Nothing
187; Corrupts registers:
188; AX, BX, DX
189;--------------------------------------------------------------------
190Interrupts_UnmaskInterruptControllerForDriveInDSDI:
191 eMOVZX bx, [di+DPT.bIdevarsOffset]
192 mov al, [cs:bx+IDEVARS.bIRQ]
193 test al, al
194 jz SHORT .Return ; Interrupts disabled
195 cmp al, 8
196 jb SHORT .UnmaskLowIrqController
197 ; Fall to .UnmaskHighIrqController
198
199;--------------------------------------------------------------------
200; .UnmaskHighIrqController
201; Parameters:
202; AL: IRQ number (8...15)
203; Returns:
204; Nothing
205; Corrupts registers:
206; AX, DX
207;--------------------------------------------------------------------
208.UnmaskHighIrqController:
209 sub al, 8 ; Slave interrupt number
210 mov dx, SLAVE_8259_IMR
211 call .ClearBitFrom8259MaskRegister
212 mov al, 2 ; Master IRQ 2 to allow slave IRQs
213 ; Fall to .UnmaskLowIrqController
214
215;--------------------------------------------------------------------
216; .UnmaskLowIrqController
217; Parameters:
218; AL: IRQ number (0...7)
219; Returns:
220; Nothing
221; Corrupts registers:
222; AX, DX
223;--------------------------------------------------------------------
224.UnmaskLowIrqController:
225 mov dx, MASTER_8259_IMR
226 ; Fall to .ClearBitFrom8259MaskRegister
227
228;--------------------------------------------------------------------
229; .ClearBitFrom8259MaskRegister
230; Parameters:
231; AL: 8259 interrupt index (0...7)
232; DX: Port address to Interrupt Mask Register
233; Returns:
234; Nothing
235; Corrupts registers:
236; AX
237;--------------------------------------------------------------------
238.ClearBitFrom8259MaskRegister:
239 push cx
240 xchg ax, cx ; IRQ index to CL
241 mov ch, 1 ; Load 1 to be shifted
242 shl ch, cl ; Shift bit to correct position
243 not ch ; Invert to create bit mask for clearing
244 in al, dx ; Read Interrupt Mask Register
245 and al, ch ; Clear wanted bit
246 out dx, al ; Write modified Interrupt Mask Register
247 pop cx
248.Return:
249 ret
250
251%endif ; MODULE_IRQ
Note: See TracBrowser for help on using the repository browser.