; PPPPPPP UU UU NN NN CCCCC HH HH ; PP PP UU UU NNN NN CC CC HH HH ; PP PP UU UU NNNN NN CC HH HH ; PPPPPPP UU UU NN NN NN CC HHHHHHHH ; PP UU UU NN NN NN CC HH HH ; PP UU UU NN NNNN CC CC HH HH ; PP UUUUU NN NNN CCCCC HH HH .TITLE PUNCH ASCII PAPER TAPE PROGRAM .IDENT /V1.07/ .ENABL LC .PSECT ; TASK TO OUTPUT AN ASCII PAPER TAPE TO THE HIGH SPEED PUNCH. ; CARRIAGE RETURN/LINE FEEDS ARE GENERATED AND PARITY MAY BE SET, CLEAR, ; EVEN, OR ODD. A LEGIBLE TAPE HEADER MAY ALSO BE SELECTED. ; A COPY MAY BE SPOOLED TO THE LINEPRINTER. ; A LONGTITUDINAL CHECKSUM IS COMPUTED AND PUNCHED IF A TAPE TERMINATOR ; IS SPECIFIED. THIS IS CHECKED IF THE TAPE IS SUBSEQUENTLY READ BY THE ; COMPLEMENTARY "INPUT" TASK. ; RUN PROGRAM AS: ; ; >PUN /SWITCHES,/SWITCHES ... ; ; SWITCHES:- ; HD * PUNCH FILENAME & DATE IN 5X8 CHARACTERS ; -HD OMIT HEADER ; CO ADD COPYRIGHT NOTICE ; -CO * OMIT COPYRIGHT NOTICE ; PY:EV{EN} * PUNCH IN EVEN PARITY ; PY:OD{D} PUNCH IN ODD PARITY ; PY:CL{EAR} PUNCH WITH PARITY CLEAR ; PY:SE{T} PUNCH WITH PARITY SET ; -PY EQUIVALENT TO PY:CL ; ET: END TAPE WITH CONTROL/ (DEFAULT IS ET:Z) * ; -ET NO TAPE TERMINATOR ; SP SPOOL A COPY OF TO LP0: ; -SP * DON'T PRINT A COPY OF ; LA LATCH CURRENT SWITCH SETTING ; -LA * DON'T LATCH SWITCHES ; -DE * DON'T DELETE FILE AFTER PUNCHING ; DE DELETE FILE AFTER PUNCHING ; ; * MARKS DEFAULT SETTINGS ; DEFAULTS MAY BE ALTERED AT TASK BUILD TIME BY GBLPAT'S TO ; DEFSW SWITCH WORD(FOR BIT SIGNIFICANCES SEE SWTAB:) ; DEFPY DEFAULT PARITY CHECK(SEE PYVAL:) ; DEFEB END BYTE ; ; ; TASK BUILD AS: ; TKB>PUNCH/CP/-FP=PUNCH ; TKB>/ ; ENTER OPTIONS: ; TKB>PAR=GEN ; TKB>ASG=TI:1:5,SY:2,PP:3 ; TKB>ACTFIL=2 ; TKB>STACK=64 ; TKB>UNITS=5 ; TKB>TASK=...PUN ; TKB>LIBR=FCSRES:RO ; TKB>// ; .PAGE ; MODIFICATIONS RECORD: ; 1.02 ADD LONGITUDINAL CHECKSUM FACILITY ; CORRECT MCR LINE EXIT. ; ; 1.03 CORRECT CARRIAGE CONTROL CHARACTER IN ERRMES AND ERRST ; CALL WTSE$ AFTER ATTACH & DETACH ; 1.04 SET DEFAULT PARITY TO /PY:EV ; REMOVE REDUNDANT CLOSE$ #GC BEFORE EXIT$S ; ; 1.05 CORRECT (ILLEGAL) WILDCARD FUNCTION CHECK. ; EXIT WITH STATUS:- ; EX$SUC IF NO ERRORS ARE DETECTED, ; EX$WAR IF PARITY SPECIFIED IS ILLEGAL OR A DEVICE ERROR OCCURS ; WHILE PUNCHING LEADER OR TRAILER, ; EX$ERR IF A COMMAND LINE ERROR OCCURS, A FILE CANNOT BE OPENED, ; OR A DEVICE ERROR OCCURS DURING PUNCHING A FILE, ; EX$SEV IF ABORTED. ; ISSUE A MESSAGE AT THE TERMINAL EVERY 30 SEC WHILE WAITING FOR ATTACH. ; CHANGE QIO'S TO QIOW'S. ; ADD DELETE SWITCH -- DELETE FILE ON SUCCESSFUL COMPLETION. ; DEFAULT FILETYPE ALONG A LINE, AND TO SUBSEQUENT LINES IF LATCHED. ; ; 1.06 10-DEC-80 ; JUST IGNORE A BLANK COMMAND LINE -- DON'T PRINT AN ERROR. ; ; 1.07 1-Apr-86 CJD ; Delete INSTITUTE from copyright message. ; Put messages in mixed case. .MCALL FDBDF$,FDRC$A,FDOP$A,NMBLK$,FINIT$,FSRSZ$,EXST$ .MCALL CSI$,CSI$1,CSI$2,GCML$,GCMLB$,GCMLD$,CSI$SW,CSI$SV,CSI$ND .MCALL QIO$C,QIOW$,QIOW$S,QIOW$C,DIR$,MRKT$C,CMKT$C,WSIG$S,CLEF$C .MCALL OPEN$R,CLOSE$,GTIM$,GET$,PRINT$,DELET$ .GLOBL $CBOMG,.PPASC,$C5TA,$CBDMG,$DAT,$TIM,.RDFUI .GLOBL DEFSW,DEFPY,DEFEB,DEFTYP START: FINIT$ ; (RE)INITIALISE FCS BR RSTART ; AND START ESTART: MOV #EX$ERR,EXSTAT ; LOAD ERROR EXIT FLAG ON RESTART HERE RSTART: TSTB SWWRD ; LATCHED SWITCHES? BMI GETCOM ; CONTINUE IF SO MOV #ETBIT!HDBIT!PYBIT,SWWRD ; ELSE SET DEFAULT SWITCHES DEFSW==.-4 MOV #EVEN,PYVAL ; DEFAULT PARITY EVEN DEFPY==.-4 MOVB #'Z,ENDBYT ; DEFAULT END ^Z DEFEB==.-4 MOV #^RTXT,DEFINP+N.FTYP ; DEFAULT FILETYPE .TXT DEFTYP==.-4 GETCOM: GCML$ #GC ; GET COMMAND LINE BCC CMDIN ; BRANCH IF OK CMPB #GE.EOF,GC+G.ERR ; CONTROL/Z? BNE ILLCOM ; NO, MUST BE AN ERROR DIR$ #EXST ; ELSE EXIT ILLCOM: JSR %5,ERRMES ; ELSE PRINT ERROR COMERR ; "COMMAND ERROR" BR ESTART ; AND TRY AGAIN CMDIN: CSI$1 #CSIBLK,GC+G.CMLD+2,GC+G.CMLD ; PRE-PROCESS COMMAND BCS ILLCOM ; BRANCH IF ERROR TST CSIBLK+C.CMLD ; BLANK LINE? BEQ GETCOM ; YES, JUST IGNORE IT BITB #CS.EQU,CSIBLK+C.STAT ; NO '=' BNE ILLCOM ; ALLOWED NXTFIL: CSI$2 #CSIBLK,OUTPUT,#SWTAB ; ALL FILES ARE "OUTPUT" BCC FILIN ; BRANCH IF OK JSR %5,ERRMES ; ELSE ERROR MESSAGE ILLSWT ; "ILLEGAL SWITCH" (PROBABLY) BR ESTART ; TRY AGAIN FILIN: BITB #CS.WLD,CSIBLK+C.STAT ; WILDCARDS? BNE ILLCOM ; ARE NOT ALLOWED BITB #CS.NMF,CSIBLK+C.STAT ; THERE MUST BE A FILENAME BEQ ILLCOM ; ERROR IF NOT OPEN$R #INPUT ; OPEN FILE BCC OPNOK ; BRANCH IF SUCCESSFUL JSR %5,ERRMES ; ELSE ANOTHER ERROR OPNFLD ; "OPEN FAILED" BR ESTART ; KEEP TRYING ; RETURN HERE FOR A NEW FILE, COULD BE ON SAME LINE NEWFIL: BITB #CS.MOR,CSIBLK+C.STAT ; MORE? BEQ RSTART ; RESTART IF NOT BR NXTFIL ; ELSE GO FOR NEXT FILE ; FILE OPENED SUCCESSFULLY, TEST PARITY SWITCH OPNOK: MOV INPUT+F.FNB+N.FTYP,DEFINP+N.FTYP ; COPY FILETYPE FOR NEXT DEFAULT BIT #PYBIT,SWWRD ; PARITY DEFINED? BNE ATTACH ; YES, BRANCH MOV #CLEAR,PYVAL ; -PY = PY:CLEAR ATTACH: QIO$C IO.ATT,3,3,,IOSTAT ; PTP IS UNIT 3 MRKT: MRKT$C 4,20.,2 ; PROMPT IN 20-SEC IF NOTHING HAPPENS WSIG: WSIG$S ; WAIT FOR ANY SIGNIFICANT EVENT CMPB IOSTAT,#IS.PND ; IS THE QIO STILL PENDING? BNE ATTCHD ; NO, GO SEE IF SUCCEEDED CLEF$C 4 ; YES, WAS THIS THE MARK TIME FINISHING? CMP $DSW,#IS.CLR ; FLAG STILL CLEAR IF NOT BEQ WSIG ; SO CONTINUE WAITING JSR %5,MESAGE ; TIMEOUT -- PRINT MESSAGE WAITNG ; "WAITING FOR PP0:" BR MRKT ; MARK TIME AGAIN ATTCHD: CMKT$C 4 ; QIO FINISHED, CANCEL MARK TIME JSR PC,PCHCHK ; CHECK FOR PUNCH SUCCESS BCS NEWFIL ; NEXT FILE IF ERROR CLR PUNERR ; CLEAR PUNCH ERROR COUNTER BIT #HDBIT,SWWRD ; FILENAME HEADER? BEQ COPYRT ; NO, TRY COPYRIGHT MOV #INPUT,%4 ; ADDRESS FDB FILENAME BLK MOV #WSPACE,-(SP) ; AND WORKSPACE MOV (SP),%0 ; ADDRESS STORED ON STACK JSR PC,DIRNAM ; FORM DEVICE NAME & UIC MOV (SP),%4 ; IN WSPACE JSR PC,DISPLA ; AND PUNCH IT MOV (SP),%0 ; READDRESS WORKSPACE MOV #INPUT,%4 ; RELOAD FDB POINTER JSR PC,FILNAM ; PUT FILENAME ASCII STRING MOV (SP),%4 ; IN WORKSPACE JSR PC,DISPLA ; DISPLAY FILENAME MOV #20.,%0 ; 2" BLANK TAPE JSR PC,RUNNUL MOV (SP),%0 ; ADDRESS WORKSPACE AGAIN JSR PC,DATIM ; FORM DATE & TIME THERE MOV (SP)+,%4 ; ADDRESS ASCII STRING JSR PC,DISPLA ; DISPLAY IT MOV #20.,%0 ; BLANK TAPE AGAIN JSR PC,RUNNUL ; NOW TEST IF COPYRIGHT MESSAGE REQUIRED. COPYRT: BIT #COBIT,SWWRD ; YES? BEQ PCHFIL ; NO, JUST PUNCH FILE DIR$ #GTIM ; GET TIME TO BUFFER MOV #WSPACE,%0 ; USE WORKSPACE FOR ASCII YEAR MOV BUFFER,%1 ; GET YEAR(1ST WORD) MOV #1,%2 ; DON'T SUPPRESS LDG ZEROES JSR PC,$CBDMG ; WHEN CONVERTING TO DECIMAL MOVB WSPACE+3,YEAR ; COPY TO YEAR IN MOVB WSPACE+4,YEAR+1 ; COPYRIGHT MESSAGE MOV #CPTMS,%4 ; ADDRESS COPYRIGHT MESSAGE JSR PC,DISPLA ; AND PUNCH IT MOV #HOLDER,%4 ; ADDRESS NAME OF HOLDER JSR PC,DISPLA ; DISPLAY THAT TOO ; DONE HEADER(IF ANY). NOW PUNCH FILE ITSELF. PCHFIL: MOV #CSMBLK+1,%0 ; CLEAR C/SUM BLOCK .REPT 4 CLR (%0)+ .ENDR MOV #134.,%0 ; LOAD COUNT FOR 13.4" LEADER CMP PYVAL,#SET ; PARITY SET? BEQ LDRSET ; YES, LEADER OF 200'S CMP PYVAL,#ODD ; ALSO IF ODD BEQ LDRSET ; SO THERE IS A RIGHT START BIT #HDBIT!COBIT,SWWRD ; WERE THERE HEADERS? BEQ READ ; NO, NO MORE LEADER REQD JSR PC,RUNNUL ; PUNCH 13" WITH PARITY CLEAR BR READ ; GO READ FILE LDRSET: JSR PC,RUNSET ; PUNCH 13" WITH PARITY SET ; READ FILE RECORD-BY-RECORD AND PUNCH IT OUT. READ: GET$ #INPUT ; GET RECORD BCC PFILB ; BRANCH IF READ CMPB #IE.EOF,INPUT+F.ERR ; END-OF-FILE? BEQ EOF ; CAN HANDLE THAT JSR PC,ERRMES ; BUT NOTHING ELSE INPERR ; PRINT "INPUT ERROR" BR EOF ; AND TREAT AS E-O-F PFILB: MOV INPUT+F.NRBD,%4 ; FETCH NO OF BYTES MOVB #15,BUFFER(%4) ; FINISH WITH CR MOVB #12,BUFFER+1(%4) ; AND LF CMPB (%4)+,(%4)+ ; 2 MORE BYTES MOV %4,COUNT ; FOR COUNT JSR PC,OUTPUT ; PUNCH IT BCC 10$ ; BRANCH IF OK MOV #EX$ERR,EXSTAT ; ELSE SET ERROR FLAG BR EOF2 ; AND GIVE UP ON PUNCH ERROR 10$: JSR PC,CMPCSM ; ADD C/SUM FOR THIS BLOCK BR READ ; AND GO BACK FOR MORE ; END-OF-FILE(OR ERROR). EOF: BIT #ETBIT,SWWRD ; E.O.F. BYTE REQD? BEQ EOF1 ; NO, BRANCH MOVB ENDBYT,%0 ; ELSE GET THE END BYTE BIC #177740,%0 ; AS A CONTROL CODE MOVB %0,BUFFER ; COPY TO BUFFER MOV #1,COUNT ; 1 BYTE COUNT JSR PC,OUTPUT ; SEND IT JSR PC,CMPCSM ; INCLUDE END BYTE IN C/SUM ; PUNCH 8 BYTES OF CHECKSUM PRECEDED BY 377. MOV #100.,%0 ; AND 10" RUNOUT JSR PC,RUNOUT QIOW$C IO.WLB,3,3,,IOSTAT,, ; CHECKSUM FROM BLOCK JSR PC,PCHCHK ; CHECK THAT IT WORKED EOF1: CMP PYVAL,#CLEAR ; DO WE REQUIRE A PARITY SET BEQ EOF2 ; LEADER? CMP PYVAL,#EVEN ; NOT IF PARITY IS EVEN BEQ EOF2 ; OR CLEAR MOV #134.,%0 ; ELSE MUST SEND JSR PC,RUNSET ; TRAILER OF 200'S EOF2: QIOW$C IO.DET,3,3,,IOSTAT ; DETACH PUNCH JSR PC,PCHCHK ; CHECK FOR FAILURE BITB #SPBIT,SWWRD ; SPOOL TO LP: ? BEQ EOF3 ; NO, JUST CLOSE IT PRINT$ #INPUT ; ELSE START THE SPOOLER BCC EOFX ; WHICH CLOSES FILE JSR %5,ERRMES ; UNLESS SPLERR ; "SPOOL FAILED" EOF3: BIT #DEBIT,SWWRD ; DELETE? BEQ EOF4 ; NO, JUST CLOSE TST PUNERR ; ANY ERRORS ON THIS FILE? BNE NODEL ; YES, DON'T DELETE DELET$ #INPUT ; NO, OK TO CLOSE & DELETE BCC EOFX ; GO FOR ANOTHER FILE IF OK NODEL: JSR %5,ERRMES ; NOT DELETED -- REPORT ERROR NOTDEL ; AND CLOSE ANYWAY EOF4: CLOSE$ #INPUT ; CLOSE THE INPUT FILE EOFX: JMP NEWFIL ; GO FOR ANOTHER .PAGE ; SUBROUTINES ; *********** ; GET CURRENT FILENAME FROM BLOCK ADDRESSED BY %4 AS AN ASCII STRING IN ; THE AREA ADDRESSED BY %0. ; SUBROUTINE DIRNAM GETS DEVICE & UIC, DESTROYS %1-%4 DIRNAM: MOV N.DVNM+F.FNB(%4),(%0)+ ; COPY DEVICE NAME(ASCII) MOV N.UNIT+F.FNB(%4),%1 ; GET UNIT NO. CLR %2 ; SUPPRESS LEADING ZEROES JSR PC,$CBOMG ; CONVERT TO OCTAL ASCII MOVB #':,(%0)+ ; PUT IN A ':' MOV F.DSPT(%4),%2 ; GET DATASET DESCRIPTOR POINTER MOV 4(%2),%1 ; ITS 3RD WORD, IF NON-ZERO BEQ 6$ ; CONTAINS NO OF BYTES IN UIC MOV 6(%2),%2 ; THEN 4TH WORD->STRING 5$: MOVB (%2)+,(%0)+ ; COPY DIRECTORY STRING SOB %1,5$ ; OF %1 BYTES CLRB (%0)+ ; FINISH WITH NULL RTS PC ; AND EXIT ; IF NO UIC DEFINED, GET THE DEFAULT 6$: JSR PC,.RDFUI ; FETCH TO %1 MOV %1,%3 ; COPY TO %3 CLR %4 ; SUPPRESS LDG ZEROES, ADD [,] MOV %0,%2 ; %2->AREA JSR PC,.PPASC ; CONVERT UIC TO ASCII CLRB (%2)+ ; FINISH WITH NULL RTS PC ; AND EXIT ; FILNAM GET FILENAME ITSELF, DESTROYS %1 FILNAM: MOV N.FNAM+F.FNB(%4),%1 ; GET 1ST 3 CHARS OF FILENAME BEQ 10$ ; BRANCH IF NULL FILENAME JSR PC,$C5TA ; CONVERT RADIX-50 TO ASCII MOV N.FNAM+2+F.FNB(%4),%1 ; GET NEXT 3 CHARS BEQ 10$ JSR PC,$C5TA ; CONVERT TO ASCII MOV N.FNAM+4+F.FNB(%4),%1 ; GET LAST 3 CHARS BEQ 10$ ; FINISHED IF NULL JSR PC,$C5TA ; ELSE CONVERT 10$: CMPB #' ,-(%0) ; TRIM TRAILING SPACES BEQ 10$ ; FROM FILENAME INC %0 ; ADDRESS NEXT SPACE MOVB #'.,(%0)+ ; PUT IN A '.' MOV N.FTYP+F.FNB(%4),%1 ; FETCH FILE TYPE BEQ 30$ ; BRANCH IF NONE JSR PC,$C5TA ; RADIX-50 AGAIN 20$: CMPB #' ,-(%0) ; TRIM TRAILING BLANKS IN THAT BEQ 20$ INC %0 30$: MOVB #';,(%0)+ ; PUT IN A ';' MOV N.FVER+F.FNB(%4),%1 ; GET VERSION NO CLR %2 ; SUPPRESS LDG ZEROES JSR PC,$CBOMG ; CONVERT VERSION TO OCTAL CLRB (%0) ; END STRING WITH NULL RTS PC ; AND EXIT ; GET TIME AND DATE AS AN ASCII STRING IN FORMAT: HH:MM___DD-MMM-YY DATIM: DIR$ #GTIM ; FORM DATE & TIME IN BUFFER MOV #WSPACE,%0 ; ASCII WILL BE IN WSPACE MOV #BUFFER+G.TIHR,%1 ; ADDRESS TIME MOV #2,%2 ; SELECT HH:MM FORM JSR PC,$TIM ; CONVERT TIME TO STRING MOVB #' ,@%0 ; INSERT 3 SPACES MOVB (%0)+,@%0 MOVB (%0)+,@%0 INC %0 MOV #BUFFER+G.TIYR,%1 ; ADDRESS DATE JSR PC,$DAT ; CONVERT TO ASCII CLRB (%0)+ ; END WITH NULL RTS PC ; AND EXIT ; TYPE AN ERROR MESSAGE ON TI:, UNIT 5 ERRMES: CMP EXSTAT,#EX$SUC ; STILL FLAGGING SUCCESS? BNE MESAGE ; NO, KEEP CURRENT EXIT STATUS CLR EXSTAT ; YES, SET TO EX$WAR=0 MOV #EX$ERR,EXSTAT ; SET ERROR EXIT STATUS MESAGE: DIR$ #ERRST ; START "PUN -- " ; ENTRY TYPE TO TYPE A GENERAL MESSAGE STORED AS: ;