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

Last change on this file since 534 was 530, checked in by aitotat@…, 11 years ago

Changes to XTIDE Universal BIOS:

  • AT builds again copy old INT 13h handler to 40h. It turned out it is needed, by XTIDE Universal BIOS at least (fixes disappearing floppy drive hotkey button when booting starts).
  • AH=48h no longer returns P-CHS parameteres for drives with more than 15,482,880 sectors (now works like described on Phoenix specification).
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
[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;--------------------------------------------------------------------
[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
[530]68    ; 40h from 13h. That system locks to infinite loop if we blindly copy 13h to 40h.
[33]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
[522]76%ifdef RELOCATE_INT13H_STACK
77    mov     si, Int13h_DiskFunctionsHandlerWithStackChange
78%else
[417]79    mov     si, Int13h_DiskFunctionsHandler
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.