# Second stage of the boot loader .code16 # Assemble for 16-bit mode .globl start start: jmp real_start # Write to the console using BIOS. # # Input: SI contains the address of the null-terminated string to be displayed cons_write: movb $0x0e, %ah # 0x0e is the INT 10h BIOS call to output the value contained in AL to screen cons_write_rpt: movb (%si), %al # Load the byte at the location contained in the SI register into AL inc %si # Add 1 to the value in SI cmp $0, %al # Compare the value in AL with 0 jz cons_write_done # If it is zero, then we are done int $0x10 # Output the character in AL to the screen jmp cons_write_rpt # and continue cons_write_done: # Something that is called will never return ret # until a 'ret' instruction is encountered. Labels do # not give a program any structure. They just give a # memory location a name that we can use in our code. cons_write_crlf: movb $0x0e, %ah # Output CR movb $0x0d, %al int $0x10 movb $0x0a, %al # Output LF int $0x10 ret cons_writeline: call cons_write call cons_write_crlf ret HexChars: .ascii "0123456789ABCDEF" cons_write_hex: movw $4, %cx movb $0x0E, %ah hexloop: rol $4, %bx movw %bx, %si and $0x000F, %si movb HexChars(%si), %al int $0x10 loop hexloop ret cons_write_int: movw $IntBuffer + 4, %si movw %bx, %ax cmpw $0, %ax jge getdigit xor %ax, %ax movb $0x0E, %ah movb $0x2D, %al int $0x10 movw %bx, %ax negw %ax getdigit: xor %dx, %dx movw $10, %cx idiv %cx addb $48, %dl movb %dl, (%si) dec %si cmp $0, %ax jne getdigit inc %si call cons_write ret IntBuffer: .string " " cons_draw_line: movw $0, err movw x1, %cx movw y1, %dx sub x0, %cx sub y0, %dx movw %cx, (deltax) movw %dx, (deltay) cons_line_check_x: movw x0, %cx movw $1, (sx) cmp x1, %cx jl cons_line_check_y negw sx negw deltax cons_line_check_y: movw y0, %dx movw $1, (sy) cmpw y1, %dx jl cons_line_prep_loop negw sy negw deltay cons_line_prep_loop: movw deltax, %ax sub deltay, %ax movw %ax, (err) cons_line_loop_start: xor %ax, %ax xor %bx, %bx movb $0x0c, %ah movb $0, %bh movb (color), %al int $0x10 cmpw x1, %cx jne cons_line_loop_next_point cmpw y1, %dx jne cons_line_loop_next_point jmp cons_line_loop_end cons_line_loop_next_point: movw err, %ax add %ax, %ax cons_line_loop_move_y_point: movw deltay, %bx negw %bx cmpw %bx, %ax jle cons_line_loop_move_x_point negw %bx subw %bx, err addw sx, %cx cons_line_loop_move_x_point: movw deltax, %bx cmpw %bx, %ax jge cons_line_loop_start addw %bx, err addw sy, %dx jmp cons_line_loop_start cons_line_loop_end: ret real_start: movw $boot_message, %si # Display our boot message call cons_writeline draw_start: # Set the Video mode to VGA 320 x 200 x 8 movb $0, %ah movb $0x13, %al int $0x10 xor %ax, %ax movw $50, x0 movw $50, y0 movw $160, x1 movw $55, y1 movb $12, color call cons_draw_line movw $150, x0 movw $150, y0 movw $50, x1 movw $50, y1 movb $10, color call cons_draw_line movw $150, x0 movw $150, y0 movw $160, x1 movw $55, y1 movb $11, color call cons_draw_line movw $10, x0 movw $10, y0 movw $310, x1 movw $190, y1 movb $9, color call cons_draw_line movw $310, x0 movw $190, y0 movw $10, x1 movw $95, y1 movb $8, color call cons_draw_line movw $10, x0 movw $95, y0 movw $10, x1 movw $10, y1 movb $7, color call cons_draw_line endless_loop: # Loop forever more jmp endless_loop # Program data boot_message: .string "Boot Loader Stage 2 loaded" x0: .int 0 y0: .int 0 x1: .int 0 y1: .int 0 deltax: .int 0 deltay: .int 0 sx: .int 0 sy: .int 0 err: .int 0 e2: .int 0 color: .byte 0