source: trunk/bootcode/regular/partmain.asm@ 128

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

Updated all debug hooks to use the new macros [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: 79.5 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 / PARTiTiON REGULAR ROUTINES
20;---------------------------------------------------------------------------
21
22IFDEF MODULE_NAMES
23DB 'PARTMAIN',0
24ENDIF
25
26PART_FixUpDefaultPartitionValues Proc Near Uses dx si di
27 ; Fix-Up Default and Last Partition - If lost, search for Bootable
28 xor bl, bl
29 mov dl, CFG_PartDefault
30 call PART_FixUpSelectionNumber
31 mov CFG_PartDefault, dl
32 mov dl, CFG_PartLast
33 call PART_FixUpSelectionNumber
34 mov CFG_PartLast, dl
35 mov dl, CFG_PartAutomatic
36 call PART_FixUpSelectionNumber
37 mov CFG_PartAutomatic, dl
38 ret
39PART_FixUpDefaultPartitionValues EndP
40
41; Our resync process for partition number is as specified:
42;==========================================================
43; - If 0FFh -> Partition Disabled, so don't do anything to it...
44; - Try to use GetXref to get the new partition no via X-Ref Table
45; - If failed, increase partition no, till overflow or hit on specific
46; characteristic
47; On overflow -> Resume search from partition no 0
48;
49; Characteristic is a partition id. If this id is 0, then a bootable partition
50; is searched for.
51
52; Fixes a partition number, adjusting it to the new IPT after redetect
53; In: DL - Number of partition
54; BL - Requested Partition ID
55; Out: DL - New number of partition (guessed normally ;)
56PART_FixUpSelectionNumber Proc Near Uses ax cx
57 cmp dl, 080h
58 je PFUPN_SelectionDisabled
59 ja PFUPN_SpecialSelection
60 call PARTSCAN_GetXref ; DL - PartitionNo prev IPT
61 cmp dh, 0FFh ; DH -> Partition No in new IPT
62 je PFUPN_SelectionGone
63 mov dl, dh
64 PFUPN_SelectionDisabled:
65 ret
66
67 PFUPN_SpecialSelection:
68 cmp dl, 0FEh ; Resume-BIOS?
69 ja PFUPN_SpecialSelectionFloppy
70 cmp byte ptr [CFG_ResumeBIOSbootSeq], 0
71 je PFUPN_SelectionGone
72 jmp PFUPN_Found
73 PFUPN_SpecialSelectionFloppy:
74 cmp byte ptr [CFG_IncludeFloppy], 0
75 je PFUPN_SelectionGone
76 jmp PFUPN_Found
77
78 ; Partition is not referenced in New-IPT or Resume-BIOS/Floppy selected, but
79 ; actual media is disabled...so dig for requested partition
80 PFUPN_SelectionGone:
81 mov cl, CFG_Partitions
82 or cl, cl
83 jz PFUPN_NothingFound ; No partitions available -> so fail
84 or bl, bl
85 jz PFUPN_BootableSearchLoop
86 ; Search for Partition ID "BL"
87 PFUPN_PartIDsearchLoop:
88 call PART_GetPartitionPointer ; Gets SI for partition DL
89 cmp bptr ds:[si+LocIPT_SystemID], bl
90 je PFUPN_Found
91 dec cl
92 jz PFUPN_NothingFound
93 inc dl ; Increase
94 cmp CFG_Partitions, dl
95 ja PFUPN_PartIDsearchLoop
96 xor dl, dl
97 jmp PFUPN_PartIDsearchLoop
98
99 ; Search for Partition ID "BL"
100 PFUPN_BootableSearchLoop:
101 call PART_GetPartitionPointer ; Gets SI for partition DL
102 mov al, ds:[si+LocIPT_Flags]
103 and al, Flags_Bootable
104 jnz PFUPN_Found
105 dec cl
106 jz PFUPN_NothingFound
107
108 inc dl ; Increase
109 cmp CFG_Partitions, dl
110 ja PFUPN_PartIDsearchLoop
111 xor dl, dl
112 jmp PFUPN_PartIDsearchLoop
113
114 PFUPN_NothingFound:
115 mov dl, 080h ; Now being Disabled
116 PFUPN_Found:
117 ret
118PART_FixUpSelectionNumber EndP
119
120; ============================================================================
121; In: DS:SI - IPT-Entry of partition
122; DS:PartitionSector - Actual Boot-Record of partition
123; Out: *none* (BootRecordCRC updated)
124; CHECKME: Verify the change (BX points to sector to CRC) is working OK
125PART_UpdateBootRecordCRC Proc Near Uses bx
126 push si
127 ;~ mov si, offset PartitionSector
128 mov si, bx
129 mov bx, 4B4Dh ; Magic: 'MK'
130 call MBR_GetCheckOfSector
131 pop si
132 mov [si+LocIPT_BootRecordCRC], bx
133 ret
134PART_UpdateBootRecordCRC EndP
135
136
137
138; Rousseau:
139; ---------
140; Bug:
141; When ResumeBIOSbootSeq is zero, BX still gets decremented and shifted left.
142; Then when used as an index into ContinueBIOSbootTable to get the address
143; of the device-name, the index is two bytes too low, and SI get's loaded
144; with whatever is before the ContinueBIOSbootTable.
145; Then when SI is used to copy a null-terminated string, it depends on the
146; bogus location SI points to where a null-byte will appear.
147; Since I placed some text before the ContinueBIOSbootTable, the bogus pointer
148; SI obtained pointed to an area where there was no null-byte in sight for
149; more than 11 bytes, causing SI to overwrite the CD-ROM IPT entry with
150; garbage. It took me a while to tackle this one because I was baffled why
151; moving text around in STD_TEXT.ASM, where ContinueBIOSbootTable resides,
152; mattered while the offset of ContinueBIOSbootTable did not change.
153; This bug is also present in v1.06 but never surfaced because STD_TEXT.ASM
154; is kinda static and luck has it that the word preceding ContinueBIOSbootTable
155; presumably pointed to an area where a null byte was near.
156;
157; BOOKMARK: The nasty pointer bug
158
159
160; Copies the device-name to the Resume-BIOS IPT entry
161PART_UpdateResumeBIOSName Proc Near Uses ax bx cx si di
162
163 ; Get BIOS resume indicator.
164 ;movzx bx, CFG_ResumeBIOSbootSeq
165 mov bl,CFG_ResumeBIOSbootSeq
166 mov bh,0
167
168 ; Clear name of IPT-entry.
169 mov di, offset BIOScontIPTentry+LocIPT_Name
170 push di
171 mov cx, 11
172 mov al, ' '
173 rep stosb
174 pop di
175
176 ; If no resume then exit.
177 test bx,bx
178 jz PURBN_NoResumeBootSeq
179
180 ; Convert to index in name-table.
181 dec bx
182 shl bx, 1
183
184 ; Put the pointer to the name in SI.
185 mov si, word ptr [ContinueBIOSbootTable+bx]
186
187 ; Copy the name to the IPT-entry.
188 PURBN_BootDeviceCopyLoop:
189 lodsb
190 or al, al
191 jz PURBN_NoResumeBootSeq
192 stosb
193 jmp PURBN_BootDeviceCopyLoop
194
195 ; We're done.
196 PURBN_NoResumeBootSeq:
197
198 ret
199PART_UpdateResumeBIOSName EndP
200
201
202
203; ============================================================================
204; Partition-Pointer Functions
205; ============================================================================
206
207; Builds Pointer-Table straight (without filtering, w/o Floppy/CD-ROM/Kernels)
208PART_CalculateStraightPartPointers Proc Near
209 mov ax, offset PartitionTable
210 mov bx, offset PartitionPointers
211 mov cx, LocIPT_MaxPartitions
212
213 PCSPP_Loop:
214 mov ds:[bx], ax ; Move address IPT entry to PPT
215 add bx, 2 ; Advance pointer to PPT entry
216 add ax, LocIPT_LenOfIPT ; Advance pointer to IPT entry
217 dec cx ; Decrement counter
218 jnz PCSPP_Loop ; Next iteration
219
220 mov al, ds:[CFG_Partitions] ; Get number of partitions
221 mov ds:[PartitionPointerCount], al ; Update number for PPT
222 ret
223PART_CalculateStraightPartPointers EndP
224
225; This here does PartitionPointers in order for displaying in BootMenu
226; [this means filtering and including Floppy/CD-ROM/Kernels, if wanted]
227PART_CalculateMenuPartPointers Proc Near Uses si
228
229;!
230;! DEBUG_PROBE
231;!
232IFDEF AUX_DEBUGx
233 push 1241h
234 call DEBUG_Probe
235ENDIF
236
237 mov si, offset PartitionTable
238 mov bx, offset PartitionPointers
239 test byte ptr [CFG_IncludeFloppy], 1
240 jz PCMPP_NoFloppyInclude
241 mov ax, offset FloppyIPTentry
242 mov ds:[bx], ax
243 add bx, 2
244 PCMPP_NoFloppyInclude:
245
246 test byte ptr [CFG_ResumeBIOSbootSeq], 0FFh
247 jz PCMPP_NoResumeBootSeqInclude
248 mov ax, offset BIOScontIPTentry
249 mov ds:[bx], ax
250 add bx, 2
251 PCMPP_NoResumeBootSeqInclude:
252
253 ;movzx cx, CFG_Partitions ; LocIPT_MaxPartitions
254 mov cl,CFG_Partitions ; LocIPT_MaxPartitions
255 mov ch,0
256
257 or cx, cx
258 jz PCMPP_NoPartitions
259 PCMPP_Loop:
260 mov al, ds:[si+LocIPT_Flags]
261 and al, Flags_Bootable
262 jz PCMPP_IsNotBootable
263 mov ds:[bx], si
264 add bx, 2
265 PCMPP_IsNotBootable:
266 add si, LocIPT_LenOfIPT
267 dec cx
268 jnz PCMPP_Loop
269 PCMPP_NoPartitions:
270 sub bx, offset PartitionPointers
271 shr bx, 1
272 mov ds:[PartitionPointerCount], bl
273 ret
274PART_CalculateMenuPartPointers EndP
275
276; Gets a pointer to the given partition
277; In: DL - Number of partition
278; Out: SI - Pointer to it
279PART_GetPartitionPointer Proc Near Uses bx
280 cmp dl, 0FEh
281 je PGPP_IsBIOSbootSeq ; FEh -> Resume BIOS boot Sequence
282 ja PGPP_IsFloppy ; FFh -> Floppy
283 ;movzx bx, dl
284 mov bl,dl
285 mov bh,0
286
287 shl bx, 1
288 mov si, word ptr [PartitionPointers+bx]
289 ret
290
291 PGPP_IsBIOSbootSeq:
292;!
293;! DEBUG_PROBE
294;!
295IFDEF AUX_DEBUGx
296 push 1242h
297 call DEBUG_Probe
298ENDIF
299
300 mov si, offset BIOScontIPTentry
301 ret
302
303 PGPP_IsFloppy:
304 mov si, offset FloppyIPTentry ; PartitionTable-LocIPT_LenOfIPT
305 ret
306PART_GetPartitionPointer EndP
307
308; Gets the number of a partition pointer
309; In: SI - Pointer to Partition
310; Out: DL - Number of partition
311PART_GetPartitionNumber Proc Near Uses bx
312 mov dl, ds:[PartitionPointerCount]
313 mov bx, offset PartitionPointers
314 PGPN_SearchLoop:
315 cmp word ptr ds:[bx], si
316 je PGPN_Found
317 add bx, 2
318 dec dl
319 jnz PGPN_SearchLoop
320 mov dl, 0FFh
321 ret
322
323 PGPN_Found:
324 sub dl, ds:[PartitionPointerCount]
325 dec dl
326 not dl
327 ret
328PART_GetPartitionNumber EndP
329
330
331;
332; Following functions are only usable, when Partition-Pointer-View is filtered
333;
334
335; They will convert from and to unfiltered view (used in Boot-Menu)
336; In: DL - Number of partition in filtered view
337; Out: DL - Number of partition in straight view
338;
339; This gets the address of the IPT-entry from the Partition Pointer Table and
340; converts that to an index into the IPT; the straight view.
341;
342PART_ConvertToStraight Proc Near
343 ;movzx bx, dl
344 mov bl,dl ; Partition number to BX
345 mov bh,0
346
347 shl bx, 1 ; Convert to word index
348 mov ax, word ptr cs:[PartitionPointers+bx] ; Get the partition pointer
349 cmp ax, offset FloppyIPTentry ; Check for Floppy
350 jb PCTS_IsBIOSbootSeq ; Nope, is BIOS-bootseq
351 je PCTS_IsFloppy ; Is Floppy
352
353 ;
354 ; Is partition, AX contains pointer to IPT entry
355 ;
356 sub ax, offset PartitionTable ; Make relative
357 mov bl, LocIPT_LenOfIPT ; Length of IPT entry
358 div bl ; Divide with IPTlength
359 mov dl, al ; Index in IPT
360 ret
361
362 PCTS_IsBIOSbootSeq:
363 mov dl, 0FEh
364 ret
365 PCTS_IsFloppy:
366 mov dl, 0FFh
367 ret
368PART_ConvertToStraight EndP
369
370
371
372; In: DL - Number of partition in straight view
373; Out: DL - Number of partition in filtered view
374;
375; This searches for the absolute offset of an IPT-entry in the
376; PartitionPointers table.
377; This table holds the offsets of IPT partition entries that are in the Menu ?
378; If the offset/entry is found it's index, the filtered number, is returned.
379;
380PART_ConvertFromStraight Proc Near Uses es di
381;!
382;! DEBUG_PROBE
383;!
384IFDEF AUX_DEBUGx
385 push 1243h
386 call DEBUG_Probe
387ENDIF
388
389 cmp dl, 0FEh
390 jb PCFS_IsPartition
391 mov ax, offset BIOScontIPTentry
392 je PCFS_DoSearch
393 mov ax, offset FloppyIPTentry
394 jmp PCFS_DoSearch
395
396
397 PCFS_IsPartition:
398 ; First we get Partition-Offset in AX
399 ;movzx ax, dl
400 mov al,dl ; Index in IPT to AX
401 mov ah,0
402 mov bl, LocIPT_LenOfIPT ; Length of an IPT entry
403 mul bl ; Mul to get relative offset
404 add ax, offset PartitionTable ; Add to get absolute offset
405
406 ;
407 ; AX now points to the IPT entry of the partition.
408 ; This address is searched for in the Partition Pointer Table.
409 ;
410
411 PCFS_DoSearch:
412 ; Now search for this offset in our filtered Partition-Pointer-Table
413 push cs
414 pop es
415 mov di, offset PartitionPointers ; Point to table
416 mov cx, LocIPT_MaxPartitions ; Max number of entries to search
417 xor dl, dl ; Reply on Not-Found = Partition==0
418 repne scasw ; Compare-Loop
419 jne PCFS_NotFound
420 sub di, 2 ; One Back, so point to compared value
421 mov dx, di ; Offset in DX
422 sub dx, offset PartitionPointers ; Make relative
423 shr dx, 1 ; Convert to Index
424 ; Adjust for IncludeFloppy/etc. is automatically done, due Pointer-LookUp
425 PCFS_NotFound:
426 ret
427PART_ConvertFromStraight EndP
428
429
430
431; In: AX - Pointer to IPT Entry
432; Out: SI - Pointer to corresponding Size-Element
433; Destroyed: AX
434PART_GetSizeElementPointer Proc Near Uses bx
435 mov si, offset PartitionSizeTable
436 sub ax, offset PartitionTable
437 mov bl, LocIPT_LenOfIPT
438 div bl ; Divide with IPTlength
439 ;movzx bx, al
440 mov bl,al
441 mov bh,0
442
443 shl ax, 1
444 shl bx, 2
445 add ax, bx ; My way of multiplying with 6
446 add si, ax ; SI - Partition Size-Element
447 ret
448PART_GetSizeElementPointer EndP
449
450; In: BX:AX - Sector Size (1=512 Bytes, 2=1024 Bytes, etc.)
451; ES:DI - Pointer to Size-Element (6 bytes)
452; Out: None, Size-Element filled out
453; Destroyed: AX, BX, DI
454PART_FillOutSizeElement Proc Near Uses cx dx
455 add di, 3 ; ES:DI - Last Digit of Size Digits
456 shr bx, 1
457 rcr ax, 1 ; /2 -> Sector Size is now KByte Size
458 xor cl, cl ; 0 - KByte, 1 - MByte, 2 - GByte
459 PFOSE_MakeSmallerLoop:
460 or bx, bx
461 jnz PFOSE_MakeSmaller
462 cmp ax, 9999
463 jbe PFOSE_IsSmallEnough
464 PFOSE_MakeSmaller:
465 mov dx, bx
466 and dx, 1023 ; My crazy way of dividing a 32-bit
467 shr ax, 10 ; value through 1024 using 16-bit
468 shr bx, 10 ; instructions...
469 shl dx, 6
470 or ax, dx
471 inc cl ; Value got smaller...
472 jmp PFOSE_MakeSmallerLoop
473
474 PFOSE_IsSmallEnough:
475 ; First write the type of this Size-Element (KB/MB/GB)
476 mov bx, 'BK'
477 cmp cl, 1
478 jb PFOSE_WriteType
479 je PFOSE_IsMBtype
480 mov bx, 'BG'
481 jmp PFOSE_WriteType
482 PFOSE_IsMBtype:
483 mov bx, 'BM'
484 PFOSE_WriteType:
485 mov word ptr es:[di+1], bx
486 mov bx, 10 ; Digits are 10-Based
487 xor dx, dx
488 PFOSE_DigitLoop:
489 xor dx, dx
490 div bx ; AX - Digit, DX - Remainder
491 add dl, '0' ; Convert digit to ASCII digit
492 mov es:[di], dl
493 or ax, ax
494 jz PFOSE_EndOfDigitLoop
495 dec di ; Go to previous char
496 jmp PFOSE_DigitLoop
497
498 PFOSE_EndOfDigitLoop:
499 ret
500PART_FillOutSizeElement EndP
501
502
503
504
505
506
507
508
509
510
511
512; This routine is called to hide a partition
513; In: DL - Partition to hide
514; Destroyed: None
515PART_HidePartition Proc Near Uses ax bx cx dx si di
516
517IFDEF AUX_DEBUG
518 IF 0
519 DBG_TEXT_OUT_AUX 'PART_HidePartition:'
520 PUSHRF
521 ;~ call DEBUG_DumpRegisters
522 ;~ call AuxIO_DumpParagraph
523 ;~ call AuxIO_TeletypeNL
524 POPRF
525 ENDIF
526ENDIF
527
528 call PART_GetPartitionPointer ; Pointer to partition (DL) -> SI
529
530 ; First load the partition table of that partition...
531 mov ax, wptr [si+LocIPT_AbsolutePartTable+0]
532 mov bx, wptr [si+LocIPT_AbsolutePartTable+2]
533 mov cx, wptr [si+LocIPT_LocationPartTable+1]
534 mov dh, bptr [si+LocIPT_LocationPartTable+0]
535 mov dl, [si+LocIPT_Drive]
536 call DriveIO_LoadPartition
537 ; Partition-Table now LOADED
538 mov di, offset PartitionSector+446 ; ES:DI - 1st partitionentry...
539
540 ; Put our partition's location into registers...
541 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
542 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
543 sub ax, wptr [si+LocIPT_AbsolutePartTable+0]
544 sbb bx, wptr [si+LocIPT_AbsolutePartTable+2]
545 ; BX:AX - absolute position of partition relative to partition table
546 ; ...and search for it...
547 PHP_SearchLoop:
548 cmp ax, wptr es:[di+LocBRPT_RelativeBegin]
549 jne PHP_SearchMismatch
550 cmp bx, wptr es:[di+LocBRPT_RelativeBegin+2]
551 jne PHP_SearchMismatch
552 jmp PHP_SearchMatch
553 PHP_SearchMismatch:
554 add di, LocBRPT_LenOfEntry ; 16 Bytes per partition entry
555 cmp di, 500+offset PartitionSector
556 jb PHP_SearchLoop
557 jmp MBR_HaltSystem ; not found, something is wrong here
558
559 ; Found entry...
560 PHP_SearchMatch:
561 mov al, bptr es:[di+LocBRPT_SystemID] ; Partition-ID into AL
562 call PART_SearchFileSysHiddenID ; Put on =STEALTH=
563 mov bptr es:[di+LocBRPT_SystemID], al
564 call DriveIO_SavePartition ; Saves Partition-Table
565 ret
566PART_HidePartition EndP
567
568
569
570
571
572; This here is for marking the first "good" non-hidden partition as being
573; active. It requires the partition table at EXECBASE.
574; Some BIOSes have problems with no primary marked active. Actually this is
575; a buggy implementation, because the MBR-code should normally check,
576; *not* the BIOS. This one *could* cause havoc to some systems, but I can't
577; do anything else.
578PART_MarkFirstGoodPrimary Proc Near Uses ax si di
579
580IFDEF AUX_DEBUG
581 IF 0
582 DBG_TEXT_OUT_AUX 'PART_MarkFirstGoodPrimary:'
583 PUSHRF
584 ;~ call DEBUG_DumpRegisters
585 ;~ call AuxIO_DumpParagraph
586 ;~ call AuxIO_TeletypeNL
587 POPRF
588 ENDIF
589ENDIF
590
591 mov di, offset PartitionSector+446 ; DS:SI - 1st partitionentry
592 ; First action to do: Remove the active flag from every partition
593 push di
594 mov cl, 4
595 PMPP_RemoveActiveFlagLoop:
596 and bptr es:[di+LocBRPT_Flags], 7Fh
597 add di, LocBRPT_LenOfEntry
598 dec cl
599 jnz PMPP_RemoveActiveFlagLoop
600 pop di
601 ; First Search, will hit on any PartitionID that is:
602 ; a) not 0
603 ; b) not hidden
604 ; c) not extended partition (05h or 0Fh)
605 PMPP_Search1Loop:
606 mov al, bptr es:[di+LocBRPT_SystemID]
607 or al, al
608 jz PMPP_Search1NoHit
609 cmp al, 05h
610 je PMPP_Search1NoHit
611 cmp al, 0Fh
612 je PMPP_Search1NoHit
613 mov bl, al ; BL == AL == PartitionID
614 push si
615 call PART_SearchFileSysName
616 pop si ; AL == UnhiddenPartitionID
617 cmp al, bl ; if ID is unhidden...
618 je PMPP_SearchHit
619 PMPP_Search1NoHit:
620 add di, LocBRPT_LenOfEntry ; 16 Bytes per Partition-Entry
621 cmp di, 500+offset PartitionSector
622 jb PMPP_Search1Loop
623
624 mov di, offset PartitionSector+446 ; DS:SI - 1st Partition-Entry
625 ; Second Search, hit on anything that is not an extended partition
626 ; (05 or 0Fh)
627 PMPP_Search2Loop:
628 mov al, bptr es:[di+LocBRPT_SystemID]
629 or al, al
630 jz PMPP_Search2NoHit
631 cmp al, 05h
632 je PMPP_Search2NoHit
633 cmp al, 0Fh
634 jne PMPP_SearchHit
635 PMPP_Search2NoHit:
636 add di, LocBRPT_LenOfEntry ; 16 Bytes per Partition-Entry
637 cmp di, 500+offset PartitionSector
638 jb PMPP_Search2Loop
639 jmp PMPP_SearchFailed
640
641 PMPP_SearchHit:
642 or bptr es:[di], 80h ; SET ACTIVE PARTITION
643 PMPP_SearchFailed:
644 ret
645PART_MarkFirstGoodPrimary EndP
646
647; Searches the Name and Flags to a FileSysID (PartitionID)
648; In: AL - FileSysID
649; Out: AL - Unhidden File-System-ID, AH - Flags for this File-System
650; SI - Pointer to Name (8char)
651; Destroyed: *none*
652PART_SearchFileSysName Proc Near Uses bx dx
653 ;movzx bx, al
654 mov bl,al
655 mov bh,0
656
657 mov si, offset FileSysIDs
658 PSFSN_SearchLoop:
659 lodsw ; AL - NormalID, AH-HiddenID
660 mov dl, ds:[si] ; DL - File-System-Flags
661 inc si
662 cmp al, bl ; Check, if Unhidden-ID matches...
663 je PSFSN_Match
664 cmp ah, bl ; Check, if Hidden-ID matches...
665 je PSFSN_Match
666 mov al, bl ; So Unhidden-ID will be Original-ID
667 cmp ah, 0 ; Unknown (last ID in table)
668 je PSFSN_Match
669 inc bh
670 jmp PSFSN_SearchLoop
671
672 PSFSN_Match:
673 ; AL is already Unhidden-ID
674 mov ah, dl
675 ; AH is now the FileSystem-Flag
676 ;movzx bx, bh
677 mov bl,bh
678 mov bh,0
679
680 shl bx, 3 ; Offsets * 8
681 mov si, offset FileSysNames
682 add si, bx
683 ret
684PART_SearchFileSysName EndP
685
686; Searches the Hidden ID corresponding to a FileSysID (PartitionID)
687; In: AL - FileSysID
688; Out: AL - Hidden File-System-ID
689PART_SearchFileSysHiddenID Proc Near Uses bx
690 ;movzx bx, al
691 mov bl,al
692 mov bh,0
693
694 mov si, offset FileSysIDs
695 PSFSHI_SearchLoop:
696 lodsw ; AL - NormalID, AH-HiddenID
697 inc si
698 cmp al, bl ; Check, if Unhidden-ID matches...
699 je PSFSHI_Match
700 cmp ah, bl ; Check, if Hidden-ID matches...
701 je PSFSHI_Match
702 mov ah, bl ; So Unhidden-ID will get replied...
703 cmp ah, 0 ; Unknown (last ID in table)
704 je PSFSHI_Match
705 inc bh
706 jmp PSFSHI_SearchLoop
707
708 PSFSHI_Match:
709 mov al, ah ; AL = Hidden ID
710 ret
711PART_SearchFileSysHiddenID EndP
712
713; In: DS:SI - Partition-Name, CX - Maximum/Total Length
714; Out: Carry-Flag set, if valid Partition-Name
715; Destroyed: None
716PART_CheckForValidPartName Proc Near Uses ax cx dx si
717 ; Our logic is as follows:
718 ; If all chars are U -> Invalid (due reformated signature)
719 ; If anything below 32, but 0 -> Invalid (due invalid chars)
720 ; If anything above 165 -> Invalid (due invalid chars)
721 ; If anything between 123-128 -> Invalid (due invalid chars)
722 ; DX - holds count of 'U's
723 push cx
724 or cx, cx
725 jz PCFVPN_InvalidName
726 xor dx, dx
727 PCFVPN_CheckLoop:
728 lodsb
729 cmp al, 0
730 je PCFVPN_ValidChar
731 cmp al, 32
732 jb PCFVPN_InvalidName
733 cmp al, 165
734 ja PCFVPN_InvalidName
735 cmp al, 123
736 jb PCFVPN_ValidChar
737 cmp al, 128
738 jbe PCFVPN_InvalidName
739 PCFVPN_ValidChar:
740 cmp al, 'U'
741 jne PCFVPN_NoMagic
742 inc dx
743 PCFVPN_NoMagic:
744 dec cx
745 jnz PCFVPN_CheckLoop
746 pop cx
747 cmp cx, dx
748 clc
749 je PCFVPN_WasMagic
750 stc
751 PCFVPN_WasMagic:
752 ret
753 PCFVPN_InvalidName:
754 pop cx
755 clc
756 ret
757PART_CheckForValidPartName EndP
758
759
760
761; Compare a volume-label in the IPT to the install-volume
762; SI holds pointer to entry in IPT
763; CY set if this entry is also the install-volume
764PART_IsInstallVolume Proc Near Uses ax cx dx si di
765 cld ; Advance upwards with lodsb
766 mov di, offset OS2_InstallVolume ; Address of install-volume label (max. 11 chars)
767
768 mov cx, 11 ; Maximum length of label
769 xor dl, dl ; Not found yet
770
771 ; Compare next character
772 PART_IsInstallVolumeNext:
773 lodsb ; Load byte from SI (IPT-entry)
774 ;cmp al,' ' ; If space then use zero
775 ;jne PART_IsInstallVolume_skip1
776 ;xor al,al
777 PART_IsInstallVolume_skip1:
778 xchg ah,al ; Save char to AH
779 xchg si,di ; Exchange pointers
780 lodsb ; Load byte from SI (install-volume label)
781 ;cmp al,' ' ; If space then use zero
782 ;jne PART_IsInstallVolume_skip2
783 ;xor al,al
784 PART_IsInstallVolume_skip2:
785 xchg si,di ; Reexchange pointers
786 ;~ call AuxIO_Teletype
787 call CONV_ToUpper
788 ;~ call AuxIO_Teletype
789 xchg al,ah
790 ;~ call AuxIO_Teletype
791 call CONV_ToUpper
792 ;~ call AuxIO_Teletype
793 ;~ call AuxIO_TeletypeNL
794
795 ; Are both of them zero ?
796 ; Then the names could be the same, but cx must not equal 11
797 ; because that would indicate a null-string.
798 mov dh,al
799 or dh,ah
800 jz PART_IsInstallVolumeFound
801
802 cmp ah,al ; Are the the same ?
803 jnz PART_IsInstallVolumeNotFound ; Nope, compare ended
804 loop PART_IsInstallVolumeNext ; Yep, Compare next character
805
806 PART_IsInstallVolumeFound:
807 ; If CX is still 11 this was a zero string
808 ; and thus not a valid volume-name.
809 ; This should not occur as this function is only called when the first
810 ; byte is non-zero.
811 cmp cx,11
812 je PART_IsInstallVolumeNotFound
813 ; Found !
814 mov dl,1 ; Found
815 jmp PART_IsInstallVolumeEnd
816
817
818 PART_IsInstallVolumeNotFound:
819 mov dl,0
820 jmp PART_IsInstallVolumeEnd
821
822
823 PART_IsInstallVolumeEnd:
824 ; Set the status in CY
825 mov al,dl
826 add al,'0'
827 ;~ call AuxIO_TeletypeHexByte
828 ;~ call AuxIO_TeletypeNL
829 rcr dl,1 ; Put found-flag in CY
830 ret
831PART_IsInstallVolume EndP
832
833
834
835
836
837
838; If found CY=1, AL=partnum, else CY=0, AL=0FFH
839; BOOKMARK: Setup Phase1
840PART_SetupPhase1 Proc Uses bx cx dx si di
841
842 ;
843 ; Enumberate Bootable Systems by name
844 ; and prepare Phase 1 if active.
845 ;
846 ; This can also be implemented using the
847 ; Installable LVM-flag I think.
848 ; But at the time I had lesser knowledge about LVM...
849 ; So this algorithm may change in the future.
850 ;
851 mov byte ptr [Phase1Active],0 ; Clear phase1 indicator
852 mov si, offset PartitionTable ; Pointer to IPT
853 xor cx,cx
854 mov cl,[CFG_Partitions] ; Partitions in IPT
855
856 ; Process next entry in IPT
857 MBR_Parts:
858 add si, 4
859 ;push si
860 ;push si
861 ;call MBR_TeletypeVolName
862 ;pop si
863 call PART_IsInstallVolume ; Check if this is install-volume
864 jnc MBR_Parts_NI
865
866 ;
867 ; Install Volume found
868 ;
869 mov byte ptr [Phase1Active],1 ; Set phase1 indicator
870
871 mov al,' '
872 mov bl,7
873 mov ah, 0eh
874 int 10h
875
876 mov al,'('
877 mov bl,7
878 mov ah, 0eh
879 int 10h
880
881
882
883 mov al,[CFG_Partitions]
884 sub al,cl
885
886 mov dh,al
887
888
889 mov [CFG_PartAutomatic],al ; Setup entry for install-volume
890 mov [CFG_PartLast],al
891
892 add al,'1'
893 mov bl,7
894 mov ah, 0eh
895 int 10h
896
897 mov al,')'
898 mov bl,7
899 mov ah, 0eh
900 int 10h
901
902 ;mov bx,cx ; ????
903
904 mov al,dh
905 stc
906 jmp PART_SetupPhase1_found
907
908 MBR_Parts_NI:
909 ;xor si,si
910 ;call MBR_TeletypeNL
911 ;pop si
912 add si, 30 ; Add remainder of IPT entry
913 loop MBR_Parts
914
915 mov al,0ffh
916 clc
917
918 PART_SetupPhase1_found:
919
920 ret
921
922PART_SetupPhase1 EndP
923
924
925
926
927;~ PART_GetOldPartitionCount Proc Uses cx dx di
928 ;~ mov di,offset [PartitionXref]
929 ;~ mov dx,LocIPT_MaxPartitions
930 ;~ mov cx,dx
931 ;~ mov al,0ffh
932 ;~ cld
933 ;~ repne scasb
934 ;~ inc cx
935 ;~ sub dx,cx
936 ;~ mov ax,dx
937 ;~ ret
938;~ PART_GetOldPartitionCount EndP
939
940
941
942
943
944;~ HELEMAAL NAKIJKEN !
945;~ DRIVELETTER ASIGNMENT CORRIGEREN
946;~ WORDT TOCH BOOTDRIVE IN BPB GEZET ALS NON-OS/2 SYSTEEM BOOT ?
947
948
949
950; ###################
951; # START PARTITION #
952; ###################
953
954; Starts Partition DL from Internal Partition Table.
955; In: DL - Number of partition (filtered view)
956; Out: No Return...
957; Destroyed: None, due to no return ;-)
958; Logic: - Harddrive: loads partition Table
959; sets partition active
960; saves partition table
961; hides partitions, if needed
962; Linux-Support, if needed
963; load boot sector
964; VIBR checking, if wanted
965; install MBR Protection, if wanted
966; Special Boot Support, if needed (OS/2 Extended partitions)
967; Copy boot-sector to StartBase
968; run boot sector...
969PART_StartPartition Proc Near Uses ax dx es di
970
971IFDEF AUX_DEBUG
972 IF 0
973 DBG_TEXT_OUT_AUX 'PART_StartPartition:'
974 PUSHRF
975 ;~ call DEBUG_DumpRegisters
976 ;~ call AuxIO_DumpParagraph
977 ;~ call AuxIO_TeletypeNL
978 POPRF
979 ENDIF
980ENDIF
981
982 ;
983 ; Local Storage for this much too large function.
984 ;
985 local BootPartNo:byte
986 local PhysDiskBpbIndex:word ; Index into BPB to field of phys-disk
987 local FSType:byte ; The FS used on the loaded BPB
988 ; Only used for FAT/HPFS/JFS
989 local LVMdl:byte ; LVM drive-letter
990 local BPBdl:byte ; BPB boot-drive-letter. (at 25h)
991
992
993 ; Get Partition-Pointer (SI) to Partition-To-Boot (DL).
994 ; DL is filtered partition number and thus uses the PPT.
995 ; Returned is the address of the IPT entry of the partition to boot.
996 call PART_GetPartitionPointer
997
998
999 ;
1000 ; SI now points to the IPT entry for the partition to be booted.
1001 ;
1002
1003
1004 ; This converts DL filered view to straight view, aka index into the IPT.
1005 ; Needed for later.
1006 ; Destroys AX,BX
1007 call PART_ConvertToStraight
1008
1009 ; Save for later use.
1010 mov [BootPartNo], dl
1011 ; Straight - FFh -> Floppy boot
1012 ; FEh -> BIOS continue (CD-ROM, ZIP, etc.)
1013
1014 ; This converts the PPT to have pointers to all the IPT entries.
1015 ; We need straight pointers from now on, so calculate the table...
1016 ; Destroys AX,BX,CX
1017 call PART_CalculateStraightPartPointers
1018
1019
1020
1021 ; SI contains the pointer to the IPT to what partition to boot
1022 ; in this whole routine...it may never get messed up.
1023
1024 ; ------------------------------------------------- PRINT NAME BEING BOOTED
1025
1026 push si
1027 mov dl, [si+LocIPT_Drive] ; Disk where partition resides
1028 mov dh, [si+LocIPT_SystemID] ; AB FileSystem ID (08=NTFS, FC=JFS)
1029 ; Copy Partition-Name to BootingNow area for display purposes
1030 add si, LocIPT_Name ; Advance to AB partition-name
1031 mov cx, 11 ; Max. length of AB name/label
1032 call GetLenOfName ; Returns CX with length of label
1033 mov di, offset TXT_BootingNowPartName
1034 jz PSP_NoName ; Don't copy if zero length label
1035 rep movsb ; Copy label-name to boot
1036 PSP_NoName:
1037 xor al, al ; Null-terminate label-string
1038 stosb ; Ending Zero
1039
1040 ;
1041 ; Display "Booting the system using "
1042 ;
1043 mov si, offset TXT_BootingNow1
1044 call MBR_Teletype
1045
1046 ;~ pusha
1047 ;~ call MBR_Teletype
1048 ;~ mov si,offset TXT_BootingNowPartName
1049 ;~ call MBR_Teletype
1050 ;~ popa
1051
1052
1053 ;
1054 ; DL will be zero for floppy-disk or 80h+ for harddisk.
1055 ; Note thus that DL contains the BIOS disk numer and not the AB value
1056 ; for floppy or cdrom.
1057 ;
1058 or dl, dl
1059 jnz PSP_IsHarddisc
1060
1061 ; When booting floppy/CD-ROM/etc., we got other text to be displayed...
1062 mov si, offset TXT_BootingNowPartName
1063 call MBR_TeletypeVolName
1064 jmp PSP_IsFloppyCDROMetc ; JUMPS BUITEN SI POP !!! AANPASSEN
1065
1066
1067 PSP_IsHarddisc:
1068
1069
1070 ;
1071 ; Save configuration on HDD boots (save CFG_PartLast)
1072 ;
1073 call DriveIO_SaveConfiguration
1074
1075
1076 ;
1077 ; Prints out BootingNow2 including PartitionName
1078 ;
1079 mov si, offset TXT_BootingNowPartName
1080 call MBR_TeletypeVolName
1081 mov si, offset TXT_BootingNowPartition
1082 call MBR_Teletype
1083
1084 ; restores SI (IPT-pointer)
1085 pop si
1086
1087
1088
1089 ;
1090 ; Get the CHS and LBA location of sector containing
1091 ; the partition-table for the partition.
1092 ;
1093 mov ax, wptr [si+LocIPT_AbsolutePartTable+0]
1094 mov bx, wptr [si+LocIPT_AbsolutePartTable+2]
1095 mov cx, wptr [si+LocIPT_LocationPartTable+1]
1096 mov dh, bptr [si+LocIPT_LocationPartTable+0]
1097 mov dl, [si+LocIPT_Drive]
1098
1099IFDEF AUX_DEBUG
1100 IF 1
1101 pushf
1102 pusha
1103 mov si,offset [ptetb]
1104 call AuxIO_Print
1105 call DEBUG_DumpRegisters
1106 call AuxIO_TeletypeNL
1107 mov ax, word ptr [FreeDriveletterMap+00h]
1108 mov dx, word ptr [FreeDriveletterMap+02h]
1109 call AuxIO_TeletypeBinDWord
1110 popa
1111 popf
1112 ENDIF
1113ENDIF
1114
1115
1116 ;
1117 ; This loads the MBR in case of PRI or the EBR in case of LOG partitions.
1118 ;
1119 ; BOOKMARK: PBR/EBR loading
1120 call DriveIO_LoadPartition ; Load Table... [LOAD]
1121
1122
1123 ; -------------------------------------------------- MODIFY PARTITION TABLE
1124
1125 ; Make sure ES is correctly setup.
1126 push cs
1127 pop es
1128
1129 ; ES:DI - First Partitionentry
1130 mov di, offset PartitionSector+446
1131
1132 ; Remove all active-flags for safety reasons, primary partition table will
1133 ; have one partition set active by ScanPartition-routine.
1134 push di
1135 mov cl, 4
1136 PSP_RemoveActiveFlagLoop:
1137 and bptr es:[di+LocBRPT_Flags], 7Fh
1138 add di, LocBRPT_LenOfEntry
1139 dec cl
1140 jnz PSP_RemoveActiveFlagLoop
1141 pop di
1142
1143
1144 ;
1145 ; Put the partition-to-be-booted location into registers...
1146 ;
1147 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
1148 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
1149 sub ax, wptr [si+LocIPT_AbsolutePartTable+0]
1150 sbb bx, wptr [si+LocIPT_AbsolutePartTable+2]
1151
1152
1153 ; BX:AX - absolute position of partition relative to partition table
1154 ; ...and search for it...
1155 PSP_SearchLoop:
1156 cmp ax, wptr es:[di+LocBRPT_RelativeBegin]
1157 jne PSP_SearchMismatch
1158 cmp bx, wptr es:[di+LocBRPT_RelativeBegin+2]
1159 jne PSP_SearchMismatch
1160 jmp PSP_SearchMatch
1161 PSP_SearchMismatch:
1162 add di, LocBRPT_LenOfEntry ; 16 Bytes per Partition-Entry
1163 cmp di, 500+offset PartitionSector
1164 jb PSP_SearchLoop
1165
1166 ;
1167 ; Entry not found, Halt System.
1168 ;
1169 jmp MBR_HaltSystem
1170
1171 ; ------------------------------------------------------------- ENTRY FOUND
1172 PSP_SearchMatch:
1173 or byte ptr es:[di+LocBRPT_Flags], 80h ; set ACTIVE partition
1174
1175
1176
1177 ;
1178 ; Save the Partition Table.
1179 ;
1180 call DriveIO_SavePartition ; Saves the Partition-Table [SAVE]
1181
1182
1183
1184 ; --------------------------------------------------------------- OS/2 I13X
1185 ; Now check if the partition to get booted is above 8 GB.
1186 ; If yes, set magic bytes 'I13X' at 3000:0 for boot-loader to recognize.
1187 ; This method is (c) by IBM <g>
1188 ; Rousseau: Booting IBM-BM also requires the LBA address of the IBM-BM
1189 ; partitionafter the 'I13X' signature.
1190 ; Also, FS needs to be set to 3000H.
1191 ; This info was obtained by examining the LVM 2,x MBR-code.
1192 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
1193 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
1194 add ax, wptr es:[di+LocBRPT_AbsoluteLength+0] ; Add length to absolute
1195 adc bx, wptr es:[di+LocBRPT_AbsoluteLength+2] ; begin location
1196 ; BX:AX -> Absolute End-Position of Partition
1197
1198
1199 ;
1200 ; Always use INT13X v1.0.8+.
1201 ;
1202 ;~ test byte ptr [CFG_ForceLBAUsage], 1
1203 ;~ jnz PSP_ForceI13X
1204 jmp PSP_ForceI13X
1205
1206 ; LBA-boundary at 16450560 (FB0400h) (16320x16x63)
1207 cmp bx, 00FBh
1208 jb PSP_NoI13X
1209
1210 ;
1211 ; BOOKMARK: Setup 'I13X' signature.
1212 ;
1213 PSP_ForceI13X:
1214 push es
1215 push di
1216 push si
1217
1218 ; Setup ES and FS.
1219 ; FS needs to keep this address.
1220 mov ax, 3000h
1221 mov es, ax
1222 ; mov fs,ax
1223 db 08eh
1224 db 0e0h
1225
1226 ; Insert signature
1227 xor di, di
1228 mov word ptr es:[di+00], '1I'
1229 mov word ptr es:[di+02], 'X3'
1230
1231 ;mov wptr es:[di], 0
1232 ;mov wptr es:[di+2], 0
1233
1234 ; Insert LBA address.
1235 mov ax, [si+LocIPT_AbsoluteBegin+0]
1236 mov es:[di+04], ax
1237 mov ax, [si+LocIPT_AbsoluteBegin+2]
1238 mov es:[di+06], ax
1239
1240 pop si
1241 pop di
1242 pop es
1243
1244
1245
1246 PSP_NoI13X:
1247
1248 ; now check, if we need to hide any partition
1249 test byte ptr [si+LocIPT_Flags], Flags_HideFeature
1250 jz PSP_NoHideFeature
1251
1252 ; ---------------------------------------------------- PARTITION HIDING
1253
1254 ; display "hide active"
1255 push si
1256 mov si, offset TXT_BootingHide
1257 call MBR_Teletype
1258 pop si
1259
1260
1261 ; First, find Hide-Config
1262 mov dl, [BootPartNo] ; EntryNumber is straight view
1263 ;~ mov ax, LocIPT_MaxPartitions
1264 mov ax, LocHPT_LenOfHPT
1265 mul dl
1266 mov di, offset HidePartitionTable
1267 add di, ax ; We got the pointer
1268
1269
1270 ; So process Hide-Config. Read out Bitfield-Entries,
1271 ; each points to a partition.
1272 ; 3Fh is end-marker / maximum entries = CFG_Partitions
1273 mov cl, [CFG_Partitions]
1274 mov ch,0 ; Index in bitfield array.
1275 mov dh,6 ; Bitfield width.
1276 mov bx,di ; Pointer to entry.
1277
1278 PSP_PartitionsHideLoop:
1279 mov dl,ch
1280 call CONV_GetBitfieldValue
1281 mov dl,al
1282
1283 ;~ mov dl, es:[di]
1284 ;~ inc di
1285 ;~ cmp dl, 0FFh
1286 cmp dl,3fh ; Max value for 6-bits field.
1287 je PSP_EndOfHideProcess ; -> End of Hiding
1288 call PART_HidePartition ; Now hide that partition
1289 inc ch ; Next bitfield.
1290 dec cl
1291 jnz PSP_PartitionsHideLoop
1292
1293
1294 PSP_EndOfHideProcess:
1295
1296 ; --- HIDE COMPLETED ---
1297 ; So something got hidden and we have to remark a primary partition,
1298 ; if we are booting something non-primary from the boot-disk.
1299 mov al, [BIOS_BootDisk]
1300 cmp bptr [si+LocIPT_Drive], al
1301 jne PSP_HideAdjustPrimaryMark ; When booting any hdd, but boot-disk
1302 mov ax, wptr [si+LocIPT_AbsolutePartTable]
1303 mov bx, wptr [si+LocIPT_AbsolutePartTable+2]
1304 or ax, ax
1305 jnz PSP_HideAdjustPrimaryMark ; or booting non-primary partition
1306 or bx, bx ; on boot-disk.
1307 jz PSP_NoHideAdjustPrimaryMark
1308
1309 PSP_HideAdjustPrimaryMark:
1310 ; Load Primary Partition Table...
1311 xor ax, ax
1312 xor bx, bx
1313 mov cx, 0001h ; Cylinder 0, Sector 1
1314 xor dh, dh ; Head 0
1315 mov dl, [BIOS_BootDisk] ; Boot Disk
1316
1317 ; This uses the boot-disk and alters 'CurPartition_Location'.
1318 ; CHECKME: How does 81h being the boot-disk influences this ?
1319 call DriveIO_LoadPartition ; Load Primary Partition Table
1320
1321 ; This would only be needed for very old BIOSses
1322 call PART_MarkFirstGoodPrimary
1323
1324 ; CHECKME: Disabled writing back MBR with modified boot flags
1325 ; This is a safety measure now that booting AirBoot from other disks
1326 ; than 80h can occur.
1327 ;~ call DriveIO_SavePartition ; Saves the Partition-Table
1328
1329
1330 PSP_NoHideAdjustPrimaryMark:
1331
1332
1333 PSP_NoHideFeature:
1334 ; Check, if we are supposed to ignore LVM altogether...
1335 test byte ptr [CFG_IgnoreLVM], 1
1336 jnz PSP_NoLVMReassignment
1337
1338 ; ---------------------------------------------------- LVM REASSIGNMENT
1339
1340 ; Driveletter must be set for this partition
1341 test byte ptr [si+LocIPT_Flags], Flags_DriveLetter
1342 jz PSP_NoLVMReassignment
1343 ;movzx bx, BootPartNo ; EntryNumber is straight view
1344 mov bl,[BootPartNo] ; EntryNumber is straight view
1345 mov bh,0
1346
1347 mov al, bptr [DriveLetters+bx]
1348 sub al, 3Dh ; Convert e.g. 80h -> 'C'
1349 cmp al, bptr [PartitionVolumeLetters+bx]
1350
1351
1352 ;~ je PSP_NoLVMReassignment ; If driveletters match -> no change
1353 ; Rousseau:
1354 ; But there can still be other partitions with the same drive-letter.
1355 ; For instance if the user did an advanced installation with multiple
1356 ; eComStation systems using the same boot-drive-letter.
1357 ; So, even if the drive-letter forced is the same as the
1358 ; partition-volume-letter, other partitions still need to be checked
1359 ; and possibly hidden. So we always do the drive-letter reassignment,
1360 ; which is enhanced to keep data-partitions (those -not- in the Menu)
1361 ; visible. So the 'je' instruction above is commented-out.
1362
1363
1364 ;
1365 ; Give partition SI letter AL
1366 ;
1367 call LVM_DoLetterReassignment
1368
1369
1370
1371
1372 PSP_NoLVMReassignment:
1373 push si
1374 ; -------------------------------------------------- -"PLEASE WAIT..."-
1375 PSP_IsFloppyCDROMetc:
1376 mov si, offset TXT_BootingWait
1377 call MBR_Teletype ; display "please wait" ; SI staat nog op stack; aanpassen !!!!
1378 pop si
1379
1380 ; Process Partition Tables, if M$-Hack required (changes Ext Part Type)
1381 call MSHACK_ProcessPartTables
1382
1383 test byte ptr [CFG_BootMenuActive], 0FFh
1384 jz PSP_NoMenuNoSound
1385
1386 ; ---------------------------------------------------------- BOOT-SOUND
1387 call SOUND_ExecuteBoot
1388
1389 PSP_NoMenuNoSound:
1390
1391 ; --------------------------------------------- SPECIAL BOOT PROCESSING
1392 ; Check here, if the Boot shall be done via resume to BIOS...
1393 mov al, byte ptr [si+LocIPT_SystemID]
1394 cmp al, 0FEh ; Via BIOS ? (aka resume BIOS boot sequence)
1395 je PSP_ResumeBIOSbootSeq
1396
1397 jmp PSP_StartNormal
1398
1399 PSP_ResumeBIOSbootSeq:
1400 int 18h ; Give control back to BIOS
1401 db 0EAh ; if return to here -> Reboot
1402 dw 0FFF0h
1403 dw 0F000h
1404
1405
1406 ; =======================================================================
1407 ; FROM THIS POINT ON, ONLY DS and SI REGISTER IS NEEDED TO BE PRESERVED
1408 ; =======================================================================
1409
1410 PSP_StartNormal:
1411 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
1412 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
1413 mov cx, [si+LocIPT_LocationBegin+1]
1414 mov dh, [si+LocIPT_LocationBegin+0]
1415 mov dl, [si+LocIPT_Drive]
1416
1417 ; This loads the PBR of the partition.
1418 call DriveIO_LoadPartition ; Loads boot-sector... [PARTBOOTSEC]
1419
1420 ;
1421 ; The JFS PBR-code does not use the passed BPB in memory but uses the BPB
1422 ; on disk. This breaks the drive-letter feature on JFS.
1423 ; So we make a copy of the PBR in memory, and if the partition is JFS
1424 ; we later adjust the physical-disk and boot-drive-letter in this
1425 ; copy and write it back to disk.
1426 ; Then the JFS PBR-code will see the correct boot-drive-letter.
1427 ;
1428 pusha
1429 mov si,offset [PartitionSector]
1430 mov di,offset [PBRSector]
1431 mov cx,100h
1432 cld
1433 rep movsw
1434 popa
1435
1436
1437
1438 ; Check if the disk is a harddisk or a floppy.
1439 mov dl,[si+LocIPT_Drive]
1440 cmp dl, 80h
1441 jae is_harddisk
1442
1443 ;
1444 ; This is a dirty hack to fix booting from a floppy.
1445 ; With all the modifications made since v1.06 this feature was broken
1446 ; because Int13X is used implicitly now, and that does not work
1447 ; for diskette access.
1448 ; This jumps to the code that loads and starts the pbr-code.
1449 ; Note that it also skips virus checking !
1450 ; This will be fixed at a later date.
1451 jmp boot_from_floppy
1452
1453 ;
1454 ; The disk is a harddisk so we need to do various checks and fixes.
1455 ;
1456 is_harddisk:
1457
1458 test byte ptr [CFG_DetectVIBR], 1
1459 jz PSP_NoVIBR
1460 test byte ptr [si+LocIPT_Flags], Flags_VIBR_Detection
1461 jz PSP_NoVIBR
1462
1463
1464 ; ----------------------------------------------------- CHECKS FOR VIBR
1465 ; BOOKMARK: Check for virus in PBR
1466 push si
1467 mov si, offset PartitionSector
1468 mov bx, 4B4Dh ; Magic: 'MK'
1469 call MBR_GetCheckOfSector
1470 pop si
1471
1472 cmp [si+LocIPT_BootRecordCRC], bx
1473 je PSP_NoVIBR
1474 mov bx, [si+LocIPT_BootRecordCRC]
1475 or bx, bx
1476 jz PSP_NoVIBR
1477 ; Oh Oh, got a virus :(
1478 mov si, offset TXT_VirusFoundMain
1479 call MBR_Teletype
1480 mov si, offset TXT_VirusFound2 ; VIBR-Virus
1481 call MBR_Teletype
1482 mov si, offset TXT_VirusFoundEnd
1483 call MBR_Teletype
1484 jmp MBR_HaltSystem
1485
1486 PSP_NoVIBR:
1487 test byte ptr [CFG_ProtectMBR], 1
1488 jz PSP_NoMBRprotect
1489 ; --------------------------------------------- INSTALLS MBR-PROTECTION
1490 ; We need DS:SI later...
1491 push ds
1492 push si
1493
1494 ; First subtract 1024 bytes from Base-Memory...
1495 push ds
1496 mov ax, 40h
1497 mov ds, ax
1498 mov dx, word ptr ds:[13h]
1499 dec dx ; 1 == 1kbyte
1500 mov word ptr ds:[13h], dx
1501 pop ds
1502 shl dx, 6 ; trick, now DX is a segment
1503
1504 ; Now copy in our code (to DX:0)...
1505
1506 mov si, offset MBR_Protection ; DS:SI - Source Image
1507 mov es, dx
1508 xor di, di ; ES:DI - Destination
1509 ;~ mov cx, 512
1510 mov cx, 384
1511 rep movsw ; Move 768 bytes...
1512
1513 ; Now fill in variables...
1514
1515 xor ax, ax
1516 mov ds, ax
1517 mov si, 10h*4
1518 xor di, di ; INT 10h Vector to MBR Protection
1519 ;movsd
1520 movsw
1521 movsw
1522
1523 mov si, 13h*4 ; INT 13h Vector to MBR Protection
1524 ;movsd
1525 movsw
1526 movsw
1527
1528 mov al, CFG_IgnoreWriteToMBR ; Option to MBR Protection
1529 stosb
1530
1531 ; Now switch INT 13h vector to MBR Protection
1532
1533 sub si, 4
1534 mov ax, 9
1535 mov ds:[si], ax
1536 mov ds:[si+2], dx ; Vector hardcoded at DS:0009
1537 ; MBR-Protection now active :)
1538
1539 ; Restore DS:SI
1540 pop si
1541 pop ds
1542
1543
1544
1545 PSP_NoMBRprotect:
1546
1547 ; Display volume-name in bold
1548 ; Just before booting the selected partition
1549 ;pushf
1550 ;pusha
1551 ;push si
1552 ;add si, LocIPT_Name
1553 ;call MBR_TeletypeVolName
1554 ;xor si,si
1555 ;call MBR_TeletypeNL
1556 ;pop si
1557 ;popa
1558 ;popf
1559
1560
1561
1562
1563
1564 ; ------------------------------------------------ SPECIAL PARTITION SUPPORT
1565 ; needed by OS/2 Warp / eComStation
1566
1567
1568 ;cmp byte ptr [si+LocIPT_SystemID],08 ; I hate Microsuck NTFS check
1569 mov di, offset PartitionSector ; ES:DI - Actual Boot-Record
1570
1571 ; Special Support Detection
1572 ;mov ax, word ptr es:[di+18h]
1573 ;cmp ax, 003Fh ; Physical Layout-Sectors... Safety check
1574
1575
1576
1577 ;
1578 ; At this point, SI points to IPT and DI points to the PBR from disk.
1579 ; Depending on the type of BPB used, the physical disk field is at
1580 ; different locations: 24h for old-style (OS/2) BPB's and 40h for
1581 ; FAT32 BPB's.
1582 ; The OS/2 boot-drive-letter is located at 25h in an old-style BPB,
1583 ; while the corresponding field in a FAT32 BPB is located at 41h but
1584 ; used for different purposes.
1585 ; In case of HPFS, using old-style BPB's, the boot-drive-letter needs
1586 ; to be adjusted if it is zero.
1587 ; In that case we trace the LVM-info for that partition and use the
1588 ; drive-letter defined there.
1589 ; This fixes issues #3067 and #3119.
1590 ; Adjusting the physical disk is always done but at different locations
1591 ; depending on the BPB used.
1592 ; Also, the "hidden sectors" field is adjusted to contain the absolute
1593 ; offset from the start of the disk instead of the relative offset to
1594 ; the start of the partition.
1595 ; http://homepage.ntlworld.com./jonathan.deboynepollard/FGA/bios-parameter-block.html
1596 ;
1597
1598
1599 ; Get index of phys-disk field in BX
1600 call PART_GetFieldIndex
1601 mov [PhysDiskBpbIndex],ax
1602 mov bx,ax
1603
1604 ; Locate cursor for output of debug-info
1605 ;~ pusha
1606 ;~ mov ch,7
1607 ;~ mov cl,0
1608 ;~ call VideoIO_Color
1609 ;~ mov ch,6
1610 ;~ mov cl,1
1611 ;~ call VideoIO_Locate
1612 ;~ popa
1613
1614
1615 ; Debug display physdisk, ptype and physdisk offset in BPB
1616 ;~ pusha
1617 ;~ mov ah,[si+LocIPT_Drive]
1618 ;~ mov al,[si+LocIPT_SystemID]
1619 ;~ call VideoIO_PrintHexWord
1620 ;~ mov ax,bx
1621 ;~ call VideoIO_PrintHexWord
1622 ;~ mov ax,[si+LocIPT_AbsolutePartTable+02]
1623 ;~ call VideoIO_PrintHexWord
1624 ;~ mov ax,[si+LocIPT_AbsolutePartTable+00]
1625 ;~ call VideoIO_PrintHexWord
1626 ;~ mov al,[ExtendedAbsPosSet]
1627 ;~ call VideoIO_PrintHexByte
1628 ;~ mov al,'-'
1629 ;~ call VideoIO_PrintSingleChar
1630 ;~ mov al,byte ptr [Menu_EntrySelected]
1631 ;~ call VideoIO_PrintHexByte
1632 ;~ mov al,byte ptr [CFG_PartAutomatic]
1633 ;~ call VideoIO_PrintHexByte
1634 ;~ mov al,byte ptr [Phase1Active]
1635 ;~ call VideoIO_PrintHexByte
1636 ;~ mov al,byte ptr [NewPartitions]
1637 ;~ call VideoIO_PrintHexByte
1638 ;~ mov al, byte ptr [OldPartitionCount]
1639 ;~ call VideoIO_PrintHexByte
1640 ;~ popa
1641
1642
1643 ;
1644 ; If the partition is IBM-BM we skip all the BPB adjustments.
1645 ; IBM-BM does no need them.
1646 ;
1647 cmp byte ptr [si+LocIPT_SystemID], 0ah
1648 jnz no_os2_bm
1649 jmp chainload_ibm_bm
1650
1651
1652 no_os2_bm:
1653
1654 ;
1655 ; Update the phys-disk field
1656 ; DI points to PartitionSector
1657 ; BX holds index to phys-disk field
1658 ;
1659 mov al,byte ptr [si+LocIPT_Drive] ; Moet dit niet later gebeuren ??? (NT/WIN LDR hangs)
1660 mov es:[di+bx],al
1661
1662
1663 ;
1664 ; Legacy systems do not put the correct values in the "hidden sectors"
1665 ; field. Also, this field will be incorrect if a partition is moved on
1666 ; disk by a disktool not accounting for this field.
1667 ; Linux does not have a BPB at all, and does not use this field.
1668 ; So we set the correct value here obtained by the partition scanner.
1669 ; This fixing is done by OS/2 BM as well, according to Martin.
1670 ;
1671
1672 ; BOOKMARK: Fix hidden sectors field
1673 mov ax,[si+LocIPT_AbsoluteBegin]
1674 mov es:[di+1ch], ax ; Low word of 32-bits "hidden sectors"
1675
1676 mov ax,[si+LocIPT_AbsoluteBegin+2]
1677 mov es:[di+1eh], ax ; High word of 32-bits "hidden sectors"
1678
1679 ;
1680 ; Check partitions to see if boot-drive-letter fixing is needed.
1681 ; FAT12/FAT16/HPFS/JFS will have the value at 25h fixed
1682 ; to the LVM-info drive-letter. (+3dh to convert to BIOS notation)
1683 ;
1684
1685
1686 ; Setup partition disk and LBA address
1687 mov dl,byte ptr [si+LocIPT_Drive]
1688 mov cx,[si+LocIPT_AbsoluteBegin+00h]
1689 mov bx,[si+LocIPT_AbsoluteBegin+02h]
1690
1691 ; AL is gonna be used to shift-in CY status.
1692 ; If the type of file-system is one of FAT12/FAT16/HPFS/JFS then
1693 ; AL will be <> 0 and the boot-drive-letter can be tested / fixed.
1694 mov al,0
1695
1696
1697 ;
1698 ; The PBR is already loaded, no need to load it again in the
1699 ; calls below.
1700 ;
1701 ; Better use the already done discovery to determine the system.
1702 ;
1703 ; FIXME: PBR Already loaded
1704
1705 ; When FAT12/FAT16/HPFS/JFS then boot-drive-letter can be tested
1706 ; or adjusted.
1707 call PART_IsJFS
1708 rcl al,1
1709 call PART_IsHPFS
1710 rcl al,1
1711 call PART_IsFAT
1712 rcl al,1
1713 mov ah,al
1714
1715 ; Store for later reference.
1716 mov [FSType],al
1717
1718
1719 ;
1720 ; When the phys-disk byte (80h) is put in this BPB in RAM,
1721 ; Windows will not find it's loader if Windows itself
1722 ; is installed in a logical partition but the loader is on FAT
1723 ; in a primary.
1724 ; This goes for all NT-based versions ?
1725 ;
1726
1727
1728 ;
1729 ; See if phys-disk / boot-drive-letter fix is needed
1730 ; depending on FS used.
1731 ; AL will be 0 for any file-system other than FAT12/FAT16/HPFS/JFS.
1732 ; In that case no fixing of boot-drive-letters is needed.
1733 ;
1734 test al,al
1735 jz bdl_ok
1736
1737
1738 ;
1739 ; We have a partition that potentially can have incorrect values
1740 ; for the boot-drive-letter or incorrect LVM drive-letters.
1741 ;
1742 ; The boot-drive-letter can be zero as the result of copying / moving
1743 ; partitions or restoring a HPFS system from archive.
1744 ; In that case the LVM drive-letter is used if present.
1745 ;
1746 ; Incorrect LVM drive-letters are the result of the drive-letter
1747 ; reassign function when two or more eComStation installations use the
1748 ; same boot-drive-letter.
1749 ; In that case the boot-drive-letter is assigned to the
1750 ; LVM drive-letter.
1751 ;
1752 ; If both are zero there is no way to obtain the correct
1753 ; boot-drive-letter value. The user needs to examine CONFIG.SYS and
1754 ; force that letter for the partition.
1755 ;
1756
1757
1758
1759
1760
1761 ;
1762 ; Get the drive-letter for the partition from the LVM-info.
1763 ; Returns CY=1 if AL contains drive-letter, CY=0 and AL=0 if
1764 ; no letter assigned (hidden) or no LVM info found.
1765 ;
1766 mov dl,byte ptr [si+LocIPT_Drive]
1767 mov cx,[si+LocIPT_AbsoluteBegin+00h]
1768 mov bx,[si+LocIPT_AbsoluteBegin+02h]
1769 call LVM_GetDriveLetter
1770
1771
1772 ; Save for later use.
1773 mov byte ptr [LVMdl], al
1774
1775 ; See if the drive-letter feature is active.
1776 ; If active, we force the drive-letter from the user.
1777 test byte ptr [si+LocIPT_Flags], Flags_DriveLetter
1778
1779 ; Nope, it's not so we don't force the boot-drive-letter.
1780 jz PSP_NoLogicalSupport
1781
1782 ; Partition index in BX
1783 mov bl,[BootPartNo] ; EntryNumber is straight view
1784 mov bh,0
1785
1786 ; Get the user specified boot-drive-letter.
1787 ; 80h notation.
1788 mov al, bptr [DriveLetters+bx]
1789
1790 ; Safety check for zero value.
1791 test al,al
1792 jz PSP_NoValidUserDriveLetter
1793
1794 ; Convert 80h notation to ASCII.
1795 sub al,3dh ; 80h - 3dh = 43h = 'C', etc.
1796
1797 PSP_NoValidUserDriveLetter:
1798 ; Here we misuse the LVM-dl storage to store the user forced
1799 ; or zero drive-letter.
1800 mov byte ptr [LVMdl], al
1801
1802
1803 PSP_NoLogicalSupport:
1804
1805 ; A possibly valid drive-letter has been obtained from either
1806 ; LVM-info or the drive-letter feature.
1807 ; It's in [LDMdl] local storage.
1808
1809
1810
1811 ;
1812 ; Get the boot-drive-letter from the BPB of the partition.
1813 ;
1814 mov bx, [PhysDiskBpbIndex]
1815 inc bx
1816 mov al,es:[di+bx] ; 80h=C:,81h=D:, etc.
1817 ; Store it for later use
1818 mov byte ptr [BPBdl], al
1819
1820
1821 ; See if both the LVM drive-letter and the BPB drive-letter are zero.
1822 ; If so, then we have a problem.
1823 ; No valid drive-letter can be obtained and the user has to examine
1824 ; CONFIG.SYS and set that letter in the drive-letter feature
1825 ; for the partition.
1826 mov ah,al
1827 mov al, byte ptr [LVMdl]
1828 or al,ah
1829 jz no_valid_boot_drive_letter_found
1830
1831
1832 ; See if both the LVM drive-letter and the BPB drive-letter are
1833 ; the same. In that case we should have a valid situation and no
1834 ; adjustments need to be made.
1835 cmp al,ah
1836 jz PSP_valid_boot_drive
1837
1838
1839 ;
1840 ; Ok, at least one of them is valid.
1841 ;
1842
1843 ; See if the BPB boot-drive-letter is valid
1844 ; This one is supposed not to change since OS/2 cannot be booted
1845 ; from another drive then it was installed on.
1846 test ah,ah
1847 jnz BPB_boot_drive_valid
1848
1849 ; Nope it's not.
1850 ; So we use the LVM drive-letter for the BPB boot-drive-letter.
1851 ; Convert to BIOS notation ('C'+3dh=80h, 'D'->81h, etc.)
1852 ; This is where the user can fix this issue by using the
1853 ; drive-letter feature.
1854 add al,3dh
1855 mov bx,[PhysDiskBpbIndex]
1856 ; Advance to field for drive-letter in BIOS notation (OS/2)
1857 inc bx
1858 ; Fix the boot-drive-letter field in the BPB
1859 mov es:[di+bx],al
1860
1861 jmp PSP_valid_boot_drive
1862
1863 ;
1864 ; OS/2 uses this field to indicate the boot-drive-letter for the system.
1865 ; It is in BIOS notation where 80h='C', 81h='D' ... 97h='Z'.
1866 ; This is the field that get's forced to a specific value when the
1867 ; drive-letter feature of AiR-BOOT is used.
1868 ; Also, this field is the culprit of AiR-BOOT v1.07 not handling it
1869 ; correctly when the system uses HPFS and this byte is zero.
1870 ; This mostly involved booting older OS/2 versions on HPFS.
1871 ; See issues #3067 and #3119 on http://bugs.ecomstation.nl
1872 ;
1873
1874
1875 ;
1876 ; Here we enter when the LVM drive-letter is zero or not the same
1877 ; as the BPB boot-drive-letter.
1878 ; This can be the case when booting a hidden partition, LVM-dl = zero,
1879 ; or the LVM-dl was reassigned because another system with the same
1880 ; drive-letter was booted previously.
1881 ; In any case, we set the LVM drive-letter to the BPB boot-drive-letter
1882 ; so the system can be booted.
1883 ; Driveletters on other partitions have already been reassigned by the
1884 ; reassignement-procedure earlier.
1885 ;
1886 BPB_boot_drive_valid:
1887
1888
1889
1890
1891 ;
1892 ; ALWAYS SET LVM to BPB
1893 ;
1894 ;~ mov dl,byte ptr [si+LocIPT_Drive]
1895 ;~ mov cx,[si+LocIPT_AbsoluteBegin+00h]
1896 ;~ mov bx,[si+LocIPT_AbsoluteBegin+02h]
1897 ;~ mov al,[BPBdl]
1898 ;~ sub al,3dh
1899 ;~ call LVM_SetDriveLetter ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1900
1901
1902 ;
1903 ; ALWAYS SET BPB to LVM
1904 ;
1905 mov dl,byte ptr [si+LocIPT_Drive]
1906 mov cx,[si+LocIPT_AbsoluteBegin+00h]
1907 mov bx,[si+LocIPT_AbsoluteBegin+02h]
1908 call LVM_GetDriveLetter ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1909 add al,3dh
1910 mov bx,[PhysDiskBpbIndex]
1911 inc bx
1912 mov es:[di+bx],al
1913
1914
1915 update_PBR:
1916
1917
1918
1919 ;
1920 ; Here both the boot-drive-letter and the LVM drive-letter are zero.
1921 ; So the only way to determine the drive-letter is to examine CONFIG.SYS.
1922 ; Then force that drive-letter in the drive-letter feature.
1923 no_valid_boot_drive_letter_found:
1924 ; HERE SHOULD COME AN ERROR POP-UP ABOUT NO BOOT-DRIVE OR NO LVM-INFO.
1925 ; WE CONTINUE BOOTING BUT OS/2 WILL MOST PROBABLY FAIL TO BOOT.
1926
1927 ; FIXME: Issue some kind of warning
1928
1929 ;mov ah,07h
1930 ;mov si,offset CheckID_MBR
1931 ;call VideoIO_Print
1932
1933 hang:
1934 ;jmp hang
1935
1936
1937
1938
1939 PSP_valid_boot_drive:
1940
1941
1942
1943
1944 ;
1945 ; Boot DriveLetter OK.
1946 ;
1947 bdl_ok:
1948
1949
1950IFDEF AUX_DEBUG
1951 IF 0
1952 pushf
1953 pusha
1954 call AuxIO_TeletypeNL
1955 mov bx, [PhysDiskBpbIndex]
1956 inc bx
1957 mov al, [di+bx]
1958 call AuxIO_TeletypeHexByte
1959 mov bl,[BootPartNo]
1960 mov al, [DriveLetters+bx]
1961 call AuxIO_TeletypeHexByte
1962 mov al, [PartitionVolumeLetters+bx]
1963 add al, 3dh
1964 call AuxIO_TeletypeHexByte
1965 mov al, [LVMdl]
1966 add al, 3dh
1967 call AuxIO_TeletypeHexByte
1968 mov al, [si+LocIPT_SystemID]
1969 call AuxIO_TeletypeHexByte
1970 mov al,[FSType]
1971 call AuxIO_TeletypeHexByte
1972 popa
1973 popf
1974 ENDIF
1975ENDIF
1976
1977 ;
1978 ; If the partition getting booted is a JFS partition then write-back
1979 ; the modified PBR to the disk.
1980 ; Note that it's not the in-memory PBR that get's written back, but
1981 ; a copy of the original where only the phys-disk and boot-drive-letter
1982 ; are adjusted.
1983 ;
1984 pusha
1985 mov al,[FSType]
1986 cmp al,04h ; JFS
1987 je write_back_pbr
1988 cmp al,02h ; HPFS
1989 je write_back_pbr
1990
1991 jmp no_jfs_pbr
1992
1993
1994 write_back_pbr:
1995
1996 ; Save IPT pointer
1997 push si
1998
1999 ; Copy the boot-drive and boot-drive-letter fields.
2000 mov si,offset [PartitionSector]
2001 mov di,offset [PBRSector]
2002 mov al,[si+24h]
2003 mov [di+24h],al
2004 mov al,[si+25h]
2005 mov [di+25h],al
2006
2007 ; Restore IPT pointer
2008 pop si
2009
2010
2011 ; BOOKMARK: Update the CRC of the Partition Boot Record.
2012 mov bx, offset [PBRSector]
2013 call PART_UpdateBootRecordCRC
2014 call DriveIO_SaveConfiguration
2015
2016
2017 ; Setup the registers for the partition location.
2018 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
2019 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
2020 mov cx, [si+LocIPT_LocationBegin+1]
2021 mov dh, [si+LocIPT_LocationBegin+0]
2022 mov dl, [si+LocIPT_Drive]
2023
2024
2025 ; BOOKMARK: Write the adjusted HPFS/JFS PBR to disk.
2026 mov si, offset [PBRSector]
2027 call DriveIO_SaveSector
2028
2029 no_jfs_pbr:
2030 popa
2031
2032
2033
2034 ; ----------------------------------------------- LOGICAL PARTITION SUPPORT
2035
2036
2037
2038 ; AiR-BOOT now works around it by using the LVM-info (DLAT) of
2039 ; the partiton if present.
2040 ; Note however that if the drive-letter feature is active,
2041 ; this will override AB's automatic fixing.
2042 ;
2043 ; Test if the drive-letter feature is active for this partition.
2044 ; If so, then the drive that the user defined will be placed at
2045 ; byte 25h (37d) of the in-ram PartitionSector (BPB).
2046 ; (BIOS 80h notation: 80h=C, 81h=D, etc.)
2047 ; This is a remedy for when the corresponding field (25h) in the BPB on
2048 ; disk is zero.
2049 ;
2050
2051
2052
2053 ;
2054 ; Control is transferred to this point if we are booting IBM-BM.
2055 ; IBM-BM does not need the BPB fixes.
2056 ; It does require a other special stuff, which is already taken care of.
2057 ;
2058 chainload_ibm_bm:
2059
2060 ;
2061 ; Control is transferred to this point if we are booting a floppy.
2062 ; Booting from floppy skips all the harddisk related stuff.
2063 ; This is a dirty hack to fix the boot from floppy feature.
2064 ;
2065 boot_from_floppy:
2066
2067
2068
2069
2070 ;
2071 ; Here we copy the prepared boot-record to 0000:7C00h
2072 ; to give it control later on.
2073 ;
2074 push es
2075 push si
2076 mov ax, StartBaseSeg
2077 mov es, ax
2078 mov cx, 256
2079 mov si, offset PartitionSector
2080 mov di, StartBasePtr
2081 cld
2082 rep movsw
2083 pop si
2084 pop es
2085
2086 ; --------------------------------------------------- NOW START BOOT-RECORD
2087
2088
2089
2090
2091IFDEF AUX_DEBUG
2092 IF 1
2093 pushf
2094 pusha
2095 call DEBUG_Dump2
2096 ;~ call DEBUG_DumpBSSSectors
2097 call DEBUG_DumpDriveLetters
2098 call DEBUG_DumpVolumeLetters
2099 call AuxIO_TeletypeNL
2100 popa
2101 popf
2102 ENDIF
2103ENDIF
2104
2105
2106
2107;
2108; ################################## BYE BYE ##################################
2109;
2110
2111 IFNDEF AUX_DEBUG
2112 ; Skip wait-for-key
2113 jmp StartPBR
2114 ENDIF
2115
2116 ;
2117 ; Wait for keypress
2118 ;
2119 xor ax, ax
2120 int 16h
2121
2122 ; Is escape-key ?
2123 cmp al, 1bh
2124
2125 ; Nope, Go activate PBR loader
2126 jne StartPBR
2127
2128 ;push ds
2129 ;pop es
2130
2131 ; Yep, restart AiR-BOOT so simulate load DX:BX with old BIOS SS:SP
2132 jmp AirbootRestart
2133
2134 ; Yep, Reenter bootmenu
2135 ;~ jmp MBR_Main_ReEnterBootMenuPre
2136
2137
2138
2139;
2140; Transfer control to the PBR
2141;
2142StartPBR:
2143
2144 ; Debug display index
2145 ;pusha
2146 ;mov al, cs:[si+LocIPT_Drive] ; Drive Physical No
2147 ;mov ah, cs:[si+LocIPT_SystemID] ; SystemID
2148 ;call VideoIO_PrintHexWord
2149 ;xor ax, ax
2150 ;int 16h
2151 ;popa
2152
2153 ;~ jmp skip_delay
2154
2155
2156 ;
2157 ; Show dot's to indicate something is happening...
2158 ;
2159 call VideoIO_ShowWaitDots
2160
2161 ;
2162 ; Enter here to skip delay.
2163 ;
2164 skip_delay:
2165
2166
2167
2168
2169 ;
2170 ; BYE BYE (prepare some registers? look at other MBR-code)
2171 ;
2172 xor ax, ax
2173 xor bx, bx
2174 xor cx, cx
2175 mov ds, ax
2176 mov es, ax
2177 xor dh, dh
2178 mov dl, cs:[si+LocIPT_Drive] ; Drive Physical No
2179
2180
2181 ; BOOKMARK: JUMP TO PBR CODE
2182 ; ###############################
2183 ; # JUMP TO THE PBR LOADER CODE #
2184 ; ###############################
2185 db 0EAh
2186 dw StartBasePtr
2187 dw StartBaseSeg
2188
2189
2190PART_StartPartition EndP
2191
2192
2193
2194
2195
2196
2197
2198
2199;
2200; ######################################
2201; # Is this a primary partition or not #
2202; ######################################
2203;
2204; In
2205; --
2206; DL = Physical Disk
2207; BX:CX = LBA sector
2208;
2209; Out
2210; ---
2211; AX = Index in PT if found, otherwise -1
2212; CY = Set if Primary, clear if not
2213;
2214PART_IsPrimaryPartition Proc Near Uses bx cx dx si di ds es
2215
2216IFDEF AUX_DEBUG
2217 IF 0
2218 DBG_TEXT_OUT_AUX 'PART_IsPrimaryPartition:'
2219 PUSHRF
2220 ;~ call DEBUG_DumpRegisters
2221 ;~ call AuxIO_DumpParagraph
2222 ;~ call AuxIO_TeletypeNL
2223 POPRF
2224 ENDIF
2225ENDIF
2226
2227 ; Push LBA address of partition
2228 push bx
2229 push cx
2230
2231 ; Load LBA sector 0 from the disk specified in DL
2232 xor bx,bx
2233 xor ax,ax
2234 mov di,ds
2235 mov si,offset [TmpSector]
2236 call DriveIO_ReadSectorLBA
2237
2238 ; Restore partitions LBA address to DI:SI
2239 pop si
2240 pop di
2241
2242 ; Return with index -1 and CY clear if there was an
2243 ; error loading the sector.
2244 mov ax,-1
2245 cmc
2246 jnc PART_IsPrimaryPartition_exit
2247
2248 ; Compare the partition address with each entry in the P-table
2249 mov cx,4 ; Nr. of PT-entries
2250 mov dx,offset [TmpSector]
2251 add dx,01beh+08h ; Point DX to 1st partition address
2252
2253 next_pe:
2254 ; Compute pointer to PE
2255 mov bx,dx ; Point BX to 1st partition address
2256 mov ax,cx ; Get PE-index
2257 dec ax ; Index is zero based so adjust it
2258 shl ax,4 ; PE's are 16 bytes in size
2259 add bx,ax ; Make BX point to the PE
2260
2261 ; Compare LBA address
2262 push si
2263 push di
2264 xor si,[bx+00h] ; Will put 0 in SI if the same
2265 xor di,[bx+02h] ; Will put 0 in DI if the same
2266 or si,di ; Wil set ZF if both zero
2267 pop di
2268 pop si
2269 loopnz next_pe ; Try next entry if non-zero
2270
2271 ; Partition found or counter exhausted
2272 mov ax,-1
2273 clc
2274 ; Not found, so exit with NC and invalid index
2275 jnz PART_IsPrimaryPartition_exit
2276
2277 ; Partition is Primary, set CY and return index
2278 mov ax,cx
2279 stc
2280
2281 PART_IsPrimaryPartition_exit:
2282 ret
2283PART_IsPrimaryPartition Endp
2284
2285
2286
2287;
2288; #############################
2289; # Is this an HPFS partition #
2290; #############################
2291;
2292; In
2293; --
2294; SI = Pointer to IPT entry
2295;
2296; Out
2297; ---
2298; CY = Set if HPFS partition, clear if not
2299;
2300PART_IsHPFS Proc Near Uses ax
2301 mov al, [si+LocIPT_SystemID] ; Get SystemID
2302 cmp al, 07h ; Compare with AiR-BOOT ID for HPFS
2303 stc ; Assume HPFS
2304 je PART_IsHPFS_exit ; Yep
2305 clc ; Nope, clear CY
2306 PART_IsHPFS_exit:
2307 ret
2308PART_IsHPFS Endp
2309
2310
2311;
2312; ###########################
2313; # Is this a JFS partition #
2314; ###########################
2315;
2316; In
2317; --
2318; SI = Pointer to IPT entry
2319;
2320; Out
2321; ---
2322; CY = Set if JFS partition, clear if not
2323;
2324PART_IsJFS Proc Near Uses ax
2325 mov al, [si+LocIPT_SystemID] ; Get SystemID
2326 cmp al, 0fch ; Compare with AiR-BOOT ID for JFS
2327 stc ; Assume JFS
2328 je PART_IsJFS_exit ; Yep
2329 clc ; Nope, clear CY
2330 PART_IsJFS_exit:
2331 ret
2332PART_IsJFS Endp
2333
2334
2335
2336;
2337; #############################
2338; # Is this an NTFS partition #
2339; #############################
2340;
2341; In
2342; --
2343; SI = Pointer to IPT entry
2344;
2345; Out
2346; ---
2347; CY = Set if NTFS partition, clear if not
2348;
2349PART_IsNTFS Proc Near Uses ax
2350 mov al, [si+LocIPT_SystemID] ; Get SystemID
2351 cmp al, 08h ; Compare with AiR-BOOT ID for NTFS
2352 stc ; Assume NTFS
2353 je PART_IsNTFS_exit ; Yep
2354 clc ; Nope, clear CY
2355 PART_IsNTFS_exit:
2356 ret
2357PART_IsNTFS Endp
2358
2359
2360;
2361; ######################################
2362; # Is this a FAT12 or FAT16 partition #
2363; ######################################
2364;
2365; In
2366; --
2367; SI = Pointer to IPT entry
2368;
2369; Out
2370; ---
2371; CY = Set if FAT12 or FAT16 partition, clear if not
2372;
2373PART_IsFAT Proc Near Uses ax
2374 mov al, [si+LocIPT_SystemID] ; Get SystemID
2375 cmp al, 04h ; Is FAT12 ?
2376 stc
2377 je PART_IsFAT_exit ; Yep
2378 cmp al, 06h ; Is FAT16 CHS ?
2379 stc
2380 je PART_IsFAT_exit ; Yep
2381 cmp al, 0eh ; Is FAT16 LBA ?
2382 stc
2383 je PART_IsFAT_exit ; Yep
2384 clc ; Nope
2385 PART_IsFAT_exit:
2386 ret
2387PART_IsFAT Endp
2388
2389
2390;
2391; #############################
2392; # Is this a FAT32 partition #
2393; #############################
2394;
2395; In
2396; --
2397; SI = Pointer to IPT entry
2398;
2399; Out
2400; ---
2401; CY = Set if FAT32 partition, clear if not
2402;
2403PART_IsFAT32 Proc Near Uses ax
2404 mov al, [si+LocIPT_SystemID] ; Get SystemID
2405 cmp al, 0bh ; Is FAT32 CHS ?
2406 stc
2407 je PART_IsFAT32_exit ; Yep
2408 cmp al, 0ch ; Is FAT32 LBA ?
2409 stc
2410 je PART_IsFAT32_exit ; Yep
2411 clc ; Nope
2412 PART_IsFAT32_exit:
2413 ret
2414PART_IsFAT32 Endp
2415
2416
2417
2418;
2419; ##############################################################
2420; # Does this partition have the Windows BootManager installed #
2421; ##############################################################
2422;
2423; In
2424; --
2425; DL = Physical Disk
2426; BX:CX = LBA sector
2427;
2428; Out
2429; ---
2430; CY = Set if BOOTMGR found, clear if not
2431;
2432;PART_IsWinBMGR Proc Near Uses ax bx cx dx si di ds es
2433;
2434; ; Load specified LBA sector (BX:CX) from the disk in DL
2435; mov di,ds
2436; mov si,offset [TmpSector]
2437; mov ax, cx ; LBA low is now in AX
2438; call DriveIO_ReadSectorLBA
2439
2440; ; Point to location of 'BOOTMGR' signature.
2441; add si,169h
2442
2443; ; DL holds equality status
2444; xor dl,dl
2445; cld
2446
2447; ; Load letter into AL, xor with letter will result 0 if the same.
2448; ; Then or to DL.
2449; ; If at the end of the sequence DL is zero, the signature is present.
2450; lodsb
2451; xor al,'B'
2452; or dl,al
2453; lodsb
2454; xor al,'O'
2455; or dl,al
2456; lodsb
2457; xor al,'O'
2458; or dl,al
2459; lodsb
2460; xor al,'T'
2461; or dl,al
2462; lodsb
2463; xor al,'M'
2464; or dl,al
2465; lodsb
2466; xor al,'G'
2467; or dl,al
2468; lodsb
2469; xor al,'R'
2470; or dl,al
2471
2472; ; Assume not present
2473; clc
2474; jnz PART_IsWinBMGR_exit
2475
2476; ; BOOTMGR signature found
2477; stc
2478
2479; PART_IsWinBMGR_exit:
2480; ret
2481;PART_IsWinBMGR Endp
2482
2483
2484;
2485; ##########################################################
2486; # Get the offset of the phys-disk field in the PBR (BPB) #
2487; ##########################################################
2488;
2489; In
2490; --
2491; DS:SI = IPT
2492;
2493; Out
2494; ---
2495; AX = Index in PBR for phys-disk field
2496;
2497PART_GetFieldIndex Proc Near uses bx cx dx
2498 ; Check for FAT32 partition
2499 mov dl,bptr [si+LocIPT_Drive]
2500 mov cx,[si+LocIPT_AbsoluteBegin+00h]
2501 mov bx,[si+LocIPT_AbsoluteBegin+02h]
2502 call PART_IsFAT32
2503 mov ax,24h ; Offset in old-style BPB
2504 jnc PART_GetFieldIndex_exit
2505 mov ax,40h ; Offset in FAT32 BPB
2506 PART_GetFieldIndex_exit:
2507 ret
2508PART_GetFieldIndex EndP
Note: See TracBrowser for help on using the repository browser.