diff --git a/Makefile b/Makefile index c962b64..385fafb 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ NASM = nasm PYTHON = python3 QEMU = qemu-system-i386 +BUILDOPTS = + .SUFFIXES: .SUFFIXES: .bin .asm .ans .wall @@ -26,10 +28,10 @@ viewer.bin: ponydos.inc memory.bin: ponydos.inc .asm.bin: - $(NASM) -fbin -o $@ $< + $(NASM) -fbin $(BUILDOPTS) -o $@ $< .ans.wall: - $(PYTHON) process_wallpaper.py $@ $< 7 0 0 0 + env BUILDOPTS='$(BUILDOPTS)' $(PYTHON) process_wallpaper.py $@ $< 7 0 0 0 run: ponydos.img $(QEMU) -drive file=$<,index=0,if=floppy,format=raw diff --git a/README.md b/README.md index afa1537..af5e297 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,16 @@ run `make`. `make run` runs the floppy disk image `ponydos.img` with QEMU. By default, `qemu-system-i386` is invoked. If you want to use a different backend, use `make QEMU= run`. +### Build options + +You can configure the build using build options passed to the build system using +the `BUILDOPTS` variable, e.g. `make BUILDOPTS='-DBLINKY'`. It is advised to run +`make clean` before changing the value of `BUILDOPTS`. + +* `-DBLINKY` builds an image which restricts the number of colours to 8. This is + for compatibility with BIOSs which use the highest bit of background colour to + signal that a cell should blink. + ### How do I contribute? There is a model `hello.asm` file to demonstrate how best to use the @@ -70,3 +80,7 @@ You don't. At the moment, PonyDOS is only offered as a live floppy disk image with no installation option, for your safety. + +#### How do I stop my entire desktop from blinking? + +Build with the [build option](#build-options) `-DBLINKY`. diff --git a/hello.asm b/hello.asm index b7965b0..9f60c86 100644 --- a/hello.asm +++ b/hello.asm @@ -2,6 +2,14 @@ cpu 8086 bits 16 +%ifdef BLINKY +TITLEBAR_ATTRIBUTE equ 0x07 +WINDOW_ATTRIBUTE equ 0x70 +%else +TITLEBAR_ATTRIBUTE equ 0x0f +WINDOW_ATTRIBUTE equ 0xf0 +%endif + WINDOW_STATUS_NORMAL equ 0 WINDOW_STATUS_MOVE equ 1 WINDOW_STATUS_RESIZE equ 2 @@ -498,12 +506,12 @@ render_window: mov cx, [window_height] mul cx mov cx, ax - mov ax, 0xf000 ; Attribute is in the high byte + mov ax, WINDOW_ATTRIBUTE<<8 ; Attribute is in the high byte rep stosw ; Set title bar to be white-on-black mov di, window_data - mov ax, 0x0f00 + mov ax, TITLEBAR_ATTRIBUTE<<8 mov cx, [window_width] rep stosw diff --git a/memory.asm b/memory.asm index 3d03605..54c6de8 100644 --- a/memory.asm +++ b/memory.asm @@ -2,6 +2,14 @@ cpu 8086 bits 16 +%ifdef BLINKY +TITLEBAR_ATTRIBUTE equ 0x07 +WINDOW_ATTRIBUTE equ 0x70 +%else +TITLEBAR_ATTRIBUTE equ 0x0f +WINDOW_ATTRIBUTE equ 0xf0 +%endif + WINDOW_STATUS_NORMAL equ 0 WINDOW_STATUS_MOVE equ 1 @@ -572,9 +580,9 @@ window_status db WINDOW_STATUS_NORMAL window_move_x_offset dw 0 window_data: - db 'U', 0x0f, 's', 0x0f, 'a', 0x0f, 'g', 0x0f, 'e', 0x0f - times 10-5-1 db 0x00, 0x0f - db 'x', 0x0f - db '0', 0xf0, '1', 0xf0, '2', 0xf0, '3', 0xf0, '4', 0xf0, '5' - db 0xf0, '6', 0xf0, '7', 0xf0, '8', 0xf0, '9', 0xf0 - .indicators: times 10 db 0x00, 0xf0 + db 'U', TITLEBAR_ATTRIBUTE, 's', TITLEBAR_ATTRIBUTE, 'a', TITLEBAR_ATTRIBUTE, 'g', TITLEBAR_ATTRIBUTE, 'e', TITLEBAR_ATTRIBUTE + times 10-5-1 db 0x00, TITLEBAR_ATTRIBUTE + db 'x', TITLEBAR_ATTRIBUTE + db '0', WINDOW_ATTRIBUTE, '1', WINDOW_ATTRIBUTE, '2', WINDOW_ATTRIBUTE, '3', WINDOW_ATTRIBUTE, '4', WINDOW_ATTRIBUTE, '5' + db WINDOW_ATTRIBUTE, '6', WINDOW_ATTRIBUTE, '7', WINDOW_ATTRIBUTE, '8', WINDOW_ATTRIBUTE, '9', WINDOW_ATTRIBUTE + .indicators: times 10 db 0x00, WINDOW_ATTRIBUTE diff --git a/process_wallpaper.py b/process_wallpaper.py index f92ab47..dfc346c 100644 --- a/process_wallpaper.py +++ b/process_wallpaper.py @@ -1,3 +1,4 @@ +import os import sys from collections import namedtuple @@ -14,6 +15,15 @@ if len(sys.argv) != 7: print("Usage: {sys.argv[0]} outfile infile default_fgcolor default_bgcolor origin_x origin_y", file=sys.stderr) sys.exit(1) +blinky_vgamode = False +if 'BUILDOPTS' in os.environ: + for opt in os.environ['BUILDOPTS'].split(): + if opt == '-DBLINKY': + blinky_vgamode = True + else: + print(f"Error: Unrecognized build option {opt}", file=sys.stderr) + sys.exit(1) + outfile = sys.argv[1] infile = sys.argv[2] @@ -118,5 +128,14 @@ with open(outfile, 'wb') as f: for y in range(HEIGHT): for x in range(WIDTH): fgcolor, bgcolor, bold = attributes[x][y] + fgcolor = fgcolor | (8 if bold else 0) + if blinky_vgamode: + # VGA mode can be set up so that the highest + # bit of the bg colour marks that the cell + # should blink instead of intensity + # Restrict the colours (including foreground + # to account for swapping of the two) to 0…7 + fgcolor = fgcolor & 0x7 + bgcolor = bgcolor & 0x7 char = chars[x][y] - f.write(bytes([char, (bgcolor<<4) | fgcolor | (8 if bold else 0)])) + f.write(bytes([char, (bgcolor<<4) | fgcolor])) diff --git a/shell.asm b/shell.asm index dcacbb5..5ef1c6e 100644 --- a/shell.asm +++ b/shell.asm @@ -1,4 +1,16 @@ %include "ponydos.inc" +cpu 8086 +bits 16 + +%ifdef BLINKY +TITLEBAR_ATTRIBUTE equ 0x07 +WINDOW_ATTRIBUTE equ 0x70 +DISK_ATTRIBUTE equ 0x07 +%else +TITLEBAR_ATTRIBUTE equ 0x0f +WINDOW_ATTRIBUTE equ 0xf0 +DISK_ATTRIBUTE equ 0x0f +%endif struc window .next resw 1 @@ -637,7 +649,7 @@ launch: show_launch_error: mov di, launch_error_dialog.filename mov cx, FS_DIRENT_NAME_SIZE-1 - mov ah, 0xf0 + mov ah, WINDOW_ATTRIBUTE .copy: lodsb test al, al @@ -937,11 +949,11 @@ render_file_window: mov es, ax mov di, [si + window.data] mov cx, [si + window.width] - mov ax, 0x0f00 + mov ax, TITLEBAR_ATTRIBUTE<<8 rep stosw mov cx, (ROWS-1)*COLUMNS - mov ax, 0xf000 + mov ax, WINDOW_ATTRIBUTE<<8 rep stosw mov di, [si + window.data] @@ -1225,28 +1237,28 @@ viewer_file_name db 'viewer.bin', 0 ; ------------------------------------------------------------------ disk_icon: - db 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f - db 0x00, 0x0f, 0x00, 0x0f, 0x09, 0x0f, 0x00, 0x0f, 0x00, 0x0f - db 0x00, 0x0f, 0x00, 0x0f, '|', 0x0f, 0x00, 0x0f, 0x00, 0x0f + db 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE + db 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x09, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE + db 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, '|', DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE oom_error_dialog: - db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f - times 13-5-1 db 0x00, 0x0f - db 'x', 0x0f - db 'O', 0xf0, 'u', 0xf0, 't', 0xf0, ' ', 0xf0, 'o', 0xf0, 'f', 0xf0 - db ' ', 0xf0, 'm', 0xf0, 'e', 0xf0, 'm', 0xf0, 'o', 0xf0, 'r', 0xf0 - db 'y', 0xf0 + db 'E', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'o', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE + times 13-5-1 db 0x00, TITLEBAR_ATTRIBUTE + db 'x', TITLEBAR_ATTRIBUTE + db 'O', WINDOW_ATTRIBUTE, 'u', WINDOW_ATTRIBUTE, 't', WINDOW_ATTRIBUTE, ' ', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 'f', WINDOW_ATTRIBUTE + db ' ', WINDOW_ATTRIBUTE, 'm', WINDOW_ATTRIBUTE, 'e', WINDOW_ATTRIBUTE, 'm', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 'r', WINDOW_ATTRIBUTE + db 'y', WINDOW_ATTRIBUTE launch_error_dialog: - db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f - times FS_DIRENT_NAME_SIZE-1-5-1 db 0x00, 0x0f - db 'x', 0x0f - db 'C', 0xf0, 'a', 0xf0, 'n', 0xf0, 'n', 0xf0, 'o', 0xf0, 't', 0xf0 - db ' ', 0xf0, 'l', 0xf0, 'a', 0xf0, 'u', 0xf0, 'n', 0xf0, 'c', 0xf0 - db 'h', 0xf0, ' ', 0xf0, 'f', 0xf0, 'i', 0xf0, 'l', 0xf0, 'e', 0xf0 - db ':', 0xf0 - times FS_DIRENT_NAME_SIZE-1-19 db 0x00, 0xf0 - .filename times FS_DIRENT_NAME_SIZE-1 db 0x00, 0xf0 + db 'E', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'o', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE + times FS_DIRENT_NAME_SIZE-1-5-1 db 0x00, TITLEBAR_ATTRIBUTE + db 'x', TITLEBAR_ATTRIBUTE + db 'C', WINDOW_ATTRIBUTE, 'a', WINDOW_ATTRIBUTE, 'n', WINDOW_ATTRIBUTE, 'n', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 't', WINDOW_ATTRIBUTE + db ' ', WINDOW_ATTRIBUTE, 'l', WINDOW_ATTRIBUTE, 'a', WINDOW_ATTRIBUTE, 'u', WINDOW_ATTRIBUTE, 'n', WINDOW_ATTRIBUTE, 'c', WINDOW_ATTRIBUTE + db 'h', WINDOW_ATTRIBUTE, ' ', WINDOW_ATTRIBUTE, 'f', WINDOW_ATTRIBUTE, 'i', WINDOW_ATTRIBUTE, 'l', WINDOW_ATTRIBUTE, 'e', WINDOW_ATTRIBUTE + db ':', WINDOW_ATTRIBUTE + times FS_DIRENT_NAME_SIZE-1-19 db 0x00, WINDOW_ATTRIBUTE + .filename times FS_DIRENT_NAME_SIZE-1 db 0x00, WINDOW_ATTRIBUTE windows: times window.size db 0 diff --git a/viewer.asm b/viewer.asm index acfa540..bb8041c 100644 --- a/viewer.asm +++ b/viewer.asm @@ -2,6 +2,19 @@ cpu 8086 bits 16 +%ifdef BLINKY +TITLEBAR_ATTRIBUTE equ 0x07 +WINDOW_ATTRIBUTE equ 0x70 +CANCEL_ATTRIBUTE equ 0x07 +%else +TITLEBAR_ATTRIBUTE equ 0x0f +WINDOW_ATTRIBUTE equ 0xf0 +CANCEL_ATTRIBUTE equ 0x8f +%endif +OK_ATTRIBUTE equ 0x20 +OPEN_DIALOG_ATTRIBUTE equ 0x70 +FILENAME_ATTRIBUTE equ WINDOW_ATTRIBUTE + WINDOW_STATUS_NORMAL equ 0 WINDOW_STATUS_MOVE equ 1 WINDOW_STATUS_RESIZE equ 2 @@ -591,14 +604,14 @@ event_click: mov bx, ax inc bx - cmp byte [bx], CANCEL_COLOR + cmp byte [bx], CANCEL_ATTRIBUTE jne .not_cancel .cancel: call unhook_self_from_window_chain mov byte [exiting], 1 jmp .end .not_cancel: - cmp byte [bx], OK_COLOR + cmp byte [bx], OK_ATTRIBUTE jne .not_ok .ok: call filename_ok @@ -921,12 +934,12 @@ render_window: mov cx, [window.height] mul cx mov cx, ax - mov ax, 0xf000 ; Attribute is in the high byte + mov ax, WINDOW_ATTRIBUTE<<8 ; Attribute is in the high byte rep stosw ; Set title bar to be white-on-black mov di, text_window_data - mov ax, 0x0f00 + mov ax, TITLEBAR_ATTRIBUTE<<8 mov cx, [window.width] rep stosw @@ -1233,46 +1246,44 @@ cur_filename_address dw filename_window_data.filename file_opened db 0 ; pre-built windows -CANCEL_COLOR equ 0x8f -OK_COLOR equ 0x20 filename_window_data: ; header - db 'V', 0x0f, 'i', 0x0f, 'e', 0x0f, 'w', 0x0f, 'e', 0x0f, 'r', 0x0f - times FS_DIRENT_NAME_SIZE + 2 - 7 db 0, 0x0f - db 'x', 0x0f + db 'V', TITLEBAR_ATTRIBUTE, 'i', TITLEBAR_ATTRIBUTE, 'e', TITLEBAR_ATTRIBUTE, 'w', TITLEBAR_ATTRIBUTE, 'e', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE + times FS_DIRENT_NAME_SIZE + 2 - 7 db 0, TITLEBAR_ATTRIBUTE + db 'x', TITLEBAR_ATTRIBUTE ; blank line - times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70 + times FS_DIRENT_NAME_SIZE + 2 db 0, OPEN_DIALOG_ATTRIBUTE ; filename - db 0, 0x70 + db 0, OPEN_DIALOG_ATTRIBUTE .filename: - times FS_DIRENT_NAME_SIZE db 0, 0xf0 - db 0, 0x70 + times FS_DIRENT_NAME_SIZE db 0, FILENAME_ATTRIBUTE + db 0, OPEN_DIALOG_ATTRIBUTE ; blank line - times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70 + times FS_DIRENT_NAME_SIZE + 2 db 0, OPEN_DIALOG_ATTRIBUTE ; buttons line - times 7 db 0, 0x70 - db 0, 0x8f, 'C', 0x8f, 'a', 0x8f, 'n', 0x8f, 'c', 0x8f, 'e', 0x8f, 'l', 0x8f, 0, 0x8f - times 5 db 0, 0x70 - db 0, 0x20, 'O', 0x20, 'K', 0x20, 0x, 0x20 - times 8 db 0, 0x70 + times 7 db 0, OPEN_DIALOG_ATTRIBUTE + db 0, CANCEL_ATTRIBUTE, 'C', CANCEL_ATTRIBUTE, 'a', CANCEL_ATTRIBUTE, 'n', CANCEL_ATTRIBUTE, 'c', CANCEL_ATTRIBUTE, 'e', CANCEL_ATTRIBUTE, 'l', CANCEL_ATTRIBUTE, 0, CANCEL_ATTRIBUTE + times 5 db 0, OPEN_DIALOG_ATTRIBUTE + db 0, OK_ATTRIBUTE, 'O', OK_ATTRIBUTE, 'K', OK_ATTRIBUTE, 0x, OK_ATTRIBUTE + times 8 db 0, OPEN_DIALOG_ATTRIBUTE ; blank line - times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70 + times FS_DIRENT_NAME_SIZE + 2 db 0, OPEN_DIALOG_ATTRIBUTE oom_window_data: - db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f - times 13-5-1 db 0x00, 0x0f - db 'x', 0x0f - db 'O', 0xf0, 'u', 0xf0, 't', 0xf0, ' ', 0xf0, 'o', 0xf0, 'f', 0xf0 - db ' ', 0xf0, 'm', 0xf0, 'e', 0xf0, 'm', 0xf0, 'o', 0xf0, 'r', 0xf0 - db 'y', 0xf0 + db 'E', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'o', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE + times 13-5-1 db 0x00, TITLEBAR_ATTRIBUTE + db 'x', TITLEBAR_ATTRIBUTE + db 'O', WINDOW_ATTRIBUTE, 'u', WINDOW_ATTRIBUTE, 't', WINDOW_ATTRIBUTE, ' ', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 'f', WINDOW_ATTRIBUTE + db ' ', WINDOW_ATTRIBUTE, 'm', WINDOW_ATTRIBUTE, 'e', WINDOW_ATTRIBUTE, 'm', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 'r', WINDOW_ATTRIBUTE + db 'y', WINDOW_ATTRIBUTE ood_window_data: - db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f - times 17-5-1 db 0x00, 0x0f - db 'x', 0x0f - db 'O', 0xf0, 'u', 0xf0, 't', 0xf0, ' ', 0xf0, 'o', 0xf0, 'f', 0xf0 - db ' ', 0xf0, 'd', 0xf0, 'i', 0xf0, 's', 0xf0, 'k', 0xf0, ' ', 0xf0 - db 's', 0xf0, 'p', 0xf0, 'a', 0xf0, 'c', 0xf0, 'e', 0xf0 + db 'E', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'o', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE + times 17-5-1 db 0x00, TITLEBAR_ATTRIBUTE + db 'x', TITLEBAR_ATTRIBUTE + db 'O', WINDOW_ATTRIBUTE, 'u', WINDOW_ATTRIBUTE, 't', WINDOW_ATTRIBUTE, ' ', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 'f', WINDOW_ATTRIBUTE + db ' ', WINDOW_ATTRIBUTE, 'd', WINDOW_ATTRIBUTE, 'i', WINDOW_ATTRIBUTE, 's', WINDOW_ATTRIBUTE, 'k', WINDOW_ATTRIBUTE, ' ', WINDOW_ATTRIBUTE + db 's', WINDOW_ATTRIBUTE, 'p', WINDOW_ATTRIBUTE, 'a', WINDOW_ATTRIBUTE, 'c', WINDOW_ATTRIBUTE, 'e', WINDOW_ATTRIBUTE section .bss text_window_data resw ROWS*COLUMNS