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

Last change on this file was 621, checked in by krille_n_, 2 years ago

Changes:

  • Fixed three different bugs all causing the boot menu to show drives using IRQs even though the BIOS had been built without MODULE_IRQ.
  • Fixed two bugs in XTIDECFG where loading a BIOS from file and then loading the old settings from EEPROM would
    • overwrite ROMVARS.wFlags in the loaded BIOS file (in RAM). The possibly resulting mismatch of module flags could make it impossible to change settings for modules included in the BIOS or allow changing settings for modules not included in the BIOS.
    • not copy the color theme over to the loaded BIOS.
  • Also fixed two very minor bugs in XTIDECFG in BiosFile_LoadFileFromDSSItoRamBuffer and BiosFile_SaveRamBufferToFileInDSSI where the error handling in these routines would close whatever file handle that happened to match the error code returned by DOS in AX.
  • Made significant changes to the new flash ROM programming routines to reduce the size. Also fixed a minor bug that would cause the second verification to be skipped and return success when programming a 64 KB block of data.
  • Changed the custom BIOS build file names to the 8.3 format.
  • Changed some help strings in XTIDECFG to clarify things.
  • Other minor optimizations and fixes.
File size: 9.0 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-2013 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 unless
25; MODULE_DRIVEXLATE has been included in the BIOS.
26;
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
35;--------------------------------------------------------------------
36Interrupts_InitializeInterruptVectors:
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.
44%ifndef MODULE_DRIVEXLATE
45    cmp     BYTE [RAMVARS.bDrvCnt], 0
46    je      SHORT Interrupts_InstallHandlerToVectorInALFromCSSI.Interrupts_Return
47%endif
48    ; Fall to .InitializeInt13hAnd40h
49
50;--------------------------------------------------------------------
51; .InitializeInt13hAnd40h
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
59;--------------------------------------------------------------------
60.InitializeInt13hAnd40h:
61%ifdef MODULE_MFM_COMPATIBILITY
62    mov     ax, [es:BIOS_DISK_INTERRUPT_13h*4+2]; Load old INT 13h segment
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
72    mov     [RAMVARS.fpOldI13h+2], ax           ; Store old INT 13h segment
73    xchg    dx, ax
74    mov     ax, [es:BIOS_DISK_INTERRUPT_13h*4]  ; Load old INT 13h offset
75    mov     [RAMVARS.fpOldI13h], ax             ; Store old INT 13h offset
76%endif
77
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
80    ; 40h from 13h. That system locks to infinite loop if we blindly copy 13h to 40h.
81    call    FloppyDrive_IsInt40hInstalled
82    jc      SHORT .Int40hAlreadyInstalled
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
85.Int40hAlreadyInstalled:
86
87    mov     al, BIOS_DISK_INTERRUPT_13h         ; INT 13h interrupt vector offset
88%ifdef RELOCATE_INT13H_STACK
89    mov     si, Int13h_DiskFunctionsHandlerWithStackChange
90%else
91    mov     si, Int13h_DiskFunctionsHandler
92%endif
93
94%ifndef MODULE_IRQ
95    ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
96%else
97    call    Interrupts_InstallHandlerToVectorInALFromCSSI
98    ; Fall to .InitializeHardwareIrqHandlers
99
100;--------------------------------------------------------------------
101; .InitializeHardwareIrqHandlers
102;   Parameters:
103;       ES:     BDA and Interrupt Vector segment (zero)
104;   Returns:
105;       Nothing
106;   Corrupts registers:
107;       BX, CX, DX, SI, DI, AX
108;--------------------------------------------------------------------
109.InitializeHardwareIrqHandlers:
110    call    RamVars_GetIdeControllerCountToCX
111    mov     di, ROMVARS.ideVars0+IDEVARS.bIRQ
112.IdeControllerLoop:
113    mov     al, [cs:di]
114    add     di, BYTE IDEVARS_size           ; Increment to next controller
115    call    .InstallLowOrHighIrqHandler
116    loop    .IdeControllerLoop
117.Return:
118    ret     ; This ret is shared with .InstallLowOrHighIrqHandler
119
120;--------------------------------------------------------------------
121; .InstallLowOrHighIrqHandler
122;   Parameters:
123;       AL:     IRQ number, 0 if IRQ disabled
124;       ES:     BDA and Interrupt Vector segment (zero)
125;   Returns:
126;       Nothing
127;   Corrupts registers:
128;       BX, SI
129;--------------------------------------------------------------------
130.InstallLowOrHighIrqHandler:
131    test    al, al
132    jz      SHORT .Return   ; IRQ not used
133%ifdef USE_AT
134    cmp     al, 8
135    jb      SHORT .InstallLowIrqHandler
136    ; Fall to .InstallHighIrqHandler
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:
146;       AL, BX, SI
147;--------------------------------------------------------------------
148.InstallHighIrqHandler:
149    add     al, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8   ; Interrupt vector number
150    mov     si, IdeIrq_InterruptServiceRoutineForIrqs8to15
151    jmp     SHORT Interrupts_InstallHandlerToVectorInALFromCSSI
152%endif ; USE_AT
153
154;--------------------------------------------------------------------
155; .InstallLowIrqHandler
156;   Parameters:
157;       AL:     IRQ number (0...7)
158;       ES:     BDA and Interrupt Vector segment (zero)
159;   Returns:
160;       Nothing
161;   Corrupts registers:
162;       AL, BX, SI
163;--------------------------------------------------------------------
164.InstallLowIrqHandler:
165    add     al, BYTE HARDWARE_IRQ_0_INTERRUPT_08h       ; Interrupt vector number
166    mov     si, IdeIrq_InterruptServiceRoutineForIrqs2to7
167    ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
168%endif ; MODULE_IRQ
169
170
171;--------------------------------------------------------------------
172; Interrupts_InstallHandlerToVectorInALFromCSSI
173;   Parameters:
174;       AL:     Interrupt vector number (for example 13h)
175;       ES:     BDA and Interrupt Vector segment (zero)
176;       CS:SI:  Ptr to interrupt handler
177;   Returns:
178;       Nothing
179;   Corrupts registers:
180;       AX, BX
181;--------------------------------------------------------------------
182Interrupts_InstallHandlerToVectorInALFromCSSI:
183    mov     bl, 4                   ; Shift for DWORD offset, MUL smaller than other alternatives
184    mul     bl
185    xchg    ax, bx
186    cli
187    mov     [es:bx], si             ; Store offset
188    mov     [es:bx+2], cs           ; Store segment
189    sti
190.Interrupts_Return:
191    ret
192
193
194%ifdef MODULE_IRQ
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:
205    eMOVZX  bx, [di+DPT.bIdevarsOffset]     ; Clears CF on pre-386 CPUs
206%ifndef USE_386
207%ifdef USE_UNDOC_INTEL
208    salc
209    or      al, [cs:bx+IDEVARS.bIRQ]
210%else
211    mov     al, [cs:bx+IDEVARS.bIRQ]
212    test    al, al
213%endif
214%else ; USE_386
215    mov     al, [cs:bx+IDEVARS.bIRQ]
216    test    al, al
217%endif
218    jz      SHORT .Return   ; Interrupts disabled
219    cmp     al, 8
220    jb      SHORT .UnmaskLowIrqController
221    ; Fall to .UnmaskHighIrqController
222
223;--------------------------------------------------------------------
224; .UnmaskHighIrqController
225;   Parameters:
226;       AL:     IRQ number (8...15)
227;   Returns:
228;       Nothing
229;   Corrupts registers:
230;       AX, DX
231;--------------------------------------------------------------------
232.UnmaskHighIrqController:
233    sub     al, 8               ; Slave interrupt number
234    mov     dx, SLAVE_8259_IMR
235    call    .ClearBitFrom8259MaskRegister
236    mov     al, 2               ; Master IRQ 2 to allow slave IRQs
237    ; Fall to .UnmaskLowIrqController
238
239;--------------------------------------------------------------------
240; .UnmaskLowIrqController
241;   Parameters:
242;       AL:     IRQ number (0...7)
243;   Returns:
244;       Nothing
245;   Corrupts registers:
246;       AX, DX
247;--------------------------------------------------------------------
248.UnmaskLowIrqController:
249    mov     dx, MASTER_8259_IMR
250    ; Fall to .ClearBitFrom8259MaskRegister
251
252;--------------------------------------------------------------------
253; .ClearBitFrom8259MaskRegister
254;   Parameters:
255;       AL:     8259 interrupt index (0...7)
256;       DX:     Port address to Interrupt Mask Register
257;   Returns:
258;       Nothing
259;   Corrupts registers:
260;       AX
261;--------------------------------------------------------------------
262.ClearBitFrom8259MaskRegister:
263    push    cx
264    xchg    cx, ax              ; IRQ index to CL
265    in      al, dx              ; Read Interrupt Mask Register
266%ifdef USE_NEC_V
267    eCLR1   al, cl              ; Clear wanted bit
268%else
269    mov     ch, ~1              ; Load bit mask to be rotated
270    rol     ch, cl              ; Rotate mask to correct position for clearing
271    and     al, ch              ; Clear wanted bit
272%endif
273    out     dx, al              ; Write modified Interrupt Mask Register
274    pop     cx
275.Return:
276    ret
277
278%endif ; MODULE_IRQ
Note: See TracBrowser for help on using the repository browser.