%include "ponydos.inc" struc window .next resw 1 .width resw 1 .height resw 1 .x resw 1 .y resw 1 .data resw 1 .size: endstruc cpu 8086 bits 16 org 0 ; 0x0000 jmp near process_event ; 0x0003 initialize: push ds push cs pop ds ; Set wallpaper mov si, wallpaper_name xor dx, dx call PONYDOS_SEG:SYS_OPEN_FILE mov bp, PONYDOS_SEG mov es, bp mov bx, GLOBAL_WALLPAPER xor di, di ; read call PONYDOS_SEG:SYS_MODIFY_SECTORS ; Create window 1 mov ax, cs add ax, 0x000 xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax mov [windows + 0*window.size + window.next], ax mov word [windows + 0*window.size + window.width], 16 mov word [windows + 0*window.size + window.height], 4 mov word [windows + 0*window.size + window.x], 10 mov word [windows + 0*window.size + window.y], 3 mov word [windows + 0*window.size + window.data], window_1 ; Create window 2 mov ax, cs add ax, 0x001 xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax mov [windows + 1*window.size + window.next], ax mov word [windows + 1*window.size + window.width], 40 mov word [windows + 1*window.size + window.height], 4 mov word [windows + 1*window.size + window.x], 14 mov word [windows + 1*window.size + window.y], 6 mov word [windows + 1*window.size + window.data], window_2 call request_redraw ; Temporary testing mov ax, cs mov es, ax mov di, window_1 + 32 mov cx, 3 mov dx, 16 call print_ls mov di, window_2 + 80 mov cx, 3 mov dx, 40 call print_ls pop ds retf process_event: push ax push bx push cx push dx push si push di push bp push ds push es mov bp, cs mov ds, bp mov es, bp cmp ax, WM_PAINT jne .not_paint call paint .not_paint: cmp ax, WM_MOUSE jne .not_mouse call mouse .not_mouse: pop es pop ds pop bp pop di pop si pop dx pop cx pop bx pop ax retf paint: call get_window mov bx, [si + window.next] call forward_event ; Draw a rectangle on-screen mov bx, [si + window.width] mov cx, bx mov dx, [si + window.height] mov di, [si + window.x] mov bp, [si + window.y] mov si, [si + window.data] call PONYDOS_SEG:SYS_DRAW_RECT ret mouse: call get_window push cx ; Y xor bx, bx mov bl, ch ; X xor ch, ch cmp cx, [si + window.x] jl .outside cmp bx, [si + window.y] jl .outside sub cx, [si + window.x] cmp [si + window.width], cx jle .outside sub bx, [si + window.y] cmp [si + window.height], bx jle .outside mov si, [si + window.data] add si, 18 test dl, MOUSE_PRIMARY jz .not_clicking .clicking: mov al, '*' xchg byte [si], al cmp al, '*' je .end call request_redraw jmp .end .not_clicking: mov al, ' ' xchg byte [si], al cmp al, ' ' je .end call request_redraw .end: pop cx ret .outside: pop cx mov bx, [si + window.next] call forward_event ret ; in: ; bx = valid window id for this process ; out: ; si = pointer to window's data block get_window: mov si, cs sub bx, si mov si, windows push ax push dx mov ax, window.size mul bx add si, ax pop dx pop ax ret request_redraw: push es push bp mov bp, PONYDOS_SEG mov es, bp mov byte [es:GLOBAL_REDRAW], 1 pop bp pop es ret ; in ; cx = height of window (>= 1) ; dx = width of window in characters ; es:di = start of output print_ls: push ax push bx push cx push si push di push bp push ds mov bp, PONYDOS_SEG mov ds, bp push cx push di mov si, GLOBAL_DIRENTS + 2 xor ax, ax ; Maximum filename size .name_loop: cmp word [ds:si - 2], 0 je .done_names push cx call strlen mov bx, cx pop cx cmp bx, dx jle .not_long_filename mov bx, dx .not_long_filename: cmp ax, bx jge .not_new_max mov ax, bx .not_new_max: push si push di .copy: movsb inc di ; Formatting dec bx jnz .copy pop di pop si ; Move to next line add di, dx add di, dx add si, FS_DIRENT_SIZE cmp si, GLOBAL_DIRENTS + 0x200 jge .done_names dec cx jnz .name_loop .done_names: pop di pop cx ; Don't print sizes for too short a window cmp dx, 10 jle .done add ax, 5 ; 1 whitespace, 4 length cmp ax, dx jle .not_truncate mov ax, dx .not_truncate: sub ax, 5 ; Go to start of where to put the file length add di, ax add di, ax mov si, GLOBAL_DIRENTS .size_loop: mov ax, word [ds:si] test ax, ax jz .done mov byte [es:di + 8], 'K' shr ax, 1 aam ; mango add ax, 0x3030 cmp ah, 0x30 je .one_digit mov byte [es:di + 2], ' ' mov [es:di + 4], ah jmp .one_digit_print .one_digit: test word [ds:si], 1 jnz .one_and_half_digit mov byte [es:di + 4], ' ' .one_digit_print: mov [es:di + 6], al jmp .next_iter_size_loop .one_and_half_digit: mov byte [es:di], ' ' mov byte [es:di + 2], al mov byte [es:di + 4], '.' mov byte [es:di + 6], '5' .next_iter_size_loop: ; Move to next line add di, dx add di, dx add si, FS_DIRENT_SIZE cmp si, GLOBAL_DIRENTS + 0x200 jge .done dec cx jnz .size_loop .done: pop ds pop bp pop di pop si pop cx pop bx pop ax ret ; in: ; ds:si = string ; out: ; cx = stlen strlen: push ax push di push es mov cx, ds mov es, cx mov di, si mov cx, -1 xor ax, ax repne scasb not cx dec cx pop es pop di pop ax ret ; in: ; bx = window ID ; out: ; clobbers bp forward_event: cmp bx, 0 je .end push cs ; Return segment mov bp, .end push bp ; Return offset mov bp, 0xf000 and bp, bx push bp ; Call segment xor bp, bp push bp ; Call offset retf .end: ret wallpaper_name db 'wallpaper.bin', 0 %include "debug.inc" window_1: db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f, '1', 0x0f times 8 db ' ', 0x0f times 16 db ' ', 0xf0 times 16 db ' ', 0xf0 times 16 db ' ', 0xf0 window_2: db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f, '2', 0x0f times 32 db ' ', 0x0f times 40 db ' ', 0xf0 times 40 db ' ', 0xf0 times 40 db ' ', 0xf0 windows: times window.size db 0 times window.size db 0