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:
|
os_start_cli:
|
||||||
pusha
|
pusha
|
||||||
|
|
||||||
|
|
||||||
call os_print_newline
|
call os_print_newline
|
||||||
|
|
||||||
@@ -67,14 +68,14 @@ os_read_cli:
|
|||||||
call os_compare_strings
|
call os_compare_strings
|
||||||
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
|
||||||
cmp cl, 1
|
cmp cl, 1
|
||||||
je .ed
|
je .ed
|
||||||
|
|
||||||
jmp .unkown
|
jmp .unkown
|
||||||
|
|
||||||
.unkown:
|
.unkown:
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -132,6 +135,15 @@ os_set_text_mode:
|
|||||||
mov dh, 0
|
mov dh, 0
|
||||||
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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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,97 +72,208 @@ 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:
|
|
||||||
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
|
; COMMANDS
|
||||||
|
; DELETE ;
|
||||||
.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
|
; 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
|
inc bx
|
||||||
call get_byte_of_line ; CX = byte of start of new line (relative to file buffer)
|
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
|
call get_byte_of_line
|
||||||
mov ax, ed_start_int
|
mov ax, [ed_operation_from]
|
||||||
sub ax, cx
|
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:
|
.quit:
|
||||||
popa
|
popa
|
||||||
ret
|
jmp os_start_cli
|
||||||
|
|
||||||
|
; This could probably go in disk_?
|
||||||
shift_data_left:
|
shift_data_left:
|
||||||
mov si, ed_shift_from
|
; Calculate source pointer
|
||||||
mov cx, ed_shift_by
|
mov si, [ed_operation_by]
|
||||||
mov di, ed_shift_from
|
add si, file_buffer
|
||||||
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
|
; 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:
|
get_byte_of_line:
|
||||||
push dx
|
push dx
|
||||||
|
push si
|
||||||
|
push ax
|
||||||
|
|
||||||
mov si, file_buffer
|
mov si, file_buffer
|
||||||
|
|
||||||
xor dx,dx
|
xor dx,dx
|
||||||
xor cx,cx
|
xor cx,cx
|
||||||
|
|
||||||
jmp .increment_line_count
|
jmp .increment_line_count
|
||||||
.line_loop:
|
.line_loop:
|
||||||
|
xor ax,ax
|
||||||
lodsb
|
lodsb
|
||||||
inc cx
|
inc cx
|
||||||
|
|
||||||
cmp al, 0Ah
|
cmp al, 0Ah
|
||||||
je .increment_line_count
|
je .increment_line_count
|
||||||
|
|
||||||
|
jmp .line_loop
|
||||||
.increment_line_count:
|
.increment_line_count:
|
||||||
inc dx
|
inc dx
|
||||||
cmp dx, bx
|
cmp dx, bx
|
||||||
jne .line_loop
|
jl .line_loop
|
||||||
inc cx
|
jmp .exit
|
||||||
|
.exit:
|
||||||
|
pop ax
|
||||||
|
pop si
|
||||||
pop dx
|
pop dx
|
||||||
ret
|
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_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
|
||||||
|
|||||||
Reference in New Issue
Block a user