Compare commits
24 Commits
9550f09f44
...
main
Author | SHA1 | Date |
---|---|---|
dzwdz | 3de45fe1e5 | |
dzwdz | 23c6be10fa | |
dzwdz | 156cca7375 | |
dzwdz | f286fc3fb9 | |
dzwdz | 8fe193ff39 | |
dzwdz | 2cc9a4f89e | |
dzwdz | 9e883b837d | |
dzwdz | e9d279fcf3 | |
dzwdz | b3e2ce7421 | |
dzwdz | fd05486fb3 | |
dzwdz | 55d7045b33 | |
dzwdz | 61d466a8c0 | |
dzwdz | 3289db1dd3 | |
dzwdz | d59152fcc0 | |
dzwdz | a38a1faa5a | |
dzwdz | 9cea35fd48 | |
dzwdz | b80b6e4019 | |
dzwdz | 758c43ba04 | |
dzwdz | 2bfc51f37e | |
dzwdz | 674f986e61 | |
dzwdz | 56e895fb1c | |
dzwdz | 666876c67c | |
dzwdz | baf573a710 | |
dzwdz | 0a76ca7a00 |
9
Makefile
9
Makefile
|
@ -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
257
boot.s
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue