]> git.saurik.com Git - apple/boot.git/blame - i386/boot0/boot0.s
boot-122.tar.gz
[apple/boot.git] / i386 / boot0 / boot0.s
CommitLineData
57c72a9a 1; Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
14c7c974
A
2;
3; @APPLE_LICENSE_HEADER_START@
4;
57c72a9a 5; Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
4f6e3300
A
6; Reserved. This file contains Original Code and/or Modifications of
7; Original Code as defined in and that are subject to the Apple Public
57c72a9a 8; Source License Version 2.0 (the "License"). You may not use this file
4f6e3300
A
9; except in compliance with the License. Please obtain a copy of the
10; License at http://www.apple.com/publicsource and read it before using
11; this file.
14c7c974
A
12;
13; The Original Code and all software distributed under the License are
4f6e3300 14; distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14c7c974
A
15; EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16; INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
4f6e3300
A
17; FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
18; License for the specific language governing rights and limitations
19; under the License.
14c7c974
A
20;
21; @APPLE_LICENSE_HEADER_END@
22;
23; Boot Loader: boot0
24;
25; A small boot sector program written in x86 assembly whose only
f083c6c3
A
26; responsibility is to locate the active partition, load the
27; partition booter into memory, and jump to the booter's entry point.
28; It leaves the boot drive in DL and a pointer to the partition entry in SI.
14c7c974 29;
f083c6c3 30; This boot loader must be placed in the Master Boot Record.
14c7c974
A
31;
32; In order to coexist with a fdisk partition table (64 bytes), and
33; leave room for a two byte signature (0xAA55) in the end, boot0 is
34; restricted to 446 bytes (512 - 64 - 2). If boot0 did not have to
75b89a82 35; live in the MBR, then we would have 510 bytes to work with.
14c7c974 36;
75b89a82 37; boot0 is always loaded by the BIOS or another booter to 0:7C00h.
14c7c974
A
38;
39; This code is written for the NASM assembler.
40; nasm boot0.s -o boot0
41
14c7c974 42
75b89a82
A
43;
44; Set to 1 to enable obscure debug messages.
45;
46DEBUG EQU 0
47
48;
f083c6c3 49; Set to 1 to support loading the partition booter (boot1) from a
75b89a82
A
50; logical partition.
51;
52EXT_PART_SUPPORT EQU 1
53
57c72a9a
A
54CHS_SUPPORT EQU 1
55
75b89a82
A
56;
57; Various constants.
58;
59kBoot0Segment EQU 0x0000
60kBoot0Stack EQU 0xFFF0 ; boot0 stack pointer
61kBoot0LoadAddr EQU 0x7C00 ; boot0 load address
62kBoot0RelocAddr EQU 0xE000 ; boot0 relocated address
63
64kMBRBuffer EQU 0x1000 ; MBR buffer address
65kExtBuffer EQU 0x1200 ; EXT boot block buffer address
14c7c974 66
75b89a82
A
67kPartTableOffset EQU 0x1be
68kMBRPartTable EQU kMBRBuffer + kPartTableOffset
69kExtPartTable EQU kExtBuffer + kPartTableOffset
14c7c974 70
75b89a82
A
71kSectorBytes EQU 512 ; sector size in bytes
72kBootSignature EQU 0xAA55 ; boot sector signature
14c7c974 73
75b89a82
A
74kPartCount EQU 4 ; number of paritions per table
75kPartTypeBoot EQU 0xab ; boot2 partition type
76kPartTypeExtDOS EQU 0x05 ; DOS extended partition type
77kPartTypeExtWin EQU 0x0f ; Windows extended partition type
78kPartTypeExtLinux EQU 0x85 ; Linux extended partition type
14c7c974 79
f083c6c3
A
80kPartActive EQU 0x80
81
75b89a82
A
82%ifdef FLOPPY
83kDriveNumber EQU 0x00
84%else
85kDriveNumber EQU 0x80
86%endif
87
14c7c974 88;
75b89a82
A
89; Format of fdisk partition entry.
90;
91; The symbol 'part_size' is automatically defined as an `EQU'
92; giving the size of the structure.
93;
94 struc part
95.bootid: resb 1 ; bootable or not
96.head: resb 1 ; starting head, sector, cylinder
97.sect: resb 1 ;
98.cyl: resb 1 ;
99.type: resb 1 ; partition type
100.endhead resb 1 ; ending head, sector, cylinder
101.endsect: resb 1 ;
102.endcyl: resb 1 ;
103.lba: resd 1 ; starting lba
104.sectors resd 1 ; size in sectors
105 endstruc
14c7c974 106
14c7c974 107;
75b89a82
A
108; Macros.
109;
110%macro DebugCharMacro 1
111 mov al, %1
112 call print_char
113%endmacro
14c7c974 114
75b89a82
A
115%if DEBUG
116%define DebugChar(x) DebugCharMacro x
117%else
118%define DebugChar(x)
119%endif
14c7c974
A
120
121;--------------------------------------------------------------------------
122; Start of text segment.
123
124 SEGMENT .text
125
75b89a82 126 ORG 0xE000 ; must match kBoot0RelocAddr
14c7c974
A
127
128;--------------------------------------------------------------------------
75b89a82 129; Boot code is loaded at 0:7C00h.
14c7c974
A
130;
131start
75b89a82
A
132 ;
133 ; Set up the stack to grow down from kBoot0Segment:kBoot0Stack.
14c7c974
A
134 ; Interrupts should be off while the stack is being manipulated.
135 ;
75b89a82
A
136 cli ; interrupts off
137 xor ax, ax ; zero ax
138 mov ss, ax ; ss <- 0
139 mov sp, kBoot0Stack ; sp <- top of stack
140 sti ; reenable interrupts
141
142 mov es, ax ; es <- 0
143 mov ds, ax ; ds <- 0
14c7c974 144
14c7c974 145 ;
75b89a82 146 ; Relocate boot0 code.
14c7c974 147 ;
75b89a82
A
148 mov si, kBoot0LoadAddr ; si <- source
149 mov di, kBoot0RelocAddr ; di <- destination
150 ;
151 cld ; auto-increment SI and/or DI registers
152 mov cx, kSectorBytes/2 ; copy 256 words
153 repnz movsw ; repeat string move (word) operation
14c7c974
A
154
155 ; Code relocated, jump to start_reloc in relocated location.
156 ;
75b89a82 157 jmp 0:start_reloc
14c7c974
A
158
159;--------------------------------------------------------------------------
160; Start execution from the relocated location.
161;
75b89a82
A
162start_reloc:
163
164 DebugChar('>')
14c7c974 165
75b89a82
A
166.loop:
167
168%if DEBUG
169 mov al, dl
170 call print_hex
171%endif
14c7c974 172
14c7c974 173 ;
75b89a82
A
174 ; Clear various flags in memory.
175 ;
176 xor eax, eax
57c72a9a
A
177 mov [first_part], eax ; clear EBIOS LBA offset
178 mov [this_part], eax
14c7c974 179
57c72a9a
A
180%if CHS_SUPPORT
181 mov [ebios_present], al ; clear EBIOS support flag
182
75b89a82
A
183 ;
184 ; Check if EBIOS is supported for this hard drive.
185 ;
186 mov ah, 0x41 ; Function 0x41
187 mov bx, 0x55AA ; check signature
75b89a82 188 int 0x13
14c7c974 189
75b89a82
A
190 ;
191 ; If successful, the return values are as follows:
192 ;
193 ; carry = 0
194 ; ah = major version of EBIOS extensions (0x21 = version 1.1)
195 ; al = altered
196 ; bx = 0xAA55
197 ; cx = support bits. bit 0 must be set for function 0x42.
198 ;
199 jc .ebios_check_done
200 cmp bx, 0xAA55 ; check BX = 0xAA55
201 jnz .ebios_check_done
202 test cl, 0x01 ; check enhanced drive read support
f083c6c3 203 setnz [ebios_present] ; EBIOS supported, set flag
75b89a82
A
204 DebugChar('E') ; EBIOS supported
205.ebios_check_done:
57c72a9a
A
206%else
207 inc al
208 mov [ebios_present], al
209%endif
75b89a82 210
f083c6c3
A
211 ;
212 ; Since this code may not always reside in the MBR, always start by
213 ; loading the MBR to kMBRBuffer.
214 ;
215 mov al, 1 ; load one sector
216 xor bx, bx
217 mov es, bx ; MBR load segment = 0
218 mov bx, kMBRBuffer ; MBR load address
219 mov si, bx ; pointer to fake partition entry
57c72a9a 220%if CHS_SUPPORT
f083c6c3
A
221 mov WORD [si], 0x0000 ; CHS DX: head = 0
222 mov WORD [si + 2], 0x0001 ; CHS CX: cylinder = 0, sector = 1
57c72a9a
A
223%endif
224 mov DWORD [si + part.lba], 0x00000000 ; LBA sector 0
f083c6c3
A
225
226 call load
227 jc .next_drive ; MBR load error
228
75b89a82
A
229 ;
230 ; Look for the booter partition in the MBR partition table,
231 ; which is at offset kMBRPartTable.
232 ;
233 mov di, kMBRPartTable ; pointer to partition table
75b89a82
A
234 call find_boot ; will not return on success
235
236.next_drive:
237 inc dl ; next drive number
238 test dl, 0x4 ; went through all 4 drives?
239 jz .loop ; not yet, loop again
240
57c72a9a 241error:
75b89a82
A
242 mov si, boot_error_str
243 call print_string
244
245hang:
57c72a9a 246 hlt
75b89a82 247 jmp SHORT hang
14c7c974
A
248
249;--------------------------------------------------------------------------
f083c6c3 250; Find the active (boot) partition and load the booter from the partition.
14c7c974
A
251;
252; Arguments:
75b89a82
A
253; DL = drive number (0x80 + unit number)
254; DI = pointer to fdisk partition table.
14c7c974 255;
75b89a82 256; Clobber list:
57c72a9a 257; EAX, BX, EBP
14c7c974 258;
75b89a82
A
259find_boot:
260 push cx ; preserve CX and SI
14c7c974
A
261 push si
262
14c7c974 263 ;
75b89a82
A
264 ; Check for boot block signature 0xAA55 following the 4 partition
265 ; entries.
14c7c974 266 ;
75b89a82 267 cmp WORD [di + part_size * kPartCount], kBootSignature
57c72a9a 268 jne NEAR .exit ; boot signature not found
14c7c974 269
75b89a82
A
270 mov si, di ; make SI a pointer to partition table
271 mov cx, kPartCount ; number of partition entries per table
14c7c974 272
75b89a82 273.loop:
14c7c974 274 ;
f083c6c3 275 ; First scan through the partition table looking for the active
75b89a82
A
276 ; partition. Postpone walking the extended partition chain for
277 ; the second pass. Do not merge the two without changing the
278 ; buffering scheme used to store extended partition tables.
279 ;
280%if DEBUG
75b89a82
A
281 mov al, [si + part.type] ; print partition type
282 call print_hex
283%endif
284
57c72a9a
A
285 cmp BYTE [si + part.type], 0
286 je .continue
f083c6c3 287 cmp BYTE [si + part.bootid], kPartActive
75b89a82 288 jne .continue
14c7c974 289
f083c6c3
A
290 DebugChar('*')
291
57c72a9a
A
292 ; fix offset for load
293 mov eax, [this_part]
294 mov [first_part], eax
295
14c7c974 296 ;
f083c6c3 297 ; Found boot partition, read boot sector to memory.
14c7c974 298 ;
f083c6c3
A
299 mov al, 1
300 mov bx, kBoot0Segment
75b89a82 301 mov es, bx
f083c6c3 302 mov bx, kBoot0LoadAddr
75b89a82 303 call load ; will not return on success
57c72a9a 304 jc error ; load error, keep looking?
14c7c974 305
f083c6c3
A
306 ;
307 ; Fix up absolute block location in partition record.
75b89a82 308 ;
f083c6c3 309 mov eax, [si + part.lba]
57c72a9a 310 add eax, [this_part]
f083c6c3 311 mov [si + part.lba], eax
57c72a9a
A
312
313 DebugChar('J')
75b89a82 314 ;
f083c6c3
A
315 ; Jump to partition booter. The drive number is already in register DL.
316 ; SI is pointing to the modified partition entry.
75b89a82 317 ;
f083c6c3 318 jmp kBoot0Segment:kBoot0LoadAddr
14c7c974 319
75b89a82
A
320.continue:
321 add si, part_size ; advance SI to next partition entry
322 loop .loop ; loop through all partition entries
14c7c974 323
75b89a82 324%if EXT_PART_SUPPORT
14c7c974 325 ;
75b89a82
A
326 ; No primary (or logical) boot partition found in the current
327 ; partition table. Restart and look for extended partitions.
14c7c974 328 ;
75b89a82
A
329 mov si, di ; make SI a pointer to partition table
330 mov cx, kPartCount ; number of partition entries per table
14c7c974 331
75b89a82 332.ext_loop:
14c7c974 333
75b89a82 334 mov al, [si + part.type] ; AL <- partition type
14c7c974 335
75b89a82
A
336 cmp al, kPartTypeExtDOS ; Extended DOS
337 je .ext_load
14c7c974 338
75b89a82
A
339 cmp al, kPartTypeExtWin ; Extended Windows(95)
340 je .ext_load
14c7c974 341
75b89a82
A
342 cmp al, kPartTypeExtLinux ; Extended Linux
343 je .ext_load
14c7c974 344
75b89a82
A
345.ext_continue:
346 ;
347 ; Advance si to the next partition entry in the extended
348 ; partition table.
349 ;
350 add si, part_size ; advance SI to next partition entry
351 loop .ext_loop ; loop through all partition entries
352 jmp .exit ; boot partition not found
14c7c974 353
75b89a82 354.ext_load:
57c72a9a
A
355 DebugChar('L')
356
357 ; Save current partition offset, since for extended
358 ; partitions we will overwrite it when loading the new
359 ; table.
360 ;
361 mov ebp, [si + part.lba]
362
75b89a82
A
363 ;
364 ; Setup the arguments for the load function call to bring the
365 ; extended partition table into memory.
366 ; Remember that SI points to the extended partition entry.
367 ;
368 mov al, 1 ; read 1 sector
369 xor bx, bx
370 mov es, bx ; es = 0
371 mov bx, kExtBuffer ; load extended boot sector
372 call load
373 jc .ext_continue ; load error
14c7c974 374
75b89a82
A
375 ;
376 ; The LBA address of all extended partitions is relative based
377 ; on the LBA address of the extended partition in the MBR, or
378 ; the extended partition at the head of the chain. Thus it is
379 ; necessary to save the LBA address of the first extended partition.
380 ;
57c72a9a
A
381
382 DebugChar('+')
383
384 add ebp, [first_part]
385 mov [this_part], ebp
386
387 mov eax,[first_part]
388 or eax, eax
75b89a82 389 jnz .ext_find_boot
57c72a9a
A
390 mov [first_part], ebp
391
392%if DEBUG
393 DebugChar('=')
394 mov eax, ebp
395 call print_hex
396%endif
75b89a82
A
397
398.ext_find_boot:
57c72a9a 399
75b89a82
A
400 ;
401 ; Call find_boot recursively to scan through the extended partition
402 ; table. Load DI with a pointer to the extended table in memory.
403 ;
75b89a82
A
404 mov di, kExtPartTable ; partition table pointer
405 call find_boot ; recursion...
14c7c974 406
75b89a82
A
407 ;
408 ; Since there is an "unwritten" rule that limits each partition table
409 ; to have 0 or 1 extended partitions, there is no point in looking for
410 ; any additional extended partition entries at this point. There is no
411 ; boot partition linked beyond the extended partition that was loaded
412 ; above.
413 ;
14c7c974 414
75b89a82 415%endif ; EXT_PART_SUPPORT
14c7c974 416
75b89a82
A
417.exit:
418 ;
419 ; Boot partition not found. Giving up.
420 ;
14c7c974
A
421 pop si
422 pop cx
423 ret
424
425;--------------------------------------------------------------------------
75b89a82 426; load - Load one or more sectors from a partition.
14c7c974
A
427;
428; Arguments:
75b89a82
A
429; AL = number of 512-byte sectors to read.
430; ES:BX = pointer to where the sectors should be stored.
431; DL = drive number (0x80 + unit number)
432; SI = pointer to the partition entry.
14c7c974
A
433;
434; Returns:
75b89a82
A
435; CF = 0 success
436; 1 error
437;
438load:
439 push cx
57c72a9a 440%if CHS_SUPPORT
f083c6c3
A
441 test BYTE [ebios_present], 1
442 jz .chs
57c72a9a 443%endif
75b89a82 444
f083c6c3
A
445.ebios:
446 mov cx, 5 ; load retry count
447.ebios_loop:
448 call read_lba ; use INT13/F42
449 jnc .exit
450 loop .ebios_loop
75b89a82 451
57c72a9a 452%if CHS_SUPPORT
f083c6c3
A
453.chs:
454 mov cx, 5 ; load retry count
455.chs_loop:
456 call read_chs ; use INT13/F2
457 jnc .exit
458 loop .chs_loop
57c72a9a 459%endif
f083c6c3
A
460
461.exit
75b89a82 462 pop cx
14c7c974
A
463 ret
464
57c72a9a 465%if CHS_SUPPORT
14c7c974 466;--------------------------------------------------------------------------
75b89a82 467; read_chs - Read sectors from a partition using CHS addressing.
14c7c974
A
468;
469; Arguments:
75b89a82
A
470; AL = number of 512-byte sectors to read.
471; ES:BX = pointer to where the sectors should be stored.
472; DL = drive number (0x80 + unit number)
473; SI = pointer to the partition entry.
14c7c974
A
474;
475; Returns:
75b89a82
A
476; CF = 0 success
477; 1 error
14c7c974 478;
75b89a82
A
479read_chs:
480 pusha ; save all registers
14c7c974 481
75b89a82
A
482 ;
483 ; Read the CHS start values from the partition entry.
484 ;
485 mov dh, [ si + part.head ] ; drive head
486 mov cx, [ si + part.sect ] ; drive sector + cylinder
14c7c974 487
75b89a82
A
488 ;
489 ; INT13 Func 2 - Read Disk Sectors
490 ;
491 ; Arguments:
492 ; AH = 2
493 ; AL = number of sectors to read
494 ; CH = lowest 8 bits of the 10-bit cylinder number
495 ; CL = bits 6 & 7: cylinder number bits 8 and 9
496 ; bits 0 - 5: starting sector number (1-63)
497 ; DH = starting head number (0 to 255)
498 ; DL = drive number (80h + drive unit)
499 ; es:bx = pointer where to place sectors read from disk
500 ;
501 ; Returns:
502 ; AH = return status (sucess is 0)
503 ; AL = burst error length if ah=0x11 (ECC corrected)
504 ; carry = 0 success
505 ; 1 error
506 ;
75b89a82
A
507 mov ah, 0x02 ; Func 2
508 int 0x13 ; INT 13
509 jnc .exit
14c7c974 510
f083c6c3 511 DebugChar('r') ; indicate INT13/F2 error
14c7c974 512
75b89a82
A
513 ;
514 ; Issue a disk reset on error.
515 ; Should this be changed to Func 0xD to skip the diskette controller
516 ; reset?
517 ;
518 xor ax, ax ; Func 0
519 int 0x13 ; INT 13
520 stc ; set carry to indicate error
14c7c974 521
75b89a82
A
522.exit:
523 popa
14c7c974 524 ret
57c72a9a 525%endif
14c7c974
A
526
527;--------------------------------------------------------------------------
75b89a82 528; read_lba - Read sectors from a partition using LBA addressing.
14c7c974
A
529;
530; Arguments:
75b89a82
A
531; AL = number of 512-byte sectors to read (valid from 1-127).
532; ES:BX = pointer to where the sectors should be stored.
533; DL = drive number (0x80 + unit number)
534; SI = pointer to the partition entry.
14c7c974 535;
75b89a82
A
536; Returns:
537; CF = 0 success
538; 1 error
14c7c974 539;
75b89a82
A
540read_lba:
541 pusha ; save all registers
542 mov bp, sp ; save current SP
14c7c974 543
14c7c974 544 ;
75b89a82
A
545 ; Create the Disk Address Packet structure for the
546 ; INT13/F42 (Extended Read Sectors) on the stack.
547 ;
14c7c974 548
75b89a82
A
549 ; push DWORD 0 ; offset 12, upper 32-bit LBA
550 push ds ; For sake of saving memory,
551 push ds ; push DS register, which is 0.
14c7c974 552
57c72a9a 553 mov ecx, [first_part] ; offset 8, lower 32-bit LBA
75b89a82
A
554 add ecx, [si + part.lba]
555 push ecx
14c7c974 556
75b89a82 557 push es ; offset 6, memory segment
14c7c974 558
75b89a82 559 push bx ; offset 4, memory offset
14c7c974 560
75b89a82
A
561 xor ah, ah ; offset 3, must be 0
562 push ax ; offset 2, number of sectors
14c7c974 563
75b89a82 564 push WORD 16 ; offset 0-1, packet size
14c7c974 565
57c72a9a
A
566 DebugChar('<')
567%if DEBUG
568 mov eax, ecx
569 call print_hex
570%endif
571
75b89a82
A
572 ;
573 ; INT13 Func 42 - Extended Read Sectors
574 ;
575 ; Arguments:
576 ; AH = 0x42
577 ; DL = drive number (80h + drive unit)
578 ; DS:SI = pointer to Disk Address Packet
579 ;
580 ; Returns:
581 ; AH = return status (sucess is 0)
582 ; carry = 0 success
583 ; 1 error
584 ;
585 ; Packet offset 2 indicates the number of sectors read
586 ; successfully.
587 ;
75b89a82
A
588 mov si, sp
589 mov ah, 0x42
590 int 0x13
591
592 jnc .exit
14c7c974 593
f083c6c3 594 DebugChar('R') ; indicate INT13/F42 error
75b89a82
A
595
596 ;
597 ; Issue a disk reset on error.
598 ; Should this be changed to Func 0xD to skip the diskette controller
599 ; reset?
14c7c974 600 ;
75b89a82
A
601 xor ax, ax ; Func 0
602 int 0x13 ; INT 13
603 stc ; set carry to indicate error
14c7c974 604
75b89a82
A
605.exit:
606 mov sp, bp ; restore SP
607 popa
14c7c974
A
608 ret
609
610;--------------------------------------------------------------------------
611; Write a string to the console.
612;
613; Arguments:
75b89a82
A
614; DS:SI pointer to a NULL terminated string.
615;
616; Clobber list:
617; AX, BX, SI
618;
619print_string
620 mov bx, 1 ; BH=0, BL=1 (blue)
621 cld ; increment SI after each lodsb call
622.loop
623 lodsb ; load a byte from DS:SI into AL
624 cmp al, 0 ; Is it a NULL?
625 je .exit ; yes, all done
626 mov ah, 0xE ; INT10 Func 0xE
627 int 0x10 ; display byte in tty mode
628 jmp short .loop
629.exit
14c7c974
A
630 ret
631
75b89a82 632
14c7c974
A
633;--------------------------------------------------------------------------
634; Write a ASCII character to the console.
635;
636; Arguments:
75b89a82 637; AL = ASCII character.
14c7c974 638;
75b89a82
A
639print_char
640 pusha
641 mov bx, 1 ; BH=0, BL=1 (blue)
642 mov ah, 0x0e ; bios INT 10, Function 0xE
643 int 0x10 ; display byte in tty mode
644 popa
645 ret
14c7c974 646
57c72a9a
A
647%if DEBUG
648
14c7c974 649;--------------------------------------------------------------------------
57c72a9a 650; Write the 4-byte value to the console in hex.
14c7c974
A
651;
652; Arguments:
57c72a9a 653; EAX = Value to be displayed in hex.
14c7c974 654;
75b89a82 655print_hex:
57c72a9a
A
656 pushad
657 mov cx, WORD 4
658 bswap eax
659.loop
14c7c974
A
660 push ax
661 ror al, 4
75b89a82 662 call print_nibble ; display upper nibble
14c7c974 663 pop ax
75b89a82 664 call print_nibble ; display lower nibble
57c72a9a
A
665 ror eax, 8
666 loop .loop
75b89a82
A
667
668 mov al, 10 ; carriage return
669 call print_char
670 mov al, 13
671 call print_char
57c72a9a 672 popad
14c7c974 673 ret
57c72a9a 674
75b89a82 675print_nibble:
14c7c974
A
676 and al, 0x0f
677 add al, '0'
678 cmp al, '9'
75b89a82 679 jna .print_ascii
14c7c974 680 add al, 'A' - '9' - 1
75b89a82
A
681.print_ascii:
682 call print_char
14c7c974
A
683 ret
684
f083c6c3
A
685getc:
686 pusha
687 mov ah, 0
688 int 0x16
689 popa
690 ret
57c72a9a 691%endif ;DEBUG
f083c6c3 692
14c7c974
A
693
694;--------------------------------------------------------------------------
695; NULL terminated strings.
696;
57c72a9a 697boot_error_str db 10, 13, 'b0 error', 0
14c7c974
A
698
699;--------------------------------------------------------------------------
700; Pad the rest of the 512 byte sized booter with zeroes. The last
701; two bytes is the mandatory boot sector signature.
702;
703; If the booter code becomes too large, then nasm will complain
704; that the 'times' argument is negative.
705
706pad_boot
75b89a82
A
707 times 446-($-$$) db 0
708
709%ifdef FLOPPY
710;--------------------------------------------------------------------------
711; Put fake partition entries for the bootable floppy image
712;
713part1bootid db 0x80 ; first partition active
714part1head db 0x00 ; head #
715part1sect db 0x02 ; sector # (low 6 bits)
716part1cyl db 0x00 ; cylinder # (+ high 2 bits of above)
717part1systid db 0xab ; Apple boot partition
718times 3 db 0x00 ; ignore head/cyl/sect #'s
719part1relsect dd 0x00000001 ; start at sector 1
720part1numsect dd 0x00000080 ; 64K for booter
721part2bootid db 0x00 ; not active
722times 3 db 0x00 ; ignore head/cyl/sect #'s
723part2systid db 0xa8 ; Apple UFS partition
724times 3 db 0x00 ; ignore head/cyl/sect #'s
725part2relsect dd 0x00000082 ; start after booter
726; part2numsect dd 0x00000abe ; 1.44MB - 65K
727part2numsect dd 0x000015fe ; 2.88MB - 65K
728%endif
14c7c974
A
729
730pad_table_and_sig
731 times 510-($-$$) db 0
75b89a82 732 dw kBootSignature
57c72a9a
A
733
734
735 ABSOLUTE 0xE400
14c7c974 736
57c72a9a
A
737;
738; In memory variables.
739;
740first_part resd 1 ; starting LBA of the intial extended partition.
741this_part resd 1 ; starting LBA of the current extended partition.
742ebios_present resb 1 ; 1 if EBIOS is supported, 0 otherwise.
743
14c7c974 744 END