works nicely from the floppy master
authorJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 17 Dec 2020 03:34:33 +0000 (05:34 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 17 Dec 2020 03:34:33 +0000 (05:34 +0200)
.gitignore
Makefile
README.md [new file with mode: 0644]
bootsplash.asm
lut.inc [new file with mode: 0644]
lutgen/Makefile [new file with mode: 0644]
lutgen/lutgen.c [new file with mode: 0644]

index 492e4f8..48b722b 100644 (file)
@@ -8,3 +8,4 @@
 dis
 rle/rle
 rle/unrle
+lutgen/lutgen
index fc3da3e..2f6fab5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,12 +5,18 @@ $(img): $(bin)
        dd if=/dev/zero of=$@ bs=512 count=2880
        dd if=$< of=$@ bs=512 conv=notrunc
 
-$(bin): bootsplash.asm nuclear.rle
+$(bin): bootsplash.asm nuclear.rle fire.pal
        nasm -f bin -o $@ $<
 
 nuclear.rle: nuclear.img rle/rle
        cat $< | rle/rle >$@ 2>rle.log
 
+nuclear.img: nuclear.pgm
+       dd if=$< of=$@ bs=1 skip=61
+
+fire.pal: fire.ppm
+       dd if=$< of=$@ bs=1 skip=59
+
 rle/rle:
        $(MAKE) -C rle
 
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..1f34f05
--- /dev/null
+++ b/README.md
@@ -0,0 +1,42 @@
+Bootsplash
+----------
+Small bootable program that shows a splash effect every time you boot it up, and
+when you hit any key on the keyboard, it proceeds to load the actual system (or
+your regular boot loader) off the hard drive.
+
+
+Author: John Tsiombikas <nuclear@member.fsf.org>
+
+Not copyrighted, public domain software. Feel free to use it any way you like.
+If public domain is not legally recognized in your country, you may instead use
+it under the terms of the Creative Commons CC0 license.
+
+Future improvements (TODO list):
+
+  - Option to load active partition instead of MBR from the selected boot device
+    to make bootsplash itself installable on the MBR (as it is, it would just
+    infinitely load itself).
+  - Add BIOS parameter block and fake partition table, to make it more likely
+    to be loadable from a USB stick.
+  - Add timeout to boot automatically if no key is pressed for a certain amount
+    of time.
+
+Build
+-----
+To build bootsplash you need the netwide assembler (nasm). If you want to
+customize the image used by the effect, you'll also need a C compiler to build
+the RLE encoder under `rle`.
+
+The data files are not in the repo. You'll need to get them from one of the
+release archives.
+
+  - `nuclear.pgm`: 320x200 greyscale image used by the effect in binary Portable
+    GreyMap format.  This is fed into the `rle` encoder to produce `nuclear.rle`
+    which is `incbin`-ed into the bootsplash program.
+  - `fire.ppm`: 256x1 RGB image in binary Portable PixMap format. The header gets
+    stripped and the resulting `fire.pal` file is `incbin`-ed into the program.
+
+If you don't want to customize the effect, simply copy the final files
+(`nuclear.rle` and `fire.pal`) and type make.
+
+To install onto a floppy, just use `dd`.
index 5885c4d..b7f53c7 100644 (file)
@@ -1,13 +1,26 @@
        org 7c00h
        bits 16
 
+BOOT_DEV equ 80h
+
 stacktop equ 7b00h
 boot_driveno equ 7b00h ; 1 byte
 stage2_size equ stage2_end - stage2_start
 
-spawn_rate equ 256
+spawn_rate equ 512
 framebuf equ 40000h
 
+%macro floppy_motor_off 0
+       pushf
+       and dl, 80h
+       jnz %%end       ; skip if high bit is set (i.e. it's not a floppy)
+       mov dx, 3f2h
+       in al, dx
+       and al, 0fh
+       out dx, al
+%%end: popf
+%endmacro
+
 start:
        xor ax, ax
        mov ds, ax
@@ -23,12 +36,13 @@ start:
        xor ax, ax
        mov es, ax
        mov bx, stage2_start
-       mov ah, 2               ; read sectors LBA call
+       mov ah, 2               ; read sectors call
        mov al, (stage2_size + 511) / 512  ; num sectors
        mov cx, 2               ; ch: cylinder, cl: sector
        xor dx, dx              ; dh: head
        mov dl, [boot_driveno]
        int 13h
+       floppy_motor_off        ; turn off floppy motor (if dl is < 80h)
        jnc stage2_start        ; loaded successfully, jump to it
 
        ; failed to load second sector
@@ -52,15 +66,19 @@ printstr:
 .done: ret
 
 str_load_fail db "Failed to load second stage!",0
-str_booting db "Booting ...",0
+str_booting db "Booting system... ",0
+str_bootfail db "failed!",0
 
 
        times 510-($-$$) db 0
-       dw 0xaa55
+bootsig dw 0xaa55
 
        ; start of the second stage
 stage2_start:
+       pushf
+       cli
        call splash
+       popf
 
        xor ax, ax
        mov es, ax
@@ -69,10 +87,39 @@ stage2_start:
        mov ax, str_booting
        call printstr
 
-       cli
-.hang: hlt
+       ; blank out the existing boot signature to really see if a boot sector
+       ; gets loaded correctly
+       xor ax, ax
+       mov [bootsig], ax
+
+       ; load from BOOT_DEV into 7c00h and jump
+       mov bx, 7c00h
+       mov ax, 0201h           ; ah: call 2 (read sectors), al: count = 1
+       mov cx, 1               ; ch: cylinder 0, cl: sector 1
+       mov dx, BOOT_DEV        ; dh: head 0, dl: boot device number
+       int 13h
+       floppy_motor_off        ; turn floppy motor off (if dl < 80h)
+
+       jc .fail                ; BIOS will set the carry flag on failure
+       mov ax, [bootsig]
+       cmp ax, 0aa55h
+       jnz .fail               ; fail if what we loaded is not a valid boot sect
+
+       mov ax, 0e0dh
+       mov bx, 7
+       int 10h
+       mov ax, 0e0ah
+       int 10h
+
+       jmp 7c00h               ; all checks passed, jump there
+
+.fail: mov ax, str_bootfail
+       call printstr
+.hang: cli
+       hlt
        jmp .hang
 
+
        ; splash screen effect
 splash:
        mov ax, 13h
@@ -142,6 +189,15 @@ splash:
        xor edx, edx
        div dword [num_spawn_pos]       ; edx <- rand % num_spawn_pos
        mov bx, [es:edx * 2]            ; grab one of the spawn positions
+
+       ; animate the spawn position
+       xor ax, ax
+       mov al, [frameno]
+       mov bp, ax
+       movsx ax, byte [bp + sintab]
+       sar ax, 3
+       add bx, ax
+
        mov byte [fs:bx], 0xff          ; plot a pixel there
        dec cx
        jnz .spawn
@@ -153,13 +209,23 @@ splash:
        xor ax, ax      ; use: pixel accum
        xor dx, dx      ; use: second pixel
 .blurloop:
+       xor ax, ax
        mov al, [bx]
        mov dl, [bx + 320]
        add ax, dx
-       shr ax, 1
+       mov dl, [bx + 319]
+       add ax, dx
+       mov dl, [bx + 321]
+       add ax, dx
+       mov dl, [bx + 640]
+       add ax, dx
+       xor dx, dx
+       mov cx, 5
+       div cx
        mov [bx], al
+
        inc bx
-       cmp bx, 64000 - 320 * 2
+       cmp bx, 64000 - 640
        jnz .blurloop
 
 
@@ -184,6 +250,8 @@ splash:
        xor ax, ax
        mov ds, ax
 
+       inc word [frameno]
+
        ; check for keypress
        in al, 64h
        and al, 1
@@ -240,7 +308,10 @@ randval dd 0ace1h
 
 
        ; data
+%include "lut.inc"
+
 num_spawn_pos dd 0
+frameno dw 0
        align 16
 spawn_pos:
 imgrle:        incbin "nuclear.rle"
diff --git a/lut.inc b/lut.inc
new file mode 100644 (file)
index 0000000..5dc6fdc
--- /dev/null
+++ b/lut.inc
@@ -0,0 +1,257 @@
+sintab:
+       db 0
+       db 2
+       db 5
+       db 8
+       db 11
+       db 15
+       db 18
+       db 21
+       db 24
+       db 27
+       db 30
+       db 33
+       db 36
+       db 39
+       db 42
+       db 45
+       db 48
+       db 51
+       db 54
+       db 56
+       db 59
+       db 62
+       db 65
+       db 67
+       db 70
+       db 72
+       db 75
+       db 77
+       db 80
+       db 82
+       db 85
+       db 87
+       db 89
+       db 91
+       db 93
+       db 96
+       db 98
+       db 100
+       db 101
+       db 103
+       db 105
+       db 107
+       db 108
+       db 110
+       db 111
+       db 113
+       db 114
+       db 116
+       db 117
+       db 118
+       db 119
+       db 120
+       db 121
+       db 122
+       db 123
+       db 123
+       db 124
+       db 125
+       db 125
+       db 126
+       db 126
+       db 126
+       db 126
+       db 126
+       db 127
+       db 126
+       db 126
+       db 126
+       db 126
+       db 126
+       db 125
+       db 125
+       db 124
+       db 123
+       db 123
+       db 122
+       db 121
+       db 120
+       db 119
+       db 118
+       db 117
+       db 116
+       db 114
+       db 113
+       db 111
+       db 110
+       db 108
+       db 107
+       db 105
+       db 103
+       db 101
+       db 100
+       db 98
+       db 96
+       db 93
+       db 91
+       db 89
+       db 87
+       db 85
+       db 82
+       db 80
+       db 77
+       db 75
+       db 72
+       db 70
+       db 67
+       db 65
+       db 62
+       db 59
+       db 56
+       db 54
+       db 51
+       db 48
+       db 45
+       db 42
+       db 39
+       db 36
+       db 33
+       db 30
+       db 27
+       db 24
+       db 21
+       db 18
+       db 15
+       db 11
+       db 8
+       db 5
+       db 2
+       db 0
+       db -3
+       db -6
+       db -9
+       db -12
+       db -16
+       db -19
+       db -22
+       db -25
+       db -28
+       db -31
+       db -34
+       db -37
+       db -40
+       db -43
+       db -46
+       db -49
+       db -52
+       db -55
+       db -57
+       db -60
+       db -63
+       db -66
+       db -68
+       db -71
+       db -73
+       db -76
+       db -78
+       db -81
+       db -83
+       db -86
+       db -88
+       db -90
+       db -92
+       db -94
+       db -97
+       db -99
+       db -101
+       db -102
+       db -104
+       db -106
+       db -108
+       db -109
+       db -111
+       db -112
+       db -114
+       db -115
+       db -117
+       db -118
+       db -119
+       db -120
+       db -121
+       db -122
+       db -123
+       db -124
+       db -124
+       db -125
+       db -126
+       db -126
+       db -127
+       db -127
+       db -127
+       db -127
+       db -127
+       db -128
+       db -127
+       db -127
+       db -127
+       db -127
+       db -127
+       db -126
+       db -126
+       db -125
+       db -124
+       db -124
+       db -123
+       db -122
+       db -121
+       db -120
+       db -119
+       db -118
+       db -117
+       db -115
+       db -114
+       db -112
+       db -111
+       db -109
+       db -108
+       db -106
+       db -104
+       db -102
+       db -101
+       db -99
+       db -97
+       db -94
+       db -92
+       db -90
+       db -88
+       db -86
+       db -83
+       db -81
+       db -78
+       db -76
+       db -73
+       db -71
+       db -68
+       db -66
+       db -63
+       db -60
+       db -57
+       db -55
+       db -52
+       db -49
+       db -46
+       db -43
+       db -40
+       db -37
+       db -34
+       db -31
+       db -28
+       db -25
+       db -22
+       db -19
+       db -16
+       db -12
+       db -9
+       db -6
+       db -3
diff --git a/lutgen/Makefile b/lutgen/Makefile
new file mode 100644 (file)
index 0000000..56c882c
--- /dev/null
@@ -0,0 +1,8 @@
+LDFLAGS = -lm
+
+lutgen: lutgen.o
+       $(CC) -o $@ $< $(LDFLAGS)
+
+clean:
+       $(RM) lutgen
+       $(RM) lutgen.o
diff --git a/lutgen/lutgen.c b/lutgen/lutgen.c
new file mode 100644 (file)
index 0000000..2e5bf27
--- /dev/null
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <math.h>
+
+int main(void)
+{
+       int i;
+
+       printf("sintab:\n");
+       for(i=0; i<256; i++) {
+               float x = sin((float)i / 128.0f * M_PI);
+               printf("\tdb %d\n", (int)(x * 127.5f - 0.5f));
+       }
+       return 0;
+}