6 # move stack to just below the code
10 # use the code segment for data access
19 mov $_boot2_size, %eax
22 # load the second stage boot loader and jump to it
23 mov $_boot2_size, %eax
31 # set es to the start of the destination buffer to allow reading in
43 .set SECT_PER_TRACK, 18
48 # read_sectors(first, num)
53 mov ARG_SIDX(%bp), %ax
62 1: cmp ARG_NSECT(%bp), %cx
78 movw $3, VAR_ATTEMPTS(%bp)
81 # calculate the track (sidx / sectors_per_track)
84 mov $SECT_PER_TRACK, %cx
87 # save the remainder in ax
92 # cylinder (track/2) in ch [0-7] and cl[6,7]<-[8,9]
96 # sector num cl[0-5] is sidx % sectors_per_track (saved in ax)
99 # ah = 2 (read), al = 1 sectors
101 movb drive_number, %dl
105 # abort after 3 attempts
106 decw VAR_ATTEMPTS(%bp)
109 # error detected, reset controller and retry
119 # increment es:bx accordingly (advance es if bx overflows)
132 str_read_error: .asciz "Failed to read sector: "
136 mov $str_read_error, %si
159 # expects string pointer in ds:si
179 # expects number in eax
197 # print the backwards string
219 drive_number: .byte 0