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

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

Previosly committed flash fix for configurator was incomplete. Now fixed properly.
Added MODULE_MFM_COMPATIBILITY.

File size: 8.7 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 mov [es:bx], si ; Store offset
187 mov [es:bx+2], cs ; Store segment
188.Interrupts_Return:
189 ret
190
191
192%ifdef MODULE_IRQ
193;--------------------------------------------------------------------
194; Interrupts_UnmaskInterruptControllerForDriveInDSDI
195; Parameters:
196; DS:DI: Ptr to DPT
197; Returns:
198; Nothing
199; Corrupts registers:
200; AX, BX, DX
201;--------------------------------------------------------------------
202Interrupts_UnmaskInterruptControllerForDriveInDSDI:
203 eMOVZX bx, [di+DPT.bIdevarsOffset]
204 mov al, [cs:bx+IDEVARS.bIRQ]
205 test al, al
206 jz SHORT .Return ; Interrupts disabled
207 cmp al, 8
208 jb SHORT .UnmaskLowIrqController
209 ; Fall to .UnmaskHighIrqController
210
211;--------------------------------------------------------------------
212; .UnmaskHighIrqController
213; Parameters:
214; AL: IRQ number (8...15)
215; Returns:
216; Nothing
217; Corrupts registers:
218; AX, DX
219;--------------------------------------------------------------------
220.UnmaskHighIrqController:
221 sub al, 8 ; Slave interrupt number
222 mov dx, SLAVE_8259_IMR
223 call .ClearBitFrom8259MaskRegister
224 mov al, 2 ; Master IRQ 2 to allow slave IRQs
225 ; Fall to .UnmaskLowIrqController
226
227;--------------------------------------------------------------------
228; .UnmaskLowIrqController
229; Parameters:
230; AL: IRQ number (0...7)
231; Returns:
232; Nothing
233; Corrupts registers:
234; AX, DX
235;--------------------------------------------------------------------
236.UnmaskLowIrqController:
237 mov dx, MASTER_8259_IMR
238 ; Fall to .ClearBitFrom8259MaskRegister
239
240;--------------------------------------------------------------------
241; .ClearBitFrom8259MaskRegister
242; Parameters:
243; AL: 8259 interrupt index (0...7)
244; DX: Port address to Interrupt Mask Register
245; Returns:
246; Nothing
247; Corrupts registers:
248; AX
249;--------------------------------------------------------------------
250.ClearBitFrom8259MaskRegister:
251 push cx
252 xchg cx, ax ; IRQ index to CL
253 in al, dx ; Read Interrupt Mask Register
254 mov ch, ~1 ; Load bit mask to be rotated
255 rol ch, cl ; Rotate mask to correct position for clearing
256 and al, ch ; Clear wanted bit
257 out dx, al ; Write modified Interrupt Mask Register
258 pop cx
259.Return:
260 ret
261
262%endif ; MODULE_IRQ
Note: See TracBrowser for help on using the repository browser.