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
69 str_rdsec_msg: .asciz "rdsec: "
70 str_cyl_msg: .asciz " C "
71 str_head_msg: .asciz " H "
72 str_sec_msg: .asciz " S "
82 movw $3, VAR_ATTEMPTS(%bp)
85 # calculate the track (sidx / sectors_per_track)
87 mov $str_rdsec_msg, %si
91 mov $SECT_PER_TRACK, %cx
94 # save the remainder in ax
99 # cylinder (track/2) in ch [0-7] and cl[6,7]<-[8,9]
103 # sector num cl[0-5] is sidx % sectors_per_track (saved in ax)
107 mov $str_cyl_msg, %si
114 mov $str_head_msg, %si
119 mov $str_sec_msg, %si
124 # ah = 2 (read), al = 1 sectors
126 movb drive_number, %dl
130 # abort after 3 attempts
131 decw VAR_ATTEMPTS(%bp)
134 # error detected, reset controller and retry
144 # increment es:bx accordingly (advance es if bx overflows)
157 str_read_error: .asciz "err read sector: "
160 mov $str_read_error, %si
167 # prints a string (ds:si) followed by a number (eax)
184 # expects string pointer in ds:si
212 # expects number in eax
231 # print the backwards string
255 .set UART_DATA, 0x3f8
256 .set UART_DIVLO, 0x3f8
257 .set UART_DIVHI, 0x3f9
258 .set UART_FIFO, 0x3fa
259 .set UART_LCTL, 0x3fb
260 .set UART_MCTL, 0x3fc
261 .set UART_LSTAT, 0x3fd
262 .set DIV_9600, 115200 / 9600
265 .set FIFO_ENABLE, 0x01
266 .set FIFO_SEND_CLEAR, 0x04
267 .set FIFO_RECV_CLEAR, 0x02
271 .set LST_TREG_EMPTY, 0x20
288 # clear and enable fifo
289 mov $FIFO_ENABLE, %al
290 or $FIFO_SEND_CLEAR, %al
291 or $FIFO_RECV_CLEAR, %al
302 # expects a character in al
307 # wait until the transmit register is empty
310 and $LST_TREG_EMPTY, %al
319 # expects a string in ds:si
330 drive_number: .byte 0