static char rcsid[] = "$Header: access.c,v 800.0 85/07/30 13:50:33 root Exp $";
static char sccsid[]="%W% %Y% %Q% %G%";

#include "defs.h"

MSG		ODDADR;
MSG		BADDAT;
MSG		BADTXT;
MAP		txtmap;
MAP		datmap;
INT		wtflag;
STRING		errflg;
INT		errno;
INT		pid;
POS		accessf();

/* file handling and access routines */

put(adr,space,value)
L_INT	adr;
{
	accessf(WT,adr,space,value);
}

POS	get(adr, space)
L_INT	adr;
{
	register unsigned data = accessf(RD,adr,space,0);
#ifdef BOOTSTRAP
	register unsigned temp;
	temp = data >> 8;		/* do a byte swap */
	data = ( ( data & 0xFF ) << 8 ) | temp;
	return( data );
#else
	return((data>>16)&0xFFFF);
#endif /* of ifdef BOOTSTRAP */
}

POS	chkget(n, space)
L_INT	n;
{
	register INT		w;

	w = get(n, space);
	chkerr();
	return(w);
}

POS	accessf(mode,adr,space,value)
L_INT	adr;
{
	INT	w, w1, pmode, rd, file, rmode;
	rd = mode==RD;

	IF space == NSP THEN return(0); FI

	IF pid		/* tracing on? */
	THEN IF (adr&01) ANDF !rd THEN error(ODDADR); FI
	     rmode = (space&DSP? RDUSER : RIUSER);
	     pmode = (space&DSP?(rd?RDUSER:WDUSER):(rd?RIUSER:WIUSER));
	     if (!rd)
	     {
		w1 = ptrace(rmode, pid, adr, 0);
		value = (w1&0xFFFF) | (value&0xFFFF0000);
	     }
	     w = ptrace(pmode, pid, (adr&~01), value);
	     IF adr&01
	     THEN w1 = ptrace(pmode, pid, (adr+1), value);
		  w = ((w<<8)&0xFFFF0000) | ((w1>>8)&0xFFFF);
	     FI
	     IF errno
	     THEN errflg = (space&DSP ? BADDAT : BADTXT);
	     FI
	     return(w);
	FI
	w = 0;
	IF mode==WT ANDF wtflag==0
	THEN	error("not in write mode");
	FI
	IF !chkmap(&adr,space)
	THEN return(0);
	FI
	file=(space&DSP?datmap.ufd:txtmap.ufd);
	IF longseek(file,adr)==0 ORF
	   (rd ? read(file,&w,2) : write(file,&value,2)) < 1
	THEN	errflg=(space&DSP?BADDAT:BADTXT);
	FI
	return(w);

}

chkmap(adr,space)
	register L_INT	*adr;
	register INT		space;
{
	register MAPPTR amap;
	amap=((space&DSP?&datmap:&txtmap));
	IF space&STAR ORF !within(*adr,amap->b1,amap->e1)
	THEN IF within(*adr,amap->b2,amap->e2)
	     THEN
#ifdef ADB_DEBUG
		if (adbdebug)
			fprintf(stderr,"adr 0x%x -2-> 0x%x\n",
				*adr,*adr + (amap->f2)-(amap->b2));
#endif ADB_DEBUG
		*adr += (amap->f2)-(amap->b2);
	     ELSE errflg=(space&DSP?BADDAT:BADTXT); return(0);
	     FI
	ELSE
#ifdef ADB_DEBUG
		if (adbdebug)
			fprintf(stderr,"adr 0x%x -1-> 0x%x\n",
				*adr,*adr + (amap->f1)-(amap->b1));
#endif ADB_DEBUG
		*adr += (amap->f1)-(amap->b1);
	FI
	return(1);
}

within(adr,lbd,ubd)
POS	adr, lbd, ubd;
{
	return(adr>=lbd && adr<ubd);
}
