second stage loader loading semi-works
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 10 Apr 2018 01:18:43 +0000 (04:18 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 10 Apr 2018 01:18:43 +0000 (04:18 +0300)
Makefile
gdbnotes
src/boot/boot.s
src/boot/boot2.s

index d034876..9117c3f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -20,6 +20,10 @@ ifneq ($(shell uname -m), i386)
        ldarch = -m elf_i386
 endif
 
+floppy.img: $(bin)
+       dd if=/dev/zero of=$@ bs=512 count=2880
+       dd if=$< of=$@ conv=notrunc
+
 $(bin): $(elf)
        objcopy -O binary $< $@
 
@@ -41,4 +45,4 @@ cleandep:
 
 .PHONY: run
 run: $(bin)
-       qemu-system-i386 -fda $(bin)
+       qemu-system-i386 -fda floppy.img
index e03261f..fb31bbf 100644 (file)
--- a/gdbnotes
+++ b/gdbnotes
@@ -7,4 +7,4 @@ b *0x7c00
 
 examine register with: i r eax
 
-$ objdump -D test
+$ objdump -D test -m i8086
index 499c386..ac4a424 100644 (file)
@@ -3,10 +3,10 @@
 
        cli
        cld
-       # move stack to the top of 512k
-       mov $0x7000, %ax
+       # move stack to just below the code
+       xor %ax, %ax
        mov %ax, %ss
-       xor %sp, %sp
+       mov $0x7c00, %sp
        # use the code segment for data access
        mov %cs, %ax
        mov %ax, %ds
@@ -25,7 +25,7 @@
        shr $9, %eax
        and $0x1ff, %ebx
        jz 0f
-       inc %eax
+       inc %ax
 0:     pushw %ax
        pushw $1
        # set es to the start of the destination buffer to allow reading in
@@ -34,7 +34,7 @@
        shr $4, %bx
        mov %bx, %es
        xor %bx, %bx
-       call read_sect
+       call read_sectors
        jmp boot2_addr
 
        cli
        .set ARG_NSECT, 6
        .set ARG_SIDX, 4
 
-# read_sect(first, num)
-read_sect:
+# read_sectors(first, num)
+read_sectors:
        push %bp
        mov %sp, %bp
 
        mov ARG_SIDX(%bp), %ax
-       mov ARG_NSECT(%bp), %cx
+       xor %cx, %cx
 
        jmp 1f
 0:     push %ax
        call read_sector
-       add $2, %sp
+       pop %ax
+       inc %ax
+       inc %cx
 1:     cmp ARG_NSECT(%bp), %cx
        jnz 0b
 
        pop %bp
        ret
 
+       .set VAR_ATTEMPTS, -2
+
 # read_sector(sidx)
 read_sector:
        push %bp
        mov %sp, %bp
+       sub $2, %sp
        push %cx
        push %dx
 
+       movw $3, VAR_ATTEMPTS(%bp)
+
+.Lread_try:
        # calculate the track (sidx / sectors_per_track)
        mov 4(%bp), %ax
        xor %dx, %dx
@@ -92,7 +100,22 @@ read_sector:
        mov $0x0201, %ax
        movb drive_number, %dl
        int $0x13
+       jnc .Lread_ok
+
+       # abort after 3 attempts
+       decw VAR_ATTEMPTS(%bp)
+       jz .Lread_fail
+
+       # error detected, reset controller and retry
+       xor %ah, %ah
+       int $0x13
+       jmp .Lread_try
 
+.Lread_fail:
+       mov 4(%bp), %ax
+       jmp abort_read
+
+.Lread_ok:
        # increment es:bx accordingly (advance es if bx overflows)
        add $512, %bx
        jno 0f
@@ -100,11 +123,26 @@ read_sector:
        add $4096, %ax
        mov %ax, %es
 
-       pop %dx
+0:     pop %dx
        pop %cx
+       add $2, %sp
        pop %bp
        ret
 
+str_read_error: .asciz "Failed to read sector: "
+
+abort_read:
+       push %ax
+       mov $str_read_error, %si
+       call print_str
+
+       xor %eax, %eax
+       pop %ax
+       call print_num
+
+       cli
+       hlt
+
 clearscr:
        push %es
        pushw $0xb800
@@ -116,6 +154,28 @@ clearscr:
        pop %es
        ret
 
+cursor_x: .byte 0
+
+# expects string pointer in ds:si
+print_str:
+       push %es
+       pushw $0xb800
+       pop %es
+       xor %di, %di
+       movb $0, cursor_x
+
+0:     mov (%si), %al
+       mov %al, %es:(%di)
+       movb $7, %es:1(%di)
+       inc %si
+       add $2, %di
+       incb cursor_x
+       cmp $0, %al
+       jnz 0b
+
+       pop %es
+       ret
+
 # expects number in eax
 print_num:
        # save es
@@ -137,7 +197,10 @@ print_num:
        # print the backwards string
        pushw $0xb800
        pop %es
-       xor %di, %di
+       movb cursor_x, %al
+       xor %ah, %ah
+       shl $1, %ax
+       mov %ax, %di
 
 0:     dec %si
        mov (%si), %al
index 47121ee..7b8c7bb 100644 (file)
@@ -5,20 +5,44 @@
        mov $0x13, %ax
        int $0x10
 
-       pushw $63
-       pushw $63
-       pushw $0
-       pushw $0xff
-       call set_palette
-       add $8, %sp
+       # copy palette
+       mov $logo_pal, %si
+       xor %cl, %cl
 
+0:     mov $0x3c8, %dx
+       movb %cl, %al
+       outb %al, %dx
+       inc %dx
+       # red
+       movb (%si), %al
+       inc %si
+       shr $2, %al
+       outb %al, %dx
+       # green
+       movb (%si), %al
+       inc %si
+       shr $2, %al
+       outb %al, %dx
+       # blue
+       movb (%si), %al
+       inc %si
+       shr $2, %al
+       outb %al, %dx
+       inc %cl
+       jno 0b
+
+       # copy pixels
        pushw $0xa000
        pop %es
        xor %di, %di
+       mov $logo_pix, %eax
+       shr $4, %eax
+       mov %ax, %ds
+       xor %si, %si
        mov $16000, %ecx
-       mov $0xffffffff, %eax
-       rep stosl
+       rep movsl
 
+       cli
        hlt
 
 set_palette:
@@ -34,3 +58,10 @@ set_palette:
        movw 8(%bp), %ax
        outb %al, %dx
        ret
+
+logo_pal:
+       .incbin "logo.pal"
+
+       .align 16
+logo_pix:
+       .incbin "logo.raw"