Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 

545 rindas
14 KiB

BITS 16
%define svim_starting_row_number_for_text 2
%define svim_end_row_number_for_text 24
%define svim_magic_buffer_size 2048
svim:
pusha ; save state before program
sub sp, svim_magic_buffer_size
mov [buffer_for_svim_base_left_of_cursor], sp
sub sp, svim_magic_buffer_size
mov [buffer_for_svim_base_right_of_cursor], sp
mov bx, sp
mov BYTE [bx], 0 ; be sure that the first byte is zero.
mov WORD [svim_counter_char_in_left_buffer], 0 ; reset these to zero
mov WORD [svim_counter_char_in_right_buffer], 0
mov WORD [svim_get_cursor_distance_to_next_line_break], 0
mov BYTE [svim_save_on_exit], 0
call os_clear_screen
xor bx, bx
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x00 ; row zero
mov dl, 0x17 ; coloumn zero
int 0x10
mov si, welcome_svim_select_file
call print
call printCRLF
mov si, seperate_line
call print
call lsfs_list_files_command
; move cursor to the bootom
xor ax, ax
xor bx, bx
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x17 ; row zero
mov dl, 0x00 ; coloumn zero
int 0x10
mov si, welcome_svim
call print
call printCRLF
mov si, welcome_svim_enter_fileindex
call print
; Ask the user for the filename
xor bx, bx
xor cx, cx ; are going to be the counter
xor dx, dx
.enter_fileindex_loop:
push cx
.loop_no_push:
mov ax, 0x10 ; BIOS call to wait for key
int 0x16
cmp ax, 0x1c0d ; enter key
je .fileindex_done
cmp ax, 0x0e08 ; backspace
jne .no_enter_fileindex
cmp cx, 0
je .loop_no_push
pop cx
sub cx, 1
mov bx, [buffer_for_svim_base_left_of_cursor]
add bx, cx
mov BYTE [bx], 0
; Go back one space
mov ax, 0x0e08 ; ah=0x0e means teletype output. al=0x08 means backspace character.
int 0x10
; Place a NULL
mov al, 0x0 ; NULL
int 0x10
; Go back one space again as the above print of NULL pushes the cursor forward again.
mov ax, 0x0e08
int 0x10
jmp .enter_fileindex_loop
.no_enter_fileindex:
mov bh, 0x00
mov bl, 0x02
mov ah, 0x0E
int 0x10 ; print char
pop cx
mov bx, [buffer_for_svim_base_left_of_cursor]
add bx, cx
mov [bx], al
add cx, 1
; fileindex must only be 120 chars
cmp cx, 120
jae .fileindex_done
jmp .enter_fileindex_loop
.fileindex_done:
pop cx ; Cleanup, and now contain filename size
mov ax, cx
add ax, [buffer_for_svim_base_left_of_cursor]
mov bx, ax
mov BYTE [bx], 0
mov si, [buffer_for_svim_base_left_of_cursor]
call zstring_to_integer ; ax now contain the interger index for the file
mov [fileindex_for_open_file], ax ; save the file index
call svim_redraw_window
; LOAD FILE
; Prepare to ask the filesystem to load the file
; The file system should be given the file_id and the buffer where we can write
mov ax, [fileindex_for_open_file]
mov bx, [buffer_for_svim_base_left_of_cursor]
call lsfs_read_file
;mov bx, [buffer_for_svim_base_left_of_cursor]
;add bx, svim_magic_buffer_size - 2
;mov ax, [bx]
mov [svim_counter_char_in_left_buffer], ax
;mov [svim_counter_char_in_left_buffer], ax
; print buffer
;mov si, [buffer_for_svim_base_left_of_cursor]
;mov es, si
;call print
.svim_loop:
; Redraw the whole text,
; move cursor to the top, where the text has to start (line 2)
xor ax, ax
xor bx, bx
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x02 ; row
mov dl, 0x00 ; coloumn
int 0x10
mov si, [buffer_for_svim_base_left_of_cursor]
call print
; Check if there is somthing to the right of the cursor that should be written to screen
mov cx, [svim_counter_char_in_right_buffer]
cmp cx, 0 ; Nothing to be written
je .no_write_right_of_the_cursor
call get_cursor_position
push dx
mov bx, [buffer_for_svim_base_right_of_cursor]
dec bx
mov cx, [svim_counter_char_in_right_buffer]
call print_reverse
pop dx
xor ax, ax
xor bx, bx
mov ah, 0x02
mov bx, 0x00 ; page zero
int 0x10
.no_write_right_of_the_cursor:
xor bx, bx
xor cx, cx
xor dx, dx
mov ax, 0x1000 ; BIOS call to wait for key
int 0x16
cmp ax, 0x1c0d ; enter key
jne .no_enter
mov bx, [buffer_for_svim_base_left_of_cursor]
add bx, [svim_counter_char_in_left_buffer]
mov BYTE [bx], 13 ; put char in the buffer
mov BYTE [bx + 1], 10 ; put char in the buffer
mov bx, [svim_counter_char_in_left_buffer]
add bx, 0x02
mov [svim_counter_char_in_left_buffer], bx
call svim_redraw_window
jmp .svim_loop
.no_enter:
cmp ax, 0x4be0 ; left key
jne .check_up_key
call handle_left_key_pressed
jmp .svim_loop
.check_up_key:
cmp ax, 0x48e0 ; up key
jne .check_right_key
call handle_up_key_pressed
jmp .svim_loop
.check_right_key:
cmp ax, 0x4de0 ; right key
jne .check_down_key
call handle_right_key_pressed
jmp .svim_loop
.check_down_key:
cmp ax, 0x50e0 ; down key
jne .check_tab_key
call handle_down_key_pressed
jmp .svim_loop
.check_tab_key:
cmp ax, 0x0f09 ; tab key
jne .no_special_key_pressed
mov bx, [buffer_for_svim_base_left_of_cursor]
add bx, [svim_counter_char_in_left_buffer]
mov BYTE [bx], 0x20 ; put space char in the buffer
mov BYTE [bx + 1], 0x20 ; put space char in the buffer
mov bx, [svim_counter_char_in_left_buffer]
add bx, 0x02
mov [svim_counter_char_in_left_buffer], bx
call svim_redraw_window
jmp .svim_loop
jmp .svim_loop
.no_special_key_pressed:
cmp ax, 0x11b ; ESC key
je .end_svim
cmp ax, 0x3c00 ; f2 key
je .f2_key_pushed
cmp ax, 0x3d00 ; f3 key
je .f3_key_pushed
cmp ax, 0x0e08 ; backspace
je .backspace_pushed
mov bx, ax
mov ax, 0xe20
mov al, bl
mov bx, [buffer_for_svim_base_left_of_cursor]
add bx, [svim_counter_char_in_left_buffer]
mov [bx], al ; put char in the buffer
mov bx, [svim_counter_char_in_left_buffer]
add bx, 0x01
mov [svim_counter_char_in_left_buffer], bx
int 0x10 ; print char
jmp .svim_loop
.end_svim:
;mov bx, [buffer_for_svim_base_left_of_cursor]
;add bx, svim_magic_buffer_size - 2
;mov [bx], ax
; When saving the file, we need to have all the data in the left buffer.
; So we loop through the right buffer and palce the data in the left.
mov ax, [svim_counter_char_in_right_buffer]
.copy_data_to_left_buffer:
cmp ax, 0
je .stop_copy
call handle_right_key_pressed
dec ax
jmp .copy_data_to_left_buffer
.stop_copy:
mov ax, [fileindex_for_open_file]
mov bx, [buffer_for_svim_base_left_of_cursor]
mov cx, [svim_counter_char_in_left_buffer]
mov dl, [svim_save_on_exit]
test dl, dl ; if zero qiut without exit
jz .svim_quit
call lsfs_write_file
.svim_quit:
call os_clear_screen
add sp, svim_magic_buffer_size
add sp, svim_magic_buffer_size
popa
ret
.f2_key_pushed:
mov al, 1
mov [svim_save_on_exit], al
call svim_redraw_window
jmp .svim_loop
.f3_key_pushed:
mov al, 0
mov [svim_save_on_exit], al
call svim_redraw_window
jmp .svim_loop
.backspace_pushed:
mov bx, [svim_counter_char_in_left_buffer]
cmp bx, 0
je .svim_loop
mov cx, bx
sub cx , 1
mov bx, [buffer_for_svim_base_left_of_cursor]
add bx, cx
.delete_linebreak:
cmp BYTE [bx], 10
jne .delete_char
mov BYTE [bx], 0
; cx is already the counter
sub cx, 1 ; Substract one charecter from the buffer, CR and LF
sub bx, 1
mov BYTE [bx], 0
mov [svim_counter_char_in_left_buffer], cx
call svim_redraw_window
jmp .svim_loop
.delete_char:
mov BYTE [bx], 0
mov [svim_counter_char_in_left_buffer], cx
call svim_redraw_window
jmp .svim_loop
handle_left_key_pressed:
pusha
mov ax, [svim_counter_char_in_left_buffer]
cmp ax, 0
je .end
mov bx, [buffer_for_svim_base_left_of_cursor]
add bx, ax
dec bx ; Because it faces the next free spot
mov dx, [bx]
mov BYTE [bx], 0
push dx
mov cx, [svim_counter_char_in_right_buffer]
mov bx, [buffer_for_svim_base_right_of_cursor]
add bx, cx
mov [bx], dx
inc bx
mov BYTE [bx], 0 ; be sure that the next byte is always zero
dec ax
inc cx
mov [svim_counter_char_in_left_buffer], ax
mov [svim_counter_char_in_right_buffer], cx
pop bx
cmp bx, 10 ; check if we hit a line break.
jne .end
call handle_left_key_pressed ; we have hit a linebreak and need to go once more
.end:
popa
ret
handle_right_key_pressed:
pusha
mov ax, [svim_counter_char_in_right_buffer]
cmp ax, 0 ; check if we have more on the right side of the buffer
je .end ; If we don't, jump to the end and do nothing.
mov bx, [buffer_for_svim_base_right_of_cursor]
add bx, ax
dec bx ; Because it faces the next free spot
mov dx, [bx]
mov BYTE [bx], 0
push dx
mov cx, [svim_counter_char_in_left_buffer]
mov bx, [buffer_for_svim_base_left_of_cursor]
add bx, cx
mov [bx], dx
inc bx
mov BYTE [bx], 0 ; be sure that the next byte is always zero
dec ax
inc cx
mov [svim_counter_char_in_right_buffer], ax
mov [svim_counter_char_in_left_buffer], cx
pop bx
cmp bx, 13 ; check if we hit a line break.
jne .end
call handle_right_key_pressed ; we have hit a linebreak and need to go once more
.end:
popa
ret
handle_up_key_pressed:
call get_cursor_position ; Find the position of the cursor
xor cx, cx
mov cl, dl ; Store coulun count
push cx ; save the column count.
inc cx
.find_first_line_break:
cmp BYTE cl, 0
je .find_right_position_on_new_line
call handle_left_key_pressed
dec cl
jmp .find_first_line_break
.find_right_position_on_new_line:
call svim_get_left_line_count ; updates the value in svim_get_cursor_distance_to_next_line_break
mov ax, [svim_get_cursor_distance_to_next_line_break]
pop cx
.move_curser_to_correct_position_on_the_new_line:
cmp cx, ax
jge .end
call handle_left_key_pressed
dec ax
jmp .move_curser_to_correct_position_on_the_new_line
.end:
ret
handle_down_key_pressed:
call get_cursor_position ; Find the position of the cursor
xor ax, ax
mov al, dl ; Store coulun count
push ax ; save the column count.
call svim_get_right_line_count ; updates the value in svim_get_cursor_distance_to_next_line_break
mov cx, [svim_get_cursor_distance_to_next_line_break]
.find_first_line_break:
cmp cx, 0
je .find_left_position_on_new_line
call handle_right_key_pressed
dec cx
jmp .find_first_line_break
.find_left_position_on_new_line:
call svim_get_right_line_count ; updates the value in svim_get_cursor_distance_to_next_line_break
mov ax, [svim_get_cursor_distance_to_next_line_break]
pop cx
cmp cx, ax
jle .move_curser_to_correct_position_on_the_new_line
mov cx, ax
.move_curser_to_correct_position_on_the_new_line:
cmp cx, 0
je .end
call handle_right_key_pressed
dec cx
jmp .move_curser_to_correct_position_on_the_new_line
.end:
ret
svim_get_left_line_count:
pusha
xor ax, ax ; Number of chars in the right side buffer
xor cx, cx ; This is our counter to the next line break
mov ax, [svim_counter_char_in_left_buffer]
mov bx, [buffer_for_svim_base_left_of_cursor]
add bx, ax
dec bx
.check_next:
cmp ax, 0 ; check if we have hit the absolut beginnig of the string
je .end
mov BYTE dl, [bx]
cmp BYTE dl, 10 ; See if we have hit an linebreak
je .end_line_break
dec bx ; dec one, to check the prev char, until we hit a line break.
dec ax
inc cx ; add one to the counter
jmp .check_next
.end_line_break:
;inc cx ; add one to the counter
.end:
mov WORD [svim_get_cursor_distance_to_next_line_break], cx
popa
ret
svim_get_right_line_count:
pusha
xor ax, ax ; Number of chars in the right side buffer
xor cx, cx ; This is our counter to the next line break
mov ax, [svim_counter_char_in_right_buffer]
mov bx, [buffer_for_svim_base_right_of_cursor]
add bx, ax
dec bx
.check_next:
cmp ax, 0 ; check if we have hit the absolut beginnig of the string
je .end
mov BYTE dl, [bx]
cmp BYTE dl, 13 ; See if we have hit an linebreak
je .end_line_break
dec bx ; dec one, to check the prev char, until we hit a line break.
dec ax
inc cx ; add one to the counter
jmp .check_next
.end_line_break:
inc cx ; add one to the counter
.end:
mov WORD [svim_get_cursor_distance_to_next_line_break], cx
popa
ret
get_cursor_position:
xor ax, ax
xor bx, bx
mov ah, 0x03
mov bh, 0x00 ; page number 0
int 0x10
ret
svim_redraw_window:
call os_clear_screen
; move cursor to the bootom
xor ax, ax
xor bx, bx
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x17 ; row zero
mov dl, 0x00 ; coloumn zero
int 0x10
mov si, seperate_line
call print
mov si, welcome_svim
call print
mov al, [svim_save_on_exit]
test al, al
jz .not_save_mode
mov si, svim_string_save
jmp .after_not_safe_mode
.not_save_mode:
mov si, svim_string_not_save
.after_not_safe_mode:
call print
; move cursor to the top
xor ax, ax
xor bx, bx
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x00 ; row zero
mov dl, 0x00 ; coloumn zero
int 0x10
; Load from disk and, enter it, into the buffer
mov si, welcome_svim_select_file
call print
mov ax, [fileindex_for_open_file]
call dumpax10
call printCRLF
mov si, seperate_line
call print
ret
svim_get_cursor_offset_on_current_line dw 0
svim_get_cursor_distance_to_next_line_break dw 0
buffer_for_svim_base_left_of_cursor dw 0
buffer_for_svim_base_right_of_cursor dw 0
svim_counter_char_in_left_buffer dw 0
svim_counter_char_in_right_buffer dw 0
seperate_line db '________________________________________________________________________________', 0
welcome_svim db 'Vim like text editor for SingOS, ESC to exit svim - ', 0
svim_string_save db 'save-mode', 0
svim_string_not_save db 'not-save-mode', 0
welcome_svim_select_file db 'svim v0.2.0 - Open file: ', 0
welcome_svim_enter_fileindex db 'Enter fileindex: ', 0
fileindex_for_open_file dw 0
svim_total_file_size_counter dw 0
svim_save_on_exit db 0