source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectDrives.asm @ 200

Last change on this file since 200 was 200, checked in by gregli@…, 11 years ago

Added logic to skip scanning COM ports if a COM port was already found during the normal detection process, to avoid finding the same serial drive twice and preseting the OS with two drives which in reality point to the same physical file on the server. Also added logic to skip scanning for the slave serial drive if the master was not found. And various small optimizations.

File size: 6.1 KB
Line 
1; Project name  :   XTIDE Universal BIOS
2; Description   :   Functions for detecting drive for the BIOS.
3
4; Section containing code
5SECTION .text
6
7;--------------------------------------------------------------------
8; Detects all IDE hard disks to be controlled by this BIOS.
9;
10; DetectDrives_FromAllIDEControllers
11;   Parameters:
12;       DS:     RAMVARS segment
13;       ES:     BDA segment (zero)
14;   Returns:
15;       Nothing
16;   Corrupts registers:
17;       All (not segments)
18;--------------------------------------------------------------------
19DetectDrives_FromAllIDEControllers:
20    call    RamVars_GetIdeControllerCountToCX
21    mov     bp, ROMVARS.ideVars0            ; CS:BP now points to first IDEVARS
22
23.DriveDetectLoop:                           ; Loop through IDEVARS
24    mov     si, g_szDetect                  ; Setup standard print string
25%ifdef MODULE_SERIAL
26    cmp     byte [cs:bp+IDEVARS.bDevice], DEVICE_SERIAL_PORT
27    jnz     .DriveNotSerial                 ; Special print string for serial drives
28    mov     si, g_szDetectCOM
29.DriveNotSerial:
30%endif
31    call    .DetectDrives_WithIDEVARS       ; Detect Master and Slave
32    add     bp, BYTE IDEVARS_size           ; Point to next IDEVARS
33    loop    .DriveDetectLoop
34       
35%ifdef MODULE_SERIAL
36    call    FindDPT_ToDSDIforSerialDevice   ; Did we already find any serial drives? 
37    jc      .done                           ; Yes, do not scan
38    mov     al,[cs:ROMVARS.wFlags]          ; Configurator set to always scan?
39    or      al,[es:BDA.bKBFlgs1]            ; Or, did the user hold down the ALT key?
40    and     al,8                            ; 8 = alt key depressed, same as FLG_ROMVARS_SERIAL_ALWAYSDETECT
41    jz      .done                           
42    mov     bp, ROMVARS.ideVarsSerialAuto   ; Point to our special IDEVARS sructure, just for serial scans
43    mov     si, g_szDetectCOMAuto           ; Special, special print string for serial drives during a scan
44;;; fall-through                   
45%else
46    ret
47%endif
48
49%if FLG_ROMVARS_SERIAL_SCANDETECT != 8
50%error "DetectDrives is currently coded to assume that FLG_ROMVARS_SERIAL_SCANDETECT is the same bit as the ALT key code in the BDA.  Changes in the code will be needed if these values are no longer the same."
51%endif
52
53;--------------------------------------------------------------------
54; Detects IDE hard disks by using information from IDEVARS.
55;
56; DetectDrives_WithIDEVARS
57;   Parameters:
58;       CS:BP:      Ptr to IDEVARS
59;       DS:         RAMVARS segment
60;       ES:         Zero (BDA segment)
61;       SI:         Ptr to template string
62;   Returns:
63;       Nothing
64;   Corrupts registers:
65;       AX, BX, DX, SI, DI
66;--------------------------------------------------------------------
67.DetectDrives_WithIDEVARS:
68    push    cx
69
70    push    si     
71    mov     ax, g_szMaster
72    mov     bh, MASK_DRVNHEAD_SET                               ; Select Master drive
73    call    StartDetectionWithDriveSelectByteInBHandStringInAX  ; Detect and create DPT + BOOTNFO
74    pop     si
75
76%ifdef MODULE_SERIAL
77;
78; This block of code checks to see if we found a master during a serial drives scan.  If no master
79; was found, there is no point in scanning for a slave as the server will not return a slave without a master,
80; as there is very little point given the drives are emulated.  Performing the slave scan will take 
81; time to rescan all the COM port and baud rate combinations.
82;
83    jnc     .masterFound
84    pop     cx
85    jcxz    .done       ; note that CX will only be zero after the .DriveDetectLoop, indicating a serial scan
86    push    cx
87.masterFound:
88%endif
89       
90    mov     ax, g_szSlave
91    mov     bh, MASK_DRVNHEAD_SET | FLG_DRVNHEAD_DRV
92    call    StartDetectionWithDriveSelectByteInBHandStringInAX
93    pop     cx
94       
95.done: 
96    ret
97
98       
99;--------------------------------------------------------------------
100; StartDetectionWithDriveSelectByteInBHandStringInAX
101;   Parameters:
102;       AX:     Offset to "Master" or "Slave" string
103;       BH:     Drive Select byte for Drive and Head Register
104;       CS:BP:  Ptr to IDEVARS for the drive
105;       DS:     RAMVARS segment
106;       ES:     Zero (BDA segment)
107;   Returns:
108;       CF:     Set on failure, Clear on success
109;               Note that this is set in the last thing both cases
110;               do: printing the drive name, or printing "Not Found"
111;   Corrupts registers:
112;       AX, BX, CX, DX, SI, DI
113;--------------------------------------------------------------------
114StartDetectionWithDriveSelectByteInBHandStringInAX:
115    call    DetectPrint_StartDetectWithMasterOrSlaveStringInAXandIdeVarsInCSBP
116    ; Fall to .ReadAtaInfoFromHardDisk
117
118;--------------------------------------------------------------------
119; .ReadAtaInfoFromHardDisk
120;   Parameters:
121;       BH:     Drive Select byte for Drive and Head Register
122;       CS:BP:  Ptr to IDEVARS for the drive
123;       DS:     RAMVARS segment
124;       ES:     Zero (BDA segment)
125;   Returns:
126;       CF:     Cleared if ATA-information read successfully
127;               Set if any error
128;   Corrupts registers:
129;       AX, BL, CX, DX, SI, DI
130;--------------------------------------------------------------------
131.ReadAtaInfoFromHardDisk:
132    mov     si, BOOTVARS.rgbAtaInfo     ; ES:SI now points to ATA info location
133    push    es
134    push    si
135    push    bx
136    call    Device_IdentifyToBufferInESSIwithDriveSelectByteInBH
137    pop     bx
138    pop     si
139    pop     es
140    jnc     SHORT CreateBiosTablesForHardDisk
141    ; Fall to .ReadAtapiInfoFromDrive
142
143.ReadAtapiInfoFromDrive:                ; Not yet implemented
144    ;call   ReadAtapiInfoFromDrive      ; Assume CD-ROM
145    ;jnc    SHORT _CreateBiosTablesForCDROM
146    jmp     short DetectDrives_DriveNotFound
147
148
149;--------------------------------------------------------------------
150; CreateBiosTablesForHardDisk
151;   Parameters:
152;       BH:     Drive Select byte for Drive and Head Register
153;       CS:BP:  Ptr to IDEVARS for the drive
154;       ES:SI   Ptr to ATA information for the drive
155;       DS:     RAMVARS segment
156;       ES:     BDA/Bootnfo segment
157;   Returns:
158;       Nothing
159;   Corrupts registers:
160;       AX, BX, CX, DX, SI, DI
161;--------------------------------------------------------------------
162CreateBiosTablesForHardDisk:
163    call    CreateDPT_FromAtaInformation
164    jc      SHORT DetectDrives_DriveNotFound
165    call    BootInfo_CreateForHardDisk
166    jmp     short DetectPrint_DriveNameFromBootnfoInESBX
167
168;--------------------------------------------------------------------
169; DetectDrives_DriveNotFound
170;   Parameters:
171;       Nothing
172;   Returns:
173;       CF:     Set (from BootMenuPrint_NullTerminatedStringFromCSSIandSetCF)
174;   Corrupts registers:
175;       AX, SI
176;--------------------------------------------------------------------
177DetectDrives_DriveNotFound:     
178    mov     si, g_szNotFound
179    jmp     BootMenuPrint_NullTerminatedStringFromCSSIandSetCF     
180
Note: See TracBrowser for help on using the repository browser.