void PMAPI PM_restorePMvect(int intno, PMFARPTR isr) { FARPTR ph; FP_SET(ph,isr.off,isr.sel); _dx_pmiv_set(intno,ph); }
int PMAPI PM_unlockCodePages(void (*p)(),uint len,PM_lockHandle *lh) { CONFIG_INF config; FARPTR fp; _dx_config_inf(&config, (UCHAR*)&config); FP_SET(fp,p,config.c_cs_sel); return (_dx_ulock_pgs(fp,len) == 0); }
void PMAPI PM_setPMvect(int intno, PM_intHandler isr) { CONFIG_INF config; FARPTR ph; PM_saveDS(); _dx_config_inf(&config, (UCHAR*)&config); FP_SET(ph,(uint)isr,config.c_cs_sel); _dx_pmiv_set(intno,ph); }
static void setISR(int intno, void (PMAPI *isr)()) { CONFIG_INF config; FARPTR ph; lockPMHandlers(); /* Ensure our handlers are locked */ _dx_config_inf(&config, (UCHAR*)&config); FP_SET(ph,(uint)isr,config.c_cs_sel); _dx_apmiv_set(intno,ph); }
static REALPTR _dx_alloc_rmode_wrapper (pmodeHook pmHook, rmodeHook rmHook, int len, int stack_size, ReturnType returnType) { #define DOFS 0x2C /* offset of data section (tiny model) */ #define DSIZE 16 /* sizeof data section at wrapper end */ #define WOFS (DOFS+DSIZE) /* offset of userWrapper code (optional) */ static unsigned char wrapper[] = { 0x16, // 00 push ss 0x06, // 01 push es 0x1E, // 02 push ds 0x0E, // 03 push cs 0x1F, // 04 pop ds ;DS = CS 0xF8, // 05 clc 0xE8,0x33,0, // 06 call userWrapper ;33 relative (3A-8) 0x72,0x1C, // 09 jc short @exit 0x66,0x60, // 0B pushad 0x66,0xFF,0x36,DOFS+12,0, // 0D push taskId ;taskId to call 0x66,0x6A,0, // 12 push 0 ;use default selectors 0xFF,0x36,DOFS+4,0, // 15 push ourCS 0x66,0xFF,0x36,DOFS,0, // 19 push protGlue ;(*protGlue)() 0xFF,0x1E,DOFS+8,0, // 1E call rm2pmAddr 0x83,0xC4,14, // 22 add sp,14 ;discard used stack 0x66,0x61, // 25 popad 0x1F, // 27 @exit:pop ds 0x07, // 28 pop es 0x17, // 29 pop ss 0xCB, // 2A retf 0x90, // 2B nop 0,0,0,0, // +0 protGlue dd ? 0,0,0,0, // +4 ourCS dw ?,? 0,0,0,0, // +8 rm2pmAddr dd ? 0,0,0,0 // +12 taskId dd ? }; // +16 userWrapper: .. FARPTR pmCbuf, fpWrapper; REALPTR rmCbuf, rm2pmAddr, dosReal; USHORT para, paras, left; ULONG cbufSize, i; UINT *stack; assert (sizeof(wrapper) == (DOFS+DSIZE)); if (!pmHook || numWrappers == MAX_WRAPPERS) return (0); _dx_rmlink_get (&rm2pmAddr,&rmCbuf,&cbufSize,&pmCbuf); len += sizeof(wrapper); paras = (len + 15) / 16; para = 0; if (_dx_real_above(paras,¶,&left)) { ULONG temp; if (_dx_cmem_usage(0,0,&temp,&temp)) return (0); if (_dx_real_above(paras,¶,&left)) para = 0; if (_dx_cmem_usage(0,1,&temp,&temp)) { if (para) _dx_real_free (para); return (0); } if (!para) return (0); } for (i = 0; i < MAX_WRAPPERS; i++) if (!_rmcb[i].dosReal) break; *(ULONG*) (wrapper+DOFS+0) = (ULONG)&PmodeGlue; /* pmode helper */ *(ULONG*) (wrapper+DOFS+4) = My_CS(); /* pmode CS */ *(ULONG*) (wrapper+DOFS+8) = (ULONG)rm2pmAddr; /* rm->pm addr */ *(ULONG*) (wrapper+DOFS+12) = i; /* task Id */ wrapper [0x2A] = returnType; /* RETF or IRET */ /* * lock pages used by callback (for 386|VMM, allthough untested) */ FP_SET (fpWrapper,para << 4, SS_DOSMEM); _dx_lock_pgs (fpWrapper, len); _dx_lock_pgsn ((void*)&PmodeGlue, (UINT)&PmGlueEnd - (UINT)&PmodeGlue); RP_SET (dosReal,0,para); FillRealMem (dosReal, 0, len); WriteRealMem (dosReal, &wrapper, sizeof(wrapper)); if (rmHook) WriteRealMem(dosReal+WOFS,(void*)rmHook,len-sizeof(wrapper)); else FillRealMem (dosReal+5,0x90,6); stack_size += sizeof(UINT) + 3; /* add a DWORD for marker */ stack_size &= ~3; /* make number of DWORDs */ stack = malloc (stack_size); if (!stack) return (0); _rmcb [i].dosReal = dosReal; _rmcb [i].callback = pmHook; _rmcb [i].stackStart = stack; _rmcb [i].stackTop = stack + stack_size/sizeof(UINT) - 2; _rmcb [i].stackTop[1] = MARKER; _rmcb [i].marker = MARKER; _dx_lock_pgsn ((void*)stack, stack_size); #if 0 printf ("dosReal %08lX, rm2pmAddr %08lX, len %d, stack %08X\n", dosReal,rm2pmAddr,len,stack); #endif numWrappers++; return (dosReal); }