Allow launching programs from the shell
This commit is contained in:
parent
ebf106dcc4
commit
6ebb889fcf
5 changed files with 208 additions and 13 deletions
4
Makefile
4
Makefile
|
@ -6,7 +6,7 @@ PYTHON = python3
|
||||||
|
|
||||||
all: ponydos.img
|
all: ponydos.img
|
||||||
|
|
||||||
FS_FILES = ponydos.wall passion.wall shell.bin
|
FS_FILES = ponydos.wall passion.wall shell.bin hello.bin
|
||||||
|
|
||||||
ponydos.img: ponydos.bin $(FS_FILES)
|
ponydos.img: ponydos.bin $(FS_FILES)
|
||||||
$(PYTHON) assemble_floppy.py $@ ponydos.bin $(FS_FILES)
|
$(PYTHON) assemble_floppy.py $@ ponydos.bin $(FS_FILES)
|
||||||
|
@ -18,6 +18,8 @@ ponydos.bin: ponydos_static.inc
|
||||||
|
|
||||||
shell.bin: ponydos.inc
|
shell.bin: ponydos.inc
|
||||||
|
|
||||||
|
hello.bin: ponydos.inc
|
||||||
|
|
||||||
.asm.bin:
|
.asm.bin:
|
||||||
$(NASM) -fbin -o $@ $<
|
$(NASM) -fbin -o $@ $<
|
||||||
|
|
||||||
|
|
39
hello.asm
Normal file
39
hello.asm
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
%include "ponydos.inc"
|
||||||
|
cpu 8086
|
||||||
|
bits 16
|
||||||
|
|
||||||
|
; 0x0000
|
||||||
|
jmp near process_event
|
||||||
|
|
||||||
|
; 0x0003 PROC_INITIALIZE_ENTRYPOINT
|
||||||
|
; This needs to preserve ds
|
||||||
|
initialize:
|
||||||
|
push ds
|
||||||
|
|
||||||
|
call deallocate_own_memory
|
||||||
|
|
||||||
|
pop ds
|
||||||
|
retf
|
||||||
|
|
||||||
|
process_event:
|
||||||
|
retf
|
||||||
|
|
||||||
|
deallocate_own_memory:
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push es
|
||||||
|
|
||||||
|
mov bx, PONYDOS_SEG
|
||||||
|
mov es, bx
|
||||||
|
|
||||||
|
; Segment 0xn000 corresponds to slot n in the allocation table
|
||||||
|
mov bx, cs
|
||||||
|
mov cl, 12
|
||||||
|
shr bx, cl
|
||||||
|
|
||||||
|
mov byte [es:GLOBAL_MEMORY_ALLOCATION_MAP + bx], 0
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
ret
|
|
@ -72,7 +72,7 @@ load_shell:
|
||||||
call 0:modify_sectors
|
call 0:modify_sectors
|
||||||
; TODO: error management? Surely this works...
|
; TODO: error management? Surely this works...
|
||||||
|
|
||||||
call 0x1000:3
|
call 0x1000:PROC_INITIALIZE_ENTRYPOINT
|
||||||
|
|
||||||
initialize_screen:
|
initialize_screen:
|
||||||
; Disable text cursor
|
; Disable text cursor
|
||||||
|
|
|
@ -4,6 +4,7 @@ GLOBAL_WALLPAPER equ 0x500
|
||||||
GLOBAL_DIRENTS equ 0x2000
|
GLOBAL_DIRENTS equ 0x2000
|
||||||
|
|
||||||
FS_DIRENT_SIZE equ 32
|
FS_DIRENT_SIZE equ 32
|
||||||
|
FS_DIRENT_NAME_SIZE equ 30
|
||||||
FS_FILE_MAX_SIZE equ 128
|
FS_FILE_MAX_SIZE equ 128
|
||||||
|
|
||||||
WM_PAINT equ 0
|
WM_PAINT equ 0
|
||||||
|
@ -13,3 +14,7 @@ WM_UNHOOK equ 3
|
||||||
|
|
||||||
MOUSE_PRIMARY equ 0x01
|
MOUSE_PRIMARY equ 0x01
|
||||||
MOUSE_SECONDARY equ 0x02
|
MOUSE_SECONDARY equ 0x02
|
||||||
|
|
||||||
|
MEM_ALLOCATION_MAP_SIZE equ 10
|
||||||
|
|
||||||
|
PROC_INITIALIZE_ENTRYPOINT equ 3
|
||||||
|
|
171
shell.asm
171
shell.asm
|
@ -27,13 +27,26 @@ initialize:
|
||||||
push cs
|
push cs
|
||||||
pop ds
|
pop ds
|
||||||
|
|
||||||
|
; Has shell been started already?
|
||||||
|
mov bp, PONYDOS_SEG
|
||||||
|
mov es, bp
|
||||||
|
cmp word [es:GLOBAL_WINDOW_CHAIN_HEAD], 0
|
||||||
|
je .not_relaunch
|
||||||
|
.relaunch:
|
||||||
|
; TODO: Display an alert if trying to re-run shell
|
||||||
|
; Clean up memory when exiting
|
||||||
|
mov bx, cs
|
||||||
|
mov cl, 12
|
||||||
|
shr bx, cl
|
||||||
|
mov byte [es:GLOBAL_MEMORY_ALLOCATION_MAP + bx], 0
|
||||||
|
jmp .end
|
||||||
|
.not_relaunch:
|
||||||
|
|
||||||
; Set wallpaper
|
; Set wallpaper
|
||||||
mov si, wallpaper_name
|
mov si, wallpaper_name
|
||||||
xor dx, dx
|
xor dx, dx
|
||||||
call PONYDOS_SEG:SYS_OPEN_FILE
|
call PONYDOS_SEG:SYS_OPEN_FILE
|
||||||
|
|
||||||
mov bp, PONYDOS_SEG
|
|
||||||
mov es, bp
|
|
||||||
mov bx, GLOBAL_WALLPAPER
|
mov bx, GLOBAL_WALLPAPER
|
||||||
xor di, di ; read
|
xor di, di ; read
|
||||||
call PONYDOS_SEG:SYS_MODIFY_SECTORS
|
call PONYDOS_SEG:SYS_MODIFY_SECTORS
|
||||||
|
@ -62,6 +75,7 @@ initialize:
|
||||||
|
|
||||||
call request_redraw
|
call request_redraw
|
||||||
|
|
||||||
|
.end:
|
||||||
pop ds
|
pop ds
|
||||||
retf
|
retf
|
||||||
|
|
||||||
|
@ -117,7 +131,7 @@ process_event:
|
||||||
; al = WM_PAINT
|
; al = WM_PAINT
|
||||||
; bx = window ID
|
; bx = window ID
|
||||||
; out:
|
; out:
|
||||||
; trashes everything
|
; clobbers everything
|
||||||
paint:
|
paint:
|
||||||
call get_window
|
call get_window
|
||||||
|
|
||||||
|
@ -142,7 +156,7 @@ paint:
|
||||||
; ch = Y
|
; ch = Y
|
||||||
; dl = mouse buttons held down
|
; dl = mouse buttons held down
|
||||||
; out:
|
; out:
|
||||||
; trashes everything
|
; clobbers everything
|
||||||
mouse:
|
mouse:
|
||||||
call get_window
|
call get_window
|
||||||
|
|
||||||
|
@ -180,11 +194,11 @@ mouse:
|
||||||
.not_clicking:
|
.not_clicking:
|
||||||
|
|
||||||
test dl, MOUSE_PRIMARY | MOUSE_SECONDARY
|
test dl, MOUSE_PRIMARY | MOUSE_SECONDARY
|
||||||
jz .not_primary_held
|
jz .not_buttons_held
|
||||||
.primary_held:
|
.buttons_held:
|
||||||
mov byte [si + window.mouse_released_inside], 0
|
mov byte [si + window.mouse_released_inside], 0
|
||||||
jmp .inside
|
jmp .inside
|
||||||
.not_primary_held:
|
.not_buttons_held:
|
||||||
mov byte [si + window.mouse_released_inside], 1
|
mov byte [si + window.mouse_released_inside], 1
|
||||||
|
|
||||||
.inside:
|
.inside:
|
||||||
|
@ -212,8 +226,13 @@ mouse:
|
||||||
; dl = which buttons are held down
|
; dl = which buttons are held down
|
||||||
; si = pointer to window structure
|
; si = pointer to window structure
|
||||||
; out:
|
; out:
|
||||||
; trashes everything
|
; dl = which buttons are held down
|
||||||
|
; si = pointer to window structure
|
||||||
|
; clobbers everything else
|
||||||
click:
|
click:
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
|
||||||
cmp byte [si + window.icon], 0
|
cmp byte [si + window.icon], 0
|
||||||
je .file_window
|
je .file_window
|
||||||
.icon:
|
.icon:
|
||||||
|
@ -233,9 +252,43 @@ click:
|
||||||
jne .not_close
|
jne .not_close
|
||||||
.close:
|
.close:
|
||||||
call hide_file_window
|
call hide_file_window
|
||||||
|
jmp .end
|
||||||
.not_close:
|
.not_close:
|
||||||
|
|
||||||
|
; If clicked within the content area
|
||||||
|
mov ax, bx
|
||||||
|
sub ax, [si + window.y]
|
||||||
|
jz .end
|
||||||
|
|
||||||
|
; Find the start of the line user clicked on
|
||||||
|
mov bx, [si + window.width]
|
||||||
|
shl bx, 1
|
||||||
|
mul bx
|
||||||
|
|
||||||
|
mov si, [si + window.data]
|
||||||
|
add si, ax
|
||||||
|
|
||||||
|
; Zero out launch_filename
|
||||||
|
mov di, launch_filename
|
||||||
|
mov cx, FS_DIRENT_NAME_SIZE
|
||||||
|
xor al, al
|
||||||
|
rep stosb
|
||||||
|
|
||||||
|
; Copy file name to launch_filename
|
||||||
|
mov di, launch_filename
|
||||||
|
.copy_filename_loop:
|
||||||
|
lodsw
|
||||||
|
test al, al
|
||||||
|
jz .copy_filename_loop_end
|
||||||
|
stosb
|
||||||
|
jmp .copy_filename_loop
|
||||||
|
.copy_filename_loop_end:
|
||||||
|
|
||||||
|
call launch
|
||||||
|
|
||||||
.end:
|
.end:
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
show_file_window:
|
show_file_window:
|
||||||
|
@ -282,13 +335,80 @@ hide_file_window:
|
||||||
call request_redraw
|
call request_redraw
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; out:
|
||||||
|
; clobbers everything
|
||||||
|
launch:
|
||||||
|
mov si, launch_filename
|
||||||
|
|
||||||
|
; Is it a .bin file?
|
||||||
|
call strlen
|
||||||
|
cmp cx, 4
|
||||||
|
jb .end ; No, too short
|
||||||
|
add si, cx
|
||||||
|
sub si, 4
|
||||||
|
mov di, bin_extension
|
||||||
|
call strcmp
|
||||||
|
jne .end ; No, wrong extension
|
||||||
|
|
||||||
|
mov si, launch_filename
|
||||||
|
mov dx, 1 ; Don't create a new file if not found
|
||||||
|
call PONYDOS_SEG:SYS_OPEN_FILE
|
||||||
|
test ax, ax
|
||||||
|
; TODO: Display an alert on file not being found
|
||||||
|
jz .end
|
||||||
|
|
||||||
|
push ax
|
||||||
|
push cx
|
||||||
|
|
||||||
|
; Allocate a segment
|
||||||
|
mov ax, PONYDOS_SEG
|
||||||
|
mov es, ax
|
||||||
|
mov si, GLOBAL_MEMORY_ALLOCATION_MAP
|
||||||
|
mov cx, MEM_ALLOCATION_MAP_SIZE
|
||||||
|
.find_free_segment:
|
||||||
|
mov al, [es:si]
|
||||||
|
test al, al
|
||||||
|
jz .found_free_segment
|
||||||
|
inc si
|
||||||
|
loop .find_free_segment
|
||||||
|
; TODO: Display an alert on OOM error
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
jmp .end
|
||||||
|
.found_free_segment:
|
||||||
|
mov byte [es:si], 1 ; Mark as used
|
||||||
|
|
||||||
|
; Set up es to point to the allocated segment
|
||||||
|
sub si, GLOBAL_MEMORY_ALLOCATION_MAP
|
||||||
|
mov cl, 12
|
||||||
|
shl si, cl
|
||||||
|
mov es, si
|
||||||
|
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
xor bx, bx ; Load at the start of the segment
|
||||||
|
xor di, di ; Read
|
||||||
|
call PONYDOS_SEG:SYS_MODIFY_SECTORS
|
||||||
|
|
||||||
|
; Transfer control to the newly loaded binary
|
||||||
|
push cs ; Return segment
|
||||||
|
mov ax, .end
|
||||||
|
push ax ; Return offset
|
||||||
|
push es ; Call segment
|
||||||
|
mov ax, PROC_INITIALIZE_ENTRYPOINT
|
||||||
|
push ax ; Call offset
|
||||||
|
retf
|
||||||
|
|
||||||
|
.end:
|
||||||
|
ret
|
||||||
|
|
||||||
; in:
|
; in:
|
||||||
; al = WM_KEYBOARD
|
; al = WM_KEYBOARD
|
||||||
; bx = window ID
|
; bx = window ID
|
||||||
; cl = typed character
|
; cl = typed character
|
||||||
; cl = typed key
|
; cl = typed key
|
||||||
; out:
|
; out:
|
||||||
; trashes everything
|
; clobbers everything
|
||||||
keyboard:
|
keyboard:
|
||||||
call get_window
|
call get_window
|
||||||
mov si, [si + window.data]
|
mov si, [si + window.data]
|
||||||
|
@ -304,7 +424,7 @@ keyboard:
|
||||||
; out:
|
; out:
|
||||||
; ax = own ID if not the window to unhook
|
; ax = own ID if not the window to unhook
|
||||||
; next ID if the window to unhook
|
; next ID if the window to unhook
|
||||||
; trashes everything else
|
; clobbers everything else
|
||||||
unhook:
|
unhook:
|
||||||
call get_window
|
call get_window
|
||||||
|
|
||||||
|
@ -573,6 +693,31 @@ strlen:
|
||||||
pop ax
|
pop ax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; in:
|
||||||
|
; ds:si = string1
|
||||||
|
; ds:di = string2
|
||||||
|
; out:
|
||||||
|
; zf(ef) = strings are equal
|
||||||
|
strcmp:
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
lodsb
|
||||||
|
cmp [di], al
|
||||||
|
jne .end
|
||||||
|
|
||||||
|
test al, al
|
||||||
|
jz .end
|
||||||
|
|
||||||
|
inc di
|
||||||
|
jmp .loop
|
||||||
|
|
||||||
|
.end:
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
ret
|
||||||
|
|
||||||
; in:
|
; in:
|
||||||
; bx = window ID
|
; bx = window ID
|
||||||
; out:
|
; out:
|
||||||
|
@ -605,6 +750,8 @@ forward_event:
|
||||||
|
|
||||||
wallpaper_name db 'ponydos.wall', 0
|
wallpaper_name db 'ponydos.wall', 0
|
||||||
|
|
||||||
|
bin_extension db '.bin', 0
|
||||||
|
|
||||||
%include "debug.inc"
|
%include "debug.inc"
|
||||||
|
|
||||||
file_window_visible db 0
|
file_window_visible db 0
|
||||||
|
@ -618,8 +765,10 @@ file_window:
|
||||||
db 'A', 0x0f, ':', 0x0f
|
db 'A', 0x0f, ':', 0x0f
|
||||||
times 37 db ' ', 0x0f
|
times 37 db ' ', 0x0f
|
||||||
db 'x', 0x0f
|
db 'x', 0x0f
|
||||||
times 15*40 db ' ', 0xf0
|
times 15*40 db 0, 0xf0
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
times window.size db 0
|
times window.size db 0
|
||||||
times window.size db 0
|
times window.size db 0
|
||||||
|
|
||||||
|
launch_filename times FS_DIRENT_NAME_SIZE db 0
|
||||||
|
|
Loading…
Reference in a new issue