source: trunk/bootcode/regular/driveio.asm@ 110

Last change on this file since 110 was 110, checked in by Ben Rietbroek, 8 years ago

Use the LBA read/write functions in load/save sector [v1.1.1-testing]

CAUTION:
This is a testbuild !
AirBoot uses the BIOS to access disks and a small coding error can trash
partition tables or other vital disk structures. You are advised to make
backups of TRACK0 and EBRs before using this testbuild. More info at:
https://rousseaux.github.io/netlabs.air-boot/pdf/AirBoot-v1.1.0-manual.pdf

File size: 49.9 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
23
24IFDEF MODULE_NAMES
25DB 'DRIVEIO',0
26ENDIF
27
28;
29; Check if INT13X extensions are supported.
30; AirBoot requires these extensions, and will halt if they are not available.
31; Modified: AX, BX, CX, DX, CF
32DriveIO_CheckFor13extensions Proc Near
33 mov ah, 41h
34 mov bx, 55AAh
35 mov dl, [BIOS_BootDisk] ; We check using the boot-disk
36 int 13h
37 jc PCCF13E_NotFound ; Error occured
38 cmp bx, 0AA55h
39 je PCCF13E_Found
40 PCCF13E_NotFound:
41 ret
42 PCCF13E_Found:
43 and cx, 1 ; Check 42h-44h,47h,48h supported
44 jz PCCF13E_NotFound ; Sig OK but no support, strange beast
45 mov byte ptr [CurIO_UseExtension], 1
46 ret
47DriveIO_CheckFor13extensions EndP
48
49
50; Note: Some routines set DS/ES to CS or even address via CS, even if its not
51; needed. This was done for SECURITY. So DO NOT remove it.
52; Its there to make sure the correct data is loaded/written to/from
53; harddrive.
54;
55; IF YOU MODIFY ANYTHING IN HERE, YOU MAY EASILY BREAK YOUR HARDDRIVE!
56
57; Will only load base-configuration, will NOT load IPT nor Hide-Config
58; Those are originally loaded on startup and will NOT get reloaded.
59DriveIO_LoadConfiguration Proc Near Uses ax bx cx dx es
60 mov ax, cs
61 mov es, ax
62 mov bx, offset Configuration
63 xor dh, dh
64 mov dl, [BIOS_BootDisk] ; Disk we booted from
65 mov cx, 0037h ; Sector 55 (CHS)
66 mov ax, 0201h ; Function 02, read 1 sector...
67 int 13h
68 jnc DIOLC_NoError
69 call MBR_LoadError ; Will Abort BootUp
70 DIOLC_NoError:
71 ret
72DriveIO_LoadConfiguration EndP
73
74DriveIO_SaveConfiguration Proc Near Uses ax bx cx dx ds es si
75 mov ax, cs
76 mov ds, ax
77 mov es, ax ; Safety first (CS==DS==ES)
78 ; --- Overwrite Floppy-Name with "FloppyDrive"
79 mov si, offset TXT_Floppy_Drive
80 mov di, offset PartitionTable
81 sub di, 30 ; Adjust to Floppy-Name
82 mov cx, 11
83 rep movsb
84 mov si, offset Configuration ; Calculate new checksum
85 xor bx, bx
86
87 ; Changed from 5 to calculated value (not here, see compat. issue below)
88 ; Fixes issue: #2987 -- "air-boot doesn't remember drive letter"
89 ; Size of the ab-configuration in 512 byte sectors
90 ;mov cx, (MBR_BackUpMBR - Configuration) / 200h
91
92 ; AB v1.07 stores a 5 sector configuration with a 5 sector checksum.
93 ; AB v1.0.8+ *should* stores a 7 sector configuration with a
94 ; 7 sector checksum.
95 ; Because 5 was hardcoded here, SET(A)BOOT v1.07 will see see an AB v1.0.8+
96 ; config as corrupted, while this is not the case.
97 ; So, for compatibility reasons, in v1.0.8+, the checksum stored is over
98 ; 5 sectors, to be compatible with v1.07.
99 ; This may change (be corrected) in future versions !
100 mov cx,5
101
102 mov dx, [CFG_CheckConfig]
103 mov [CFG_CheckConfig], bx
104 DIOSC_Loop:
105 call MBR_GetCheckOfSector
106 loop DIOSC_Loop
107 mov [CFG_CheckConfig], bx
108 ; --------------------------------------------------------------------
109 ; ES == CS
110 mov bx, offset Configuration
111 xor dh, dh
112 mov dl, [BIOS_BootDisk] ; Disk we booted from
113 mov cx, 0037h ; Sector 55 (CHS)
114
115 ; Changed from 5 to calculated value
116 ; Fixes issue: #2987 -- "air-boot doesn't remember drive letter"
117 ; Size of the ab-configuration in 512 byte sectors
118 mov al, (MBR_BackUpMBR - Configuration) / 200h
119 mov ah,03h
120
121 int 13h
122 jnc DIOSC_NoError
123 call MBR_SaveError ; Will Abort BootUp
124 DIOSC_NoError:
125 ret
126DriveIO_SaveConfiguration EndP
127
128DriveIO_UpdateFloppyName Proc Near Uses bx cx dx ds si es di
129 mov ax, cs
130 mov ds, ax
131 mov es, ax
132
133 mov ah, 00h ; Function 0 - Reset Drive
134 xor dl, dl
135 int 13h
136 xor dx, dx ; Cylinder=0, Head=0
137 mov cx, 1 ; Sector=1, Drive=0
138 mov bx, offset TmpSector ; ES:BX - TmpSector
139 mov ax, 0201h ; Function 2 - Load Sector
140 int 13h
141 jnc DIOUFN_AllFine
142
143 ; --- Overwrite Floppy-Name with "No Disc"
144 mov si, offset TXT_Floppy_NoDisc
145 xor ax, ax
146 DIOUFN_WriteFloppyName:
147 mov di, offset PartitionTable
148 sub di, 30 ; Adjust to Floppy-Name
149 mov cl, 11
150 rep movsb
151 ret ; AX=-1 -> GotDisc, =0 -> NoDisc
152
153 ; --- Floppy found and read, data in TempSector
154 DIOUFN_AllFine:
155 mov ax, -1
156 mov si, offset TXT_Floppy_NoName
157 cmp wptr es:[bx+54], 'AF'
158 jne DIOUFN_WriteFloppyName
159 cmp wptr es:[bx+56], '1T'
160 jne DIOUFN_WriteFloppyName
161 cmp bptr es:[bx+58], '2'
162 jne DIOUFN_WriteFloppyName
163 mov si, bx
164 add si, 43 ; FAT12 - Volume Label Location
165 jmp DIOUFN_WriteFloppyName
166DriveIO_UpdateFloppyName EndP
167
168; =============================================================================
169; HARDDRIVE / GENERAL ACCESS
170; =============================================================================
171; The following routines are used for harddisc/floppy access.
172; The access is done via INT 13h/CHS or INT 13h/LBA.
173; Access will be done prefered by INT 13h/CHS, because it's (I wonder!) much
174; faster, than the LBA-method. I don't know, why LBA is so slow. Perhaps BIOS.
175;
176; Internal access (to AiR-BOOT) is always done via INT 13h/CHS.
177
178DriveIO_GetHardDriveCount Proc Near Uses ds si
179 push ds
180 push si
181 push 0040h
182 pop ds
183 mov si, 0075h
184 mov dh, ds:[si] ; 40:75 -> POST: Total Harddiscs == DL
185 pop si
186 pop ds
187 mov [TotalHarddiscs], dh
188 ret
189DriveIO_GetHardDriveCount EndP
190
191
192; Fills our LBA-Usage table. It holds the LBA-address, where BIOS/CHS access is
193; stopped and BIOS/LBA access is started.
194; This is calculated by Sector*Heads. Comparing will get done with Bit 25-10
195; on LBA sectors, so we actually divide sector number by 1024.
196DriveIO_InitLBASwitchTable Proc Near Uses es di
197 mov di, offset LBASwitchTable
198 mov dh, [TotalHarddiscs]
199 mov dl, 80h ; First disk to process
200 DIOILUT_DriveLoop:
201 push dx
202 push di
203 mov ah, 08h
204 int 13h ; DISK - GET DRIVE PARAMETERS
205 mov ah, 0FBh ; Assume 255 heads/63 sectors, if error
206 jc DIOILUT_Error
207 and cl, 111111b ; Isolate lower 6 bits of CL -> sector count
208
209 ;movzx ax, cl
210 mov al,cl
211 mov ah,0
212
213 mov bl, dh ; DH -> max head number
214 mul bl ; AX = Sectors*Heads
215 shl ah, 1
216 shl ah, 1 ; Shift 2 bits, so we are able to compare to
217 ; bit 16-23 of the LBA address
218 DIOILUT_Error:
219 pop di
220 pop dx
221 mov bptr ds:[di], ah ; Save that value
222 inc di ; Go to next BYTE
223 inc dl ; Next disk
224 dec dh ; Decrease disks to process
225 jnz DIOILUT_DriveLoop ; Next disk if DH != 0
226 ret
227DriveIO_InitLBASwitchTable EndP
228
229
230
231
232;FIXME: Only LBA gets updated, need to update CHS too !!!!!!!
233
234; Adjusts BX:AX / CX:DX to meet LVM sector location
235; BX:AX / CX:DX point to MBR or EBR !
236; Destroys SI
237; Rousseau: Enhanced to handle sector-numbers 127 and 255 besides 63 for LVM-info sectors.
238; Ugly, need to cleanup.
239DriveIO_LVMAdjustToInfoSector Proc Near
240 push cx ; Save Cyl/Sec part
241 xor ch,ch ; Clear low Cyl part
242 and cl,63 ; Clear high Cyl part
243 push bx ; We need BX...
244 push dx ; and DX temoraily
245 mov bx,offset [TrueSecs] ; Offset of sector table
246 xor dh,dh ; Clear DH because we use DL as index
247 and dl,01111111b ; Remove high bit of BIOS disk-nr
248 shl dx,2 ; Index to DWORD table
249 add bx,dx ; Point to TrueSecs for this disk
250 mov si,[bx] ; Get SPT for this disk
251 pop dx ; Restore DX...
252 pop bx ; and BX
253 ;~ sub si,cx ; Adjust offset !! INCORRECT FOR LBA (TP CX != 0 !!)
254 dec si
255 pop cx ; Restore Cyl/Sec part
256 add ax,si ; Add offset to low part...
257 adc bx,0 ; and high part of LBA address
258 or cl,63 ; Adjust CHS part !FIX ME for > 63! !! FIX HUGE DRIVE !!
259
260
261 ret
262
263DriveIO_LVMAdjustToInfoSector EndP
264
265
266
267
268
269
270; #########################################################################
271; Routine: Loads partition to ExecBase and checks for validity
272; #########################################################################
273; Calling : bx:ax - Absolute sector
274; cx:dx - Cylinder/Sector, Side/Drive (hi/lo-byte)
275; Returns : Carry Set if invalid partition encountered
276; Preserve: all registers
277; #########################################################################
278DriveIO_LoadPartition Proc Near Uses si
279 mov wptr cs:[CurPartition_Location+0], ax
280 mov wptr cs:[CurPartition_Location+2], bx
281 mov wptr cs:[CurPartition_Location+4], dx
282 mov wptr cs:[CurPartition_Location+6], cx ; Saves the location
283 mov si, offset PartitionSector ; DS:SI - ExecBase
284 call DriveIO_LoadSector
285 clc
286 cmp wptr [si+LocBR_Magic], 0AA55h
287 je DIOLP_Success
288 ; We check, if we are scanning partitions. In that case, if CHS is not 0/0/1
289 ; we will display a "bad partition table" message and halt the system.
290 cmp cx, 0001h
291 jne DIOLP_Failed
292 or dh, dh
293 jnz DIOLP_Failed
294 stc ; Set carry, so no partition table
295 DIOLP_Success:
296
297 IFDEF AUX_DEBUG
298 ; show current partition location
299 ;~ pushf
300 ;~ pusha
301 ;~ call AuxIO_TeletypeNL
302 ;~ mov si,offset db_curpartloc
303 ;~ call AuxIO_Print
304 ;~ mov dx,word ptr [CurPartition_Location+02]
305 ;~ mov ax,word ptr [CurPartition_Location+00]
306 ;~ call AuxIO_TeletypeHexDWord
307 ;~ call AuxIO_TeletypeNL
308 ;~ mov si,offset PartitionSector
309 ;~ call AuxIO_DumpSector
310 ;~ call AuxIO_TeletypeNL
311 ;~ popa
312 ;~ popf
313 ENDIF
314
315 ret
316 DIOLP_Failed:
317 jmp DriveIO_GotLoadError
318DriveIO_LoadPartition EndP
319
320; #########################################################################
321; Routine: Writes a partition from ExecBase to its original sector
322; #########################################################################
323; Calling : none
324; Returns : none
325; Preserve: all registers
326; #########################################################################
327DriveIO_SavePartition Proc Near Uses ax bx cx dx si
328 mov ax, wptr cs:[CurPartition_Location+0]
329 mov bx, wptr cs:[CurPartition_Location+2]
330 mov dx, wptr cs:[CurPartition_Location+4]
331 mov cx, wptr cs:[CurPartition_Location+6] ; Gets prev. saved location
332 mov si, offset PartitionSector ; DS:SI - ExecBase
333 cmp wptr [si+LocBR_Magic], 0AA55h ; Checks for signature, if not found
334 jne DIOSP_SevereError ; we assume a really bad error
335 call DriveIO_SaveSector
336 DIOSP_SevereError:
337 ret
338DriveIO_SavePartition EndP
339
340; Keeps DS:SI for caller
341DriveIO_LoadTmpSector Proc Near
342 mov si, offset TmpSector
343 call DriveIO_LoadSector
344 ret
345DriveIO_LoadTmpSector EndP
346
347; Keeps DS:SI for caller
348DriveIO_SaveTmpSector Proc Near
349 mov si, offset TmpSector
350 call DriveIO_SaveSector
351 ret
352DriveIO_SaveTmpSector EndP
353
354
355
356; Keeps DS:SI for caller, sets carry if valid LVM sector encountered
357DriveIO_LoadLVMSector Proc Near Uses ax bx cx dx
358 test byte ptr [CFG_IgnoreLVM], 1 ; We are supposed to ignore LVM, so
359 jnz DIOLLVMS_NoLVMSector ; don't load but declare as bad!
360 mov ax, wptr cs:[CurPartition_Location+0]
361 mov bx, wptr cs:[CurPartition_Location+2]
362 mov dx, wptr cs:[CurPartition_Location+4]
363 mov cx, wptr cs:[CurPartition_Location+6] ; Gets cur. partition location
364
365 call DriveIO_LVMAdjustToInfoSector
366
367 mov si, offset LVMSector
368 call DriveIO_LoadSector
369
370 IFDEF AUX_DEBUG
371 ; show current partition location
372 ;~ pushf
373 ;~ pusha
374 ;~ call AuxIO_TeletypeNL
375 ;~ mov si,offset db_curlvmsec
376 ;~ call AuxIO_Print
377 ;~ mov dx,bx
378 ;~ call AuxIO_TeletypeHexDWord
379 ;~ call AuxIO_TeletypeNL
380 ;~ mov si,offset LVMSector
381 ;~ call AuxIO_DumpSector
382 ;~ call AuxIO_TeletypeNL
383 ;~ popa
384 ;~ popf
385 ENDIF
386
387 call LVM_CheckSectorSignature
388 jnc DIOLLVMS_NoLVMSector
389 call LVM_CheckSectorCRC
390 jnc DIOLLVMS_NoLVMSector
391 ret
392 ; This here is called, if an invalid (or no) LVM information sector is found
393 ; It will truncate the first byte of the sector, so all other routines
394 ; will notice it easily by just comparing the first byte.
395 DIOLLVMS_NoLVMSector:
396 mov bptr [si+LocLVM_SignatureStart], 0
397 ret
398DriveIO_LoadLVMSector EndP
399
400
401
402; Keeps DS:SI for caller, saves at anytime w/o checks (!)
403DriveIO_SaveLVMSector Proc Near Uses ax bx cx dx
404 test byte ptr [CFG_IgnoreLVM], 1 ; We are supposed to ignore LVM, so
405 jnz DIOSLVMS_SevereError ; don't save at anytime (security!)
406 mov ax, wptr cs:[CurPartition_Location+0]
407 mov bx, wptr cs:[CurPartition_Location+2]
408 mov dx, wptr cs:[CurPartition_Location+4]
409 mov cx, wptr cs:[CurPartition_Location+6] ; Gets cur. partition location
410 call LVM_CheckSectorSignature
411 jnc DIOSLVMS_SevereError ; LVM Signature must be there
412
413 IFDEF AUX_DEBUG
414;~ dioatlvm db 'DriveIO_LVMAdjustToInfoSector',10,0
415 ;~ pushf
416 ;~ pusha
417 ;~ mov si,offset dioatlvm
418 ;~ call AuxIO_Print
419 ;~ popa
420 ;~ popf
421 call DEBUG_DumpRegisters
422 call DEBUG_DumpCHS
423 ENDIF
424
425 call DriveIO_LVMAdjustToInfoSector
426
427 IFDEF AUX_DEBUG
428 call DEBUG_DumpRegisters
429 call DEBUG_DumpCHS
430 ENDIF
431
432 mov si, offset LVMSector
433 call DriveIO_SaveSector
434 DIOSLVMS_SevereError:
435 ret
436DriveIO_SaveLVMSector EndP
437
438
439
440; Special error message instead of "LOAD ERROR" during partition scanning,
441; so users will notice that something is bad with their partition table(s)
442DriveIO_GotLoadError Proc Near
443 test byte ptr cs:[CurIO_Scanning], 1 ; Must be CS:, cause DS!=CS maybe here
444 jnz InScanMode
445 jmp MBR_LoadError
446 InScanMode:
447 mov si, offset TXT_BrokenPartitionTable
448 push cs
449 pop ds
450 call MBR_Teletype
451 mov si, offset BrokenHDD
452 sub dl, 50h ; 80h -> '0'
453 cmp dl, 39h
454 jbe DIOGLE_BelowA
455 add dl, 7 ; 3Ah -> 'A'
456 DIOGLE_BelowA:
457 mov bptr [si+5], dl
458 call MBR_Teletype
459
460 ; JWasm: cannot jump to local label in other procedure.
461 ; Changed to halt here.
462 ;jmp MBRLE_Halt
463 DriveIO_GotLoadError_halt:
464 jmp DriveIO_GotLoadError_halt
465DriveIO_GotLoadError EndP
466
467; #########################################################################
468; Routine: Loads a specified sector to DS:DI
469; #########################################################################
470; Calling : bx:ax - Absolute sector
471; cx:dx - Cylinder/Sector, Side/Drive (hi/lo-byte)
472; ds:si - Destination-Adress
473; Returns : none
474; Preserve: all registers
475; #########################################################################
476DriveIO_LoadSector Proc Near Uses ax bx cx dx ds si es di
477
478 ; Is the drive not a harddrive?
479 cmp dl, 80h
480 jb DIOLS_UseNormal
481
482 test byte ptr cs:[CurIO_UseExtension], 1
483 jz DIOLS_UseNormal
484 ; Are we forced do use LBA via Setting?
485 jnz DIOLS_UseExtension
486
487 ; Upper 8 bits of LBA-address set?
488 ; Then use LBA (maximum boundary is 16320x16x63 = FB0400h)
489 or bh, bh
490 jnz DIOLS_UseExtension
491 ; Compare Switch-Table value to bit 16-23 of LBA-address
492 mov di, dx
493 and di, 007Fh
494 cmp bptr cs:[LBASwitchTable+di], bl
495 jbe DIOLS_UseExtension
496 DIOLS_UseNormal:
497 mov di, 3
498 DIOLS_ErrorLoop:
499 push ds
500 pop es
501 mov bx, si ; ES:BX - Destination
502 mov ax, 0201h ; Function 2 - Load Sector
503 int 13h
504 jnc DIOLS_Success
505 dec di
506 jnz DIOLS_ErrorLoop
507
508 ; Sector load failed...
509 jmp DriveIO_GotLoadError
510
511 DIOLS_UseExtension:
512
513 mov di, ds ; segment for transfer address
514 mov cx, ax ; low word of lba
515 call DriveIO_ReadSectorLBA ; extended read
516 jc DriveIO_GotLoadError ; halt on error
517
518 ;~ push cx
519 ;~ mov cs:[INT13X_DAP_NumBlocks], 1 ; Copy ONE sector
520 ;~ mov wptr cs:[INT13X_DAP_Transfer+0], si
521 ;~ mov cx, ds
522 ;~ mov wptr cs:[INT13X_DAP_Transfer+2], cx ; Fill out Transfer Adress
523 ;~ mov wptr cs:[INT13X_DAP_Absolute+0], ax
524 ;~ mov wptr cs:[INT13X_DAP_Absolute+2], bx ; Fill out Absolute Sector
525 ;~ push cs
526 ;~ pop ds
527 ;~ mov si, offset [INT13X_DAP]
528 ;~ mov ah, 42h ; Extended Read
529 ;~ int 13h
530 ;~ pop cx
531 ;~ jnc DIOLS_Success
532
533 ; Sector load failed...
534 ;~ jmp DriveIO_GotLoadError
535
536 DIOLS_Success:
537 ret
538DriveIO_LoadSector EndP
539
540
541
542;##############################################################################
543;# ACTION : Reads a sector from disk using INT13 extensions
544;# ----------------------------------------------------------------------------
545;# IN : BX:CX - LBA address of sector
546;# : DI:SI - SEG:OFF of transfer buffer
547;# ----------------------------------------------------------------------------
548;# OUT : CF=1 - failure, AH failure code
549;# ----------------------------------------------------------------------------
550;# EFFECTS : Modifies DAP structure and fills transfer buffer
551;##############################################################################
552DriveIO_ReadSectorLBA Proc Near Uses bx cx dx si di ds es
553
554 ; One sector to read
555 mov cs:[INT13X_DAP_NumBlocks], 1
556
557 ; Setup transfer address
558 mov wptr cs:[INT13X_DAP_Transfer+0], si ; offset
559 mov wptr cs:[INT13X_DAP_Transfer+2], di ; segment
560
561 ; Setup LBA64 address of requested sector
562 mov wptr cs:[INT13X_DAP_Absolute+0], cx ; low word lower part
563 mov wptr cs:[INT13X_DAP_Absolute+2], bx ; high word lower part
564 mov wptr cs:[INT13X_DAP_Absolute+4], 0 ; low word upper part
565 mov wptr cs:[INT13X_DAP_Absolute+6], 0 ; high word upper part
566
567 ; Address of packet
568 mov si, offset [INT13X_DAP] ; disk address packet
569
570 ; Do the extended read
571 mov ah, 42h ; read function
572 int 13h ; transfer to bios
573
574 ; Error occured
575 jc DriveIO_ReadSectorLBA_exit
576
577 ; AH should also be zero
578 test ah, ah
579 stc
580 jnz DriveIO_ReadSectorLBA_exit
581
582 ; Disk read succeeded, clear CF
583 clc
584
585 DriveIO_ReadSectorLBA_exit:
586 ret
587
588DriveIO_ReadSectorLBA EndP
589
590
591
592;##############################################################################
593;# ACTION : Writes a sector to disk using INT13 extensions
594;# ----------------------------------------------------------------------------
595;# IN : AL - write flags, AL.0 verify (1.0,2.0), AL.1 verify (2.1+)
596;# : BX:CX - LBA address of sector
597;# : DI:SI - SEG:OFF of transfer buffer
598;# ----------------------------------------------------------------------------
599;# OUT : CF=1 - failure, AH failure code
600;# ----------------------------------------------------------------------------
601;# EFFECTS : Modifies DAP structure and mofifies the disk
602;##############################################################################
603DriveIO_WriteSectorLBA Proc Near Uses bx cx dx si di ds es
604
605 ; Mask reserved bits for wrte flags -- should check version here
606 and al, 03h
607
608 ; One sector to read
609 mov cs:[INT13X_DAP_NumBlocks], 1
610
611 ; Setup transfer address
612 mov wptr cs:[INT13X_DAP_Transfer+0], si ; offset
613 mov wptr cs:[INT13X_DAP_Transfer+2], di ; segment
614
615 ; Setup LBA64 address of requested sector
616 mov wptr cs:[INT13X_DAP_Absolute+0], cx ; low word lower part
617 mov wptr cs:[INT13X_DAP_Absolute+2], bx ; high word lower part
618 mov wptr cs:[INT13X_DAP_Absolute+4], 0 ; low word upper part
619 mov wptr cs:[INT13X_DAP_Absolute+6], 0 ; high word upper part
620
621 ; Address of packet
622 mov si, offset [INT13X_DAP] ; disk address packet
623
624 ; Do the extended write
625 mov ah, 43h ; write function
626 int 13h ; transfer to bios
627
628 ; Error occured
629 jc DriveIO_WriteSectorLBA_exit
630
631 ; AH should also be zero
632 test ah, ah
633 stc
634 jnz DriveIO_WriteSectorLBA_exit
635
636 ; Disk write succeeded, clear CF
637 clc
638
639 DriveIO_WriteSectorLBA_exit:
640 ret
641
642DriveIO_WriteSectorLBA EndP
643
644
645
646;
647; ############################################################
648; # Check for a valid MBR-sector to be written to disk #
649; ############################################################
650;
651; In
652; --
653; DL = Physical Disk
654; BX:CX = LBA sector
655; DI:SI = Source buffer
656;
657; Out
658; ---
659; CY = 1 if invalid MBR in source buffer, 0 if valid
660;
661; This routine is called when DriveIO_SaveSector attempts to write to the MBR.
662; It checks if the sector to be written has some sensible values in certain
663; places. In fact, if the sector is written to the boot-disk, the AiR-BOOT
664; signature should be present and the partition table should be the same
665; as the one at the start of the AiR-BOOT code in memory, except maybe for the
666; active flags.
667; For other disks, only the active flags are checked to be 00h or 80h and
668; the AA55h MBR signature.
669;
670DriveIO_ProtectMBR Proc Near
671 pusha ; Push all registers
672 push es ; Push ES because we need it for string instructions
673 push cs ; Make ES point...
674 pop es ; to CS
675
676 ; Save the pointer to the sector to write in BX
677 mov bx,si
678
679 ;
680 ; If the sector to be written is not the boot-disk, then skip
681 ; checking the AiR-BOOT MBR.
682 ;
683 cmp dl, [BIOS_BootDisk]
684 jne DriveIO_ProtectMBR_is_not_bootdisk
685
686 ;
687 ; The boot-disk is accessed so the sector to be written must be
688 ; the AiR-BOOT MBR. This is the same as the first 512 bytes
689 ; relocated to 8000:0000 and this the start of the AB-code.
690 ;
691 mov si,bx ; Get pointer to sector to write
692 xor di,di ; Point DI to start of AB-code (MBR)
693 mov cx, offset [MBR_PartTable] ; Bytes upto P-table must be same
694 cld ; Compare upwards
695 repe cmpsb ; Compare upto P-table
696
697 ; If not the same this is not the an AiR-BOOT boot-disk MBR !
698 jne DriveIO_ProtectMBR_not_valid_MBR ; SEVERE ERROR !
699
700 ; Continue with signature check
701 jmp DriveIO_ProtectMBR_check_signature
702
703
704 ;
705 ; The disk is not the boot-disk so we don't know what kind of MBR is on it.
706 ; Some sanity checks should be here.
707 ;
708 DriveIO_ProtectMBR_is_not_bootdisk:
709
710 ;
711 ; sanity checks...
712 ;
713
714 ; Continue with signature check
715 jmp DriveIO_ProtectMBR_check_signature
716
717
718 DriveIO_ProtectMBR_check_signature:
719 ; See if the sector to write contains a valid signature
720 mov si,bx ; Get pointer to sector to write
721 mov di, offset [MBR_Sig] ; Offset to MBR signature
722 add si,di ; Make SI point to it in sec to write
723 lodsw ; Load it
724 cmp ax,0aa55h ; See if it is valid
725
726 ; If no signature this cannot be a valid MBR !
727 jne DriveIO_ProtectMBR_not_valid_MBR ; SEVERE ERROR !
728
729
730 ;
731 ; The sector to be written seems to be valid.
732 ; Set CY=0 to indicate a valid MBR.
733 ;
734 DriveIO_ProtectMBR_is_valid_MBR:
735 clc
736 jmp DriveIO_ProtectMBR_end
737
738 ;
739 ; Something is terribly wrong; a non-MBR sector seems about to be written.
740 ; Set CY=1 and let the calling code handle this situation.
741 ;
742 DriveIO_ProtectMBR_not_valid_MBR:
743 stc
744 jmp DriveIO_ProtectMBR_end
745
746 ;
747 ; Return to the caller with no registers modyfied except FLAGS.
748 ;
749 DriveIO_ProtectMBR_end:
750 pop es
751 popa
752 ret
753DriveIO_ProtectMBR Endp
754
755
756
757; #########################################################################
758; Routine: Checks if the MBR is addressed by either CHS or LBA
759; #########################################################################
760; Calling : bx:ax - Absolute sector
761; cx:dx - Cylinder/Sector, Side/Drive (hi/lo-byte)
762; Returns : ZF=1 if MBR is addressed, else ZF=0
763; Preserve: all registers
764; #########################################################################
765DriveIO_MBR_Addressed Proc
766 push ax
767 push bx
768
769 or bx,ax ; Results in 0 in BX if MBR is addressed by LBA
770 jz DriveIO_MBR_Addressed_done
771
772 mov ax,cx ; Results in 1 in AX if CYL 0, SEC 1 is addressed
773 add al,dh ; Results in 1 in AX if HEAD 0 is addressed
774 dec ax ; Results in 0 in AX if MBR is addressed by CHS
775
776 DriveIO_MBR_Addressed_done:
777 pop bx
778 pop ax
779 ret
780DriveIO_MBR_Addressed EndP
781
782
783
784
785; #########################################################################
786; Routine: Writes DS:SI to a specified sector
787; #########################################################################
788; Calling : bx:ax - Absolute sector
789; cx:dx - Cylinder/Sector, Side/Drive (hi/lo-byte)
790; ds:si - Source-Adress
791; Returns : none
792; Preserve: all registers
793; #########################################################################
794DriveIO_SaveSector Proc Near Uses ax bx cx dx ds si es di
795
796
797 ;!
798 ;! DEBUG_BLOCK
799 ;! Force write to LBA0 to test interception routine.
800 ;! Do *NOT* enable unless you are debugging, will overwrite MBR !
801 ;!
802 ;~ __DIO_FORCE_LBA0_WRITE__ EQU
803 IFDEF AUX_DEBUG
804 IFDEF __DIO_FORCE_LBA0_WRITE__
805 xor ax,ax
806 xor bx,bx
807 xor cx,cx
808 inc cx
809 xor dh,dh
810 ENDIF
811 ENDIF
812
813
814 ;!
815 ;! DEBUG_BLOCK
816 ;! Check what is being written to disk.
817 ;! Uncomment below to activate.
818 ;!
819 __DIO_SS_DMP__ EQU
820 IFDEF AUX_DEBUG
821 IFDEF __DIO_SS_DMP__
822 pusha
823 push si
824 mov si,offset [dioss]
825 call AuxIO_Print
826 pop si
827 call DEBUG_DumpRegisters
828 call AuxIO_DumpSector
829 call AuxIO_TeletypeNL
830 popa
831 ENDIF
832 ENDIF
833
834 ;
835 ; Check if the MBR is the destination for the write.
836 ; ZF=1 if so.
837 ;
838 call DriveIO_MBR_Addressed
839 jnz DriveIO_SaveSector_continue_write
840
841
842 ; MBR is addressed, check the sector that is requested to be written.
843 ; For the bootdisk it should contain the AiR-BOOT signature, valid
844 ; partition-table entries and the AA55h signature.
845 ; If not, something is terribly wrong in some piece of the AB code.
846 ; For any other disk (80h+) at least a valid partition table should
847 ; be present together with the AA55h signature.
848 call DriveIO_ProtectMBR
849 jnc DriveIO_SaveSector_continue_write
850
851
852 ;
853 ; WE HAVE A SEVERE ERROR CONDITION !
854 ; SOME AB CODE TRIES TO WRITE A NON-MBR TO THE DISK !
855 ; ASK THE USER TO REPORT THIS !
856 ; HALT THE SYSTEM !
857 ;
858
859 ; Show error-box
860 mov cx, 0C04h
861 mov si, offset NonMBRwrite
862 call SETUP_ShowErrorBox
863 mov cx, 0C04h
864 mov si, offset NonMBRwrite_rep
865 call SETUP_ShowErrorBox
866
867
868 IFDEF AUX_DEBUG
869 pusha
870 mov si, offset NonMBRwrite
871 call AuxIO_TeletypeNL
872 call AuxIO_Print
873 call AuxIO_TeletypeNL
874 popa
875 ENDIF
876
877 ; Show popup and halt the system.
878 jmp HaltSystem
879
880
881
882 ;
883 ; Continue the write if not MBR sector or MBR to write is validated.
884 ;
885 DriveIO_SaveSector_continue_write:
886 test byte ptr cs:[CurIO_UseExtension], 1
887 jz DIOSS_UseNormal
888 ; Are we forced do use LBA via Setting?
889 ; Always use INT13X on v1.0.8+.
890 ;~ test byte ptr cs:[CFG_ForceLBAUsage], 1
891 ;~ jnz DIOSS_UseExtension
892 jmp DIOSS_UseExtension
893 ; Is the drive not a harddrive?
894 cmp dl, 80h
895 jb DIOSS_UseNormal
896 ; Upper 8 bits of LBA-address set? -> Use LBA (maximum boundary is FB0400h)
897 or bh, bh
898 jnz DIOSS_UseExtension
899 ; Compare Switch-Table value to bit 16-23 of LBA-address
900 mov di, dx
901 and di, 007Fh
902 cmp bptr cs:[LBASwitchTable+di], bl
903 jbe DIOSS_UseExtension
904
905 DIOSS_UseNormal:
906 mov di, 3
907 DIOSS_ErrorLoop:
908 push ds
909 pop es
910 mov bx, si ; ES:BX - Destination
911 mov ax, 0301h ; Function 3 - Write Sector
912 int 13h
913 jnc DIOSS_Success
914 dec di
915 jnz DIOSS_ErrorLoop
916 call MBR_SaveError
917
918 DIOSS_UseExtension:
919
920 mov di, ds ; segment for transfer address
921 mov cx, ax ; low word of lba
922 xor ax, ax ; no verify
923 call DriveIO_WriteSectorLBA ; extended write
924 jc MBR_SaveError ; halt on error
925
926 ;~ push cx
927 ;~ mov cs:[INT13X_DAP_NumBlocks], 1 ; Copy ONE sector
928 ;~ mov wptr cs:[INT13X_DAP_Transfer+0], si
929 ;~ mov cx, ds
930 ;~ mov wptr cs:[INT13X_DAP_Transfer+2], cx ; Fill out Transfer Adress
931 ;~ mov wptr cs:[INT13X_DAP_Absolute+0], ax
932 ;~ mov wptr cs:[INT13X_DAP_Absolute+2], bx ; Fill out Absolute Sector
933 ;~ push cs
934 ;~ pop ds
935 ;~ mov si, offset [INT13X_DAP]
936 ;~ mov ax, 4300h ; Extended Write (No Verify)
937 ;~ int 13h
938 ;~ pop cx
939 ;~ jnc DIOSS_Success
940 ;~ call MBR_SaveError
941
942 DIOSS_Success:
943 ret
944DriveIO_SaveSector EndP
945
946
947
948; ------------------------------------------------------
949; Rousseau: # Load the master LVM-sector if one exists #
950; ------------------------------------------------------
951; Load the master LVM-sector to get the number of sectors per track as
952; OS/2 views the drive. If no master LVM-sector is found it is assumed OS/2
953; is not installed. The master LVM-sector can be located at three different
954; places depending on drive size and partitioning scheme and driver used.
955; When DANIS506.ADD is used, the OS/2 extended geometry will be 255/127 for
956; drives >502GiB but <1TiB. Then the location will be sector 127 which
957; is LBA 126 (7Eh).
958; IBM1S506.ADD will always use 255/255 for the extended OS/2 geometry.
959; DANIS506.ADD will use 255/255 for drives >1TiB.
960; Then the location of the master LVM-sector will be 255 which is LBA 254 (FEh).
961; When OS/2 is installed on a huge drive that alread had a system on it, OS/2
962; will be confined to the lower 502GiB of the drive.
963; In this case the normal geometry from Int13X will be used.
964; This is also the case when no valid master LVM-sector can be found.
965;
966; Return CF when valid master LVM sector found, NC if not.
967; Loads sector at [LVMSector] !
968DriveIO_LoadMasterLVMSector Proc Near
969 pusha
970
971 ;~ mov si,offset db_lmlvm
972 ;~ call AuxIO_Print
973
974 ;~ ; Physical disk
975 ;~ mov al,'<'
976 ;~ call VideoIO_PrintSingleChar
977 ;~ mov al,dl
978 ;~ call VideoIO_PrintHexByte
979 ;~ mov al,'>'
980 ;~ call VideoIO_PrintSingleChar
981;~
982 ;~ call AuxIO_TeletypeHexByte
983 ;~ call AuxIO_TeletypeNL
984
985
986 ; Loop over the sector-translation table,
987 ; process the first three values from high (255) to low.
988 ; (bios spt, most likely 63)
989 mov cx,3
990 DriveIO_LoadMasterLVMSector_NextTry:
991 ; Number of sectors to read
992 mov [INT13X_DAP_NumBlocks],1
993
994 ; Setup destination address
995 mov si, offset [LVMSector]
996 mov word ptr [INT13X_DAP_Transfer+0],si
997 mov ax, ds
998 mov word ptr [INT13X_DAP_Transfer+2],ax
999
1000 ; Get the sector-number of the next possible LVM sector (255,127,63)
1001 ; using the translation table and the counter as the index
1002 mov bx,offset secs_per_track_table
1003 mov ax,cx
1004 dec ax
1005 xlatb
1006 dec al
1007
1008 ;
1009 ; AX now contains the LBA address of the sector
1010 ; that could be an LVM sector.
1011 ; This is all in track0 so the address will not exceed 64kiB sectors.
1012 ;
1013
1014 ;~ push ax
1015 ;~ push ax
1016 ;~ mov al,'$'
1017 ;~ call VideoIO_PrintSingleChar
1018 ;~ pop ax
1019 ;~ call VideoIO_PrintHexByte
1020 ;~ mov al,'$'
1021 ;~ call VideoIO_PrintSingleChar
1022 ;~ pop ax
1023
1024 IFDEF AUX_DEBUG
1025 ; Dump the value
1026 ;~ call AuxIO_TeletypeHexByte
1027 ;~ call AuxIO_TeletypeNL
1028 ENDIF
1029
1030 ; Setup the requested LBA sector number
1031 mov word ptr [INT13X_DAP_Absolute+0],ax ; LBA low NORMAL I/O GEBRUIKEN !
1032 mov word ptr [INT13X_DAP_Absolute+2],00h ; LBA high
1033 mov si, offset [INT13X_DAP] ; address request packet
1034 mov ah, 42h
1035 int 13h ; do the i/o, CF=1->error, CF=0->success
1036
1037IFDEF AUX_DEBUG
1038 pushf
1039 pusha
1040 pushf
1041 xor ax, ax
1042 mov al, dl
1043 call AuxIO_TeletypeHexWord
1044 mov al, '#'
1045 call AuxIO_Teletype
1046 popf
1047 mov ax,0000h
1048 rcl al, 1
1049 call AuxIO_TeletypeHexWord
1050 mov al, '#'
1051 call AuxIO_Teletype
1052 mov ax,word ptr [INT13X_DAP_Absolute+0]
1053 call AuxIO_TeletypeHexWord
1054 mov al, '#'
1055 call AuxIO_Teletype
1056 popa
1057 popf
1058ENDIF
1059
1060 cmc ; Complement carry so we can exit imm. on error
1061 jnc DriveIO_LoadMasterLVMSector_End ; oops, return with NC
1062
1063
1064 mov si,offset [LVMSector]
1065
1066 ; See if this is a valid LVM-sector
1067 ; ZF=0 if valid
1068 call LVM_ValidateSector
1069
1070; pushf
1071; mov ah,0
1072; rcl ah,1
1073; mov al,'|'
1074; call VideoIO_PrintSingleChar
1075; mov al,ah
1076; call VideoIO_PrintHexByte
1077; mov al,'|'
1078; call VideoIO_PrintSingleChar
1079; popf
1080
1081
1082 ; Yep, we found the master LVM-sector
1083 jnz DriveIO_LoadMasterLVMSector_Found
1084 ; Try next location
1085 loop DriveIO_LoadMasterLVMSector_NextTry
1086
1087 ; No master LVM-sector found, set CF=false
1088 clc
1089
1090 DriveIO_LoadMasterLVMSector_Found:
1091 ; Store the address for later use.
1092 mov ax, word ptr [INT13X_DAP_Absolute]
1093 mov word ptr [MasterLVMLBA], ax
1094
1095 DriveIO_LoadMasterLVMSector_End:
1096 popa
1097 ret
1098DriveIO_LoadMasterLVMSector Endp
1099
1100
1101
1102
1103; ---------------------------------------------------
1104; Rousseau ## Large drives, (OS/2) geometry and LBA ##
1105; ---------------------------------------------------
1106; A sector size of 512 bytes is assumed in the below calculations.
1107; Note that this scheme changes when the sector size will be 4096 or larger,
1108; like with modern drives that do not translate to 512 bytes per sector anymore.
1109; These drives will have a capacity above the 2TiB LBA32 boundary.
1110; For now, we assume drives <=2TiB with a sector size of 512 bytes.
1111
1112; There are a few boundaries that are of importance.
1113; Note that these are disk-boundaries and not partition boundaries.
1114; Even with a small partition, like <502GiB, OS/2 will use extended geometry on
1115; an empty huge disk.
1116; These boundaries are (from high to low):
1117
1118; (code 5)
1119; 2^32 = 4294967296 = 100000000 sectors = 2048 GiB
1120; This is the LBA32 2TiB boundary.
1121; Everything above it must be addressed using LBA48.
1122; OS/2 can currently not address this space above.
1123
1124; (code4)
1125; 65536*255*255 = 4261478400 = FE010000 sectors ~ 2032 GiB
1126; This is the max OS/2 boundary using 255/255 extended geometry.
1127; OS/2 can currently not address this space above.
1128
1129; (code 3)
1130; 2^31 = 2147483648 = 80000000 sectors = 1024 GiB
1131; This is the LBA32 1TiB boundary.
1132; OS/2 can address this space and will use 255/255 extended geometry.
1133
1134; (code 2)
1135; 65536*255*127 = 2122383360 = 7E810000 sectors ~ 1012 GiB
1136; This is the DANI 1TiB boundary.
1137; OS/2 can address this space and will use 255/255 extended geometry.
1138; Below this DANI will use 255/127 extended geometry.
1139; This matters on where the LVM-sectors are located !
1140
1141; (code 1)
1142; 65536*255*63 = 1052835840 = 3EC10000 sectors ~ 502 GiB
1143; This is the current OS/2 limit using this geometry because OS/2 can
1144; currently not address more than 65536 cylinders.
1145; DANI will address space above with 255/127 extended geometry up until
1146; the DANI 1TiB boundary (code 2)
1147
1148; (code 0)
1149; Everything below 65536*255*63 will be addressed using standard geometry.
1150
1151
1152;
1153; This function will return the following values:
1154;
1155
1156; 5 = This drive is above the 2^32 LBA32 (2TB) boundary and has more
1157; than 4294967296 sectors.
1158; LBA48 addressing is needed to access the complete capacity of the drive.
1159; OS/2 is currently unable to do so.
1160
1161; 4 = This drive is above the 65536*255*255 (4261478400) boundary but below 2^32.
1162; This is an OS/2 boundary and OS/2 is not able to access the drive above
1163; this boundary.
1164
1165; 3 = This drive is above the 2^31 (1TB) boundary and has more than
1166; 2147483648 sectors.
1167; OS/2 is able to access the drive using it's extended geometry.
1168; Both DANIS506 and IBM1S506 will use the 255/255 scheme.
1169
1170; 2 = This drive is above the 65536*255*127 (2122383360) boundary but below 2^31.
1171; OS/2 is able to access the drive using it's extended geometry.
1172; Both DANIS506 and IBM1S506 will use the 255/255 scheme.
1173
1174; 1 = This drive is above the 65536*255*63 (1052835840) boundary but
1175; below 65536*255*127.
1176; OS/2 is able to access the drive using it's extended geometry.
1177; Note that DANIS506 will use 255/127 and IBM1S506 will use 255/255 geometry !
1178; Using DANI or IBM influences the location of the LVM info-sectors !
1179
1180; 0 = This drive is below the 65536*255*63 (1052835840) boundary.
1181; OS/2 is able to access this drive using the standard 255/63 geometry.
1182
1183; So, any return value >0 means OS/2 extended geometry will be used.
1184; Value 1 will use 255/127 with DANIS506 but 255/255 with IBM1S506.
1185; Values 2 and 3 will use 255/255 on both drivers.
1186; You can or with 0x01 and check for 3 in this case.
1187; Any value above 3 will be a drive who's capacity cannot be fully used by OS/2
1188; The upper limit of 65536*255*255 will be in effect here.
1189
1190; Note this function currently handles the boot-drive only !
1191; It should be extended and use dl for the drive-number as a parameter.
1192; Because we use this function to get this info in a number of places,
1193; all regs and flags except AX are saved and restored.
1194
1195; DL contains BIOS disk-number; 80h for first, 81h for second, etc.
1196DriveIO_GatherDiskInfo Proc Near
1197 pushf
1198 push bx
1199 push cx
1200 push dx
1201 push si
1202 push di
1203 push es
1204
1205 ; Set ES to CS for buffer clearing
1206 push cs
1207 pop es
1208
1209 ; Clear the buffer
1210 ; Also setup the buffer size.
1211 ; Old Phoenix BIOSses require word (flags) at 02 to be zero,
1212 ; so we clear the whole buffer to be sure.
1213 mov cx, i13xbuf_size ; Dynamically calculated by assembler.
1214 mov di, offset i13xbuf ; Points to size field.
1215 mov [di],cx ; Setup buffer-size.
1216 inc di
1217 inc di ; Now pointing at actual buffer.
1218 xor ah,ah ; Fill value.
1219 cld ; Direction up.
1220 rep stosb ; Clear buffer.
1221
1222 ; Get the drive parameters
1223 mov ah, 48h ; Get Drive Parameters (extended version)
1224 ;mov dl, 80h ; Drive number
1225 mov si, offset i13xbuf ; Buffer for result-info
1226 push dx
1227 int 13h ; Call the BIOS-function
1228 pop dx
1229
1230 ; Do some error-checking
1231 or ah,ah ; AH is zero if no error (ZF=1 if no error)
1232 mov ax,0 ; Setup code for non-huge drive (does not influence ZF)
1233 jz DriveIO_GatherDiskInfo_ok ; Return if error (AL<>0 thus ZF=0) but CY not set, assuming non-huge drive
1234 jnc DriveIO_GatherDiskInfo_ok ; Return if error (CY=1), assuming non-huge drive
1235 jmp DriveIO_GatherDiskInfo_ret
1236
1237
1238 DriveIO_GatherDiskInfo_ok:
1239
1240 ;
1241 ; Store the drive geometry
1242 ;
1243
1244 mov si, offset i13xbuf
1245
1246 xor dh,dh
1247 and dl,01111111b
1248 shl dx,1
1249 shl dx,1
1250
1251 ; Store number of cylinders on disk
1252 mov bx, offset BIOS_Cyls
1253 add bx,dx
1254 mov ax,[si+04h]
1255
1256 mov word ptr [bx+00],ax
1257 mov ax,[si+06]
1258 mov word ptr [bx+02],ax
1259
1260 ; Store number of heads per cylinder
1261 mov bx, offset BIOS_Heads
1262 add bx,dx
1263 mov ax,[si+08h]
1264 mov word ptr [bx+00],ax
1265 mov ax,[si+0ah]
1266 mov word ptr [bx+02],ax
1267
1268 ; Store number of sectors per track
1269 mov bx, offset BIOS_Secs
1270 add bx,dx
1271 mov ax,[si+0ch]
1272 mov word ptr [bx+00],ax
1273
1274 ; Update first byte of translation-table to conform to BIOS SPT
1275 mov byte ptr [secs_per_track_table], al
1276
1277 mov ax,[si+0eh]
1278 mov word ptr [bx+02],ax
1279
1280 ; Store total secs
1281 mov bx, offset BIOS_TotalSecs
1282 add bx,dx
1283 add bx,dx
1284 mov ax,[si+10h]
1285
1286 mov word ptr [bx+00],ax
1287 mov ax,[si+12h]
1288 mov word ptr [bx+02],ax
1289 mov ax,[si+14h]
1290 mov word ptr [bx+04],ax
1291 mov ax,[si+18h]
1292 mov word ptr [bx+06],ax
1293
1294 ; Store number of bytes per sector
1295 mov bx, offset BIOS_Bytes
1296 add bx,dx
1297 mov ax,[si+18h]
1298 mov [bx],ax
1299
1300
1301 ;
1302 ; See of it's a huge drive of not
1303 ;
1304
1305 ; Drive is larger than 2TiB
1306 mov ax,5 ; Drive code (5)
1307 mov bx, [si+14h] ; Low word of high dword of sector-count
1308 or bx, [si+16h] ; High word of high dword of sector-count
1309 jnz DriveIO_GatherDiskInfo_ret ; If non-zero we have a drive with >2^32 sectors and thus LBA48 addressing
1310
1311 ; Drive is larger than max OS/2 capacity
1312 dec ax ; Drive code (4)
1313 mov bx, [si+12h] ; High word of low dword of sector-count
1314 cmp bx, 0fe01h ; Boundary
1315 jae DriveIO_GatherDiskInfo_ret ; If above or equal to boundary,
1316 ; we have a drive larger than to 65536*255*255 = FE010000 sectors
1317
1318 ; Drive can be completely utilized by OS/2
1319 dec ax ; Drive code (3)
1320 cmp bx, 8000h ; Boundary
1321 jae DriveIO_GatherDiskInfo_ret ; If above or equal to boundary,
1322 ; we have a drive larger than 2^31 sectors but smaller than 65536*255*255
1323
1324 ; This is the small area between DANI 1TiB and LBA 1TiB
1325 dec ax ; Drive code (2)
1326 cmp bx, 7e81h ; Boundary
1327 jae DriveIO_GatherDiskInfo_ret ; If above or equal to boundary,
1328 ; we have a drive larger than 65536*255*127 but <65536*255*255
1329 ; DANIS506.ADD will use 255/255 extended geometry
1330
1331 ; DANI will use 255/127 in this area, this could impact the location of LVM-sectors ! (last sec on track)
1332 dec ax ; Drive code (1)
1333 cmp bx, 3ec1h ; Boundary
1334 jae DriveIO_GatherDiskInfo_ret ; If above or equal to boundary,
1335 ; we have a drive larger than 65536*255*63 sectors (OS/2 502GiB Limit!)
1336 ; DANIS506.ADD will use 255/127 extended geometry !
1337 ; IBM1S506.ADD will use 255/255 extended geometry !
1338
1339 ; We have a drive that can be addressed using standard 255/63 geometry
1340 dec ax ; Drive code (0)
1341 ; We have a drive smaller than 65536*255*63 = 3EC10000 sectors
1342
1343 DriveIO_GatherDiskInfo_ret:
1344 pop es
1345 pop di
1346 pop si
1347 pop dx
1348 pop cx
1349 pop bx
1350
1351 mov byte ptr [CurIO_UseExtension],1
1352
1353 popf
1354 ret
1355DriveIO_GatherDiskInfo EndP
1356
1357
1358
1359; Values for sectors per track table corresponding to DriveIO_IsHugeDrive return value.
1360secs_per_track_table db 63,127,255,255,255,255
1361
1362;db_lmlvm: db 'Load Master LVM -- disk: ',0
Note: See TracBrowser for help on using the repository browser.