Example #1
0
void PMAPI PM_restorePMvect(int intno, PMFARPTR isr)
{
    FARPTR  ph;

    FP_SET(ph,isr.off,isr.sel);
    _dx_pmiv_set(intno,ph);
}
Example #2
0
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);
}
Example #3
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);
}
Example #4
0
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);
}
Example #5
0
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,&para,&left))
  {
    ULONG temp;

    if (_dx_cmem_usage(0,0,&temp,&temp))
       return (0);
    if (_dx_real_above(paras,&para,&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);
}