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

📄 inthndlr.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************//*                                                              *//*                          inthndlr.c                          *//*                                                              *//*    Interrupt Handler and Function dispatcher for Kernel      *//*                                                              *//*                      Copyright (c) 1995                      *//*                      Pasquale J. Villani                     *//*                      All Rights Reserved                     *//*                                                              *//* This file is part of DOS-C.                                  *//*                                                              *//* DOS-C is free software; you can redistribute it and/or       *//* modify it under the terms of the GNU General Public License  *//* as published by the Free Software Foundation; either version *//* 2, or (at your option) any later version.                    *//*                                                              *//* DOS-C is distributed in the hope that it will be useful, but *//* WITHOUT ANY WARRANTY; without even the implied warranty of   *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See    *//* the GNU General Public License for more details.             *//*                                                              *//* You should have received a copy of the GNU General Public    *//* License along with DOS-C; see the file COPYING.  If not,     *//* write to the Free Software Foundation, 675 Mass Ave,         *//* Cambridge, MA 02139, USA.                                    *//*                                                              *//****************************************************************/#define MAIN#include "portab.h"#include "globals.h"#include "nls.h"#ifdef VERSION_STRINGSBYTE *RcsId =    "$Id: inthndlr.c,v 1.96 2006/05/20 20:50:44 mceric Exp $";#endif#ifdef TSCSTATIC VOID StartTrace(VOID);static bTraceNext = FALSE;#endif#if 0                           /* Very suspicious, passing structure by value??                                   Deactivated -- 2000/06/16 ska *//* Special entry for far call into the kernel                           */#pragma argsusedVOID FAR int21_entry(iregs UserRegs){  int21_handler(UserRegs);}#endif/* Structures needed for int 25 / int 26 */struct HugeSectorBlock {  ULONG blkno;  WORD nblks;  BYTE FAR *buf;};/* Normal entry.  This minimizes user stack usage by avoiding local     *//* variables needed for the rest of the handler.                        *//* this here works on the users stack !! and only very few functions    are allowed                                                          */VOID ASMCFUNC int21_syscall(iregs FAR * irp){  Int21AX = irp->AX;  switch (irp->AH)  {    /* Set Interrupt Vector                                         */    case 0x25:      setvec(irp->AL, (intvec)MK_FP(irp->DS, irp->DX));      break;      /* DosVars - get/set dos variables                              */    case 0x33:      switch (irp->AL)      {          /* Get Ctrl-C flag                                      */        case 0x00:          irp->DL = break_ena;          break;          /* Set Ctrl-C flag                                      */        case 0x01:          break_ena = irp->DL & 1;          break;        case 0x02:             /* andrew schulman: get/set extended control break  */          {            UBYTE tmp = break_ena;            break_ena = irp->DL & 1;            irp->DL = tmp;          }          break;          /* Get Boot Drive                                       */        case 0x05:          irp->DL = BootDrive;          break;          /* Get (real) DOS-C version                             */        case 0x06:          irp->BL = os_major;          irp->BH = os_minor;          irp->DL = rev_number;          irp->DH = version_flags;      /* bit3:runs in ROM,bit 4: runs in HMA */          break;        case 0x03:             /* DOS 7 does not set AL */        case 0x07:             /* neither here */        default:               /* set AL=0xFF as error, NOT carry */          irp->AL = 0xff;          break;	  /* set FreeDOS returned version for int 21.30 from BX */	case 0xfc:             /* 0xfc ... 0xff are FreeDOS extensions */	  os_setver_major = irp->BL;	  os_setver_minor = irp->BH;	  break;          /* Toggle DOS-C rdwrblock trace dump                    */#ifdef DEBUG        case 0xfd:          bDumpRdWrParms = !bDumpRdWrParms;          break;#endif          /* Toggle DOS-C syscall trace dump                      */#ifdef DEBUG        case 0xfe:          bDumpRegs = !bDumpRegs;          break;#endif          /* Get DOS-C release string pointer                     */        case 0xff:          irp->DX = FP_SEG(os_release);          irp->AX = FP_OFF(os_release);      }      break;    /* Get Interrupt Vector                                           */    case 0x35:    {      intvec p = getvec(irp->AL);      irp->ES = FP_SEG(p);      irp->BX = FP_OFF(p);      break;    }      /* Set PSP                                                      */    case 0x50:      cu_psp = irp->BX;      break;      /* Get PSP                                                      */    case 0x51:      /* UNDOCUMENTED: return current psp                             */    case 0x62:      irp->BX = cu_psp;      /* Normal DOS function - DO NOT ARRIVE HERE          */ /* default: */  }}#ifdef WITHFAT32      /* DOS 7.0+ FAT32 extended functions */int int21_fat32(lregs *r){  COUNT rc;    switch (r->AL)  {    /* Get extended drive parameter block */    case 0x02:    {      struct dpb FAR *dpb;      struct xdpbdata FAR *xddp;          if (r->CX < sizeof(struct xdpbdata))        return DE_INVLDBUF;      dpb = GetDriveDPB(r->DL, &rc);      if (rc != SUCCESS)        return rc;      /* hazard: no error checking! */      flush_buffers(dpb->dpb_unit);      dpb->dpb_flags = M_CHANGED;       /* force reread of drive BPB/DPB */          if (media_check(dpb) < 0)        return DE_INVLDDRV;          xddp = MK_FP(r->ES, r->DI);            fmemcpy(&xddp->xdd_dpb, dpb, sizeof(struct dpb));      xddp->xdd_dpbsize = sizeof(struct dpb);      /* if it doesn't look like an extended DPB, fill in those fields */      if (!ISFAT32(dpb) && dpb->dpb_xsize != dpb->dpb_size)      {        xddp->xdd_dpb.dpb_nfreeclst_un.dpb_nfreeclst_st.dpb_nfreeclst_hi =          (dpb->dpb_nfreeclst == 0xFFFF ? 0xFFFF : 0);        dpb16to32(&xddp->xdd_dpb);        xddp->xdd_dpb.dpb_xfatsize = dpb->dpb_fatsize;        xddp->xdd_dpb.dpb_xcluster = (dpb->dpb_cluster == 0xFFFF ?                       0xFFFFFFFFuL : dpb->dpb_cluster);      }      break;    }    /* Get extended free drive space */    case 0x03:    {      struct xfreespace FAR *xfsp = MK_FP(r->ES, r->DI);          if (r->CX < sizeof(struct xfreespace))        return DE_INVLDBUF;      rc = DosGetExtFree(MK_FP(r->DS, r->DX), xfsp);      if (rc != SUCCESS)        return rc;      xfsp->xfs_datasize = sizeof(struct xfreespace);      xfsp->xfs_version.actual = 0;      break;    }    /* Set DPB to use for formatting */    case 0x04:    {      struct xdpbforformat FAR *xdffp = MK_FP(r->ES, r->DI);      struct dpb FAR *dpb;      if (r->CX < sizeof(struct xdpbforformat))      {        return DE_INVLDBUF;      }      dpb = GetDriveDPB(r->DL, &rc);      if (rc != SUCCESS)        return rc;            xdffp->xdff_datasize = sizeof(struct xdpbforformat);      xdffp->xdff_version.actual = 0;          switch ((UWORD) xdffp->xdff_function)      {        case 0x00:        {          ULONG nfreeclst = xdffp->xdff_f.setdpbcounts.nfreeclst;          ULONG cluster = xdffp->xdff_f.setdpbcounts.cluster;          if (ISFAT32(dpb))          {            if ((dpb->dpb_xfsinfosec == 0xffff                 && (nfreeclst != 0 || cluster != 0))                || nfreeclst == 1 || nfreeclst > dpb->dpb_xsize                || cluster == 1 || cluster > dpb->dpb_xsize)            {              return DE_INVLDPARM;            }            dpb->dpb_xnfreeclst = nfreeclst;            dpb->dpb_xcluster = cluster;            write_fsinfo(dpb);          }          else          {            if ((unsigned)nfreeclst == 1 || (unsigned)nfreeclst > dpb->dpb_size ||                (unsigned)cluster == 1 || (unsigned)cluster > dpb->dpb_size)            {              return DE_INVLDPARM;            }            dpb->dpb_nfreeclst = (UWORD)nfreeclst;            dpb->dpb_cluster = (UWORD)cluster;          }          break;        }        case 0x01:        {          ddt *pddt = getddt(r->DL);          fmemcpy(&pddt->ddt_bpb, xdffp->xdff_f.rebuilddpb.bpbp,                  sizeof(bpb));        }        case 0x02:        {        rebuild_dpb:            /* hazard: no error checking! */          flush_buffers(dpb->dpb_unit);          dpb->dpb_flags = M_CHANGED;                    if (media_check(dpb) < 0)            return DE_INVLDDRV;          break;        }        case 0x03:        {          struct buffer FAR *bp;          bpb FAR *bpbp;          DWORD newmirroring =            xdffp->xdff_f.setmirroring.newmirroring;                if (newmirroring != -1              && (ISFAT32(dpb)                  && (newmirroring & ~(0xf | 0x80))))          {            return DE_INVLDPARM;          }          xdffp->xdff_f.setmirroring.oldmirroring =            (ISFAT32(dpb) ? dpb->dpb_xflags : 0);          if (newmirroring != -1 && ISFAT32(dpb))          {            bp = getblock(1, dpb->dpb_unit);            bp->b_flag &= ~(BFR_DATA | BFR_DIR | BFR_FAT);            bp->b_flag |= BFR_VALID | BFR_DIRTY;            bpbp = (bpb FAR *) & bp->b_buffer[BT_BPB];            bpbp->bpb_xflags = (UWORD)newmirroring;          }          goto rebuild_dpb;        }        case 0x04:        {          struct buffer FAR *bp;          bpb FAR *bpbp;          DWORD rootclst = xdffp->xdff_f.setroot.newrootclst;          if (!ISFAT32(dpb)              || (rootclst != -1                  && (rootclst == 1                      || (ULONG)rootclst > dpb->dpb_xsize)))          {            return DE_INVLDPARM;          }          xdffp->xdff_f.setroot.oldrootclst = dpb->dpb_xrootclst;          if (rootclst != -1)          {            bp = getblock(1, dpb->dpb_unit);            bp->b_flag &= ~(BFR_DATA | BFR_DIR | BFR_FAT);            bp->b_flag |= BFR_VALID | BFR_DIRTY;            bpbp = (bpb FAR *) & bp->b_buffer[BT_BPB];            bpbp->bpb_xrootclst = rootclst;          }          goto rebuild_dpb;        }      }          break;    }    /* Extended absolute disk read/write */    /* TODO(vlp) consider using of the 13-14th bits of SI */    case 0x05:    {      struct HugeSectorBlock FAR *SectorBlock =        (struct HugeSectorBlock FAR *)MK_FP(r->DS, r->BX);      UBYTE mode;            if (r->CX != 0xffff || ((r->SI & 1) == 0 && r->SI != 0)          || (r->SI & ~0x6001))      {        return DE_INVLDPARM;      }          if (r->DL > lastdrive || r->DL == 0)        return -0x207;          if (r->SI == 0)        mode = DSKREADINT25;      else        mode = DSKWRITEINT26;          r->AX =        dskxfer(r->DL - 1, SectorBlock->blkno, SectorBlock->buf,                SectorBlock->nblks, mode);          if (mode == DSKWRITEINT26)        if (r->AX <= 0)          setinvld(r->DL - 1);            if (r->AX > 0)        return -0x20c;      break;    }  default:    return DE_INVLDFUNC;  }  return SUCCESS;}#endifVOID ASMCFUNC int21_service(iregs FAR * r){  COUNT rc;  long lrc;  lregs lr; /* 8 local registers (ax, bx, cx, dx, si, di, ds, es) */#define FP_DS_DX (MK_FP(lr.DS, lr.DX))#define FP_ES_DI (MK_FP(lr.ES, lr.DI))#define CLEAR_CARRY_FLAG()  r->FLAGS &= ~FLG_CARRY#define SET_CARRY_FLAG()    r->FLAGS |= FLG_CARRY  ((psp FAR *) MK_FP(cu_psp, 0))->ps_stack = (BYTE FAR *) r;  fmemcpy(&lr, r, sizeof(lregs) - 4);  lr.DS = r->DS;  lr.ES = r->ES;dispatch:#ifdef DEBUG  if (bDumpRegs)  {    fmemcpy(&error_regs, user_r, sizeof(iregs));    printf("System call (21h): %02x\n", user_r->AX);    dump_regs = TRUE;    dump();  }#endif  if ((lr.AH >= 0x38 && lr.AH <= 0x4F) || (lr.AH >= 0x56 && lr.AH <= 0x5c) ||      (lr.AH >= 0x5e && lr.AH <= 0x60) || (lr.AH >= 0x65 && lr.AH <= 0x6a) ||      lr.AH == 0x6c)  {    CLEAR_CARRY_FLAG();    if (lr.AH != 0x59)      CritErrCode = SUCCESS;  }  /* Clear carry by default for these functions */  /* Check for Ctrl-Break */  if (break_ena || (lr.AH >= 1 && lr.AH <= 5) || (lr.AH >= 8 && lr.AH <= 0x0b))    check_handle_break(&syscon);  /* The dispatch handler                                         */  switch (lr.AH)  {      /* int 21h common error handler                                 */    case 0x64:    	goto error_invalid;      /* case 0x00:   --> Simulate a DOS-4C-00 */      /* Read Keyboard with Echo                      */    case 0x01:  DOS_01:      lr.AL = read_char_stdin(TRUE);      write_char_stdout(lr.AL);      break;      /* Display Character                                            */    case 0x02:  DOS_02:      lr.AL = lr.DL;      write_char_stdout(lr.AL);      break;      /* Auxiliary Input                                                      */    case 0x03:    {      int sft_idx = get_sft_idx(STDAUX);      lr.AL = read_char(sft_idx, sft_idx, TRUE);      break;    }      /* Auxiliary Output                                                     */    case 0x04:      write_char(lr.DL, get_sft_idx(STDAUX));      break;      /* Print Character                                                      */    case 0x05:      write_char(lr.DL, get_sft_idx(STDPRN));      break;      /* Direct Console I/O                                            */    case 0x06:  DOS_06:      if (lr.DL != 0xff)        goto DOS_02;      lr.AL = 0x00;      r->FLAGS |= FLG_ZERO;      if (StdinBusy()) {        DosIdle_int();        break;      }      r->FLAGS &= ~FLG_ZERO;      /* fall through */      /* Direct Console Input                                         */    case 0x07:  DOS_07:      lr.AL = read_char_stdin(FALSE);      break;      /* Read Keyboard Without Echo                                   */    case 0x08:  DOS_08:      lr.AL = read_char_stdin(TRUE);      break;      /* Display String                                               */    case 0x09:      {        unsigned char c;        unsigned char FAR *bp = FP_DS_DX;        while ((c = *bp++) != '$')

⌨️ 快捷键说明

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