Compare commits

...

24 Commits

Author SHA1 Message Date
dzwdz 3de45fe1e5 fix bug with skipping over sectors 2021-08-22 20:08:04 +02:00
dzwdz 23c6be10fa add the greyscale palette 2021-08-22 19:49:07 +02:00
dzwdz 156cca7375 minor cleanup 2021-08-22 18:52:25 +02:00
dzwdz f286fc3fb9 save some bytes in the palette code 2021-08-22 18:48:22 +02:00
dzwdz 8fe193ff39 remove color test bar 2021-08-22 18:29:12 +02:00
dzwdz 2cc9a4f89e palette 0-16 2021-08-22 18:25:11 +02:00
dzwdz 9e883b837d working counter 2021-08-21 23:53:45 +02:00
dzwdz e9d279fcf3 proper sector reading; CHS 2021-08-20 23:58:02 +02:00
dzwdz b3e2ce7421 spaghetti key handling 2021-08-19 22:48:53 +02:00
dzwdz fd05486fb3 switch between sectors 2021-08-19 22:41:14 +02:00
dzwdz 55d7045b33 read sector from disk 2021-08-19 22:37:38 +02:00
dzwdz 61d466a8c0 switch %ds and %es 2021-08-19 22:20:23 +02:00
dzwdz 3289db1dd3 copy itself to 0x7000 and execute from there 2021-08-19 22:13:02 +02:00
dzwdz d59152fcc0 use an entire floppy image 2021-08-19 21:57:02 +02:00
dzwdz a38a1faa5a fix indentation 2021-08-19 21:28:06 +02:00
dzwdz 9cea35fd48 the text is now scrolleable
it uses selfmodifying code so the visualization is blinking
it's a feature ok
2021-08-19 21:25:36 +02:00
dzwdz b80b6e4019 make the comments slightly better, change names of stuff 2021-08-19 20:45:37 +02:00
dzwdz 758c43ba04 screenshot prep 2021-08-19 16:37:47 +02:00
dzwdz 2bfc51f37e move stuff around 2021-08-19 16:31:26 +02:00
dzwdz 674f986e61 background color 2021-08-19 16:26:38 +02:00
dzwdz 56e895fb1c partial text visualization 2021-08-19 16:23:08 +02:00
dzwdz 666876c67c print the sector number 2021-08-19 16:06:02 +02:00
dzwdz baf573a710 scale up the visualization 2021-08-19 15:48:41 +02:00
dzwdz 0a76ca7a00 change the loop condition in the visualization code 2021-08-19 15:25:52 +02:00
2 changed files with 216 additions and 50 deletions

View File

@ -1,11 +1,16 @@
boot.bin: boot.o
ld -o $@ --oformat binary -Ttext 0x7c00 $<
ld -o $@ --oformat binary -Ttext 0x7000 $<
boot.o: boot.s
as -o $@ $<
floppy.bin: boot.bin floppy_base.bin
rm -vf $@
cp floppy_base.bin $@
dd if=boot.bin of=$@ conv=notrunc
.PHONY: boot disasm hexdump
boot: boot.bin
boot: floppy.bin
qemu-system-i386 -drive file=$^,index=0,if=floppy,format=raw
disasm: boot.bin

257
boot.s
View File

@ -1,100 +1,261 @@
.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 vga_init
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 16-231
# bh - color id
# dx - used up for the port number
mov $16, %bh
xor %ch, %ch
mov $0x7c1, %ax # pointer to _Xterm_grad
mov %ax, %ds
palette_loop:
# 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
mov %cl, %bl # stash %cl in %bl
mov %al, %cl # output R
mov %cx, %si
mov (%si), %al
# 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, %cl # G
mov %cx, %si
mov (%si), %al
mov %ah, %bl # G
mov (%bx), %al
out %al, %dx
mov %bl, %cl # B
mov %cx, %si
mov (%si), %al
mov %cl, %bl # B
mov (%bx), %al
out %al, %dx
inc %bh
inc %ch
jnz palette_loop # loop until 0
# TODO first 16 + grayscale
before_loop:
mov $0xA000, %ax # ES = vga memory
mov %ax, %es
mov $0x7c0, %ax # DS = the bootsector
# %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 $0, %di
loop:
movb %ds:(%si), %cl
movb %cl, %es:(%di)
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
mov $16, %cl # if we've crossed a 16 pixel boundary, skip to the next line
and %di, %cx
jz not_eol
add $304, %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:
inc %si # only iterate 512 times
cmp $512, %si
jl loop
jl render_loop
incb %es:319
end:
hlt
jmp end
# .fill (510-(.-_start))/4, 4, 0xc4c5c6c7 # color stripes for testing
# 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