; flat assembler IDE for DOS/DPMI ; Copyright (c) 1999-2022, Tomasz Grysztar. ; All rights reserved. format MZ heap 0 stack stack_segment:stack_top-stack_bottom entry loader:init segment loader use16 init: mov ax,3301h xor dl,dl int 21h push ds cs pop ds mov ax,2524h mov dx,dos_error_handler int 21h pop ds mov ax,1A00h xor bx,bx int 10h cmp al,1Ah jne short no_vga cmp bl,8 jne short no_vga mov ax,1687h int 2Fh or ax,ax ; DPMI installed? jnz short no_dpmi test bl,1 ; 32-bit programs supported? jz short no_dpmi mov word [cs:mode_switch],di mov word [cs:mode_switch+2],es mov bx,si ; allocate memory for DPMI data mov ah,48h int 21h jnc switch_to_protected_mode init_failed: call init_error db 'DPMI initialization failed.',0Dh,0Ah,0 no_vga: call init_error db 'Color VGA adapter is required.',0Dh,0Ah,0 no_dpmi: call init_error db '32-bit DPMI services are not available.',0Dh,0Ah,0 init_error: pop si push cs pop ds display_error: lodsb test al,al jz short error_finish mov dl,al mov ah,2 int 21h jmp short display_error error_finish: mov ax,4CFFh int 21h dos_error_handler: mov al,3 iret switch_to_protected_mode: mov es,ax mov ds,[ds:2Ch] mov ax,1 call far [cs:mode_switch] ; switch to protected mode jc init_failed mov cx,1 xor ax,ax int 31h ; allocate descriptor for code jc init_failed mov si,ax xor ax,ax int 31h ; allocate descriptor for data jc init_failed mov di,ax mov dx,cs lar cx,dx shr cx,8 or cx,0C000h mov bx,si mov ax,9 int 31h ; set code descriptor access rights jc init_failed mov dx,ds lar cx,dx shr cx,8 or cx,0C000h mov bx,di int 31h ; set data descriptor access rights jc init_failed mov ecx,main shl ecx,4 mov dx,cx shr ecx,16 mov ax,7 int 31h ; set data descriptor base address jc init_failed mov bx,si int 31h ; set code descriptor base address jc init_failed mov cx,0FFFFh mov dx,0FFFFh mov ax,8 ; set segment limit to 4 GB int 31h jc init_failed mov bx,di int 31h jc init_failed mov ax,ds mov ds,di mov [main_selector],di mov [psp_selector],es mov [environment_selector],ax cli mov ss,di mov esp,stack_top sti mov es,di mov cx,1 xor ax,ax int 31h ; allocate descriptor for BIOS data segment jc init_failed mov bx,ax lar cx,[environment_selector] shr cx,8 mov ax,9 int 31h ; set descriptor access rights jc init_failed xor cx,cx mov dx,400h mov ax,7 int 31h ; set base address of BIOS data segment jc init_failed xor cx,cx mov dx,0FFh mov ax,8 int 31h ; set limit of BIOS data segment jc init_failed mov fs,bx mov [bios_selector],bx mov cx,1 xor ax,ax int 31h ; allocate descriptor for video segment jc init_failed mov bx,ax lar cx,[environment_selector] shr cx,8 mov ax,9 int 31h ; set descriptor access rights jc init_failed mov cx,0Bh mov dx,8000h mov ax,7 int 31h ; set base address of video segment jc init_failed xor cx,cx mov dx,4000-1 mov ax,8 int 31h ; set limit of video segment jc init_failed mov gs,bx mov [video_selector],bx push si push start retf mode_switch dd ? segment main use32 start: cld call init_video jc startup_failed call init_editor_memory jc startup_failed xor eax,eax mov [next_instance],eax mov [previous_instance],eax mov [file_path],eax mov ecx,1000h mov [line_buffer_size],ecx call get_memory or eax,eax jz startup_failed mov [line_buffer],eax mov [line_buffer_handle],ebx mov [stack_limit],stack_bottom mov edi,upper_case_table xor al,al mov ecx,80h prepare_case_table: stosb inc al loop prepare_case_table make_extended_case_table: push eax mov dl,al mov ax,6520h int 21h mov al,[esp] jc upper_case_character_ok mov al,dl upper_case_character_ok: stosb pop eax inc al jnz make_extended_case_table mov esi,upper_case_table+'A' mov edi,upper_case_table+'a' mov ecx,26 rep movsb xor al,al mov edi,lower_case_table prepare_lower_case_table: stosb inc al jnz prepare_lower_case_table mov esi,lower_case_table+'a' mov edi,lower_case_table+'A' mov ecx,26 rep movsb mov eax,80h xor edx,edx make_lower_case_table: mov dl,[upper_case_table+eax] cmp al,dl je lower_case_character_ok cmp dl,80h jb lower_case_character_ok mov [lower_case_table+edx],al lower_case_character_ok: inc al jnz make_lower_case_table mov edi,characters xor al,al prepare_characters_table: stosb inc al jnz prepare_characters_table mov esi,characters+'a' mov edi,characters+'A' mov ecx,26 rep movsb mov edi,characters mov esi,symbol_characters+1 movzx ecx,byte [esi-1] xor eax,eax convert_table: lodsb mov byte [edi+eax],0 loop convert_table mov [selected_character],'p' call get_low_memory push ds mov ds,[environment_selector] xor esi,esi mov edi,ini_path skip_environment: lodsb test al,al jnz skip_environment lodsb test al,al jnz skip_environment add esi,2 copy_program_path: lodsb stosb test al,al jnz copy_program_path pop ds dec edi mov edx,edi find_extension_start: cmp edi,ini_path je attach_extension cmp byte [edi-1],'.' je replace_extension cmp byte [edi-1],'/' je attach_extension dec edi jmp find_extension_start attach_extension: mov edi,edx mov al,'.' stosb replace_extension: mov [ini_extension],edi xor eax,eax mov [ini_data],eax mov [main_project_file],eax mov [clipboard],eax mov [current_operation],al mov [find_flags],eax mov [command_flags],al call load_configuration call update_positions call switch_to_ide_screen mov esi,81h process_arguments: push ds mov ds,[psp_selector] mov edi,filename_buffer find_argument: lodsb cmp al,20h je find_argument cmp al,9 je find_argument cmp al,22h je quoted_argument dec esi copy_argument: lodsb cmp al,20h je argument_end cmp al,9 je argument_end cmp al,0Dh je argument_end stosb jmp copy_argument quoted_argument: lodsb cmp al,0Dh je argument_end stosb cmp al,22h jne quoted_argument lodsb cmp al,22h je quoted_argument dec edi argument_end: dec esi pop ds cmp edi,filename_buffer je main_loop xor al,al stosb push esi mov edx,filename_buffer call load_file pop esi jmp process_arguments main_loop: call update_cursor call update_screen xor al,al xchg [current_operation],al mov [last_operation],al mov [was_selection],1 mov eax,[selection_line] or eax,eax jz no_selection cmp eax,[caret_line] jne get_command mov eax,[selection_position] cmp eax,[caret_position] jne get_command no_selection: mov [was_selection],0 mov eax,[caret_line] mov [selection_line],eax mov eax,[caret_position] mov [selection_position],eax mov eax,[caret_line_number] mov [selection_line_number],eax get_command: call wait_for_input cmp ah,1 je close_editor jb character cmp al,0Eh je new_editor cmp ah,94h je switch_editor cmp ah,0A5h je switch_editor cmp ah,3Bh je open_help cmp ah,3Ch je save_current cmp ah,55h je save_as cmp ah,3Eh je open_file cmp ah,3Fh je goto cmp ah,41h je search cmp ah,5Ah je search_next cmp ah,64h je replace cmp ah,43h je compile_and_run cmp ah,66h je compile cmp ah,65h je build_symbols cmp ah,5Ch je assign_to_compiler cmp ah,59h je toggle_readonly cmp ah,63h je calculator cmp ah,6Ch je show_user_screen cmp ah,44h je options cmp ah,3Dh je search_next test byte [fs:17h],1000b jz no_alt cmp ah,2Dh je close_all cmp ah,0Eh je undo cmp ah,0A3h je disable_undo cmp ah,98h je scroll_up cmp ah,0A0h je scroll_down cmp ah,9Bh je scroll_left cmp ah,9Dh je scroll_right no_alt: or al,al jz no_ascii cmp al,0E0h jne ascii no_ascii: cmp ah,4Bh je left_key cmp ah,4Dh je right_key cmp ah,48h je up_key cmp ah,50h je down_key cmp ah,47h je home_key cmp ah,4Fh je end_key cmp ah,77h je screen_home cmp ah,75h je screen_end cmp ah,73h je word_left cmp ah,74h je word_right cmp ah,8Dh je word_left cmp ah,91h je word_right cmp ah,49h je pgup_key cmp ah,51h je pgdn_key cmp ah,84h je text_home cmp ah,76h je text_end cmp ah,52h je ins_key cmp ah,0A2h je switch_blocks cmp ah,40h je f6_key cmp ah,93h je block_delete cmp ah,92h je block_copy cmp ah,53h je del_key cmp ah,78h jb get_command cmp ah,80h ja get_command sub ah,77h movzx ecx,ah jmp select_editor ascii: cmp al,7Fh je word_back cmp al,20h jae character cmp al,8 je backspace_key cmp al,9 je tab_key cmp al,0Dh je enter_key cmp al,19h je ctrl_y_key cmp al,1Ah je undo cmp al,18h je block_cut cmp al,3 je block_copy cmp al,16h je block_paste cmp al,0Fh je open_file cmp al,13h je save_current cmp al,6 je search cmp al,7 je goto cmp al,1 je select_all cmp al,2 je ascii_table jmp get_command character: test [editor_mode],FEMODE_READONLY jnz get_command cmp [was_selection],0 je no_selection_to_replace call store_status_for_undo test [editor_style],FES_SECURESEL jnz character_undo_ok push eax call delete_block pop eax call put_character call finish_edit mov [selection_line],0 jmp text_modified no_selection_to_replace: mov [current_operation],20h cmp [last_operation],20h jne character_undopoint mov edx,[unmodified_state] cmp edx,[undo_data] jne character_undo_ok or [unmodified_state],-1 jmp character_undo_ok character_undopoint: call store_status_for_undo character_undo_ok: call put_character call finish_edit mov [selection_line],0 jmp text_modified tab_key: test [editor_mode],FEMODE_READONLY jnz get_command call store_status_for_undo cmp [was_selection],0 je tab_securesel test [editor_style],FES_SECURESEL jnz tab_securesel call delete_block tab_securesel: call tabulate mov [selection_line],0 call finish_edit jmp text_modified enter_key: test [editor_mode],FEMODE_READONLY jnz get_command call store_status_for_undo cmp [was_selection],0 je enter_secureselection_ok test [editor_style],FES_SECURESEL jnz enter_secureselection_ok call delete_block enter_secureselection_ok: call carriage_return mov [selection_line],0 test [editor_mode],FEMODE_OVERWRITE jnz text_modified call finish_edit jmp text_modified backspace_key: test [editor_mode],FEMODE_READONLY jnz get_command test byte [fs:17h],100b jnz replace cmp [was_selection],0 je no_selection_to_clear test [editor_style],FES_SECURESEL jz block_delete no_selection_to_clear: cmp [caret_position],0 je line_back mov [current_operation],8 cmp [last_operation],8 jne backspace_undopoint mov edx,[unmodified_state] cmp edx,[undo_data] jne undo_back_ok or [unmodified_state],-1 jmp undo_back_ok backspace_undopoint: call store_status_for_undo undo_back_ok: dec [caret_position] call delete_character call finish_edit mov [selection_line],0 jmp text_modified line_back: test [editor_mode],FEMODE_OVERWRITE jnz get_command mov esi,[caret_line] mov esi,[esi+4] or esi,esi jz get_command call store_status_for_undo mov [caret_line],esi dec [caret_line_number] call check_line_length mov [caret_position],ecx call cut_line_break call finish_edit mov [selection_line],0 jmp text_modified word_back: call store_status_for_undo push [caret_position] mov esi,[caret_line] xor eax,eax xchg eax,[esi+4] push eax call move_to_previous_word pop eax mov esi,[caret_line] mov [esi+4],eax pop ecx sub ecx,[caret_position] call delete_from_line call finish_edit jmp text_modified del_key: test byte [fs:17h],11b jnz block_cut test [editor_mode],FEMODE_READONLY jnz get_command cmp [was_selection],0 je no_selection_on_del test [editor_style],FES_SECURESEL jz block_delete no_selection_on_del: mov esi,[caret_line] test [editor_mode],FEMODE_OVERWRITE jnz delete_char call check_line_length cmp ecx,[caret_position] ja delete_char cmp dword [esi],0 je get_command call store_status_for_undo call cut_line_break call finish_edit mov [selection_line],0 jmp text_modified delete_char: mov [current_operation],0E0h cmp [last_operation],0E0h je undo_delete_ok call store_status_for_undo undo_delete_ok: call delete_character call finish_edit mov [selection_line],0 jmp text_modified ctrl_y_key: test [editor_mode],FEMODE_READONLY jnz get_command call store_status_for_undo call remove_line jmp text_modified f6_key: test [editor_mode],FEMODE_READONLY jnz get_command call store_status_for_undo call duplicate_line jmp text_modified left_key: cmp [caret_position],0 jle text_modified dec [caret_position] jmp moved_caret right_key: mov eax,[caret_position] cmp eax,[maximum_position] jae text_modified inc [caret_position] jmp moved_caret up_key: call move_line_up jmp moved_caret down_key: call move_line_down jmp moved_caret home_key: mov [caret_position],0 jmp moved_caret end_key: call move_to_line_end jmp moved_caret screen_home: mov eax,[window_line] mov [caret_line],eax mov eax,[window_line_number] mov [caret_line_number],eax jmp moved_caret screen_end: mov eax,[window_line_number] add eax,[window_height] dec eax call find_line mov [caret_line],esi mov [caret_line_number],ecx jmp moved_caret pgup_key: call move_page_up jmp moved_caret pgdn_key: call move_page_down jmp moved_caret text_home: mov eax,[first_line] mov [caret_line],eax mov [caret_line_number],1 jmp moved_caret text_end: or eax,-1 call find_line mov [caret_line],esi mov [caret_line_number],ecx jmp moved_caret word_left: call move_to_previous_word jmp moved_caret word_right: call get_caret_segment call move_to_next_word jmp moved_caret scroll_left: cmp [window_position],0 je main_loop dec [window_position] jmp moved_window scroll_right: inc [window_position] jmp moved_window scroll_up: mov esi,[window_line] mov esi,[esi+4] or esi,esi jz main_loop mov [window_line],esi dec [window_line_number] jmp moved_window scroll_down: mov esi,[window_line] find_next_window_line: mov esi,[esi] btr esi,0 jc find_next_window_line or esi,esi jz main_loop mov [window_line],esi inc [window_line_number] jmp moved_window ins_key: and byte [fs:18h],not 80h test byte [fs:17h],11b jnz block_paste switch_mode: xor [editor_mode],FEMODE_OVERWRITE jmp main_loop switch_blocks: xor [editor_mode],FEMODE_VERTICALSEL jmp main_loop block_delete: test [editor_mode],FEMODE_READONLY jnz get_command cmp [was_selection],0 je get_command call store_status_for_undo call delete_block mov [selection_line],0 jmp operation_done block_copy: cmp [was_selection],0 je get_command call copy_to_clipboard jmp get_command copy_to_clipboard: cmp [clipboard],0 je allocate_clipboard mov ebx,[clipboard_handle] call release_memory allocate_clipboard: call get_block_length inc ecx call get_memory mov [clipboard],eax mov [clipboard_handle],ebx or eax,eax jz not_enough_memory mov edi,[clipboard] call copy_block retn block_cut: cmp [was_selection],0 je get_command call copy_to_clipboard jmp block_delete block_paste: test [editor_mode],FEMODE_READONLY jnz get_command call store_status_for_undo cmp [was_selection],0 je paste_secureselection_ok test [editor_style],FES_SECURESEL jnz paste_secureselection_ok call delete_block paste_secureselection_ok: mov esi,[clipboard] or esi,esi jz operation_done call insert_block jc paste_failed test [editor_style],FES_SECURESEL jz no_selection_after_paste mov eax,[caret_line] mov ecx,[caret_line_number] mov edx,[caret_position] xchg eax,[selection_line] xchg ecx,[selection_line_number] xchg edx,[selection_position] mov [caret_line],eax mov [caret_line_number],ecx mov [caret_position],edx jmp operation_done no_selection_after_paste: mov [selection_line],0 jmp operation_done paste_failed: call undo_changes jmp operation_done undo: test [editor_mode],FEMODE_READONLY jnz get_command test [editor_mode],FEMODE_NOUNDO jnz enable_undo test byte [fs:17h],11b jnz redo mov eax,[undo_data] test eax,eax jz get_command call undo_changes jmp operation_done redo: test [editor_mode],FEMODE_READONLY jnz get_command mov eax,[redo_data] test eax,eax jz get_command call redo_changes jmp operation_done enable_undo: and [editor_mode],not FEMODE_NOUNDO jmp main_loop disable_undo: call clear_redo_data call clear_undo_data or [editor_mode],FEMODE_NOUNDO jmp operation_done toggle_readonly: xor [editor_mode],FEMODE_READONLY jmp main_loop select_all: or eax,-1 call find_line mov [caret_line],esi mov [caret_line_number],ecx call check_line_length mov [caret_position],ecx mov eax,1 call find_line mov [selection_line],esi mov [selection_line_number],ecx mov [selection_position],0 jmp operation_done ascii_table: call ascii_table_window jc main_loop test al,al jz main_loop cmp al,1Ah je main_loop jmp character moved_caret: test byte [fs:17h],11b jnz operation_done mov [selection_line],0 jmp operation_done text_modified: cmp [was_selection],0 jne operation_done mov [selection_line],0 operation_done: call update_positions call let_caret_appear call update_window jmp main_loop moved_window: call update_positions cmp [was_selection],0 jne main_loop mov [selection_line],0 jmp main_loop new_editor: call create_editor_instance jmp main_loop close_editor: or [command_flags],8 jmp closing_loop close_all: and [command_flags],not 8 closing_loop: mov eax,[undo_data] cmp eax,[unmodified_state] je do_close mov esi,[file_path] call get_file_title mov ebx,esi mov esi,_saving_question mov eax,2 shl 24 mov ax,[message_box_colors] mov [first_button],_yes mov [second_button],_no call message_box cmp eax,1 jb main_loop ja do_close cmp [file_path],0 jne save_before_closing call get_saving_path jc main_loop save_before_closing: call save_file jc main_loop do_close: call remove_editor_instance jc shutdown test [command_flags],8 jnz main_loop call update_cursor call update_screen jmp closing_loop switch_editor: test byte [fs:17h],11b jnz previous_editor mov eax,[next_instance] or eax,eax jnz do_switch mov eax,[previous_instance] or eax,eax jz get_command find_first_editor: mov ebx,[eax+SEGMENT_HEADER_LENGTH+previous_instance-editor_data] or ebx,ebx jz do_switch mov eax,ebx jmp find_first_editor do_switch: call switch_editor_instance jmp main_loop previous_editor: mov eax,[previous_instance] or eax,eax jnz do_switch mov eax,[next_instance] or eax,eax jz get_command find_last_editor: mov ebx,[eax+SEGMENT_HEADER_LENGTH+next_instance-editor_data] or ebx,ebx jz do_switch mov eax,ebx jmp find_last_editor select_editor: mov eax,[editor_memory] mov edx,[previous_instance] prepare_for_editor_counting: or edx,edx jz find_selected_editor mov eax,edx mov edx,[edx+SEGMENT_HEADER_LENGTH+previous_instance-editor_data] jmp prepare_for_editor_counting find_selected_editor: dec ecx jz selected_editor_found mov eax,[eax+SEGMENT_HEADER_LENGTH+next_instance-editor_data] or eax,eax jz get_command jmp find_selected_editor selected_editor_found: cmp eax,[editor_memory] je get_command jmp do_switch show_user_screen: call switch_to_user_screen mov ah,10h int 16h call switch_to_ide_screen jmp main_loop save_current: test [editor_mode],FEMODE_READONLY jnz save_as cmp [file_path],0 jne do_save save_as: call get_saving_path jc main_loop do_save: call save_file jmp main_loop open_file: mov esi,_open call file_open_dialog jc main_loop call load_file jmp main_loop open_help: mov edi,[ini_extension] mov eax,'TXT' stosd mov edx,ini_path call load_file or [editor_mode],FEMODE_READONLY jmp main_loop goto: call goto_dialog jc main_loop or edx,edx jz goto_position_ok dec edx mov [caret_position],edx mov [selection_position],edx goto_position_ok: or ecx,ecx jz goto_line_ok mov eax,ecx call find_line mov [caret_line],esi mov [selection_line],esi mov [caret_line_number],ecx mov [selection_line_number],ecx goto_line_ok: call update_positions call let_caret_appear call update_window jmp main_loop search: call find_dialog jc main_loop call find_first jc not_found call show_found_text jmp main_loop not_found: call update_screen mov edi,buffer+1000h push edi call get_search_text jc main_loop mov edi,buffer mov esi,_not_found_after test [search_flags],FEFIND_BACKWARD jz make_not_found_message mov esi,_not_found_before make_not_found_message: mov ebx,esp call sprintf pop eax call release_search_data mov esi,buffer mov ebx,_find movzx eax,[message_box_colors] call message_box jmp main_loop show_found_text: mov eax,[caret_position] xchg eax,[selection_position] mov [caret_position],eax call update_positions call let_caret_appear call update_window mov eax,[caret_position] xchg eax,[selection_position] mov [caret_position],eax ret replace: call replace_dialog jc main_loop mov [replaces_count],0 push edi call find_first jc not_found call store_status_for_undo replace_loop: test [command_flags],1 jz do_replace call show_found_text call let_caret_appear call update_window call update_screen mov ebx,_replace mov esi,_replace_prompt mov eax,2 shl 24 mov ax,[message_box_colors] mov [first_button],_yes mov [second_button],_no or [command_flags],80h call message_box and [command_flags],not 80h cmp eax,1 jb replacing_finished ja replace_next do_replace: push [caret_line_number] push [caret_position] call delete_block pop edx ecx cmp ecx,[caret_line_number] jne simple_replace cmp edx,[caret_position] jne simple_replace mov esi,[esp] call insert_block mov esi,[caret_line] mov ecx,[caret_line_number] mov edx,[caret_position] 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 jmp replace_done simple_replace: mov esi,[esp] call insert_block replace_done: inc [replaces_count] replace_next: call find_next jnc replace_loop replacing_finished: call release_search_data call let_caret_appear call update_window call update_screen mov edi,buffer mov esi,_replaces_made mov ebx,replaces_count call sprintf mov esi,buffer mov ebx,_find movzx eax,[message_box_colors] call message_box jmp main_loop search_next: cmp [search_data],0 je main_loop call find_next jc not_found call show_found_text jmp main_loop build_symbols: and [command_flags],not 2 or [command_flags],4 jmp do_compile compile: and [command_flags],not (2 or 4) jmp do_compile compile_and_run: and [command_flags],not 4 or [command_flags],2 do_compile: push [editor_memory] mov eax,[main_project_file] or eax,eax jz got_main_file call switch_editor_instance got_main_file: cmp [file_path],0 jne main_file_path_ok call update_screen call get_saving_path jc main_loop call update_screen main_file_path_ok: mov eax,[editor_memory] push eax mov edx,[previous_instance] test edx,edx jz save_all_files mov eax,edx find_first_to_save: mov edx,[eax+SEGMENT_HEADER_LENGTH+previous_instance-editor_data] or edx,edx jz save_all_files mov eax,edx jmp find_first_to_save save_all_files: call switch_editor_instance cmp [file_path],0 je save_next mov eax,[undo_data] cmp eax,[unmodified_state] je save_next call save_file jc main_loop save_next: mov eax,[next_instance] or eax,eax jnz save_all_files pop eax call switch_editor_instance mov edi,buffer+3000h mov byte [edi],0 call get_current_directory mov esi,[file_path] mov edi,buffer mov ebx,edi copy_directory_path: lodsb or al,al jz directory_path_ok stosb cmp al,'\' jne copy_directory_path mov ebx,edi jmp copy_directory_path directory_path_ok: mov byte [ebx],0 mov esi,buffer call go_to_directory mov eax,[file_path] mov [input_file],eax mov [symbols_file],0 test [command_flags],4 jz symbols_file_name_ok mov edi,buffer+2000h mov [symbols_file],edi mov esi,eax xor ebx,ebx copy_file_name: lodsb stosb test al,al jz file_name_copied cmp al,'.' jne copy_file_name mov ebx,edi jmp copy_file_name file_name_copied: test ebx,ebx jz attach_fas_extension mov edi,ebx attach_fas_extension: dec edi mov eax,'.fas' stosd xor al,al stosb symbols_file_name_ok: pop eax call switch_editor_instance mov cx,1000h mov ah,1 int 10h mov esi,_compile mov cx,0316h mov ah,[window_colors] call draw_centered_window add edi,2 mov [progress_offset],edi mov eax,[memory_limit] test eax,eax jnz allocate_memory mov ax,500h mov edi,buffer int 31h mov eax,[edi] allocate_memory: mov ecx,eax mov edx,eax shr edx,2 sub eax,edx mov [memory_end],eax mov [additional_memory_end],edx call get_memory or eax,eax jnz memory_allocated mov eax,[additional_memory_end] shl eax,1 cmp eax,4000h jb not_enough_memory jmp allocate_memory get_current_directory: mov ah,19h int 21h mov bl,al mov dl,al inc dl xor esi,esi mov ax,7147h call dos_int jnc got_current_directory cmp ax,7100h je get_current_directory_short invalid_current_directory: stc ret get_current_directory_short: mov ah,47h call dos_int jc invalid_current_directory got_current_directory: cmp byte [buffer],0 je drive_prefix cmp byte [buffer+1],':' je copy_current_directory cmp word [buffer],'\\' je copy_current_directory drive_prefix: mov al,bl add al,'A' mov ah,':' stosw mov al,'\' stosb copy_current_directory: mov esi,buffer call copy_asciiz clc ret go_to_directory: cmp esi,buffer je directory_path_ready mov edi,buffer call copy_asciiz mov esi,buffer directory_path_ready: mov ah,0Eh mov dl,[buffer] sub dl,'A' jc current_directory_ok cmp dl,'Z'-'A' jbe change_current_drive sub dl,'a'-'A' change_current_drive: int 21h xor dx,dx mov ax,713Bh call dos_int cmp ax,7100h jne current_directory_ok mov ah,3Bh call dos_int current_directory_ok: ret memory_allocated: mov [allocated_memory],ebx mov [memory_start],eax add eax,[memory_end] mov [memory_end],eax mov [additional_memory],eax add [additional_memory_end],eax xor eax,eax mov [initial_definitions],eax mov [output_file],eax mov [display_length],eax mov ax,204h mov bl,9 int 31h mov dword [keyboard_handler],edx mov word [keyboard_handler+4],cx mov ax,205h mov bl,9 mov cx,cs mov edx,aborting_handler int 31h mov eax,[fs:6Ch] mov [start_time],eax call preprocessor call draw_progress_segment call parser call draw_progress_segment call assembler call draw_progress_segment call formatter call draw_progress_segment mov ax,205h mov bl,9 mov edx,dword [keyboard_handler] mov cx,word [keyboard_handler+4] int 31h test [command_flags],2 jnz execute mov esi,buffer+3000h call go_to_directory call show_display_buffer call update_screen mov edi,buffer movzx eax,[current_pass] inc eax call number_as_text mov eax,' pas' stosd mov eax,'ses,' stosd mov al,20h stosb mov eax,[fs:6Ch] sub eax,[start_time] mov ebx,100 mul ebx mov ebx,182 div ebx or eax,eax jz show_bytes_count xor edx,edx mov ebx,10 div ebx push edx call number_as_text mov al,'.' stosb pop eax call number_as_text mov eax,' sec' stosd mov eax,'onds' stosd mov ax,', ' stosw show_bytes_count: mov eax,[written_size] call number_as_text mov eax,' byt' stosd mov eax,'es.' stosd mov ebx,[allocated_memory] call release_memory mov esi,buffer mov ebx,_compile movzx eax,[message_box_colors] mov [first_button],_ok mov [second_button],_get_display cmp [display_length],0 je show_compilation_summary or eax,2 shl 24 show_compilation_summary: call message_box cmp eax,2 jb main_loop cmp [clipboard],0 je get_display_to_clipboard mov ebx,[clipboard_handle] call release_memory get_display_to_clipboard: mov ecx,[display_length] inc ecx call get_memory mov [clipboard_handle],ebx mov [clipboard],eax or eax,eax jz not_enough_memory xor esi,esi mov edi,eax mov ecx,[display_length] push ds mov ds,[low_memory_selector] rep movsb pop ds xor al,al stosb jmp main_loop execute: mov edx,[output_file] call adapt_path mov ebx,[allocated_memory] call release_memory cmp [output_format],3 ja cannot_execute call release_low_memory call switch_to_user_screen call close_video mov edi,buffer+200h lea edx,[edi-buffer] mov ax,0D00h stosw lea esi,[edi-buffer] xor al,al stosb mov al,20h mov ecx,11 rep stosb xor al,al mov ecx,25 rep stosb lea ebx,[edi-buffer] xor eax,eax stosw mov ax,buffer_segment shl eax,16 mov ax,dx stosd mov ax,si stosd stosd mov ax,4B00h xor dx,dx call dos_int mov esi,buffer+3000h call go_to_directory call init_video jc startup_failed call switch_to_ide_screen call get_low_memory jmp main_loop cannot_execute: mov esi,buffer+3000h call go_to_directory mov esi,_not_executable mov ebx,_error movzx eax,[error_box_colors] call message_box jmp main_loop draw_progress_segment: mov eax,[progress_offset] mov ecx,4 draw_progress_filler: mov byte [gs:eax],254 add eax,2 loop draw_progress_filler mov [progress_offset],eax ret aborting_handler: push eax in al,60h cmp al,1 jne no_abort mov dword [esp+4],abort_compiling mov word [esp+4+4],cs no_abort: pop eax jmp pword [cs:keyboard_handler] abort_compiling: cli mov ax,[cs:main_selector] mov esp,stack_top mov ss,ax mov ds,ax mov es,ax mov fs,[bios_selector] mov gs,[video_selector] mov ax,205h mov bl,9 mov edx,dword [keyboard_handler] mov cx,word [keyboard_handler+4] int 31h sti discard_keyboard_buffer: mov ah,11h int 16h jz keyboard_buffer_ok mov ah,10h int 16h jmp discard_keyboard_buffer keyboard_buffer_ok: mov ebx,[allocated_memory] call release_memory mov esi,buffer+3000h call go_to_directory jmp main_loop assign_to_compiler: mov eax,[editor_memory] xchg eax,[main_project_file] cmp eax,[editor_memory] jne main_loop mov [main_project_file],0 jmp main_loop calculator: call calculator_window jmp main_loop options: push [editor_style] call options_dialog pop eax jnc main_loop mov [editor_style],eax jmp main_loop startup_failed: mov esi,_startup_failed error_message_loop: lodsb or al,al jz error_message_ok mov dl,al mov ah,2 int 21h jmp error_message_loop error_message_ok: mov ax,4C0Fh int 21h init_video: call check_video_mode mov bx,gs movzx edx,byte [fs:4Ah] mov [screen_width],edx shl edx,1 mov [video_pitch],edx movzx eax,byte [fs:84h] inc eax mov [screen_height],eax imul edx,eax push edx dec edx shld ecx,edx,16 mov ax,8 int 31h jc video_init_failed pop ecx call get_memory jc video_init_failed mov [video_storage],eax mov [video_storage_handle],ebx clc ret video_init_failed: stc ret check_video_mode: test byte [fs:65h],110b jnz set_video_mode cmp byte [fs:4Ah],80 jb set_video_mode ret set_video_mode: mov ax,3 int 10h ret close_video: mov ebx,[video_storage_handle] call release_memory ret switch_to_ide_screen: call check_video_mode xor esi,esi mov edi,[video_storage] mov ecx,[video_pitch] imul ecx,[screen_height] rep movs byte [es:edi],[gs:esi] mov ah,3 xor bh,bh int 10h mov [stored_cursor],cx mov [stored_cursor_position],dx mov ah,0Fh int 10h mov [stored_page],bh mov ax,0500h int 10h mov al,[fs:65h] mov [stored_mode],al mov ax,1003h xor bx,bx int 10h mov eax,[screen_width] mov [window_width],eax mov eax,[screen_height] sub eax,2 mov [window_height],eax call update_window ret switch_to_user_screen: push es gs pop es mov esi,[video_storage] xor edi,edi mov ecx,[video_pitch] imul ecx,[screen_height] rep movs byte [es:edi],[ds:esi] mov ah,1 mov cx,[stored_cursor] int 10h mov ah,2 xor bh,bh mov dx,[stored_cursor_position] int 10h mov ah,5 mov al,[stored_page] int 10h mov ax,1003h xor bh,bh mov bl,[stored_mode] shr bl,5 and bl,1 int 10h pop es ret create_editor_instance: call flush_editor_data mov esi,[editor_memory] find_last_instance: mov eax,[esi+SEGMENT_HEADER_LENGTH+next_instance-editor_data] or eax,eax jz attach_new_instance mov esi,eax jmp find_last_instance attach_new_instance: push esi call init_editor_memory pop esi jc not_enough_memory mov eax,[editor_memory] xchg eax,[esi+SEGMENT_HEADER_LENGTH+next_instance-editor_data] mov [next_instance],eax mov [previous_instance],esi xor eax,eax mov [file_path],eax flush_editor_data: mov edi,[editor_memory] test edi,edi jz flush_ok add edi,SEGMENT_HEADER_LENGTH mov esi,editor_data mov ecx,editor_data_size rep movsb flush_ok: ret switch_editor_instance: call flush_editor_data cmp eax,[editor_memory] je editor_switch_ok mov [editor_memory],eax lea esi,[eax+SEGMENT_HEADER_LENGTH] mov edi,editor_data mov ecx,editor_data_size rep movsb editor_switch_ok: call update_positions ret remove_editor_instance: mov eax,[editor_memory] xor eax,[main_project_file] jnz main_project_file_ok mov [main_project_file],eax main_project_file_ok: mov esi,[previous_instance] mov edi,[next_instance] mov eax,edi or edi,edi jz next_instance_links_ok mov [edi+SEGMENT_HEADER_LENGTH+previous_instance-editor_data],esi next_instance_links_ok: or esi,esi jz previous_instance_links_ok mov [esi+SEGMENT_HEADER_LENGTH+next_instance-editor_data],edi mov eax,esi previous_instance_links_ok: push eax call release_editor_memory mov eax,[file_path] or eax,eax jz file_path_released mov ebx,[file_path_handle] call release_memory file_path_released: pop eax or eax,eax jz no_instance_left call switch_editor_instance clc ret no_instance_left: stc ret load_file: push edx push [editor_memory] call get_full_pathname push esi call flush_editor_data mov esi,[esp] mov edx,[editor_memory] prepare_to_scan_editors: mov eax,[edx+SEGMENT_HEADER_LENGTH+previous_instance-editor_data] or eax,eax jz scan_editors mov edx,eax jmp prepare_to_scan_editors scan_editors: mov edi,[edx+SEGMENT_HEADER_LENGTH+file_path-editor_data] or edi,edi jz scan_next_editor xor ecx,ecx mov ebx,lower_case_table compare_pathnames: mov al,[esi+ecx] xlatb mov ah,al mov al,[edi+ecx] xlatb cmp al,ah jne scan_next_editor or al,ah jz file_found inc ecx jmp compare_pathnames scan_next_editor: mov edx,[edx+SEGMENT_HEADER_LENGTH+next_instance-editor_data] or edx,edx jnz scan_editors mov eax,[undo_data] sub eax,[unmodified_state] or eax,[file_path] jz open_in_current_instance call create_editor_instance open_in_current_instance: pop esi call use_pathname mov edx,[file_path] call open jc load_failed xor edx,edx mov al,2 call lseek push eax ebx lea ecx,[eax+1] call get_memory or eax,eax jz not_enough_memory mov esi,eax mov edi,ecx pop ebx xor edx,edx xor al,al call lseek pop ecx mov edx,esi mov byte [edx+ecx],0 call read jc load_failed call close push edi call set_text pop ebx call release_memory add esp,8 ret file_found: mov eax,edx call switch_editor_instance pop esi add esp,8 ret load_failed: mov eax,[previous_instance] or eax,[next_instance] jnz cancel_instance cancel_path_only: xor ebx,ebx xchg ebx,[file_path] call release_memory jmp editor_cancelled cancel_instance: mov eax,[editor_memory] cmp eax,[esp] je cancel_path_only call remove_editor_instance editor_cancelled: pop eax call switch_editor_instance call update_screen mov edi,buffer mov esi,_loading_error mov ebx,esp call sprintf pop eax mov esi,buffer mov ebx,_error movzx eax,[error_box_colors] call message_box ret get_full_pathname: call adapt_path sub edi,buffer mov ax,7160h xor cx,cx xor si,si stc call dos_int jnc got_full_pathname mov ah,60h call dos_int jc full_pathname_exit got_full_pathname: lea esi,[buffer + edi] cmp word [esi],'\\' jne full_pathname_ok cmp dword [esi+3],'.\A.' jne full_pathname_ok mov al,[esi+2] mov ah,':' add esi,5 mov [esi],ax full_pathname_ok: clc full_pathname_exit: ret use_pathname: mov edi,[file_path] or edi,edi jnz copy_pathname mov ecx,1000h push esi call get_memory pop esi or eax,eax jz not_enough_memory mov edi,eax mov [file_path],edi mov [file_path_handle],ebx copy_pathname: lodsb stosb or al,al jnz copy_pathname ret save_file: mov edx,[file_path] call create jc file_creation_error mov [file_handle],ebx mov esi,[first_line] mov edi,[line_buffer] copy_text: mov ecx,[esi+8] lea eax,[edi+ecx] mov edx,[line_buffer_size] shr edx,1 sub eax,edx cmp eax,[line_buffer] ja flush_to_file mov ebp,edi xor edx,edx push ecx call copy_from_line pop ecx test [editor_style],FES_OPTIMALFILL jz line_copied cmp ecx,8 jb line_copied push esi edi ecx mov esi,ebp mov edi,[line_buffer] mov eax,[line_buffer_size] shr eax,1 add edi,eax push edi mov ecx,[esp+4] xor al,al rep stosb mov ecx,[esp+4] mov edi,[esp] call syntax_proc pop ebx ecx edi mov esi,ebp mov edi,ebp sub ebx,esi xor edx,edx optimal_fill: lodsb cmp al,20h jne store_character cmp byte [esi-1+ebx],0 jne store_character mov eax,esi sub eax,ebp test eax,111b jz store_tab inc edx mov al,20h stosb loop optimal_fill jmp optimal_fill_done store_tab: mov al,20h or edx,edx jz store_character sub edi,edx mov al,9 store_character: stosb xor edx,edx loop optimal_fill optimal_fill_done: pop esi jmp line_copied line_copied: or esi,esi jz flush_to_file mov ax,0A0Dh stosw jmp copy_text flush_to_file: push esi mov edx,[line_buffer] mov ecx,edi sub ecx,edx mov ebx,[file_handle] call write jc file_writing_error pop esi mov edi,[line_buffer] or esi,esi jnz copy_text mov ebx,[file_handle] call close mov eax,[undo_data] mov [unmodified_state],eax clc ret file_writing_error: add esp,4 file_creation_error: call update_screen mov esi,_saving_error mov ebx,_error movzx eax,[error_box_colors] call message_box stc ret get_saving_path: mov esi,_save_as call file_open_dialog jc saving_aborted push edx cmp byte [edx+ecx-1],'\' je save_in_new_directory call open pop edx jc saving_allowed push edx call close call update_screen mov edi,buffer mov esi,_overwrite_question mov ebx,esp call sprintf mov esi,buffer mov ebx,_save_as mov eax,2 shl 24 mov ax,[message_box_colors] mov [first_button],_yes mov [second_button],_no call message_box pop edx cmp eax,1 jb saving_aborted je saving_allowed call update_screen jmp get_saving_path save_in_new_directory: mov byte [edx+ecx-1],0 call update_screen mov edi,buffer mov esi,_directory_question mov ebx,esp call sprintf mov esi,buffer mov ebx,_save_as mov eax,2 shl 24 mov ax,[message_box_colors] mov [first_button],_yes mov [second_button],_no call message_box pop esi cmp eax,1 jb saving_aborted jne saving_directory_ok mov edi,buffer call copy_asciiz mov ax,7139h xor edx,edx call dos_int jnc new_directory_created cmp ax,7100h jne error_creating_directory mov ah,39h call dos_int jc error_creating_directory new_directory_created: mov ax,713Bh call dos_int jnc saving_directory_ok cmp ax,7100h jne error_creating_directory mov ah,3Bh call dos_int jc error_creating_directory saving_directory_ok: call update_screen jmp get_saving_path error_creating_directory: call update_screen mov esi,_directory_error mov ebx,_error movzx eax,[error_box_colors] call message_box jmp saving_directory_ok saving_allowed: call get_full_pathname jc invalid_saving_path call use_pathname clc ret invalid_saving_path: call update_screen mov esi,_invalid_path mov ebx,_error movzx eax,[error_box_colors] call message_box saving_aborted: stc ret load_configuration: call load_ini_file xor eax,eax mov [memory_limit],eax mov al,100 mov [passes_limit],ax mov ebx,_section_compiler mov esi,_key_compiler_memory call get_ini_int jc memory_setting_ok cmp eax,1 shl (32-10) jae memory_setting_ok shl eax,10 mov [memory_limit],eax memory_setting_ok: mov esi,_key_compiler_passes call get_ini_int jc passes_setting_ok test eax,eax jz passes_setting_ok cmp eax,10000h ja passes_setting_ok mov [passes_limit],ax passes_setting_ok: mov ebx,_section_options mov esi,_key_options_securesel call get_ini_int jc securesel_init_ok and [editor_style],not FES_SECURESEL test eax,eax jz securesel_init_ok or [editor_style],FES_SECURESEL securesel_init_ok: mov esi,_key_options_autobrackets call get_ini_int jc autobrackets_init_ok and [editor_style],not FES_AUTOBRACKETS test eax,eax jz autobrackets_init_ok or [editor_style],FES_AUTOBRACKETS autobrackets_init_ok: mov esi,_key_options_autoindent call get_ini_int jc autoindent_init_ok and [editor_style],not FES_AUTOINDENT test eax,eax jz autoindent_init_ok or [editor_style],FES_AUTOINDENT autoindent_init_ok: mov esi,_key_options_smarttabs call get_ini_int jc smarttabs_init_ok and [editor_style],not FES_SMARTTABS test eax,eax jz smarttabs_init_ok or [editor_style],FES_SMARTTABS smarttabs_init_ok: mov esi,_key_options_optimalfill call get_ini_int jc optimalfill_init_ok and [editor_style],not FES_OPTIMALFILL test eax,eax jz optimalfill_init_ok or [editor_style],FES_OPTIMALFILL optimalfill_init_ok: mov ebx,_section_colors mov esi,_key_color_text call get_ini_int jc color_text_init_ok and al,0Fh and [text_colors],0F0h or [text_colors],al color_text_init_ok: mov esi,_key_color_background call get_ini_int jc color_background_init_ok and al,0Fh shl al,4 and [text_colors],0Fh or [text_colors],al color_background_init_ok: mov esi,_key_color_seltext call get_ini_int jc color_seltext_init_ok and al,0Fh and [selection_colors],0F0h or [selection_colors],al color_seltext_init_ok: mov esi,_key_color_selbackground call get_ini_int jc color_selbackground_init_ok and al,0Fh shl al,4 and [selection_colors],0Fh or [selection_colors],al color_selbackground_init_ok: mov esi,_key_color_symbols call get_ini_int jc color_symbols_init_ok mov [symbol_color],al color_symbols_init_ok: mov esi,_key_color_numbers call get_ini_int jc color_numbers_init_ok mov [number_color],al color_numbers_init_ok: mov esi,_key_color_strings call get_ini_int jc color_strings_init_ok mov [string_color],al color_strings_init_ok: mov esi,_key_color_comments call get_ini_int jc color_comments_init_ok mov [comment_color],al color_comments_init_ok: mov esi,_key_color_statustext call get_ini_int jc color_statustext_init_ok and al,0Fh and [status_colors],0F0h or [status_colors],al color_statustext_init_ok: mov esi,_key_color_statusbackground call get_ini_int jc color_statusbackground_init_ok and al,0Fh shl al,4 and [status_colors],0Fh or [status_colors],al color_statusbackground_init_ok: mov esi,_key_color_wintext call get_ini_int jc color_wintext_init_ok and al,0Fh and [window_colors],0F0h or [window_colors],al color_wintext_init_ok: mov esi,_key_color_winbackground call get_ini_int jc color_winbackground_init_ok and al,0Fh shl al,4 and [window_colors],0Fh or [window_colors],al color_winbackground_init_ok: mov esi,_key_color_msgtext call get_ini_int jc color_msgtext_init_ok and al,0Fh and byte [message_box_colors+1],0F0h or byte [message_box_colors+1],al color_msgtext_init_ok: mov esi,_key_color_msgbackground call get_ini_int jc color_msgbackground_init_ok and al,0Fh shl al,4 and byte [message_box_colors+1],0Fh or byte [message_box_colors+1],al color_msgbackground_init_ok: mov esi,_key_color_msgseltext call get_ini_int jc color_msgseltext_init_ok and al,0Fh and byte [message_box_colors],0F0h or byte [message_box_colors],al color_msgseltext_init_ok: mov esi,_key_color_msgselbackground call get_ini_int jc color_msgselbackground_init_ok and al,0Fh shl al,4 and byte [message_box_colors],0Fh or byte [message_box_colors],al color_msgselbackground_init_ok: mov esi,_key_color_errtext call get_ini_int jc color_errtext_init_ok and al,0Fh and byte [error_box_colors+1],0F0h or byte [error_box_colors+1],al color_errtext_init_ok: mov esi,_key_color_errbackground call get_ini_int jc color_errbackground_init_ok and al,0Fh shl al,4 and byte [error_box_colors+1],0Fh or byte [error_box_colors+1],al color_errbackground_init_ok: mov esi,_key_color_errseltext call get_ini_int jc color_errseltext_init_ok and al,0Fh and byte [error_box_colors],0F0h or byte [error_box_colors],al color_errseltext_init_ok: mov esi,_key_color_errselbackground call get_ini_int jc color_errselbackground_init_ok and al,0Fh shl al,4 and byte [error_box_colors],0Fh or byte [error_box_colors],al color_errselbackground_init_ok: mov esi,_key_color_boxtext call get_ini_int jc color_boxtext_init_ok and al,0Fh and [box_colors],0F0h or [box_colors],al color_boxtext_init_ok: mov esi,_key_color_boxbackground call get_ini_int jc color_boxbackground_init_ok and al,0Fh shl al,4 and [box_colors],0Fh or [box_colors],al color_boxbackground_init_ok: mov esi,_key_color_boxseltext call get_ini_int jc color_boxseltext_init_ok and al,0Fh and byte [box_selection_colors],0F0h or byte [box_selection_colors],al color_boxseltext_init_ok: mov esi,_key_color_boxselbackground call get_ini_int jc color_boxselbackground_init_ok and al,0Fh shl al,4 and byte [box_selection_colors],0Fh or byte [box_selection_colors],al color_boxselbackground_init_ok: ret load_ini_file: cmp [ini_data],0 je open_ini_file mov ebx,[ini_data_handle] call release_memory open_ini_file: mov edi,[ini_extension] mov eax,'INI' stosd mov edx,ini_path call open jc no_ini_file xor edx,edx mov al,2 call lseek push eax xor edx,edx xor al,al call lseek mov ecx,[esp] add ecx,800h push ebx call get_memory mov [ini_data],eax mov [ini_data_handle],ebx pop ebx ecx test eax,eax jz ini_loaded mov edx,eax mov byte [edx+ecx],1Ah mov [ini_data_length],ecx call read call close ret no_ini_file: mov ecx,800h call get_memory mov [ini_data],eax test eax,eax jz ini_loaded mov byte [eax],1Ah mov [ini_data_length],0 ini_loaded: ret get_ini_value: mov edi,esi mov esi,[ini_data] test esi,esi jz ini_value_not_found call find_ini_block jc ini_value_not_found call find_ini_value ret ini_value_not_found: stc ret find_ini_block: lodsb cmp al,20h je find_ini_block cmp al,9 je find_ini_block cmp al,'[' jne look_for_ini_block_in_next_line find_block_name: lodsb cmp al,20h je find_block_name cmp al,9 je find_block_name dec esi mov edx,ebx compare_block_name_char: lodsb mov ah,[edx] inc edx cmp al,']' je end_of_block_name cmp al,20h je end_of_block_name cmp al,9 je end_of_block_name cmp al,1Ah je end_of_block_name cmp al,0Dh je end_of_block_name cmp al,0Ah je end_of_block_name or ah,ah jz look_for_ini_block_in_next_line sub ah,al jz compare_block_name_char jns block_name_char_case_insensitive neg ah sub al,20h block_name_char_case_insensitive: cmp ah,20h jne look_for_ini_block_in_next_line cmp al,41h jb look_for_ini_block_in_next_line cmp al,5Ah jna compare_block_name_char look_for_ini_block_in_next_line: dec esi call find_next_ini_line cmp byte [esi],1Ah jne find_ini_block stc ret end_of_block_name: test ah,ah jnz look_for_ini_block_in_next_line cmp al,']' je end_of_block_name_ok cmp al,20h je find_block_name_closing_bracket cmp al,9 jne look_for_ini_block_in_next_line find_block_name_closing_bracket: lodsb jmp end_of_block_name end_of_block_name_ok: call find_next_ini_line clc ret find_next_ini_line: lodsb cmp al,0Dh je line_ending cmp al,0Ah je line_ending cmp al,1Ah jne find_next_ini_line dec esi ret line_ending: lodsb cmp al,0Dh je line_ending cmp al,0Ah je line_ending dec esi ret find_ini_value: lodsb cmp al,20h je find_ini_value cmp al,9 je find_ini_value cmp al,0Dh je next_ini_value cmp al,0Ah je next_ini_value dec esi cmp al,1Ah je no_ini_value_found cmp al,'[' je no_ini_value_found mov edx,edi compare_value_name_char: lodsb mov ah,[edx] inc edx cmp al,'=' je end_of_value_name cmp al,20h je end_of_value_name cmp al,9 je end_of_value_name cmp al,1Ah je end_of_value_name cmp al,0Dh je end_of_value_name cmp al,0Ah je end_of_value_name or ah,ah jz next_ini_value sub ah,al jz compare_value_name_char jns value_name_char_case_insensitive neg ah sub al,20h value_name_char_case_insensitive: cmp ah,20h jne next_ini_value cmp al,41h jb next_ini_value cmp al,5Ah jna compare_value_name_char next_ini_value: dec esi call find_next_ini_line cmp byte [esi],1Ah jne find_ini_value no_ini_value_found: stc ret end_of_value_name: test ah,ah jnz next_ini_value cmp al,'=' je ini_value_found cmp al,20h je find_ini_value_start cmp al,9 jne next_ini_value find_ini_value_start: lodsb jmp end_of_value_name ini_value_found: xor ecx,ecx find_value_length: cmp byte [esi+ecx],0Dh je value_length_found cmp byte [esi+ecx],0Ah je value_length_found cmp byte [esi+ecx],1Ah je value_length_found inc ecx jmp find_value_length value_length_found: clc ret get_ini_int: call get_ini_value jc no_ini_int push ebx call atoi pop ebx ret no_ini_int: stc ret atoi: lodsb cmp al,20h je atoi cmp al,9 je atoi mov bl,al xor eax,eax xor edx,edx cmp bl,'-' je atoi_digit cmp bl,'+' je atoi_digit dec esi atoi_digit: mov dl,[esi] sub dl,30h jc atoi_done cmp dl,9 ja atoi_done mov ecx,eax shl ecx,1 jc atoi_overflow shl ecx,1 jc atoi_overflow add eax,ecx shl eax,1 jc atoi_overflow js atoi_overflow add eax,edx jc atoi_overflow inc esi jmp atoi_digit atoi_overflow: stc ret atoi_done: cmp bl,'-' jne atoi_sign_ok neg eax atoi_sign_ok: clc ret update_ini_value: mov ebp,edx mov esi,[ini_data] test esi,esi jz cannot_update_ini call find_ini_block jc create_ini_block call find_ini_value jc create_ini_value mov edi,esi mov esi,ebp jecxz place_for_ini_value_exhausted copy_value_to_ini: lodsb test al,al jz shift_rest_of_ini_down stosb loop copy_value_to_ini place_for_ini_value_exhausted: cmp byte [esi],0 jne shift_rest_of_ini_up ret shift_rest_of_ini_down: lea esi,[edi+ecx] neg ecx xchg ecx,[ini_data_length] add [ini_data_length],ecx inc ecx add ecx,[ini_data] sub ecx,esi rep movsb ret shift_rest_of_ini_up: push esi edi mov edi,esi xor al,al or ecx,-1 repne scasb neg ecx sub ecx,2 mov esi,[ini_data] add esi,[ini_data_length] mov edi,esi add edi,ecx add [ini_data_length],ecx mov ebp,ecx mov ecx,esi sub ecx,[esp] inc ecx std rep movsb cld pop edi esi mov ecx,ebp rep movsb ret cannot_update_ini: ret create_ini_block: push edi mov edi,[ini_data] mov ecx,[ini_data_length] add edi,ecx jecxz make_ini_block_header mov ax,0A0Dh stosw make_ini_block_header: mov al,'[' stosb mov esi,ebx call copy_str mov al,']' stosb mov ax,0A0Dh stosw pop esi append_ini_value: call copy_str mov al,'=' stosb mov esi,ebp call copy_str mov ax,0A0Dh stosw mov ecx,edi sub ecx,[ini_data] mov [ini_data_length],ecx mov al,1Ah stosb ret copy_str: lodsb test al,al jz str_copied stosb jmp copy_str str_copied: ret create_ini_value: cmp esi,[ini_data] je ini_value_placement_ok dec esi mov al,[esi] cmp al,20h je create_ini_value cmp al,9 je create_ini_value cmp al,0Dh je create_ini_value cmp al,0Ah je create_ini_value inc esi find_place_for_ini_value: mov al,[esi] lodsb cmp al,0Ah je ini_value_placement_ok cmp al,1Ah je value_at_end_of_ini cmp al,0Dh jne find_place_for_ini_value cmp byte [esi],0Ah jne ini_value_placement_ok inc esi ini_value_placement_ok: push edi esi xor al,al or ecx,-1 repne scasb mov edi,ebp repne scasb neg ecx mov edi,ecx mov ecx,esi neg ecx mov esi,[ini_data] add esi,[ini_data_length] add [ini_data_length],edi add edi,esi add ecx,esi inc ecx std rep movsb cld pop edi esi call copy_str mov al,'=' stosb mov esi,ebp call copy_str mov ax,0A0Dh stosw ret value_at_end_of_ini: xchg esi,edi mov ax,0A0Dh stosw jmp append_ini_value shutdown: call switch_to_user_screen call load_ini_file cmp [ini_data],0 je exit mov ebx,_section_options mov edi,_key_options_securesel test [editor_style],FES_SECURESEL setnz al add al,'0' mov edx,line_buffer mov byte [edx+1],0 mov [edx],al call update_ini_value mov edi,_key_options_autobrackets test [editor_style],FES_AUTOBRACKETS setnz al add al,'0' mov edx,line_buffer mov [edx],al call update_ini_value mov edi,_key_options_autoindent test [editor_style],FES_AUTOINDENT setnz al add al,'0' mov edx,line_buffer mov [edx],al call update_ini_value mov edi,_key_options_smarttabs test [editor_style],FES_SMARTTABS setnz al add al,'0' mov edx,line_buffer mov [edx],al call update_ini_value mov edi,_key_options_optimalfill test [editor_style],FES_OPTIMALFILL setnz al add al,'0' mov edx,line_buffer mov [edx],al call update_ini_value mov edx,ini_path call create jc exit mov edx,[ini_data] mov ecx,[ini_data_length] call write call close exit: mov ax,4C00h int 21h ; Positioning update_positions: mov eax,[screen_width] mov [window_width],eax mov eax,[screen_height] sub eax,2 mov [window_height],eax call update_window ret update_cursor: xor bh,bh mov edx,[caret_position] sub edx,[window_position] jc cursor_out_of_sight cmp edx,[window_width] jae cursor_out_of_sight mov eax,[caret_line_number] sub eax,[window_line_number] jc cursor_out_of_sight cmp eax,[window_height] jae cursor_out_of_sight inc al mov dh,al mov ah,2 int 10h test [editor_mode],FEMODE_OVERWRITE jnz block_cursor mov ah,1 mov cx,0D0Eh int 10h ret block_cursor: mov ah,1 mov cx,000Fh int 10h ret cursor_out_of_sight: mov ah,1 mov cx,1000h int 10h ret ; Text drawing update_screen: call update_title_bar mov eax,[peak_line_length] xor edx,edx mov ebx,SEGMENT_DATA_LENGTH div ebx inc eax mul ebx shl eax,1 mov ecx,eax cmp [line_buffer],0 je line_buffer_reallocate cmp ecx,[line_buffer_size] jbe line_buffer_ok mov [line_buffer],0 push ecx mov ebx,[line_buffer_handle] call release_memory pop ecx line_buffer_reallocate: mov [line_buffer_size],ecx call get_memory or eax,eax jz memory_shortage mov [line_buffer],eax mov [line_buffer_handle],ebx line_buffer_ok: mov esi,[window_line] mov edx,[window_line_number] mov eax,[video_pitch] mov [screen_offset],eax mov edi,[line_buffer] prepare_line: add esi,SEGMENT_HEADER_LENGTH mov ecx,SEGMENT_DATA_LENGTH rep movsb mov esi,[esi-SEGMENT_LENGTH] btr esi,0 jc prepare_line push esi edx mov ecx,edi mov esi,[line_buffer] sub ecx,esi push ecx mov al,[text_colors] and al,0Fh rep stosb mov esi,[line_buffer] mov ecx,[esp] lea edi,[esi+ecx] call syntax_proc line_prepared: mov edi,screen_row_buffer mov ecx,[window_width] mov al,20h mov ah,[text_colors] rep stosw pop ecx mov esi,[line_buffer] lea ebx,[esi+ecx] add esi,[window_position] add ebx,[window_position] sub ecx,[window_position] jbe text_drawing_ok mov edi,screen_row_buffer cmp ecx,[window_width] jbe draw_text mov ecx,[window_width] draw_text: movsb mov al,[text_colors] and al,0F0h or al,[ebx] stosb inc ebx loop draw_text text_drawing_ok: mov edi,screen_row_buffer cmp [selection_line],0 je selection_marked mov eax,[selection_line_number] cmp eax,[caret_line_number] jne mark_multiline_selection cmp eax,[esp] jne selection_marked mark_simple_selection: mov eax,[selection_position] mov ecx,[caret_position] cmp eax,ecx jbe simple_selection_boundaries_ok xchg eax,ecx simple_selection_boundaries_ok: sub ecx,[window_position] jbe selection_marked sub eax,[window_position] jae simple_selection_start_ok xor eax,eax simple_selection_start_ok: cmp ecx,[window_width] jbe simple_selection_length_ok mov ecx,[window_width] simple_selection_length_ok: sub ecx,eax jbe selection_marked lea edi,[screen_row_buffer+eax*2] draw_selection: inc edi mov al,[selection_colors] stosb loop draw_selection jmp selection_marked mark_multiline_selection: test [editor_mode],FEMODE_VERTICALSEL jnz mark_vertical_selection mov eax,[selection_line_number] mov ebx,[selection_position] mov edx,[caret_line_number] mov ebp,[caret_position] cmp eax,edx jbe multiline_selection_boundaries_ok xchg eax,edx xchg ebx,ebp multiline_selection_boundaries_ok: mov edi,screen_row_buffer mov ecx,[window_width] cmp eax,[esp] ja selection_marked je mark_selection_start cmp edx,[esp] ja draw_selection jb selection_marked mark_selection_end: cmp ebp,[window_position] jbe selection_marked sub ebp,[window_position] cmp ecx,ebp jbe draw_selection mov ecx,ebp jmp draw_selection mark_selection_start: sub ebx,[window_position] jbe draw_selection sub ecx,ebx jbe selection_marked lea edi,[edi+ebx*2] jmp draw_selection mark_vertical_selection: mov eax,[selection_line_number] mov edx,[caret_line_number] sub eax,[esp] jz mark_simple_selection sub edx,[esp] jz mark_simple_selection xor eax,edx js mark_simple_selection selection_marked: push es gs pop es mov esi,screen_row_buffer mov edi,[screen_offset] mov ecx,[window_width] shr ecx,1 rep movsd setc cl rep movsw mov eax,[window_width] shl eax,1 sub edi,eax add edi,[video_pitch] mov [screen_offset],edi pop es pop edx esi inc edx mov eax,edx sub eax,[window_line_number] cmp eax,[window_height] jae screen_ok mov edi,[line_buffer] or esi,esi jnz prepare_line push esi edx push [window_position] jmp line_prepared screen_ok: call update_status_bar ret syntax_proc: mov ebx,characters xor edx,edx scan_syntax: lodsb check_character: cmp al,20h je syntax_space cmp al,3Bh je syntax_comment mov ah,al xlatb or al,al jz syntax_symbol or edx,edx jnz syntax_neutral cmp ah,27h je syntax_string cmp ah,22h je syntax_string cmp ah,24h je syntax_pascal_hex cmp ah,39h ja syntax_neutral cmp ah,30h jae syntax_number syntax_neutral: or edx,-1 inc edi loop scan_syntax jmp syntax_done syntax_space: xor edx,edx inc edi loop scan_syntax jmp syntax_done syntax_symbol: mov al,[symbol_color] stosb xor edx,edx loop scan_syntax jmp syntax_done syntax_pascal_hex: cmp ecx,1 je syntax_neutral mov al,[esi] mov ah,al xlatb or al,al jz syntax_neutral cmp ah,24h jne syntax_number cmp ecx,2 je syntax_neutral mov al,[esi+1] xlatb or al,al jz syntax_neutral syntax_number: mov al,[number_color] stosb loop number_character jmp syntax_done number_character: lodsb mov ah,al xlatb xchg al,ah or ah,ah jz check_character cmp al,20h je check_character cmp al,3Bh je check_character mov al,[number_color] stosb loop number_character jmp syntax_done syntax_string: mov al,[string_color] stosb dec ecx jz syntax_done lodsb cmp al,ah jne syntax_string mov al,[string_color] stosb dec ecx jz syntax_done lodsb cmp al,ah je syntax_string xor edx,edx jmp check_character process_comment: lodsb cmp al,20h jne syntax_comment inc edi loop process_comment jmp syntax_done syntax_comment: mov al,[comment_color] stosb loop process_comment syntax_done: ret ; Status drawing update_status_bar: mov edi,screen_row_buffer mov al,20h mov ecx,[screen_width] rep stosb mov edi,screen_row_buffer+256 mov eax,'Row ' stosd mov eax,[caret_line_number] call number_as_text mov al,'/' stosb mov eax,[lines_count] call number_as_text mov eax,', Co' stosd mov eax,'lumn' stosd mov al,' ' stosb mov eax,[caret_position] inc eax call number_as_text mov al,'/' stosb mov eax,[maximum_position] inc eax call number_as_text mov ecx,edi mov esi,screen_row_buffer+256 sub ecx,esi mov eax,[screen_width] lea edi,[screen_row_buffer+eax-1] sub edi,ecx mov byte [edi-2],0B3h lea ebx,[edi-11] rep movsb mov edi,ebx sub ebx,2 test [editor_mode],FEMODE_READONLY jnz readonly_status mov eax,[undo_data] cmp eax,[unmodified_state] je editor_status_ok mov eax,'Modi' stosd mov eax,'fied' stosd jmp editor_status_ok readonly_status: dec ebx dec edi mov eax,'Read' stosd mov al,'-' stosb mov eax,'only' stosd editor_status_ok: mov byte [ebx],0B3h push ebx mov edi,screen_row_buffer+1 xor eax,eax mov edx,[previous_instance] count_preceding_instances: inc eax or edx,edx jz preceding_instances_count_ok mov edx,[edx+SEGMENT_HEADER_LENGTH+previous_instance-editor_data] jmp count_preceding_instances preceding_instances_count_ok: push eax call number_as_text mov al,'/' stosb pop eax mov edx,[next_instance] count_following_instances: or edx,edx jz following_instances_count_ok inc eax mov edx,[edx+SEGMENT_HEADER_LENGTH+next_instance-editor_data] jmp count_following_instances following_instances_count_ok: call number_as_text inc edi mov al,'-' stosb inc edi pop ecx sub ecx,edi mov esi,[file_path] call get_file_title print_file_title: lodsb or al,al jz editor_title_ok stosb loop print_file_title editor_title_ok: push es gs pop es mov edi,[video_pitch] mov eax,[screen_height] dec eax imul edi,eax mov esi,screen_row_buffer mov ecx,[screen_width] mov ah,[status_colors] draw_status_bar: lodsb stosw loop draw_status_bar pop es ret get_file_title: or esi,esi jz untitled mov ebx,esi find_file_name: lodsb or al,al jz file_title_ok cmp al,'\' jne find_file_name mov ebx,esi jmp find_file_name file_title_ok: mov esi,ebx ret untitled: mov esi,_untitled ret update_title_bar: mov edi,screen_row_buffer mov al,20h mov ecx,[screen_width] sub ecx,10+1 rep stosb mov al,0B3h stosb mov esi,_caption mov edi,screen_row_buffer+1 draw_caption: lodsb or al,al jz caption_ok stosb jmp draw_caption caption_ok: mov edx,[main_project_file] or edx,edx jz main_file_title_ok mov al,20h stosb mov al,'-' stosb mov al,20h stosb mov esi,[file_path] cmp edx,[editor_memory] je get_main_file_title mov esi,[edx+SEGMENT_HEADER_LENGTH+file_path-editor_data] get_main_file_title: call get_file_title mov ecx,[screen_width] add ecx,screen_row_buffer-14 sub ecx,edi print_main_file_title: lodsb or al,al jz main_file_title_ok stosb loop print_main_file_title main_file_title_ok: push es gs pop es xor edi,edi mov esi,screen_row_buffer mov ecx,[screen_width] sub ecx,10 mov ah,[status_colors] draw_title_bar: lodsb stosw loop draw_title_bar pop es call update_clock ret update_clock: mov edi,[screen_width] mov ecx,10 sub edi,ecx shl edi,1 mov al,[status_colors] prepare_clock_colors: mov [gs:edi+(ecx-1)*2+1],al loop prepare_clock_colors mov ah,2Ch int 21h mov [gs:edi],byte 20h mov al,ch aam add ax,'00' mov [gs:edi+1*2],ah mov [gs:edi+2*2],al mov [gs:edi+3*2],byte ':' mov al,cl aam add ax,'00' mov [gs:edi+4*2],ah mov [gs:edi+5*2],al mov [gs:edi+6*2],byte ':' mov al,dh aam add ax,'00' mov [gs:edi+7*2],ah mov [gs:edi+8*2],al mov [gs:edi+9*2],byte 20h ret wait_for_input: call update_clock mov ah,11h int 16h jz wait_for_input mov ah,10h int 16h test ax,ax jz wait_for_input ret number_as_text: push ebx mov ecx,1000000000 xor edx,edx xor bl,bl number_loop: div ecx push edx cmp ecx,1 je store_digit or bl,bl jnz store_digit or al,al jz digit_ok not bl store_digit: add al,'0' stosb digit_ok: mov eax,ecx xor edx,edx mov ecx,10 div ecx mov ecx,eax pop eax or ecx,ecx jnz number_loop pop ebx ret sprintf: lodsb cmp al,'%' je format_parameter stosb or al,al jnz sprintf ret format_parameter: lodsb mov edx,[ebx] add ebx,4 cmp al,'s' je insert_string cmp al,'d' je insert_number or al,al jnz sprintf dec esi jmp sprintf insert_number: push esi mov eax,edx call number_as_text pop esi jmp sprintf insert_string: push esi mov esi,edx string_insertion_loop: lodsb or al,al jz string_insertion_ok stosb jmp string_insertion_loop string_insertion_ok: pop esi jmp sprintf ; Windows message_box: push eax ebx xor ebp,ebp mov edi,buffer+200h mov dl,[esp+4+3] or dl,dl jnz calculate_buttons_width mov dl,1 mov [first_button],_ok calculate_buttons_width: mov [buttons_width],0 mov eax,[first_button] call add_button_width dec dl jz buttons_width_ok add [buttons_width],2 mov eax,[second_button] call add_button_width jmp buttons_width_ok add_button_width: push edi mov edi,eax xor al,al or ecx,-1 repne scasb neg cl add cl,6-2 add [buttons_width],cl pop edi ret buttons_width_ok: mov al,[buttons_width] mov [message_width],al start_message_line: mov ebx,edi mov edx,edi mov ecx,[screen_width] sub ecx,14 mov eax,[screen_height] sub eax,7 inc ebp cmp ebp,eax jae message_prepared copy_message: lodsb stosb cmp al,20h jne message_character_ok mov edx,edi message_character_ok: cmp byte [esi],0 je message_prepared loop copy_message cmp edx,ebx je split_word lea eax,[edx-1] mov ecx,[screen_height] sub ecx,7 inc ebp cmp ebp,ecx je cut_message mov byte [eax],0Ah sub eax,ebx mov ebx,edx mov ecx,[screen_width] lea ecx,[ecx-14+ebx] sub ecx,edi cmp al,[message_width] jbe copy_message mov [message_width],al jmp copy_message cut_message: mov edi,eax jmp message_prepared split_word: mov eax,[screen_width] sub eax,14 mov [message_width],al mov al,0Ah stosb jmp start_message_line message_prepared: mov eax,edi sub eax,ebx cmp al,[message_width] jbe message_width_ok mov [message_width],al message_width_ok: xor al,al stosb mov ecx,ebp mov ch,cl add ch,6 mov cl,[message_width] add cl,8 pop esi mov ah,[esp+1] call draw_centered_window mov esi,buffer+200h add edi,2*2 draw_message: xor ecx,ecx add edi,[video_pitch] draw_message_row: lodsb or al,al jz message_drawn cmp al,0Ah je draw_message mov byte [gs:edi+ecx*2],al inc ecx jmp draw_message_row message_drawn: add edi,[video_pitch] add edi,[video_pitch] mov cx,1000h mov ah,1 int 10h movzx eax,[message_width] sub al,[buttons_width] and al,not 1 add edi,eax cmp byte [esp+3],2 jae two_button_message pop eax mov ah,al mov esi,[first_button] call draw_button wait_for_ok: call wait_for_input cmp ah,1 je message_aborted cmp al,20h je message_ok cmp al,0Dh jne wait_for_ok message_ok: mov eax,1 ret message_aborted: xor eax,eax ret two_button_message: pop edx xor cl,cl test edx,10000h jnz two_button_loop mov cl,-1 two_button_loop: push edi mov al,dl and al,cl mov ah,cl not ah and ah,dh or ah,al mov esi,[first_button] call draw_button add edi,2*2 mov al,dh and al,cl mov ah,cl not ah and ah,dl or ah,al mov esi,[second_button] call draw_button push ecx edx call wait_for_input pop edx ecx edi cmp ah,1 je message_aborted cmp al,9 je two_button_switch cmp ah,0Fh je two_button_switch cmp ah,4Bh je two_button_switch cmp ah,4Dh je two_button_switch cmp ah,48h je two_button_switch cmp ah,50h je two_button_switch cmp al,0Dh je button_selected cmp al,20h je button_selected mov ebx,lower_case_table xlatb mov ah,al mov esi,[first_button] mov al,[esi] xlatb cmp al,ah je message_ok mov esi,[second_button] mov al,[esi] xlatb cmp al,ah je message_second_choice jmp two_button_loop button_selected: or cl,cl jnz message_ok message_second_choice: mov eax,2 ret two_button_switch: not cl jmp two_button_loop draw_button: push es gs pop es mov al,'[' stosw mov al,20h stosw stosw draw_button_label: lodsb or al,al jz button_label_ok stosw jmp draw_button_label button_label_ok: mov al,20h stosw stosw mov al,']' stosw pop es ret draw_centered_window: mov dl,byte [screen_width] sub dl,cl shr dl,1 mov dh,byte [screen_height] sub dh,ch shr dh,1 test [command_flags],80h jz draw_window mov ebx,[caret_line_number] sub ebx,[window_line_number] add ebx,3 cmp bl,dh jbe draw_window mov al,dh add al,ch add al,3 cmp al,bl jb draw_window mov dh,bl movzx edi,ch add edi,ebx add edi,2 cmp edi,[screen_height] jb draw_window sub dh,ch sub dh,4 draw_window: push es gs pop es movzx edi,dh imul edi,[video_pitch] movzx ebx,dl shl ebx,1 add edi,ebx movzx edx,ch movzx ecx,cl sub ecx,4 sub edx,2 push ecx edi mov al,' ' stos word [edi] mov al,'É' stos word [edi] mov al,'Í' stos word [edi] dec ecx mov al,' ' stos word [edi] dec ecx draw_title: lods byte [esi] or al,al jz title_ok stos word [edi] loop draw_title jmp finish_upper_border title_ok: mov al,' ' stos word [edi] dec ecx jz finish_upper_border mov al,'Í' rep stos word [edi] finish_upper_border: mov al,'»' stos word [edi] mov al,' ' stos word [edi] pop edi ecx add edi,[video_pitch] lea ebp,[edi+2*2] draw_window_lines: push ecx edi mov al,' ' stos word [edi] mov al,'º' stos word [edi] mov al,' ' rep stos word [edi] mov al,'º' stos word [edi] mov al,' ' stos word [edi] mov byte [es:edi+1],8 mov byte [es:edi+3],8 pop edi ecx add edi,[video_pitch] dec edx jnz draw_window_lines push ecx edi mov al,' ' stos word [edi] mov al,'È' stos word [edi] mov al,'Í' rep stos word [edi] mov al,'¼' stos word [edi] mov al,' ' stos word [edi] mov byte [es:edi+1],8 mov byte [es:edi+3],8 pop edi ecx mov eax,[video_pitch] lea edi,[edi+eax+2*2+1] mov al,8 add ecx,4 finish_bottom_shadow: stos byte [edi] inc edi loop finish_bottom_shadow mov edi,ebp mov eax,edi cdq idiv [video_pitch] sar edx,1 mov dh,al pop es ret create_edit_box: mov byte [ebx],1 mov [ebx+1],al mov [ebx+2],dx mov [ebx+4],ecx xor eax,eax mov [ebx+8],eax mov [ebx+12],eax lea edi,[ebx+16] xor ecx,ecx or esi,esi jz edit_box_text_ok init_edit_box_text: lodsb or al,al jz edit_box_text_ok stosb inc ecx cmp cx,[ebx+6] jb init_edit_box_text edit_box_text_ok: mov [ebx+8],cx mov [ebx+12],cx xor al,al stosb test byte [ebx+1],1 jz draw_edit_box set_edit_box_focus: push ebx mov ah,1 mov cx,0D0Eh int 10h pop ebx jmp draw_edit_box kill_edit_box_focus: mov word [ebx+10],0 push ebx mov ah,1 mov cx,1000h int 10h pop ebx draw_edit_box: test byte [ebx+1],1 jz edit_box_position_ok mov ax,[ebx+10] sub ax,[ebx+12] jae edit_box_position_correction movzx ax,byte [ebx+4] add ax,[ebx+10] sub ax,2 sub ax,[ebx+12] jae edit_box_position_ok edit_box_position_correction: sub [ebx+10],ax edit_box_position_ok: push es gs pop es movzx edi,byte [ebx+3] imul edi,[video_pitch] movzx eax,byte [ebx+2] lea edi,[edi+eax*2] mov al,20h cmp word [ebx+10],0 je edit_box_left_edge_ok mov al,1Bh edit_box_left_edge_ok: mov ah,[box_colors] stosw movzx eax,word [ebx+10] lea esi,[ebx+16+eax] movzx ebp,byte [ebx+4] sub ebp,2 mov edx,[ebx+12] cmp dx,[ebx+14] jbe draw_edit_box_before_selection ror edx,16 draw_edit_box_before_selection: movzx ecx,dx sub cx,[ebx+10] jbe draw_edit_box_selection mov ah,[box_colors] call draw_edit_box_part draw_edit_box_selection: mov ax,dx sub ax,cx shr edx,16 mov cx,dx sub cx,ax jbe draw_edit_box_after_selection mov ah,[box_selection_colors] test byte [ebx+1],1 jnz edit_box_selection_visible mov ah,[box_colors] edit_box_selection_visible: call draw_edit_box_part draw_edit_box_after_selection: mov ah,[box_colors] mov cx,[ebx+8] sub cx,dx jbe draw_edit_box_ending call draw_edit_box_part draw_edit_box_ending: mov ecx,ebp mov al,20h rep stosw movzx edx,word [ebx+8] lea edx,[ebx+16+edx] cmp esi,edx jae edit_box_right_edge_ok mov al,1Ah edit_box_right_edge_ok: stosw test byte [ebx+1],1 jz edit_box_cursor_ok mov dx,[ebx+2] inc dl mov ax,[ebx+12] sub ax,[ebx+10] add dl,al mov ah,2 push ebx mov bh,0 int 10h pop ebx edit_box_cursor_ok: pop es ret draw_edit_box_part: or bp,bp jz edit_box_part_ok cmp cx,bp jbe edit_box_part_length_ok mov cx,bp edit_box_part_length_ok: sub bp,cx draw_edit_box_character: lodsb stosw loopw draw_edit_box_character edit_box_part_ok: ret set_box_focus: or byte [ebx+1],1 mov cl,[ebx] cmp cl,1 jb set_check_box_focus je set_edit_box_focus cmp cl,2 je draw_list_box ret kill_box_focus: and byte [ebx+1],not 1 mov cl,[ebx] cmp cl,1 je kill_edit_box_focus cmp cl,2 je draw_list_box ret update_box: cmp byte [ebx],0 je update_check_box ret process_box_command: mov cl,[ebx] cmp cl,1 jb check_box_command je edit_box_command cmp cl,2 je list_box_command stc ret edit_box_command: cmp al,0E0h jne edit_box_ascii_code cmp ah,4Bh je edit_box_left_key cmp ah,4Dh je edit_box_right_key cmp ah,47h je edit_box_home_key cmp ah,4Fh je edit_box_end_key cmp ah,53h je edit_box_delete cmp ah,52h je edit_box_insert cmp ah,93h je edit_box_ctrl_delete cmp ah,92h je edit_box_ctrl_insert edit_box_unknown_command: stc ret edit_box_ascii_code: cmp al,8 je edit_box_backspace cmp al,18h je edit_box_cut_block cmp al,3 je edit_box_ctrl_insert cmp al,16h je edit_box_paste_block cmp al,20h jb edit_box_unknown_command test byte [ebx+1],100b jz edit_box_ascii_code_ok cmp al,30h jb edit_box_command_done cmp al,39h ja edit_box_command_done edit_box_ascii_code_ok: mov dx,word [ebx+12] cmp dx,word [ebx+14] je edit_box_character push eax call edit_box_delete_block pop eax edit_box_character: call edit_box_insert_character jc edit_box_command_done jmp edit_box_no_selection edit_box_delete: test byte [fs:17h],11b jnz edit_box_cut_block mov dx,word [ebx+12] cmp dx,word [ebx+14] jne edit_box_ctrl_delete cmp dx,[ebx+8] je edit_box_command_done inc dx mov [ebx+14],dx jmp edit_box_ctrl_delete edit_box_backspace: mov dx,[ebx+12] cmp dx,word [ebx+14] jne edit_box_ctrl_delete or dx,dx jz edit_box_command_done dec word [ebx+12] mov [ebx+14],dx edit_box_ctrl_delete: call edit_box_delete_block jmp edit_box_no_selection edit_box_ctrl_insert: call edit_box_copy_block jmp edit_box_command_done edit_box_cut_block: call edit_box_copy_block call edit_box_delete_block jmp edit_box_no_selection edit_box_insert_character: test byte [ebx+1],100b jz edit_box_character_allowed cmp al,30h jb edit_box_disallowed_character cmp al,39h ja edit_box_disallowed_character edit_box_character_allowed: movzx ecx,word [ebx+8] cmp cx,[ebx+6] je edit_box_full lea edi,[ebx+16+ecx] lea esi,[edi-1] sub cx,[ebx+12] std rep movsb cld stosb inc word [ebx+8] inc word [ebx+12] edit_box_disallowed_character: clc ret edit_box_full: stc ret edit_box_delete_block: movzx eax,word [ebx+12] lea esi,[ebx+16+eax] movzx eax,word [ebx+14] lea edi,[ebx+16+eax] movzx eax,word [ebx+8] lea ecx,[ebx+16+eax] cmp esi,edi jae edit_box_shift_rest_of_line xchg esi,edi edit_box_shift_rest_of_line: sub ecx,esi mov eax,edi rep movsb mov ecx,esi sub ecx,edi sub [ebx+8],cx sub eax,ebx sub eax,16 mov [ebx+12],ax mov [ebx+14],ax ret edit_box_copy_block: movzx ecx,word [ebx+12] movzx edx,word [ebx+14] cmp ecx,edx je edit_box_block_copied ja edit_box_block_start_ok xchg ecx,edx edit_box_block_start_ok: sub ecx,edx lea esi,[ebx+16+edx] push ebx esi ecx cmp [clipboard],0 je edit_box_allocate_clipboard mov ebx,[clipboard_handle] call release_memory edit_box_allocate_clipboard: mov ecx,[esp] inc ecx call get_memory mov [clipboard],eax mov [clipboard_handle],ecx or eax,eax jz not_enough_memory mov edi,eax pop ecx esi ebx rep movsb xor al,al stosb edit_box_block_copied: ret edit_box_insert: test byte [fs:17h],11b jz edit_box_command_done edit_box_paste_block: call edit_box_delete_block mov esi,[clipboard] or esi,esi jz edit_box_command_done edit_box_insert_block: lodsb or al,al jz edit_box_no_selection cmp al,0Dh je edit_box_no_selection push esi call edit_box_insert_character pop esi jnc edit_box_insert_block jmp edit_box_no_selection edit_box_left_key: cmp word [ebx+12],0 je edit_box_no_selection dec word [ebx+12] jmp edit_box_moved_cursor edit_box_right_key: mov ax,[ebx+8] cmp [ebx+12],ax je edit_box_no_selection inc word [ebx+12] jmp edit_box_moved_cursor edit_box_home_key: mov word [ebx+12],0 jmp edit_box_moved_cursor edit_box_end_key: mov ax,[ebx+8] mov [ebx+12],ax jmp edit_box_moved_cursor edit_box_moved_cursor: test byte [fs:17h],11b jnz edit_box_redraw edit_box_no_selection: mov ax,[ebx+12] mov [ebx+14],ax edit_box_redraw: call draw_edit_box edit_box_command_done: movzx eax,word [ebx+8] mov byte [ebx+16+eax],0 clc ret create_list_box: mov byte [ebx],2 mov [ebx+1],al mov [ebx+2],dx mov [ebx+4],ecx xor eax,eax mov [ebx+8],eax mov [ebx+12],esi draw_list_box: mov ax,[ebx+8] sub ax,[ebx+10] jb list_box_adjust_up movzx dx,byte [ebx+5] sub ax,dx jb list_box_adjustments_ok inc ax add [ebx+10],ax jmp list_box_adjustments_ok list_box_adjust_up: add [ebx+10],ax list_box_adjustments_ok: movzx edi,byte [ebx+3] imul edi,[video_pitch] movzx ecx,byte [ebx+2] lea edi,[edi+ecx*2] movzx edx,word [ebx+10] push es gs pop es draw_list_box_row: mov ah,[box_colors] movzx ecx,byte [ebx+4] cmp dx,[ebx+6] jae draw_empty_list_box_row mov esi,[ebx+12] mov esi,[esi+edx*4] test byte [ebx+1],1 jz list_box_row_colors_ok cmp dx,[ebx+8] jne list_box_row_colors_ok mov ah,[box_selection_colors] list_box_row_colors_ok: sub ecx,2 mov al,20h stosw draw_list_box_item: lodsb test al,al jnz draw_list_box_item_character dec esi mov al,20h draw_list_box_item_character: stosw loop draw_list_box_item mov al,20h cmp byte [esi],0 je list_box_item_ending mov al,1Ah list_box_item_ending: stosw jmp list_box_row_drawn draw_empty_list_box_row: mov al,20h rep stosw list_box_row_drawn: inc edx mov ax,dx sub ax,[ebx+10] cmp al,[ebx+5] jae list_box_drawn add edi,[video_pitch] movzx ecx,byte [ebx+4] shl ecx,1 sub edi,ecx jmp draw_list_box_row list_box_drawn: pop es ret list_box_command: cmp ah,48h je list_box_up_key cmp ah,50h je list_box_down_key cmp ah,47h je list_box_home_key cmp ah,4Fh je list_box_end_key cmp ah,49h je list_box_pgup_key cmp ah,51h je list_box_pgdn_key stc ret list_box_home_key: xor eax,eax mov [ebx+8],ax jmp list_box_redraw list_box_end_key: mov ax,[ebx+6] dec ax mov [ebx+8],ax jmp list_box_redraw list_box_pgup_key: movzx ax,byte [ebx+5] sub [ebx+8],ax jae list_box_redraw mov word [ebx+8],0 jmp list_box_redraw list_box_pgdn_key: movzx ax,byte [ebx+5] add [ebx+8],ax mov ax,[ebx+6] dec ax cmp [ebx+8],ax jbe list_box_redraw mov [ebx+8],ax jmp list_box_redraw list_box_up_key: mov ax,[ebx+8] sub ax,1 jc list_box_command_done dec word [ebx+8] jmp list_box_redraw list_box_down_key: mov ax,[ebx+8] inc ax cmp ax,[ebx+6] jae list_box_command_done mov [ebx+8],ax list_box_redraw: call draw_list_box list_box_command_done: clc ret create_check_box: mov byte [ebx],0 mov [ebx+1],al mov [ebx+2],dx mov [ebx+4],cl mov [ebx+8],ebp mov [ebx+12],edi movzx edx,byte [ebx+3] imul edx,[video_pitch] movzx ecx,byte [ebx+2] lea edx,[edx+ecx*2] mov al,'[' test byte [ebx+1],2 jz draw_check_box_left_bracket mov al,'(' draw_check_box_left_bracket: mov byte [gs:edx],al add edx,2 mov al,20h test byte [ebx+1],2 jnz set_up_radio_initial_state test [edi],ebp jz draw_check_box_initial_state mov al,'+' jmp draw_check_box_initial_state set_up_radio_initial_state: cmp [edi],ebp jne draw_check_box_initial_state mov al,7 draw_check_box_initial_state: mov byte [gs:edx],al add edx,2 mov al,']' test byte [ebx+1],2 jz draw_check_box_right_bracket mov al,')' draw_check_box_right_bracket: mov byte [gs:edx],al add edx,2*2 movzx ecx,byte [ebx+4] draw_check_box_text: lodsb or al,al jz check_box_text_ok mov [gs:edx],al add edx,2 loop draw_check_box_text check_box_text_ok: test byte [ebx+1],1 jnz set_check_box_focus ret set_check_box_focus: push ebx mov ah,2 mov dx,[ebx+2] inc dl xor bh,bh int 10h mov ah,1 mov cx,0D0Eh int 10h pop ebx ret check_box_command: cmp al,20h je switch_check_box_state stc ret switch_check_box_state: mov edi,[ebx+12] mov eax,[ebx+8] test byte [ebx+1],2 jnz set_radio_state xor [edi],eax call update_check_box clc ret set_radio_state: mov [edi],eax call update_check_box clc ret update_check_box: movzx edx,byte [ebx+3] imul edx,[video_pitch] movzx ecx,byte [ebx+2] lea edx,[edx+(ecx+1)*2] mov edi,[ebx+12] mov eax,[ebx+8] test byte [ebx+1],2 jnz redraw_radio test [edi],eax mov al,20h jz check_box_state_ok mov al,'+' check_box_state_ok: mov byte [gs:edx],al ret redraw_radio: cmp [edi],eax mov al,20h jne radio_state_ok mov al,7 radio_state_ok: mov byte [gs:edx],al ret init_common_dialog: xor eax,eax mov [boxes_count],eax mov [current_box],eax ret register_box_in_dialog: mov eax,[boxes_count] inc [boxes_count] mov [boxes+eax*4],ebx test byte [ebx+1],1 jz box_registered mov [current_box],eax box_registered: ret common_dialog_loop: call wait_for_input cmp ah,1 je common_dialog_aborted cmp al,0Dh je common_dialog_ok cmp al,9 je common_dialog_cycle_boxes cmp ah,0Fh je common_dialog_reverse_cycle_boxes mov edx,[current_box] mov ebx,[boxes+edx*4] call process_box_command jnc common_dialog_command_processed cmp ah,48h je common_dialog_previous_box cmp ah,50h je common_dialog_next_box cmp ah,4Bh je common_dialog_previous_box cmp ah,4Dh je common_dialog_next_box jmp common_dialog_loop common_dialog_command_processed: xor edx,edx update_boxes: mov ebx,[boxes+edx*4] push edx call update_box pop edx inc edx cmp edx,[boxes_count] jb update_boxes mov eax,[common_dialog_callback] test eax,eax jz common_dialog_loop call eax jmp common_dialog_loop common_dialog_next_box: mov edx,[current_box] lea eax,[edx+1] cmp eax,[boxes_count] je common_dialog_loop mov [current_box],eax jmp common_dialog_switch_box common_dialog_previous_box: mov edx,[current_box] or edx,edx jz common_dialog_loop dec [current_box] jmp common_dialog_switch_box common_dialog_cycle_boxes: mov edx,[current_box] inc [current_box] mov eax,[current_box] cmp eax,[boxes_count] jb common_dialog_switch_box mov [current_box],0 jmp common_dialog_switch_box common_dialog_reverse_cycle_boxes: mov edx,[current_box] sub [current_box],1 jnc common_dialog_switch_box mov eax,[boxes_count] add [current_box],eax common_dialog_switch_box: mov ebx,[boxes+edx*4] call kill_box_focus mov edx,[current_box] mov ebx,[boxes+edx*4] call set_box_focus jmp common_dialog_loop common_dialog_ok: clc ret common_dialog_aborted: stc ret get_entered_number: xor edx,edx get_digit: lodsb or al,al jz entered_number_ok sub al,30h movzx eax,al imul edx,10 add edx,eax jmp get_digit entered_number_ok: ret draw_static: lodsb or al,al jz fill_static mov [gs:edi],al add edi,2 loop draw_static ret fill_static: mov byte [gs:edi],20h add edi,2 loop fill_static dec esi ret file_open_dialog: push esi mov edi,buffer+3000h mov byte [edi],0 call get_current_directory cmp byte [edi-2],'\' je browser_startup_path_ok mov word [edi-1],'\' browser_startup_path_ok: xor eax,eax mov [file_list_buffer_handle],eax call make_list_of_files pop esi mov dx,0308h mov cl,35h mov ch,byte [screen_height] sub ch,7 mov ah,[window_colors] call draw_window push edx mov eax,[video_pitch] mov edx,[screen_height] sub edx,11 imul edx,eax lea edx,[edi+edx+8*2] mov [current_box],edx lea edi,[edi+eax+2*2] mov esi,_file mov ecx,5 call draw_static mov ebx,filename_buffer xor esi,esi mov ecx,27h + 256 shl 16 mov edx,[esp] add dx,0108h mov al,1 call create_edit_box mov ebx,boxes mov esi,[file_list] mov ecx,[file_list_buffer_top] sub ecx,esi shl ecx,16-2 mov cl,27h mov ch,byte [screen_height] sub ch,15 pop edx add dx,0308h xor al,al call create_list_box call draw_browser_path file_input_loop: call wait_for_input cmp ah,1 je filename_aborted cmp al,0Dh je filename_accepted cmp ah,0Fh je activate_file_browser cmp ah,50h je activate_file_browser mov ebx,filename_buffer call process_box_command jmp file_input_loop activate_file_browser: mov ebx,filename_buffer call kill_box_focus mov ebx,boxes call set_box_focus call update_file_input file_browser_loop: call wait_for_input cmp ah,1 je filename_aborted cmp al,0Dh je filename_accepted cmp ah,0Fh je activate_file_input cmp ah,4Bh je activate_file_input cmp al,8 je go_to_parent_directory mov ebx,boxes push dword [ebx+8] call process_box_command pop eax cmp ax,[ebx+8] je file_browser_loop call update_file_input jmp file_browser_loop go_to_parent_directory: cmp byte [buffer+3000h+3],0 je file_browser_loop mov edi,buffer mov eax,'..' stosd jmp browser_chdir filename_accepted: mov edx,filename_buffer+16 movzx eax,word [edx-16+8] test eax,eax jz got_filename cmp byte [edx+eax-1],'\' je browser_path_entered cmp byte [edx+eax-1],':' jne got_filename browser_path_entered: mov esi,edx mov edi,buffer copy_path_to_browse: lodsb stosb test al,al jnz copy_path_to_browse cmp word [buffer+1],':' je browser_directory_ok cmp byte [edi-2],'\' jne browser_chdir mov byte [edi-2],0 browser_chdir: xor dx,dx mov ax,713Bh call dos_int jnc browser_directory_ok cmp ax,7100h jne file_list_selection_ok mov ah,3Bh call dos_int jc file_list_selection_ok browser_directory_ok: cmp byte [buffer+1],':' jne browser_drive_ok mov dl,[buffer] sub dl,'A' cmp dl,'Z'-'A' jbe browser_change_drive sub dl,'a'-'A' browser_change_drive: mov ah,0Eh int 21h browser_drive_ok: push 0 cmp dword [buffer],'..' jne name_to_select_ok mov edi,buffer+3000h mov al,'\' or ecx,-1 find_last_directory_name: mov esi,edi repne scasb cmp byte [edi],0 jne find_last_directory_name lea ecx,[edi-1] sub ecx,esi mov edi,buffer+400h mov [esp],ecx mov ebx,upper_case_table get_name_to_select: lodsb xlatb stosb loop get_name_to_select name_to_select_ok: mov edi,buffer+3000h call get_current_directory jc browser_drive_invalid cmp byte [edi-2],'\' je browser_new_path_ok mov word [edi-1],'\' browser_new_path_ok: call make_list_of_files call draw_browser_path mov ebx,filename_buffer xor eax,eax mov [ebx+8],eax mov [ebx+12],eax mov [ebx+16],al mov ebx,boxes mov esi,[file_list] mov [ebx+12],esi mov ecx,[file_list_buffer_top] sub ecx,esi shr ecx,2 mov [ebx+6],cx xor eax,eax mov [ebx+8],eax mov eax,esi pop edx find_name_to_select: cmp eax,[file_list_buffer_top] je file_list_selection_ok mov esi,[eax] add esi,2 mov edi,buffer+400h mov ecx,edx repe cmpsb je select_directory add eax,4 jmp find_name_to_select select_directory: sub eax,[file_list] shr eax,2 mov [ebx+8],ax file_list_selection_ok: test byte [filename_buffer+1],1 jnz activate_file_input jmp activate_file_browser browser_drive_invalid: mov dl,[buffer+3000h] sub dl,'A' cmp dl,'Z'-'A' jbe browser_restore_drive sub dl,'a'-'A' browser_restore_drive: mov ah,0Eh int 21h pop eax jmp file_list_selection_ok got_filename: cmp [filename_buffer+16],0 je file_input_loop call release_list_of_files mov edx,filename_buffer+16 movzx ecx,word [filename_buffer+8] clc ret filename_aborted: call release_list_of_files stc ret activate_file_input: mov ebx,boxes call kill_box_focus mov ebx,filename_buffer call set_box_focus jmp file_input_loop update_file_input: mov ebx,boxes mov esi,[ebx+12] movzx eax,word [ebx+8] mov esi,[esi+eax*4] mov ah,[esi] add esi,2 mov edi,filename_buffer+16 copy_file_item: lodsb stosb test al,al jnz copy_file_item cmp ah,[browser_symbols+2] je file_item_copied cmp ah,[browser_symbols+3] je file_item_copied mov byte [edi-1],'\' stosb file_item_copied: mov ecx,edi sub ecx,1+filename_buffer+16 mov ebx,filename_buffer mov [ebx+8],cx mov [ebx+12],cx xor eax,eax mov [ebx+10],ax mov [ebx+14],ax call draw_edit_box ret draw_browser_path: mov edi,[current_box] mov esi,buffer+3000h mov ecx,27h call draw_static add edi,[video_pitch] sub edi,27h*2 mov ecx,27h call draw_static ret make_list_of_files: cmp [file_list_buffer_handle],0 je default_buffer_for_file_list mov edi,[file_list_buffer_top] mov ecx,[file_list_buffer_size] sub edi,ecx jmp init_file_list default_buffer_for_file_list: mov edi,buffer+1000h mov ecx,2000h init_file_list: lea ebx,[edi+ecx] mov [file_list_buffer_top],ebx mov ah,1Ah xor edx,edx call dos_int mov ah,19h int 21h mov dl,al mov ah,0Eh int 21h movzx ecx,al mov dword [buffer],'A:' list_drives: push ecx edi mov ax,290Ch xor esi,esi mov di,10h call dos_int pop edi inc al jz try_next_drive cmp byte [buffer],'B' jne add_drive test byte [fs:10h],11000000b jz try_next_drive add_drive: sub ebx,4 mov [ebx],edi mov esi,buffer mov ax,2004h stosw movsw movsb try_next_drive: inc byte [buffer] pop ecx loop list_drives mov [file_list],ebx mov [file_list_buffer],edi cmp byte [buffer+3000h],0 je file_list_made mov edi,buffer mov eax,'*.*' stosd mov ax,714Eh mov cx,31h xor esi,esi xor edx,edx mov di,10h call dos_int mov ebx,eax jnc long_file_names_list mov ah,4Eh mov cx,31h xor edx,edx call dos_int jc file_list_made short_file_names_list: sub [file_list],4 mov edx,[file_list] mov edi,[file_list_buffer] cmp edi,edx jae not_enough_memory_for_list mov [edx],edi mov esi,buffer+1Eh test byte [esi-1Eh+15h],10h jnz short_directory_name mov ebx,lower_case_table mov ax,2003h stosw jmp copy_short_file_name short_directory_name: mov ebx,upper_case_table cmp word [esi],'..' je short_parent_directory cmp byte [esi],'.' je short_directory_to_hide mov ax,2002h stosw jmp copy_short_file_name short_parent_directory: cmp byte [buffer+3000h+3],0 je short_directory_to_hide mov ax,2001h stosw copy_short_file_name: lodsb xlat byte [ebx] cmp edi,[file_list] jae not_enough_memory_for_list stosb test al,al jnz copy_short_file_name short_file_name_copied: mov [file_list_buffer],edi mov ah,4Fh call dos_int jnc short_file_names_list jmp file_list_made short_directory_to_hide: add [file_list],4 jmp short_file_name_copied not_enough_memory_for_long_file_name: pop ebx mov ax,71A1h call dos_int not_enough_memory_for_list: cmp [file_list_buffer_handle],0 jne really_not_enough_memory_for_list mov ax,500h mov edi,buffer int 31h mov ecx,[edi] cmp ecx,2000h jbe really_not_enough_memory_for_list cmp ecx,100000h jbe allocate_buffer_for_file_list mov ecx,100000h allocate_buffer_for_file_list: mov [file_list_buffer_size],ecx call get_memory or eax,eax jz really_not_enough_memory_for_list mov [file_list_buffer_handle],ebx mov edi,eax mov ecx,[file_list_buffer_size] jmp init_file_list really_not_enough_memory_for_list: add [file_list],4 jmp file_list_made long_file_names_list: push ebx sub [file_list],4 mov edx,[file_list] mov edi,[file_list_buffer] cmp edi,edx jae not_enough_memory_for_long_file_name mov [edx],edi mov esi,buffer+10h+2Ch test byte [esi-2Ch],10h jnz long_directory_name mov ax,2003h stosw mov ebx,lower_case_table jmp copy_long_file_name long_directory_to_hide: add [file_list],4 jmp long_file_name_copied long_directory_name: mov ebx,upper_case_table cmp byte [esi],'.' jne long_directory_show cmp byte [esi+1],0 je long_directory_to_hide cmp word [esi+1],'.' jne long_directory_show cmp byte [buffer+3000h+3],0 je long_directory_to_hide mov ax,2001h stosw jmp copy_long_file_name long_directory_show: mov ax,2002h stosw copy_long_file_name: lodsb xlatb cmp edi,[file_list] jae not_enough_memory_for_long_file_name stosb test al,al jnz copy_long_file_name long_file_name_copied: mov [file_list_buffer],edi pop ebx mov ax,714Fh xor esi,esi mov di,10h call dos_int jnc long_file_names_list mov ax,71A1h call dos_int file_list_made: mov edx,[file_list_buffer_top] sub edx,[file_list] shr edx,2 mov ebp,edx sort_file_list: shr ebp,1 jz file_list_sorted mov ebx,ebp sorting_iteration: cmp ebx,edx jae sort_file_list mov eax,ebx place_into_right_blocks: cmp eax,ebp jb sort_next_offset push edx mov edx,eax sub eax,ebp push eax mov esi,[file_list] lea eax,[esi+eax*4] lea edx,[esi+edx*4] mov esi,[eax] mov edi,[edx] mov ecx,257 repe cmpsb jbe exchange_ok mov esi,[eax] xchg esi,[edx] mov [eax],esi exchange_ok: pop eax edx jmp place_into_right_blocks sort_next_offset: inc ebx jmp sorting_iteration file_list_sorted: mov esi,[file_list] mov ebx,browser_symbols make_browser_symbols: cmp esi,[file_list_buffer_top] je file_list_done mov edx,[esi] mov al,[edx] dec al xlatb mov [edx],al add esi,4 jmp make_browser_symbols file_list_done: ret release_list_of_files: mov ebx,[file_list_buffer_handle] test ebx,ebx jz list_of_files_released call release_memory list_of_files_released: ret goto_dialog: mov esi,_position mov dx,080Bh mov cx,0719h mov ah,[window_colors] call draw_window push edx push edi mov eax,[video_pitch] lea edi,[edi+eax+5*2] mov esi,_row mov ecx,4 call draw_static pop edi mov eax,[video_pitch] lea eax,[eax*3] lea edi,[edi+eax+2*2] mov esi,_column mov ecx,7 call draw_static call init_common_dialog mov edi,buffer+200h mov esi,edi mov eax,[caret_line_number] call number_as_text xor al,al stosb mov dx,[esp] mov ebx,buffer mov ecx,9 + 7 shl 16 add dx,010Ah mov al,101b call create_edit_box call register_box_in_dialog mov edi,buffer+200h mov esi,edi mov eax,[caret_position] inc eax call number_as_text xor al,al stosb pop edx mov ebx,buffer+100h mov ecx,9 + 7 shl 16 add dx,030Ah mov al,100b call create_edit_box call register_box_in_dialog mov [common_dialog_callback],0 call common_dialog_loop jc goto_dialog_done mov esi,buffer+16 call get_entered_number mov ecx,edx mov esi,buffer+100h+16 call get_entered_number clc goto_dialog_done: ret find_dialog: push [find_flags] mov esi,_find mov dx,050Dh mov cx,0A36h mov ah,[window_colors] call draw_window push edx mov eax,[video_pitch] lea edi,[edi+eax+2*2] mov esi,_text_to_find mov ecx,13 call draw_static call init_common_dialog call get_word_at_caret mov edi,[line_buffer] mov esi,[caret_line] call copy_from_line xor al,al stosb mov dx,[esp] mov ebx,buffer mov esi,[line_buffer] mov ecx,32 + 1000 shl 16 add dx,0110h mov al,1 call create_edit_box call register_box_in_dialog mov dx,[esp] mov ebx,buffer+800h mov esi,_case_sensitive mov edi,find_flags mov ebp,FEFIND_CASESENSITIVE add dx,0310h mov cl,18h xor al,al call create_check_box call register_box_in_dialog mov dx,[esp] mov ebx,buffer+810h mov esi,_whole_words mov edi,find_flags mov ebp,FEFIND_WHOLEWORDS add dx,0410h mov cl,18h xor al,al call create_check_box call register_box_in_dialog mov dx,[esp] mov ebx,buffer+820h mov esi,_backward mov edi,find_flags mov ebp,FEFIND_BACKWARD add dx,0510h mov cl,18h xor al,al call create_check_box call register_box_in_dialog pop edx mov ebx,buffer+830h mov esi,_search_in_whole_text mov edi,find_flags mov ebp,FEFIND_INWHOLETEXT add dx,0610h mov cl,18h xor al,al call create_check_box call register_box_in_dialog mov [common_dialog_callback],0 call common_dialog_loop pop eax jc find_dialog_aborted mov esi,buffer+16 mov eax,[find_flags] clc ret find_dialog_aborted: mov [find_flags],eax ret replace_dialog: push [find_flags] mov esi,_replace mov dx,050Dh mov cx,0D36h mov ah,[window_colors] call draw_window push edx push edi mov eax,[video_pitch] lea edi,[edi+eax+2*2] mov esi,_text_to_find mov ecx,13 call draw_static pop edi mov eax,[video_pitch] imul eax,3 lea edi,[edi+eax+6*2] mov esi,_new_text mov ecx,9 call draw_static call init_common_dialog call get_word_at_caret mov edi,[line_buffer] mov esi,[caret_line] call copy_from_line xor al,al stosb mov dx,[esp] mov ebx,buffer mov esi,[line_buffer] mov ecx,32 + 1000 shl 16 add dx,0110h mov al,1 call create_edit_box call register_box_in_dialog mov dx,[esp] mov ebx,buffer+400h xor esi,esi mov ecx,32 + 1000 shl 16 add dx,0310h xor al,al call create_edit_box call register_box_in_dialog mov dx,[esp] mov ebx,buffer+800h mov esi,_case_sensitive mov edi,find_flags mov ebp,FEFIND_CASESENSITIVE add dx,0510h mov cl,18h xor al,al call create_check_box call register_box_in_dialog mov dx,[esp] mov ebx,buffer+810h mov esi,_whole_words mov edi,find_flags mov ebp,FEFIND_WHOLEWORDS add dx,0610h mov cl,18h xor al,al call create_check_box call register_box_in_dialog mov dx,[esp] mov ebx,buffer+820h mov esi,_backward mov edi,find_flags mov ebp,FEFIND_BACKWARD add dx,0710h mov cl,18h xor al,al call create_check_box call register_box_in_dialog mov dx,[esp] mov ebx,buffer+830h mov esi,_replace_in_whole_text mov edi,find_flags mov ebp,FEFIND_INWHOLETEXT add dx,0810h mov cl,18h xor al,al call create_check_box call register_box_in_dialog pop edx mov ebx,buffer+840h mov esi,_prompt mov edi,command_flags mov ebp,1 add dx,0910h mov cl,18h xor al,al call create_check_box call register_box_in_dialog mov [common_dialog_callback],0 call common_dialog_loop pop eax jc replace_dialog_aborted mov esi,buffer+16 mov edi,buffer+400h+16 mov eax,[find_flags] clc ret replace_dialog_aborted: mov [find_flags],eax ret options_dialog: mov esi,_options mov dx,0616h mov cx,0922h mov ah,[window_colors] call draw_window push edx call init_common_dialog mov ebx,buffer mov esi,_secure_selection mov edi,editor_style mov ebp,FES_SECURESEL add dx,0102h mov cl,16h mov al,1 call create_check_box call register_box_in_dialog mov dx,[esp] mov ebx,buffer+10h mov esi,_auto_brackets mov edi,editor_style mov ebp,FES_AUTOBRACKETS add dx,0202h mov cl,16h xor al,al call create_check_box call register_box_in_dialog mov dx,[esp] mov ebx,buffer+20h mov esi,_auto_indent mov edi,editor_style mov ebp,FES_AUTOINDENT add dx,0302h mov cl,16h xor al,al call create_check_box call register_box_in_dialog mov dx,[esp] mov ebx,buffer+30h mov esi,_smart_tabs mov edi,editor_style mov ebp,FES_SMARTTABS add dx,0402h mov cl,16h xor al,al call create_check_box call register_box_in_dialog pop edx mov ebx,buffer+40h mov esi,_optimal_fill mov edi,editor_style mov ebp,FES_OPTIMALFILL add dx,0502h mov cl,16h xor al,al call create_check_box call register_box_in_dialog mov [common_dialog_callback],0 jmp common_dialog_loop ascii_table_window: mov esi,_ascii_table mov dx,0616h mov cx,0C24h mov ah,[window_colors] call draw_window push edx mov ah,[window_colors] xor al,al mov edx,8 draw_ascii_table: mov ecx,32 draw_ascii_row: mov [gs:edi],ax add edi,2 inc al loop draw_ascii_row add edi,[video_pitch] sub edi,32*2 dec edx jnz draw_ascii_table mov ecx,32 draw_ascii_table_border: mov byte [gs:edi+(ecx-1)*2],'Ä' loop draw_ascii_table_border add edi,[video_pitch] push edi mov ah,1 mov cx,000Fh int 10h ascii_table_update: mov dl,[selected_character] mov dh,dl and dl,11111b shr dh,5 add dx,word [esp+4] mov ah,2 xor bh,bh int 10h mov edi,screen_row_buffer+10h mov eax,'Dec:' stosd mov al,20h stosb movzx eax,[selected_character] call number_as_text mov al,20h stosb mov eax,'Hex:' stosd mov al,20h stosb mov al,[selected_character] shr al,4 cmp al,10 sbb al,69h das stosb mov al,[selected_character] and al,0Fh cmp al,10 sbb al,69h das stosb xor al,al stosb sub edi,30+1 mov esi,edi mov eax,'Char' stosd mov eax,'acte' stosd mov eax,'r: ' stosd mov ecx,screen_row_buffer+10h sub ecx,edi mov al,20h rep stosb mov edi,[esp] add edi,1*2 mov ecx,30 call draw_static mov edi,[esp] mov al,[selected_character] mov [gs:edi+12*2],al ascii_table_loop: call wait_for_input or ah,ah jz pure_ascii_char cmp ah,48h je ascii_table_up cmp ah,50h je ascii_table_down cmp ah,4Bh je ascii_table_left cmp ah,4Dh je ascii_table_right cmp ah,1 je ascii_table_exit cmp al,0E0h je ascii_table_loop cmp al,13 je ascii_table_done cmp al,2 je ascii_table_done cmp al,20h jb ascii_table_loop pure_ascii_char: mov [selected_character],al jmp ascii_table_update ascii_table_exit: pop eax eax stc ret ascii_table_done: pop eax eax mov al,[selected_character] clc ret ascii_table_up: cmp [selected_character],20h jb ascii_table_loop sub [selected_character],20h jmp ascii_table_update ascii_table_down: cmp [selected_character],0E0h jae ascii_table_loop add [selected_character],20h jmp ascii_table_update ascii_table_left: test [selected_character],11111b jz ascii_table_loop dec [selected_character] jmp ascii_table_update ascii_table_right: mov al,[selected_character] inc al test al,11111b jz ascii_table_loop mov [selected_character],al jmp ascii_table_update calculator_window: mov [results_selection],0 mov esi,_calculator mov dx,0602h mov cx,0B4Ch mov ah,[window_colors] call draw_window push edi edx mov eax,[video_pitch] lea edi,[edi+eax+2*2] mov esi,_expression mov ecx,11 call draw_static mov eax,[video_pitch] lea eax,[eax*3] mov edi,[esp+4] lea edi,[edi+eax+2*2] mov esi,_result mov ecx,65 call draw_static call init_common_dialog mov ebx,buffer xor esi,esi mov ecx,56 + 1000 shl 16 mov dx,[esp] add dx,010Eh mov al,1 call create_edit_box call register_box_in_dialog mov ebx,buffer+2000h mov esi,_null mov edi,results_selection xor ebp,ebp mov dx,[esp] add dx,0402h mov cl,18h mov al,2 call create_check_box call register_box_in_dialog mov ebx,buffer+2010h mov esi,_null mov edi,results_selection mov ebp,1 mov dx,[esp] add dx,0502h mov cl,18h mov al,2 call create_check_box call register_box_in_dialog mov ebx,buffer+2020h mov esi,_null mov edi,results_selection mov ebp,2 mov dx,[esp] add dx,0602h mov cl,18h mov al,2 call create_check_box call register_box_in_dialog mov ebx,buffer+2030h mov esi,_null mov edi,results_selection mov ebp,3 mov dx,[esp] add dx,0702h mov cl,18h mov al,2 call create_check_box call register_box_in_dialog pop edx edi mov eax,[video_pitch] lea edi,[edi+eax*4+6*2] mov [results_offset],edi mov [common_dialog_callback],calculate_result calculator_loop: call common_dialog_loop jc close_calculator mov esi,[results_offset] mov eax,[results_selection] imul eax,[video_pitch] add esi,eax mov edi,buffer+16 copy_result: lods byte [gs:esi] cmp al,20h je result_ready stosb inc esi jmp copy_result result_ready: mov ecx,edi sub ecx,buffer+16 mov ebx,buffer mov [ebx+8],cx mov [ebx+12],cx xor eax,eax mov [ebx+10],ax mov [ebx+14],ax cmp [current_box],0 jne activate_expression_box call draw_edit_box jmp calculator_loop activate_expression_box: mov edx,[current_box] mov ebx,[boxes+edx*4] call kill_box_focus mov [current_box],0 mov ebx,buffer call set_box_focus jmp calculator_loop close_calculator: ret calculate_result: mov esi,buffer+16 movzx eax,word [buffer+8] lea edi,[esi+eax] xor eax,eax stosb mov [progress_offset],eax mov [hash_tree],eax mov [macro_status],al mov [symbols_file],eax not eax mov [source_start],eax mov eax,buffer+1000h mov [memory_end],eax mov [labels_list],eax mov [resume_esp],esp mov [resume_eip],calculator_error call convert_line push edi call convert_expression cmp byte [esi],0 jne invalid_expression mov al,')' stosb pop esi mov [error_line],0 mov [current_line],-1 mov [value_size],0 call calculate_expression cmp [error_line],0 je present_result jmp [error] present_result: mov ebp,edi cmp byte [ebp+13],0 je result_in_64bit_composite_range test byte [ebp+7],80h jnz result_in_64bit_composite_range mov esi,_null mov edi,[results_offset] add edi,[video_pitch] mov ecx,65 push edi call draw_static pop edi add edi,[video_pitch] mov ecx,65 push edi call draw_static pop edi add edi,[video_pitch] mov ecx,65 call draw_static jmp present_decimal result_in_64bit_composite_range: mov eax,[ebp] mov edx,[ebp+4] mov edi,buffer+3000h mov word [edi],'b' make_binary_number: mov bl,'0' shrd eax,edx,1 adc bl,0 dec edi mov [edi],bl shr edx,1 jnz make_binary_number test eax,eax jnz make_binary_number mov esi,edi mov eax,[video_pitch] mov edi,[results_offset] lea edi,[edi+eax*2] mov ecx,65 call draw_static mov ecx,[ebp] mov edx,[ebp+4] mov edi,buffer+3000h mov word [edi],'o' make_octal_number: mov al,cl and al,111b add al,'0' dec edi mov [edi],al shrd ecx,edx,3 shr edx,3 jnz make_octal_number test ecx,ecx jnz make_octal_number mov esi,edi mov eax,[video_pitch] mov edi,[results_offset] lea eax,[eax*3] add edi,eax mov ecx,65 call draw_static mov ecx,[ebp] mov edx,[ebp+4] mov edi,buffer+3000h mov word [edi],'h' make_hexadecimal_number: mov al,cl and al,0Fh cmp al,10 sbb al,69h das dec edi mov [edi],al shrd ecx,edx,4 shr edx,4 jnz make_hexadecimal_number test ecx,ecx jnz make_hexadecimal_number cmp al,'A' jb hexadecimal_number_ok dec edi mov byte [edi],'0' hexadecimal_number_ok: mov esi,edi mov eax,[video_pitch] mov edi,[results_offset] lea edi,[edi+eax] mov ecx,65 call draw_static present_decimal: mov edi,buffer+3000h mov byte [edi],0 mov ecx,10 xor bl,bl cmp byte [ebp+13],0 je make_decimal_number mov bl,'-' mov eax,[ebp] mov edx,[ebp+4] not eax not edx add eax,1 adc edx,0 mov [ebp],eax mov [ebp+4],edx or eax,edx jnz make_decimal_number dec edi mov byte [edi],'6' mov dword [ebp],99999999h mov dword [ebp+4],19999999h make_decimal_number: mov eax,[ebp+4] xor edx,edx div ecx mov [ebp+4],eax mov eax,[ebp] div ecx mov [ebp],eax add dl,'0' dec edi mov [edi],dl or eax,[ebp+4] jnz make_decimal_number test bl,bl jz decimal_number_ok dec edi mov [edi],bl decimal_number_ok: mov esi,edi mov edi,[results_offset] mov ecx,65 call draw_static ret calculator_error: mov ebx,[video_pitch] mov ebp,[results_offset] mov edx,4 clear_results: mov ecx,65 mov edi,ebp call fill_static add ebp,ebx dec edx jnz clear_results ret ; Memory allocation get_memory: push esi edi mov ebx,ecx shr ebx,16 mov ax,501h int 31h jc dpmi_allocation_failed mov ax,bx shl eax,16 mov ax,cx mov edx,main shl edx,4 sub eax,edx mov bx,si shl ebx,16 mov bx,di pop edi esi ret dpmi_allocation_failed: xor eax,eax pop edi esi ret release_memory: push esi edi mov esi,ebx shr esi,16 mov di,bx mov ax,502h int 31h pop edi esi ret get_low_memory: mov ax,100h mov bx,-1 int 31h movzx eax,bx shl eax,4 mov [low_memory_size],eax mov ax,100h int 31h mov [low_memory_selector],dx jnc low_memory_ok xor edx,edx mov [low_memory_size],edx low_memory_ok: ret release_low_memory: cmp [low_memory_size],0 je low_memory_ok mov ax,101h mov dx,[low_memory_selector] int 31h ret ; File operations dos_int: push 0 push 0 push 0 pushw buffer_segment pushw buffer_segment stc pushfw push eax push ecx push edx push ebx push 0 push ebp push esi push edi mov ax,300h mov bx,21h xor cx,cx mov edi,esp push es ss pop es int 31h pop es mov edi,[esp] mov esi,[esp+4] mov ebp,[esp+8] mov ebx,[esp+10h] mov edx,[esp+14h] mov ecx,[esp+18h] mov ah,[esp+20h] sahf mov eax,[esp+1Ch] lea esp,[esp+32h] ret open: push esi edi call adapt_path mov ax,716Ch mov bx,100000b mov dx,1 xor cx,cx xor si,si call dos_int jnc open_done cmp ax,7100h je old_open stc jmp open_done old_open: mov ax,3D00h xor dx,dx call dos_int open_done: mov bx,ax pop edi esi ret adapt_path: mov esi,edx mov edi,buffer copy_path: lodsb cmp al,'/' jne path_char_ok mov al,'\' path_char_ok: stosb or al,al jnz copy_path ret create: push esi edi call adapt_path mov ax,716Ch mov bx,100001b mov dx,10010b xor cx,cx xor si,si xor di,di call dos_int jnc create_done cmp ax,7100h je old_create stc jmp create_done old_create: mov ah,3Ch xor cx,cx xor dx,dx call dos_int create_done: mov bx,ax pop edi esi ret write: push edx esi edi ebp mov ebp,ecx mov esi,edx write_loop: mov ecx,1000h sub ebp,1000h jnc do_write add ebp,1000h mov ecx,ebp xor ebp,ebp do_write: push ecx mov edi,buffer shr ecx,2 rep movsd mov ecx,[esp] and ecx,11b rep movsb pop ecx mov ah,40h xor dx,dx call dos_int or ebp,ebp jnz write_loop pop ebp edi esi edx ret read: push edx esi edi ebp mov ebp,ecx mov edi,edx read_loop: mov ecx,1000h sub ebp,1000h jnc do_read add ebp,1000h mov ecx,ebp xor ebp,ebp do_read: push ecx mov ah,3Fh xor dx,dx call dos_int cmp ax,cx jne eof mov esi,buffer mov ecx,[esp] shr ecx,2 rep movsd pop ecx and ecx,11b rep movsb or ebp,ebp jnz read_loop read_done: pop ebp edi esi edx ret eof: pop ecx stc jmp read_done close: mov ah,3Eh int 21h ret lseek: mov ah,42h mov ecx,edx shr ecx,16 int 21h pushf shl edx,16 popf mov dx,ax mov eax,edx ret ; Other functions needed by assembler core get_environment_variable: push esi edi mov ebx,_section_environment call get_ini_value pop edi ebx jnc found_value_in_ini push ds mov ds,[environment_selector] xor esi,esi compare_variable_names: mov edx,ebx compare_name_char: lodsb mov ah,[es:edx] inc edx cmp al,'=' je end_of_variable_name or ah,ah jz next_variable sub ah,al jz compare_name_char cmp ah,20h jne next_variable cmp al,41h jb next_variable cmp al,5Ah jna compare_name_char next_variable: lodsb or al,al jnz next_variable cmp byte [esi],0 jne compare_variable_names pop ds ret end_of_variable_name: or ah,ah jnz next_variable copy_variable_value: lodsb cmp edi,[es:memory_end] jae out_of_memory stosb or al,al jnz copy_variable_value dec edi pop ds ret found_value_in_ini: lea eax,[edi+ecx] cmp eax,[memory_end] jae out_of_memory rep movsb ret make_timestamp: mov ah,2Ah int 21h push dx cx movzx ecx,cx 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,byte [esp+3] 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 pop cx jbe day_correction_ok sub ebp,2 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: pop dx movzx eax,dl dec eax add eax,ebp mov ebx,24 mul ebx push eax mov ah,2Ch int 21h pop eax push dx movzx ebx,ch add eax,ebx mov ebx,60 mul ebx movzx ebx,cl add eax,ebx mov ebx,60 mul ebx pop bx movzx ebx,bh add eax,ebx adc edx,0 ret display_block: mov edi,[display_length] mov eax,[display_length] add eax,ecx cmp eax,[low_memory_size] ja not_enough_memory mov [display_length],eax push es mov es,[low_memory_selector] rep movsb pop es ret ; Error handling not_enough_memory: call update_screen mov esi,_memory_error mov ebx,_error movzx eax,[error_box_colors] call message_box mov esp,stack_top jmp main_loop fatal_error: cmp [progress_offset],0 je error_outside_compiler pop esi mov esp,stack_top push esi mov ax,205h mov bl,9 mov edx,dword [keyboard_handler] mov cx,word [keyboard_handler+4] int 31h mov ebx,[allocated_memory] call release_memory call update_screen show_error_summary: mov esi,buffer+3000h call go_to_directory mov esi,_assembler_error mov edi,buffer mov ebx,esp call sprintf mov esi,buffer mov ebx,_compile movzx eax,[error_box_colors] mov [first_button],_ok mov [second_button],_get_display cmp [display_length],0 je show_compilation_summary or eax,2000000h jmp show_compilation_summary assembler_error: cmp [progress_offset],0 je error_outside_compiler pop esi mov esp,stack_top push esi mov ax,205h mov bl,9 mov edx,dword [keyboard_handler] mov cx,word [keyboard_handler+4] int 31h and [output_file],0 call show_display_buffer call update_screen mov ebx,[current_line] find_error_origin: test dword [ebx+4],80000000h jz error_origin_found mov ebx,[ebx+8] jmp find_error_origin error_origin_found: mov esi,[ebx] mov edi,filename_buffer copy_error_file: lodsb stosb or al,al jnz copy_error_file push dword [ebx+4] mov ebx,[allocated_memory] call release_memory mov edx,filename_buffer call load_file show_error_line: pop eax call find_line xor eax,eax mov [selection_line],esi mov [selection_line_number],ecx mov [selection_position],eax mov [caret_position],eax push esi lea edi,[esi+SEGMENT_HEADER_LENGTH] lea ebp,[esi+SEGMENT_LENGTH] mov ebx,characters xor edx,edx check_for_more_lines: call peek_character jc no_more_lines cmp al,3Bh je no_more_lines mov ah,al xlatb or al,al jz symbol or edx,edx jnz neutral cmp ah,27h je quoted cmp ah,22h je quoted neutral: or edx,-1 jmp check_for_more_lines peek_character: cmp edi,ebp je peek_next_segment mov al,[edi] inc edi clc ret peek_next_segment: mov esi,[esi] btr esi,0 lea edi,[esi+SEGMENT_HEADER_LENGTH] lea ebp,[esi+SEGMENT_LENGTH] jc peek_character stc ret symbol: cmp ah,'\' je backslash xor edx,edx jmp check_for_more_lines quoted: call peek_character jc no_more_lines cmp al,ah jne quoted call peek_character jc no_more_lines cmp al,ah je quoted dec edi xor edx,edx jmp check_for_more_lines backslash: call peek_character jc more_lines cmp al,20h je backslash cmp al,3Bh jne no_more_lines comment: mov esi,[esi] btr esi,0 jc comment more_lines: or esi,esi jz last_line inc ecx mov [esp],esi jmp check_for_more_lines last_line: pop [caret_line] mov [caret_line_number],ecx mov eax,[maximum_position] mov [caret_position],eax jmp error_line_highlighted no_more_lines: or esi,esi jz last_line pop eax inc ecx mov [caret_line],esi mov [caret_line_number],ecx error_line_highlighted: call let_caret_appear mov eax,[caret_line] xchg eax,[selection_line] mov [caret_line],eax mov eax,[caret_line_number] xchg eax,[selection_line_number] mov [caret_line_number],eax mov eax,[caret_position] xchg eax,[selection_position] mov [caret_position],eax call let_caret_appear call update_window call update_screen jmp show_error_summary error_outside_compiler: mov esp,[resume_esp] jmp [resume_eip] ; Assembler core 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' ; Assembler constants include '..\..\tables.inc' include '..\..\messages.inc' include '..\..\version.inc' ; String constants _caption db 'flat assembler ',VERSION_STRING,0 _copyright db 'Copyright (c) 1999-2022, Tomasz Grysztar',0 _null db 0 _untitled db 'Untitled',0 _compile db 'Compile',0 _error db 'Error',0 _ok db 'OK',0 _yes db 'Yes',0 _no db 'No',0 _get_display db 'Get display to clipboard',0 _open db 'Open',0 _save_as db 'Save as',0 _file db 'File:',0 _position db 'Position',0 _row db 'Row:',0 _column db 'Column:',0 _find db 'Find',0 _replace db 'Replace',0 _text_to_find db 'Text to find:',0 _new_text db 'New text:',0 _expression db 'Expression:',0 _result db 'Result:',0 _case_sensitive db 'Case sensitive',0 _whole_words db 'Whole words',0 _backward db 'Backward search',0 _search_in_whole_text db 'Search in whole text',0 _replace_in_whole_text db 'Replace in whole text',0 _prompt db 'Prompt on replace',0 _options db 'Editor options',0 _secure_selection db 'Secure selection',0 _auto_brackets db 'Automatic brackets',0 _auto_indent db 'Automatic indents',0 _smart_tabs db 'Smart tabulation',0 _optimal_fill db 'Optimal fill on saving',0 _ascii_table db 'ASCII table',0 _calculator db 'Calculator',0 _startup_failed db 'Failed to allocate required memory.',0 _memory_error db 'Not enough memory to complete this operation.',0 _loading_error db 'Could not load file %s.',0 _saving_error db 'Could not write file to disk.',0 _not_executable db 'Cannot execute this kind of file.',0 _saving_question db 'File was modified. Save it now?',0 _overwrite_question db 'File %s already exists. Do you want to replace it?',0 _directory_question db 'Directory %s does not exist. Do you want to create it now?',0 _directory_error db 'Failed to create the directory.',0 _invalid_path db 'Invalid path.',0 _not_found_after db 'Text %s not found after current position.',0 _not_found_before db 'Text %s not found before current position.',0 _replace_prompt db 'Replace this occurence?',0 _replaces_made db '%d replaces made.',0 _assembler_error db 'Error: %s.',0 _section_environment db 'Environment',0 _section_compiler db 'Compiler',0 _key_compiler_memory db 'Memory',0 _key_compiler_passes db 'Passes',0 _section_options db 'Options',0 _key_options_securesel db 'SecureSelection',0 _key_options_autobrackets db 'AutoBrackets',0 _key_options_autoindent db 'AutoIndent',0 _key_options_smarttabs db 'SmartTabs',0 _key_options_optimalfill db 'OptimalFill',0 _section_colors db 'Colors',0 _key_color_text db 'Text',0 _key_color_background db 'Background',0 _key_color_seltext db 'SelectionText',0 _key_color_selbackground db 'SelectionBackground',0 _key_color_symbols db 'Symbols',0 _key_color_numbers db 'Numbers',0 _key_color_strings db 'Strings',0 _key_color_comments db 'Comments',0 _key_color_statustext db 'StatusText',0 _key_color_statusbackground db 'StatusBackground',0 _key_color_wintext db 'WindowText',0 _key_color_winbackground db 'WindowBackground',0 _key_color_msgtext db 'MessageText',0 _key_color_msgbackground db 'MessageBackground',0 _key_color_msgseltext db 'MessageSelectionText',0 _key_color_msgselbackground db 'MessageSelectionBackground',0 _key_color_errtext db 'ErrorText',0 _key_color_errbackground db 'ErrorBackground',0 _key_color_errseltext db 'ErrorSelectionText',0 _key_color_errselbackground db 'ErrorSelectionBackground',0 _key_color_boxtext db 'BoxText',0 _key_color_boxbackground db 'BoxBackground',0 _key_color_boxseltext db 'BoxSelectionText',0 _key_color_boxselbackground db 'BoxSelectionBackground',0 ; Configuration editor_style dd FES_AUTOINDENT+FES_SMARTTABS+FES_SECURESEL+FES_OPTIMALFILL text_colors db 87h selection_colors db 7Fh symbol_color db 0Fh number_color db 0Ah string_color db 0Ch comment_color db 3 status_colors db 2Fh window_colors db 3Fh box_colors db 1Fh box_selection_colors db 9Fh message_box_colors dw 3F1Fh error_box_colors dw 4E6Eh ; Other constants browser_symbols db 18h,09h,07h,0F0h ; Editor core include '..\memory.inc' include '..\navigate.inc' include '..\edit.inc' include '..\blocks.inc' include '..\search.inc' include '..\undo.inc' ; Editor constants SEGMENT_LENGTH = 160 BLOCK_LENGTH = 1024 * SEGMENT_LENGTH SEGMENT_HEADER_LENGTH = 16 SEGMENT_DATA_LENGTH = SEGMENT_LENGTH - SEGMENT_HEADER_LENGTH FEMODE_OVERWRITE = 1 FEMODE_VERTICALSEL = 2 FEMODE_NOUNDO = 4 FEMODE_READONLY = 8 FEFIND_CASESENSITIVE = 1 FEFIND_WHOLEWORDS = 2 FEFIND_BACKWARD = 4 FEFIND_INWHOLETEXT = 8 FES_AUTOINDENT = 0001h FES_AUTOBRACKETS = 0002h FES_SMARTTABS = 0004h FES_SECURESEL = 0008h FES_OPTIMALFILL = 0010h include '..\version.inc' ; Editor data editor_data: next_instance dd ? previous_instance dd ? file_path dd ? file_path_handle dd ? include '..\variable.inc' editor_data_size = $ - editor_data if editor_data_size > SEGMENT_DATA_LENGTH err end if lower_case_table db 100h dup ? upper_case_table db 100h dup ? ; Assembler core data include '..\..\variable.inc' ; Interface specific data psp_selector dw ? environment_selector dw ? main_selector dw ? bios_selector dw ? video_selector dw ? screen_width dd ? screen_height dd ? video_pitch dd ? video_storage dd ? video_storage_handle dd ? stored_cursor dw ? stored_cursor_position dw ? stored_page db ? stored_mode db ? low_memory_size dd ? low_memory_selector dw ? last_operation db ? current_operation db ? was_selection db ? line_buffer dd ? line_buffer_size dd ? line_buffer_handle dd ? screen_offset dd ? screen_row_buffer db 512 dup ? clipboard dd ? clipboard_handle dd ? main_project_file dd ? memory_limit dd ? allocated_memory dd ? start_time dd ? progress_offset dd ? keyboard_handler dp ? display_length dd ? find_flags dd ? replaces_count dd ? selected_character db ? command_flags db ? message_width db ? buttons_width db ? first_button dd ? second_button dd ? file_handle dd ? filename_buffer db 17+256 dup ? ini_data dd ? ini_data_handle dd ? ini_data_length dd ? ini_extension dd ? ini_path db 260 dup ? file_list dd ? file_list_buffer dd ? file_list_buffer_top dd ? file_list_buffer_handle dd ? file_list_buffer_size dd ? current_box dd ? boxes_count dd ? boxes dd 16 dup ? common_dialog_callback dd ? resume_esp dd ? resume_eip dd ? results_offset dd ? results_selection dd ? segment buffer_segment buffer = (buffer_segment-main) shl 4 db 4000h dup ? segment stack_segment stack_bottom = (stack_segment-main) shl 4 db 4000h dup ? stack_top = stack_bottom + $