Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.2 SOURCE/6/BLKIO.C
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

118 lines
4.8 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***************************************************************************
*
* _ b l k i o F u n c t i o n
* -----------------------------
* Copyright 1982,1983 by Digital Research Inc. All rights reserved.
*
* The _blkio function is used to read / write a set of contiguous
* sectors in an open file.
* Note: if CPM, it will use CP/M function 44 (Set Multi-Sector Count)
* if os_multisectorio is TRUE (BDOS versions 3.0 and above).
* Note 2: if PC-DOS, it will use block read and write functions.
*
* Edits:
* 8-Dec-83 whf handle PC-DOS changes.
*
* Calling Sequence:
* ret = _blkio(ccbp,sector,buffer,count,bdosfunc);
*
* Where:
* ret = sectors actually read/written
* ccbp -> the open file channel control block
* sector = The desired starting sector number
* buffer = The memory address to begin transfer
* count = the number of sectors to read/write
* bdosfunc= The BDOS function number (B_READ / B_WRITE)
*
****************************************************************************/
#include "portab.h"
#include "osif.h"
#include "osiferr.h"
#include "osattr.h"
#define MIN(x,y) ( ((x) < (y)) ? (x) : (y) )
LONG
_blkio(ccbp,sector,buffer,count,bdosfunc)
/****************************/
FD *ccbp; /* open file pointer */
LONG sector; /* Sector number */
BYTE *buffer; /* User's buffer area */
LONG count; /* # of sectors to do */
int bdosfunc; /* BDOS function to use */
{ /****************************/
#if PCDOS /*=============================================================*/
REG WORD seccnt; /* number sectors xferred */
WORD _pc_readblk(), _pc_writeblk(); /* functions to read/write */
if( bdosfunc == B_READ )
return _pc_readblk(&(ccbp->fcb),sector,buffer,(WORD)count,SECSIZ);
else return _pc_writeblk(&(ccbp->fcb),sector,buffer,(WORD)count,SECSIZ);
}
#endif /*==============================================================*/
#if CPM /*==============================================================*/
WORD nsecs; /* # secs to xfer each time */
LONG seccnt; /* # sectors processed */
WORD xuser; /* old user number */
WORD retcode; /* return code from BDOS */
WORD Used_Multisec; /* flag for resetting msecio*/
/****************************/
seccnt = 0; /* Zero count initally */
Used_Multisec = 0; /* Haven't used it yet */
xuser = _chkuser(ccbp->user); /* Check for changed user # */
nsecs = 1; /* default: xfer singly */
/* */
while (count > 0) /* Until all sectors xferred*/
{ /* */
__OSIF(SETDMA,buffer); /* Set new DMA address */
#if HILO /*==========================================================*/
ccbp->fcb.record = sector; /* Set new record number */
#else /*----------------------------------------------------------*/
ccbp->fcb.record = sector << 8; /* Set new record number */
#endif /*==========================================================*/
/* Multi Sector I/O xfer? */
if( (count > 1 && os_multisectorio ) || nsecs > 1 )
{ /* yes! */
if( os_oldmultisec )
nsecs = MIN(16,count); /* Older version of msecio */
else nsecs = MIN(128,count);/* Later version of msecio */
++Used_Multisec; /* Flag: need to reset */
__OSIF(F_MULTISEC,nsecs); /* make the call */
} /******* */
/****************************/
retcode = __OSIF(bdosfunc,&(ccbp->fcb));/* do the read/write*/
/****************************/
if(retcode != 0)
{ /****************************/
if(nsecs>1) /* were we trying multi-sec?*/
{ /* yes! do error handling */
if( os_oldmultisec ) /* Older msecio? */
nsecs = __cpmrv >> 12; /* adjust nsecs read like so*/
else nsecs = __cpmrv >> 8;/* later versions: use AH */
} /*** */
else nsecs = 0; /* ow. assume 0 secs read */
seccnt += nsecs; /* Return nfg */
break; /* Return from bottom */
} /****************************/
/* */
sector += nsecs; /* Increment sector number */
count -= nsecs; /* Down count */
seccnt += nsecs; /* Bump sector count */
buffer += nsecs*SECSIZ; /* Increment address */
} /****************************/
_uchkuser(ccbp->user,xuser); /* Reset user # if needed */
if( Used_Multisec ) /* Need to reset msecio? */
__OSIF(F_MULTISEC,1); /* then do so... */
return(seccnt); /* All is OK */
} /****************************/
#endif /*==================================================================*/
============*/
============*/