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

Last change on this file since 268 was 258, checked in by gregli@…, 13 years ago

Added floppy drive emulation over the serial connection (MODULE_SERIAL_FLOPPY). Along the way, various optimizations were made to stay within the 8K ROM size target. Also, serial code now returns the number of sectors transferred.

File size: 6.8 KB
RevLine 
[90]1; Project name : XTIDE Universal BIOS
[33]2; Description : Functions for initializing the BIOS.
3
4; Section containing code
5SECTION .text
6
7;--------------------------------------------------------------------
8; Interrupts_InitializeInterruptVectors
9; Parameters:
10; DS: RAMVARS segment
11; ES: BDA and Interrupt Vector segment (zero)
12; Returns:
13; Nothing
14; Corrupts registers:
15; All except segments
[86]16;--------------------------------------------------------------------
[33]17Interrupts_InitializeInterruptVectors:
[97]18 ; Fall to .InitializeInt13hAnd40h
[33]19
20;--------------------------------------------------------------------
[97]21; .InitializeInt13hAnd40h
[33]22; Parameters:
23; DS: RAMVARS segment
24; ES: BDA and Interrupt Vector segment (zero)
25; Returns:
26; Nothing
27; Corrupts registers:
28; AX, BX, CX, DX, SI, DI
[86]29;--------------------------------------------------------------------
[97]30.InitializeInt13hAnd40h:
[181]31 mov ax, [es:BIOS_DISK_INTERRUPT_13h*4+2]; Load old INT 13h segment
32 mov [RAMVARS.fpOldI13h+2], ax ; Store old INT 13h segment
33 xchg dx, ax
[152]34 mov ax, [es:BIOS_DISK_INTERRUPT_13h*4] ; Load old INT 13h offset
[33]35 mov [RAMVARS.fpOldI13h], ax ; Store old INT 13h offset
[181]36
[33]37 ; Only store INT 13h handler to 40h if 40h is not already installed.
38 ; At least AMI BIOS for 286 stores 40h handler by itself and calls
39 ; 40h from 13h. That system locks to infinite loop if we copy 13h to 40h.
40 call FloppyDrive_IsInt40hInstalled
[243]41 jc SHORT .Int40hAlreadyInstalled
[152]42 mov [es:BIOS_DISKETTE_INTERRUPT_40h*4], ax ; Store old INT 13h offset
43 mov [es:BIOS_DISKETTE_INTERRUPT_40h*4+2], dx ; Store old INT 13h segment
[243]44.Int40hAlreadyInstalled:
[258]45
46 mov al, BIOS_DISK_INTERRUPT_13h ; INT 13h interrupt vector offset
47 mov si, Int13h_DiskFunctionsHandler ; Interrupt handler offset
48 call Interrupts_InstallHandlerToVectorInALFromCSSI
[97]49 ; Fall to .InitializeHardwareIrqHandlers
[33]50
51;--------------------------------------------------------------------
[97]52; .InitializeHardwareIrqHandlers
[33]53; Parameters:
54; ES: BDA and Interrupt Vector segment (zero)
55; Returns:
56; Nothing
57; Corrupts registers:
[258]58; BX, CX, DX, SI, DI, AX
[86]59;--------------------------------------------------------------------
[97]60.InitializeHardwareIrqHandlers:
[33]61 call RamVars_GetIdeControllerCountToCX
62 mov di, ROMVARS.ideVars0 ; CS:SI points to first IDEVARS
63.IdeControllerLoop:
[258]64 mov al, BYTE [cs:di+IDEVARS.bIRQ]
[33]65 add di, BYTE IDEVARS_size ; Increment to next controller
66 call .InstallLowOrHighIrqHandler
67 loop .IdeControllerLoop
[86]68.Return:
69 ret ; This ret is shared with .InstallLowOrHighIrqHandler
[33]70
71;--------------------------------------------------------------------
72; .InstallLowOrHighIrqHandler
73; Parameters:
[258]74; AL: IRQ number, 0 if IRQ disabled
[33]75; ES: BDA and Interrupt Vector segment (zero)
76; Returns:
77; Nothing
78; Corrupts registers:
79; BX, SI
[86]80;--------------------------------------------------------------------
[33]81.InstallLowOrHighIrqHandler:
[258]82 test al, al
[86]83 jz SHORT .Return ; IRQ not used
[258]84 cmp al, 8
[86]85 jb SHORT .InstallLowIrqHandler
[162]86 ; Fall to .InstallHighIrqHandler
[33]87
88;--------------------------------------------------------------------
89; .InstallHighIrqHandler
90; Parameters:
91; BX: IRQ number (8...15)
92; ES: BDA and Interrupt Vector segment (zero)
93; Returns:
94; Nothing
95; Corrupts registers:
[258]96; AL, BX, SI
[86]97;--------------------------------------------------------------------
[97]98.InstallHighIrqHandler:
[258]99 add al, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8 ; Interrupt vector number
[150]100 mov si, IdeIrq_InterruptServiceRoutineForIrqs8to15
[258]101 jmp SHORT Interrupts_InstallHandlerToVectorInALFromCSSI
[33]102
103;--------------------------------------------------------------------
104; .InstallLowIrqHandler
105; Parameters:
[258]106; AL: IRQ number (0...7)
[33]107; ES: BDA and Interrupt Vector segment (zero)
108; Returns:
109; Nothing
110; Corrupts registers:
[258]111; AL, BX, SI
[86]112;--------------------------------------------------------------------
[33]113.InstallLowIrqHandler:
[258]114 add al, BYTE HARDWARE_IRQ_0_INTERRUPT_08h ; Interrupt vector number
[150]115 mov si, IdeIrq_InterruptServiceRoutineForIrqs2to7
[258]116 ; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
[33]117
118
119;--------------------------------------------------------------------
[258]120; Interrupts_InstallHandlerToVectorInALFromCSSI
[33]121; Parameters:
[258]122; AL: Interrupt vector number (for example 13h)
[33]123; ES: BDA and Interrupt Vector segment (zero)
124; CS:SI: Ptr to interrupt handler
125; Returns:
126; Nothing
127; Corrupts registers:
[258]128; AX, BX
[86]129;--------------------------------------------------------------------
[258]130Interrupts_InstallHandlerToVectorInALFromCSSI:
131 mov bl, 4 ; Shift for DWORD offset, MUL smaller than other alternatives
132 mul bl
133 xchg ax, bx
[33]134 mov [es:bx], si ; Store offset
135 mov [es:bx+2], cs ; Store segment
136 ret
137
138
139;--------------------------------------------------------------------
140; Interrupts_UnmaskInterruptControllerForDriveInDSDI
141; Parameters:
142; DS:DI: Ptr to DPT
143; Returns:
144; Nothing
145; Corrupts registers:
146; AX, BX, DX
147;--------------------------------------------------------------------
148Interrupts_UnmaskInterruptControllerForDriveInDSDI:
[150]149 eMOVZX bx, BYTE [di+DPT.bIdevarsOffset]
[33]150 mov al, [cs:bx+IDEVARS.bIRQ]
[86]151 test al, al
152 jz SHORT .Return ; Interrupts disabled
[33]153 cmp al, 8
[86]154 jb SHORT .UnmaskLowIrqController
[162]155 ; Fall to .UnmaskHighIrqController
[33]156
157;--------------------------------------------------------------------
158; .UnmaskHighIrqController
159; Parameters:
160; AL: IRQ number (8...15)
161; Returns:
162; Nothing
163; Corrupts registers:
164; AX, DX
165;--------------------------------------------------------------------
[97]166.UnmaskHighIrqController:
[33]167 sub al, 8 ; Slave interrupt number
[152]168 mov dx, SLAVE_8259_IMR
[33]169 call .ClearBitFrom8259MaskRegister
170 mov al, 2 ; Master IRQ 2 to allow slave IRQs
171 ; Fall to .UnmaskLowIrqController
172
173;--------------------------------------------------------------------
174; .UnmaskLowIrqController
175; Parameters:
176; AL: IRQ number (0...7)
177; Returns:
178; Nothing
179; Corrupts registers:
180; AX, DX
181;--------------------------------------------------------------------
182.UnmaskLowIrqController:
[152]183 mov dx, MASTER_8259_IMR
[33]184 ; Fall to .ClearBitFrom8259MaskRegister
185
186;--------------------------------------------------------------------
187; .ClearBitFrom8259MaskRegister
188; Parameters:
189; AL: 8259 interrupt index (0...7)
190; DX: Port address to Interrupt Mask Register
191; Returns:
192; Nothing
193; Corrupts registers:
194; AX
195;--------------------------------------------------------------------
196.ClearBitFrom8259MaskRegister:
197 push cx
198 xchg ax, cx ; IRQ index to CL
199 mov ch, 1 ; Load 1 to be shifted
200 shl ch, cl ; Shift bit to correct position
201 not ch ; Invert to create bit mask for clearing
202 in al, dx ; Read Interrupt Mask Register
203 and al, ch ; Clear wanted bit
204 out dx, al ; Write modified Interrupt Mask Register
205 pop cx
[86]206.Return:
[33]207 ret
Note: See TracBrowser for help on using the repository browser.