#include #include #include #include #include "emm.h" #define MEMORY #include "vmemory.h" #undef MEMORY int vmsearch(unsigned long address) { unsigned int c,free1; unsigned long adds; adds = address & VMADDMASK; /* if already mapped */ if(vmismap(address)) { vmm.address = address; return(1); } free1 = 0xffff; for(c = 0;c < vmtblnum;c++) { if((vmtable[c].use == VMFREE) || (vmtable[c].use == VMBLANK)) { if(c < free1) free1 = c; continue; } if(adds != vmtable[c].address) continue; if(vmtable[c].type == VMEMS) { if(vmentry != c) { if(!emsmapf(vmtable[c].page,0)) return(0); } } vmentry = c; vmm.addbase = adds; vmm.address = address; break; } vmm.freeent = free1; if(c >= vmtblnum) return(0); return(1); } int vmmap(unsigned long address) { unsigned int c; unsigned long adds; unsigned char far *addp; if(vmsearch(address)) return(1); adds = address & VMADDMASK; /* if no free entry */ if(vmm.freeent == 0xffff) { if(!vmm.emsready) /* ems not available */ return(0); if(vmtblnum >= VMTBLSIZE) /* vmtable not available */ return(0); if(!emsrealc(emm.lpages + 1)) /* ems can not allocate */ return(0); vmtable[vmtblnum].type = VMEMS; vmtable[vmtblnum].page = emm.lpages - 1; vmtable[vmm.freeent].use = VMFREE; vmm.freeent = vmtblnum++; } if(vmtable[vmm.freeent].type == VMCONV) addp = vmcmtbl[vmm.freeent]; else /* EMS */ { if(!emsmapf(vmtable[vmm.freeent].page,0)) return(0); addp = vmm.emsadd; } if(vmtable[vmm.freeent].use != VMBLANK) { for(c = 0;c < VMMEMSIZE;c++) *addp++ = 0xff; } vmtable[vmm.freeent].address = adds; vmtable[vmm.freeent].use = VMINUSE; vmentry = vmm.freeent; vmm.addbase = adds; vmm.address = address; return(1); } unsigned char far *vmmap1(unsigned long address) { unsigned int c; unsigned long adds; unsigned char far *ptr; adds = address & VMADDMASK; for(c = 0;c < vmtblnum;c++) { if((vmtable[c].use == VMFREE) || (vmtable[c].use == VMBLANK)) continue; if(adds != vmtable[c].address) continue; if(vmtable[c].type == VMCONV) ptr = vmcmtbl[c] + (address & ~VMADDMASK); else /* EMS */ { if(!emsmapf(vmtable[c].page,1)) return((unsigned char far *)0l); FP_SEG(ptr) = emm.ppflame[1].segment; FP_OFF(ptr) = (unsigned int)(address & ~VMADDMASK); } break; } if(c >= vmtblnum) return((unsigned char far *)0l); return(ptr); } int vmgarbag() { int freecnt; unsigned int entry,c; unsigned char far *addp; freecnt = 0; for(entry = 0;entry < vmtblnum;entry++) { if(vmtable[entry].type == VMCONV) addp = vmcmtbl[entry]; else /* EMS */ { if(!emsmapf(vmtable[entry].page,0)) return(0); addp = vmm.emsadd; } for(c = 0;c < VMMEMSIZE;c++) { if(0xff != *addp++) break; } if(c == VMMEMSIZE) /* blank (all data is 0xff) */ { vmtable[entry].use = VMBLANK; freecnt++; } } return(freecnt); } int vminit() { int c; unsigned int freesize; vmm.vmready = 0; vmm.emsready = 0; /* get virtual memory table */ if(NULL == (vmtable = (VMTABLE *)calloc(VMTBLSIZE,sizeof(VMTABLE)))) return(0); /* get conventional memory block */ freesize = _memavl(); if(freesize > 0x100) freesize -= 0x100; for(c = 0;c < VMCMBSIZE ;c++) { if(NULL == (vmcmtbl[c] = _fmalloc(VMMEMSIZE))) break; if(freesize > _memavl()) { _ffree(vmcmtbl[c]); break; } vmtable[c].type = VMCONV; vmtable[c].use = VMFREE; } vmtblnum = c; if(c) vmm.vmready = 1; else vmm.vmready = 0; /* get EMS handle */ vmm.emsready = 0; if(emsphys()) { if(emsalloc(0)) { FP_SEG(vmm.emsadd) = emm.ppflame[0].segment; FP_OFF(vmm.emsadd) = 0; vmm.emsready = 1; } } if(!vmm.vmready && !vmm.emsready) /* no memory */ return(0); vmentry = 0; vmm.address = 0l; vmm.step = 1l; return(1); } int vmflush() { int c; if(vmm.emsready) emsfree(); if(!vmm.vmready) return(1); for(c = 0;c < vmtblnum;c++) { if(vmtable[c].type == VMCONV) _ffree(vmcmtbl[c]); } free((char *)vmtable); vmm.vmready = 0; vmm.emsready = 0; return(1); } void vmaddr(unsigned long address) { vmm.address = address; return; } void vmstep(long step) { vmm.step = step; return; } unsigned char vmread() { unsigned char far *vmptr; /* if logical address is out of phisical memory block */ if(!vmismap(vmm.address)) { if(!vmsearch(vmm.address)) /* if no entry */ { vmm.address += vmm.step; return(0xff); /* blank data is 0xff */ } } setvmptr(vmptr); vmm.address += vmm.step; return(*vmptr); } int vmwrite(unsigned char data) { unsigned char far *vmptr; /* if logical address is out of phisical memory block */ if(!vmismap(vmm.address)) { if(!vmmap(vmm.address)) /* if ems memory not available */ { if(!vmgarbag()) /* if no entry that all data is 0xff */ return(0); if(!vmmap(vmm.address)) /* if can not mapping free entry */ return(0); } } setvmptr(vmptr); *vmptr = data; vmm.address += vmm.step; return(1); } int vmreadb(unsigned char *buf,unsigned int size) { long offset; unsigned char far *vmptr; for(offset = 0xffffffff;size;size--) { if((offset < 0l) || (offset >= VMMEMSIZE)) { if(vmsearch(vmm.address)) { setvmptr(vmptr); offset = vmm.address & ~VMADDMASK; } else /* if no entry */ vmptr = (unsigned char far *)0l; } if((unsigned char far *)0l == vmptr) *buf++ = 0xff; /* blank data is 0xff */ else { *buf++ = *vmptr; vmptr += (int)vmm.step; } offset += vmm.step; vmm.address += vmm.step; } return(1); } int vmwriteb(unsigned char *buf,unsigned int size) { long offset; unsigned char far *vmptr; for(offset = 0xffffffff;size;size--) { if((offset < 0l) || (offset >= VMMEMSIZE)) { if(!vmmap(vmm.address)) /* if ems memory not available */ { if(!vmgarbag()) /* if no entry that all data is 0xff */ return(0); if(!vmmap(vmm.address)) /* if can not mapping free entry */ return(0); } setvmptr(vmptr); offset = vmm.address & ~VMADDMASK; } *vmptr = *buf++; vmptr += (int)vmm.step; offset += vmm.step; vmm.address += vmm.step; } return(1); } int vmmove(unsigned long sorce,unsigned long distin,unsigned long size) { unsigned long soffset,doffset; unsigned char far *svmptr,far *dvmptr; int direc; if(size == 0l) return(1); if(sorce == distin) return(1); else if(sorce > distin) direc = 1; else if((sorce + size - 1l) < distin) direc = 1; else { sorce += (size - 1l); distin += (size - 1l); direc = 0; } for(soffset = doffset = 0xffffffff;size;size--) { if(soffset >= VMMEMSIZE) { svmptr = vmmap1(sorce); soffset = sorce & ~VMADDMASK; } if(doffset >= VMMEMSIZE) { if(!vmmap(distin)) /* if ems memory not available */ { if(!vmgarbag()) /* if no entry that all data is 0xff */ return(0); if(!vmmap(distin)) /* if can not mapping free entry */ return(0); } setvmptr(dvmptr); doffset = distin & ~VMADDMASK; } if(direc == 1) { if((unsigned char far *)0l == svmptr) *dvmptr++ = 0xff; /* blank memory */ else *dvmptr++ = *svmptr++; soffset++; doffset++; sorce++; distin++; } else { if((unsigned char far *)0l == svmptr) *dvmptr-- = 0xff; /* blank memory */ else *dvmptr-- = *svmptr--; soffset--; doffset--; sorce--; distin--; } } return(1); } int vmfill(unsigned long address,unsigned char data,unsigned long size) { unsigned long offset; unsigned char far *vmptr; for(offset = 0xffffffff;size;size--) { if(offset >= VMMEMSIZE) { if(!vmmap(address)) /* if ems memory not available */ { if(!vmgarbag()) /* if no entry that all data is 0xff */ return(0); if(!vmmap(address)) /* if can not mapping free entry */ return(0); } setvmptr(vmptr); offset = address & ~VMADDMASK; } *vmptr++ = data; offset++; address++; } return(1); } int vmerase() { unsigned int c; for(c = 0;c < vmtblnum;c++) vmtable[c].use = VMFREE; for(c = 0;c < vmtblnum;c++) { if(vmtable[c].type != VMCONV) break; } if(vmm.emsready) /* ems available */ { if(emsrealc(0)) /* free ems logical pages */ vmtblnum = c; } else vmtblnum = c; vmm.address = 0l; vmm.step = 1l; return(1); } unsigned long vmfirst(unsigned long start,unsigned long end) { unsigned char far *addp; unsigned long addrf,addr; unsigned int entry,c; if(start > end) return(0l); addrf = end; for(entry = 0;entry < vmtblnum;entry++) { if((vmtable[entry].use == VMFREE) || (vmtable[entry].use == VMBLANK)) continue; if(vmtable[entry].type == VMCONV) addp = vmcmtbl[entry]; else /* EMS */ { if(!emsmapf(vmtable[entry].page,0)) return(0l); addp = vmm.emsadd; } addr = vmtable[entry].address; if((addr < (start & VMADDMASK)) || (addr > (end & VMADDMASK))) continue; for(c = 0;c < VMMEMSIZE;c++) { if(0xff != *addp++) { if((start <= addr) && (addr <= end)) { if(addrf > addr) addrf = addr; } } addr++; } } return(addrf); } unsigned long vmlast(unsigned long start,unsigned long end) { unsigned char far *addp; unsigned long addrl,addr; unsigned int entry,c; if(start > end) return(0l); addrl = start; for(entry = 0;entry < vmtblnum;entry++) { if((vmtable[entry].use == VMFREE) || (vmtable[entry].use == VMBLANK)) continue; if(vmtable[entry].type == VMCONV) addp = vmcmtbl[entry]; else /* EMS */ { if(!emsmapf(vmtable[entry].page,0)) return(0); addp = vmm.emsadd; } addr = vmtable[entry].address; if((addr < (start & VMADDMASK)) || (addr > (end & VMADDMASK))) continue; for(c = 0;c < VMMEMSIZE;c++) { if(0xff != *addp++) { if((start <= addr) && (addr <= end)) { if(addrl < addr) addrl = addr; } } addr++; } } return(addrl); }