2023-03-25 22:53:02 +00:00
|
|
|
|
%include "ponydos.inc"
|
|
|
|
|
cpu 8086
|
|
|
|
|
bits 16
|
|
|
|
|
|
|
|
|
|
WINDOW_STATUS_NORMAL equ 0
|
|
|
|
|
WINDOW_STATUS_MOVE equ 1
|
|
|
|
|
WINDOW_STATUS_RESIZE equ 2
|
|
|
|
|
|
|
|
|
|
; Resize button, title, space, close button
|
|
|
|
|
WINDOW_MIN_WIDTH equ 1 + 8 + 1 + 1
|
2023-03-25 23:54:39 +00:00
|
|
|
|
WINDOW_MIN_HEIGHT equ 3
|
2023-03-25 22:53:02 +00:00
|
|
|
|
|
|
|
|
|
; 0x0000
|
|
|
|
|
jmp near process_event
|
|
|
|
|
|
|
|
|
|
; 0x0003 PROC_INITIALIZE_ENTRYPOINT
|
|
|
|
|
; initialize needs to preserve ds
|
|
|
|
|
initialize:
|
|
|
|
|
push ds
|
|
|
|
|
|
|
|
|
|
; On entry, ds and es will not be set correctly for us
|
|
|
|
|
mov bp, cs
|
|
|
|
|
mov es, bp
|
|
|
|
|
mov ds, bp
|
|
|
|
|
|
|
|
|
|
call hook_self_onto_window_chain
|
|
|
|
|
|
|
|
|
|
call render_window
|
|
|
|
|
|
|
|
|
|
; We must explicitly request redraw from the compositor
|
|
|
|
|
call request_redraw
|
|
|
|
|
|
|
|
|
|
pop ds
|
|
|
|
|
retf
|
|
|
|
|
|
|
|
|
|
; process_event needs to preserve all registers other than ax
|
|
|
|
|
; in:
|
|
|
|
|
; al = event
|
|
|
|
|
; bx = window ID
|
|
|
|
|
; cx, dx = event-specific
|
|
|
|
|
; out:
|
|
|
|
|
; ax = event-specific
|
|
|
|
|
process_event:
|
|
|
|
|
push bx
|
|
|
|
|
push cx
|
|
|
|
|
push dx
|
|
|
|
|
push si
|
|
|
|
|
push di
|
|
|
|
|
push bp
|
|
|
|
|
push ds
|
|
|
|
|
push es
|
|
|
|
|
|
|
|
|
|
; On entry, ds and es will not be set correctly for us
|
|
|
|
|
mov bp, cs
|
|
|
|
|
mov ds, bp
|
|
|
|
|
mov es, bp
|
|
|
|
|
|
|
|
|
|
cmp al, WM_PAINT
|
|
|
|
|
jne .not_paint
|
|
|
|
|
call event_paint
|
|
|
|
|
jmp .end
|
|
|
|
|
.not_paint:
|
|
|
|
|
|
|
|
|
|
cmp al, WM_MOUSE
|
|
|
|
|
jne .not_mouse
|
|
|
|
|
call event_mouse
|
|
|
|
|
jmp .end
|
|
|
|
|
.not_mouse:
|
|
|
|
|
|
|
|
|
|
cmp al, WM_KEYBOARD
|
|
|
|
|
jne .not_keyboard
|
|
|
|
|
call event_keyboard
|
|
|
|
|
jmp .end
|
|
|
|
|
.not_keyboard:
|
|
|
|
|
|
|
|
|
|
cmp al, WM_UNHOOK
|
|
|
|
|
jne .not_unhook
|
|
|
|
|
call event_unhook
|
|
|
|
|
jmp .end
|
|
|
|
|
.not_unhook:
|
|
|
|
|
|
|
|
|
|
.end:
|
|
|
|
|
pop es
|
|
|
|
|
pop ds
|
|
|
|
|
pop bp
|
|
|
|
|
pop di
|
|
|
|
|
pop si
|
|
|
|
|
pop dx
|
|
|
|
|
pop cx
|
|
|
|
|
pop bx
|
|
|
|
|
retf
|
|
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------
|
2023-03-26 12:29:07 +00:00
|
|
|
|
; Filename handling
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
; in:
|
|
|
|
|
; cl = typed character
|
|
|
|
|
; ch = pressed key
|
|
|
|
|
; out:
|
|
|
|
|
; clobbers bx
|
|
|
|
|
filename_char_add:
|
2023-03-26 14:35:13 +00:00
|
|
|
|
cmp word [cur_filename_address], filename_window_data.filename + 2*(FS_DIRENT_NAME_SIZE-1)
|
2023-03-26 12:29:07 +00:00
|
|
|
|
je .done
|
|
|
|
|
|
|
|
|
|
mov bx, [cur_filename_address]
|
|
|
|
|
mov byte [bx], cl
|
|
|
|
|
add word [cur_filename_address], 2
|
|
|
|
|
|
|
|
|
|
call request_redraw
|
|
|
|
|
|
|
|
|
|
.done:
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; out:
|
|
|
|
|
; clobbers bx
|
|
|
|
|
filename_char_del:
|
|
|
|
|
cmp word [cur_filename_address], filename_window_data.filename
|
|
|
|
|
je .done
|
|
|
|
|
|
|
|
|
|
mov bx, [cur_filename_address]
|
|
|
|
|
mov byte [bx - 2], 0x00
|
|
|
|
|
sub word [cur_filename_address], 2
|
|
|
|
|
|
|
|
|
|
call request_redraw
|
|
|
|
|
|
|
|
|
|
.done:
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; out:
|
|
|
|
|
; clobbers everything
|
|
|
|
|
filename_ok:
|
2023-03-27 10:34:52 +00:00
|
|
|
|
; Just ignore if there's no filename.
|
|
|
|
|
cmp byte [filename_window_data.filename], 0
|
|
|
|
|
je .end
|
|
|
|
|
|
2023-03-26 12:29:07 +00:00
|
|
|
|
mov cx, FS_DIRENT_NAME_SIZE
|
|
|
|
|
mov di, window_title
|
|
|
|
|
mov si, filename_window_data.filename
|
|
|
|
|
.loop:
|
|
|
|
|
lodsb
|
|
|
|
|
stosb
|
|
|
|
|
inc si
|
|
|
|
|
loop .loop
|
|
|
|
|
|
|
|
|
|
mov si, window_title
|
|
|
|
|
xor dx, dx ; do create empty file
|
2023-03-27 10:34:52 +00:00
|
|
|
|
call PONYDOS_SEG:SYS_OPEN_FILE
|
|
|
|
|
test ax, ax
|
|
|
|
|
jnz .got_file
|
|
|
|
|
mov si, ood_window
|
|
|
|
|
call raise_error
|
|
|
|
|
ret
|
2023-03-26 12:29:07 +00:00
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
.got_file:
|
|
|
|
|
call allocate_segment
|
|
|
|
|
test dx, dx
|
|
|
|
|
jnz .got_memory
|
|
|
|
|
mov si, oom_window
|
|
|
|
|
call raise_error
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
.got_memory:
|
2023-03-26 12:29:07 +00:00
|
|
|
|
mov [cur_file_address + 2], dx
|
|
|
|
|
mov word [cur_file_address], 0
|
|
|
|
|
mov word [beg_file_address], 0
|
|
|
|
|
|
|
|
|
|
push es
|
|
|
|
|
mov es, dx
|
|
|
|
|
xor bx, bx
|
|
|
|
|
xor di, di ; read
|
2023-03-27 10:34:52 +00:00
|
|
|
|
call PONYDOS_SEG:SYS_MODIFY_SECTORS
|
2023-03-26 12:29:07 +00:00
|
|
|
|
pop es
|
|
|
|
|
|
|
|
|
|
mov ch, cl
|
|
|
|
|
xor cl, cl
|
|
|
|
|
shl cx, 1 ; Multiply by 512
|
|
|
|
|
mov [end_file_address], cx
|
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov si, text_window
|
|
|
|
|
mov di, window
|
|
|
|
|
mov cx, window_struc.size
|
|
|
|
|
rep movsb
|
2023-03-26 12:29:07 +00:00
|
|
|
|
|
|
|
|
|
mov byte [file_opened], 1
|
|
|
|
|
|
|
|
|
|
call render_window
|
|
|
|
|
call request_redraw
|
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
.end:
|
2023-03-26 12:29:07 +00:00
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
; Text file handling
|
2023-03-25 22:53:02 +00:00
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
; in:
|
|
|
|
|
; es:di = where to start printing on screen
|
|
|
|
|
print_file:
|
|
|
|
|
push ax
|
|
|
|
|
push bx
|
|
|
|
|
push cx
|
|
|
|
|
push dx
|
|
|
|
|
push si
|
|
|
|
|
push di
|
|
|
|
|
push ds
|
|
|
|
|
|
|
|
|
|
lds si, [cur_file_address]
|
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov cx, [cs:window.height]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
dec cx
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov dx, [cs:window.width]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
mov bl, 1 ; Haven't read anything yet
|
|
|
|
|
.window_loop:
|
|
|
|
|
push di
|
|
|
|
|
.line_loop:
|
|
|
|
|
cmp si, [cs:end_file_address]
|
|
|
|
|
jne .not_end_file
|
|
|
|
|
test bl, bl
|
|
|
|
|
jz .end_window_loop ; Need to have read something to hit end-of-file
|
|
|
|
|
|
|
|
|
|
.not_end_file:
|
|
|
|
|
lodsb
|
|
|
|
|
xor bl, bl ; Have read something
|
|
|
|
|
|
|
|
|
|
; Special byte handling
|
|
|
|
|
cmp al, 0x0A ; \n
|
|
|
|
|
je .next_line
|
|
|
|
|
|
|
|
|
|
cmp al, 0x09 ; \t
|
|
|
|
|
jne .null_check
|
|
|
|
|
add di, 8
|
|
|
|
|
sub dx, 4
|
|
|
|
|
jc .next_line
|
|
|
|
|
jz .next_line
|
|
|
|
|
jmp .line_loop
|
|
|
|
|
|
|
|
|
|
.null_check:
|
|
|
|
|
test al, al
|
|
|
|
|
jz .end_window_loop
|
|
|
|
|
|
|
|
|
|
stosb
|
|
|
|
|
inc di
|
|
|
|
|
dec dx
|
|
|
|
|
jnz .line_loop
|
|
|
|
|
.next_line:
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov dx, [cs:window.width]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
|
|
|
|
|
pop di
|
2023-03-27 10:34:52 +00:00
|
|
|
|
add di, [cs:window.width]
|
|
|
|
|
add di, [cs:window.width]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
loop .window_loop
|
|
|
|
|
|
|
|
|
|
.ret:
|
|
|
|
|
pop ds
|
|
|
|
|
pop di
|
|
|
|
|
pop si
|
|
|
|
|
pop dx
|
|
|
|
|
pop cx
|
|
|
|
|
pop bx
|
|
|
|
|
pop ax
|
|
|
|
|
ret
|
2023-03-26 12:29:07 +00:00
|
|
|
|
|
2023-03-25 22:53:02 +00:00
|
|
|
|
.end_window_loop:
|
|
|
|
|
pop di
|
|
|
|
|
jmp .ret
|
|
|
|
|
|
|
|
|
|
; out:
|
|
|
|
|
; dx = non-zero if cur_file_address is updated
|
|
|
|
|
file_next_line:
|
|
|
|
|
push ax
|
|
|
|
|
push si
|
|
|
|
|
push ds
|
|
|
|
|
|
|
|
|
|
xor dx, dx
|
|
|
|
|
|
|
|
|
|
lds si, [cur_file_address]
|
|
|
|
|
|
|
|
|
|
.loop:
|
|
|
|
|
lodsb
|
|
|
|
|
|
|
|
|
|
cmp al, 0x0A ; \n
|
|
|
|
|
je .found_next_line
|
|
|
|
|
|
|
|
|
|
test al, al
|
|
|
|
|
jz .ret
|
|
|
|
|
|
|
|
|
|
cmp si, [cs:end_file_address]
|
|
|
|
|
je .ret
|
|
|
|
|
|
|
|
|
|
jmp .loop
|
|
|
|
|
|
|
|
|
|
.found_next_line:
|
|
|
|
|
cmp si, [cs:end_file_address]
|
|
|
|
|
je .ret
|
|
|
|
|
|
|
|
|
|
cmp byte [ds:si], 0
|
|
|
|
|
je .ret
|
|
|
|
|
|
|
|
|
|
not dx
|
|
|
|
|
mov [cs:cur_file_address], si
|
|
|
|
|
|
|
|
|
|
.ret:
|
|
|
|
|
pop ds
|
|
|
|
|
pop si
|
|
|
|
|
pop ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; out:
|
|
|
|
|
; dx = non-zero if cur_file_address is updated
|
|
|
|
|
file_prev_line:
|
|
|
|
|
push ax
|
|
|
|
|
push si
|
|
|
|
|
push ds
|
|
|
|
|
|
|
|
|
|
std
|
|
|
|
|
|
|
|
|
|
xor dx, dx
|
|
|
|
|
|
|
|
|
|
lds si, [cur_file_address]
|
|
|
|
|
cmp si, [cs:beg_file_address] ; Already at the beginning?
|
|
|
|
|
je .ret
|
|
|
|
|
|
|
|
|
|
dec si
|
|
|
|
|
cmp si, [cs:beg_file_address] ; Last line was empty?
|
|
|
|
|
je .ret
|
|
|
|
|
|
|
|
|
|
dec si
|
|
|
|
|
.loop:
|
|
|
|
|
cmp si, [cs:beg_file_address]
|
|
|
|
|
je .found_prev_line
|
|
|
|
|
lodsb
|
|
|
|
|
|
|
|
|
|
cmp al, 0x0A ; \n
|
|
|
|
|
jne .loop
|
|
|
|
|
|
|
|
|
|
inc si
|
|
|
|
|
inc si
|
|
|
|
|
|
|
|
|
|
.found_prev_line:
|
|
|
|
|
not dx
|
|
|
|
|
mov [cs:cur_file_address], si
|
|
|
|
|
|
|
|
|
|
.ret:
|
|
|
|
|
cld
|
|
|
|
|
|
|
|
|
|
pop ds
|
|
|
|
|
pop si
|
|
|
|
|
pop ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
; Event handlers
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
; in:
|
|
|
|
|
; al = WM_PAINT
|
|
|
|
|
; bx = window ID
|
|
|
|
|
; out:
|
|
|
|
|
; clobbers everything
|
|
|
|
|
event_paint:
|
|
|
|
|
; Forward the paint event to the next window in the chain
|
|
|
|
|
; We must do this before we paint ourselves, because painting must
|
|
|
|
|
; happen from the back to the front
|
|
|
|
|
; Because we only have one window, we don't need to save our own ID
|
|
|
|
|
mov bx, [window_next]
|
|
|
|
|
call send_event
|
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov bx, [window.width] ; Buffer width, usually same as window width
|
|
|
|
|
mov cx, [window.width]
|
|
|
|
|
mov dx, [window.height]
|
|
|
|
|
mov di, [window.x]
|
|
|
|
|
mov bp, [window.y]
|
|
|
|
|
mov si, [window.data_address]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
|
|
|
|
|
cmp di, 0
|
|
|
|
|
jge .not_clip_left
|
|
|
|
|
.clip_left:
|
|
|
|
|
; Adjust the start of buffer to point to the first cell
|
|
|
|
|
; that is on screen
|
|
|
|
|
sub si, di
|
|
|
|
|
sub si, di
|
|
|
|
|
; Adjust window width to account for non-rendered area
|
|
|
|
|
; that is off screen
|
|
|
|
|
add cx, di
|
|
|
|
|
; Set X to 0
|
|
|
|
|
xor di, di
|
|
|
|
|
.not_clip_left:
|
|
|
|
|
|
|
|
|
|
mov ax, di
|
|
|
|
|
add ax, cx
|
|
|
|
|
cmp ax, COLUMNS
|
|
|
|
|
jle .not_clip_right
|
|
|
|
|
.clip_right:
|
|
|
|
|
; Adjust the width to only go as far as the right edge
|
|
|
|
|
sub ax, COLUMNS
|
|
|
|
|
sub cx, ax
|
|
|
|
|
.not_clip_right:
|
|
|
|
|
|
|
|
|
|
mov ax, bp
|
|
|
|
|
add ax, dx
|
|
|
|
|
cmp ax, ROWS
|
|
|
|
|
jle .not_clip_bottom
|
|
|
|
|
.clip_bottom:
|
|
|
|
|
; Adjust the height to only go as far as the bottom edge
|
|
|
|
|
sub ax, ROWS
|
|
|
|
|
sub dx, ax
|
|
|
|
|
.not_clip_bottom:
|
|
|
|
|
|
|
|
|
|
call PONYDOS_SEG:SYS_DRAW_RECT
|
|
|
|
|
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; in:
|
|
|
|
|
; al = WM_MOUSE
|
|
|
|
|
; bx = window ID
|
|
|
|
|
; cl = X
|
|
|
|
|
; ch = Y
|
|
|
|
|
; dl = mouse buttons held down
|
|
|
|
|
; out:
|
|
|
|
|
; clobbers everything
|
|
|
|
|
event_mouse:
|
|
|
|
|
test dl, MOUSE_PRIMARY | MOUSE_SECONDARY
|
|
|
|
|
jnz .not_end_window_change
|
|
|
|
|
; If we were moving or resizing the window, releasing the
|
|
|
|
|
; button signals the end of the action
|
|
|
|
|
mov byte [window_status], WINDOW_STATUS_NORMAL
|
|
|
|
|
.not_end_window_change:
|
|
|
|
|
|
|
|
|
|
; Expand X and Y to 16 bits for easier calculations
|
|
|
|
|
; Because we only have one window, we don't need to save our own ID
|
|
|
|
|
xor bx, bx
|
|
|
|
|
mov bl, ch
|
|
|
|
|
xor ch, ch
|
|
|
|
|
|
|
|
|
|
; Are we moving the window at the moment?
|
|
|
|
|
cmp byte [window_status], WINDOW_STATUS_MOVE
|
|
|
|
|
jne .not_moving
|
|
|
|
|
call move_window
|
|
|
|
|
.not_moving:
|
|
|
|
|
|
|
|
|
|
; Are we resizing the window at the moment?
|
|
|
|
|
cmp byte [window_status], WINDOW_STATUS_RESIZE
|
|
|
|
|
jne .not_resizing
|
|
|
|
|
call resize_window
|
|
|
|
|
.not_resizing:
|
|
|
|
|
|
|
|
|
|
; Check if the mouse is outside our window
|
2023-03-27 10:34:52 +00:00
|
|
|
|
cmp cx, [window.x]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
jl .outside ; x < window_x
|
2023-03-27 10:34:52 +00:00
|
|
|
|
cmp bx, [window.y]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
jl .outside ; y < window_y
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov ax, [window.x]
|
|
|
|
|
add ax, [window.width]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
cmp ax, cx
|
|
|
|
|
jle .outside ; window_x + window_width <= x
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov ax, [window.y]
|
|
|
|
|
add ax, [window.height]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
cmp ax, bx
|
|
|
|
|
jle .outside ; window_y + window_height <= y
|
|
|
|
|
|
|
|
|
|
.inside:
|
|
|
|
|
cmp byte [window_mouse_released_inside], 0
|
|
|
|
|
je .not_click
|
|
|
|
|
test dl, MOUSE_PRIMARY | MOUSE_SECONDARY
|
|
|
|
|
jz .not_click
|
|
|
|
|
.click:
|
|
|
|
|
call event_click
|
|
|
|
|
.not_click:
|
|
|
|
|
|
|
|
|
|
; We need to keep track of if the mouse has been inside our
|
|
|
|
|
; window without the buttons held, in order to avoid
|
|
|
|
|
; generating click events in cases where the cursor is
|
|
|
|
|
; dragged into our window while buttons are held
|
|
|
|
|
test dl, MOUSE_PRIMARY | MOUSE_SECONDARY
|
|
|
|
|
jz .buttons_not_held
|
|
|
|
|
.buttons_held:
|
|
|
|
|
mov byte [window_mouse_released_inside], 0
|
|
|
|
|
jmp .buttons_end
|
|
|
|
|
.buttons_not_held:
|
|
|
|
|
mov byte [window_mouse_released_inside], 1
|
|
|
|
|
.buttons_end:
|
|
|
|
|
|
|
|
|
|
; We must forward the event even if it was inside our
|
|
|
|
|
; window, to make sure other windows know when the mouse
|
|
|
|
|
; leaves them
|
|
|
|
|
; Set x and y to 255 so that windows below ours don't think
|
|
|
|
|
; the cursor is inside them
|
|
|
|
|
; Also clear the mouse buttons – not absolutely necessary
|
|
|
|
|
; but it's cleaner if other windows don't get any
|
|
|
|
|
; information about the mouse
|
|
|
|
|
mov al, WM_MOUSE
|
|
|
|
|
mov bx, [window_next]
|
|
|
|
|
mov cx, 0xffff
|
|
|
|
|
xor dl, dl
|
|
|
|
|
call send_event
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
.outside:
|
|
|
|
|
mov byte [window_mouse_released_inside], 0
|
|
|
|
|
|
|
|
|
|
; Not our window, forward the event
|
|
|
|
|
mov al, WM_MOUSE
|
|
|
|
|
mov ch, bl ; Pack the X and Y back into cx
|
|
|
|
|
mov bx, [window_next]
|
|
|
|
|
call send_event
|
|
|
|
|
ret
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; in:
|
|
|
|
|
; bx = Y
|
|
|
|
|
; cx = X
|
|
|
|
|
; dl = mouse buttons
|
|
|
|
|
event_click:
|
2023-03-25 22:54:48 +00:00
|
|
|
|
push ax
|
2023-03-25 22:53:02 +00:00
|
|
|
|
; This is not a true event passed into our event handler, but
|
|
|
|
|
; rather one we've synthetized from the mouse event
|
|
|
|
|
; The reason we synthetize this event is because most interface
|
|
|
|
|
; elements react to clicks specifically, so having this event
|
|
|
|
|
; making implementing them easier
|
|
|
|
|
|
|
|
|
|
; Raising a window is done by first unhooking, then rehooking it to
|
|
|
|
|
; the window chain
|
|
|
|
|
call unhook_self_from_window_chain
|
|
|
|
|
call hook_self_onto_window_chain
|
|
|
|
|
call request_redraw
|
|
|
|
|
|
|
|
|
|
; Did the user click the title bar?
|
2023-03-27 10:34:52 +00:00
|
|
|
|
cmp [window.y], bx
|
2023-03-25 22:53:02 +00:00
|
|
|
|
jne .not_title_bar
|
|
|
|
|
.title_bar:
|
|
|
|
|
; Did the user click the window close button?
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov ax, [window.x]
|
|
|
|
|
add ax, [window.width]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
dec ax
|
|
|
|
|
cmp ax, cx
|
|
|
|
|
jne .not_close
|
|
|
|
|
.close:
|
2023-03-27 10:34:52 +00:00
|
|
|
|
call close_window
|
2023-03-25 23:54:39 +00:00
|
|
|
|
jmp .end
|
2023-03-25 22:53:02 +00:00
|
|
|
|
.not_close:
|
|
|
|
|
|
|
|
|
|
; Did the user click on the resize button?
|
2023-03-26 12:29:07 +00:00
|
|
|
|
cmp byte [file_opened], 0
|
|
|
|
|
je .not_resize ; Can't resize while entering filename
|
2023-03-27 10:34:52 +00:00
|
|
|
|
cmp [window.x], cx
|
2023-03-25 22:53:02 +00:00
|
|
|
|
jne .not_resize
|
|
|
|
|
.resize:
|
|
|
|
|
mov byte [window_status], WINDOW_STATUS_RESIZE
|
2023-03-25 23:54:39 +00:00
|
|
|
|
jmp .end
|
2023-03-25 22:53:02 +00:00
|
|
|
|
.not_resize:
|
|
|
|
|
|
|
|
|
|
; Clicking on the title bar signals beginning of a window
|
|
|
|
|
; move
|
|
|
|
|
mov byte [window_status], WINDOW_STATUS_MOVE
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov ax, [window.x]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
sub ax, cx
|
|
|
|
|
mov [window_move_x_offset], ax
|
2023-03-25 23:54:39 +00:00
|
|
|
|
jmp .end
|
|
|
|
|
|
2023-03-25 22:53:02 +00:00
|
|
|
|
.not_title_bar:
|
2023-03-26 12:29:07 +00:00
|
|
|
|
cmp byte [file_opened], 0
|
|
|
|
|
jne .not_filename_window
|
|
|
|
|
.filename_window:
|
2023-03-27 10:34:52 +00:00
|
|
|
|
sub bx, [window.y]
|
|
|
|
|
sub cx, [window.x]
|
2023-03-26 12:29:07 +00:00
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov ax, [window.width]
|
2023-03-26 12:29:07 +00:00
|
|
|
|
shl ax, 1
|
|
|
|
|
mul bx
|
|
|
|
|
add ax, cx
|
|
|
|
|
add ax, cx
|
|
|
|
|
|
|
|
|
|
add ax, filename_window_data
|
|
|
|
|
mov bx, ax
|
|
|
|
|
inc bx
|
|
|
|
|
|
|
|
|
|
cmp byte [bx], CANCEL_COLOR
|
|
|
|
|
jne .not_cancel
|
|
|
|
|
.cancel:
|
|
|
|
|
call unhook_self_from_window_chain
|
|
|
|
|
call deallocate_own_memory
|
|
|
|
|
jmp .end
|
|
|
|
|
.not_cancel:
|
|
|
|
|
cmp byte [bx], OK_COLOR
|
|
|
|
|
jne .not_ok
|
|
|
|
|
.ok:
|
|
|
|
|
call filename_ok
|
|
|
|
|
.not_ok:
|
|
|
|
|
jmp .end
|
|
|
|
|
|
|
|
|
|
.not_filename_window:
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov ax, [window.x]
|
|
|
|
|
add ax, [window.width]
|
2023-03-25 23:54:39 +00:00
|
|
|
|
dec ax
|
|
|
|
|
cmp ax, cx
|
|
|
|
|
jne .not_scroll_bar
|
|
|
|
|
|
|
|
|
|
; Scroll up button?
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov ax, [window.y]
|
2023-03-25 23:54:39 +00:00
|
|
|
|
inc ax
|
|
|
|
|
cmp ax, bx
|
|
|
|
|
jne .not_scroll_up
|
|
|
|
|
.scroll_up:
|
|
|
|
|
call file_prev_line
|
|
|
|
|
test dx, dx
|
|
|
|
|
jz .end
|
|
|
|
|
|
|
|
|
|
call render_window
|
|
|
|
|
call request_redraw
|
|
|
|
|
jmp .end
|
|
|
|
|
.not_scroll_up:
|
|
|
|
|
|
|
|
|
|
; Scroll down button?
|
2023-03-27 10:34:52 +00:00
|
|
|
|
add ax, [window.height]
|
2023-03-25 23:54:39 +00:00
|
|
|
|
dec ax
|
|
|
|
|
dec ax
|
|
|
|
|
cmp ax, bx
|
|
|
|
|
jne .not_scroll_down
|
|
|
|
|
.scroll_down:
|
|
|
|
|
call file_next_line
|
|
|
|
|
test dx, dx
|
|
|
|
|
jz .end
|
|
|
|
|
|
|
|
|
|
call render_window
|
|
|
|
|
call request_redraw
|
|
|
|
|
.not_scroll_down:
|
2023-03-25 22:53:02 +00:00
|
|
|
|
|
2023-03-25 23:54:39 +00:00
|
|
|
|
.not_scroll_bar:
|
2023-03-25 22:53:02 +00:00
|
|
|
|
.end:
|
2023-03-25 22:54:48 +00:00
|
|
|
|
pop ax
|
2023-03-25 22:53:02 +00:00
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; in:
|
|
|
|
|
; al = WM_KEYBOARD
|
|
|
|
|
; bx = window ID
|
|
|
|
|
; cl = typed character
|
|
|
|
|
; ch = pressed key
|
|
|
|
|
; out:
|
|
|
|
|
; clobbers everything
|
|
|
|
|
event_keyboard:
|
2023-03-26 12:29:07 +00:00
|
|
|
|
cmp byte [file_opened], 0
|
|
|
|
|
jne .file_opened
|
2023-03-27 10:34:52 +00:00
|
|
|
|
cmp word [window.data_address], filename_window_data
|
|
|
|
|
jne .ret ; error windows
|
2023-03-26 12:29:07 +00:00
|
|
|
|
.file_not_opened:
|
|
|
|
|
cmp ch, 0x0e
|
|
|
|
|
jne .not_backspace
|
|
|
|
|
.backspace:
|
|
|
|
|
call filename_char_del
|
|
|
|
|
ret
|
|
|
|
|
.not_backspace:
|
|
|
|
|
cmp ch, 0x1c
|
|
|
|
|
jne .not_enter
|
|
|
|
|
.enter:
|
|
|
|
|
call filename_ok
|
|
|
|
|
ret
|
|
|
|
|
.not_enter:
|
|
|
|
|
call filename_char_add
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
.file_opened:
|
2023-03-25 22:53:02 +00:00
|
|
|
|
cmp ch, 0x50 ; down key
|
|
|
|
|
jne .up_key_check
|
2023-03-25 23:54:39 +00:00
|
|
|
|
.down_key:
|
|
|
|
|
call file_next_line
|
|
|
|
|
test dx, dx
|
|
|
|
|
jz .ret
|
|
|
|
|
|
|
|
|
|
call render_window
|
|
|
|
|
call request_redraw
|
|
|
|
|
ret
|
2023-03-25 22:53:02 +00:00
|
|
|
|
|
|
|
|
|
.up_key_check:
|
|
|
|
|
cmp ch, 0x48 ; up key
|
2023-03-25 23:54:39 +00:00
|
|
|
|
jne .space_check
|
|
|
|
|
.up_key:
|
|
|
|
|
call file_prev_line
|
|
|
|
|
test dx, dx
|
|
|
|
|
jz .ret
|
|
|
|
|
|
|
|
|
|
call render_window
|
|
|
|
|
call request_redraw
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
.space_check:
|
|
|
|
|
cmp cl, ' '
|
2023-03-25 22:53:02 +00:00
|
|
|
|
jne .ret
|
2023-03-25 23:54:39 +00:00
|
|
|
|
.space:
|
|
|
|
|
; Go down eight lines
|
|
|
|
|
xor ax, ax
|
|
|
|
|
mov cx, 8
|
|
|
|
|
.loop:
|
|
|
|
|
call file_next_line
|
|
|
|
|
or ax, dx
|
|
|
|
|
loop .loop
|
|
|
|
|
test ax, ax
|
|
|
|
|
jz .ret
|
|
|
|
|
|
|
|
|
|
call render_window
|
|
|
|
|
call request_redraw
|
|
|
|
|
|
2023-03-25 22:53:02 +00:00
|
|
|
|
.ret:
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; in:
|
|
|
|
|
; al = WM_UNHOOK
|
|
|
|
|
; bx = window ID
|
|
|
|
|
; cx = window ID of the window to unhook from the window chain
|
|
|
|
|
; out:
|
|
|
|
|
; ax = own window ID if we did not unhook
|
|
|
|
|
; next window ID if we did
|
|
|
|
|
; clobbers everything else
|
|
|
|
|
event_unhook:
|
|
|
|
|
cmp bx, cx
|
|
|
|
|
je .unhook_self
|
|
|
|
|
|
|
|
|
|
; Save our own ID
|
|
|
|
|
push bx
|
|
|
|
|
|
|
|
|
|
; Propagate the event
|
|
|
|
|
mov bx, [window_next]
|
|
|
|
|
call send_event
|
|
|
|
|
|
|
|
|
|
; Update window_next in case the next one unhooked
|
|
|
|
|
mov [window_next], ax
|
|
|
|
|
|
|
|
|
|
; Return our own ID
|
|
|
|
|
pop ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
.unhook_self:
|
|
|
|
|
; Return window_next to the caller, unhooking us from the
|
|
|
|
|
; chain
|
|
|
|
|
mov ax, [window_next]
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
; Event handler subroutines
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
; out:
|
|
|
|
|
; clobbers si, di, cx
|
|
|
|
|
close_window:
|
|
|
|
|
cmp word [window.data_address], oom_window_data
|
|
|
|
|
je .error_window
|
|
|
|
|
cmp word [window.data_address], ood_window_data
|
|
|
|
|
je .error_window
|
|
|
|
|
.not_error_window:
|
|
|
|
|
; Shut off app
|
|
|
|
|
call unhook_self_from_window_chain
|
|
|
|
|
call deallocate_own_memory
|
|
|
|
|
ret
|
|
|
|
|
.error_window:
|
|
|
|
|
mov si, filename_window
|
|
|
|
|
mov di, window
|
|
|
|
|
mov cx, window_struc.size
|
|
|
|
|
rep movsb
|
|
|
|
|
|
|
|
|
|
call request_redraw
|
|
|
|
|
ret
|
|
|
|
|
|
2023-03-25 22:53:02 +00:00
|
|
|
|
; in:
|
|
|
|
|
; bx = Y
|
|
|
|
|
; cx = X
|
|
|
|
|
move_window:
|
|
|
|
|
push ax
|
|
|
|
|
|
|
|
|
|
; Offset the X coördinate so that the apparent drag position
|
|
|
|
|
; remains the same
|
|
|
|
|
mov ax, cx
|
|
|
|
|
add ax, [window_move_x_offset]
|
|
|
|
|
|
|
|
|
|
; Only do an update if something has changed. Reduces flicker
|
2023-03-27 10:34:52 +00:00
|
|
|
|
cmp [window.x], ax
|
2023-03-25 22:53:02 +00:00
|
|
|
|
jne .update_location
|
2023-03-27 10:34:52 +00:00
|
|
|
|
cmp [window.y], bx
|
2023-03-25 22:53:02 +00:00
|
|
|
|
jne .update_location
|
|
|
|
|
jmp .end
|
|
|
|
|
|
|
|
|
|
.update_location:
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov [window.x], ax
|
|
|
|
|
mov [window.y], bx
|
2023-03-25 22:53:02 +00:00
|
|
|
|
call request_redraw
|
|
|
|
|
|
|
|
|
|
.end:
|
|
|
|
|
pop ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; in:
|
|
|
|
|
; bx = Y
|
|
|
|
|
; cx = X
|
|
|
|
|
resize_window:
|
|
|
|
|
push ax
|
|
|
|
|
push bx
|
|
|
|
|
push bp
|
|
|
|
|
|
|
|
|
|
; Calculate new width
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov ax, [window.width]
|
|
|
|
|
add ax, [window.x]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
sub ax, cx
|
|
|
|
|
|
|
|
|
|
cmp ax, WINDOW_MIN_WIDTH
|
|
|
|
|
jge .width_large_enough
|
|
|
|
|
mov ax, WINDOW_MIN_WIDTH
|
|
|
|
|
.width_large_enough:
|
|
|
|
|
|
|
|
|
|
cmp ax, COLUMNS
|
|
|
|
|
jle .width_small_enough
|
|
|
|
|
mov ax, COLUMNS
|
|
|
|
|
.width_small_enough:
|
|
|
|
|
|
|
|
|
|
; Calculate new height
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov bp, [window.height]
|
|
|
|
|
add bp, [window.y]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
sub bp, bx
|
|
|
|
|
|
|
|
|
|
cmp bp, WINDOW_MIN_HEIGHT
|
|
|
|
|
jge .height_large_enough
|
|
|
|
|
mov bp, WINDOW_MIN_HEIGHT
|
|
|
|
|
.height_large_enough:
|
|
|
|
|
|
|
|
|
|
cmp bp, ROWS
|
|
|
|
|
jle .height_small_engough
|
|
|
|
|
mov bp, ROWS
|
|
|
|
|
.height_small_engough:
|
|
|
|
|
|
|
|
|
|
; Only do an update if something has changed. Reduces flicker
|
2023-03-27 10:34:52 +00:00
|
|
|
|
cmp [window.width], ax
|
2023-03-25 22:53:02 +00:00
|
|
|
|
jne .update_size
|
2023-03-27 10:34:52 +00:00
|
|
|
|
cmp [window.height], bp
|
2023-03-25 22:53:02 +00:00
|
|
|
|
jne .update_size
|
|
|
|
|
jmp .end
|
|
|
|
|
|
|
|
|
|
.update_size:
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov bx, [window.x]
|
|
|
|
|
add bx, [window.width]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
sub bx, ax
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov [window.x], bx
|
|
|
|
|
mov [window.width], ax
|
2023-03-25 22:53:02 +00:00
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov bx, [window.y]
|
|
|
|
|
add bx, [window.height]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
sub bx, bp
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov [window.y], bx
|
|
|
|
|
mov [window.height], bp
|
2023-03-25 22:53:02 +00:00
|
|
|
|
|
|
|
|
|
call render_window
|
|
|
|
|
|
|
|
|
|
call request_redraw
|
|
|
|
|
|
|
|
|
|
.end:
|
|
|
|
|
pop bp
|
|
|
|
|
pop bx
|
|
|
|
|
pop ax
|
|
|
|
|
|
|
|
|
|
render_window:
|
|
|
|
|
push ax
|
|
|
|
|
push cx
|
|
|
|
|
push dx
|
|
|
|
|
push si
|
|
|
|
|
push di
|
|
|
|
|
|
|
|
|
|
; Clear window to be black-on-white
|
2023-03-26 12:29:07 +00:00
|
|
|
|
mov di, text_window_data
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov ax, [window.width]
|
|
|
|
|
mov cx, [window.height]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
mul cx
|
|
|
|
|
mov cx, ax
|
|
|
|
|
mov ax, 0xf000 ; Attribute is in the high byte
|
|
|
|
|
rep stosw
|
|
|
|
|
|
|
|
|
|
; Set title bar to be white-on-black
|
2023-03-26 12:29:07 +00:00
|
|
|
|
mov di, text_window_data
|
2023-03-25 22:53:02 +00:00
|
|
|
|
mov ax, 0x0f00
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov cx, [window.width]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
rep stosw
|
|
|
|
|
|
|
|
|
|
; Add title bar buttons
|
2023-03-26 12:29:07 +00:00
|
|
|
|
mov di, text_window_data
|
2023-03-25 22:53:02 +00:00
|
|
|
|
mov byte [di], 0x17 ; Resize arrow
|
2023-03-27 10:34:52 +00:00
|
|
|
|
add di, [window.width]
|
|
|
|
|
add di, [window.width]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
sub di, 2
|
|
|
|
|
mov byte [di], 'x' ; Close button
|
|
|
|
|
|
|
|
|
|
; Add window title
|
2023-03-26 12:29:07 +00:00
|
|
|
|
mov di, text_window_data
|
2023-03-25 22:53:02 +00:00
|
|
|
|
add di, 2
|
|
|
|
|
mov si, window_title
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov cx, [window.width]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
dec cx
|
|
|
|
|
dec cx
|
|
|
|
|
cmp cx, FS_DIRENT_NAME_SIZE
|
|
|
|
|
jle .copy_title
|
|
|
|
|
mov cx, FS_DIRENT_NAME_SIZE
|
|
|
|
|
.copy_title:
|
|
|
|
|
lodsb
|
|
|
|
|
stosb
|
|
|
|
|
inc di
|
|
|
|
|
loop .copy_title
|
|
|
|
|
|
|
|
|
|
; Print text
|
2023-03-26 12:29:07 +00:00
|
|
|
|
mov di, text_window_data
|
2023-03-27 10:34:52 +00:00
|
|
|
|
add di, [window.width]
|
|
|
|
|
add di, [window.width]
|
2023-03-25 22:53:02 +00:00
|
|
|
|
call print_file
|
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
add di, [window.width]
|
|
|
|
|
add di, [window.width]
|
2023-03-25 23:54:39 +00:00
|
|
|
|
sub di, 2
|
|
|
|
|
mov byte [di], 0x1E ; up
|
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
mov ax, [window.width]
|
|
|
|
|
mov cx, [window.height]
|
2023-03-25 23:54:39 +00:00
|
|
|
|
sub cx, 2
|
|
|
|
|
shl cx, 1
|
|
|
|
|
mul cx
|
|
|
|
|
add di, ax
|
|
|
|
|
mov byte [di], 0x1F ; down
|
|
|
|
|
|
2023-03-25 22:53:02 +00:00
|
|
|
|
pop di
|
|
|
|
|
pop si
|
|
|
|
|
pop dx
|
|
|
|
|
pop cx
|
|
|
|
|
pop ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
; Window chain
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
; in:
|
|
|
|
|
; al = event
|
|
|
|
|
; bx = window to send the event to
|
|
|
|
|
; cx, dx = event-specific
|
|
|
|
|
; out:
|
|
|
|
|
; ax = event-specific, 0 if bx=0
|
|
|
|
|
send_event:
|
|
|
|
|
test bx, bx
|
|
|
|
|
jnz .non_zero_id
|
|
|
|
|
|
|
|
|
|
; Returning 0 if the window ID is 0 makes window unhooking simpler
|
|
|
|
|
xor ax, ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
.non_zero_id:
|
|
|
|
|
push bp
|
|
|
|
|
|
|
|
|
|
; Push the return address
|
|
|
|
|
push cs
|
|
|
|
|
mov bp, .end
|
|
|
|
|
push bp
|
|
|
|
|
|
|
|
|
|
; Push the address we're doing a far-call to
|
|
|
|
|
mov bp, bx
|
|
|
|
|
and bp, 0xf000 ; Highest nybble of window ID marks the segment
|
|
|
|
|
push bp
|
|
|
|
|
xor bp, bp ; Event handler is always at address 0
|
|
|
|
|
push bp
|
|
|
|
|
|
|
|
|
|
retf
|
|
|
|
|
|
|
|
|
|
.end:
|
|
|
|
|
pop bp
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
hook_self_onto_window_chain:
|
|
|
|
|
push ax
|
|
|
|
|
push es
|
|
|
|
|
|
|
|
|
|
mov ax, PONYDOS_SEG
|
|
|
|
|
mov es, ax
|
|
|
|
|
|
|
|
|
|
; Window ID is made of the segment (top nybble) and an arbitrary
|
|
|
|
|
; process-specific part (lower three nybbles). Since we only have
|
|
|
|
|
; one window, we can leave the process-specific part as zero
|
|
|
|
|
mov ax, cs
|
|
|
|
|
|
|
|
|
|
xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
|
|
|
|
|
|
|
|
|
|
; Save the old head of the chain, so that we can propagate events
|
|
|
|
|
; down to it
|
|
|
|
|
mov [window_next], ax
|
|
|
|
|
|
|
|
|
|
pop es
|
|
|
|
|
pop ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
unhook_self_from_window_chain:
|
|
|
|
|
push bx
|
|
|
|
|
push cx
|
|
|
|
|
push es
|
|
|
|
|
|
|
|
|
|
mov ax, PONYDOS_SEG
|
|
|
|
|
mov es, ax
|
|
|
|
|
|
|
|
|
|
mov al, WM_UNHOOK
|
|
|
|
|
mov bx, [es:GLOBAL_WINDOW_CHAIN_HEAD]
|
|
|
|
|
; Our window ID is just our segment, see the comment in
|
|
|
|
|
; hook_self_onto_window_chain
|
|
|
|
|
mov cx, cs
|
|
|
|
|
call send_event
|
|
|
|
|
|
|
|
|
|
; Update the head of the chain, in case we were at the head
|
|
|
|
|
mov [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
|
|
|
|
|
|
|
|
|
|
pop es
|
|
|
|
|
pop cx
|
|
|
|
|
pop bx
|
|
|
|
|
ret
|
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
; Error handling
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
; in:
|
|
|
|
|
; si = window of error type
|
|
|
|
|
; out:
|
|
|
|
|
; clobbers si, di, cx
|
|
|
|
|
raise_error:
|
|
|
|
|
mov di, window
|
|
|
|
|
mov cx, window_struc.size
|
|
|
|
|
rep movsb
|
|
|
|
|
|
|
|
|
|
call request_redraw
|
|
|
|
|
ret
|
|
|
|
|
|
2023-03-25 22:53:02 +00:00
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
; Memory management
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
2023-03-26 12:29:07 +00:00
|
|
|
|
; out:
|
|
|
|
|
; dx = segment, 0 for none found
|
|
|
|
|
allocate_segment:
|
|
|
|
|
push ax
|
|
|
|
|
push cx
|
|
|
|
|
push si
|
|
|
|
|
push es
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
xor dx, dx
|
|
|
|
|
jmp .end
|
|
|
|
|
.found_free_segment:
|
|
|
|
|
mov byte [es:si], 1 ; Mark as used
|
|
|
|
|
|
|
|
|
|
; Set up ax to point to the allocated segment
|
|
|
|
|
sub si, GLOBAL_MEMORY_ALLOCATION_MAP
|
|
|
|
|
mov cl, 12
|
|
|
|
|
shl si, cl
|
|
|
|
|
mov dx, si
|
|
|
|
|
|
|
|
|
|
.end:
|
|
|
|
|
pop es
|
|
|
|
|
pop si
|
|
|
|
|
pop cx
|
|
|
|
|
pop ax
|
|
|
|
|
ret
|
|
|
|
|
|
2023-03-25 22:53:02 +00:00
|
|
|
|
deallocate_own_memory:
|
|
|
|
|
push bx
|
|
|
|
|
push cx
|
|
|
|
|
push es
|
|
|
|
|
|
|
|
|
|
mov bx, PONYDOS_SEG
|
|
|
|
|
mov es, bx
|
|
|
|
|
|
2023-03-26 12:29:07 +00:00
|
|
|
|
cmp byte [file_opened], 0
|
|
|
|
|
je .file_not_opened
|
|
|
|
|
.file_opened:
|
|
|
|
|
mov bx, [cur_file_address + 2]
|
|
|
|
|
mov cl, 12
|
|
|
|
|
shr bx, cl
|
|
|
|
|
|
|
|
|
|
mov byte [es:GLOBAL_MEMORY_ALLOCATION_MAP + bx], 0
|
|
|
|
|
.file_not_opened:
|
|
|
|
|
|
2023-03-25 22:53:02 +00:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
; Painting
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
request_redraw:
|
|
|
|
|
push ax
|
|
|
|
|
push es
|
|
|
|
|
|
|
|
|
|
mov ax, PONYDOS_SEG
|
|
|
|
|
mov es, ax
|
|
|
|
|
|
|
|
|
|
mov byte [es:GLOBAL_REDRAW], 1
|
|
|
|
|
|
|
|
|
|
pop es
|
|
|
|
|
pop ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
; Variables
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
2023-03-26 14:35:13 +00:00
|
|
|
|
window_title times FS_DIRENT_NAME_SIZE db 0
|
2023-03-25 22:53:02 +00:00
|
|
|
|
|
|
|
|
|
cur_file_address: dw 0 ; Segment
|
|
|
|
|
dw 0
|
2023-03-26 12:29:07 +00:00
|
|
|
|
beg_file_address dw 0
|
|
|
|
|
end_file_address dw 0
|
2023-03-25 22:53:02 +00:00
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
window:
|
|
|
|
|
.x dw 24
|
|
|
|
|
.y dw 9
|
|
|
|
|
.width dw FS_DIRENT_NAME_SIZE + 2
|
|
|
|
|
.height dw 6
|
|
|
|
|
.data_address dw filename_window_data
|
|
|
|
|
|
|
|
|
|
struc window_struc
|
|
|
|
|
.x resw 1
|
|
|
|
|
.y resw 1
|
|
|
|
|
.width resw 1
|
|
|
|
|
.height resw 1
|
|
|
|
|
.data_address resw 1
|
|
|
|
|
.size:
|
|
|
|
|
endstruc
|
|
|
|
|
|
|
|
|
|
filename_window:
|
|
|
|
|
.x dw 24
|
|
|
|
|
.y dw 9
|
|
|
|
|
.width dw FS_DIRENT_NAME_SIZE + 2
|
|
|
|
|
.height dw 6
|
|
|
|
|
.data_address dw filename_window_data
|
|
|
|
|
|
|
|
|
|
text_window:
|
|
|
|
|
.x dw 17
|
|
|
|
|
.y dw 7
|
|
|
|
|
.width dw 52
|
|
|
|
|
.height dw 16
|
|
|
|
|
.data_address dw text_window_data
|
|
|
|
|
|
|
|
|
|
oom_window:
|
|
|
|
|
.x dw 30
|
|
|
|
|
.y dw 10
|
|
|
|
|
.width dw 13
|
|
|
|
|
.height dw 2
|
|
|
|
|
.data_address dw oom_window_data
|
|
|
|
|
|
|
|
|
|
ood_window:
|
|
|
|
|
.x dw 36
|
|
|
|
|
.y dw 13
|
|
|
|
|
.width dw 17
|
|
|
|
|
.height dw 2
|
|
|
|
|
.data_address dw ood_window_data
|
2023-03-25 22:53:02 +00:00
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
window_next dw 0xffff
|
2023-03-25 22:53:02 +00:00
|
|
|
|
window_mouse_released_inside db 0
|
|
|
|
|
window_status db WINDOW_STATUS_NORMAL
|
|
|
|
|
window_move_x_offset dw 0
|
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
cur_filename_address dw filename_window_data.filename
|
|
|
|
|
file_opened db 0
|
|
|
|
|
|
|
|
|
|
; pre-built windows
|
2023-03-26 12:29:07 +00:00
|
|
|
|
CANCEL_COLOR equ 0x80
|
|
|
|
|
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
|
|
|
|
|
; blank line
|
|
|
|
|
times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70
|
|
|
|
|
; filename
|
|
|
|
|
db 0, 0x70
|
|
|
|
|
.filename:
|
|
|
|
|
times FS_DIRENT_NAME_SIZE db 0, 0xf0
|
|
|
|
|
db 0, 0x70
|
|
|
|
|
; blank line
|
|
|
|
|
times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70
|
|
|
|
|
; buttons line
|
|
|
|
|
times 7 db 0, 0x70
|
|
|
|
|
db 0, 0x80, 'C', 0x80, 'a', 0x80, 'n', 0x80, 'c', 0x80, 'e', 0x80, 'l', 0x80, 0, 0x80
|
|
|
|
|
times 5 db 0, 0x70
|
|
|
|
|
db 0, 0x20, 'O', 0x20, 'K', 0x20, 0x, 0x20
|
|
|
|
|
times 8 db 0, 0x70
|
|
|
|
|
; blank line
|
|
|
|
|
times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70
|
|
|
|
|
|
2023-03-27 10:34:52 +00:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2023-03-25 22:53:02 +00:00
|
|
|
|
section .bss
|
2023-03-26 12:29:07 +00:00
|
|
|
|
text_window_data resw ROWS*COLUMNS
|