4 .set scratchbuf, 0x7bf0
5 .set scratchbuf_size, 16
10 # move stack to just below the code
14 # use the code segment for data access
26 # load the second stage boot loader and jump to it
27 mov $_boot2_size, %eax
29 mov $loading_msg2, %si
39 # set es to the start of the destination buffer to allow reading in
48 .set SECT_PER_TRACK, 18
53 loading_msg: .asciz "Loading "
54 loading_msg2: .asciz " bytes\n"
56 sect_per_track: .short 18
57 num_cylinders: .short 80
62 movb drive_number, %dl
72 mov %ax, num_cylinders
74 mov %cx, sect_per_track
75 andw $0x3f, sect_per_track
84 # read_sectors(first, num)
89 mov ARG_SIDX(%bp), %ax
98 1: cmp ARG_NSECT(%bp), %cx
104 .set VAR_ATTEMPTS, -2
114 movw $3, VAR_ATTEMPTS(%bp)
117 # calculate the track (sidx / sectors_per_track)
121 mov sect_per_track, %cx
129 # cylinder (track/heads) in ch [0-7] and cl[6,7]<-[8,9]
139 # sector num cl[0-5] is sidx % sectors_per_track + 1
144 # ah = 2 (read), al = 1 sectors
146 movb drive_number, %dl
150 # abort after 3 attempts
151 decw VAR_ATTEMPTS(%bp)
154 # error detected, reset controller and retry
167 # increment es:bx accordingly (advance es if bx overflows)
180 str_read_error: .asciz "read error, sector: "
183 mov $str_read_error, %si
187 # prints a string (ds:si) followed by a number (eax)
204 # expects string pointer in ds:si
218 # expects character in al
236 # expects number in eax
242 movw $scratchbuf + scratchbuf_size, %si
260 .set UART_DATA, 0x3f8
261 .set UART_DIVLO, 0x3f8
262 .set UART_DIVHI, 0x3f9
263 .set UART_FIFO, 0x3fa
264 .set UART_LCTL, 0x3fb
265 .set UART_MCTL, 0x3fc
266 .set UART_LSTAT, 0x3fd
267 .set DIV_9600, 115200 / 9600
270 .set FIFO_ENABLE, 0x01
271 .set FIFO_SEND_CLEAR, 0x04
272 .set FIFO_RECV_CLEAR, 0x02
276 .set LST_TREG_EMPTY, 0x20
293 # clear and enable fifo
294 mov $FIFO_ENABLE, %al
295 or $FIFO_SEND_CLEAR, %al
296 or $FIFO_RECV_CLEAR, %al
307 # expects a character in al
320 # wait until the transmit register is empty
323 and $LST_TREG_EMPTY, %al
333 drive_number: .byte 0