diff --git a/edlin.asm b/edlin.asm index 8a3626c..4ac48db 100644 --- a/edlin.asm +++ b/edlin.asm @@ -68,11 +68,16 @@ int_ctrl_break equ 0x23 db 0x8b, 0xc0 + 8 * %1 + %2 %endmacro -%macro cmp_byteaddr_bytext 2 +; Sign extended byte to byte +%macro cmpb_addr_ext 2 db 0x82, 0x3e ; cmp byte […], byte +… (extended) dw %1 db %2 %endmacro +%macro cmpb_ext 2 + db 0x82, 0xf8 + %1 + db %2 +%endmacro jmp entrypoint @@ -95,7 +100,7 @@ entrypoint: ; 0181 mov sp, stack.end ensure_file_argument: - cmp_byteaddr_bytext psp_fcb_1 + fcb_filename, ' ' + cmpb_addr_ext psp_fcb_1 + fcb_filename, ' ' je print_filename_missing_error ; AL at program start a flag of whether drive specifier in first parameter valid @@ -166,7 +171,7 @@ setup_file_parameters: ; 01ec mov [psp_fcb_1 + fcb_record_size], ax mov [__0a58_fcb + fcb_record_size], ax - mov dx, disk_transfer_area + mov dx, file_buffer movw r_di, r_dx mov ah, sys_set_dta int 0x21 @@ -176,10 +181,10 @@ setup_file_parameters: ; 01ec mov [__0a98], cx test byte [new_file_flag], 0xff - jnz __0240 + jnz initialize_editor - sub cx, disk_transfer_area - ; cx is now the amount of memory available starting at disk_transfer_area + sub cx, file_buffer + ; cx is now the amount of memory available starting at file_buffer ; __0a94 = ¼ available memory shr cx, 1 @@ -190,33 +195,37 @@ setup_file_parameters: ; 01ec addw r_cx, r_ax movw r_dx, r_cx - add dx, disk_transfer_area + add dx, file_buffer mov [__0a96], dx read_file: mov dx, psp_fcb_1 mov ah, sys_random_block_read int 0x21 + call find_file_end_char addw r_di, r_cx -__0240: +initialize_editor: ; 0240 cld + ; Put ^Z at the end of the file in memory mov byte [di], 0x1a ; ^Z + mov [__0a9a], di mov byte [input_buffer.size], input_buffer.bufend - input_buffer.bufstart mov byte [__0c1e], 0xff ; magic mov byte [__0d48], 0x0a ; magic - mov word [__0a92], disk_transfer_area - mov word [__0a90], 1 ; magic + mov word [__0a92], file_buffer + mov word [current_line], 1 mov word [__0a80], 1 ; magic test byte [new_file_flag], 0xff - jnz __0273 + jnz editor_mainloop + call __0370 -__0273: +editor_mainloop: ; 0273 mov sp, stack.end mov ax, sys_set_interrupt * 0x100 + int_ctrl_break mov dx, ctrl_break_handler @@ -230,12 +239,15 @@ __0273: mov ah, sys_read_line int 0x21 -db 0xB0, 0x0A ; 028A mov al,0xa -db 0xE8, 0x95, 0x06 ; 028C call 0x924 -db 0xC7, 0x06, 0x82, 0x0A, 0x00, 0x00 ; 028F mov word [0xa82],0x0 -db 0xC6, 0x06, 0x7D, 0x0A, 0x00 ; 0295 mov byte [0xa7d],0x0 -db 0xBE, 0x9E, 0x0A ; 029A mov si,0xa9e -db 0xE8, 0x59, 0x00 ; 029D call 0x2f9 + mov al, 10 ; LF + call print_char + + mov word [__0a82], 0 + mov byte [__0a7d], 0 + + mov si, input_buffer.bufstart + call parse_line_specifier + db 0x89, 0x16, 0x80, 0x0A ; 02A0 mov [0xa80],dx db 0xE8, 0x43, 0x00 ; 02A4 call 0x2ea db 0x3C, 0x2C ; 02A7 cmp al,0x2c @@ -265,50 +277,79 @@ db 0x72, 0x0F ; 02DE jc 0x2ef db 0xD1, 0xE3 ; 02E0 shl bx,1 db 0xFF, 0x97, 0x4A, 0x03 ; 02E2 call [bx+0x34a] db 0xE9, 0x8A, 0xFF ; 02E6 jmp 0x273 -db 0xAC ; 02E9 lodsb -db 0x3C, 0x20 ; 02EA cmp al,0x20 -db 0x74, 0xFB ; 02EC jz 0x2e9 -db 0xC3 ; 02EE ret -db 0xBA, 0xF5, 0x09 ; 02EF mov dx,0x9f5 -db 0xB4, 0x09 ; 02F2 mov ah,0x9 -db 0xCD, 0x21 ; 02F4 int 0x21 -db 0xE9, 0x7A, 0xFF ; 02F6 jmp 0x273 -db 0xE8, 0xED, 0xFF ; 02F9 call 0x2e9 -db 0x3C, 0x2E ; 02FC cmp al,0x2e -db 0x74, 0x35 ; 02FE jz 0x335 -db 0x3C, 0x23 ; 0300 cmp al,0x23 -db 0x74, 0x37 ; 0302 jz 0x33b -db 0xBA, 0x00, 0x00 ; 0304 mov dx,0x0 -db 0xB1, 0x00 ; 0307 mov cl,0x0 -db 0x3C, 0x30 ; 0309 cmp al,0x30 -db 0x72, 0x1E ; 030B jc 0x32b -db 0x3C, 0x39 ; 030D cmp al,0x39 -db 0x77, 0x1A ; 030F ja 0x32b -db 0x81, 0xFA, 0x99, 0x19 ; 0311 cmp dx,0x1999 -db 0x73, 0xD8 ; 0315 jnc 0x2ef -db 0xB1, 0x01 ; 0317 mov cl,0x1 -db 0x2C, 0x30 ; 0319 sub al,0x30 -db 0x8B, 0xDA ; 031B mov bx,dx -db 0xD1, 0xE2 ; 031D shl dx,1 -db 0xD1, 0xE2 ; 031F shl dx,1 -db 0x03, 0xD3 ; 0321 add dx,bx -db 0xD1, 0xE2 ; 0323 shl dx,1 -db 0x98 ; 0325 cbw -db 0x03, 0xD0 ; 0326 add dx,ax -db 0xAC ; 0328 lodsb -db 0xEB, 0xDE ; 0329 jmp short 0x309 -db 0x82 ; 032B db 0x82 -db 0xF9 ; 032C stc -db 0x00, 0x74, 0xBE ; 032D add [si-0x42],dh -db 0x0B, 0xD2 ; 0330 or dx,dx -db 0x74, 0xBB ; 0332 jz 0x2ef -db 0xC3 ; 0334 ret -db 0x8B, 0x16, 0x90, 0x0A ; 0335 mov dx,[0xa90] -db 0xAC ; 0339 lodsb -db 0xC3 ; 033A ret -db 0xBA, 0xFE, 0xFF ; 033B mov dx,0xfffe -db 0xAC ; 033E lodsb -db 0xC3 ; 033F ret + +skip_spaces: ; 02e9 + lodsb + cmp al, ' ' + je skip_spaces + .ret: ret + +print_entry_error: ; 02ef + mov dx, entry_error + mov ah, sys_print_string + int 0x21 + jmp editor_mainloop + +parse_line_specifier: ; 02f9 + call skip_spaces + cmp al, '.' + je .current_line + cmp al, '#' + je .last_line + + mov dx, 0 + mov cl, 0 ; No digits read yet + + .loop: ; 0309 + cmp al, '0' + jb .not_digit + cmp al, '9' + ja .not_digit + + ; Would we overflow? + cmp dx, 65536 / 10 + jnb print_entry_error ; Yes + + mov cl, 1 ; We have now read a digit + + sub al, '0' + + ; dx = dx*10 + movw r_bx, r_dx + shl dx, 1 + shl dx, 1 + addw r_dx, r_bx + shl dx, 1 + + cbw + addw r_dx, r_ax + + lodsb + + jmp .loop + + .not_digit: ; 032b + ; Have we started reading a number? + cmpb_ext r_cl, 0 + je skip_spaces.ret ; No + + ; Yes, and it's zero + orw r_dx, r_dx + jz print_entry_error + + ; Yes, it's nonzero + ret + + .current_line: ; 0335 + mov dx, [current_line] + lodsb + ret + + .last_line: ; 033b + mov dx, 0xfffe ; TODO: Why 0xfffe and not 0xffff? + lodsb + ret + db 0x51 ; 0340 push cx db 0x57 ; 0341 push di db 0x41 ; 0342 inc cx @@ -358,7 +399,7 @@ __0370: jnz __0388 cmp dx, [__0a96] - jnc find_file_end_char.ret + jnb find_file_end_char.ret __0388: movw r_di, r_dx @@ -388,7 +429,7 @@ __03ab: movw r_ax, r_di addw r_ax, r_cx cmp ax, [__0a96] - jna __03ca ; disambiguate + jna __03ca mov di, [__0a96] movw r_cx, r_ax @@ -870,7 +911,7 @@ oom: ; 080c mov dx, oom_str mov ah, sys_print_string int 0x21 - jmp __0273 + jmp editor_mainloop db 0xB8, 0x23, 0x25 ; 0816 mov ax,0x2523 db 0xBA, 0x7D, 0x08 ; 0819 mov dx,0x87d @@ -1004,7 +1045,7 @@ ctrl_break_handler: ; 092d call newline - jmp __0273 + jmp editor_mainloop bak_extension db "BAK" ; 093e @@ -1014,7 +1055,7 @@ bak_error db "Cannot edit .BAK file--rename file$" ; 0978 directory_full_error db "No room in directory for file$" ; 099b __09b9 db "Disk full--file write not completed$" oom_str db 13, 10, "Insufficient memory", 13, 10, '$' ; 09dd -__09f5 db "Entry error", 13, 10, '$' +entry_error db "Entry error", 13, 10, '$' ; 09f5 new_file_str db "New file", 13, 10, '$' ; 0a03 __0a0e db "Not found", 13, 10, '$' __0a1a db "O.K.? $" @@ -1026,15 +1067,15 @@ __0a45 db "Abort edit (Y/N)? $" section .bss __0a58_fcb: resb 37 ; 0a58 … 0a7c -; 0a7d -resb 1 +__0a7d: resb 1 new_file_flag: resb 1 ; 0a7e __0a7f: resb 1 __0a80: resw 1 -resb 14 -__0a90: resw 1 +__0a82: resw 1 +resb 12 +current_line: resw 1 ; 0a90 __0a92: resw 1 __0a94: resw 1 @@ -1060,4 +1101,4 @@ stack: resb 256 ; 0c48 __0d48: resb 1 -disk_transfer_area: ; 0d49 +file_buffer: ; 0d49