home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
200-299
/
ff236.lzh
/
DiskHandler
/
databuff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-08-09
|
7KB
|
228 lines
/* 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;
}
}
}