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 push bx ; save dest offset
91 mov byte [read_retries], 3
93 push cx ; save linear sector number
94 ; calculate track (sidx / sectors_per_track)
97 mov cx, [sect_per_track]
105 ; cylinder (track/heads) in ch [0-7] and cl[6,7]<-[8,9]
108 mov word cx, [num_heads]
110 pop dx ; restore sidx % sectors_per_track to dx
115 ; sector num cl[0-5] is sidx % sectors_per_track + 1
120 ; ah = 2 (read), al = 1 sectors
122 mov byte dl, [DRIVENO_ADDR]
126 dec word [read_retries]
129 ; error detected, reset controller and retry
132 pop cx ; we push that at the top of the loop
167 global sect_per_track
168 sect_per_track: dw 18
180 rderr_str: db 'read error',13,10,0
181 newline_str: db 13,10,0
184 times 510-($-$$) db 0