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

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

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