bootsectordisk/boot.s

262 lines
5.4 KiB
ArmAsm
Raw Permalink Normal View History

2021-08-16 17:15:38 +00:00
.code16
2021-08-19 20:37:38 +00:00
# the currently viewed sector gets put at 0x7c00
# we move to 0x7000 to make space
2021-08-16 17:15:38 +00:00
.global _start # the linker needs to find it
_start:
jmp move_self
2021-08-16 20:47:17 +00:00
.ascii "the bootsector" # CAN AFFECT MANUALLY SET POINTER, LEAVE AT THIS LEN
2021-08-16 17:19:47 +00:00
2021-08-16 19:34:08 +00:00
_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
2021-08-16 19:34:08 +00:00
vga_init:
2021-08-16 17:15:38 +00:00
# enter mode 13h
mov $0x13, %ax
int $0x10
2021-08-22 16:52:25 +00:00
2021-08-22 16:25:11 +00:00
# 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
2021-08-16 19:34:08 +00:00
# prepare the xterm palette 16-231
2021-08-22 16:48:22 +00:00
# ch - color id
2021-08-16 19:34:08 +00:00
# dx - used up for the port number
2021-08-22 16:48:22 +00:00
mov $16, %ch
2021-08-16 20:23:04 +00:00
mov $0x701, %ax # pointer to _Xterm_grad
2021-08-16 20:23:04 +00:00
mov %ax, %ds
2021-08-16 19:34:08 +00:00
palette_loop:
2021-08-22 16:48:22 +00:00
mov %ch, %al
2021-08-22 16:25:11 +00:00
dec %dx # we can reuse the %dx from the previous loop
2021-08-16 19:34:08 +00:00
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
2021-08-16 20:23:04 +00:00
# cl - B
2021-08-22 16:48:22 +00:00
# here i'm assuming that %bh is 0, because the loop above clears it
mov %al, %bl # output R
mov (%bx), %al
2021-08-16 19:34:08 +00:00
out %al, %dx
2021-08-22 16:48:22 +00:00
mov %ah, %bl # G
mov (%bx), %al
2021-08-16 19:34:08 +00:00
out %al, %dx
2021-08-22 16:48:22 +00:00
mov %cl, %bl # B
mov (%bx), %al
2021-08-16 19:34:08 +00:00
out %al, %dx
2021-08-22 16:48:22 +00:00
inc %ch
2021-08-16 19:34:08 +00:00
jnz palette_loop # loop until 0
2021-08-22 17:49:07 +00:00
# %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
2021-08-16 19:34:08 +00:00
2021-08-19 20:20:23 +00:00
mov $0xA000, %ax # DS = vga memory
mov %ax, %ds
2021-08-19 14:26:38 +00:00
2021-08-19 20:20:23 +00:00
mov $0x7c0, %ax # ES = the bootsector
mov %ax, %es
update_screen_vgay:
2021-08-19 19:28:06 +00:00
mov $0, %dh
# "arguments":
2021-08-19 20:20:23 +00:00
# %es - has the sector at 0-512
# %dh - vga Y, should be either 0 or more than 25
update_screen:
2021-08-19 13:48:41 +00:00
.set SCALE, 6
2021-08-19 14:31:26 +00:00
.set TEXT_X, 0
2021-08-19 14:37:47 +00:00
.set TEXT_CLR, 102
2021-08-19 14:31:26 +00:00
.set IMG_X, 128
.set IMG_Y, 0
2021-08-19 13:48:41 +00:00
# %bl/h - scale iterators
2021-08-19 14:23:08 +00:00
# %al - current byte
# %si - position in sector
# %di - position in vga mem
# %dl - text X
mov $0, %si
2021-08-19 14:31:26 +00:00
mov $320*IMG_Y+IMG_X, %di
2021-08-19 14:23:08 +00:00
mov $TEXT_X, %dl
render_loop:
2021-08-19 20:20:23 +00:00
movb %es:(%si), %al
2021-08-19 13:48:41 +00:00
mov $SCALE, %bh
y_loop:
mov $SCALE, %bl
x_loop:
2021-08-19 20:20:23 +00:00
movb %al, %ds:(%di)
2021-08-19 13:48:41 +00:00
inc %di
dec %bl # loop ctr
jnz x_loop
add $320-SCALE, %di
dec %bh
jnz y_loop
sub $(320-1)*SCALE, %di
2021-08-16 17:15:38 +00:00
2021-08-19 14:23:08 +00:00
# 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)
2021-08-19 14:23:08 +00:00
int $0x10
mov $0xe, %ah # and print the charactr (again, already in the correct register)
2021-08-19 14:23:08 +00:00
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
2021-08-19 14:23:08 +00:00
add $(320-16)*SCALE, %di # go down in visualization
mov $TEXT_X, %dl # text back to left
inc %dh # and text down
2021-08-16 17:15:38 +00:00
not_eol:
cmp $512, %si
jl render_loop
2021-08-16 17:15:38 +00:00
2021-08-19 14:06:02 +00:00
2021-08-21 21:53:45 +00:00
# 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
2021-08-19 14:06:02 +00:00
mov $0xe, %ah
int $0x10
2021-08-21 21:53:45 +00:00
mov $'\b', %al # backspace two times
2021-08-19 14:06:02 +00:00
int $0x10
int $0x10
2021-08-21 21:53:45 +00:00
dec %dl
jnz digit_loop
2021-08-19 20:41:14 +00:00
mov $0, %ah # read character
int $0x16
2021-08-19 20:48:53 +00:00
# scancode in %ah
cmp $0x4d, %ah # right arrow?
jne 1f
2021-08-19 20:41:14 +00:00
2021-08-19 20:48:53 +00:00
incw %cs:_sector_num+1
read_sector:
2021-08-19 20:41:14 +00:00
_sector_num:
2021-08-22 18:08:04 +00:00
movw $0, %ax # sector num (0indexed)
2021-08-20 21:58:02 +00:00
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
2021-08-22 18:08:04 +00:00
mov %al, %ch # track
2021-08-20 21:58:02 +00:00
mov %ah, %cl # sector
2021-08-22 18:08:04 +00:00
inc %cl # sectors are 1indexed
2021-08-20 21:58:02 +00:00
2021-08-19 20:48:53 +00:00
mov $1, %al # read only one sector
2021-08-19 20:41:14 +00:00
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
2021-08-19 20:48:53 +00:00
jmp update_screen_vgay
2021-08-19 20:41:14 +00:00
2021-08-19 20:48:53 +00:00
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
2021-08-16 17:15:38 +00:00
2021-08-19 14:37:47 +00:00
.fill 510-(.-_start), 1, 0x90 # fill with 0x90 (NOPs)
2021-08-16 17:15:38 +00:00
.word 0xaa55 # boot sector magic