asm_dip/toolchain/fasmw17332/SOURCE/IDE/BLOCKS.INC
2024-11-24 23:13:28 -05:00

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