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