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
RevLine 
[90]1; Project name  :   XTIDE Universal BIOS
[33]2; Description   :   Functions for initializing the BIOS.
3
[376]4;
[491]5; XTIDE Universal BIOS and Associated Tools
[376]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.
[491]12;
[376]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
[491]16; GNU General Public License for more details.
[376]17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
[491]18;
[376]19
[33]20; Section containing code
21SECTION .text
22
23;--------------------------------------------------------------------
[431]24; Drives must be detected before this function is called!
25;
[33]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
[86]34;--------------------------------------------------------------------
[33]35Interrupts_InitializeInterruptVectors:
[431]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.
[492]43%ifndef MODULE_DRIVEXLATE
[431]44    cmp     BYTE [RAMVARS.bDrvCnt], 0
[489]45    je      SHORT Interrupts_InstallHandlerToVectorInALFromCSSI.Interrupts_Return
[431]46%endif
[97]47    ; Fall to .InitializeInt13hAnd40h
[33]48
49;--------------------------------------------------------------------
[97]50; .InitializeInt13hAnd40h
[33]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
[86]58;--------------------------------------------------------------------
[97]59.InitializeInt13hAnd40h:
[181]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
[152]63    mov     ax, [es:BIOS_DISK_INTERRUPT_13h*4]  ; Load old INT 13h offset
[33]64    mov     [RAMVARS.fpOldI13h], ax             ; Store old INT 13h offset
[181]65
[33]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
[243]70    jc      SHORT .Int40hAlreadyInstalled
[152]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
[243]73.Int40hAlreadyInstalled:
[258]74
75    mov     al, BIOS_DISK_INTERRUPT_13h         ; INT 13h interrupt vector offset
[417]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
[392]81
[398]82%ifndef MODULE_IRQ
83    ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
84%else
[392]85    call    Interrupts_InstallHandlerToVectorInALFromCSSI
[97]86    ; Fall to .InitializeHardwareIrqHandlers
[33]87
88;--------------------------------------------------------------------
[97]89; .InitializeHardwareIrqHandlers
[33]90;   Parameters:
91;       ES:     BDA and Interrupt Vector segment (zero)
92;   Returns:
93;       Nothing
94;   Corrupts registers:
[258]95;       BX, CX, DX, SI, DI, AX
[86]96;--------------------------------------------------------------------
[97]97.InitializeHardwareIrqHandlers:
[33]98    call    RamVars_GetIdeControllerCountToCX
[491]99    mov     di, ROMVARS.ideVars0+IDEVARS.bIRQ   ; CS:SI points to first IDEVARS
[33]100.IdeControllerLoop:
[491]101    mov     al, [cs:di]
[33]102    add     di, BYTE IDEVARS_size           ; Increment to next controller
103    call    .InstallLowOrHighIrqHandler
104    loop    .IdeControllerLoop
[86]105.Return:
106    ret     ; This ret is shared with .InstallLowOrHighIrqHandler
[33]107
108;--------------------------------------------------------------------
109; .InstallLowOrHighIrqHandler
110;   Parameters:
[258]111;       AL:     IRQ number, 0 if IRQ disabled
[33]112;       ES:     BDA and Interrupt Vector segment (zero)
113;   Returns:
114;       Nothing
115;   Corrupts registers:
116;       BX, SI
[86]117;--------------------------------------------------------------------
[33]118.InstallLowOrHighIrqHandler:
[258]119    test    al, al
[86]120    jz      SHORT .Return   ; IRQ not used
[258]121    cmp     al, 8
[86]122    jb      SHORT .InstallLowIrqHandler
[162]123    ; Fall to .InstallHighIrqHandler
[33]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:
[258]133;       AL, BX, SI
[86]134;--------------------------------------------------------------------
[97]135.InstallHighIrqHandler:
[258]136    add     al, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8   ; Interrupt vector number
[150]137    mov     si, IdeIrq_InterruptServiceRoutineForIrqs8to15
[258]138    jmp     SHORT Interrupts_InstallHandlerToVectorInALFromCSSI
[33]139
140;--------------------------------------------------------------------
141; .InstallLowIrqHandler
142;   Parameters:
[258]143;       AL:     IRQ number (0...7)
[33]144;       ES:     BDA and Interrupt Vector segment (zero)
145;   Returns:
146;       Nothing
147;   Corrupts registers:
[258]148;       AL, BX, SI
[86]149;--------------------------------------------------------------------
[33]150.InstallLowIrqHandler:
[258]151    add     al, BYTE HARDWARE_IRQ_0_INTERRUPT_08h       ; Interrupt vector number
[150]152    mov     si, IdeIrq_InterruptServiceRoutineForIrqs2to7
[258]153    ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
[398]154%endif ; MODULE_IRQ
[33]155
156
157;--------------------------------------------------------------------
[258]158; Interrupts_InstallHandlerToVectorInALFromCSSI
[33]159;   Parameters:
[258]160;       AL:     Interrupt vector number (for example 13h)
[33]161;       ES:     BDA and Interrupt Vector segment (zero)
162;       CS:SI:  Ptr to interrupt handler
163;   Returns:
164;       Nothing
165;   Corrupts registers:
[258]166;       AX, BX
[86]167;--------------------------------------------------------------------
[258]168Interrupts_InstallHandlerToVectorInALFromCSSI:
169    mov     bl, 4                   ; Shift for DWORD offset, MUL smaller than other alternatives
170    mul     bl
171    xchg    ax, bx
[33]172    mov     [es:bx], si             ; Store offset
173    mov     [es:bx+2], cs           ; Store segment
[489]174.Interrupts_Return:
[33]175    ret
176
177
[398]178%ifdef MODULE_IRQ
[33]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:
[294]189    eMOVZX  bx, [di+DPT.bIdevarsOffset]
[33]190    mov     al, [cs:bx+IDEVARS.bIRQ]
[86]191    test    al, al
192    jz      SHORT .Return   ; Interrupts disabled
[33]193    cmp     al, 8
[86]194    jb      SHORT .UnmaskLowIrqController
[162]195    ; Fall to .UnmaskHighIrqController
[33]196
197;--------------------------------------------------------------------
198; .UnmaskHighIrqController
199;   Parameters:
200;       AL:     IRQ number (8...15)
201;   Returns:
202;       Nothing
203;   Corrupts registers:
204;       AX, DX
205;--------------------------------------------------------------------
[97]206.UnmaskHighIrqController:
[33]207    sub     al, 8               ; Slave interrupt number
[152]208    mov     dx, SLAVE_8259_IMR
[33]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:
[152]223    mov     dx, MASTER_8259_IMR
[33]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
[86]246.Return:
[33]247    ret
[398]248
249%endif ; MODULE_IRQ
Note: See TracBrowser for help on using the repository browser.