source: trunk/BOOTCODE/REGULAR/DRIVEIO.ASM@ 29

Last change on this file since 29 was 29, checked in by Ben Rietbroek, 14 years ago

AiR-BOOT v1.06 -- Complete sourceforge mirror. (r56) [2010-02-19]
Signature-date: 2006-03-13.
Also contains binairy releases from v1.01 to v1.06, cd-rom images, etc.
If you want the whole pre v1.07 shebang, checkout this revision's trunk.
The v1.06 reference version is in 'tags/v1.06r'.
Note that this reference version uses 'NL' for 'Dutch'.

File size: 17.0 KB
Line 
1; AiR-BOOT (c) Copyright 1998-2008 M. Kiewitz
2;
3; This file is part of AiR-BOOT
4;
5; AiR-BOOT is free software: you can redistribute it and/or modify it under
6; the terms of the GNU General Public License as published by the Free
7; Software Foundation, either version 3 of the License, or (at your option)
8; any later version.
9;
10; AiR-BOOT is distributed in the hope that it will be useful, but WITHOUT ANY
11; WARRANTY: without even the implied warranty of MERCHANTABILITY or FITNESS
12; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13; details.
14;
15; You should have received a copy of the GNU General Public License along with
16; AiR-BOOT. If not, see <http://www.gnu.org/licenses/>.
17;
18;---------------------------------------------------------------------------
19; AiR-BOOT / DRIVE I/O
20;---------------------------------------------------------------------------
21
22; Note: Some routines set DS/ES to CS or even address via CS, even if its not
23; needed. This was done for SECURITY. So DO NOT remove it.
24; Its there to make sure the correct data is loaded/written to/from
25; harddrive.
26;
27; IF YOU MODIFY ANYTHING IN HERE, YOU MAY EASILY BREAK YOUR HARDDRIVE!
28
29; Will only load base-configuration, will NOT load IPT nor Hide-Config
30; Those are originally loaded on startup and will NOT get reloaded.
31DriveIO_LoadConfiguration Proc Near Uses ax bx cx dx es
32 mov ax, cs
33 mov es, ax
34 mov bx, offset Configuration
35 mov dx, 0080h ; First harddrive, Sector 55...
36 mov cx, 0037h
37 mov ax, 0201h ; Function 02, read 1 sector...
38 int 13h
39 jnc DIOLC_NoError
40 call MBR_LoadError ; Will Abort BootUp
41 DIOLC_NoError:
42 ret
43DriveIO_LoadConfiguration EndP
44
45DriveIO_SaveConfiguration Proc Near Uses ax bx cx dx ds es si
46 mov ax, cs
47 mov ds, ax
48 mov es, ax ; Safety first (CS==DS==ES)
49 ; --- Overwrite Floppy-Name with "FloppyDrive"
50 mov si, offset TXT_Floppy_Drive
51 mov di, offset PartitionTable
52 sub di, 30 ; Adjust to Floppy-Name
53 mov cx, 11
54 rep movsb
55 mov si, offset Configuration ; Calculate new checksum
56 xor bx, bx
57 mov cx, 5 ; Total of 5 Config-Sectors
58 mov dx, [CFG_CheckConfig]
59 mov [CFG_CheckConfig], bx
60 DIOSC_Loop:
61 call MBR_GetCheckOfSector
62 loop DIOSC_Loop
63 mov [CFG_CheckConfig], bx
64 ; --------------------------------------------------------------------
65 ; ES == CS
66 mov bx, offset Configuration
67 mov dx, 0080h ; First harddrive, Sector 55...
68 mov cx, 0037h
69 mov ax, 0305h ; Function 03, 5 sectors to write
70 int 13h
71 jnc DIOSC_NoError
72 call MBR_SaveError ; Will Abort BootUp
73 DIOSC_NoError:
74 ret
75DriveIO_SaveConfiguration EndP
76
77DriveIO_UpdateFloppyName Proc Near Uses bx cx dx ds si es di
78 mov ax, cs
79 mov ds, ax
80 mov es, ax
81
82 mov ah, 00h ; Function 2 - Reset Drive
83 xor dl, dl
84 int 13h
85 xor dx, dx ; Cylinder=0, Head=0
86 mov cx, 1 ; Sector=1, Drive=0
87 mov bx, offset TmpSector ; ES:BX - TmpSector
88 mov ax, 0201h ; Function 2 - Load Sector
89 int 13h
90 jnc DIOUFN_AllFine
91
92 ; --- Overwrite Floppy-Name with "No Disc"
93 mov si, offset TXT_Floppy_NoDisc
94 xor ax, ax
95 DIOUFN_WriteFloppyName:
96 mov di, offset PartitionTable
97 sub di, 30 ; Adjust to Floppy-Name
98 mov cl, 11
99 rep movsb
100 ret ; AX=-1 -> GotDisc, =0 -> NoDisc
101
102 ; --- Floppy found and read, data in TempSector
103 DIOUFN_AllFine:
104 mov ax, -1
105 mov si, offset TXT_Floppy_NoName
106 cmp wptr es:[bx+54], 'AF'
107 jne DIOUFN_WriteFloppyName
108 cmp wptr es:[bx+56], '1T'
109 jne DIOUFN_WriteFloppyName
110 cmp bptr es:[bx+58], '2'
111 jne DIOUFN_WriteFloppyName
112 mov si, bx
113 add si, 43 ; FAT12 - Volume Label Location
114 jmp DIOUFN_WriteFloppyName
115DriveIO_UpdateFloppyName EndP
116
117; =============================================================================
118; HARDDRIVE / GENERAL ACCESS
119; =============================================================================
120; The following routines are used for harddisc/floppy access.
121; The access is done via INT 13h/CHS or INT 13h/LBA.
122; Access will be done prefered by INT 13h/CHS, because it's (I wonder!) much
123; faster, than the LBA-method. I don't know, why LBA is so slow. Perhaps BIOS.
124;
125; Internal access (to AiR-BOOT) is always done via INT 13h/CHS.
126
127DriveIO_GetHardDriveCount Proc Near Uses ds si
128 push ds si
129 push 0040h
130 pop ds
131 mov si, 0075h
132 mov dh, ds:[si] ; 40:75 -> POST: Total Harddiscs == DL
133 pop si ds
134 mov TotalHarddiscs, dh
135 ret
136DriveIO_GetHardDriveCount EndP
137
138
139; Fills our LBA-Usage table. It holds the LBA-address, where BIOS/CHS access is
140; stopped and BIOS/LBA access is started.
141; This is calculated by Sector*Heads. Comparing will get done with Bit 25-10
142; on LBA sectors, so we actually divide sector number by 1024.
143DriveIO_InitLBASwitchTable Proc Near Uses es di
144 mov di, offset LBASwitchTable
145 mov dh, TotalHarddiscs
146 mov dl, 80h
147 DIOILUT_DriveLoop:
148 push dx di
149 mov ah, 08h
150 int 13h ; DISK - GET DRIVE PARAMETERS
151 mov ah, 0FBh ; Assume 255 heads/63 sectors, if error
152 jc DIOILUT_Error
153 and cl, 111111b ; Isolate lower 6 bits of CL -> sector count
154 movzx ax, cl
155 mov bl, dh ; DH -> head count
156 mul bl ; AX = Sectors*Heads
157 shl ah, 1
158 shl ah, 1 ; Shift 2 bits, so we are able to compare to
159 ; bit 16-23 of the LBA address
160 DIOILUT_Error:
161 pop di dx
162 mov bptr ds:[di], ah ; Save that value
163 inc di ; Go to next BYTE
164 inc dl
165 dec dh
166 jnz DIOILUT_DriveLoop
167 ret
168DriveIO_InitLBASwitchTable EndP
169
170; Adjusts BX:AX / CX:DX to meet LVM sector location
171; Destroys SI
172DriveIO_LVMAdjustToInfoSector Proc Near Uses
173 push cx
174 xor ch, ch
175 and cl, 63 ; Isolate lower bits, because upper
176 mov si, 63 ; ones may be used for cylinder
177 sub si, cx
178 pop cx
179 add ax, si
180 adc bx, 0 ; Adjust LBA Sector (BX:AX)
181 or cl, 63 ; Set Sector to 63
182 ret
183DriveIO_LVMAdjustToInfoSector EndP
184
185Comment *ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
186 Routine: Loads partition to ExecBase and checks for validity
187 ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
188 Calling : bx:ax - Absolute sector
189 cx:dx - Cylinder/Sector, Side/Drive (hi/lo-byte)
190 Returns : Carry Set if invalid partition encountered
191 Preserve: all registers
192 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*
193DriveIO_LoadPartition Proc Near Uses si
194 mov wptr cs:[CurPartition_Location+0], ax
195 mov wptr cs:[CurPartition_Location+2], bx
196 mov wptr cs:[CurPartition_Location+4], dx
197 mov wptr cs:[CurPartition_Location+6], cx ; Saves the location
198 mov si, offset PartitionSector ; DS:SI - ExecBase
199 call DriveIO_LoadSector
200 clc
201 cmp wptr [si+LocBR_Magic], 0AA55h
202 je DIOLP_Success
203 ; We check, if we are scanning partitions. In that case, if CHS is not 0/0/1
204 ; we will display a "bad partition table" message and halt the system.
205 cmp cx, 0001h
206 jne DIOLP_Failed
207 or dh, dh
208 jnz DIOLP_Failed
209 stc ; Set carry, so no partition table
210 DIOLP_Success:
211 ret
212 DIOLP_Failed:
213 jmp DriveIO_GotLoadError
214DriveIO_LoadPartition EndP
215
216Comment *ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
217 Routine: Writes a partition from ExecBase to its original sector
218 ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
219 Calling : none
220 Returns : none
221 Preserve: all registers
222 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*
223DriveIO_SavePartition Proc Near Uses ax bx cx dx si
224 mov ax, wptr cs:[CurPartition_Location+0]
225 mov bx, wptr cs:[CurPartition_Location+2]
226 mov dx, wptr cs:[CurPartition_Location+4]
227 mov cx, wptr cs:[CurPartition_Location+6] ; Gets prev. saved location
228 mov si, offset PartitionSector ; DS:SI - ExecBase
229 cmp wptr [si+LocBR_Magic], 0AA55h ; Checks for signature, if not found
230 jne DIOSP_SevereError ; we assume a really bad error
231 call DriveIO_SaveSector
232 DIOSP_SevereError:
233 ret
234DriveIO_SavePartition EndP
235
236; Keeps DS:SI for caller
237DriveIO_LoadTmpSector Proc Near Uses
238 mov si, offset TmpSector
239 call DriveIO_LoadSector
240 ret
241DriveIO_LoadTmpSector EndP
242
243; Keeps DS:SI for caller
244DriveIO_SaveTmpSector Proc Near Uses
245 mov si, offset TmpSector
246 call DriveIO_SaveSector
247 ret
248DriveIO_SaveTmpSector EndP
249
250; Keeps DS:SI for caller, sets carry if valid LVM sector encountered
251DriveIO_LoadLVMSector Proc Near Uses ax bx cx dx
252 test [CFG_IgnoreLVM], 1 ; We are supposed to ignore LVM, so
253 jnz DIOLLVMS_NoLVMSector ; don't load but declare as bad!
254 mov ax, wptr cs:[CurPartition_Location+0]
255 mov bx, wptr cs:[CurPartition_Location+2]
256 mov dx, wptr cs:[CurPartition_Location+4]
257 mov cx, wptr cs:[CurPartition_Location+6] ; Gets cur. partition location
258 call DriveIO_LVMAdjustToInfoSector
259 mov si, offset LVMSector
260 call DriveIO_LoadSector
261 call LVM_CheckSectorSignature
262 jnc DIOLLVMS_NoLVMSector
263 call LVM_CheckSectorCRC
264 jnc DIOLLVMS_NoLVMSector
265 ret
266 ; This here is called, if an invalid (or no) LVM information sector is found
267 ; It will truncate the first byte of the sector, so all other routines
268 ; will notice it easily by just comparing the first byte.
269 DIOLLVMS_NoLVMSector:
270 mov bptr [si+LocLVM_SignatureStart], 0
271 ret
272DriveIO_LoadLVMSector EndP
273
274; Keeps DS:SI for caller, saves at anytime w/o checks (!)
275DriveIO_SaveLVMSector Proc Near Uses ax bx cx dx
276 test [CFG_IgnoreLVM], 1 ; We are supposed to ignore LVM, so
277 jnz DIOSLVMS_SevereError ; don't save at anytime (security!)
278 mov ax, wptr cs:[CurPartition_Location+0]
279 mov bx, wptr cs:[CurPartition_Location+2]
280 mov dx, wptr cs:[CurPartition_Location+4]
281 mov cx, wptr cs:[CurPartition_Location+6] ; Gets cur. partition location
282 call LVM_CheckSectorSignature
283 jnc DIOSLVMS_SevereError ; LVM Signature must be there
284 call DriveIO_LVMAdjustToInfoSector
285 mov si, offset LVMSector
286 call DriveIO_SaveSector
287 DIOSLVMS_SevereError:
288 ret
289DriveIO_SaveLVMSector EndP
290
291; Memory-Block that holds information for LBA-access via INT 13h
292DriveIO_DAP: db 10h ; Size of paket
293 db 0 ; Reserved
294DriveIO_DAP_NumBlocks dw 0 ; Number of blocks
295DriveIO_DAP_Transfer dd 0 ; Transfer Adress
296DriveIO_DAP_Absolute dd 0 ; Absolute Sector
297 dd 0 ; Second Part of QWORD
298
299; Special error message instead of "LOAD ERROR" during partition scanning,
300; so users will notice that something is bad with their partition table(s)
301DriveIO_GotLoadError Proc Near
302 test cs:CurIO_Scanning, 1 ; Must be CS:, cause DS!=CS maybe here
303 jnz InScanMode
304 jmp MBR_LoadError
305 InScanMode:
306 mov si, offset TXT_BrokenPartitionTable
307 push cs
308 pop ds
309 call MBR_Teletype
310 mov si, offset BrokenHDD
311 sub dl, 50h ; 80h -> '0'
312 cmp dl, 39h
313 jbe DIOGLE_BelowA
314 add dl, 7 ; 3Ah -> 'A'
315 DIOGLE_BelowA:
316 mov bptr [si+5], dl
317 call MBR_Teletype
318 jmp MBRLE_Halt
319DriveIO_GotLoadError EndP
320
321Comment *ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
322 Routine: Loads a specified sector to DS:DI
323 ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
324 Calling : bx:ax - Absolute sector
325 cx:dx - Cylinder/Sector, Side/Drive (hi/lo-byte)
326 ds:si - Destination-Adress
327 Returns : none
328 Preserve: all registers
329 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*
330DriveIO_LoadSector Proc Near Uses ax bx ds si es di
331 test cs:[CurIO_UseExtension], 1
332 jz DIOLS_UseNormal
333 ; Are we forced do use LBA via Setting?
334 test cs:[CFG_ForceLBAUsage], 1
335 jnz DIOLS_UseExtension
336 ; Is the drive not a harddrive?
337 cmp dl, 80h
338 jb DIOLS_UseNormal
339 ; Upper 8 bits of LBA-address set? -> Use LBA (maximum boundary is FB0400h)
340 or bh, bh
341 jnz DIOLS_UseExtension
342 ; Compare Switch-Table value to bit 16-23 of LBA-address
343 mov di, dx
344 and di, 007Fh
345 cmp bptr cs:[LBASwitchTable+di], bl
346 jbe DIOLS_UseExtension
347 DIOLS_UseNormal:
348 mov di, 3
349 DIOLS_ErrorLoop:
350 push ds
351 pop es
352 mov bx, si ; ES:BX - Destination
353 mov ax, 0201h ; Function 2 - Load Sector
354 int 13h
355 jnc DIOLS_Success
356 dec di
357 jnz DIOLS_ErrorLoop
358 ; Sector load failed...
359 jmp DriveIO_GotLoadError
360
361 DIOLS_UseExtension:
362 push cx
363 mov cs:[DriveIO_DAP_NumBlocks], 1 ; Copy ONE sector
364 mov wptr cs:[DriveIO_DAP_Transfer+0], si
365 mov cx, ds
366 mov wptr cs:[DriveIO_DAP_Transfer+2], cx ; Fill out Transfer Adress
367 mov wptr cs:[DriveIO_DAP_Absolute+0], ax
368 mov wptr cs:[DriveIO_DAP_Absolute+2], bx ; Fill out Absolute Sector
369 push cs
370 pop ds
371 mov si, offset DriveIO_DAP
372 mov ah, 42h ; Extended Read
373 int 13h
374 pop cx
375 jnc DIOLS_Success
376 ; Sector load failed...
377 jmp DriveIO_GotLoadError
378
379 DIOLS_Success:
380 ret
381DriveIO_LoadSector EndP
382
383Comment *ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
384 Routine: Writes DS:SI to a specified sector
385 ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
386 Calling : bx:ax - Absolute sector
387 cx:dx - Cylinder/Sector, Side/Drive (hi/lo-byte)
388 ds:si - Source-Adress
389 Returns : none
390 Preserve: all registers
391 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*
392DriveIO_SaveSector Proc Near Uses ax bx cx ds si es di
393 test cs:[CurIO_UseExtension], 1
394 jz DIOSS_UseNormal
395 ; Are we forced do use LBA via Setting?
396 test cs:[CFG_ForceLBAUsage], 1
397 jnz DIOSS_UseExtension
398 ; Is the drive not a harddrive?
399 cmp dl, 80h
400 jb DIOSS_UseNormal
401 ; Upper 8 bits of LBA-address set? -> Use LBA (maximum boundary is FB0400h)
402 or bh, bh
403 jnz DIOSS_UseExtension
404 ; Compare Switch-Table value to bit 16-23 of LBA-address
405 mov di, dx
406 and di, 007Fh
407 cmp bptr cs:[LBASwitchTable+di], bl
408 jbe DIOSS_UseExtension
409 DIOSS_UseNormal:
410 mov di, 3
411 DIOSS_ErrorLoop:
412 push ds
413 pop es
414 mov bx, si ; ES:BX - Destination
415 mov ax, 0301h ; Function 3 - Write Sector
416 int 13h
417 jnc DIOSS_Success
418 dec di
419 jnz DIOSS_ErrorLoop
420 call MBR_SaveError
421
422 DIOSS_UseExtension:
423 push cx
424 mov cs:[DriveIO_DAP_NumBlocks], 1 ; Copy ONE sector
425 mov wptr cs:[DriveIO_DAP_Transfer+0], si
426 mov cx, ds
427 mov wptr cs:[DriveIO_DAP_Transfer+2], cx ; Fill out Transfer Adress
428 mov wptr cs:[DriveIO_DAP_Absolute+0], ax
429 mov wptr cs:[DriveIO_DAP_Absolute+2], bx ; Fill out Absolute Sector
430 push cs
431 pop ds
432 mov si, offset DriveIO_DAP
433 mov ax, 4300h ; Extended Write (No Verify)
434 int 13h
435 pop cx
436 jnc DIOSS_Success
437 call MBR_SaveError
438
439 DIOSS_Success:
440 ret
441DriveIO_SaveSector EndP
Note: See TracBrowser for help on using the repository browser.