4 .set scratchbuf, 0x7b00
9 # move stack to just below the code
13 # use the code segment for data access
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
40 .set SECT_PER_TRACK, 18
45 # read_sectors(first, num)
50 mov ARG_SIDX(%bp), %ax
59 1: cmp ARG_NSECT(%bp), %cx
66 str_rdsec_msg: .asciz "rdsec: "
67 str_cyl_msg: .asciz " C "
68 str_head_msg: .asciz " H "
69 str_sec_msg: .asciz " S "
79 movw $3, VAR_ATTEMPTS(%bp)
82 # calculate the track (sidx / sectors_per_track)
84 mov $str_rdsec_msg, %si
88 mov $SECT_PER_TRACK, %cx
91 # save the remainder in ax
96 # cylinder (track/2) in ch [0-7] and cl[6,7]<-[8,9]
100 # sector num cl[0-5] is sidx % sectors_per_track (saved in ax)
104 mov $str_cyl_msg, %si
111 mov $str_head_msg, %si
116 mov $str_sec_msg, %si
121 # ah = 2 (read), al = 1 sectors
123 movb drive_number, %dl
127 # abort after 3 attempts
128 decw VAR_ATTEMPTS(%bp)
131 # error detected, reset controller and retry
141 # DBG print first dword
142 mov $str_read_error + 4, %si
146 # increment es:bx accordingly (advance es if bx overflows)
159 str_read_error: .asciz "err read sect: "
162 mov $str_read_error, %si
168 # prints a string (ds:si) followed by a number (eax)
187 # expects string pointer in ds:si
215 # expects number in eax
222 movw $scratchbuf, %si
234 # print the backwards string
258 .set UART_DATA, 0x3f8
259 .set UART_DIVLO, 0x3f8
260 .set UART_DIVHI, 0x3f9
261 .set UART_FIFO, 0x3fa
262 .set UART_LCTL, 0x3fb
263 .set UART_MCTL, 0x3fc
264 .set UART_LSTAT, 0x3fd
265 .set DIV_9600, 115200 / 9600
268 .set FIFO_ENABLE, 0x01
269 .set FIFO_SEND_CLEAR, 0x04
270 .set FIFO_RECV_CLEAR, 0x02
274 .set LST_TREG_EMPTY, 0x20
291 # clear and enable fifo
292 mov $FIFO_ENABLE, %al
293 or $FIFO_SEND_CLEAR, %al
294 or $FIFO_RECV_CLEAR, %al
305 # expects a character in al
310 # wait until the transmit register is empty
313 and $LST_TREG_EMPTY, %al
322 # expects a string in ds:si
333 drive_number: .byte 0