diff --git a/viewer.asm b/viewer.asm index 038a68b..978a5c9 100644 --- a/viewer.asm +++ b/viewer.asm @@ -15,49 +15,14 @@ jmp near process_event ; 0x0003 PROC_INITIALIZE_ENTRYPOINT ; initialize needs to preserve ds -; in: -; ds:si = text filename -; ax:bx = file address -; cx = text file size in sectors initialize: push ds - ; Setup the input parameters for now - mov bp, cs - mov ds, bp - mov si, tmp_window_title - mov dx, 1 - call PONYDOS_SEG:SYS_OPEN_FILE ; TODO: error - - mov dx, 0xF000 - mov es, dx - xor bx, bx - xor di, di ; read - call PONYDOS_SEG:SYS_MODIFY_SECTORS - mov ax, es - ; End of temporary set-up - ; On entry, ds and es will not be set correctly for us mov bp, cs mov es, bp - - push cx - call strlen - mov di, window_title - rep movsb - pop cx - mov ds, bp - mov [cur_file_address + 2], ax - mov [cur_file_address], bx - mov [beg_file_address], bx - mov ch, cl - xor cl, cl - shl cx, 1 ; Multiply by 512 - add bx, cx - mov [end_file_address], bx - call hook_self_onto_window_chain call render_window @@ -126,7 +91,95 @@ process_event: retf ; ------------------------------------------------------------------ -; File handlers +; Filename handling +; ------------------------------------------------------------------ + +; in: +; cl = typed character +; ch = pressed key +; out: +; clobbers bx +filename_char_add: + cmp word [cur_filename_address], filename_window_data.filename + 2*FS_DIRENT_NAME_SIZE + 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: + 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 + call PONYDOS_SEG:SYS_OPEN_FILE ; TODO: error management + + call allocate_segment ; TODO: error management + 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 + call PONYDOS_SEG:SYS_MODIFY_SECTORS ; TODO: error management + pop es + + mov ch, cl + xor cl, cl + shl cx, 1 ; Multiply by 512 + mov [end_file_address], cx + + ; TODO: does this need to be restructured to be more safe to mouse + ; interrupts? (I think not.) + mov ax, [text_window_width] + mov [window_width], ax + mov ax, [text_window_height] + mov [window_height], ax + mov ax, [text_window_x] + mov [window_x], ax + mov ax, [text_window_y] + mov [window_y], ax + + mov byte [file_opened], 1 + + call render_window + call request_redraw + + ret + +; ------------------------------------------------------------------ +; Text file handling ; ------------------------------------------------------------------ ; in: @@ -195,7 +248,7 @@ print_file: pop bx pop ax ret - + .end_window_loop: pop di jmp .ret @@ -301,10 +354,14 @@ event_paint: mov bx, [window_next] call send_event + mov si, filename_window_data + cmp byte [file_opened], 0 + je .file_not_opened + mov si, text_window_data + .file_not_opened: mov bx, [window_width] ; Buffer width, usually same as window width mov cx, [window_width] mov dx, [window_height] - mov si, window_data mov di, [window_x] mov bp, [window_y] @@ -482,6 +539,8 @@ event_click: .not_close: ; Did the user click on the resize button? + cmp byte [file_opened], 0 + je .not_resize ; Can't resize while entering filename cmp [window_x], cx jne .not_resize .resize: @@ -498,6 +557,37 @@ event_click: jmp .end .not_title_bar: + cmp byte [file_opened], 0 + jne .not_filename_window + .filename_window: + sub bx, [window_y] + sub cx, [window_x] + + mov ax, [window_width] + 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: mov ax, [window_x] add ax, [window_width] dec ax @@ -547,6 +637,25 @@ event_click: ; out: ; clobbers everything event_keyboard: + cmp byte [file_opened], 0 + jne .file_opened + .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: cmp ch, 0x50 ; down key jne .up_key_check .down_key: @@ -728,7 +837,7 @@ render_window: push di ; Clear window to be black-on-white - mov di, window_data + mov di, text_window_data mov ax, [window_width] mov cx, [window_height] mul cx @@ -737,13 +846,13 @@ render_window: rep stosw ; Set title bar to be white-on-black - mov di, window_data + mov di, text_window_data mov ax, 0x0f00 mov cx, [window_width] rep stosw ; Add title bar buttons - mov di, window_data + mov di, text_window_data mov byte [di], 0x17 ; Resize arrow add di, [window_width] add di, [window_width] @@ -751,7 +860,7 @@ render_window: mov byte [di], 'x' ; Close button ; Add window title - mov di, window_data + mov di, text_window_data add di, 2 mov si, window_title mov cx, [window_width] @@ -767,7 +876,7 @@ render_window: loop .copy_title ; Print text - mov di, window_data + mov di, text_window_data add di, [window_width] add di, [window_width] call print_file @@ -880,6 +989,42 @@ unhook_self_from_window_chain: ; Memory management ; ------------------------------------------------------------------ +; 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 + deallocate_own_memory: push bx push cx @@ -888,7 +1033,16 @@ deallocate_own_memory: mov bx, PONYDOS_SEG mov es, bx - ; Segment 0xn000 corresponds to slot n in the allocation table + 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: + mov bx, cs mov cl, 12 shr bx, cl @@ -954,18 +1108,51 @@ window_title times FS_DIRENT_NAME_SIZE + 1 db 0 cur_file_address: dw 0 ; Segment dw 0 -beg_file_address: dw 0 -end_file_address: dw 0 +beg_file_address dw 0 +end_file_address dw 0 window_next dw 0xffff -window_x dw 17 -window_y dw 7 -window_width dw 52 -window_height dw 16 +window_x dw 24 +window_y dw 9 +window_width dw FS_DIRENT_NAME_SIZE + 2 +window_height dw 6 + +text_window_x dw 17 +text_window_y dw 7 +text_window_width dw 52 +text_window_height dw 16 window_mouse_released_inside db 0 window_status db WINDOW_STATUS_NORMAL window_move_x_offset dw 0 +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 + +cur_filename_address dw filename_window_data.filename +file_opened db 0 + section .bss -window_data resw ROWS*COLUMNS +text_window_data resw ROWS*COLUMNS