(FILECREATED "10-Jan-85 18:14:26" {IVY}<JELLINEK>WORK>PCDAC.;8 45518  

      changes to:  (FNS PCDAC.STARTWRITED/A)

      previous date: " 3-Jan-85 20:29:45" {IVY}<JELLINEK>WORK>PCDAC.;7)


(* Copyright (c) 1984, 1985 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT PCDACCOMS)

(RPAQQ PCDACCOMS ((FILES BUSMASTER)
		  (* * board-state record)
		  (RECORDS PCDAC.DIGRECORD PCDAC.DMARECORD PCDAC.ADRECORD PCDAC.DARECORD 
			   PCDAC.BOARDRECORD)
		  (VARS (PCDAC.BOARD (CREATE PCDAC.BOARDRECORD PCDACBOARD.DMACHANNEL ← 1 
					     PCDACBOARD.IOADDRESS ← 748))
			(PCDAC.TIMEOUTCOUNT 1000)
			(PCDAC.ERRORHANDLINGTOC 1000))
		  (* * status-register bits)
		  (CONSTANTS (PCDACSTATUS.DATAOUTREADY 1)
			     (PCDACSTATUS.DATAINFULL 2)
			     (PCDACSTATUS.READY 4)
			     (PCDACSTATUS.COMMAND 8)
			     (PCDACSTATUS.NOTUSED 112)
			     (PCDACSTATUS.COMPOSITEERROR 128))
		  (* * worker -- misc)
		  (FNS PCDAC.SETCLOCK PCDAC.SETUPDMA)
		  (* * worker -- A/D)
		  (FNS PCDAC.READA/DIMMEDIATE PCDAC.SETA/DPARAMETERS PCDAC.STARTREADA/D 
		       PCDAC.READA/DDATUM)
		  (* * worker -- D/A)
		  (FNS PCDAC.WRITED/AIMMEDIATE PCDAC.SETD/APARAMETERS PCDAC.STARTWRITED/A 
		       PCDAC.WRITED/ADATUM)
		  (* * worker -- digital)
		  (FNS PCDAC.SETDIGITALINPUT PCDAC.SETDIGITALOUTPUT PCDAC.READDIGITALIMMEDIATE 
		       PCDAC.WRITEDIGITALIMMEDIATE)
		  (* * reset)
		  (FNS PCDAC.STOP PCDAC.CLEARERROR PCDAC.RESET)
		  (* * status-register handshaking)
		  (FNS PCDAC.READYFORCOMMAND PCDAC.READYFORREAD PCDAC.READYFORWRITE)
		  (* * error analysis)
		  (FNS PCDAC.ERROR? PCDAC.SHOWSTATUS PCDAC.SHOWERROR PCDAC.READERROR PCDAC.TEST)
		  (* * internal -- lowest-level register-access functions)
		  (FNS PCDAC.READSTATUS PCDAC.WRITECOMMAND PCDAC.READDATABYTE PCDAC.WRITEDATABYTE)
		  (* * internal -- error analysis)
		  (FNS PCDAC.CHECKEDSTATUS PCDAC.SHOWASTATUS PCDAC.SHOWASTATUS.BITASSIGN 
		       PCDAC.SHOWSTATE PCDAC.SHOWANERROR PCDAC.SHOWANERROR.BITASTEXT)
		  (* * internal -- utility)
		  (FNS PCDAC.COMMANDASTEXT PCDAC.STATUSASTEXT PCDAC.YNQUERY)))
(FILESLOAD BUSMASTER)
(* * board-state record)

[DECLARE: EVAL@COMPILE 

(RECORD PCDAC.DIGRECORD (PCDACDIG.PORT0DIR PCDACDIG.PORT1DIR)
			PCDACDIG.PORT0DIR ←(QUOTE ??)
			PCDACDIG.PORT1DIR ←(QUOTE ??))

(RECORD PCDAC.DMARECORD (PCDACDMA.PAGE PCDACDMA.BASEADDRESS PCDACDMA.BASENPOINTS PCDACDMA.WRITETOMEM? 
				       PCDACDMA.AUTOINIT?)
			PCDACDMA.PAGE ←(QUOTE ??)
			PCDACDMA.BASEADDRESS ←(QUOTE ??)
			PCDACDMA.BASENPOINTS ←(QUOTE ??)
			PCDACDMA.WRITETOMEM? ←(QUOTE ??)
			PCDACDMA.AUTOINIT? ←(QUOTE ??))

(RECORD PCDAC.ADRECORD (PCDACAD.GAINCODE PCDACAD.STARTCHAN PCDACAD.ENDCHAN PCDACAD.NPOINTS)
		       PCDACAD.GAINCODE ←(QUOTE ??)
		       PCDACAD.STARTCHAN ←(QUOTE ??)
		       PCDACAD.ENDCHAN ←(QUOTE ??)
		       PCDACAD.NPOINTS ←(QUOTE ??))

(RECORD PCDAC.DARECORD (PCDACDA.DACSELECT PCDACDA.NPOINTS)
		       PCDACDA.DACSELECT ←(QUOTE ??)
		       PCDACDA.NPOINTS ←(QUOTE ??))

(RECORD PCDAC.BOARDRECORD (PCDACBOARD.NAME PCDACBOARD.DMACHANNEL PCDACBOARD.IOADDRESS 
					   PCDACBOARD.SYNCHRONOUS? PCDACBOARD.CLOCKPERIOD 
					   PCDACBOARD.DIGPORTDIR PCDACBOARD.SETUPDMA 
					   PCDACBOARD.SETADPARS PCDACBOARD.SETDAPARS 
					   PCDACBOARD.LASTCOMMAND PCDACBOARD.LASTWORKERCMD 
					   PCDACBOARD.STOPFLAG)
			  PCDACBOARD.CLOCKPERIOD ←(QUOTE ??)
			  PCDACBOARD.DIGPORTDIR ←(create PCDAC.DIGRECORD)
			  PCDACBOARD.SETUPDMA ←(create PCDAC.DMARECORD)
			  PCDACBOARD.SETADPARS ←(create PCDAC.ADRECORD)
			  PCDACBOARD.SETDAPARS ←(create PCDAC.DARECORD)
			  PCDACBOARD.LASTCOMMAND ←(QUOTE ??)
			  PCDACBOARD.LASTWORKERCMD ←(QUOTE ??)
			  PCDACBOARD.STOPFLAG ←(QUOTE ??))
]

(RPAQ PCDAC.BOARD (CREATE PCDAC.BOARDRECORD PCDACBOARD.DMACHANNEL ← 1 PCDACBOARD.IOADDRESS ← 748))

(RPAQQ PCDAC.TIMEOUTCOUNT 1000)

(RPAQQ PCDAC.ERRORHANDLINGTOC 1000)
(* * status-register bits)

(DECLARE: EVAL@COMPILE 

(RPAQQ PCDACSTATUS.DATAOUTREADY 1)

(RPAQQ PCDACSTATUS.DATAINFULL 2)

(RPAQQ PCDACSTATUS.READY 4)

(RPAQQ PCDACSTATUS.COMMAND 8)

(RPAQQ PCDACSTATUS.NOTUSED 112)

(RPAQQ PCDACSTATUS.COMPOSITEERROR 128)

(CONSTANTS (PCDACSTATUS.DATAOUTREADY 1)
	   (PCDACSTATUS.DATAINFULL 2)
	   (PCDACSTATUS.READY 4)
	   (PCDACSTATUS.COMMAND 8)
	   (PCDACSTATUS.NOTUSED 112)
	   (PCDACSTATUS.COMPOSITEERROR 128))
)
(* * worker -- misc)

(DEFINEQ

(PCDAC.SETCLOCK
  [LAMBDA (NTICKS)                                           (* edited: "22-Oct-84 19:43")

          (* * set DAC board clock period in 1.25 or 2.5 usec ticks)


    (PROG ((COMMAND 3))
          (if (OR (ILESSP NTICKS 2)
		  (IGREATERP NTICKS 65535))
	      then (HELP "bad NTICKS arg:" NTICKS))
          (PCDAC.READYFORCOMMAND)
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.CLOCKPERIOD of PCDAC.BOARD with NTICKS)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE NTICKS)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE (LRSH NTICKS 8))
          (if (fetch PCDACBOARD.SYNCHRONOUS? of PCDAC.BOARD)
	      then (PCDAC.READYFORCOMMAND])

(PCDAC.SETUPDMA
  [LAMBDA (PAGE ADDR NPOINTS WRITEMEM? AUTOINIT?)            (* hdj "30-Dec-84 15:38")

          (* * sets up the DAC's dma channel, leaving it unmasked -- presumes BUSDMA is initialized -- assumes BUSDMA checks 
	  its args)


    (PROG ((DMACHANNEL (fetch PCDACBOARD.DMACHANNEL of PCDAC.BOARD))
	   (DMARECORD (fetch PCDACBOARD.SETUPDMA of PCDAC.BOARD)))
          (BUSDMA.MASK DMACHANNEL)
          (BUSDMA.SETMODE DMACHANNEL WRITEMEM? AUTOINIT?)
          (replace PCDACDMA.WRITETOMEM? of DMARECORD with WRITEMEM?)
          (replace PCDACDMA.AUTOINIT? of DMARECORD with AUTOINIT?)
          (BUSDMA.SETPAGE DMACHANNEL PAGE)
          (replace PCDACDMA.PAGE of DMARECORD with PAGE)
          (BUSDMA.SETADDRESS DMACHANNEL ADDR)
          (replace PCDACDMA.BASEADDRESS of DMARECORD with ADDR)
          (BUSDMA.SETCOUNTER DMACHANNEL (ITIMES NPOINTS 2))
          (replace PCDACDMA.BASENPOINTS of DMARECORD with NPOINTS)
          (BUSDMA.UNMASK DMACHANNEL])
)
(* * worker -- A/D)

(DEFINEQ

(PCDAC.READA/DIMMEDIATE
  [LAMBDA (GAINCODE CHAN EXTTRIG?)                           (* edited: "22-Oct-84 19:44")
    (PROG ((COMMAND (if EXTTRIG?
			then 214Q
		      else 14Q)))
          (if (BITTEST GAINCODE (LOGNOT 3))
	      then (HELP "bad GAINCODE arg:" GAINCODE))
          (if (BITTEST CHAN (LOGNOT 17Q))
	      then (HELP "bad CHAN arg:" CHAN))
          (PCDAC.READYFORCOMMAND)
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE GAINCODE)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE CHAN)
          (PCDAC.READA/DDATUM)
          (if (fetch PCDACBOARD.SYNCHRONOUS? of PCDAC.BOARD)
	      then (PCDAC.READYFORCOMMAND])

(PCDAC.SETA/DPARAMETERS
  [LAMBDA (GAINCODE STARTCHAN ENDCHAN NPOINTS)               (* hdj " 2-Jan-85 13:42")

          (* * NPOINTS defaults to 64K-1 -- ENDCHAN defaults to STARTCHAN)


    (PROG ((COMMAND 13))
          (if (BITTEST GAINCODE (LOGNOT 3))
	      then (HELP "bad GAINCODE arg:" GAINCODE))
          (if (BITTEST STARTCHAN (LOGNOT 15))
	      then (HELP "bad STARTCHAN arg:" STARTCHAN))
          (if (NULL ENDCHAN)
	      then (SETQ ENDCHAN STARTCHAN)
	    elseif (BITTEST ENDCHAN (LOGNOT 15))
	      then (HELP "bad ENDCHAN arg:" ENDCHAN))
          (if (NULL NPOINTS)
	      then (SETQ NPOINTS 65535)
	    elseif (OR (ILESSP NPOINTS 3)
		       (IGREATERP NPOINTS 65535))
	      then (HELP "bad NPOINTS arg:" NPOINTS))
          (PCDAC.READYFORCOMMAND)
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND)
          (with PCDAC.ADRECORD (fetch PCDACBOARD.SETADPARS of PCDAC.BOARD)
		(SETQ PCDACAD.GAINCODE GAINCODE)
		(SETQ PCDACAD.STARTCHAN STARTCHAN)
		(SETQ PCDACAD.ENDCHAN ENDCHAN)
		(SETQ PCDACAD.NPOINTS NPOINTS))
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE GAINCODE)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE STARTCHAN)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE ENDCHAN)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE NPOINTS)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE (LRSH NPOINTS 8))
          (if (fetch PCDACBOARD.SYNCHRONOUS? of PCDAC.BOARD)
	      then (PCDAC.READYFORCOMMAND])

(PCDAC.STARTREADA/D
  [LAMBDA (DMA? CONTINUOUS? EXTCLOCK? EXTTRIG?)              (* edited: "22-Oct-84 19:46")
    (PROG ((COMMAND 14))
          (if DMA?
	      then (SETQ COMMAND (LOGOR COMMAND 16)))
          (if CONTINUOUS?
	      then (SETQ COMMAND (LOGOR COMMAND 32)))
          (if EXTCLOCK?
	      then (SETQ COMMAND (LOGOR COMMAND 64)))
          (if EXTTRIG?
	      then (SETQ COMMAND (LOGOR COMMAND 128)))
          (PCDAC.READYFORCOMMAND)
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND])

(PCDAC.READA/DDATUM
  [LAMBDA NIL                                                (* edited: "22-Oct-84 19:47")
    (PROG (LOWBYTE)
          (PCDAC.READYFORREAD)
          (SETQ LOWBYTE (PCDAC.READDATABYTE))
          (PCDAC.READYFORREAD)
          (RETURN (LOGOR LOWBYTE (LLSH (PCDAC.READDATABYTE)
				       10Q])
)
(* * worker -- D/A)

(DEFINEQ

(PCDAC.WRITED/AIMMEDIATE
  [LAMBDA (DACSELECT DATUM SECONDDATUM EXTTRIG?)             (* hdj " 3-Jan-85 17:24")
    (PROG ((COMMAND (if EXTTRIG?
			then 136
		      else 8)))
          (if (OR (MINUSP DACSELECT)
		  (IGREATERP DACSELECT 2))
	      then (HELP "bad DACSELECT arg:" DACSELECT))
          (PCDAC.READYFORCOMMAND)
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE DACSELECT)
          (PCDAC.WRITED/ADATUM DATUM)
          (if (EQ DACSELECT 2)
	      then (PCDAC.WRITED/ADATUM SECONDDATUM))
          (if (fetch PCDACBOARD.SYNCHRONOUS? of PCDAC.BOARD)
	      then (PCDAC.READYFORCOMMAND])

(PCDAC.SETD/APARAMETERS
  [LAMBDA (DACSELECT NPOINTS)                                (* hdj " 3-Jan-85 18:38")

          (* * NPOINTS defaults to 64K-1)


    (PROG ((COMMAND 9))
          (if (OR (MINUSP DACSELECT)
		  (IGREATERP DACSELECT 2))
	      then (HELP "bad DACSELECT arg:" DACSELECT))
          (if (NULL NPOINTS)
	      then (SETQ NPOINTS 65535)
	    elseif (OR (ILESSP NPOINTS 3)
		       (IGREATERP NPOINTS 65535))
	      then (HELP "bad NPOINTS arg:" NPOINTS))
          (PCDAC.READYFORCOMMAND)
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND)
          (with PCDAC.DARECORD (fetch PCDACBOARD.SETDAPARS of PCDAC.BOARD)
		(SETQ PCDACDA.DACSELECT DACSELECT)
		(SETQ PCDACDA.NPOINTS PCDACDA.NPOINTS))
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE DACSELECT)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE NPOINTS)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE (LRSH NPOINTS 8))
          (if (fetch PCDACBOARD.SYNCHRONOUS? of PCDAC.BOARD)
	      then (PCDAC.READYFORCOMMAND])

(PCDAC.STARTWRITED/A
  [LAMBDA (DMA? CONTINUOUS? EXTCLOCK? EXTTRIG?)              (* hdj "10-Jan-85 16:32")
    (PROG ((COMMAND 10))
          (if DMA?
	      then (SETQ COMMAND (LOGOR COMMAND 16)))
          (if CONTINUOUS?
	      then (SETQ COMMAND (LOGOR COMMAND 32)))
          (if EXTCLOCK?
	      then (SETQ COMMAND (LOGOR COMMAND 64)))
          (if EXTTRIG?
	      then (SETQ COMMAND (LOGOR COMMAND 128)))
          (PCDAC.READYFORCOMMAND)
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND])

(PCDAC.WRITED/ADATUM
  [LAMBDA (DATUM)                                            (* edited: "22-Oct-84 19:47")
    (if (NOT (FIXP DATUM))
	then (HELP "bad DATUM arg:" DATUM))
    (PCDAC.READYFORWRITE)
    (PCDAC.WRITEDATABYTE DATUM)
    (PCDAC.READYFORWRITE)
    (PCDAC.WRITEDATABYTE (LRSH DATUM 10Q])
)
(* * worker -- digital)

(DEFINEQ

(PCDAC.SETDIGITALINPUT
  [LAMBDA (PORTSELECT EXTTRIG?)                              (* edited: "22-Oct-84 19:48")
    (PROG ((COMMAND (if EXTTRIG?
			then 204Q
		      else 4)))
          (if (OR (MINUSP PORTSELECT)
		  (IGREATERP PORTSELECT 2))
	      then (HELP "bad PORTSELECT arg:" PORTSELECT))
          (PCDAC.READYFORCOMMAND)
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND)
          [with PCDAC.DIGRECORD (fetch PCDACBOARD.DIGPORTDIR of PCDAC.BOARD)
		(if (OR (EQ PORTSELECT 0)
			(EQ PORTSELECT 2))
		    then (SETQ PCDACDIG.PORT0DIR (QUOTE INPUT)))
		(if (OR (EQ PORTSELECT 0)
			(EQ PORTSELECT 1))
		    then (SETQ PCDACDIG.PORT1DIR (QUOTE INPUT]
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE PORTSELECT)
          (if (fetch PCDACBOARD.SYNCHRONOUS? of PCDAC.BOARD)
	      then (PCDAC.READYFORCOMMAND])

(PCDAC.SETDIGITALOUTPUT
  [LAMBDA (PORTSELECT EXTTRIG?)                              (* edited: "22-Oct-84 19:48")
    (PROG ((COMMAND (if EXTTRIG?
			then 205Q
		      else 5)))
          (if (OR (MINUSP PORTSELECT)
		  (IGREATERP PORTSELECT 2))
	      then (HELP "bad PORTSELECT arg:" PORTSELECT))
          (PCDAC.READYFORCOMMAND)
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND)
          [with PCDAC.DIGRECORD (fetch PCDACBOARD.DIGPORTDIR of PCDAC.BOARD)
		(if (OR (EQ PORTSELECT 0)
			(EQ PORTSELECT 2))
		    then (SETQ PCDACDIG.PORT0DIR (QUOTE OUTPUT)))
		(if (OR (EQ PORTSELECT 0)
			(EQ PORTSELECT 1))
		    then (SETQ PCDACDIG.PORT1DIR (QUOTE OUTPUT]
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE PORTSELECT)
          (if (fetch PCDACBOARD.SYNCHRONOUS? of PCDAC.BOARD)
	      then (PCDAC.READYFORCOMMAND])

(PCDAC.READDIGITALIMMEDIATE
  [LAMBDA (PORTSELECT EXTTRIG?)                              (* edited: "22-Oct-84 19:48")
    (PROG ((COMMAND (if EXTTRIG?
			then 206Q
		      else 6))
	   VALUE)
          (if (OR (MINUSP PORTSELECT)
		  (IGREATERP PORTSELECT 2))
	      then (HELP "bad PORTSELECT arg:" PORTSELECT))
          (PCDAC.READYFORCOMMAND)
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE PORTSELECT)
          (PCDAC.READYFORREAD)
          (SETQ VALUE (PCDAC.READDATABYTE))
          [if (EQ PORTSELECT 2)
	      then (PCDAC.READYFORREAD)
		   (SETQ VALUE (LOGOR VALUE (LLSH (PCDAC.READDATABYTE)
						  10Q]
          (if (fetch PCDACBOARD.SYNCHRONOUS? of PCDAC.BOARD)
	      then (PCDAC.READYFORCOMMAND))
          (RETURN VALUE])

(PCDAC.WRITEDIGITALIMMEDIATE
  [LAMBDA (PORTSELECT DATUM EXTTRIG?)                        (* edited: "22-Oct-84 19:49")
    (PROG ((COMMAND (if EXTTRIG?
			then 207Q
		      else 7))
	   VALUE)
          (if (OR (MINUSP PORTSELECT)
		  (IGREATERP PORTSELECT 2))
	      then (HELP "bad PORTSELECT arg:" PORTSELECT))
          (PCDAC.READYFORCOMMAND)
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE PORTSELECT)
          (PCDAC.READYFORWRITE)
          (PCDAC.WRITEDATABYTE DATUM)
          (if (EQ PORTSELECT 2)
	      then (PCDAC.READYFORWRITE)
		   (PCDAC.WRITEDATABYTE DATUM))
          (if (fetch PCDACBOARD.SYNCHRONOUS? of PCDAC.BOARD)
	      then (PCDAC.READYFORCOMMAND])
)
(* * reset)

(DEFINEQ

(PCDAC.STOP
  [LAMBDA (CERROK? ERRORHANDLING? QUERYMESSAGE)              (* jmh "14-Nov-84 18:25")

          (* * issue Stop command sequence, wait for it to take effect, and check if it succeeded -- if it did not then call 
	  PCDAC.SHOWSTATUS (and retry) -- BUT IF QUERYMESSAGE is non-NIL then it is a string describing the purpose for this 
	  PCDAC.STOP call and we only issue the Stop if the Ready bit is not set AND user says it is ok -- NOTE that the 
	  status register has to be looked at before the Stop -- this is done as though CERROK? and ERRORHANDLING? were set)



          (* * BUT IF ERRORHANDLING? -- after PCDAC.SHOWSTATUS immediately return NIL (else return T))



          (* * PCDACBOARD.STOPFLAG says whether we have caused a "command overrun" error by issuing a Stop command while a 
	  command was running -- a value of NIL means that we definitely have not done this, since we have not issued any Stop
	  commands with a command running since the error register was last successfully cleared -- a value of T means that we
	  definitely have caused a "command overrun" error, since we issued a Stop command with a command running and the 
	  composite error bit clear -- a value of (QUOTE ??) means that we may have caused a "command overrun" error, since we
	  issued a Stop command while a command was running, but since the composite error bit was set, we can't be sure 
	  (we'd have to Stop to ReadError to look at the "command overrun" bit to be sure!) -- a value of 
	  (QUOTE ??) can also mean: just loaded the package OR Stop found the status register to be trash -- PCDAC.CLEARERROR 
	  and PCDAC.RESET set NIL, PCDAC.STOP sets non-NIL, PCDAC.SHOWANERROR reads)


    (PROG ((COMMAND 15)
	   (STATUS (PCDAC.CHECKEDSTATUS T T))
	   STOPPED?)

          (* * if asked to query then if Ready is set just return T else (Ready is clear or unknown and) query whether to 
	  proceed or return NIL)


          [if (NOT (NULL QUERYMESSAGE))
	      then (if (AND (NOT (NULL STATUS))
			    (BITTEST STATUS PCDACSTATUS.READY))
		       then (RETURN T)
		     else (if (NOT (NULL STATUS))
			      then (printout T "the DAC has a command running" T))
			  (printout T "I want to STOP the DAC " QUERYMESSAGE T)
			  (if (NOT (PCDAC.YNQUERY "shall I do this"))
			      then (RETURN NIL]

          (* * we are going to issue Stop command -- set PCDACBOARD.STOPFLAG accordingly, given current state of Ready and 
	  compositeError bits -- no other action on compositeError bit now, we'll leave that for after the Stop, but we do 
	  want a nontrapping message if status register is trash)


          [if (NULL STATUS)
	      then (replace PCDACBOARD.STOPFLAG of PCDAC.BOARD with (QUOTE ??))
	    elseif (NOT (BITTEST STATUS PCDACSTATUS.READY))
	      then (if (NOT (BITTEST STATUS PCDACSTATUS.COMPOSITEERROR))
		       then (replace PCDACBOARD.STOPFLAG of PCDAC.BOARD with T)
		     elseif (NULL (fetch PCDACBOARD.STOPFLAG of PCDAC.BOARD))
		       then (replace PCDACBOARD.STOPFLAG of PCDAC.BOARD with (QUOTE ??]

          (* * issue Stop command and complete its command sequence)


          (repeatuntil (OR ERRORHANDLING? STOPPED?)
	     do (PCDAC.WRITECOMMAND COMMAND)
		(replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
		(PCDAC.READDATABYTE) 

          (* * wait for Stop to take effect and check success)


		(SETQ STOPPED? (PCDAC.READYFORCOMMAND CERROK? ERRORHANDLING?)))
          (RETURN STOPPED?])

(PCDAC.CLEARERROR
  [LAMBDA (ERRORHANDLING?)                                   (* jmh "15-Nov-84 11:59")

          (* * issue Clear Error Register command sequence and check if it succeeded -- if not then call PCDAC.SHOWSTATUS 
	  (and retry) -- NOTE ignores CompositeError until final check to see that it cleared, then never ignores it -- NOTE 
	  only STOPs the DAC if Ready bit is clear)



          (* * BUT IF ERRORHANDLING? --after PCDAC.SHOWSTATUS or after PCDAC.STOP returns NIL, immediately returns NIL 
	  (else returns T))


    (bind STATUS (COMMAND ← 1)
       do (if (NOT (PCDAC.STOP T ERRORHANDLING? "to clear the error register"))
	      then (GO FAIL))
	  (PCDAC.WRITECOMMAND COMMAND)
	  (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
	  (if (NOT (PCDAC.READYFORCOMMAND T ERRORHANDLING?))
	      then (GO FAIL))
	  (SETQ STATUS (PCDAC.CHECKEDSTATUS T ERRORHANDLING?))
	  (if (NULL STATUS)
	      then (GO FAIL)
	    elseif (BITTEST STATUS PCDACSTATUS.COMPOSITEERROR)
	      then (PCDAC.SHOWSTATUS STATUS "PCDAC.CLEARERROR failed to clear error bit" 
				     ERRORHANDLING?)
		   (RETURN NIL)
	    else (replace PCDACBOARD.STOPFLAG of PCDAC.BOARD with NIL)
		 (RETURN T))
	  FAIL
	  (printout T "PCDAC.CLEARERROR giving up" T)
	  (RETURN NIL])

(PCDAC.RESET
  [LAMBDA NIL                                                (* jmh "15-Nov-84 12:58")

          (* * issue Clear Error Register command sequence and check if it succeeded by checking whether the compositeError 
	  bit goes clear -- if not then call PCDAC.SHOWSTATUS (and retry) -- NOTE ignores CompositeError until final check to 
	  see that it cleared, then never ignores it -- NOTE only STOPs the DAC if Ready bit is clear)



          (* * BUT IF ERRORHANDLING? --after PCDAC.SHOWSTATUS or after PCDAC.STOP returns NIL, immediately returns NIL 
	  (else returns T))


    (bind STATUS (COMMAND ← 0)
       do (if (NOT (PCDAC.STOP T ERRORHANDLING? "to clear the error register"))
	      then (GO FAIL))
	  (PCDAC.WRITECOMMAND COMMAND)
	  (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
	  (replace PCDACBOARD.CLOCKPERIOD of PCDAC.BOARD with (QUOTE 4?))
	  (with PCDAC.DIGRECORD (fetch PCDACBOARD.DIGPORTDIR of PCDAC.BOARD)
		(SETQ PCDACDIG.PORT0DIR (QUOTE INPUT?))
		(SETQ PCDACDIG.PORT1DIR (QUOTE INPUT?)))
	  (with PCDAC.ADRECORD (fetch PCDACBOARD.SETADPARS of PCDAC.BOARD)
		(SETQ PCDACAD.GAINCODE (QUOTE BAD?))
		(SETQ PCDACAD.STARTCHAN (QUOTE BAD?))
		(SETQ PCDACAD.ENDCHAN (QUOTE BAD?))
		(SETQ PCDACAD.NPOINTS (QUOTE BAD?)))
	  (with PCDAC.DARECORD (fetch PCDACBOARD.SETDAPARS of PCDAC.BOARD)
		(SETQ PCDACDA.DACSELECT (QUOTE BAD?))
		(SETQ PCDACDA.NPOINTS (QUOTE BAD?)))
	  (PCDAC.READDATABYTE)
	  (if (NOT (PCDAC.READYFORCOMMAND T ERRORHANDLING?))
	      then (GO FAIL))
	  (SETQ STATUS (PCDAC.CHECKEDSTATUS T ERRORHANDLING?))
	  (if (NULL STATUS)
	      then (GO FAIL)
	    elseif (BITTEST STATUS PCDACSTATUS.COMPOSITEERROR)
	      then (PCDAC.SHOWSTATUS STATUS "PCDAC.RESET failed to clear error bit" ERRORHANDLING?)
		   (RETURN NIL)
	    else (replace PCDACBOARD.STOPFLAG of PCDAC.BOARD with NIL)
		 (RETURN T))
	  FAIL
	  (printout T "PCDAC.RESET giving up" T)
	  (RETURN NIL])
)
(* * status-register handshaking)

(DEFINEQ

(PCDAC.READYFORCOMMAND
  [LAMBDA (CERROK? ERRORHANDLING?)                           (* jmh "14-Nov-84 16:22")

          (* * loop until the Ready bit of the status register is set -- BUT if timeout then call PCDAC.SHOWSTATUS 
	  (and restart the loop) -- timeout is controlled by PCDAC.TIMEOUTCOUNT (if FIXP then it is the number of tries before
	  timeout, else never timeout))



          (* * BUT IF ERRORHANDLING? -- after PCDAC.SHOWSTATUS and after PCDAC.CHECKEDSTATUS returns NIL, immediately return 
	  NIL (else return T) -- AND timeout is controlled by PCDAC.ERRORHANDLINGTOC)


    (bind STATUS (COUNTER ← 0)
	  (MAXCOUNT ←(if ERRORHANDLING?
			 then PCDAC.ERRORHANDLINGTOC
		       else PCDAC.TIMEOUTCOUNT))
       do (SETQ STATUS (PCDAC.CHECKEDSTATUS CERROK? ERRORHANDLING?))
	  (if (NULL STATUS)
	      then (RETURN NIL)
	    elseif (BITTEST STATUS PCDACSTATUS.READY)
	      then (RETURN T)
	    elseif (AND (FIXP MAXCOUNT)
			(IGEQ (add COUNTER 1)
			      MAXCOUNT))
	      then (PCDAC.SHOWSTATUS STATUS "timeout waiting for Ready bit" ERRORHANDLING?)
		   (if ERRORHANDLING?
		       then (RETURN NIL)
		     else (SETQ COUNTER 0])

(PCDAC.READYFORREAD
  [LAMBDA (CERROK? ERRORHANDLING?)                           (* jmh "14-Nov-84 16:21")

          (* * loop until the DataOutReady bit of the status register is set -- BUT if the Ready bit is set OR timeout then 
	  call PCDAC.SHOWSTATUS (and restart the loop) -- timeout is controlled by PCDAC.TIMEOUTCOUNT 
	  (if FIXP then it is the number of tries before timeout, else never timeout))



          (* * BUT IF ERRORHANDLING? -- after PCDAC.SHOWSTATUS and after PCDAC.CHECKEDSTATUS returns NIL, immediately return 
	  NIL (else return T) -- AND timeout is controlled by PCDAC.ERRORHANDLINGTOC)


    (bind STATUS (COUNTER ← 0)
	  (MAXCOUNT ←(if ERRORHANDLING?
			 then PCDAC.ERRORHANDLINGTOC
		       else PCDAC.TIMEOUTCOUNT))
       do (SETQ STATUS (PCDAC.CHECKEDSTATUS CERROK? ERRORHANDLING?))
	  (if (NULL STATUS)
	      then (RETURN NIL)
	    elseif (BITTEST STATUS PCDACSTATUS.READY)
	      then (PCDAC.SHOWSTATUS STATUS "Ready bit set before end of command sequence" 
				     ERRORHANDLING?)
		   (if ERRORHANDLING?
		       then (RETURN NIL)
		     else (SETQ COUNTER 0))
	    elseif (BITTEST STATUS PCDACSTATUS.DATAOUTREADY)
	      then (RETURN T)
	    elseif (AND (FIXP MAXCOUNT)
			(IGEQ (add COUNTER 1)
			      MAXCOUNT))
	      then (PCDAC.SHOWSTATUS STATUS "timeout waiting for DataOutReady bit" ERRORHANDLING?)
		   (if ERRORHANDLING?
		       then (RETURN NIL)
		     else (SETQ COUNTER 0])

(PCDAC.READYFORWRITE
  [LAMBDA (CERROK? ERRORHANDLING?)                           (* jmh "14-Nov-84 16:25")

          (* * loop until the DataInFull bit of the status register is clear -- BUT if the Ready bit is set OR timeout then 
	  call PCDAC.SHOWSTATUS (and restart the loop) -- timeout is controlled by PCDAC.TIMEOUTCOUNT 
	  (if FIXP then it is the number of tries before timeout, else never timeout))



          (* * BUT IF ERRORHANDLING? -- after PCDAC.SHOWSTATUS and after PCDAC.CHECKEDSTATUS returns NIL, immediately return 
	  NIL (else return T) -- AND timeout is controlled by PCDAC.ERRORHANDLINGTOC)


    (bind STATUS (COUNTER ← 0)
	  (MAXCOUNT ←(if ERRORHANDLING?
			 then PCDAC.ERRORHANDLINGTOC
		       else PCDAC.TIMEOUTCOUNT))
       do (SETQ STATUS (PCDAC.CHECKEDSTATUS CERROK? ERRORHANDLING?))
	  (if (NULL STATUS)
	      then (RETURN NIL)
	    elseif (BITTEST STATUS PCDACSTATUS.READY)
	      then (PCDAC.SHOWSTATUS STATUS "Ready bit set before end of command sequence" 
				     ERRORHANDLING?)
		   (if ERRORHANDLING?
		       then (RETURN NIL)
		     else (SETQ COUNTER 0))
	    elseif (NOT (BITTEST STATUS PCDACSTATUS.DATAINFULL))
	      then (RETURN T)
	    elseif (AND (FIXP MAXCOUNT)
			(IGEQ (add COUNTER 1)
			      MAXCOUNT))
	      then (PCDAC.SHOWSTATUS STATUS "timeout waiting for DataInFull bit to clear" 
				     ERRORHANDLING?)
		   (if ERRORHANDLING?
		       then (RETURN NIL)
		     else (SETQ COUNTER 0])
)
(* * error analysis)

(DEFINEQ

(PCDAC.ERROR?
  [LAMBDA (CERROK?)                                          (* edited: "22-Oct-84 20:00")

          (* * return= "is the CompositeError bit of the status register set?" -- BUT if not CERROK? then doesn't return T but
	  rather calls PCDAC.SHOWSTATUS (and retries) (this is done inside PCDAC.CHECKEDSTATUS))


    (BITTEST (PCDAC.CHECKEDSTATUS CERROK?)
	     PCDACSTATUS.COMPOSITEERROR])

(PCDAC.SHOWSTATUS
  [LAMBDA (STATUS MESSAGE ERRORHANDLING?)                    (* hdj "30-Dec-84 17:41")

          (* * user should never supply MESSAGE nor ERRORHANDLING? arguments -- either one indicates that we are being called 
	  from within special error-handling or -analysis code in the PCDAC package ** CASE: called from user with STATUS 
	  argument provided -- just explain it -- CASE: called from user without STATUS argument -- fetch status and error 
	  register, explain them, offer facilities -- CASE: called from within error handling but not ERRORHANDLING? -- fetch 
	  status if necessary, error register if possible, explain them, offer facilities -- CASE: called with ERRORHANDLING? 
	  -- briefly describe status ** returns status if returns at all -- current "facilities" trivial)


    [if ERRORHANDLING?
	then 

          (* * CASE: if called with ERRORHANDLING? then we want to just give the messages that explain why we've been called, 
	  and not recurse or go into distracting detail but rather just return NIL)


	     (printout T "PCDAC error within error analysis:" T ".. ")
	     (PCDAC.SHOWASTATUS STATUS)
	     (if (STRINGP MESSAGE)
		 then (printout T "!! " MESSAGE " !!" T))
	     (PCDAC.SHOWSTATE)
      elseif (AND (NULL MESSAGE)
		  (FIXP STATUS))
	then 

          (* * CASE: if called from user and they provided a "status" argument, then presumably they just want it explained)


	     (PCDAC.SHOWASTATUS STATUS)
      else 

          (* * CASE: otherwise we are either analyzing first error or are dynamically analyzing status for interactive user --
	  we fetch/show/explain the status register, get the error register (if we can) and show/explain it, and offer to show
	  it all again or return)


	   (PROG (ERRORREG DONE? FLASHED?)
	         (repeatuntil DONE?
		    do 

          (* * get status if we don't have it, and show and explain it)


		       (if (NULL STATUS)
			   then (SETQ STATUS (PCDAC.READSTATUS)))
		       (PCDAC.SHOWASTATUS STATUS)
		       (if (STRINGP MESSAGE)
			   then (printout T "!! " MESSAGE " !!" T))
		       (PCDAC.SHOWSTATE) 

          (* * if this is all a surprise to the user, flash the screen (now before we ask the user any questions))


		       (if (AND MESSAGE (NOT FLASHED?))
			   then (SETQ FLASHED? T))

          (* * if the compositeError bit is set then we want to show and explain the error register)


		       (if (BITTEST STATUS PCDACSTATUS.COMPOSITEERROR)
			   then (SETQ ERRORREG (PCDAC.SHOWERROR ERRORREG T)))

          (* * now we ask the user if they want to see it again -- we have no "facilities" to offer at this point)


		       (SETQ DONE? (NOT (PCDAC.YNQUERY "type Y=redisplay or N=return or ↑E or etc"]

          (* * in every case return STATUS)


    STATUS])

(PCDAC.SHOWERROR
  [LAMBDA (ERROR ERRORHANDLING?)                             (* jmh "14-Nov-84 18:08")
    (PROG (RFC?)
          (if (NULL ERROR)
	      then (SETQ ERROR (PCDAC.READERROR ERRORHANDLING?)))
          (if ERROR
	      then (PCDAC.SHOWANERROR ERROR))
          (RETURN ERROR])

(PCDAC.READERROR
  [LAMBDA (ERRORHANDLING?)                                   (* edited: "22-Oct-84 21:16")

          (* * read and return the error register -- BUT if the Ready bit is clear then Stop the DAC first 
	  (first asking the user if this is ok) (this is in PCDAC.STOP) -- AND if any problems arise other than the 
	  compositeError bit being set (which is ignored) then just bitch and return NIL -- NOTE does not wait for command 
	  completion -- NOTE acts as though CERROK? were set)


    (PROG ((COMMAND 2))
          (if (NOT (PCDAC.STOP T ERRORHANDLING? "to read the error register"))
	      then (GO FAIL))
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (RETURN (LOGOR (if (NOT (PCDAC.READYFORREAD T ERRORHANDLING?))
			     then (GO FAIL)
			   else (PCDAC.READDATABYTE))
			 (LLSH (if (NOT (PCDAC.READYFORREAD T ERRORHANDLING?))
				   then (GO FAIL)
				 else (PCDAC.READDATABYTE))
			       8)))
      FAIL(printout T "PCDAC.READERROR giving up" T)
          (RETURN NIL])

(PCDAC.TEST
  [LAMBDA (NCYCLES EXTTRIG?)                                 (* jmh "15-Nov-84 13:01")

          (* * start PCDAC board's TEST command, and run NCYCLES 256-byte cycles of it -- NCYCLES default 1, nonFIXP = 
	  infinity -- STOP key stops test in any case)


    (PROG ((COMMAND 13Q)
	   (NERRORS 0)
	   (CYCLE 0))
          (PCDAC.STOP NIL NIL "to run Test")
          (PCDAC.WRITECOMMAND COMMAND)
          (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
          (replace PCDACBOARD.LASTWORKERCMD of PCDAC.BOARD with COMMAND)
          [repeatuntil (OR (NULL NCYCLES)
			   (AND (FIXP NCYCLES)
				(IGEQ (add CYCLE 1)
				      NCYCLES))
			   (KEYDOWNP (QUOTE STOP)))
	     do (add CYCLE 1)
		(for COUNTER from 1 to 400Q bind EXPECTED GOT
		   do (PCDAC.READYFORREAD)
		      (SETQ EXPECTED (LOGAND COUNTER 377Q))
		      (SETQ GOT (PCDAC.READDATABYTE))
		      (if (NEQ GOT EXPECTED)
			  then (printout T "in cycle " .I0 CYCLE " got " .I.3.8.T GOT "q vs " 
					 .I.3.8.T EXPECTED "q" T)
			       (add NERRORS 1]
          (PCDAC.STOP)
          (printout T .I0 NERRORS " errors in " .I0 CYCLE " cycles" T)
          (RETURN (if (NOT (ZEROP NERRORS))
		      then "errors"
		    else NIL])
)
(* * internal -- lowest-level register-access functions)

(DEFINEQ

(PCDAC.READSTATUS
  [LAMBDA NIL                                                (* edited: "11-Oct-84 17:18")
    (BUS.INPUT (IPLUS (fetch PCDACBOARD.IOADDRESS of PCDAC.BOARD)
		      1])

(PCDAC.WRITECOMMAND
  [LAMBDA (COMMAND)                                          (* edited: "11-Oct-84 17:18")
    (BUS.OUTPUT (IPLUS (fetch PCDACBOARD.IOADDRESS of PCDAC.BOARD)
		       1)
		COMMAND])

(PCDAC.READDATABYTE
  [LAMBDA NIL                                                (* edited: "11-Oct-84 17:18")
    (BUS.INPUT (fetch PCDACBOARD.IOADDRESS of PCDAC.BOARD])

(PCDAC.WRITEDATABYTE
  [LAMBDA (DATUM)                                            (* edited: "11-Oct-84 17:18")
    (BUS.OUTPUT (fetch PCDACBOARD.IOADDRESS of PCDAC.BOARD)
		DATUM])
)
(* * internal -- error analysis)

(DEFINEQ

(PCDAC.CHECKEDSTATUS
  [LAMBDA (CERROROK? ERRORHANDLING?)                         (* jmh "14-Nov-84 17:38")

          (* * read and return status register -- BUT if unused bits set or (compositeError bit set and not CERROROK?) then 
	  call PCDAC.SHOWSTATUS (and retry))



          (* * BUT IF ERRORHANDLING? -- after PCDAC.SHOWSTATUS immediately return NIL)


    (bind STATUS
       do (SETQ STATUS (PCDAC.READSTATUS))
	  (if (BITTEST STATUS PCDACSTATUS.NOTUSED)
	      then (PCDAC.SHOWSTATUS STATUS T ERRORHANDLING?)
		   (if ERRORHANDLING?
		       then (RETURN NIL))
	    elseif (AND (BITTEST STATUS PCDACSTATUS.COMPOSITEERROR)
			(NOT CERROROK?))
	      then (PCDAC.SHOWSTATUS STATUS "CompositeError bit set" ERRORHANDLING?)
		   (if ERRORHANDLING?
		       then (RETURN NIL))
	    else (RETURN STATUS])

(PCDAC.SHOWASTATUS
  [LAMBDA (STATUS)                                           (* jmh "15-Nov-84 12:13")
    (printout T "PCDAC status " .I3.8.T STATUS "q=" (PCDAC.STATUSASTEXT STATUS)
	      "=" T)
    (printout T ".." -3 (PCDAC.SHOWASTATUS.BITASSIGN STATUS PCDACSTATUS.COMPOSITEERROR)
	      "compositeError  "
	      (PCDAC.SHOWASTATUS.BITASSIGN STATUS PCDACSTATUS.COMMAND)
	      "Command" T)
    (printout T ".." -3 (PCDAC.SHOWASTATUS.BITASSIGN STATUS PCDACSTATUS.READY)
	      "Ready  "
	      (PCDAC.SHOWASTATUS.BITASSIGN STATUS PCDACSTATUS.DATAINFULL)
	      "dataInFull  "
	      (PCDAC.SHOWASTATUS.BITASSIGN STATUS PCDACSTATUS.DATAOUTREADY)
	      "dataOutReady" T)
    (if (BITTEST STATUS PCDACSTATUS.NOTUSED)
	then (printout T "!! Unused status bits set !!" T))
    (if (EQ STATUS 377Q)
	then (printout T "!! READING ALL-ONES !!" T])

(PCDAC.SHOWASTATUS.BITASSIGN
  [LAMBDA (STATUS MASK)                                      (* edited: "29-Sep-84 01:24")

          (* * internal to PCDAC.SHOWSTATUS)


    (if (BITTEST STATUS MASK)
	then "+"
      else "-"])

(PCDAC.SHOWSTATE
  [LAMBDA NIL                                                (* edited: "21-Oct-84 19:47")
    (printout T "last command: " (PCDAC.COMMANDASTEXT (fetch PCDACBOARD.LASTCOMMAND of PCDAC.BOARD))
	      T)
    (printout T "last worker command: " (PCDAC.COMMANDASTEXT (fetch PCDACBOARD.LASTWORKERCMD
								of PCDAC.BOARD))
	      T])

(PCDAC.SHOWANERROR
  [LAMBDA (ERROR)                                            (* jmh "14-Nov-84 13:29")

          (* * internal to PCDAC.SHOWERROR -- print messages describing the ERROR register and all the bits of it that are set
	  -- with special case to handle PCDACBOARD.STOPFLAG -- see PCDAC.STOP about PCDACBOARD.STOPFLAG)


    (PROG ((STOPFLAG (fetch PCDACBOARD.STOPFLAG of PCDAC.BOARD))
	   BITNR)
          (printout T "ERROR " .I6.8.T ERROR "q=" T)
          (if (EQ ERROR 65535)
	      then (printout T ".. (READING ALL BITS AS ONES !?)" T)
	    else (for BITNR from 0 to 15 do (if (BITTEST ERROR (LLSH 1 BITNR))
						then (printout T (PCDAC.SHOWANERROR.BITASTEXT BITNR)
							       T)
						     (if (AND (EQ BITNR 1)
							      (NOT (NULL STOPFLAG)))
							 then (printout T "..   (this is "
									(if (EQ STOPFLAG T)
									    then "probably"
									  else "possibly")
									
							      " from STOPping a running command)"
									T])

(PCDAC.SHOWANERROR.BITASTEXT
  [LAMBDA (BITNR)                                            (* edited: "17-Oct-84 17:45")
    (SELECTQ BITNR
	     (0 "err0: reserved")
	     (1 "err1: command issued while (noncontinuous) command in progress")
	     (2 "err2: attempt to set clock period to illegal value 0 or 1")
	     (3 "err4: attempt to select digital port other than 0..2")
	     (4 "err4: attempt to read digital port set for output or v.v.")
	     (5 "err5: attempt to select DAC other than 0,1,2")
	     (6 "err6: clock signal occurred before DAC ready")
	     (7 "err7: attempt to set D-A #conversions to illegal values 0,1,2")
	     (10Q "err8: attempt to select A-D channel other than 0..7 (s/e) or 0..15 (diff)")
	     (11Q "err9: attempt to set A-D gain other than 0..3")
	     (12Q "err10: clock signal occurred before A-D ready")
	     (13Q "err11: A-D mux error -- clocking too fast")
	     (14Q "err12: attempt to set A-D #conversions to illegal values 0,1,2")
	     (15Q "err13: data written to data register when command expected")
	     (16Q "err14: reserved")
	     (17Q "err15: reserved")
	     (SHOULDNT "bad BITNR"])
)
(* * internal -- utility)

(DEFINEQ

(PCDAC.COMMANDASTEXT
  [LAMBDA (COMMAND)                                          (* jmh "14-Nov-84 13:26")

          (* * return a string which names the command and its modifier bits)


    (if (FIXP COMMAND)
	then (PROG (X)
	           (SETQ X (SELECTQ (LOGAND 15 COMMAND)
				    (0 "Reset")
				    (1 "ClrErr")
				    (2 "RdErr")
				    (3 "SetClk")
				    (4 "SelDigIn")
				    (5 "SelDigOut")
				    (6 "RdDigImm")
				    (7 "WrDigImm")
				    (8 "WrD/AImm")
				    (9 "SetD/APars")
				    (10 "WrD/A")
				    (11 "Test")
				    (12 "RdA/DImm")
				    (13 "SetA/DPars")
				    (14 "RdA/D")
				    (15 "Stop")
				    (SHOULDNT "noncommand")))
	           (if (BITTEST COMMAND 240)
		       then (SETQ X (CONCAT X "("))
			    (if (BITTEST COMMAND 16)
				then (SETQ X (CONCAT X "dma ")))
			    (if (BITTEST COMMAND 32)
				then (SETQ X (CONCAT X "cont ")))
			    (if (BITTEST COMMAND 64)
				then (SETQ X (CONCAT X "xClk ")))
			    (if (BITTEST COMMAND 128)
				then (SETQ X (CONCAT X "xTrg ")))
			    (SETQ X (RPLSTRING X -1 ")")))
	           (RETURN X))
      else COMMAND])

(PCDAC.STATUSASTEXT
  [LAMBDA (STATUS)                                           (* edited: "13-Oct-84 01:07")

          (* * return string explaining PCDAC status bits)


    (PROG ((STRING ""))
          (if (BITTEST STATUS PCDACSTATUS.COMPOSITEERROR)
	      then (SETQ STRING (CONCAT STRING "E")))
          (if (BITTEST STATUS PCDACSTATUS.NOTUSED)
	      then (SETQ STRING (CONCAT STRING "XXX")))
          (if (BITTEST STATUS PCDACSTATUS.COMMAND)
	      then (SETQ STRING (CONCAT STRING "C")))
          (if (BITTEST STATUS PCDACSTATUS.READY)
	      then (SETQ STRING (CONCAT STRING "R")))
          (if (BITTEST STATUS PCDACSTATUS.DATAINFULL)
	      then (SETQ STRING (CONCAT STRING "I")))
          (if (BITTEST STATUS PCDACSTATUS.DATAOUTREADY)
	      then (SETQ STRING (CONCAT STRING "O")))
          (RETURN STRING])

(PCDAC.YNQUERY
  [LAMBDA (TEXT)                                             (* edited: "15-Oct-84 14:45")

          (* * get an answer to a Y/N question)


    (PROG (ANSWER)
          [repeatuntil (OR (EQ ANSWER (QUOTE Y))
			   (EQ ANSWER (QUOTE N)))
	     do (printout T TEXT " (Y/N) ? ")
		(SETQ ANSWER (U-CASE (READ]
          (RETURN (EQ ANSWER (QUOTE Y])
)
(PUTPROPS PCDAC COPYRIGHT ("Xerox Corporation" 1984 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (4465 6557 (PCDAC.SETCLOCK 4475 . 5452) (PCDAC.SETUPDMA 5454 . 6555)) (6584 10590 (
PCDAC.READA/DIMMEDIATE 6594 . 7578) (PCDAC.SETA/DPARAMETERS 7580 . 9479) (PCDAC.STARTREADA/D 9481 . 
10227) (PCDAC.READA/DDATUM 10229 . 10588)) (10617 14012 (PCDAC.WRITED/AIMMEDIATE 10627 . 11555) (
PCDAC.SETD/APARAMETERS 11557 . 12913) (PCDAC.STARTWRITED/A 12915 . 13658) (PCDAC.WRITED/ADATUM 13660
 . 14010)) (14043 18467 (PCDAC.SETDIGITALINPUT 14053 . 15198) (PCDAC.SETDIGITALOUTPUT 15200 . 16348) (
PCDAC.READDIGITALIMMEDIATE 16350 . 17449) (PCDAC.WRITEDIGITALIMMEDIATE 17451 . 18465)) (18486 25955 (
PCDAC.STOP 18496 . 22293) (PCDAC.CLEARERROR 22295 . 23740) (PCDAC.RESET 23742 . 25953)) (25996 30527 (
PCDAC.READYFORCOMMAND 26006 . 27291) (PCDAC.READYFORREAD 27293 . 28895) (PCDAC.READYFORWRITE 28897 . 
30525)) (30555 36999 (PCDAC.ERROR? 30565 . 30991) (PCDAC.SHOWSTATUS 30993 . 34022) (PCDAC.SHOWERROR 
34024 . 34367) (PCDAC.READERROR 34369 . 35582) (PCDAC.TEST 35584 . 36997)) (37063 37911 (
PCDAC.READSTATUS 37073 . 37283) (PCDAC.WRITECOMMAND 37285 . 37514) (PCDAC.READDATABYTE 37516 . 37706) 
(PCDAC.WRITEDATABYTE 37708 . 37909)) (37951 42720 (PCDAC.CHECKEDSTATUS 37961 . 38881) (
PCDAC.SHOWASTATUS 38883 . 39805) (PCDAC.SHOWASTATUS.BITASSIGN 39807 . 40059) (PCDAC.SHOWSTATE 40061 . 
40448) (PCDAC.SHOWANERROR 40450 . 41563) (PCDAC.SHOWANERROR.BITASTEXT 41565 . 42718)) (42753 45437 (
PCDAC.COMMANDASTEXT 42763 . 44031) (PCDAC.STATUSASTEXT 44033 . 44999) (PCDAC.YNQUERY 45001 . 45435))))
)
STOP