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

Last change on this file since 608 was 599, checked in by Tomi Tilli, 6 years ago

Hotkey bar is now updated and drawn from system timer tick handler 1Ch. This gives much more responsive key input and makes possible to implement some simple detection animation to show that system has not frozen.

File size: 8.8 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-2013 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 unless
25; MODULE_DRIVEXLATE has been included in the BIOS.
26;
27; Interrupts_InitializeInterruptVectors
28; Parameters:
29; DS: RAMVARS segment
30; ES: BDA and Interrupt Vector segment (zero)
31; Returns:
32; Nothing
33; Corrupts registers:
34; All except segments
35;--------------------------------------------------------------------
36Interrupts_InitializeInterruptVectors:
37 ; Install INT 19h handler to properly reset the system
38 mov al, BIOS_BOOT_LOADER_INTERRUPT_19h ; INT 19h interrupt vector offset
39 mov si, Int19hReset_Handler ; INT 19h handler to reboot the system
40 call Interrupts_InstallHandlerToVectorInALFromCSSI
41
42 ; If no drives detected, leave system INT 13h and 40h handlers
43 ; in place. We need our INT 13h handler to swap drive letters.
44%ifndef MODULE_DRIVEXLATE
45 cmp BYTE [RAMVARS.bDrvCnt], 0
46 je SHORT Interrupts_InstallHandlerToVectorInALFromCSSI.Interrupts_Return
47%endif
48 ; Fall to .InitializeInt13hAnd40h
49
50;--------------------------------------------------------------------
51; .InitializeInt13hAnd40h
52; Parameters:
53; DS: RAMVARS segment
54; ES: BDA and Interrupt Vector segment (zero)
55; Returns:
56; Nothing
57; Corrupts registers:
58; AX, BX, CX, DX, SI, DI
59;--------------------------------------------------------------------
60.InitializeInt13hAnd40h:
61%ifdef MODULE_MFM_COMPATIBILITY
62 mov ax, [es:BIOS_DISK_INTERRUPT_13h*4+2]; Load old INT 13h segment
63 mov [RAMVARS.fpMFMint13h+2], ax ; Store old INT 13h segment
64 xchg dx, ax
65 mov ax, [es:BIOS_DISK_INTERRUPT_13h*4] ; Load old INT 13h offset
66 mov [RAMVARS.fpMFMint13h], ax ; Store old INT 13h offset
67
68 mov [RAMVARS.fpOldI13h+2], cs
69 mov WORD [RAMVARS.fpOldI13h], Int13hMFMcompatibilityHandler
70%else
71 mov ax, [es:BIOS_DISK_INTERRUPT_13h*4+2]; Load old INT 13h segment
72 mov [RAMVARS.fpOldI13h+2], ax ; Store old INT 13h segment
73 xchg dx, ax
74 mov ax, [es:BIOS_DISK_INTERRUPT_13h*4] ; Load old INT 13h offset
75 mov [RAMVARS.fpOldI13h], ax ; Store old INT 13h offset
76%endif
77
78 ; Only store INT 13h handler to 40h if 40h is not already installed.
79 ; At least AMI BIOS for 286 stores 40h handler by itself and calls
80 ; 40h from 13h. That system locks to infinite loop if we blindly copy 13h to 40h.
81 call FloppyDrive_IsInt40hInstalled
82 jc SHORT .Int40hAlreadyInstalled
83 mov [es:BIOS_DISKETTE_INTERRUPT_40h*4], ax ; Store old INT 13h offset
84 mov [es:BIOS_DISKETTE_INTERRUPT_40h*4+2], dx ; Store old INT 13h segment
85.Int40hAlreadyInstalled:
86
87 mov al, BIOS_DISK_INTERRUPT_13h ; INT 13h interrupt vector offset
88%ifdef RELOCATE_INT13H_STACK
89 mov si, Int13h_DiskFunctionsHandlerWithStackChange
90%else
91 mov si, Int13h_DiskFunctionsHandler
92%endif
93
94%ifndef MODULE_IRQ
95 ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
96%else
97 call Interrupts_InstallHandlerToVectorInALFromCSSI
98 ; Fall to .InitializeHardwareIrqHandlers
99
100;--------------------------------------------------------------------
101; .InitializeHardwareIrqHandlers
102; Parameters:
103; ES: BDA and Interrupt Vector segment (zero)
104; Returns:
105; Nothing
106; Corrupts registers:
107; BX, CX, DX, SI, DI, AX
108;--------------------------------------------------------------------
109.InitializeHardwareIrqHandlers:
110 call RamVars_GetIdeControllerCountToCX
111 mov di, ROMVARS.ideVars0+IDEVARS.bIRQ
112.IdeControllerLoop:
113 mov al, [cs:di]
114 add di, BYTE IDEVARS_size ; Increment to next controller
115 call .InstallLowOrHighIrqHandler
116 loop .IdeControllerLoop
117.Return:
118 ret ; This ret is shared with .InstallLowOrHighIrqHandler
119
120;--------------------------------------------------------------------
121; .InstallLowOrHighIrqHandler
122; Parameters:
123; AL: IRQ number, 0 if IRQ disabled
124; ES: BDA and Interrupt Vector segment (zero)
125; Returns:
126; Nothing
127; Corrupts registers:
128; BX, SI
129;--------------------------------------------------------------------
130.InstallLowOrHighIrqHandler:
131 test al, al
132 jz SHORT .Return ; IRQ not used
133%ifdef USE_AT
134 cmp al, 8
135 jb SHORT .InstallLowIrqHandler
136 ; Fall to .InstallHighIrqHandler
137
138;--------------------------------------------------------------------
139; .InstallHighIrqHandler
140; Parameters:
141; BX: IRQ number (8...15)
142; ES: BDA and Interrupt Vector segment (zero)
143; Returns:
144; Nothing
145; Corrupts registers:
146; AL, BX, SI
147;--------------------------------------------------------------------
148.InstallHighIrqHandler:
149 add al, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8 ; Interrupt vector number
150 mov si, IdeIrq_InterruptServiceRoutineForIrqs8to15
151 jmp SHORT Interrupts_InstallHandlerToVectorInALFromCSSI
152%endif ; USE_AT
153
154;--------------------------------------------------------------------
155; .InstallLowIrqHandler
156; Parameters:
157; AL: IRQ number (0...7)
158; ES: BDA and Interrupt Vector segment (zero)
159; Returns:
160; Nothing
161; Corrupts registers:
162; AL, BX, SI
163;--------------------------------------------------------------------
164.InstallLowIrqHandler:
165 add al, BYTE HARDWARE_IRQ_0_INTERRUPT_08h ; Interrupt vector number
166 mov si, IdeIrq_InterruptServiceRoutineForIrqs2to7
167 ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
168%endif ; MODULE_IRQ
169
170
171;--------------------------------------------------------------------
172; Interrupts_InstallHandlerToVectorInALFromCSSI
173; Parameters:
174; AL: Interrupt vector number (for example 13h)
175; ES: BDA and Interrupt Vector segment (zero)
176; CS:SI: Ptr to interrupt handler
177; Returns:
178; Nothing
179; Corrupts registers:
180; AX, BX
181;--------------------------------------------------------------------
182Interrupts_InstallHandlerToVectorInALFromCSSI:
183 mov bl, 4 ; Shift for DWORD offset, MUL smaller than other alternatives
184 mul bl
185 xchg ax, bx
186 cli
187 mov [es:bx], si ; Store offset
188 mov [es:bx+2], cs ; Store segment
189 sti
190.Interrupts_Return:
191 ret
192
193
194%ifdef MODULE_IRQ
195;--------------------------------------------------------------------
196; Interrupts_UnmaskInterruptControllerForDriveInDSDI
197; Parameters:
198; DS:DI: Ptr to DPT
199; Returns:
200; Nothing
201; Corrupts registers:
202; AX, BX, DX
203;--------------------------------------------------------------------
204Interrupts_UnmaskInterruptControllerForDriveInDSDI:
205 eMOVZX bx, [di+DPT.bIdevarsOffset]
206 mov al, [cs:bx+IDEVARS.bIRQ]
207 test al, al
208 jz SHORT .Return ; Interrupts disabled
209 cmp al, 8
210 jb SHORT .UnmaskLowIrqController
211 ; Fall to .UnmaskHighIrqController
212
213;--------------------------------------------------------------------
214; .UnmaskHighIrqController
215; Parameters:
216; AL: IRQ number (8...15)
217; Returns:
218; Nothing
219; Corrupts registers:
220; AX, DX
221;--------------------------------------------------------------------
222.UnmaskHighIrqController:
223 sub al, 8 ; Slave interrupt number
224 mov dx, SLAVE_8259_IMR
225 call .ClearBitFrom8259MaskRegister
226 mov al, 2 ; Master IRQ 2 to allow slave IRQs
227 ; Fall to .UnmaskLowIrqController
228
229;--------------------------------------------------------------------
230; .UnmaskLowIrqController
231; Parameters:
232; AL: IRQ number (0...7)
233; Returns:
234; Nothing
235; Corrupts registers:
236; AX, DX
237;--------------------------------------------------------------------
238.UnmaskLowIrqController:
239 mov dx, MASTER_8259_IMR
240 ; Fall to .ClearBitFrom8259MaskRegister
241
242;--------------------------------------------------------------------
243; .ClearBitFrom8259MaskRegister
244; Parameters:
245; AL: 8259 interrupt index (0...7)
246; DX: Port address to Interrupt Mask Register
247; Returns:
248; Nothing
249; Corrupts registers:
250; AX
251;--------------------------------------------------------------------
252.ClearBitFrom8259MaskRegister:
253 push cx
254 xchg cx, ax ; IRQ index to CL
255 in al, dx ; Read Interrupt Mask Register
256%ifdef USE_NEC_V
257 eCLR1 al, cl ; Clear wanted bit
258%else
259 mov ch, ~1 ; Load bit mask to be rotated
260 rol ch, cl ; Rotate mask to correct position for clearing
261 and al, ch ; Clear wanted bit
262%endif
263 out dx, al ; Write modified Interrupt Mask Register
264 pop cx
265.Return:
266 ret
267
268%endif ; MODULE_IRQ
Note: See TracBrowser for help on using the repository browser.