/programs/develop/metcc/trunk/libc/file/fclose.c |
---|
1,11 → 1,9 |
#include "stdio.h" |
#include "string.h" |
int fclose(FILE* file) |
#include <stdio.h> |
#include <string.h> |
#include <stdlib.h> |
void fclose(FILE* file) |
{ |
int res; |
res=_msys_write_file(file->filename, 0, file->filesize, file->buffer); |
free(file->buffer); |
free(file->filename); |
free(file); |
return res; |
} |
/programs/develop/metcc/trunk/libc/file/feof.c |
---|
1,4 → 1,4 |
#include "stdio.h" |
#include <stdio.h> |
int feof(FILE* file) |
{ |
return file->filepos>=file->filesize; |
/programs/develop/metcc/trunk/libc/file/fflush.c |
---|
1,7 → 1,7 |
#include "stdio.h" |
#include <stdio.h> |
int fflush(FILE* file) |
{ |
if ((file->mode & 3)==FILE_OPEN_READ) |
return 0; |
return _msys_file_write(file->filename, 0, file->filesize, file->buffer) ? EOF : 0; |
return(EOF); |
} |
/programs/develop/metcc/trunk/libc/file/fgetc.c |
---|
1,12 → 1,22 |
#include "stdio.h" |
#include <stdio.h> |
int fgetc(FILE* file) |
{ |
if ((file->mode & 3!=FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0)) |
return EOF; |
dword res; |
if ((file->mode & 3!=FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0)) return EOF; |
if (file->filepos>=file->filesize) |
{ |
return EOF; |
} |
else |
{ |
return (int)file->buffer[file->filepos++]; |
res=_ksys_readfile(file->filename,file->filepos,1,file->buffer); |
if (res==0) |
{ |
file->filepos++; |
return (int)file->buffer[0]; |
} |
else return(res); |
} |
} |
/programs/develop/metcc/trunk/libc/file/fopen.c |
---|
1,56 → 1,95 |
#include <stdio.h> |
#include <string.h> |
#include <stdlib.h> |
extern char __argv; |
extern char __path; |
extern struct{int argc; char** argv;} __ARGS; |
char* getfullpath(const char *path){ |
char* getfullpath(const char* relpath){ |
byte prev_is_slash=0; |
int len=0, depth=0, i; |
char* buff; |
buff = malloc(strlen(__ARGS.argv[0]) + strlen(relpath)); |
if(*relpath == '/') buff[0] = '\0'; |
else { |
len = strrchr(__ARGS.argv[0], '/') - __ARGS.argv[0] + 1; |
strncpy(buff, __ARGS.argv[0], len); |
prev_is_slash = 1; |
buff[len] = 0; |
for(i=0; buff[i]; i++) |
if(buff[i] == '/' && i < len-1) depth++; |
} |
for (; *relpath; relpath++){ |
switch (*relpath){ |
case '/': |
prev_is_slash = 1; |
buff[len++] = '/'; |
int i,j,relpath_pos,localpath_size; |
int filename_size; |
char local_path; |
char *programpath; |
char *newpath; |
i=0; |
local_path=1; //enable local path |
while((*(path+i)!='\0') || (*(path+i)!=0)) |
{ |
if (*(path+i)=='.') |
{ |
if (*(path+i+1)=='/') |
{ //detected relative path |
relpath_pos=i+2; |
local_path=0; |
break; |
case '.': |
if(*(relpath+1) == '.' && *(relpath+2) == '/' && prev_is_slash){ |
if(!depth) return 0; |
buff[len-1] = 0; |
len = strrchr(buff, '/') + 1 - buff; |
buff[len] = 0; |
depth--; |
relpath += 2; |
} else { |
depth++; |
buff[len++] = '.'; |
} |
break; |
default: |
if(prev_is_slash){ |
depth++; |
prev_is_slash = 0; |
} |
buff[len++] = *relpath; |
break; |
if (*(path+i)=='/') |
{ //disabple local path |
local_path=0; |
return(path); |
} |
i++; |
} |
buff[len]= '\0'; |
return buff; |
filename_size=i; |
programpath=&__path; |
if (local_path==1) |
{ |
i=0x400; |
//find local path of program |
while(*(programpath+i)!='/') |
{ |
i--; |
} |
localpath_size=i; |
newpath=malloc(0x400); |
//copy local path to the new path |
for(i=0;i<=localpath_size;i++) |
{ |
*(newpath+i)=*(programpath+i); |
} |
//copy filename to the new path |
for(i=0;i<filename_size;i++) |
{ |
*(newpath+localpath_size+1+i)=*(path+i); |
} |
return(newpath); |
} |
//if we here than path is a relative |
i=0x400; |
//find local path of program |
while(*(programpath+i)!='/') |
{ |
i--; |
} |
localpath_size=i; |
i=0; |
//find file name size |
while((*(path+relpath_pos+i)!='\0') || (*(path+relpath_pos+i)!=0)) |
{ |
i++; |
} |
filename_size=i; |
newpath=malloc(0x400); |
//copy local path to the new path |
for(i=0;i<=localpath_size;i++) |
{ |
*(newpath+i)=*(programpath+i); |
} |
//copy filename to the new path |
for(i=0;i<filename_size;i++) |
{ |
*(newpath+localpath_size+1+i)=*(path+relpath_pos+i); |
} |
return(newpath); |
} |
FILE* fopen(const char* filename, const char *mode) |
{ |
FILE* res; |
84,59 → 123,16 |
if (*mode!=0) |
return 0; |
res=malloc(sizeof(FILE)); |
res->buffer=0; |
res->buffersize=0; |
res->buffer=malloc(256); |
res->buffersize=256; |
res->filesize=0; |
res->filepos=0; |
res->mode=imode; |
res->filename=getfullpath(filename); |
//check if file exists |
res=_msys_read_file(res->filename, 0, 0, 0, &res->filesize); |
if (res==5) |
if ((imode==FILE_OPEN_READ) || (imode==FILE_OPEN_APPEND)) |
{ |
if ((imode & 3) == FILE_OPEN_READ) |
{ |
free(res->filename); |
free(res); |
return 0; |
res->filesize=_ksys_get_filesize(res->filename); |
} |
res=_msys_create_file(res->filename); |
if (res!=0) |
{ |
free(res->filename); |
free(res); |
return 0; |
} |
res->filesize=0; |
} |
if (imode & 3==FILE_OPEN_WRITE) |
{ |
res->buffersize=512; |
res->buffer=malloc(res->buffersize); |
if (res->buffer=0) |
{ |
free(res->filename); |
free(res); |
return 0; |
} |
res->filesize=0; |
}else |
{ |
res->buffersize=(res->filesize & (~511))+512; |
res->buffer=malloc(res->buffersize); |
if (res->buffer==0) |
{ |
free(res); |
return 0; |
} |
res=_msys_read_file(res->filename,0,res->filesize,res->buffer,0); |
if (res!=0) |
{ |
free(res->buffer); |
free(res); |
} |
if (imode & 3==FILE_OPEN_APPEND) |
res->filepos=res->filesize; |
} |
return res; |
} |
/programs/develop/metcc/trunk/libc/file/fputc.c |
---|
1,24 → 1,35 |
#include "stdio.h" |
int fputc(int c,FILE* file) |
{ |
void* p; |
if ((file->mode & 3)==FILE_OPEN_READ) |
return EOF; |
dword res; |
if ((file->mode & 3)==FILE_OPEN_READ) return EOF; |
file->buffer[0]=c; |
if ((file->mode & 3)==FILE_OPEN_APPEND) |
{ |
file->filepos=file->filesize; |
if (file->filepos==file->filesize) |
{ |
file->filesize++; |
if (file->filesize>file->buffersize) |
res=_ksys_appendtofile(file->filename,file->filepos,1,file->buffer); |
if (res!=0) return(res); |
file->filepos++; |
return(0); |
} |
if ((file->mode & 3)==FILE_OPEN_WRITE) |
{ |
p=realloc(file->buffer,file->filesize+file->filesize<<1); |
if (p==0) |
return EOF; |
file->buffersize=file->filesize+file->filesize<<1; |
file->buffer=p; |
if (file->filepos==0) |
{ //file not craeted |
res=_ksys_rewritefile(file->filename,1,file->buffer); |
if (res!=0) return(res); |
file->filepos++; |
return 0; |
} |
} |
file->buffer[file->filepos]=(char)c; |
else |
{ //file craeted and need append one byte |
res=_ksys_appendtofile(file->filename,file->filepos,1,file->buffer); |
if (res!=0) return(res); |
file->filepos++; |
return 0; |
} |
} |
} |
/programs/develop/metcc/trunk/libc/file/fread.c |
---|
1,12 → 1,25 |
#include "stdio.h" |
#include <stdio.h> |
#include <mesys.h> |
int fread(void* buffer,int size,int count,FILE* file) |
{ |
if ((file->mode & 3!=FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0)) |
return 0; |
count=count*size; |
if (count+file->filepos>file->filesize) |
count=file->filesize-file->filepos; |
memcpy(buffer,file->buffer+file->filepos,count); |
file->filepos+=count; |
return count/size; |
dword res; |
dword fullsize; |
if ((file->mode & 3!=FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0)) return 0; |
fullsize=count*size; |
if ((fullsize+file->filepos)>(file->filesize)) |
{ |
fullsize=file->filesize-file->filepos; |
if (fullsize<=0) return(0); |
} |
res=_ksys_readfile(file->filename,file->filepos,fullsize,buffer); |
if (res==0) |
{ |
file->filepos=file->filepos+fullsize; |
fullsize=fullsize/size; |
return(fullsize); |
} |
else return 0; |
} |
/programs/develop/metcc/trunk/libc/file/fwrite.c |
---|
1,23 → 1,57 |
#include "stdio.h" |
int fwrite(const void* buffer,int size,int count,FILE* file) |
#include <stdio.h> |
#include <mesys.h> |
int fwrite(void *buffer,int size,int count,FILE* file) |
{ |
void* p; |
if ((file->mode & 3==FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0)) |
return 0; |
dword res; |
dword fullsize; |
if ((file->mode & 3==FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0)) return 0; |
if (file->mode & 3==FILE_OPEN_APPEND) |
file->filepos=file->filesize; |
count=count*size; |
if (file->buffersize<file->filepos+count) |
fullsize=count*size; |
if ((file->filesize)<(file->filepos+fullsize)) file->filesize=file->filepos+fullsize; |
if (file->mode & 3==FILE_OPEN_APPEND) |
{ |
p=realloc(file->buffer,(file->filepos+count)+(file->filepos+count)<<1); |
if (p==0) |
return 0; |
file->buffer=p; |
file->buffersize=(file->filepos+count)+(file->filepos+count)<<1; |
file->filepos==file->filesize; |
res=_ksys_appendtofile(file->filename,file->filepos,fullsize,buffer); |
if (res==0) |
{ |
file->filepos+=fullsize; |
fullsize=fullsize/size; |
return(fullsize); |
} |
if (file->filesize<file->filepos+count) |
file->filesize=file->filepos+count; |
memcpy(file->buffer+file->filepos,buffer,count); |
file->filepos+=count; |
return count; |
else return(0); |
} |
if (file->mode & 3==FILE_OPEN_WRITE) |
{ |
if (file->filepos==0) |
{ //file mot craeted yet |
res=_ksys_rewritefile(file->filename,fullsize,buffer); |
if (res==0) |
{ |
file->filepos+=fullsize; |
fullsize=fullsize/count; |
return(fullsize); |
} |
else return(0); |
} |
else |
{ |
res=_ksys_appendtofile(file->filename,file->filepos,fullsize,buffer); |
if (res==0) |
{ |
file->filepos+=fullsize; |
fullsize=fullsize/count; |
return(fullsize); |
} |
else return(0); |
} |
} |
else return(0); |
} |
/programs/develop/metcc/trunk/libc/file/ungetc.c |
---|
1,11 → 1,17 |
#include "stdio.h" |
int ungetc(int c,FILE* file) |
{ |
dword res; |
if (c==EOF) |
return EOF; |
if (file->filepos<=0 || file->filepos>file->filesize) |
return EOF; |
file->filepos--; |
file->buffer[file->filepos]=(char)c; |
return c; |
res=_ksys_readfile(file->filename,file->filepos,1,file->buffer); |
if (res==0) |
{ |
return(c); |
} |
else return(EOF); |
} |
/programs/develop/metcc/trunk/libc/mem/memalloc.asm |
---|
1,536 → 1,41 |
format ELF |
include "proc32.inc" |
section '.text' executable |
public malloc |
public free |
public realloc |
public mf_init |
;multithread: ;uncomment this for thread-safe version |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; Memory allocator for MenuetOS ;; |
;; Halyavin Andrey halyavin@land.ru, 2006 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; allocated mem block structure ;; |
;; +0: bit 0 - used flag ;; |
;; bits 31..1 - block size ;; |
;; +4: address of prev block ;; |
;; +8 .. +(blocksize) - allocated memory ;; |
;; +(blocksize) - next block ;; |
;; ;; |
;; free mem block structure ;; |
;; +0: bit 0 - used flag ;; |
;; bits 31..1 - block size ;; |
;; +4: address of prev block ;; |
;; +8: prev free block ;; |
;; +12: next free block ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
memblock.size=0 |
memblock.prevblock=4 |
memblock.prevfreeblock=8 |
memblock.nextfreeblock=12 |
align 4 |
proc malloc stdcall, size:dword |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; mf_init ;; |
;; Initialize memory map for dynamic use ;; |
;; input: eax: starting address or 0 ;; |
;; output: none ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
mf_init: |
push ebx |
push ecx |
test eax,eax |
jnz .noautodet |
sub esp,1024 |
mov ebx,esp |
mov ecx,-1 |
mov eax,9 |
mov eax,68 |
mov ebx,12 |
mov ecx,[size] |
int 0x40 |
mov eax,[esp+26] |
add esp,1024 |
.noautodet: |
add eax,15 |
and eax,not 15 |
mov [heapsmallblocks],eax |
add eax,2048 |
mov [heapstart],eax |
mov [heapfreelist],eax |
mov [heaplastblock],eax |
mov ecx,eax |
if defined heapstartsize |
add ecx,heapstartsize |
else |
add ecx,4096 |
end if |
add ecx,4095 |
and ecx,not 4095 |
push eax |
mov eax,64 |
mov ebx,1 |
int 0x40 |
pop eax |
mov [eax+memblock.prevblock],dword 0 |
mov [heapend],ecx |
mov [eax+memblock.size],ecx |
sub [eax+memblock.size],eax |
xor ebx,ebx |
mov dword [eax+memblock.prevfreeblock],heapfreelist-memblock.nextfreeblock |
mov [eax+memblock.nextfreeblock],ebx |
mov [heapmutex],ebx |
push edi |
mov edi,[heapsmallblocks] |
mov ecx,512 |
xor eax,eax |
rep stosd |
pop edi |
pop ecx |
pop ebx |
ret |
endp |
if defined multithread |
heaplock: |
push eax |
push ebx |
push ecx |
align 4 |
proc free stdcall, pointer:dword |
mov eax,68 |
mov ebx,1 |
.loop: |
xchg ecx,[heapmutex] |
test ecx,ecx |
jz .endloop |
int 0x40 ;change task |
jmp .loop |
.endloop: |
pop ecx |
pop ebx |
pop eax |
ret |
mov ebx,13 |
mov ecx,[pointer] |
int 0x40 |
heapunlock: |
mov [heapmutex],dword 0 |
ret |
end if |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; heap_split_block ;; |
;; Split free block to allocated block and free one. ;; |
;; input: ;; |
;; eax - size of allocated block ;; |
;; ebx - block ;; |
;; output: ;; |
;; eax - real size of allocated block ;; |
;; ebx - pointer to new block ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
heap_split_block: |
push ecx |
mov ecx,[ebx+memblock.size] |
sub ecx,16 |
cmp ecx,eax |
jge .norm |
inc dword [ebx+memblock.size] |
mov eax,ecx |
xor ebx,ebx |
pop ecx |
ret |
.norm: |
add ecx,16 |
mov [ebx+memblock.size],eax |
inc dword [ebx+memblock.size] |
mov [ebx+eax+memblock.prevblock],ebx |
add ebx,eax |
sub ecx,eax |
mov [ebx+memblock.size],ecx |
mov ecx,eax |
mov eax,ebx |
call heap_fix_right |
mov eax,ecx |
pop ecx |
ret |
align 4 |
proc realloc stdcall, pointer:dword, size:dword |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; heap_add_free_block ;; |
;; Add free block to one of free block lists. ;; |
;; input: ;; |
;; eax - address of free block ;; |
;; output: ;; |
;; none ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
heap_add_free_block: |
cmp dword [eax+memblock.size],4096 |
push ebx |
jge .bigblock |
mov ebx,[eax+memblock.size] |
shr ebx,1 |
add ebx,[heapsmallblocks] |
push dword [ebx] |
pop dword [eax+memblock.nextfreeblock] |
mov [ebx],eax |
mov dword [eax+memblock.prevfreeblock],ebx |
sub dword [eax+memblock.prevfreeblock],memblock.nextfreeblock |
mov ebx,[eax+memblock.nextfreeblock] |
test ebx,ebx |
jz .no_next_block |
mov [ebx+memblock.prevfreeblock],eax |
.no_next_block: |
pop ebx |
ret |
.bigblock: |
mov ebx,[heapfreelist] |
mov [eax+memblock.nextfreeblock],ebx |
mov [heapfreelist],eax |
mov dword [eax+memblock.prevfreeblock],heapfreelist-memblock.nextfreeblock |
; mov ebx,[eax+memblock.nextfreeblock] |
test ebx,ebx |
jz .no_next_big_block |
mov [ebx+memblock.prevfreeblock],eax |
.no_next_big_block: |
pop ebx |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; heap_remove_block ;; |
;; Remove free block from the list of free blocks. ;; |
;; input: ;; |
;; eax - free block ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
heap_remove_block: |
push ebx |
push ecx |
mov ecx,[eax+memblock.prevfreeblock] |
mov ebx,[eax+memblock.nextfreeblock] |
mov [ecx+memblock.nextfreeblock],ebx |
test ebx,ebx |
jz .no_next_block |
mov [ebx+memblock.prevfreeblock],ecx |
.no_next_block: |
pop ecx |
pop ebx |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; mf_alloc |
;; allocates a block of memory in heap |
;; intput: eax: size of block |
;; output: eax: address of allocated memory block or 0 if there's no mem. |
;; allocator will not create new nodes that contain less that 8b of space, |
;; and minimal allocation is actually 16 bytes - 8 for node and 8 for user. |
;; allocator will never create non-aligned memory blocks. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
mf_alloc: |
test eax,eax |
jg .not_null ; test that we are not allocating null size block |
xor eax,eax |
ret |
.not_null: |
if defined multithread |
call heaplock |
end if |
push edi |
; push edx |
push ecx |
push ebx |
add eax,7 |
and eax,not 7 ; make sure that block size is aligned |
lea edi,[eax+8] ; desired block size |
cmp edi,4096 |
jge .general_cycle |
mov ebx,[heapsmallblocks] |
xor ecx,ecx |
shr edi,1 |
.smallloop: |
cmp [ebx+edi],ecx |
jnz .smallblockfound |
add edi,4 |
cmp edi,2048 |
jl .smallloop |
lea edi,[eax+8] |
jmp .general_cycle |
.smallblockfound: |
lea ecx,[eax+8] |
mov eax,[ebx+edi] |
call heap_remove_block |
mov ebx,eax |
xchg eax,ecx |
call heap_split_block |
test ebx,ebx |
jz .perfect_small_block |
mov eax,ebx |
call heap_add_free_block |
.perfect_small_block: |
lea eax,[ecx+8] |
jmp .ret |
.general_cycle: |
;edi - size needed |
mov eax,[heapfreelist] |
.loop: |
test eax,eax |
jz .new_mem |
cmp [eax+memblock.size],edi |
jge .blockfound |
mov eax,[eax+memblock.nextfreeblock] |
jmp .loop |
.blockfound: |
call heap_remove_block |
mov ebx,eax |
mov ecx,eax |
mov eax,edi |
call heap_split_block |
test ebx,ebx |
jz .perfect_block |
mov eax,ebx |
call heap_add_free_block |
.perfect_block: |
lea eax,[ecx+8] |
.ret: |
if defined multithread |
call heapunlock |
end if |
pop ebx |
pop ecx |
; pop edx |
pop edi |
ret |
.new_mem: |
mov eax,edi |
add eax,4095 |
and eax,not 4095 |
mov ecx,[heapend] |
add [heapend],eax |
push eax |
mov eax,64 |
push ebx |
push ecx |
mov ecx,[heapend] |
mov ebx,1 |
mov ebx,20 |
mov eax,68 |
mov ecx,[size] |
mov edx,[pointer] |
int 0x40 |
pop ecx |
pop ebx |
pop eax |
mov [ecx+memblock.size],eax |
mov eax,[heaplastblock] |
mov [ecx+memblock.prevblock],eax |
mov [heaplastblock],ecx |
mov eax,ecx |
call heap_add_free_block |
jmp .general_cycle |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; heap_fix_right ;; |
;; input: ;; |
;; eax - pointer to free block ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
heap_fix_right: |
push ebx |
mov ebx,eax |
add ebx,[eax+memblock.size] |
cmp ebx,[heapend] |
jz .endblock |
mov [ebx+memblock.prevblock],eax |
pop ebx |
ret |
.endblock: |
mov [heaplastblock],eax |
pop ebx |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; heap_merge_left ;; |
;; input: ;; |
;; eax - pointer to free block ;; |
;; output: ;; |
;; eax - pointer to merged block ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
heap_merge_left: |
push ebx |
mov ebx,[eax+memblock.prevblock] |
test ebx,ebx |
jz .ret |
test byte [ebx+memblock.size],1 |
jnz .ret |
xchg eax,ebx |
call heap_remove_block |
mov ebx,[ebx+memblock.size] |
add [eax+memblock.size],ebx |
call heap_fix_right |
.ret: |
pop ebx |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; heap_merge_right ;; |
;; input: ;; |
;; eax - pointer to free block ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
heap_merge_right: |
push ebx |
mov ebx,eax |
add ebx,[eax+memblock.size] |
cmp ebx,[heapend] |
jz .ret |
test byte [ebx+memblock.size],1 |
jnz .ret |
xchg eax,ebx |
call heap_remove_block |
xchg eax,ebx |
mov ebx,[ebx+memblock.size] |
add [eax+memblock.size],ebx |
call heap_fix_right |
.ret: |
pop ebx |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; mf_free ;; |
;; input: ;; |
;; eax - pointer ;; |
;; output: ;; |
;; eax=1 - ok ;; |
;; eax=0 - failed ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
mf_free: |
test eax,eax |
jnz .no_null |
inc eax |
ret |
.no_null: |
if defined multithread |
call heaplock |
end if |
sub eax,8 |
dec dword [eax+memblock.size] |
call heap_merge_left |
call heap_merge_right |
call heap_add_free_block |
.ret: |
if defined multithread |
call heapunlock |
end if |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; heap_try_reloc |
;; input: |
;; eax - address |
;; ebx - new size |
;; output: |
;; ebx=1 - ok |
;; ebx=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
heap_try_reloc: |
push eax |
sub eax,8 |
add ebx,15 |
dec dword [eax+memblock.size] |
and ebx,not 7 |
cmp [eax+memblock.size],ebx |
jge .truncate |
push ebx |
mov ebx,eax |
add ebx,[eax+memblock.size] |
cmp ebx,[heapend] |
jz .fail ;todo: we can allocate new mem here |
test [ebx+memblock.size],byte 1 |
jnz .fail |
xchg eax,ebx |
call heap_remove_block |
mov eax,[eax+memblock.size] |
add [ebx+memblock.size],eax |
mov eax,ebx |
call heap_fix_right |
pop ebx |
.truncate: |
xchg eax,ebx |
call heap_split_block |
test ebx,ebx |
jz .no_last_block |
mov eax,ebx |
call heap_add_free_block |
call heap_merge_right |
.no_last_block: |
xor ebx,ebx |
pop eax |
inc ebx |
ret |
.fail: |
pop ebx |
xor ebx,ebx |
pop eax |
inc dword [eax-8+memblock.size] |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; mf_realloc |
;; input: |
;; eax - pointer |
;; ebx - new size |
;; output: |
;; eax - new pointer |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
mf_realloc: |
push ebx |
if defined multithread |
call heaplock |
end if |
call heap_try_reloc |
test ebx,ebx |
jnz .ret |
;allocate new memory |
push eax |
mov eax,[esp+4] |
call mf_alloc |
test eax,eax |
jz .fail |
push esi |
push edi |
push ecx |
mov edi,eax |
mov esi,[esp+12] |
mov ecx,[esi-8+memblock.size] |
shr ecx,2 |
rep movsd |
pop ecx |
pop edi |
pop esi |
xchg eax,[esp] |
call mf_free |
.fail: |
pop eax |
.ret: |
if defined multithread |
call heapunlock |
end if |
pop ebx |
ret |
;C entries |
malloc: |
mov eax,[esp+4] |
call mf_alloc |
ret |
free: |
mov eax,[esp+4] |
call mf_free |
ret |
realloc: |
mov edx,ebx |
mov eax,[esp+4] |
mov ebx,[esp+8] |
call mf_realloc |
mov ebx,edx |
ret |
section '.bss' writeable |
heapsmallblocks rd 1 |
heapstart rd 1 |
heapend rd 1 |
heapfreelist rd 1 |
heapmutex rd 1 |
heaplastblock rd 1 |
endp |
/programs/develop/metcc/trunk/libc/mesys/_mesys_c.c |
---|
File deleted |
\ No newline at end of file |
/programs/develop/metcc/trunk/libc/mesys/_ksys_files_acces.asm |
---|
0,0 → 1,119 |
format ELF |
section '.text' executable |
include 'proc32.inc' |
public _ksys_get_filesize |
public _ksys_readfile |
public _ksys_rewritefile |
public _ksys_appendtofile |
align 4 |
proc _ksys_get_filesize stdcall, filename:dword |
xor eax,eax |
mov ebx,[filename] |
mov [fileinfo.subproc],dword 5 |
mov [fileinfo.offset_l],eax |
mov [fileinfo.offset_h],eax |
mov [fileinfo.size],eax |
mov [fileinfo.data],dword buffer_for_info |
mov [fileinfo.letter],al |
mov [fileinfo.filename],ebx |
mov eax,70 |
mov ebx,fileinfo |
int 0x40 |
test eax,eax |
jnz error_for_file_size |
mov eax,[buffer_for_info+32] ;file size |
error_for_file_size: |
ret |
endp |
align 4 |
proc _ksys_readfile stdcall,filename:dword,position:dword,sizeblock:dword,buffer:dword |
xor eax,eax |
mov ebx,[position] |
mov ecx,[sizeblock] |
mov edx,[buffer] |
mov esi,[filename] |
mov [fileinfo.subproc],eax |
mov [fileinfo.offset_l],ebx |
mov [fileinfo.offset_h],eax |
mov [fileinfo.size],ecx |
mov [fileinfo.data],edx |
mov [fileinfo.letter],al |
mov [fileinfo.filename],esi |
mov eax,70 |
mov ebx,fileinfo |
int 0x40 |
ret |
endp |
align 4 |
proc _ksys_rewritefile stdcall,filename:dword,sizeblock:dword,data_write:dword |
xor eax,eax |
mov ebx,[sizeblock] |
mov ecx,[data_write] |
mov edx,[filename] |
mov [fileinfo.subproc],dword 2 |
mov [fileinfo.offset_l],eax |
mov [fileinfo.offset_h],eax |
mov [fileinfo.size],ebx |
mov [fileinfo.data],ecx |
mov [fileinfo.letter],al |
mov [fileinfo.filename],edx |
mov eax,70 |
mov ebx,fileinfo |
int 0x40 |
ret |
endp |
align 4 |
proc _ksys_appendtofile stdcall,filename:dword,pos:dword,sizeblock:dword,data_append:dword |
xor eax,eax |
mov ebx,[pos] |
mov ecx,[sizeblock] |
mov edx,[data_append] |
mov esi,[filename] |
mov [fileinfo.subproc],dword 3 |
mov [fileinfo.offset_l],ebx |
mov [fileinfo.offset_h],eax |
mov [fileinfo.size],ecx |
mov [fileinfo.data],edx |
mov [fileinfo.letter],al |
mov [fileinfo.filename],esi |
mov eax,70 |
mov ebx,fileinfo |
int 0x40 |
ret |
endp |
struc FILEIO |
{ |
.subproc rd 1 |
.offset_l rd 1 |
.offset_h rd 1 |
.size rd 1 |
.data rd 1 |
.letter rb 1 |
.filename rd 1 |
} |
fileinfo FILEIO |
buffer_for_info rd 11 |
/programs/develop/metcc/trunk/libc/mesys/clock.asm |
---|
1,7 → 1,15 |
format ELF |
include "public_stdcall.inc" |
include "proc32.inc" |
section '.text' executable |
public_stdcall _msys_get_system_clock,0 |
public _msys_get_system_clock |
align 4 |
proc _msys_get_system_clock stdcall |
mov eax,3 |
int 0x40 |
ret |
ret |
endp |
/programs/develop/metcc/trunk/libc/mesys/debug_board.asm |
---|
1,12 → 1,19 |
format ELF |
include "public_stdcall.inc" |
include "proc32.inc" |
section '.text' executable |
public_stdcall _msys_debug_out,4 |
;arg1 - char to out |
push ebx |
mov ecx,[esp+8] |
public _msys_debug_out |
align 4 |
proc _msys_debug_out stdcall, c:byte |
xor ecx,ecx |
mov cl,byte[c] |
mov ebx,1 |
mov eax,63 |
int 0x40 |
pop ebx |
ret 4 |
ret |
endp |
/programs/develop/metcc/trunk/libc/mesys/debug_board_.c |
---|
1,7 → 1,7 |
#include "mesys.h" |
#include <mesys.h> |
void debug_out_str(char* str) |
{ |
while (*str!='\0') |
while ((*str!='\0') || (*str!=0)) |
{ |
_msys_debug_out(*str); |
str++; |
/programs/develop/metcc/trunk/libc/mesys/keyboard.asm |
---|
1,17 → 1,29 |
format ELF |
include "public_stdcall.inc" |
include "proc32.inc" |
section '.text' executable |
public_stdcall _msys_get_key,0 |
public _msys_get_key |
public _msys_set_keyboard_mode |
align 4 |
proc _msys_get_key stdcall |
mov eax,2 |
int 0x40 |
ret |
public_stdcall _msys_set_keyboard_mode,4 |
;arg1 - mode |
endp |
align 4 |
proc _msys_set_keyboard_mode stdcall, mode:dword |
mov edx,ebx |
mov eax,66 |
xor ebx,ebx |
inc ebx |
mov ecx,[esp+4] |
mov ecx,[mode] |
mov ebx,edx |
ret 4 |
ret |
endp |