1 ; first stage boot loader
10 boot_driveno equ 7b00h
11 num_read_tries equ 7b06h ; 2 bytes
12 sect_pending equ 7b08h ; 2 bytes
13 sect_per_track equ 7b0ah ; 2 bytes
14 cur_head equ 7b0ch ; 2 bytes - current head
15 start_sect equ 7b0eh ; 2 bytes - start sector in track
16 destptr equ 7b10h ; 2 bytes - destination pointer
17 num_heads equ 7b12h ; 2 bytes - number of heads
18 cur_cyl equ 7b14h ; 2 bytes - current cylinder
20 %macro floppy_motor_off 0
23 jnz %%end ; skip if high bit is set (i.e. it's not a floppy)
35 ; start of BPB at offset 3
36 db "BSPL 0.1" ; 03h: OEM ident, 8 bytes
37 dw 512 ; 0bh: bytes per sector
38 db 1 ; 0dh: sectors per cluster
39 dw 1 ; 0eh: reserved sectors (including boot record)
40 db 2 ; 10h: number of FATs
41 dw 224 ; 11h: number of dir entries
42 dw 2880 ; 13h: number of sectors in volume
43 db 0fh ; 15h: media descriptor type (f = 3.5" HD floppy)
44 dw 9 ; 16h: number of sectors per FAT
45 dw 18 ; 18h: number of sectors per track
46 dw 2 ; 1ah: number of heads
47 dd 0 ; 1ch: number of hidden sectors
48 dd 0 ; 20h: high bits of sector count
49 db 0 ; 24h: drive number
50 db 0 ; 25h: winnt flags
51 db 28h ; 26h: signature(?)
52 dd 0 ; 27h: volume serial number
53 db "80 SIX BOOT"; 2bh: volume label, 11 bytes
54 db "FAT12 " ; 36h: filesystem id, 8 bytes
67 mov [boot_driveno], dl
69 ; query sectors per track
70 mov ah, 8 ; get drive parameters call, dl already has the drive
75 mov [sect_per_track], cx
82 ; in case of failure, try 18 sectors per track, 2 heads
83 mov word [sect_per_track], 18
84 mov word [num_heads], 2
87 ; load the rest of the code at 7e00h
94 mov [sect_pending], ax
100 mov es, ax ; destination segment 7e0h to allow loading up to 64k
101 mov word [destptr], 0
102 mov word [start_sect], 1 ; start from sector 1 to skip boot sector
103 mov word [cur_cyl], 0
104 mov word [cur_head], 0
108 mov ax, [sect_pending]
109 sub ax, cx ; num_sect = pending - start_sect
110 cmp ax, [sect_per_track]
112 mov ax, [sect_per_track] ; read max sect_per_track at a time
116 push ax ; save how many sectors we're reading
148 inc cl ; sector numbers start from 1
149 mov ah, 2 ; read sectors is call 2
150 mov dl, [boot_driveno]
153 ; track read sucessfully
154 mov word [start_sect], 0 ; all subsequent tracks are whole
165 sub [sect_pending], ax
168 shl ax, cl ; convert to bytes
173 ; loaded sucessfully, reset es back to 0 and jump
178 .fail: add sp, 2 ; clear num_sect off the stack
179 dec word [num_read_tries]
182 ; reset controller and retry
184 mov dl, [boot_driveno]
188 ; failed to load second sector
191 floppy_motor_off ; turn off floppy motor (if dl is < 80h)
192 mov ax, str_load_fail
197 ; expects string ptr in ax
211 mov cx, 4 ; 4 digits to print
212 jmp print_n_hex_digits
215 mov cx, 2 ; 2 digits to print
216 mov ah, al ; move them in place
223 mov dx, ax ; save ax, print_hex_digit destroys it
227 jnz print_n_hex_digits
233 mov al, [bx + .hexdig_tab]
240 db "0123456789abcdef"
242 str_rdtrack2 db " from ",0
243 str_rdtrack3 db "/",0
244 str_load_fail db "Failed to load 2nd stage!",0
245 str_newline db 13,10,0
247 times 510-($-$$) db 0
250 ; vi:set ts=8 sts=8 sw=8 ft=nasm: