1 ; vi:filetype=nasm ts=8 sts=8 sw=8:
13 ; setup stack and the rest of the segment registers
22 ; dl: drive number, save it
23 mov [DRIVENO_ADDR], dl
29 ; load the second stage boot loader and jump there
30 mov bx, LOADADDR ; es:bx <- destination
33 shr cx, 9 ; cx <- binsize in sectors
34 mov [binsize_sect], cx
38 inc cx ; start from sector 1 (after boot sector)
41 ; inc dest addr by 512
44 ; offset rolled over, bump es to the next 64k
50 cmp cx, [binsize_sect]
62 mov dl, [DRIVENO_ADDR]
70 mov al, ch ; low 8 bits of max cylinder
71 mov ah, cl ; bits 6,7 high bits of max cylinder
74 inc ax ; inc to make it number of cylinders
75 mov [num_cylinders], ax
77 and cx, 3fh ; bits 0-5: sect_per_track
78 mov [sect_per_track], cx
87 ; read_sector expects a linear sector number in cx, converts it to CHS
88 ; and loads the sector at es:bx
90 mov byte [read_retries], 3
92 push cx ; save linear sector number
93 ; calculate track (sidx / sectors_per_track)
96 mov cx, [sect_per_track]
104 ; cylinder (track/heads) in ch [0-7] and cl[6,7]<-[8,9]
107 mov word cx, [num_heads]
109 pop dx ; restore sidx % sectors_per_track to dx
114 ; sector num cl[0-5] is sidx % sectors_per_track + 1
119 ; ah = 2 (read), al = 1 sectors
121 mov byte dl, [DRIVENO_ADDR]
125 dec word [read_retries]
128 ; error detected, reset controller and retry
131 pop cx ; we push that at the top of the loop
165 global sect_per_track
166 sect_per_track: dw 18
178 rderr_str: db 'read error',13,10,0
179 newline_str: db 13,10,0
182 times 510-($-$$) db 0