|
18 | 18 | PARTTBL_OFFSET equ 0x1be |
19 | 19 | MAGIC_OFFSET equ 0x1fe |
20 | 20 | CODE_SIZE equ 440 |
| 21 | + WAIT_TICKS equ 54 ; ~3sec on 18.2 ticks per second |
21 | 22 |
|
22 | 23 | org RELOCATED_OFFSET |
23 | 24 |
|
@@ -56,22 +57,22 @@ scan_for_active_partition: |
56 | 57 | cmp di, signature ; scanned beyond end of table? |
57 | 58 | jb .l |
58 | 59 | .no_active: |
59 | | - call fatal ; does not return |
60 | | - db 'no active partition found', 0 |
| 60 | + mov si, no_active_msg |
| 61 | + jmp fatal ; does not return |
61 | 62 |
|
62 | 63 | ; We found an active partition. Load its boot sector to 0:7c00, |
63 | 64 | ; test the signature and far jump to 0:7c00 |
64 | 65 | chainload_bootsect: |
65 | 66 | push di ; save parttbl entry (restore to SI) |
66 | 67 | call read_boot_sector ; reads one sector |
67 | 68 | jnc .check_signature ; no read error occured? |
68 | | - call fatal ; does not return |
69 | | - db 'read error while reading drive', 0 |
| 69 | + mov si, read_error_msg |
| 70 | + jmp fatal ; does not return |
70 | 71 | .check_signature: |
71 | 72 | cmp word [BOOTSECT_OFFSET+MAGIC_OFFSET], 0xaa55 |
72 | 73 | je handoff_to_volume_bootrecord |
73 | | - call fatal ; does not return |
74 | | - db 'partition signature != 55AA', 0 |
| 74 | + mov si, invalid_vbr_sig_msg |
| 75 | + jmp fatal ; does not return |
75 | 76 |
|
76 | 77 | ;----------------------------------------------------------------------------- |
77 | 78 | handoff_to_volume_bootrecord: |
@@ -123,20 +124,42 @@ read_boot_sector: |
123 | 124 |
|
124 | 125 |
|
125 | 126 | ;----------------------------------------------------------------------------- |
126 | | -; Fatal error handler. Displays error message and waits forever |
127 | | -; IN: CS:IP = ASCIIZ with error message to print |
128 | | - |
129 | | -__fatal_print_char: |
| 127 | +; Fatal error handler. Displays error message, waits ~3 seconds, |
| 128 | +; issues INT18 to give BIOS a change to recover, then |
| 129 | +; waits forever in case INT18 returns |
| 130 | +; IN: DS:SI = ASCIIZ with error message to print |
| 131 | + |
| 132 | +fatal: |
| 133 | + call print ; print error message given in si |
| 134 | + mov si, try_next_dev_msg |
| 135 | + call print ; and print "try next" message |
| 136 | + xor ah, ah |
| 137 | + int 1ah ; get system time |
| 138 | + mov bx, dx ; store lower word in bx |
| 139 | + .wait_few_seconds: |
| 140 | + int 1ah |
| 141 | + sub dx, bx |
| 142 | + cmp dx, WAIT_TICKS ; wait a few seconds to ensure user sees |
| 143 | + jb .wait_few_seconds ; the message |
| 144 | + .next_boot_device: |
| 145 | + int 0x18 ; give BIOS chance to deal with boot failure |
| 146 | + .wait_forever: ; we should not land here! |
| 147 | + jmp short .wait_forever ; loop forever in case INT 18 returns |
| 148 | + |
| 149 | +print: |
| 150 | + lodsb |
| 151 | + test al, al |
| 152 | + jz .r |
130 | 153 | xor bx, bx ; video page 0 |
131 | | - mov ah, 0x0E ; else print it |
132 | | - int 0x10 ; via TTY mode |
133 | | -fatal: pop si ; this is the first character |
134 | | - lodsb ; get token |
135 | | - push si ; stack up potential return address |
136 | | - cmp al, 0 ; end of string? |
137 | | - jne __fatal_print_char ; until done |
138 | | - .wait_forever: |
139 | | - jmp short .wait_forever |
| 154 | + mov ah, 0x0E ; print it via TTY mode |
| 155 | + int 0x10 |
| 156 | + jmp print |
| 157 | + .r: ret |
| 158 | + |
| 159 | +read_error_msg: db 'Read error', 0 |
| 160 | +no_active_msg: db 'No active partition', 0 |
| 161 | +invalid_vbr_sig_msg: db 'VBR has illegal signature', 0 |
| 162 | +try_next_dev_msg: db '. Trying next boot device...', 0 |
140 | 163 |
|
141 | 164 |
|
142 | 165 | ;----------------------------------------------------------------------------- |
|
0 commit comments