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:
@@ -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