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

📄 blockio.c

📁 开源DOS的C代码源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
  do
  {
    if (bp->b_unit == dsk)
      bp->b_flag = 0;
    bp = b_next(bp);
  }
  while (FP_OFF(bp) != FP_OFF(firstbuf));
}

/*                                                                      */
/*                      Flush all buffers for a disk                    */
/*                                                                      */
/*      returns:                                                        */
/*              TRUE on success                                         */
/*                                                                      */
BOOL flush_buffers(REG COUNT dsk)
{
  struct buffer FAR *bp = firstbuf;
  REG BOOL ok = TRUE;

  bp = firstbuf;
  do
  {
    if (bp->b_unit == dsk)
      if (!flush1(bp))
        ok = FALSE;
    bp = b_next(bp);
  }
  while (FP_OFF(bp) != FP_OFF(firstbuf));
  return ok;
}

/*                                                                      */
/*      Write one disk buffer                                           */
/*                                                                      */
STATIC BOOL flush1(struct buffer FAR * bp)
{
/* All lines with changes on 9/4/00 by BER marked below */

  UWORD result;                 /* BER 9/4/00 */

  if ((bp->b_flag & (BFR_VALID | BFR_DIRTY)) == (BFR_VALID | BFR_DIRTY))
  {
    /* BER 9/4/00  */
    result = dskxfer(bp->b_unit, bp->b_blkno, bp->b_buffer, 1, DSKWRITE);
    if (bp->b_flag & BFR_FAT)
    {
      UWORD b_copies = bp->b_copies;
      ULONG blkno = bp->b_blkno;
#ifdef WITHFAT32
      ULONG b_offset = bp->b_offset;
      if (b_offset == 0) /* FAT32 FS */
        b_offset = bp->b_dpbp->dpb_xfatsize;
#else
      UWORD b_offset = bp->b_offset;
#endif
      while (--b_copies > 0)
      {
        blkno += b_offset;
        /* BER 9/4/00 */
        result = dskxfer(bp->b_unit, blkno, bp->b_buffer, 1, DSKWRITE);
      }
    }
  }
  else
    result = 0;                 /* This negates any error code returned in result...BER */
  /* and 0 returned, if no errors occurred - tom          */
  bp->b_flag &= ~BFR_DIRTY;     /* even if error, mark not dirty */
  if (result != 0)              /* otherwise system has trouble  */
    bp->b_flag &= ~BFR_VALID;   /* continuing.           */
  return (TRUE);                /* Forced to TRUE...was like this before dskxfer()  */
  /* returned error codes...BER */
}

/*                                                                      */
/*      Write all disk buffers                                          */
/*                                                                      */
BOOL flush(void)
{
  REG struct buffer FAR *bp = firstbuf;
  REG BOOL ok;

  ok = TRUE;
  do
  {
    if (!flush1(bp))
      ok = FALSE;
    bp->b_flag &= ~BFR_VALID;
    bp = b_next(bp);
  }
  while (FP_OFF(bp) != FP_OFF(firstbuf));

  network_redirector(REM_FLUSHALL);

  return (ok);
}

/************************************************************************/
/*                                                                      */
/*              Device Driver Interface Functions                       */
/*                                                                      */
/************************************************************************/
/*                                                                      */
/* Transfer one or more blocks to/from disk                             */
/*                                                                      */

UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
              COUNT mode)
{
  register struct dpb FAR *dpbp = get_dpb(dsk);
  if (dpbp == NULL)
  {
    return 0x0201;              /* illegal command */
  }

#if TOM
#define KeyboardShiftState() (*(BYTE FAR *)(MK_FP(0x40,0x17)))

  if (KeyboardShiftState() & 0x01)
  {
    printf("dskxfer:%s %x - %lx %u\n", mode == DSKWRITE ? "write" : "read",
           dsk, blkno, numblocks);
    if ((KeyboardShiftState() & 0x03) == 3)
      dumpBufferCache();
  }
#endif

  for (;;)
  {
    IoReqHdr.r_length = sizeof(request);
    IoReqHdr.r_unit = dpbp->dpb_subunit;

    switch (mode)
    {
      case DSKWRITE:
        if (verify_ena)
        {
          IoReqHdr.r_command = C_OUTVFY;
          break;
        }
        /* else fall through */
      case DSKWRITEINT26:
        IoReqHdr.r_command = C_OUTPUT;
        break;

      case DSKREADINT25:
      case DSKREAD:
        IoReqHdr.r_command = C_INPUT;
        break;
      default:
        return 0x0100;          /* illegal command */
    }

    IoReqHdr.r_status = 0;
    IoReqHdr.r_meddesc = dpbp->dpb_mdb;
    IoReqHdr.r_count = numblocks;
    if ((dpbp->dpb_device->dh_attr & ATTR_HUGE) || blkno >= MAXSHORT)
    {
      IoReqHdr.r_start = HUGECOUNT;
      IoReqHdr.r_huge = blkno;
    }
    else
      IoReqHdr.r_start = (UWORD)blkno;
    /*
     * Some drivers normalise transfer address so HMA transfers are disastrous!
     * Then transfer block through xferbuf (DiskTransferBuffer doesn't work!)
     * (But this won't work for multi-block HMA transfers... are there any?)
     */
    if (FP_SEG(buf) >= 0xa000 && numblocks == 1 && bufloc != LOC_CONV)
    {
      IoReqHdr.r_trans = deblock_buf;
      if (mode == DSKWRITE)
        fmemcpy(deblock_buf, buf, SEC_SIZE);
      execrh((request FAR *) & IoReqHdr, dpbp->dpb_device);
      if (mode == DSKREAD)
        fmemcpy(buf, deblock_buf, SEC_SIZE);
    }
    else
    {
      IoReqHdr.r_trans = (BYTE FAR *) buf;
      execrh((request FAR *) & IoReqHdr, dpbp->dpb_device);
    }
    if ((IoReqHdr.r_status & (S_ERROR | S_DONE)) == S_DONE)
      break;

    /* INT25/26 (_SEEMS_ TO) return immediately with 0x8002,
       if drive is not online,...

       normal operations (DIR) wait for ABORT/RETRY

       other condition codes not tested
     */
    if (mode >= DSKWRITEINT26)
      return (IoReqHdr.r_status);

  loop:
    switch (block_error(&IoReqHdr, dpbp->dpb_unit, dpbp->dpb_device, mode))
    {
      case ABORT:
      case FAIL:
        return (IoReqHdr.r_status);

      case RETRY:
        continue;

      case CONTINUE:
        break;

      default:
        goto loop;
    }
    break;
  }                             /* retry loop */
/* *** Changed 9/4/00  BER */
  return 0;                     /* Success!  Return 0 for a successful operation. */
/* End of change */

}

/*
       this removes any (additionally allocated) buffers 
       from the HMA buffer chain, because they get allocated to the 'user'
*/     
     
void AllocateHMASpace (size_t lowbuffer, size_t highbuffer)
{
  REG struct buffer FAR *bp = firstbuf;
  int n;

  if (FP_SEG(bp) != 0xffff)
    return;

  n = LoL_nbuffers;
  do
  {
    /* check if buffer intersects with requested area                  */
    if (FP_OFF(bp) < highbuffer && FP_OFF(bp+1) > lowbuffer)
    {
      flush1(bp);
      /* unlink bp from buffer chain */

      b_prev(bp)->b_next = bp->b_next;
      b_next(bp)->b_prev = bp->b_prev;
      if (FP_OFF(bp) == FP_OFF(firstbuf))
        firstbuf = b_next(bp);
      LoL_nbuffers--;
    }
    bp = b_next(bp);
  }
  while (--n);
}

⌨️ 快捷键说明

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