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

Last change on this file since 599 was 599, checked in by aitotat, 6 years ago

Hotkey bar is now updated and drawn from system timer tick handler 1Ch. This gives much more responsive key input and makes possible to implement some simple detection animation to show that system has not frozen.

File size: 8.8 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
[526]6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
[376]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;--------------------------------------------------------------------
[580]24; Drives must be detected before this function is called unless
25; MODULE_DRIVEXLATE has been included in the BIOS.
[431]26;
[33]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
[86]35;--------------------------------------------------------------------
[33]36Interrupts_InitializeInterruptVectors:
[431]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.
[492]44%ifndef MODULE_DRIVEXLATE
[431]45    cmp     BYTE [RAMVARS.bDrvCnt], 0
[489]46    je      SHORT Interrupts_InstallHandlerToVectorInALFromCSSI.Interrupts_Return
[431]47%endif
[97]48    ; Fall to .InitializeInt13hAnd40h
[33]49
50;--------------------------------------------------------------------
[97]51; .InitializeInt13hAnd40h
[33]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
[86]59;--------------------------------------------------------------------
[97]60.InitializeInt13hAnd40h:
[594]61%ifdef MODULE_MFM_COMPATIBILITY
[181]62    mov     ax, [es:BIOS_DISK_INTERRUPT_13h*4+2]; Load old INT 13h segment
[594]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
[596]67
[594]68    mov     [RAMVARS.fpOldI13h+2], cs
[596]69    mov     WORD [RAMVARS.fpOldI13h], Int13hMFMcompatibilityHandler
[594]70%else
71    mov     ax, [es:BIOS_DISK_INTERRUPT_13h*4+2]; Load old INT 13h segment
[181]72    mov     [RAMVARS.fpOldI13h+2], ax           ; Store old INT 13h segment
73    xchg    dx, ax
[152]74    mov     ax, [es:BIOS_DISK_INTERRUPT_13h*4]  ; Load old INT 13h offset
[33]75    mov     [RAMVARS.fpOldI13h], ax             ; Store old INT 13h offset
[594]76%endif
[181]77
[33]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
[530]80    ; 40h from 13h. That system locks to infinite loop if we blindly copy 13h to 40h.
[33]81    call    FloppyDrive_IsInt40hInstalled
[243]82    jc      SHORT .Int40hAlreadyInstalled
[152]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
[243]85.Int40hAlreadyInstalled:
[258]86
87    mov     al, BIOS_DISK_INTERRUPT_13h         ; INT 13h interrupt vector offset
[522]88%ifdef RELOCATE_INT13H_STACK
89    mov     si, Int13h_DiskFunctionsHandlerWithStackChange
90%else
[417]91    mov     si, Int13h_DiskFunctionsHandler
92%endif
[392]93
[398]94%ifndef MODULE_IRQ
95    ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
96%else
[392]97    call    Interrupts_InstallHandlerToVectorInALFromCSSI
[97]98    ; Fall to .InitializeHardwareIrqHandlers
[33]99
100;--------------------------------------------------------------------
[97]101; .InitializeHardwareIrqHandlers
[33]102;   Parameters:
103;       ES:     BDA and Interrupt Vector segment (zero)
104;   Returns:
105;       Nothing
106;   Corrupts registers:
[258]107;       BX, CX, DX, SI, DI, AX
[86]108;--------------------------------------------------------------------
[97]109.InitializeHardwareIrqHandlers:
[33]110    call    RamVars_GetIdeControllerCountToCX
[558]111    mov     di, ROMVARS.ideVars0+IDEVARS.bIRQ
[33]112.IdeControllerLoop:
[491]113    mov     al, [cs:di]
[33]114    add     di, BYTE IDEVARS_size           ; Increment to next controller
115    call    .InstallLowOrHighIrqHandler
116    loop    .IdeControllerLoop
[86]117.Return:
118    ret     ; This ret is shared with .InstallLowOrHighIrqHandler
[33]119
120;--------------------------------------------------------------------
121; .InstallLowOrHighIrqHandler
122;   Parameters:
[258]123;       AL:     IRQ number, 0 if IRQ disabled
[33]124;       ES:     BDA and Interrupt Vector segment (zero)
125;   Returns:
126;       Nothing
127;   Corrupts registers:
128;       BX, SI
[86]129;--------------------------------------------------------------------
[33]130.InstallLowOrHighIrqHandler:
[258]131    test    al, al
[86]132    jz      SHORT .Return   ; IRQ not used
[540]133%ifdef USE_AT
[258]134    cmp     al, 8
[86]135    jb      SHORT .InstallLowIrqHandler
[162]136    ; Fall to .InstallHighIrqHandler
[33]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:
[258]146;       AL, BX, SI
[86]147;--------------------------------------------------------------------
[97]148.InstallHighIrqHandler:
[258]149    add     al, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8   ; Interrupt vector number
[150]150    mov     si, IdeIrq_InterruptServiceRoutineForIrqs8to15
[258]151    jmp     SHORT Interrupts_InstallHandlerToVectorInALFromCSSI
[540]152%endif ; USE_AT
[33]153
154;--------------------------------------------------------------------
155; .InstallLowIrqHandler
156;   Parameters:
[258]157;       AL:     IRQ number (0...7)
[33]158;       ES:     BDA and Interrupt Vector segment (zero)
159;   Returns:
160;       Nothing
161;   Corrupts registers:
[258]162;       AL, BX, SI
[86]163;--------------------------------------------------------------------
[33]164.InstallLowIrqHandler:
[258]165    add     al, BYTE HARDWARE_IRQ_0_INTERRUPT_08h       ; Interrupt vector number
[150]166    mov     si, IdeIrq_InterruptServiceRoutineForIrqs2to7
[258]167    ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
[398]168%endif ; MODULE_IRQ
[33]169
170
171;--------------------------------------------------------------------
[258]172; Interrupts_InstallHandlerToVectorInALFromCSSI
[33]173;   Parameters:
[258]174;       AL:     Interrupt vector number (for example 13h)
[33]175;       ES:     BDA and Interrupt Vector segment (zero)
176;       CS:SI:  Ptr to interrupt handler
177;   Returns:
178;       Nothing
179;   Corrupts registers:
[258]180;       AX, BX
[86]181;--------------------------------------------------------------------
[258]182Interrupts_InstallHandlerToVectorInALFromCSSI:
183    mov     bl, 4                   ; Shift for DWORD offset, MUL smaller than other alternatives
184    mul     bl
185    xchg    ax, bx
[599]186    cli
[33]187    mov     [es:bx], si             ; Store offset
188    mov     [es:bx+2], cs           ; Store segment
[599]189    sti
[489]190.Interrupts_Return:
[33]191    ret
192
193
[398]194%ifdef MODULE_IRQ
[33]195;--------------------------------------------------------------------
196; Interrupts_UnmaskInterruptControllerForDriveInDSDI
197;   Parameters:
198;       DS:DI:  Ptr to DPT
199;   Returns:
200;       Nothing
201;   Corrupts registers:
202;       AX, BX, DX
203;--------------------------------------------------------------------
204Interrupts_UnmaskInterruptControllerForDriveInDSDI:
[294]205    eMOVZX  bx, [di+DPT.bIdevarsOffset]
[33]206    mov     al, [cs:bx+IDEVARS.bIRQ]
[86]207    test    al, al
208    jz      SHORT .Return   ; Interrupts disabled
[33]209    cmp     al, 8
[86]210    jb      SHORT .UnmaskLowIrqController
[162]211    ; Fall to .UnmaskHighIrqController
[33]212
213;--------------------------------------------------------------------
214; .UnmaskHighIrqController
215;   Parameters:
216;       AL:     IRQ number (8...15)
217;   Returns:
218;       Nothing
219;   Corrupts registers:
220;       AX, DX
221;--------------------------------------------------------------------
[97]222.UnmaskHighIrqController:
[33]223    sub     al, 8               ; Slave interrupt number
[152]224    mov     dx, SLAVE_8259_IMR
[33]225    call    .ClearBitFrom8259MaskRegister
226    mov     al, 2               ; Master IRQ 2 to allow slave IRQs
227    ; Fall to .UnmaskLowIrqController
228
229;--------------------------------------------------------------------
230; .UnmaskLowIrqController
231;   Parameters:
232;       AL:     IRQ number (0...7)
233;   Returns:
234;       Nothing
235;   Corrupts registers:
236;       AX, DX
237;--------------------------------------------------------------------
238.UnmaskLowIrqController:
[152]239    mov     dx, MASTER_8259_IMR
[33]240    ; Fall to .ClearBitFrom8259MaskRegister
241
242;--------------------------------------------------------------------
243; .ClearBitFrom8259MaskRegister
244;   Parameters:
245;       AL:     8259 interrupt index (0...7)
246;       DX:     Port address to Interrupt Mask Register
247;   Returns:
248;       Nothing
249;   Corrupts registers:
250;       AX
251;--------------------------------------------------------------------
252.ClearBitFrom8259MaskRegister:
253    push    cx
[592]254    xchg    cx, ax              ; IRQ index to CL
255    in      al, dx              ; Read Interrupt Mask Register
[596]256%ifdef USE_NEC_V
257    eCLR1   al, cl              ; Clear wanted bit
258%else
[589]259    mov     ch, ~1              ; Load bit mask to be rotated
260    rol     ch, cl              ; Rotate mask to correct position for clearing
[33]261    and     al, ch              ; Clear wanted bit
[596]262%endif
[33]263    out     dx, al              ; Write modified Interrupt Mask Register
264    pop     cx
[86]265.Return:
[33]266    ret
[398]267
268%endif ; MODULE_IRQ
Note: See TracBrowser for help on using the repository browser.