.TITLE CSINTR - CSI INTERFACE ROUTINES .IDENT /V3.4/ ;+ ; CSINTR - CSI INTERFACE ROUTINES ; ; AUTHOR: C. T. MICKELSON ; ; DATE: 16 FEB 83 ; ; PURPOSE: PROVIDE A FORTRAN CALLABLE INTERFACE TO PROGRAM COMMANDS VIA ; GCML AND CSI SOFTWARE ; ; FACILITIES: 1. GET A COMMAND LINE ; 2. CHECK COMMAND SYNTAX ; 3. GET A FILE SPECIFICATION, WITH OPTIONAL SWITCHES ; 4. PERMITS USER TO EXTRACT SWITCH PARAMETERS FROM THE ; CSINTR DATABASE WITHOUT REGARD TO THE PARTICULAR ORDER ; OR TYPE OF SWITCH THAT IS ASSOCIATED WITH A COMMAND ; ; CALLING SEQUENCES: ; ; 1. GET A COMMAND LINE (ZERO OR MORE CHARACTERS) ; ; INTEGER GETCMD,BUFLEN,NETLEN,SKPCNT ; BYTE BUFF(BUFLEN) ; ; NETLEN=GETCMD(BUFF,BUFLEN,SKPCNT) ; ; INPUTS: BUFF = STARTING ADDRESS OF COMMAND LINE BUFFER ; ; BUFLEN = LENGTH OF COMMAND LINE BUFFER ; ; OUTPUTS: BUFF = COMMAND LINE RETRIEVED BY GCML ; ; SKPCNT = NUMBER OF CHARACTERS AT START OF BUFFER ; THAT SHOULD BE IGNORED (SPACES, TABS, ETC.) ; ; NETLEN = NET LENGTH OF COMMAND LINE RECEIVED ; = -10. IF END OF FILE FOUND ; ; ANY ERRORS ENCOUNTERED WHILE TRYING TO GET A COMMAND LINE ; WILL GENERATE AN ERROR MESSAGE AND ANOTHER ATTEMPT WILL ; BE MADE TO GET A COMMAND LINE. ; ; NOTE THAT THE LUN (CMDLUN) USED BY GCML TO FETCH COMMAND ; LINES MAY BE USED BY THE CALLING PROGRAM, PROVIDED THE LUN ; IS OPENED, READ OR WRITTEN, AND CLOSED BEFORE GETCMD ; IS CALLED AGAIN. SUCH USE OF CMDLUN MUST INCLUDE AN EXPLICIT ; SPECIFICATION OF THE ENTIRE FILE DESCRIPTOR (DEVICE, UIC, ; FILENAME, AND EXTENSION) IF PREDICTABLE RESULTS ARE TO BE ; ACHIEVED. THIS IS REQUIRED BECAUSE GCML RE-ASSIGNS CMDLUN ; TO DIFFERENT DEVICES DEPENDING UPON THE LOCATION OF THE ; COMMAND FILE THE PROGRAM IS PROCESSING. ; ; 2. CHECK COMMAND SYNTAX USING CSI$1 ; ; INTEGER CHKSYN,BUFLEN,CMDLEN,SKPCNT,NETLEN ; BYTE BUFF(BUFLEN) ; ; CMDLEN=CHKSYN(BUFF(SKPCNT+1),NETLEN) ; ; INPUTS: BUFF(I)= STARTING ADDRESS OF COMMAND LINE ; TO BE CHECKED ; NETLEN = LENGTH OF COMMAND IN BUFFER ; ; OUTPUTS: BUFF(I)= COMMAND LINE AFTER COMPRESSING OUT ; UNNECESSARY BLANKS AND VERIFYING SYNTAX ; CMDLEN = LENGTH OF COMMAND LINE AFTER COMPRESSION ; ; CMDLEN IS NEGATIVE IF AN ERROR WAS DETECTED DURING SYNTAX ; CHECKING. THE MAGNITUDE OF CMDLEN INDICATES THE ; COMPRESSED COMMAND LENGTH UP TO THE ERROR. ; ; 3. GET AN INPUT OR OUTPUT FILE SPECIFICATION FROM THE LAST ; SYNTAX CHECKED COMMAND LINE ; ; INTEGER GETFIL,ISWIT(2),IDIR,ISWTAB,RESULT ; BYTE FILE(40) ; ; RESULT=GETFIL(IFILE,ISWIT,IDIR,ISWTAB) ; ; INPUTS: IDIR = 0 => GET INPUT FILE SPEC ; IDIR # 0 => GET OUTPUT FILE SPEC ; ; ISWTAB = 0 => NO SWITCHES ARE TO BE PROCESSED ; ISWTAB = N => SCAN FOR SWITCHES DEFINED IN ; SWITCH DESCRIPTOR TABLE N (N > 0). ; ; IF N IS LARGER THAN THE NUMBER OF SWITCH ; DESCRIPTOR TABLES DEFINED IN THIS MODULE, A ; VALUE OF ZERO IS USED. ; ; OUTPUTS: IFILE = NEXT FILE SPEC STRING OF DESIGNATED TYPE. ; = NL: FOR EMPTY OUTPUT FILE SPEC ; = NULL STRING FOR EMPTY INPUT FILE SPEC ; FILE SPEC STRING ENDS WITH A NULL BYTE. ; FILE SPEC STRING CAN BE USED IN A FORTRAN ; OPEN(FILE=IFILE) ; ; ISWIT(1) = BIT SET FOR CORRESPONDING SWITCH FOUND ; IN FILE SPECIFICATION. ; ; ISWIT(2) = BIT SET FOR ASSERTED BI-POLAR SWITCH. ; CLEAR FOR NEGATED SWITCH. IF SWITCH HAS ; ASSOCIATED NUMERIC OR ASCII VALUES, THEY ; WILL BE PLACED IN COMMON/SWTVAL/ ACCORDING ; TO THE STRUCTURE DEFINED BELOW. (SEE SWTVAL ; MACRO DEFINITION.) ; ; RESULT = -3 FOR SWITCH PROCESSING ERROR ; = -4 FOR WILDCARD'ED FILE SPEC ; = -7 FOR BOTH OF THE ABOVE ; = 12 (LINE FEED) FOR END OF COMMAND STRING ; = 0 IF NO ERRORS ; ; 4. THIS MODULE MAY BE USED TO PROCESS SWITCH TABLES CONTAINING ; MORE THAN 16 SWITCHES, PROVIDING THE FOLLOWING CONDITIONS ; ARE MET: ; ; A) THE LINE MULTAB=0 MUST EXIST IN THE USER'S SWITCH ; TABLE DATA BASE FILE. ; ; B) THE VECTOR ISWIT IS SIZED WITH TWO WORDS FOR EACH ; GROUP OF 16 SWITCHES OR LESS IN THE LARGEST SWITCH TABLE. ; ISWIT(ODD OR EVEN) IS EQUIVALENT TO ISWIT(1 OR 2) FOR ; EACH 16 SWITCH GROUP. ; ; C) THE TASK IN WHICH THIS ASSEMBLED MODULE IS USED IS ; BUILT WITH A VERSION OF MODULE .CSI2 CONTAINING ; THE GAC MULTAB PATCH, AS APPLIED IN ; CADCSI2.MAC. ; ; GET SWITCH PARAMETERS ; ; LOGICAL PRESEN,POLAR,GETSWT ; INTEGER VDEF(L),VKEY(N+1),VWRD(N),TABN,ISWIT(2),OSWIT(2) ; BYTE VBYT(M+1),NAME(K) ; ; PRESEN=GETSWT(ISWIT,TABN,NAME,VDEF,POLAR,VKEY,VWRD,VBYT,OSWIT) ; ; WHERE: K = LENGTH OF SWITCH NAME TO BE TESTED (K MUST BE EVEN) ; L = NUMBER OF NUMERIC VALUES FOR SWITCH TO BE TESTED ; M = MAXIMUM OVER ALL SWITCHES OF THE SUM OF ASCII VALUE ; (CHARACTER+1) COUNTS ; N = MAXIMUM NUMBER OF VALUES ASSOCIATED ; WITH ANY SWITCH TO BE TESTED ; ; INPUTS: ISWIT = SWITCH PARAMETER VECTOR FROM GETFIL ; ; TABN = SWITCH TABLE NUMBER TO SEARCH, SAME AS TO GETFIL ; ; NAME = NAME OF SWITCH TO TEST ENDING WITH A NULL IF ; SWITCH NAME HAS AN ODD NUMBER OF CHARACTERS ; ; VDEF = A VECTOR OF DEFAULT VALUES FOR THE SWITCH BEING ; TESTED. ITS LENGTH (L) IS DETERMINED BY THE ; NUMBER OF NUMERIC VALUES ASSOCIATED WITH THE ; SWITCH BEING TESTED. ; ; OUTPUTS: PRESEN = A LOGICAL VALUE RETURNED BY THE GETSWT FUNCTION ; THAT DEFINES WHETHER THE SWITCH BEING TESTED WAS ; PRESENT ; ; POLAR = A LOGICAL VALUE RETURNED TO INDICATE THE POLARITY ; OF THE TESTED SWITCH. IF PRESEN IS .TRUE. THEN ; POLAR IS .TRUE. IF THE SWITCH WAS ASSERTED, AND ; .FALSE. IF IT WAS NEGATED. ; ; VKEY = A VECTOR INDICATING THE VALUES IN THE SWITCH ; SPECIFICATION. THE LENGTH OF VKEY IS DETERMINED ; BY THE LARGEST NUMBER OF VALUES ; ASSOCIATED WITH ANY SWITCH TO BE TESTED. ; ; VKEY(I)=1 => SWITCH VALUE IS IN VWRD(I) ; VKEY(I)>1 => ASCII SWITCH VALUE STARTS AT ; VBYT(VKEY(I)) AND ENDS WITH A NULL ; VKEY(I)=0 => NO MORE VALUES ; VKEY(I)<0 => VALUE WAS NOT SPECIFIED ; -1 => NUMERIC VALUE NOT SPECIFIED ; -2 => STRING VALUE NOT SPECIFIED ; ; VWRD = A VECTOR OF NUMERIC SWITCH VALUES EXTRACTED FROM ; THE SWITCH SPECIFICATION. THE LENGTH OF VWRD IS ; DETERMINED IN THE SAME WAY AS VKEY. ; ; VWRD(I) = SWITCH VALUE IF VKEY(I)=1 ; VWRD(I) = DONT CARE IF VKEY(I)#1 ; ; VBYT = A VECTOR OF ASCII STRING SWITCH VALUES. EACH ; VALUE STRING ENDS WITH A NULL CHARACTER. A STRING ; VALUE STARTS AT VBYT(VKEY(I)) WHEN VKEY(I)>1. ; VBYT MUST BE LARGE ENOUGH TO CONTAIN ALL THE ; CHARACTERS CONTAINED IN ALL ASCII VALUES ; ASSOCIATED WITH A SWITCH, PLUS ROOM FOR THE ; NULL THAT ENDS EACH VALUE. ; ; OSWIT = A TWO WORD VECTOR INTO WHICH GETSWT PLACES THE ; VALUES IN ISWIT WITH THE MASK BIT ASSOCIATED WITH ; THE TESTED SWITCH CLEARED. OSWIT IS CHANGED ONLY ; IF THE TESTED SWITCH IS PRESENT IN THE FILE SPEC. ; ; IF SWITCHES IN A SECOND OR THIRD 16 SWITCH GROUP ; ARE TO BE TESTED, THE ISWIT AND OSWIT PARAMETERS ; TO GETSWT MUST CORRESPOND TO THE SWITCH GROUP ; CONTAINING THE SWITCH NAME. IF A SWITCH IS NAMED ; IN GROUP 2 OR 3 OF A SWITCH TABLE, THE ISWIT AND ; OSWIT PARAMETERS SHOULD BE ISWIT(3 OR 5) AND ; OSWIT(3 OR 5). ; ; WHEN A SWITCH IS TESTED, THE DEFAULT VALUES ARE USED TO RE-INITIALIZE ; THE SWITCH DATABASE SO THAT USER SPECIFIED VALUES CAN BE DETECTED ; IN SUBSEQUENT COMMANDS. ; ; ASCII VALUES ARE CLEARED TO BLANKS SO THAT SUBSEQUENT SPECIFICATION ; OF THE SAME SWITCH CAN DETERMINE WHERE THE USER'S PARAMETER LIST ENDS. ; ; SWITCHES THAT USE NUMERIC VALUES WILL BE SET TO THE VALUE OF THE ; CORRESPONDING DEFAULT IN VDEF (WITH THE SIGN BIT ON). IN THIS WAY ; ALL NUMERIC VALUES EXCEPT ADDRESSES CAN BE DISTINGUISHED FROM AN ; UNSPECIFIED PARAMETER WHEN THE SWITCH IS RESPECIFIED. ; ; FOR ADDRESSES, ALL VALUES REQUIRED FOR A COMMAND MUST BE SPECIFIED ; BY THE USER, AS THERE IS NO WAY TO DETECT THE ABSENCE OF A ; VALUE IN A SUBSEQUENT SPECIFICATION OF THE SAME SWITCH. ; ; AS A CONVENTION, THE CALLING PROGRAM COULD USE THE NEGATION OF ; A SWITCH TO INDICATE THAT OLD PARAMETER VALUES ARE TO BE USED. ; ;- .NLIST ; ; MACRO CALLS ; .MCALL GCMLB$,GCML$ .MCALL CSI$,CSI$SW,CSI$SV,CSI$ND,CSI$1,CSI$2 .MCALL QIOW$,QIOW$S,DIR$,GLUN$C,ALUN$S .MCALL OLDPST,GCMLDF,SWTSRT,SWTEND,SWTNEG .MCALL SWTVAL,GENVAL,TMSGDF,CERRDF,FTYPDF ; ; PSECT DEFINITIONS ; .PSECT $CODE1,REL,RO,I,CON,LCL .PSECT $PDATA,REL,RO,D,CON,LCL .PSECT $IDATA,REL,RW,D,CON,LCL .PSECT $VARS,REL,RW,D,CON,LCL .PSECT $SWTDF,REL,RO,D,CON,LCL .PSECT SWTVAL,REL,RW,D,OVR,GBL .PSECT $SWTVL,REL,RO,D,CON,LCL .PSECT $SWTBL,REL,RO,D,OVR,GBL .PSECT $SWTMK,REL,RW,D,CON,LCL ; CSI$ ; ; PASS NUMBER SYMBOL ; .IF NDF PASS PASS=0 .ENDC PASS=PASS+1 ; ; SYSTEM MACRO EQUATES ; GERR=GCMD+G.ERR GMODE=GCMD+G.MODE GCMLD=GCMD+G.CMLD GCBUF=GCMD+G.DPRM-2 GSIZE=GCMD+G.SIZE CCMLD=CSIBF+C.CMLD CSTAT=CSIBF+C.STAT CDIRD=CSIBF+C.DIRD CFILD=CSIBF+C.FILD CDEVD=CSIBF+C.DEVD CSWAD=CSIBF+C.SWAD CMKW1=CSIBF+C.MKW1 CMKW2=CSIBF+C.MKW2 ; ; LOCAL EQUATES ; CMDSZ=2. ;LENGTH OF GCML COMMAND BUFFER (DUMMY BUFFER) NEWLIN=12 ;LINE FEED CHARACTER CODE SWTERR=-3 ;SWITCH ERROR CODE OK=0 ;NORMAL GETFIL RETURN ISTB=10 ;SWITCH TABLE OFFSET FOR GETFIL IDIR=6 ;INPUT/OUTPUT DIRECTION PARAM OFFSET FOR GETFIL ISWT=4 ;SWITCH PARAM OFFSET FOR GETFIL IFIL=2 ;FILE PARAM OFFSET FOR GETFIL GBUF=2 ;BUFFER OFFSET FOR GETCMD GLEN=4 ;LENGTH OFFSET FOR GETCMD GSKP=6 ;SKIP COUNT OFFSET FOR GETCMD CBUF=2 ;BUFFER OFFSET FOR CHKSYN CLEN=4 ;LENGTH OFFSET FOR CHKSYN WLDERR=-4 ;WILDCARD STATUS CODE DFLNG=9. ;DEFAULT UIC STRING LENGTH .IF EQ PASS-1 SWTNUM=0 ;INITIALIZE NUMBER OF SWITCH DESCRIPTOR TABLES MASKAD=0 ;SET INITIAL MASK WORD ADDRESS (NONE) .ENDC ;IN PASS 1 ONLY ; PARAMETER ADDRESS OFFSETS IN GETSWT CALLING SEQUENCE ISWIT=2 ;SWITCH FLAGS FROM GETFIL TABN=4 ;SWITCH TABLE NUMBER, SAME AS INPUT TO GETFIL NAME=6 ;SWITCH NAME VDEF=10 ;DEFAULT VALUE VECTOR POLAR=12 ;SWITCH POLARITY VKEY=14 ;SWITCH VALUE KEY VECTOR VWRD=16 ;SWITCH VALUE WORD VECTOR VBYT=20 ;ASCII SWITCH VALUE STRING VECTOR OSWIT=22 ;SWITCH FLAGS WITH TESTED SWITCH BIT CLEARED ; ; VARIABLE AND CONSTANT DEFINITIONS ; .PSECT $SWTBL SWTBLS: ;SET STARTING ADDRESS OF SWITCH TABLE ADDRESS LIST .PSECT $VARS BYTAD: .WORD 0 ;ADDRESS OF ASCII STRING VECTOR - 1 BASWIT: .WORD 0 ;BASE ADDRESS OF LAST SWITCH TABLE SCANNED .PSECT $PDATA NLADR: .ASCII /NL/ NLENG=.-NLADR .EVEN SYDEV: .WORD SYLNG .WORD SYADR SYADR: .ASCII /SY:/ SYLNG=.-SYADR .EVEN ; ; BEGINNING OF CODE ; .PSECT $CODE1 .ENABL LSB GETCMD:: MOV GBUF(R5),GCBUF ;USERS BUFFER ADDRESS TO GCML DATA STRUCTURE MOV @GLEN(R5),R0 ;GET BUFFER LENGTH MOV R0,GSIZE ;MOVE TO GCML STRUCTURE SUB #2,R0 ;REDUCE FOR GCML OVERHEAD BYTES BICB #GE.CON,GMODE ;CLEAR CONTINUATION BIT CMP R0,#80. ;CHECK SIZE OF USER BUFFER BLE 2$ ;BRANCH IF TOO SHORT FOR CONTINUATION BISB #GE.CON,GMODE ;SET CONTINUATION IF BIG ENOUGH 2$: TST DFDON ;TEST IF UIC SETUP DONE BNE 5$ ;YES, CONTINUE INC DFDON ;SET FLAG JSR PC,.RDFUI ;GET DEFAULT UIC MOV R1,R3 ;MOV IT TO R3 MOV #DFADR,R2 ;SET STRING ADDRESS IN R2 CLR R4 ;CLEAR CONTROL FLAGS JSR PC,.PPASC ;CONVERT UIC TO ASCII SUB #DFADR,R2 ;COMPUTE LENGTH OF STRING MOV R2,DFUIC ;SAVE IN UIC DESCRIPTOR .IF EQ PASS-1 ;IF PASS 1 .=.+12. ;LEAVE ROOM FOR NEXT TWO INSTRUCTIONS .IFF ;ELSE DURING PASS 2 .IF DF LOCASE ;IF USER WANTS LOWER CASE IN COMMAND LINE BISB #GE.LC,GMODE ;SET LOWER CASE MODE BIT .IFF ;ELSE BICB #GE.LC,GMODE ;FORCE UPPER CASE ONLY .ENDC ;DF LOCASE .IF DF COMENT ;IF USER WANTS COMMENTS PASSED TO CALLER BICB #GE.COM,GMODE ;CLEAR COMMENT SUPPRESS BIT .IFF ;ELSE BISB #GE.COM,GMODE ;SET COMMENT SUPPRESS BIT .ENDC ;DF COMENT .ENDC ;EQ PASS-1 5$: ALUN$S #CMDLUN,LUNDAT,LUNDAT+2 ;ASSIGN COMMAND DEVICE TO LUN 6$: MOV GBUF(R5),R0 ;GET COMMAND BUFFER ADDRESS MOV #-2,R1 ADD @GLEN(R5),R1 ;GET LENGTH-2 10$: CLRB (R0)+ ;CLEAR BUFFER SOB R1,10$ ;LOOP GCML$ #GCMD ;GET A COMMAND BCC 40$ ;IF CC, SKIP ERROR TESTS MOVB GERR,R0 ;GET ERROR FLAG FROM GCML CMPB #GE.EOF,R0 ;TEST FOR CTRL Z BNE 20$ ;IF NOT SET, CONTINUE TST R0 ;SET UP EOF RETURN AS 4 BYTE INTEGER SXT R1 RTS PC 20$: CLR R1 ;CLEAR MESSAGE POINTER CMPB #GE.BIF,R0 ;TEST FOR ERROR BEQ 30$ ;IF SET, FOUND ERROR INC R1 ;BUMP MESSAGE POINTER CMPB #GE.MDE,R0 BEQ 30$ INC R1 CMPB #GE.RBG,R0 BEQ 30$ INC R1 CMPB #GE.IOR,R0 BEQ 30$ INC R1 CMPB #GE.OPR,R0 BNE 40$ 30$: ASL R1 ;DOUBLE POINTER MOV GEERSM(R1),R0 ;GET MESSAGE ADDRESS MOV GEERSL(R1),R1 ;GET MESSAGE LENGTH QIOW$S #IO.WVB,#TILUN,#QIOEFG,,,, BR 6$ 40$: MOV GCMLD+2,@GSKP(R5) ;ADDRESS OF START OF COMMAND TEXT SUB GBUF(R5),@GSKP(R5) ;SUBTRACT BASE OF USER BUFFER MOV GCMLD,R0 ;SET UP RETURN LENGTH SXT R1 ;AS A DOUBLE PRECISION VALUE GLUN$C CMDLUN,LUNDAT,$CODE1 ;SAVE LUN ASSIGNMENT DATA CLRB LUNDAT+3 RTS PC CHKSYN:: MOV @CLEN(R5),CCMLD ;SET UP CSI COMMAND LENGTH MOV CBUF(R5),CCMLD+2 ;AND ADDRESS CSI$1 #CSIBF MOV CCMLD,R0 ;GET COMMAND LINE LENGTH BCC 60$ ;IF CC, CONTINUE MOV CFILD+2,R0 ;GET COMMAND LINE LENGTH UP TO ERROR SUB CBUF(R5),R0 ADD CFILD,R0 NEG R0 ;MAKE IT NEGATIVE 60$: SXT R1 ;EXTEND RETURN INTEGER CLR OUTCTR ;CLEAR OUTPUT FILE CTR RTS PC ;RETURN .DSABL LSB .ENABL LSB GETFIL:: CLR CSWAD ;ASSUME NO SWITCHES MOV @ISTB(R5),R1 ;GET SWITCH TABLE POINTER BLE 5$ ;BRANCH IF NO SWITCHES EXPECTED CMP R1,#SWTNUM ;COMPARE WITH NUMBER OF SWITCH TABLES BGT 5$ ;POINTER TOO LARGE, USE NONE DEC R1 ;DECREMENT POINTER ASL R1 ;DOUBLE IT MOV SWTBLS(R1),CSWAD ;GET SWITCH TABLE ADDRESS TO CSI 5$: MOV CSWAD,BASWIT ;SAVE ADDRESS OF LAST TABLE SCANNED MOV #OK,RTNVAL ;CLEAR RETURN VALUE TST @IDIR(R5) ;GET DIRECTION PARAMETER BEQ INFILE ;IF ZERO, GET INPUT SPEC OTFILE: CSI$2 #CSIBF,OUTPUT BCC 10$ ;TEST FOR SWITCH ERRORS MOV #SWTERR,RTNVAL ;SET ERROR RETURN VALUE 10$: INC OUTCTR ;COUNT OUTPUT FILES CMP OUTCTR,#TYPNUM ;TEST FOR TOO MANY BLE 20$ ;OK MOV #TYPNUM,OUTCTR ;CLAMP AT MAXIMUM 20$: MOV CDIRD,-(SP) ;SAVE DIRECTORY STRING LENGTH MOV CFILD,-(SP) ;SAVE FILE STRING LENGTH MOV CDEVD,-(SP) ;SAVE DEVICE DESCRIPTOR MOV CDEVD+2,-(SP) BITB #CS.WLD,CSTAT ;TEST FOR WILDCARD SPECIFIER BEQ 25$ ;IF EQ, CONTINUE ADD #WLDERR,RTNVAL ;INDICATE WILDCARD ERROR 25$: BITB #CS.NMF!CS.DIF!CS.DVF,CSTAT ;TEST FOR ANY FILE SPEC BNE 30$ ;CONTINUE FOR OUTPUT FILE CLR CDIRD ;CLEAR DIRECTORY SPEC CLR CFILD ;CLEAR FILE SPEC MOV #NLENG,CDEVD ;SET DEVICE TO NL: MOV #NLADR,CDEVD+2 BITB #CS.MOR,CSTAT ;ANY MORE OUTPUT FILES BNE 30$ ;IF NE, YES CMP #OK,RTNVAL ;TEST FOR PREVIOUS ERRORS BNE 30$ ;YES, SAVE THEM MOV #NEWLIN,RTNVAL ;ELSE, RETURN NEWLINE 30$: MOV OUTCTR,TYPPTR ;SET DEFAULT FILE TYPE POINTER MOV IFIL(R5),R1 ;GET FILE PARAM ADDRESS BR 50$ INFILE: CSI$2 #CSIBF,INPUT BCC 40$ ;TEST FOR SWITCH ERRORS MOV #SWTERR,RTNVAL ;SET ERROR RETURN VALUE 40$: MOV CDIRD,-(SP) ;SAVE DIRECTORY STRING LENGTH MOV CFILD,-(SP) ;SAVE FILE STRING LENGTH MOV CDEVD,-(SP) ;SAVE DEVICE DESCRIPTOR MOV CDEVD+2,-(SP) BITB #CS.WLD,CSTAT ;TEST FOR WILCARD SPECIFIER BEQ 45$ ;IF EQ, CONTINUE ADD #WLDERR,RTNVAL ;INDICATE WILDCARD ERROR 45$: MOV IFIL(R5),R1 ;GET FILE PARAM ADDRESS CLR TYPPTR ;CLEAR DEFAULT FILE TYPE POINTER BITB #CS.NMF!CS.DIF!CS.DVF,CSTAT BNE 50$ ;CONTINUE FOR INPUT FILE BITB #CS.MOR,CSTAT ;TEST FOR FOR INPUT FILES BNE 90$ ;IF CS.MOR SET, MORE FILES MOV #NEWLIN,RTNVAL ;SET END OF COMMAND LINE BR 90$ ;PACK SWITCHES 50$: MOV #CDEVD,R2 ;GET ADDRESS OF DEVICE DESC TST (R2) ;IF NO DEVICE STRING BNE 52$ MOV #SYDEV,R2 ;FORCE SY: 52$: JSR PC,MOVSTG ;OUTPUT DEVICE STRING TST CDEVD ;TEST FOR DEVICE NAME SPECIFIED BEQ 55$ ;IF EQ, CONTINUE MOVB #72,(R1)+ ;OUTPUT DEVICE DELIMITER ':' 55$: MOV #CDIRD,R2 ;GET ADDRESS OF UIC DESC TST (R2) ;IF NO UIC STRING BNE 57$ MOV #DFUIC,R2 ;FORCE DEFAULT 57$: JSR PC,MOVSTG ;OUTPUT UIC STRING TST CFILD ;TEST LENGTH OF FILE STRING BEQ 90$ ;IF ZERO, FINISH FILE SPEC MOV CFILD+2,R3 ;GET FILE STRING ADDRESS MOV CFILD,R2 ;GET FILE STRING LENGTH CLR DOTFLG ;CLEAR EXTENSION FLAG 60$: CMPB #73,(R3) ;TEST NEXT CHARACTER FOR ';' BNE 70$ ;IF NE, CONTINUE JSR PC,INSTYP ;FORCE FILE TYPE BEFORE ';' 70$: MOVB (R3)+,R0 ;GET NEXT CHARACTER MOVB R0,(R1)+ ;OUTPUT TO FILE STRING CMPB #56,R0 ;COMPARE WITH '.' BNE 80$ ;IF NE, CONTINUE INC DOTFLG ;SET EXTENSION FLAG 80$: SOB R2,60$ ;LOOP JSR PC,INSTYP ;INSERT DEFAULT FILE TYPE 90$: CLRB (R1) ;PACK A NULL INTO STRING MOV ISWT(R5),R1 ;GET SWITCH PARAMETER ADDRESS .IF EQ PASS-1 ;IF PASS 1 .=.+10. ;LEAVE ROOM FOR NEXT THREE INSTRUCTIONS .IFF ;ELSE .IF DF MULTAB ;IF ALLOWING MULTIPLE SWITCH MASKS MOV BASWIT,R0 ;POINT AT SWITCH DESCRIPTOR TABLE BEQ 100$ ;IF ZERO, NO SWITCH TABLE JSR PC,MVMSKS ;MOVE SWITCH MASKS AND POLARITIES TO USER SPACE .IFF ;ELSE, ONLY ONE SWITCH MASK MOV CMKW1,(R1)+ ;OUTPUT SWITCH MASK MOV CMKW2,(R1) ;OUTPUT SWITCH POLARITY NOP ;PAD TO SAME LENGTH AS .IFT CODE ABOVE .ENDC ;DF MULTAB .ENDC ;EQ PASS-1 100$: MOV (SP)+,CDEVD+2 ;RESTORE DEVICE DESCRIPTOR MOV (SP)+,CDEVD MOV (SP)+,CFILD ;RESTORE FILE STRING LENGTH MOV (SP)+,CDIRD ;RESTORE DIRECTORY STRING LENGTH MOV RTNVAL,R0 ;SET UP RETURN VALUE SXT R1 ;SIGN EXTEND RTS PC ;RETURN .DSABL LSB .ENABL LSB MOVSTG: MOV 2(R2),R3 ;GET STRING ADDRESS MOV (R2),R2 ;GET STRING LENGTH 10$: MOVB (R3)+,(R1)+ ;MOVE A CHARACTER SOB R2,10$ ;LOOP RTS PC ;RETURN .DSABL LSB .ENABL LSB INSTYP: TST DOTFLG ;TEST FOR PREVIOUS TYPE BNE 20$ INC DOTFLG ;SET EXTENSION FLAG MOV R3,-(SP) ;SAVE R3 MOV R2,-(SP) ;SAVE R2 MOV #TYPLEN,R2 ;GET EXTENSION LENGTH MOV TYPPTR,R3 ;GET EXTENSION POINTER ASL R3 ;DOUBLE IT MOV TYPTAB(R3),R3 ;GET ADDRESS OF EXTENSION 10$: MOVB (R3)+,(R1)+ ;MOVE A CHARACTER SOB R2,10$ ;LOOP MOV (SP)+,R2 ;RESTORE R2 MOV (SP)+,R3 ;RESTORE R3 20$: RTS PC ;RETURN .DSABL LSB .ENABL LSB MVMSKS: CLR (R1) ;CLEAR SWITCH PRESENT WORD 10$: TST (R0)+ ;TEST SWITCH NAME WORD BEQ 50$ ;IF ZERO, END OF SWITCHES, EXIT BMI 10$ ;IF NEGATIVE, MORE FOLLOWS TST (R0)+ ;SKIP OVER SWITCH MASK WORD 20$: MOV (R0),R2 ;GET SWITCH MASK WORD ADDRESS BIC #1,R2 ;CLEAR 'SET'/'CLEAR' BIT MOV (R2),(R1)+ ;MOVE SWITCH PRESENT MASK MOV 2(R2),(R1)+ ;MOVE SWITCH POLARITY WORD 30$: ADD #4,R0 ;POINT TO NEXT SWITCH TABLE ENTRY 40$: TST (R0)+ ;TEST SWITCH NAME WORD BEQ 50$ ;IF ZERO, END OF SWITCHES, EXIT BMI 40$ ;IF NEGATIVE, MORE FOLLOWS TST (R0)+ ;SKIP OVER SWITCH MASK WORD MOV (R0),-(SP) ;SAVE SWITCH MASK ADDRESS BIC #1,(SP) ;CLEAR 'SET'/'CLEAR' BIT CMP (SP)+,R2 ;COMPARE WITH LAST MASK ADDRESS BEQ 30$ ;IF EQ, CHECK NEXT SWITCH BR 20$ ;ELSE, SAVE NEXT SET OF MASK WORDS 50$: RTS PC ;DONE, EXIT .DSABL LSB .ENABL LSB GETSWT:: MOV R1,-(SP) ;SAVE REGISTERS MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) CLR R0 ;ASSUME SWITCH NOT PRESENT MOV @TABN(R5),R1 ;GET TABLE NUMBER BLE LEAVE ;BAD IF .LE. 0, EXIT DEC R1 ;SUBTRACT 1 ASL R1 ;DOUBLE TO FORM INDEX MOV SWTBLS(R1),R1 ;GET SWITCH TABLE ADDRESS 10$: TST (R1) ;TEST FOR END OF SWITCH TABLE BEQ LEAVE ;END OF TABLE, NO MATCH, EXIT MOV NAME(R5),R2 ;GET NAME STRING ADDRESS MOV R1,R3 ;INITIALIZE WORKING REGISTER 20$: ;SKIP R1 TO END OF SWITCH NAME TST (R1)+ ;TEST WORD OF SWITCH NAME BMI 20$ ;NOT LAST WORD, CONTINUE 30$: CMP R1,R3 ;TEST FOR END OF SWITCH NAME BEQ 40$ ;GOT A MATCH MOVB (R3)+,R4 ;GET A CHARACTER FROM DATABASE BIC #177600,R4 ;CLEAR UPPER BIT OF CHARACTER CMPB R4,(R2)+ ;COMPARE WITH SWITCH NAME BEQ 30$ ;STILL A POSSIBLE MATCH ADD #6,R1 ;NO MATCH, MOVE TO NEXT ENTRY BR 10$ ;TEST NEXT ENTRY 40$: ;HERE FOR A MATCH, R1 POINTS TO FLAG WORD MOV ISWIT(R5),R2 ;GET ADDRESS OF SWITCH FLAGS BIT (R1),(R2) ;TEST FOR SWITCH PRESENT BEQ LEAVE ;BRANCH IF NOT PRESENT, EXIT MOV OSWIT(R5),R3 ;GET ADDRESS OF OSWIT VECTOR MOV (R2)+,(R3) ;MOVE MASK WORD BIC (R1),(R3)+ ;CLEAR MASK BIT MOV (R2),(R3) ;MOVE SECOND WORD, UNCHANGED MOV #-1,R0 ;SET SWITCH PRESENT CLR @POLAR(R5) ;ASSUME SWITCH NEGATED BIT (R1)+,(R2) ;TEST POLARITY BIT BEQ 50$ MOV R0,@POLAR(R5) ;SET SWITCH POLARITY TRUE 50$: BIT #1,(R1)+ ;TEST LSB OF MASK WORD ADDRESS BEQ 60$ ;IF SET, CLEAR FUNCTION COM @POLAR(R5) ;SO COMPLEMENT SWITCH POLARITY 60$: MOV (R1),R1 ;POINT TO SWITCH VALUE DESCRIPTORS CLR @VKEY(R5) ;ASSUME NO VALUES BIC #1,R1 ;CLEAR NEGATION ENABLE FLAG BEQ LEAVE ;IF ZERO, NO VALUES, EXIT MOV R0,-(SP) ;SAVE R0, RETURN VALUE MOV VDEF(R5),R0 ;POINT R0 TO DEFAULT VALUES MOV VKEY(R5),R2 ;POINT R2 TO KEY VECTOR MOV VWRD(R5),R3 ;POINT R3 TO WRD VECTOR MOV VBYT(R5),R4 ;POINT R4 TO BYT VECTOR MOV R4,BYTAD ;SAVE BYT BASE ADDRESS DEC BYTAD ;DECREMENT IT CLRB (R4)+ ;CLEAR FIRST DATA BYTE MOV R5,-(SP) ;SAVE R5 NXTVAL: ;DO NEXT SWITCH VALUE TST (R1) ;TEST FOR END OF SWITCH VALUES BEQ ENDVAL ;END OF VALUES, DO CLEANUP MOVB (R1)+,R5 ;GET SWITCH TYPE DEC R5 ;SUBTRACT 1 ASL R5 ;DOUBLE TO FORM INDEX JMP @TBL(R5) ;DISPATCH TO PROCESS VALUE TBL: .WORD ASCII .WORD OCTAL .WORD DECIM .WORD HEX ENDVAL: CLR (R2) ;END OF VALUE LIST MOV (SP)+,R5 ;RESTORE R5 MOV (SP)+,R0 ;RESTORE R0 LEAVE: MOV (SP)+,R4 ;RESTORE REGISTERS MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 RTS PC ;RETURN ASCII: ;PROCESS ASCII VALUE TST (R3)+ ;BUMP WRD VECTOR ADDRESS MOV R4,R5 ;GET NEXT BYTE ADDRESS SUB BYTAD,R5 ;SUBTRACT BASE -1 MOV R5,(R2) ;STORE INDEX INTO KEY VECTOR MOVB (R1)+,R5 ;GET VALUE LENGTH MOV R1,-(SP) ;SAVE DESCRIPTOR POINTER MOV (R1),R1 ;GET VALUE ADDRESS CMPB #40,(R1) ;IF STILL BLANK, NO NEW PARAMETER BNE 70$ ;NOT BLANK, CONTINUE MOV #-2,(R2) ;SET KEY NEGATIVE BR 80$ ;FINISH UP 70$: MOVB (R1),(R4) ;MOVE A CHARACTER MOVB #40,(R1) ;BLANK OUT STRING CMPB (R1)+,(R4) ;TEST FOR BLANK BEQ 75$ ;IF BLANK, DONT MOVE POINTER TSTB (R4)+ ;NON-BLANK, COUNT IT 75$: SOB R5,70$ ;DO NEXT CHARACTER CLRB (R4)+ ;STORE A NULL BYTE 80$: MOV (SP)+,R1 ;RESTORE R1 TST (R1)+ ;BUMP R1 PAST VALUE ADDRESS TST (R2)+ ;BUMP R2 OVER KEY VALUE BR NXTVAL OCTAL: ;PROCESS OCTAL OR HEX: ;HEX VALUE TSTB (R1)+ ;SKIP VALUE LENGTH, = 2 BYTES MOV #1,(R2) ;SET VALUE FLAG IN KEY VECTOR MOV R1,-(SP) ;SAVE DESCRIPTOR POINTER MOV (R1),R1 ;GET VALUE ADDRESS MOV (R1),(R3)+ ;GET VALUE TO WORD VECTOR MOV (R0)+,(R1) ;MOVE DEFAULT VALUE BR 80$ DECIM: ;PROCESS DECIMAL VALUE TSTB (R1)+ ;SKIP VALUE LENGTH, = 2 BYTES MOV #1,(R2) ;SET VALUE FLAG IN KEY VECTOR MOV R1,-(SP) ;SAVE DESCRIPTOR POINTER MOV (R1),R1 ;GET VALUE ADDRESS MOV (R1),(R3) ;GET VALUE TO WORD VECTOR MOV (R0)+,(R1) ;MOVE DEFAULT VALUE BIS #100000,(R1) ;SET SIGN BIT CMP (R3),(R1) ;COMPARE DEFAULT TO VALUE BNE 90$ ;CONTINUE NEG (R2) ;COMPLEMENT KEY VALUE BIC #100000,(R3) ;CLEAR SIGN BIT 90$: TST (R3)+ ;BUMP VWRD ADDRESS BR 80$ .DSABL LSB .LIST