source: xtideuniversalbios/tags/XTIDE_Universal_BIOS_v1.1.1/Src/Initialization/Initialize.asm@ 309

Last change on this file since 309 was 23, checked in by Tomi Tilli, 14 years ago

Booting is now possible from hard disks if floppy controller reset fails.
AH=00h, Disk Controller Reset now returns error code for the requested drive only.

File size: 12.5 KB
Line 
1; File name : Initialize.asm
2; Project name : IDE BIOS
3; Created date : 23.3.2010
4; Last update : 1.7.2010
5; Author : Tomi Tilli
6; Description : Functions for initializing the BIOS.
7
8; Section containing code
9SECTION .text
10
11;--------------------------------------------------------------------
12; Initializes the BIOS.
13; This function is called from main BIOS ROM search routine.
14;
15; Initialize_FromMainBiosRomSearch
16; Parameters:
17; Nothing
18; Returns:
19; Nothing
20; Corrupts registers:
21; Nothing
22;--------------------------------------------------------------------
23ALIGN JUMP_ALIGN
24Initialize_FromMainBiosRomSearch:
25 pushf
26 push es
27 push ds
28 ePUSHA
29
30 call Initialize_ShouldSkip
31 jc SHORT .ReturnFromRomInit
32
33 ePUSH_T ax, .ReturnFromRomInit ; Push return address
34 test BYTE [cs:ROMVARS.wFlags], FLG_ROMVARS_LATE
35 jnz SHORT Initialize_PrepareLateInitialization
36 jmp SHORT Initialize_AndDetectDrives
37
38ALIGN JUMP_ALIGN
39.ReturnFromRomInit:
40 ePOPA
41 pop ds
42 pop es
43 popf
44 retf
45
46
47;--------------------------------------------------------------------
48; Checks if user wants to skip ROM initialization.
49;
50; Initialize_ShouldSkip
51; Parameters:
52; Nothing
53; Returns:
54; CF: Set if ROM initialization is to be skipped
55; Cleared to continue ROM initialization
56; Corrupts registers:
57; AX, DS
58;--------------------------------------------------------------------
59ALIGN JUMP_ALIGN
60Initialize_ShouldSkip:
61 sti ; Enable interrupts
62 LOAD_BDA_SEGMENT_TO ds, ax
63 mov al, [BDA.bKBFlgs1] ; Load shift flags
64 eSHR_IM al, 3 ; Set CF if CTRL is held down
65 ret
66
67
68;--------------------------------------------------------------------
69; Installs INT 19h boot loader handler for late initialization.
70;
71; Initialize_PrepareLateInitialization
72; Parameters:
73; Nothing
74; Returns:
75; Nothing
76; Corrupts registers:
77; BX, SI, ES
78;--------------------------------------------------------------------
79ALIGN JUMP_ALIGN
80Initialize_PrepareLateInitialization:
81 LOAD_BDA_SEGMENT_TO es, bx
82 mov bl, INTV_BOOTSTRAP
83 mov si, Int19h_LateInitialization
84 ; Fall to Initialize_InstallInterruptHandler
85
86;--------------------------------------------------------------------
87; Installs any interrupt handler.
88;
89; Initialize_InstallInterruptHandler
90; Parameters:
91; BX: Interrupt vector number (for example 13h)
92; ES: BDA and Interrupt Vector segment (zero)
93; CS:SI: Ptr to interrupt handler
94; Returns:
95; Nothing
96; Corrupts registers:
97; BX
98;--------------------------------------------------------------------
99ALIGN JUMP_ALIGN
100Initialize_InstallInterruptHandler:
101 eSHL_IM bx, 2 ; Shift for DWORD offset
102 mov [es:bx], si ; Store offset
103 mov [es:bx+2], cs ; Store segment
104 ret
105
106
107;--------------------------------------------------------------------
108; Initializes the BIOS variables and detects IDE drives.
109;
110; Initialize_AndDetectDrives
111; Parameters:
112; Nothing
113; Returns:
114; Nothing
115; Corrupts registers:
116; All, including segments
117;--------------------------------------------------------------------
118ALIGN JUMP_ALIGN
119Initialize_AndDetectDrives:
120 call DetectPrint_RomFoundAtSegment
121 call RamVars_Initialize
122 call RamVars_GetSegmentToDS
123 LOAD_BDA_SEGMENT_TO es, ax
124 call Initialize_InterruptVectors
125 call DetectDrives_FromAllIDEControllers
126 call CompatibleDPT_CreateForDrives80hAnd81h
127 jmp Initialize_ResetDetectedDrives
128
129
130;--------------------------------------------------------------------
131; Initializes Interrupt Vectors.
132;
133; Initialize_InterruptVectors
134; Parameters:
135; DS: RAMVARS segment
136; ES: BDA and Interrupt Vector segment (zero)
137; Returns:
138; Nothing
139; Corrupts registers:
140; All except segments
141;--------------------------------------------------------------------
142ALIGN JUMP_ALIGN
143Initialize_InterruptVectors:
144 call Initialize_Int13hAnd40h
145 call Initialize_Int19h
146 jmp SHORT Initialize_HardwareIrqHandlers
147
148
149;--------------------------------------------------------------------
150; Initializes INT 13h and 40h handlers for Hard Disk and
151; Floppy Drive BIOS functions.
152;
153; Initialize_Int13hAnd40h
154; Parameters:
155; DS: RAMVARS segment
156; ES: BDA and Interrupt Vector segment (zero)
157; Returns:
158; Nothing
159; Corrupts registers:
160; AX, BX, CX, DX, SI, DI
161;--------------------------------------------------------------------
162ALIGN JUMP_ALIGN
163Initialize_Int13hAnd40h:
164 mov ax, [es:INTV_DISK_FUNC*4] ; Load old INT 13h offset
165 mov dx, [es:INTV_DISK_FUNC*4+2] ; Load old INT 13h segment
166 mov [RAMVARS.fpOldI13h], ax ; Store old INT 13h offset
167 mov [RAMVARS.fpOldI13h+2], dx ; Store old INT 13h segment
168 mov bx, INTV_DISK_FUNC ; INT 13h interrupt vector offset
169 mov si, Int13h_DiskFunctions ; Interrupt handler offset
170 call Initialize_InstallInterruptHandler
171
172 ; Only store INT 13h handler to 40h if 40h is not already installed.
173 ; At least AMI BIOS for 286 stores 40h handler by itself and calls
174 ; 40h from 13h. That system locks to infinite loop if we copy 13h to 40h.
175 call FloppyDrive_IsInt40hInstalled
176 jnc SHORT Initialize_Int40h
177 ret
178
179;--------------------------------------------------------------------
180; Initializes INT 40h handler for Floppy Drive BIOS functions.
181;
182; Initialize_Int40h
183; Parameters:
184; DX:AX: Ptr to old INT 13h handler
185; ES: BDA and Interrupt Vector segment (zero)
186; Returns:
187; Nothing
188; Corrupts registers:
189; Nothing
190;--------------------------------------------------------------------
191ALIGN JUMP_ALIGN
192Initialize_Int40h:
193 mov [es:INTV_FLOPPY_FUNC*4], ax ; Store offset
194 mov [es:INTV_FLOPPY_FUNC*4+2], dx ; Store segment
195 ret
196
197
198;--------------------------------------------------------------------
199; Initializes INT 19h handler for boot loader.
200;
201; Initialize_Int19h
202; Parameters:
203; DS: RAMVARS segment
204; ES: BDA and Interrupt Vector segment (zero)
205; Returns:
206; Nothing
207; Corrupts registers:
208; BX, SI
209;--------------------------------------------------------------------
210ALIGN JUMP_ALIGN
211Initialize_Int19h:
212 eMOVZX bx, [cs:ROMVARS.bBootLdrType] ; Load boot loader type
213 mov si, INTV_BOOTSTRAP ; 19h
214 xchg bx, si ; SI=Loader type, BX=19h
215 jmp [cs:si+.rgwSetupBootLoader] ; Jump to install selected loader
216ALIGN WORD_ALIGN
217.rgwSetupBootLoader:
218 dw .SetupBootMenuLoader ; BOOTLOADER_TYPE_MENU
219 dw .SetupSimpleLoader ; BOOTLOADER_TYPE_SIMPLE
220 dw .SetupBootMenuLoader ; reserved
221 dw .NoBootLoader ; BOOTLOADER_TYPE_NONE
222
223ALIGN JUMP_ALIGN
224.NoBootLoader:
225 test BYTE [cs:ROMVARS.wFlags], FLG_ROMVARS_LATE
226 jnz SHORT .SetupSimpleLoader ; Boot loader required for late initialization
227 ret
228ALIGN JUMP_ALIGN
229.SetupSimpleLoader:
230 mov si, Int19h_SimpleBootLoader
231 jmp Initialize_InstallInterruptHandler
232ALIGN JUMP_ALIGN
233.SetupBootMenuLoader:
234 mov si, Int19hMenu_BootLoader
235 jmp Initialize_InstallInterruptHandler
236
237
238;--------------------------------------------------------------------
239; Initializes hardware IRQ handlers.
240;
241; Initialize_HardwareIrqHandlers
242; Parameters:
243; ES: BDA and Interrupt Vector segment (zero)
244; Returns:
245; Nothing
246; Corrupts registers:
247; AX, BX, CX, DX, SI, DI
248;--------------------------------------------------------------------
249ALIGN JUMP_ALIGN
250Initialize_HardwareIrqHandlers:
251 mov di, ROMVARS.ideVars0 ; CS:SI points to first IDEVARS
252 call Initialize_GetIdeControllerCountToCX
253ALIGN JUMP_ALIGN
254.IdeControllerLoop:
255 mov al, [cs:di+IDEVARS.bIRQ] ; Load IRQ number
256 add di, BYTE IDEVARS_size ; Increment to next controller
257 call Initialize_LowOrHighIrqHandler
258 loop .IdeControllerLoop
259 ret
260
261;--------------------------------------------------------------------
262; Returns number of IDE controllers handled by our BIOS.
263;
264; Initialize_GetIdeControllerCountToCX
265; Parameters:
266; Nothing
267; Returns:
268; CX: Number of IDE controllers to handle
269; Corrupts registers:
270; Nothing
271;--------------------------------------------------------------------
272ALIGN JUMP_ALIGN
273Initialize_GetIdeControllerCountToCX:
274 mov cx, 1 ; Assume lite mode (one controller)
275 test BYTE [cs:ROMVARS.wFlags], FLG_ROMVARS_FULLMODE
276 jz SHORT .Return
277 mov cl, [cs:ROMVARS.bIdeCnt]
278ALIGN JUMP_ALIGN
279.Return:
280 ret
281
282;--------------------------------------------------------------------
283; Initializes hardware IRQ handler for specific IRQ.
284;
285; Initialize_LowOrHighIrqHandler
286; Parameters:
287; AL: IRQ number, 0 if IRQ disabled
288; ES: BDA and Interrupt Vector segment (zero)
289; Returns:
290; Nothing
291; Corrupts registers:
292; AX, BX, DX, SI
293;--------------------------------------------------------------------
294ALIGN JUMP_ALIGN
295Initialize_LowOrHighIrqHandler:
296 test al, al ; IRQ disabled?
297 jz SHORT .Return ; If so, return
298 eMOVZX bx, al ; Copy IRQ number to BX
299 cmp al, 8 ; High IRQ? (AT systems only)
300 jae SHORT Initialize_HighIrqHandler
301 jmp SHORT Initialize_LowIrqHandler
302ALIGN JUMP_ALIGN
303.Return:
304 ret
305
306
307;--------------------------------------------------------------------
308; Initializes handler for high IRQ (8...15).
309;
310; Initialize_HighIrqHandler
311; Parameters:
312; AL,BX: IRQ number (8...15)
313; ES: BDA and Interrupt Vector segment (zero)
314; Returns:
315; Nothing
316; Corrupts registers:
317; AX, BX, DX, SI
318;--------------------------------------------------------------------
319ALIGN JUMP_ALIGN
320Initialize_HighIrqHandler:
321 add bx, BYTE INTV_IRQ8 - 8 ; Interrupt vector number
322 mov si, HIRQ_InterruptServiceRoutineForIrqs8to15
323 call Initialize_InstallInterruptHandler
324 ; Fall to Initialize_UnmaskHighIrqController
325
326;--------------------------------------------------------------------
327; Unmasks interrupt from Slave 8259 interrupt controller (IRQs 8...15)
328;
329; Initialize_HighIrqHandler
330; Parameters:
331; AL: IRQ number (8...15)
332; Returns:
333; Nothing
334; Corrupts registers:
335; AX, DX
336;--------------------------------------------------------------------
337ALIGN JUMP_ALIGN
338Initialize_UnmaskHighIrqController:
339 sub al, 8 ; Slave interrupt number
340 mov dx, PORT_8259SL_IMR ; Load Slave Mask Register address
341 call Initialize_ClearBitFrom8259MaskRegister
342 mov al, 2 ; Master IRQ 2 to allow slave IRQs
343 jmp SHORT Initialize_UnmaskLowIrqController
344
345
346;--------------------------------------------------------------------
347; Initializes handler for low IRQ (0...7).
348;
349; Initialize_LowIrqHandler
350; Parameters:
351; AL,BX: IRQ number (0...7)
352; ES: BDA and Interrupt Vector segment (zero)
353; Returns:
354; Nothing
355; Corrupts registers:
356; AX, BX, DX, SI
357;--------------------------------------------------------------------
358ALIGN JUMP_ALIGN
359Initialize_LowIrqHandler:
360 add bx, BYTE INTV_IRQ0 ; Interrupt vector number
361 mov si, HIRQ_InterruptServiceRoutineForIrqs2to7
362 call Initialize_InstallInterruptHandler
363 ; Fall to Initialize_UnmaskLowIrqController
364
365;--------------------------------------------------------------------
366; Unmasks interrupt from Master 8259 interrupt controller (IRQs 0...7)
367;
368; Initialize_UnmaskLowIrqController
369; Parameters:
370; AL: IRQ number (0...7)
371; Returns:
372; Nothing
373; Corrupts registers:
374; AX, DX
375;--------------------------------------------------------------------
376ALIGN JUMP_ALIGN
377Initialize_UnmaskLowIrqController:
378 mov dx, PORT_8259MA_IMR ; Load Mask Register address
379 ; Fall to Initialize_ClearBitFrom8259MaskRegister
380
381;--------------------------------------------------------------------
382; Unmasks interrupt from Master or Slave 8259 Interrupt Controller.
383;
384; Initialize_ClearBitFrom8259MaskRegister
385; Parameters:
386; AL: 8259 interrupt index (0...7)
387; DX: Port address to Interrupt Mask Register
388; Returns:
389; Nothing
390; Corrupts registers:
391; AX
392;--------------------------------------------------------------------
393ALIGN JUMP_ALIGN
394Initialize_ClearBitFrom8259MaskRegister:
395 push cx
396 xchg ax, cx ; IRQ index to CL
397 mov ch, 1 ; Load 1 to be shifted
398 shl ch, cl ; Shift bit to correct position
399 not ch ; Invert to create bit mask for clearing
400 in al, dx ; Read Interrupt Mask Register
401 and al, ch ; Clear wanted bit
402 out dx, al ; Write modified Interrupt Mask Register
403 pop cx
404 ret
405
406
407;--------------------------------------------------------------------
408; Resets all hard disks.
409;
410; Initialize_ResetDetectedDrives
411; Parameters:
412; DS: RAMVARS segment
413; Returns:
414; Nothing
415; Corrupts registers:
416; AX, BX, CX, DX, DI
417;--------------------------------------------------------------------
418ALIGN JUMP_ALIGN
419Initialize_ResetDetectedDrives:
420 xor ah, ah ; Disk Controller Reset
421 mov dl, 80h ; Reset all floppy drives and hard disks
422 int INTV_DISK_FUNC
423 ret
Note: See TracBrowser for help on using the repository browser.