262 lines
5.4 KiB
ArmAsm
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
|