mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 16:34:07 +00:00
116 lines
4.8 KiB
C
116 lines
4.8 KiB
C
/***************************************************************************
|
|
*
|
|
* _ 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 /*==================================================================*/
|