.TITLE LABWORK - LAB DATA ACQUISITION ROUTINES .IDENT /V0103/ .ENABLE LC ; ; VERSION 1.3 ; ; This is a collection of various subroutines used with my data ; acquisition programs. Included here are some TE16 mag tape ; handling routines, a DR11-K input routine, and AR11 input/output ; routines. ; ; Before using these routines on your system be sure that the ; CSR's for the TE16, the DR11-K, the AR11, and the front panel ; switch register are right for your system. Also note that this ; was written for a PDP-11/55 which has 18 bit addressing, so if ; you have a PDP-11/70 or another 22 bit addressable machine realize ; that these tape routines will NOT work on your machine without ; modifications. I leave all modifications to the user. ; ; Author : Richard A. Crawford ; E-Systems, Inc. ; P.O. Box 1056 CBN-27 ; Greenville, Texas 75401 ; (214) 457-6018 ; ; Date : January 5, 1984 ; ; Revisions: ; 1.1 : January 10, 1984 - Added AR11 routines ; 1.2 : January 18, 1984 - Improved AR11 routines to work ; faster and better. ; 1.3 : January 19, 1984 - Added Line Clock Start and Stop Code ; .PAGE .SBTTL DEFINE - DEFINITIONS OF VARIABLES USED IN LABWORK ; ; DEFINE SYSTEM DIRECTIVES ; .MCALL STIM$,DIR$ ; ; TE16 MAG TAPE REGISTER DEFINITIONS ; MTCS1=172440 ;CSR 1 MTWC= 172442 ;Word count register MTBA= 172444 ;UNIBUS address register MTFC= 172446 ;Frame count MTCS2=172450 ;CSR 2 MTFS= 172452 ;Formatter status MTER= 172454 ;Error register MTAS= 172456 ;Attention summary MTDT= 172466 ;Drive type MTTC= 172472 ;Tape control ; ; TE16 TAPE FUNCTION COMMANDS ; REWOFF=03 ;Rewind Offline REWIND=07 ;Rewind DRVCLR=11 ;Drive Clear ERASE =25 ;Erase Tape WRTMRK=27 ;Write File Mark SPCFOR=31 ;Space Forward SPCREV=33 ;Space Reverse WRTCKF=51 ;Write Check Forward WRTCKR=57 ;Write Check Reverse WRTFOR=61 ;Write Forward REDFOR=71 ;Read Forward REDREV=77 ;Read Reverse ; ; ; BIT DEFINITIONS ; BIT0 = 1 BIT1 = 2 BIT2 = 4 BIT3 = 10 BIT4 = 20 BIT5 = 40 BIT6 = 100 BIT7 = 200 BIT8 = 400 BIT9 = 1000 BIT10= 2000 BIT11= 4000 BIT12= 10000 BIT13= 20000 BIT14= 40000 BIT15= 100000 ; ; DR11-K CSR AND INPUT REGISTER DEFINITIONS ; DRCSR=170420 ;DR11-K CSR DRINRG=170422 ;DR11-K Input Register ; ; FRONT PANEL SWITCH REGISTER DEFINITION ; SWR=177570 ; ; AR11 REGISTER DEFINITIONS ; ADSR=170400 ;A/D Status Register ADBR=170402 ;A/D Buffer CKSR=170404 ;Clock Status Register CKBR=170406 ;Clock Buffer/Preset Buffer DASR=170410 ;D/A Display Status Register XBUF=170412 ;D/A Channel 0 D/A Buffer YBUF=170414 ;D/A Channel 1 D/A Buffer ADMASK=40 ;A/D Status Register Mask CKMASK=401 ;A/D Clock Status Register Mask DAMASK=0 ;D/A Display Register Mask ; ; LINE CLOCK STATUS REGISTER DEFINITION (RAC1.3) ; LNCLK=177546 ; ; DIGITAL PATHWAYS TCU-150 REGISTER ASSIGNMENTS (RAC1.3) ; YRMODA=160770 ;Bits 0 - 4 : Day ;Bits 5 - 8 : Month ;Bits 9 -15 : Year HRMIN =160772 ;Bits 0 - 4 : Minutes ;Bits 8 -12 : Hours SEC =160774 ;Bits 0 - 5 : Seconds ; ; MASKS FOR ROUTINE THAT GETS TIME FROM THE TCU-150 (RAC1.3) ; YRMSK =000777 ;Blank out Month and Day MONMSK=177037 ;Blank out Year and Day DAYMSK=177740 ;Blank out Year and Month HRMSK =160377 ;Blank out Minutes MINMSK=177700 ;Blank out Hours SECMSK=177700 ;Blank out all but Seconds ; ; SET UP A BUFFER TO HOLD THE TIME (RAC1.3) ; NEWTIM: .BLKW 10 OLDTIM: .BLKW 10 ; ; STIM$ DPB (RAC1.3) ; SETTIM: STIM$ NEWTIM,OLDTIM ; ; EXIT STATUS DEFINITIONS ; STAT1: ;EXIT STATUS +1 ;STATUS = 1 : Everything is OK .WORD 1,0 .WORD 1 .WORD STAT1 STATN1: ;EXIT STATUS -1 ;STATUS = -1 : Something's wrong .WORD -1,0 .WORD 1 .WORD STATN1 .PAGE .SBTTL INITAT - MAG TAPE INITIALIZATION ROUTINE ; ; INITAT initializes the mag tape registers, clears all errors, ; and selects the proper controller and formatter. ; ; Calling sequence : CALL INITAT(IN) ; Where : ; IN is the tape drive number ; INITAT:: ;FORTRAN ENTRY POINT FOR INITIALIZING TAPE REGISTERS MOV @2(R5),R0 ;Get tape drive number BIS #BIT5,MTCS2 ;Clear errors, initialize controller ;and formatter BIC #BIT0!BIT1!BIT2,MTCS2 ;Select Formatter 0 BIC #177777,MTTC ;Clear Tape Control Register XOR R0,MTTC ;Select proper drive number BIC #177777,MTFC ;Clear Frame Count Register BIC #177777,MTWC ;Clear Word Count Register BIC #177777,MTBA ;Clear Base Address Register BIC #177777,MTCS1 ;Clear Status and Control Register 1 BIS #BIT0,MTCS1 ;Issue a NO-OP to CSR1 RTS PC ;Return .PAGE .SBTTL SETWRT - TAPE REGISTER MASK DEFINITION ROUTINE FOR WRITTING ; ; SETWRT initializes the various register masks used in the ; routine TPBLTR. ; ; Calling sequence : CALL SETWRT(IN,LEN,EXTADD(1),EXTADD(2), ; TCMASK,WCMASK,FCMASK,CSRMSK(1),CSRMSK(2)) ; Where: ; IN is the tape drive number, ; LEN is the length of the array to be written, ; EXTADD'S are the address extension bits for the arrays, ; TCMASK is the Tape Control Mask, ; WCMASK is the Word Count Mask, ; FCMASK is the Frame Count Mask and, ; CSRMSK'S are the CSR1 masks for both arrays. SETWRT::;FORTRAN ENTRY FOR MASK DEFINITIONS FOR WRITTING ;Define TCMASK (Tape Control Mask) BIC #177777,R0 ;Clear R0 BIS #BIT10!BIT7!BIT6,R0 ;Select 1600 BPI Formatter Map MOV @2(R5),R1 ;Get the drive number XOR R1,R0 ;Move drive number into mask MOV R0,@12(R5) ;Move R0 into TCMASK ;Define WCMASK (Word Count Mask) MOV @4(R5),R0 ;Get array length NEG R0 ;Make a two's compliment of R0 MOV R0,@14(R5) ;Move R0 into WCMASK ;Define FCMASK (Frame Count Mask) ASL R0 ;Double R0 (words to bytes) MOV R0,@16(R5) ;Move R0 into FCMASK ;Define CSRMSK(1) (Write Mask for Array #1) MOV @6(R5),R0 ;Get address extension bits for Array 1 ASH #10,R0 ;Shift bits to proper location MOV #WRTFOR,R1 ;Move Write Mask into R1 XOR R1,R0 ;Put UNIBUS Ext. bits into Write Mask MOV R0,@20(R5) ;Move R0 into CSRMSK(1) ;Define CSRMSK(2) (Write Mask for Array #2) MOV @10(R5),R0 ;Get address extension bits for Array 1 ASH #10,R0 ;Shift bits to proper location MOV #WRTFOR,R1 ;Move Write Mask into R1 XOR R1,R0 ;Put UNIBUS Ext. bits into Write Mask MOV R0,@22(R5) ;Move R0 into CSRMSK(2) RTS PC ;Return to caller .PAGE .SBTTL SETRED - TAPE REGISTER MASK DEFINITION ROUTINE FOR READING ; ; SETRED initializes the various register masks used in the ; routine TPBLTR. ; ; Calling sequence : CALL SETRED(IN,LEN,EXTADD(1),EXTADD(2), ; TCMASK,WCMASK,FCMASK,CSRMSK(1),CSRMSK(2)) ; Where: ; IN is the tape drive number, ; LEN is the length of the array to be written, ; EXTADD'S are the address extension bits for the arrays, ; TCMASK is the Tape Control Mask, ; WCMASK is the Word Count Mask, ; FCMASK is the Frame Count Mask and, ; CSRMSK'S are the CSR1 masks for both arrays. SETRED::;FORTRAN ENTRY FOR MASK DEFINITIONS FOR READING ;Define TCMASK (Tape Control Mask) BIC #177777,R0 ;Clear R0 BIS #BIT10!BIT7!BIT6,R0 ;Select 1600 BPI Formatter Map MOV @2(R5),R1 ;Get the drive number XOR R1,R0 ;Move drive number into mask MOV R0,@12(R5) ;Move R0 into TCMASK ;Define WCMASK (Word Count Mask) MOV @4(R5),R0 ;Get array length NEG R0 ;Make a two's compliment of R0 MOV R0,@14(R5) ;Move R0 into WCMASK ;Define FCMASK (Frame Count Mask) ASL R0 ;Double R0 (words to bytes) MOV R0,@16(R5) ;Move R0 into FCMASK ;Define CSRMSK(1) (Read Mask for Array #1) MOV @6(R5),R0 ;Get address extension bits for Array 1 ASH #10,R0 ;Shift bits to proper location MOV #REDFOR,R1 ;Move Read Mask into R1 XOR R1,R0 ;Put UNIBUS Ext. bits into Read Mask MOV R0,@20(R5) ;Move R0 into CSRMSK(1) ;Define CSRMSK(2) (Read Mask for Array #2) MOV @10(R5),R0 ;Get address extension bits for Array 1 ASH #10,R0 ;Shift bits to proper location MOV #REDFOR,R1 ;Move Read Mask into R1 XOR R1,R0 ;Put UNIBUS Ext. bits into Read Mask MOV R0,@22(R5) ;Move R0 into CSRMSK(2) RTS PC ;Return to caller .PAGE .SBTTL TPBLTR - MAG TAPE BLOCK TRANSFER ROUTINE ; ; ; TPBLTR will either read a block from a tape and put it into a ; buffer or it will accept a buffer from the caller and will write ; that block to a tape. It was written for TE16 tape drives. Notice ; that there is not much error checking as this routine was written ; for speed. ; ; Calling sequence: CALL TPBLTR(TCMASK,WCMASK,FCMASK,BASADD,CSRMSK) ; Where : ; TCMASK is the Tape Control Mask, ; WCMASK is the Word Count Mask, ; FCMASK is the Frame Count Mask, ; BASADD is the lower 16 bits of the address of the output array, ; CSRMSK is the tape CSR1 mask. ; TPBLTR::;FORTRAN ENTRY POINT FOR WRITTING TO MAG TAPE BIT #BIT0,MTCS1 ;Previous block finished? BEQ 5$ ;Yes, then continue on ;Block not written so we got bad problems MOV #STATN1+4,R5 ;Set Exit Status to -1 JSR PC,EXST ;Call Exit With Status ;Take care of any errors produced during the previous operation 5$: BIT #BIT14,MTFS ;Error Summary Bit set? BEQ 20$ ;No, then continue MOV #DRVCLR,MTCS1 ;Yes, then clear Formatter BIS #BIT5,MTCS2 ;and clear Controller and Error Reg. 10$: BIT #BIT0,MTCS1 ;Clear done? BNE 10$ ;No, then loop for it ;Set Tape Status and Control 2 Register 20$: BIC #47,MTCS2 ;Clear initialization bit and select ;Formatter zero ;Set the Tape Control Resister MOV @2(R5),MTTC ;Clear Tape Status and Control 1 Register BIC #1777,MTCS1 ;Clear last command ;Load the Word and Frame Count Registers MOV @4(R5),MTWC ;Load Word Transfer Resigter MOV @6(R5),MTFC ;Load the Frame Count Register ;Load the Bus Address Register MOV @10(R5),MTBA ;Load the Mag Tape Status and Control 1 Register MOV @12(R5),MTCS1 ;Move in CSR1 Mask (Start Read/Write) ;Do we need to quit yet? BIT #BIT0,SWR ;See if SWR BIT 0 is set BNE EXIT1 ;If it is then STOP RTS PC ;Return EXIT1: ;Take care of Exit With Status = 1 MOV #STAT1+4,R5 ;Set Exit Status to +1 JSR PC,EXST ;Exit the program with Status .PAGE .SBTTL INPDR - DR11-K READING ROUTINE INPDR:: ;FORTRAN ENTRY POINT FOR READING DATA FROM THE DR11-K MOV DRCSR,R1 ;Get value of DR11-K's CSR BIT #200,R1 ;External Data Ready Signal Received? BEQ INPDR ;No, keep looping MOV DRINRG,R0 ;Yes, get value in Input Register MOV #177777,DRINRG ;Reset Input Register XOR R1,DRCSR ;Clear DRCSR RTS PC ;Return .PAGE .SBTTL A2DSUB - AR11 INPUT/OUTPUT ROUTINES ;RAC1.1 - 1/10/84 : Added these AR11 input/output routines A2DGO:: ;FORTRAN ENTRY POINT FOR AR11 A/D SETUP MOV @2(R5),CKBR ;Put # of ticks into Clock. Buf. Reg. MOV @4(R5),R0 ;Fetch Rate Mask MOV #ADMASK,ADSR ;Initialize A/D Status Register ;(Enable overflow to start A/D process) MOV #CKMASK,CKSR ;Initialize Clock Status Register ;(Start count at 1 MHz rate) XOR R0,CKSR ;Put Rate Mask in Clock Status Register RTS PC ;Return D2AGO:: ;FORTRAN ENTRY POINT FOR AR11 D/A SETUP MOV @2(R5),CKBR ;Put # of ticks into Clock. Buf. Reg. MOV @4(R5),R0 ;Fetch Rate Mask MOV #DAMASK,DASR ;Initialize D/A Display Register MOV #CKMASK,CKSR ;Initialize Clock Status Register ;(Start count at 1 MHz rate) XOR R0,CKSR ;Put Rate Mask in Clock Status Register RTS PC ;Return INAR:: ;FORTRAN ENTRY POINT FOR GETTING DATA FROM THE AR11 ; This routine will fill an ARRAY of length LEN. ; Calling Sequence : ; CALL INAR(ARRAY,LEN) MOV 2(R5),R1 ;Get address of ARRAY !RAC1.2 MOV @4(R5),R2 ;Get length of ARRAY !RAC1.2 MOV #1,R3 ;Initialize counter !RAC1.2 LOOP1: BIT #BIT7,ADSR ;Is Done Flag set? BEQ LOOP1 ;No, try again MOV ADBR,(R1) ;Get data sample (Clears Done Flag) SUB #1000,(R1)+ ;Scale data about 0 LOOP2: BIT #BIT7,CKSR ;Is Overflow Flag set? BEQ LOOP2 ;No, try again BIC #BIT7,CKSR ;Clear Overflow Flag INC R3 ;Increment counter !RAC1.2 CMP R3,R2 ;Done yet? !RAC1.2 BLE LOOP1 ;No, then get next sample !RAC1.2 RTS PC ;Return OUTAR:: ;FORTRAN ENTRY POINT FOR PUTTING DATA OUT FROM THE AR11 ; This routine will output an ARRAY of length LEN. ; Calling Sequence : ; CALL OUTAR(ARRAY,LEN) MOV 2(R5),R1 ;Get address of ARRAY !RAC1.2 MOV @4(R5),R2 ;Get length of ARRAY !RAC1.2 MOV #1,R3 ;Initialize counter !RAC1.2 LOOP3: BIT #BIT7,CKSR ;Is Overflow Flag set? BEQ LOOP3 ;No, try again BIC #BIT7,CKSR ;Clear Overflow Flag LOOP4: BIT #BIT7,DASR ;Is Done Flag set? BEQ LOOP4 ;No, try again ADD #1000,(R1) ;Remove scale about 0 MOV (R1)+,XBUF ;Put data out the AR11 INC R3 ;Increment counter !RAC1.2 CMP R3,R2 ;Done yet? !RAC1.2 BLE LOOP3 ;No, then get next sample !RAC1.2 RTS PC ;Return .PAGE .SBTTL CLOCK - LINE CLOCK START/STOP ROUTINES ;RAC1.3 - 1/19/84 : Added these Line Clock Start/Stop routines. ; This was done to make it possible to stop the clock and ; run either ADORDA or DR2TAP without the system executing ; its timing instructions every second (This caused a loss ; of one sample per second in ADORDA at a 4000 Hz sample ; rate). STARIT will start the Line Frequency Clock running ; again, then look at our systems Digital Pathways TCU-150 ; time keeper to get the correct time, and then it will set ; the systems line clock to this time. ; ; If you do not have a TCU-150 time keeper then drop all ; the code dealing with it and get the time from the user ; in the calling routine and then set the Line Frequency ; Clock with that information. ; ; If you do have a TCU-150 then please check the DEFINE ; module above for the proper register definitions and ; masks. STOPIT:: ;FORTRAN ENTRY POINT TO STOP THE LINE FREQUENCY CLOCK ; This routine will stop the System Line Clock. The calling ; sequence is : ; ; CALL STOPIT ; MOV #200,LNCLK ;Stop the Clock RTS PC STARIT:: ;FORTRAN ENTRY POINT TO START THE LINE FREQUENCY CLOCK ; This routine will get the time from a Digital Pathways TCU-150 ; and then sets the system time. ; Calling Sequence : ; ; CALL STARIT(array) ; ; Where ARRAY is a 6 element Integer array that will contain the ; time the clock was set to. ; Start the Line Clock Running again : MOV #300,LNCLK ; Get the time from the TCU-150: MOV YRMODA,R0 ;Get Year, Month, and Day MOV HRMIN,R1 ;Get Hours and Minutes MOV SEC,R2 ;Get Seconds ; Get the Year : MOV R0,R3 ;Copy YRMODA BIC #YRMSK,R3 ;Clear out Month and Day SWAB R3 ;Move Year to lower Byte ROR R3 ;Move Year Right one position MOV R3,NEWTIM ;Put Year into NEWTIM Buffer ; Get the Month : MOV R0,R3 ;Copy YRMODA BIC #MONMSK,R3 ;Clear out Year and Day ASH #-5,R3 ;Move Month Right five places MOV R3,NEWTIM+2 ;Put Month into NEWTIM Buffer ; Get the Day : BIC #DAYMSK,R0 ;Clear out Year and Month MOV R0,NEWTIM+4 ;Put Day into NEWTIM Buffer ; Get the Hour : MOV R1,R3 ;Copy HRMIN BIC #HRMSK,R3 ;Clear out Minutes SWAB R3 ;Move Hours into lower Byte MOV R3,NEWTIM+6 ;Put Hours into NEWTIM Buffer ; Get the Minutes : BIC #MINMSK,R1 ;Clear out Hours MOV R1,NEWTIM+10 ;Put Minutes into NEWTIM Buffer ; Get the seconds : BIC #SECMSK,R2 ;Clear out all but Seconds MOV R2,NEWTIM+12 ;Put Seconds into NEWTIM Buffer ; Set the Ticks of Seconds : MOV #0,NEWTIM+14 ;Set Ticks = 0 ; Set the Ticks Per second : MOV #74,NEWTIM+16 ;Set Ticks/Sec = 60(10) = 74(8) ; Set the Line Clock : DIR$ #SETTIM ;Set the time ; Let the calling routine know the time : MOV 2(R5),R0 ;Get the Address of ARRAY MOV NEWTIM ,(R0) ;Pass Back the Year MOV NEWTIM+2 ,2(R0) ;Pass Back the Month MOV NEWTIM+4 ,4(R0) ;Pass Back the Day MOV NEWTIM+6 ,6(R0) ;Pass Back the Hour MOV NEWTIM+10,10(R0) ;Pass Back the Minute MOV NEWTIM+12,12(R0) ;Pass Back the Second RTS PC ;Return .END