📄 pm.c
字号:
}}void * PMAPI PM_mallocShared(long size){ return PM_malloc(size);}void PMAPI PM_freeShared(void *ptr){ PM_free(ptr);}#define GetRMVect(intno,isr) *(isr) = ((ulong*)rmZeroPtr)[intno]#define SetRMVect(intno,isr) ((ulong*)rmZeroPtr)[intno] = (isr)ibool PMAPI PM_doBIOSPOST( ushort axVal, ulong BIOSPhysAddr, void *mappedBIOS, ulong BIOSLen){ static int firstTime = true; static uchar *rmZeroPtr; long Current10,Current6D,Current42; RMREGS regs; RMSREGS sregs; /* Create a zero memory mapping for us to use */ if (firstTime) { rmZeroPtr = PM_mapPhysicalAddr(0,0x7FFF,true); firstTime = false; } /* Remap the secondary BIOS to 0xC0000 physical */ if (BIOSPhysAddr != 0xC0000L || BIOSLen > 32768) { /* SMX cannot virtually remap the BIOS, so we can only work if all * the secondary controllers are identical, and we then use the * BIOS on the first controller for all the remaining controllers. * * For OS'es that do virtual memory, and remapping of 0xC0000 * physical (perhaps a copy on write mapping) should be all that * is needed. */ return false; } /* Save current handlers of int 10h and 6Dh */ GetRMVect(0x10,&Current10); GetRMVect(0x6D,&Current6D); /* POST the secondary BIOS */ GetRMVect(0x42,&Current42); SetRMVect(0x10,Current42); /* Restore int 10h to STD-BIOS */ regs.x.ax = axVal; PM_callRealMode(0xC000,0x0003,®s,&sregs); /* Restore current handlers */ SetRMVect(0x10,Current10); SetRMVect(0x6D,Current6D); /* Second the primary BIOS mappin 1:1 for 0xC0000 physical */ if (BIOSPhysAddr != 0xC0000L) { /* SMX does not support this */ (void)mappedBIOS; } return true;}void PMAPI PM_sleep(ulong milliseconds){ ulong microseconds = milliseconds * 1000L; LZTimerObject tm; LZTimerOnExt(&tm); while (LZTimerLapExt(&tm) < microseconds) ; LZTimerOffExt(&tm);}int PMAPI PM_getCOMPort(int port){ switch (port) { case 0: return 0x3F8; case 1: return 0x2F8; } return 0;}int PMAPI PM_getLPTPort(int port){ switch (port) { case 0: return 0x3BC; case 1: return 0x378; case 2: return 0x278; } return 0;}PM_MODULE PMAPI PM_loadLibrary( const char *szDLLName){ (void)szDLLName; return NULL;}void * PMAPI PM_getProcAddress( PM_MODULE hModule, const char *szProcName){ (void)hModule; (void)szProcName; return NULL;}void PMAPI PM_freeLibrary( PM_MODULE hModule){ (void)hModule;}int PMAPI PM_setIOPL( int level){ return level;}/****************************************************************************REMARKS:Internal function to convert the find data to the generic interface.****************************************************************************/static void convertFindData( PM_findData *findData, struct find_t *blk){ ulong dwSize = findData->dwSize; memset(findData,0,findData->dwSize); findData->dwSize = dwSize; if (blk->attrib & _A_RDONLY) findData->attrib |= PM_FILE_READONLY; if (blk->attrib & _A_SUBDIR) findData->attrib |= PM_FILE_DIRECTORY; if (blk->attrib & _A_ARCH) findData->attrib |= PM_FILE_ARCHIVE; if (blk->attrib & _A_HIDDEN) findData->attrib |= PM_FILE_HIDDEN; if (blk->attrib & _A_SYSTEM) findData->attrib |= PM_FILE_SYSTEM; findData->sizeLo = blk->size; strncpy(findData->name,blk->name,PM_MAX_PATH); findData->name[PM_MAX_PATH-1] = 0;}#define FIND_MASK (_A_RDONLY | _A_ARCH | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM)/****************************************************************************REMARKS:Function to find the first file matching a search criteria in a directory.****************************************************************************/void * PMAPI PM_findFirstFile( const char *filename, PM_findData *findData){ struct find_t *blk; if ((blk = PM_malloc(sizeof(*blk))) == NULL) return PM_FILE_INVALID; if (_dos_findfirst((char*)filename,FIND_MASK,blk) == 0) { convertFindData(findData,blk); return blk; } return PM_FILE_INVALID;}/****************************************************************************REMARKS:Function to find the next file matching a search criteria in a directory.****************************************************************************/ibool PMAPI PM_findNextFile( void *handle, PM_findData *findData){ struct find_t *blk = handle; if (_dos_findnext(blk) == 0) { convertFindData(findData,blk); return true; } return false;}/****************************************************************************REMARKS:Function to close the find process****************************************************************************/void PMAPI PM_findClose( void *handle){ PM_free(handle);}/****************************************************************************REMARKS:Function to determine if a drive is a valid drive or not. Under Unix thisfunction will return false for anything except a value of 3 (consideredthe root drive, and equivalent to C: for non-Unix systems). The drivenumbering is: 1 - Drive A: 2 - Drive B: 3 - Drive C: etc****************************************************************************/ibool PMAPI PM_driveValid( char drive){ RMREGS regs; regs.h.dl = (uchar)(drive - 'A' + 1); regs.h.ah = 0x36; /* Get disk information service */ PM_int86(0x21,®s,®s); return regs.x.ax != 0xFFFF; /* AX = 0xFFFF if disk is invalid */}/****************************************************************************REMARKS:Function to get the current working directory for the specififed drive.Under Unix this will always return the current working directory regardlessof what the value of 'drive' is.****************************************************************************/void PMAPI PM_getdcwd( int drive, char *dir, int len){ uint oldDrive,maxDrives; _dos_getdrive(&oldDrive); _dos_setdrive(drive,&maxDrives); getcwd(dir,len); _dos_setdrive(oldDrive,&maxDrives);}/****************************************************************************REMARKS:Function to change the file attributes for a specific file.****************************************************************************/void PMAPI PM_setFileAttr( const char *filename, uint attrib){#if defined(TNT) && defined(_MSC_VER) DWORD attr = 0; if (attrib & PM_FILE_READONLY) attr |= FILE_ATTRIBUTE_READONLY; if (attrib & PM_FILE_ARCHIVE) attr |= FILE_ATTRIBUTE_ARCHIVE; if (attrib & PM_FILE_HIDDEN) attr |= FILE_ATTRIBUTE_HIDDEN; if (attrib & PM_FILE_SYSTEM) attr |= FILE_ATTRIBUTE_SYSTEM; SetFileAttributes((LPSTR)filename, attr);#else uint attr = 0; if (attrib & PM_FILE_READONLY) attr |= _A_RDONLY; if (attrib & PM_FILE_ARCHIVE) attr |= _A_ARCH; if (attrib & PM_FILE_HIDDEN) attr |= _A_HIDDEN; if (attrib & PM_FILE_SYSTEM) attr |= _A_SYSTEM; _dos_setfileattr(filename,attr);#endif}/****************************************************************************REMARKS:Function to create a directory.****************************************************************************/ibool PMAPI PM_mkdir( const char *filename){#ifdef __GNUC__ return mkdir(filename,S_IRUSR) == 0;#else/*AM: return mkdir(filename) == 0; */ return(false);#endif}/****************************************************************************REMARKS:Function to remove a directory.****************************************************************************/ibool PMAPI PM_rmdir( const char *filename){/*AM: return rmdir(filename) == 0; */ return(false);}/****************************************************************************REMARKS:Allocates a block of locked, physically contiguous memory. The memorymay be required to be below the 16Meg boundary.****************************************************************************/void * PMAPI PM_allocLockedMem( uint size, ulong *physAddr, ibool contiguous, ibool below16M){ void *p; uint r_seg,r_off; PM_lockHandle lh; /* Under DOS the only way to know the physical memory address is to * allocate the memory below the 1Meg boundary as real mode memory. * We also allocate 4095 bytes more memory than we need, so we can * properly page align the start of the memory block for DMA operations. */ if (size > 4096) return NULL; if ((p = PM_allocRealSeg((size + 0xFFF) & ~0xFFF,&r_seg,&r_off)) == NULL) return NULL; *physAddr = ((r_seg << 4) + r_off + 0xFFF) & ~0xFFF; PM_lockDataPages(p,size*2,&lh); return p;}void PMAPI PM_freeLockedMem(void *p,uint size,ibool contiguous){ (void)size; PM_freeRealSeg(p);}/*-------------------------------------------------------------------------*//* Generic DPMI routines common to 16/32 bit code *//*-------------------------------------------------------------------------*/ulong PMAPI DPMI_mapPhysicalToLinear(ulong physAddr,ulong limit){ PMREGS r; ulong physOfs; if (physAddr < 0x100000L) { /* We can't map memory below 1Mb, but the linear address are already * mapped 1:1 for this memory anyway so we just return the base address. */ return physAddr; } /* Round the physical address to a 4Kb boundary and the limit to a * 4Kb-1 boundary before passing the values to DPMI as some extenders * will fail the calls unless this is the case. If we round the * physical address, then we also add an extra offset into the address * that we return. */ physOfs = physAddr & 4095; physAddr = physAddr & ~4095; limit = ((limit+physOfs+1+4095) & ~4095)-1; r.x.ax = 0x800; /* DPMI map physical to linear */ r.x.bx = physAddr >> 16; r.x.cx = physAddr & 0xFFFF; r.x.si = limit >> 16; r.x.di = limit & 0xFFFF; PM_int386(0x31, &r, &r); if (r.x.cflag) return 0xFFFFFFFFUL; return ((ulong)r.x.bx << 16) + r.x.cx + physOfs;}int PMAPI DPMI_setSelectorBase(ushort sel,ulong linAddr){ PMREGS r; r.x.ax = 7; /* DPMI set selector base address */ r.x.bx = sel; r.x.cx = linAddr >> 16; r.x.dx = linAddr & 0xFFFF; PM_int386(0x31, &r, &r); if (r.x.cflag) return 0; return 1;}ulong PMAPI DPMI_getSelectorBase(ushort sel){ PMREGS r; r.x.ax = 6; /* DPMI get selector base address */ r.x.bx = sel;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -