.MCALL .MODULE .MODULE QUEMAN,VERSION=16,COMMENT=,AUDIT=YES ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. ; Edit History: ; ; 001 06-Oct-80 12:47 PM Chasin, Geoff [240,98] ; PROBLEMS WITH RE-ENTRY ; (001) ; 002 29-Oct-80 12:59 PM Chasin, Geoff [240,98] ; REPATCH PATCH; FIX WILDCARD ROUTINE ; (002) ; 003 30-Apr-81 10:44 AM David Fingerhut [240,134] ; Add /SINCE and /DATE ; (003) ; 004 23-Jun-81 03:39 PM David Fingerhut [240,134] ; Put in /QUERY option ; (004) ; 005 04-Nov-81 02:15 PM David Fingerhut [40,134] ; Change /DATE option from /E to /C ; (005) ; 006 06-Nov-81 11:19 AM David Fingerhut [40,134] ; add /BEFORE (/J) ; (006) ; 007 14-Apr-82 10:59 AM David Fingerhut [40,134] ; Add /X (/INFORMATION) ; (007) ; 008 15-DEC-82 2:00 PM Carlos Alonso ; After abort and monitor error clear Queue bit in ; config word for failing print command. ; (008) ; 009 16-DEC-82 2:15 PM Carlos Alonso ; Set User Error Byte for /L switch depending on ; queue empty or not. ; 010 21-DEC-82 Carlos Alonso ; Check that the RT11 running is the latest version ; 011 7-JAN-83 Carlos Alonso ; If the number of banner pages is not specified then ; use a -1 as an indicator to Queue as the number of banner. ; Queue will print the default unless the default is zero! ; 012 6-NOV-83 Linda Banche ; Allow RESORC to chain to QUEMAN ; 013 7-SEP-84 George Thissell ; Allow lowercase switches ; 014 7-Jun-89 R. Hamilton ; Prevent wildcard access of non-RT directories. Use CSTAT and ; DEVTR in REALDV to support extended-unit names. ; Allow short labels in magtape records. ; V12 16-May-90 Bill Gavin ; Fix SHOW QUEUE display problem (ACTION Item #5801) ; ; v13 01-Nov-1990 JFW ; bracket error messages with ;+/;ERROR/.../;- ; ; (014) 11-Aug-91 MBG Extended magtape error checking ; ; 015 31-Mar-1997 Tim Shoppa ; Handle both 4- and 2- digit years. ; ; 016 7-Oct-1998 Tim Shoppa ; Gripe if the user attempts to enter a date field more than once. ; ; QUEMAN PROGRAM FOR RT-11 V04 ; AUTHOR: SCOTT DAVIS .ENABL GBL .NLIST BEX .LIBRARY "SRC:SYSTEM.MLB" .MCALL .ASSUME .BR .CHCOPY .CLOSE .CSISPC .CSTAT .MCALL .DATE .DSTATU .EXIT .GTLIN .GTIM .GVAL .MCALL .LOOKUP .PRINT .SETTOP .SPFUN .RCVDW .READW .MCALL .SDATW .TTYIN .WRITW .PSECT DATA .SBTTL DATA .NLIST BEX ;MESSAGES ;+ ;ERROR MSGLST MSGTAB ERRMSG EM0 ERRMSG EM1 ERRMSG EM2 ERRMSG EM3 ERRMSG EM4 ERRMSG EM5 ERRMSG EM6 ERRMSG EM7 ERRMSG EM8 ERRMSG EM9 MSGEND ;- QUE:: .NLCSI PART=PREFIX TYPE=I LEV:: .ASCII \X-\<200> .EVEN ERAR:: .BYTE 0 .BYTE 200 .WORD QUE .WORD LEV .WORD MSGTAB .WORD 0 .WORD CSI PRPT: .ASCII /Number of banner pages? /<200> PM2: .ASCII /Delete workfile? /<200> VERSN: .NLCSI ;001 LOGHDR: .ASCIZ \Files queued:\ ;004 .EVEN ; SYSTEM INFO $JSW = 44 ;JSW IN ASECT CHAIN$ = 400 ;CHAIN BIT IN JSW CSW.DI = 76 ;DEVICE INDEX MASK IN CSW C.UNIT = 11 ;OFFSET TO UNIT IN CHANNEL AREA S.PNAM = 404 ;OFFSET TO $PNAM TABLE IN RMON JS.GTL = 10 ;DCL CONTINUATION BIT JS.REE = 20000 ;RE ENTER BIT USRBUF = 266 ;OFFSET TO USR START $ERRBY =: 52 ;EMT error byte SYSPTR = 54 ;->BYTE 54 (RMON) SYSGEN = 372 ;OFFSET FROM BASE OF RMON TO SYSGEN WORD STASK$ = 40000 ;BIT IN SYSGEN WORD FOR SYSTEM TASKING CONFIG = 300 ;OFFSET FROM BASE OF RMON TO CONFIG WORD QUEUE$ = 2000 ;BIT IN CONFIG FOR QUEUE INSP = 36 ;OFFSET IN FILE SPECS USERRB = 53 ;USER ERROR BYTE SUCCS$ = 1 ;SUCCES WARN$ = 2 ;WARNING ERROR$ = 3 ;ERROR FATAL$ = 10 ;FATAL UCOND$ = 20 ;UNCONDITIONAL SYSVER = 276 ;OFFSET TO SYSTEM VERSION VERS = 5 ;CURRENT VERSION OF RT11 ; ; SWITCH TABLE SWTAB: .ASCII \AKDHMLPRSN/IJCQWX\<0> ;007 .EVEN ;**-1 ACTAB: .WORD $ABRT .WORD $COPY .WORD $DEL .WORD $HED .WORD $KLL .WORD $LST .WORD $SET .WORD $RST .WORD $SSPD .WORD $NHED .WORD $CONT .WORD $SINC ;006 .WORD $BEFOR ;006 .WORD $DATE .WORD $QRY ;004 .WORD $LOG ;004 .WORD $INFO ;007 ;007 ; FLAG BITS FOR MESSAGES SENT TO QUEUE ;**-1 FLG.DE = 1 ;DELETE FILE AFTER PRINTING FLG.CP = 2 ;MAKE MULTIPLE COPIES FLG.HD = 4 ;CREATE BANNER PAGES FLG.JR = 10 ;JOB REQUEST FLG.KL = 100 ;REMOVE JOB/FILE FROM QUEUE FLG.SS = 200 ;SEND QUEUE STATUS TO REQUESTING JOB FLG.SP = 400 ;SET DEFAULT PARAMETERS FLG.SU = 1000 ;SUSPEND JOB FLG.RS = 2000 ;RESUME JOB FLG.AB = 100000 ;ABORT QUEUE IMMEDIATELY ; FLAG BITS FOR MESSAGES SENT FROM QUEUE FLG.RA = 0 ;REQUEST ACCEPTED FLG.IR = 100000 ;ILLEGAL JOB REQUEST FLG.QF = 100004 ;QUEUE WORK FILE FULL ; JOB REQUEST MESSAGE BLOCK OFFSETS JRM.FL = 0 ;JOB REQUEST FLAG JRM.J1 = 2 ;FIRST WORD OF REQUESTING JOB'S NAME JRM.J2 = 4 ;SECOND WORD OF REQUESTING JOB'S NAME JRM.J3 = 6 ;THIRD WORD OF REQUESTING JOB'S NAME JRM.BA = 10 ;REQUEST BLOCK ADDRESS JRM.ZE = 12 ;ZERO ; JOB REQUEST BLOCK OFFSETS JRB.FL = 0 ;FLAGS JRB.CP = 2 ;# COPIES BYTE JRB.BN = 3 ;# BANNERS BYTE JRB.OD = 4 ;OUTPUT DEVICE (DEFAULT TO LP:) (RAD50) JRB.J1 = 6 ;REQUESTING JOB'S LOGICAL JOB NAME (RAD50) JRB.J2 = 10 ;REQUESTING JOB'S LOGICAL JOB NAME (RAD50) JRB.NR = 12 ;# OF FILE REQUEST BLOCKS ; FILE REQUEST BLOCK OFFSETS FRB.FL = 0 ;FLAGS FRB.CP = 2 ;# COPIES BYTE FRB.BN = 3 ;# BANNERS BYTE FRB.DV = 4 ;INPUT DEVICE (RAD50) (DEFAULT TO SY:) FRB.F1 = 6 ;FILENAME (RAD50) FRB.F2 = 10 ;FILENAME (RAD50) FRB.EX = 12 ;EXTENSION (RAD50) ; OPTION MODIFICATION FLAG BITS ;003 ;003 FLG.DA = 1 ;/C (/DATE) SPECIFIED ;006 FLG.SI = 2 ;/I (/SINCE) SPECIFIED FLG.QR = 4 ;/Q (/QUERY) SPECIFIED ;004 FLG.LG = 10 ;/W (/LOG) SPECIFIED ;004 FLG.QN = 20 ;QUERY PROMPT WAS ANSWERED "N" ;004 FLG.QC = 40 ;A FILE WAS COPIED ;004 FLG.BE = 100 ;/J (/BEFORE) SPECIFIED ;006 FLG.IN = 200 ;/X (/INFORMATION) SPECIFIED ;007 ;007 ; STORAGE AREAS ;**-1 MFLAG:: .WORD 0 ;OPTION MODIFICATION FLAG WORD ;003 PROMPT::.BLKW 7. ;AREA FOR QUERY PROMPT ;004 .ASCII / ?/<200> ;004 .EVEN LOGPR:: .BLKW 7. ;AREA FOR LOG .ASCII / / .BYTE 0 RADF:: .BLKW 4 ;RAD50 FILENAME FOR QUERY ;004 ACK: .BLKW 6 ;PLACE FOR QUEUE'S REPLY AREA: .BLKW 10 ;EMT BLOCK DFTYP: .RAD50 \LST\ ;DEFAULT EXTENSIONS .WORD 0,0 .RAD50 \LST\ FLAG: .WORD 0 ;WILD CARD FLAG LIM: .LIMIT ;FOR BUFFER ALLOCATION OUTSP: .BLKW 39. ;FOR CSI PROCESSING PATS: .BLKW 10. ;FOR PATTERN MATCHING OF WILD CARDS QUEBLK: .RAD50 /MQ/ ;FOR LOOKUP OF QUEUE .ASCIZ /QUEUE/ .EVEN RETSP: .WORD 0,0 ;DSTATUS BLOCK RETSP6: .WORD 0,0 ;DSTATUS BLOCK SVSP: .WORD 0 ;SP SAVE WORD $MES: .WORD FLG.JR ;REQUEST TO QUEUE .NLCSI TYPE=I PART=NAME $BFF: .WORD 0 ;POINTER TO BLOCKS .WORD 0 $BUF: .WORD 0 ;$ -- PERMANENT VARIABLE SET,START OF BUFFER $BLK: .WORD 0 ;START OF BUFFER FOR THIS LINE $CNT: .WORD 0 ;#BLKS $TMP: .WORD 0 ;STORAGE FOR WILD CARDS $$BLK: .WORD 0 ;$$--TEMPORARY,PLACE IIN BUFFER $$CNT: .WORD 0 ;RUNNING CNT $$NUM: .WORD 0 ;NUMBER READ IN ;***** The following words must be in this order ***** ;003 DAY:: .WORD 0 ;Current date (0-31) ;003 MON:: .WORD 0 ;Current month (0-12) ;003 YEAR:: .WORD 0 ;Current year (72-199) ;003 UDATE:: ;003 UYEAR:: .WORD 0 ;/DATE entered year UMON:: .WORD 0 ;/DATE entered month UDAY:: .WORD 0 ;/DATE entered date ;003 TDAY:: .WORD 0 ;Temp day used in date conversions ;003 TMON:: .WORD 0 ;Temp month ;003 TYEAR:: .WORD 0 ;Temp year ;003 BDATE:: BYEAR:: .WORD 0 ;/BEFORE entered year BMON:: .WORD 0 ;/BEFORE entered month BDAY:: .WORD 0 ;/BEFORE entered day SDATE:: SYEAR:: .WORD 0 ;/SINCE entered year SMON:: .WORD 0 ;/SINCE entered month SDAY:: .WORD 0 ;/SINCE entered day ;***** End of order dependent area ***** ;003 MONTHS::.RAD50 \BADJANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC\ ;003 UDATSB::.WORD 0 ;Flags for fields of dates set ;016 BDATSB::.WORD 0 SDATSB::.WORD 0 DATE:: .WORD 0 ;CURRENT DATE DFLAG:: .WORD 0 ;Flag word for /BEFORE and /SINCE SWD:: .WORD 0 ;Number of times procedure SD was entere;003 ;003 ; STRING CONSTANTS R50AS= 132500 R50DK: .RAD50 \DK\ R50LP: .RAD50 \LP\ PRCENT= 45 DOT= 56 BLANK= 40 ASTERK= 52 ; CONSTANTS AND VARIABLES FOR DIRECTORY MANIPULATION CODE ; STATUS BITS IN ENTRY: DS.EOS= 4000 ;1= END OF SEGMENT ENTRY DS.PRM= 2000 ;1= PERMANENT ENTRY DS.EMP= 1000 ;1= EMPTY ENTRY ; DIRECTORY HEADER OFFSETS DH.AVL= 0 ;# AVAILABLE DIRECTORY SEGMENTS DH.NXT= 2 ;POINTER TO NEXT DIRECTORY SEG DH.HI= 4 ;HIGHEST DIRECTORY SEGMENT OPEN DH.EXB= 6 ;# OF EXTRA BYTES IN DIRECTORY ENTRIES DH.STB= 10 ;STARTING BLOCK # FOR FILES IN SEGMENT DH.SIZ= 12 ;SIZE OF DIRECTORY HEADER WORDS ; DIRECTORY ENTRY OFFSETS DE.FN1= 2 ;OFFSET TO FIRST WORD OF FILENAME DE.FN2= 4 ;OFFSET TO SECOND WORD OF FILENAME DE.TYP= 6 ;OFFSET TO TYPE DE.LEN= 10 ;OFFSET TO SIZE DE.DAT= 14 ;OFFSET TO CREATION DATE DE.SIZ= 16 ;SIZE OF DIRECTORY ENTRY ; CSTAT area offsets CS.UNT =: 10 ; offset to unit number CS.NAM =: 12 ; offset to device name ; DSTATUS DEVICE ID'S MTIDEN= 20 ;MT MMIDEN= 11 ;MM CTIDEN= 13 ;CT MSIDEN= 35 ;MS (OBVIOUSLY THE MOST IMPORTANT ONE) MUIDEN= 60 ;MU ; DSTATUS attribute bits FILST$ =: 100000 ; Random-Access Device RONLY$ =: 40000 ; Device is READ_ONLY WONLY$ =: 20000 ; Device is WRITE_ONLY SPECL$ =: 10000 ; Special Directory Device HNDLR$ =: 4000 ; Abort/Exit bit 1 SPFUN$ =: 2000 ; Device handler does SPFUNS ABORT$ =: 1000 ; Abort/Exit bit 2 VARSZ$ =: 400 ; Variable Size Device ; SPFUNS AND TAPE LABEL INFO SF.MRE =: 373 ;REWIND SF.MRD =: 370 ;READ SF.MFS =: 376 ;FORWARD SPACE SF.MBS =: 375 ;BACK SPACE EM.EOF =: 1 ;EOF EM.EFT =: 3 ;EOF w/EOT EM.SML =: 6 ;Indicates a 'short block' on read. SF.CFF =: 375 ;SPACE FORWARD (Cassette ONLY) SF.CLB =: 376 ;BACKSPACE BLOCK (Cassette ONLY) ; MAGTAPE DIRECTORY OFFSETS MT.HDR = "HD ;HEADER LABEL MT.EOF = "EO ;EOF LABEL LABSIZ = 400 ;SIZE OF RT-11 LABELS (well, they used to be) MT.SEQ = 31. ;Offset to file sequence number MT.FID = 4 ;Offset to filename MT.YER = 42. ;Offset to file creation year MT.DAY = 44. ;Offset to file creation day (Julian) MT.FSZ = 54. ;Offset to file size (records) ; Cassette symbolics and offsets CTCSR = 177500 ;Cassette control/status register CTHDSZ = 32. ;Size of cassette header record in bytes CT.FID = 0 ;Offset to filename CT.TYP = 6 ;Offset to filetype CT.SEQ = 12. ;Offset to file sequence number CT.DAY = 14. ;Offset to day of file creation CT.MON = 16. ;Offset to month of file creation CT.YER = 18. ;Offset to year of file creation CT.EOF = 4000 ;End-of-file bit in CTCSR CT.EOT = 20000 ;End-of-tape bit in CTCSR ; STORAGE INFO ICHAN= 0 ;INPUT CHANNEL INBFSZ= 2000 ;SIZE IN BYTES FOR READS AVAIL: .WORD 0 ;# OF AVAILABLE DIRECTORY SEGMENTS FLG1: .WORD 0 ;USED FOR MAGTAPE EOSFLG: .WORD 0 ;END OF SEGMENT FLAG HISEG: .WORD 0 ;HIGHEST DIRECTORY SEGMENT IN USE NXTDSG: .WORD 0 ;NEXT SEGMENT TO READ NXTFIL: .WORD 0 ;POINTER TO NEXT ENTRY RBLK: .WORD 0 ;PHYSICAL BLOCK TO READ SAV: .WORD 0 ;SAVE WORD FOR NEXT SEGMENT POINTER SBLOCK: .WORD 0 ;STARTING BLOCK # OF CURRENT FILE XTRABY: .WORD 0 ;# OF EXTRA BYTES IN DIRECTORY ; STORAGE LKBLK: .BLKW 4 ;USED FOR LOOKUP'S AND SPFUN'S FLSP: .WORD 0,0,0,0 ;PHONEY FILESPEC FOR LOOKUP CHARS: .BLKW 6 ;CURRENT DIRECTORY FILENAME IN ASCII IBUF: .BLKW 1000 ;GENERAL PURPOSE BUFFER CSDATA: .BLKW 6 ; .CSTAT area ; /L STORAGE AND CONSTANTS $NLL: .ASCIZ / RT-11 Device Queue is Empty/ $HD1: .ASCIZ /Device Job Status Copies File/ $HD2: .ASCIZ /------ --- ------ ------ ----/ .EVEN CQE= 4 LQE= 6 QIO= 10 QJBSV= 34 FLG3: .WORD 0 FLG4: .WORD 0 LQ: .WORD 0 CQ: .WORD 0 NMB: .WORD 0 TMP: .WORD 0 TAB= 11 QFL: .RAD50 /DK/ .RAD50 /QUFIL/ .RAD50 /TMP/ ;+ ; QUEUE Chain Area ; ; The format for the QUEUE chain area is ; ;location value use ; ;500 .RAD50 \SY \ RAD50 program name to chain to ; .RAD50 \QUE\ ; .RAD50 \MAN\ ; .RAD50 \SAV\ ;510 .WORD 1 # switches to send to QUEMAN ( 1 here) ;512 .ASCIZ \/L/A\ switch(es) to send, in the format /switch ; Note: only switches WITHOUT values are accepted ; ;- .ASECT .= $JSW .WORD JS.REE .PSECT MAIN .SBTTL MAIN PROGRAM .LIST BEX ;+ ; THIS IS THE MAIN PROGRAM FOR QUEMAN ; IT WILL: ; 1-- CHECK IF WE HAVE SYSTEM TASKING AND ISSUE ; A .LOOKUP IF WE DO ; 2-- GET THE FIRST COMMAND LINE AND INITIALIZE ; VARIABLES ; 3-- GET AND INITIALIZE A BUFFER ; 4-- PROCESS SWITCHES APPROPRIATELY ; 5-- PROCESS BOTH WILDCARD AND NORMAL FILES ; 6-- IF THERE IS A CONTINUATION LINE, GO TO 3 ; 7-- SEND MESSAGE TO QUEUE AND WAIT FOR A REPLY ; 8-- IF ERROR SEND MESSAGE AND THEN EXIT ;- BR RSTRT ;RE ENTRY POINT ;001 ;001 START:: .GVAL #AREA,#SYSVER ;Get version CMPB #VERS,R0 ;CORRECT VERSION? ;010 BEQ 1$ ;YES, BRANCH ;010 ;+ ;ERROR .ERR #ERAR,#EM9,LEVEL=F,RETURN=Y ;010 ;;;<-F-WRONG VERSION OF RT11> ;- .EXIT ;010 1$: JSR PC,PAT1 ;SAVE THE STACK ;002 MOV LIM+2,$BUF ;SET UP FOR SETTOP ;001 MOV USRBUF(R0),R0 ;->USR TST -(R0) ;ONE WORD LESS .SETTOP ;GET BUFFER MOV R0,LIM+2 ;UPDATE LIMIT RSTRT: .GVAL #AREA,#CONFIG BIT #QUEUE$,R0 ;QUEUE PRESENT? ;001 BNE 1$ ;IF NE YES ;001 ;+ ;ERROR .ERR #ERAR,#EM5,LEVEL=F,RETURN=YES ;001 ;- .EXIT ;NO QUEUE ;001 1$: .GTIM #AREA,#TIME ;Get time-of-day (and maybe cause date r;003 .DATE ;Get the date ;003 MOV R0,DATE ;Save it ;003 CALL CONDAT ;Convert it to something useable ;003 MOV TDAY,DAY ;Save converted day, mon, year ;003 MOV TMON,MON ;003 MOV TYEAR,YEAR ;003 MOV TDAY,UDAY ;Set up defaults for /DATE MOV TMON,UMON MOV TYEAR,UYEAR CLR UDATSB ;016 MOV TDAY,BDAY ;Set up defaults for /BEFORE MOV TMON,BMON MOV TYEAR,BYEAR CLR BDATSB ;016 MOV TDAY,SDAY ;Set up defaults for /SINCE MOV TMON,SMON MOV TYEAR,SYEAR CLR SDATSB ;016 MOV #$CNT,R0 ;POINT TO ENTRIES ;003 CLR (R0)+ ;ZERO THEM CLR (R0)+ ;ZERO THEM CLR (R0)+ ;ZERO THEM CLR (R0)+ ;ZERO THEM CLR (R0)+ ;ZERO THEM MOV $BUF,$BLK ;INITIALIZE $BLK CSI: MOV SVSP,SP ;RESTORE THE STACK BIT #CHAIN$,@#$JSW ;WERE WE CHAINED TO? BEQ 4$ ;IF NOT, BRANCH BIC #CHAIN$,@#$JSW ;CLEAR CHAIN BIT MOV #510,R3 ;GET START OF SWITCH AREA MOV (R3)+,R4 ;SAVE THE NUMBER OF SWITCHES MOV R4,R0 2$: TSTB (R3)+ ;PUSH PAST THE / CLR -(SP) BISB (R3)+,@SP ;PUT THE SWITCH ONTO THE STACK DEC R0 BGT 2$ ;GET ALL THE SWITCHES MOV R4,-(SP) ;PUT NO. OF SWITCHES ON STACK BR 10$ ;MERGE BELOW 3$: .PRINT #VERSN ;PRINT VERSION # BR RSTRT ;SPLIT 4$: .CSISPC #OUTSP,#DFTYP,#0,#IBUF ;PARSE THE COMMAND LINE BCC 5$ ;IF CC OK ;+ ;ERROR .ERR #ERAR,#EM2,LEVEL=E,RETURN=NO ;ILLEGAL COMMAND LINE ;- 5$: TSTB IBUF ;ANY INPUT? BEQ 3$ ;IF not do version number 10$: CLR MFLAG ;CLEAR MODIFICATION FLAG;004 JSR PC,$STUP ;GET BUFFER AND INITIALI;004 MOV (SP)+,R2 ;GET # OF SWITCHES BEQ 30$ ;IF EQ NONE 15$: MOV #SWTAB,R3 ;R3 -> SWITCH TABLE MOV #ACTAB,R4 ;R4 -> ACTION TABLE MOV (SP)+,R5 ;R5 = SWITCH CMPB #'a,R5 ; Between a and z ? BHI 22$ ; Branch if not CMPB #'z,R5 ; Between a and z ? BLO 22$ ; Branch if not BICB #40,R5 ; Capitalize it 22$: TST R5 ; Anything there? BMI 20$ ;IF MI VALUE IS PRESENT CMPB #'H,R5 ;IS THE SWITCH THE BANNER PAGE? ;011 BNE 16$ ;NO, BRANCH ;011 MOV #-1,-(SP) ;STORE -1 AS VALUE ;011 BR 20$ ;BRANCH! ;011 16$: CLR -(SP) ;ELSE FAKE ONE 20$: CMPB (R3)+,R5 ;IS THIS THE SWITCH? BEQ 25$ ;IT CERTAINLY IS TST (R4)+ ;BUMP POINTER BNE 20$ ;IF NE MORE TO CHECK MOVB R5,@#18.+EM.EM4 ;FILL IN SWITCH IN MESSAGE ;+ ;ERROR .ERR #ERAR,#EM4,LEVEL=E,RETURN=NO ;- 25$: MOV (SP)+,R0 ;GET POSSIBLE VALUE JSR PC,@(R4)+ ;GO PROCESS SWITCH SOB R2,15$ ;CONTINUE IF MORE 30$: MOV #OUTSP,R0 ;RO ->FILES MOV R0,R2 ;INIT FOR LATER USE MOV $$BLK,R5 ;R5->START OF BUFFER CMP (R5)+,(R5)+ ;POINT TO DEVICE IN BLK1 MOV $$NUM,R4 ;FILL IN #READ IN TST $CNT ;CONTINUATION LINE? BNE 60$ ;IF NE YES BIC #FLG.QC,MFLAG ;NONE COPIED YET ;004 TST @R0 ;DEVICE SPEC? BEQ 45$ ;IF EQ NO CMP @R0,R50DK ;DK? BNE 50$ ;IF NE NO MOV #IBUF,R3 ;POINT TO ORIGINAL CML 35$: CMPB @R3,#': ;HAVE WE FOUND A : BNE 40$ ;IF NE NO BR 50$ ;IF YES DK WAS NOT DEFAULT 40$: CMPB @R3,#'= ;DID WE FIND AN =? BEQ 45$ ;IF EQ YES, CHANGE DK TO LP CMPB @R3,#'/ ;DID WE FIND A /? BEQ 45$ ;IF EQ YES CMPB (R3)+,#'< ;IS IT A NEXT JFB .DSTATUS #RETSP,R2 ;ARE YOU THERE? BCS $ILDV ;IF CS NO TST RETSP6 ;HANDLER LOADED? BEQ $HNDER ;IF EQ NO 60$: ADD #INSP,R2 ;POINT TO INPUT FILE SPECS ; Process input file list 65$: .DSTATUS #RETSP,R2 ;DEVICE LEGAL? BCS $ILDV ;IF CS NO TST RETSP6 ;HANDLER LOADED? BEQ $HNDER ;IF EQ NO MOV #PATS,R1 ;R1->SCRATCH AREA MOV R2,R0 ;SAVE POSITION TST (R0)+ ;->FILE JSR PC,RTOA ;CONVERT MOV #12,R3 ;CHECK 9 CHARACTERS ;002 MOV #PATS,R0 ;R0->ASCII STRING 70$: CMPB #PRCENT,@R0 ;%? BEQ 75$ ;IF EQ YES CMPB #ASTERK,(R0)+ ;*? BEQ 75$ ;IF EQ YES SOB R3,70$ ;CHECK NEXT CHARACTER BR 80$ ;NO WILDCARDS 75$: MOV RETSP,R0 ; Get the input device's status BIC #^C,R0 ; Isolate certain bits BEQ $ILDV ; If both zero, no good for wildcards CMP #,R0 ; If both one, no good either. BEQ $ILDV JSR PC,$WCRD ;GO PROCESS WILDCARD BR 86$ ;NEXT FILE ;004 ;004 80$: .LOOKUP #AREA,#10,R2,#0 ;FILE THERE? BCS $FNF ;IF CS NO MOV #10,R0 ;POINT TO CHANNEL JSR PC,REALDV ;GET THE REAL PHYSICAL DEVICE .CLOSE #10 ;CLOSE MOV R2,R3 ;FAKE DIRECTORY ENTRY ;004 CALL QUERY ;DO QUERY PROCESSING ;004 TST R0 ;IS SHE SURE? ;004 BNE 85$ ;YES ;004 DEC $$NUM ;THAT'S ONE LESS TO QUEU;004 BR 86$ ;DON'T FILL IN BLOCK ;004 85$: JSR PC,MKBLK ;FILL IN THE BLOCK ;004 86$: SOB R4,65$ ;CONTINUE ;004 MOV $BUF,R0 ;POINT TO BUFFER ADD #6,R0 ;POINT TO JOBNAM TST @R0 ;PRESENT? BNE 90$ ;IF NE YES MOV R0,R1 ;R1->JOBNAM WORD ADD #14,R1 ;R1->FILNAM IN FIRST BLOCK MOV (R1)+,(R0)+ ;MOVE IT IN MOV (R1)+,(R0)+ ;MOVE IT IN BR 95$ ;MERGE BELOW 90$: CMP (R0)+,(R0)+ ;R0->#FILE BLOCKS 95$: ADD $$NUM,@R0 ;UPDATE IT TST $$CNT ;CONTINUATION NOW? BNE 100$ ;IF NE YES BIT #FLG.QC,MFLAG ;ARE THERE ANY TO BE COP;004 BNE 100$ ;BRANCH IF NOT ;004 JMP RSTRT ;NOTHING TO QUEUE ;004 ;004 100$: JMP $SEND ;GO SEND THE REQUEST ;004 ;004 MOV $$CNT,$CNT ;UPDATE CNT ;004 MOV $$BLK,$BLK ;UPDATE FREE BLK POINTER JMP CSI ;GET NEXT LINE $HNDER: MOV R2,R1 ;POINT TO FILE SPEC TST (R2)+ ;BUMP POINTER CLR (R2)+ ;ZERO FILL CLR (R2)+ ;ZERO FILL CLRB (R2)+ ;ZERO FILL ;+ ;ERROR .ERR #ERAR,#EM1,LEVEL=F,FILE=R1,RETURN=YES ;- .EXIT ;ABORT $ILDV: MOV R2,R1 ;POINT TO FILE SPEC TST (R2)+ ;BUMP POINTER BEQ 1$ ;IF EQ NO DEVICE CLR (R2)+ ;ZERO FILL CLR (R2)+ ;ZERO FILL CLRB (R2)+ ;ZERO FILL ;+ ;ERROR .ERR #ERAR,#EM3,LEVEL=F,FILE=R1,RETURN=NO 1$: .ERR #ERAR,#EM2,LEVEL=E,RETURN=NO ;- $FNF: .CLOSE #10 BIT #FLG.IN,MFLAG ;/INFO SPECIFIED? ;007 BNE 1$ ;BRANCH IF SO ;007 ;+ ;ERROR .ERR #ERAR,#EM0,FILE=R2,LEVEL=E,RETURN=NO 1$: .ERR #ERAR,#EM0,FILE=R2,LEVEL=I,RETURN=NO ;007 ;- ;007 .SBTTL CREATE A BLOCK ROUTINE ;+ ; THIS ROUTINE WILL FILL IN THE DV:FILNAM.EXT ; IN THE PROPER BLOCK. ; INPUT: R2-> FILSPEC ; R5-> 3RD WORD OF THE FILE REQUEST BLOCK ; OUTPUT: R5-> DEVICE SPEC IN NEXT SKELETON BLOCK ; R2-> NEXT FIL SPEC ;- MKBLK: MOV (R2)+,(R5)+ ;DEVICE MOV (R2)+,(R5)+ ;FIL MOV (R2)+,(R5)+ ;NAM MOV (R2)+,(R5)+ ;EXT MOV R5,$$BLK ;UPDATE POINTER CMP (R5)+,(R5)+ ;BUMP POINTER BIS #FLG.QC,MFLAG ;A COPY IS TO BE DONE ;004 RTS PC ;SPLIT ;+ ; THIS ROUTINE WILL CHECK FOR A LEGAL FILE SPEC ON ; A SWITCH AND THEN POINT TO THE FILE REQUEST BLOCK ; THAT IT GOES WITH. ;- $PTBLK: MOVB R5,NMB ;SAVE THE ASCII SWITCH IN CASE OF ERROR BIC #100377,R5 ;GET # OF FILE SWAB R5 ;IN LOW BYTE MOV #OUTSP,R1 ;R1-> FILE SPECS TST R5 ;FIRST FILE? BEQ 15$ ;IF EQ YES CMPB -(R5),-(R5) ;DECREMENT IT ADD #INSP-10,R1 ;SET UP FOR LOOP MOV R5,-(SP) ;SAVE IT 5$: ADD #10,R1 ;POINT TO NEXT BLOCK SOB R5,5$ ;LOOP MOV (SP)+,R5 ;RESTORE R5 10$: TST @R1 ;FILE? BNE 15$ ;IF NE YES MOVB NMB,@#EM.EM4+18. ;FILL IN SWITCH ;001 ;+ ;ERROR .ERR #ERAR,#EM4,LEVEL=E,RETURN=NO ;- 15$: MOV $$BLK,R1 ;POINT TO JRB'S TST R5 ;FIRST ONE? BEQ 25$ ;IF EQ YES 20$: ADD #14,R1 ;POINT TO NEXT DEC R5 ;DECREMENT BNE 20$ ;LOOP 25$: RTS PC ;RETURN .SBTTL SWITCH ROUTINES ;+ ; ABORT SWITCH ROUTINE ;- $ABRT: MOV $BUF,R0 ;GET RID OF RETURN ADDRESS BIS #FLG.AB,@R0 ;FILL IN ABORT FLAG IN JRB TST (SP)+ ;POP RETURN ADDRESS JMP $SEND ;SEND THE BLOCK ;+ ; # OF COPIES ROUTINE ;- $COPY: JSR PC,$PTBLK BIS #FLG.CP,@R1 ;SET FLAG MOVB R0,FRB.CP(R1) ;FILL IN VALUE RTS PC ;RETURN WITH A JOB WELL DONE ;+ ; DELETE ROUTINE ;- $DEL: JSR PC,$PTBLK BIS #FLG.DE,@R1 ;SET FLAG RTS PC ;SPLIT ;+ ; # OF BANNER PAGES ROUTINE ; $NHED: CLR R0 ;SAY 0 VALUE ;MERGE $HED: JSR PC,$PTBLK BIS #FLG.HD,@R1 ;SET FLAG MOVB R0,FRB.BN(R1) ;FILL IN VALUE RTS PC ;SPLIT ;+ ; MUTILATE AN UNSUSPECTING ENTRY ROUTINE ;- $KLL: BIC #100377,R5 ;GET FILE TST R5 ;0? BNE 1$ ;IF NE ERROR MOV $BUF,R1 ;POINT TO JOB BLOCK BIS #FLG.KL,@R1 ;SET FLAG MOV #OUTSP,R0 ;POINT TO FILE SPEC CMP (R1)+,(R1)+ ;POINT TO DEVICE IN JRB MOV (R0)+,(R1)+ ;PUT IN DEVICE MOV (R0)+,(R1)+ ;JOBNAME MOV (R0)+,(R1)+ ;JOBNAME CLR $$NUM ;#JOBS TST (SP)+ ;POP RETURN ADDRESS JMP $SEND ;GO SEND IT ;+ ;ERROR 1$: .ERR #ERAR,#EM2,LEVEL=E,RETURN=NO ;- ;+ ; SPECIFY A DATE ;003 ;- $DATE: BIS #FLG.DA,MFLAG ;Set flag ;003 JSR PC,SD ;Validate date ;003 RTS PC ;Return ;003 ;003 ;+ ;003 ; SPECIFY /SINCE ;003 ;- ;003 $SINC: BIS #FLG.SI,MFLAG ;Set flag ;003 JSR PC,SD ;Validate date ;003 RTS PC ;Return ;003 ;003 ;+ ;006 ; SPECIFY /BEFORE ;006 $BEFOR: BIS #FLG.BE,MFLAG ;Set flag ;006 JSR PC,SD ;Validate date ;006 RTS PC ;Return ;006 ;+ ;004 ; SPECIFY /QUERY ;004 ;- ;004 $QRY: BIS #FLG.QR,MFLAG ;Set flag ;004 BIC #FLG.LG,MFLAG ;No /LOG with /QUERY ;004 RTS PC ;004 ;004 ;+ ;004 ; SPECIFY /LOG ;004 $LOG: .PRINT #LOGHDR ;Print LOG header ;004 BIT #FLG.QR,MFLAG ;/Q specified? ;004 BNE 9$ ;Yes - no /LOG ;004 BIS #FLG.LG,MFLAG ;set flag ;004 9$: RTS PC ;004 ;007 ;+ ;**-1 ; SPECIFY /INFORMATION ;007 $INFO: BIS #FLG.IN,MFLAG ;Set flag ;007 RTS PC ;007 ;007 ;+ ;007 ; LIST ROUTINE ;003 ; ; If the queue is empty the user error byte will be set to ; success, if the queue is not empty the error byte will be ; set to warning. (c.a.) ;- ;003 $LST: .CHCOPY #AREA,#3,#0,#QUEBLK+2 ;OPEN THE CHANNEL BCC 5$ ;IF CC OK ;+ ;ERROR .ERR #ERAR,#EM5,RETURN=YES,LEVEL=F ;- .EXIT ;WAVE GOODBYE 5$: MOV @#SYSPTR,R3 ;ADD BASE OF RMON TO OFFSET ADD #38.,R3 ;+OFFSET TO ENTRY (ASSUMING CHANNEL #3) MOV @R3,R4 ;R4=HIBLOCK TSTB -(R4) ;DONE .READW #AREA,#3,#IBUF,#512.,R4 ;READ THE CONTROL BLOCK BCC 10$ ;IF CC OK ;+ ;ERROR .ERR #ERAR,#EM7,LEVEL=F,RETURN=YES,FILE=#QFL ;- .EXIT 10$: INC FLG1 ;INITIALIZE FLAG MOV #IBUF,R2 ;POINT TO BUFFER MOV CQE(R2),CQ ;SAVE CURRENT ELEMENT MOV LQE(R2),LQ ;SAVE LAST ELEMENT CMP CQ,LQ ;Q EMPTY? BNE 15$ ;IF NE NO INC FLG3 ;SAY LAST FILE 15$: MOVB LQ,R1 ;R1=OFFSET BIC #177400,R1 ;NO SIGN EXTEND ASL R1 ;MAKE INTO BYTE OFFSETT ADD #IBUF,R1 ;R1=VALUE OF R2 WHEN AT LAST ELEMENT MOV R1,TMP ;SAVE IT .PRINT #$HD1 ;PRINT HEADER .PRINT #$HD2 ;PRINT HEADER MOV $BUF,R1 ;R1->TO OUTPUT BUFFER ADD #QJBSV+4,R2 ;POINT TO SAVED REQ BLK MOVB (R2)+,NMB ;SAVE IT TSTB (R2)+ ;POINT TO # OF COPIES MOV (R2)+,R0 ;RAD50 DEVICE CALL $R50ASC ;CONVERT AND PUT IN CMPB #BLANK,-1(R1) ;LAST CHARACTER A BLANK? BNE 20$ ;IF NE NO TSTB -(R1) ;FIX R1 20$: MOVB #':,(R1)+ ;PUT IN : MOVB #TAB,(R1)+ ;PUT IN TAB MOV (R2)+,R0 ;POINT TO JOBNAME CALL $R50ASC ;CONVERT IT MOV (R2)+,R0 ;SECOND HALF CALL $R50ASC ;CONVERT MOVB #TAB,(R1)+ ;FILL IN TAB MOV #IBUF+QIO,R5 ;POINT TO I/O IN PROG WORD TSTB (R5)+ ;I/O QUEUED? BNE 30$ ;IF EQ NO TSTB @R5 ;SUSPENDED? BEQ 25$ ;IF EQ NO TST FLG3 ;Q MAY BE EMPTY BNE 25$ ;IF NE YES MOVB #'S,(R1)+ ;PUT IN STATUS BR 35$ ;MERGE BELOW 25$: .PRINT #$NLL BISB #SUCCS$,@#USERRB ;SET USER ERROR BYTE JMP $DN ;MERGE BELOW 30$: BISB #WARN$,@#USERRB ;SET USER ERROR BYTE MOVB #'P,(R1)+ ;STATUS 35$: MOVB #TAB,(R1)+ ;TAB MOVB CQ+1,R5 ;R5=BLK# OF CQE .READW #AREA,#3,#IBUF,#512.,R5 MOV #IBUF,R2 ;POINT TO BUFFER MOVB CQ,R3 ;R3=OFFSET TO CQ BIC #177400,R3 ;SIGN EXETEND ASL R3 ;MAKE IT AA ADDRESS ADD R3,R2 ;ADD IT TO BUFFER FOR 1ST TIME BIT #FLG.JR,@R2 ;IS CQ A JRB? BEQ 40$ ;IF EQ NO MOVB -2(R1),FLG4 ;SAVE STATUS MOV $BUF,R1 ;ELSE START OVER 40$: CMP R2,#IBUF+512. ;READ IN A NEW BUFFER? BLO 45$ ;IF MI NO JSR PC,$RDW ;READ IT IN 45$: CMPB LQ+1,R5 ;ISTHIS LASTQ? BNE 50$ ;IF NE NO CMP R2,TMP ;ON THE LAST ELEMENT? BNE 50$ ;IF NE NO INC FLG3 ;SET FLAG 50$: BIT #FLG.JR,@R2 ;JRB? BNE 85$ ;IF NE YES TST FLG1 ;FIRST TIME? BNE 55$ ;IF NE YES MOVB #TAB,(R1)+ ;PUT IN TABS MOVB #TAB,(R1)+ ;PUT IN TABS MOVB #TAB,(R1)+ ;PUT IN TABS 55$: CLR FLG1 ;FIX FLAG TST (R2)+ ;POINT TO COPIES TSTB @R2 ;DEFAULT? BEQ 60$ ;IF EQ YES MOVB @R2,R3 ;FILLIN THE # OF COPIES BR 70$ ;MERGE 60$: TSTB NMB ;DEFAULT BEQ 65$ ;IF EQ DEFAULT MOVB NMB,R3 ;FILL IN BR 70$ ;MERGE 65$: MOVB #1,R3 ;DEFAULT 70$: BIC #177400,R3 ;MAKE SURE NO SIGN EXTEND JSR PC,CVT10 ;PUT IT IN MOVB #TAB,(R1)+ ;TAB TST (R2)+ ;POINT TO DEVICE MOV (R2)+,R0 ;CONVERT CALL $R50ASC ;CONVERT CMPB #BLANK,-1(R1) ;LAST CHARACTER A BLANK? BNE 75$ ;IF NE NO TSTB -(R1) ;FIX R1 75$: MOVB #':,(R1)+ ;FILL IN : MOVB #' ,(R1)+ ;FILL IN BLANK MOV R2,R0 ;SET UP FOR FILE NAME CALL RTOA ;FILLIT IN JSR PC,$DNE ;WRITE THE LINE ADD #12,R2 ;UPDATE POINTER TST FLG3 ;LAST TIME? BNE $DN ;IF NE YES 80$: BR 40$ ;CONTINUE 85$: BIT #FLG.KL,(R2)+ ;KILL? BEQ 105$ ;GET NEW BLOCK 90$: ADD #14.,R2 ;POINT TO NEXT CMPB LQ+1,R5 ;DONE? BNE 95$ ;IF NE NO CMP R2,TMP ;DONE? BEQ $DN ;IF EQ YES 95$: CMP R2,#IBUF+512. ;READ MORE BLO 100$ ;IF MI NO JSR PC,$RDW ;READ IT 100$: BIT #FLG.JR,(R2)+ ;JRB? BEQ 90$ ;IF EQ NO TST -(R2) ;FIX POINTER BR 85$ ;CONTINUE 105$: MOVB (R2)+,NMB ;DEFAULT COPIES TSTB (R2)+ ;POINT TO DEVICE MOV (R2)+,R0 ;PUT IT IN CALL $R50ASC ;CONVERT CMPB #BLANK,-1(R1) ;LAST CHARACTER A BLANK? BNE 110$ ;IF NE NO TSTB -(R1) ;FIX R1 110$: MOVB #':,(R1)+ ;PUT IN : MOVB #TAB,(R1)+ ;PUT IN TAB MOV (R2)+,R0 ;JOBNAME CALL $R50ASC ;PUT IT IN MOV (R2)+,R0 ;SECOND HALF CALL $R50ASC ;PUT IT IN MOVB #TAB,(R1)+ ;TAB TST FLG4 ;FIRST FILE? BEQ 115$ ;IF EQ NO MOVB FLG4,(R1)+ ;PROPER STATUS CLR FLG4 ;CLEAR FLAG BR 120$ ;MERGE 115$: MOVB #'Q,(R1)+ ;STATUS 120$: MOVB #TAB,(R1)+ ;TAB INC FLG1 ;SAY NO TAB LINE ADD #6,R2 ;UPDATE BR 80$ ;CONTINUE ;+ ; THIS ROUTINE WILL READ IN THE NEXT BLOCK ; FROM QUFILE.TMP ;- $RDW: INC R5 ;UPDATE BLOCK # CMP R5,R4 ;R5 = CNTRL BLOCK? BNE 110$ ;IF NE NO CLR R5 ;READ BLOCK 0 110$: .READW #AREA,#3,#IBUF,#512.,R5 ;GET NEXT BLOCK MOV #IBUF,R2 ;FIX R2 RTS PC ;RETURN ;+ ; THIS ROUTINE OUTPUTS A LINE TO THE CONSOLE ;- $DNE: MOVB #'.,-5(R1) ;PUT . IN FILE NAME CLRB (R1)+ ;PUT IN ZERO BYTE MOV $BUF,R1 ;REPOINT TO BUFFER .PRINT R1 ;OUTPUT LINE RTS PC ;+ ; THIS ROUTINE FINISHES UP ;- $DN: CLR FLG3 ;UPDATE FLAG .CLOSE #3 JMP RSTRT ;RESTART ;+ ; SET PARAMETERS ROUTINE ;- $SET: BIS #JS.GTL,@#$JSW ;SET UP FOR GETLIN .GTLIN #IBUF,#PRPT ;GET PARAMETER MOV $BUF,R4 ;GET BUFFER BIS #FLG.SP,@R4 ;SET BIT CLR JRB.NR(R4) ;FIX JRB MOV #IBUF,R1 ;SET UP TO CONVERT TST (R4)+ ;BUMP POINTER JSR PC,ASCOCT ;CONVERT IT SWAB @R4 ;SET UP BLK .GTLIN #IBUF,#PM2 CMPB IBUF,#'Y ;YES? BNE 10$ ;IF NE NO MOV $BUF,R4 ;POINT TO REQ BLOCK INCB JRB.CP(R4) ;INDICATE DELETE 10$: BIC #JS.GTL,@#$JSW ;RESET JSW BIT TST (SP)+ ;POP RETURN ADDRESS JMP $SEND ;GO SEND IT ;+ ; RESTORE A JOB ROUTINE ;- $RST: MOV $BUF,R1 ;POINT TO JOB BLOCK BIS #FLG.RS,@R1 ;SET FLAG TST (SP)+ ;POP RETURN ADDRESS JMP $SEND ;GO SEND IT ;+ ; SUSPEND A JOB ROUTINE ;- $SSPD: MOV $BUF,R1 ;POINT TO JOB BLOCK BIS #FLG.SU,@R1 ;SET FLAG TST (SP)+ ;POP RETURN ADDRESS JMP $SEND ;GO SEND IT ;+ ; CONTINUATION LINE ROUTINE ;- $CONT: TST $$CNT ;TURN ON //? BNE 5$ ;IF NE NO INC $$CNT ;TURN ON $$CNT BIS #JS.GTL,@#$JSW ;SET GET LINE BIT FOR DCL BR 20$ ;MERGE BELOW 5$: CLR $$CNT ;TURN IT OFF BIC #JS.GTL,@#$JSW ;CLEAR FOR EXIT BIC #100377,R5 ;GET # OF FILE SWAB R5 ;IN LOW BYTE CMPB #3,R5 ;IS IT ON FIRST SPEC? BNE 15$ ;IF NE NO MOV #OUTSP+INSP,R1 ;GET SPEC TST @R1 ;FILE? BNE 20$ ;IF NE YES 10$: TST (SP)+ ;POP RETURN ADDRESS JMP $SEND ;SEND WHAT WE HAVE 15$: TST R5 ;FIRST FILE? BEQ 10$ ;IF EQ YES 20$: RTS PC ;SPLIT .SBTTL GET AND INITIALIZE BUFFER ROUTINE ;+ ; THIS ROUTINE WILL CALCULATE HOW MANY NEW ; BLOCKS ARE NEEDED IN THE BUFFER. IT WILL ; THEN ISSUE A .SETTOP TO GET THAT MANY. ; THE NEW BLOCKS ARE THEN INITIALIZED TO ; THE APPROPRIATE DEFAULTS. ;- $STUP: MOV $BLK,R0 ;GET HIGH LIMIT MOV R0,$$BLK ;UPDATE TEMPORARY POINTERS CLR $$NUM ;CLEAR $$NUM FOR LATER MOV $CNT,$$CNT ;UPDATE TEMPORARY POINTERS MOV R0,R1 ;SAVE IT CLR R4 ;R4 = 0 MOV #OUTSP,R5 ;R5->FIL;E DESCRIPTORS TST $$CNT ;CONTINUATION? BNE 5$ ;IF NE YES DEC $$NUM ;FIX FOR FIRST ENTRY INC R4 ;NEED A JRB 5$: MOV #6,R3 ;COUNTER ADD #INSP,R5 ;POINT TO INPUT SPECS 10$: TST @R5 ;IS THERE A SPEC? BEQ 15$ ;IF EQ NO INC R4 ;UPDATE R4 ADD #10,R5 ;POINT TO NEXT SPEC SOB R3,10$ ;LOOP 15$: ADD R4,$$NUM ;SAVE # BLOCKS TST R4 ;NO SPECS? BEQ 30$ ;IF EQ YES 20$: MOV #6,R5 ;COUNTER 25$: CLR (R1)+ ;FILL IT IN CMP LIM+2,R1 ;ENOUGH ROOM? BLOS 35$ ;IF LOS NO SOB R5,25$ ;LOOP SOB R4,20$ ;LOOP 30$: RTS PC ;ALL DONE ;+ ;ERROR 35$: .ERR #ERAR,#EM8,LEVEL=E,RETURN=NO ;- .SBTTL SEND REQUEST ROUTINE ;+ ; THIS ROUTINE WILL DETERMINE IF WE HAVE A ; SYSTEM TASKING MONITOR PRESENT AND IF SO ; WILL : ; .LOOKUP QUEUE ; .WRITW OUR REQUEST BLOCK ; .READW WAIT FOR QUEUE'S RESPONCE ; PROCEED TO GO ; ELSEWE WILL: ; .SDATW OUR REQUEST BLOCK ; .RCVDW WAIT FOR A REPLY ; GO TO RESTART ; IF ANY ERRORS OCCUR WE WILL NONCHALANTLY ; INSULT THE USER. ;- $SEND: MOV $BUF,R1 ;FILL IN BLOCK ADDRESS BIS #FLG.JR,@R1 ;SET BIT MOV R1,$BFF ;FILL IN ADDRESS .GVAL #AREA,#SYSGEN BIT #STASK$,R0 ;SYS TASKING? BEQ 10$ ;IF EQ NO .LOOKUP #AREA,#16,#QUEBLK ;SAY HELLO BCS 25$ ;IF CS HE'S NOT HOME .WRITW #AREA,#16,#$MES,#6 ;SEND HIM OUR REQUEST BCS 25$ ;LEAVING SO SOON? .READW #AREA,#16,#ACK,#6 ;WAIT FOR A REPLY BCS 25$ ;NO QUEUE MOV ACK+2,R0 ;STATUS BNE 15$ ;IF NE ERROR .CLOSE #16 5$: JMP RSTRT ;001 ;GO GET A NEW REQUEST ;001 ;001 10$: .SDATW #AREA,#$MES,#6 ;SEND DATA BCS 25$ ;IF CS QUEUE LEFT .RCVDW #AREA,#ACK,#6 ;REPLY BCS 25$ ;NO QUEUE MOV ACK+2,R0 ;SUCCESS? BEQ 5$ ;IF EQ YES ;+ ;ERROR 15$: .ERR #ERAR,#EM6,LEVEL=E,RETURN=NO 25$: .ERR #ERAR,#EM5,LEVEL=F,RETURN=YES ;- MOV @#SYSPTR,R0 ;POINTER TO RMON ;008 BIC #QUEUE$,CONFIG(R0) ;CLEAR QUEUE RUNNING BIT;008 .EXIT .SBTTL MATCH1- Filename match driver ;+ ; MATCH1 ; This is the driver for matching input filenames against the directory ; entries. ; INPUTS: ; R3 -> directory entry ;004 ; OUTPUTS: ; R0 <> 0 if any of the input files matched the current file ; R0-R4 modified ;- MATCH1:: MOV R3,R0 ;Point to the directory entry ADD #DE.FN1,R0 ;Point to the 1st word of the filename MOV #CHARS,R1 ;Point to storage area for ASCII of the name CALL RTOA ;Convert the filename to ASCII BIT #DS.PRM,@R3 ;Is it a permanent file? BNE 10$ ;Branch if so 5$: CLR R0 ;Signal no match BR 15$ ; and return 10$: MOV #PATS,R1 ;Point to input filenames MOV #CHARS,R4 ;Point to the filename (from directory) CALL MATCH ;Go see if the filenames match TST R0 ;Did they match? BEQ 15$ ;Branch if not. We're done MOV #PATS+7,R1 ;Point to the extension ADD #7,R4 ;Point to the extension CALL MATCH ;Go see if the filetypes match TST R0 ;Did they match? BNE 19$ ;Branch if so ;003 15$: RTS PC ;NO MATCH RETURN 19$: CLR DFLAG ;Clear date option flag BIT #FLG.DA,MFLAG ;Doing /DATE? BEQ 191$ ;Branch if not CALL CHKDAT ;Check for a valid date for /DATE TST R0 ;Matching dates? BEQ 15$ ;No match return 191$: BIT #FLG.BE,MFLAG ;Doing /BEFORE? BEQ 192$ ;Branch if not BIS #FLG.BE,DFLAG ;Set flag for CHKDAT CALL CHKDAT ;Check for a valid date for /BEFORE TST R0 ;Matching dates? BEQ 15$ ;No match return 192$: BIT #FLG.SI,MFLAG ;Doing /SINCE BEQ 20$ ;Branch if not CLR DFLAG ;Clear date option flag BIS #FLG.SI,DFLAG ;Set flag for CHKDAT CALL CHKDAT ;Check for a valid date for /SINCE TST R0 ;Matching date? BEQ 15$ ;No match return ;003 20$: JSR PC,QUERY ;DO QUERY IF NECESSARY ;004 TST R0 ;IS IT A MATCH (Y) ;004 BEQ 15$ ;NO MATCH (N or /NOQUERY) ;004 ;004 TST FLAG ;FIRST WLD CARD? ;004 BEQ 25$ ;IF EQ YES JSR PC,$NBLK ;MUST MAKE A NEW ENTRY 25$: INC FLAG ;UPDATE FLAG MOV R2,-(SP) ;SAVE R2 MOV R3,R2 ;POINT TO FILE SPEC MOV @(SP),@R2 ;FILL IN DEVICE JSR PC,MKBLK ;FILL IN BLOCK MOV (SP)+,R2 ;RESTORE IT JMP 15$ ;CONTINUE .SBTTL MATCH- Pattern match routine ;+ ; MATCH ; This routine does a wildcard pattern match against an ASCII pattern string ; pointed to by R1 and a test string pointed to by R2. The matchable ; wildcards are: ; "%" => match any non-null, non-blank character ; "*" => match any string ; Both strings must end in an ASCII blank. ; If there is a match, R0 returns as <> 0. ; R1 is modified. ;- MATCH:: JSR R5,$SAVRG ;SAVE REGISTERS CLR R0 ;Assume failure MOV #BLANK,R2 ;An ASCII blank is often used 5$: MOVB (R1)+,R3 ;Get the next pattern character CMPB #ASTERK,R3 ;Is it a "*"? BNE 10$ ;Branch if not CMPB @R1,R2 ;Are we at the end of the string? BEQ 15$ ;Branch if so. We have a match 10$: CMPB @R4,R2 ;Is this the end of the test string? BNE 20$ ;Branch if not CMPB R3,R2 ;At the end of the pattern string? BNE 30$ ;Branch if not. Return a level 15$: INC R0 ;Else it matched!!! BR 30$ ;Return a level 20$: CMPB R3,R2 ;Is this the end of the pattern string? BEQ 30$ ;Branch if so CMPB #ASTERK,R3 ;Is the pattern character a "*"? BEQ 25$ ;Branch if so CMPB (R4)+,R3 ;Does test char match pattern char? BEQ 5$ ;Branch if yes CMPB #PRCENT,R3 ;Is the pattern char a "%"? BEQ 5$ ;Branch if so. It matches. BR 30$ ;Else return to caller 25$: MOV R1,-(SP) ;Save R1 MOV R4,-(SP) ; and R2 JSR PC,5$ ;And call self!!!! MOV (SP)+,R4 ;Restore R2 MOV (SP)+,R1 ; and R1 TST R0 ;Did the strings match? BNE 30$ ;Branch if so CMPB (R4)+,R2 ;At the end of the test string yet? BNE 25$ ;Branch if not 30$: RETURN ;Return a level .SBTTL CHKDAT- Check two dates for a 'match' ;003 ;003 ;+ ; CHKDAT ;003 ; This routine is used to determine if the current file qualifies ;003 ; as a match in regards to its creation date. It is only called ;003 ; if /I or /C was specified on the command line. ;006 ; INPUTS: ; DFLAG - If FLG.BE or FLG.SI is set in it, CHKDAT will check ; for a /BEFORE or /SINCE match. If neither are set, CHKDAT ; will assume /DATE. ; R3 -> a directory entry ;003 ; OUTPUTS: ; R0 <> 0 If the dates match ;003 ; All registers are saved ;003 ;- CHKDAT:: ;003 MOV R1,-(SP) ;Save regs ;003 MOV R2,-(SP) ;003 MOV R4,-(SP) ;003 MOV R5,-(SP) MOV #UDATE,R2 ;R2 -> /DATE storage area BIT #FLG.BE,DFLAG ;Doing /BEFORE this time? BEQ 7$ ;Branch if not MOV #BDATE,R2 ;R2 -> /BEFORE storage area 7$: BIT #FLG.SI,DFLAG ;Doing /SINCE this time? BEQ 8$ ;Branch if not MOV #SDATE,R2 ;R2 -> /SINCE storage area 8$: MOV DE.DAT(R3),R0 ;Get the file's creation date ;003 CALL CONDAT ;Make it useful ;003 CLR R0 ;Clear the match flag ;003 MOV #TYEAR+2,R1 ;Point to the converted year ;003 MOV #3,R4 ;Initialize a counter ;003 1$: MOV -(R1),R5 ;Get the file's creation date ;003 SUB (R2)+,R5 ;Subtract the given date ;003 BEQ 4$ ;Branch if they are the same ;003 BLT 35$ ;Branch if created before given date ;006 BIT #FLG.SI,DFLAG ;'since' switch? 3$: BEQ 6$ ;Branch if not ;003 BR 5$ ;Good date ;006 35$: BIT #FLG.BE,DFLAG ;Doing /BEFORE? ;006 BEQ 6$ ;Branch if not ;006 BR 5$ ;Good date ;006 4$: DEC R4 ;Down the counter BNE 1$ ;Try again ;003 BIT #FLG.BE,DFLAG ;Doing /BEFORE? BNE 6$ ;Branch if so 5$: INC R0 ;Good date. ;003 6$: MOV (SP)+,R5 ;Restore regs ;003 MOV (SP)+,R4 ;003 MOV (SP)+,R2 ;003 MOV (SP)+,R1 ;003 RETURN ;Bad date. ;003 ;003 ;003 .SBTTL NEXTDK- Get a disk directory entry ;003 ;003 ;+ ;003 ; NEXTDK ;003 ; This routine points R3 at the next directory entry of a disk directory;003 ; R3 cannot be modified once NEXTDK has been called. ;003 ; OUTPUTS: ;003 ; R3 -> next directory entry, if one exists ;003 ; C-bit = 1 if no more directory entries ;003 ;- ;003 ;003 NEXTDK::TST EOSFLG ;Have we got a segment? BNE 35$ ;Branch if yes 5$: MOV NXTDSG,RBLK ;Get the next directory segment BNE 10$ ;If NE then we're not at end SEC ;Flag no more entries BR 45$ ; and return to caller 10$: MOV SP,EOSFLG ;Fix the end-of-segment flag ASL RBLK ;Each directory segment is 2 blocks ADD #4,RBLK ;Offset to block 6 for 1st one MOV #IBUF,R3 ;Point R3 at the input buffer MOV R3,NXTFIL ;Set the pointer to the next file ADD #DH.SIZ,NXTFIL ;Skip the header words .READW #AREA,#ICHAN,R3,#INBFSZ/2,RBLK ;Read a directory segment BCC 20$ ;Branch if no error ;+ ;ERROR 15$: .ERR #ERAR,#EM7,LEVEL=F,RETURN=NO,FILE=R2 ;- .EXIT 20$: MOV DH.EXB(R3),XTRABY ;Set the number of extra bytes BIT #1,XTRABY ;Odd number of extra bytes? BNE 15$ ;Branch if so. Illegal directory. MOV DH.NXT(R3),NXTDSG ;Set the next directory segment MOV DH.STB(R3),SBLOCK ;Get starting block number for segment BNE 25$ ;If EQ, then illegal directory 25$: TST HISEG ;Is this the first segment? BNE 30$ ;Branch if not MOV DH.HI(R3),HISEG ;Else get the highest segment open MOV DH.AVL(R3),AVAIL ; and the highest available BLE 15$ ;If <= 0, illegal directory CMP #37,AVAIL ;Too many directory segments? BLO 15$ ;Branch if so 30$: TST EOSFLG ;Was the last entry end of a segment? BEQ 5$ ;Branch if so 35$: MOV NXTFIL,R3 ;Point R3 at the next entry BIT #DS.EOS,@R3 ;Are we pointing to end of the segment? BEQ 40$ ;Branch if not CLR EOSFLG ;Set the flag 40$: ADD #DE.SIZ,NXTFIL ;Point to next file entry for next loop ADD XTRABY,NXTFIL ;Don't forget extra bytes CLC ;Clear the carry bit 45$: RETURN .SBTTL NEXTMT- Get next magtape filename ;+ ; NEXTMT ; This is the main magtape directory routine. It is called from ; from $WCRD ; INPUTS: ; An HDR label starting at IBUF. ; OUTPUTS: ; R3 -> a pseudo-directory entry at IBUF+1000 ; CHARS contains the filename ; SBLOCK contains the file sequence number ; All registers modified. ;- NEXTMT:: MOV R2,-(SP) ;SAVE R2 MOV R5,-(SP) ;SAVE R5 TST EOSFLG ;Have we encountered EOT or LEOT? BEQ 5$ ;Branch if not CALL REWIND ;Start a rewind SEC ; say we're done BR 80$ ; and return with done. 5$: MOV #IBUF+1000,R3 ;Put fake directory entry here. MOV #IBUF,R4 ;Point to input buffer MOV R4,R0 ;Point to filename ADD #MT.FID,R0 ; MOV #CHARS,R1 ;Store the filename here MOV R1,R5 ;Save it. CMPB #377,@R0 ;Deleted file? BNE 15$ ;Branch if not 10$: CLR DE.LEN(R3) ;Length is zero MOV #DS.EMP,@R3 ;Empty file BR 45$ ;Go get positioned for next file 15$: MOV #DS.PRM,@R3 ;Make it a permanent entry MOV #13,R2 ;Blank file the filename area 20$: MOVB #BLANK,(R1)+ ; DEC R2 ; BNE 20$ ;Branch if not MOV #6,R2 ;Filenames are 6 characters long 25$: CMPB #DOT,@R0 ; or until the '.' is found BEQ 30$ ;Branch if found MOVB (R0)+,(R5)+ ;Move in the character DEC R2 ;Done? BNE 25$ ;Branch if not 30$: CMPB #DOT,@R0 ;Was the last character a '.'? BNE 35$ ;Branch if not TSTB (R0)+ ;Else get rid of it SUB #4,R1 ;Point R1 at the filetype area MOV #3,R2 ;Move 3 characters 35$: CMPB #DOT,@R0 ;Is it a dot? BEQ 40$ ;Branch if so. Done. MOVB (R0)+,(R1)+ ;Move in the character DEC R2 ;Done? BNE 35$ ;Branch if not 40$: MOV R4,R1 ;Point to the file sequence number ADD #MT.SEQ,R1 ; CLRB 4(R1) ;Mark the end CALL GETNUM ;Convert it to binary MOV R5,SBLOCK ;Save it BEQ 10$ ;If it's equal, it's an empty file. CALL GETNAM ;Convert the name to RAD50 45$: CALL FORWSP ;Space forward tapemark 50$: CALL FORWSP ;Space forward tapemark 55$: CALL READML ;Read a label (we hope) BCC 60$ ;Branch if no error CMP LKBLK,#EM.EOF ;End of file w/o EOT? BEQ 56$ ;Yep... CMP LKBLK,#EM.EFT ;End-of-file w/EOT BNE 55$ ;Nope... 56$: CLR DE.LEN(R3) ;We hit EOF without a label. Zero length BR 75$ ;Finish up 60$: CMP IBUF,#MT.HDR ;Did we get a header label? BNE 65$ ;Branch if not CALL BACKSP ;Else do 2 backspaces to tapemark CALL BACKSP ; followed by a space forward BR 50$ ; and a read ; to get to the EOF label 65$: CMP IBUF,#MT.EOF ;Did we get the EOF label? BNE 55$ ;Branch if not. Try reading another block BIT #DS.PRM,@R3 ;Is this file there? BEQ 70$ ;Branch if not MOV R4,R1 ;Point to record count ADD #MT.FSZ,R1 ; CLRB 6(R1) ;Mark the end of the field CALL GETNUM ;Go make it binary MOV R5,DE.LEN(R3) ;Save it 70$: CALL FORWSP ;Space forward tapemark CALL READML ;Read the next label for next time BCC 80$ ;Branch if no error BIT #DS.PRM,@R3 ;*C* Failed to get next-time's HDR1. Do we ;*C* have one to return THIS time? BEQ 75$ ;*C* if not, leave C-set and return. CLC ;*C* no error THIS time; catch EOF next call. 75$: MOV SP,EOSFLG ;*C* Else assume EOR or LEOT 80$: MOV (SP)+,R5 ;*C* Restore registers MOV (SP)+,R2 ;*C* RETURN .SBTTL READML - Read a magtape label ;+ ; READML ; Reads a magtape record and returns success if an error was due ; to short record ;- .ENABL LSB READML: CALL READMT ; Read tape record .BR CHCKSB ; Fall through... .SBTTL CHCKSB- Check for a 'short block' read ;+ ; CHCKSB ; This routine checks to see if a magtape read error was caused ; by the record containing less data than requested. If so, ; the Z bit is returned = 1 and the C-bit is clear. Otherwise, ; C is set and Z is zero. ;- CHCKSB:: TSTB @#$ERRBY ;Was it a hard error? BNE 10$ ;Then check for short read... CLZ ;EOF/EOT or BOT... BR 20$ 10$: CMP LKBLK,#EM.SML ; Was it a 'short block'? BEQ 30$ ; If EQ, C is clear too. 20$: SEC ; If NE, Set C to indicate error 30$: RETURN .SBTTL READMT- Read a magtape record ;+ ; READMT ; This routine is called to read magtape records. A .SPFUN is used ; so that the extra information can be obtained. ;- READMT::.SPFUN #AREA,#ICHAN,#SF.MRD,#IBUF,#LABSIZ,#LKBLK,#0 RETURN .SBTTL FORWSP/BACKSP/REWIND functions FORWSP: JSR R5,SPFUN1 ; Forwardspace Tapemark .WORD SF.MFS RETURN BACKSP: JSR R5,SPFUN1 ; Backspace Tapemark .WORD SF.MBS RETURN REWIND: JSR R5,SPFUN ; Rewind Tape .WORD SF.MRE RETURN .DSABL LSB .SBTTL NEXTCT- Get the next cassette filename ;+ ; NEXTCT ; This is the main routine for handling cassette directories. It ; is JMP'ed to from GETFIL. ; INPUTS: ; Cassette positioned before a file label. ; OUTPUTS: ; R3 -> a pseudo-directory entry at IBUF+1000 ; The ASCII filename stored at CHARS ; The file sequence number stored in the length position of the ; pseudo-directory entry. ;- NEXTCT:: MOV #IBUF+1000,R3 ;Use 2nd half of buffer for fake directory MOV #DS.PRM,@R3 ;Assume that a permanent entry is there MOV R2,-(SP) ;SAVE R2 MOV #IBUF,R4 ;Point to input buffer TST @#CTCSR ;Did we get an error on last operation? BPL 1$ ;Branch if not BIT #,@#CTCSR ;EOF or EOT? BNE 2$ ;Branch if not. Ignore it 1$: .READW #AREA,#ICHAN,R4,#CTHDSZ/2,#0 ;Read a header record TSTB IBUF ;Get anything? BEQ 2$ ;Branch if not. LEOT TST @#CTCSR ;Get an error? BPL 3$ ;Branch if not 2$: MOV #DS.EOS,@R3 ;Say end-of-segment found. CLR NXTDSG ;Say end-of-directory found. CALL REWIND SEC ;Say "That's all folks" BR 7$ ; and return 3$: MOV #CHARS,R1 ;Point to ASCII filname storage area MOV R4,R2 ;Point to the filename MOV #6,R0 ;Move 6 characters 4$: MOVB (R2)+,(R1)+ ; DEC R0 ;Decrement the character count BNE 4$ ;Branch if more MOVB #BLANK,(R1)+ ;Put in the blank MOVB (R2)+,(R1)+ ;Now move in 3 character filetype MOVB (R2)+,(R1)+ ; MOVB (R2)+,(R1)+ ; MOVB #BLANK,@R1 ; and another blank CMPB #'*,CHARS ;Is it a deleted file? BNE 5$ ;Branch if not MOV #DS.EMP,@R3 ;Say so 5$: CLR DE.LEN(R3) ;Clear out the length word BISB CT.SEQ(R4),DE.LEN(R3) ;Put sequence number in place of length CALL GETNAM ;We need the RAD50 of the filename 6$: JSR R5,SPFUN ;Do some strange CT manipulations .WORD SF.CLB ;Backspace a block JSR R5,SPFUN ; .WORD SF.CFF ; and then forward a file. CLC ;There's more to come... 7$: MOV (SP)+,R2 ;RESTORE RETURN .SBTTL PROCESS WILDCARD ROUTINE ;+ ; THIS ROUTINE PROCESSES WILD CARDS ;- $WCRD: BIC #FLG.QN,MFLAG ;NO "N" ON QUERY YET ;004 INC FLG1 ;FIX FLAG ;004 MOV #1,NXTDSG ;INITIALIZE POINTER MOV R2,-(SP) ;PUSH R2 MOV R4,-(SP) ;PUSH R4 MOV @R2,FLSP ;SET UP FOR NFS LOOKUP .LOOKUP #AREA,#ICHAN,#FLSP,#0 BCS 50$ ;IF CS ERROR MOV #ICHAN,R0 ;POINT TO CHANNEL JSR PC,REALDV ;GET PHYSICAL DEVICE NAME 5$: MOV RETSP,R0 ;GET DSTATUS BLOCK BMI 20$ ;IF MI RANDOM ACCESS CMPB #CTIDEN,R0 ;CASSETTE? BNE 15$ ;IF NE NO TST FLG1 ;FIRST TIME? BEQ 10$ ;IF EQ NO CLR FLG1 ;CLEAR IT CALL REWIND ;REWIND 10$: JSR PC,NEXTCT ;GO GET NEXT ENTRY BCS 40$ ;IF CS DONE BR 35$ ;MERGE 15$: CMPB #MTIDEN,R0 ;MAGTAPE? BEQ 25$ ;IF EQ YES CMPB #MSIDEN,R0 ;MAGTAPE? BEQ 25$ ;IF EQ YES CMPB #MMIDEN,R0 ;MAG TAPE BEQ 25$ ;IF EQ YES CMPB #MUIDEN,R0 ;MAG TAPE BEQ 25$ ;IF EQ YES 20$: JSR PC,NEXTDK ;GET NEXT ENTRY BCS 40$ ;IF CS DONE BR 35$ ;MERGE 25$: TST FLG1 ;FIRST TIME? BEQ 30$ ;IF EQ NO CLR FLG1 ;CLEAR FLAG CALL REWIND ;REWIND CALL READML ;GET VOL LABEL BCS 50$ ;IF CS ERROR CALL READML ;GET HEADER BCS 50$ ;IF CS ERROR CMP #MT.HDR,IBUF ;HEADER? BNE 50$ ;IF NO ILLEGAL DIRECTORY 30$: JSR PC,NEXTMT ;GET ENTRY BCS 40$ ;IF CS DONE 35$: JSR PC,MATCH1 ;MATCH? BR 5$ ;CONTINUE 40$: .CLOSE #ICHAN MOV (SP)+,R4 ;RESTORE R4 MOV (SP)+,R2 ;AND R2 TST FLAG ;ANY FOUND? BNE 45$ ;IF NE YES BIT #FLG.QN,MFLAG ;WAS "N" GIVEN ON QUERY ;004 BEQ 44$ ;NOPE, NONE ;004 DEC $$NUM ;NONE TO QUEUE FOR THIS WILDCARD ;004 BR 45$ ;BUT SOME DID MATCH ;004 44$: JMP $FNF ;ABORT ;004 ;004 45$: ADD #10,R2 ;UPDATE IT CLR FLG1 ;CLEAR FLAG CLR FLAG ;FIX FLAG RTS PC ;SPLIT ;+ ;ERROR 50$: .ERR #ERAR,#EM7,LEVEL=F,RETURN=NO,FILE=R2 ;- .SBTTL MAKE A NEW ENTRY ROUTINE ;+ ; THIS ROUTINE WILL CREATE A NEW SKELETON BLOCK ; THAT IS CONTIGUOUS WITH THE ONE -> BY SAV. ; ALL THE FOLLOWING BLOCKS ARE MOVED DOWN AND ; POINTERS ARE UPDATED ;- $NBLK: MOV R5,R0 ;GET POINTER SUB #16.,R0 ;POINT TO LAST ENTRY MOV R4,-(SP) ;SAVE REG MOV R1,-(SP) ;SAVE REG MOV R0,-(SP) ;SAVE REG MOV $$NUM,R1 ;GET #BLK ASL R1 ;CALCULATE 12.* $$NUM ADD $$NUM,R1 ;R1 = 3* $$NUM ASL R1 ;CALCULATE ASL R1 ;CALCULATE ASL R1 ;CALCULATE ADD R1,R0 ;ADD IT TO GET ADDRESS OF LAST POSSIBLE BLOCK ASR R1 ;NOW USE AS A LOOP COUNTER INC R1 ;R1=CORRECT COUNTER CMP R0,LIM+2 ;ENOUGH ROOM? BHIS 3$ ;IF HIS NO 2$: MOV @R0,12.(R0) ;MOVE THE BLK'S TST -(R0) ;POINT TO NEXT WORD SOB R1,2$ ;LOOP INC $$NUM ;FIX COUNTER MOV (SP)+,R0 ;RESTORE MOV (SP)+,R1 ;RESTORE MOV (SP)+,R4 ;RESTORE RTS PC ;RETURN 3$: .CLOSE #ICHAN ;CLOSE CHANNEL ;+ ;ERROR .ERR #ERAR,#EM8,LEVEL=E,RETURN=NO ;- .SBTTL RTOA- Convert 3 RAD50 words to ASCII ;+ ; RTOA ; This routine converts 3 RAD50 words to ASCII. It assumes that the 3 ; words to convert is a filename block, and inserts blanks accordingly. ; INPUTS: ; R0 -> 3 word block ; R1 -> 11 byte block to store the ASCII ; OUTPUTS: ; R1 updated past the end of the ASCII ;- RTOA:: MOV R0,-(SP) ;Save R0 MOV R2,-(SP) ; and R2 MOV R0,R2 ;Point to the RAD50 to convert MOV (R2)+,R0 ;Get the first word CALL $R50ASC ;Convert it ;CG09 MOV (R2)+,R0 ;Get next word CALL $R50ASC ; and convert it ;CG09 MOVB #BLANK,(R1)+ ;Move in a blank MOV @R2,R0 ;Get the next word CALL $R50ASC ;Convert it ;CG09 MOVB #BLANK,(R1)+ ;Store the final blank MOV (SP)+,R2 ;Restore the registers MOV (SP)+,R0 ; RETURN .SBTTL GETNAM- Convert filename to RAD50 ;+ ; GETNAM ; This routine converts the ASCII stored at CHARS to 3 words of RAD50. ; Called from the magtape and cassette routines to produce pseudo- ; directory entries. ; INPUTS: ; R3 -> to a pseudo-directory entry ; OUTPUTS: ; R0 is modified ; RAD50 is stored in the filename/filetype locations of the ; pseudo-entry. ;- GETNAM:: MOV R1,-(SP) ;Save R1 ;CG09+ MOV #CHARS,R1 ;R1 -> ASCII CALL $ASCR50 ;Convert it to RAD50 MOV R0,DE.FN1(R3) ;Store it CALL $ASCR50 ;Convert the next 3 characters MOV R0,DE.FN2(R3) ; and store the RAD50 TSTB (R1)+ ;Skip the blank CALL $ASCR50 ;Convert the filetype MOV R0,DE.TYP(R3) ;Save it MOV (SP)+,R1 ;Restore R1 ;CG09- RETURN .SBTTL GETNUM - Convert ASCII to binary, decimal GETNUM:: MOV R3,-(SP) CLR R3 1$: MOVB (R1)+,R0 SUB #'0,R0 BMI 10$ CMP #9.,R0 BLO 10$ ASL R3 MOV R3,-(SP) ASL R3 ASL R3 ADD (SP)+,R3 ADD R0,R3 BR 1$ 10$: MOV (SP)+,R3 RETURN .SBTTL SPFUN and SPFUN1- Issue .SPFUN request ;+ ; SPFUN, SPFUN1 ; SPFUN is used to issue .SPFUN's to the cassette handler, and to do ; single block spacing on magtapes. ; SPFUN1 is used to space to tapemarks on magtapes. ; Both assume that a magtape or cassette is open on channel ICHAN. ; ; CALL: ; JSR R5,SPFUN(1) ; .WORD code ;code is the .SPFUN code to execute ; ; OUTPUTS: ; R0 is modified. ;- .ENABL LSB SPFUN1:: MOV #-1,-(SP) ;Space to tapemark entry BR 1$ ; SPFUN:: CLR -(SP) ;Cassette or single MT block spacing entry 1$: ; MOV #AREA,R0 ;Point to the EMT area block ; MOV #32*400+ICHAN,@R0 ;Move in function and channel ; MOV #LKBLK,2(R0) ;Error reporting block for magtapes ; MOV (SP)+,6(R0) ;Word count ; CLR 12(R0) ;CLEAR COMPLETION ARG FOR CT: ; MOV (R5)+,10(R0) ;.SPFUN code ; EMT 375 ;Execute it NOP .SPFUN #AREA,#ICHAN,@R5,,@SP,#LKBLK,#0 BIT (SP)+,(R5)+ ; *C* give up passed arguments RTS R5 ;And return to caller. .DSABL LSB .SBTTL $SAVRG- Save and restore registers 2-5 ;+ ; $SAVRG ; This routine saves and restores registers 2-5 ; CALL: ; JSR R5,$SAVRG ;- $SAVRG:: MOV R4,-(SP) ;Save register 4 MOV R3,-(SP) ; 3 MOV R2,-(SP) ; 2 MOV R5,-(SP) ;Save the return address MOV 10(SP),R5 ;Restore R5 JSR PC,@(SP)+ ;Co-routine return MOV (SP)+,R2 ;Restore the registers MOV (SP)+,R3 ; MOV (SP)+,R4 ; MOV (SP)+,R5 ; RETURN .SBTTL ;+ ; THIS ROUTINE CHECKS A LINE OF INPUT FOR OCTAL CHARACTERS, AND THEN ; ASSEMBLES THE ASCII CHARACTERS INTO A ONE WORD OCTAL NUMBER. ; ; INPUTS: ; R1 -> POINTS TO NEXT CHARACTER IN GTLIN BUFFER ; R4 -> POINTS TO STORAGE WORD FOR OCTAL NUMBER ; ; OUTPUTS: ; R4 -> NEXT WORD FOR /Q SWITCH STORAGE ; R1 -> POINTER TO NEXT OR LAST CHAR IN GTLIN BUFFER ; R0,R2 -> RANDOM ;- ASCOCT: CLR @R4 ;CLEAR STORAGE WORD MOVB (R1)+,R0 ;SOMETHING MUST ALWAYS BE ENTERED FOR ADDRESS BNE 3$ ;IF THE FIRST CHAR IS NOT A ZERO -> OK 1$: BR 4$ ;REDO THIS LINE 2$: MOVB (R1)+,R0 ;GET NEXT CHARACTER FROM INPUT LINE BEQ 4$ ;0 -> DONE 3$: CMPB R0,#'0 ;IS THE CHARACTER > OR = 0? BLO 5$ ;LO -> NO, NOT VALID CHAR CMPB R0,#'7 ;IS IT LESS THAN 8? BHI 5$ ;HI -> NO, NOT VALID CHAR BICB #370,R0 ;CLEAR ASCII BITS LEAVING OCTAL NUMBER ASL @R4 ;ROTATE STORAGE WORD ASL @R4 ;TO LET IT RECEIVE THE ASL @R4 ;NEXT DIGIT ADD R0,@R4 ;ADD IN NEW DIGIT BR 2$ ;LOOP UNTILL INVALID CHAR, OR END OF LINE 4$: RTS PC ;RETURN ;+ ;ERROR 5$: .ERR #ERAR,#EM2,LEVEL=E,RETURN=NO ;- .SBTTL BINARY TO DECIMAL ASCII ROUTINE ;+ ; THIS ROUTINE WILL TAKE THE # OF COPIES IN BINARY ; FROM R3 AND CONVERT IT TO ASCII DECIMAL IN (R1)+. ;- CVT10: MOV R3,-(SP) ;CONVERT # IN R3 TO ASCII IN (R1)+ CLR R3 ;SAVE THEN CLEAR R3 1$: INC R3 ;CONVERT... SUB #10.,@SP BGE 1$ ADD #72,@SP DEC R3 BEQ 2$ CALL CVT10 2$: MOVB (SP)+,(R1)+ RTS PC ;003 .SBTTL REALDV - Get physical device name ;+ ; R0 = channel ; R2 -> dev name ; CALL REALDV ; R0 is clobbered ;- .ENABL LSB REALDV: MOV R1,-(SP) MOV R0,R1 ; Move the channel to R1 .CSTAT #AREA,R1,#CSDATA ; Get info about channel BCS 10$ ; branch if error MOV #CSDATA,R0 ; R0 -> CSDATA MOV CS.UNT(R0),R1 ; get CSTAT's unit no., MOV CS.NAM(R0),R0 ; get CSTAT's device name, CALL $DEVTR ; translate to phys name MOV R0,@R2 ; put 'er there. 10$: MOV (SP)+,R1 RETURN ...... .DSABL LSB ;003 .SBTTL SD- /I,/C ;006 ;+ ;003 ; SD ;003 ; This routine handles user specified dates for /I and /C. ;006 ; It no longer quits working 1-Jan-2000! ;016 ; NOTE: ;003 ; This routine is called by GETDAT. It must not modify R2. ;003 ;- ;003 ;003 DAYFLG =100000 ;Flags to indicate set fields ;016 MONFLG =40000 ;016 YEAFLG =20000 ;016 SD:: MOV R2,-(SP) ;Save R2 MOV R4,-(SP) ;Save R4 ;016 MOV R5,R3 ;PUT SWITCH WORD IN R3 ;003 MOV #UDATE,R2 ;Point to /DATE storage area MOV #UDATSB,R4 ;Point to /DATE set bits ;016 CMPB #'C,R3 ;Doing /DATE? BEQ 1$ ;Branch if so MOV #BDATE,R2 ;Point to /BEFORE storage area MOV #BDATSB,R4 ;Point to the /BEFORE set bits ;016 CMPB #'J,R3 ;Doing /BEFORE? BEQ 1$ ;Branch if so MOV #SDATE,R2 ;Must be /SINCE MOV #SDATSB,R4 ;Point to the /SINCE set bits ;016 1$: TST R3 ;Was a value given? ;003 BGE 7$ ;Branch if not. We're through. ;003 TST R0 ;Check the value for validity ;003 BLE 510$ ;No good. Error. ;003 CMP #31.,R0 ;Is it a day? ;003 BLT 2$ ;Branch if not ;003 BIT #DAYFLG,(R4) ;Have we already set the day? ;016 BNE 510$ ; if so, operator error ;016 MOV R0,4(R2) ;Else save it in DAY BIS #DAYFLG,(R4) ;Mark that we've set the day ;016 BR 7$ ; and return to caller ;003 ;003 2$: CMP #2099.,R0 ;Is it too big for a 4-digit year? ;015 BLT 4$ ;Branch if so ;015 CMP #1972.,R0 ;Is it big enough for a 4-digit year? ;015 BLE 3$ ;Yes, go to 4-digit year code ;015 CMP #99.,R0 ;Is it too big for a 2-digit year? ;015 BLT 4$ ;Branch if so ;015 CMP #72.,R0 ;Is it big enough for a 2-digit year? ;015 BLT 310$ ;Yes, branch to 2-digit year code ;015 BR 510$ ; Otherwise operator error ;016 3$: SUB #1900.,R0 ;Bring year into range 72.-199. ;015 310$: BIT #YEAFLG,(R4) ;Have we already set the year? ;016 BNE 510$ ; if so, operator error ;016 MOV R0,(R2) ;Save it in YEAR ;015 BIS #YEAFLG,(R4) ;And mark that we've set it ;016 BR 7$ ;Return ;003 ;003 4$: MOV #MONTHS+2,R3 ;Point to RAD50 month names. ;003 CLR R1 ;Initialize counter. ;003 5$: INC R1 ;Bump counter ;003 CMP (R3)+,R0 ;Is this one it? ;003 BEQ 6$ ;Branch if so ;003 TST @R3 ;Anything left? ;003 BNE 5$ ;Branch if so ;003 510$: ;+ ;ERROR .ERR #ERAR,#EM2,LEVEL=E,RETURN=NO ;003 ;- ;003 6$: BIT #MONFLG,(R4) ;Have we already set this month? ;016 BNE 510$ ;If so, operator error ;016 MOV R1,2(R2) ;Save it in MONTH BIS #MONFLG,(R4) ;And mark that we've set the month ;016 7$: MOV (SP)+,R4 ;Restore R4 ;016 MOV (SP)+,R2 ;Restore R2 RETURN ;003 ;003 .SBTTL CONDAT ;003 ;003 ;+ ;003 ; CONDAT ;003 ; This routine converts the RT-11 format date into something usable. ;003 ; INPUTS: ;003 ; R0 contains the RT-11 format date ;003 ; OUTPUTS: ;003 ; The current day, month, and year stored in TDAY, TMON, and ;003 ; TYEAR. ;003 ; R0 is modified ;003 ;- ;003 ;003 ;003 CONDAT:: ;003 MOV R1,-(SP) ;Save R1 ;003 MOV R2,-(SP) ; and R2 ;003 MOV R0,R1 ;Get the date ;003 BIC #177740,R1 ;Clear all but the year ;003 MOV R0,R2 ;Get the Epoch ASR R2 ;Push it around SWAB R2 ; until we have BIC #^c140,R2 ; epoch*32 ADD R2,R1 ;Add it to the year ADD #72.,R1 ;RT-11 years are -72 ;003 MOV R1,TYEAR ;Save the year ;003 MOV #32.,R2 ;Divide by 32 ;003 CALL DDIV ;This will put the day in the low 5 bits;003 MOV R0,TDAY ;Store it ;003 BIC #177740,TDAY ;Get rid of all but the day ;003 CALL DDIV ;Now get the month ;003 BIC #177760,R0 ; and get rid of the epoch bits MOV R0,TMON ; and save it ;003 MOV (SP)+,R2 ;Restore the registers ;003 MOV (SP)+,R1 ; ;003 RETURN ;003 ;003 ;003 .SBTTL DDIV- Single precision divide ;003 ;003 ;+ ;003 ; DDIV ;003 ; INPUTS: ;003 ; R0 = dividend ;003 ; R2 = divisor ;003 ; OUTPUTS: ;003 ; R0 = quotient ;003 ; R1 = remainder ;003 ; R2 is unchanged ;003 ;- ;003 ;003 DDIV:: ;003 MOV #16.,-(SP) ;Push the shift count ;003 CLR R1 ;Clear out the remainder ;003 1$: ASL R0 ;Double precision shift ;003 ROL R1 ; ;003 CMP R2,R1 ;Will the divisor fit? ;003 BHI 2$ ;Branch if not ;003 SUB R2,R1 ; ;003 INC R0 ; ;003 2$: DEC @SP ;Done? ;003 BGT 1$ ;Branch if not ;003 TST (SP)+ ;Clean the stack ;003 RETURN ;003 ;003 .SBTTL QUERY - Confirm an operation or print log ;004 ;+ ;004 ; QUERY ;004 ; This procedure does the query for copy commands or prints the log. ;004 ; R3 -> Directory entry ;004 ; R2 -> Physical device name ;004 ; ;004 ; CALL QUERY ;004 ; ;004 ; R0 = 1 if /QUERY was not specified or if user typed "Y*", or /LOG ;004 ; R0 = 0 in all other cases ;004 ; ;004 ;- ;004 ;004 QUERY:: ;004 MOV R1,-(SP) ;Save R1 ;004 BIT #,MFLAG ;/QUERY or /LOG specifed? ;004 BEQ 9$ ;Branch if not ;004 MOV #PROMPT,R1 ;R1 -> Buffer for prompt ;004 BIT #FLG.LG,MFLAG ;Doing /LOG? BEQ 15$ ;Branch if not MOV #LOGPR,R1 ;R1 -> Buffer for log 15$: MOV R1,-(SP) ;Save buffer pointer MOV #RADF,R0 ;R0 -> Buffer for RAD50 filenm ;004 MOV @R2,(R0)+ ;Fill in device ;004 MOV 2(R3),(R0)+ ; and filename ;004 MOV 4(R3),(R0)+ ; and rest of filename ;004 MOV 6(R3),(R0) ; and filetype ;004 MOV #RADF,R0 ;R0 -> Buffer for RAD50 filenm ;004 CALL $FNASC ;Convert filename to ASCII ;004 16$: CMPB #' ,(R1) ;Are we at the space? BEQ 2$ ;Branch if so MOVB #' ,(R1)+ ;Move in a space BR 16$ ;Check next char 2$: MOV (SP)+,R1 ;Restore buffer pointer .PRINT R1 ;Print the prompt ;004 BIT #FLG.LG,MFLAG ;/LOG? ;004 BNE 9$ ;Yes; don't do prompt ;004 .TTYIN ;Get a character ;004 MOV R0,-(SP) ;Save it ;004 1$: .TTYIN ;Get the rest ;004 CMPB #12,R0 ;Is it a LF? ;004 BNE 1$ ;Branch if not. ;004 CMPB #'Y,(SP)+ ;Is the first char a "Y"? ;004 BEQ 9$ ;Branch if it is a Y ;004 CLR R0 ;No match ;004 BIS #FLG.QN,MFLAG ;NO MATCH, BUT FILE FOUND ;004 BR 10$ ;004 9$: MOV #1,R0 ;Indicate a match ;004 10$: MOV (SP)+,R1 ;Restore R1 ;004 RETURN ;004 ;004 .SBTTL PATCH AREA ;004 .PSECT $PAT PAT1: MOV SP,SVSP ;002 MOV @#SYSPTR,R0 ;002 RTS PC ;002 .BLKW <64.-5.> ;PATCH SPACE ;002 .END START