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

📄 blockio.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************//*                                                              *//*                          blockio.c                           *//*                            DOS-C                             *//*                                                              *//*      Block cache functions and device driver interface       *//*                                                              *//*                      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.                                    *//*                                                              *//****************************************************************/#include "portab.h"#include "globals.h"#ifdef VERSION_STRINGSstatic BYTE *blockioRcsId =    "$Id: blockio.c,v 1.31 2004/04/20 18:43:03 bartoldeman Exp $";#endif#define b_next(bp) ((struct buffer FAR *)(MK_FP(FP_SEG(bp), bp->b_next)))#define b_prev(bp) ((struct buffer FAR *)(MK_FP(FP_SEG(bp), bp->b_prev)))#define bufptr(fbp) ((struct buffer FAR *)(MK_FP(FP_SEG(bp), fbp)))/************************************************************************//*                                                                      *//*                      block cache routines                            *//*                                                                      *//************************************************************************//* #define DISPLAY_GETBLOCK */STATIC BOOL flush1(struct buffer FAR * bp);/*    this searches the buffer list for the given disk/block.        returns:    a far pointer to the buffer.    If the buffer is found the UNCACHE bit is not set and else it is set.            new:        upper layer may set UNCACHE attribute        UNCACHE buffers are recycled first.        intended to be used for full sector reads into application buffer        resets UNCACHE upon a "HIT" -- so then this buffer will not be        recycled anymore.*/STATIC void move_buffer(struct buffer FAR *bp, size_t firstbp){  /* connect bp->b_prev and bp->b_next */  b_next(bp)->b_prev = bp->b_prev;  b_prev(bp)->b_next = bp->b_next;  /* insert bp between firstbp and firstbp->b_prev */  bp->b_prev = bufptr(firstbp)->b_prev;  bp->b_next = firstbp;  b_next(bp)->b_prev = FP_OFF(bp);  b_prev(bp)->b_next = FP_OFF(bp);}STATIC struct buffer FAR *searchblock(ULONG blkno, COUNT dsk){  int fat_count = 0;  struct buffer FAR *bp;  size_t lastNonFat = 0;  size_t uncacheBuf = 0;  seg bufseg = FP_SEG(firstbuf);  size_t firstbp = FP_OFF(firstbuf);#ifdef DISPLAY_GETBLOCK  printf("[searchblock %d, blk %ld, buf ", dsk, blkno);#endif  /* Search through buffers to see if the required block  */  /* is already in a buffer                               */  bp = MK_FP(bufseg, firstbp);  do  {    if ((bp->b_blkno == blkno) &&        (bp->b_flag & BFR_VALID) && (bp->b_unit == dsk))    {      /* found it -- rearrange LRU links      */#ifdef DISPLAY_GETBLOCK      printf("HIT %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp));#endif      bp->b_flag &= ~BFR_UNCACHE;  /* reset uncache attribute */      if (FP_OFF(bp) != firstbp)      {        *(UWORD *)&firstbuf = FP_OFF(bp);        move_buffer(bp, firstbp);      }      return bp;    }    if (bp->b_flag & BFR_UNCACHE)      uncacheBuf = FP_OFF(bp);    if (bp->b_flag & BFR_FAT)      fat_count++;    else      lastNonFat = FP_OFF(bp);    bp = b_next(bp);  } while (FP_OFF(bp) != firstbp);  /*     now take either the last buffer in chain (not used recently)     or, if we are low on FAT buffers, the last non FAT buffer   */  if (uncacheBuf)  {    bp = bufptr(uncacheBuf);  }  else if (bp->b_flag & BFR_FAT && fat_count < 3 && lastNonFat)  {    bp = bufptr(lastNonFat);  }  else  {    bp = b_prev(bufptr(firstbp));  }  bp->b_flag |= BFR_UNCACHE;  /* set uncache attribute */#ifdef DISPLAY_GETBLOCK  printf("MISS, replace %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp));#endif  if (FP_OFF(bp) != firstbp)          /* move to front */  {    move_buffer(bp, firstbp);    *(UWORD *)&firstbuf = FP_OFF(bp);  }  return bp;}BOOL DeleteBlockInBufferCache(ULONG blknolow, ULONG blknohigh, COUNT dsk, int mode){  struct buffer FAR *bp = firstbuf;          /* Search through buffers to see if the required block  */  /* is already in a buffer                               */  do  {    if (blknolow <= bp->b_blkno &&        bp->b_blkno <= blknohigh &&        (bp->b_flag & BFR_VALID) && (bp->b_unit == dsk))    {      if (mode == XFR_READ)        flush1(bp);      else        bp->b_flag = 0;    }    bp = b_next(bp);  }  while (FP_OFF(bp) != FP_OFF(firstbuf));  return FALSE;}#if TOMvoid dumpBufferCache(void){  struct buffer FAR *bp = firstbuf;  int printed = 0;  /* Search through buffers to see if the required block  */  /* is already in a buffer                               */  do  {    printf("%8lx %02x ", bp->b_blkno, bp->b_flag);    if (++printed % 6 == 0)      printf("\n");    bp = b_next(bp);  }  while (FP_OFF(bp) != FP_OFF(firstbuf));  printf("\n");}#endif/*                                                                      *//*      Return the address of a buffer structure containing the         *//*      requested block.                                                *//*      if overwrite is set, then no need to read first                 *//*                                                                      *//*      returns:                                                        *//*              requested block with data                               *//*      failure:                                                        *//*              returns NULL                                            *//*                                                                      */struct buffer FAR *getblk(ULONG blkno, COUNT dsk, BOOL overwrite){  /* Search through buffers to see if the required block  */  /* is already in a buffer                               */  struct buffer FAR *bp = searchblock(blkno, dsk);  if (!(bp->b_flag & BFR_UNCACHE))  {    return bp;  }  /* The block we need is not in a buffer, we must make a buffer  */  /* available, and fill it with the desired block                */  /* take the buffer that lbp points to and flush it, then read new block. */  if (!flush1(bp))    return NULL;  /* Fill the indicated disk buffer with the current track and sector */  if (!overwrite && dskxfer(dsk, blkno, bp->b_buffer, 1, DSKREAD))  {    return NULL;  }  bp->b_flag = BFR_VALID | BFR_DATA;  bp->b_unit = dsk;  bp->b_blkno = blkno;  return bp;}/*                                                                      *//*      Mark all buffers for a disk as not valid                        *//*                                                                      */VOID setinvld(REG COUNT dsk){  struct buffer FAR *bp = firstbuf;

⌨️ 快捷键说明

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