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:
2
data/test.asm
Normal file
2
data/test.asm
Normal file
@@ -0,0 +1,2 @@
|
||||
X = 100
|
||||
PRINT X
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user