added fasm2 as well
This commit is contained in:
643
toolchain/fasm2/source/dos/fasmg.asm
Normal file
643
toolchain/fasm2/source/dos/fasmg.asm
Normal file
@ -0,0 +1,643 @@
|
||||
|
||||
include 'macro/struct.inc'
|
||||
|
||||
include '../version.inc'
|
||||
|
||||
BUFFER_SIZE = 4000h
|
||||
STACK_SIZE = 4000h
|
||||
|
||||
format MZ
|
||||
heap 0
|
||||
stack stack_segment:stack_top-stack_bottom
|
||||
entry loader:startup
|
||||
|
||||
use i386
|
||||
|
||||
segment loader use16
|
||||
|
||||
startup:
|
||||
|
||||
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 startup_error
|
||||
db 'DPMI initialization failed.',0Dh,0Ah,0
|
||||
no_dpmi:
|
||||
call startup_error
|
||||
db '32-bit DPMI services are not available.',0Dh,0Ah,0
|
||||
startup_error:
|
||||
pop si
|
||||
push cs
|
||||
pop ds
|
||||
show_message:
|
||||
lodsb
|
||||
test al,al
|
||||
jz message_shown
|
||||
mov dl,al
|
||||
mov ah,2
|
||||
int 21h
|
||||
jmp show_message
|
||||
message_shown:
|
||||
mov ax,4CFFh
|
||||
int 21h
|
||||
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 gs,ax ; environment selector in GS
|
||||
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
|
||||
mov ax,gs
|
||||
lar cx,ax
|
||||
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 ; BIOS data selector in FS
|
||||
push si
|
||||
push start
|
||||
retf
|
||||
|
||||
mode_switch dd ?
|
||||
|
||||
segment main use32
|
||||
|
||||
start:
|
||||
|
||||
call system_init
|
||||
|
||||
call get_arguments
|
||||
mov bl,al
|
||||
cmp [no_logo],0
|
||||
jne logo_ok
|
||||
mov esi,_logo
|
||||
xor ecx,ecx
|
||||
call display_string
|
||||
logo_ok:
|
||||
test bl,bl
|
||||
jnz display_usage_information
|
||||
|
||||
xor al,al
|
||||
mov ecx,[verbosity_level]
|
||||
jecxz init
|
||||
or al,TRACE_ERROR_STACK
|
||||
dec ecx
|
||||
jz init
|
||||
or al,TRACE_DISPLAY
|
||||
init:
|
||||
|
||||
call assembly_init
|
||||
|
||||
mov eax,[fs:6Ch]
|
||||
mov [timer],eax
|
||||
|
||||
assemble:
|
||||
mov esi,[initial_commands]
|
||||
mov edx,[source_path]
|
||||
call assembly_pass
|
||||
jc assembly_done
|
||||
|
||||
mov eax,[current_pass]
|
||||
cmp eax,[maximum_number_of_passes]
|
||||
jb assemble
|
||||
|
||||
call show_display_data
|
||||
|
||||
mov esi,_error_prefix
|
||||
xor ecx,ecx
|
||||
call display_error_string
|
||||
mov esi,_code_cannot_be_generated
|
||||
xor ecx,ecx
|
||||
call display_error_string
|
||||
mov esi,_message_suffix
|
||||
xor ecx,ecx
|
||||
call display_error_string
|
||||
|
||||
jmp assembly_failed
|
||||
|
||||
assembly_done:
|
||||
|
||||
call show_display_data
|
||||
|
||||
cmp [first_error],0
|
||||
jne assembly_failed
|
||||
|
||||
cmp [no_logo],0
|
||||
jne summary_done
|
||||
mov eax,[current_pass]
|
||||
xor edx,edx
|
||||
call itoa
|
||||
call display_string
|
||||
mov esi,_passes
|
||||
cmp [current_pass],1
|
||||
jne display_passes_suffix
|
||||
mov esi,_pass
|
||||
display_passes_suffix:
|
||||
xor ecx,ecx
|
||||
call display_string
|
||||
mov eax,[fs:6Ch]
|
||||
sub eax,[timer]
|
||||
mov ecx,36000
|
||||
mul ecx
|
||||
shrd eax,edx,16
|
||||
shr edx,16
|
||||
mov ecx,10
|
||||
div ecx
|
||||
mov [timer],edx
|
||||
or edx,eax
|
||||
jz display_output_length
|
||||
xor edx,edx
|
||||
call itoa
|
||||
call display_string
|
||||
mov esi,_message_suffix
|
||||
mov ecx,1
|
||||
call display_string
|
||||
mov eax,[timer]
|
||||
xor edx,edx
|
||||
call itoa
|
||||
call display_string
|
||||
mov esi,_seconds
|
||||
xor ecx,ecx
|
||||
call display_string
|
||||
display_output_length:
|
||||
call get_output_length
|
||||
push eax edx
|
||||
call itoa
|
||||
call display_string
|
||||
pop edx eax
|
||||
mov esi,_bytes
|
||||
cmp eax,1
|
||||
jne display_bytes_suffix
|
||||
test edx,edx
|
||||
jnz display_bytes_suffix
|
||||
mov esi,_byte
|
||||
display_bytes_suffix:
|
||||
xor ecx,ecx
|
||||
call display_string
|
||||
mov esi,_new_line
|
||||
xor ecx,ecx
|
||||
call display_string
|
||||
summary_done:
|
||||
|
||||
mov ebx,[source_path]
|
||||
mov edi,[output_path]
|
||||
call write_output_file
|
||||
jc write_failed
|
||||
|
||||
call assembly_shutdown
|
||||
call system_shutdown
|
||||
|
||||
mov ax,4C00h
|
||||
int 21h
|
||||
|
||||
assembly_failed:
|
||||
|
||||
call show_errors
|
||||
|
||||
call assembly_shutdown
|
||||
call system_shutdown
|
||||
|
||||
mov ax,4C02h
|
||||
int 21h
|
||||
|
||||
write_failed:
|
||||
mov ebx,_write_failed
|
||||
jmp fatal_error
|
||||
|
||||
out_of_memory:
|
||||
mov ebx,_out_of_memory
|
||||
jmp fatal_error
|
||||
|
||||
fatal_error:
|
||||
|
||||
mov esi,_error_prefix
|
||||
xor ecx,ecx
|
||||
call display_error_string
|
||||
mov esi,ebx
|
||||
xor ecx,ecx
|
||||
call display_error_string
|
||||
mov esi,_message_suffix
|
||||
xor ecx,ecx
|
||||
call display_error_string
|
||||
|
||||
call assembly_shutdown
|
||||
call system_shutdown
|
||||
|
||||
mov ax,4C03h
|
||||
int 21h
|
||||
|
||||
display_usage_information:
|
||||
|
||||
mov esi,_usage
|
||||
xor ecx,ecx
|
||||
call display_string
|
||||
|
||||
call system_shutdown
|
||||
|
||||
mov ax,4C01h
|
||||
int 21h
|
||||
|
||||
get_arguments:
|
||||
push ds
|
||||
mov ds,[psp_selector]
|
||||
mov esi,81h
|
||||
mov edi,command_line
|
||||
mov ecx,7Fh
|
||||
move_command_line:
|
||||
lodsb
|
||||
cmp al,0Dh
|
||||
je command_line_moved
|
||||
stosb
|
||||
loop move_command_line
|
||||
command_line_moved:
|
||||
pop ds
|
||||
xor eax,eax
|
||||
stosb
|
||||
mov [initial_commands],eax
|
||||
mov [source_path],eax
|
||||
mov [output_path],eax
|
||||
mov [no_logo],al
|
||||
mov [verbosity_level],eax
|
||||
mov [maximum_number_of_passes],100
|
||||
mov [maximum_number_of_errors],1
|
||||
mov [maximum_depth_of_stack],10000
|
||||
mov esi,command_line
|
||||
mov edi,parameters
|
||||
get_argument:
|
||||
xor ah,ah
|
||||
read_character:
|
||||
lodsb
|
||||
test al,al
|
||||
jz no_more_arguments
|
||||
cmp al,22h
|
||||
je switch_quote
|
||||
cmp ax,20h
|
||||
je end_argument
|
||||
stosb
|
||||
jmp read_character
|
||||
end_argument:
|
||||
xor al,al
|
||||
stosb
|
||||
find_next_argument:
|
||||
mov al,[esi]
|
||||
test al,al
|
||||
jz no_more_arguments
|
||||
cmp al,20h
|
||||
jne next_argument_found
|
||||
inc esi
|
||||
jmp find_next_argument
|
||||
switch_quote:
|
||||
xor ah,1
|
||||
jmp read_character
|
||||
next_argument_found:
|
||||
cmp al,'-'
|
||||
je get_option
|
||||
cmp al,'/'
|
||||
je get_option
|
||||
cmp [source_path],0
|
||||
je get_source_path
|
||||
cmp [output_path],0
|
||||
je get_output_path
|
||||
error_in_arguments:
|
||||
or al,-1
|
||||
retn
|
||||
get_source_path:
|
||||
mov [source_path],edi
|
||||
jmp get_argument
|
||||
get_output_path:
|
||||
mov [output_path],edi
|
||||
jmp get_argument
|
||||
no_more_arguments:
|
||||
cmp [source_path],0
|
||||
je error_in_arguments
|
||||
xor al,al
|
||||
stosb
|
||||
retn
|
||||
get_option:
|
||||
inc esi
|
||||
lodsb
|
||||
cmp al,'e'
|
||||
je set_errors_limit
|
||||
cmp al,'E'
|
||||
je set_errors_limit
|
||||
cmp al,'i'
|
||||
je insert_initial_command
|
||||
cmp al,'I'
|
||||
je insert_initial_command
|
||||
cmp al,'p'
|
||||
je set_passes_limit
|
||||
cmp al,'P'
|
||||
je set_passes_limit
|
||||
cmp al,'r'
|
||||
je set_recursion_limit
|
||||
cmp al,'R'
|
||||
je set_recursion_limit
|
||||
cmp al,'v'
|
||||
je set_verbose_mode
|
||||
cmp al,'V'
|
||||
je set_verbose_mode
|
||||
cmp al,'n'
|
||||
je set_no_logo
|
||||
cmp al,'N'
|
||||
jne error_in_arguments
|
||||
set_no_logo:
|
||||
or [no_logo],-1
|
||||
mov al,[esi]
|
||||
cmp al,20h
|
||||
je find_next_argument
|
||||
test al,al
|
||||
jnz error_in_arguments
|
||||
jmp find_next_argument
|
||||
set_verbose_mode:
|
||||
call get_option_value
|
||||
jc error_in_arguments
|
||||
cmp edx,2
|
||||
ja error_in_arguments
|
||||
mov [verbosity_level],edx
|
||||
jmp find_next_argument
|
||||
set_errors_limit:
|
||||
call get_option_value
|
||||
jc error_in_arguments
|
||||
test edx,edx
|
||||
jz error_in_arguments
|
||||
mov [maximum_number_of_errors],edx
|
||||
jmp find_next_argument
|
||||
set_recursion_limit:
|
||||
call get_option_value
|
||||
jc error_in_arguments
|
||||
test edx,edx
|
||||
jz error_in_arguments
|
||||
mov [maximum_depth_of_stack],edx
|
||||
jmp find_next_argument
|
||||
set_passes_limit:
|
||||
call get_option_value
|
||||
jc error_in_arguments
|
||||
test edx,edx
|
||||
jz error_in_arguments
|
||||
mov [maximum_number_of_passes],edx
|
||||
jmp find_next_argument
|
||||
get_option_value:
|
||||
xor eax,eax
|
||||
mov edx,eax
|
||||
find_option_value:
|
||||
cmp byte [esi],20h
|
||||
jne get_option_digit
|
||||
inc esi
|
||||
jmp find_option_value
|
||||
get_option_digit:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je option_value_ok
|
||||
test al,al
|
||||
jz option_value_ok
|
||||
sub al,30h
|
||||
jc invalid_option_value
|
||||
cmp al,9
|
||||
ja invalid_option_value
|
||||
imul edx,10
|
||||
jo invalid_option_value
|
||||
add edx,eax
|
||||
jc invalid_option_value
|
||||
jmp get_option_digit
|
||||
option_value_ok:
|
||||
dec esi
|
||||
clc
|
||||
ret
|
||||
invalid_option_value:
|
||||
stc
|
||||
ret
|
||||
insert_initial_command:
|
||||
push edi
|
||||
find_command_segment:
|
||||
cmp byte [esi],20h
|
||||
jne command_segment_found
|
||||
inc esi
|
||||
jmp find_command_segment
|
||||
command_segment_found:
|
||||
xor ah,ah
|
||||
cmp byte [esi],22h
|
||||
jne measure_command_segment
|
||||
inc esi
|
||||
inc ah
|
||||
measure_command_segment:
|
||||
mov ebx,esi
|
||||
scan_command_segment:
|
||||
mov ecx,esi
|
||||
mov al,[esi]
|
||||
test al,al
|
||||
jz command_segment_measured
|
||||
cmp ax,20h
|
||||
je command_segment_measured
|
||||
cmp ax,22h
|
||||
je command_segment_measured
|
||||
inc esi
|
||||
cmp al,22h
|
||||
jne scan_command_segment
|
||||
command_segment_measured:
|
||||
sub ecx,ebx
|
||||
mov edi,[initial_commands]
|
||||
lea eax,[ecx+2]
|
||||
test edi,edi
|
||||
jz allocate_initial_commands_buffer
|
||||
mov edx,[initial_commands_length]
|
||||
add edi,edx
|
||||
add eax,edx
|
||||
cmp eax,[initial_commands_maximum_length]
|
||||
ja grow_initial_commands_buffer
|
||||
copy_initial_command:
|
||||
xchg esi,ebx
|
||||
rep movsb
|
||||
mov esi,ebx
|
||||
sub edi,[initial_commands]
|
||||
mov [initial_commands_length],edi
|
||||
mov al,[esi]
|
||||
test al,al
|
||||
jz initial_command_ready
|
||||
cmp al,20h
|
||||
jne command_segment_found
|
||||
initial_command_ready:
|
||||
mov edi,[initial_commands]
|
||||
add edi,[initial_commands_length]
|
||||
mov ax,0Ah
|
||||
stosw
|
||||
inc [initial_commands_length]
|
||||
pop edi
|
||||
jmp find_next_argument
|
||||
allocate_initial_commands_buffer:
|
||||
push ecx
|
||||
mov ecx,eax
|
||||
call malloc
|
||||
mov [initial_commands],eax
|
||||
mov [initial_commands_maximum_length],ecx
|
||||
mov edi,eax
|
||||
pop ecx
|
||||
jmp copy_initial_command
|
||||
grow_initial_commands_buffer:
|
||||
push ecx
|
||||
mov ecx,eax
|
||||
mov eax,[initial_commands]
|
||||
call realloc
|
||||
mov [initial_commands],eax
|
||||
mov [initial_commands_maximum_length],ecx
|
||||
mov edi,eax
|
||||
add edi,[initial_commands_length]
|
||||
pop ecx
|
||||
jmp copy_initial_command
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '../malloc.inc'
|
||||
include '../assembler.inc'
|
||||
include '../symbols.inc'
|
||||
include '../expressions.inc'
|
||||
include '../conditions.inc'
|
||||
include '../floats.inc'
|
||||
include '../directives.inc'
|
||||
include '../calm.inc'
|
||||
include '../errors.inc'
|
||||
include '../map.inc'
|
||||
include '../reader.inc'
|
||||
include '../output.inc'
|
||||
include '../console.inc'
|
||||
|
||||
_logo db 'flat assembler version g.',VERSION,13,10,0
|
||||
|
||||
_usage db 'Usage: fasmg source [output]',13,10
|
||||
db 'Optional settings:',13,10
|
||||
db ' -e limit Set the maximum number of displayed errors (default 1)',13,10
|
||||
db ' -p limit Set the maximum allowed number of passes (default 100)',13,10
|
||||
db ' -r limit Set the maximum depth of the stack (default 10000)',13,10
|
||||
db ' -v flag Enable or disable showing all lines from the stack (default 0)',13,10
|
||||
db ' -i command Insert instruction at the beginning of source',13,10
|
||||
db ' -n Do not show logo nor summary',13,10
|
||||
db 0
|
||||
|
||||
_pass db ' pass, ',0
|
||||
_passes db ' passes, ',0
|
||||
_dot db '.'
|
||||
_seconds db ' seconds, ',0
|
||||
_byte db ' byte.',0
|
||||
_bytes db ' bytes.',0
|
||||
|
||||
_write_failed db 'failed to write the output file',0
|
||||
_out_of_memory db 'not enough memory to complete the assembly',0
|
||||
_code_cannot_be_generated db 'could not generate code within the allowed number of passes',0
|
||||
|
||||
include '../tables.inc'
|
||||
include '../messages.inc'
|
||||
|
||||
align 4
|
||||
|
||||
include '../variables.inc'
|
||||
|
||||
psp_selector dw ?
|
||||
main_selector dw ?
|
||||
|
||||
malloc_freelist dd ?
|
||||
|
||||
source_path dd ?
|
||||
output_path dd ?
|
||||
maximum_number_of_passes dd ?
|
||||
|
||||
initial_commands dd ?
|
||||
initial_commands_length dd ?
|
||||
initial_commands_maximum_length dd ?
|
||||
|
||||
timestamp dq ?
|
||||
|
||||
timer dd ?
|
||||
verbosity_level dd ?
|
||||
no_logo db ?
|
||||
|
||||
command_line db 80h dup ?
|
||||
parameters db 80h dup ?
|
||||
|
||||
segment buffer_segment
|
||||
|
||||
buffer = (buffer_segment-main) shl 4
|
||||
|
||||
db BUFFER_SIZE dup ?
|
||||
|
||||
segment stack_segment
|
||||
|
||||
stack_bottom = (stack_segment-main) shl 4
|
||||
|
||||
db STACK_SIZE dup ?
|
||||
|
||||
stack_top = stack_bottom + $
|
415
toolchain/fasm2/source/dos/system.inc
Normal file
415
toolchain/fasm2/source/dos/system.inc
Normal file
@ -0,0 +1,415 @@
|
||||
|
||||
LINE_FEED equ 13,10
|
||||
|
||||
system_init:
|
||||
cld
|
||||
mov [malloc_freelist],0
|
||||
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
|
||||
mov dword [timestamp],eax
|
||||
mov dword [timestamp+4],edx
|
||||
retn
|
||||
|
||||
system_shutdown:
|
||||
; call mcheck
|
||||
retn
|
||||
|
||||
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]
|
||||
retn
|
||||
|
||||
open:
|
||||
; in: edx - path to file
|
||||
; out: ebx = file handle, cf set on error
|
||||
; preserves: esi, edi
|
||||
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
|
||||
retn
|
||||
adapt_path:
|
||||
mov esi,edx
|
||||
mov edi,buffer
|
||||
copy_path:
|
||||
lodsb
|
||||
cmp al,'/'
|
||||
jne path_char_ok
|
||||
mov al,'\'
|
||||
path_char_ok:
|
||||
stosb
|
||||
cmp edi,buffer+BUFFER_SIZE
|
||||
jae out_of_memory
|
||||
test al,al
|
||||
jnz copy_path
|
||||
retn
|
||||
|
||||
create:
|
||||
; in: edx - path to file
|
||||
; out: ebx = file handle, cf set on error
|
||||
; preserves: esi, edi
|
||||
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
|
||||
retn
|
||||
|
||||
write:
|
||||
; in: ebx = file handle, edx - data, ecx = number of bytes
|
||||
; out: cf set on error
|
||||
; preserves: ebx, esi, edi
|
||||
push esi edi ebp
|
||||
mov ebp,ecx
|
||||
mov esi,edx
|
||||
write_loop:
|
||||
mov ecx,BUFFER_SIZE
|
||||
sub ebp,BUFFER_SIZE
|
||||
jnc do_write
|
||||
add ebp,BUFFER_SIZE
|
||||
mov ecx,ebp
|
||||
xor ebp,ebp
|
||||
do_write:
|
||||
push ecx
|
||||
mov edi,buffer
|
||||
rep movsb
|
||||
pop ecx
|
||||
mov ah,40h
|
||||
xor dx,dx
|
||||
call dos_int
|
||||
or ebp,ebp
|
||||
jnz write_loop
|
||||
pop ebp edi esi
|
||||
ret
|
||||
|
||||
read:
|
||||
; in: ebx = file handle, edx - buffer, ecx = number of bytes
|
||||
; out: cf set on error
|
||||
; preserves: ebx, esi, edi
|
||||
push esi edi ebp
|
||||
mov ebp,ecx
|
||||
mov edi,edx
|
||||
read_loop:
|
||||
mov ecx,BUFFER_SIZE
|
||||
sub ebp,BUFFER_SIZE
|
||||
jnc do_read
|
||||
add ebp,BUFFER_SIZE
|
||||
mov ecx,ebp
|
||||
xor ebp,ebp
|
||||
do_read:
|
||||
push ecx
|
||||
mov ah,3Fh
|
||||
xor dx,dx
|
||||
call dos_int
|
||||
cmp ax,cx
|
||||
jne read_eof
|
||||
mov esi,buffer
|
||||
pop ecx
|
||||
rep movsb
|
||||
or ebp,ebp
|
||||
jnz read_loop
|
||||
read_done:
|
||||
pop ebp edi esi
|
||||
ret
|
||||
read_eof:
|
||||
pop ecx
|
||||
stc
|
||||
jmp read_done
|
||||
|
||||
close:
|
||||
; in: ebx = file handle
|
||||
; preserves: ebx, esi, edi
|
||||
mov ah,3Eh
|
||||
int 21h
|
||||
ret
|
||||
|
||||
lseek:
|
||||
; in: ebx = file handle, cl = method, edx:eax = offset
|
||||
; out: edx:eax = new offset from the beginning of file, cf set on error
|
||||
; preserves: ebx, esi, edi
|
||||
mov dx,ax
|
||||
xchg ecx,eax
|
||||
shr ecx,16
|
||||
mov ah,42h
|
||||
int 21h
|
||||
pushf
|
||||
shl edx,16
|
||||
popf
|
||||
mov dx,ax
|
||||
mov eax,edx
|
||||
xor edx,edx
|
||||
ret
|
||||
|
||||
get_timestamp:
|
||||
; out: edx:eax = timestamp
|
||||
; preserves: ebx, ecx, esi, edi
|
||||
; note: during the passes of a single assembly this function should always return the same value
|
||||
mov eax,dword [timestamp]
|
||||
mov edx,dword [timestamp+4]
|
||||
retn
|
||||
|
||||
display_string:
|
||||
; in:
|
||||
; esi - string
|
||||
; ecx = string length, zero for ASCIIZ string
|
||||
; preserves: ebx, esi
|
||||
push ebx
|
||||
mov ebx,1
|
||||
jmp write_string
|
||||
display_error_string:
|
||||
; in:
|
||||
; esi - string
|
||||
; ecx = string length, zero for ASCIIZ string
|
||||
; preserves: ebx, esi
|
||||
push ebx
|
||||
mov ebx,2
|
||||
write_string:
|
||||
test ecx,ecx
|
||||
jnz string_length_ok
|
||||
xor al,al
|
||||
mov edi,esi
|
||||
or ecx,-1
|
||||
repne scasb
|
||||
neg ecx
|
||||
sub ecx,2
|
||||
string_length_ok:
|
||||
mov edx,esi
|
||||
call write
|
||||
pop ebx
|
||||
retn
|
||||
|
||||
get_environment_variable:
|
||||
; in:
|
||||
; esi - name
|
||||
; edi - buffer for value
|
||||
; ecx = size of buffer
|
||||
; out:
|
||||
; eax = length of value
|
||||
; preserves: ebx, esi, edi
|
||||
push ebx esi edi
|
||||
mov ebx,esi
|
||||
xor esi,esi
|
||||
compare_variable_names:
|
||||
mov edx,ebx
|
||||
compare_name_character:
|
||||
lods byte [gs:esi]
|
||||
mov ah,[edx]
|
||||
inc edx
|
||||
cmp al,'='
|
||||
je end_of_variable_name
|
||||
test ah,ah
|
||||
jz next_variable
|
||||
sub ah,al
|
||||
jz compare_name_character
|
||||
cmp ah,20h
|
||||
jne next_variable
|
||||
cmp al,41h
|
||||
jb next_variable
|
||||
cmp al,5Ah
|
||||
jna compare_name_character
|
||||
next_variable:
|
||||
lods byte [gs:esi]
|
||||
test al,al
|
||||
jnz next_variable
|
||||
cmp byte [gs:esi],0
|
||||
jne compare_variable_names
|
||||
mov ah,al
|
||||
end_of_variable_name:
|
||||
test ah,ah
|
||||
jnz next_variable
|
||||
add ecx,edi
|
||||
mov edx,esi
|
||||
copy_variable_value:
|
||||
lods byte [gs:esi]
|
||||
cmp edi,ecx
|
||||
jae variable_value_next_character
|
||||
stosb
|
||||
variable_value_next_character:
|
||||
or al,al
|
||||
jnz copy_variable_value
|
||||
lea eax,[esi-1]
|
||||
sub eax,edx
|
||||
pop edi esi ebx
|
||||
ret
|
||||
|
||||
VALLOC_MIN = 40000h
|
||||
|
||||
valloc:
|
||||
; in: ecx = requested minimum size
|
||||
; out: eax - allocated block, ecx = allocated size, zero if failed
|
||||
; preserves: ebx, esi, edi
|
||||
cmp ecx,VALLOC_MIN
|
||||
jbe valloc_size_minimum
|
||||
dec ecx
|
||||
and ecx,(-1) shl 12
|
||||
add ecx,1 shl 12
|
||||
jmp valloc_size_ready
|
||||
valloc_size_minimum:
|
||||
mov ecx,VALLOC_MIN
|
||||
valloc_size_ready:
|
||||
push ebx esi edi
|
||||
push ecx
|
||||
mov ebx,ecx
|
||||
shr ebx,16
|
||||
mov ax,501h
|
||||
int 31h
|
||||
movzx eax,cx
|
||||
pop ecx
|
||||
jc valloc_failed
|
||||
shl ebx,16
|
||||
or eax,ebx
|
||||
mov edx,main
|
||||
shl edx,4
|
||||
sub eax,edx
|
||||
pop edi esi ebx
|
||||
ret
|
||||
valloc_failed:
|
||||
xor ecx,ecx
|
||||
pop edi esi ebx
|
||||
retn
|
Reference in New Issue
Block a user