@ -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
; 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
; move cursor to the bootom
;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 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, 0x17 ; row zero
mov dh, 0x02 ; row
mov dl, 0x00 ; coloumn zero
mov dl, 0x00 ; coloumn
int 0x10
int 0x10
mov si, .seperate_line
mov si, [buffer_for_svim_base_left_of_cursor]
call print
mov si, .welcome_svim
call print
call print
; move cursor to the top
; 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 ax, ax
xor bx, bx
xor bx, bx
mov ah, 0x02
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov bx, 0x00 ; page zero
mov dh, 0x00 ; row zero
mov dl, 0x00 ; coloumn zero
int 0x10
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
; 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]
call lsfs_read_file
;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
jmp .svim_loop
xor dx, dx
mov ax, 0x0e0d
int 0x10
mov ax, 0x0e0a
.no_enter:
int 0x10
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_enter:
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
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
int 0x10
ret
; Place a NULL
svim_redraw_window:
mov al, 0x0 ; NULL
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
; Go back one space again as the above print of NULL pushes the cursor forward again.
mov si, seperate_line
mov ax, 0x0e08
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
int 0x10
jmp .svim_loop
; Load from disk and, enter it, into the buffer
mov si, welcome_svim_select_file
call print
mov ax, [fileindex_for_open_file]
;.f_key_pushed:
call dumpax10
;mov al, 0x01 ;arg: index 1
call printCRLF
;call os_change_screen
;jmp .svim_loop
;.load_buffer_svim:
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