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

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

Updated debugging state [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.8 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
971 ;
972 ; Local Storage for this much too large function.
973 ;
974 local BootPartNo:byte
975 local PhysDiskBpbIndex:word ; Index into BPB to field of phys-disk
976 local FSType:byte ; The FS used on the loaded BPB
977 ; Only used for FAT/HPFS/JFS
978 local LVMdl:byte ; LVM drive-letter
979 local BPBdl:byte ; BPB boot-drive-letter. (at 25h)
980
981IFDEF AUX_DEBUG
982 IF 0
983 DBG_TEXT_OUT_AUX 'PART_StartPartition:'
984 PUSHRF
985 call DEBUG_DumpRegisters
986 ;~ call AuxIO_DumpParagraph
987 ;~ call AuxIO_TeletypeNL
988 POPRF
989 ENDIF
990ENDIF
991
992 ; Get Partition-Pointer (SI) to Partition-To-Boot (DL).
993 ; DL is filtered partition number and thus uses the PPT.
994 ; Returned is the address of the IPT entry of the partition to boot.
995 call PART_GetPartitionPointer
996
997
998 ;
999 ; SI now points to the IPT entry for the partition to be booted.
1000 ;
1001
1002
1003 ; This converts DL filered view to straight view, aka index into the IPT.
1004 ; Needed for later.
1005 ; Destroys AX,BX
1006 call PART_ConvertToStraight
1007
1008 ; Save for later use.
1009 mov [BootPartNo], dl
1010 ; Straight - FFh -> Floppy boot
1011 ; FEh -> BIOS continue (CD-ROM, ZIP, etc.)
1012
1013 ; This converts the PPT to have pointers to all the IPT entries.
1014 ; We need straight pointers from now on, so calculate the table...
1015 ; Destroys AX,BX,CX
1016 call PART_CalculateStraightPartPointers
1017
1018
1019
1020 ; SI contains the pointer to the IPT to what partition to boot
1021 ; in this whole routine...it may never get messed up.
1022
1023 ; ------------------------------------------------- PRINT NAME BEING BOOTED
1024
1025 push si
1026 mov dl, [si+LocIPT_Drive] ; Disk where partition resides
1027 mov dh, [si+LocIPT_SystemID] ; AB FileSystem ID (08=NTFS, FC=JFS)
1028 ; Copy Partition-Name to BootingNow area for display purposes
1029 add si, LocIPT_Name ; Advance to AB partition-name
1030 mov cx, 11 ; Max. length of AB name/label
1031 call GetLenOfName ; Returns CX with length of label
1032 mov di, offset TXT_BootingNowPartName
1033 jz PSP_NoName ; Don't copy if zero length label
1034 rep movsb ; Copy label-name to boot
1035 PSP_NoName:
1036 xor al, al ; Null-terminate label-string
1037 stosb ; Ending Zero
1038
1039 ;
1040 ; Display "Booting the system using "
1041 ;
1042 mov si, offset TXT_BootingNow1
1043 call MBR_Teletype
1044
1045 ;~ pusha
1046 ;~ call MBR_Teletype
1047 ;~ mov si,offset TXT_BootingNowPartName
1048 ;~ call MBR_Teletype
1049 ;~ popa
1050
1051
1052 ;
1053 ; DL will be zero for floppy-disk or 80h+ for harddisk.
1054 ; Note thus that DL contains the BIOS disk numer and not the AB value
1055 ; for floppy or cdrom.
1056 ;
1057 or dl, dl
1058 jnz PSP_IsHarddisc
1059
1060 ; When booting floppy/CD-ROM/etc., we got other text to be displayed...
1061 mov si, offset TXT_BootingNowPartName
1062 call MBR_TeletypeVolName
1063 jmp PSP_IsFloppyCDROMetc ; JUMPS BUITEN SI POP !!! AANPASSEN
1064
1065
1066 PSP_IsHarddisc:
1067
1068
1069 ;
1070 ; Save configuration on HDD boots (save CFG_PartLast)
1071 ;
1072 call DriveIO_SaveConfiguration
1073
1074
1075 ;
1076 ; Prints out BootingNow2 including PartitionName
1077 ;
1078 mov si, offset TXT_BootingNowPartName
1079 call MBR_TeletypeVolName
1080 mov si, offset TXT_BootingNowPartition
1081 call MBR_Teletype
1082
1083 ; restores SI (IPT-pointer)
1084 pop si
1085
1086
1087
1088 ;
1089 ; Get the CHS and LBA location of sector containing
1090 ; the partition-table for the partition.
1091 ;
1092 mov ax, wptr [si+LocIPT_AbsolutePartTable+0]
1093 mov bx, wptr [si+LocIPT_AbsolutePartTable+2]
1094 mov cx, wptr [si+LocIPT_LocationPartTable+1]
1095 mov dh, bptr [si+LocIPT_LocationPartTable+0]
1096 mov dl, [si+LocIPT_Drive]
1097
1098IFDEF AUX_DEBUG
1099 IF 0
1100 pushf
1101 pusha
1102 mov si,offset [ptetb]
1103 call AuxIO_Print
1104 call DEBUG_DumpRegisters
1105 call AuxIO_TeletypeNL
1106 mov ax, word ptr [FreeDriveletterMap+00h]
1107 mov dx, word ptr [FreeDriveletterMap+02h]
1108 call AuxIO_TeletypeBinDWord
1109 popa
1110 popf
1111 ENDIF
1112ENDIF
1113
1114
1115 ;
1116 ; This loads the MBR in case of PRI or the EBR in case of LOG partitions.
1117 ;
1118 ; BOOKMARK: PBR/EBR loading
1119 call DriveIO_LoadPartition ; Load Table... [LOAD]
1120
1121
1122 ; -------------------------------------------------- MODIFY PARTITION TABLE
1123
1124 ; Make sure ES is correctly setup.
1125 push cs
1126 pop es
1127
1128 ; ES:DI - First Partitionentry
1129 mov di, offset PartitionSector+446
1130
1131 ; Remove all active-flags for safety reasons, primary partition table will
1132 ; have one partition set active by ScanPartition-routine.
1133 push di
1134 mov cl, 4
1135 PSP_RemoveActiveFlagLoop:
1136 and bptr es:[di+LocBRPT_Flags], 7Fh
1137 add di, LocBRPT_LenOfEntry
1138 dec cl
1139 jnz PSP_RemoveActiveFlagLoop
1140 pop di
1141
1142
1143 ;
1144 ; Put the partition-to-be-booted location into registers...
1145 ;
1146 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
1147 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
1148 sub ax, wptr [si+LocIPT_AbsolutePartTable+0]
1149 sbb bx, wptr [si+LocIPT_AbsolutePartTable+2]
1150
1151
1152 ; BX:AX - absolute position of partition relative to partition table
1153 ; ...and search for it...
1154 PSP_SearchLoop:
1155 cmp ax, wptr es:[di+LocBRPT_RelativeBegin]
1156 jne PSP_SearchMismatch
1157 cmp bx, wptr es:[di+LocBRPT_RelativeBegin+2]
1158 jne PSP_SearchMismatch
1159 jmp PSP_SearchMatch
1160 PSP_SearchMismatch:
1161 add di, LocBRPT_LenOfEntry ; 16 Bytes per Partition-Entry
1162 cmp di, 500+offset PartitionSector
1163 jb PSP_SearchLoop
1164
1165 ;
1166 ; Entry not found, Halt System.
1167 ;
1168 jmp MBR_HaltSystem
1169
1170 ; ------------------------------------------------------------- ENTRY FOUND
1171 PSP_SearchMatch:
1172 or byte ptr es:[di+LocBRPT_Flags], 80h ; set ACTIVE partition
1173
1174
1175
1176 ;
1177 ; Save the Partition Table.
1178 ;
1179 call DriveIO_SavePartition ; Saves the Partition-Table [SAVE]
1180
1181
1182
1183 ; --------------------------------------------------------------- OS/2 I13X
1184 ; Now check if the partition to get booted is above 8 GB.
1185 ; If yes, set magic bytes 'I13X' at 3000:0 for boot-loader to recognize.
1186 ; This method is (c) by IBM <g>
1187 ; Rousseau: Booting IBM-BM also requires the LBA address of the IBM-BM
1188 ; partitionafter the 'I13X' signature.
1189 ; Also, FS needs to be set to 3000H.
1190 ; This info was obtained by examining the LVM 2,x MBR-code.
1191 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
1192 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
1193 add ax, wptr es:[di+LocBRPT_AbsoluteLength+0] ; Add length to absolute
1194 adc bx, wptr es:[di+LocBRPT_AbsoluteLength+2] ; begin location
1195 ; BX:AX -> Absolute End-Position of Partition
1196
1197
1198 ;
1199 ; Always use INT13X v1.0.8+.
1200 ;
1201 ;~ test byte ptr [CFG_ForceLBAUsage], 1
1202 ;~ jnz PSP_ForceI13X
1203 jmp PSP_ForceI13X
1204
1205 ; LBA-boundary at 16450560 (FB0400h) (16320x16x63)
1206 cmp bx, 00FBh
1207 jb PSP_NoI13X
1208
1209 ;
1210 ; BOOKMARK: Setup 'I13X' signature.
1211 ;
1212 PSP_ForceI13X:
1213 push es
1214 push di
1215 push si
1216
1217 ; Setup ES and FS.
1218 ; FS needs to keep this address.
1219 mov ax, 3000h
1220 mov es, ax
1221 ; mov fs,ax
1222 db 08eh
1223 db 0e0h
1224
1225 ; Insert signature
1226 xor di, di
1227 mov word ptr es:[di+00], '1I'
1228 mov word ptr es:[di+02], 'X3'
1229
1230 ;mov wptr es:[di], 0
1231 ;mov wptr es:[di+2], 0
1232
1233 ; Insert LBA address.
1234 mov ax, [si+LocIPT_AbsoluteBegin+0]
1235 mov es:[di+04], ax
1236 mov ax, [si+LocIPT_AbsoluteBegin+2]
1237 mov es:[di+06], ax
1238
1239 pop si
1240 pop di
1241 pop es
1242
1243
1244
1245 PSP_NoI13X:
1246
1247 ; now check, if we need to hide any partition
1248 test byte ptr [si+LocIPT_Flags], Flags_HideFeature
1249 jz PSP_NoHideFeature
1250
1251 ; ---------------------------------------------------- PARTITION HIDING
1252
1253 ; display "hide active"
1254 push si
1255 mov si, offset TXT_BootingHide
1256 call MBR_Teletype
1257 pop si
1258
1259
1260 ; First, find Hide-Config
1261 mov dl, [BootPartNo] ; EntryNumber is straight view
1262 ;~ mov ax, LocIPT_MaxPartitions
1263 mov ax, LocHPT_LenOfHPT
1264 mul dl
1265 mov di, offset HidePartitionTable
1266 add di, ax ; We got the pointer
1267
1268
1269 ; So process Hide-Config. Read out Bitfield-Entries,
1270 ; each points to a partition.
1271 ; 3Fh is end-marker / maximum entries = CFG_Partitions
1272 mov cl, [CFG_Partitions]
1273 mov ch,0 ; Index in bitfield array.
1274 mov dh,6 ; Bitfield width.
1275 mov bx,di ; Pointer to entry.
1276
1277 PSP_PartitionsHideLoop:
1278 mov dl,ch
1279 call CONV_GetBitfieldValue
1280 mov dl,al
1281
1282 ;~ mov dl, es:[di]
1283 ;~ inc di
1284 ;~ cmp dl, 0FFh
1285 cmp dl,3fh ; Max value for 6-bits field.
1286 je PSP_EndOfHideProcess ; -> End of Hiding
1287 call PART_HidePartition ; Now hide that partition
1288 inc ch ; Next bitfield.
1289 dec cl
1290 jnz PSP_PartitionsHideLoop
1291
1292
1293 PSP_EndOfHideProcess:
1294
1295 ; --- HIDE COMPLETED ---
1296 ; So something got hidden and we have to remark a primary partition,
1297 ; if we are booting something non-primary from the boot-disk.
1298 mov al, [BIOS_BootDisk]
1299 cmp bptr [si+LocIPT_Drive], al
1300 jne PSP_HideAdjustPrimaryMark ; When booting any hdd, but boot-disk
1301 mov ax, wptr [si+LocIPT_AbsolutePartTable]
1302 mov bx, wptr [si+LocIPT_AbsolutePartTable+2]
1303 or ax, ax
1304 jnz PSP_HideAdjustPrimaryMark ; or booting non-primary partition
1305 or bx, bx ; on boot-disk.
1306 jz PSP_NoHideAdjustPrimaryMark
1307
1308 PSP_HideAdjustPrimaryMark:
1309 ; Load Primary Partition Table...
1310 xor ax, ax
1311 xor bx, bx
1312 mov cx, 0001h ; Cylinder 0, Sector 1
1313 xor dh, dh ; Head 0
1314 mov dl, [BIOS_BootDisk] ; Boot Disk
1315
1316 ; This uses the boot-disk and alters 'CurPartition_Location'.
1317 ; CHECKME: How does 81h being the boot-disk influences this ?
1318 call DriveIO_LoadPartition ; Load Primary Partition Table
1319
1320 ; This would only be needed for very old BIOSses
1321 call PART_MarkFirstGoodPrimary
1322
1323 ; CHECKME: Disabled writing back MBR with modified boot flags
1324 ; This is a safety measure now that booting AirBoot from other disks
1325 ; than 80h can occur.
1326 ;~ call DriveIO_SavePartition ; Saves the Partition-Table
1327
1328
1329 PSP_NoHideAdjustPrimaryMark:
1330
1331
1332 PSP_NoHideFeature:
1333 ; Check, if we are supposed to ignore LVM altogether...
1334 test byte ptr [CFG_IgnoreLVM], 1
1335 jnz PSP_NoLVMReassignment
1336
1337 ; ---------------------------------------------------- LVM REASSIGNMENT
1338
1339 ; Driveletter must be set for this partition
1340 test byte ptr [si+LocIPT_Flags], Flags_DriveLetter
1341 jz PSP_NoLVMReassignment
1342 ;movzx bx, BootPartNo ; EntryNumber is straight view
1343 mov bl,[BootPartNo] ; EntryNumber is straight view
1344 mov bh,0
1345
1346 mov al, bptr [DriveLetters+bx]
1347 sub al, 3Dh ; Convert e.g. 80h -> 'C'
1348 cmp al, bptr [PartitionVolumeLetters+bx]
1349
1350
1351 ;~ je PSP_NoLVMReassignment ; If driveletters match -> no change
1352 ; Rousseau:
1353 ; But there can still be other partitions with the same drive-letter.
1354 ; For instance if the user did an advanced installation with multiple
1355 ; eComStation systems using the same boot-drive-letter.
1356 ; So, even if the drive-letter forced is the same as the
1357 ; partition-volume-letter, other partitions still need to be checked
1358 ; and possibly hidden. So we always do the drive-letter reassignment,
1359 ; which is enhanced to keep data-partitions (those -not- in the Menu)
1360 ; visible. So the 'je' instruction above is commented-out.
1361
1362
1363 ;
1364 ; Give partition SI letter AL
1365 ;
1366 call LVM_DoLetterReassignment
1367
1368
1369
1370
1371 PSP_NoLVMReassignment:
1372 push si
1373 ; -------------------------------------------------- -"PLEASE WAIT..."-
1374 PSP_IsFloppyCDROMetc:
1375 mov si, offset TXT_BootingWait
1376 call MBR_Teletype ; display "please wait" ; SI staat nog op stack; aanpassen !!!!
1377 pop si
1378
1379 ; Process Partition Tables, if M$-Hack required (changes Ext Part Type)
1380 call MSHACK_ProcessPartTables
1381
1382 test byte ptr [CFG_BootMenuActive], 0FFh
1383 jz PSP_NoMenuNoSound
1384
1385 ; ---------------------------------------------------------- BOOT-SOUND
1386 call SOUND_ExecuteBoot
1387
1388 PSP_NoMenuNoSound:
1389
1390 ; --------------------------------------------- SPECIAL BOOT PROCESSING
1391 ; Check here, if the Boot shall be done via resume to BIOS...
1392 mov al, byte ptr [si+LocIPT_SystemID]
1393 cmp al, 0FEh ; Via BIOS ? (aka resume BIOS boot sequence)
1394 je PSP_ResumeBIOSbootSeq
1395
1396 jmp PSP_StartNormal
1397
1398 PSP_ResumeBIOSbootSeq:
1399 int 18h ; Give control back to BIOS
1400 db 0EAh ; if return to here -> Reboot
1401 dw 0FFF0h
1402 dw 0F000h
1403
1404
1405 ; =======================================================================
1406 ; FROM THIS POINT ON, ONLY DS and SI REGISTER IS NEEDED TO BE PRESERVED
1407 ; =======================================================================
1408
1409 PSP_StartNormal:
1410 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
1411 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
1412 mov cx, [si+LocIPT_LocationBegin+1]
1413 mov dh, [si+LocIPT_LocationBegin+0]
1414 mov dl, [si+LocIPT_Drive]
1415
1416 ; This loads the PBR of the partition.
1417 call DriveIO_LoadPartition ; Loads boot-sector... [PARTBOOTSEC]
1418
1419 ;
1420 ; The JFS PBR-code does not use the passed BPB in memory but uses the BPB
1421 ; on disk. This breaks the drive-letter feature on JFS.
1422 ; So we make a copy of the PBR in memory, and if the partition is JFS
1423 ; we later adjust the physical-disk and boot-drive-letter in this
1424 ; copy and write it back to disk.
1425 ; Then the JFS PBR-code will see the correct boot-drive-letter.
1426 ;
1427 pusha
1428 mov si,offset [PartitionSector]
1429 mov di,offset [PBRSector]
1430 mov cx,100h
1431 cld
1432 rep movsw
1433 popa
1434
1435
1436
1437 ; Check if the disk is a harddisk or a floppy.
1438 mov dl,[si+LocIPT_Drive]
1439 cmp dl, 80h
1440 jae is_harddisk
1441
1442 ;
1443 ; This is a dirty hack to fix booting from a floppy.
1444 ; With all the modifications made since v1.06 this feature was broken
1445 ; because Int13X is used implicitly now, and that does not work
1446 ; for diskette access.
1447 ; This jumps to the code that loads and starts the pbr-code.
1448 ; Note that it also skips virus checking !
1449 ; This will be fixed at a later date.
1450 jmp boot_from_floppy
1451
1452 ;
1453 ; The disk is a harddisk so we need to do various checks and fixes.
1454 ;
1455 is_harddisk:
1456
1457 test byte ptr [CFG_DetectVIBR], 1
1458 jz PSP_NoVIBR
1459 test byte ptr [si+LocIPT_Flags], Flags_VIBR_Detection
1460 jz PSP_NoVIBR
1461
1462
1463 ; ----------------------------------------------------- CHECKS FOR VIBR
1464 ; BOOKMARK: Check for virus in PBR
1465 push si
1466 mov si, offset PartitionSector
1467 mov bx, 4B4Dh ; Magic: 'MK'
1468 call MBR_GetCheckOfSector
1469 pop si
1470
1471 cmp [si+LocIPT_BootRecordCRC], bx
1472 je PSP_NoVIBR
1473 mov bx, [si+LocIPT_BootRecordCRC]
1474 or bx, bx
1475 jz PSP_NoVIBR
1476 ; Oh Oh, got a virus :(
1477 mov si, offset TXT_VirusFoundMain
1478 call MBR_Teletype
1479 mov si, offset TXT_VirusFound2 ; VIBR-Virus
1480 call MBR_Teletype
1481 mov si, offset TXT_VirusFoundEnd
1482 call MBR_Teletype
1483 jmp MBR_HaltSystem
1484
1485 PSP_NoVIBR:
1486 test byte ptr [CFG_ProtectMBR], 1
1487 jz PSP_NoMBRprotect
1488 ; --------------------------------------------- INSTALLS MBR-PROTECTION
1489 ; We need DS:SI later...
1490 push ds
1491 push si
1492
1493 ; First subtract 1024 bytes from Base-Memory...
1494 push ds
1495 mov ax, 40h
1496 mov ds, ax
1497 mov dx, word ptr ds:[13h]
1498 dec dx ; 1 == 1kbyte
1499 mov word ptr ds:[13h], dx
1500 pop ds
1501 shl dx, 6 ; trick, now DX is a segment
1502
1503 ; Now copy in our code (to DX:0)...
1504
1505 mov si, offset MBR_Protection ; DS:SI - Source Image
1506 mov es, dx
1507 xor di, di ; ES:DI - Destination
1508 ;~ mov cx, 512
1509 mov cx, 384
1510 rep movsw ; Move 768 bytes...
1511
1512 ; Now fill in variables...
1513
1514 xor ax, ax
1515 mov ds, ax
1516 mov si, 10h*4
1517 xor di, di ; INT 10h Vector to MBR Protection
1518 ;movsd
1519 movsw
1520 movsw
1521
1522 mov si, 13h*4 ; INT 13h Vector to MBR Protection
1523 ;movsd
1524 movsw
1525 movsw
1526
1527 mov al, CFG_IgnoreWriteToMBR ; Option to MBR Protection
1528 stosb
1529
1530 ; Now switch INT 13h vector to MBR Protection
1531
1532 sub si, 4
1533 mov ax, 9
1534 mov ds:[si], ax
1535 mov ds:[si+2], dx ; Vector hardcoded at DS:0009
1536 ; MBR-Protection now active :)
1537
1538 ; Restore DS:SI
1539 pop si
1540 pop ds
1541
1542
1543
1544 PSP_NoMBRprotect:
1545
1546 ; Display volume-name in bold
1547 ; Just before booting the selected partition
1548 ;pushf
1549 ;pusha
1550 ;push si
1551 ;add si, LocIPT_Name
1552 ;call MBR_TeletypeVolName
1553 ;xor si,si
1554 ;call MBR_TeletypeNL
1555 ;pop si
1556 ;popa
1557 ;popf
1558
1559
1560
1561
1562
1563 ; ------------------------------------------------ SPECIAL PARTITION SUPPORT
1564 ; needed by OS/2 Warp / eComStation
1565
1566
1567 ;cmp byte ptr [si+LocIPT_SystemID],08 ; I hate Microsuck NTFS check
1568 mov di, offset PartitionSector ; ES:DI - Actual Boot-Record
1569
1570 ; Special Support Detection
1571 ;mov ax, word ptr es:[di+18h]
1572 ;cmp ax, 003Fh ; Physical Layout-Sectors... Safety check
1573
1574
1575
1576 ;
1577 ; At this point, SI points to IPT and DI points to the PBR from disk.
1578 ; Depending on the type of BPB used, the physical disk field is at
1579 ; different locations: 24h for old-style (OS/2) BPB's and 40h for
1580 ; FAT32 BPB's.
1581 ; The OS/2 boot-drive-letter is located at 25h in an old-style BPB,
1582 ; while the corresponding field in a FAT32 BPB is located at 41h but
1583 ; used for different purposes.
1584 ; In case of HPFS, using old-style BPB's, the boot-drive-letter needs
1585 ; to be adjusted if it is zero.
1586 ; In that case we trace the LVM-info for that partition and use the
1587 ; drive-letter defined there.
1588 ; This fixes issues #3067 and #3119.
1589 ; Adjusting the physical disk is always done but at different locations
1590 ; depending on the BPB used.
1591 ; Also, the "hidden sectors" field is adjusted to contain the absolute
1592 ; offset from the start of the disk instead of the relative offset to
1593 ; the start of the partition.
1594 ; http://homepage.ntlworld.com./jonathan.deboynepollard/FGA/bios-parameter-block.html
1595 ;
1596
1597
1598 ; Get index of phys-disk field in BX
1599 call PART_GetFieldIndex
1600 mov [PhysDiskBpbIndex],ax
1601 mov bx,ax
1602
1603 ; Locate cursor for output of debug-info
1604 ;~ pusha
1605 ;~ mov ch,7
1606 ;~ mov cl,0
1607 ;~ call VideoIO_Color
1608 ;~ mov ch,6
1609 ;~ mov cl,1
1610 ;~ call VideoIO_Locate
1611 ;~ popa
1612
1613
1614 ; Debug display physdisk, ptype and physdisk offset in BPB
1615 ;~ pusha
1616 ;~ mov ah,[si+LocIPT_Drive]
1617 ;~ mov al,[si+LocIPT_SystemID]
1618 ;~ call VideoIO_PrintHexWord
1619 ;~ mov ax,bx
1620 ;~ call VideoIO_PrintHexWord
1621 ;~ mov ax,[si+LocIPT_AbsolutePartTable+02]
1622 ;~ call VideoIO_PrintHexWord
1623 ;~ mov ax,[si+LocIPT_AbsolutePartTable+00]
1624 ;~ call VideoIO_PrintHexWord
1625 ;~ mov al,[ExtendedAbsPosSet]
1626 ;~ call VideoIO_PrintHexByte
1627 ;~ mov al,'-'
1628 ;~ call VideoIO_PrintSingleChar
1629 ;~ mov al,byte ptr [Menu_EntrySelected]
1630 ;~ call VideoIO_PrintHexByte
1631 ;~ mov al,byte ptr [CFG_PartAutomatic]
1632 ;~ call VideoIO_PrintHexByte
1633 ;~ mov al,byte ptr [Phase1Active]
1634 ;~ call VideoIO_PrintHexByte
1635 ;~ mov al,byte ptr [NewPartitions]
1636 ;~ call VideoIO_PrintHexByte
1637 ;~ mov al, byte ptr [OldPartitionCount]
1638 ;~ call VideoIO_PrintHexByte
1639 ;~ popa
1640
1641
1642 ;
1643 ; If the partition is IBM-BM we skip all the BPB adjustments.
1644 ; IBM-BM does no need them.
1645 ;
1646 cmp byte ptr [si+LocIPT_SystemID], 0ah
1647 jnz no_os2_bm
1648 jmp chainload_ibm_bm
1649
1650
1651 no_os2_bm:
1652
1653 ;
1654 ; Update the phys-disk field
1655 ; DI points to PartitionSector
1656 ; BX holds index to phys-disk field
1657 ;
1658 mov al,byte ptr [si+LocIPT_Drive] ; Moet dit niet later gebeuren ??? (NT/WIN LDR hangs)
1659 mov es:[di+bx],al
1660
1661
1662 ;
1663 ; Legacy systems do not put the correct values in the "hidden sectors"
1664 ; field. Also, this field will be incorrect if a partition is moved on
1665 ; disk by a disktool not accounting for this field.
1666 ; Linux does not have a BPB at all, and does not use this field.
1667 ; So we set the correct value here obtained by the partition scanner.
1668 ; This fixing is done by OS/2 BM as well, according to Martin.
1669 ;
1670
1671 ; BOOKMARK: Fix hidden sectors field
1672 mov ax,[si+LocIPT_AbsoluteBegin]
1673 mov es:[di+1ch], ax ; Low word of 32-bits "hidden sectors"
1674
1675 mov ax,[si+LocIPT_AbsoluteBegin+2]
1676 mov es:[di+1eh], ax ; High word of 32-bits "hidden sectors"
1677
1678 ;
1679 ; Check partitions to see if boot-drive-letter fixing is needed.
1680 ; FAT12/FAT16/HPFS/JFS will have the value at 25h fixed
1681 ; to the LVM-info drive-letter. (+3dh to convert to BIOS notation)
1682 ;
1683
1684
1685 ; Setup partition disk and LBA address
1686 mov dl,byte ptr [si+LocIPT_Drive]
1687 mov cx,[si+LocIPT_AbsoluteBegin+00h]
1688 mov bx,[si+LocIPT_AbsoluteBegin+02h]
1689
1690 ; AL is gonna be used to shift-in CY status.
1691 ; If the type of file-system is one of FAT12/FAT16/HPFS/JFS then
1692 ; AL will be <> 0 and the boot-drive-letter can be tested / fixed.
1693 mov al,0
1694
1695
1696 ;
1697 ; The PBR is already loaded, no need to load it again in the
1698 ; calls below.
1699 ;
1700 ; Better use the already done discovery to determine the system.
1701 ;
1702 ; FIXME: PBR Already loaded
1703
1704 ; When FAT12/FAT16/HPFS/JFS then boot-drive-letter can be tested
1705 ; or adjusted.
1706 call PART_IsJFS
1707 rcl al,1
1708 call PART_IsHPFS
1709 rcl al,1
1710 call PART_IsFAT
1711 rcl al,1
1712 mov ah,al
1713
1714 ; Store for later reference.
1715 mov [FSType],al
1716
1717
1718 ;
1719 ; When the phys-disk byte (80h) is put in this BPB in RAM,
1720 ; Windows will not find it's loader if Windows itself
1721 ; is installed in a logical partition but the loader is on FAT
1722 ; in a primary.
1723 ; This goes for all NT-based versions ?
1724 ;
1725
1726
1727 ;
1728 ; See if phys-disk / boot-drive-letter fix is needed
1729 ; depending on FS used.
1730 ; AL will be 0 for any file-system other than FAT12/FAT16/HPFS/JFS.
1731 ; In that case no fixing of boot-drive-letters is needed.
1732 ;
1733 test al,al
1734 jz bdl_ok
1735
1736
1737 ;
1738 ; We have a partition that potentially can have incorrect values
1739 ; for the boot-drive-letter or incorrect LVM drive-letters.
1740 ;
1741 ; The boot-drive-letter can be zero as the result of copying / moving
1742 ; partitions or restoring a HPFS system from archive.
1743 ; In that case the LVM drive-letter is used if present.
1744 ;
1745 ; Incorrect LVM drive-letters are the result of the drive-letter
1746 ; reassign function when two or more eComStation installations use the
1747 ; same boot-drive-letter.
1748 ; In that case the boot-drive-letter is assigned to the
1749 ; LVM drive-letter.
1750 ;
1751 ; If both are zero there is no way to obtain the correct
1752 ; boot-drive-letter value. The user needs to examine CONFIG.SYS and
1753 ; force that letter for the partition.
1754 ;
1755
1756
1757
1758
1759
1760 ;
1761 ; Get the drive-letter for the partition from the LVM-info.
1762 ; Returns CY=0 if AL contains drive-letter, '*' or 0.
1763 ; Returns CY=1 and AL=0 if no LVM info found.
1764 ; The new 'LVM_GetDriveLetter' directly uses SI, so the loading of
1765 ; DL, CX and BX is not needed. We'll leave it here for now.
1766 ;
1767 mov dl,byte ptr [si+LocIPT_Drive]
1768 mov cx,[si+LocIPT_AbsoluteBegin+00h]
1769 mov bx,[si+LocIPT_AbsoluteBegin+02h]
1770
1771 ; Now uses SI, not DL,CX,BX
1772 call LVM_GetDriveLetter
1773 ;//! CHECKME: No test on LVM info found
1774
1775 ; Save for later use.
1776 mov byte ptr [LVMdl], al
1777
1778 ; See if the drive-letter feature is active.
1779 ; If active, we force the drive-letter from the user.
1780 test byte ptr [si+LocIPT_Flags], Flags_DriveLetter
1781
1782 ; Nope, it's not so we don't force the boot-drive-letter.
1783 jz PSP_NoLogicalSupport
1784
1785 ; Partition index in BX
1786 mov bl,[BootPartNo] ; EntryNumber is straight view
1787 mov bh,0
1788
1789 ; Get the user specified boot-drive-letter.
1790 ; 80h notation.
1791 mov al, bptr [DriveLetters+bx]
1792
1793 ; Safety check for zero value.
1794 test al,al
1795 jz PSP_NoValidUserDriveLetter
1796
1797 ; Convert 80h notation to ASCII.
1798 sub al,3dh ; 80h - 3dh = 43h = 'C', etc.
1799
1800 PSP_NoValidUserDriveLetter:
1801 ; Here we misuse the LVM-dl storage to store the user forced
1802 ; or zero drive-letter.
1803 mov byte ptr [LVMdl], al
1804
1805
1806 PSP_NoLogicalSupport:
1807
1808 ; A possibly valid drive-letter has been obtained from either
1809 ; LVM-info or the drive-letter feature.
1810 ; It's in [LDMdl] local storage.
1811
1812
1813
1814 ;
1815 ; Get the boot-drive-letter from the BPB of the partition.
1816 ;
1817 mov bx, [PhysDiskBpbIndex]
1818 inc bx
1819 mov al,es:[di+bx] ; 80h=C:,81h=D:, etc.
1820 ; Store it for later use
1821 mov byte ptr [BPBdl], al
1822
1823
1824 ; See if both the LVM drive-letter and the BPB drive-letter are zero.
1825 ; If so, then we have a problem.
1826 ; No valid drive-letter can be obtained and the user has to examine
1827 ; CONFIG.SYS and set that letter in the drive-letter feature
1828 ; for the partition.
1829 mov ah,al
1830 mov al, byte ptr [LVMdl]
1831 or al,ah
1832 jz no_valid_boot_drive_letter_found
1833
1834
1835 ; See if both the LVM drive-letter and the BPB drive-letter are
1836 ; the same. In that case we should have a valid situation and no
1837 ; adjustments need to be made.
1838 cmp al,ah
1839 jz PSP_valid_boot_drive
1840
1841
1842 ;
1843 ; Ok, at least one of them is valid.
1844 ;
1845
1846 ; See if the BPB boot-drive-letter is valid
1847 ; This one is supposed not to change since OS/2 cannot be booted
1848 ; from another drive then it was installed on.
1849 test ah,ah
1850 jnz BPB_boot_drive_valid
1851
1852 ; Nope it's not.
1853 ; So we use the LVM drive-letter for the BPB boot-drive-letter.
1854 ; Convert to BIOS notation ('C'+3dh=80h, 'D'->81h, etc.)
1855 ; This is where the user can fix this issue by using the
1856 ; drive-letter feature.
1857 add al,3dh
1858 mov bx,[PhysDiskBpbIndex]
1859 ; Advance to field for drive-letter in BIOS notation (OS/2)
1860 inc bx
1861 ; Fix the boot-drive-letter field in the BPB
1862 mov es:[di+bx],al
1863
1864 jmp PSP_valid_boot_drive
1865
1866 ;
1867 ; OS/2 uses this field to indicate the boot-drive-letter for the system.
1868 ; It is in BIOS notation where 80h='C', 81h='D' ... 97h='Z'.
1869 ; This is the field that get's forced to a specific value when the
1870 ; drive-letter feature of AiR-BOOT is used.
1871 ; Also, this field is the culprit of AiR-BOOT v1.07 not handling it
1872 ; correctly when the system uses HPFS and this byte is zero.
1873 ; This mostly involved booting older OS/2 versions on HPFS.
1874 ; See issues #3067 and #3119 on http://bugs.ecomstation.nl
1875 ;
1876
1877
1878 ;
1879 ; Here we enter when the LVM drive-letter is zero or not the same
1880 ; as the BPB boot-drive-letter.
1881 ; This can be the case when booting a hidden partition, LVM-dl = zero,
1882 ; or the LVM-dl was reassigned because another system with the same
1883 ; drive-letter was booted previously.
1884 ; In any case, we set the LVM drive-letter to the BPB boot-drive-letter
1885 ; so the system can be booted.
1886 ; Driveletters on other partitions have already been reassigned by the
1887 ; reassignement-procedure earlier.
1888 ;
1889 BPB_boot_drive_valid:
1890
1891
1892
1893
1894 ;
1895 ; ALWAYS SET LVM to BPB
1896 ;
1897 ;~ mov dl,byte ptr [si+LocIPT_Drive]
1898 ;~ mov cx,[si+LocIPT_AbsoluteBegin+00h]
1899 ;~ mov bx,[si+LocIPT_AbsoluteBegin+02h]
1900 ;~ mov al,[BPBdl]
1901 ;~ sub al,3dh
1902 ;~ call LVM_SetDriveLetter ; !! NOT IMPLEMENTED !!
1903
1904
1905;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1906 ;
1907 ; ALWAYS SET BPB to LVM
1908 ;
1909 mov dl, byte ptr [si+LocIPT_Drive]
1910 mov cx, [si+LocIPT_AbsoluteBegin+00h]
1911 mov bx, [si+LocIPT_AbsoluteBegin+02h]
1912
1913 ; Now uses SI, not DL,CX,BX
1914 call LVM_GetDriveLetter
1915 ;//! CHECKME: No test on LVM info found
1916
1917 add al, 3dh
1918 mov bx, [PhysDiskBpbIndex]
1919 inc bx
1920 mov es:[di+bx], al
1921
1922
1923 update_PBR:
1924
1925
1926
1927 ;
1928 ; Here both the boot-drive-letter and the LVM drive-letter are zero.
1929 ; So the only way to determine the drive-letter is to examine CONFIG.SYS.
1930 ; Then force that drive-letter in the drive-letter feature.
1931 no_valid_boot_drive_letter_found:
1932 ; HERE SHOULD COME AN ERROR POP-UP ABOUT NO BOOT-DRIVE OR NO LVM-INFO.
1933 ; WE CONTINUE BOOTING BUT OS/2 WILL MOST PROBABLY FAIL TO BOOT.
1934
1935 ; FIXME: Issue some kind of warning
1936
1937 ;mov ah,07h
1938 ;mov si,offset CheckID_MBR
1939 ;call VideoIO_Print
1940
1941 hang:
1942 ;jmp hang
1943
1944
1945
1946
1947 PSP_valid_boot_drive:
1948
1949
1950
1951
1952 ;
1953 ; Boot DriveLetter OK.
1954 ;
1955 bdl_ok:
1956
1957
1958IFDEF AUX_DEBUG
1959 IF 0
1960 pushf
1961 pusha
1962 call AuxIO_TeletypeNL
1963 mov bx, [PhysDiskBpbIndex]
1964 inc bx
1965 mov al, [di+bx]
1966 call AuxIO_TeletypeHexByte
1967 mov bl,[BootPartNo]
1968 mov al, [DriveLetters+bx]
1969 call AuxIO_TeletypeHexByte
1970 mov al, [PartitionVolumeLetters+bx]
1971 add al, 3dh
1972 call AuxIO_TeletypeHexByte
1973 mov al, [LVMdl]
1974 add al, 3dh
1975 call AuxIO_TeletypeHexByte
1976 mov al, [si+LocIPT_SystemID]
1977 call AuxIO_TeletypeHexByte
1978 mov al,[FSType]
1979 call AuxIO_TeletypeHexByte
1980 popa
1981 popf
1982 ENDIF
1983ENDIF
1984
1985 ;
1986 ; If the partition getting booted is a JFS partition then write-back
1987 ; the modified PBR to the disk.
1988 ; Note that it's not the in-memory PBR that get's written back, but
1989 ; a copy of the original where only the phys-disk and boot-drive-letter
1990 ; are adjusted.
1991 ;
1992 pusha
1993 mov al,[FSType]
1994 cmp al,04h ; JFS
1995 je write_back_pbr
1996 cmp al,02h ; HPFS
1997 je write_back_pbr
1998
1999 jmp no_jfs_pbr
2000
2001
2002 write_back_pbr:
2003
2004 ; Save IPT pointer
2005 push si
2006
2007 ; Copy the boot-drive and boot-drive-letter fields.
2008 mov si,offset [PartitionSector]
2009 mov di,offset [PBRSector]
2010 mov al,[si+24h]
2011 mov [di+24h],al
2012 mov al,[si+25h]
2013 mov [di+25h],al
2014
2015 ; Restore IPT pointer
2016 pop si
2017
2018
2019 ; BOOKMARK: Update the CRC of the Partition Boot Record.
2020 mov bx, offset [PBRSector]
2021 call PART_UpdateBootRecordCRC
2022 call DriveIO_SaveConfiguration
2023
2024
2025 ; Setup the registers for the partition location.
2026 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
2027 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
2028 mov cx, [si+LocIPT_LocationBegin+1]
2029 mov dh, [si+LocIPT_LocationBegin+0]
2030 mov dl, [si+LocIPT_Drive]
2031
2032
2033 ; BOOKMARK: Write the adjusted HPFS/JFS PBR to disk.
2034 mov si, offset [PBRSector]
2035 call DriveIO_SaveSector
2036
2037 no_jfs_pbr:
2038 popa
2039
2040
2041
2042 ; ----------------------------------------------- LOGICAL PARTITION SUPPORT
2043
2044
2045
2046 ; AiR-BOOT now works around it by using the LVM-info (DLAT) of
2047 ; the partiton if present.
2048 ; Note however that if the drive-letter feature is active,
2049 ; this will override AB's automatic fixing.
2050 ;
2051 ; Test if the drive-letter feature is active for this partition.
2052 ; If so, then the drive that the user defined will be placed at
2053 ; byte 25h (37d) of the in-ram PartitionSector (BPB).
2054 ; (BIOS 80h notation: 80h=C, 81h=D, etc.)
2055 ; This is a remedy for when the corresponding field (25h) in the BPB on
2056 ; disk is zero.
2057 ;
2058
2059
2060
2061 ;
2062 ; Control is transferred to this point if we are booting IBM-BM.
2063 ; IBM-BM does not need the BPB fixes.
2064 ; It does require a other special stuff, which is already taken care of.
2065 ;
2066 chainload_ibm_bm:
2067
2068 ;
2069 ; Control is transferred to this point if we are booting a floppy.
2070 ; Booting from floppy skips all the harddisk related stuff.
2071 ; This is a dirty hack to fix the boot from floppy feature.
2072 ;
2073 boot_from_floppy:
2074
2075
2076
2077
2078 ;
2079 ; Here we copy the prepared boot-record to 0000:7C00h
2080 ; to give it control later on.
2081 ;
2082 push es
2083 push si
2084 mov ax, StartBaseSeg
2085 mov es, ax
2086 mov cx, 256
2087 mov si, offset PartitionSector
2088 mov di, StartBasePtr
2089 cld
2090 rep movsw
2091 pop si
2092 pop es
2093
2094 ; --------------------------------------------------- NOW START BOOT-RECORD
2095
2096
2097
2098
2099IFDEF AUX_DEBUG
2100 IF 1
2101 pushf
2102 pusha
2103 call DEBUG_Dump2
2104 ;~ call DEBUG_DumpBSSSectors
2105 call DEBUG_DumpDriveLetters
2106 call DEBUG_DumpVolumeLetters
2107 call AuxIO_TeletypeNL
2108 popa
2109 popf
2110 ENDIF
2111ENDIF
2112
2113
2114
2115;
2116; ################################## BYE BYE ##################################
2117;
2118
2119 IFNDEF AUX_DEBUG
2120 ; Skip wait-for-key
2121 jmp StartPBR
2122 ENDIF
2123
2124 ;
2125 ; Wait for keypress
2126 ;
2127 xor ax, ax
2128 int 16h
2129
2130 ; Is escape-key ?
2131 cmp al, 1bh
2132
2133 ; Nope, Go activate PBR loader
2134 jne StartPBR
2135
2136 ;push ds
2137 ;pop es
2138
2139 ; Yep, restart AiR-BOOT so simulate load DX:BX with old BIOS SS:SP
2140 jmp AirbootRestart
2141
2142 ; Yep, Reenter bootmenu
2143 ;~ jmp MBR_Main_ReEnterBootMenuPre
2144
2145
2146
2147;
2148; Transfer control to the PBR
2149;
2150StartPBR:
2151
2152 ; Debug display index
2153 ;pusha
2154 ;mov al, cs:[si+LocIPT_Drive] ; Drive Physical No
2155 ;mov ah, cs:[si+LocIPT_SystemID] ; SystemID
2156 ;call VideoIO_PrintHexWord
2157 ;xor ax, ax
2158 ;int 16h
2159 ;popa
2160
2161 ;~ jmp skip_delay
2162
2163
2164 ;
2165 ; Show dot's to indicate something is happening...
2166 ;
2167 call VideoIO_ShowWaitDots
2168
2169 ;
2170 ; Enter here to skip delay.
2171 ;
2172 skip_delay:
2173
2174
2175
2176
2177 ;
2178 ; BYE BYE (prepare some registers? look at other MBR-code)
2179 ;
2180 xor ax, ax
2181 xor bx, bx
2182 xor cx, cx
2183 mov ds, ax
2184 mov es, ax
2185 xor dh, dh
2186 mov dl, cs:[si+LocIPT_Drive] ; Drive Physical No
2187
2188
2189 ; BOOKMARK: JUMP TO PBR CODE
2190 ; ###############################
2191 ; # JUMP TO THE PBR LOADER CODE #
2192 ; ###############################
2193 db 0EAh
2194 dw StartBasePtr
2195 dw StartBaseSeg
2196
2197
2198PART_StartPartition EndP
2199
2200
2201
2202
2203
2204
2205
2206
2207;
2208; ######################################
2209; # Is this a primary partition or not #
2210; ######################################
2211;
2212; In
2213; --
2214; DL = Physical Disk
2215; BX:CX = LBA sector
2216;
2217; Out
2218; ---
2219; AX = Index in PT if found, otherwise -1
2220; CY = Set if Primary, clear if not
2221;
2222PART_IsPrimaryPartition Proc Near Uses bx cx dx si di ds es
2223
2224IFDEF AUX_DEBUG
2225 IF 0
2226 DBG_TEXT_OUT_AUX 'PART_IsPrimaryPartition:'
2227 PUSHRF
2228 ;~ call DEBUG_DumpRegisters
2229 ;~ call AuxIO_DumpParagraph
2230 ;~ call AuxIO_TeletypeNL
2231 POPRF
2232 ENDIF
2233ENDIF
2234
2235 ; Push LBA address of partition
2236 push bx
2237 push cx
2238
2239 ; Load LBA sector 0 from the disk specified in DL
2240 xor bx,bx
2241 xor ax,ax
2242 mov di,ds
2243 mov si,offset [TmpSector]
2244 call DriveIO_ReadSectorLBA
2245
2246 ; Restore partitions LBA address to DI:SI
2247 pop si
2248 pop di
2249
2250 ; Return with index -1 and CY clear if there was an
2251 ; error loading the sector.
2252 mov ax,-1
2253 cmc
2254 jnc PART_IsPrimaryPartition_exit
2255
2256 ; Compare the partition address with each entry in the P-table
2257 mov cx,4 ; Nr. of PT-entries
2258 mov dx,offset [TmpSector]
2259 add dx,01beh+08h ; Point DX to 1st partition address
2260
2261 next_pe:
2262 ; Compute pointer to PE
2263 mov bx,dx ; Point BX to 1st partition address
2264 mov ax,cx ; Get PE-index
2265 dec ax ; Index is zero based so adjust it
2266 shl ax,4 ; PE's are 16 bytes in size
2267 add bx,ax ; Make BX point to the PE
2268
2269 ; Compare LBA address
2270 push si
2271 push di
2272 xor si,[bx+00h] ; Will put 0 in SI if the same
2273 xor di,[bx+02h] ; Will put 0 in DI if the same
2274 or si,di ; Wil set ZF if both zero
2275 pop di
2276 pop si
2277 loopnz next_pe ; Try next entry if non-zero
2278
2279 ; Partition found or counter exhausted
2280 mov ax,-1
2281 clc
2282 ; Not found, so exit with NC and invalid index
2283 jnz PART_IsPrimaryPartition_exit
2284
2285 ; Partition is Primary, set CY and return index
2286 mov ax,cx
2287 stc
2288
2289 PART_IsPrimaryPartition_exit:
2290 ret
2291PART_IsPrimaryPartition Endp
2292
2293
2294
2295;
2296; #############################
2297; # Is this an HPFS partition #
2298; #############################
2299;
2300; In
2301; --
2302; SI = Pointer to IPT entry
2303;
2304; Out
2305; ---
2306; CY = Set if HPFS partition, clear if not
2307;
2308PART_IsHPFS Proc Near Uses ax
2309 mov al, [si+LocIPT_SystemID] ; Get SystemID
2310 cmp al, 07h ; Compare with AiR-BOOT ID for HPFS
2311 stc ; Assume HPFS
2312 je PART_IsHPFS_exit ; Yep
2313 clc ; Nope, clear CY
2314 PART_IsHPFS_exit:
2315 ret
2316PART_IsHPFS Endp
2317
2318
2319;
2320; ###########################
2321; # Is this a JFS partition #
2322; ###########################
2323;
2324; In
2325; --
2326; SI = Pointer to IPT entry
2327;
2328; Out
2329; ---
2330; CY = Set if JFS partition, clear if not
2331;
2332PART_IsJFS Proc Near Uses ax
2333 mov al, [si+LocIPT_SystemID] ; Get SystemID
2334 cmp al, 0fch ; Compare with AiR-BOOT ID for JFS
2335 stc ; Assume JFS
2336 je PART_IsJFS_exit ; Yep
2337 clc ; Nope, clear CY
2338 PART_IsJFS_exit:
2339 ret
2340PART_IsJFS Endp
2341
2342
2343
2344;
2345; #############################
2346; # Is this an NTFS partition #
2347; #############################
2348;
2349; In
2350; --
2351; SI = Pointer to IPT entry
2352;
2353; Out
2354; ---
2355; CY = Set if NTFS partition, clear if not
2356;
2357PART_IsNTFS Proc Near Uses ax
2358 mov al, [si+LocIPT_SystemID] ; Get SystemID
2359 cmp al, 08h ; Compare with AiR-BOOT ID for NTFS
2360 stc ; Assume NTFS
2361 je PART_IsNTFS_exit ; Yep
2362 clc ; Nope, clear CY
2363 PART_IsNTFS_exit:
2364 ret
2365PART_IsNTFS Endp
2366
2367
2368;
2369; ######################################
2370; # Is this a FAT12 or FAT16 partition #
2371; ######################################
2372;
2373; In
2374; --
2375; SI = Pointer to IPT entry
2376;
2377; Out
2378; ---
2379; CY = Set if FAT12 or FAT16 partition, clear if not
2380;
2381PART_IsFAT Proc Near Uses ax
2382 mov al, [si+LocIPT_SystemID] ; Get SystemID
2383 cmp al, 04h ; Is FAT12 ?
2384 stc
2385 je PART_IsFAT_exit ; Yep
2386 cmp al, 06h ; Is FAT16 CHS ?
2387 stc
2388 je PART_IsFAT_exit ; Yep
2389 cmp al, 0eh ; Is FAT16 LBA ?
2390 stc
2391 je PART_IsFAT_exit ; Yep
2392 clc ; Nope
2393 PART_IsFAT_exit:
2394 ret
2395PART_IsFAT Endp
2396
2397
2398;
2399; #############################
2400; # Is this a FAT32 partition #
2401; #############################
2402;
2403; In
2404; --
2405; SI = Pointer to IPT entry
2406;
2407; Out
2408; ---
2409; CY = Set if FAT32 partition, clear if not
2410;
2411PART_IsFAT32 Proc Near Uses ax
2412 mov al, [si+LocIPT_SystemID] ; Get SystemID
2413 cmp al, 0bh ; Is FAT32 CHS ?
2414 stc
2415 je PART_IsFAT32_exit ; Yep
2416 cmp al, 0ch ; Is FAT32 LBA ?
2417 stc
2418 je PART_IsFAT32_exit ; Yep
2419 clc ; Nope
2420 PART_IsFAT32_exit:
2421 ret
2422PART_IsFAT32 Endp
2423
2424
2425
2426;
2427; ##############################################################
2428; # Does this partition have the Windows BootManager installed #
2429; ##############################################################
2430;
2431; In
2432; --
2433; DL = Physical Disk
2434; BX:CX = LBA sector
2435;
2436; Out
2437; ---
2438; CY = Set if BOOTMGR found, clear if not
2439;
2440;PART_IsWinBMGR Proc Near Uses ax bx cx dx si di ds es
2441;
2442; ; Load specified LBA sector (BX:CX) from the disk in DL
2443; mov di,ds
2444; mov si,offset [TmpSector]
2445; mov ax, cx ; LBA low is now in AX
2446; call DriveIO_ReadSectorLBA
2447
2448; ; Point to location of 'BOOTMGR' signature.
2449; add si,169h
2450
2451; ; DL holds equality status
2452; xor dl,dl
2453; cld
2454
2455; ; Load letter into AL, xor with letter will result 0 if the same.
2456; ; Then or to DL.
2457; ; If at the end of the sequence DL is zero, the signature is present.
2458; lodsb
2459; xor al,'B'
2460; or dl,al
2461; lodsb
2462; xor al,'O'
2463; or dl,al
2464; lodsb
2465; xor al,'O'
2466; or dl,al
2467; lodsb
2468; xor al,'T'
2469; or dl,al
2470; lodsb
2471; xor al,'M'
2472; or dl,al
2473; lodsb
2474; xor al,'G'
2475; or dl,al
2476; lodsb
2477; xor al,'R'
2478; or dl,al
2479
2480; ; Assume not present
2481; clc
2482; jnz PART_IsWinBMGR_exit
2483
2484; ; BOOTMGR signature found
2485; stc
2486
2487; PART_IsWinBMGR_exit:
2488; ret
2489;PART_IsWinBMGR Endp
2490
2491
2492;
2493; ##########################################################
2494; # Get the offset of the phys-disk field in the PBR (BPB) #
2495; ##########################################################
2496;
2497; In
2498; --
2499; DS:SI = IPT
2500;
2501; Out
2502; ---
2503; AX = Index in PBR for phys-disk field
2504;
2505PART_GetFieldIndex Proc Near uses bx cx dx
2506 ; Check for FAT32 partition
2507 mov dl,bptr [si+LocIPT_Drive]
2508 mov cx,[si+LocIPT_AbsoluteBegin+00h]
2509 mov bx,[si+LocIPT_AbsoluteBegin+02h]
2510 call PART_IsFAT32
2511 mov ax,24h ; Offset in old-style BPB
2512 jnc PART_GetFieldIndex_exit
2513 mov ax,40h ; Offset in FAT32 BPB
2514 PART_GetFieldIndex_exit:
2515 ret
2516PART_GetFieldIndex EndP
Note: See TracBrowser for help on using the repository browser.