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

Last change on this file since 502 was 501, checked in by aitotat@…, 12 years ago

Changes to XTIDE Universal BIOS:

  • XTIDE rev 2 and modded XTIDE rev 1 work again (fixed A0<->A3 swap when accessing Control Block Registers).
  • System INT 13h handler is no longer copied to INT 40h (testing if something uses INT 40h).
  • Removed controller hardware reset: now AH=0h and AH=Dh will only re-initialize drives (SB16 Tertiary and Quaternary IDE should now be safe to use when using Secondary IDE).
File size: 8.5 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
[376]6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2012 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.
[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
[501]66 ; NOTE! Installing INT 40h handler is currently uncommented to test
67 ; if it is really needed. I suspect that it is not. Many bytes can be
68 ; saved if INT 40h related code can be removed.
69%if 0
70
[33]71 ; Only store INT 13h handler to 40h if 40h is not already installed.
72 ; At least AMI BIOS for 286 stores 40h handler by itself and calls
73 ; 40h from 13h. That system locks to infinite loop if we copy 13h to 40h.
74 call FloppyDrive_IsInt40hInstalled
[243]75 jc SHORT .Int40hAlreadyInstalled
[152]76 mov [es:BIOS_DISKETTE_INTERRUPT_40h*4], ax ; Store old INT 13h offset
77 mov [es:BIOS_DISKETTE_INTERRUPT_40h*4+2], dx ; Store old INT 13h segment
[243]78.Int40hAlreadyInstalled:
[501]79%endif ; 0
[258]80
81 mov al, BIOS_DISK_INTERRUPT_13h ; INT 13h interrupt vector offset
[417]82 mov si, Int13h_DiskFunctionsHandler
83%ifdef RELOCATE_INT13H_STACK
84 test BYTE [cs:ROMVARS.wFlags], FLG_ROMVARS_FULLMODE
85 eCMOVNZ si, Int13h_DiskFunctionsHandlerWithStackChange
86%endif
[392]87
[398]88%ifndef MODULE_IRQ
89 ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
90%else
[392]91 call Interrupts_InstallHandlerToVectorInALFromCSSI
[97]92 ; Fall to .InitializeHardwareIrqHandlers
[33]93
94;--------------------------------------------------------------------
[97]95; .InitializeHardwareIrqHandlers
[33]96; Parameters:
97; ES: BDA and Interrupt Vector segment (zero)
98; Returns:
99; Nothing
100; Corrupts registers:
[258]101; BX, CX, DX, SI, DI, AX
[86]102;--------------------------------------------------------------------
[97]103.InitializeHardwareIrqHandlers:
[33]104 call RamVars_GetIdeControllerCountToCX
[491]105 mov di, ROMVARS.ideVars0+IDEVARS.bIRQ ; CS:SI points to first IDEVARS
[33]106.IdeControllerLoop:
[491]107 mov al, [cs:di]
[33]108 add di, BYTE IDEVARS_size ; Increment to next controller
109 call .InstallLowOrHighIrqHandler
110 loop .IdeControllerLoop
[86]111.Return:
112 ret ; This ret is shared with .InstallLowOrHighIrqHandler
[33]113
114;--------------------------------------------------------------------
115; .InstallLowOrHighIrqHandler
116; Parameters:
[258]117; AL: IRQ number, 0 if IRQ disabled
[33]118; ES: BDA and Interrupt Vector segment (zero)
119; Returns:
120; Nothing
121; Corrupts registers:
122; BX, SI
[86]123;--------------------------------------------------------------------
[33]124.InstallLowOrHighIrqHandler:
[258]125 test al, al
[86]126 jz SHORT .Return ; IRQ not used
[258]127 cmp al, 8
[86]128 jb SHORT .InstallLowIrqHandler
[162]129 ; Fall to .InstallHighIrqHandler
[33]130
131;--------------------------------------------------------------------
132; .InstallHighIrqHandler
133; Parameters:
134; BX: IRQ number (8...15)
135; ES: BDA and Interrupt Vector segment (zero)
136; Returns:
137; Nothing
138; Corrupts registers:
[258]139; AL, BX, SI
[86]140;--------------------------------------------------------------------
[97]141.InstallHighIrqHandler:
[258]142 add al, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8 ; Interrupt vector number
[150]143 mov si, IdeIrq_InterruptServiceRoutineForIrqs8to15
[258]144 jmp SHORT Interrupts_InstallHandlerToVectorInALFromCSSI
[33]145
146;--------------------------------------------------------------------
147; .InstallLowIrqHandler
148; Parameters:
[258]149; AL: IRQ number (0...7)
[33]150; ES: BDA and Interrupt Vector segment (zero)
151; Returns:
152; Nothing
153; Corrupts registers:
[258]154; AL, BX, SI
[86]155;--------------------------------------------------------------------
[33]156.InstallLowIrqHandler:
[258]157 add al, BYTE HARDWARE_IRQ_0_INTERRUPT_08h ; Interrupt vector number
[150]158 mov si, IdeIrq_InterruptServiceRoutineForIrqs2to7
[258]159 ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
[398]160%endif ; MODULE_IRQ
[33]161
162
163;--------------------------------------------------------------------
[258]164; Interrupts_InstallHandlerToVectorInALFromCSSI
[33]165; Parameters:
[258]166; AL: Interrupt vector number (for example 13h)
[33]167; ES: BDA and Interrupt Vector segment (zero)
168; CS:SI: Ptr to interrupt handler
169; Returns:
170; Nothing
171; Corrupts registers:
[258]172; AX, BX
[86]173;--------------------------------------------------------------------
[258]174Interrupts_InstallHandlerToVectorInALFromCSSI:
175 mov bl, 4 ; Shift for DWORD offset, MUL smaller than other alternatives
176 mul bl
177 xchg ax, bx
[33]178 mov [es:bx], si ; Store offset
179 mov [es:bx+2], cs ; Store segment
[489]180.Interrupts_Return:
[33]181 ret
182
183
[398]184%ifdef MODULE_IRQ
[33]185;--------------------------------------------------------------------
186; Interrupts_UnmaskInterruptControllerForDriveInDSDI
187; Parameters:
188; DS:DI: Ptr to DPT
189; Returns:
190; Nothing
191; Corrupts registers:
192; AX, BX, DX
193;--------------------------------------------------------------------
194Interrupts_UnmaskInterruptControllerForDriveInDSDI:
[294]195 eMOVZX bx, [di+DPT.bIdevarsOffset]
[33]196 mov al, [cs:bx+IDEVARS.bIRQ]
[86]197 test al, al
198 jz SHORT .Return ; Interrupts disabled
[33]199 cmp al, 8
[86]200 jb SHORT .UnmaskLowIrqController
[162]201 ; Fall to .UnmaskHighIrqController
[33]202
203;--------------------------------------------------------------------
204; .UnmaskHighIrqController
205; Parameters:
206; AL: IRQ number (8...15)
207; Returns:
208; Nothing
209; Corrupts registers:
210; AX, DX
211;--------------------------------------------------------------------
[97]212.UnmaskHighIrqController:
[33]213 sub al, 8 ; Slave interrupt number
[152]214 mov dx, SLAVE_8259_IMR
[33]215 call .ClearBitFrom8259MaskRegister
216 mov al, 2 ; Master IRQ 2 to allow slave IRQs
217 ; Fall to .UnmaskLowIrqController
218
219;--------------------------------------------------------------------
220; .UnmaskLowIrqController
221; Parameters:
222; AL: IRQ number (0...7)
223; Returns:
224; Nothing
225; Corrupts registers:
226; AX, DX
227;--------------------------------------------------------------------
228.UnmaskLowIrqController:
[152]229 mov dx, MASTER_8259_IMR
[33]230 ; Fall to .ClearBitFrom8259MaskRegister
231
232;--------------------------------------------------------------------
233; .ClearBitFrom8259MaskRegister
234; Parameters:
235; AL: 8259 interrupt index (0...7)
236; DX: Port address to Interrupt Mask Register
237; Returns:
238; Nothing
239; Corrupts registers:
240; AX
241;--------------------------------------------------------------------
242.ClearBitFrom8259MaskRegister:
243 push cx
244 xchg ax, cx ; IRQ index to CL
245 mov ch, 1 ; Load 1 to be shifted
246 shl ch, cl ; Shift bit to correct position
247 not ch ; Invert to create bit mask for clearing
248 in al, dx ; Read Interrupt Mask Register
249 and al, ch ; Clear wanted bit
250 out dx, al ; Write modified Interrupt Mask Register
251 pop cx
[86]252.Return:
[33]253 ret
[398]254
255%endif ; MODULE_IRQ
Note: See TracBrowser for help on using the repository browser.