# 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 # Draw Line function cons_draw_line: movw $0, err # Make sure that err starts at 0 movw %ax, (x0) # Move the initial vars from the registers to static memory movw %bx, (y0) movw %cx, (x1) movw %dx, (y1) movw %si, (color) movw x1, %cx # Load x1 and y1 into the registers movw y1, %dx sub x0, %cx # Remove x/y0 from x/y1 to get the delta values sub y0, %dx movw %cx, (deltax) # Store the delta values movw %dx, (deltay) cons_line_check_x: movw x0, %cx # Load x0 into register cx so we can manipulate this value to plot each pixel movw $1, (sx) # Preload the x slope with 1 cmp x1, %cx # Check if x0 is less than x1 and we can move to y jl cons_line_check_y negw sx # If x1 is greater than we need to flip the slope and the x delta values negw deltax # Flipping the deltax here saves us from having to have an abs function because if # x0 was greater than x1 we know we have a negative delta value and we flip it to pos cons_line_check_y: movw y0, %dx # Load y0 into register dx so we can manipulate this value to plot each pixel movw $1, (sy) # Preload the y slope with 1 cmpw y1, %dx # Check if y0 is less than y1 and we can start our plotting jl cons_line_prep_loop negw sy # if y1 is greater than we need to flip the slope y and delta y values negw deltay cons_line_prep_loop: movw deltax, %ax # Calculate the err variable by subtracting delta y from delta x sub deltay, %ax movw %ax, (err) cons_line_loop_start: xor %ax, %ax # Clear ax and bx for use with the draw function xor %bx, %bx movb $0x0c, %ah # Set the function byte to plot the pixel movb $0, %bh # Set the video page number movb (color), %al # Set the color of the pixel int $0x10 # Call the int cmpw x1, %cx # Check if x0 and x1 are equal, if not then we are still plotting jne cons_line_loop_next_point cmpw y1, %dx # Check if y0 and y1 are equal, if not then we are still plotting jne cons_line_loop_next_point jmp cons_line_loop_end # if both x's and y's are equal then we can end the function cons_line_loop_next_point: movw err, %ax # Load err into ax so that we can change it sal %ax # e2 is 2 * err, so we can arithmatic shift left cons_line_loop_move_y_point: movw deltay, %bx negw %bx # We need negative deltay to compare cmpw %bx, %ax # Check if we need to apply the slope value to y jle cons_line_loop_move_x_point negw %bx # Change deltay back to normal subw %bx, err # Remove the deltay from the err check addw sx, %cx # Add the slope value to the current y value cons_line_loop_move_x_point: movw deltax, %bx cmpw %bx, %ax # Check if we need to apply the x slope value jge cons_line_loop_start addw %bx, err # Add the deltax to the err value addw sy, %dx # Add the slope value to the current x value jmp cons_line_loop_start # Go back to the start of the loop cons_line_loop_end: ret # Finish the loop and return to the call address 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 256 movb $0, %ah movb $0x13, %al int $0x10 xor %ax, %ax movw $50, %ax # Plot a line, ax = x0, bx = y0, cx = x1, dx = y1, si = color movw $50, %bx movw $160, %cx movw $55, %dx movw $12, %si # The Color using the si counter because we dont have enough normal registers call cons_draw_line # Draw the rest of the lines movw $160, %ax movw $55, %bx movw $90, %cx movw $150, %dx movw $11, %si call cons_draw_line movw $90, %ax movw $150, %bx movw $50, %cx movw $50, %dx movw $14, %si call cons_draw_line movw $10, %ax movw $10, %bx movw $310, %cx movw $10, %dx movw $9, %si call cons_draw_line movw $310, %ax movw $10, %bx movw $310, %cx movw $190, %dx movw $10, %si call cons_draw_line movw $310, %ax movw $190, %bx movw $10, %cx movw $190, %dx movw $13, %si call cons_draw_line movw $10, %ax movw $190, %bx movw $10, %cx movw $10, %dx movw $15, %si call cons_draw_line movw $75, %ax movw $150, %bx movw $250, %cx movw $110, %dx movw $1, %si call cons_draw_line movw $210, %ax movw $30, %bx movw $300, %cx movw $150, %dx movw $6, %si call cons_draw_line movw $180, %ax movw $180, %bx movw $170, %cx movw $20, %dx movw $3, %si call cons_draw_line endless_loop: # Loop forever more jmp endless_loop # Program data boot_message: .string "Boot Loader Stage 2 loaded" x0: .word 0 # Setup the static memory to hold our variables y0: .word 0 x1: .word 0 y1: .word 0 deltax: .word 0 deltay: .word 0 sx: .word 0 sy: .word 0 err: .word 0 e2: .word 0 color: .word 0