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

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

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