add flat assembler toolchain

This commit is contained in:
2024-11-24 23:13:28 -05:00
parent 99e8e4072b
commit dbfd94ea40
302 changed files with 145599 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 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,467 @@
; flat assembler interface for Win32 IDE
; Copyright (c) 1999-2022, Tomasz Grysztar.
; All rights reserved.
flat_assembler:
mov [initial_definitions],0
mov edx,[esp+4]
invoke GetFullPathName,edx,1000h,path_buffer,param_buffer
or eax,eax
jz exit_program
mov esi,path_buffer
mov [input_file],esi
mov [symbols_file],0
test [command_flags],2
jz symbols_file_name_ok
mov edi,path_buffer+1000h
mov [symbols_file],edi
mov ecx,eax
rep movsb
mov ecx,eax
xor al,al
stosb
sub edi,2
mov ebx,edi
mov al,'.'
std
repne scasb
cld
je attach_fas_extension
mov edi,ebx
attach_fas_extension:
inc edi
mov eax,'.fas'
stosd
xor al,al
stosb
symbols_file_name_ok:
mov [hfile],0
invoke GlobalAlloc,GMEM_MOVEABLE,1
mov [hmem_display],eax
invoke GlobalLock,[hmem_display]
mov byte [eax],0
invoke GlobalUnlock,[hmem_display]
mov [display_size],1
mov [error_data_size],0
mov [allocated_memory],0
mov eax,[compiler_memory]
shl eax,10
jz out_of_memory
allocate_memory:
mov edx,eax
shr edx,2
mov ecx,eax
sub ecx,edx
mov [memory_end],ecx
mov [additional_memory_end],edx
invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE
or eax,eax
jnz memory_allocated
mov eax,[additional_memory_end]
shl eax,1
cmp eax,4000h
jb out_of_memory
jmp allocate_memory
memory_allocated:
mov [allocated_memory],eax
mov [memory_start],eax
mov [code_start],eax
add eax,[memory_end]
mov [memory_end],eax
mov [additional_memory],eax
add [additional_memory_end],eax
mov [tagged_blocks],0
mov eax,esp
and eax,not 0FFFh
add eax,1000h-10000h
mov [stack_limit],eax
invoke PostMessage,[hwnd_progress],PBM_SETPOS,0,0
invoke SetThreadPriority,[hthread],[compiler_priority]
invoke GetTickCount
mov [start_time],eax
mov [preprocessing_done],0
call preprocessor
invoke PostMessage,[hwnd_progress],PBM_SETPOS,1,0
or [preprocessing_done],-1
call parser
invoke PostMessage,[hwnd_progress],PBM_SETPOS,2,0
call assembler
invoke PostMessage,[hwnd_progress],PBM_SETPOS,3,0
call formatter
invoke PostMessage,[hwnd_progress],PBM_SETPOS,4,0
call show_display_buffer
invoke GetTickCount
sub eax,[start_time]
mov [total_time],eax
mov esi,[output_file]
mov edi,path_buffer
copy_executable_name:
lodsb
stosb
or al,al
jnz copy_executable_name
xor al,al
exit_program:
movzx eax,al
push eax
mov eax,[allocated_memory]
or eax,eax
jz memory_ok
invoke VirtualFree,eax,0,MEM_RELEASE
mov [allocated_memory],0
memory_ok:
mov eax,[hfile]
or eax,eax
jz handle_ok
invoke CloseHandle,eax
handle_ok:
invoke PostMessage,[hwnd_compiler],WM_COMMAND,IDOK,0
call [ExitThread]
get_environment_variable:
invoke GetEnvironmentVariable,esi,string_buffer,1000h
mov ecx,[memory_end]
sub ecx,edi
cmp ecx,1000h
jbe get_local_variable
mov ecx,1000h
get_local_variable:
invoke GetPrivateProfileString,_section_environment,esi,string_buffer,edi,ecx,ini_path
add edi,eax
cmp edi,[memory_end]
jae out_of_memory
retn
open:
mov ebx,edx
invoke WaitForSingleObject,[mutex],-1
invoke CreateFile,ebx,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
cmp eax,-1
je file_error
mov [hfile],eax
mov ebx,eax
clc
retn
file_error:
stc
retn
create:
mov ebx,edx
invoke WaitForSingleObject,[mutex],-1
invoke CreateFile,ebx,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0
cmp eax,-1
je file_error
mov ebx,eax
clc
retn
write:
invoke WriteFile,ebx,edx,ecx,bytes_count,0
or eax,eax
jz file_error
clc
retn
read:
mov ebp,ecx
invoke ReadFile,ebx,edx,ecx,bytes_count,0
or eax,eax
jz file_error
cmp ebp,[bytes_count]
jne file_error
clc
retn
close:
cmp ebx,[hfile]
jne close_handle
mov [hfile],0
close_handle:
invoke CloseHandle,ebx
invoke ReleaseMutex,[mutex]
retn
lseek:
movzx eax,al
invoke SetFilePointer,ebx,edx,0,eax
cmp eax,-1
je file_error
clc
retn
display_block:
push edi
push ecx
add ecx,[display_size]
invoke GlobalReAlloc,[hmem_display],ecx,GMEM_MOVEABLE
or eax,eax
jz out_of_memory
mov [hmem_display],eax
invoke GlobalLock,[hmem_display]
add eax,[display_size]
lea edi,[eax-1]
pop ecx
add [display_size],ecx
rep movsb
xor al,al
stosb
invoke GlobalUnlock,[hmem_display]
pop edi
retn
fatal_error:
cmp [hthread],0
je error_outside_compiler
pop [error_message]
error_with_no_source:
mov al,0FFh
jmp exit_program
assembler_error:
cmp [hthread],0
je error_outside_compiler
call show_display_buffer
pop [error_message]
mov ebx,[current_line]
test ebx,ebx
jz error_with_no_source
xor ecx,ecx
get_error_lines:
mov eax,[ebx]
cmp byte [eax],0
je get_next_error_line
test byte [ebx+7],80h
jz error_lines_ok
inc ecx
mov edx,ebx
find_definition_origin:
mov edx,[edx+12]
test byte [edx+7],80h
jnz find_definition_origin
mov eax,[edx+4]
and eax,7FFFFFFFh
push eax
mov edx,[edx]
push edx
get_next_error_line:
mov ebx,[ebx+8]
jmp get_error_lines
error_lines_ok:
inc ecx
mov eax,[ebx+4]
and eax,7FFFFFFFh
push eax
mov edx,[ebx]
push edx
mov ebx,ecx
inc ecx
shl ecx,3
mov [error_data_size],ecx
invoke GlobalAlloc,GMEM_MOVEABLE,ecx
mov [hmem_error_data],eax
invoke GlobalLock,[hmem_error_data]
mov [eax],ebx
invoke GlobalUnlock,[hmem_error_data]
xor ebx,ebx
store_error_lines:
pop edx
invoke GetFullPathName,edx,1000h,path_buffer,param_buffer
inc eax
mov esi,eax
add eax,[error_data_size]
invoke GlobalReAlloc,[hmem_error_data],eax,GMEM_MOVEABLE
invoke GlobalLock,[hmem_error_data]
mov edi,eax
add edi,[error_data_size]
mov ecx,esi
mov esi,path_buffer
rep movsb
pop edx
mov [eax+8+ebx*8+4],edx
sub edi,eax
xchg [error_data_size],edi
mov [eax+8+ebx*8],edi
mov esi,[eax]
invoke GlobalUnlock,[hmem_error_data]
inc ebx
cmp ebx,esi
jb store_error_lines
mov edi,[additional_memory]
cmp [preprocessing_done],0
jne error_in_preprocessed
xor al,al
stosb
jmp instruction_converted
error_in_preprocessed:
mov esi,[current_line]
add esi,16
xor dl,dl
convert_instruction:
lodsb
cmp al,1Ah
je copy_symbol
cmp al,22h
je copy_symbol
cmp al,3Bh
je ignore_preprocessor_symbols
stosb
or al,al
jz instruction_converted
xor dl,dl
jmp convert_instruction
copy_symbol:
or dl,dl
jz space_ok
mov byte [edi],20h
inc edi
space_ok:
cmp al,22h
je quoted
lodsb
movzx ecx,al
rep movsb
or dl,-1
jmp convert_instruction
quoted:
mov al,27h
stosb
lodsd
mov ecx,eax
jecxz quoted_copied
copy_quoted:
lodsb
stosb
cmp al,27h
jne quote_ok
stosb
quote_ok:
loop copy_quoted
quoted_copied:
mov al,27h
stosb
or dl,-1
jmp convert_instruction
ignore_preprocessor_symbols:
xor al,al
stosb
instruction_converted:
sub edi,[additional_memory]
mov ebx,[error_data_size]
lea eax,[ebx+edi]
invoke GlobalReAlloc,[hmem_error_data],eax,GMEM_MOVEABLE
invoke GlobalLock,[hmem_error_data]
mov ecx,edi
mov [eax+4],ebx
lea edi,[eax+ebx]
mov esi,[additional_memory]
rep movsb
invoke GlobalUnlock,[hmem_error_data]
mov al,2
jmp exit_program
error_outside_compiler:
mov esp,[resume_esp]
jmp [resume_eip]
make_timestamp:
invoke GetSystemTime,systime
movzx ecx,[systime.wYear]
mov eax,ecx
sub eax,1970
mov ebx,365
mul ebx
mov ebp,eax
mov eax,ecx
sub eax,1969
shr eax,2
add ebp,eax
mov eax,ecx
sub eax,1901
mov ebx,100
div ebx
sub ebp,eax
mov eax,ecx
xor edx,edx
sub eax,1601
mov ebx,400
div ebx
add ebp,eax
movzx ecx,[systime.wMonth]
mov eax,ecx
dec eax
mov ebx,30
mul ebx
add ebp,eax
cmp ecx,8
jbe months_correction
mov eax,ecx
sub eax,7
shr eax,1
add ebp,eax
mov ecx,8
months_correction:
mov eax,ecx
shr eax,1
add ebp,eax
cmp ecx,2
jbe day_correction_ok
sub ebp,2
movzx ecx,word [systime.wYear]
test ecx,11b
jnz day_correction_ok
xor edx,edx
mov eax,ecx
mov ebx,100
div ebx
or edx,edx
jnz day_correction
mov eax,ecx
mov ebx,400
div ebx
or edx,edx
jnz day_correction_ok
day_correction:
inc ebp
day_correction_ok:
movzx eax,[systime.wDay]
dec eax
add eax,ebp
mov ebx,24
mul ebx
movzx ecx,[systime.wHour]
add eax,ecx
mov ebx,60
mul ebx
movzx ecx,[systime.wMinute]
add eax,ecx
mov ebx,60
mul ebx
movzx ecx,[systime.wSecond]
add eax,ecx
adc edx,0
retn
include '..\..\errors.inc'
include '..\..\symbdump.inc'
include '..\..\preproce.inc'
include '..\..\parser.inc'
include '..\..\exprpars.inc'
include '..\..\assemble.inc'
include '..\..\exprcalc.inc'
include '..\..\formats.inc'
include '..\..\x86_64.inc'
include '..\..\avx.inc'
include '..\..\tables.inc'
include '..\..\messages.inc'
section '.bss' readable writeable
include '..\..\variable.inc'
allocated_memory dd ?
start_time dd ?
total_time dd ?
display_size dd ?
error_message dd ?
error_data_size dd ?
preprocessing_done db ?

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

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