From 2b146d7fb7d0812dfcd4ac213682e947ba98051c Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Thu, 17 Dec 2020 05:34:33 +0200 Subject: [PATCH] works nicely from the floppy --- .gitignore | 1 + Makefile | 8 +- README.md | 42 +++++++++ bootsplash.asm | 87 +++++++++++++++++-- lut.inc | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lutgen/Makefile | 8 ++ lutgen/lutgen.c | 14 +++ 7 files changed, 408 insertions(+), 9 deletions(-) create mode 100644 README.md create mode 100644 lut.inc create mode 100644 lutgen/Makefile create mode 100644 lutgen/lutgen.c diff --git a/.gitignore b/.gitignore index 492e4f8..48b722b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ dis rle/rle rle/unrle +lutgen/lutgen diff --git a/Makefile b/Makefile index fc3da3e..2f6fab5 100644 --- 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 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 + +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`. diff --git a/bootsplash.asm b/bootsplash.asm index 5885c4d..b7f53c7 100644 --- a/bootsplash.asm +++ b/bootsplash.asm @@ -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 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 index 0000000..56c882c --- /dev/null +++ b/lutgen/Makefile @@ -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 index 0000000..2e5bf27 --- /dev/null +++ b/lutgen/lutgen.c @@ -0,0 +1,14 @@ +#include +#include + +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; +} -- 1.7.10.4