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