32V/usr/src/standalone/tdcopy.c

Compare this file to the similar file:
Show the results in this format:

#include "MBA.h"
#include "RP.h"
#include "TM.h"
# include "CON.h"
# define BLKMAX  32768
# define MIN(a,b) (a<b?a:b)
#define MAXTER 10  /*  max. no. consec. tape errors */
/*		*/
int blksiz , tfoff , tboff , dboff , tunit , dens ;
int count , *tmMBA , *rpMBA , dblks , wsize ;
unsigned int ins , outs ;
unsigned int nread  , bytoff , error ;
int *RPptr , *TMptr ;
int rpcyl,rptrk,rpsec;
char input[150] , *bufptr , retry ;
/*		*/
main() {
register int i ;
/*
*  Stand-alone program to copy TM[23]/TE16 mag tape to
*  RP06/RM03 disk.
*  User specifies tape and disk MBA no.'s, tape and disk unit no.'s,
*  tape block size, tape file offset, tape block offset in file,
*  and disk sector offset.
*/

putlin("tdcopy : TM03 tape-to-disk copy") ;
putnl() ;
 
tmbno :
count = getval("tape MBA #") ;
if ((count < 0) || (count > MAXMBA-1)) goto tmbno ;
tmMBA = TMptr = (int *)(M_BASE + (count*NEXSPC)) ; /* TM02 MBA addr */
 
tuni :
tunit = getval("tape unit #") ;
if ((tunit < 0) || (tunit > 7)) goto tuni ;
TMptr = (int *)((int)TMptr + (tunit*EXTSIZ) + M_extern) ; /*  ptr. to MBA
		ext. reg set for this TM02 unit */
 
/*
*  ignore density prompt for tape read - TM02 recognizes and adjusts
*  for NRZ or PE input (800 or 1600 BPI)
gden :
dens = getval("tape density(8 or 16)") ;
if (dens == 0) dens = TM_D800 ;
else if ((dens != 8)&&(dens!=16)) goto gden ;
*/
dens = (dens==16?TM_D1600:TM_D800) ;
 
toff :
tfoff = getval("tape file offset") ;
if (tfoff < 0) goto toff ;
 
gtbo :
tboff = getval("tape block offset") ;
if (tboff < 0) goto gtbo ;
putnl() ;
 
gdm :
count = getval("disk MBA #") ;
if ((count < 0) || (count > MAXMBA-1)) goto gdm ;
rpMBA = RPptr = (int *)(M_BASE + (count*NEXSPC)) ; /* RP06 MBA addr */
 
dun :
count = getval("disk unit") ;
if ((count > 7) || (count < 0)) goto dun ;
RPptr = (int *)((int)RPptr +  (count*EXTSIZ) + M_extern) ; /* ptr to MBA ext reg set for
			this RP06 unit */
 
doff :
dboff = getval("disk block offset") ;
putnl() ;
 
gknt :
count = getval("no. of input blocks") ;
if (count < 0) goto gknt ;
 
if (init()) {
	putlin("init() error") ;
	return(-1) ;
	}
 
if ((dboff < 0) || (dboff > MAXSEC-1)) goto doff ;
 
if (tapfil(TMptr,tfoff)) {
	tioerr :
	putlin("tape positioning error") ;
	return(-1) ;
	}
if (tapfsp(TMptr,tboff)) goto tioerr ;
 
/* read in 1st block of tape file to determine block size */
nread = 1 ;
blksiz = 65536 ;
for (retry=0,i=10,error=0;i;i--) {
	if ((tread()&TM_FCE) != TM_FCE) {
		if (++error > MAXTER)
			goto tioerr;
		}
	else break ;
	}
retry++;
blksiz = (*(TMptr+TM_fc)) & 0xffff ;
pdstr(" = tape block size",blksiz) ;
nread = M_BCMAX/blksiz ; /* no. of tape reads to fill input buffer */
wsize = nread * blksiz ; /* no. bytes each write to disc */
dblks = wsize/512 ; /* no. of disc blocks on each write */
*(TMptr+TM_cs1) = TM_DCLR | TM_GO ;
twait(TMptr) ;
if (tapbsp(TMptr,1)) goto tioerr ;
putnl() ;
 
for (error = 0 ; (error == 0) && (count > 0) ; count -= nread ) {
	if (i=tread(TMptr)) {
		putlin("tape i/o error") ;
		TME_print(i) ;
		goto ioerr ;
		}
	ins += nread ;  /*  count of tape blocks input */
	if (i=dwrite(RPptr)) {
		putlin("disk i/o error") ;
		RPE_print(i) ;
		ioerr :
			error++ ;
			continue ;
		}
	outs += dblks ;  /*  count of disk blocks output */
}
 
fini :
/*  no rewind on normal termination */
if (error == 0) putlin("normal termination") ;
else taprew(TMptr) ;
pdstr(" input blocks read",ins) ;
pdstr(" output blocks written",outs) ;
return(0) ;
}
 
/*		*/
 
init() {
/*
*  Initialization.
*  Initialize MBA's and tape/disk units.
*  Initialize TM2/TE16 for drive 0 , 800 BPI, PDP11, etc.
*  Set up MBA  map registers to map a max.
*    transfer of 'M_BCMAX' bytes.
*/
register int *mp0 , *mp1 , i , page ;
extern char *end ;
 
*(rpMBA+M_cr) = MBAinit ; /* init. RP06 MBA */
if (rpMBA != tmMBA)
	*(tmMBA+M_cr) = MBAinit ;
if ((*(RPptr+RP_sr) & RP_MOL) == 0) {
	putlin("disk unit not online") ;
	return(-1) ;
	}
 
*(RPptr+RP_cr) = RP_RIP | RP_GO ; /* preset */
dwait(RPptr) ;
if (i=derror(RPptr)) {
	putlin("disk init error") ;
	RPE_print(i) ;
	return(-1) ;
	}
*(RPptr+RP_off) = RP_FMT ; /* set format bit */
 
i = *(RPptr+RP_dt)&0777 ;  /* get disk type */
if (i==RP6typ) { /* RP06 */
	rpsec=RP6SEC; rpcyl=RP6CYL; rptrk=RP6TRK;
	}
else {
	if (i==RM3typ) {
		rpsec=RM3SEC; rpcyl=RM3CYL; rptrk=RM3TRK;
		}
	else return(-1);
	}
 
/* set TM03 unit no., density, PDP11 normal mode, odd parity
	abort on error */
*(TMptr+TM_tc) = tunit | dens | TM_PNOR | TM_EABO ;
*(TMptr+TM_cs1) = TM_DCLR | TM_GO ;
twait(TMptr) ;
if (i=terror(TMptr)) {
	tierr :
	putlin("tape init error") ;
	TME_print(i) ;
	return(-1) ;
	}
if ((*(TMptr+TM_ds) & TM_MOL) == 0) {
	putlin("tape unit not online") ;
	return(-1) ;
	}
*(TMptr+TM_cs1) = TM_RWND | TM_GO ;
twait(TMptr) ;
if (i=terror(TMptr)) goto tierr ;
 
bufptr = (char *)((((int)&end)+511)&017777777000) ;
page = ((int)((int)bufptr>>9)&017777777) | 0x80000000 ; /* SBI page no. */
mp0 = (int *)((int)tmMBA + (int)(M_map*4)) ;
mp1 = (int *)((int)rpMBA + (int)(M_map*4)) ;
for (i = ((M_BCMAX+511)/512)+1 ; i ; i--,page++) {
	(*mp0++) = page ;
	(*mp1++) = page ;
	}
return(0) ;
}
 
/*		*/
 
tread()
{
/*
*  Function to read TM2/TE16 tape drive, 'blksiz' bytes each
*  read, and 'nread' reads.
*/
register int i, j , k , *t , *m , teknt ;
 
m = tmMBA ;
t = TMptr ;
for (i=MIN(nread,count),j=0,teknt=0 ; i ; i--,j++) {
	trloop :
	*(m+M_var) = j * blksiz ;
	*(m+M_bc) = (-blksiz) ; /* MBA byte count reg */
	*(t+TM_cs1) = TM_REDF | TM_GO ; /* read forward */
	twait(t) ; /* wait for ready */
	if (k=terror(t)) {
		if ((++teknt > MAXTER) || (retry == 0)) return(k);
		*(t+TM_cs1) = TM_DCLR | TM_GO ;
		twait(t);
		if (k=tapbsp(t,1)) return(k);
		goto trloop;
		}
	}
return(0) ; /* normal return */
}
 
/*		*/
 
dwrite()
{
/*
*  Function to write 'wsize' bytes to disc
*  from buffer '*bufptr'.
*/
register int i , j , *m , *d ;
 
m = rpMBA ;
d = RPptr ;
*(d+RP_cr) = RP_DC | RP_GO ; /* drive clear */
dwait(d) ;
*(d+RP_cyl) = dboff/RP6ST ; /* cylinder no. */
i = dboff%RP6ST ;
j = (i/rpsec)<<8 ; /* track */
*(d+RP_stk) = j | (i%rpsec) ; /* sector : track */
*(m+M_bc) = (count<nread?-(count*512):(-wsize)) ; /* byte count */
*(m+M_var) = 0 ; /* virt addr reg = map no. + byte off */
*(d+RP_cr) = RP_WR | RP_GO ;
dwait(d) ;
if (i=derror(d)) return(i) ; /* error */
dboff += dblks ;  /*  point to next disc sector */
return(0) ; /* normal return */
}