diff --git a/README.md b/README.md index 776e02c..b7ef551 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,9 @@ Feel free to add anything you think would fit in * refactor shell.asm a bit: - add/verify function header comments -* basic error handling in viewer -* error pop-ups in all programs * a release-able README ### Nice to have +* more file listing windows * ponysay diff --git a/shell.asm b/shell.asm index a5cc345..0d7353d 100644 --- a/shell.asm +++ b/shell.asm @@ -75,7 +75,7 @@ initialize: ; Initialize file window but don't show it mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.width], 40 - mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.height], 16 + mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.height], 17 mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.x], 10 mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.y], 4 mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.data], file_window diff --git a/viewer.asm b/viewer.asm index a0d3df5..5ec075f 100644 --- a/viewer.asm +++ b/viewer.asm @@ -130,7 +130,10 @@ filename_char_del: ; out: ; clobbers everything filename_ok: - ; TODO: error management for empty file filename + ; Just ignore if there's no filename. + cmp byte [filename_window_data.filename], 0 + je .end + mov cx, FS_DIRENT_NAME_SIZE mov di, window_title mov si, filename_window_data.filename @@ -142,9 +145,22 @@ filename_ok: mov si, window_title xor dx, dx ; do create empty file - call PONYDOS_SEG:SYS_OPEN_FILE ; TODO: error management + call PONYDOS_SEG:SYS_OPEN_FILE + test ax, ax + jnz .got_file + mov si, ood_window + call raise_error + ret - call allocate_segment ; TODO: error management + .got_file: + call allocate_segment + test dx, dx + jnz .got_memory + mov si, oom_window + call raise_error + ret + + .got_memory: mov [cur_file_address + 2], dx mov word [cur_file_address], 0 mov word [beg_file_address], 0 @@ -153,7 +169,7 @@ filename_ok: mov es, dx xor bx, bx xor di, di ; read - call PONYDOS_SEG:SYS_MODIFY_SECTORS ; TODO: error management + call PONYDOS_SEG:SYS_MODIFY_SECTORS pop es mov ch, cl @@ -161,22 +177,17 @@ filename_ok: 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 si, text_window + mov di, window + mov cx, window_struc.size + rep movsb mov byte [file_opened], 1 call render_window call request_redraw + .end: ret ; ------------------------------------------------------------------ @@ -196,9 +207,9 @@ print_file: lds si, [cur_file_address] - mov cx, [cs:window_height] + mov cx, [cs:window.height] dec cx - mov dx, [cs:window_width] + mov dx, [cs:window.width] mov bl, 1 ; Haven't read anything yet .window_loop: push di @@ -233,11 +244,11 @@ print_file: dec dx jnz .line_loop .next_line: - mov dx, [cs:window_width] + mov dx, [cs:window.width] pop di - add di, [cs:window_width] - add di, [cs:window_width] + add di, [cs:window.width] + add di, [cs:window.width] loop .window_loop .ret: @@ -355,16 +366,12 @@ 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 di, [window_x] - mov bp, [window_y] + 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] cmp di, 0 jge .not_clip_left @@ -439,16 +446,16 @@ event_mouse: .not_resizing: ; Check if the mouse is outside our window - cmp cx, [window_x] + cmp cx, [window.x] jl .outside ; x < window_x - cmp bx, [window_y] + cmp bx, [window.y] jl .outside ; y < window_y - mov ax, [window_x] - add ax, [window_width] + mov ax, [window.x] + add ax, [window.width] cmp ax, cx jle .outside ; window_x + window_width <= x - mov ax, [window_y] - add ax, [window_height] + mov ax, [window.y] + add ax, [window.height] cmp ax, bx jle .outside ; window_y + window_height <= y @@ -519,30 +526,24 @@ event_click: call request_redraw ; Did the user click the title bar? - cmp [window_y], bx + cmp [window.y], bx jne .not_title_bar .title_bar: ; Did the user click the window close button? - mov ax, [window_x] - add ax, [window_width] + mov ax, [window.x] + add ax, [window.width] dec ax cmp ax, cx jne .not_close .close: - call unhook_self_from_window_chain - ; Nothing can call into us again after we unhook - ; the window, so deallocate the memory we have - ; reserved - call deallocate_own_memory - ; We don't need to call request_redraw here, since - ; it will be called unconditionally above + call close_window jmp .end .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 + cmp [window.x], cx jne .not_resize .resize: mov byte [window_status], WINDOW_STATUS_RESIZE @@ -552,7 +553,7 @@ event_click: ; Clicking on the title bar signals beginning of a window ; move mov byte [window_status], WINDOW_STATUS_MOVE - mov ax, [window_x] + mov ax, [window.x] sub ax, cx mov [window_move_x_offset], ax jmp .end @@ -561,10 +562,10 @@ event_click: cmp byte [file_opened], 0 jne .not_filename_window .filename_window: - sub bx, [window_y] - sub cx, [window_x] + sub bx, [window.y] + sub cx, [window.x] - mov ax, [window_width] + mov ax, [window.width] shl ax, 1 mul bx add ax, cx @@ -589,14 +590,14 @@ event_click: jmp .end .not_filename_window: - mov ax, [window_x] - add ax, [window_width] + mov ax, [window.x] + add ax, [window.width] dec ax cmp ax, cx jne .not_scroll_bar ; Scroll up button? - mov ax, [window_y] + mov ax, [window.y] inc ax cmp ax, bx jne .not_scroll_up @@ -611,7 +612,7 @@ event_click: .not_scroll_up: ; Scroll down button? - add ax, [window_height] + add ax, [window.height] dec ax dec ax cmp ax, bx @@ -640,6 +641,8 @@ event_click: event_keyboard: cmp byte [file_opened], 0 jne .file_opened + cmp word [window.data_address], filename_window_data + jne .ret ; error windows .file_not_opened: cmp ch, 0x0e jne .not_backspace @@ -736,6 +739,27 @@ event_unhook: ; Event handler subroutines ; ------------------------------------------------------------------ +; 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 + ; in: ; bx = Y ; cx = X @@ -748,15 +772,15 @@ move_window: add ax, [window_move_x_offset] ; Only do an update if something has changed. Reduces flicker - cmp [window_x], ax + cmp [window.x], ax jne .update_location - cmp [window_y], bx + cmp [window.y], bx jne .update_location jmp .end .update_location: - mov [window_x], ax - mov [window_y], bx + mov [window.x], ax + mov [window.y], bx call request_redraw .end: @@ -772,8 +796,8 @@ resize_window: push bp ; Calculate new width - mov ax, [window_width] - add ax, [window_x] + mov ax, [window.width] + add ax, [window.x] sub ax, cx cmp ax, WINDOW_MIN_WIDTH @@ -787,8 +811,8 @@ resize_window: .width_small_enough: ; Calculate new height - mov bp, [window_height] - add bp, [window_y] + mov bp, [window.height] + add bp, [window.y] sub bp, bx cmp bp, WINDOW_MIN_HEIGHT @@ -802,24 +826,24 @@ resize_window: .height_small_engough: ; Only do an update if something has changed. Reduces flicker - cmp [window_width], ax + cmp [window.width], ax jne .update_size - cmp [window_height], bp + cmp [window.height], bp jne .update_size jmp .end .update_size: - mov bx, [window_x] - add bx, [window_width] + mov bx, [window.x] + add bx, [window.width] sub bx, ax - mov [window_x], bx - mov [window_width], ax + mov [window.x], bx + mov [window.width], ax - mov bx, [window_y] - add bx, [window_height] + mov bx, [window.y] + add bx, [window.height] sub bx, bp - mov [window_y], bx - mov [window_height], bp + mov [window.y], bx + mov [window.height], bp call render_window @@ -839,8 +863,8 @@ render_window: ; Clear window to be black-on-white mov di, text_window_data - mov ax, [window_width] - mov cx, [window_height] + mov ax, [window.width] + mov cx, [window.height] mul cx mov cx, ax mov ax, 0xf000 ; Attribute is in the high byte @@ -849,14 +873,14 @@ render_window: ; Set title bar to be white-on-black mov di, text_window_data mov ax, 0x0f00 - mov cx, [window_width] + mov cx, [window.width] rep stosw ; Add title bar buttons mov di, text_window_data mov byte [di], 0x17 ; Resize arrow - add di, [window_width] - add di, [window_width] + add di, [window.width] + add di, [window.width] sub di, 2 mov byte [di], 'x' ; Close button @@ -864,7 +888,7 @@ render_window: mov di, text_window_data add di, 2 mov si, window_title - mov cx, [window_width] + mov cx, [window.width] dec cx dec cx cmp cx, FS_DIRENT_NAME_SIZE @@ -878,17 +902,17 @@ render_window: ; Print text mov di, text_window_data - add di, [window_width] - add di, [window_width] + add di, [window.width] + add di, [window.width] call print_file - add di, [window_width] - add di, [window_width] + add di, [window.width] + add di, [window.width] sub di, 2 mov byte [di], 0x1E ; up - mov ax, [window_width] - mov cx, [window_height] + mov ax, [window.width] + mov cx, [window.height] sub cx, 2 shl cx, 1 mul cx @@ -986,6 +1010,22 @@ unhook_self_from_window_chain: pop bx ret +; ------------------------------------------------------------------ +; 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 + ; ------------------------------------------------------------------ ; Memory management ; ------------------------------------------------------------------ @@ -1083,21 +1123,59 @@ cur_file_address: dw 0 ; Segment beg_file_address dw 0 end_file_address dw 0 +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 + window_next dw 0xffff -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 +cur_filename_address dw filename_window_data.filename +file_opened db 0 + +; pre-built windows CANCEL_COLOR equ 0x80 OK_COLOR equ 0x20 filename_window_data: @@ -1123,8 +1201,21 @@ filename_window_data: ; blank line times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70 -cur_filename_address dw filename_window_data.filename -file_opened db 0 - +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 + section .bss text_window_data resw ROWS*COLUMNS