537 lines
10 KiB
Plaintext
537 lines
10 KiB
Plaintext
|
|
||
|
; flat editor core
|
||
|
; Copyright (c) 1999-2015, Tomasz Grysztar.
|
||
|
; All rights reserved.
|
||
|
|
||
|
insert_block:
|
||
|
test [editor_mode],FEMODE_VERTICALSEL
|
||
|
jz block_to_insert_ok
|
||
|
push esi
|
||
|
or edx,-1
|
||
|
xor ecx,ecx
|
||
|
count_line_characters:
|
||
|
lodsb
|
||
|
cmp al,9
|
||
|
je cannot_insert
|
||
|
cmp al,0Dh
|
||
|
je count_next_line
|
||
|
or al,al
|
||
|
jz end_of_line
|
||
|
inc ecx
|
||
|
jmp count_line_characters
|
||
|
end_of_line:
|
||
|
dec esi
|
||
|
jmp check_block_width
|
||
|
count_next_line:
|
||
|
lodsb
|
||
|
cmp al,0Ah
|
||
|
je check_block_width
|
||
|
dec esi
|
||
|
check_block_width:
|
||
|
cmp edx,-1
|
||
|
je line_to_insert_ok
|
||
|
cmp edx,ecx
|
||
|
je line_to_insert_ok
|
||
|
cannot_insert:
|
||
|
pop esi
|
||
|
stc
|
||
|
retn
|
||
|
line_to_insert_ok:
|
||
|
mov edx,ecx
|
||
|
xor ecx,ecx
|
||
|
cmp byte [esi],0
|
||
|
jne count_line_characters
|
||
|
pop esi
|
||
|
block_to_insert_ok:
|
||
|
mov eax,[caret_line]
|
||
|
mov ecx,[caret_line_number]
|
||
|
mov edx,[caret_position]
|
||
|
mov [selection_line],eax
|
||
|
mov [selection_line_number],ecx
|
||
|
mov [selection_position],edx
|
||
|
mov ebx,esi
|
||
|
get_line_to_insert:
|
||
|
lodsb
|
||
|
or al,al
|
||
|
jz insert_full_line
|
||
|
cmp al,0Dh
|
||
|
je insert_full_line
|
||
|
cmp al,0Ah
|
||
|
je insert_full_line
|
||
|
cmp al,9
|
||
|
jne get_line_to_insert
|
||
|
push esi
|
||
|
dec esi
|
||
|
mov ecx,esi
|
||
|
sub ecx,ebx
|
||
|
mov esi,ebx
|
||
|
push ecx
|
||
|
call insert_into_line
|
||
|
pop ecx
|
||
|
add [caret_position],ecx
|
||
|
mov ecx,[caret_position]
|
||
|
and ecx,not 111b
|
||
|
sub ecx,[caret_position]
|
||
|
add ecx,8
|
||
|
xor esi,esi
|
||
|
push ecx
|
||
|
call insert_into_line
|
||
|
pop ecx
|
||
|
add [caret_position],ecx
|
||
|
pop esi
|
||
|
mov ebx,esi
|
||
|
jmp get_line_to_insert
|
||
|
insert_full_line:
|
||
|
dec esi
|
||
|
push esi
|
||
|
mov ecx,esi
|
||
|
sub ecx,ebx
|
||
|
mov esi,ebx
|
||
|
push ecx
|
||
|
call insert_into_line
|
||
|
pop ecx
|
||
|
add [caret_position],ecx
|
||
|
pop esi
|
||
|
lodsb
|
||
|
or al,al
|
||
|
jz last_line_inserted
|
||
|
cmp al,0Ah
|
||
|
je lf_first
|
||
|
lodsb
|
||
|
cmp al,0Ah
|
||
|
je next_line_to_insert
|
||
|
dec esi
|
||
|
jmp next_line_to_insert
|
||
|
lf_first:
|
||
|
lodsb
|
||
|
cmp al,0Dh
|
||
|
je next_line_to_insert
|
||
|
dec esi
|
||
|
next_line_to_insert:
|
||
|
mov ebx,[selection_position]
|
||
|
test [editor_mode],FEMODE_VERTICALSEL
|
||
|
jnz insert_in_next_line
|
||
|
test [editor_mode],FEMODE_OVERWRITE
|
||
|
jz insert_new_line
|
||
|
push esi
|
||
|
call clear_rest_of_line
|
||
|
pop esi
|
||
|
xor ebx,ebx
|
||
|
insert_in_next_line:
|
||
|
push esi ebx
|
||
|
mov esi,[caret_line]
|
||
|
call check_line_length
|
||
|
pop ebx
|
||
|
call go_to_next_line
|
||
|
pop esi
|
||
|
mov ebx,esi
|
||
|
jmp get_line_to_insert
|
||
|
last_line_inserted:
|
||
|
mov esi,[caret_line]
|
||
|
call check_line_length
|
||
|
clc
|
||
|
retn
|
||
|
insert_new_line:
|
||
|
push esi
|
||
|
push [caret_line]
|
||
|
push [caret_line_number]
|
||
|
xor ebx,ebx
|
||
|
call break_line
|
||
|
pop [caret_line_number]
|
||
|
pop ebx esi
|
||
|
push [caret_line]
|
||
|
mov [caret_line],ebx
|
||
|
go_to_end_of_first_line:
|
||
|
test byte [ebx],1
|
||
|
jz insert_full_lines
|
||
|
mov ebx,[ebx]
|
||
|
dec ebx
|
||
|
jmp go_to_end_of_first_line
|
||
|
insert_full_lines:
|
||
|
call allocate_segment
|
||
|
jc memory_shortage
|
||
|
call store_allocated_segment_for_undo
|
||
|
mov [ebx],eax
|
||
|
mov ebx,eax
|
||
|
mov eax,[caret_line]
|
||
|
mov [ebx+4],eax
|
||
|
mov [caret_line],ebx
|
||
|
inc [caret_line_number]
|
||
|
inc [lines_count]
|
||
|
call set_line
|
||
|
jc full_lines_inserted
|
||
|
jmp insert_full_lines
|
||
|
full_lines_inserted:
|
||
|
pop edi
|
||
|
mov eax,[caret_line]
|
||
|
mov [edi+4],eax
|
||
|
mov [ebx],edi
|
||
|
call cut_line_break
|
||
|
mov esi,[caret_line]
|
||
|
call check_line_length
|
||
|
clc
|
||
|
retn
|
||
|
set_line:
|
||
|
mov edi,ebx
|
||
|
add edi,SEGMENT_HEADER_LENGTH
|
||
|
mov ecx,SEGMENT_DATA_LENGTH
|
||
|
mov [caret_position],0
|
||
|
push ebx
|
||
|
copy_line:
|
||
|
lodsb
|
||
|
or al,al
|
||
|
jz last_line_set
|
||
|
cmp al,0Ah
|
||
|
je copy_lf
|
||
|
cmp al,0Dh
|
||
|
je copy_cr
|
||
|
cmp al,9
|
||
|
je copy_tab
|
||
|
set_character:
|
||
|
stosb
|
||
|
loop copy_line
|
||
|
extra_segment:
|
||
|
call allocate_segment
|
||
|
jc memory_shortage
|
||
|
call store_allocated_segment_for_undo
|
||
|
mov edi,eax
|
||
|
or eax,1
|
||
|
mov [ebx],eax
|
||
|
or ebx,1
|
||
|
mov [edi+4],ebx
|
||
|
mov ebx,edi
|
||
|
add edi,SEGMENT_HEADER_LENGTH
|
||
|
mov ecx,SEGMENT_DATA_LENGTH
|
||
|
add [caret_position],ecx
|
||
|
jmp copy_line
|
||
|
copy_tab:
|
||
|
mov al,20h
|
||
|
mov edx,SEGMENT_DATA_LENGTH
|
||
|
sub edx,ecx
|
||
|
add edx,[caret_position]
|
||
|
and edx,111b
|
||
|
cmp edx,111b
|
||
|
je set_character
|
||
|
dec esi
|
||
|
jmp set_character
|
||
|
copy_lf:
|
||
|
cmp byte [esi],0Dh
|
||
|
jne copy_new_line
|
||
|
inc esi
|
||
|
jmp copy_new_line
|
||
|
copy_cr:
|
||
|
cmp byte [esi],0Ah
|
||
|
jne copy_new_line
|
||
|
inc esi
|
||
|
copy_new_line:
|
||
|
pop edx
|
||
|
call finish_line
|
||
|
clc
|
||
|
retn
|
||
|
last_line_set:
|
||
|
pop edx
|
||
|
call finish_line
|
||
|
stc
|
||
|
retn
|
||
|
finish_line:
|
||
|
mov eax,SEGMENT_DATA_LENGTH
|
||
|
sub eax,ecx
|
||
|
add eax,[caret_position]
|
||
|
mov [caret_position],eax
|
||
|
mov [edx+8],eax
|
||
|
call register_length
|
||
|
mov al,20h
|
||
|
rep stosb
|
||
|
retn
|
||
|
|
||
|
delete_block:
|
||
|
test [editor_mode],FEMODE_VERTICALSEL
|
||
|
jnz delete_vertical_block
|
||
|
mov eax,[caret_line_number]
|
||
|
cmp eax,[selection_line_number]
|
||
|
je delete_vertical_block
|
||
|
mov esi,[caret_line]
|
||
|
mov ecx,[caret_line_number]
|
||
|
mov edx,[caret_position]
|
||
|
cmp ecx,[selection_line_number]
|
||
|
jbe position_for_deleting_ok
|
||
|
xchg esi,[selection_line]
|
||
|
xchg ecx,[selection_line_number]
|
||
|
xchg edx,[selection_position]
|
||
|
mov [caret_line],esi
|
||
|
mov [caret_line_number],ecx
|
||
|
mov [caret_position],edx
|
||
|
position_for_deleting_ok:
|
||
|
test [editor_mode],FEMODE_OVERWRITE
|
||
|
jnz clear_block
|
||
|
call get_caret_segment
|
||
|
cmp edx,SEGMENT_DATA_LENGTH
|
||
|
jb first_line_of_block
|
||
|
call attach_empty_segments
|
||
|
first_line_of_block:
|
||
|
mov ecx,[caret_position]
|
||
|
sub ecx,edx
|
||
|
skip_rest_of_first_line:
|
||
|
add ecx,SEGMENT_DATA_LENGTH
|
||
|
mov eax,[esi]
|
||
|
btr eax,0
|
||
|
jnc end_of_first_line
|
||
|
mov esi,eax
|
||
|
jmp skip_rest_of_first_line
|
||
|
end_of_first_line:
|
||
|
call store_segment_for_undo
|
||
|
mov edi,esi
|
||
|
mov esi,eax
|
||
|
remove_middle_lines:
|
||
|
cmp esi,[selection_line]
|
||
|
je middle_lines_removed
|
||
|
call store_freed_segment_for_undo
|
||
|
mov ebx,[esi]
|
||
|
call cancel_line
|
||
|
mov esi,ebx
|
||
|
btr esi,0
|
||
|
jnc remove_middle_lines
|
||
|
remove_middle_line_segments:
|
||
|
call store_freed_segment_for_undo
|
||
|
mov esi,[esi]
|
||
|
btr esi,0
|
||
|
jc remove_middle_line_segments
|
||
|
jmp remove_middle_lines
|
||
|
middle_lines_removed:
|
||
|
call store_segment_for_undo
|
||
|
mov eax,esi
|
||
|
or eax,1
|
||
|
mov [edi],eax
|
||
|
mov eax,edi
|
||
|
or eax,1
|
||
|
mov [esi+4],eax
|
||
|
call cancel_line
|
||
|
add ecx,[selection_position]
|
||
|
sub ecx,[caret_position]
|
||
|
call delete_from_line
|
||
|
mov esi,[caret_line]
|
||
|
find_following_line:
|
||
|
mov esi,[esi]
|
||
|
btr esi,0
|
||
|
jc find_following_line
|
||
|
or esi,esi
|
||
|
jz following_line_ok
|
||
|
call store_segment_for_undo
|
||
|
mov eax,[caret_line]
|
||
|
mov [esi+4],eax
|
||
|
following_line_ok:
|
||
|
mov esi,[caret_line]
|
||
|
call check_line_length
|
||
|
block_deleted:
|
||
|
retn
|
||
|
clear_block:
|
||
|
push [caret_line]
|
||
|
push [caret_position]
|
||
|
clear_lines:
|
||
|
call clear_rest_of_line
|
||
|
mov [caret_line],esi
|
||
|
mov [caret_position],0
|
||
|
cmp esi,[selection_line]
|
||
|
jne clear_lines
|
||
|
mov ecx,[selection_position]
|
||
|
call clear_in_line
|
||
|
pop [caret_position]
|
||
|
pop [caret_line]
|
||
|
retn
|
||
|
delete_vertical_block:
|
||
|
push [caret_line]
|
||
|
push [caret_line_number]
|
||
|
mov eax,[caret_position]
|
||
|
cmp eax,[selection_position]
|
||
|
jbe delete_vertical_block_line
|
||
|
xchg eax,[selection_position]
|
||
|
mov [caret_position],eax
|
||
|
delete_vertical_block_line:
|
||
|
mov ecx,[selection_position]
|
||
|
sub ecx,[caret_position]
|
||
|
call delete_from_line
|
||
|
mov esi,[caret_line]
|
||
|
call check_line_length
|
||
|
mov esi,[caret_line]
|
||
|
mov eax,[caret_line_number]
|
||
|
cmp eax,[selection_line_number]
|
||
|
je vertical_block_deleted
|
||
|
ja delete_in_previous_line
|
||
|
delete_in_next_line:
|
||
|
mov esi,[esi]
|
||
|
btr esi,0
|
||
|
jc delete_in_next_line
|
||
|
mov [caret_line],esi
|
||
|
inc [caret_line_number]
|
||
|
jmp delete_vertical_block_line
|
||
|
delete_in_previous_line:
|
||
|
mov esi,[esi+4]
|
||
|
mov [caret_line],esi
|
||
|
dec [caret_line_number]
|
||
|
jmp delete_vertical_block_line
|
||
|
vertical_block_deleted:
|
||
|
pop [caret_line_number]
|
||
|
pop [caret_line]
|
||
|
mov [selection_line],0
|
||
|
retn
|
||
|
|
||
|
get_block_length:
|
||
|
test [editor_mode],FEMODE_VERTICALSEL
|
||
|
jnz get_length_of_vertical_block
|
||
|
mov esi,[caret_line]
|
||
|
mov edx,[caret_position]
|
||
|
mov ebx,[selection_line]
|
||
|
mov ecx,[selection_position]
|
||
|
mov eax,[caret_line_number]
|
||
|
cmp eax,[selection_line_number]
|
||
|
je get_length_of_vertical_block
|
||
|
jb get_length_of_standard_block
|
||
|
xchg esi,ebx
|
||
|
xchg ecx,edx
|
||
|
get_length_of_standard_block:
|
||
|
push ecx
|
||
|
mov ecx,[esi+8]
|
||
|
sub ecx,edx
|
||
|
jae add_length_of_line
|
||
|
xor ecx,ecx
|
||
|
add_length_of_line:
|
||
|
add ecx,2
|
||
|
add [esp],ecx
|
||
|
skip_standard_block_line:
|
||
|
mov esi,[esi]
|
||
|
btr esi,0
|
||
|
jc skip_standard_block_line
|
||
|
cmp esi,ebx
|
||
|
je length_of_block_ok
|
||
|
mov ecx,[esi+8]
|
||
|
jmp add_length_of_line
|
||
|
length_of_block_ok:
|
||
|
pop ecx
|
||
|
retn
|
||
|
get_length_of_vertical_block:
|
||
|
mov edx,[caret_line_number]
|
||
|
sub edx,[selection_line_number]
|
||
|
jae vertical_dimension_ok
|
||
|
neg edx
|
||
|
vertical_dimension_ok:
|
||
|
mov eax,[caret_position]
|
||
|
sub eax,[selection_position]
|
||
|
jae horizontal_dimension_ok
|
||
|
neg eax
|
||
|
horizontal_dimension_ok:
|
||
|
mov ecx,eax
|
||
|
add eax,2
|
||
|
mul edx
|
||
|
add ecx,eax
|
||
|
retn
|
||
|
|
||
|
copy_block:
|
||
|
test [editor_mode],FEMODE_VERTICALSEL
|
||
|
jnz copy_vertical_block
|
||
|
mov esi,[caret_line]
|
||
|
mov edx,[caret_position]
|
||
|
mov ebx,[selection_line]
|
||
|
mov ecx,[selection_position]
|
||
|
mov eax,[caret_line_number]
|
||
|
cmp eax,[selection_line_number]
|
||
|
je copy_vertical_block
|
||
|
jb copy_standard_block
|
||
|
xchg esi,ebx
|
||
|
xchg ecx,edx
|
||
|
copy_standard_block:
|
||
|
push ecx
|
||
|
push ebx
|
||
|
mov ecx,[esi+8]
|
||
|
sub ecx,edx
|
||
|
jb after_line_end
|
||
|
call copy_from_line
|
||
|
jmp block_line_copied
|
||
|
after_line_end:
|
||
|
mov esi,[esi]
|
||
|
btr esi,0
|
||
|
jc after_line_end
|
||
|
block_line_copied:
|
||
|
pop ebx
|
||
|
copy_next_line:
|
||
|
mov ax,0A0Dh
|
||
|
stosw
|
||
|
cmp esi,ebx
|
||
|
je copy_from_last_line
|
||
|
push ebx
|
||
|
mov ecx,[esi+8]
|
||
|
xor edx,edx
|
||
|
call copy_from_line
|
||
|
pop ebx
|
||
|
jmp copy_next_line
|
||
|
copy_from_last_line:
|
||
|
pop ecx
|
||
|
xor edx,edx
|
||
|
call copy_from_line
|
||
|
xor al,al
|
||
|
stosb
|
||
|
retn
|
||
|
copy_vertical_block:
|
||
|
mov esi,[caret_line]
|
||
|
mov ebx,[selection_line]
|
||
|
mov edx,[caret_position]
|
||
|
mov ecx,[selection_position]
|
||
|
mov eax,[caret_line_number]
|
||
|
cmp eax,[selection_line_number]
|
||
|
jbe vertical_block_starting_line_ok
|
||
|
xchg esi,ebx
|
||
|
vertical_block_starting_line_ok:
|
||
|
cmp edx,ecx
|
||
|
jbe vertical_block_starting_position_ok
|
||
|
xchg edx,ecx
|
||
|
vertical_block_starting_position_ok:
|
||
|
sub ecx,edx
|
||
|
copy_line_from_vertical_block:
|
||
|
mov eax,ebx
|
||
|
sub eax,esi
|
||
|
push eax ebx ecx edx
|
||
|
call copy_from_line
|
||
|
pop edx ecx ebx eax
|
||
|
or eax,eax
|
||
|
jz vertical_block_copied
|
||
|
mov ax,0A0Dh
|
||
|
stosw
|
||
|
jmp copy_line_from_vertical_block
|
||
|
vertical_block_copied:
|
||
|
xor al,al
|
||
|
stosb
|
||
|
retn
|
||
|
copy_from_line:
|
||
|
mov ebx,ecx
|
||
|
find_copying_origin:
|
||
|
cmp edx,SEGMENT_DATA_LENGTH
|
||
|
jb copy_line_segment
|
||
|
mov esi,[esi]
|
||
|
btr esi,0
|
||
|
jnc line_data_ended
|
||
|
sub edx,SEGMENT_DATA_LENGTH
|
||
|
jmp find_copying_origin
|
||
|
copy_line_segment:
|
||
|
mov ecx,SEGMENT_DATA_LENGTH
|
||
|
sub ecx,edx
|
||
|
cmp ebx,ecx
|
||
|
jae line_segment_length_ok
|
||
|
mov ecx,ebx
|
||
|
line_segment_length_ok:
|
||
|
sub ebx,ecx
|
||
|
mov eax,[esi]
|
||
|
lea esi,[esi+SEGMENT_HEADER_LENGTH+edx]
|
||
|
rep movsb
|
||
|
mov esi,eax
|
||
|
btr esi,0
|
||
|
jnc line_data_ended
|
||
|
xor edx,edx
|
||
|
jmp copy_line_segment
|
||
|
line_data_ended:
|
||
|
or ebx,ebx
|
||
|
jz line_copy_done
|
||
|
mov ecx,ebx
|
||
|
mov al,20h
|
||
|
rep stosb
|
||
|
line_copy_done:
|
||
|
retn
|