home *** CD-ROM | disk | FTP | other *** search
- /* databuff.c - Buffer management routines */
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- /* |_o_o|\\ Copyright (c) 1988 The Software Distillery. All Rights Reserved */
- /* |. o.| || This program may not be distributed without the permission of */
- /* | . | || the authors: BBS: (919) 481-6436 */
- /* | o | || John Toebes John Mainwaring Jim Cooper */
- /* | . |// Bruce Drake Gordon Keener Dave Baker */
- /* ====== */
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /* Buffer management routines : */
- /* ModBlock GetBlock */
- /* FindBuffer AllocBuffers FreeBuffers FlushBuffers FlushOne */
-
- #include "handler.h"
-
- char *GetBlock(global, key)
- GLOBAL global;
- KEY key;
- {
- int i;
-
- i = FindBuffer(global, key, 1);
-
- if (i == -1)
- return(NULL);
-
- BUG(("GetBlock: Key %ld Buff %08lx\n", key, global->blkbuf[i].bb_blk));
- return(global->blkbuf[i].bb_blk);
- }
-
- char *ModBlock(global, key)
- GLOBAL global;
- KEY key;
- {
- int i;
-
- /* Make sure we have the rights to write to the disk */
- if (global->diskstate != ID_VALIDATED)
- {
- BUG(("ModBlock - Write protected disk\n"));
- global->pkt->dp_Res1 = DOS_FALSE;
- global->pkt->dp_Res2 = ERROR_DISK_WRITE_PROTECTED;
- return(NULL);
- }
-
- /* Locate the block in a buffer */
- i = FindBuffer(global, key, 1);
-
- /* Gee, it wasn't found, just return an error */
- if (i == -1)
- return(NULL);
-
- /* Mark it as having been touched so we flush it later */
- global->blkbuf[i].bb_dirty = 1;
-
- BUG(("ModBlock: Key %ld Buff %08lx\n", key, global->blkbuf[i].bb_blk));
- return(global->blkbuf[i].bb_blk);
- }
-
- int FindBuffer(global, key, readin)
- register GLOBAL global;
- KEY key;
- int readin;
- {
- register int i;
- int num;
- struct BlockBuffer *tmpglob;
-
- /* First pass, go through and see if it is already in a buffer */
- for (i = 0; i< global->dskenv.de_numbufs; i++)
- {
- if (global->blkbuf[i].bb_key == key &&
- global->blkbuf[i].bb_used)
- {
- if (global->blkbuf[i].bb_priority < 0xff)
- global->blkbuf[i].bb_priority++;
- return(i);
- }
- }
-
- /* For some reason it wasn't in a buffer already (imagine that). So we */
- /* want to go through and decrement all the priorities of the buffers */
- /* and select a candidate for flushing to hold our new block. Note that */
- /* an empty buffer is assumed to have a priority of 0 while a buffer in */
- /* use will never be decremented below 1 */
- tmpglob = &global->blkbuf[0];
- num = 0;
- for (i = 0; i < global->dskenv.de_numbufs; i++)
- {
- if (global->blkbuf[i].bb_used &&
- (global->blkbuf[i].bb_priority > 1))
- global->blkbuf[i].bb_priority--;
-
- if (global->blkbuf[i].bb_priority < tmpglob->bb_priority)
- {
- tmpglob = &global->blkbuf[i];
- num = i;
- }
- }
-
- /* Now tmpglob points to our new buffer. Empty it out if necessary */
- FlushOne(global, num);
-
- /* Mark it for the new buffer that we want to use it as */
- tmpglob->bb_used = 1;
- tmpglob->bb_key = key;
- tmpglob->bb_priority = global->dskenv.de_numbufs;
- tmpglob->bb_dirty = 0; /* Hopefully FlushOne reset it but who knows */
-
- /* Did they ask us to read it in? */
- if (readin)
- {
- if (ReadPhy(global, tmpglob->bb_blk, key))
- {
- BUG(("Failure reading in key %ld\n", key));
- tmpglob->bb_used = 0;
- tmpglob->bb_key = -1;
- tmpglob->bb_priority = 0;
- num = -1; /* indicate the failure */
- }
- }
-
- return(num);
- }
- void FreeBlkBuffs(global)
- GLOBAL global;
- {
- BUG(("FreeBlkBuffs\n"));
- FreeMem((char *)global->blkbuf,((sizeof(struct BlockBuffer))*
- (global->dskenv.de_numbufs)));
- global->blkbuf = NULL;
- }
-
- int AllocBlkBuffs(global, newsize)
- GLOBAL global;
- int newsize;
- {
- struct BlockBuffer *tmpbuff;
- int i;
-
- BUG(("AllocBlkBuffs size:%ld\n",newsize));
- if ((tmpbuff = (struct BlockBuffer *)AllocMem(((sizeof(struct BlockBuffer))
- * newsize),(MEMF_PUBLIC | MEMF_CLEAR)))== NULL){
- BUG(("AllocBlkBuffs Failed\n"));
- return(0);
- }
- /* successfully allocated copy stuff over and free old */
- if (global->blkbuf){
- for(i=0;i < (global->dskenv.de_numbufs);i++){
- if (i < newsize){
- tmpbuff[i].bb_blk = global->blkbuf[i].bb_blk;
- }
- if (i >= newsize){
- FreeMem(global->blkbuf[i].bb_blk,
- ((global->dskenv.de_sizeblock) * BYTESPERLONG));
- }
- }
- FreeBlkBuffs(global);
- }
- BUG(("Allocated blk buffs at:%08lx\n",tmpbuff));
- /* allocate memory for data blocks */
- for(i=0;i < newsize;i++){
- if (tmpbuff[i].bb_blk == NULL){
- if((tmpbuff[i].bb_blk = (char *)
- AllocMem(((global->dskenv.de_sizeblock) * BYTESPERLONG),
- global->dskenv.de_membuftype))==NULL){
- /* we will loose some bytes here for now */
- global->dskenv.de_numbufs = i;
- return(NULL);
- }
- }
- tmpbuff[i].bb_key = -1;
- }
- global->blkbuf = tmpbuff;
- global->dskenv.de_numbufs = newsize;
- return(-1);
- }
-
- void FlushOne(global, num)
- GLOBAL global;
- int num;
- {
- /* Does this buffer need to be written out to disk ? */
- if (global->blkbuf[num].bb_dirty &&
- global->blkbuf[num].bb_used)
- {
- /* Ok, see if it needs to be checksummed */
- if (global->blkbuf[num].bb_used != ST_BITMAP)
- DoCheckSum(global, global->blkbuf[num].bb_blk);
-
- /* At last we get to write out the block */
- while(WritePhy(global,
- global->blkbuf[num].bb_blk, global->blkbuf[num].bb_key))
- {
- if (!request(global, REQ_ERROR, NULL))
- break;
- ResetDrive(global);
- }
- }
-
- /* Now we need to reset it so it doesn't get written out again */
- global->blkbuf[num].bb_dirty = 0;
-
- }
-
- void FlushBuffers(global, purge)
- GLOBAL global;
- int purge;
- {
- register int i;
-
- for (i = 0; i < global->dskenv.de_numbufs; i++)
- {
- FlushOne(global, i);
-
- /* Did they want us to forget about when we are done ? */
- if (purge)
- {
- /* If we don't want the buffer any more we need to zap it */
- global->blkbuf[i].bb_used = 0;
- global->blkbuf[i].bb_key = -1;
- global->blkbuf[i].bb_priority = 0;
- }
- }
- }
-