📄 pm.c
字号:
rmregs.pB[0].bBufferType = INPUT_BUFFER; rmregs.pB[0].bSelCRF = REG_OFFSET(reg_es); rmregs.pB[0].bOffCRF = REG_OFFSET(reg_edi); rmregs.pB[0].pAddress = RMBuf; rmregs.pB[0].ulSize = 1024; break; case 0x4F0A: /* Due to bugs in the mini-VDM in OS/2, the 0x4F0A protected * mode interface functions will not work (we never get any * selectors returned), so we fail this function here. The * rest of the VBE/Core driver will work properly if this * function is failed, because the VBE 2.0 and 3.0 specs * allow for this. */ regs->eax = 0x014F; return; } } if (useVPMI) PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,NULL,&rmregs); else { DosSysCtl(6, &rmregs); } OUTDPMI(eax); OUTDPMI(ebx); OUTDPMI(ecx); OUTDPMI(edx); OUTDPMI(esi); OUTDPMI(edi); if (((regs->eax & 0xFFFF) == 0x004F) && ((eax & 0xFFFF) == 0x4F00)) { /* Hack to fix up the missing 'VESA' string for mini-VDM */ memcpy(RMBuf,"VESA",4); } regs->ds = rmregs.aCRF.reg_ds; regs->es = rmregs.aCRF.reg_es; regs->flags = rmregs.aCRF.reg_eflag;}#define IN(reg) rmregs.reg = in->e.reg#define OUT(reg) out->e.reg = rmregs.reg/****************************************************************************REMARKS:Issue a real mode interrupt.****************************************************************************/int PMAPI PM_int86( int intno, RMREGS *in, RMREGS *out){ DPMI_regs rmregs; memset(&rmregs, 0, sizeof(rmregs)); IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi); DPMI_int86(intno,&rmregs); OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi); out->x.cflag = rmregs.flags & 0x1; return out->x.ax;}/****************************************************************************REMARKS:Issue a real mode interrupt.****************************************************************************/int PMAPI PM_int86x( int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs){ DPMI_regs rmregs; memset(&rmregs, 0, sizeof(rmregs)); IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi); rmregs.es = sregs->es; rmregs.ds = sregs->ds; DPMI_int86(intno,&rmregs); OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi); sregs->es = rmregs.es; sregs->cs = rmregs.cs; sregs->ss = rmregs.ss; sregs->ds = rmregs.ds; out->x.cflag = rmregs.flags & 0x1; return out->x.ax;}/****************************************************************************REMARKS:Call a real mode far function.****************************************************************************/void PMAPI PM_callRealMode( uint seg, uint off, RMREGS *in, RMSREGS *sregs){ PM_fatalError("PM_callRealMode not supported on OS/2!");}/****************************************************************************REMARKS:Return the amount of available memory.****************************************************************************/void PMAPI PM_availableMemory( ulong *physical, ulong *total){ /* Unable to get reliable values from OS/2 for this */ *physical = *total = 0;}/****************************************************************************REMARKS:Allocate a block of locked, physical memory for DMA operations.****************************************************************************/void * PMAPI PM_allocLockedMem( uint size, ulong *physAddr, ibool contiguous, ibool below16M){ parmsIn[0] = size; parmsIn[1] = contiguous; parmsIn[2] = below16M; CallSDDHelp(PMHELP_ALLOCLOCKED); *physAddr = parmsOut[1]; return (void*)parmsOut[0];}/****************************************************************************REMARKS:Free a block of locked physical memory.****************************************************************************/void PMAPI PM_freeLockedMem( void *p, uint size, ibool contiguous){ parmsIn[0] = (ulong)p; CallSDDHelp(PMHELP_FREELOCKED);}/****************************************************************************REMARKS:Allocates a new block of pages for the page block manager.****************************************************************************/static pageblock *PM_addNewPageBlock(void){ int i; pageblock *newBlock; char *p,*next; /* Allocate memory for the new page block, and add to head of list */ if (DosAllocSharedMem((void**)&newBlock,NULL,PAGE_BLOCK_SIZE,OBJ_GETTABLE | PAG_READ | PAG_WRITE | PAG_COMMIT)) return NULL; if (!PM_lockDataPages(newBlock,PAGE_BLOCK_SIZE,&newBlock->lockHandle)) return NULL; newBlock->prev = NULL; newBlock->next = pageBlocks; if (pageBlocks) pageBlocks->prev = newBlock; pageBlocks = newBlock; /* Initialise the page aligned free list for the page block */ newBlock->freeCount = PAGES_PER_BLOCK; newBlock->freeList = p = (char*)(((ulong)(newBlock + 1) + (PM_PAGE_SIZE-1)) & ~(PM_PAGE_SIZE-1)); newBlock->freeListStart = newBlock->freeList; newBlock->freeListEnd = p + (PAGES_PER_BLOCK-1) * PM_PAGE_SIZE; for (i = 0; i < PAGES_PER_BLOCK; i++,p = next) FREELIST_NEXT(p) = next = p + PM_PAGE_SIZE; FREELIST_NEXT(p - PM_PAGE_SIZE) = NULL; return newBlock;}/****************************************************************************REMARKS:Allocates a page aligned and page sized block of memory****************************************************************************/void * PMAPI PM_allocPage( ibool locked){ pageblock *block; void *p; /* Scan the block list looking for any free blocks. Allocate a new * page block if no free blocks are found. */ for (block = pageBlocks; block != NULL; block = block->next) { if (block->freeCount) break; } if (block == NULL && (block = PM_addNewPageBlock()) == NULL) return NULL; block->freeCount--; p = block->freeList; block->freeList = FREELIST_NEXT(p); (void)locked; return p;}/****************************************************************************REMARKS:Free a page aligned and page sized block of memory****************************************************************************/void PMAPI PM_freePage( void *p){ pageblock *block; /* First find the page block that this page belongs to */ for (block = pageBlocks; block != NULL; block = block->next) { if (p >= block->freeListStart && p <= block->freeListEnd) break; } CHECK(block != NULL); /* Now free the block by adding it to the free list */ FREELIST_NEXT(p) = block->freeList; block->freeList = p; if (++block->freeCount == PAGES_PER_BLOCK) { /* If all pages in the page block are now free, free the entire * page block itself. */ if (block == pageBlocks) { /* Delete from head */ pageBlocks = block->next; if (block->next) block->next->prev = NULL; } else { /* Delete from middle of list */ CHECK(block->prev != NULL); block->prev->next = block->next; if (block->next) block->next->prev = block->prev; } /* Unlock the memory and free it */ PM_unlockDataPages(block,PAGE_BLOCK_SIZE,&block->lockHandle); DosFreeMem(block); }}/****************************************************************************REMARKS:Map in all the shared memory blocks for managing the memory pages above.****************************************************************************/void PMAPI PM_mapSharedPages(void){ pageblock *block; /* Map all the page blocks above into the shared memory for process */ for (block = pageBlocks; block != NULL; block = block->next) { DosGetSharedMem(block, PAG_READ | PAG_WRITE); }}/****************************************************************************REMARKS:Lock linear memory so it won't be paged.****************************************************************************/int PMAPI PM_lockDataPages( void *p, uint len, PM_lockHandle *lockHandle){ parmsIn[0] = (ulong)p; parmsIn[1] = len; CallSDDHelp(PMHELP_LOCKPAGES); lockHandle->h[0] = parmsOut[1]; lockHandle->h[1] = parmsOut[2]; lockHandle->h[2] = parmsOut[3]; return parmsOut[0];}/****************************************************************************REMARKS:Unlock linear memory so it won't be paged.****************************************************************************/int PMAPI PM_unlockDataPages( void *p, uint len, PM_lockHandle *lockHandle){ parmsIn[0] = lockHandle->h[0]; parmsIn[1] = lockHandle->h[1]; parmsIn[2] = lockHandle->h[2]; return CallSDDHelp(PMHELP_UNLOCKPAGES);}/****************************************************************************REMARKS:Lock linear memory so it won't be paged.****************************************************************************/int PMAPI PM_lockCodePages( void (*p)(), uint len, PM_lockHandle *lockHandle){ parmsIn[0] = (ulong)p; parmsIn[1] = len; CallSDDHelp(PMHELP_LOCKPAGES); lockHandle->h[0] = parmsOut[1]; lockHandle->h[1] = parmsOut[2]; lockHandle->h[2] = parmsOut[3]; return parmsOut[0];}/****************************************************************************REMARKS:Unlock linear memory so it won't be paged.****************************************************************************/int PMAPI PM_unlockCodePages( void (*p)(), uint len, PM_lockHandle *lockHandle){ parmsIn[0] = lockHandle->h[0]; parmsIn[1] = lockHandle->h[1]; parmsIn[2] = lockHandle->h[2]; return CallSDDHelp(PMHELP_UNLOCKPAGES);}/****************************************************************************REMARKS:Call the VBE/Core software interrupt to change display banks.****************************************************************************/void PMAPI PM_setBankA( int bank){ INTCRF rmregs; if (!InitInt10()) return; memset(&rmregs, 0, sizeof(rmregs)); rmregs.ulBIOSIntNo = 0x10; rmregs.aCRF.reg_eax = 0x4F05; rmregs.aCRF.reg_ebx = 0x0000; rmregs.aCRF.reg_edx = bank; PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL);}/****************************************************************************REMARKS:Call the VBE/Core software interrupt to change display banks.****************************************************************************/void PMAPI PM_setBankAB( int bank){ INTCRF rmregs; if (!InitInt10()) return; memset(&rmregs, 0, sizeof(rmregs)); rmregs.ulBIOSIntNo = 0x10; rmregs.aCRF.reg_eax = 0x4F05; rmregs.aCRF.reg_ebx = 0x0000; rmregs.aCRF.reg_edx = bank; PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL); rmregs.ulBIOSIntNo = 0x10; rmregs.aCRF.reg_eax = 0x4F05; rmregs.aCRF.reg_ebx = 0x0001; rmregs.aCRF.reg_edx = bank; PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL);}/****************************************************************************REMARKS:Call the VBE/Core software interrupt to change display start address.****************************************************************************/void PMAPI PM_setCRTStart( int x, int y, int waitVRT){ INTCRF rmregs; if (!InitInt10()) return; memset(&rmregs, 0, sizeof(rmregs)); rmregs.ulBIOSIntNo = 0x10; rmregs.aCRF.reg_eax = 0x4F07; rmregs.aCRF.reg_ebx = waitVRT; rmregs.aCRF.reg_ecx = x; rmregs.aCRF.reg_edx = y; PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL);}/****************************************************************************REMARKS:Execute the POST on the secondary BIOS for a controller.****************************************************************************/ibool PMAPI PM_doBIOSPOST( ushort axVal, ulong BIOSPhysAddr, void *mappedBIOS, ulong BIOSLen){ (void)axVal; (void)BIOSPhysAddr; (void)mappedBIOS; (void)BIOSLen; return false;}/****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -