Compare commits

...

1 Commits
v1.0 ... master

Author SHA1 Message Date
Juhani Krekelä d4c15687c8 Add option for 8-colour mode
Some BIOSs initialize the VGA card by default into a mode where the high
bit of background nybble signals that the cell should blink. The simple
way to avoid this is by restricting the background colours to the range
0…7. However, since our mouse cursor is implemented by swapping the
foreground and the background colours, we also need to restrict the
foreground colours to the range 0…7.
2023-05-11 22:02:18 +03:00
7 changed files with 138 additions and 64 deletions

View File

@ -2,6 +2,8 @@ NASM = nasm
PYTHON = python3 PYTHON = python3
QEMU = qemu-system-i386 QEMU = qemu-system-i386
BUILDOPTS =
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .bin .asm .ans .wall .SUFFIXES: .bin .asm .ans .wall
@ -26,10 +28,10 @@ viewer.bin: ponydos.inc
memory.bin: ponydos.inc memory.bin: ponydos.inc
.asm.bin: .asm.bin:
$(NASM) -fbin -o $@ $< $(NASM) -fbin $(BUILDOPTS) -o $@ $<
.ans.wall: .ans.wall:
$(PYTHON) process_wallpaper.py $@ $< 7 0 0 0 env BUILDOPTS='$(BUILDOPTS)' $(PYTHON) process_wallpaper.py $@ $< 7 0 0 0
run: ponydos.img run: ponydos.img
$(QEMU) -drive file=$<,index=0,if=floppy,format=raw $(QEMU) -drive file=$<,index=0,if=floppy,format=raw

View File

@ -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 By default, `qemu-system-i386` is invoked. If you want to use a different
backend, use `make QEMU=<backend> run`. backend, use `make QEMU=<backend> 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? ### How do I contribute?
There is a model `hello.asm` file to demonstrate how best to use the 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 At the moment, PonyDOS is only offered as a live floppy disk image with no
installation option, for your safety. installation option, for your safety.
#### How do I stop my entire desktop from blinking?
Build with the [build option](#build-options) `-DBLINKY`.

View File

@ -2,6 +2,14 @@
cpu 8086 cpu 8086
bits 16 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_NORMAL equ 0
WINDOW_STATUS_MOVE equ 1 WINDOW_STATUS_MOVE equ 1
WINDOW_STATUS_RESIZE equ 2 WINDOW_STATUS_RESIZE equ 2
@ -498,12 +506,12 @@ render_window:
mov cx, [window_height] mov cx, [window_height]
mul cx mul cx
mov cx, ax 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 rep stosw
; Set title bar to be white-on-black ; Set title bar to be white-on-black
mov di, window_data mov di, window_data
mov ax, 0x0f00 mov ax, TITLEBAR_ATTRIBUTE<<8
mov cx, [window_width] mov cx, [window_width]
rep stosw rep stosw

View File

@ -2,6 +2,14 @@
cpu 8086 cpu 8086
bits 16 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_NORMAL equ 0
WINDOW_STATUS_MOVE equ 1 WINDOW_STATUS_MOVE equ 1
@ -572,9 +580,9 @@ window_status db WINDOW_STATUS_NORMAL
window_move_x_offset dw 0 window_move_x_offset dw 0
window_data: window_data:
db 'U', 0x0f, 's', 0x0f, 'a', 0x0f, 'g', 0x0f, 'e', 0x0f db 'U', TITLEBAR_ATTRIBUTE, 's', TITLEBAR_ATTRIBUTE, 'a', TITLEBAR_ATTRIBUTE, 'g', TITLEBAR_ATTRIBUTE, 'e', TITLEBAR_ATTRIBUTE
times 10-5-1 db 0x00, 0x0f times 10-5-1 db 0x00, TITLEBAR_ATTRIBUTE
db 'x', 0x0f db 'x', TITLEBAR_ATTRIBUTE
db '0', 0xf0, '1', 0xf0, '2', 0xf0, '3', 0xf0, '4', 0xf0, '5' db '0', WINDOW_ATTRIBUTE, '1', WINDOW_ATTRIBUTE, '2', WINDOW_ATTRIBUTE, '3', WINDOW_ATTRIBUTE, '4', WINDOW_ATTRIBUTE, '5'
db 0xf0, '6', 0xf0, '7', 0xf0, '8', 0xf0, '9', 0xf0 db WINDOW_ATTRIBUTE, '6', WINDOW_ATTRIBUTE, '7', WINDOW_ATTRIBUTE, '8', WINDOW_ATTRIBUTE, '9', WINDOW_ATTRIBUTE
.indicators: times 10 db 0x00, 0xf0 .indicators: times 10 db 0x00, WINDOW_ATTRIBUTE

View File

@ -1,3 +1,4 @@
import os
import sys import sys
from collections import namedtuple 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) print("Usage: {sys.argv[0]} outfile infile default_fgcolor default_bgcolor origin_x origin_y", file=sys.stderr)
sys.exit(1) 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] outfile = sys.argv[1]
infile = sys.argv[2] infile = sys.argv[2]
@ -118,5 +128,14 @@ with open(outfile, 'wb') as f:
for y in range(HEIGHT): for y in range(HEIGHT):
for x in range(WIDTH): for x in range(WIDTH):
fgcolor, bgcolor, bold = attributes[x][y] 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] char = chars[x][y]
f.write(bytes([char, (bgcolor<<4) | fgcolor | (8 if bold else 0)])) f.write(bytes([char, (bgcolor<<4) | fgcolor]))

View File

@ -1,4 +1,16 @@
%include "ponydos.inc" %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 struc window
.next resw 1 .next resw 1
@ -637,7 +649,7 @@ launch:
show_launch_error: show_launch_error:
mov di, launch_error_dialog.filename mov di, launch_error_dialog.filename
mov cx, FS_DIRENT_NAME_SIZE-1 mov cx, FS_DIRENT_NAME_SIZE-1
mov ah, 0xf0 mov ah, WINDOW_ATTRIBUTE
.copy: .copy:
lodsb lodsb
test al, al test al, al
@ -937,11 +949,11 @@ render_file_window:
mov es, ax mov es, ax
mov di, [si + window.data] mov di, [si + window.data]
mov cx, [si + window.width] mov cx, [si + window.width]
mov ax, 0x0f00 mov ax, TITLEBAR_ATTRIBUTE<<8
rep stosw rep stosw
mov cx, (ROWS-1)*COLUMNS mov cx, (ROWS-1)*COLUMNS
mov ax, 0xf000 mov ax, WINDOW_ATTRIBUTE<<8
rep stosw rep stosw
mov di, [si + window.data] mov di, [si + window.data]
@ -1225,28 +1237,28 @@ viewer_file_name db 'viewer.bin', 0
; ------------------------------------------------------------------ ; ------------------------------------------------------------------
disk_icon: disk_icon:
db 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f db 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE
db 0x00, 0x0f, 0x00, 0x0f, 0x09, 0x0f, 0x00, 0x0f, 0x00, 0x0f db 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x09, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE
db 0x00, 0x0f, 0x00, 0x0f, '|', 0x0f, 0x00, 0x0f, 0x00, 0x0f db 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, '|', DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE, 0x00, DISK_ATTRIBUTE
oom_error_dialog: oom_error_dialog:
db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f db 'E', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'o', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE
times 13-5-1 db 0x00, 0x0f times 13-5-1 db 0x00, TITLEBAR_ATTRIBUTE
db 'x', 0x0f db 'x', TITLEBAR_ATTRIBUTE
db 'O', 0xf0, 'u', 0xf0, 't', 0xf0, ' ', 0xf0, 'o', 0xf0, 'f', 0xf0 db 'O', WINDOW_ATTRIBUTE, 'u', WINDOW_ATTRIBUTE, 't', WINDOW_ATTRIBUTE, ' ', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 'f', WINDOW_ATTRIBUTE
db ' ', 0xf0, 'm', 0xf0, 'e', 0xf0, 'm', 0xf0, 'o', 0xf0, 'r', 0xf0 db ' ', WINDOW_ATTRIBUTE, 'm', WINDOW_ATTRIBUTE, 'e', WINDOW_ATTRIBUTE, 'm', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 'r', WINDOW_ATTRIBUTE
db 'y', 0xf0 db 'y', WINDOW_ATTRIBUTE
launch_error_dialog: launch_error_dialog:
db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f 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, 0x0f times FS_DIRENT_NAME_SIZE-1-5-1 db 0x00, TITLEBAR_ATTRIBUTE
db 'x', 0x0f db 'x', TITLEBAR_ATTRIBUTE
db 'C', 0xf0, 'a', 0xf0, 'n', 0xf0, 'n', 0xf0, 'o', 0xf0, 't', 0xf0 db 'C', WINDOW_ATTRIBUTE, 'a', WINDOW_ATTRIBUTE, 'n', WINDOW_ATTRIBUTE, 'n', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 't', WINDOW_ATTRIBUTE
db ' ', 0xf0, 'l', 0xf0, 'a', 0xf0, 'u', 0xf0, 'n', 0xf0, 'c', 0xf0 db ' ', WINDOW_ATTRIBUTE, 'l', WINDOW_ATTRIBUTE, 'a', WINDOW_ATTRIBUTE, 'u', WINDOW_ATTRIBUTE, 'n', WINDOW_ATTRIBUTE, 'c', WINDOW_ATTRIBUTE
db 'h', 0xf0, ' ', 0xf0, 'f', 0xf0, 'i', 0xf0, 'l', 0xf0, 'e', 0xf0 db 'h', WINDOW_ATTRIBUTE, ' ', WINDOW_ATTRIBUTE, 'f', WINDOW_ATTRIBUTE, 'i', WINDOW_ATTRIBUTE, 'l', WINDOW_ATTRIBUTE, 'e', WINDOW_ATTRIBUTE
db ':', 0xf0 db ':', WINDOW_ATTRIBUTE
times FS_DIRENT_NAME_SIZE-1-19 db 0x00, 0xf0 times FS_DIRENT_NAME_SIZE-1-19 db 0x00, WINDOW_ATTRIBUTE
.filename times FS_DIRENT_NAME_SIZE-1 db 0x00, 0xf0 .filename times FS_DIRENT_NAME_SIZE-1 db 0x00, WINDOW_ATTRIBUTE
windows: windows:
times window.size db 0 times window.size db 0

View File

@ -2,6 +2,19 @@
cpu 8086 cpu 8086
bits 16 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_NORMAL equ 0
WINDOW_STATUS_MOVE equ 1 WINDOW_STATUS_MOVE equ 1
WINDOW_STATUS_RESIZE equ 2 WINDOW_STATUS_RESIZE equ 2
@ -591,14 +604,14 @@ event_click:
mov bx, ax mov bx, ax
inc bx inc bx
cmp byte [bx], CANCEL_COLOR cmp byte [bx], CANCEL_ATTRIBUTE
jne .not_cancel jne .not_cancel
.cancel: .cancel:
call unhook_self_from_window_chain call unhook_self_from_window_chain
mov byte [exiting], 1 mov byte [exiting], 1
jmp .end jmp .end
.not_cancel: .not_cancel:
cmp byte [bx], OK_COLOR cmp byte [bx], OK_ATTRIBUTE
jne .not_ok jne .not_ok
.ok: .ok:
call filename_ok call filename_ok
@ -921,12 +934,12 @@ render_window:
mov cx, [window.height] mov cx, [window.height]
mul cx mul cx
mov cx, ax 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 rep stosw
; Set title bar to be white-on-black ; Set title bar to be white-on-black
mov di, text_window_data mov di, text_window_data
mov ax, 0x0f00 mov ax, TITLEBAR_ATTRIBUTE<<8
mov cx, [window.width] mov cx, [window.width]
rep stosw rep stosw
@ -1233,46 +1246,44 @@ cur_filename_address dw filename_window_data.filename
file_opened db 0 file_opened db 0
; pre-built windows ; pre-built windows
CANCEL_COLOR equ 0x8f
OK_COLOR equ 0x20
filename_window_data: filename_window_data:
; header ; header
db 'V', 0x0f, 'i', 0x0f, 'e', 0x0f, 'w', 0x0f, 'e', 0x0f, 'r', 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, 0x0f times FS_DIRENT_NAME_SIZE + 2 - 7 db 0, TITLEBAR_ATTRIBUTE
db 'x', 0x0f db 'x', TITLEBAR_ATTRIBUTE
; blank line ; blank line
times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70 times FS_DIRENT_NAME_SIZE + 2 db 0, OPEN_DIALOG_ATTRIBUTE
; filename ; filename
db 0, 0x70 db 0, OPEN_DIALOG_ATTRIBUTE
.filename: .filename:
times FS_DIRENT_NAME_SIZE db 0, 0xf0 times FS_DIRENT_NAME_SIZE db 0, FILENAME_ATTRIBUTE
db 0, 0x70 db 0, OPEN_DIALOG_ATTRIBUTE
; blank line ; blank line
times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70 times FS_DIRENT_NAME_SIZE + 2 db 0, OPEN_DIALOG_ATTRIBUTE
; buttons line ; buttons line
times 7 db 0, 0x70 times 7 db 0, OPEN_DIALOG_ATTRIBUTE
db 0, 0x8f, 'C', 0x8f, 'a', 0x8f, 'n', 0x8f, 'c', 0x8f, 'e', 0x8f, 'l', 0x8f, 0, 0x8f 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, 0x70 times 5 db 0, OPEN_DIALOG_ATTRIBUTE
db 0, 0x20, 'O', 0x20, 'K', 0x20, 0x, 0x20 db 0, OK_ATTRIBUTE, 'O', OK_ATTRIBUTE, 'K', OK_ATTRIBUTE, 0x, OK_ATTRIBUTE
times 8 db 0, 0x70 times 8 db 0, OPEN_DIALOG_ATTRIBUTE
; blank line ; 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: oom_window_data:
db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f db 'E', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'o', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE
times 13-5-1 db 0x00, 0x0f times 13-5-1 db 0x00, TITLEBAR_ATTRIBUTE
db 'x', 0x0f db 'x', TITLEBAR_ATTRIBUTE
db 'O', 0xf0, 'u', 0xf0, 't', 0xf0, ' ', 0xf0, 'o', 0xf0, 'f', 0xf0 db 'O', WINDOW_ATTRIBUTE, 'u', WINDOW_ATTRIBUTE, 't', WINDOW_ATTRIBUTE, ' ', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 'f', WINDOW_ATTRIBUTE
db ' ', 0xf0, 'm', 0xf0, 'e', 0xf0, 'm', 0xf0, 'o', 0xf0, 'r', 0xf0 db ' ', WINDOW_ATTRIBUTE, 'm', WINDOW_ATTRIBUTE, 'e', WINDOW_ATTRIBUTE, 'm', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 'r', WINDOW_ATTRIBUTE
db 'y', 0xf0 db 'y', WINDOW_ATTRIBUTE
ood_window_data: ood_window_data:
db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f db 'E', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE, 'o', TITLEBAR_ATTRIBUTE, 'r', TITLEBAR_ATTRIBUTE
times 17-5-1 db 0x00, 0x0f times 17-5-1 db 0x00, TITLEBAR_ATTRIBUTE
db 'x', 0x0f db 'x', TITLEBAR_ATTRIBUTE
db 'O', 0xf0, 'u', 0xf0, 't', 0xf0, ' ', 0xf0, 'o', 0xf0, 'f', 0xf0 db 'O', WINDOW_ATTRIBUTE, 'u', WINDOW_ATTRIBUTE, 't', WINDOW_ATTRIBUTE, ' ', WINDOW_ATTRIBUTE, 'o', WINDOW_ATTRIBUTE, 'f', WINDOW_ATTRIBUTE
db ' ', 0xf0, 'd', 0xf0, 'i', 0xf0, 's', 0xf0, 'k', 0xf0, ' ', 0xf0 db ' ', WINDOW_ATTRIBUTE, 'd', WINDOW_ATTRIBUTE, 'i', WINDOW_ATTRIBUTE, 's', WINDOW_ATTRIBUTE, 'k', WINDOW_ATTRIBUTE, ' ', WINDOW_ATTRIBUTE
db 's', 0xf0, 'p', 0xf0, 'a', 0xf0, 'c', 0xf0, 'e', 0xf0 db 's', WINDOW_ATTRIBUTE, 'p', WINDOW_ATTRIBUTE, 'a', WINDOW_ATTRIBUTE, 'c', WINDOW_ATTRIBUTE, 'e', WINDOW_ATTRIBUTE
section .bss section .bss
text_window_data resw ROWS*COLUMNS text_window_data resw ROWS*COLUMNS