Files
crawos/source/kernel/programs/ed.asm
2026-03-08 22:07:21 +00:00

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