1 ; first stage boot loader
6 extern _stage2_start_seg
10 num_read_tries equ 7b06h ; 2 bytes
11 sect_pending equ 7b08h ; 2 bytes
12 sect_per_track equ 7b0ah ; 2 bytes
13 cur_head equ 7b0ch ; 2 bytes - current head
14 start_sect equ 7b0eh ; 2 bytes - start sector in track
15 destptr equ 7b10h ; 2 bytes - destination pointer
16 num_heads equ 7b12h ; 2 bytes - number of heads
17 cur_cyl equ 7b14h ; 2 bytes - current cylinder
19 %macro floppy_motor_off 0
22 jnz %%end ; skip if high bit is set (i.e. it's not a floppy)
34 ; start of BPB at offset 3
35 db "BSPL 0.1" ; 03h: OEM ident, 8 bytes
36 dw 512 ; 0bh: bytes per sector
37 db 1 ; 0dh: sectors per cluster
38 dw 1 ; 0eh: reserved sectors (including boot record)
39 db 2 ; 10h: number of FATs
40 dw 224 ; 11h: number of dir entries
41 dw 2880 ; 13h: number of sectors in volume
42 db 0fh ; 15h: media descriptor type (f = 3.5" HD floppy)
43 dw 9 ; 16h: number of sectors per FAT
44 dw 18 ; 18h: number of sectors per track
45 dw 2 ; 1ah: number of heads
46 dd 0 ; 1ch: number of hidden sectors
47 dd 0 ; 20h: high bits of sector count
48 db 0 ; 24h: drive number
49 db 0 ; 25h: winnt flags
50 db 28h ; 26h: signature(?)
51 dd 0 ; 27h: volume serial number
52 db "80 SIX BOOT"; 2bh: volume label, 11 bytes
53 db "FAT12 " ; 36h: filesystem id, 8 bytes
66 mov [boot_driveno], dl
68 ; query sectors per track
69 mov ah, 8 ; get drive parameters call, dl already has the drive
74 mov [sect_per_track], cx
81 ; in case of failure, try 18 sectors per track, 2 heads
82 mov word [sect_per_track], 18
83 mov word [num_heads], 2
86 ; load the rest of the code high
92 mov [sect_pending], ax
93 mov ax, _stage2_start_seg
94 mov es, ax ; destination segment
96 mov word [start_sect], 1 ; start from sector 1 to skip boot sector
98 mov word [cur_head], 0
102 mov ax, [sect_pending]
103 sub ax, cx ; num_sect = pending - start_sect
104 cmp ax, [sect_per_track]
106 mov ax, [sect_per_track] ; read max sect_per_track at a time
110 push ax ; save how many sectors we're reading
142 inc cl ; sector numbers start from 1
143 mov ah, 2 ; read sectors is call 2
144 mov dl, [boot_driveno]
147 ; track read sucessfully
148 mov word [start_sect], 0 ; all subsequent tracks are whole
159 sub [sect_pending], ax
162 shl ax, cl ; convert to bytes
167 ; loaded sucessfully, load segment registers and jump
168 .done: mov ax, _stage2_start_seg
177 .fail: add sp, 2 ; clear num_sect off the stack
178 dec word [num_read_tries]
181 ; reset controller and retry
183 mov dl, [boot_driveno]
187 ; failed to load second sector
190 floppy_motor_off ; turn off floppy motor (if dl is < 80h)
191 mov ax, str_load_fail
196 ; expects string ptr in ax
210 mov cx, 4 ; 4 digits to print
211 jmp print_n_hex_digits
214 mov cx, 2 ; 2 digits to print
215 mov ah, al ; move them in place
222 mov dx, ax ; save ax, print_hex_digit destroys it
226 jnz print_n_hex_digits
232 mov al, [bx + .hexdig_tab]
239 db "0123456789abcdef"
241 str_rdtrack2 db " from ",0
242 str_rdtrack3 db "/",0
243 str_load_fail db "Failed to load 2nd stage!",0
244 str_newline db 13,10,0
246 times 510-($-$$) db 0
249 ; vi:set ts=8 sts=8 sw=8 ft=nasm: