#include #include "types.h" #include #include #include #include "memman.h" #include //#include #include "swaper.c" #include #include #include #define DPMI_INT 0x31 #define LOAD_BUFFER 4096 #undef malloc void bonz_table(); #define NON_GETMEM_RESERVED (4*1024) static const char ** mman_pathlist=NULL; char mman_patch=0; static int max_handle=0; //static FILE *log; void (*mman_action)(int action)=NULL; int32_t last_load_size; void def_mman_group_table(const char ** p) { mman_pathlist = p; } void standard_mem_error(size_t size) { display_error("memory allocation error %lu", (unsigned long)size); exit(1); } void load_error(const char *filename) { char buff[256]; SEND_LOG("(ERROR) Load error detected, system can't load file: %s",filename); sprintf(buff,"Load error while loading file: %s", filename); display_error(buff); exit(1); } void standard_swap_error() { char buff[256]; sprintf(buff,"Swap error. Maybe disk is full"); display_error(buff); exit(1); } void (*mem_error)(size_t)=standard_mem_error; void (*swap_error)()=standard_swap_error; void *getmem(int32_t size) { void *p,*res; if (!size) return NULL; do { res=malloc(NON_GETMEM_RESERVED); if (res!=NULL) { p=(void *)malloc(size); free(res); } else p=NULL; if (p==NULL) mem_error(size); } while (p==NULL); // SEND_LOG("(ALLOC) **** Alloc: %p size %d",p,*((int32_t *)p-1)); return p; } void *load_file(const char *filename, size_t *sz) { FILE *f; int32_t *p; size_t size; if (mman_action!=NULL) mman_action(MMA_READ); SEND_LOG("(LOAD) Loading file '%s'",filename); f=fopen_icase(filename, "rb"); if (f==NULL) { load_error(filename); return NULL; } fseek(f,0, SEEK_END); size=ftell(f); fseek(f,0, SEEK_SET); p=(void *)getmem(size); if (fread(p,1,size,f)!=size) load_error(filename); fclose(f); *sz=size; return p; } //--------------- BLOCK MASTER OPERATION SYSTEM -------------------------- //--------------- part: MEMORY MANAGER ----------------------------------- typedef struct tnametable { char name[12]; int32_t seek; }TNAMETABLE; typedef struct tnametable_ref { const TNAMETABLE *data; uint32_t count; } TNAMETABLE_REF; typedef struct ddlmap_info { const void *ptr; size_t size; TNAMETABLE_REF nametable; } TDDLMAP_INFO; #define MAX_PATCHES 4 static TDDLMAP_INFO ddlmap[MAX_PATCHES]; static int next_name_read=0; static int last_group; handle_groups _handles; uint32_t bk_global_counter=0; char *swap_path; static int test_file_exist_DOS(int group,char *filename) { const char *f = build_pathname(2, mman_pathlist[group], filename); if (!check_file_exists(f)) return 0; return 1; } #if 0 void load_grp_table() { int32_t i = 0;; SEND_LOG("(LOAD) Loading Group Table"); const uint32_t *src_table = (const uint32_t *)bmf_m; //fseek(bmf,4,SEEK_SET); i = src_table[1];//fread(&i,4,1,bmf); grptable=(int32_t *)getmem(i+4); //fseek(bmf,0,SEEK_SET); grptabsiz = src_table[0]; //fread(grptable,i,1,bmf); grptabsiz=i; for(i=0;i<(grptabsiz>>3);i++) grptable[i*2+1]=(grptable[i*2+1]-grptabsiz)>>4; SEND_LOG("(LOAD) Group Table Loaded"); } #endif static TNAMETABLE_REF load_file_table(const void *bmf_m) { const uint32_t *src_table = (const uint32_t *)bmf_m; uint32_t grptabsiz = src_table[1]; TNAMETABLE_REF out; out.data = (const TNAMETABLE *)((const char *)bmf_m + grptabsiz); out.count = (out.data[0].seek - grptabsiz)/sizeof(TNAMETABLE); return out; } int get_file_entry_in_table(const TNAMETABLE_REF *where, char *name) { for(uint32_t i = 0; i< where->count; ++i) { if (strncmp(where->data[i].name, name, 12) == 0) { return where->data[i].seek; } } return -1; } char get_file_entry(int group,char *name, THANDLE_DATA *h) { char ex; ex=mman_patch && test_file_exist_DOS(group,name); if (!ex) { for (int i = 0; i < MAX_PATCHES; ++i) { const TDDLMAP_INFO *nfo = &ddlmap[i]; if (nfo->ptr) { int sk = get_file_entry_in_table(&nfo->nametable, name); if (sk >= 0) { h->src_index = i; h->offset = sk; return 1; } } } } return 0; } THANDLE_DATA *get_handle(int handle) { int group,list; group=handle/BK_MINOR_HANDLES; list=handle % BK_MINOR_HANDLES; if (_handles[group]==NULL) { _handles[group]=(handle_list *)getmem(sizeof(handle_list)); memset(_handles[group],0,sizeof(handle_list)); } if (handle>max_handle) max_handle=handle; return ((THANDLE_DATA *)_handles[group])+list; } static char need_to_be_free(const void *ptr) { for (int i = 0; i < MAX_PATCHES; ++i) { const TDDLMAP_INFO *nfo = &ddlmap[i]; if (nfo->ptr) { const char *beg = (const char *)nfo->ptr; const char *p = (const char *)ptr; if (p >= beg && p < beg+nfo->size) return 0; } } return 1; } THANDLE_DATA *kill_block(int handle) { THANDLE_DATA *h; h=get_handle(handle);if (h->status==BK_NOT_USED) return h; if (h->flags & BK_LOCKED) { SEND_LOG("(ERROR) Unable to kill block! It is LOCKED! '%-.12s' (%04X)",h->src_file,handle); return NULL; } SEND_LOG("(KILL) Killing block '%-.12s' (%04X)",h->src_file,handle); if (h->status==BK_SAME_AS) return h; if (h->status==BK_PRESENT) { ablock_free(h->blockdata); } h->status=BK_NOT_LOADED; h->flags&=~BK_HSWAP; return h; } THANDLE_DATA *zneplatnit_block(int handle) { THANDLE_DATA *h; h=kill_block(handle); if (h->status==BK_SAME_AS) return zneplatnit_block(h->offset); return h; } static void add_patch(const void *bmf, size_t sz) { for (int i = 0; i < MAX_PATCHES; ++i) { if (ddlmap[i].ptr == NULL) { ddlmap[i].ptr = bmf; ddlmap[i].size = sz; ddlmap[i].nametable = load_file_table(bmf); return; } } display_error("memman: Too many patches"); abort(); } char add_patch_file(const char *filename) { size_t bmf_s; const void *bmf = map_file_to_memory(file_icase_find(filename), &bmf_s); if (bmf) { add_patch(bmf, bmf_s); return 1; } return 0; } void init_manager(void) { next_name_read=0; last_group=0; memset(_handles,0,sizeof(_handles)); memset(ddlmap,0,sizeof(ddlmap)); } int find_same(const char *name,ABLOCK_DECODEPROC decomp) { THANDLE_DATA *p; int i,j; decomp; if (name[0]==0) return -1; for(i=0;istatus=BK_SAME_AS; h->offset=i; return h; } strcopy_n(h->src_file,filename,sizeof(h->src_file)); h->offset=0; strupper(h->src_file); h->loadproc=decompress; if (filename[0]) { get_file_entry(path,h->src_file,h); } SEND_LOG("(REGISTER) File/Block registred '%-.12s' handle %04X",h->src_file,handle); SEND_LOG("(REGISTER) Seekpos=%d",h->seekpos); h->flags=0; h->path=path; if (h->status!=BK_DIRLIST) h->status=BK_NOT_LOADED; h->counter=bk_global_counter++; return h; } const void *afile(char *filename,int group,int32_t *blocksize) { char *d; char entr; void *p; d=alloca(strlen(filename)+1); strcpy(d,filename); strupper(d); THANDLE_DATA hd; entr = get_file_entry(group, d, &hd); if (entr!=0) { SEND_LOG("(LOAD) Afile is loading file '%s' from group %d",d,group); const TDDLMAP_INFO *nfo = &ddlmap[hd.src_index]; const int32_t * szptr = (const int32_t *)((const char *)nfo->ptr+hd.offset); *blocksize = *szptr; return szptr+1; } else if (mman_pathlist!=NULL) { const char *name = build_pathname(2,mman_pathlist[group],d); size_t sz; SEND_LOG("(LOAD) Afile is loading file '%s' from disk (group %d)",d,group); p=load_file(name, &sz); *blocksize=sz; } else return NULL; return p; } void *afile_copy(char *filename,int group,int32_t *blocksize) { const void *ptr = afile(filename, group, blocksize); if (need_to_be_free(ptr)) return (void *)ptr; void *cpy = getmem(*blocksize); memcpy(cpy, ptr, *blocksize); return cpy; } static void decompress_data(THANDLE_DATA *h, int handle) { if (h->loadproc) { int32_t sz = h->size; const void *r = h->loadproc(h->blockdata, &sz, handle); if (r != h->blockdata) { ablock_free(h->blockdata); h->blockdata = r; h->size = sz; } } } const void *ablock(int handle) { THANDLE_DATA *h; sem: h=get_handle(handle); if (h->status==BK_SAME_AS) { handle=h->offset; goto sem; } if (h->status==BK_PRESENT) { return h->blockdata; } if (h->status==BK_DIRLIST) { ablock_free(h->blockdata);h->status=BK_NOT_LOADED; } if (h->status==BK_NOT_LOADED) { void *p;int32_t s; SEND_LOG("(LOAD) Loading file as block '%-.12s' %04X",h->src_file,handle); if (h->offset==0) { if (h->src_file[0]!=0) { size_t sz; if (mman_action!=NULL) mman_action(MMA_READ); const char *name = build_pathname(2,mman_pathlist[h->path], h->src_file); p=load_file(name, &sz); s=sz; } else { p=NULL; s=0; } h->blockdata=p; h->status=BK_PRESENT; h->size=s; decompress_data(h, handle); return h->blockdata; } else { const TDDLMAP_INFO *nfo = &ddlmap[h->src_index]; if (mman_action!=NULL) mman_action(MMA_READ); const int32_t *szptr =(const int32_t *)((const char *)nfo->ptr+h->offset); s = *szptr; void *p = (void *)(szptr+1); h->blockdata=p; h->status=BK_PRESENT; h->size=s; decompress_data(h, handle); return h->blockdata; } } return NULL; } void *ablock_copy(int handle) { const void *ptr = ablock(handle); if (need_to_be_free(ptr)) return (void *)ptr; THANDLE_DATA *h = get_handle(handle); void *cpy = getmem(h->size); memcpy(cpy, ptr, h->size); h->blockdata = cpy; return cpy; } void alock(int handle) { THANDLE_DATA *h; h=get_handle(handle); if (!h->lockcount) { h->flags|=BK_LOCKED; if (h->status==BK_SAME_AS) alock(h->offset); } h->lockcount++; //SEND_LOG("(LOCK) Handle locked %04X (count %d)",handle,h->lockcount); } void aunlock(int handle) { THANDLE_DATA *h; h=get_handle(handle); if (h->lockcount) h->lockcount--;else return; if (!h->lockcount) { h->flags&=~BK_LOCKED; if (h->status==BK_SAME_AS) aunlock(h->offset); } //SEND_LOG("(LOCK) Handle unlocked %04X (count %d)",handle,h->lockcount); } void undef_handle(int handle) { THANDLE_DATA *h; h=get_handle(handle); if (h->status!=BK_NOT_USED) { if (kill_block(handle)==NULL) return; SEND_LOG("(REGISTER) File/Block unregistred %04X (%-.12s)",handle,h->src_file); } h->src_file[0]=0; h->offset=0; h->flags=0; h->status=BK_NOT_USED; h->loadproc = 0; } void close_manager() { int i,j; for(i=0;istatus!=BK_NOT_USED && h->status!=BK_SAME_AS) { int k; for(k=0;k<5;k++) copys[k]=h->flags & (1<src_file[0]) strcopy_n(nname,h->src_file,sizeof(nname));else strcpy(nname,""); printf("%04Xh ... %12s %s %s %08lXh %6d %10d %6d \n",i*BK_MINOR_HANDLES+j, nname,names[h->status-1], copys,(unsigned long)(uintptr_t)h->blockdata,h->size,h->counter,h->lockcount); ln++; total_data+=h->size; if(h->status==BK_PRESENT)total_mem+=h->size; if (ln%24==23) { char c; printf("Enter to continue, q-quit:"); c=getchar(); if (c=='q' || c=='Q') { while (getchar()!='\n'); return; } } } } } printf("Data: %7d KB, Loaded: %7d KB",total_data/1024,total_mem/1024); while (getchar()!='\n'); } void *grealloc(void *p,int32_t size) { void *q; if (!size) { free(p); return NULL; } q=realloc(p,size); if (q!=NULL) { // SEND_LOG("(ALLOC) **** Realloc: New %p size %d\n",q,*((int32_t *)q-1)); return q; } q=getmem(size); free(q); q=realloc(p,size); return q; } #ifdef LOGFILE /* void free(void *c) { if (c==NULL) return; SEND_LOG("(ALLOC)��� Dealloc: %p size %d",c,*((int32_t *)c-1)); free(c); } */ /* int get_time_macro(); #pragma aux get_time_macro parm[]=\ "mov ah,02"\ "int 1ah"\ "mov al,dh"\ "shl eax,16"\ "mov ax,cx"\ modify[eax ecx edx ebx esi edi] char get_bcd(char bcd); #pragma aux get_bcd parm[al]=\ "mov bl,al"\ "shr al,4"\ "mov ah,10"\ "mul ah"\ "and bl,0fh"\ "add al,bl"\ value[al] modify [eax ebx] */ char *get_time_str() { time_t long_time; struct tm *newtime; static char text[20]; time( &long_time ); /* Get time as int32_t integer. */ newtime = localtime( &long_time ); /* Convert to local time. */ sprintf(text,"%02d:%02d:%02d",newtime->tm_hour,newtime->tm_min,newtime->tm_sec); return text; } #endif int32_t get_handle_size(int handle) { THANDLE_DATA *h; h=get_handle(handle); if (h->status==BK_NOT_USED) return -1; return h->size; } /*void *malloc(size_t size) { static char zavora=1; void *c; c=_nmalloc(size); if (log!=NULL && zavora) { zavora=0; fprintf(log,"Alloc: %p size %d\n",c,*((int32_t *)c-1)); zavora=1; } return c; } */ void ablock_free(const void *ptr) { if (need_to_be_free(ptr)) free((void *)ptr); }