(FILECREATED "28-Jul-85 16:06:04" {IVY}<HTHOMPSON>LISP>EDIN>PCDAC.;4 65398  

      changes to:  (FNS DigitalScope ScopeInWindow PCDAC.RESET)
		   (VARS PCDACCOMS)

      previous date: "29-Jun-85 18:42:22" {IVY}<HTHOMPSON>LISP>EDIN>PCDAC.;1)


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

(PRETTYCOMPRINT PCDACCOMS)

(RPAQQ PCDACCOMS ((E (RESETSAVE CLISPIFYPRETTYFLG NIL))
		  (* * 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 PCDAC.HARDRESET)
		  (* * 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)
		  (* * Checkout)
		  (FNS MAKE.PCDAC.TEST LevelOut PlayBack PCDACTestRead DigitalScope 
		       PCDACTestWindowButtonFn DoPCDACTest DontMove FakeIt1 FakeIt2 ScopeInWindow)
		  (CONSTANTS (PCDAC.DMACHANNEL 1))
		  (VARS (PCDACTestMenu)
			(ScopeHTickHeight 5)
			(ScopeVTickWidth 5)
			(\PCDACTestBufferStart)
			PCDACTestMenuItems PCDACTestTogMenuSpecs1 PCDACTestTogMenuSpecs2 PCDACIcon)
		  (DECLARE: DONTCOPY DONTEVAL@LOAD DOEVAL@COMPILE
			    (GLOBALVARS \PCDACTestBufferStart PCDACTestMenuItems 
					PCDACTestTogMenuSpecs1 PCDACTestTogMenuSpecs2 PCDACIcon 
					PCDACTestMenu))
		  (FILES (SYSLOAD)
			 BUSMASTER)))
(* * board-state record)

[DECLARE: EVAL@COMPILE 

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

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

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

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

(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 ← '??
			  PCDACBOARD.DIGPORTDIR ←(create PCDAC.DIGRECORD)
			  PCDACBOARD.SETUPDMA ←(create PCDAC.DMARECORD)
			  PCDACBOARD.SETADPARS ←(create PCDAC.ADRECORD)
			  PCDACBOARD.SETDAPARS ←(create PCDAC.DARECORD)
			  PCDACBOARD.LASTCOMMAND ← '??
			  PCDACBOARD.LASTWORKERCMD ← '??
			  PCDACBOARD.STOPFLAG ← '??)
]

(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                                                (* ht: "28-Jul-85 13:41")
    (bind STATUS (COMMAND ← 0)
       do (if (NOT (PCDAC.STOP T T))
	      then (GO FAIL))
	  (PCDAC.WRITECOMMAND COMMAND)
	  (replace PCDACBOARD.LASTCOMMAND of PCDAC.BOARD with COMMAND)
	  (replace PCDACBOARD.CLOCKPERIOD of PCDAC.BOARD with '4?)
	  (with PCDAC.DIGRECORD (fetch PCDACBOARD.DIGPORTDIR of PCDAC.BOARD)
		(PCDACDIG.PORT0DIR← 'INPUT?)
		(PCDACDIG.PORT1DIR← 'INPUT?))
	  (with PCDAC.ADRECORD (fetch PCDACBOARD.SETADPARS of PCDAC.BOARD)
		(PCDACAD.GAINCODE← 'BAD?)
		(PCDACAD.STARTCHAN← 'BAD?)
		(PCDACAD.ENDCHAN← 'BAD?)
		(PCDACAD.NPOINTS← 'BAD?))
	  (with PCDAC.DARECORD (fetch PCDACBOARD.SETDAPARS of PCDAC.BOARD)
		(PCDACDA.DACSELECT← 'BAD?)
		(PCDACDA.NPOINTS← 'BAD?))
	  (PCDAC.READDATABYTE)
	  (if (NOT (PCDAC.READYFORCOMMAND T T))
	      then (GO FAIL))
	  (STATUS←(PCDAC.CHECKEDSTATUS T T))
	  (if STATUS=NIL
	      then (GO FAIL)
	    elseif (BITTEST STATUS PCDACSTATUS.COMPOSITEERROR)
	      then (PCDAC.SHOWSTATUS STATUS "PCDAC.RESET failed to clear error bit" T)
		   (RETURN NIL)
	    else (replace PCDACBOARD.STOPFLAG of PCDAC.BOARD with NIL)
		 (RETURN T))
	  FAIL
	  (printout T "PCDAC.RESET giving up" T)
	  (RETURN NIL])

(PCDAC.HARDRESET
  [LAMBDA NIL                                                (* ht: "22-Jun-85 16:46")
    (BUS.RESET)
    (PCDAC.RESET])
)
(* * 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                                                (* ht: " 4-Jun-85 16:32")
    (PCBUS.INPUT (fetch PCDACBOARD.IOADDRESS of PCDAC.BOARD)+ 1])

(PCDAC.WRITECOMMAND
  [LAMBDA (COMMAND)                                          (* ht: " 4-Jun-85 16:32")
    (PCBUS.OUTPUT (fetch PCDACBOARD.IOADDRESS of PCDAC.BOARD)+ 1 COMMAND])

(PCDAC.READDATABYTE
  [LAMBDA NIL                                                (* ht: " 4-Jun-85 16:32")
    (PCBUS.INPUT (fetch PCDACBOARD.IOADDRESS of PCDAC.BOARD])

(PCDAC.WRITEDATABYTE
  [LAMBDA (DATUM)                                            (* ht: " 4-Jun-85 16:32")
    (PCBUS.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])
)
(* * Checkout)

(DEFINEQ

(MAKE.PCDAC.TEST
  [LAMBDA NIL                                                (* ht: "20-Jun-85 11:06")
    (FILESLOAD (SYSLOAD)
	       TOGMENU)
    (let ((mw (CREATEW NIL "PC D/A-A/D Test Window")))
	 (DSPSCROLL 'ON
		    mw)
	 (WINDOWPROP mw 'ICON
		     PCDACIcon)
	 (WINDOWPROP mw 'PCDACMenus
		     (NCONC (bind tm tw ttw for tms in PCDACTestTogMenuSpecs1
			       collect (ttw←(TogMenu tm←(MakeTogMenu tms::1)
						     tms:1 NIL 0 0 T))
				       (WINDOWPROP ttw 'MINSIZE
						   (FUNCTION DontMove))
				       (WINDOWPROP ttw 'MAXSIZE
						   (FUNCTION DontMove))
				       (if tw
					   then (ATTACHWINDOW ttw tw 'BOTTOM
							      'RIGHT)

          (* * following is a kludge to avoid bug in reshaping chains of fixed size windows -
	  it is really only important on the first window in each column of menus)


						(WINDOWPROP tw 'DOSHAPEFN
							    (FUNCTION FakeIt1))
					 else (ATTACHWINDOW ttw mw 'LEFT
							    'TOP))
				       (tw←ttw)
				       (REDISPLAYW ttw)
				       tm)
			    (bind tm tw ttw for tms in PCDACTestTogMenuSpecs2
			       collect (ttw←(TogMenu tm←(MakeTogMenu tms::1)
						     tms:1 NIL 0 0 T))
				       (WINDOWPROP ttw 'MINSIZE
						   (FUNCTION DontMove))
				       (WINDOWPROP ttw 'MAXSIZE
						   (FUNCTION DontMove))
				       (if tw
					   then (ATTACHWINDOW ttw tw 'BOTTOM
							      'LEFT)

          (* * following is a kludge to avoid bug in reshaping chains of fixed size windows -
	  it is really only important on the first window in each column of menus)


						(WINDOWPROP tw 'DOSHAPEFN
							    (FUNCTION FakeIt2))
					 else (ATTACHWINDOW ttw mw 'RIGHT
							    'TOP))
				       (tw←ttw)
				       (REDISPLAYW ttw)
				       tm)))
	 (let ((pw (CREATEW '(0 0 75 10)
			    NIL NIL T)))
	      (ATTACHWINDOW pw mw 'TOP
			    'RIGHT)
	      (WINDOWPROP pw 'MAXSIZE
			  (CONS 0 0))
	      (WINDOWPROP pw 'MINSIZE
			  (CONS 0 0))
	      (DSPFONT '(GACHA 8)
		       pw)
	      (DSPSCROLL T pw)
	      (WINDOWPROP pw 'PAGEFULLFN
			  'NILL)
	      (WINDOWPROP pw 'RESHAPEFN
			  (FUNCTION CLOSEW))

          (* * the reason I do this myself instead of using GETPROMPTWINDOW exclusively is to get the position and width as I 
	  want them)


	      (WINDOWPROP mw 'PromptWindow
			  (CONS pw 0))
	      pw)
	 (WINDOWPROP mw 'BUTTONEVENTFN
		     (FUNCTION PCDACTestWindowButtonFn))
	 mw])

(LevelOut
  [LAMBDA (window channel level)                             (* ht: "20-Jun-85 10:55")
    (PCDAC.STOP)
    (PCDAC.WRITED/AIMMEDIATE channel (PLUS 2048 level)
			     NIL NIL])

(PlayBack
  [LAMBDA (window channel sampleRate dontXfer)               (* ht: "29-Jun-85 18:31")
    (PCDAC.STOP)
    (BUSDMA.INIT)
    [PCDAC.SETCLOCK (FIX (FQUOTIENT 1.0/sampleRate (CONSTANT 1.25E-6]
    (PCBUS.WRITEARRAY \SSDataArray 0 32768 'SWAP
		      \PCDACTestBufferStart T)
    (PCDAC.SETUPDMA 1 0 32768 NIL T)
    (PCDAC.SETD/APARAMETERS channel)
    (PCDAC.STARTWRITED/A T T])

(PCDACTestRead
  [LAMBDA (msg)                                              (* ht: "25-Jun-85 15:23")
    (let ((pw (WINDOWPROP (MAINWINDOW $$TogWindow$$ T)
			  'PromptWindow))
	  r v width)
	 width←35+(STRINGWIDTH msg (DSPFONT NIL pw:1))
	 r←(APPEND (WINDOWPROP pw:1 'REGION))
	 r:LEFT←r:LEFT+(r:WIDTH-width)
	 r:WIDTH←width
	 r:HEIGHT←(HEIGHTIFWINDOW (-(DSPLINEFEED NIL pw:1)))
	 pw::1←1
	 (SHAPEW pw:1 r)
	 (DSPRESET pw:1)
	 v←(NLSETQ (RESETLST (RESETSAVE (TTYDISPLAYSTREAM pw:1))
			     (RESETSAVE (TTY.PROCESS (THIS.PROCESS)))
			     (printout T msg)
			     (CLEARBUF T T)
			     (READ T)))
	 (CLOSEW pw:1)
	 (if v
	     then v:1])

(DigitalScope
  [LAMBDA (window channel sampleRate gain compression maxAmpl midpoint displayEvery)
                                                             (* ht: "28-Jul-85 14:09")
    (RESETLST (RESETSAVE (RECLAIMMIN MAX.SMALLP))
	      (PROG ((vTextWidth (STRINGWIDTH "-2048" (DSPFONT NIL window)))
		     (hTextHeight (FONTPROP (DSPFONT NIL window)
					    'HEIGHT))
		     (midChar (QUOTIENT (FONTPROP (DSPFONT NIL window)
						  'ASCENT)
					2))
		     old reg base left height dataWidth dataSize sliceWidth arraySize nSlices 
		     rightEdge correctWidth file sliceSize xferSize estLength nPages device array)
		    (SETQ reg (DSPCLIPPINGREGION NIL window))
		    (SETQ old (ATTACHEDWINDOWREGION window))
		    (SETQ base (PLUS hTextHeight ScopeHTickHeight))
		    (SETQ left (PLUS vTextWidth ScopeVTickWidth))
		    (SETQ height (QUOTIENT (DIFFERENCE (WINDOWPROP window 'HEIGHT)
						       (PLUS base midChar))
					   2))
		    (SETQ dataWidth (DIFFERENCE (WINDOWPROP window 'WIDTH)
						left))
		    (CLEARW window)
		    [SETQ array (if (AND (BOUNDP '\SSDataArray)
					 (ARRAYP \SSDataArray))
				  else (SETQ \SSDataArray (ARRAY 32768 'WORD
								 0 0 128]
		    (SETQ dataSize (TIMES compression dataWidth))
		    (SETQ arraySize 32768)

          (* * the following are derived from disEvery=rPP*sliceWidth + fPP*disEv*sampleRate/1000)


		LP  [if displayEvery=NIL
			then 

          (* * as fast as possible given the width of the window)



          (* * displayEvery = rPP*sliceWidth*1000/ (1000-fPP*samp))


			     [SETQ displayEvery (FIX (FQUOTIENT (TIMES 1000.0 1.0 dataWidth)
								(DIFFERENCE 1000.0 (TIMES .0055 
										       sampleRate]

          (* * this test is not really right -
	  clearly one can%'t stand to fill the entire buffer -
	  there would then be no time to get it out before being stepped on. But doing better would require a dicey 
	  calculation of how likely we are to be stepped on given the sample rate and the buffer size...)


			     [if (IGREATERP (FIX (QUOTIENT (FTIMES displayEvery sampleRate)
							   1000.0))
					    arraySize)
				 then (SETQ displayEvery (FIX (FQUOTIENT (TIMES arraySize 1000.0)
									 sampleRate]
			     (GO LP)
		      else 

          (* * sliceWidth = number of points we can repaint = disEvery/rPP * (1 -
	  fPP*samp/1000))


			   (SETQ sliceWidth
			     (IMIN dataWidth (FIX (QUOTIENT (TIMES (DIFFERENCE 1.0
									       (QUOTIENT
										 (TIMES .0055 
										       sampleRate)
										 1000.0))
								   displayEvery)
							    1.0))
				   (FQUOTIENT (QUOTIENT (FTIMES displayEvery sampleRate)
							1000.0)
					      compression]
		    (SETQ sliceSize (TIMES sliceWidth compression))
		    (if (IGREATERP (SETQ xferSize (FIX (QUOTIENT (FTIMES displayEvery sampleRate)
								 1000.0)))
				   arraySize)
			then (HELP "too long"))

          (* * make sure there are an integral number of slices in the window)


		    [SETQ correctWidth (TIMES sliceWidth (SETQ nSlices (QUOTIENT dataWidth sliceWidth]
		    (SETQ rightEdge (PLUS correctWidth left))
		    [if (NOT (IEQP dataWidth correctWidth))
			then (SHAPEW window (create REGION
						    LEFT ←(fetch LEFT of old)
						    BOTTOM ←(fetch BOTTOM of old)
						    HEIGHT ←(fetch HEIGHT of old)
						    WIDTH ←(DIFFERENCE (fetch WIDTH of old)
								       (DIFFERENCE dataWidth 
										   correctWidth]
		    (MOVETO 0 (DIFFERENCE base midChar)
			    window)
		    (printout window .I5 (DIFFERENCE midpoint maxAmpl))
		    (MOVETO 0 (PLUS height (DIFFERENCE base midChar))
			    window)
		    (printout window .I5 midpoint)
		    (MOVETO 0 (PLUS height height (DIFFERENCE base midChar))
			    window)
		    (printout window .I5 (PLUS midpoint maxAmpl))
		    (MOVETO left base window)
		    (RELDRAWTO (MINUS ScopeVTickWidth)
			       0 1 NIL window)
		    (MOVETO left (PLUS base height)
			    window)
		    (RELDRAWTO (MINUS ScopeVTickWidth)
			       0 1 NIL window)
		    (MOVETO left (PLUS base height height)
			    window)
		    (RELDRAWTO (MINUS ScopeVTickWidth)
			       0 1 NIL window)
		    (bind index for del from 0 to correctWidth by (SELECTQ sampleRate
									   (27000 27)
									   20)
		       do (MOVETO (PLUS left del)
				  base window)
			  (RELDRAWTO 0 (MINUS ScopeHTickHeight)
				     1 NIL window)
			  (if (EQ (IMOD del (SELECTQ sampleRate
						     (27000 135)
						     100))
				  0)
			      then (SETQ index (QUOTIENT (TIMES 1000 del compression)
							 sampleRate))
				   (MOVETO (PLUS left del (MINUS (QUOTIENT (STRINGWIDTH index
											(DSPFONT
											  NIL window))
									   2)))
					   (PLUS base (MINUS ScopeHTickHeight)
						 (DSPLINEFEED NIL window)))
				   (PRIN3 index window)))
		    (PCDAC.STOP T)
		    (PCDAC.CLEARERROR)
		    (BUSDMA.INIT)

          (* * the CONSTANT is to fix a DWIMIFY bug)


		    [PCDAC.SETCLOCK (FIX (QUOTIENT 1.0 (FTIMES (CONSTANT 1.25E-6)
							       sampleRate]
		    (PCDAC.SETUPDMA 1 0 32768 T T)
		    (PCDAC.SETA/DPARAMETERS gain channel)
		    (TOTOPW window)
		    (RECLAIM)
		    (MOVETO left (PLUS base height)
			    window)
		    (printout T "Use STOP key or any mouse button to stop:")
		    (PCDAC.STARTREADA/D T T)
		    (ADD.PROCESS (LIST 'ScopeInWindow
				       window xferSize sliceWidth sliceSize compression rightEdge 
				       height maxAmpl (PLUS 2048 midpoint)
				       left base (PLUS (DSPYOFFSET NIL window)
						       base height)
				       height array)
				 'WINDOW
				 window])

(PCDACTestWindowButtonFn
  [LAMBDA (window)                                           (* ht: "19-Jun-85 14:15")
    (DECLARE (SPECVARS window))
    (TOTOPW window)
    (MENU (OR PCDACTestMenu PCDACTestMenu←(create MENU
						  ITEMS ← PCDACTestMenuItems])

(DoPCDACTest
  [LAMBDA (fn window argIndices)                             (* ht: "19-Jun-85 14:38")
    (RESETFORM (TTYDISPLAYSTREAM window)
	       (APPLY fn (CONS window (bind (menus ←(WINDOWPROP window 'PCDACMenus)) for i
					 in argIndices collect (TogMenuValue (CAR (NTH menus i])

(DontMove
  [LAMBDA (w)                                                (* ht: "19-Jun-85 15:41")
    (CONS (fetch WIDTH of (WINDOWPROP w 'REGION))
	  (fetch HEIGHT of (WINDOWPROP w 'REGION])

(FakeIt1
  [LAMBDA (w r)                                              (* ht: "19-Jun-85 17:21")
    (let [(wr (WINDOWPROP w 'REGION]
	 (MOVEW w (PLUS r:RIGHT 1 (MINUS wr:WIDTH))
		(PLUS r:TOP 1 (MINUS wr:HEIGHT])

(FakeIt2
  [LAMBDA (w r)                                              (* ht: "19-Jun-85 17:25")
    (let [(wr (WINDOWPROP w 'REGION]
	 (MOVEW w r:LEFT (PLUS r:TOP 1 (MINUS wr:HEIGHT])

(ScopeInWindow
  [LAMBDA (window xferSize sliceWidth sliceSize compression rightEdge scaleNum scaleDenom offset 
		  leftMargin bottomMargin base height array)
                                                             (* ht: "28-Jul-85 14:13")
    (bind (nextBufEnd ← xferSize)
	  (lastArrayPtr ← 0)
	  (redisplayRegion ←(APPEND (DSPCLIPPINGREGION NIL window)))
	  (stream ←(WINDOWPROP window 'DSP))
	  (arrayBase ←(ARRAYBASE array))
	  (arraySize ←(ARRAYSIZE array))
	  (lastAddress ← 32768)
	  bottom destBM top lastBufEnd currentAddress wrapped dispPos truePos left right y
       first (TTYDISPLAYSTREAM window)
	     (replace LEFT of redisplayRegion with leftMargin)
	     (replace WIDTH of redisplayRegion with sliceWidth)
	     (add (fetch BOTTOM of redisplayRegion)
		  bottomMargin)
	     (replace HEIGHT of redisplayRegion with (IDIFFERENCE (fetch HEIGHT of redisplayRegion)
								  bottomMargin))
	     [SETQ bottom (IMAX 0 (IPLUS (fetch BOTTOM of redisplayRegion)
					 (DSPYOFFSET NIL stream]
	     (SETQ destBM (DSPDESTINATION NIL stream))
	     [SETQ top (IMIN (SUB1 SCREENHEIGHT)
			     (IPLUS bottom (fetch HEIGHT of redisplayRegion]
       until (OR (MOUSESTATE (NOT UP))
		 (KEYDOWNP 'STOP))
       do                                                    (* (PCDAC.ERROR?))

          (* * Get the current location of the dma transfer, in words. Open coded for speed)


	  (if (BUSDMA.FASTUPDATEADDR PCDAC.DMACHANNEL currentAddress wrapped)
	      then (add currentAddress 32768))
	  (if (OR (EQ wrapped 'DoubleWrap)
		  (IGREATERP (IPLUS currentAddress currentAddress (IMINUS lastAddress)
				    -32768)
			     nextBufEnd))
	      then                                           (* falling behind -
							     punt)
		   (FLASHWINDOW window)
		   (SETQ nextBufEnd currentAddress)
		   (SETQ wrapped NIL)
	    elseif (ILESSP currentAddress nextBufEnd)
	      then (GO $$LP))
	  (SETQ lastAddress currentAddress)
	  (if (GREATERP nextBufEnd 32768)
	      then                                           (* slice lies across buffer end)
		   (SETQ wrapped NIL)
		   (SETQ nextBufEnd (IDIFFERENCE nextBufEnd 32768)))
	  (if (MINUSP (SETQ lastBufEnd (IDIFFERENCE nextBufEnd xferSize)))
	      then (PCBUS.READARRAY array (IPLUS 32768 lastBufEnd)
				    (IMINUS lastBufEnd)
				    'SWAP
				    lastArrayPtr T)
		   (PCBUS.READARRAY array 0 nextBufEnd 'SWAP
				    (IMOD (IDIFFERENCE lastArrayPtr lastBufEnd)
					  arraySize)
				    T)
	    else (PCBUS.READARRAY array lastBufEnd xferSize 'SWAP
				  lastArrayPtr T))

          (* * Dont call redisplayw, because it does a resetvars which burns conses which we can%'t afford)


	  (DSPFILL redisplayRegion NIL NIL stream)
	  (SETQ dispPos (IPLUS (fetch LEFT of redisplayRegion)
			       (DSPXOFFSET NIL stream)))
	  (SETQ truePos (IMOD (IDIFFERENCE (IPLUS lastArrayPtr xferSize)
					   sliceSize)
			      arraySize))
	  [SETQ left (IMAX 0 (IPLUS (fetch LEFT of redisplayRegion)
				    (DSPXOFFSET NIL stream]
	  [SETQ right (IMIN (SUB1 SCREENWIDTH)
			    (IPLUS left (fetch WIDTH of redisplayRegion]
	  (SETQ y (IPLUS (IQUOTIENT (ITIMES scaleNum (IDIFFERENCE (ELT array (MAX (IDIFFERENCE 
											  truePos 
										      compression)
										  0))
								  offset))
				    scaleDenom)
			 base))
	  [for i from 1 to (fetch WIDTH of redisplayRegion)
	     do (\CLIPANDDRAWLINE1 (SUB1 dispPos)
				   y dispPos (SETQ y (IPLUS (IQUOTIENT (ITIMES scaleNum
									       (IDIFFERENCE
										 (\GETBASE arrayBase 
											  truePos)
										 offset))
								       scaleDenom)
							    base))
				   'REPLACE
				   destBM left right bottom top stream)
		(add dispPos 1)
		(if (IGEQ (add truePos compression)
			  arraySize)
		    then (SETQ truePos (IDIFFERENCE truePos arraySize]
	  (if (IGEQ (add lastArrayPtr xferSize)
		    arraySize)
	      then (SETQ lastArrayPtr (IDIFFERENCE lastArrayPtr arraySize)))
	  (add nextBufEnd xferSize)
	  (if (EQ (add (fetch LEFT of redisplayRegion)
		       sliceWidth)
		  rightEdge)
	      then (replace LEFT of redisplayRegion with leftMargin))
       finally (PCDAC.STOP)
	       (PCDAC.CLEARERROR)
	       (SETQ \PCDACTestBufferStart lastArrayPtr])
)
(DECLARE: EVAL@COMPILE 

(RPAQQ PCDAC.DMACHANNEL 1)

(CONSTANTS (PCDAC.DMACHANNEL 1))
)

(RPAQQ PCDACTestMenu NIL)

(RPAQQ ScopeHTickHeight 5)

(RPAQQ ScopeVTickWidth 5)

(RPAQQ \PCDACTestBufferStart NIL)

(RPAQQ PCDACTestMenuItems ((Scope (DoPCDACTest 'DigitalScope
					       window
					       '(1 3 4 6 7 8 9))
				  "Display a digital oscilliscope trace")
			   ("Level Out" (DoPCDACTest 'LevelOut
						     window
						     '(2 5))
					"Put the designated level value on the given output channel")
			   (Reset (DoPCDACTest 'PCDAC.HARDRESET
					       window NIL)
				  "Reset the PC")
			   (Play (DoPCDACTest 'PlayBack
					      window
					      '(2 3))
				 "Play back the most recently collected buffer")))

(RPAQQ PCDACTestTogMenuSpecs1 (("Input Channel" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
	("Output Channel" 1 0 (Both 2))
	("Sample Rate" (27K 27000)
		       (10K 10000)
		       (5K 5000)
		       ((TogMenuValue)
			(PCDACTestRead "Sample rate: ")
			NIL "Will prompt and read" Other))
	("Input Gain" (1 0)
		      (2 1)
		      (4 2)
		      (8 3))))

(RPAQQ PCDACTestTogMenuSpecs2 (("Level Datum" (PFS-1 2047)
					      (PFS-2 2046)
					      0
					      (MFS+1 -2047)
					      (MFS -2048)
					      ((TogMenuValue)
					       (PCDACTestRead "Level value: ")
					       NIL "Will prompt and read" Other))
			       ("Time Compression" 1 2 10 30 ((TogMenuValue)
						    (PCDACTestRead "Compression ratio: ")
						    NIL "Will prompt and read" Other))
			       ("Max Amplitude" 1000 2048 2 10 ((TogMenuValue)
						 (PCDACTestRead "Max Amplitude: ")
						 NIL "Will prompt and read" Other))
			       ("Midpoint" 0 (PFS-2 2046)
					   (MFS+1 -2047)
					   ((TogMenuValue)
					    (PCDACTestRead "Midpoint value: ")
					    NIL "Will prompt and read" Other))
			       ("Display Every" 100 500 1000 (AFAP (NILL)
								   NIL "As fast as possible")
						((TogMenuValue)
						 (PCDACTestRead "Display every (msec): ")
						 NIL "Will prompt and read" Other))))

(RPAQ PCDACIcon (READBITMAP))
(64 64
"OOOOOOOOOOOOOOOO"
"OOOOOOOOOOOOOOOO"
"LBBBBBBBBBBBBB@C"
"LBBBBBBNCOOOOOHC"
"L@HHHHHLKOOOOOHC"
"L@HLIHHLKOOOOOHC"
"LBBNCJBNCOOOOOHC"
"LBBNCJBNCOOOOOHC"
"L@HLIHHLKOOOOOHC"
"L@HNKHHLKOOOOOHC"
"LBBOOJBNCOOOOOHC"
"LBBGOBBNCOOOOOHC"
"L@HKNHHLHHIOHHHC"
"L@HILHHLHHIOHHHC"
"LBBCNBBNBBCOBB@C"
"LBBCNBBNBBCOJB@C"
"L@HKLHHLHHIOHHHC"
"L@HILHHLHHIOHHHC"
"LBBCNBBNBBCOBB@C"
"LBBCNBBNBBCOBB@C"
"L@HILHHLHHIOHHHC"
"L@HILHHLHHIOHHHC"
"LBBCNBBNBBCOBB@C"
"LBBCNBBNBBCOBB@C"
"L@HILHHLHHIOHHHC"
"L@HILHHLHHIOHHHC"
"LBBCNBBNBBCOBB@C"
"LBBCNBBNBBCOBB@C"
"L@HILHHLHHIOHHHC"
"L@HILHHLHHIOHHHC"
"LBBCNBBNBBCOBB@C"
"LBBCNBBNBBCOBB@C"
"L@HILHHLHHIOHHHC"
"L@HILHINHHIOHHHC"
"LBBCNBCOBBCOBB@C"
"LBBCNBGOJBCOBB@C"
"L@HILHOOHHIOHHHC"
"L@HILHOOHHIOHHHC"
"LBBCNBGOJBCOBB@C"
"LBBCNBGOJBCOBB@C"
"L@HILHOOHHIOHHHC"
"L@HKNHOOHHIOHHHC"
"LBBCOBGOJBCOBB@C"
"LBBOOJGOJBCOBB@C"
"L@HOOHOOHHIOHHHC"
"L@HNKHOOHHIOHHHC"
"LBBNCJGOJBCOBB@C"
"LBBNCJGOJBCOBB@C"
"L@HLIHKOHHIOHHHC"
"L@HLIHINHHHHHHHC"
"L@@@@@@@@@@@@@@C"
"L@@@@@@@@@@@@@@C"
"L@@@@@@@@@@@@@@C"
"L@@@@@@@@@@@@@@C"
"L@@@O@OCLA@GH@@C"
"L@@@HI@JBBHHD@@C"
"L@@@HI@BBBHH@@@C"
"L@@@OA@BBDDH@@@C"
"L@@@HA@JBGLHD@@C"
"L@@@H@OCLHBGH@@C"
"L@@@@@@@@@@@@@@C"
"L@@@@@@@@@@@@@@C"
"L@@@@@@@@@@@@@@C"
"OOOOOOOOOOOOOOOO")
(DECLARE: DONTCOPY DONTEVAL@LOAD DOEVAL@COMPILE 
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS \PCDACTestBufferStart PCDACTestMenuItems PCDACTestTogMenuSpecs1 PCDACTestTogMenuSpecs2 
	    PCDACIcon PCDACTestMenu)
)
)
(FILESLOAD (SYSLOAD)
	   BUSMASTER)
(PUTPROPS PCDAC COPYRIGHT ("Xerox Corporation" 1984 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (4985 7077 (PCDAC.SETCLOCK 4995 . 5972) (PCDAC.SETUPDMA 5974 . 7075)) (7104 11110 (
PCDAC.READA/DIMMEDIATE 7114 . 8098) (PCDAC.SETA/DPARAMETERS 8100 . 9999) (PCDAC.STARTREADA/D 10001 . 
10747) (PCDAC.READA/DDATUM 10749 . 11108)) (11137 14532 (PCDAC.WRITED/AIMMEDIATE 11147 . 12075) (
PCDAC.SETD/APARAMETERS 12077 . 13433) (PCDAC.STARTWRITED/A 13435 . 14178) (PCDAC.WRITED/ADATUM 14180
 . 14530)) (14563 18987 (PCDAC.SETDIGITALINPUT 14573 . 15718) (PCDAC.SETDIGITALOUTPUT 15720 . 16868) (
PCDAC.READDIGITALIMMEDIATE 16870 . 17969) (PCDAC.WRITEDIGITALIMMEDIATE 17971 . 18985)) (19006 25862 (
PCDAC.STOP 19016 . 22813) (PCDAC.CLEARERROR 22815 . 24260) (PCDAC.RESET 24262 . 25704) (
PCDAC.HARDRESET 25706 . 25860)) (25903 30434 (PCDAC.READYFORCOMMAND 25913 . 27198) (PCDAC.READYFORREAD
 27200 . 28802) (PCDAC.READYFORWRITE 28804 . 30432)) (30462 36906 (PCDAC.ERROR? 30472 . 30898) (
PCDAC.SHOWSTATUS 30900 . 33929) (PCDAC.SHOWERROR 33931 . 34274) (PCDAC.READERROR 34276 . 35489) (
PCDAC.TEST 35491 . 36904)) (36970 37772 (PCDAC.READSTATUS 36980 . 37170) (PCDAC.WRITECOMMAND 37172 . 
37377) (PCDAC.READDATABYTE 37379 . 37567) (PCDAC.WRITEDATABYTE 37569 . 37770)) (37812 42581 (
PCDAC.CHECKEDSTATUS 37822 . 38742) (PCDAC.SHOWASTATUS 38744 . 39666) (PCDAC.SHOWASTATUS.BITASSIGN 
39668 . 39920) (PCDAC.SHOWSTATE 39922 . 40309) (PCDAC.SHOWANERROR 40311 . 41424) (
PCDAC.SHOWANERROR.BITASTEXT 41426 . 42579)) (42614 45298 (PCDAC.COMMANDASTEXT 42624 . 43892) (
PCDAC.STATUSASTEXT 43894 . 44860) (PCDAC.YNQUERY 44862 . 45296)) (45320 61770 (MAKE.PCDAC.TEST 45330
 . 47971) (LevelOut 47973 . 48179) (PlayBack 48181 . 48617) (PCDACTestRead 48619 . 49360) (
DigitalScope 49362 . 55630) (PCDACTestWindowButtonFn 55632 . 55919) (DoPCDACTest 55921 . 56263) (
DontMove 56265 . 56491) (FakeIt1 56493 . 56737) (FakeIt2 56739 . 56946) (ScopeInWindow 56948 . 61768))
)))
STOP