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

Last change on this file since 23 was 23, checked in by aitotat, 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.