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

2
data/test.asm Normal file
View File

@@ -0,0 +1,2 @@
X = 100
PRINT X

View File

@@ -1,6 +1,7 @@
os_start_cli: os_start_cli:
pusha pusha
call os_print_newline call os_print_newline
mov si, prompt mov si, prompt
@@ -68,7 +69,7 @@ os_read_cli:
cmp cl, 1 cmp cl, 1
je .ls je .ls
; ED ;ED
mov si, user_input mov si, user_input
mov di, ed_string mov di, ed_string
call os_compare_strings call os_compare_strings
@@ -85,6 +86,11 @@ os_read_cli:
jmp .finish jmp .finish
.finish: .finish:
; Clear the user input
mov al, 0
mov cx, 20
mov di,user_input
repe stosb
popa popa
call os_start_cli call os_start_cli

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,21 +1,34 @@
; Planned commands: ; Planned commands:
; i insert ; [ ] i insert
; a append ; [ ] a append
; d delete ; [-] d delete
; l prints lines ; [x] l prints lines
; w save to disk ; [ ] w save to disk
; q quit ; [x] q quit
ed: ed:
pusha pusha
call .determine_line_count call determine_line_count
.main_loop: .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 ax, ed_prompt
mov bx, 40 mov bx, 40
call keyboard_display_input ; AX = string location, BX = max prompt length 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 si, ed_prompt
mov bx, 0 ; Keeps track of whether comma has passed mov bx, 0 ; Keeps track of whether comma has passed
jmp .get_token jmp .get_token
.error:
call ed_error
jmp .main_loop
; Types of tokens: ; Types of tokens:
; Number: eg 123 ; Number: eg 123
; Doller (refers to the last line) $ ; Doller (refers to the last line) $
@@ -29,6 +42,10 @@ ed:
cmp al, ',' cmp al, ','
je .comma je .comma
; DOLLAR SIGN
cmp al, '$'
je .dollar
; NUMBER ; NUMBER
call check_is_number call check_is_number
jc .get_number_token jc .get_number_token
@@ -36,24 +53,17 @@ ed:
; COMMAND ; COMMAND
call check_is_letter call check_is_letter
jc .get_letter_token jc .get_letter_token
jmp .error
.error: ; Output ?
mov ah, 0Eh
mov al, '?'
int 10h
mov al, 0Ah
int 10h
mov al, 0Dh
int 10h
jmp .main_loop
; Assign a number to either the start or end int (start,end) ; 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: .get_number_token:
push si
dec 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 cmp bx, 0
je .assign_start_int je .assign_start_int
jg .assign_end_int jg .assign_end_int
@@ -62,24 +72,185 @@ ed:
jmp .after_int_assign jmp .after_int_assign
.assign_end_int: .assign_end_int:
mov [ed_end_int], ax 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: .after_int_assign:
pop si dec si
jmp .get_token jmp .get_token
; Determines a command ; Determines a command
.get_letter_token: .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' cmp al, 'd'
je .delete je .delete
cmp al, 'q' cmp al, 'q'
je .quit 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 ; Changes the value from start int to end int
.comma: .comma:
mov bx, 1 mov bx, 1
jmp .get_token jmp .get_token
.determine_line_count:
; 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
; 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_operation_from], cx
; Get the number of bytes to shift left by
mov bx, [ed_start_int]
call get_byte_of_line
mov ax, [ed_operation_from]
sub ax, cx
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
jmp os_start_cli
; This could probably go in disk_?
shift_data_left:
; Calculate source pointer
mov si, [ed_operation_by]
add si, file_buffer
; 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
jl .line_loop
jmp .exit
.exit:
pop ax
pop si
pop dx
ret
determine_line_count:
mov si, file_buffer mov si, file_buffer
mov dx, file_length ; STORES THE LENGTH OF THE FILE IN BYTES mov dx, file_length ; STORES THE LENGTH OF THE FILE IN BYTES
xor cx,cx xor cx,cx
@@ -91,68 +262,18 @@ ed:
cmp dx, 0 cmp dx, 0
jg .line_count_loop jg .line_count_loop
mov [ed_line_count], cx mov [ed_line_count], cx
jmp .main_loop ret
.increment_line_count: .increment_line_count:
inc cx inc cx
jmp .line_count_loop jmp .line_count_loop
; COMMANDS
.delete:
; set up registers to shift data left
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 bx, ed_start_int
call get_byte_of_line
mov ax, ed_start_int
sub ax, cx
mov [ed_shift_by], ax
.quit:
popa
ret
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
; BX = target line
get_byte_of_line:
push dx
mov si, file_buffer
xor dx,dx
xor cx,cx
jmp .increment_line_count
.line_loop:
lodsb
inc cx
cmp al, 0Ah
je .increment_line_count
.increment_line_count:
inc dx
cmp dx, bx
jne .line_loop
inc cx
pop dx
ret
ed_data_start: db "ED IS COOL" ed_data_start: db "ED IS COOL"
ed_prompt: times 40 db 0 ed_prompt: times 40 db 0
ed_start_int: dw 0 ed_start_int: dw 1
ed_end_int: dw 0 ed_end_int: dw 0
ed_line_count: dw 0 ed_line_count: dw 0
ed_shift_from: dw 0 ed_operation_from: dw 0
ed_shift_by: dw 0 ed_operation_by: dw 0
ed_tmp: dd 0