mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 01:14:21 +00:00
Upload
Digital Research
This commit is contained in:
173
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/clib/writebin.c
Normal file
173
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/clib/writebin.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* W r t b i n F u n c t i o n
|
||||
* ------------------------------
|
||||
*
|
||||
* Function "wrtbin" is called from "write" to take advantage of a
|
||||
* potential multi-sector transfer for binary files.
|
||||
*
|
||||
* 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 OFFSECT (fp->offset & ~(SECSIZ-1))
|
||||
#define HIWSECT (fp->hiwater-1 & ~(SECSIZ-1))
|
||||
|
||||
|
||||
UWORD _wrtbin(fp,buff,bytes) /****************************/
|
||||
/* */
|
||||
REG FD *fp; /* -> CCB */
|
||||
REG BYTE *buff; /* -> User's buffer */
|
||||
REG 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 /*=============================================================*/
|
||||
LOCAL LONG xsector; /* Sector temp */
|
||||
LOCAL LONG nsector; /* Multi-sector count */
|
||||
LOCAL LONG written; /* # bytes to write */
|
||||
REG BYTE *p1; /* Temp buffer pointer */
|
||||
/****************************/
|
||||
written = bytes; /* Remember request length */
|
||||
xsector = fp->offset >> 7; /* Calculate present sector */
|
||||
/****************************/
|
||||
if((fp -> offset & (SECSIZ-1)) != 0) /* Are we at a boundary? */
|
||||
{ /* */
|
||||
if(xsector != fp->sector) /* No, do sectors match? */
|
||||
{ /* */
|
||||
if((fp->flags & DIRTY) != 0) /* No, is buffer dirty? */
|
||||
{ /* */
|
||||
if(_blkio(fp,fp->sector, /* */
|
||||
fp->buffer,1L,B_WRITE) != 1) /* Yes, write it */
|
||||
RETERR(FAILURE,EIO); /* Couldn't write buffer */
|
||||
fp->flags &= ~DIRTY; /* Clear dirty bit */
|
||||
} /****************************/
|
||||
/* */
|
||||
if( OFFSECT <= HIWSECT) /* Within the hiwater area? */
|
||||
/* MGL */
|
||||
{ /* If yes, then read it */
|
||||
if(_blkio(fp,xsector,fp->buffer, /* */
|
||||
1L,B_READ) != 1) /* Try to read the correct */
|
||||
RETERR(FAILURE,EIO); /* Can't */
|
||||
} /****************************/
|
||||
else _wrtclear(fp->buffer,SECSIZ); /* Zero out the buffer */
|
||||
/* */
|
||||
fp->sector = xsector; /* Label buffer */
|
||||
/* */
|
||||
} /****************************/
|
||||
p1 = &fp->buffer[(int)fp->offset&(SECSIZ-1)];/* 1st loc in buffer */
|
||||
/* */
|
||||
while( p1 < fp->buffer+SECSIZ && /* while still in buffer */
|
||||
bytes > 0) /* And still writing */
|
||||
{ /* */
|
||||
*p1++ = *buff++; /* Move a byte */
|
||||
bytes--; /* Decrement counter */
|
||||
} /****************************/
|
||||
if (bytes <= 0) /* Byte count exhausted?? */
|
||||
{ /* */
|
||||
if( p1 == fp->buffer+SECSIZ ) /* buffer full? */
|
||||
{ /* yes... */
|
||||
if(_blkio(fp,xsector,fp->buffer,1L, /* Write full buffer */
|
||||
B_WRITE) != 1) /* */
|
||||
RETERR(FAILURE,EIO); /* Couldn't */
|
||||
fp->flags &= ~DIRTY; /* turn off dirty bit */
|
||||
} else fp->flags |= DIRTY; /* Yes, buffer is now dirty */
|
||||
fp->offset += written; /* fix offset */
|
||||
if(fp->offset > fp->hiwater) /* See if above hiwater mark*/
|
||||
fp->hiwater = fp->offset; /* Fix if necessary */
|
||||
return(written); /* Return original byte cnt */
|
||||
} /****************************/
|
||||
if(_blkio(fp,xsector,fp->buffer,1L, /* Write full buffer */
|
||||
B_WRITE) != 1) /* */
|
||||
RETERR(FAILURE,EIO); /* Couldn't */
|
||||
xsector++; /* Bump sector counter */
|
||||
} /* End boundary problem code*/
|
||||
/****************************/
|
||||
/* */
|
||||
/************************************************* */
|
||||
/* The observant reader will note that after the above malarkey, we are now */
|
||||
/* aligned on a sector boundary. The following code exploits the oppor- */
|
||||
/* tunity to do a multi-sector write. */
|
||||
/************************************************* */
|
||||
/* */
|
||||
nsector = bytes >> 7; /* divide by 128 for sectors*/
|
||||
if(nsector > 0) /* Check for no more left */
|
||||
{
|
||||
if ( (xsector <= fp->sector) ||
|
||||
(fp->sector < xsector+nsector) )
|
||||
{
|
||||
fp->flags &= ~DIRTY;
|
||||
fp->sector = -1;
|
||||
}
|
||||
if(_blkio(fp,xsector,buff, /* */
|
||||
nsector,B_WRITE) != nsector) /* Multi-sector xfer */
|
||||
RETERR(FAILURE,EIO); /* Just quit on error */
|
||||
}
|
||||
/****************************/
|
||||
bytes -= (nsector << 7); /* Subtract multi-sector */
|
||||
/* Byte count */
|
||||
buff += (nsector << 7); /* Update address */
|
||||
fp->offset += written; /* Update offset now */
|
||||
/* (All I/O is complete) */
|
||||
if(fp->offset > fp->hiwater) /* Fix up hiwater mark */
|
||||
fp->hiwater = fp->offset; /* */
|
||||
if(bytes == 0) /* If done, */
|
||||
return(written); /* return success */
|
||||
/****************************/
|
||||
if((fp->flags & DIRTY) != 0) /* Is buffer dirty? */
|
||||
{ /* Test (again) here in case*/
|
||||
if(_blkio(fp,fp->sector, /* of boundary condition */
|
||||
fp->buffer,1L,B_WRITE) != 1) /* Yes, write it */
|
||||
RETERR(FAILURE,EIO); /* Couldn't write buffer */
|
||||
} /****************************/
|
||||
fp -> flags |= DIRTY; /* Let's dirty the buffer */
|
||||
fp -> sector = fp -> offset >> 7; /* Mark sector number */
|
||||
if( OFFSECT <= HIWSECT ) /* Sector in high water area*/
|
||||
/* MGL */
|
||||
_blkio(fp,fp->sector,fp->buffer,1L, /* Read sector */
|
||||
B_READ); /* */
|
||||
else _wrtclear(fp->buffer,SECSIZ);
|
||||
p1 = &(fp->buffer[0]); /* p1 -> address */
|
||||
while(bytes > 0) /* Move the bytes */
|
||||
{ /* */
|
||||
*p1++ = *buff++; /* One at a time */
|
||||
bytes--; /* Decrement count */
|
||||
} /****************************/
|
||||
/* */
|
||||
return(written); /* Return requested # */
|
||||
} /****************************/
|
||||
|
||||
MLOCAL _wrtclear(ptr,bytes)
|
||||
REG BYTE *ptr;
|
||||
REG WORD bytes;
|
||||
{
|
||||
while (bytes-- > 0)
|
||||
*ptr++ = 0;
|
||||
}
|
||||
#endif /*=============================================================*/
|
||||
Reference in New Issue
Block a user