ED: Gotten l (list) working, need to work more on d (delete) as there's a bug with deleting lines that are not line 1.

This commit is contained in:
deadvey
2026-03-11 21:16:52 +00:00
parent 88716c0b64
commit 245cfa57f3
8 changed files with 234 additions and 84 deletions

View File

@@ -1,21 +1,34 @@
; Planned commands:
; i insert
; a append
; d delete
; l prints lines
; w save to disk
; q quit
; [ ] i insert
; [ ] a append
; [-] d delete
; [x] l prints lines
; [ ] w save to disk
; [x] q quit
ed:
pusha
call .determine_line_count
call determine_line_count
.main_loop:
; CLEAR VARIABLES
mov [ed_start_int], 0
mov [ed_end_int], 0
mov [ed_operation_from], 0
mov [ed_operation_by], 0
; Setup prompt
mov ax, ed_prompt
mov bx, 40
call keyboard_display_input ; AX = string location, BX = max prompt length
cmp bx, 1 ; I user pressed escape
je .quit
mov si, ed_prompt
mov bx, 0 ; Keeps track of whether comma has passed
jmp .get_token
.error:
call ed_error
jmp .main_loop
; Types of tokens:
; Number: eg 123
; Doller (refers to the last line) $
@@ -29,6 +42,10 @@ ed:
cmp al, ','
je .comma
; DOLLAR SIGN
cmp al, '$'
je .dollar
; NUMBER
call check_is_number
jc .get_number_token
@@ -36,24 +53,17 @@ ed:
; COMMAND
call check_is_letter
jc .get_letter_token
.error: ; Output ?
mov ah, 0Eh
mov al, '?'
int 10h
mov al, 0Ah
int 10h
mov al, 0Dh
int 10h
jmp .main_loop
jmp .error
; Assign a number to either the start or end int (start,end)
.dollar:
mov ax, [ed_line_count]
inc si ; Cancel out the last dec si
jmp .after_int_cast
.get_number_token:
push si
dec si
call string_cast_to_int ; AX = integer
call string_cast_to_int ; AX = integer, DX = length of int string
.after_int_cast:
cmp bx, 0
je .assign_start_int
jg .assign_end_int
@@ -62,97 +72,208 @@ ed:
jmp .after_int_assign
.assign_end_int:
mov [ed_end_int], ax
; Check it's not after the end of the file
cmp ax, [ed_line_count]
jg .error
; Check it's not less than the start int
cmp ax, [ed_start_int]
jl .error
.after_int_assign:
pop si
dec si
jmp .get_token
; Determines a command
.get_letter_token:
; If ed int
cmp [ed_end_int], 0
je .set_end_int
.after_end_int_check:
cmp al, 'l'
je .list
cmp al, 'd'
je .delete
cmp al, 'q'
je .quit
jmp .get_token
call ed_error
jmp .main_loop
; If no end int is assigned, set it to the start int
.set_end_int:
cmp bx,0
push ax
jne .end_int_to_end ; If , has been passed
.end_int_to_start_int:
mov ax, [ed_start_int]
mov [ed_end_int], ax
pop ax
jmp .after_end_int_check
.end_int_to_end:
mov ax, [ed_line_count]
mov [ed_end_int], ax
pop ax
jmp .after_end_int_check
; Changes the value from start int to end int
.comma:
mov bx, 1
jmp .get_token
.determine_line_count:
mov si, file_buffer
mov dx, file_length ; STORES THE LENGTH OF THE FILE IN BYTES
xor cx,cx
.line_count_loop:
lodsb
cmp al, 0Ah
je .increment_line_count
dec dx
cmp dx, 0
jg .line_count_loop
mov [ed_line_count], cx
jmp .main_loop
.increment_line_count:
inc cx
jmp .line_count_loop
; COMMANDS
; DELETE ;
.delete:
; Adjust the ed line count
mov ax,[ed_end_int]
sub ax,[ed_start_int] ; difference in the lines
inc ax
sub [ed_line_count], ax
; set up registers to shift data left
mov bx, ed_end_int
; Get the byte of where the left shift will start
mov bx, [ed_end_int]
inc bx
call get_byte_of_line ; CX = byte of start of new line (relative to file buffer)
mov [ed_shift_from], cx
mov [ed_operation_from], cx
mov bx, ed_start_int
; Get the number of bytes to shift left by
mov bx, [ed_start_int]
call get_byte_of_line
mov ax, ed_start_int
mov ax, [ed_operation_from]
sub ax, cx
mov [ed_shift_by], ax
mov [ed_operation_by], ax
; Perform the shift
call shift_data_left
; Adjust the file metadata byte count
mov ax, [file_length]
sub ax, [ed_operation_by]
mov [file_length], ax
; Exit
call text_newline
jmp .main_loop
; LIST ;
.list:
; set up registers to print the data
; Get the byte of where the printing will start
mov bx, [ed_start_int]
call get_byte_of_line ; CX = byte of start of new line (relative to file buffer)
mov si, cx
; Get the number of bytes to print
mov bx,[ed_end_int]
inc bx
call get_byte_of_line
sub cx,si
call text_newline
add si, file_buffer
call text_print_raw
jmp .main_loop
.quit:
popa
ret
jmp os_start_cli
; This could probably go in disk_?
shift_data_left:
mov si, ed_shift_from
mov cx, ed_shift_by
mov di, ed_shift_from
sub di, cx
mov dx, file_length ; STORES THE LENGTH OF THE FILE IN BYTES
.shift_left_loop:
lodsb
stosb
cmp al, 0
jne .shift_left_loop
jmp ed.main_loop
; Calculate source pointer
mov si, [ed_operation_by]
add si, file_buffer
; BX = target line
; Calculate destination pointer
mov di, si
sub di, [ed_operation_by]
; Loop count
mov cx, file_length ; STORES THE LENGTH OF THE FILE IN BYTES
sub cx, ed_operation_by
; Perform the actual left shift
rep movsb
; Override the rest with zeroes
mov cx, [ed_operation_by]
mov al, 0
rep stosb
ret
ed_error:
pusha
call text_newline
mov ah, 0Eh
mov al, '?'
int 10h
call text_newline
popa
ret
; IN: BX = target line
; OUT: CX = relative byte
; TODO fix
get_byte_of_line:
push dx
push si
push ax
mov si, file_buffer
xor dx,dx
xor cx,cx
jmp .increment_line_count
.line_loop:
xor ax,ax
lodsb
inc cx
cmp al, 0Ah
je .increment_line_count
jmp .line_loop
.increment_line_count:
inc dx
cmp dx, bx
jne .line_loop
inc cx
jl .line_loop
jmp .exit
.exit:
pop ax
pop si
pop dx
ret
determine_line_count:
mov si, file_buffer
mov dx, file_length ; STORES THE LENGTH OF THE FILE IN BYTES
xor cx,cx
.line_count_loop:
lodsb
cmp al, 0Ah
je .increment_line_count
dec dx
cmp dx, 0
jg .line_count_loop
mov [ed_line_count], cx
ret
.increment_line_count:
inc cx
jmp .line_count_loop
ed_data_start: db "ED IS COOL"
ed_prompt: times 40 db 0
ed_start_int: dw 0
ed_start_int: dw 1
ed_end_int: dw 0
ed_line_count: dw 0
ed_shift_from: dw 0
ed_shift_by: dw 0
ed_operation_from: dw 0
ed_operation_by: dw 0
ed_tmp: dd 0