mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
209 lines
5.4 KiB
C
209 lines
5.4 KiB
C
|
|
/****************************************************************
|
|
* *
|
|
* CP/M-68K BDOS Disk Read/Write Module *
|
|
* *
|
|
* This module contains functions to perform sequential *
|
|
* or random access read or write to the disk for CP/M-68K *
|
|
* *
|
|
* It includes the following external functions: *
|
|
* *
|
|
* seqread() - sequential disk read *
|
|
* *
|
|
* *
|
|
* Compiled with Alcyon C on the VAX *
|
|
* *
|
|
****************************************************************/
|
|
|
|
#include "stdio.h" /* Standard I/O declarations */
|
|
|
|
#include "bdosdef.h" /* Type and structure declarations for BDOS */
|
|
|
|
|
|
/* External function definitions */
|
|
EXTERN UWORD rdsec(); /* disk read routine */
|
|
EXTERN WORD swap(); /* assembly language byte swapper */
|
|
EXTERN UWORD dirscan(); /* directory scanning routine */
|
|
EXTERN BOOLEAN openfile(); /* open file function passed to dirscan */
|
|
|
|
|
|
/**********************************************************/
|
|
/* First, some utility functions used by seqio and ranio */
|
|
/**********************************************************/
|
|
|
|
/******************************
|
|
* FCB block number routines *
|
|
******************************/
|
|
|
|
WORD blkindx(fcbp)
|
|
/* return index into fcb disk map */
|
|
|
|
REG struct fcb *fcbp; /* pointer to fcb */
|
|
{
|
|
REG struct dpb *dparmp; /* pointer to disk parameter block */
|
|
REG WORD i;
|
|
REG WORD blkshf;
|
|
BSETUP
|
|
|
|
dparmp = GBL.parmp;
|
|
blkshf = dparmp->bsh;
|
|
i = ((fcbp->extent) & dparmp->exm) << (7 - blkshf);
|
|
return (i + (UBWORD(fcbp->cur_rec) >> blkshf) );
|
|
}
|
|
|
|
|
|
UWORD blknum(fcbp, index, wrdfcb)
|
|
/* return block number in fcb indicated by index */
|
|
|
|
REG struct fcb *fcbp; /* pointer to fcb */
|
|
REG WORD index; /* index into disk map of fcb */
|
|
WORD wrdfcb; /* boolean, fcb disk map of words? */
|
|
{
|
|
if (wrdfcb)
|
|
return( swap(fcbp->dskmap.big[index]) );
|
|
else return( UBWORD(fcbp->dskmap.small[index]) );
|
|
}
|
|
|
|
|
|
/*********************
|
|
* disk read routine *
|
|
*********************/
|
|
|
|
UWORD do_io(block, rcrd)
|
|
|
|
UWORD block; /* block number */
|
|
UBYTE rcrd; /* record number */
|
|
{
|
|
LONG lsec;
|
|
REG struct dpb *dparmp;
|
|
BSETUP
|
|
|
|
dparmp = GBL.parmp; /* init dpb pointer */
|
|
lsec = ((LONG)block << (dparmp->bsh)) +
|
|
(LONG)(rcrd & (dparmp->blm));
|
|
return( rdsec(lsec, GBL.dmaadr) );
|
|
}
|
|
|
|
|
|
/*******************************************
|
|
* routine for crossing extent boundaries *
|
|
*******************************************/
|
|
|
|
WORD new_ext(fcbp)
|
|
/* If sequential I/O, open the next extent */
|
|
|
|
REG struct fcb *fcbp; /* pointer to fcb */
|
|
{
|
|
REG UBYTE mod; /* module number */
|
|
REG UBYTE ext; /* extent number */
|
|
BSETUP
|
|
|
|
mod = (fcbp->s2) & 0x3f;
|
|
ext = (fcbp->extent) + 1; /* for sequential, incr extent */
|
|
if (ext >= 32)
|
|
{
|
|
ext = 0;
|
|
mod += 1;
|
|
}
|
|
if (mod >= 64) return(6); /* past maximum file size */
|
|
if ( mod == ((fcbp->s2) & 0x3f) )
|
|
if ( ! ((ext ^ (fcbp->extent)) & ~((GBL.parmp)->exm) & 0x1f) )
|
|
{ /* we're in same logical extent */
|
|
fcbp->extent = ext;
|
|
return(0);
|
|
}
|
|
/* Extent or Module numbers don't match */
|
|
/* Close the old extent and open a new one */
|
|
fcbp->s2 = mod;
|
|
fcbp->extent = ext;
|
|
if ( dirscan(openfile, fcbp) >= 255 ) /* open new extent */
|
|
return(4); /* reading unwritten extent */
|
|
return(0);
|
|
}
|
|
|
|
|
|
/************************************
|
|
* Routine to calculate the maximum *
|
|
* extent number of an FCB in a *
|
|
* extent-folded environment *
|
|
************************************/
|
|
|
|
UWORD calcext(fcbp)
|
|
|
|
REG struct fcb *fcbp;
|
|
|
|
{
|
|
REG UWORD i;
|
|
REG BYTE *p;
|
|
BSETUP
|
|
|
|
i = 15;
|
|
p = &(fcbp->dskmap.small[16]);
|
|
do
|
|
{
|
|
if (*--p) break;
|
|
i -= 1;
|
|
} while (i);
|
|
/* Now i contains the index of the last non-zero block in the FCB */
|
|
if ((GBL.parmp)->dsm > 255) i >>= 1;
|
|
i >>= 7 - ((GBL.parmp)->bsh);
|
|
return ( (fcbp->extent) & ~((GBL.parmp)->exm) & 0x1f | i );
|
|
}
|
|
|
|
|
|
/*********************************
|
|
* Routine to get the actual *
|
|
* record count of the currently *
|
|
* active logical extent of a FCB *
|
|
*********************************/
|
|
|
|
UWORD get_rc(fcbp)
|
|
|
|
REG struct fcb *fcbp;
|
|
|
|
{
|
|
REG UWORD ext;
|
|
|
|
ext = calcext(fcbp); /* find last active extent in fcb */
|
|
if (ext == fcbp->extent) return(UBWORD(fcbp->rcdcnt));
|
|
/* if this is the last active fcb, return fcb's rc */
|
|
else if (ext > fcbp->extent) return(128);
|
|
/* if the fcb has more extents past this one, then */
|
|
/* the current one is logically full */
|
|
else return (0);
|
|
/* if we seeked past the last active extent, rc = 0 */
|
|
}
|
|
|
|
|
|
/************************
|
|
* seqread entry point *
|
|
************************/
|
|
|
|
UWORD seqread(fcbp)
|
|
|
|
REG struct fcb *fcbp; /* fcbp is a pointer to a fcb */
|
|
|
|
{
|
|
REG UWORD block; /* block number from fcb */
|
|
REG WORD index; /* index into disk map of fcb */
|
|
REG WORD parm; /* parameter to do-io */
|
|
REG WORD bigfile; /* file system is in word mode */
|
|
BSETUP
|
|
|
|
bigfile = ((GBL.parmp)->dsm) & ~0xff;
|
|
if (fcbp->cur_rec == 128)
|
|
{ /* time to try next extent */
|
|
if ( new_ext(fcbp) )
|
|
return(1); /* if can't open new extent, error */
|
|
fcbp->cur_rec = 0; /* opened new extent, zero cur_rec */
|
|
}
|
|
if ( UBWORD(fcbp->cur_rec) >= get_rc(fcbp) )
|
|
return(1); /* this is end of file */
|
|
index = blkindx(fcbp); /* get index into fcb disk map */
|
|
block = blknum(fcbp, index, bigfile);
|
|
if ( ! block) /* no data allocated at that position */
|
|
return(1); /* reading unwritten data */
|
|
return( do_io(block, (fcbp->cur_rec)++) );
|
|
}
|
|
|