added fasm2 as well

This commit is contained in:
2024-11-25 00:04:53 -05:00
parent 8a974e9c89
commit dceb330571
165 changed files with 78512 additions and 0 deletions

View File

@ -0,0 +1,536 @@
; 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 at_end_of_line
inc ecx
jmp count_line_characters
at_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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,199 @@
; flat editor core
; Copyright (c) 1999-2015, Tomasz Grysztar.
; All rights reserved.
init_editor_memory:
mov ecx,BLOCK_LENGTH
call get_memory
or eax,eax
jz memory_error
mov [editor_memory],eax
mov dword [eax],0
mov dword [eax+4],0
mov dword [eax+8],ebx
lea ebx,[eax+SEGMENT_LENGTH]
mov [unallocated_segments],ebx
mov [memory_search_segment],ebx
add eax,BLOCK_LENGTH
mov [unallocated_segments_end],eax
mov [memory_search_block],eax
mov [released_segments],0
call allocate_segment
mov [first_line],eax
mov [lines_count],1
mov [peak_line_length],0
mov [caret_line],eax
mov [caret_line_number],1
mov [window_line],eax
mov [window_line_number],1
mov edi,eax
xor eax,eax
mov ecx,SEGMENT_HEADER_LENGTH shr 2
rep stosd
mov eax,20202020h
mov ecx,SEGMENT_DATA_LENGTH shr 2
rep stosd
call allocate_segment
jc memory_shortage
mov [lengths_table],eax
mov edi,eax
xor eax,eax
mov ecx,SEGMENT_LENGTH shr 2
rep stosd
mov [caret_position],eax
mov [window_position],eax
mov [selection_line],eax
mov [undo_data],eax
mov [redo_data],eax
mov [search_data],eax
mov [editor_mode],eax
mov [unmodified_state],eax
clc
retn
memory_error:
stc
retn
reset_editor_memory:
mov esi,[editor_memory]
lea eax,[esi+SEGMENT_LENGTH]
mov [unallocated_segments],eax
mov [memory_search_segment],eax
lea eax,[esi+BLOCK_LENGTH]
mov [unallocated_segments_end],eax
mov [memory_search_block],eax
mov [released_segments],0
mov ebx,[esi]
release_blocks:
or ebx,ebx
jz release_done
push dword [ebx]
mov ebx,[ebx+8]
call release_memory
pop ebx
jmp release_blocks
release_done:
mov ebx,[editor_memory]
xor eax,eax
mov [ebx],eax
mov [undo_data],eax
mov [redo_data],eax
mov [search_data],eax
call allocate_segment
jc memory_shortage
mov [first_line],eax
mov [window_line],eax
mov [caret_line],eax
mov edi,eax
xor eax,eax
mov ecx,SEGMENT_HEADER_LENGTH shr 2
rep stosd
mov eax,20202020h
mov ecx,SEGMENT_DATA_LENGTH shr 2
rep stosd
xor eax,eax
mov [selection_line],eax
mov [peak_line_length],eax
mov [window_position],eax
inc eax
mov [window_line_number],eax
mov [caret_line_number],eax
mov [lines_count],eax
call allocate_segment
jc memory_shortage
mov [lengths_table],eax
mov edi,eax
xor eax,eax
mov ecx,SEGMENT_LENGTH shr 2
rep stosd
retn
release_editor_memory:
mov esi,[editor_memory]
release:
push dword [esi]
mov ebx,[esi+8]
call release_memory
pop esi
or esi,esi
jnz release
mov [editor_memory],0
retn
allocate_segment:
mov eax,[unallocated_segments]
cmp eax,[unallocated_segments_end]
je simple_allocation_failed
add [unallocated_segments],SEGMENT_LENGTH
clc
retn
simple_allocation_failed:
push ebx esi
mov ebx,[memory_search_block]
mov esi,[memory_search_segment]
cmp [released_segments],16
jb add_new_block
find_free_segment:
cmp esi,ebx
je find_in_next_block
cmp dword [esi],-1
je reuse_segment
add esi,SEGMENT_LENGTH
cmp esi,[memory_search_segment]
jne find_free_segment
add_new_block:
sub ebx,BLOCK_LENGTH
find_last_memory_block:
cmp dword [ebx],0
je allocate_more_memory
mov ebx,[ebx]
jmp find_last_memory_block
allocate_more_memory:
mov ecx,BLOCK_LENGTH
push ebx
call get_memory
pop esi
or eax,eax
jz allocation_failed
mov [esi],eax
mov dword [eax],0
mov [eax+4],esi
mov [eax+8],ebx
lea ebx,[eax+BLOCK_LENGTH]
mov [unallocated_segments_end],ebx
add eax,SEGMENT_LENGTH
lea ebx,[eax+SEGMENT_LENGTH]
mov [unallocated_segments],ebx
mov [released_segments],0
pop esi ebx
clc
retn
allocation_failed:
xor eax,eax
pop esi ebx
stc
retn
reuse_segment:
mov eax,esi
mov [memory_search_block],ebx
add esi,SEGMENT_LENGTH
mov [memory_search_segment],esi
dec [released_segments]
pop esi ebx
clc
retn
find_in_next_block:
sub ebx,BLOCK_LENGTH
mov esi,[ebx]
lea ebx,[esi+BLOCK_LENGTH]
or esi,esi
jnz find_free_segment
mov ebx,[editor_memory]
mov esi,ebx
add ebx,BLOCK_LENGTH
jmp find_free_segment
memory_shortage:
call undo_changes
jmp not_enough_memory

View File

@ -0,0 +1,511 @@
; flat editor core
; Copyright (c) 1999-2015, Tomasz Grysztar.
; All rights reserved.
find_line:
mov esi,[first_line]
mov ecx,1
mov edx,[window_line_number]
cmp eax,edx
jae forward_from_window
sub edx,eax
cmp edx,eax
jb backward_from_window
jmp find_forward
forward_from_window:
mov esi,[window_line]
mov ecx,edx
find_forward:
cmp ecx,eax
je line_found
cmp dword [esi],0
je line_found
mov ebx,esi
forward_skip_line:
mov ebx,[ebx]
btr ebx,0
jc forward_skip_line
or ebx,ebx
jz line_found
mov esi,ebx
inc ecx
jmp find_forward
backward_from_window:
mov esi,[window_line]
mov ecx,[window_line_number]
find_backward:
cmp ecx,eax
je line_found
cmp dword [esi+4],0
je line_found
mov esi,[esi+4]
dec ecx
jmp find_backward
line_found:
retn
get_caret_segment:
mov edx,[caret_position]
mov esi,[caret_line]
find_segment:
cmp edx,SEGMENT_DATA_LENGTH
jb segment_found
test byte [esi],1
jz segment_found
mov esi,[esi]
dec esi
sub edx,SEGMENT_DATA_LENGTH
jmp find_segment
segment_found:
retn
check_line_length:
xor edx,edx
mov ebx,esi
count_line_segments:
test byte [esi],1
jz last_line_segment
mov esi,[esi]
dec esi
add edx,SEGMENT_DATA_LENGTH
jmp count_line_segments
last_line_segment:
lea edi,[esi+SEGMENT_LENGTH-1]
mov al,20h
mov ecx,SEGMENT_DATA_LENGTH
std
repe scasb
cld
setne al
movzx eax,al
add ecx,eax
jnz line_segments_ok
or edx,edx
jz line_segments_ok
call store_freed_segment_for_undo
mov eax,[esi]
mov esi,[esi+4]
dec esi
call store_segment_for_undo
mov [esi],eax
sub edx,SEGMENT_DATA_LENGTH
jmp last_line_segment
line_segments_ok:
add ecx,edx
mov edx,ecx
cmp edx,[ebx+8]
je line_length_checked
mov esi,ebx
call store_segment_for_undo
xchg [ebx+8],edx
push edx
mov eax,[ebx+8]
call register_length
pop eax
call unregister_length
line_length_checked:
retn
register_length:
cmp eax,[peak_line_length]
jbe peak_length_ok
mov [peak_line_length],eax
peak_length_ok:
or eax,eax
jz ignore_zero_length
push ebx
call find_lengths_segment
inc dword [ebx+SEGMENT_HEADER_LENGTH+eax*4]
pop ebx
ignore_zero_length:
retn
find_lengths_segment:
mov ebx,[lengths_table]
try_lengths_segment:
cmp eax,SEGMENT_DATA_LENGTH/4
jb length_entry_ok
sub eax,SEGMENT_DATA_LENGTH/4
cmp dword [ebx],0
je add_lengths_segment
mov ebx,[ebx]
jmp try_lengths_segment
add_lengths_segment:
push eax ecx edi
call allocate_segment
jc memory_shortage
call store_allocated_segment_for_undo
mov [ebx],eax
mov edi,eax
xor eax,eax
stosd
mov eax,ebx
stosd
mov eax,[ebx+8]
add eax,SEGMENT_DATA_LENGTH/4
stosd
add edi,SEGMENT_HEADER_LENGTH-12
mov ecx,SEGMENT_DATA_LENGTH shr 2
xor eax,eax
rep stosd
lea ebx,[edi-SEGMENT_LENGTH]
pop edi ecx eax
jmp try_lengths_segment
length_entry_ok:
retn
unregister_length:
or eax,eax
jz ignore_zero_length
push ebx
cmp eax,[peak_line_length]
je unregister_peak_length
call find_lengths_segment
dec dword [ebx+SEGMENT_HEADER_LENGTH+eax*4]
length_unregistered:
pop ebx
retn
unregister_peak_length:
call find_lengths_segment
dec dword [ebx+SEGMENT_HEADER_LENGTH+eax*4]
jnz length_unregistered
find_reduced_peak:
or eax,eax
jz try_earlier_lengths_segment
dec eax
cmp dword [ebx+SEGMENT_HEADER_LENGTH+eax*4],0
je find_reduced_peak
add eax,[ebx+8]
mov [peak_line_length],eax
jmp length_unregistered
try_earlier_lengths_segment:
mov ebx,[ebx+4]
mov eax,SEGMENT_DATA_LENGTH/4
or ebx,ebx
jnz find_reduced_peak
mov [peak_line_length],ebx
jmp length_unregistered
update_window:
mov edx,[window_line_number]
cmp edx,1
je window_vertical_position_ok
add edx,[window_height]
dec edx
cmp edx,[lines_count]
jle window_vertical_position_ok
sub edx,[lines_count]
window_vertical_correction:
mov esi,[window_line]
mov esi,[esi+4]
or esi,esi
jz window_vertical_position_ok
mov [window_line],esi
dec [window_line_number]
dec edx
jnz window_vertical_correction
window_vertical_position_ok:
mov ecx,[peak_line_length]
cmp ecx,[caret_position]
jae caret_position_ok
mov ecx,[caret_position]
caret_position_ok:
cmp [selection_line],0
je selection_position_ok
cmp ecx,[selection_position]
jae selection_position_ok
mov ecx,[selection_position]
selection_position_ok:
mov eax,[window_width]
dec eax
cmp ecx,eax
jae edit_space_width_ok
mov ecx,eax
edit_space_width_ok:
mov [maximum_position],ecx
mov edx,[window_position]
or edx,edx
jz window_horizontal_position_ok
add edx,[window_width]
inc ecx
cmp edx,ecx
jbe window_horizontal_position_ok
sub edx,ecx
sub [window_position],edx
jnc window_horizontal_position_ok
mov [window_position],0
window_horizontal_position_ok:
retn
let_caret_appear:
mov eax,[caret_position]
cmp eax,[window_position]
jl horizontal_correction
mov ecx,[window_width]
jecxz last_position_ok
dec ecx
last_position_ok:
add ecx,[window_position]
mov eax,[caret_position]
sub eax,ecx
jbe horizontal_ok
add eax,[window_position]
horizontal_correction:
mov [window_position],eax
horizontal_ok:
mov esi,[caret_line]
mov ecx,[caret_line_number]
cmp ecx,[window_line_number]
jl vertical_correction
mov eax,[window_height]
or eax,eax
jz vertical_check
dec eax
vertical_check:
neg eax
add eax,[caret_line_number]
cmp [window_line_number],eax
jge vertical_ok
mov esi,[window_line]
mov ecx,[window_line_number]
vertical_find:
mov esi,[esi]
btr esi,0
jc vertical_find
inc ecx
cmp ecx,eax
jl vertical_find
vertical_correction:
mov [window_line],esi
mov [window_line_number],ecx
vertical_ok:
retn
move_line_up:
mov esi,[caret_line]
mov eax,[esi+4]
or eax,eax
jz cannot_move
mov [caret_line],eax
dec [caret_line_number]
clc
retn
cannot_move:
stc
retn
move_line_down:
mov esi,[caret_line]
find_next_line:
mov eax,[esi]
or eax,eax
jz cannot_move
btr eax,0
jnc down_ok
mov esi,eax
jmp find_next_line
down_ok:
mov [caret_line],eax
inc [caret_line_number]
clc
retn
move_page_up:
mov eax,[caret_line_number]
sub eax,[window_height]
ja pgup_caret_ok
mov eax,1
pgup_caret_ok:
call find_line
mov [caret_line],esi
mov [caret_line_number],ecx
mov eax,[window_line_number]
sub eax,[window_height]
ja pgup_window_ok
mov eax,1
cmp [window_line_number],eax
je moved_ok
pgup_window_ok:
call find_line
mov [window_line],esi
mov [window_line_number],ecx
retn
move_page_down:
mov eax,[caret_line_number]
add eax,[window_height]
call find_line
mov [caret_line],esi
mov [caret_line_number],ecx
mov eax,[window_line_number]
mov ecx,[window_height]
add eax,ecx
mov ebx,[lines_count]
sub ebx,ecx
jbe moved_ok
inc ebx
cmp eax,ebx
jb pgdn_window_ok
mov eax,ebx
cmp [window_line_number],eax
je moved_ok
pgdn_window_ok:
call find_line
mov [window_line],esi
mov [window_line_number],ecx
moved_ok:
retn
move_to_previous_word:
call get_caret_segment
mov ecx,[caret_position]
sub ecx,edx
cmp edx,SEGMENT_DATA_LENGTH
jbe find_word_to_the_left
mov edx,SEGMENT_DATA_LENGTH
find_word_to_the_left:
sub edx,1
jc word_in_previous_segment
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
call recognize_character
jnc find_word_start
jmp find_word_to_the_left
word_in_previous_segment:
mov eax,[esi+4]
or eax,eax
jz previous_word_ok
mov esi,eax
btr esi,0
jnc word_in_previous_line
mov edx,SEGMENT_DATA_LENGTH
sub ecx,edx
jmp find_word_to_the_left
word_in_previous_line:
mov [caret_line],esi
dec [caret_line_number]
mov edx,SEGMENT_DATA_LENGTH
xor ecx,ecx
find_last_segment:
test byte [esi],1
jz find_word_to_the_left
mov esi,[esi]
dec esi
add ecx,SEGMENT_DATA_LENGTH
jmp find_last_segment
find_word_start:
sub edx,1
jc word_on_segment_edge
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
call recognize_character
jc previous_word_ok
jmp find_word_start
word_on_segment_edge:
mov esi,[esi+4]
btr esi,0
jnc previous_word_ok
mov edx,SEGMENT_DATA_LENGTH
sub ecx,edx
jmp find_word_start
previous_word_ok:
add ecx,edx
inc ecx
mov [caret_position],ecx
retn
move_to_next_word:
mov ecx,[caret_position]
sub ecx,edx
find_word_end:
cmp edx,SEGMENT_DATA_LENGTH
jae word_wraps_segment_edge
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
call recognize_character
jc find_word_to_the_right
add edx,1
jmp find_word_end
word_wraps_segment_edge:
mov esi,[esi]
or esi,esi
jz move_to_line_end
btr esi,0
jnc word_in_next_line
add ecx,SEGMENT_DATA_LENGTH
sub edx,SEGMENT_DATA_LENGTH
jmp find_word_end
find_word_to_the_right:
cmp edx,SEGMENT_DATA_LENGTH
jae word_in_next_segment
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
call recognize_character
jnc next_word_ok
add edx,1
jmp find_word_to_the_right
word_in_next_segment:
mov esi,[esi]
or esi,esi
jz move_to_line_end
btr esi,0
jnc word_in_next_line
add ecx,SEGMENT_DATA_LENGTH
sub edx,SEGMENT_DATA_LENGTH
jmp find_word_to_the_right
word_in_next_line:
mov [caret_line],esi
inc [caret_line_number]
xor ecx,ecx
xor edx,edx
jmp find_word_to_the_right
next_word_ok:
add ecx,edx
mov [caret_position],ecx
retn
move_to_line_end:
mov esi,[caret_line]
mov eax,[esi+8]
mov [caret_position],eax
retn
get_word_at_caret:
call get_caret_segment
mov ebx,[caret_position]
sub ebx,edx
find_left_edge:
or edx,edx
jz left_edge_in_previous_segment
cmp edx,SEGMENT_DATA_LENGTH
ja left_edge_ok
mov al,[esi+SEGMENT_HEADER_LENGTH+edx-1]
call recognize_character
jc left_edge_ok
dec edx
jmp find_left_edge
left_edge_in_previous_segment:
mov esi,[esi+4]
btr esi,0
jnc left_edge_ok
mov edx,SEGMENT_DATA_LENGTH
sub ebx,edx
jmp find_left_edge
left_edge_ok:
add ebx,edx
call get_caret_segment
mov ecx,[caret_position]
sub ecx,edx
find_right_edge:
cmp edx,SEGMENT_DATA_LENGTH
jae right_edge_in_next_segment
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
call recognize_character
jc right_edge_ok
inc edx
jmp find_right_edge
right_edge_in_next_segment:
mov esi,[esi]
btr esi,0
jnc right_edge_ok
xor edx,edx
add ecx,SEGMENT_DATA_LENGTH
jmp find_right_edge
right_edge_ok:
add ecx,edx
sub ecx,ebx
mov edx,ebx
retn

View File

@ -0,0 +1,529 @@
; flat editor core
; Copyright (c) 1999-2015, Tomasz Grysztar.
; All rights reserved.
find_first:
mov [search_flags],eax
call release_search_data
or esi,esi
jz nothing_to_search_for
mov edi,esi
xor al,al
xor ecx,ecx
sub ecx,edi
repne scasb
lea ebx,[edi-1]
sub ebx,esi
jz nothing_to_search_for
lea ecx,[(256+ebx)*4+ebx]
push ebx
call get_memory
or eax,eax
jz not_enough_memory
mov [search_data],eax
mov [search_handle],ebx
pop ebx
mov edi,eax
lea ecx,[256+ebx]
mov eax,ebx
rep stosd
mov ecx,ebx
mov ebx,[search_data]
mov edx,ecx
test [search_flags],FEFIND_BACKWARD
jnz text_for_backward_search
test [search_flags],FEFIND_CASESENSITIVE
jnz copy_search_text
push ebx
mov ebx,upper_case_table
convert_search_text:
lodsb
xlatb
stosb
loop convert_search_text
pop ebx
jmp make_character_shifts_table
copy_search_text:
rep movsb
jmp make_character_shifts_table
text_for_backward_search:
add edi,ecx
mov edx,ecx
push ebx
mov ebx,upper_case_table
reverse_search_text:
lodsb
test [search_flags],FEFIND_CASESENSITIVE
jnz reverse_store_character
xlatb
reverse_store_character:
dec edi
mov [edi],al
dec ecx
jnz reverse_search_text
pop ebx
add edi,edx
xor ecx,ecx
make_character_shifts_table:
cmp edx,ecx
je character_shifts_table_ok
dec edi
jecxz character_shift_ok
mov al,[edi]
cmp [ebx+eax*4],edx
jne character_shift_ok
mov [ebx+eax*4],ecx
character_shift_ok:
inc ecx
jmp make_character_shifts_table
character_shifts_table_ok:
lea edi,[ebx+(256+ecx)*4]
push edi
lea edi,[edi+ecx-2]
movzx eax,byte [edi+1]
mov edx,[ebx+eax*4]
mov [ebx+256*4],edx
cmp ecx,1
je suffix_match_shifts_table_done
mov ecx,2
mov esi,edi
sub esi,edx
make_suffix_match_shifts_table:
cmp esi,[esp]
jb store_suffix_match_shift
mov al,[esi]
cmp al,[edi]
je store_suffix_match_shift
find_suffix_match:
dec esi
inc edx
cmp esi,[esp]
jb match_part_of_suffix
push ecx esi edi
repe cmpsb
pop edi esi ecx
jne find_suffix_match
jmp store_suffix_match_shift
match_part_of_suffix:
mov eax,[esp]
push ecx esi edi
xchg eax,esi
sub eax,esi
add ecx,eax
repe cmpsb
pop edi esi ecx
jne suffix_match_shifts_table_done
store_suffix_match_shift:
mov [ebx+256*4+(ecx-1)*4],edx
dec esi
dec edi
inc ecx
cmp ecx,[ebx]
jbe make_suffix_match_shifts_table
suffix_match_shifts_table_done:
pop eax
find_next:
mov edi,[search_data]
or edi,edi
jz nothing_to_search_for
push [caret_line]
push [caret_line_number]
push [caret_position]
push [selection_position]
test [search_flags],FEFIND_BACKWARD
jnz search_backward
test [search_flags],FEFIND_INWHOLETEXT
jz search_for_text
mov eax,[first_line]
mov [caret_line],eax
xor eax,eax
mov [caret_position],eax
inc eax
mov [caret_line_number],eax
search_for_text:
mov ecx,[edi]
dec ecx
add ecx,[caret_position]
mov esi,[caret_line]
cmp ecx,[peak_line_length]
jae text_not_in_this_line
mov [caret_position],ecx
call get_caret_segment
mov edi,[search_data]
mov eax,[edi]
lea ebx,[edi+(256+eax)*4]
mov ah,[ebx+eax-1]
mov ebx,upper_case_table
search_in_line:
cmp edx,SEGMENT_DATA_LENGTH
jae text_not_in_this_line
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
test [search_flags],FEFIND_CASESENSITIVE
jnz compare_last_character
xlatb
compare_last_character:
cmp al,ah
je partial_match
mismatch_shift:
movzx ecx,al
mov ecx,[edi+ecx*4]
shift_search_position:
add edx,ecx
add ecx,[caret_position]
cmp ecx,[peak_line_length]
jae text_not_in_this_line
mov [caret_position],ecx
check_search_position:
cmp edx,SEGMENT_DATA_LENGTH
jb search_in_line
mov ecx,[esi]
btr ecx,0
jnc search_in_line
sub edx,SEGMENT_DATA_LENGTH
mov esi,ecx
jmp check_search_position
partial_match:
mov ecx,[edi]
dec ecx
jz text_found
push edi
lea edi,[edi+(256+ecx+1)*4]
lea edi,[edi+ecx]
compare_text:
sub edx,1
jc compare_in_previous_segment
dec edi
mov al,20h
cmp edx,SEGMENT_DATA_LENGTH
jae compare_character
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
test [search_flags],FEFIND_CASESENSITIVE
jnz compare_character
xlatb
compare_character:
cmp al,[edi]
loope compare_text
pop edi
je text_found
neg ecx
add ecx,[edi]
dec ecx
add edx,ecx
mov ecx,[edi+(256+ecx-1)*4]
jmp shift_search_position
compare_in_previous_segment:
mov esi,[esi+4]
and esi,not 1
mov edx,SEGMENT_DATA_LENGTH
jmp compare_text
text_not_in_this_line:
mov esi,[esi]
or esi,esi
jz text_not_found
btr esi,0
jc text_not_in_this_line
search_in_next_line:
mov [caret_line],esi
inc [caret_line_number]
mov [caret_position],0
mov edi,[search_data]
jmp search_for_text
text_found:
mov eax,[caret_position]
inc eax
mov [selection_position],eax
sub eax,[edi]
mov [caret_position],eax
jz left_text_edge_ok
test [search_flags],FEFIND_WHOLEWORDS
jz left_text_edge_ok
mov edi,[search_data]
mov ecx,[edi]
mov al,[edi+(256+ecx)*4]
call recognize_character
jc left_text_edge_ok
dec [caret_position]
call get_caret_segment
inc [caret_position]
cmp edx,SEGMENT_DATA_LENGTH
jae left_text_edge_ok
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
call recognize_character
jnc found_not_acceptable
left_text_edge_ok:
mov eax,[caret_position]
xchg eax,[selection_position]
mov [caret_position],eax
mov edi,[search_data]
mov ecx,[edi]
lea edi,[edi+(256+ecx)*4]
mov al,[edi+ecx-1]
cmp al,20h
je right_text_edge_blank
test [search_flags],FEFIND_WHOLEWORDS
jz right_text_edge_ok
call recognize_character
jc right_text_edge_ok
call get_caret_segment
cmp edx,SEGMENT_DATA_LENGTH
jae right_text_edge_ok
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
call recognize_character
jc right_text_edge_ok
mov eax,[selection_position]
mov [caret_position],eax
found_not_acceptable:
mov edi,[search_data]
mov ecx,[edi]
mov eax,[edi+(256+ecx-1)*4]
add [caret_position],eax
jmp search_for_text
right_text_edge_blank:
call get_caret_segment
check_for_blank_end:
mov ecx,SEGMENT_DATA_LENGTH
sub ecx,edx
jz blank_end_next_segment
push edi
mov al,20h
lea edi,[esi+SEGMENT_HEADER_LENGTH+edx]
repe scasb
pop edi
jne right_text_edge_ok
blank_end_next_segment:
mov esi,[esi]
or esi,esi
jz text_not_found
btr esi,0
jnc search_in_next_line
xor edx,edx
jmp check_for_blank_end
right_text_edge_ok:
mov eax,[caret_line]
mov ecx,[caret_line_number]
mov [selection_line],eax
mov [selection_line_number],ecx
and [search_flags],not FEFIND_INWHOLETEXT
add esp,16
clc
retn
text_not_found:
pop [selection_position]
pop [caret_position]
pop [caret_line_number]
pop [caret_line]
nothing_to_search_for:
stc
retn
search_backward:
test [search_flags],FEFIND_INWHOLETEXT
jz backward_search_for_text
or eax,-1
call find_line
mov [caret_line],esi
mov [caret_line_number],ecx
call move_to_line_end
backward_search_for_text:
mov ecx,[caret_position]
sub ecx,1
jc backward_text_not_in_this_line
mov [caret_position],ecx
mov edi,[search_data]
mov eax,[edi]
mov al,[edi+(256+eax)*4]
cmp al,20h
jne backward_search_starting_position_ok
mov esi,[caret_line]
mov ecx,[esi+8]
mov edi,[search_data]
mov eax,[edi]
sub ecx,eax
jc backward_text_not_in_this_line
cmp ecx,[caret_position]
jae backward_search_starting_position_ok
mov [caret_position],ecx
backward_search_starting_position_ok:
call get_caret_segment
mov edi,[search_data]
mov eax,[edi]
lea ebx,[edi+(256+eax)*4]
mov ah,[ebx+eax-1]
mov ebx,upper_case_table
cmp edx,SEGMENT_DATA_LENGTH
jb backward_search_in_line
mov ecx,edx
sub ecx,SEGMENT_DATA_LENGTH-1
sub edx,ecx
sub [caret_position],ecx
backward_search_in_line:
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
test [search_flags],FEFIND_CASESENSITIVE
jnz compare_first_character
xlatb
compare_first_character:
cmp al,ah
je backward_partial_match
backward_mismatch_shift:
movzx ecx,al
mov ecx,[edi+ecx*4]
shift_backward_search_position:
sub edx,ecx
sub [caret_position],ecx
jc backward_text_not_in_this_line
check_backward_search_position:
cmp edx,0
jge backward_search_in_line
mov esi,[esi+4]
and esi,not 1
add edx,SEGMENT_DATA_LENGTH
jmp check_backward_search_position
backward_partial_match:
mov ecx,[edi]
dec ecx
jz backward_text_found
push edi
lea edi,[edi+(256+ecx+1)*4]
lea edi,[edi+ecx]
backward_compare_text:
inc edx
cmp edx,SEGMENT_DATA_LENGTH
jae compare_in_next_segment
dec edi
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
test [search_flags],FEFIND_CASESENSITIVE
jnz backward_compare_character
xlatb
backward_compare_character:
cmp al,[edi]
loope backward_compare_text
pop edi
je backward_text_found
neg ecx
add ecx,[edi]
dec ecx
sub edx,ecx
mov ecx,[edi+(256+ecx)*4]
jmp shift_backward_search_position
compare_in_next_segment:
sub edx,SEGMENT_DATA_LENGTH
mov esi,[esi]
btr esi,0
jnc compare_blank_space
dec edx
jmp backward_compare_text
compare_blank_space:
pop edi
cmp ecx,[edi]
jbe backward_text_found
backward_text_not_in_this_line:
mov esi,[caret_line]
mov esi,[esi+4]
or esi,esi
jz text_not_found
mov [caret_line],esi
dec [caret_line_number]
mov ecx,[peak_line_length]
mov [caret_position],ecx
jmp backward_search_for_text
backward_text_found:
test [search_flags],FEFIND_WHOLEWORDS
jz backward_left_text_edge_ok
cmp [caret_position],0
je backward_left_text_edge_ok
mov edi,[search_data]
mov ecx,[edi]
lea edi,[edi+(256+ecx)*4]
mov al,[edi+ecx-1]
call recognize_character
jc backward_left_text_edge_ok
dec [caret_position]
call get_caret_segment
inc [caret_position]
cmp edx,SEGMENT_DATA_LENGTH
jae backward_left_text_edge_ok
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
call recognize_character
jnc backward_found_not_acceptable
backward_left_text_edge_ok:
mov eax,[caret_position]
mov [selection_position],eax
mov edi,[search_data]
mov ecx,[edi]
add eax,ecx
mov [caret_position],eax
test [search_flags],FEFIND_WHOLEWORDS
jz backward_right_text_edge_ok
mov al,[edi+(256+ecx)*4]
call recognize_character
jc backward_right_text_edge_ok
call get_caret_segment
cmp edx,SEGMENT_DATA_LENGTH
jae backward_right_text_edge_ok
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
call recognize_character
jc backward_right_text_edge_ok
mov eax,[selection_position]
mov [caret_position],eax
backward_found_not_acceptable:
mov edi,[search_data]
mov ecx,[edi]
mov eax,[edi+(256+ecx-1)*4]
sub [caret_position],eax
jbe backward_text_not_in_this_line
jmp backward_search_for_text
backward_right_text_edge_ok:
mov eax,[caret_position]
xchg eax,[selection_position]
mov [caret_position],eax
mov eax,[caret_line]
mov ecx,[caret_line_number]
mov [selection_line],eax
mov [selection_line_number],ecx
and [search_flags],not FEFIND_INWHOLETEXT
add esp,16
clc
retn
get_search_text_length:
mov ecx,[search_data]
test ecx,ecx
jz no_search_text
mov ecx,[ecx]
clc
retn
get_search_text:
mov esi,[search_data]
test esi,esi
jz no_search_text
mov ecx,[esi]
lea esi,[esi+(256+ecx)*4]
test [search_flags],FEFIND_BACKWARD
jnz copy_inverted_text
rep movsb
xor al,al
stosb
clc
retn
copy_inverted_text:
mov al,[esi+ecx-1]
stosb
loop copy_inverted_text
xor al,al
stosb
clc
retn
no_search_text:
stc
retn
release_search_data:
mov edi,[search_data]
test edi,edi
jz search_data_released
mov ebx,[search_handle]
call release_memory
mov [search_data],0
search_data_released:
retn

View File

@ -0,0 +1,339 @@
; flat editor core
; Copyright (c) 1999-2015, Tomasz Grysztar.
; All rights reserved.
store_status_for_undo:
pusha
test [editor_mode],FEMODE_NOUNDO
jnz undo_disabled
call clear_redo_data
call allocate_segment
jc not_enough_memory
mov dword [eax],0
mov edi,eax
xchg eax,[undo_data]
push eax edi
call allocate_segment
pop edi
jnc store_editor_status
xor eax,eax
stosd
jmp not_enough_memory
store_editor_status:
mov dword [eax],0
mov dword [eax+4],0
stosd
pop eax
stosd
lea esi,[editor_status]
mov ecx,editor_status_size shr 2
rep movsd
mov esi,[lengths_table]
store_lengths_table:
call store_segment_for_undo
mov esi,[esi]
or esi,esi
jnz store_lengths_table
popa
store_status_for_undo_ok:
retn
undo_disabled:
call clear_redo_data
call clear_undo_data
or [unmodified_state],-1
popa
retn
store_segment_for_undo:
pusha
or esi,esi
jz segment_for_undo_done
call clear_redo_data
mov esi,[undo_data]
or esi,esi
jz segment_for_undo_done
mov ebx,[esi]
mov eax,[esp+4]
call prepare_slot_for_undo_storage
jc segment_for_undo_done
push edi
call allocate_segment
pop edi
mov ebx,eax
stosd
mov eax,[esp+4]
stosd
jc memory_shortage
mov esi,eax
mov edi,ebx
mov ecx,SEGMENT_LENGTH shr 2
rep movsd
segment_for_undo_done:
popa
store_segment_for_undo_ok:
retn
prepare_slot_for_undo_storage:
mov esi,[undo_data]
mov esi,[esi]
mov ecx,[esi+4]
lea edi,[esi+8]
repne scasd
jne get_free_slot
stc
retn
get_free_slot:
mov ecx,[esi+4]
lea edi,[esi+8+ecx*8]
inc ecx
cmp ecx,SEGMENT_DATA_LENGTH/8
jbe slot_ok
push esi
call allocate_segment
jc memory_shortage
mov esi,eax
mov ebx,[undo_data]
mov [ebx],esi
pop dword [esi]
mov ecx,1
lea edi,[esi+8]
slot_ok:
mov [esi+4],ecx
clc
retn
store_allocated_segment_for_undo:
pusha
call clear_redo_data
mov eax,[esp+1Ch]
xor edx,edx
mov [eax],edx
mov esi,[undo_data]
or esi,esi
jz segment_for_undo_done
call prepare_slot_for_undo_storage
jc segment_for_undo_done
xor eax,eax
stosd
mov eax,[esp+1Ch]
stosd
popa
retn
store_freed_segment_for_undo:
pusha
call clear_redo_data
mov esi,[undo_data]
or esi,esi
jz segment_for_undo_done
call prepare_slot_for_undo_storage
jc segment_for_undo_done
mov eax,[esp+4]
stosd
xor eax,eax
stosd
popa
retn
undo_changes:
mov esi,[undo_data]
or esi,esi
jz undo_ok
mov ebx,[esi]
mov eax,[redo_data]
xchg eax,[esi+4]
mov [undo_data],eax
mov [redo_data],esi
add esi,8
lea edi,[editor_status]
mov ecx,editor_status_size shr 2
call exchange_data
xor edx,edx
segments_block:
or ebx,ebx
jz undo_finished
mov esi,ebx
xchg ebx,edx
xchg ebx,[esi]
add esi,4
lodsd
mov ecx,eax
jecxz undo_finished
lea esi,[esi+ecx*8]
restore_segments:
sub esi,8
push esi ecx
mov edi,[esi+4]
mov esi,[esi]
or edi,edi
jz restore_next
or esi,esi
jz restore_next
mov ecx,SEGMENT_LENGTH shr 2
call exchange_data
restore_next:
pop ecx esi
loop restore_segments
jmp segments_block
undo_finished:
mov esi,[redo_data]
mov [esi],edx
undo_ok:
retn
exchange_data:
mov eax,[esi]
xchg eax,[edi]
mov [esi],eax
add esi,4
add edi,4
loop exchange_data
retn
redo_changes:
mov esi,[redo_data]
or esi,esi
jz redo_ok
mov ebx,[esi]
mov eax,[undo_data]
xchg eax,[esi+4]
mov [redo_data],eax
mov [undo_data],esi
add esi,8
lea edi,[editor_status]
mov ecx,editor_status_size shr 2
call exchange_data
xor edx,edx
redo_segments_block:
or ebx,ebx
jz redo_finished
mov esi,ebx
xchg ebx,edx
xchg ebx,[esi]
add esi,4
lodsd
mov ecx,eax
jecxz redo_finished
redo_segments:
push esi ecx
mov edi,[esi+4]
mov esi,[esi]
or edi,edi
jz redo_next
or esi,esi
jz redo_next
mov ecx,SEGMENT_LENGTH shr 2
call exchange_data
redo_next:
pop ecx esi
add esi,8
loop redo_segments
jmp redo_segments_block
redo_finished:
mov esi,[undo_data]
mov [esi],edx
redo_ok:
retn
clear_redo_data:
mov esi,[redo_data]
or esi,esi
jz redo_data_ok
clear_redo_block:
or ebx,-1
xchg ebx,[esi]
inc [released_segments]
mov eax,[esi+4]
mov [redo_data],eax
clear_redo_segments:
or ebx,ebx
jz next_redo_block
mov esi,ebx
or ebx,-1
xchg ebx,[esi]
inc [released_segments]
add esi,4
lodsd
mov ecx,eax
jecxz next_redo_block
release_redo_segments:
push esi ecx
mov edi,[esi+4]
mov esi,[esi]
or edi,edi
jz release_next_segment
or eax,-1
or esi,esi
jnz release_data
xchg eax,[edi]
jmp data_released
release_data:
xchg eax,[esi]
data_released:
cmp eax,-1
je release_next_segment
inc [released_segments]
release_next_segment:
pop ecx esi
add esi,8
loop release_redo_segments
jmp clear_redo_segments
next_redo_block:
mov esi,[redo_data]
or esi,esi
je redo_data_ok
cmp esi,[unmodified_state]
jne clear_redo_block
mov [unmodified_state],-1
jmp clear_redo_block
redo_data_ok:
retn
clear_undo_data:
mov esi,[undo_data]
push esi
clear_undo_block:
or esi,esi
jz undo_data_ok
or ebx,-1
xchg ebx,[esi]
inc [released_segments]
add esi,4
lodsd
mov [undo_data],eax
clear_undo_segments:
or ebx,ebx
jz next_undo_block
mov esi,ebx
or ebx,-1
xchg ebx,[esi]
inc [released_segments]
add esi,4
lodsd
mov ecx,eax
jecxz next_undo_block
lea esi,[esi+ecx*8]
release_segments:
sub esi,8
mov edx,[esi]
or edx,edx
jz release_next
or eax,-1
xchg [edx],eax
cmp eax,-1
je release_next
inc [released_segments]
release_next:
loop release_segments
next_undo_block:
mov esi,[undo_data]
cmp esi,[unmodified_state]
jne clear_undo_block
or [unmodified_state],-1
jmp clear_undo_block
undo_data_ok:
pop esi
cmp esi,[unmodified_state]
jne unmodified_ok
mov [unmodified_state],0
unmodified_ok:
retn

View File

@ -0,0 +1,40 @@
; flat editor core
; Copyright (c) 1999-2015, Tomasz Grysztar.
; All rights reserved.
editor_memory dd ?
label editor_status
first_line dd ?
lines_count dd ?
peak_line_length dd ?
maximum_position dd ?
window_line dd ?
window_position dd ?
window_line_number dd ?
caret_line dd ?
caret_position dd ?
caret_line_number dd ?
selection_line dd ?
selection_position dd ?
selection_line_number dd ?
editor_mode dd ?
editor_status_size = $ - editor_status
window_width dd ?
window_height dd ?
unallocated_segments dd ?
unallocated_segments_end dd ?
released_segments dd ?
memory_search_block dd ?
memory_search_segment dd ?
lengths_table dd ?
undo_data dd ?
redo_data dd ?
search_data dd ?
search_flags dd ?
search_handle dd ?
unmodified_state dd ?

View File

@ -0,0 +1,39 @@
; flat editor version 3.12
; Copyright (c) 1999-2015, Tomasz Grysztar.
; All rights reserved.
;
; This programs is free for commercial and non-commercial use as long as
; the following conditions are adhered to.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are
; met:
;
; 1. Redistributions of source code must retain the above copyright notice,
; this list of conditions and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
; The licence and distribution terms for any publically available
; version or derivative of this code cannot be changed. i.e. this code
; cannot simply be copied and put under another distribution licence
; (including the GNU Public Licence).
FEDIT_VERSION_STRING equ "3.12"
FEDIT_VERSION_MAJOR = 3
FEDIT_VERSION_MINOR = 12

View File

@ -0,0 +1,504 @@
; flat assembler g interface for Windows IDE
; Copyright (c) 2014-2024, Tomasz Grysztar.
; All rights reserved.
flat_assembler:
mov esi,[esp+4]
mov [source_path],esi
mov [maximum_number_of_errors],MAX_ERRORS
xor al,al
call assembly_init
mov eax,[maximum_number_of_passes]
shl eax,16
invoke PostMessage,[hwnd_progress],PBM_SETRANGE,0,eax
invoke PostMessage,[hwnd_progress],PBM_SETPOS,0,0
invoke GetTickCount
mov [timer],eax
assemble:
mov esi,source_header
mov edx,[source_path]
call assembly_pass
jc assembly_done
mov ebx,[current_pass]
invoke PostMessage,[hwnd_progress],PBM_SETPOS,ebx,0
cmp ebx,[maximum_number_of_passes]
jb assemble
call show_display_data
cmp [first_error],0
jne assembly_failed
call assembly_shutdown
mov esi,_code_cannot_be_generated
jmp fatal_error
assembly_done:
call show_display_data
cmp [first_error],0
jne assembly_failed
mov [executable_path],0
mov ebx,[source_path]
mov edi,[output_path]
call write_output_file
jc write_failed
mov eax,[current_pass]
xor edx,edx
call itoa
call display_error_string
mov esi,_passes
cmp [current_pass],1
jne display_passes_suffix
mov esi,_pass
display_passes_suffix:
xor ecx,ecx
call display_error_string
invoke GetTickCount
sub eax,[timer]
xor edx,edx
add eax,50
mov ecx,1000
div ecx
mov ebx,eax
mov eax,edx
xor edx,edx
mov ecx,100
div ecx
mov [timer],eax
xchg eax,ebx
or ebx,eax
jz display_output_length
xor edx,edx
call itoa
call display_error_string
mov esi,_message_suffix
mov ecx,1
call display_error_string
mov eax,[timer]
xor edx,edx
call itoa
call display_error_string
mov esi,_seconds
xor ecx,ecx
call display_error_string
display_output_length:
call get_output_length
push eax edx
call itoa
call display_error_string
pop edx eax
mov esi,_bytes
cmp eax,1
jne display_bytes_suffix
test edx,edx
jnz display_bytes_suffix
mov esi,_byte
display_bytes_suffix:
xor ecx,ecx
call display_error_string
mov esi,_new_line
xor ecx,ecx
call display_error_string
summary_done:
call assembly_shutdown
xor eax,eax
jmp shutdown
assembly_failed:
mov ebx,[first_error]
collect_error:
call show_error_message
xor esi,esi
mov ecx,1
call display_error_string
mov esi,[ebx+Error.preprocessed_data]
mov ecx,[ebx+Error.preprocessed_length]
push ebx
call show_preprocessed_line
pop ebx
xor esi,esi
mov ecx,1
call display_error_string
mov eax,[ebx+sizeof.Error+SourceContext.number_of_entries]
test eax,eax
jz display_error_message
lea esi,[ebx+sizeof.Error+sizeof.SourceContext]
dec eax
imul eax,sizeof.SourceEntry
lea edi,[esi+eax]
push esi edi
lea esi,[edi+SourceEntry.type]
mov ecx,1
call display_error_string
pop edi esi
find_file_source:
cmp [edi+SourceEntry.type],SOURCE_FILE
jne try_next_source_entry
cmp [edi+SourceEntry.line_number],0
jne file_source_found
try_next_source_entry:
cmp edi,esi
je no_file_source
sub edi,sizeof.SourceEntry
jmp find_file_source
file_source_found:
lea esi,[edi+SourceEntry.line_number]
mov ecx,4
push edi
call display_error_string
pop edi
mov esi,[edi+SourceEntry.name]
call display_error_string
jmp error_collected
no_file_source:
xor esi,esi
mov ecx,4
call display_error_string
error_collected:
xor esi,esi
mov ecx,1
call display_error_string
mov ebx,[ebx+Error.next]
test ebx,ebx
jnz collect_error
call assembly_shutdown
mov eax,2
jmp shutdown
write_failed:
call assembly_shutdown
mov esi,_write_failed
jmp fatal_error
out_of_memory:
call assembly_shutdown
mov esi,_out_of_memory
fatal_error:
xor ecx,ecx
call display_error_string
mov eax,1
shutdown:
push eax
invoke PostMessage,[hwnd_compiler],WM_COMMAND,IDOK,0
call [ExitThread]
LINE_FEED equ 13,10
system_init:
invoke HeapCreate,0,20000h,0
mov [memory],eax
test eax,eax
jz out_of_memory
invoke GetSystemTime,systemtime
invoke SystemTimeToFileTime,systemtime,filetime
mov ebx,[filetime.dwLowDateTime]
mov eax,[filetime.dwHighDateTime]
sub ebx,116444736000000000 and 0FFFFFFFFh
sbb eax,116444736000000000 shr 32
xor edx,edx
mov ecx,10000000
div ecx
mov dword [timestamp+4],eax
mov eax,ebx
div ecx
mov dword [timestamp],eax
retn
system_shutdown:
cmp [memory],0
je memory_released
invoke HeapDestroy,[memory]
memory_released:
retn
malloc:
malloc_fixed:
malloc_growable:
; in: ecx = requested size
; out: eax - allocated block, ecx = allocated size, on error jumps to out_of_memory (does not return)
; preserves: ebx, esi, edi
; note:
; use of malloc_fixed hints that block will be kept as is until the end of assembly
; use of malloc_growable hints that block is likely to be resized
invoke HeapAlloc,[memory],0,ecx
test eax,eax
jz out_of_memory
memory_allocated:
push eax
invoke HeapSize,[memory],0,eax
mov ecx,eax
pop eax
cmp ecx,-1
je out_of_memory
retn
realloc:
; in: eax - memory block, ecx = requested size
; out: eax - resized block, ecx = allocated size, on error jumps to out_of_memory (does not return)
; preserves: ebx, esi, edi
invoke HeapReAlloc,[memory],0,eax,ecx
test eax,eax
jnz memory_allocated
jmp out_of_memory
mfree:
; in: eax - memory block
; out: cf set on error
; preserves: ebx, esi, edi
; note: eax may have value 0 or -1, it should be treated as invalid input then
test eax,eax
jz interface_error
cmp eax,-1
je interface_error
invoke HeapFree,[memory],0,eax
test eax,eax
jz interface_error
clc
retn
interface_error:
stc
retn
open:
; in: edx - path to file
; out: ebx = file handle, cf set on error
; preserves: esi, edi
mov ebx,edx
invoke WaitForSingleObject,[mutex],-1
invoke CreateFile,ebx,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
cmp eax,-1
je release_mutex
mov ebx,eax
clc
retn
create:
; in: edx - path to file
; out: ebx = file handle, cf set on error
; preserves: esi, edi
cmp [executable_path],0
jne path_catching_done
push esi edi
mov esi,edx
mov edi,executable_path
catch_path:
lodsb
stosb
test al,al
jnz catch_path
pop edi esi
path_catching_done:
mov ebx,edx
invoke WaitForSingleObject,[mutex],-1
invoke CreateFile,ebx,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0
cmp eax,-1
je release_mutex
mov ebx,eax
clc
retn
write:
; in: ebx = file handle, edx - data, ecx = number of bytes
; out: cf set on error
; preserves: ebx, esi, edi
push ecx
invoke WriteFile,ebx,edx,ecx,systmp,0
pop ecx
test eax,eax
jz interface_error
cmp ecx,[systmp]
jne interface_error
clc
retn
read:
; in: ebx = file handle, edx - buffer, ecx = number of bytes
; out: cf set on error
; preserves: ebx, esi, edi
push ecx
invoke ReadFile,ebx,edx,ecx,systmp,0
pop ecx
test eax,eax
jz interface_error
cmp ecx,[systmp]
jne interface_error
clc
retn
close:
; in: ebx = file handle
; preserves: ebx, esi, edi
invoke CloseHandle,ebx
release_mutex:
invoke ReleaseMutex,[mutex] ; this relies on the fact that engine never opens more than one file at once
stc
retn
lseek:
; in: ebx = file handle, cl = method, edx:eax = offset
; out: edx:eax = new offset from the beginning of file, cf set on error
; preserves: ebx, esi, edi
movzx ecx,cl
mov [systmp],edx
invoke SetFilePointer,ebx,eax,systmp,ecx
cmp eax,-1
jne lseek_ok
invoke GetLastError
test eax,eax
jnz interface_error
not eax
lseek_ok:
mov edx,[systmp]
clc
retn
get_timestamp:
; out: edx:eax = timestamp
; preserves: ebx, ecx, esi, edi
; note: during the passes of a single assembly this function should always return the same value
mov eax,dword [timestamp]
mov edx,dword [timestamp+4]
retn
display_string:
; in:
; esi - string
; ecx = string length, zero for ASCIIZ string
; preserves: ebx, esi
push ebx
mov ebx,stdout
jmp write_string
display_error_string:
; in:
; esi - string
; ecx = string length, zero for ASCIIZ string
; preserves: ebx, esi
push ebx esi
mov ebx,stderr
write_string:
test ecx,ecx
jnz write_string_to_buffer
xor al,al
mov edi,esi
or ecx,-1
repne scasb
neg ecx
sub ecx,2
write_string_to_buffer:
mov edi,[ebx]
push ecx
invoke HeapSize,[hheap],0,dword [ebx]
mov edx,eax
sub eax,4
sub eax,[edi]
mov ecx,[esp]
sub ecx,eax
jb string_buffer_ready ; do not fit tight, leave room for terminating zero
add edx,ecx
inc edx
invoke HeapReAlloc,[hheap],0,dword [ebx],edx
test eax,eax
jz shutdown
mov [ebx],eax
mov edi,eax
string_buffer_ready:
pop ecx
mov eax,[edi]
add [edi],ecx
lea edi,[edi+4+eax]
xor al,al
test esi,esi
jz zero_string
rep movsb
stosb
pop esi ebx
retn
zero_string:
rep stosb
pop esi ebx
retn
get_environment_variable:
; in:
; esi - name
; edi - buffer for value
; ecx = size of buffer
; out:
; eax = length of value
; preserves: ebx, esi, edi
push ecx
invoke GetEnvironmentVariable,esi,string_buffer,1000h
invoke GetPrivateProfileString,_section_environment,esi,string_buffer,string_buffer,1000h,ini_path
mov ecx,[esp]
push esi edi
mov esi,string_buffer
copy_env_val:
lodsb
jecxz next_env_char
mov [edi],al
dec ecx
next_env_char:
inc edi
test al,al
jnz copy_env_val
mov eax,edi
pop edi esi ecx
sub eax,edi
retn
include '../../assembler.inc'
include '../../symbols.inc'
include '../../expressions.inc'
include '../../conditions.inc'
include '../../floats.inc'
include '../../directives.inc'
include '../../calm.inc'
include '../../errors.inc'
include '../../map.inc'
include '../../reader.inc'
include '../../output.inc'
include '../../console.inc'
section '.rdata' data readable
include '../../tables.inc'
include '../../messages.inc'
_pass db ' pass, ',0
_passes db ' passes, ',0
_dot db '.'
_seconds db ' seconds, ',0
_byte db ' byte.',0
_bytes db ' bytes.',0
_write_failed db 'Failed to write the output file.',0
_out_of_memory db 'Not enough memory to complete the assembly.',0
_code_cannot_be_generated db 'Could not generate code within the allowed number of passes.',0
version_string db VERSION,0
section '.bss' readable writeable
include '../../variables.inc'
source_string dd ?
source_path dd ?
output_path dd ?
maximum_number_of_passes dd ?
timestamp dq ?
systemtime SYSTEMTIME
filetime FILETIME
memory dd ?
systmp dd ?
timer dd ?
stdout dd ?
stderr dd ?

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
; flat editor mode flags
FEMODE_OVERWRITE = 1
FEMODE_VERTICALSEL = 2
FEMODE_NOUNDO = 4
FEMODE_READONLY = 8
; flat editor search flags
FEFIND_CASESENSITIVE = 1
FEFIND_WHOLEWORDS = 2
FEFIND_BACKWARD = 4
FEFIND_INWHOLETEXT = 8
; flat editor styles
FES_AUTOINDENT = 0001h
FES_AUTOBRACKETS = 0002h
FES_SMARTTABS = 0004h
FES_SECURESEL = 0008h
FES_OPTIMALFILL = 0010h
FES_CONSOLECARET = 0020h
FES_REVIVEDEADKEYS = 0040h
FES_TIMESCROLL = 0080h
; flat editor messages
FEM_SETMODE = WM_USER + 0
FEM_GETMODE = WM_USER + 1
FEM_SETPOS = WM_USER + 2
FEM_GETPOS = WM_USER + 3
FEM_SETSYNTAXHIGHLIGHT = WM_USER + 4
FEM_SETRIGHTCLICKMENU = WM_USER + 5
FEM_SETTEXTCOLOR = WM_USER + 6
FEM_SETSELCOLOR = WM_USER + 7
FEM_FINDFIRST = WM_USER + 8
FEM_FINDNEXT = WM_USER + 9
FEM_CANFINDNEXT = WM_USER + 10
FEM_GETLINELENGTH = WM_USER + 11
FEM_GETLINE = WM_USER + 12
FEM_GETWORDATCARET = WM_USER + 13
FEM_BEGINOPERATION = WM_USER + 14
FEM_ENDOPERATION = WM_USER + 15
FEM_MARKUNMODIFIED = WM_USER + 16
FEM_ISUNMODIFIED = WM_USER + 17
FEM_GETSEARCHTEXT = WM_USER + 18
FEM_GETSEARCHFLAGS = WM_USER + 19
FEM_RELEASESEARCH = WM_USER + 20
FEM_REDO = WM_USER + 84
FEM_CANREDO = WM_USER + 85
; flat editor notifications
FEN_SETFOCUS = 01h
FEN_KILLFOCUS = 02h
FEN_TEXTCHANGE = 03h
FEN_POSCHANGE = 04h
FEN_MODECHANGE = 05h
FEN_OUTOFMEMORY = 0Fh
; flat editor position structure
struct FEPOS
selectionPosition dd ?
selectionLine dd ?
caretPosition dd ?
caretLine dd ?
ends

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B