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

Last change on this file since 558 was 558, checked in by krille_n_@…, 11 years ago

Changes:

  • Building the BIOS Drive Information Tool now works again.
  • Moved all XT-CF related code to MODULE_8BIT_IDE_ADVANCED. I don't see how an XT-CF card could work without *_ADVANCED anyway but if I'm wrong, feel free to undo this. Note! The autodetection code in XTIDECFG has NOT been changed to reflect this (still relies on MODULE_8BIT_IDE).
  • Optimizations and fixes in general.
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-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!
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    ; 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 blindly 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%ifdef RELOCATE_INT13H_STACK
77    mov     si, Int13h_DiskFunctionsHandlerWithStackChange
78%else
79    mov     si, Int13h_DiskFunctionsHandler
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+IDEVARS.bIRQ
100.IdeControllerLoop:
101    mov     al, [cs:di]
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%ifdef USE_AT
122    cmp     al, 8
123    jb      SHORT .InstallLowIrqHandler
124    ; Fall to .InstallHighIrqHandler
125
126;--------------------------------------------------------------------
127; .InstallHighIrqHandler
128;   Parameters:
129;       BX:     IRQ number (8...15)
130;       ES:     BDA and Interrupt Vector segment (zero)
131;   Returns:
132;       Nothing
133;   Corrupts registers:
134;       AL, BX, SI
135;--------------------------------------------------------------------
136.InstallHighIrqHandler:
137    add     al, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8   ; Interrupt vector number
138    mov     si, IdeIrq_InterruptServiceRoutineForIrqs8to15
139    jmp     SHORT Interrupts_InstallHandlerToVectorInALFromCSSI
140%endif ; USE_AT
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.