source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Initialization/Initialize.asm@ 14

Last change on this file since 14 was 3, checked in by Tomi Tilli, 15 years ago
File size: 12.6 KB
Line 
1; File name : Initialize.asm
2; Project name : IDE BIOS
3; Created date : 23.3.2010
4; Last update : 2.5.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 ; Initialize to speed up POST. DOS will reset drives anyway.
421 eMOVZX cx, BYTE [RAMVARS.bDrvCnt]
422 jcxz .Return
423 mov dl, [RAMVARS.bFirstDrv]
424ALIGN JUMP_ALIGN
425.InitLoop:
426 call AH9h_InitializeDriveForUse
427 inc dx ; Next drive
428 loop .InitLoop
429.Return:
430 ret
Note: See TracBrowser for help on using the repository browser.