C C C. Program to transfer data to or from the HP9820 C. calculator via the HP11205A serial io interface. C. The output cable from the serial io interface C. is connected to the RS-232 cable from the DL-11 C. interface in the PDP-11/45. This requires that C. the regular terminal be disconnected. The null C. modem is not required for communications via the C. HP11205A interface. The HP peripheral control II C. ROM is used. C C. Note that the baud rate for the DL-11 interface in C. the PDP-11 and the baud rate for the HP11205A interface C. must be the same. For the program tests, 1200 C. baud was used. C C. ** IdioSyncrasies of the Communications system: ** C C. The 11205A interface echoes all input characters C. this results in 'TYPE-AHEAD' being filled C. on a transfer from the 11 to the HP9820. C. RSX-11D version 6.2 permits type-ahead to be cleared C. by program command. C C. The slow speed of the HP system requires that the C. PDP-11 do a wait before writing to the HP so the C. HP can either get into the state to read data or C. put data away before another character is sent. C. The buffer in the HP11205A interface is only one C. character long , but the character is not stored if the C. interface is not doing a read function when the character C. arrives. C C. If no wait is specified i.e. in response to prompt C. a default wait of 0.35 second is used. The actual wait C. required is both a function of the hardware and how C. the HP9820 program is written. For the program used C. in debugging the system, the minimum waits required: C. HP9820 to PDP-11 350 Milliseconds minimum (25O bad, 300 OK) C. PDP-11 to HP9820 350 Milliseconds minimum (150 bad, 200 OK) C C. If a wait is done before a read, the data being C. sent by the HP9820 goes into the 'TYPE-AHEAD' buffer. C. Due to the peculiarities of the 'TYPE-AHEAD' C. buffer the data can be lost. C C. All of the above waits are waits within the PDP-11 C. not the HP9820 wait function!! C C. A slight delay (such as a single instruction) must be C. done between a 'READ BYTE' and 'WRITE BYTE' command to the C. HP11205A interface to prevent extra bits being added to C. the byte written out.this may also be a problem with HP C. 'READ' & 'WRITE' commands also. C C. The HP 'READ' command is not capable of reading C. alphabetic characters other than the 'E' in the C. exponential format. See page 2-6 Peripheral Control C. book. C C C. For debugging purposes the any terminal can be substituted C. for the HP9820 system. This works for transfers in either C. direction. The null modem is not required if the calculator C. is being connected directly to a HP2640 terminal. Any required C. data and control characters are typed on the HP2640A. C C. The task may be built with the /-FP switch. C. It must be built with the /-CP switch since C. getting checkpointed during a data transfer C. could result in lost data or control characters. C. The priority should be specified such that other C. user programs will not keep this program from running. C. PRI=200 used in task build. C C. Signals used in the communications: C C. [Send] S --sender:HP9820, transfer t0 11 from 9820 request C. [Receive] R --sender:HP9820, transfer to 9820 from 11 request C. [Go] G --sender:PDP-11, ready for more data from 9820 C. [Fire] F --sender:HP9820, ready for more data from 11 C. [Memory] M --sender:HP9820, more data from 11 will overflow C. 9820 memory C. [Done] D --sender:PDP-11, ^z received by 11,files closed C. [Done] D --sender:HP9820, ^z received from 11. C. [CTRL Z] Z --sender: both , indicates end of file, also will C. cause an exit to MCR when sent from C. 9820 if program is waiting for C. a S or R. C C C. Files created from the HP9820 data are in ASCII format C. so there will be no restrictions with data types C. control characters are not written though. C C. Program uses the FORTRAN debug feature! C C. Program history: C. C. Written by W.t. Howatt C. Crnl nov 1976, for RSX-11D version 6B Modified september 1977 C. for RSX-11D version 6.2. C C IMPLICIT LOGICAL*1 (D) IMPLICIT LOGICAL*1 (B) DIMENSION BUFFER(80), DSTAT(4) COMMON /DCF/ DS, DR, DG, DF, DCR, DLF, DD, 1DM, DZ, DW, DRD COMMON/LUN/ LHP, LDSKI, LDSKO, LBUG, LUT COMMON /ITIM/ITIX DATA DS, DR, DG, DF, DCR, DLF, DD, DM, DZ/ 1"123, "122, "107, "106, "15, "12, "104, "115, "132/ DATA LHP, LDSKI, LDSKO, LBUG, LUT/ 1 3, 2, 1, 4, 5/ C CALL GETMCR (BUFFER,IDS) LBUG = 4 !DEBUG LUN C WRITE (LUT, 220) 220 FORMAT(' HP9820 - PDP-11 DATA TRANSFER PROGRAM',/, 1 ' **** SET BAUD RATES CORRECTLY ****',//) 348 WRITE (LUT, 349) 349 FORMAT ('$INTERFACE ? (HP0 OR HP1) > ') ITERM = -1 READ (LUT, 350, END=30) HP 350 FORMAT (A3) IF (HP .EQ. 'HP0') ITERM = 2 IF (HP .EQ. 'HP1') ITERM = 3 IF (HP .EQ. 'TT0') ITERM = 0 IF (HP .EQ. 'TT1') ITERM = 1 IF (HP .EQ. 'TT4') ITERM = 4 IF (ITERM .EQ. -1) GO TO 348 C CALL ASNLUN ( LHP, 'TT', ITERM, IDS) IF (IDS .LT. 0) STOP ' CANT ASSIGN LUN TO HP' C CALL ASSIGN (LBUG, 'TI:', 3) C C. Detach from HP lun before attach CALL WTQIO ("2000, LHP, 4, , DSTAT,0,IDS) IF (IDS .LT. 0) STOP ' INITIAL DETACH DIRECTIVE FAILURE' IF (DSTAT(1) .LT. -7) STOP ' BAD INITIAL DETACH STATUS' C C. Attach HP calculator CALL WTQIO ("1400, LHP, 2, , DSTAT, 0, IDS) IF (IDS .LT. 0) STOP ' HP ATTACH DIRECTIVE FAILURE' IF (DSTAT(1) .GT. 0) GO TO 2 WRITE(LBUG, 4) DSTAT(1) 4 FORMAT(' BAD ATTACH STATUS, STATUS = ',I4) GO TO 348 C C. Main program loop: Program always gets back here after C. a file transfer. C 2 DW=.TRUE. DRD=.FALSE. ITIX = 35 5 CONTINUE D WRITE(LBUG,366) D366 FORMAT('$WAIT (MILLISECONDS) > ') D READ(LBUG,367,END=30,ERR=5) ITIX C. Set default to 350 ms & convert to clock ticks D IF(ITIX.EQ.0) ITIX=350 D ITIX=ITIX/10 D367 FORMAT(I6) CALL CLRTYP !CLEAR TYPEAHEAD WRITE (LUT, 700) 700 FORMAT(' HPXFR WAITING FOR S, R, OR Z' ) 10 ICHR=80 NTRC=1 CALL QIORW(LHP, BUFFER, ICHR, DRD, NTRC) C. Examine buffer for legal control characters or Z. DCTRL = 0 DO 20 I=1,ICHR IF(BUFFER(I).EQ.DZ) GO TO 30 IF(BUFFER(I) .EQ. DS .OR. BUFFER(I) .EQ. DR) DCTRL = BUFFER(I) 20 CONTINUE IF(DCTRL.NE.DS) GO TO 25 CALL IACEPT GO TO 5 25 IF(DCTRL.NE.DR) GO TO 26 CALL ISEND GO TO 5 26 CONTINUE WRITE(LUT,710)(BUFFER(K),K=1,ICHR),ICHR 710 FORMAT(' HPXFR--ILLEGAL CHARACTER--NOT S, R OR Z' 1,/,1X,40O3,I4) GO TO 5 30 CONTINUE WRITE(LUT,720) 720 FORMAT(' HPXFR--EXIT CALLED VIA HP9820 OR TI',//) C. Detach the HP calculator lun CALL WTQIO("2000, LHP, 3,,DSTAT,0,IDS) IF(IDS .LT. 0) STOP 'HPXFR - FINAL DETACH DIRECTIVE FAILURE' IF(DSTAT(1) .LT. -7) STOP 'HPXFR - BAD FINAL DETACH STATUS' 730 CALL EXIT END SUBROUTINE ISEND C. This routine is for sending data to the HP9820. C. Entered when 'R' is received from 9820. C. It does the following: C. Opens a file C. Waits for F from 9820 C. Reads record from file C. Checks for Z and counts characters C. Sends HP9820 character count C. (used by 9820 to select correct format) C. waits for F from 9820 C. If F--send the data record or a Z C. If M--no transfer--return C. If Z sent , wait for HP9820 to send D C. return C IMPLICIT LOGICAL*1 (B) IMPLICIT LOGICAL*1 (D) DIMENSION BUFFER(80), DNAME(32), DSTAT(4),BUFCHR(5) COMMON /LUN/ LHP, LDSKI, LDSKO, LBUG, LUT COMMON /DCF/ DS, DR, DG, DF, DCR, DLF, 1DD, DM, DZ, DW, DRD C NTRC=0 D WRITE(LBUG,215) D215 FORMAT(' HPXFR--ISEND CALLED VIA HP9820!!!!') C C. Open file to obtain data, get filename first 150 WRITE(LUT,200) 200 FORMAT('$ENTER FILENAME FOR DATA > ') READ(LUT,300,END=777,ERR=150) NCHR,DNAME 300 FORMAT(Q,32A1) DNAME(NCHR+1) = 0 WRITE(LUT, 305) 305 FORMAT(/) C CLOSE (UNIT=LDSKO) C. Specify file as readonly since no write is required and it C. also will prevent file from being locked if abort required. OPEN (UNIT=LDSKO, NAME=DNAME, TYPE='OLD', READONLY, ERR=325) GO TO 450 325 WRITE(LUT,350) (DNAME(I),I=1,NCHR) 350 FORMAT(' ISEND--BAD OPEN ',32A1) GO TO 150 C 450 CALL CLEAR C C. Look for a F indicating HP ready to start data transfer NCHR=5 NTRC=60 CALL QIORW(LHP,BUFCHR,NCHR,DRD,NTRC) C C. Check characters from 9820 to see if we should start C. data transfer, stop sending data or are finished. BSTRT=.FALSE. DO 500 J=1,NCHR IF(BUFCHR(J).EQ.DF) BSTRT=.TRUE. IF(BUFCHR(J).EQ.DM) GO TO 910 IF(BUFCHR(J).EQ.DD) GO TO 750 500 CONTINUE D WRITE(LBUG,333) (BUFCHR(L),L=1,NCHR) D333 FORMAT( ' BUFCHR ',5(1X,O4)) IF(.NOT.BSTRT) GO TO 450 C C. Read a record from disk. READ(LDSKO,600,ERR=900,END=700) NCTR, BUFFER 600 FORMAT(Q,80A1) D WRITE(LBUG,610) (BUFFER(I),I=1,NCTR) D610 FORMAT(' DISK READ:',/ D 1,66A1,/,40A1) C C. Write character count to HP for formatting C. must use encode to get it into ASCII for HP ENCODE(2,1000,BUFCHR)NCTR 1000 FORMAT(I2) C. Put in a LF for HP 'RED' function NCHR=3 BUFCHR(3)=DLF D NTRC=65 DO 650 K=1,NCHR CALL QIORW(LHP,BUFCHR(K),1,DW,NTRC) 650 CONTINUE C 670 CALL CLEAR C C. Look for F after char count indicating HP ready for data. NCHR=4 D NTRC=66 CALL QIORW(LHP,BUFCHR,NCHR,DRD,NTRC) D WRITE(LBUG,444) (BUFCHR(L),L=1,NCHR) D444 FORMAT(' 1BUFCHR ',5(1X,O4)) DASTRT=.FALSE. DO 675 J=1,NCHR IF(BUFCHR(J).EQ.DM) GO TO 910 IF(BUFCHR(J).EQ.DF) DASTRT=.TRUE. 675 CONTINUE IF(.NOT.DASTRT) GO TO 670 C C. Now we can send the record of data to HP C. since HP slow, put wait between characters i.e. C. wait-char-wait-char-wait-char.........char-wait-LF C. HP 'RED' format looks for LF as end of record. C BUFFER(NCTR+1)=DLF D NTRC=68 DO 685 K=1,NCTR+1 CALL QIORW(LHP,BUFFER(K),1,DW,NTRC) 685 CONTINUE GO TO 450 C C. End of file detected C. Inform HP to set up for byte read by telling it one char is coming. 700 ENCODE(2,1000,BUFCHR)01 NCHR=3 C. Put a LF in for benefit of HP 'RED' statement BUFCHR(3)=DLF D NTRC=70 DO 744 J=1,NCHR CALL QIORW(LHP,BUFCHR(J),1,DW,NTRC) 744 CONTINUE C C. Should get a F back from HP now D NTRC=80 800 NCHR=5 CALL QIORW(LHP,BUFCHR,NCHR,DRD,NTRC) DO 810, J=1,NCHR IF(BUFCHR(J).EQ.DF) GO TO 820 810 CONTINUE GO TO 800 C C. Now send the Z (end of file) character 820 NCHR=1 BUFCHR(1)=DZ D NTRC=85 CALL QIORW(LHP,BUFCHR,NCHR,DW,NTRC) C C. Should get D (done) back from HP 710 NCHR=5 D NTRC=72 CALL QIORW(LHP,BUFCHR,NCHR,DRD,NTRC) DO 730 I=1,NCHR IF(BUFCHR(I).EQ.DD) GO TO 750 730 CONTINUE WRITE(LUT,740) (BUFCHR(I),I=1,NCHR) 740 FORMAT(' ISEND--D EXPECTED, RECEIVED ', 6A1) GO TO 710 750 WRITE(LUT,760) 760 FORMAT(' DONE RECEIVED FROM HP9820') CLOSE (UNIT=LDSKO) 777 RETURN C C. Error section 900 WRITE(LUT,905) 905 FORMAT(' ISEND--READ ERROR ON INPUT DEVICE--EXITING') CLOSE (UNIT=LDSKO) CALL EXIT 910 CLOSE (UNIT=LDSKO) WRITE(LUT,915) 915 FORMAT(' ISEND--HP MEMORY CAPACITY (MAY BE) EXCEEDED') RETURN END SUBROUTINE IACEPT C. This routine is for accepting data from the HP9820. C. Entered when a 'S' is received from HP9820. C. It does the following: C. Opens a file C. Sends a G (G for go) C. Accepts 4 registers from HP9820 C. Tests for Z C. Writes proper data to file C. Sends G to HP9820 to request more data C. when receives Z(END OF FILE) closes file C. Sends HP9820 a D character to indicate C. end of transmission. C IMPLICIT LOGICAL*1 (B) IMPLICIT LOGICAL*1 (D) DIMENSION DNAME(32),BUFFER(80),DSTAT(4),DVALID(6) COMMON /LUN/ LHP, LDSKI, LDSKO, LBUG, LUT COMMON /DCF/ DS, DR, DG, DF, DCR, DLF, DD, 1DM, DZ, DW, DRD DATA DVALID / "56, "55, "53, "40, "105, "132 / C. . - + Space E Z C NTRC=0 C. Give message for initial debugging D WRITE (LBUG,215) D215 FORMAT (' IACEPT--ACCEPT CALLED VIA 9820 !!!!!'/) C 100 FORMAT(80A1) C. Open a file to put the data into, get a filename first 150 WRITE(LUT,200) 200 FORMAT('$ENTER FILENAME TO STORE DATA > ') READ (LUT,300,END=777,ERR=150) NCHR,DNAME 300 FORMAT(Q,32A1) DNAME(NCHR+1) = 0 WRITE(LUT, 305) 305 FORMAT(/) CLOSE (UNIT=LDSKI) OPEN (UNIT=LDSKI, NAME=DNAME, TYPE='NEW', ERR=325, 1 CARRIAGECONTROL='LIST') GO TO 400 325 WRITE(LUT,350)(DNAME(I),I=1,NCHR) 350 FORMAT(' IACEPT--BAD OPEN ',32A1) GO TO 150 C 400 CONTINUE D WRITE(LBUG,401) D401 FORMAT(' FILE OPEN') C CALL CLRTYP C C. Send a G to HP9820 to start data transfer C. do this section until Z encountered 375 BUFFER(1)=DG NCHR=1 CALL QIORW(LHP, BUFFER, NCHR, DW, NTRC) C. Do QIO to read data assume 80 characters. 450 NCHR=80 NTRC=20 CALL QIORW(LHP,BUFFER,NCHR,DRD,NTRC) C. Write first 5 characters in octal format D WRITE(LBUG,217) (BUFFER(L),L=1,5) D217 FORMAT(' BUFFER READ :',5(1X,O4)) C C. Check for Z or data IFRST=1 BEND=.FALSE. C. Loop takes only valid data after superflous C. control characters & garbage. Helps eliminate C. any junk left over in type-ahead on first time C. through. Assumes last char on line is a . C. A line is processed until a Z is detected, C. a line with a Z imbedded is written up to Z inclusive. C. However, the Z is changed to a CTRL Z to close the file. C DO 475 K=1,NCHR IF(BUFFER(K).NE.DZ) GO TO 470 BEND=.TRUE. BUFFER(K) = BUFFER(K) - "100 !Now ^Z GO TO 476 470 DO 474 L=1,6 IF(BUFFER(K).EQ.DVALID(L)) GO TO 475 474 CONTINUE IF(BUFFER(K) .LT."60 .OR. BUFFER(K) .GT."71) IFRST=K+1 475 CONTINUE 476 CONTINUE D WRITE(LBUG,501)IFRST,NCHR,BEND D501 FORMAT(' IFRST= ',I4,' NCHR= ',I4 D 1,' BEND= ',L5) C. Following condition true only if garbage on line IF(IFRST.GT.NCHR) GO TO 375 C. Write buffer into file. WRITE(LDSKI,100,ERR=950) (BUFFER(J),J=IFRST,NCHR) IF(.NOT.BEND) GO TO 375 C 600 CLOSE (UNIT=LDSKI) D WRITE(LBUG,610) D610 FORMAT(' Z DETECTED FROM 9820-FILE CLOSED') C. Send D to HP9820 BUFFER(1)=DD NCHR=1 NTRC=40 CALL QIORW(LHP,BUFFER,NCHR,DW,NTRC) D WRITE(LBUG,650) D650 FORMAT(' IACEPT--DONE SENT TO HP9820',//) 777 RETURN 950 CONTINUE WRITE(LBUG,951) 951 FORMAT(' IACEPT--I/O ERROR ON OUTPUT DEVICE--EXIT CALLED') CALL EXIT END SUBROUTINE CLEAR C. Subroutine to clear typeahead buffer via call to 'CLRTYP' C. and then send a 'G' to the HP9820 to indicate ready to go. C LOGICAL*1 DW COMMON /LUN/ LHP, LDSKI, LDSKO, LBUG, LUT C CALL CLRTYP C C. Tell HP TYPEAHEAD is cleared and we are ready D NTRC = 70 BUF = 'G' NCHR = 1 DW = .TRUE. CALL QIORW(LHP, BUF, NCHR, DW, NTRC) RETURN END SUBROUTINE CLRTYP C. Does QIO with zero length timeout to clear typeahead. C DIMENSION IPRMR(6) LOGICAL*1 BUFFER(80), DSTAT(4) COMMON /LUN/ LHP, LDSKI, LDSKO, LBUG, LUT DATA IRVB, IRNE, IEFN, ITMO/ 1 "10400, 16, 1, "200/ C IREAD = IRVB + IRNE + ITMO CALL GETADR(IPRMR, BUFFER) IPRMR(2) = 80 IPRMR(3) = 0 !0 LENGTH TIMEOUT TO CLR 100 CALL WTQIO(IREAD, LHP, IEFN, , DSTAT, IPRMR, IDS) IF(IDS .LT. 0) GO TO 900 IF(DSTAT(1) .LT. 0) GO TO 920 IF(DSTAT(1) .NE. 2) GO TO 100 RETURN C C. Error section 900 WRITE(LBUG,910) IDS 910 FORMAT(' CLRTYP--QIO FAILURE IDS = ',I4) CALL EXIT 920 WRITE(LBUG,930) DSTAT(1) 930 FORMAT(' CLRTYP--QIO FAILURE STATUS = ',I4) CALL EXIT END SUBROUTINE QIORW(LUN,BUFFER,NCHAR,DWRITE,ITRACE) C. Parameter DWRITE controls the QIO function C C. DWRITE=false, Do a read QIO C. DWRITE=true, Do a write QIO C. WAITQIO is function used C C. Lun is the lun for the QIO C. Buffer is QIO data area C. Char is the character count C. ITRACE is a number printed when debug is on C. allows tracing program execution C. a wait is done before a write QIO C LOGICAL *1 BUFFER(80),DSTAT(4),DWRITE DIMENSION IPRMR(6) COMMON/ITIM/ ITIX EQUIVALENCE (ICHR,DSTAT(3)) DATA IRVB, IPASS, IRNE, IEFN, IWVB, ITMO/ 1"10400, 8, 16, 1, "11000, "200 / LBUG=4 DO 10 I=1,6 IPRMR(I)=0 10 CONTINUE D WRITE(LBUG,15) ITRACE D15 FORMAT(' QIORW--TRACE= ',I4) IF(DWRITE) GO TO 500 C C. Read QIO section---timeout & no echo 105 CONTINUE D WRITE(LBUG,250) D250 FORMAT(' READ QIO CALLED') IREAD=IRVB + IRNE + ITMO CALL GETADR(IPRMR,BUFFER) IPRMR(2)=NCHAR IPRMR(3) = 1 CALL WTQIO(IREAD,LUN,IEFN,,DSTAT,IPRMR,IDS) IF(IDS.LT.0) GO TO 900 IF(DSTAT(1) .LT. 0 .AND. DSTAT(1) .NE. -10) GO TO 920 IF(DSTAT(1) .NE. 2) GO TO 247 WRITE(5,300) 300 FORMAT(' QIORW--READ TMO') IF(ICHR .GT. 0) WRITE(5,301) (BUFFER(K), K=1,ICHR) 301 FORMAT(1X, A1) GO TO 105 247 NCHAR=ICHR D WRITE(LBUG,251) D251 FORMAT(' RETURNING FROM READ QIO') RETURN C C. Write QIO section 500 CONTINUE CALL WAIT(ITIX, 0, IDS) IF(IDS .LT. 0) STOP 'QIORW--WAIT DIRECTIVE FAILURE' D WRITE(LBUG,260) D260 FORMAT(' WRITE QIO CALLED') IWRIT=IWVB CALL GETADR(IPRMR,BUFFER) IPRMR(2)=NCHAR CALL WTQIO(IWRIT,LUN,IEFN,,DSTAT,IPRMR,IDS) IF(IDS.LT.0) GO TO 900 IF(DSTAT(1).LT.0) GO TO 920 D WRITE(LBUG,261) D261 FORMAT(' RETURNING FROM WRITE QIO') RETURN C C. Error message handling area C 900 CONTINUE WRITE(LBUG,950) IDS,DWRITE 950 FORMAT(' QIORW--QIO FAILURE IDS= ',I4, 1' WRITE? ',L4) CALL EXIT 920 CONTINUE WRITE(LBUG,960) DSTAT(1),DWRITE 960 FORMAT(' QIORW--QIO FAILURE STATUS =',I4, 1' WRITE? ',L4) CALL EXIT END