# This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # MANIFEST # Makefile # am9519.h # camac.h # ces8210.h # vmeConfig.h # camacLib.c # This archive created: Wed Dec 6 12:25:48 1989 sed 's/^X//' << \SHAR_EOF > MANIFEST XThis shar archive contains a library for accessing/controlling the XCreative Electronic Systems CBD-8210 Camac Branch Highway Driver. XModule 'camacLib' provides primitive access to the device. XMore formal access according to ESONE standards is provided by Xthe module 'camacEsone'. CamacEsone does not provide block transfer Xor scan modes at this time, but they could be added. X XD'Anne Thompson XNational Optical Astronomy Observatories XP.O. Box 26732 XTucson, AZ 85726 X(602) 325-9335 Xdat@noao.edu {...}!uunet!noao.edu!dat X XArchive Contents (excluding this Manifest file) X-------------------------------------------------------------------- X 2146 Makefile X 3304 camac.h X 2822 ces8210.h X 3087 am9519.h X 1470 vmeConfig.h X 13185 camacLib.c X 29526 camacEsone.c X 1357 camacBuildRef.nr X 675 camacCCC.nr X 692 camacCCZ.nr X 521 camacCLC.nr X 1621 camacDLAM.nr X 706 camacDREG.nr X 595 camacECD.nr X 1095 camacECI.nr X 607 camacELM.nr X 2582 camacEsone.nr X 404 camacEsoneInit.nr X 687 camacFSA.nr X 1039 camacIn.nr X 1507 camacLNK.nr X 1683 camacLib.nr X 1051 camacLibInit.nr X 810 camacOut.nr X 909 camacProbe.nr X 675 camacSSA.nr X 543 camacTCD.nr X 584 camacTCI.nr X 651 camacTGL.nr X 456 camacTLM.nr X 1003 camacTest.nr X 77993 total SHAR_EOF sed 's/^X//' << \SHAR_EOF > Makefile X X# D'Anne Thompson X# National Optical Astronomy Observatories X# P.O. Box 26732 X# Tucson, AZ 85726 X# (602) 325-9335 X# dat@noao.edu {...}!uunet!noao.edu!dat X# X# Support for '.s' files run through the C pre-processor. X.SUFFIXES : .lint .s .c X.s.o : X @/bin/rm -f $@ X $(ASM_P1) $< >tmp.c X $(CC) -E $(INCLUDES) -DASMLANGUAGE tmp.c >tmp.i X $(ASM_P2) tmp.i >tmp.s X $(AS) -o $@ tmp.s X @/bin/rm -f tmp.c tmp.i tmp.s X XVW = /vw XASM_P1 = cat XASM_P2 = cat XAS = as XINCLUDES = -I$(VW)/h XCFLAGS = -O $(INCLUDES) X XOBJS = camacLib.o camacEsone.o XSRCS = camacLib.c camacEsone.c XHDRS = camac.h ces8210.h am9519.h vmeConfig.h X Xall : $(OBJS) docs X XcamacEsone.o : camacEsone.c $(HDRS) X cc -c $(CFLAGS) camacEsone.c X X# camacLib.c contains 'C' and 'asm' code, needs two passes XcamacLib.o: camacLib.c $(HDRS) X cc -c $(CFLAGS) camacLib.c X cc -E $(INCLUDES) -DASMLANGUAGE camacLib.c > tmp.s X as tmp.s -o tmp.o X ld -r camacLib.o tmp.o -o camacLib.o X @/bin/rm -f tmp.s tmp.o X Xdocs : .docs X X.docs : camacLib.nr camacEsone.nr X touch .docs X XcamacLib.nr : camacLib.c $(VW)/bin/mangen $(VW)/bin/msplit $(VW)/bin/xp X mangen -n lib camacLib.c X mv mg.out camacLib.nr X msplit -s .nr file.names X nroff -mangen `sort file.names` | lpr X /bin/rm -f file.names X X# shar builds a compressed shar file of sources, headers and documentation. Xshar : MANIFEST camacLib.shar.Z X XMANIFEST: Manifest.hdr Makefile $(HDRS) $(SRCS) .docs X /bin/cp Manifest.hdr MANIFEST X wc -c Makefile $(HDRS) $(SRCS) *.nr >>MANIFEST X XcamacLib.shar.Z : Makefile MANIFEST $(HDRS) $(SRCS) .docs X /bin/rm -f camacLib.shar.Z X shar -v -o camacLib.shar MANIFEST Makefile $(HDRS) $(SRCS) *.nr X compress -v camacLib.shar X X# removes any extraneous material, including .o and .nr files X# only the sources, headers, and the makefile will remain Xclean : X /bin/rm -f *.o core a.out *.nr .docs *.shar* MANIFEST SHAR_EOF sed 's/^X//' << \SHAR_EOF > am9519.h X/* am9519.h - header for amd 9519 priority interrupt controller chip */ X X#ifndef INCam9519_h X#define INCam9519_h X X/* Xwritten by; X XD'Anne Thompson XNational Optical Astronomy Observatories XP.O. Box 26732 XTucson, AZ 85726 X(602) 325-9335 Xdat@noao.edu {...}!uunet!noao.edu!dat X*/ X X X/* Xmodification history X-------------------- X01a 29may89,dat - fixed up for exporting X*/ X X X/* XAM_9519 Command Codes X'Or' or 'Add' in the bit number for commands dealing with Xa single bit. X*/ X X#define AM_RESET 0x0 X#define AM_CLIMRIRR 0x10 /* clear all imr and irr bits */ X#define AM_CLIMRIRRB 0x18 /* clr single imr and irr bit */ X#define AM_CLIMR 0x20 /* clear all imr bits */ X#define AM_CLIMRB 0x28 /* clear single imr bit */ X#define AM_STIMR 0x30 /* set all imr bits */ X#define AM_STIMRB 0x38 /* set single imr bit */ X#define AM_CLIRR 0x40 /* clear all irr bits */ X#define AM_CLIRRB 0x48 /* clear single irr bit */ X#define AM_STIRR 0x50 /* set all irr bits */ X#define AM_STIRRB 0x58 /* set single irr bit */ X#define AM_CLISR 0x70 /* clear all isr bits */ X#define AM_CLISRB 0x78 /* clear single irs bit */ X#define AM_LOAD04 0x80 /* Load mode bits 0-4 */ X#define AM_LOAD56 0xa0 /* Load mode bit 5-6 */ X#define AM_WRIMR 0xb0 /* Preselect IMR for data writes */ X#define AM_WRACR 0xc0 /* Preselect ACR for data writes */ X#define AM_WRMEM 0xe0 /* Preselect ref.memory for writing, X or'd with vector size code and vector # */ X X/* XMode bits 0 - 4. To be or'd with the AM_LOAD04 command X*/ X# define AM_RPRI 0x1 /* Rotating priority levels */ X# define AM_FPRI 0x0 /* Fixed priority levels */ X# define AM_CVEC 0x2 /* All interrupts use same vector */ X# define AM_IVEC 0x0 /* All interrupts, individual vectors */ X# define AM_POLL 0x4 /* Polled cycle mode */ X# define AM_INTR 0x0 /* Interrupt cycle mode */ X# define AM_G_HI 0x8 /* GINT output active HI */ X# define AM_G_LO 0x0 /* GINT output active LO */ X# define AM_I_HI 0x10 /* IREQ inputs active HI */ X# define AM_I_LO 0x0 /* IREQ inputs active LO */ X/* default for mode bits 0-4 */ X# define AM_04INIT (AM_I_HI|AM_G_LO|AM_FPRI|AM_IVEC|AM_INTR) X X/* XMode bits 5,6 are set separately with the AM_LOAD56 command. XThese control the source of data appearing at the data port during Xread data operations. To be or'd with the AM_LOAD56 command. X*/ X# define AM_MSET 0x01 /* Set bit 7, master enable */ X# define AM_MCLR 0x02 /* Clear bit 7, master disable */ X# define AM_ISR 0x0 /* Preselect ISR register */ X# define AM_IMR 0x04 /* Preselect IMR register */ X# define AM_IRR 0x08 /* Preselect IRR register */ X# define AM_ACR 0x0c /* Preselect Auto-clear register */ X/* default for mode bits 5 and 6 */ X# define AM_56INIT (AM_ISR|AM_MSET) X X/* XVector size code, or'd into the AM_WRMEM command. XThe vector number must also be or'd into the low order 3 bits XThe vector number is written to the data register one byte at Xa time following the AM_WRMEM command. X*/ X# define AM_8BIT 0x0 /* vector is 1 byte long */ X# define AM_16BIT 0x08 /* vector is 2 bytes long */ X# define AM_24BIT 0x10 /* vector is 3 bytes long */ X# define AM_32BIT 0x18 /* vector is 4 bytes long */ X X#endif SHAR_EOF sed 's/^X//' << \SHAR_EOF > camac.h X/* camac.h - camac access library header file */ X X#ifndef INCcamac_h X#define INCcamac_h X X/* Xwritten by; X XD'Anne Thompson XNational Optical Astronomy Observatories XP.O. Box 26732 XTucson, AZ 85726 X(602) 325-9335 Xdat@noao.edu {...}!uunet!noao.edu!dat X*/ X X X/* Xmodification history X-------------------- X01c 29may89,dat - cleaned up for exporting. X01b 17feb89,dat - converted to vxWorks X01a xxoct88,dat - original (intermetrics) X*/ X X#include "lstLib.h" /* linked lam lists */ X#include "semLib.h" /* lam semaphores */ X#include "ces8210.h" /* camac status bit definitions */ X X/* XThis header file defines the interface to both the 'camacLib' and Xthe 'camacESONE' modules. X*/ X X X/************************************************************** X* X* camacLib interface definitions X* X* This section describes the interface to the camacLib module. X* X*/ X Xtypedef USHORT CAM_STAT; /* camac status word */ Xtypedef ULONG CAM_REF; /* camac address pointer */ X XIMPORT CAM_REF camacBuildRef();/* (b, c, n, a, f, size) */ XIMPORT STATUS camacIn(); /* (cam_ref, pData, pStatus) */ XIMPORT STATUS camacOut(); /* (cam_ref, data, pStatus) */ XIMPORT STATUS camacTest(); /* (cam_ref, pStatus) */ XIMPORT STATUS camacProbe(); /* (cam_ref) */ X X/* Macro to check for good status - Must have either X or Q */ X#define CAM_STAT_OK(status) ((status)&(CAM_X_BIT|CAM_Q_BIT)) X X X/****************************************************************** X* X* camacESONE module interface X* X*/ X X/* X * The lam handler is called as follows: X * (pLam->handler) (pLam->arg, pLam) X * the handler gets the optional argument, and a pointer to X * the lam structure. X * The handler returns a BOOL value. It returns TRUE if it X * successfully handled the LAM condition and reset the LAM. X * It returns FALSE if it didn't. The master interrupt handler X * will attempt to clear the LAM with camacCLM (lam) if the X * user handler returns FALSE. X * X * ESONE LAM handling routines. X * X * intArray[] is REQUIRED. X * intArray[0] is the Graded Lam #, (0 --> use 'n' from bcna) X * intArray[1] is the optional mailbox address. (use NULL for no mailbox) X */ Xtypedef struct { X NODE node; X CAM_REF bcna; /* f=0, size=LONG */ X short bitnum; /* 0--> sub_address lam */ X short bglam; X SEM_ID sem; /* given upon LAM occurrence */ X FUNCPTR handler; /* 1=success, 0=failure */ X int arg; X} LAM_DATA; Xtypedef LAM_DATA *CAM_LAM; X/* macros for scanning lam lists */ X#define lamNext(x) ((CAM_LAM)lstNext((NODE *)(x))) X#define lamFirst(x) ((CAM_LAM)lstFirst(x)) X X X/* IMPORT CAM_REF camacDREG (); /* (b,c,n,a) */ XIMPORT STATUS camacSSA (); /* (f, reg, pShort, pStatus) */ XIMPORT STATUS camacFSA (); /* (f, reg, pLong, pStatus) */ XIMPORT STATUS camacCCC (); /* (reg) */ XIMPORT STATUS camacCCZ (); /* (reg) */ XIMPORT STATUS camacECI (); /* (reg, flag) */ XIMPORT STATUS camacECD (); /* (reg, flag) */ XIMPORT BOOL camacTCI (); /* (reg) */ XIMPORT BOOL camacTCD (); /* (reg) */ XIMPORT BOOL camacTGL (); /* (reg) */ XIMPORT CAM_LAM camacDLAM (); /* (b, c, n, m, intArray) */ XIMPORT STATUS camacCLC (); /* (lam) */ XIMPORT STATUS camacELM (); /* (lam, flag) */ XIMPORT STATUS camacLNK (); /* (lam, pFunc, arg) */ XIMPORT BOOL camacTLM (); /* (lam) */ X X/* camacDREG is really just a macro to camacBuildRef() */ X#define camacDREG(b,c,n,a) camacBuildRef(b,c,n,a,0,CAM_LONG) X X#endif /* !INCcamac_h */ SHAR_EOF sed 's/^X//' << \SHAR_EOF > ces8210.h X/* ces8210.h - header file for CES-CBD 8210 Camac Branch Highway Driver */ X X#ifndef INCces8210_h X#define INCces8210_h X X/* Xwritten by; X XD'Anne Thompson XNational Optical Astronomy Observatories XP.O. Box 26732 XTucson, AZ 85726 X(602) 325-9335 Xdat@noao.edu {...}!uunet!noao.edu!dat X*/ X X X/* Xmodification history X-------------------- X28may89,dat - fixed up for export. X*/ X X/* XBecause of our Herikon cpu's limitations we must limit ourselves to X16 bit VMEbus transactions. Define the Branch Highway device as a Xsimple array of shorts. We will use #define's to identify special Xregisters within the structure. X*/ X X/* XStandard Board setup: XInterrupt Level 2 vector, set to IV_CAMAC_IT2 (See vmeConfig.h) XInterrupt Level 4 vector, set to IV_CAMAC_IT4 (See vmeConfig.h) XTime Out Selection (J3) = 8 microsec = in,in,in,out,in XLevel Selects = all TTL j4=j5=B(left), j6=out, j7=j8=in X*/ X X#ifndef ASMLANGUAGE Xtypedef struct { X short reg[8*32*16*32*2]; /* 262,144 shorts = 512KB */ X} CES8210; X#endif X X#define BCSR reg[29697] /* CR0, N29, A0, F0, (halfword) */ X#define BD1 reg[29699] X#define BD2 reg[29701] X#define BD3 reg[29703] X#define BITF reg[29705] /* CR0, N29, A0, F4 */ X#define BC1 reg[29707] X#define BC2 reg[29709] X#define BC3 reg[29711] X#define BCAR reg[29713] X#define BTB reg[29715] /* CR0, N29, A0, F9 *read* */ X#define BZ reg[29715] /* CR0, N29, A0, F9 *write* */ X#define BGL_U reg[29716] /* upper 8 bits, read FIRST */ X#define BGL_L reg[29717] /* lower 16 bits, read SECOND */ X X#define CAM_Q_BIT 0x8000 /* 'Q' */ X#define CAM_X_BIT 0x4000 /* 'X' */ X#define CAM_TO 0x2000 /* Time out */ X#define CAM_BD 0x1000 /* Branch Demand Pending */ X#define CAM_MNOX 0x0800 /* Mask the NO-X bus error, default = 1 */ X#define CAM_MTO 0x0020 /* Mask Timeout, default = 1 */ X#define CAM_MLAM 0x0010 /* Mask all LAMS, default = 1 */ X#define CAM_MIT2 0x0008 /* Mask external interrupt #2 */ X#define CAM_MIT4 0x0004 /* Mask external interrupt #4 */ X#define CAM_IT2 0x0002 /* State of external interrupt #2 */ X#define CAM_IT4 0x0001 /* State of external interrupt #4 */ X X#define CAM_F_SHIFT (2) X#define CAM_A_SHIFT (7) X#define CAM_N_SHIFT (11) X#define CAM_C_SHIFT (16) X#define CAM_B_SHIFT (19) X X/* mask out cnaf, leaving ptr to branch driver */ X#define CAM_B_MASK (0xfff80000) X#define CAM_CNAF_MASK (0x0007ffff) X X/* low order address bits pointing to CSR of a branch driver */ X#define CAM_CSR (0x0000e802) X X/* mask off b and c, leaving only n,a, and f */ X#define CAM_NAF_MASK (0x0000fffc) X X/* mask off n,a,f leaving ptr to b,c */ X#define CAM_BC_MASK (~CAM_NAF_MASK) X X/* mask out f, reference is changed to have F = 0, size = LONG */ X#define CAM_BCNA_MASK (0xffffff80) X X/* size codes even short word address is start of a 24 bit cycle, X * odd word address is start of a single 16 bit cycle. */ X#define CAM_LONG (0) X#define CAM_SHORT (2) X X#endif SHAR_EOF sed 's/^X//' << \SHAR_EOF > vmeConfig.h X/* vmeConfig.h - VME bus configuration for 'aries' */ X X#ifndef INCvmeConfig_h X#define INCvmeConfig_h X X/* Xwritten by; X XD'Anne Thompson XNational Optical Astronomy Observatories XP.O. Box 26732 XTucson, AZ 85726 X(602) 325-9335 Xdat@noao.edu {...}!uunet!noao.edu!dat X*/ X X X/* Xmodification history X-------------------- X01b 01jun89,dat - updated for archive exporting X01a 03mar89,dat - converted to vxWorks X*/ X X#include "vme.h" /* address modifier codes */ X X/****************************************************************** X* X* Camac branch Drivers, CES-CBD8210 (A24D16) X* X* VMEA24 (0x800000 thru 0x9fffff) X* Maximum of 4 branches ( #0 thru #3 ) X* Base addresses are all relative to CAMAC_BR0_ADDR, which cannot be X* changed. X*/ X X/* number of active branches */ X#define CAM_MAX_BRANCH (4) X X/* vme address of first branch *FIXED* */ X#define CAMAC_BR0_ADDR (0x800000) X X/* vme address space code (from $VW/h/vme.h) */ X#define CAMAC_ADDR_SPACE (VME_AM_STD_SUP_DATA) X X/* interrupt vector for it2, SAME JUMPER SETTINGS FOR ALL BRANCHES */ X#define CAMAC_IT2_INUM (193) /* IRQ2 */ X X/* interrupt vector for it4, SAME FOR ALL BRANCHES */ X#define CAMAC_IT4_INUM (194) /* IRQ4 */ X X/* interrupt vectors (changeable) for individual branches */ X#define CAMAC_BR0_INUM (144) /* IRQ3, 144 thru 167 */ X#define CAMAC_BR1_INUM (168) /* IRQ3, 168 thru 191 */ X#define CAMAC_BR2_INUM (196) /* IRQ3, 196 thru 219 */ X#define CAMAC_BR3_INUM (220) /* IRQ3, 220 thru 243 */ X X#endif /* !INC vmeConfig_h */ SHAR_EOF sed 's/^X//' << \SHAR_EOF > camacLib.c X/* camacLib.c - camac Library */ X X/* Xwritten by; X XD'Anne Thompson XNational Optical Astronomy Observatories XP.O. Box 26732 XTucson, AZ 85726 X(602) 325-9335 Xdat@noao.edu {...}!uunet!noao.edu!dat X*/ X X/* Xmodification history X-------------------- X01b 20jan89,dat updated to use tcpLib.h X0a0 27oct88 dat written X*/ X X/* XThis module represents the basic simple interface to the CES-CBD 8210 Xcamac driver. Only primitive access methods are implemented here. XSee module camacEsone for formalized access routines. X XCAMACLIBINIT XThe camacLibInit () function must be called prior to any attempted Xcamac accesses. It is necessary to intercept the bus error exception Xvector so that accesses to non-existant branches/crates don't crash Xthe system. X XROM IMAGES: XBecause of self-modifying code for the bus error exception Xintercept code, the intercept handling routine must be in RAM Xat execution time. The remaining parts of the text segment may Xreside in and be executed from ROM. X XCONTROLLER CONFUSION: XThe camac branch driver is based upon a bit-slice controller. It Xhas been known to get confused by illegal access attempts such Xas trying to read a register using a write function code (F16). XThe controller will straighten itself out usually after the next Xvalid transaction. Be careful when using the primitive routines XcamacIn, camacOut, and camacTest. The esone standard interface Xis much safer. X*/ X X#ifndef ASMLANGUAGE X X#include "vxWorks.h" X#include "iv68k.h" /* interrupt routines */ X#include "vmeConfig.h" /* vme addresses */ X#include "camac.h" /* camac routines */ X X XIMPORT FUNCPTR intVecGet (); XIMPORT intVecSet (); XIMPORT int camacIntercept(); XIMPORT short camacPatch[]; X XCES8210 *camacBaseAddr=NULL; XCES8210 *camacTopAddr=NULL; X X#define F16 (16<> 16; X camacPatch[2] = (ULONG)oldVector; X X intVecSet (IV_BUS_ERROR, camacIntercept); X } X X/*HELP: sysIntEnable (2); */ X sysIntEnable (3); X/*HELP: sysIntEnable (4); */ X X return OK; X } X X X/******************************************************* X* X* camacBuildRef - generate a camac reference X* X* Given the geographical and local addressing parameters X* for a camac operation, this routine returns the local X* cpu address for that operation. X* X* Crate #0 is permitted since the branch driver control and X* status registers live in the space allocated to crate #0. X* Similarly, slot numbers (n) 26 thru 31 are permitted because X* crate controller special functions respond to those addresses. X* X* NOTES: X* In normal usage most references are built with both 'a' and 'f' X* set to zero. The user will 'or' in the desired codes when X* making the actual function call. The following example shows X* this usage. X* X* .CS X* .nf X* #define A2 (2 << CAM_A_SHIFT) X* #define A0 (0) X* #define F16 (16 << CAM_F_SHIFT) X* #define F2 (2 << CAM_F_SHIFT) X* X* /* ioModule = branch 0, crate 2, slot 14 * X* ioModule = camacBuildRef (0,2,14,0,0,CAM_LONG); X* X* camacIn (ioModule|A2|F2, &newData, NULL); X* camacOut (ioModule|A0|F16, newCommand, NULL); X* .fi X* .CE X*/ X XCAM_REF camacBuildRef (b, c, n, a, f, sz) X int b; /* branch number */ X int c; /* crate number */ X int n; /* slot number */ X int a; /* sub-address */ X int f; /* function code */ X int sz; /* size code: ~0 -> short, 0 -> long */ X X { X if (b < 0 || b >= CAM_MAX_BRANCH X || c < 0 || c > 7 X || n < 1 || n > 32 X || a < 0 || a > 15 X || f < 0 || f > 31 X ) X return NULL; X else X return (CAM_REF) ( X (char *)camacBaseAddr X + (b << CAM_B_SHIFT) X + (c << CAM_C_SHIFT) X + (n << CAM_N_SHIFT) X + (a << CAM_A_SHIFT) X + (f << CAM_F_SHIFT) X + (sz ? CAM_SHORT : CAM_LONG) ); X } X X/******************************************************* X* X* camacIn - perform a camac input function X* X* Perform a read data operation on a camac register (function X* codes 0 through 7). X* X* If the camac operation reference was defined as being 'long' X* then the data pointer must point to a long integer location. X* If it was defined as short, then it must point to X* a short integer location. X* X* The transaction status is stored at the location given by X* pStatus. If pStatus is zero or NULL, then the X* camac status word is discarded. X* X* WARNING: X* The camac driver microcode can be confused by attempting X* a read cycle with a camac reference that does not represent X* a valid read function code, 0 through 7. X* X* RETURNS: X* Returns ERROR if the camac cycle fails (no-X and no-Q). X*/ X XSTATUS camacIn (camRef, pData, pStatus) X CAM_REF camRef; /* camac operation reference */ X char *pData; /* data pointer, camRef determines size */ X CAM_STAT *pStatus; /* status result pointer */ X X { X int oldLevel; X CAM_STAT status; X /* Integer to pointer conversion */ X FAST USHORT *pCamac = (USHORT *)(camRef); X X X oldLevel = intLock (); X if ((camRef & CAM_SHORT) == CAM_SHORT) X *(USHORT *)pData = *pCamac; X else X { X FAST ULONG temp = *pCamac++ << 16; X *(ULONG *)pData = temp | *pCamac; X } X X /* transaction status */ X status = *(USHORT *)(((ULONG)pCamac&CAM_B_MASK)|CAM_CSR); X X intUnlock (oldLevel); X X if (pStatus != NULL) X *pStatus = status; X X return CAM_STAT_OK(status) ? OK : ERROR; X } X X X/******************************************************* X* X* camacOut - perform a camac output function X* X* Output data to a camac register (function codes 16 thru 23). X* X* The transaction status is stored at the location given by X* pStatus. If pStatus is zero or NULL, then the X* camac status word is discarded. X* X* WARNING: X* The camac driver microcode can be confused by attempting X* a write cycle with a camac reference that does not represent X* a valid write function code, 16 through 23. X* X* RETURNS: X* Returns ERROR if the camac cycle fails (no-X and no-Q). X*/ X XSTATUS camacOut (camRef, data, pStatus) X CAM_REF camRef; /* camac operation reference */ X ULONG data; /* data to be written */ X CAM_STAT *pStatus; /* status result pointer */ X X { X int oldLevel; X CAM_STAT status; X FAST short *pCamac = (short *)(camRef); X X oldLevel = intLock (); X X if ((camRef & CAM_SHORT) == CAM_SHORT) X *pCamac = data; X else X { X *pCamac++ = data >> 16; X *pCamac = data; X } X X status = *(short *)(((ULONG)pCamac & CAM_B_MASK) | CAM_CSR); X X intUnlock (oldLevel); X X if (pStatus) X *pStatus = status; X X return CAM_STAT_OK(status) ? OK : ERROR ; X } X X X/******************************************************* X* X* camacTest - perform a camac test function X* X* Perform a non-data camac test function (function codes 8 thru 15 X* and 24 thru 31). X* X* The transaction status is stored at the location given by pStatus. X* If pStatus is zero or NULL, the status word is discarded. X* X* NOTE: X* The return code is the success/error code for the X* camac cycle itself, not just the Q bit response. X* You must use the status result pointer to obtain X* the status word if you want to examine just the Q bit. X* X* WARNING: X* The camac driver microcode can be confused by attempting X* a test cycle with a camac reference that does not represent X* a valid test function code, 8 through 15 and 24 through 31. X* X* RETURNS: X* Returns ERROR if the camac cycle does not return X or Q status. X*/ X XSTATUS camacTest (camRef, pStatus) X CAM_REF camRef; /* camac operation reference */ X CAM_STAT *pStatus; /* result status pointer */ X X { X int oldLevel; X CAM_STAT status; X X /* Integer to pointer conversion */ X FAST short *pCamac = (short *)(camRef|CAM_SHORT); X X oldLevel = intLock (); X status = *pCamac; X status = *(short *)(((ULONG)pCamac & CAM_B_MASK) | CAM_CSR); X intUnlock (oldLevel); X if (pStatus) X *pStatus = status; X return CAM_STAT_OK(status) ? OK : ERROR ; X } X X/******************************************************* X* X* camacProbe - test for presence of module X* X* Tries to determine if there is a module present at a X* given camac address. For write operations and test operations X* this is determined by the presence of either X or Q status X* following an access cycle. For a read operation, a non-zero X* data response will also yield a present indication. X* X* RETURNS: X* Returns OK if branch, crate, and module are all present. X* Returns ERROR if absent or off-line. X* X* WARNING: X* There is a possibility of a false absent indication for home-built X* write-only modules that give neither X nor Q. It is just not possible X* to detect the presence/absence of such a poorly designed module. X* (You guessed it, NOAO has some of these). X*/ X XSTATUS camacProbe (camRef) X CAM_REF camRef; /* camac address/operation code */ X X { X STATUS temp; X if (camRef & F8) X { X /* SUCCESS if either X or Q is returned */ X temp = camacTest (camRef, (CAM_STAT *)NULL); X } X else X { X if (camRef & F16) X /* SUCCESS if either X or Q is returned */ X temp = camacOut (camRef, (ULONG)0, (CAM_STAT *)NULL); X else X { X /* SUCCESS if X, or Q, or data is nonZero */ X long dummy = 0; X temp = camacIn (camRef, (char *)&dummy, (CAM_STAT *)NULL); X /* If we get non-zero data, then it MUST BE OK */ X if (dummy != 0) X temp = OK; X } X } X X return (temp); X } X X#endif /* !ASMLANGAUGE */ X X#ifdef ASMLANGUAGE X X#include "ces8210.h" X X/************************************************************** X* X* camacIntercept - intercept bus error exceptions X* X* Intercept bus error exceptions, in order to fix up references X* to non existant camac branches or crates. X* X* If the user references into a non existant branch, two bus errors X* will occur. The first on the module reference, and the second X* upon trying to reference the branch status register. This routine X* intercepts both errors returning a zero for the data reference and X* a timeout indication from the non existant branch driver module. X* X* If the user references a non-existant crate on a good branch, then X* the branch driver will abort the data reference with a bus error, X* which will be intercepted. The user will get a timeout directly X* from the branch status register. X*/ X X/* LOCAL camacIntercept () */ X X .globl _camacIntercept X .globl _camacPatch X .globl _camacBaseAddr /* branch 0 address */ X .globl _camacTopAddr /* last camac address */ X X/* EXCEPTION FRAME INFORMATION (with d0 on stack) */ X#define SSW 0xa + 4 /* Stack Offset to Special Status Word */ X#define SSW_RW_BIT 0x6 /* bit 6, byte 1 */ X#define SSW_DF_BIT 0x0 /* bit 0, byte 0 */ X X#define FRAME_TYPE 0x6 + 4 /* Stack offset to the Frame Id Nibble */ X#define SHORT_FRAME 0xa0 /* Compare the whole byte, lower nibble */ X#define LONG_FRAME 0xb0 /* has to be zero anyway. */ X X#define FAULT_ADDR 0x10 + 4/* Stack offset to the fault address */ X#define DIB 0x2c /* Stack offset to Data Input Buffer */ X X .text X .even X_camacIntercept: X movel d0,sp@- /* save one register */ X cmpb #SHORT_FRAME,sp@(FRAME_TYPE) X beq cam_1 X cmpb #LONG_FRAME,sp@(FRAME_TYPE) X beq cam_1 X bra not_camac /* not a bus error frame */ X Xcam_1: X btst #SSW_DF_BIT,sp@(SSW) X beq not_camac /* not a data fault */ X X movel sp@(FAULT_ADDR), d0 X cmpl _camacTopAddr,d0 X bcc not_camac /* bcc = bhis */ X cmpl _camacBaseAddr,d0 X bcs not_camac /* bcs = blo */ X X btst #SSW_RW_BIT,sp@(SSW+1) X beq fixed /* ignore a faulted camac write cycle */ X X movel sp@(FAULT_ADDR),sp@- X andl #CAM_CNAF_MASK,sp@ X cmpl #CAM_CSR,sp@+ X bne cam_2 /* not a CSR address fault */ X X movel #CAM_TO,sp@(DIB) /* return CSR = Time_Out */ X bra fixed X Xcam_2: X clrl sp@(DIB) /* All other faulted reads return 0 */ X Xfixed: X bclr #SSW_DF_BIT,sp@(SSW) /* don't rerun the instruction */ X movel sp@+,d0 X rte X Xnot_camac: X movel sp@+,d0 X_camacPatch: X/* Patched Locations SELF_MODIFYING_CODE */ X jmp 0:l /* patched to point to orig handler */ X .word 0 X .word 0 X#endif /*ASMLANGUAGE*/ SHAR_EOF # End of shell archive exit 0