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

Last change on this file since 595 was 594, checked in by Tomi Tilli, 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.