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

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

Removed the dependency between MODULE_BOOT_MENU and MODULE_HOTKEYS. With these changes, 0, 1, or 2 of them can be included in a build. This change also means that the hotkeys don't work while the menu is up. But the most important hotkey there was for Rom Boot, and that has been added to the menu as a choice proper. Lots of changes across the board in the hotkeys code - even if we eventually back this change out (becaue, for example we want hotkeys to work in the menu) we should probably start from this base and add that functionality back in, as these changes results in approximately 120 bytes of savings and includes new functionality, such as the Rom Boot menu item and the Com Detect hotkey.

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_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 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+IDEVARS.bIRQ   ; CS:SI points to first IDEVARS
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    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.