mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-22 16:04:18 +00:00
147 lines
6.3 KiB
C
147 lines
6.3 KiB
C
/***************************************************************************
|
||
*
|
||
* W r t b i n F u n c t i o n
|
||
* ------------------------------
|
||
* Copyright 1984, Digital Research Inc. All rights reserved.
|
||
*
|
||
* Function "wrtbin" is called from "write" to take advantage of a
|
||
* potential multi-sector transfer for binary files.
|
||
*
|
||
* Completely re-written 7 Feb 1984 whf.
|
||
*
|
||
* Calling sequence:
|
||
* ret = _wrtbin(fp,buffer,bytes);
|
||
*
|
||
* Where:
|
||
* fp Points to the affected ccb.
|
||
* buffer Is the buffer address
|
||
* bytes Is the number of bytes to write
|
||
*
|
||
* ret Is the number of bytes actually written
|
||
*
|
||
****************************************************************************/
|
||
|
||
#include "portab.h"
|
||
#include "osif.h"
|
||
#include "osiferr.h"
|
||
#include "errno.h"
|
||
|
||
#define NDEBUG
|
||
#include "assert.h"
|
||
|
||
#define OFFSECT (fp->offset & ~(SECSIZ-1))
|
||
#define HIWSECT (fp->hiwater-1 & ~(SECSIZ-1))
|
||
|
||
|
||
UWORD _wrtbin(fp,buff,bytes) /****************************/
|
||
/* */
|
||
REG FD *fp; /* -> CCB */
|
||
BYTE *buff; /* -> User's buffer */
|
||
UWORD bytes; /* # bytes to write */
|
||
{ /****************************/
|
||
|
||
#if PCDOS /*=============================================================*/
|
||
UWORD ii; /* Byte counter */
|
||
UWORD _pc_writeblk(); /* OS function Write Rnd Blk*/
|
||
/* */
|
||
ii = _pc_writeblk(&(fp->fcb),fp->offset,buff,(WORD)bytes,1); /* */
|
||
if( ii==0 ) /* Problems? */
|
||
RETERR(FAILURE,EIO); /* Tell them so */
|
||
fp->offset += ii; /* Incr pos in file */
|
||
if( fp->offset > fp->hiwater ) /* Need to advance? */
|
||
fp->hiwater = fp->offset; /* then do so */
|
||
return ii; /* Number written */
|
||
} /****************************/
|
||
#endif /*=============================================================*/
|
||
|
||
#if CPM /*=============================================================*/
|
||
REG UWORD nbs; /* counter */
|
||
UWORD xsector; /* Current sector */
|
||
UWORD nsector; /* Multi-sector count */
|
||
UWORD written; /* # bytes to written */
|
||
UWORD BufPos; /* Position in buffer */
|
||
/****************************/
|
||
/****************************/
|
||
written = 0; /* Num written so far */
|
||
/* Get buffer cleaned and */
|
||
/* current: */
|
||
xsector = fp->offset >> 7; /* Calculate present sector */
|
||
if(xsector != fp->sector) { /* Do sectors match? */
|
||
if(fp->flags & DIRTY) /* No, is buffer dirty? */
|
||
if(_blkio(fp,fp->sector,fp->buffer,1L,B_WRITE) != 1) /* */
|
||
RETERR(FAILURE,EIO); /* Couldn't write buffer */
|
||
if( OFFSECT > HIWSECT) /* Within the hiwater area? */
|
||
blkfill(fp->buffer,0,SECSIZ); /* No: Zero out the buffer */
|
||
else if(_blkio(fp,(LONG)xsector,fp->buffer,1L,B_READ) != 1)
|
||
RETERR(FAILURE,EIO); /* Can't preread buffer */
|
||
fp->flags &= ~DIRTY; /* Clear dirty bit */
|
||
fp->sector = xsector; /* Buffer labelled */
|
||
} /****************************/
|
||
/****************************/
|
||
/* Xfer data to buffer until*/
|
||
/* 1) end of data, */
|
||
/* 2) end of buffer, or */
|
||
/* 3) sector aligned multi- */
|
||
/* sector write. */
|
||
BufPos = fp->offset & (SECSIZ-1); /* Where are we in buffer? */
|
||
nbs = SECSIZ - BufPos; /* Room left in buffer */
|
||
if( nbs > bytes ) /* More room than we need? */
|
||
nbs = bytes; /* Adjust to bytes to xfer*/
|
||
else if( nbs == SECSIZ ) /* Sector aligned multi-sec?*/
|
||
nbs = 0; /* Don't buffer now. */
|
||
if( nbs > 0 ) { /* Any room/data to buffer? */
|
||
blkmove(fp->buffer+BufPos,buff,nbs);/* Move into write buffer */
|
||
written += nbs; /* Indicate we've written */
|
||
fp->offset += nbs; /* " " " */
|
||
buff += nbs; /* Ground we've covered */
|
||
bytes -= nbs; /* num bytes left to write */
|
||
if( BufPos + nbs != SECSIZ ) { /* Buffer full? */
|
||
fp->flags |= DIRTY; /* No, mark it */
|
||
fp->sector = xsector; /* Label buffer */
|
||
} else { /* */
|
||
if(_blkio(fp,(LONG)xsector,fp->buffer,1L,B_WRITE) != 1)
|
||
RETERR(FAILURE,EIO); /* Couldn't */
|
||
fp->flags &= ~DIRTY; /* turn off dirty bit */
|
||
fp->sector = -1; /* buffer clean */
|
||
xsector++; /* Bump sector counter */
|
||
} /****************************/
|
||
} /****************************/
|
||
/* */
|
||
/****************************/
|
||
if( bytes >= SECSIZ ) { /* Can we do multisector io?*/
|
||
nsector = bytes >> 7; /* divide by 128 for sectors*/
|
||
if(_blkio(fp,(LONG)xsector,buff,(LONG)nsector,B_WRITE) != nsector)
|
||
/* Multi-sector xfer */
|
||
RETERR(FAILURE,EIO); /* Just quit on error */
|
||
xsector += nsector; /* Update current sector */
|
||
nbs = nsector << 7; /* number bytes xferred */
|
||
written += nbs; /* Indicate we've written */
|
||
fp->offset += nbs; /* " " " */
|
||
buff += nbs; /* Ground we've covered */
|
||
bytes -= nbs; /* num bytes left to write */
|
||
} /****************************/
|
||
/****************************/
|
||
if( bytes > 0 ) { /* Any room/data to buffer? */
|
||
ASSERT( fp->flags & DIRTY == 0 ); /* Buffer should be clean */
|
||
if( OFFSECT > HIWSECT) /* Within the hiwater area? */
|
||
blkfill(fp->buffer,0,SECSIZ); /* No: Zero out the buffer */
|
||
else if(_blkio(fp,(LONG)xsector,fp->buffer,1L,B_READ) != 1)
|
||
RETERR(FAILURE,EIO); /* Can't preread buffer */
|
||
ASSERT( bytes < SECSIZ ); /* Should be cut to size */
|
||
blkmove(fp->buffer,buff,bytes); /* Move into write buffer */
|
||
fp->flags |= DIRTY; /* Mark buffer */
|
||
fp->sector = xsector; /* and label */
|
||
written += bytes; /* Indicate we've written */
|
||
fp->offset += bytes; /* " " " */
|
||
buff += bytes; /* Ground we've covered */
|
||
} /****************************/
|
||
/* */
|
||
if(fp->offset > fp->hiwater) /* See if above hiwater mark*/
|
||
fp->hiwater = fp->offset; /* Fix if necessary */
|
||
return written; /* Return requested # */
|
||
} /****************************/
|
||
|
||
#endif /*=============================================================*/
|
||
=====*/
|
||
=====*/
|