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
--- /dev/null
+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`.
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
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
.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
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
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
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
xor ax, ax
mov ds, ax
+ inc word [frameno]
+
; check for keypress
in al, 64h
and al, 1
; data
+%include "lut.inc"
+
num_spawn_pos dd 0
+frameno dw 0
align 16
spawn_pos:
imgrle: incbin "nuclear.rle"