@ -1,9 +1,19 @@
BITS 16
BITS 16
%define svim_starting_row_number_for_text 2
%define svim_end_row_number_for_text 24
%define svim_magic_buffer_size 2048
%define svim_magic_buffer_size 2048
svim:
svim:
pusha ; save state before program
pusha ; save state before program
sub sp, svim_magic_buffer_size
sub sp, svim_magic_buffer_size
mov [.buffer_for_svim_base], sp
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
call os_clear_screen
@ -13,10 +23,10 @@ svim:
mov dh, 0x00 ; row zero
mov dh, 0x00 ; row zero
mov dl, 0x17 ; coloumn zero
mov dl, 0x17 ; coloumn zero
int 0x10
int 0x10
mov si, . welcome_svim_select_file
mov si, welcome_svim_select_file
call print
call print
call printCRLF
call printCRLF
mov si, . seperate_line
mov si, seperate_line
call print
call print
call lsfs_list_files_command
call lsfs_list_files_command
@ -29,10 +39,10 @@ svim:
mov dl, 0x00 ; coloumn zero
mov dl, 0x00 ; coloumn zero
int 0x10
int 0x10
mov si, . welcome_svim
mov si, welcome_svim
call print
call print
call printCRLF
call printCRLF
mov si, . welcome_svim_enter_fileindex
mov si, welcome_svim_enter_fileindex
call print
call print
; Ask the user for the filename
; Ask the user for the filename
@ -52,7 +62,7 @@ svim:
je .loop_no_push
je .loop_no_push
pop cx
pop cx
sub cx, 1
sub cx, 1
mov bx, [. buffer_for_svim_base]
mov bx, [buffer_for_svim_base_left_of_cursor ]
add bx, cx
add bx, cx
mov BYTE [bx], 0
mov BYTE [bx], 0
; Go back one space
; Go back one space
@ -74,7 +84,7 @@ svim:
mov ah, 0x0E
mov ah, 0x0E
int 0x10 ; print char
int 0x10 ; print char
pop cx
pop cx
mov bx, [. buffer_for_svim_base]
mov bx, [buffer_for_svim_base_left_of_cursor ]
add bx, cx
add bx, cx
mov [bx], al
mov [bx], al
add cx, 1
add cx, 1
@ -87,67 +97,64 @@ svim:
.fileindex_done:
.fileindex_done:
pop cx ; Cleanup, and now contain filename size
pop cx ; Cleanup, and now contain filename size
mov ax, cx
mov ax, cx
add ax, [. buffer_for_svim_base]
add ax, [buffer_for_svim_base_left_of_cursor ]
mov bx, ax
mov bx, ax
mov BYTE [bx], 0
mov BYTE [bx], 0
mov si, [. buffer_for_svim_base]
mov si, [buffer_for_svim_base_left_of_cursor ]
call zstring_to_integer ; ax now contain the interger index for the file
call zstring_to_integer ; ax now contain the interger index for the file
mov [. fileindex_for_open_file], ax ; save the file index
mov [fileindex_for_open_file], ax ; save the file index
call os_clear_screen
call svim_redraw_window
; LOAD FILE
; move cursor to the bootom
; Prepare to ask the filesystem to load the file
xor ax, ax
; The file system should be given the file_id and the buffer where we can write
xor bx, bx
mov ax, [fileindex_for_open_file]
mov ah, 0x02
mov bx, [buffer_for_svim_base_left_of_cursor]
mov bh, 0x00 ; page number 0
call lsfs_read_file
mov dh, 0x17 ; row zero
mov dl, 0x00 ; coloumn zero
int 0x10
mov si, .seperate_line
;mov bx, [buffer_for_svim_base_left_of_cursor]
call print
;add bx, svim_magic_buffer_size - 2
mov si, .welcome_svim
;mov ax, [bx]
call p rint
mov [svim_ counter_ch ar_ in_lef t_buffer], ax
; move cursor to the top
;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 ax, ax
xor bx, bx
xor bx, bx
mov ah, 0x02
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov bh, 0x00 ; page number 0
mov dh, 0x00 ; row zero
mov dh, 0x02 ; row
mov dl, 0x00 ; coloumn zero
mov dl, 0x00 ; coloumn
int 0x10
int 0x10
; Load from disk and, enter it, into the buffer
mov si, .welcome_svim_select_file
mov si, [buffer_for_svim_base_left_of_cursor]
call print
mov ax, [.fileindex_for_open_file]
call dumpax10
call printCRLF
mov si, .seperate_line
call print
call print
; LOAD FILE
; Check if there is somthing to the right of the cursor that should be written to screen
; Prepare to ask the filesystem to load the file
mov cx, [svim_counter_char_in_right_buffer]
; The file system should be given the file_id and the buffer where we can write
cmp cx, 0 ; Nothing to be written
mov ax, [.fileindex_for_open_file]
je .no_write_right_of_the_cursor
mov bx, [.buffer_for_svim_base]
call get_cursor_position
call lsfs_read_file
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
;mov bx, [.buffer_for_svim_base]
.no_write_right_of_the_cursor:
;add bx, svim_magic_buffer_size - 2
;mov ax, [bx]
mov [.buffer_counter_svim], ax
; print buffer
mov si, [.buffer_for_svim_base]
mov es, si
call print
.svim_loop:
xor bx, bx
xor bx, bx
xor cx, cx
xor cx, cx
xor dx, dx
xor dx, dx
@ -155,98 +162,384 @@ svim:
int 0x16
int 0x16
cmp ax, 0x1c0d ; enter key
cmp ax, 0x1c0d ; enter key
jne .no_enter
jne .no_enter
mov bx, [. buffer_for_svim_base]
mov bx, [buffer_for_svim_base_left_of_cursor ]
add bx, [.buffer_counter_svim ]
add bx, [svim_counter_char_in_left_buffer ]
mov BYTE [bx], 13 ; put char in the buffer
mov BYTE [bx], 13 ; put char in the buffer
mov BYTE [bx + 1], 10 ; put char in the buffer
mov BYTE [bx + 1], 10 ; put char in the buffer
mov bx, [.buffer_counter_svim ]
mov bx, [svim_counter_char_in_left_buffer ]
add bx, 0x02
add bx, 0x02
mov [.buffer_counter_svim ], bx
mov [svim_counter_char_in_left_buffer ], bx
xor bx, bx
call svim_redraw_window
xor cx, cx
xor dx, dx
mov ax, 0x0e0d
int 0x10
mov ax, 0x0e0a
int 0x10
jmp .svim_loop
jmp .svim_loop
.no_enter:
.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
cmp ax, 0x11b ; ESC key
je .end_svim
je .end_svim
;cmp ax, 0x3c00 ; f2 key
cmp ax, 0x3c00 ; f2 key
;je .f_key_pushed
je .f2_key_pushed
cmp ax, 0x3d00 ; f3 key
je .f3_key_pushed
cmp ax, 0x0e08 ; backspace
cmp ax, 0x0e08 ; backspace
je .backspace_pushed
je .backspace_pushed
mov bx, ax
mov bx, ax
mov ax, 0xe20
mov ax, 0xe20
mov al, bl
mov al, bl
mov bx, [.buffer_for_svim_base]
mov bx, [buffer_for_svim_base_left_of_cursor ]
add bx, [.buffer_counter_svim]
add bx, [svim_counter_char_in_left_buffer ]
mov [bx], al ; put char in the buffer
mov [bx], al ; put char in the buffer
mov bx, [.buffer_counter_svim]
mov bx, [svim_counter_char_in_left_buffer ]
add bx, 0x01
add bx, 0x01
mov [.buffer_counter_svim], bx
mov [svim_counter_char_in_left_buffer ], bx
int 0x10 ; print char
int 0x10 ; print char
jmp .svim_loop
jmp .svim_loop
.end_svim:
.end_svim:
;mov bx, [.buffer_for_svim_base]
;mov bx, [buffer_for_svim_base_left_of_cursor ]
;add bx, svim_magic_buffer_size - 2
;add bx, svim_magic_buffer_size - 2
;mov [bx], ax
;mov [bx], ax
mov ax, [.fileindex_for_open_file]
; When saving the file, we need to have all the data in the left buffer.
mov bx, [.buffer_for_svim_base]
; So we loop through the right buffer and palce the data in the left.
mov cx, [.buffer_counter_svim]
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
call lsfs_write_file
.svim_quit:
call os_clear_screen
call os_clear_screen
add sp, svim_magic_buffer_size
add sp, svim_magic_buffer_size
add sp, svim_magic_buffer_size
popa
popa
ret
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:
.backspace_pushed:
mov bx, [.buffer_counter_svim]
mov bx, [svim_counter_char_in_left_buffer ]
cmp bx, 0
cmp bx, 0
je .svim_loop
je .svim_loop
;print_format .debug_buffer_counter, bx
mov cx, bx
mov cx, bx
sub cx, 1
sub cx , 1
mov bx, [.buffer_for_svim_base]
mov bx, [buffer_for_svim_base_left_of_cursor ]
add bx, cx
add bx, cx
.delete_linebreak:
cmp BYTE [bx], 10
jne .delete_char
mov BYTE [bx], 0
mov BYTE [bx], 0
mov [.buffer_counter_svim], cx
; cx is already the counter
;print_format .debug_buffer_counter, cx
sub cx, 1 ; Substract one charecter from the buffer, CR and LF
; Go back one space
sub bx, 1
mov ax, 0x0e08 ; ah=0x0e means teletype output. al=0x08 means backspace character.
mov BYTE [bx], 0
int 0x10
mov [svim_counter_char_in_left_buffer], cx
call svim_redraw_window
jmp .svim_loop
; Place a NULL
.delete_char:
mov al, 0x0 ; NULL
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
int 0x10
ret
; Go back one space again as the above print of NULL pushes the cursor forward again.
svim_redraw_window:
mov ax, 0x0e08
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
int 0x10
jmp .svim_loop
mov si, seperate_line
call print
mov si, welcome_svim
call print
;.f_key_pushed:
mov al, [svim_save_on_exit]
;mov al, 0x01 ;arg: index 1
test al, al
;call os_change_screen
jz .not_save_mode
;jmp .svim_loop
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
;.load_buffer_svim:
; 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
.debug_buffer_counter db 'Buffer count: %d', 13, 10, 0
svim_get_cursor_offset_on_current_line dw 0
.welcome_svim db 'Vim like text editor for SingOS, ESC to exit', 0
svim_get_cursor_distance_to_next_line_break dw 0
.welcome_svim_select_file db 'svim v0.0.5 - Open file: ', 0
buffer_for_svim_base_left_of_cursor dw 0
.welcome_svim_enter_fileindex db 'Enter fileindex: ', 0
buffer_for_svim_base_right_of_cursor dw 0
.seperate_line db '________________________________________________________________________________', 0
svim_counter_char_in_left_buffer dw 0
.fileindex_for_open_file dw 0
svim_counter_char_in_right_buffer dw 0
.buffer_for_svim_base dw 0
seperate_line db '________________________________________________________________________________', 0
.buffer_counter_svim dw 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