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

Last change on this file since 522 was 522, checked in by aitotat@…, 9 years ago

Changes to XTIDE Universal BIOS:

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