bootsectordisk/boot.s

262 lines
5.4 KiB
ArmAsm

.code16
# the currently viewed sector gets put at 0x7c00
# we move to 0x7000 to make space
.global _start # the linker needs to find it
_start:
jmp move_self
.ascii "the bootsector" # CAN AFFECT MANUALLY SET POINTER, LEAVE AT THIS LEN
_Xterm_grad:
.byte 0x00, 0x5f / 4, 0x87 / 4, 0xaf / 4, 0xd7 / 4, 0xff / 4
# saves some work later on when i'll want to execute sectors
move_self:
mov $512, %si
move_self_loop:
movb 0x7c00(%si), %ah
movb %ah, 0x7000(%si)
dec %si
jnz move_self_loop
jmp (vga_init-0xc00) # correct IP
vga_init:
# enter mode 13h
mov $0x13, %ax
int $0x10
# prepare the xterm palette 0-15
# 7 and 8 aren't right, TODO
# bl - counter rgb
xor %bh, %bh
palette1_loop:
mov %bh, %al
mov %al, %ah
mov $0x3c8, %dx
out %al, %dx
inc %dx
mov $3, %bl
palette1_color:
xor %al, %al # 0 al
shr $1, %ah # sets carry to the lost bit
adc $0, %al # add carry to %al, setting it to the carry flag
_palette1_sal:
sal $5, %al
sub $1, %al # this gets changed to 6 in the second half
# it will increase the lightness
adc $0, %al
out %al, %dx
dec %bl
jnz palette1_color
cmp $8, %bh
jne palette1_not7
inc _palette1_sal+2
palette1_not7:
inc %bh
jnz palette1_loop
# prepare the xterm palette 16-231
# ch - color id
# dx - used up for the port number
mov $16, %ch
mov $0x701, %ax # pointer to _Xterm_grad
mov %ax, %ds
palette_loop:
mov %ch, %al
dec %dx # we can reuse the %dx from the previous loop
out %al, %dx
inc %dx
sub $16, %al # the colors start at 16, real_id = id - 16
mov $6, %bl
xor %ah, %ah
div %bl # al = real_id / 6
# ah = remainder
mov %ah, %cl # cl = real_id % 6
xor %ah, %ah
div %bl # al = real_id / 6 / 6
# ah = remainder
# at this point
# al - R
# ah - G
# cl - B
# here i'm assuming that %bh is 0, because the loop above clears it
mov %al, %bl # output R
mov (%bx), %al
out %al, %dx
mov %ah, %bl # G
mov (%bx), %al
out %al, %dx
mov %cl, %bl # B
mov (%bx), %al
out %al, %dx
inc %ch
jnz palette_loop # loop until 0
# %ah stores the current shade
# %ch iterator
mov $2, %ah
mov $232, %ch
# the pattern i'm aiming for is
# [2, 5, 7, 10, 12, 15, 17, 20, 22, 25, 27, 30, 32, 35, 37, 40, 42, 45, 47, 50, 52, 55, 57, 60]
# +3 +2 +3 +2 +3 +2 +3 +2 +3 +2 +3 +2 +3 +2 +3 +2 +3 +2 ...
palette_greys:
mov %ch, %al
dec %dx
out %al, %dx
inc %dx
mov %ah, %al
out %al, %dx
out %al, %dx
out %al, %dx
add $2, %ah # TODO this is obviously wrong
inc %ch
jnz palette_greys
mov $0xA000, %ax # DS = vga memory
mov %ax, %ds
mov $0x7c0, %ax # ES = the bootsector
mov %ax, %es
update_screen_vgay:
mov $0, %dh
# "arguments":
# %es - has the sector at 0-512
# %dh - vga Y, should be either 0 or more than 25
update_screen:
.set SCALE, 6
.set TEXT_X, 0
.set TEXT_CLR, 102
.set IMG_X, 128
.set IMG_Y, 0
# %bl/h - scale iterators
# %al - current byte
# %si - position in sector
# %di - position in vga mem
# %dl - text X
mov $0, %si
mov $320*IMG_Y+IMG_X, %di
mov $TEXT_X, %dl
render_loop:
movb %es:(%si), %al
mov $SCALE, %bh
y_loop:
mov $SCALE, %bl
x_loop:
movb %al, %ds:(%di)
inc %di
dec %bl # loop ctr
jnz x_loop
add $320-SCALE, %di
dec %bh
jnz y_loop
sub $(320-1)*SCALE, %di
# text preview
cmp $25, %dh # the screen only has 25 lines, we can't render more
jnb text_overflow
mov $TEXT_CLR, %bl # update %bl with the text color
mov $0x2, %ah # move cursor (the position is already loaded)
int $0x10
mov $0xe, %ah # and print the charactr (again, already in the correct register)
int $0x10
text_overflow:
inc %dl # text forward
inc %si # sector forward
mov $15, %cl # check if %si is a multiple of 16
and %si, %cx
jnz not_eol # if it is, then we've finished the current row
add $(320-16)*SCALE, %di # go down in visualization
mov $TEXT_X, %dl # text back to left
inc %dh # and text down
not_eol:
cmp $512, %si
jl render_loop
# print sector number
int $0x10 # wild assumption - %ah == 0xe
int $0x10 # printing some garbage to make this line up
int $0x10
mov %cs:_sector_num+1, %cx
mov $4, %dl # loop counter
mov $231, %bl # TODO can be removed if i change the loop condition higher up
digit_loop:
mov %cx, %ax
mov $10, %dh # base 10
div %dh # %al = quotient ; %ah = remainder
ror $8, %ax # swap those around
add $'0', %al
mov %ah, %cl # save remainder
xor %ch, %ch
mov $0xe, %ah
int $0x10
mov $'\b', %al # backspace two times
int $0x10
int $0x10
dec %dl
jnz digit_loop
mov $0, %ah # read character
int $0x16
# scancode in %ah
cmp $0x4d, %ah # right arrow?
jne 1f
incw %cs:_sector_num+1
read_sector:
_sector_num:
movw $0, %ax # sector num (0indexed)
movb $18, %ch # divide by 18 (sectors / track)
div %ch
# %ah - sector
# %al - track * 2, 1st bit - head
mov $0x100, %dx # head / drive number
and %al, %dh
sar $1, %al
mov %al, %ch # track
mov %ah, %cl # sector
inc %cl # sectors are 1indexed
mov $1, %al # read only one sector
xor %bx, %bx # write to es:bx
# mov $0, %ah # reset disk system
# int $0x13
mov $2, %ah # actual read
int $0x13 # TODO error checking
jmp update_screen_vgay
1:
# not the right arrow
# left arrow?
cmp $0x4b, %ah
jne 1f
decw %cs:_sector_num+1 # it is, decrease sector and read
jmp read_sector
1: # default: scroll text
xorb $-7, %cs:update_screen_vgay+1
jmp update_screen_vgay
.fill 510-(.-_start), 1, 0x90 # fill with 0x90 (NOPs)
.word 0xaa55 # boot sector magic