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

Last change on this file since 490 was 489, checked in by gregli@…, 12 years ago

Added version string to initial title banner, for cases where there is not a boot menu (just hotkeys, or no hotkeys). Also ifdef'd out some unused code.

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_HOTKEYS
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 ; Only store INT 13h handler to 40h if 40h is not already installed.
67 ; At least AMI BIOS for 286 stores 40h handler by itself and calls
68 ; 40h from 13h. That system locks to infinite loop if we copy 13h to 40h.
69 call FloppyDrive_IsInt40hInstalled
70 jc SHORT .Int40hAlreadyInstalled
71 mov [es:BIOS_DISKETTE_INTERRUPT_40h*4], ax ; Store old INT 13h offset
72 mov [es:BIOS_DISKETTE_INTERRUPT_40h*4+2], dx ; Store old INT 13h segment
73.Int40hAlreadyInstalled:
74
75 mov al, BIOS_DISK_INTERRUPT_13h ; INT 13h interrupt vector offset
76 mov si, Int13h_DiskFunctionsHandler
77%ifdef RELOCATE_INT13H_STACK
78 test BYTE [cs:ROMVARS.wFlags], FLG_ROMVARS_FULLMODE
79 eCMOVNZ si, Int13h_DiskFunctionsHandlerWithStackChange
80%endif
81
82%ifndef MODULE_IRQ
83 ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
84%else
85 call Interrupts_InstallHandlerToVectorInALFromCSSI
86 ; Fall to .InitializeHardwareIrqHandlers
87
88;--------------------------------------------------------------------
89; .InitializeHardwareIrqHandlers
90; Parameters:
91; ES: BDA and Interrupt Vector segment (zero)
92; Returns:
93; Nothing
94; Corrupts registers:
95; BX, CX, DX, SI, DI, AX
96;--------------------------------------------------------------------
97.InitializeHardwareIrqHandlers:
98 call RamVars_GetIdeControllerCountToCX
99 mov di, ROMVARS.ideVars0 ; CS:SI points to first IDEVARS
100.IdeControllerLoop:
101 mov al, [cs:di+IDEVARS.bIRQ]
102 add di, BYTE IDEVARS_size ; Increment to next controller
103 call .InstallLowOrHighIrqHandler
104 loop .IdeControllerLoop
105.Return:
106 ret ; This ret is shared with .InstallLowOrHighIrqHandler
107
108;--------------------------------------------------------------------
109; .InstallLowOrHighIrqHandler
110; Parameters:
111; AL: IRQ number, 0 if IRQ disabled
112; ES: BDA and Interrupt Vector segment (zero)
113; Returns:
114; Nothing
115; Corrupts registers:
116; BX, SI
117;--------------------------------------------------------------------
118.InstallLowOrHighIrqHandler:
119 test al, al
120 jz SHORT .Return ; IRQ not used
121 cmp al, 8
122 jb SHORT .InstallLowIrqHandler
123 ; Fall to .InstallHighIrqHandler
124
125;--------------------------------------------------------------------
126; .InstallHighIrqHandler
127; Parameters:
128; BX: IRQ number (8...15)
129; ES: BDA and Interrupt Vector segment (zero)
130; Returns:
131; Nothing
132; Corrupts registers:
133; AL, BX, SI
134;--------------------------------------------------------------------
135.InstallHighIrqHandler:
136 add al, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8 ; Interrupt vector number
137 mov si, IdeIrq_InterruptServiceRoutineForIrqs8to15
138 jmp SHORT Interrupts_InstallHandlerToVectorInALFromCSSI
139
140;--------------------------------------------------------------------
141; .InstallLowIrqHandler
142; Parameters:
143; AL: IRQ number (0...7)
144; ES: BDA and Interrupt Vector segment (zero)
145; Returns:
146; Nothing
147; Corrupts registers:
148; AL, BX, SI
149;--------------------------------------------------------------------
150.InstallLowIrqHandler:
151 add al, BYTE HARDWARE_IRQ_0_INTERRUPT_08h ; Interrupt vector number
152 mov si, IdeIrq_InterruptServiceRoutineForIrqs2to7
153 ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
154%endif ; MODULE_IRQ
155
156
157;--------------------------------------------------------------------
158; Interrupts_InstallHandlerToVectorInALFromCSSI
159; Parameters:
160; AL: Interrupt vector number (for example 13h)
161; ES: BDA and Interrupt Vector segment (zero)
162; CS:SI: Ptr to interrupt handler
163; Returns:
164; Nothing
165; Corrupts registers:
166; AX, BX
167;--------------------------------------------------------------------
168Interrupts_InstallHandlerToVectorInALFromCSSI:
169 mov bl, 4 ; Shift for DWORD offset, MUL smaller than other alternatives
170 mul bl
171 xchg ax, bx
172 mov [es:bx], si ; Store offset
173 mov [es:bx+2], cs ; Store segment
174.Interrupts_Return:
175 ret
176
177
178%ifdef MODULE_IRQ
179;--------------------------------------------------------------------
180; Interrupts_UnmaskInterruptControllerForDriveInDSDI
181; Parameters:
182; DS:DI: Ptr to DPT
183; Returns:
184; Nothing
185; Corrupts registers:
186; AX, BX, DX
187;--------------------------------------------------------------------
188Interrupts_UnmaskInterruptControllerForDriveInDSDI:
189 eMOVZX bx, [di+DPT.bIdevarsOffset]
190 mov al, [cs:bx+IDEVARS.bIRQ]
191 test al, al
192 jz SHORT .Return ; Interrupts disabled
193 cmp al, 8
194 jb SHORT .UnmaskLowIrqController
195 ; Fall to .UnmaskHighIrqController
196
197;--------------------------------------------------------------------
198; .UnmaskHighIrqController
199; Parameters:
200; AL: IRQ number (8...15)
201; Returns:
202; Nothing
203; Corrupts registers:
204; AX, DX
205;--------------------------------------------------------------------
206.UnmaskHighIrqController:
207 sub al, 8 ; Slave interrupt number
208 mov dx, SLAVE_8259_IMR
209 call .ClearBitFrom8259MaskRegister
210 mov al, 2 ; Master IRQ 2 to allow slave IRQs
211 ; Fall to .UnmaskLowIrqController
212
213;--------------------------------------------------------------------
214; .UnmaskLowIrqController
215; Parameters:
216; AL: IRQ number (0...7)
217; Returns:
218; Nothing
219; Corrupts registers:
220; AX, DX
221;--------------------------------------------------------------------
222.UnmaskLowIrqController:
223 mov dx, MASTER_8259_IMR
224 ; Fall to .ClearBitFrom8259MaskRegister
225
226;--------------------------------------------------------------------
227; .ClearBitFrom8259MaskRegister
228; Parameters:
229; AL: 8259 interrupt index (0...7)
230; DX: Port address to Interrupt Mask Register
231; Returns:
232; Nothing
233; Corrupts registers:
234; AX
235;--------------------------------------------------------------------
236.ClearBitFrom8259MaskRegister:
237 push cx
238 xchg ax, cx ; IRQ index to CL
239 mov ch, 1 ; Load 1 to be shifted
240 shl ch, cl ; Shift bit to correct position
241 not ch ; Invert to create bit mask for clearing
242 in al, dx ; Read Interrupt Mask Register
243 and al, ch ; Clear wanted bit
244 out dx, al ; Write modified Interrupt Mask Register
245 pop cx
246.Return:
247 ret
248
249%endif ; MODULE_IRQ
Note: See TracBrowser for help on using the repository browser.