
Changed the parameters for the function to load into registers Changed all the data types to words instead of int in case ints are not allowed
261 lines
7.3 KiB
ArmAsm
261 lines
7.3 KiB
ArmAsm
# 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
|
|
|
|
# Added Write Hex and Int functions to help with debugging
|
|
|
|
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 # Make sure that err starts at 0
|
|
movw %ax, (x0) # Move the initial vars from the registers to static memory
|
|
movb %cl, (y0)
|
|
movw %bx, (x1)
|
|
movb %ch, (y1)
|
|
movb %dl, (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 x slope with 1
|
|
cmp x1, %cx # Check if x1 is less than x0 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
|
|
|
|
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 y slope with 1
|
|
cmpw y1, %dx # Check if y1 is less than y0 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 multiply it
|
|
add %ax, %ax # e2 is 2 * err, so we can just add err to itself
|
|
|
|
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 8
|
|
movb $0, %ah
|
|
movb $0x13, %al
|
|
int $0x10
|
|
xor %ax, %ax
|
|
|
|
movw $50, %ax # Plot a line, ax = x0, bx = x1, cl = y0, ch = y1, dl = color
|
|
movb $50, %cl # the X values require a full register but the y's only require a byte since the max value is 200
|
|
movw $160, %bx
|
|
movb $55, %ch
|
|
movb $12, %dl # The Color also only requires a byte
|
|
call cons_draw_line
|
|
|
|
# Draw the rest of the lines
|
|
movw $160, %ax
|
|
movb $55, %cl
|
|
movw $90, %bx
|
|
movb $150, %ch
|
|
movb $11, %dl
|
|
call cons_draw_line
|
|
|
|
movw $90, %ax
|
|
movb $150, %cl
|
|
movw $50, %bx
|
|
movb $50, %ch
|
|
movb $14, %dl
|
|
call cons_draw_line
|
|
|
|
movw $10, %ax
|
|
movb $10, %cl
|
|
movw $310, %bx
|
|
movb $10, %ch
|
|
movb $9, %dl
|
|
call cons_draw_line
|
|
|
|
movw $310, %ax
|
|
movb $10, %cl
|
|
movw $310, %bx
|
|
movb $190, %ch
|
|
movb $10, %dl
|
|
call cons_draw_line
|
|
|
|
movw $310, %ax
|
|
movb $190, %cl
|
|
movw $10, %bx
|
|
movb $190, %ch
|
|
movb $13, %dl
|
|
call cons_draw_line
|
|
|
|
movw $10, %ax
|
|
movb $190, %cl
|
|
movw $10, %bx
|
|
movb $10, %ch
|
|
movb $15, %dl
|
|
call cons_draw_line
|
|
|
|
movw $75, %ax
|
|
movb $150, %cl
|
|
movw $250, %bx
|
|
movb $110, %ch
|
|
movb $1, %dl
|
|
call cons_draw_line
|
|
|
|
movw $210, %ax
|
|
movb $30, %cl
|
|
movw $300, %bx
|
|
movb $150, %ch
|
|
movb $6, %dl
|
|
call cons_draw_line
|
|
|
|
movw $180, %ax
|
|
movb $180, %cl
|
|
movw $170, %bx
|
|
movb $20, %ch
|
|
movb $3, %dl
|
|
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
|
|
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: .byte 0 |