.PSECT DOC .TITLE DOC - DOCUMENTATION UTILITY .IDENT /790607/ ; ; NOTE: IF .IDENT IS CHANGED THEN THE CORESPONDING CHANGE SHOULD ; BE MADE TO THE CONTENTS OF THE STRING "LETI". ; ; THIS CODE HAS BEEN DEVELOPED BY THE COMPUTING ; GROUP OF THE ATMOSPHERIC SCIENCES DIVISION, ; ALBERTA RESEARCH. THIS WORK FUNDED BY THE ; ALBERTA WEATHER MODIFICATION BOARD. ; ; THERE IS EXPLICITLY NO COPYRIGHT ON THIS SOFTWARE, ; AND ITS DISTRIBUTION IS ENCOURAGED. NO RESPONSIBILITY ; NOR GUARANTEE IS MADE OR ASSUMED BY THE AUTHOR, OR ; BY ALBERTA RESEARCH. ; ; SUGGESTIONS OR CHANGES ARE INVITED, AND WILL BE ; DISTRIBUTED TO OTHER USERS OF THIS SOFTWARE THROUGH ; THE DECUS IAS/RSX SPECIAL INTEREST GROUP. ; ; ; VERSION: 790207 (WK05.00) ; WRITTEN BY: W. KORENDYK ; DATE WRITTEN: 20-FEB-79 ; ; RELATED DOCUMENTATION: ; ; ; ROUTINES USED: ; ; ; MODIFICATIONS: ; ; CODE NAME DATE ; ; GW001 G. WARNKE 01-MAY-79 ; ADDED THE STRING SUBSTITUTION AND DEFINITION ROUTINES. THESE ROUTINES ; ALLOW THE USER OF DOC TO DEFINE STRING VARIABLES AND SUBSTITUTE THESE ; VARIABLES IN THE OUTPUT RECORDS. ALSO ADDED WAS AN INITIALIZATION ROUTINE ; WHICH INITIALIZE CERTAIN STRING VARIABLES WITH USEFUL INFORMATION SUCH ; AS THE TIME, DATE, WEEKDAY, ETC. ; ; GW002 G. WARNKE 06-JUN-79 ; MODIFIED THE LOCATE LABEL ROUTINE SO THAT IT CHECKS THE LABEL ; SIZE WHEN ATTEMPTING TO FIND A LABEL. BEFORE THIS MODIFICATION, ; ANY LABEL THAT HAD THE SAME STARTING CHARACTERS AS THE LABEL BEING ; SEARCHED FOR, WOULD BE CONSIDERED TO BE THE LABEL BEING SEARCHED ; FOR. FOR EXAMPLE, A SEARCH FOR THE LABEL "LABEL" WOULD RESULT IN ; A MATCH FOR ANY OF "LABEL1", "LABEL2", "LABELEND", ETC. ; NOW NONE OF THE ABOVE WOULD BE CONSIDERED AS A MATCH. ; ; GW003 G. WARNKE 07-JUN-79 ; MODIFIED STRING DEFINITION ROUTINE TO ZERO THE STRING VARIABLE ; IF NO DEFINITION FOR THE STRING IS SPECIFIED IN THE COMMAND STRING. ; EXAMPLE: "$D T" WOULD CAUSE THE STRING VARIABLE "T" TO BE ZEROED. ; ;+ ; ; DOC -- PROGRAM TO ALLOW FOR THE QUICK AND EASY ; PRODUCTION OF STANDARD DOCUMENTATION. THIS ; PROGRAM TAKES CONTROL INPUT FROM A SPECIFIED ; INPUT FILE AND GENERATES RUNOFF SOURCE FILES. ; IF THE FILE TO BE USED IS NOT SPECIFIED, IT ; USES A STANDARD DEFAULT FILE. ; ; AUTHOR: W. KORENDYK ; WRITTEN: NOVEMBER 22, 1977 (V 4.00) ; LAST MOD: JANUARY 16, 1978 (V 4.01) ; FEBRUARY 7, 1979 ; ; VERSION: 05.00 (790207) ; ;- .ENABLE LC .MCALL ENTER,LEAVE,TINIT,TTYOUT,PSTR .MCALL FCSMC$,QIOW$,EXCHS,EXIT$S,GTIM$S .MCALL CSI$,CSI$1,CSI$2,GMCR$ .MCALL CSI1G,CSI2 .MCALL GCML,RCML$,GCMLB$ .MCALL .CALLV FCSMC$ ; .SBTTL >I. ERROR CONTROL ; ; ERROR SUPPORT ADDRESSES ; ERRPFX::PSTR ^*/DOC -- /* ;COME HERE IF AN RETURN ;ERROR IS ENCOUNTERED ; DIE:: CLOSE$ #OUTFDB ;TRY CLOSING OUT FILE MOV CURFDB,R1 ;ATTEMPT TO CLOSE 1$: CLOSE$ @R1 ;ALL THE INPUT FILES TST -(R1) ;POINT TO PREVIOUS CMP #FDBS,R1 ;IF THERE IS ONE, BLOS 1$ ;AND THERE IS ; RSTART: MOV SPSAVE,SP ;RESTORE THE STACK POINTER MOV #FDBS,CURFDB ;RESET FDB QUEUE, MOV #BASE,POINT ; THE MARK LIFO, RCML$ #GCBLK ; BR START2 ;NOW START AGAIN ; TERMIN: EXIT$S ;AND STOP ON AN EOF ; SPSAVE: .WORD 0 ;SAVE SP HERE .SBTTL >II. MAIN LINE CODE START: TINIT TILUN,TTYEVF ;INIT FOR TERMINAL I/O FINIT$ ;AND FOR FILE I/O ; START2: MOV SP,SPSAVE ;SAVE SP FOR ERROR RESTART CALL INILVB ;INITIALIZE LOGICAL VARIABLES CALL INISTR ;INITIALIZE STRING BUFFERS GCML #GCBLK,,,TERMIN,GCERR ;GET THE COMMAND LINE CSI1G #CSBLK,GCBLK,CS1ERR ;AND PARSE IT CSI2 #CSBLK,OUTPUT,,CS2ERR ;GET OUTPUT NAME BITB #CS.NMF,C.STAT(R0) ;IS ONE GIVEN? BNE 4$ ;YES TST C.CMLD(R0) ;WAS THERE A COMMAND LINE??? BEQ RSTART ;IF EQ NO SO REPROMPT CALL ERRPFX ;OUTPUT THE ERROR PSTR ^*/OUTPUT FILE SPECIFICATION ERROR/* JMP DIE 4$: MOV #OUDSDS,R5 ;WHERE TO PUT DSDS CALL SAVEDS ;AND PUT IT THERE ; BITB #CS.EQU,C.STAT(R0) ;IS THERE AN '='? BEQ 1$ ;IF EQ THEN NO ; CSI2 #CSBLK,INPUT,,CS2ERR ;PARSE INPUT NAME BITB #CS.NMF,C.STAT(R0) ;IS THERE A NAME? BEQ 1$ ;IF EQ THEN NO FDOP$R @CURFDB,,#CSBLK+C.DSDS 1$: OPEN$R @CURFDB,,,,,,IOERR ;OPEN INPUT FILE OPEN$W #OUTFDB,,,,,,IOERR ;OPEN OUTPUT FILE ; CALL GOTOIT ;GO TO IT ; DONE: CLOSE$ @CURFDB,IOERR ;CLOSE IN-FILE CLOSE$ #OUTFDB,IOERR ;CLOSE OUT-FILE JMP RSTART ;AND RESTART ; ;+ ; SAVEDS - ROUTINE TO SAVE THE DSDS AS PARSED INTO ; THE CSI CONTROL BLOCK. ; ; INPUTS: R5 => WHERE TO SAVE DSDS ; ;- SAVEDS: ENTER R0,R1,R5 ;SAVE REGISTERS MOV #CSBLK+C.DSDS,R0 ; ADDRESS OF DSDS MOV #6,R1 ;LOOP COUNTER 1$: MOV (R0),(R5)+ ;MOVE IT IN CLR (R0)+ ;CLEARING OUT CSBLK SOB R1,1$ LEAVE ;LEAVE RETURN ;RETURN .SBTTL >III. PROCESS THE INPUT STREAM ;+ ; ; GOTOIT -- ROUTINE WHICH ACTUALLY ACCOMPLISHES ; THE READING AND WRITING FROM FILE TO FILE ; BY READING IN A RECORD FROM THE CURRENT INPUT ; FILE, PROCESSING IT, AND WRITING IT OUT TO THE ; OUTPUT FILE. ; ;- GOTOIT: MOV POINT,-(SP) ;;;;;;;;;;;;;;;;;;;;;;;;;; 1$: CALL RDRECD ; READ A RECORD FROM IN FILE BCS 10$ ; IF CS, THEN EOF READ CALL PROREC ; PROCESS THE RECORD BCS 10$ ; IF CS, THEN STOP PROCESSING FILE BR 1$ ; GO TO IT SOME MORE 10$: MOV (SP)+,POINT ; RESTORE POINTER INTO MARK FILE STACK RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; .SBTTL > A. READ AN INPUT RECORD ;+ ; ; RDRECD -- ROUTINE TO READ IN A RECORD OF THE INPUT FILE ; INTO THE COMMON "CURRENT LINE" RECORD BUFFER. ; ; OUTPUTS: R1 = ADDRESS OF THE RECORD BUFFER ; R2 = LENGTH OF THE RECORD READ ; C-BIT SET IFF EOF READ ; ;- RDRECD: ENTER R0 ;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV #BUF1,R1 ;THIS IS WHERE WE GET$ @CURFDB,R1 ;GET A RECORD BCC 10$ ;ALL IS COOL CMPB #IE.EOF,F.ERR(R0) ;AN EOF? BEQ 15$ ;WE'RE DONE CALL IOERR ;SOMETHING ELSE 10$: MOV F.NRBD(R0),R2 ;GET RECORD SIZE BR 20$ 15$: SEC ;INDICATE EOF 20$: LEAVE ; RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;; .SBTTL > B. PROCESS THE INPUTTED RECORD ;+ ; ; PROREC -- ROUTINE TO PROCESS THE RECORD FROM THE ; INPUT STREAM. ; ; INPUTS: R1 = ADDRESS OF THE RECORD ; R2 = LENGTH OF THE RECORD ; PROREC: ENTER R0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CMPB #COMCHR,(R1) ; IS THIS A COMMAND RECORD? BEQ 10$ ; IF EQ, THEN YES IT IS CMPB #'@,(R1) ; (INDIRECT FILE? BEQ 12$ ; IF EQ, THEN YES) CALL OUTPUT ; NO, OUTPUT IT AS IS BR 30$ ; AND LEAVE ;;;;;;;;;;;;;; 10$: CLC ; INC R1 ; SKIP OVER THE CONTROL CHARACTER DEC R2 ; (ONE LESS IN BUFFER) BLE 30$ ; THERE IS NO MORE 12$: MOV #CONTAB,R0 ;CONTROL CHARACTER TABLE 11$: CMPB (R0)+,(R1) ;A RECOGNIZED COMMAND? BEQ 20$ ;YES IT IS TSTB (R0) ;WAS THAT THE LAST CON. CHAR? BEQ 30$ ;YES, SO TREAT AS A COMMENT LINE BR 11$ ;NO, SO TRY THE NEXT ONE. ; 20$: SUB #CONTAB,R0 ;GET DISPLACEMENT IN TABLE DEC R0 ;IN ZERO OFFSET ASL R0 ;AS A WORD COUNT CALL @DISTAB(R0) ;DISPATCH TO ROUTINE. ; 30$: LEAVE ;THAT'S ALL FOLKS RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .SBTTL > C. OUTPUT A RECORD ;+ ; ; OUTPUT -- ROUTINE TO OUTPUT A RECORD TO THE OUTPUT FILE. ; ; INPUTS: R1 = ADDRESS OF THE RECORD TO OUTPUT ; R2 = LENGTH OF THE RECORD ; ; OUTPUTS: R0 IS CORRUPTED ; ;- OUTPUT: PUT$ #OUTFDB,R1,R2,IOERR RETURN .SBTTL >IV. CONTROL CHARACTER .SBTTL > A. CHARATER RECOGNITION TABLE ; ; CONTROL CHARACTER RECOGNITION TABLE ; CONTAB: .BYTE 'M,'m ;MARK FILE POSITION .BYTE 'T,'t ;RESUME WITH TERMINAL INPUT .BYTE '@,'@ ;INDIRECT FILE ACCESS .BYTE 'P,'p ;TERMINAL OUTPUT (PROMPT) .BYTE 'Q,'q ;LOGICAL INPUT (QUERY) .BYTE 'I,'i ;CONDITIONAL EXECUTION .BYTE 'G,'g ;GOTO STATEMENT .BYTE 'S,'s ;STRING SUBSTITUTION .BYTE 'D,'d ;STRING DEFINITION .BYTE 'L,'l ;LABEL .BYTE 'C,'c ;COMMENT .BYTE 0 ;TABLE TERMINATION .EVEN .SBTTL > B. DISPATCH TABLE ; ; CONTROL CHARACTER DISPATCH TABLE ; DISTAB: .WORD MARK1,MARK1 ;MARK FILE POSITION .WORD INTI,INTI ;RESUME WITH TERMINAL INPUT .WORD INDIR,INDIR ;INDIRECT FILE ACCESS .WORD PROMPT,PROMPT ;TERMINAL OUTPUT .WORD QUERY,QUERY ;LOGICAL INPUT .WORD CONDIT,CONDIT ;CONDITIONAL EXECUTION .WORD GOTO,GOTO ;GOTO LABEL .WORD SSUBS1,SSUBS1 ;STRING SUBSTITUTIONS .WORD SDEFN,SDEFN ;STRING DEFINITIONS .WORD LABEL,LABEL ;LABEL RECORD .WORD COMMNT,COMMNT ;COMMENT RECORD .WORD 0 ;TABLE TERMINATION .SBTTL >V. CONTROL FUNCTIONS ;+ ; ; ALL CONTROL FUNCTIONS ARE SELF CONTAINED AND OPERATE ON THE ; CURRENT RECORD (AS POINTED TO BY R1). THEY MUST CONFORM TO: ; ; INPUTS: R1 = ADDRESS OF THE RECORD ; R2 = LENGTH OF THE RECORD ; ; OUTPUTS: C-BIT SET IFF IT IS NO LONGER SAFE ; TO PROCESS THE CURRENT INPUT FILE. ; ; EACH ROUTINE IS RESPONSIBLE FOR THE ISSUANCE OF ITS OWN ; WARNING AND ERROR MESSAGES. ; ;- .SBTTL > A. REMEMBER FILE POSITIONS .SBTTL > 1. MARK CURRENT POSITION ;+ ; ; MARK1 -- ROUTINE TO MARK THE CURRENT POSITION OF ; THE OUTPUT FILE. ; ;- MARK1: MOV R0,-(SP) ;SAVE REGISTER MOV #OUTFDB,R0 ;GET OUT PUT FILE FDB ADDRESS CALL MARK ;MARK THE OUTPUT FILE MOV (SP)+,R0 ;RESTORE THE REGISTER RETURN ;AND GO HOME ;+ ; MARK -- ROUTINE TO MARK THE CURRNT POSITION, AND ; REMEMBER IT FOR LATER REFERENCE. ; ; INPUT: R0 = FDB OF FILE TO MARK ; ;- MARK: ENTER R1,R2,R3,R5 MOV POINT,R5 ;THE "STACK" POINTER CMP #BOT,R5 ;STILL IN "STACK" BLOS 10$ ;NO, ERROR 4$: CALL .MARK ;OBTAIN THE POSITION, BCC 5$ ;WORKED GREAT CALL IOERR ;NOT SO GREAT 5$: MOV R1,(R5)+ ;AND STACK THEM. MOV R2,(R5)+ ; MOV R3,(R5)+ ; MOV R5,POINT ;AND REMEMBER POINTER 6$: CLC ;INDICATE EVERYTHING O.K. LEAVE RETURN ; 10$: CALL ERRPFX PSTR ^#/*** WARNING ***/# PSTR ^#/MAX LEVEL OF MARK EMBEDDING REACHED/# PSTR ^#/OLDEST MARK DELETED/# MOV #BASE,R5 ;NOW DELETE OLDEST MARK MOV #LEV-1*3,R1 ;START TRANSFER 11$: MOV 6(R5),(R5)+ SOB R1,11$ BR 4$ ;NOW MARK THE FILE ; .SBTTL > 2. UNMARK AND REWIND OUTPUT ; ;+ ; UNMARK -- ROUTINE TO REWIND FILE TO THE LAST MARK. ; ; INPUT: R0 = FDB OF FILE TO UNMARK ; ; ;- .MCALL OFNB$U UNMARK: ENTER R1,R2,R3,R5 MOV POINT,R5 ;GET "STACK POINTER CMP #BASE,R5 ;CHECK BOUNDS BHIS 10$ ;NO PLACE TO REWIND TO MOV -(R5),R3 MOV -(R5),R2 MOV -(R5),R1 MOV R5,POINT ;NEW POINTER ; CLOSE$ ,IOERR ; OFNB$U ,,,,,,IOERR CALL .POINT ;POSITION IN FILE BCC 10$ ;WORKED GREAT CMPB #IE.EOF,F.ERR(R0) ;IF UNMARK DOESN'T MOVE BEQ 10$ ;POINTER THEN EOF RETURNED ;SO IGNORE IT CALL IOERR ;NOT SO GREAT 10$: LEAVE RETURN ; .SBTTL > 3. REMOVE LAST MARKED POSITION ;+ ; CLEAR -- ROUTINE TO REMOVE THE LAST MARKED POSITION ; ;- CLEAR: CMP #BASE,POINT ;AT BASE? BHIS 1$ ;YEH, NOTHING TO DO SUB #6,POINT ;REMOVE MARK 1$: RETURN ; ; .SBTTL > 4. MARKING STACK ; ;+ ; STORAGE FOR FILE MARKING ; ; NOTE THAT NESTING LEVEL IS SET AT 8. ; ;- LEV =10 POINT: .WORD BASE BASE: .BLKW LEV*3 BOT: .WORD 0 .SBTTL > B. BEGIN READING FROM TERMINAL ;+ ; INTI -- ROUTINE TO READ IN FROM THE TEMINAL. ; INPUT TERMINATES AND RESORTS BACK TO ; THE CALLER ON RECEIPT OF A EOF. ; ; INPUTS: R1 = CURRENT RECORD BUFFER ADDRESS ; R2 = CURRENT RECORD BUFFER SIZE ; ; OUTPUTS: SAME ; ;- INTI: ENTER R1,R2 CALL TRMINP ;READ A LINE FROM THE TERMINAL CMPB #IS.SUC,(R2) ;WAS IT GOOD???? BEQ 2$ ;IF EQ YES CMPB #IE.EOF,(R2) ;AN EOF? BEQ 10$ ;YES CALL IOERR ;SOMETHING ELSE 1$: CALL TRMINP ;READ A RECORD CMPB #IS.SUC,(R2) ;SUCCESSFUL??? BEQ 2$ ;IF EQ YES CMPB #IE.EOF,(R2) ;AN EOF? BEQ 20$ ;YES CALL IOERR ;NO, SOMETHING ELSE 2$: MOV 2(R2),R2 ;GET THE RECORD SIZE CALL OUTPUT ;OUTPUT RECORD IN HAND BR 1$ ;AND GET MORE ; 10$: MOV 2(R2),R2 ;ANYTHING READ??? BNE 25$ ;YES, SO PUT IT OUT MOV #OUTFDB,R0 CALL UNMARK ;UNMARK THE OUTPUT BR 30$ ;AND LEAVE ; 20$: MOV 2(R2),R2 ;ANYTHING READ??? BEQ 27$ ;NO, SO IGNORE RECORD 25$: CALL OUTPUT ;PUT OUT THE RECORD 27$: CALL CLEAR ;CLEAR THE LAST MARK 30$: LEAVE ; RETURN ; .SBTTL > 1. READ ONE RECORD ;+ ; ; TRMINP -- ROUTINE TO READ ONE RECORD FROM TI: ; ; INPUTS: NONE ; ; OUTPUTS: R1 = TERMINAL RECORD BUFFER ADRESS ; R2 = IO STATUS BLOCK ADRESS FOR THE READ DIRECTIVE ; ;_ ; TRMINP: MOV #IO.RLB,READ+Q.IOFN ;SET TO READ LOGICAL BLOCK DIR$ #READ ;READ IT MOV #NAME,R1 ;ADRESS OF BUFFER MOV #RDST,R2 ;ADRESS OF STATUS BLOCK RETURN .SBTTL > C. LOGICAL INPUT (QUERY) ;+ ; ; QUERY -- ROUTINE TO QUERY THE USER FOR THE LOGICAL ; ASSIGNMENT OF A DEFINED VARIABLE. THE SYNTAX ; OF THE INPUT RECORD IS: ; ; (*)QUERY VARIBL LINE-OF-COMMENT-OR-PROMPT ; ; ACCEPTABLE RESPONSES ARE: ; ; => NO ; NO => NO ; YES => YES ; => YES ; ; THE ROUTINE CONTINUES TO PROMPT UNTIL A VALID REPLY ; IS RECEIVED. A CTRL/Z WILL TERMINATE PROCESSING. ; ;- SCRLF: .WORD 0 ;SRORAGE FOR DPRMPT: .ASCII ;[Y/N]?; ;DEFAULT PROMPT .EVEN LPRMPT=.-DPRMPT ;AND ITS LENGTH QUERY: ENTER R0 ;;;;;;;;;;;;;;;;;;;;;;;; CALL NUWORD ; POINT TO THE VARIABLE NAME BCS 100$ ; IF CS, THEN NOT FOUND MOV R1,-(SP) ; SAVE CURRENT POSITION AND MOV R2,-(SP) ; STRING LENGTH CALL FINDVB ; LOCATE VARIABLE IN TABLE BCC 1$ ; IF CC, WE FOUND IT MOV (SP)+,R2 ; ELSE POINT BACK TO BEGINNING OF VARIABLE MOV (SP)+,R1 ; NAME CALL FILLVB ; THEN FILL IN TABLE WITH THIS ONE BCS 100$ ; NO ROOM FOR IT BR 5$ ; SKIP STACK CLEAN 1$: CMP (SP)+,(SP)+ ; CLEAN THE STACK 5$: TST R2 ; PROMPT SPECIFIED??? BGT 6$ ; IF GT YES MOV #DPRMPT,R1 ; NO, SO USE DEFAULT PROMPT MOV #LPRMPT,R2 BR 7$ ; PUT OUT DEFAULT PROMPT 6$: CALL SSUBS ; PARSE THE QUERRY LINE 7$: MOVB #15,-(R1) ; INSERT CARRAIGE RETURN INC R2 MOVB #12,-(R1) ; AND LINE FEED INTO BUFFER INC R2 CLRB (R0) ; VARIABLE=YES MOV #IO.RPR,READ+Q.IOFN MOV R1,READ+Q.IOPL+6; SET UP PROMPT FOR THE READ MOV R2,READ+Q.IOPL+10 2$: DIR$ #READ ; READ WITH PROMPT TST RDST+2 ; ANYTHING READ? BEQ 3$ ; IF EQ, THEN NO, USE TERMINATOR CMPB #'Y,NAME ; A "YES"? BEQ 100$ ; YES, SO DONE CMPB #'y,NAME ; A "YES"? BEQ 100$ ; YES, SO DONE CMPB #'N,NAME ; A "NO"? BEQ 99$ ; YES CMPB #'n,NAME ; A "NO"? BEQ 99$ ; YES BR 2$ ; ASK AGAIN 3$: CMPB #33,RDST+1 ; AN ESC? BEQ 100$ ; IF SO, ASSUME "YES" CMPB #CR,RDST+1 ; A CARRIAGE RETURN? BEQ 99$ ; IF SO ASSUME A "NO" CMPB #IE.EOF,RDST ; AN EOF? BEQ 110$ ; IF SO, ASSUME FILE TERMINATION BR 2$ ; ASK AGAIN ; 99$: COMB (R0) ; NEGATE VARIABLE 100$: CLC ; INDICATE SUCCESSFUL ASSIGNMENT BR 111$ ; 110$: SEC ; TELL TO STOP FILE PROCESSING 111$: LEAVE ; RETURN ; .MCALL QIOW$ READ: QIOW$ IO.RLB,TILUN,TTYEVF,,RDST,, RDST: .BLKW 2 NAME: .BLKB 80. NLWRD: .WORD 0 .SBTTL > D. INDIRECT FILE PROCESSING .SBTTL > 1. PROCESS NEXT LEVEL ; ;+ ; ; INDIR -- ROUTINE TO OPEN THE NEXT LEVEL OF FILE ; INDIRECTION. CURRENTLY, EACH FILE IS LEFT ; OPEN AS THE NEXT LEVEL OF INDIRECTION IS ; ATTAINED. HOPEFULLY, THIS CAN BE RELIEVED ; LATER WITH THE USE OF THE MARK AND POSITION. ; ; INPUTS: R1 = ADDRESS OF LAST RECORD READ. ; ("@FILENAME") ; R2 = LENGTH OF LAST RECORD READ ; ;- INDIR: ENTER R1,R2 INC R1 ;SKIP OVER '@' DEC R2 ; CALL SSUBS ;PARSE THE INPUT FILE LINE CALL PRSE ;PARSE THE NAME GIVEN CALL GETFDB ;GET NEXT AVALABLE FDB BCC 1$ ;ISN'T ONE TO GET CALL 3$ ;ISSUE WARNING BR 2$ ;AND CONTINUE 1$: FDOP$R R0,,#CSBLK+C.DSDS ;INSERT DSDS OPEN$R R0,,,,,,IOERR ;OPEN THE FILE CALL GOTOIT ;GO TO IT FROM THERE CLOSE$ @CURFDB,IOERR ;DONE WITH THIS FILE CALL RELFDB ;FREE FDB 2$: CLC LEAVE ; RETURN ; ; ; 3$: CALL ERRPFX ;ERROR PREFIX PSTR ^#/***WARNING***/# PSTR ^#/MAX LEVEL OF INDIRECTION EXCEEDED/# PSTR ^#/RECORD IN ERROR: /# TTYOUT R1,R2 PSTR ^#/FURTHER LEVELS IGNORED/# RETURN .SBTTL > 2. PARSE FILE NAME ;+ ; ; PRSE -- ROUTINE TO PARSE THE GIVEN FILE NAME, AND ; LEAVE RESULTING DSDS IN CSI BLOCK. ; ; INPUTS: R1 = COMMAND LINE ; R2 = LENGTH OF COMMAND LINE ; ; OUTPUTS: R0 = ADDRESS OF CSI BLOCK ; CSI BLOCK OFFSET C.DSDS IS FILLED ; AS FOR FIRST PARSE OF OUTPUT ; SPECIFIER. ; ;- PRSE: CSI$1 #CSBLK,R1,R2 ;PARSE FILE NAME BCC 1$ ;WAS COOL CALL CS1ERR ;NOT GOOD 1$: CSI$2 ,OUTPUT ;GET A DSDS BCC 2$ ;GOT IT. CALL CS2ERR ; 2$: RETURN ; .SBTTL > 3. GET NEXT AVAILABLE FDB ; ;+ ; ; GETFDB -- ROUTINE TO PULL THE NEXT AVAILABLE ; FDB FROM THE LIST OF FDBS. ; ; OUTPUTS: CURFDB = ADDRESS OF FDB POINTER ; R0 = FDB POINTER ; CARRY SET IF NO FDB AVAILABLE ; ;- GETFDB: ENTER R1 MOV CURFDB,R1 ;GET CURRENT POINTER MOV (R1)+,R0 ;GET FDB FROM IT MOV (R1),R0 ; BEQ 1$ ;NOTHING THERE MOV R1,CURFDB ;UPDATE POINTER CLC ;INDICATE SUCCESS BR 2$ ;LEAVE 1$: SEC ;INDICATE FAILURE 2$: LEAVE RETURN .SBTTL > 4. RELEASE CURRENT FDB ; ;+ ; ; RELFDB -- ROUTINE WHICH TAKES THE CURRENTLY POINTED ; TO FDB AS DEFUNCT, AND BACKS UP THE LIST TO THE ; LAST AVAILABLE FDB. ; ;- RELFDB: ENTER R1 MOV CURFDB,R1 ;GET CURRENT CMP #FDBS,-(R1) ;UPDATE BHI 1$ ;STILL IN TABLE TST (R1)+ ;GET BACK INTO LIST BR 2$ ;LEAVE 1$: MOV R1,CURFDB ;NEW POINTER CLC ;INDICATE SUCCESS 2$: LEAVE ; RETURN ; .SBTTL > E. TERMINAL OUTPUT (PROMPT) ; ;+ ; ; PROMPT -- ROUTINE WHICH OUTPUTS THE CURRENT RECORD ; AS A PROMPT TO THE TERMINAL. ; ; ;- .MCALL PCRLF PROMPT: CALL NUWORD ;FIND PROMPT STRING BCS 1$ ;IF CS NOT FOUND SO PUT OUT BLANK LINE CALL SSUBS ;PARSE THE PROMPT STRING 1$: MOVB #LF,-(R1) ;INSERT CONTROL CHAR INC R2 ;AND COUNT IT TTYOUT R1,R2 ;ISSUE THE PROMPT PSTR ^#<7># ;AND ADVANCE CARRIAGE RETURN ; .SBTTL > F. CONDITIONAL EXECUTION ;+ ; ; CONDIT -- ROUTINE TO CONDITIONAL EXECUTE THE SPECIFIED ; "RECORD" DEPENDENT ON THE LOGICAL ASSIGNMENT OF ; THE SPECIFIED VARIABLE ; ; THE SYNTAX OF THE RECORD IS: ; ; (*)IF VARIBL EXECUTE-THIS-LINE ; ;- CONDIT: ENTER R0,R4,R5 ;;;;;;;;;;;;;;;;;;;;;;;;; CALL NUWORD ; POINT TO THE VARIABLE BCS 100$ ; NOT FOUND CALL FINDVB ; LOCATE IT IN TABLE BCS 100$ ; NOT FOUND, ASSUME FALSE TSTB (R0) ; CHECK VARIABLE BNE 100$ ; IF NE, THEN FALSE TST R2 ; CHECK LENGTH OF THE STRING BEQ 100$ ; IF EQ, THEN NOTHING TO EXECUTE CALL PROREC ; PROCESS THE RECORD 100$: CLC LEAVE ; RETURN ; ;+ ; ; THIS MACRO REWINDS A FILE BACK TO ITS BEGINNING. ; ; INPUT: FDB ADRESS OF FILE ; ;- .MACRO REWIND,FDB ;MACRO TOO REWIND TO START OF FILE MOV FDB,R0 ;R0 = FDB ADRESS CLR R1 ;R1 = HIGH ORDER BLOCK NUMBER MOV #1,R2 ;R2 = LOW ORDER BLOCK NUMBER CLR R3 ;R3 = NUMBER OF BYTE IN BLOCK CALL .POINT .ENDM .SBTTL > G. BRANCH COMMAND (GOTO) .SBTTL > 1. GOTO LABEL ;+ ; ; GOTO -- ROUTINE TO FORCE RESUMPTION OF RECORD PROCESSING ; AT THE LABEL SPECIFIED. ; ; THE SYNTAX OF THE RECORD IS: ; ; (*)GOTO LABEL ; ;- GOTO: ENTER R1,R2,R4,R5 ;;;;;;;;;;;;;;;;;; CALL NUWORD ; POINT TO THE LABEL NAME BCS 99$ ; NO NAME THERE CALL NUWORD ; ISOLATE THE LABEL CMP #20,R5 ; MORE THAN 16 CHARACTERS??? BGE 1$ ; IF GE NO SO TRANSFER ALL MOV #20,R5 ; ONLY TRANSFER FIRST 16 CHARACTERS 1$: MOV R5,LLAB ; AND REMEMBER THE LABEL'S LENGTH MOV #LAB,R1 ; WHERE TO PUT LABEL 2$: MOVB (R4)+,(R1)+ ; MOVE THE LABEL OVER SOB R5,2$ ; REWIND @CURFDB ; REWIND THE CURRENT FILE CALL LOCATE ; LOCATE THE LABEL BCS 10$ ; NOT FOUND MOV @CURFDB,R0 ; GET CURRENT INPUT FDB CALL MARK ; MARK THIS POSITION CALL LOCATE ; LOCATE IT AGAIN BCC 20$ ; IF CC, FOUND, SO AMBIGUOUS MOV @CURFDB,R0 ; INPUT FDB CALL UNMARK ; REWIND TO THE LABEL BR 99$ ; THAT IS ALL ; 10$: CALL 15$ ; PRE MESSAGE PSTR ^#/" NOT FOUND/# BR 25$ ; 15$: CALL ERRPFX ; ERROR PREFIX PSTR ^#/LABEL: "/# ; TTYOUT #LAB,LLAB ; RETURN 20$: CALL 15$ ; PRE MESSAGE PSTR ^#/" AMBIGUOUS/# 25$: SEC ; STOP PROCESSING FILE BR 100$ ; LEAVE ; 99$: CLC ; INDICATE SUCCESS 100$: LEAVE ; RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .SBTTL > 2. LOCATE LABEL ;+ ; ; LOCATE -- ROUTINE TO LOCATE THE SPECIFIED LABEL IN THE CURRENT ; FILE (FROM THE CURRENT POSITION). ; ; ASSUMES THAT LABEL IS STORED AT "LAB". ; ; OUTPUTS: CARRY SET IFF EOF DETECTED ; ;- LOCATE: ENTER ;;;;;;;;;;;;;;;;;;;;;;;;;;; 1$: CALL RDRECD ; READ IN A RECORD BCS 10$ ; EOF DETECTED CMPB #COMCHR,(R1) ; A COMMAND LINE? BNE 1$ ; NO CMPB #'L,1(R1) ; A LABEL DEFINITION? BEQ 2$ ; YES CMPB #'l,1(R1) ; LABEL DEFINITION??? BNE 1$ ; IF NE NO 2$: CALL NUWORD ; POINT TO THE NAME BCS 1$ ; NOTHING THERE CALL NUWORD ; ISOLATE IT CMP LLAB,R5 ; SAME LENGTH AS LABEL WE HAVE? ***GW002 BNE 1$ ; IF NE THEN THIS NOT THE LABEL ***GW002 MOV #LAB,R1 ; POINT TO OUR LABEL 3$: CMPB (R1)+,(R4)+ ; DO THE LABELS MATCH? BNE 1$ ; IF NE, THEN NO SOB R5,3$ ; CHECK WHOLE LABEL 10$: LEAVE ; THE LABEL EXISTS RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;; ; LAB: .BLKB 20 ; 20 CHARS IS A BIG VARIABLE LLAB: .WORD 0 ; LENGTH OF REMEMBERED LABEL .SBTTL > H. COMMENTS ;+ ; ; COMMNT -- ROUTINE TO PROCESS COMMENT RECORDS ; ;- COMMNT: RETURN ;INGORE THE RECORD .SBTTL > I. LABEL DEFINITION ;+ ; ; LABEL -- ROUTINE TO PROCESS A LABEL DEFINITION ; ;- LABEL: RETURN ;IGNORE RECORD .SBTTL > J. DYNAMIC STRING DEFINITION .SBTTL > 1. STRING TABLES .NLIST BEX ; ; ; SYMBOLS FOR DEFINING ADRESSESS ; NVAR=36. ;# OF STRING VARIABLES VARSIZ=32. ;BYTES PER STRING VARIABLE COMCHR='$ ;CONTROL CHARACTER SPACE=' SPCHAR='% ;CHARACTER TO DENOTE STRING SUBSTITUION SOUTBF=512. ;SIZE OF THE OUTPUT BUFFER DAYADR='D-'A*VARSIZ+ATOZ ;ADRESS FOR NUMERIC DAY MTHADR='M-'A*VARSIZ+ATOZ ;ADRESS FOR NUMERIC MONTH YRADR='Y-'A*VARSIZ+ATOZ ;ADRESS FOR NUMERIC YEAR WKDADR='W-'A*VARSIZ+ATOZ ;ADRESS FOR GENERIC DAY NMNADR='N-'A*VARSIZ+ATOZ ;ADRESS FOR GENERIC MONTH TIMADR='T-'A*VARSIZ+ATOZ ;ADRESS FOR TIME IN FORM HH:MM:SS.S IDADR='I-'A*VARSIZ+ATOZ ;ADRESS FOR PROGRAM IDENTIFICATION OPSADR='O-'A*VARSIZ+ATOZ ;ADRESS FOR OPERATING SYTEM IDENT VERADR='V-'A*VARSIZ+ATOZ ;ADRESS FOR PROGRAM VERSION ;VARIABLE NAME LOOKUP TABLE VARTAB: .ASCII /ABCDEFGHIJKLMNOPQRSTUVWXYZ/ .ASCII /0123456789/ NLTDIG=.-VARTAB ;# OF BIG LETTERS AND DIGITS .ASCIZ /abcdefghijklmnopqrstuvwxyz/ .EVEN ATOZ: .REPT 26. ;STORAGE FOR VARIABLES A-Z .BLKB VARSIZ .ENDR OTO9: .REPT 10. ;STORAGE FOR VARIABLES 0-9 .BLKB VARSIZ .ENDR SETVAR: .WORD IDADR ;ADRESSESS OF PREDEFINED ASCII STRINGS .WORD OPSADR,VERADR .WORD 0 ;TABLE TERMINATOR SETPOS: .WORD LETI,LETO,LETV ;ADRESS TO FIND PREDEFINED ASCII STRINGS LETI: .ASCIZ /790607/ LETO: .ASCIZ /RSX-11M V3.1/ LETV: .ASCIZ /DOC 790207 (V5.0)/ .EVEN .DSABLE LC ;ALL MONTHS AND DAYS IN UPPER CASE MONTHS: .ASCIZ /January/<0><0> LMONTH=.-MONTHS .ASCIZ /February/<0> .ASCIZ /March/<0><0><0><0> .ASCIZ /April/<0><0><0><0> .ASCIZ /May/<0><0><0><0><0><0> .ASCIZ /June/<0><0><0><0><0> .ASCIZ /July/<0><0><0><0><0> .ASCIZ /August/<0><0><0> .ASCIZ /September/ .ASCIZ /October/<0><0> .ASCIZ /November/<0> .ASCIZ /December/<0> .EVEN DAYS: .ASCIZ /Sunday/<0><0><0> LDAYS=.-DAYS .ASCIZ /Monday/<0><0><0> .ASCIZ /Tuesday/<0><0> .ASCIZ /Wednesday/ .ASCIZ /Thursday/<0> .ASCIZ /Friday/<0><0><0> .ASCIZ /Saturday/<0> .EVEN .ENABLE LC BLWRD: .WORD 0 ;SPACE FOR RECORD CONTROL CHARACTERS OUTBUF: .BLKB SOUTBF ;BUFFER FOR BUILDING RECORDS TIMBUF: .BLKW 8. ;TIME BUFFER X1: .WORD 0 ;PARAMETERS FOR STRING SUBSTITUTION X2: .WORD 0 .SBTTL > 2. INITIAL STRING DEFINITIONS ;+ ; ; INISTR -- ROUTINE TO DEFINE THE SYSTEM DEFINED STRINGS. ; ;- INISTR: MOV #ATOZ,R0 ;GET VARIABLE BUFFER BASE MOV #NVAR,R1 ;NUMBER OF VARIABLES 1$: CLRB (R0) ;BLANK ALL FIELDS ADD #VARSIZ,R0 ;OFFSET TO NEXT VARIABLE SOB R1,1$ ;LOOP TILL ALL DONE MOV #SETVAR,R0 ;FILL IN ALL SET VARIABLES MOV #SETPOS,R1 ;CORRESPONDING ADRESS LOOKUP 2$: MOV (R0)+,R2 ;GET VARIABLE BUFFER ADRESS BEQ 6$ ;IF EQ NO MORE TO DO MOV (R1)+,R3 ;GET ASCII STRING ADRESS 4$: MOVB (R3)+,(R2)+ ;MOVE IN STRING BNE 4$ ;ALL OF IT BR 2$ ;GO ON TO NEXT VARIABLE 6$: GTIM$S #TIMBUF ;GET THE SYSTEM TIME MOV #TIMADR,R0 ;ADRESS TO PUT CONVERTED TIME MOV #TIMBUF+G.TIHR,R1 ;START OF BINARY TIME MOV #4,R2 ;CONVERT TO HH:MM:SS.S CALL $TIM ;DO IT CLRB (R0) ;MARK END OF BUFFER MOV #YRADR,R0 ;GET NUMERIC YEAR ADRESS MOV #1900.,R1 ;SET UP BINARY ADD TIMBUF+G.TIYR,R1 ;YEAR CLR R2 ;SUPRESS ZEROS CALL $CBDMG ;COVERT TO NUMERIC DECIMAL CLRB (R0) ;MARK END OF BUFFER MOV #MTHADR,R0 ;GET NUMERIC MONTH ADRESS MOV TIMBUF+G.TIMO,R1 ;GET BINARY MONTH CLR R2 ;ZERO SUPRESS CALL $CBDMG ;CONVERT TO NUMERIC DECIMAL CLRB (R0) ;MARK END OF BUFFER MOV #DAYADR,R0 ;GET NUMERIC DAY ADRESS MOV TIMBUF+G.TIDA,R1 ;AND BINARY DAY CLR R2 ;ZERO SUPRESS CALL $CBDMG ;CONVERT AND STORE CLRB (R0) ;MARK END MOV TIMBUF+G.TIMO,R1 ;GET BINARY MONTH DEC R1 ;0 = JANUARY, 11 = DECEMBER MUL #LMONTH,R1 ;OFFSET INTO MONTH ADD #MONTHS,R1 ;LOOKUP TABLE MOV #NMNADR,R0 ;ADRESS TO STORE GENERIC MONTH 10$: MOVB (R1)+,(R0)+ ;MOVE IT IN BNE 10$ MOV #TIMBUF+G.TIYR,R1 ;GET ADRESS OF YEAR .CALLV IDAY,<4(R1),2(R1),(R1)> ;FIND WEEKDAY, 1 = SUNDAY & 7 = SATURDAY DEC R0 ;0 = SUNDAY MUL #LDAYS,R0 ;CALCULATE OFFSET ADD #DAYS,R1 ;INTO WEEKDAY LOOKUP TABLE MOV #WKDADR,R0 ;ADRESS TO STORE GENERIC WEEKDAY 20$: MOVB (R1)+,(R0)+ ;MOVE IT IN BNE 20$ RETURN ;;;;;;;;;;;;;;;;;;;;; .SBTTL > 3. THE DEFINE COMMAND ;+ ; ; SDEFN -- ROUTINE WHICH ALLOWS THE USER DEFINITION OF TEXT ; STRINGS. THE FORMAT OF THE COMMAND LINE IS: ; ; (*)DEFINE V ; ; ; INPUTS: R1 = POINTER TO CHARACTER AFTER THE CONTROL CHARACTER ; R2 = AMOUNT OF STRING REMAINING ; ; OUTPUTS: NONE, ALL REGISTERS RESTORED ; ;- SDEFN: ENTER R0,R1,R2,R3,R4,R5 ;SAVE REGISTERS CALL NUWORD ;FIND SYMBOL TO BE DEFINED BCS 100$ ;NONE, SO IGNORE COMMAND CMPB #'?,(R1) ;TERMINAL INPUT BUFFER SPECIFIED?? BEQ 80$ ;IF EQ YES, BUT NOT ALLOWED TO ;DEFINE TERMINAL INPUT BUFFER SO ;TELL HIM CALL FNDBUF ;FIND BUFFER CORRESPONDING TO ;SYMBOL SPECIFIED BCS 80$ ;IF CS THEN NO SUCH VARIABLE SO TELL ;HIM AND LEAVE CALL NUWORD ;FIND START OF DEFINITION STRING BCS 50$ ;IF NO STRING, ZERO VARIABLE ***GW003 MOV #31.,R4 ;SET MAX. OUTPUT BUFFER SIZE CALL PARSE ;PARSE DEFINITION STRING AND FILL IN ;THE STORAGE LOCATION 50$: CLRB (R3)+ ;MARK END OF BUFFER BR 100$ ;AND WE ARE DONE 80$: CALL ERRPFX ;NO SUCH VARIABLE PSTR ^#/INVALID STRING VARIABLE SPECIFIED/# PSTR ^#/RECORD IN ERROR: /# TTYOUT R1,R2 ;GIVE HIM REST OF LINE PCRLF ;CARRAIGE RETURN AND LINE FEED 100$: CLC ;INCATE SUCESS LEAVE ;RESTORE THE REGISTERS RETURN .SBTTL > K. DYNAMIC STRING SUBSTITUTION ;+ ; ; SSUBS1 -- ROUTINE TO ALLOW FOR THE DYNAMIC STRING SUBSTITUTION ; THE FORMAT OF THE COMMAND LINE IS: ; ; (*)STRING ; ;- ; ; ; INPUTS: R1 - POINTS TO CHARACTER AFTER THE CONTROL CHARACTER ; R2 - AMOUNT OF STRING REMAINING ; ; OUTPUTS: NONE, ALL REGISTERS RESTORED ; ;- SSUBS1: ENTER R1,R2 ;SAVE REGISTERS CALL NUWORD ;FIND STRING TO BE PARSED BCS 1$ ;IF CS NO STRING SO IGNORE CALL SSUBS ;PARSE THE LINE TST R2 ;ANYTHING THERE??? BEQ 1$ ;IF EQ NO CALL OUTPUT ;YES, SO PUT IT IN OUTPUT FILE 1$: CLC ;INDICATE SUCESS LEAVE ;RESTORE REGISTERS RETURN ;AND RETURN SSUBS: ENTER R0,R3,R4,R5 ;SAVE REGISTERS MOV #OUTBUF,R3 ;SET UP OUTPUT BUFFER MOV #SOUTBF,R4 ;AND MAXIMUM SIZE CALL PARSE ;FILL IT IN MOV #OUTBUF,R1 ;POINT TO BUFFER MOV #SOUTBF,R2 ;CALCULATE ITS LENGTH SUB R4,R2 LEAVE ;RESTORE THE REGISTERS RETURN ;;;;;;;;;;;;;;;;;;;;;;;; .SBTTL > L. SUPPORT SUBROUTINES FOR STRING SUBSTITUTION .SBTTL > 1. FIND VARIABLE BUFFER ; ;+ ; ; FNDBUF -- ROUTINE TO FIND THE BUFFER FOR A VARIABLE A-Z OR 0-9. ; EVERY BUFFER IS 32 BYTES WITH ONE BUFFER FOR EVERY ONE OF THE ; POSSIBLE 36 SYMBOLS. ; ; INPUT - R1 POINTS TO SYMBOL WHOSE BUFFER IS TO BE FOUND ; ; OUTPUT - R3 IS ADRESS OF BUFFER IF FOUND ; CS IF BUFFER NOT FOUND ; ;- ; FNDBUF: MOV #VARTAB,R3 ;GET ADRESS OF LOOKUP TABLE 1$: CMPB (R3)+,(R1) ;THIS THE ONE? BEQ 3$ ;IF EQ YES TSTB (R3) ;LAST ENTRY IN TABLE? BNE 1$ ;NO, SO KEEP LOOKING CMPB (R1),#'? ;TERMINAL INPUT BUFFER?? BNE 2$ ;IF NE NO SO NO BUFFER ENTER R1,R2 ;SAVE REGISTERS CALL TRMINP ;READ RECORD FROM TERMINAL CMPB #IS.SUC,(R2) ;SUCCESSFUL???? BEQ 21$ ;YES CMPB #IE.EOF,(R2) ;TERMINATE BY A ^Z??? BEQ 21$ ;YES, SO SUCCESSFUL CALL IOERR ;NO, SO TELL HIM 21$: MOV 2(R2),R2 ;GET BYTE COUNT ADD R1,R2 ;POINT TO END OF RECORD CLRB (R2) ;INSERT NULL TO DELINIATE END MOV R1,R3 ;R3 = POINTER TO BUFFER CLC LEAVE RETURN 2$: SEC ;YES, SO INDICATE FAILURE RETURN 3$: SUB #VARTAB,R3 ;CALCULATE OFFSET DEC R3 ;ACCOUNT FOR AUTO INCREMENT CMP #NLTDIG,R3 ;ARE WE INTO SMALL LETTERS?? BGT 4$ ;IF GT NO SUB #NLTDIG,R3 ;ADJUST SO THAT SMALL AND CAPITAL ;LETTERS HAVE THE SAME BUFFERS 4$: ASH #5,R3 ;32 BYTES PER VARIABLE ADD #ATOZ,R3 ;ADD BASE ADDRESS CLC ;INDICATE SUCESS RETURN ;AND GO HOME .SBTTL > 2. PARSE STRING ; ;+ ; ; PARSE -- ROUTINE TO TAKE A STRING AND PARSE IT FOR ANY % CHARACTERS. ; ANY CHARACTER FOLLOWING A % IS CONSIDERED TO DESIGNATE ONE ; OF THE POSSIBLE 36 PREDEFINED STORAGE LOCATIONS (A-Z OR 0-9) AND ; SUBSTITUTION OF THE STRING STORED IN THE SPECIFIED STORAGE LOCATIONS ; IS MADE FOR THE "%A(X1,X2)". FOR MORE DETAIL SEE THE "STRSUB" ; ROUTINE. ; ; INPUTS: R1 - POINTS TO START OF STRING ; R2 - LENGTH OF INPUT STRING ; R3 - POINTS TO OUTPUT BUFFER ; R4 - MAXIMUM SIZE OF OUTPUT BUFFER ; ; OUTPUT: R1 - CURRENT POSITION IN STRING ; R2 - LENGTH OF INPUT STRING REMAINING ; R3 - CURRENT POSITION IN OUT PUT BUFFER ; R4 - SPACE REMAINING IN OUT PUT BUFFER ; ; ;- ; PARSE: CMPB (R1),#SPCHAR ;SPECIAL SYMBOL??? BNE 3$ ;NO, SO CONTINUE CALL SYPARS ;YES, SO CALL SYMBOL PARSER BCS 70$ ;IF CS THEN SOMETHING WRONG SO LEAVE BR 10$ ;ESE CHECK BUFFERS 3$: MOVB (R1)+,(R3)+ ;STORE THE CHARACTER DEC R4 ;ONE MORE IN OUTPUT BUFFER DEC R2 ;ONE LESS IN INPUT BUFFER 10$: TST R2 ;INPUT BUFFER EMPTY?? BLE 60$ ;YES SO QUIT TST R4 ;OUTPUT BUFFER FULL??? BGT PARSE ;GO BACK FOR NEXT CHARACTER 60$: CLC ;ELSE CLEAR CARRY 70$: RETURN ;AND LEAVE .SBTTL > 2. PARSE SUBSTITUTION COMMANDS ; ;+ ; ; SYPARS - THIS ROUTINE IS CALLED BY THE ROUTINE PARSE TO PARSE ANY SECTION ; OF AN INPUT STRING PROCEEDED BY A %. FOR EXAMPLE, IF THE SECTION OF ; THE STRING WAS "%D(4,20)" THEN THIS ROUTINE WOULD PUT THE CONTENTS ; OF THE PREDEFINED STORAGE LOCATION "D" FROM THE FOURTH TO THE ; TWENTYTH POSITION, INTO THE OUTPUT BUFFER. ; ; INPUTS: R1 - POSITIONED ON THE % SIGN ; R2 - LENGTH OF TOTAL INPUT STRING REMAINING ; R3 - CURRENT POSITION IN OUTPUT BUFFER ; R4 - NUMBER OF BYTES LEFT TO BE FILLED IN OUTPUT BUFFER ; ; OUTPUTS: R1 - POSITIONED NEXT BYTE AFTER "%" STRING ; R2 - LENGTH OF INPUT STRING REMAINING ; R3 - CURRENT POSITION IN OUTPUT BUFFER ; R4 - NUMBER OF BYTES LEFT IN OUTPUT BUFFER ; ;- ; SYPARS: DEC R2 ;ACCOUNT FOR THE % BNE 10$ ;LAST CHARACTER? MOVB (R1)+,(R3)+ ;YES, SO STORE IT DEC R4 ;ACCOUNT FOR IT AND LEAVE BR 99$ 10$: INC R1 ;SKIP OVER THAT NASTY % MOV R3,R5 ;SAVE THE OUTPUT BUFFER POINTER CALL FNDBUF ;FIND SYMBOL BUFFER BCC 20$ ;IF CC WE GOT IT MOV R5,R3 ;RESTORE OUTPUT BUFFER POINTER MOVB #SPCHAR,(R3)+ ;FAKE THE % DEC R4 ;ACCOUNT FOR IT CLC ;INDICATE SUCESS RETURN ;GO BACK FOR MORE 20$: CALL CALPRM ;CALCULATE PARAMETERS BCS 100$ ;IF CS THEN SOMETHING WRONG SO RUN AWAY MOV R3,R0 ;NOW GET INPUT BUFFER FOR SYMBOL MOV R5,R3 ;STORE OUTPUT BUFFER ADRESS 23$: DEC X1 ;SPACE OVER TO STARTING COLUMN BLT 25$ ;IF LT WE ARE THERE TSTB (R0)+ ;END OF BUFFER BNE 23$ ;IF NE THEN NO SO KEEP SPACING BR 99$ ;END OF BUFFER SO DONE 25$: DEC X2 ;MORE CHARACTERS TO COME??? BLT 99$ ;IF LT NO SO QUIT TSTB (R0) ;END OF VARIABLE BUFFER???? BEQ 99$ ;IF EQ YES SO QUIT MOVB (R0)+,(R3)+ ;TRANSFER CHARACTER DEC R4 ;AND COUNT IT BGT 25$ ;IF GT THE OUTPUT BUFFER NOT FULL SO ;CONTINUE 99$: CLC ;INDICATE SUCESS 100$: RETURN ;AND CALL IT A DAY .SBTTL > 4. CALCULATE PARAMETERS ; ;+ ; ; CALPRM -- THIS ROUTINE IS USED BY SYPARS TO CALCULATE THE PARAMETERS ; GIVEN IN A STIRNG LIKE "%A(3,8)". IF NO PARAMETERS SPECIFIED ; A DEFAULT OF (0,32) IS USED FOR (X1,X2). IF SYNTAX ERROR OR ; OTHER ERROR ENCOUNTERED THEN CARRY IS SET AND ERROR MESSAGE ; OUTPUT. ; ; INPUTS: R1 - POINTS TO CHARACTER FOLLOWING % ; R2 - AMOUNT OF INPUT STRING REMAINING ; ; OUTPUTS: IF NO ERRORS ; R1 - POINTER TO CHARACTER AFTER END OF PARAMETERS ; R2 - LENGTH OF STRING LEFT ; ; IF ERRORS ; CS & R1,R2 UNRELIABLE ; ;- ; CALPRM: CLR X1 ;SET DEFAULT PARAMETERS MOV #30.,X2 ;FOR 31. CHARACTERS INC R1 ;SKIP VARIALBE NAME DEC R2 ;AND ACCOUNT FOR IT BLE 700$ ;IF LE THEN NO MORE CHARACTERS SO USE ;DEFAULT PARAMETERS CMPB (R1),#'( ;VALID PARAMETER DELIMETER???? BNE 700$ ;NO, SO USE DEFAULT PARAMETERS MOV R1,R0 ;STORE INPUT BUFFER ADRESS MOV R1,-(SP) ;SAVE IT FOR LATER USE MOV R2,-(SP) ;AND ALSO SAVE STRING LENGTH INC R0 ;SKIP THE DELIMETER CMPB (R0),#') ;IS IT ()??? BNE 10$ ;NO, SO PARSE PARAMETERS INC R0 ;YES, SO SKIP IT BR 600$ ;AND USE DEFAULT PARAMETERS 10$: CALL $CDTB ;CONVERT THE ASCII NUMBER FROM DECIMAL ;TO BINARY MAGNITUDE MOV R1,X1 ;STORE IN LOCATION X1 CMPB #'),R2 ;ONLY ONE PARAMETER??? BEQ 600$ ;YEP, SO LEAVE X2 AT DEFAULT CMPB #',,R2 ;MORE THAN ONE PARAMETER??? BNE 630$ ;NO, SO ERROR CMPB (R0),#') ;IS IT (X1,)??? BNE 20$ ;IF NE NO SO PARSE X2 INC R0 ;YES, SO SKIP LAST DELIMETER BR 600$ ;AND USE DEFAULT X2 20$: CALL $CDTB ;CONVERT SECOND PARAMETER CMPB #'),R2 ;PROPER DELIMETER??? BNE 630$ ;NO, SO TELL HIM HE SCREWED UP MOV R1,X2 ;STORE SECOND PARAMETER 600$: SUB 2(SP),R0 ;CALCULATE LENGTH OF WHOLE STRING ;JUST CONVERTED CMP R0,(SP) ;PAST END OF LINE??? BGT 630$ ;IF GT YES AND SOMETHING WRONG CMP #31.,X2 ;PARAMETER IN BOUND??? BLT 630$ ;NO, SO TELL HIM SUB X1,X2 ;SET X2 = NUMBER OF CHARACTERS TO MOVE ;& X1 = STARTING POSITION BLT 630$ ;IF LT THEN X1 > X2 SO INCOMPATABLE DEC X1 ;ADJUST TO 0 ORIGIN MOV (SP)+,R2 ;RESTORE REGISTERS MOV (SP)+,R1 SUB R0,R2 ;ADJUST THE CHARACTER COUNT ADD R0,R1 ;AND UPDATE THE POINTER BR 700$ ;AND WE ARE DONE 630$: MOV (SP)+,R2 ;RESTORE OLD COUNT MOV (SP)+,R1 ;AND POSITION 650$: CALL ERRPFX ;TELL HIM OF ERROR PSTR ^#/INVALID PARAMETERS OR DELIMITERS/# PSTR ^#/RECORD IN ERROR: /# TTYOUT R1,R2 ;TRY AND SHOW IT TO HIM PCRLF SEC ;INDICATE ERROR TO OTHER ROUTINES RETURN ;AND GO HOME 700$: INC X2 ;ADJUST PARAMETER SINCE NUMBER OF CHARACTERS ;TO TRANSFER = X2 -X1 +1 CLC ;INDICATE SUCCESS RETURN ;AND WE ARE DONE .SBTTL >VI. SUPPORT SUBROUTINES .SBTTL > A. ISOATE INPUT WORDS ;+ ; ; NUWORD -- ROUTINE TO ADVANCE THE INPUT STRING POINTER, ; WHILE AT THE SAME TIME ISOLATING THE "CURRENTLY ; POINTED TO" WORD. IT ASSUMES THAT WORDS ARE DELINEATED ; WITH BLANKS (SPACES), AND THAT THE POINTER IS INITIALLY ; AT THE START OF THE "CURRENT" WORD. ; ; INPUTS: R1 = CURRENT STRING POSITION ; R2 = AMOUNT OF STRING REMAINING ; ; OUTPUTS: R1 = START OF THE NEXT WORD ; R2 = LENGTH OF THE STRING REMAINING ; R4 = START OF PREVIOUS WORD (== INPUT R1) ; R5 = LENGTH OF THE PREVIOUS WORD ; CARRY SET IFF THERE IS NO NEW WORD (IE. R2=0) ; ;- NUWORD: MOV R1,R4 ; COPY INPUT POINTER 1$: CMPB #40,(R1)+ ; A SPACE? BEQ 2$ ; IF SO, HAVE REACHED END OF WORD CMPB #11,-1(R1) ; A TAB??? BEQ 2$ ; IF SO HAVE REACHED END OF WORD DEC R2 ; ONE LESS CHARACTER BEQ 3$ ; THERE ARE NO MORE BR 1$ ; GET GOING WITH WHAT THERE IS 2$: DEC R2 ; ONE LESS CHARACTER 3$: MOV R1,R5 ; WHERE WE ARE LESS WHERE SUB R4,R5 ; WE WERE IS LENGTH OF THE WORD TST R2 ; IS THERE MORE? BEQ 10$ ; NO 4$: CMPB #40,(R1)+ ; LOOK FOR A NON-BLANK BEQ 5$ ; IF EQ THEN BLANK CMPB #11,-1(R1) ; IS IT A TAB??? BNE 6$ ; IF NE THEN A NON-BLANK 5$: DEC R2 ; ARE THERE MORE CHARACTERS? BEQ 10$ ; IF EQ, THEN NO MORE BR 4$ ; 6$: DEC R1 ; LOOK BACK AT THE NON-BLANK CLC ; INDICATE SUCCESS BR 11$ ; 10$: SEC ; INDICATE NO NEW WORD 11$: RETURN ; .SBTTL > B. LOGICAL VARIABLE MANIPULATION .SBTTL > 1. VARIABLE TABLES ; NVARS =20 ;NUMBER OF VARIABLES SUPPORTED VBNAMS: .BLKW 2*NVARS ;LIST OF VARIABLE NAMES VBEND: ;END OF TABLE MARKER ; NXTFRE: .WORD VBNAMS ;NEXT FREE VARIABLE NAME BUFFER ; VARIBS: .BLKB NVARS ;THE ACTUAL VARIABLES ; .SBTTL > 2. MISCELLANEOUS ROUTINES ;+ ; ; GTNAME -- ROUTINE TO TAKE NAME FROM STRING, AND FILL IN THE ; VARIABLE NAME TABLE ENTRY. ; ; INPUT: R0 = ADDRESS OF 4-BYTE BLOCK TO HOLD NAME ; R1 = CURRENT INPUT STRING POSITION ; R2 = REMAINING LENGTH OF IN STRING ; ; OUTPUT: R1 = ADDRESS OF NEXT WORD ; R2 = AMOUNT OF STRING REMAINING ; ;- GTNAME: ENTER R0,R4,R5 ;;;;;;;;;;;;;;;;;;;;; CALL NUWORD ; ISOLATE THE VARIABLE NAME SUB #4,R5 ; (AT MOST, WE ARE ONLY CONCERNED BMI 1$ ; WITH THE FIRST FOUR CHARACTERS CLR R5 ; OF THE VARIABLE NAME. THE REST 1$: ADD #4,R5 ; ARE JUST IGNORED.) MOV #20040,(R0) ; BLANK OUT PREVIOUS NAME MOV (R0),2(R0) ; 2$: MOVB (R4)+,(R0)+ ; MOVE OVER THE VARIABLE NAME SOB R5,2$ ; LEAVE ; RETURN ;;;;;;;;;;;;;;;;;;;;; ; ;+ ; ; GETVB -- ROUTINE TO GET THE ACTUAL VARIABLE ONCE THE ; VARIABLE NAME HAS BEEN LOCATED (INSERTED) ; ; INPUT: R0 = ADDRESS OF THE VARIABLE NAME IN THE LIST ; ; OUTPUT: R0 = ADDRESS OF THE LOGICAL VARIABLE ; ;- GETVB: SUB #VBNAMS,R0 ; DISPLACEMENT INTO NAME LIST ASR R0 ; AS A DISPLACEMENT ASR R0 ; INTO THE BYTE TABLE ADD #VARIBS,R0 ; OF LOGICAL VARIABLES RETURN ; .SBTTL > 3. LOCATE NAME ENTRY ;+ ; ; FINVB -- ROUTINE TO LOCATE THE NAME ENTRY FROM THE LIST OF ; NAMES CORRESPONDING TO THE USER SUPPLIED VARIABLE NAME. ; ; INPUT: R1 = START OF VARIABLE NAME ; R2 = LENGTH OF REMAINING STRING ; ; OUTPUT: R0 = ADDRESS OF THE VARIABLE ; R1 = NEXT WORD ; R2 = LENGTH OF REMAINING STRING ; CARRY SET IFF VARIABLE NOT FOUND ; NOTE: IF VARIABLE NOT FOUND THEN R1 IS RESTORED TO ; START OF VARIABLE NAME AND R2 IS THE LENGHT OF THE ; REMAINING STRING. ; ;- VBNAME: .BLKW 2 ; FINDVB: MOV #VBNAME,R0 ;WHERE TO PUT THE CALL GTNAME ;VARIABLE NAME MOV #VBNAMS,R0 ; LOOK TO ALL THE NAMES 1$: CMP NXTFRE,R0 ; AT THE FREE SPACE? BLOS 10$ ; YES, SO THE VAR IS NOT HERE CMPB (R0),VBNAME ; THIS IT? BNE 5$ ; DEFINITELY NOT CMPB 1(R0),VBNAME+1 ; BNE 5$ ; CMPB 2(R0),VBNAME+2 ; BNE 5$ ; CMPB 3(R0),VBNAME+3 ; BEQ 6$ ; IF EQ, THEN WE FOUND IT 5$: CMP (R0)+,(R0)+ ; LOOK TO THE NEXT NAME BR 1$ ; AND SEE IF THAT IS IT 6$: CALL GETVB ; LOCATE VARIABLE CLC ; INDICATE ENTRY FOUND BR 11$ ; 10$: SEC ; 11$: RETURN ; .SBTTL > 4. INSERT NAME ENTRY ;+ ; ; FILLVB -- ROUTINE TO INSERT A VARIABLE NAME INTO THE ; LIST OF VARIABLE NAMES. ; ; (INPUT/OUTPUT AS FOR FINDVB EXCEPT: ; ; CARRY SET IFF NO SPACE REMAINS FOR THE VARIABLE. ; ;- FILLVB: MOV NXTFRE,R0 ;GET NEXT FREE SPACE CMP R0,#VBEND ;ANY SPACE LEFT BHIS 10$ ;NO CALL GTNAME ;GET VARIABLE NAME ADD #4,NXTFRE ;UPDATE NEXT SPACE POINTER CALL GETVB ;LOCATE VARIABLE CLC ;INDICATE SUCCESS BR 11$ ; 10$: SEC ;FAILURE 11$: RETURN ; ; ; .SBTTL > 5. LOGICAL VARIABLE INITIALIZATION ;+ ; ; INILVB -- ROUTINE TO INITIALIZE THE SUPPORT FOR THE ; LOGICAL VARIABLE MANIPULATION. ; ;- INILVB: MOV #VBNAMS,NXTFRE ;EMPTY THE VARIABLE LIST RETURN .SBTTL >VII. BUFFERS AND VARIABLES .SBTTL > A. FILE BUFFERS AND FDBS .SBTTL > 1. LUNS AND EVFS .NLIST BEX ; ; INDLEV =4 ;LEVEL OF INDIRECTION ; ; EVF'S AND LUNS ; OUTLUN =1 ;OUTPUT FILE LUN OUTEVF =1 ;AND EVF ; TILUN =2 ;TERMINAL IO LUN TTYEVF =2 ;AND EVF ; TIFLUN =3 ;TERMINAL "FILE" LUN TIFEVF =3 ;AND EVF ; INFLUN =4 ;THE FIRST IN-FILE LUN INFEVF =4 ;AND EVF .SBTTL > 2. INPUT FDBS ; ; ; THE INPUT FILES ; .MACRO FDBDF,N FDB'N: FDBDF$ ;DEFINE FDB BLOCK FDAT$A R.VAR,FD.CR ;FILE ATTRIBUTES FDRC$A ,BUF1,132. ;RECORD ; FDOP$A INFLUN+DD,INDSDS,NMBLK1 ;FILE NAME FDOP$A INFLUN+DD,,NMBLK1 ;FILE NAME FDBF$A INFEVF+DD ;EVF .ENDM ; DD=0 .REPT INDLEV FDBDF \DD DD=DD+1 .ENDR ; ; .MACRO FDBLST,N .WORD FDB'N .ENDM ; DD=0 FDBS=. .REPT INDLEV FDBLST \DD DD=DD+1 .ENDR .WORD 0 ;LIST TERMINATOR ; ; CURFDB: .WORD FDBS ;FIRST FDB ; ; INDSDS: .WORD LDEV,DEV ; .WORD LUIC,UIC ; .WORD LNAM,NAM ; ; DEV: .ASCII /DM1:/ ;DEFAULT DEVICE ; LDEV =.-DEV ; ; UIC: .ASCII /[111,1]/ ;DEFAULT UIC ; LUIC =.-UIC ; ; NAM: .ASCII /DOC.SRC;0/ ;DEFAULT NAME ; LNAM =.-NAM ; .EVEN ; NMBLK1: NMBLK$ DOC,SRC,,SY,0 ;HIS DEFAULTS, ; (IF DSDS GETS REPLACED) ; .SBTTL > 3. OUTPUT FDB ;;;; ; ; THE OUTPUT FDB ; OUTFDB: FDBDF$ ;DEFINE FDB BLOCK FDAT$A R.VAR,FD.CR ;FILE ATTRIBUTES FDRC$A ,BUF1,132. ;RECORD FDOP$A OUTLUN,OUDSDS,NMBLK2 ;FILE NAME FDBF$A OUTEVF ;EVF ; OUDSDS: .WORD 0,0 .WORD 0,0 .WORD 0,0 ; NMBLK2: NMBLK$ ,RNO,,SY,0 ;DEFAULT NAME ; .SBTTL > 4. TERMINAL FDB ;;;;; ; ; THE TERMINAL'S FDB ; TIFDB: FDBDF$ ;DEFINE FDB BLOCK FDAT$A R.VAR,FD.CR ;FILE ATTRIBUTES FDRC$A ,BUF1,80. ;RECORD FDOP$A TIFLUN,TIDSDS ;FILE NAME FDBF$A TIFEVF ;FILE EVF ; TIDSDS: .WORD LTI,TI .WORD 0,0 .WORD 0,0 ; TI: .ASCII /TI:/ LTI =.-TI .SBTTL > B. MISCELLANEOUS .SBTTL > 1. CSI CONTROL BLOCK ; ; CSI CONTROL BLOCK ; CSI$ .EVEN CSBLK: .BLKB C.SIZE .EVEN ; .SBTTL > 2. TERMINAL OUTPUT BUFFERS ; ; ; ; ; ; ; ; ; ; ; ; ; ; .SBTTL > 3. GCML CONTROL BLOCK ; GCLUN =TILUN GCBLK: GCMLB$ 2,DOC,,GCLUN ; .SBTTL > 4. THE REST ; ; THE REMAINING STORES ; ; ; GMCR BLOCK ; GMCR: GMCR$ .EVEN ; ; BUF1: .BLKW 132. ;THE RECORD BUFFER ; ; FSRSZ$ INDLEV+4 .SBTTL >VIII.THE END .END START