forked from offtopia/ponydos
Load wallpaper from disk
This commit is contained in:
parent
465f6ebf22
commit
ff1b91f3dd
5 changed files with 247 additions and 11 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
*.bin
|
*.bin
|
||||||
|
*.img
|
||||||
|
|
20
Makefile
20
Makefile
|
@ -1,20 +1,28 @@
|
||||||
NASM = nasm
|
NASM = nasm
|
||||||
|
PYTHON = python3
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.SUFFIXES: .bin .asm
|
.SUFFIXES: .bin .asm .ansi
|
||||||
|
|
||||||
all: ponydos.bin
|
all: ponydos.img
|
||||||
|
|
||||||
run: ponydos.bin
|
ponydos.img: ponydos.bin wallpaper.bin
|
||||||
qemu-system-i386 -fda ponydos.bin
|
rw -i /dev/zero -o $@ -c 1440K
|
||||||
|
rw -i ponydos.bin -o $@
|
||||||
|
rw -i wallpaper.bin -o $@ -O 512
|
||||||
|
|
||||||
.asm.bin:
|
.asm.bin:
|
||||||
$(NASM) -fbin -o $@ $<
|
$(NASM) -fbin -o $@ $<
|
||||||
|
|
||||||
|
.ansi.bin:
|
||||||
|
$(PYTHON) process_wallpaper.py $< $@ 7 0 0 0
|
||||||
|
|
||||||
|
run: ponydos.img
|
||||||
|
qemu-system-i386 -fda $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.bin
|
rm -f *.bin *.img
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
qemu-system
|
|
||||||
|
|
||||||
.PHONY: all run clean distclean
|
.PHONY: all run clean distclean
|
||||||
|
|
130
ponydos.asm
130
ponydos.asm
|
@ -6,6 +6,8 @@ org 0x7c00
|
||||||
COLUMNS equ 80
|
COLUMNS equ 80
|
||||||
ROWS equ 25
|
ROWS equ 25
|
||||||
|
|
||||||
|
WALLPAPER equ 0x500
|
||||||
|
|
||||||
jmp 0:start
|
jmp 0:start
|
||||||
start:
|
start:
|
||||||
cld
|
cld
|
||||||
|
@ -27,6 +29,8 @@ start:
|
||||||
xor al, al
|
xor al, al
|
||||||
rep stosb
|
rep stosb
|
||||||
|
|
||||||
|
mov [boot_disk], dl
|
||||||
|
|
||||||
initialize_mouse:
|
initialize_mouse:
|
||||||
; Initialize mouse
|
; Initialize mouse
|
||||||
; https://www.ctyme.com/intr/rb-1601.htm
|
; https://www.ctyme.com/intr/rb-1601.htm
|
||||||
|
@ -60,21 +64,26 @@ initialize_mouse:
|
||||||
|
|
||||||
.done:
|
.done:
|
||||||
|
|
||||||
initialize_screen:
|
load_wallpaper:
|
||||||
mov ax, 0xb800 ; VGA text video memory
|
|
||||||
mov es, ax
|
|
||||||
|
|
||||||
; Clear screen with asterisks and 15-0 background-foreground
|
; Clear screen with asterisks and 15-0 background-foreground
|
||||||
mov ax, 0xf000 + '*'
|
mov ax, 0xf000 + '*'
|
||||||
mov cx, 25*80
|
mov cx, 25*80
|
||||||
xor di, di
|
mov di, WALLPAPER
|
||||||
rep stosw
|
rep stosw
|
||||||
|
|
||||||
|
mov ax, 1
|
||||||
|
mov bl, [boot_disk]
|
||||||
|
mov cx, 8
|
||||||
|
mov di, WALLPAPER
|
||||||
|
call read_sectors
|
||||||
|
|
||||||
|
initialize_screen:
|
||||||
; Disable text cursor
|
; Disable text cursor
|
||||||
mov ah, 0x01
|
mov ah, 0x01
|
||||||
mov ch, 0x20
|
mov ch, 0x20
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
|
call draw_wallpaper
|
||||||
call flip_mouse_cursor
|
call flip_mouse_cursor
|
||||||
|
|
||||||
mainloop:
|
mainloop:
|
||||||
|
@ -98,6 +107,30 @@ mainloop:
|
||||||
call flip_mouse_cursor
|
call flip_mouse_cursor
|
||||||
jmp mainloop
|
jmp mainloop
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; Drawing subroutines
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
|
||||||
|
draw_wallpaper:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push es
|
||||||
|
|
||||||
|
mov bx, 0xb800
|
||||||
|
mov es, bx
|
||||||
|
|
||||||
|
mov si, WALLPAPER
|
||||||
|
xor di, di
|
||||||
|
mov cx, 80*25
|
||||||
|
rep movsw
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
flip_mouse_cursor:
|
flip_mouse_cursor:
|
||||||
push ax
|
push ax
|
||||||
push bx
|
push bx
|
||||||
|
@ -131,6 +164,75 @@ flip_mouse_cursor:
|
||||||
pop ax
|
pop ax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; Disk subroutines
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
|
||||||
|
; in:
|
||||||
|
; ax = LBA of first sector
|
||||||
|
; bl = drive number
|
||||||
|
; cx = number of sectors to read (must be at least 1)
|
||||||
|
; es:di = output buffer
|
||||||
|
read_sectors:
|
||||||
|
push ax
|
||||||
|
push cx
|
||||||
|
push di
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
call read_sector
|
||||||
|
inc ax
|
||||||
|
add di, 512
|
||||||
|
loop .loop
|
||||||
|
|
||||||
|
pop di
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; in:
|
||||||
|
; ax = LBA of first sector
|
||||||
|
; bl = drive number
|
||||||
|
; es:di = output buffer
|
||||||
|
read_sector:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
|
||||||
|
mov cx, 18
|
||||||
|
div cx
|
||||||
|
|
||||||
|
; cl = sector (1…18)
|
||||||
|
mov cl, dl
|
||||||
|
inc cl
|
||||||
|
|
||||||
|
; dh = head (0…1)
|
||||||
|
mov dh, 1
|
||||||
|
and dh, al
|
||||||
|
|
||||||
|
; ch = cylinder
|
||||||
|
shr ax, 1
|
||||||
|
mov ch, al
|
||||||
|
|
||||||
|
; dl = drive number
|
||||||
|
mov dl, bl
|
||||||
|
|
||||||
|
; es:bx = output buffer
|
||||||
|
mov bx, di
|
||||||
|
|
||||||
|
mov ax, 0x0201 ; read one sector
|
||||||
|
int 0x13
|
||||||
|
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; Mouse callback
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
|
||||||
Y_OVERFLOW equ 0x80
|
Y_OVERFLOW equ 0x80
|
||||||
X_OVERFLOW equ 0x40
|
X_OVERFLOW equ 0x40
|
||||||
Y_NEGATIVE equ 0x20
|
Y_NEGATIVE equ 0x20
|
||||||
|
@ -205,6 +307,10 @@ mouse_handler:
|
||||||
pop ax
|
pop ax
|
||||||
retf
|
retf
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; Debug routines
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
|
||||||
hexprint16:
|
hexprint16:
|
||||||
xchg ah, al
|
xchg ah, al
|
||||||
call hexprint8
|
call hexprint8
|
||||||
|
@ -234,10 +340,22 @@ hexprint4:
|
||||||
pop ax
|
pop ax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
hang:
|
||||||
|
hlt
|
||||||
|
jmp hang
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; Padding and boot sector signature
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
|
||||||
times 510-($-$$) db 0
|
times 510-($-$$) db 0
|
||||||
db 0x55
|
db 0x55
|
||||||
db 0xaa
|
db 0xaa
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; Zero-initialized variables
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
_bss_start:
|
_bss_start:
|
||||||
|
|
||||||
|
@ -248,4 +366,6 @@ mouse_buttons resb 1
|
||||||
mouse_column resb 1
|
mouse_column resb 1
|
||||||
mouse_row resw 1
|
mouse_row resw 1
|
||||||
|
|
||||||
|
boot_disk resb 1
|
||||||
|
|
||||||
_bss_end:
|
_bss_end:
|
||||||
|
|
82
process_wallpaper.py
Normal file
82
process_wallpaper.py
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
WIDTH = 80
|
||||||
|
HEIGHT = 25
|
||||||
|
# ANSI orders the colours black, red, green, yellow, blue, magenta, cyan, white
|
||||||
|
# VGA orders them black, blue, green, cyan, red, magenta, yellow, white
|
||||||
|
color_map = [0, 4, 2, 6, 1, 5, 3, 7]
|
||||||
|
|
||||||
|
if len(sys.argv) != 7:
|
||||||
|
print("Usage: {sys.argv[0]} infile outfile default_fgcolor default_bgcolor origin_x origin_y", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
infile = sys.argv[1]
|
||||||
|
outfile = sys.argv[2]
|
||||||
|
|
||||||
|
default_fgcolor = int(sys.argv[3])
|
||||||
|
assert 0 <= default_fgcolor <= 15
|
||||||
|
default_bgcolor = int(sys.argv[4])
|
||||||
|
assert 0 <= default_bgcolor <= 15
|
||||||
|
|
||||||
|
origin_x = int(sys.argv[5])
|
||||||
|
assert 0 <= origin_x < WIDTH
|
||||||
|
origin_y = int(sys.argv[6])
|
||||||
|
assert 0 <= origin_y < HEIGHT
|
||||||
|
|
||||||
|
chars = [bytearray([0]*HEIGHT) for _ in range(WIDTH)]
|
||||||
|
attributes = [[(default_fgcolor, default_bgcolor)]*HEIGHT for _ in range(WIDTH)]
|
||||||
|
|
||||||
|
with open(infile, 'rb') as f:
|
||||||
|
ansitext = f.read()
|
||||||
|
|
||||||
|
x = origin_x
|
||||||
|
y = origin_y
|
||||||
|
fgcolor = default_fgcolor
|
||||||
|
bgcolor = default_bgcolor
|
||||||
|
|
||||||
|
line = 1
|
||||||
|
line_start = 0
|
||||||
|
index = 0
|
||||||
|
while index < len(ansitext):
|
||||||
|
if ansitext[index:].startswith(b'\x1b['):
|
||||||
|
index += len(b'\x1b[')
|
||||||
|
escape_length = ansitext[index:].index(b'm')
|
||||||
|
escape = ansitext[index:index+escape_length]
|
||||||
|
for color_parameter in escape.split(b';'):
|
||||||
|
color_parameter = int(color_parameter)
|
||||||
|
if color_parameter == 39:
|
||||||
|
fgcolor = default_fgcolor
|
||||||
|
elif color_parameter == 49:
|
||||||
|
bgcolor = default_bgcolor
|
||||||
|
elif 30 <= color_parameter <= 37:
|
||||||
|
fgcolor = color_map[color_parameter - 30]
|
||||||
|
elif 40 <= color_parameter <= 47:
|
||||||
|
bgcolor = color_map[color_parameter - 40]
|
||||||
|
elif 90 <= color_parameter <= 97:
|
||||||
|
fgcolor = color_map[color_parameter - 90] + 8
|
||||||
|
elif 100 <= color_parameter <= 107:
|
||||||
|
bgcolor = color_map[color_parameter - 100] + 8
|
||||||
|
else:
|
||||||
|
print(f'{line},{index-line_start+1}: Unknown colour escape {color_parameter}')
|
||||||
|
index += escape_length + len(b'm')
|
||||||
|
elif ansitext[index] == 13:
|
||||||
|
x = origin_x
|
||||||
|
index += 1
|
||||||
|
elif ansitext[index] == 10:
|
||||||
|
x = origin_x
|
||||||
|
y += 1
|
||||||
|
index += 1
|
||||||
|
line += 1
|
||||||
|
line_start = index
|
||||||
|
else:
|
||||||
|
chars[x][y] = ansitext[index]
|
||||||
|
attributes[x][y] = (fgcolor, bgcolor)
|
||||||
|
index += 1
|
||||||
|
x += 1
|
||||||
|
|
||||||
|
with open(outfile, 'wb') as f:
|
||||||
|
for y in range(HEIGHT):
|
||||||
|
for x in range(WIDTH):
|
||||||
|
fgcolor, bgcolor = attributes[x][y]
|
||||||
|
char = chars[x][y]
|
||||||
|
f.write(bytes([char, (bgcolor<<4) | fgcolor]))
|
25
wallpaper.ansi
Normal file
25
wallpaper.ansi
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
ANSI art is my
|
||||||
|
[91mp[92ma[93ms[94ms[95mi[96mo[97mn
|
||||||
|
line 3
|
||||||
|
line 4
|
||||||
|
line 5
|
||||||
|
line 6
|
||||||
|
line 7
|
||||||
|
line 8
|
||||||
|
line 9
|
||||||
|
line 10
|
||||||
|
line 11
|
||||||
|
line 12
|
||||||
|
line 13
|
||||||
|
line 14
|
||||||
|
line 15
|
||||||
|
line 16
|
||||||
|
line 17
|
||||||
|
line 18
|
||||||
|
line 19
|
||||||
|
line 20
|
||||||
|
line 21
|
||||||
|
line 22
|
||||||
|
line 23
|
||||||
|
line 24
|
||||||
|
line 25
|
Loading…
Reference in a new issue