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

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

Previosly committed flash fix for configurator was incomplete. Now fixed properly.
Added MODULE_MFM_COMPATIBILITY.

File size: 8.7 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
67   
68    mov     [RAMVARS.fpOldI13h+2], cs
69    mov     WORD [RAMVARS.fpOldI13h], Int13hMFMcompatibilityHandler 
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
[33]186    mov     [es:bx], si             ; Store offset
187    mov     [es:bx+2], cs           ; Store segment
[489]188.Interrupts_Return:
[33]189    ret
190
191
[398]192%ifdef MODULE_IRQ
[33]193;--------------------------------------------------------------------
194; Interrupts_UnmaskInterruptControllerForDriveInDSDI
195;   Parameters:
196;       DS:DI:  Ptr to DPT
197;   Returns:
198;       Nothing
199;   Corrupts registers:
200;       AX, BX, DX
201;--------------------------------------------------------------------
202Interrupts_UnmaskInterruptControllerForDriveInDSDI:
[294]203    eMOVZX  bx, [di+DPT.bIdevarsOffset]
[33]204    mov     al, [cs:bx+IDEVARS.bIRQ]
[86]205    test    al, al
206    jz      SHORT .Return   ; Interrupts disabled
[33]207    cmp     al, 8
[86]208    jb      SHORT .UnmaskLowIrqController
[162]209    ; Fall to .UnmaskHighIrqController
[33]210
211;--------------------------------------------------------------------
212; .UnmaskHighIrqController
213;   Parameters:
214;       AL:     IRQ number (8...15)
215;   Returns:
216;       Nothing
217;   Corrupts registers:
218;       AX, DX
219;--------------------------------------------------------------------
[97]220.UnmaskHighIrqController:
[33]221    sub     al, 8               ; Slave interrupt number
[152]222    mov     dx, SLAVE_8259_IMR
[33]223    call    .ClearBitFrom8259MaskRegister
224    mov     al, 2               ; Master IRQ 2 to allow slave IRQs
225    ; Fall to .UnmaskLowIrqController
226
227;--------------------------------------------------------------------
228; .UnmaskLowIrqController
229;   Parameters:
230;       AL:     IRQ number (0...7)
231;   Returns:
232;       Nothing
233;   Corrupts registers:
234;       AX, DX
235;--------------------------------------------------------------------
236.UnmaskLowIrqController:
[152]237    mov     dx, MASTER_8259_IMR
[33]238    ; Fall to .ClearBitFrom8259MaskRegister
239
240;--------------------------------------------------------------------
241; .ClearBitFrom8259MaskRegister
242;   Parameters:
243;       AL:     8259 interrupt index (0...7)
244;       DX:     Port address to Interrupt Mask Register
245;   Returns:
246;       Nothing
247;   Corrupts registers:
248;       AX
249;--------------------------------------------------------------------
250.ClearBitFrom8259MaskRegister:
251    push    cx
[592]252    xchg    cx, ax              ; IRQ index to CL
253    in      al, dx              ; Read Interrupt Mask Register
[589]254    mov     ch, ~1              ; Load bit mask to be rotated
255    rol     ch, cl              ; Rotate mask to correct position for clearing
[33]256    and     al, ch              ; Clear wanted bit
257    out     dx, al              ; Write modified Interrupt Mask Register
258    pop     cx
[86]259.Return:
[33]260    ret
[398]261
262%endif ; MODULE_IRQ
Note: See TracBrowser for help on using the repository browser.