159 lines
2.6 KiB
NASM
159 lines
2.6 KiB
NASM
; Planned commands:
|
|
; i insert
|
|
; a append
|
|
; d delete
|
|
; l prints lines
|
|
; w save to disk
|
|
; q quit
|
|
ed:
|
|
pusha
|
|
call .determine_line_count
|
|
.main_loop:
|
|
mov ax, ed_prompt
|
|
mov bx, 40
|
|
call keyboard_display_input ; AX = string location, BX = max prompt length
|
|
mov si, ed_prompt
|
|
mov bx, 0 ; Keeps track of whether comma has passed
|
|
jmp .get_token
|
|
|
|
; Types of tokens:
|
|
; Number: eg 123
|
|
; Doller (refers to the last line) $
|
|
; Comma ,
|
|
; Command: eg i
|
|
; eg 123,127i
|
|
.get_token:
|
|
lodsb
|
|
|
|
; COMMA
|
|
cmp al, ','
|
|
je .comma
|
|
|
|
; NUMBER
|
|
call check_is_number
|
|
jc .get_number_token
|
|
|
|
; 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
|
|
|
|
; Assign a number to either the start or end int (start,end)
|
|
.get_number_token:
|
|
push si
|
|
dec si
|
|
call string_cast_to_int ; AX = integer
|
|
cmp bx, 0
|
|
je .assign_start_int
|
|
jg .assign_end_int
|
|
.assign_start_int:
|
|
mov [ed_start_int], ax
|
|
jmp .after_int_assign
|
|
.assign_end_int:
|
|
mov [ed_end_int], ax
|
|
.after_int_assign:
|
|
pop si
|
|
jmp .get_token
|
|
|
|
; Determines a command
|
|
.get_letter_token:
|
|
cmp al, 'd'
|
|
je .delete
|
|
cmp al, 'q'
|
|
je .quit
|
|
jmp .get_token
|
|
|
|
; 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:
|
|
; 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_prompt: times 40 db 0
|
|
ed_start_int: dw 0
|
|
ed_end_int: dw 0
|
|
|
|
ed_line_count: dw 0
|
|
|
|
ed_shift_from: dw 0
|
|
ed_shift_by: dw 0
|