(FILECREATED "17-Jan-85 18:16:24" {ERIS}<SPEECH>MAILREADER>COMMUNICARD.;2 14558  

      changes to:  (VARS COMMUNICARDCOMS DATA)

      previous date: " 9-Jan-85 13:14:38" {ERIS}<SPEECH>MAILREADER>COMMUNICARD.;1)


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

(PRETTYCOMPRINT COMMUNICARDCOMS)

(RPAQQ COMMUNICARDCOMS ((* The variables CTRL DATA DTMF and RST contain the i/o location addresses of 
			   the Communicard in the PC's i/o space)
	(VARS CTRL DATA DTMF RST)
	(* Variables identifying the different bits in the CTRL register)
	(VARS HAND LINE MONITOR OH PHONE RDY TONE)
	(VARS BACKWARDS.LIMIT BANK BEEP.LIMIT ENB FAST.LIMIT RESPONSE.LIMIT SLOW.LIMIT SMEAR.LIMIT 
	      SPEECH.THRESHOLD SPEECH1.LIMIT SPEECH2.LIMIT SPEECH3.LIMIT)
	(* Utility functions)
	(FNS BINARY BINSTAT C.PEEK C.SETUP CORRECT HEX HEXCHAR INP OUT POLL START.CTRL.MONITOR 
	     TEST.PORT)
	(FNS ANSWERING.MACHINE COMMUNICARD.SETUP DIAL DIAL.DIGIT INIT.ANSWERING.MACHINE MAKE.REG.MENU 
	     OFF.HAND OFF.HOOK OFF.LINE OFF.PHONE ON.HAND ON.HOOK ON.LINE ON.PHONE PLAYIT RECORDIT 
	     REG.MENU.FN RINGING? STATUS STORE.MESSAGE TEST TEST.PLAY.FILE TEST.TONE TONE? 
	     WAIT.FOR.CALL)
	(P (FILESLOAD BUSEXTENDER BUSMASTER))))



(* The variables CTRL DATA DTMF and RST contain the i/o location addresses of the Communicard 
in the PC's i/o space)


(RPAQQ CTRL 630)

(RPAQQ DATA 631)

(RPAQQ DTMF 628)

(RPAQQ RST 629)



(* Variables identifying the different bits in the CTRL register)


(RPAQQ HAND 16)

(RPAQQ LINE 4)

(RPAQQ MONITOR 32)

(RPAQQ OH 1)

(RPAQQ PHONE 2)

(RPAQQ RDY 128)

(RPAQQ TONE 64)

(RPAQQ BACKWARDS.LIMIT 5000)

(RPAQQ BANK 4)

(RPAQQ BEEP.LIMIT 2000)

(RPAQQ ENB 8)

(RPAQQ FAST.LIMIT 5000)

(RPAQQ RESPONSE.LIMIT 30000)

(RPAQQ SLOW.LIMIT 5000)

(RPAQQ SMEAR.LIMIT 5000)

(RPAQQ SPEECH.THRESHOLD 128)

(RPAQQ SPEECH1.LIMIT 30000)

(RPAQQ SPEECH2.LIMIT 5000)

(RPAQQ SPEECH3.LIMIT 5000)



(* Utility functions)

(DEFINEQ

(BINARY
  [LAMBDA (INT)                                              (* pkh: "12-Dec-84 10:51")
                                                             (* Takes a decimal input number and converts it into a 
							     binary number which is printed out;
							     returns nothing)
    (PRINTNUM (QUOTE (FIX NIL 2))
	      INT)
    (PACK])

(BINSTAT
  [LAMBDA NIL                                                (* pkh: "20-Dec-84 12:32")
    (BINARY (BUS.INPUT CTRL])

(C.PEEK
  [LAMBDA NIL                                                (* pkh: "12-Dec-84 10:53")
                                                             (* Adds a process which reads the CTRL register of the 
							     Communicard at frequent intervals and prints out the 
							     register status)
    (ADD.PROCESS (QUOTE (while T do (BLOCK 250)
			       (printout T (POLL CTRL)
					 T])

(C.SETUP
  [LAMBDA NIL                                                (* pkh: "20-Dec-84 14:26")
    (BUS.RESET)
    (OFF.LINE)
    (ON.HAND)
    (OFF.HOOK)
    (ON.PHONE)
    (BINSTAT])

(CORRECT
  [LAMBDA (DATUM)                                            (* hdj " 1-Dec-84 17:21")
    (if (IGREATERP DATUM 127)
	then (IDIFFERENCE DATUM 128)
      else DATUM])

(HEX
  [LAMBDA (STR)                                              (* hdj "30-Nov-84 16:37")
    (PROG (LENGTH STRING)
          (SETQ STRING (SUBSTRING STR 1))
          (SETQ LENGTH (NCHARS STRING))
          (RETURN (for X from 1 to LENGTH sum (TIMES (EXPT 16 (IDIFFERENCE LENGTH X))
						     (HEXCHAR (GNC STRING])

(HEXCHAR
  [LAMBDA (CHAR)                                             (* hdj "30-Nov-84 16:36")
    (SELECTQ CHAR
	     ((0 1 2 3 4 5 6 7 8 9)
	       CHAR)
	     (A 10)
	     (B 11)
	     (C 12)
	     (D 13)
	     (E 14)
	     (F 15)
	     NIL])

(INP
  [LAMBDA (A)                                                (* hdj "30-Nov-84 17:14")
    (BUS.INPUT A])

(OUT
  [LAMBDA (A D)                                              (* hdj "30-Nov-84 17:14")
    (BUS.OUTPUT A D])

(POLL
  [LAMBDA (ADDR)                                             (* pkh: "12-Dec-84 10:54")

          (* Causes the byte at this address to be printed out. Notice that BINARY does not return the binary digit but rather
	  PACK of NIL)


    (BINARY (BUS.INPUT ADDR])

(START.CTRL.MONITOR
  [LAMBDA NIL                                                (* pkh: "19-Dec-84 17:58")
    (ADD.PROCESS (QUOTE (while T do (printout T (BINARY (BUS.INPUT CTRL))
					      T)
			       (BLOCK 100])

(TEST.PORT
  [LAMBDA NIL                                                (* pkh: "20-Dec-84 12:12")
    (while T
       do (BUS.OUTPUT DATA 32)
	  (BLOCK 1)
	  (BUS.OUTPUT DATA 128])
)
(DEFINEQ

(ANSWERING.MACHINE
  [LAMBDA NIL                                                (* hdj " 2-Dec-84 13:27")
    (PROG (PHONEMESSAGESTREAM)
          (SETQ PHONEMESSAGESTREAM (OPENSTREAM (QUOTE {DSK}<SPEECH>MESSAGES.SPEECH)
					       (QUOTE APPEND)))
          (printout STATUSSTREAM "-- Started at " (DATE)
		    " --" T)
          (while (WAIT.FOR.CALL)
	     do (OFF.HOOK)
		(printout STATUSSTREAM "call at " (DATE)
			  T)
		(PLAYIT SPEECH1.ARRAY)
		(PLAYIT BEEP.ARRAY)
		(RECORDIT RESPONSE.ARRAY)
		(PLAYIT SPEECH2.ARRAY)
		(PLAYIT RESPONSE.ARRAY)
		(PLAYIT BACKWARDS.ARRAY)
		(PLAYIT RESPONSE.ARRAY (QUOTE BACKWARDS))
		(PLAYIT SLOW.ARRAY)
		(PLAYIT RESPONSE.ARRAY (QUOTE SLOW))
		(PLAYIT FAST.ARRAY)
		(PLAYIT RESPONSE.ARRAY (QUOTE FAST))
		(PLAYIT SMEAR.ARRAY)
		(PLAYIT RESPONSE.ARRAY (QUOTE SMEAR))
		(PLAYIT SPEECH3.ARRAY)
		(BLOCK 2000)
		(ON.HOOK)
		(STORE.MESSAGE PHONEMESSAGESTREAM RESPONSE.ARRAY))
          (CLOSEF PHONEMESSAGESTREAM])

(COMMUNICARD.SETUP
  [LAMBDA NIL                                                (* pkh: "19-Dec-84 17:45")
    (BUS.RESET)
    (ON.LINE)
    (ON.HOOK])

(DIAL
  [LAMBDA (PHONE.NUMBER)                                     (* hdj " 2-Dec-84 11:46")
    (PROG ((STRING (SUBSTRING PHONE.NUMBER 1)))
          (for X from 1 to (NCHARS STRING) do (DIAL.DIGIT (GNC STRING])

(DIAL.DIGIT
  [LAMBDA (DIGIT)                                            (* hdj " 2-Dec-84 12:07")
    (if (ZEROP DIGIT)
	then (SETQ DIGIT 10))
    (if (NUMBERP DIGIT)
	then (for X from 1 to DIGIT
		do (PRIN3 ".")
		   (ON.HOOK)
		   (BLOCK 200)
		   (OFF.HOOK)
		   (BLOCK 100))
	     (TERPRI)
	     (BLOCK 2000])

(INIT.ANSWERING.MACHINE
  [LAMBDA NIL                                                (* hdj " 1-Dec-84 17:33")

          (* * comment)


    (PROG NIL
          (SETQ SPEECH1.ARRAY (ARRAY SPEECH1.LIMIT (QUOTE BYTE)
				     0 0))
          (SETQ SPEECH2.ARRAY (ARRAY SPEECH2.LIMIT (QUOTE BYTE)
				     0 0))
          (SETQ SPEECH3.ARRAY (ARRAY SPEECH3.LIMIT (QUOTE BYTE)
				     0 0))
          (SETQ RESPONSE.ARRAY (ARRAY RESPONSE.LIMIT (QUOTE BYTE)
				      0 0))
          (SETQ BACKWARDS.ARRAY (ARRAY BACKWARDS.LIMIT (QUOTE BYTE)
				       0 0))
          (printout T 
"now run TEST.RECORD on SPEECH1.ARRAY, SPEECH2.ARRAY, SPEECH3.ARRAY, RESPONSE.ARRAY, and BACKWARDS.ARRAY."
		    T])

(MAKE.REG.MENU
  [LAMBDA NIL                                                (* pkh: " 3-Dec-84 17:49")
    (ADDMENU (create MENU
		     ITEMS ← (APPEND (QUOTE (7 6 5 4 3 2 1 0))
				     (QUOTE (0 0 0 0 0 0 0 0)))
		     MENUCOLUMNS ← 8
		     WHENSELECTEDFN ← (QUOTE REG.MENU.FN])

(OFF.HAND
  [LAMBDA NIL                                                (* hdj " 2-Dec-84 11:27")
    (BUS.OUTPUT CTRL (LOGAND (LOGNOT HAND)
			     (BUS.INPUT CTRL])

(OFF.HOOK
  [LAMBDA NIL                                                (* hdj " 2-Dec-84 11:27")
    (BUS.OUTPUT CTRL (LOGOR (BUS.INPUT CTRL)
			    OH])

(OFF.LINE
  [LAMBDA NIL                                                (* hdj " 2-Dec-84 11:27")
    (BUS.OUTPUT CTRL (LOGAND (LOGNOT LINE)
			     (BUS.INPUT CTRL])

(OFF.PHONE
  [LAMBDA NIL                                                (* hdj " 2-Dec-84 11:27")
    (BUS.OUTPUT CTRL (LOGOR PHONE (BUS.INPUT CTRL])

(ON.HAND
  [LAMBDA NIL                                                (* hdj " 2-Dec-84 11:27")
    (BUS.OUTPUT CTRL (LOGOR HAND (BUS.INPUT CTRL])

(ON.HOOK
  [LAMBDA NIL                                                (* hdj " 2-Dec-84 11:27")
    (BUS.OUTPUT CTRL (LOGAND (BUS.INPUT CTRL)
			     (LOGNOT OH])

(ON.LINE
  [LAMBDA NIL                                                (* hdj " 2-Dec-84 11:27")
    (BUS.OUTPUT CTRL (LOGOR LINE (BUS.INPUT CTRL])

(ON.PHONE
  [LAMBDA NIL                                                (* hdj " 2-Dec-84 11:27")
    (BUS.OUTPUT CTRL (LOGAND (LOGNOT PHONE)
			     (BUS.INPUT CTRL])

(PLAYIT
  [LAMBDA (ARRAY OPTION)                                     (* hdj " 2-Dec-84 12:32")
    (LET [(LIMIT (SUB1 (ARRAYSIZE ARRAY]
      (SELECTQ OPTION
	       [SLOW (for DATUM from 0 to LIMIT
			do (BUS.OUTPUT DATA (ELT ARRAY DATUM))
			   (BUS.OUTPUT DATA (ELT ARRAY DATUM]
	       [FAST (for DATUM from 0 to LIMIT by 2 do (BUS.OUTPUT
							  DATA
							  (LRSH (IPLUS (ELT ARRAY DATUM)
								       (ELT ARRAY (ADD1 DATUM)))
								1]
	       [BACKWARDS (for DATUM from LIMIT to 0 by -1 do (BUS.OUTPUT DATA (ELT ARRAY DATUM]
	       [SMEAR (for DATUM from 0 to (IDIFFERENCE LIMIT 3)
			 do (BUS.OUTPUT DATA (ELT ARRAY (IPLUS DATUM 2)))
			    (BUS.OUTPUT DATA (ELT ARRAY (IPLUS DATUM 1)))
			    (BUS.OUTPUT DATA (ELT ARRAY DATUM]
	       (for DATUM from 0 to LIMIT do (BUS.OUTPUT DATA (ELT ARRAY DATUM])

(RECORDIT
  [LAMBDA (ARRAY)                                            (* hdj " 1-Dec-84 17:00")
    (BUS.OUTPUT DATA SPEECH.THRESHOLD)
    (for DATUM from 0 to (SUB1 (ARRAYSIZE ARRAY)) do (SETA ARRAY DATUM (BUS.INPUT DATA])

(REG.MENU.FN
  [LAMBDA (ITEM FROMMENU BUTTON)                             (* pkh: " 3-Dec-84 17:49")
    (IF ITEM = 0
	THEN NIL])

(RINGING?
  [LAMBDA NIL                                                (* pkh: "12-Dec-84 11:09")
                                                             (* Determines whether the phone is ringing by checking 
							     the MONITOR bit in the CTRL register.
							     Returns T when a ringing has been detected)
    (ZEROP (LOGAND MONITOR (BUS.INPUT CTRL])

(STATUS
  [LAMBDA NIL                                                (* pkh: "20-Dec-84 13:27")
    (PROG (STATUS)
          (SETQ STATUS (BUS.INPUT CTRL))
          (printout T "Status: ")
          (printout T (COND
		      ((ZEROP (LOGAND OH STATUS))
			"on")
		      (T "off"))
		    "hook/"
		    (COND
		      ((ZEROP (LOGAND PHONE STATUS))
			"")
		      (T "no "))
		    "phone/"
		    (COND
		      ((ZEROP (LOGAND LINE STATUS))
			"off")
		      (T "on"))
		    "line/"
		    (COND
		      ((ZEROP (LOGAND HAND STATUS))
			"off")
		      (T "on"))
		    "hand/"
		    (COND
		      ((ZEROP (LOGAND MONITOR STATUS))
			"")
		      (T "not "))
		    "ringing/"
		    (COND
		      ((ZEROP (LOGAND TONE STATUS))
			"no ")
		      (T ""))
		    "tone " T])

(STORE.MESSAGE
  [LAMBDA (FILE SAMPLE)                                      (* hdj " 2-Dec-84 13:31")
    (\BOUTS FILE (fetch (ARRAYP BASE) of SAMPLE)
	    0
	    (ARRAYSIZE SAMPLE])

(TEST
  [LAMBDA NIL                                                (* hdj " 2-Dec-84 11:27")
    (while T do (if (RINGING?)
		    then (OFF.HOOK)
			 (BUS.OUTPUT DATA SPEECH.THRESHOLD)
			 (for DATUM from 0 to (SUB1 SPEECH.LIMIT) do (SETA SPEECHARRAY DATUM
									   (BUS.INPUT DATA)))
			 (ON.HOOK])

(TEST.PLAY.FILE
  [LAMBDA (FILE)                                             (* hdj " 1-Dec-84 17:13")
    (while T do (if (RINGING?)
		    then (OFF.HOOK)
			 (for DATUM from 0 to (SUB1 SPEECH.LIMIT) do (BUS.OUTPUT DATA (BIN FILE)))
			 (ON.HOOK])

(TEST.TONE
  [LAMBDA NIL                                                (* pkh: "12-Dec-84 11:34")
    (PROG (THE.TONE)
          (while T
	     do (COND
		  ((RINGING?)
		    (OFF.HOOK)
		    (BLOCK 2000)))
		(COND
		  ((NOT (ZEROP (LOGAND (BUS.INPUT CTRL)
				       TONE)))
		    (printout T "tone " (LOGAND 15 (BUS.INPUT DTMF))
			      T)
		    (BUS.OUTPUT DTMF 0])

(TONE?
  [LAMBDA NIL                                                (* hdj " 2-Dec-84 12:10")
    (COND
      ((ZEROP (LOGAND (BUS.INPUT CTRL)
		      TONE))
	NIL)
      (T (PROG1 (LOGAND 15 (BUS.INPUT DTMF))
		(BUS.OUTPUT DTMF 0])

(WAIT.FOR.CALL
  [LAMBDA NIL                                                (* pkh: "12-Dec-84 11:12")

          (* Causes a block whenever both the phone is not ringing and no one is pressing the STOP (key; returns T when the 
	  phone is ringing provided the stop key is not depressed; if it is depressed it returns NIL))


    (while [AND (NOT (RINGING?))
		(NOT (KEYDOWNP (QUOTE STOP]
       do (BLOCK))
    (NOT (KEYDOWNP (QUOTE STOP])
)
(FILESLOAD BUSEXTENDER BUSMASTER)
(PUTPROPS COMMUNICARD COPYRIGHT ("Xerox Corporation" 1984 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (2062 5128 (BINARY 2072 . 2455) (BINSTAT 2457 . 2599) (C.PEEK 2601 . 3040) (C.SETUP 3042
 . 3260) (CORRECT 3262 . 3464) (HEX 3466 . 3857) (HEXCHAR 3859 . 4117) (INP 4119 . 4241) (OUT 4243 . 
4368) (POLL 4370 . 4663) (START.CTRL.MONITOR 4665 . 4915) (TEST.PORT 4917 . 5126)) (5129 14437 (
ANSWERING.MACHINE 5139 . 6238) (COMMUNICARD.SETUP 6240 . 6411) (DIAL 6413 . 6669) (DIAL.DIGIT 6671 . 
7065) (INIT.ANSWERING.MACHINE 7067 . 7842) (MAKE.REG.MENU 7844 . 8157) (OFF.HAND 8159 . 8348) (
OFF.HOOK 8350 . 8523) (OFF.LINE 8525 . 8714) (OFF.PHONE 8716 . 8885) (ON.HAND 8887 . 9053) (ON.HOOK 
9055 . 9241) (ON.LINE 9243 . 9409) (ON.PHONE 9411 . 9601) (PLAYIT 9603 . 10625) (RECORDIT 10627 . 
10899) (REG.MENU.FN 10901 . 11046) (RINGING? 11048 . 11445) (STATUS 11447 . 12313) (STORE.MESSAGE 
12315 . 12525) (TEST 12527 . 12897) (TEST.PLAY.FILE 12899 . 13211) (TEST.TONE 13213 . 13655) (TONE? 
13657 . 13928) (WAIT.FOR.CALL 13930 . 14435)))))
STOP