mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
Upload
Digital Research
This commit is contained in:
155
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/clib/channels.c
Normal file
155
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/clib/channels.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* C H A N N E L A L L O C A T I N G R O U T I N E S
|
||||
* -----------------------------------------------------
|
||||
* Copyright 1984 by Digital Research Inc. All rights reserved.
|
||||
*
|
||||
* Herein are all the routines which deal with Channel Control Block
|
||||
* (CCB) allocation and initialization. These routines (documented
|
||||
* individually below) are:
|
||||
*
|
||||
* i = _allocc();
|
||||
* _freec(i);
|
||||
* _chinit();
|
||||
* __chinit(fd)
|
||||
* ccbptr = _chkc(ch);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include "portab.h" /* Include std definitions */
|
||||
#include "osif.h" /* Also CP/M ones */
|
||||
#include "osiferr.h" /* To set error vars */
|
||||
#include "errno.h" /* Error return vals */
|
||||
|
||||
#ifdef MAXF5 /*--------------------------*/
|
||||
# define MAXCCBS 5 /* Maximum Num CCBs */
|
||||
maxfiles5() { ; } /* stubroutine for option.h */
|
||||
#else /*--------------------------*/
|
||||
|
||||
#ifdef MAXF10 /*--------------------------*/
|
||||
# define MAXCCBS 10 /* Maximum Num CCBs */
|
||||
#else /*--------------------------*/
|
||||
# define MAXCCBS 16 /* Maximum Num CCBs */
|
||||
#endif /*--------------------------*/
|
||||
|
||||
#endif /*--------------------------*/
|
||||
|
||||
LONG _chvec ={0}; /* Allocate storage */
|
||||
FD _fds[MAXCCBS]; /* Allocate CCB storage */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* _ A L L O C C / _ F R E E C R O U T I N E S
|
||||
* -------------------------------------------------
|
||||
* Routines "_allocc" and "_freec" are used to allocate / deallocate a
|
||||
* channel number so that the user may do I/O directly without the OTS
|
||||
* getting in the way.
|
||||
* Note that this scheme preserves compatibility with OS's that really
|
||||
* truly use channels, and allows users to inform the C Run Time Library
|
||||
* routines that they are using the channel.
|
||||
* It's not important to use these routines under CP/M, since CP/M
|
||||
* allows you to have as many FCBs as you wish.
|
||||
*
|
||||
* Calling Sequence:
|
||||
* i = _allocc();
|
||||
* _freec(i);
|
||||
*****************************************************************************/
|
||||
|
||||
WORD _allocc() /****************************/
|
||||
{ /* */
|
||||
REG WORD i; /* Define 2 temporaries */
|
||||
REG LONG j; /* */
|
||||
/* */
|
||||
j = 1; /* Start with channel 0 */
|
||||
for(i=0;i<MAXCCBS;i++) /* Look at the bits */
|
||||
{ /* */
|
||||
if((j & _chvec) == 0) /* If 0, then channel free */
|
||||
{ /* */
|
||||
_chvec |= j; /* set allocated bit */
|
||||
return(i); /* and return the channel # */
|
||||
} /* */
|
||||
j <<= 1; /* Up to next bit */
|
||||
} /* End FOR loop */
|
||||
RETERR(FAILURE,EMFILE); /* All channels in use! */
|
||||
} /****************************/
|
||||
|
||||
WORD _freec(ch) /****************************/
|
||||
WORD ch; /* Channel number to free */
|
||||
{ /* */
|
||||
_chvec &= ~(1 << ch); /* Clear appropriate bit */
|
||||
return(SUCCESS); /* Return OK */
|
||||
} /****************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* C C B I N I T I A L I Z A T I O N
|
||||
* -----------------------------------
|
||||
* Routine "_chinit" is called from the run-time initialization to clear
|
||||
* out all the CCB storage.
|
||||
* Calling sequence:
|
||||
* _chinit();
|
||||
*
|
||||
* Routine "__chinit(fd)" is called from other low-level routines
|
||||
* for single channel initialization.
|
||||
* Calling sequence:
|
||||
* __chinit(fd)
|
||||
* where: fd = file descriptor #
|
||||
*****************************************************************************/
|
||||
|
||||
_chinit() /****************************/
|
||||
{ /* */
|
||||
REG WORD i; /* Index */
|
||||
for(i=0;i<MAXCCBS;i++) /* For all channels */
|
||||
__chinit(i); /* Init fds(i); */
|
||||
} /****************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* The __chinit routine initializes only 1 channel.
|
||||
*****************************************************************************/
|
||||
|
||||
__chinit(i)
|
||||
{ /****************************/
|
||||
REG FD *ch; /* -> CCB */
|
||||
REG BYTE *p; /* Byte pointer temporary */
|
||||
|
||||
ch = _getccb(i); /* convert fd to CCB */
|
||||
ch -> chan = i; /* Load channel byte */
|
||||
ch -> flags = 0; /* clear flag word */
|
||||
ch -> user = 0; /* assume user 0 */
|
||||
ch -> sector = -1; /* Set no sector in buff */
|
||||
ch -> offset = 0; /* Clear file offset word */
|
||||
ch -> hiwater = 0; /* Init hiwater mark */
|
||||
ch -> fcb.drive = 0; /* Init drive field of fcb */
|
||||
p = &ch->fcb.fname[0]; /* Set to file var */
|
||||
while (p< &ch->fcb.ftype[3]) /* Init file name fields */
|
||||
*p++ = ' '; /* To spaces */
|
||||
while (p < &ch->fcb.record) /* Init rest of fcb */
|
||||
*p++ = 0; /* To zeros */
|
||||
} /****************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* C H A N N E L N U M B E R V A L I D A T I O N
|
||||
* -------------------------------------------------
|
||||
* This routine is used to validate a channel number and return the
|
||||
* pointer to the ccb area. The channel must be in range and open.
|
||||
*
|
||||
* Calling Sequence:
|
||||
*
|
||||
* Where:
|
||||
* ch Is the channel number
|
||||
* ccbptr Is the returned ccb address, NULLFD if error
|
||||
*****************************************************************************/
|
||||
|
||||
FD *_chkc(ch) /****************************/
|
||||
REG UWORD ch; /* Facilitate error check */
|
||||
{ /* */
|
||||
REG FD *xcb; /* -> CCB */
|
||||
/****************************/
|
||||
if(ch >= MAXCCBS) /* Is channel in range? */
|
||||
RETERR(NULLFD,EBADF); /* No, quit now. */
|
||||
/* */
|
||||
xcb = _getccb(ch); /* xcb -> ccb for channel */
|
||||
if((xcb->flags & OPENED) == 0) /* Is channel OPEN? */
|
||||
RETERR(NULLFD,EBADF); /* Noooooooo!! */
|
||||
return(xcb); /* Else, return pointer */
|
||||
} /****************************/
|
Reference in New Issue
Block a user