/*
 * MAC  Version 2.0           Author :  Vincent Hayward
 *                                      School of Electrical Engineering
 *                                      Purdue University
 *      Dir     : h
 *      File    : jcom.h
 *      Remarks : Set of macros for lsi11 / joint proc communication
 *                Defines the DRV11 // interface adress.
 *      Usage   : Included for joint processor control
 */

#define CSR     (unsigned short *)0176770
#define OBUF    (unsigned short *)0176772
#define IBUF    (unsigned short *)0176774

/****************************************************************************/
/*                                                                          */
/*                         External I/O Group                               */
/*                                                                          */
/****************************************************************************/


/*       modify by oring the contents of latch buffers of devices           */

#define bisio(d) \
((*CSR) = 0, (*OBUF) = CNTRLR, (*CSR)++, (*OBUF) = ((*IBUF) | (d)))


/*     modify by anding the contents of latch buffers of devices            */

#define bicio(d) \
((*CSR) = 0, (*OBUF) = CNTRLR, (*CSR)++, (*OBUF) = ((*IBUF) & ~(d)))


/*     read device register and mask the desired bits                       */
/* note : after this call, (*IBUF) may be read as many times as needed    */

#define getio(d) \
((*CSR) = 0, (*OBUF) = CNTRLR, (*CSR)++, (*IBUF) & (d))



/****************************************************************************/
/*                                                                          */
/*                          Joint Command Group                             */
/*                                                                          */
/****************************************************************************/


/*              wait for REQA : transfer completed                          */

#define eotwait \
{int i = 0; while (!((*CSR) & REQA)) if (i++ == 100) zexit(100);}


/*       send a write command with the associated data                      */
/*       to a specified joint processor                                     */

#define putj(c, v, j) \
{(*CSR) = 0; (*OBUF) = (c) | (j); (*CSR)++; (*OBUF) = (v); eotwait}


/*          send a read command and return data                             */
/*          from a specified joint processor                                */

#define getj(c, v, j) \
{(*CSR) = 0; (*OBUF) = (c) | (j); (*CSR)++; eotwait; (v) = (*IBUF);}


/*      same as above but with 6 pieces of data stored in an array          */
/*      for each of the joint processors                                    */

#define put6j(c, a) \
{int i = 0; \
(*CSR) = 0; (*OBUF) = SEQUENT | (c); (*CSR)++; \
while (i < 6) { (*OBUF) = a[i++]; eotwait; } }


/*     same as above but with 6 pieces of data stored in an array           */
/*     for each of the joint processors                                     */

#define get6j(c, a) \
{int i = 0; \
(*CSR) = 0; (*OBUF) = SEQUENT | (c); (*CSR)++; \
while(i < 6) { eotwait; a[i++] = (*IBUF); } }


/*    same as above but writes same data to each of the joints              */


#define put6jg(c, v) \
{int i = 6; \
(*CSR) = 0; (*OBUF) = SEQUENT | (c); (*CSR)++; \
while (i--) { (*OBUF) = (v); eotwait;}}



/****************************************************************************/
/*                                                                          */
/*                    RAM Parameter Access Group                            */
/*                                                                          */
/****************************************************************************/



/*     read the parameters stored in the specified joint processor ram      */
/*     return the one byte parameter                                        */

#define getp(p, v ,j) \
{putj(SETPAR, ADDR | (p) >> 8, j) ;\
(*CSR) = 0; (*OBUF) = READM | (j); (*CSR)++; \
if ((p) > 05400) (v) = (*IBUF); else (v) = (*IBUF) & 0377;}


/*     set one byte parameter in the specified joint processor ram          */

#define putp(p, v, j) \
{putj(SETPAR, (p) | (v) & 0377, j);}


/* modify a parameter by oring the previous value with the supplied one     */

#define modop(p, m, j) \
{int v; \
getp(p, v, j) \
putj(SETPAR, (p) | v & 0377 | (m) & 0377, j)}



/*        same as above but accesses the 6 joint processors                 */

#define put6p(p, a) \
{int i; unsigned dl[6]; \
for (i = 0;  i < 6;  i++) dl[i] = (p) | (a)[i] & 0377; put6j(SETPAR, dl);}


/*        same as above but accesses the 6 joint processors                 */

#define get6p(p, a) \
{int i = 0; \
put6jg(SETPAR, ADDR | (p) >> 8); \
(*CSR) = 0; (*OBUF) = SEQUENT | READM; (*CSR)++; \
if (p > 05400) { while(i < 6) { eotwait; (a)[i++] = (*IBUF); } } \
else { while(i < 6) { eotwait; (a)[i++] = (*IBUF) & 0377; } } }


/*        same as above but accesses the 6 joint processors, gets 2 bytes   */

#define get6w(p, a) \
{int i = 0; \
put6jg(SETPAR, ADDR | (p) >> 8); \
(*CSR) = 0; (*OBUF) = SEQUENT | READM; (*CSR)++; \
while(i < 6) { eotwait; (a)[i++] = (*IBUF); } }


/*        same as above but puts the same value to each joint               */

#define put6pg(p, v) \
{put6jg(SETPAR, (p) | (v) & 0377)}


/*        same as above but modifies the 6 joints by oring                  */

#define modo6p(p, a) \
{int i; unsigned dl[6]; \
get6p(p, dl); \
for (i = 0; i < 6; i++) { dl[i] &= 0377; dl[i] |= (p) | (a)[i] & 0377;} \
put6j(SETPAR, dl) ;}


/*        same as above but same modification for all joints                */

#define modo6pg(p, m) \
{int i; unsigned dl[6]; \
get6p(p, dl); \
for (i = 0;  i < 6;  i++) { dl[i] &= 0377; dl[i] |= p | m & 0377; } \
put6j(SETPAR, dl)



/****************************************************************************/
/*                                                                          */
/*                Service Group                                             */
/*                                                                          */
/****************************************************************************/




/*                        check for REQB                                    */

#define jreqb \
(((*CSR) & REQB) ? ((*CSR) = 0, (*OBUF) = STOPP, (*IBUF) >> 8) : 0)


/*                      check all joint tolerances                          */

#define jtol \
((*CSR) = 0, (*OBUF) = STOPP, (*IBUF) & 0377)
