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,5 +1,6 @@
os_start_cli:
pusha
call os_print_newline
@@ -67,14 +68,14 @@ os_read_cli:
call os_compare_strings
cmp cl, 1
je .ls
; ED
;ED
mov si, user_input
mov di, ed_string
call os_compare_strings
cmp cl, 1
je .ed
jmp .unkown
.unkown:
@@ -85,6 +86,11 @@ os_read_cli:
jmp .finish
.finish:
; Clear the user input
mov al, 0
mov cx, 20
mov di,user_input
repe stosb
popa
call os_start_cli

View File

@@ -171,7 +171,7 @@ disk_clear_output_buffer:
; OUT
; data_buffer: file contents
; TODO use predefined data for calculations
; carry flag: set if failed to load file
; CX = 0 if failed to load
disk_load_file:
pusha
call string_length ; cl = string length
@@ -235,10 +235,11 @@ disk_load_file:
jmp .done_fail
.done_fail:
popa
stc
mov bx, 1
ret
.done:
popa
xor bx,bx
ret
; Write data to file

View File

@@ -28,6 +28,8 @@ keyboard_check_key:
; IN:
; AX = output address
; BX = max length
; OUT:
; BX = 1 if escape is pressed
keyboard_display_input:
pusha
mov di, ax
@@ -55,14 +57,15 @@ keyboard_display_input:
jmp .check_key_pressed
.esc_key:
stc
popa
mov bx, 1
ret
.enter_key:
mov al, 0
stosb
popa
xor bx,bx
ret ; Return to the parent function (whatever that may be)
.backspace:

View File

@@ -106,39 +106,42 @@ string_join:
ret
; ------------------------------------------------------------------------
; TODO
; Converts a string to an integer
; IN: SI = string location (max 5 chars, up to '65536')
; OUT: AX = number
; OUT: AX = number, DX = length of int string
string_cast_to_int:
pusha
push cx
push bx
push dx
xor cx,cx
.loop:
xor ax,ax
lodsb
cmp al, 30h
; Exit if the character is not a number
cmp al,'0'
jl .finish
cmp al, 39h
cmp al,'9'
jg .finish
sub al, 30h
sub al, '0'
mov bx, ax
mov ax, 10
mul cx ; Multiple the current value by 10
add ax, bx ; Then add the new digit
mov cx, ax
jmp .loop
.finish:
mov [int_tmp], cx
popa
mov ax, [int_tmp]
mov ax,cx
pop dx
pop bx
pop cx
ret
; ------------------------------------------------------------------------
; IN: AX = integer (unsigned)
; OUT: AX -> null-terminated string
string_cast_from_int:
pusha
cld ; Write backwards

View File

@@ -55,10 +55,16 @@ text_print_raw:
je .space
cmp al, 0Ah ; When there's an NL or CR, do both, linux encodes files only with NL
je .new_line
cmp al, 09h ; TAB
je .tab
cmp al, 0Dh
je .repeat
int 10h
jmp .repeat
.tab:
mov al, ' '
int 10h
jmp .repeat
.space:
mov al, 20h
int 10h
@@ -68,9 +74,6 @@ text_print_raw:
int 10h
mov al, 0Dh
int 10h
push ax
call os_read_input ; wait until key is pressed until it prints the next line
pop ax
jmp .repeat
.finish:
popa
@@ -132,6 +135,15 @@ os_set_text_mode:
mov dh, 0
mov dl, 0
int 10h
text_newline:
pusha
mov ax,0E0Ah
int 10h
mov al,0Dh
int 10h
popa
ret
popa
ret

View File

@@ -7,7 +7,8 @@ util_cat:
add si, 4 ; Move si to after 'CAT'
call disk_load_file
jc .done ; if file failed to load, just quit
cmp bx, 1
je .done
mov si, file_buffer
mov cx, [file_length]
@@ -36,7 +37,8 @@ util_basic:
; TODO make this more consistent to account for double spaces
;add si, 3 ; Move si to after 'BAS'
call disk_load_file
jc .done
cmp bx, 1
je .done
mov si, file_buffer

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