📄 fasmd.asm
字号:
; flat assembler IDE for DOS/DPMI
; Copyright (c) 1999-2007, 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
mov ax,1A00h
xor bx,bx
int 10h
cmp al,1Ah
jne no_vga
cmp bl,8
jne no_vga
mov ax,1687h
int 2Fh
or ax,ax ; DPMI installed?
jnz no_dpmi
test bl,1 ; 32-bit programs supported?
jz 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
jc init_failed
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
no_vga:
call init_error
db 'Color VGA adapter is required.',0Dh,0Ah,24h
no_dpmi:
call init_error
db '32-bit DPMI services are not available.',0Dh,0Ah,24h
init_failed:
call init_error
db 'DPMI initialization failed.',0Dh,0Ah,24h
init_error:
mov ah,9
pop dx
push cs
pop ds
int 21h
mov ax,4CFFh
int 21h
mode_switch dd ?
segment main use32
start:
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],ecx
mov edi,case_table
xor al,al
mov ecx,80h
prepare_case_table:
stosb
inc al
loop prepare_case_table
prepare_extended_case_table:
push eax
mov dl,al
mov ax,6520h
int 21h
mov al,[esp]
jc extended_case_character_ok
mov al,dl
extended_case_character_ok:
stosb
pop eax
inc al
jnz prepare_extended_case_table
mov esi,case_table+'a'
mov edi,case_table+'A'
mov ecx,26
rep movsb
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
xor eax,eax
mov [main_project_file],eax
mov [clipboard],eax
mov [last_operation],al
mov [find_flags],eax
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,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,5Ch
je assign_to_compiler
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,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:
cmp [was_selection],0
je no_selection_to_replace
call store_status_for_undo
test [editor_style],AES_SECURESEL
jnz character_undo_ok
push eax
call delete_block
pop eax
call put_character
mov esi,[caret_line]
call check_line_length
mov [selection_line],0
jmp text_modified
no_selection_to_replace:
mov [current_operation],20h
cmp [last_operation],20h
je character_undo_ok
call store_status_for_undo
character_undo_ok:
call put_character
mov esi,[caret_line]
call check_line_length
mov [selection_line],0
jmp text_modified
tab_key:
call store_status_for_undo
cmp [was_selection],0
je tab_securesel
test [editor_style],AES_SECURESEL
jnz tab_securesel
call delete_block
tab_securesel:
call tabulate
mov [selection_line],0
mov esi,[caret_line]
call check_line_length
jmp text_modified
enter_key:
call store_status_for_undo
cmp [was_selection],0
je enter_secureselection_ok
test [editor_style],AES_SECURESEL
jnz enter_secureselection_ok
call delete_block
enter_secureselection_ok:
call carriage_return
mov [selection_line],0
test [editor_mode],AEMODE_OVERWRITE
jnz text_modified
mov esi,[caret_line]
call check_line_length
jmp text_modified
backspace_key:
test byte [fs:17h],100b
jnz replace
cmp [was_selection],0
je no_selection_to_clear
test [editor_style],AES_SECURESEL
jz block_delete
no_selection_to_clear:
cmp [caret_position],0
je line_back
mov [current_operation],8
cmp [last_operation],8
je undo_back_ok
call store_status_for_undo
undo_back_ok:
dec [caret_position]
call delete_character
mov esi,[caret_line]
call check_line_length
mov [selection_line],0
jmp text_modified
line_back:
test [editor_mode],AEMODE_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
mov esi,[caret_line]
call check_line_length
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
mov esi,[caret_line]
call check_line_length
jmp text_modified
del_key:
test byte [fs:17h],11b
jnz block_cut
cmp [was_selection],0
je no_selection_on_del
test [editor_style],AES_SECURESEL
jz block_delete
no_selection_on_del:
mov esi,[caret_line]
test [editor_mode],AEMODE_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
mov esi,[caret_line]
call check_line_length
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
mov esi,[caret_line]
call check_line_length
mov [selection_line],0
jmp text_modified
ctrl_y_key:
call remove_line
jmp text_modified
f6_key:
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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -