⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inthndlr.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 4 页
字号:
  }  goto exit_dispatch;long_check:  if (lrc >= SUCCESS)  {    lr.AX = (UWORD)lrc;    goto exit_dispatch;  }  rc = (int)lrc;short_check:  if (rc < SUCCESS)    goto error_exit;  goto exit_dispatch;error_invalid:  rc = DE_INVLDFUNC;error_exit:  lr.AX = -rc;  if (CritErrCode == SUCCESS)    CritErrCode = lr.AX;      /* Maybe set */error_carry:  SET_CARRY_FLAG();exit_dispatch:  fmemcpy(r, &lr, sizeof(lregs) - 4);  r->DS = lr.DS;  r->ES = lr.ES;real_exit:;#ifdef DEBUG  if (bDumpRegs)  {    fmemcpy(&error_regs, user_r, sizeof(iregs));    dump_regs = TRUE;    dump();  }#endif}#if 0        /* No kernel INT-23 handler required no longer -- 1999/04/15 ska *//* ctrl-Break handler */#pragma argsusedVOID INRPT FAR int23_handler(int es, int ds, int di, int si, int bp,                             int sp, int bx, int dx, int cx, int ax,                             int ip, int cs, int flags){  tsr = FALSE;  return_mode = 1;  return_code = -1;  mod_sto(CTL_C);  DosMemCheck();#ifdef TSC  StartTrace();#endif  return_user();}#endifstruct int25regs {  UWORD es, ds;  UWORD di, si, bp, sp;  UWORD bx, dx, cx, ax;  UWORD flags, ip, cs;};/*     this function is called from an assembler wrapper function */VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r){  ULONG blkno;  UWORD nblks;  BYTE FAR *buf;  UBYTE drv;  if (mode == 0x26)    mode = DSKWRITEINT26;  else    mode = DSKREADINT25;  drv = r->ax;  if (drv >= lastdrive)  {    r->ax = 0x201;    SET_CARRY_FLAG();    return;  }#ifdef WITHFAT32  {    struct dpb FAR *dpbp = get_dpb(drv);    if (dpbp != NULL && ISFAT32(dpbp))    {      r->ax = 0x207;      SET_CARRY_FLAG();      return;    }  }#endif  nblks = r->cx;  blkno = r->dx;  buf = MK_FP(r->ds, r->bx);  if (nblks == 0xFFFF)  {    /*struct HugeSectorBlock FAR *lb = MK_FP(r->ds, r->bx); */    blkno = ((struct HugeSectorBlock FAR *)buf)->blkno;    nblks = ((struct HugeSectorBlock FAR *)buf)->nblks;    buf = ((struct HugeSectorBlock FAR *)buf)->buf;  }  InDOS++;  r->ax = dskxfer(drv, blkno, buf, nblks, mode);  CLEAR_CARRY_FLAG();  if (r->ax != 0)  {    SET_CARRY_FLAG();    if (mode == DSKWRITEINT26)      setinvld(drv);  }  --InDOS;}/*VOID int25_handler(struct int25regs FAR * r) { int2526_handler(DSKREAD,r); }VOID int26_handler(struct int25regs FAR * r) { int2526_handler(DSKWRITE,r); }*/#ifdef TSCSTATIC VOID StartTrace(VOID){  if (bTraceNext)  {#ifdef DEBUG    bDumpRegs = TRUE;#endif    bTraceNext = FALSE;  }#ifdef DEBUG  else    bDumpRegs = FALSE;#endif}#endif/* this function is called from an assembler wrapper function   and serves the internal dos calls - int2f/12xx and int2f/4a01,4a02.*/struct int2f12regs {#ifdef I386#ifdef __WATCOMC__  /* UWORD gs, fs;  ** GS/FS are protected through SI/DI */#else  UWORD high_edx,#ifdef _MSC_VER        high_ecx,#else /* __BORLANDC__ */        high_ebx,#endif        high_eax;#endif#endif  UWORD es, ds;  UWORD di, si, bp;  xreg b, d, c, a;  UWORD ip, cs, flags;  UWORD callerARG1;             /* used if called from INT2F/12 */};/* WARNING: modifications in `r' are used outside of int2F_12_handler() * On input r.AX==0x12xx, 0x4A01 or 0x4A02 */VOID ASMCFUNC int2F_12_handler(struct int2f12regs r){  COUNT rc;  long lrc;  if (r.AH == 0x4a)  {    size_t size = 0, offs = 0xffff;    r.ES = offs;    if (FP_SEG(firstAvailableBuf) == offs) /* HMA present? */    {      offs = FP_OFF(firstAvailableBuf);      size = ~offs;                        /* BX for query HMA   */      if (r.AL == 0x02)                    /* allocate HMA space */      {        if (r.BX < size)          size = r.BX;        AllocateHMASpace(offs, offs+size);        firstAvailableBuf += size;      }    }    r.DI = offs;    r.BX = size;    return;  }  switch (r.AL)  {    case 0x00:                 /* installation check */      r.AL = 0xff;      break;    case 0x03:                 /* get DOS data segment */      r.DS = FP_SEG(&nul_dev);      break;    case 0x06:                 /* invoke critical error */      /* code, drive number, error, device header */      r.AL = CriticalError(r.callerARG1 >> 8,                           (r.callerARG1 & (EFLG_CHAR << 8)) ? 0 :                           r.callerARG1 & 0xff, r.DI, MK_FP(r.BP, r.SI));      break;    case 0x08:                 /* decrease SFT reference count */      {        sft FAR *p = MK_FP(r.ES, r.DI);        r.AX = p->sft_count;        if (--p->sft_count == 0)          --p->sft_count;      }      break;    case 0x0c:                 /* perform "device open" for device, set owner for FCB */      if (lpCurSft->sft_flags & SFT_FDEVICE)      {        request rq;        rq.r_unit = 0;        rq.r_status = 0;        rq.r_command = C_OPEN;        rq.r_length = sizeof(request);        execrh((request FAR *) & rq, lpCurSft->sft_dev);      }      /* just do it always, not just for FCBs */      lpCurSft->sft_psp = cu_psp;      break;    case 0x0d:                 /* get dos date/time */      r.AX = dos_getdate();      r.DX = dos_gettime();      break;    case 0x11:                 /* normalise ASCIIZ filename */    {      char c;      char FAR *s = MK_FP(r.DS, r.SI);      char FAR *t = MK_FP(r.ES, r.DI);      do      {        c = *s++;        /* uppercase character */        /* for now, ASCII only because nls.c cannot handle DS!=SS */        if (c >= 'a' && c <= 'z')          c -= 'a' - 'A';        else if (c == '/')          c = '\\';        *t++ = c;      }      while (c);      break;    }    case 0x12:                 /* get length of asciiz string */      r.CX = fstrlen(MK_FP(r.ES, r.DI)) + 1;      break;    case 0x13:      /* uppercase character */        /* for now, ASCII only because nls.c cannot handle DS!=SS */      r.AL = (unsigned char)r.callerARG1;      if (r.AL >= 'a' && r.AL <= 'z')        r.AL -= 'a' - 'A';      break;    case 0x16:      /* get address of system file table entry - used by NET.EXE         BX system file table entry number ( such as returned from 2F/1220)         returns         ES:DI pointer to SFT entry         BX relative entry number within SFT */      {        int rel_idx = idx_to_sft_(r.BX);        if (rel_idx == -1)        {          r.FLAGS |= FLG_CARRY;          break;        }        r.FLAGS &= ~FLG_CARRY;        r.BX = rel_idx;        r.ES = FP_SEG(lpCurSft);        r.DI = FP_OFF(lpCurSft);        break;      }    case 0x17:                 /* get current directory structure for drive - used by NET.EXE                                   STACK: drive (0=A:,1=B,...)                                   ; returns                                   ;   CF set if error                                   ;   DS:SI pointer to CDS for drive                                   ;                                    ; called like                                   ;   push 2 (c-drive)                                   ;   mov ax,1217                                   ;   int 2f                                   ;                                   ; probable use: get sizeof(CDSentry)                                 */      {        struct cds FAR *cdsp = get_cds(r.callerARG1 & 0xff);        if (cdsp == NULL)        {          r.FLAGS |= FLG_CARRY;          break;        }        r.DS = FP_SEG(cdsp);        r.SI = FP_OFF(cdsp);        r.FLAGS &= ~FLG_CARRY;        break;      }    case 0x18:                 /* get caller's registers */      r.DS = FP_SEG(user_r);      r.SI = FP_OFF(user_r);      break;    case 0x1b:                 /* #days in February - valid until 2099. */      r.AL = (r.CL & 3) ? 28 : 29;      break;    case 0x20:                 /* get job file table entry */      {        psp FAR *p = MK_FP(cu_psp, 0);        unsigned char FAR *idx;        if (r.BX >= p->ps_maxfiles)        {          r.AL = -DE_INVLDHNDL;          r.FLAGS |= FLG_CARRY;          break;        }        idx = &p->ps_filetab[r.BX];        r.FLAGS &= ~FLG_CARRY;        r.ES = FP_SEG(idx);        r.DI = FP_OFF(idx);      }      break;    case 0x21:                 /* truename */      DosTruename(MK_FP(r.DS, r.SI), MK_FP(r.ES, r.DI));      break;    case 0x23:                 /* check if character device */      {        struct dhdr FAR *dhp;        dhp = IsDevice((BYTE FAR *) DirEntBuffer.dir_name);        if (dhp == NULL)        {          r.FLAGS |= FLG_CARRY;          break;        }        r.BH = dhp->dh_attr;        r.FLAGS &= ~FLG_CARRY;      }      break;    case 0x25:                 /* get length of asciiz string */      r.CX = fstrlen(MK_FP(r.DS, r.SI)) + 1;      break;    case 0x26:                 /* open file */      r.FLAGS &= ~FLG_CARRY;      CritErrCode = SUCCESS;      lrc = DosOpen(MK_FP(r.DS, r.DX), O_LEGACY | O_OPEN | r.CL, 0);      goto long_check;    case 0x27:                 /* close file */      r.FLAGS &= ~FLG_CARRY;      CritErrCode = SUCCESS;      rc = DosClose(r.BX);      goto short_check;    case 0x28:                 /* move file pointer */      /*       * RBIL says: "sets user stack frame pointer to dummy buffer,       * moves BP to AX, performs LSEEK, and restores frame pointer"       * We obviously don't do it like that. Does this do any harm?! --L.G.       */      r.FLAGS &= ~FLG_CARRY;      CritErrCode = SUCCESS;      if (r.BP < 0x4200 || r.BP > 0x4202)        goto error_invalid;#if 0      {        sft FAR *s = get_sft(r.BX);        if ((rc = _SftSeek(s, MK_ULONG(r.CX, r.DX), r.BP & 0xff)) >= SUCCESS)        {          r.DX = hiword (s->sft_posit);          r.AX = loword (s->sft_posit);        }      }      goto short_check;#else        goto error_invalid;#endif    case 0x29:                 /* read from file */      r.FLAGS &= ~FLG_CARRY;      CritErrCode = SUCCESS;      lrc = DosRead(r.BX, r.CX, MK_FP(r.DS, r.DX));      goto long_check;    case 0x2a:                 /* Set FastOpen but does nothing. */      r.FLAGS &= ~FLG_CARRY;      break;    case 0x2c:                 /* added by James Tabor For Zip Drives                                   Return Null Device Pointer          */      /* by UDOS+RBIL: get header of SECOND device driver in device chain,          omitting the NUL device TE */      r.BX = FP_SEG(nul_dev.dh_next);      r.AX = FP_OFF(nul_dev.dh_next);      break;    case 0x2e:                 /* GET or SET error table addresse - ignored                                   called by MS debug with  DS != DOSDS, printf                                   doesn't work!! */      break;    case 0x2f:      if (r.DX)      {        os_setver_major = r.DL;        os_setver_minor = r.DH;      }      else      {        os_setver_major = os_major;        os_setver_minor = os_minor;      }      break;    default:      if (r.AL <= 0x31)      {        put_string("unimplemented internal dos function INT2F/12");        put_unsigned(r.AL, 16, 2);        put_string("\n");        r.FLAGS |= FLG_CARRY;      }  }  return;long_check:  if (lrc >= SUCCESS)  {    r.AX = (UWORD)lrc;    return;  }  rc = (int)lrc;short_check:  if (rc < SUCCESS)    goto error_exit;  return;error_invalid:  rc = DE_INVLDFUNC;error_exit:  r.AX = -rc;  if (CritErrCode == SUCCESS)    CritErrCode = r.AX;      /* Maybe set */  r.FLAGS |= FLG_CARRY;}/* * 2000/09/04  Brian Reifsnyder * Modified interrupts 0x25 & 0x26 to return more accurate error codes. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -