include "macros.inc" ; ; OS function implementation ; SmallC for KolibriOS ; ;B+ General definitions ;B+ File defs ;const ;param BAD equ -1 files equ 100 save_buffer equ 0x20000 ;32 save_buffer_w equ 0x400000 ;32 save_file_name equ 0x20000 ;system EOF equ -1 ;memory fileinfo equ I_END start_data equ (fileinfo+16384) ; mem_heap equ 0x100000 ; g_handle equ 0x300000 ;dword - pointer - relative to file ;dword - begin of file ;dword - file size ;dword - 0/1 <=> read/write ;E:. ;E:. init_osfunc: ;B+ Init OS functions ;B+ Clear file handles mov edi,g_handle mov ecx,files shl ecx,2 ;*4 xor eax,eax cld rep stosd ;E:. ret ;E:. ;B+ Main OS functions ppp dd 70 _OS_fopen: ;B+ Implement "fopen" ;esp+4 - mode ;esp+8 - file name ; mov eax,-1 ; int 0x40 ; mov ebx,[esp+8]; ; push dword 10 ; push dword [ppp] ; push ebx ; push dword 12 ; call _outstrg ; add esp,4*4 ; add [ppp],10 ; cmp byte [ebx+8],0 ; jne .l ; mov byte [ebx+8],'?' ;.l: ; cmp [ppp],80 ; je .l mov ecx , [esp+4] ; file mode mov [file_mode],ecx ;B+ Copy file name mov esi,[esp+8] mov edi,[p_filename] mov ecx,12 .next_copy: lodsb ;fill name (space) or al,al jz .fill_space ;set upper case cmp al,'a' jb .good_char cmp al,'z' ja .good_char add al,'A'-'a' .good_char: stosb dec ecx jnz .next_copy .fill_space: mov al,' ' cld rep stosb mov eax,[file_mode] cmp byte [eax],'w' jne .no_wri ;B+ Copy file name mov esi,[esp+8] mov edi,[w_file_name] mov ecx,12 .next_copy2: lodsb ;fill name (space) or al,al jz .fill_space2 ;set upper case cmp al,'a' jb .good_char2 cmp al,'z' ja .good_char2 add al,'A'-'a' .good_char2: stosb dec ecx jnz .next_copy2 .fill_space2: ;mov al,' ' ;cld rep stosb .no_wri: ;E:. ;B+ Find file handle mov eax,g_handle .new_handle: cmp dword [eax+4],0 je .find_place add eax,16 cmp eax,g_handle+files*16-16 jne .new_handle xor eax,eax ; no free handle ret .find_place: ; TMP: mov eax,[.ccc] ; TMP: add [.ccc],16 ;E:. push eax ;B+ Test open mode mov eax,[esp+4+4] cmp byte [eax],'r' je .open_read cmp byte [eax],'w' je .open_write ;bad mode add esp,4 mov eax,eax ; invalid open mode ret ;E:. ; TMP:.ccc dd g_handle .open_read: ;B+ Open for read ;B+ Read file ;Wait to read correct mov ebx,100 mov eax,5 int 0x40 mov eax,[g_fileend] mov dword [file_parameters+2*4],2000 ;read all mov dword [file_parameters+3*4],eax mov dword [file_parameters],0 mov ebx,file_parameters mov eax,58 int 0x40 ;E:. ;B+ TEST FILE FOUND or eax,eax jz .file_found cmp eax,5 je .file_found ; mov ecx,eax ; eax ; mov ebx,8 shl 16 + 0x0100 ; mov edx,100 shl 16 + 120 ; mov esi,0xffffff ; mov eax,47 ; int 0x40 ;file not found - return 0 add esp,4 xor eax,eax ret .file_found: ;E:. pop eax push ebx xchg eax,ebx ;B+ Fill file handle ;save current pointer xor eax,eax mov [ebx],eax ;save file begin mov eax,[g_fileend] mov [ebx+4],eax ;save file size pop eax mov [ebx+8],eax ;reserve file zone add eax,7 and eax,not 7 add [g_fileend],eax ;save file mode mov eax,0 ;read mov [ebx+12],eax ;E:. xchg eax,ebx ;return pointer place ret ;E:. .open_write: ;B+ Open for write ;B+ Reserve filename ; p_filename -> w_file_name ;pusha ; mov eax, w_file_name ; mov ebx, [p_filename] ;.ncpy: ; mov ch, byte [ebx] ; cmp ch, 0 ; je .ecpy ; mov [eax], ch ; inc dword [eax] ; inc dword [ebx] ;jmp .ncpy ; ;.ecpy: ; ;popa mov [save_buffer_p], save_buffer_w mov esi,[p_filename] mov edi,[g_fileend] mov ecx,12 cld rep movsb add [g_fileend],16 ;E:. pop ebx ;B+ Fill file handle ;save begin pointer xor eax,eax mov [ebx],eax ;save file begin mov eax,[g_fileend] mov [ebx+4],eax ;save file zone mov dword [ebx+8],save_buffer ;reserve file zone add [g_fileend],save_buffer ;save file mode mov eax,1 ;write mov [ebx+12],eax ;E:. xchg eax,ebx ;return pointer place ret ;E:. ;E:. _OS_fclos: ;B+ Close file ;esp+4 - file handle ;B+ Test write mode - save file mov eax,[esp+4] mov eax,[eax+12] cmp eax,1 ;E:. jne .no_write mov eax, [esp+4] mov ecx, [eax] mov ebx, [eax+8] mov ebx, [save_buffer_p] sub ebx, save_buffer_w ; ebx = number of read bytes = file size ; save loaded file mov [dest_info.bytes],ebx ; file size in bytes mov [dest_info.bytes+4], save_buffer_w ;mov eax, [p_filename];[w_file_name] ;mov [destination],eax mov eax,70 mov ebx,dest_info mcall ; check if 58 function failed test eax,eax je .ok_write add eax,7 ; error number += 7 cmp eax,6+7 jna .copy_error mov eax,7+7 jmp .copy_error .copy_error: .ok_write: ;E:. jmp .read .no_write: ;B+ Test read mode - if no error end cmp eax,0 je .read mov eax,BAD ret ;E:. .read: ;B+ Relace memory ;find file size mov eax,[esp+4] mov ecx,[eax+8] add ecx,7 and ecx,not 7 push ecx ;mov memory mov esi,[eax+4] mov edi,esi add esi,ecx mov ecx,[g_fileend] sub ecx,edi jz .is_last shr ecx,2 inc ecx ;not neccessery cld rep movsd ;update gl. memory .is_last: pop ecx sub dword [g_fileend],ecx ;update file pointers mov edx,ecx mov ecx,[eax+4] mov eax,g_handle .new_handle1: mov ebx,[eax+4] cmp ebx,ecx jbe .no_update sub ebx,edx mov [eax+4],ebx .no_update: add eax,16 cmp eax,g_handle+files*16 jne .new_handle1 ;clear handle mov edi,[esp+4] xor eax,eax cld stosd stosd stosd stosd ;E:. ret ;E:. _OS_fgetc: ;B+ Load char from file ;esp+4 - input file mov eax,[esp+4] mov ebx,[eax] cmp ebx,[eax+8] je .eof inc dword [eax] add ebx,[eax+4] movzx eax,byte [ebx] ret .eof: mov eax,EOF ret ;E:. ;rrr db 'g',0 _OS_fputc: ;B+ Save char to file ;esp+4 - output file ;esp+8 - char to write ;push dword '<' ;mov cl,1 ;push dword 0 ;call test_outch ;add esp,8 ;B+ Temp - write direct. cmp dword [esp+4],__iob jne .real_write0 jmp _OS_exit .real_write0: cmp dword [esp+4],__iob+32 jne .real_write1 mov [print_textcolor],0x00ffff jmp test_outch .real_write1: cmp dword [esp+4],__iob+64 jne .real_write2 mov [print_textcolor],0x77ffff jmp test_outch .real_write2: ;E:. mov ebx,[save_buffer_p] mov eax,[esp+8] mov [ebx],eax inc dword [save_buffer_p] ret ;push dword '<' ;mov cl,1 ;push dword 0 ;call test_outch ;add esp,8 mov eax,[esp+4] mov ebx,[eax] push ebx cmp ebx,[eax+8] jne .write_normal ;B+ Alloc save_buffer bytes ;mov memory mov ebx,[esp+4+4] mov esi,[g_fileend] mov edi,esi add edi,save_buffer-4 mov ecx,esi sub ecx,[ebx+4] sub ecx,[ebx+8] shr ecx,2 jz .is_last sub esi,4 std rep movsd .is_last: ;expand file size add dword [eax+8],save_buffer ;update file pointers mov ebx,g_handle .new_handle: mov ecx,[ebx+4] cmp [eax+4],ecx jae .no_update add dword [ebx+4],save_buffer .no_update: add ebx,16 cmp ebx,g_handle+files*16-16 jne .new_handle ;E:. .write_normal: pop ebx inc dword [eax] add ebx,[eax+4] mov cl,[esp+8] mov byte [ebx],cl ;sub [test_outch.x_coord],2 ; ;push dword '>' ;mov cl,1 ;push dword 0 ;call test_outch ;add esp,8 ; ;sub [test_outch.x_coord],6 xor eax,eax ret ;E:. _OS_callo: ;B+ Alloc memory ;find all size mov eax,[esp+4] mov ebx,[esp+8] mul ebx push eax ;clear memory mov edi,[.mem_p] xor eax,eax mov ecx,[esp] cld rep stosb ;update new memory pointer pop ebx push dword [.mem_p] add ebx,7 and ebx,not 7 add [.mem_p],ebx ;return value pop eax ret .mem_p dd mem_heap ;E:. _OS_exit: ;B+ Exit program ; ;TMP ; mov eax,-1 ; int 0x40 mov esp,[exit_esp] sub esp,4 ret ;E:. ;E:. ;B+ Test procedures ;B+ Definitions LEFTMARGIN equ 11 BEGIN_CHARS equ 20 NL equ 10 ;E:. print_textcolor dd 0x00ffff _file_beg: ;B+ Show begin of file - test fopen ;esp+4 - file handle (descriptor) mov eax,[esp+4] mov ebx,10 shl 16 + 30 mov ecx,[print_textcolor] mov edx,[eax+4] mov esi,BEGIN_CHARS mov eax,4 int 0x40 ret ;E:. _outstrg: ;B+ Draw black text - test function call ;esp+4*4 - x ;esp+4*3 - y ;esp+4*2 - *c ;esp+4*1 - len mov ebx,[esp+4*4] shl ebx,16 mov bx,[esp+4*3] mov ecx,[print_textcolor] mov edx,[esp+4*2] mov esi,[esp+4] mov eax,4 int 0x40 ret ;E:. test_outch: ;B+ Draw one char - use as _OS_fputc, to test printf(...) ;esp+8 - char to write ;this is test! \b \r - not nesessary mov al,[esp+8] cmp al,NL jne .no_newline add [.y_coord],10 mov [.x_coord],LEFTMARGIN ret .no_newline: mov ebx,[.x_coord] shl ebx,16 mov bx,word [.y_coord] mov ecx,[print_textcolor] mov [.out_char],al mov edx,.out_char mov esi,1 mov eax,4 int 0x40 add [.x_coord],6 ;mov eax,5 ;mov ebx,5 ;int 0x40 ret .x_coord dd LEFTMARGIN .y_coord dd 60 .out_char db 0 ;E:. ;E:. ;B+ Data section ;B+ Memory managment g_fileend dd g_handle+files*4*4 ;from 2MB+100*4*4 ;w_buff dd ;E:. save_buffer_p dd save_buffer_w ;B+ File parameters file_parameters: dd 0x0 ; mode dd 0x0 ; first block dd 1000 ; block read dd -1 ; return place dd fileinfo ; work area filepath: times 100 db 0 file_mode dd 0 ;file mode dest_info: ; DESTINATION FILEINFO dd 2 dd 0 dd 0 .bytes dd ? dd save_buffer db 0 destination: dd save_file_name ;db "EXAMPLE.ASM",0 w_file_name dd save_file_name p_filename dd 0x0 ;E:. ;E:. ;TO DO mov eax,-1 int 0x40 ;TO DO