SUBROUTINE READIT C C PURPOSE: READS ASCII COMMAND LINE FROM UNIT # LUNCMD (EITHER TERMINAL, C UNIT #LUNTI, OR FILE OPENED BY "LOAD" COMMAND ON UNIT #LUNFIL--MUST BE C DEFINED PRIOR TO CALL), DELETES EMBEDDED SPACES FROM COMMAND (EXCEPT C "" FIELDS), AND CHECKS FOR A REAL # IN FIRST PART OF COMMAND. C C IF NUMBER IS FOUND AND UNDER KEYBOARD CONTROL (PROGRAM "STATE"=0), C DECODED # IS MOVED INTO X REGISTER IN /STACK/ COMMON. C IF NUMBER IS FOUND AND LOADING MEMORY FROM KEYBOARD OR FILE C ("STATE">0), NUMBER IS PRECEEDED BY INTERNAL CODE FOR THE "CONSTANT" C COMMAND (CURRENTLY # 120) AND PACKED AS 9 BYTES INTO CMND IN /COMAND/ C COMMON. NOTE:THE "CONSTANT" COMMAND WILL LOAD X REGISTER WHEN EXECUTED C UNDER PROGRAM CONTROL ("STATE"<0). READIT THEN CALLS REPLCE TO LOAD C THE "CONSTANT" COMMAND INTO PROGRAM MEMORY. C C ONCE LEADING NUMBER IS DEALT WITH, CHECK IF ANYTHING STILL LEFT C TO INTERPRET. IF YES AND UNDER KEYBOARD CONTROL ("STATE"=0), C INTERCEPT ANY SINGLE CHARACTER COMMAND TO SEE IF IT IS AN ALPHA C CHARACTER. IF HAVE SINGLE ALPHA CHARACTER, FIND CORRESPONDING C CHARACTER ASSOCIATED WITH THE "LABEL" COMMAND IN MEMORY AND C START PROGRAM EXECUTION FROM THERE (SET "STATE"<0). C C IF COMMAND IS LONGER THAN 1 CHARACTER, OR LOADING MEMORY, C REPACK THE COMMAND INTO CMND IN /COMAND/ COMMON AND LET NEXT C ROUTINE TRY AND DECIPHER IT. C C NOTE: WHENEVER "LENGTH" IN /COMAND/ COMMON IS > 0, CMND IS ASSUMED C TO BE AN ASCII STRING READY FOR CODING TO INTERNAL FORM; WHEN C "LENGTH" IS < 0, CMND IS ASSUMED TO CONTAIN AN INTERNALLY CODED C COMMAND. ABSOLUTE VALUE OF LENGTH IS BYTE COUNT OF STRING OR CODED C COMMAND. C C DESCRIPTION OF VARIABLES: C LUNCMD -COMMON INTEGER VARIABLE SPECIFIES UNIT NUMBER TO READ C LUNTI -UNIT # CURRENTLY ASSIGNED TO TI: C LUNFIL -UNIT # CURRENTLY ASSIGNED FOR FILE I/O C LENGTH -COMMON INTEGER VARIABLE SET TO CURRENT COMMAND LENGTH C LCMND -LOCAL VARIABLE DEFINING CURRENT LIMIT FOR "LENGTH" C CMND -COMMON BYTE ARRAY FOR COMMAND C X -COMMON DOUBLE PRECISION VALUE FOR NUMBER ENTERED UNDER C KEYBOARD CONTROL C ERROR -COMMON BYTE FLAG SET < 0 ON ERROR C STKLFT -COMMON BYTE FLAG ENABLING (<0>) OF DISABLING (=0) STACK LIFT C ON NEXT NUMERIC ENTRY. C STATE -COMMON BYTE FLAG; SET TO 0 FOR KEYBOARD CONTROL, C SET +VE TO LOAD PROGRAM MEMORY, SET +VE TO RUN C PROGRAM FROM INTERNAL MEMORY. C PC -COMMON INTEGER VARIABLE POINTING TO CURRENT PROGRAM STEP C NSTEPS -LOCAL INTEGER DEFINING CURRENT MAX # PROGRAM STEPS C P -COMMON BYTE ARRAY CONTAINING INTERNAL PROGRAM MEMORY C CNST -LOCAL BYTE VARIABLE SET TO CODE # CURRENTLY ASSIGNED C FOR THE "CONSTANT" COMMAND. C DTEMP -DOUBLE PRECISION VARIABLE TO HOLD DECODED # RETURNED BY "GETX" C DBLEX -BYTE ARRAY EQUIVALENCED TO DTEMP SO CAN REPACK BYTES OF C NUMBER ON OFF-WORD BOUNDARIES. C AAA,ZZZ,LCA,LCZ -DEFINE ASCII LIMITS FOR ALPHABETIC CHARACTERS C BUFFER -TEMPORARY STORAGE OF ASCII COMMAND STRING WHILE IT'S BEING C INTERPRETTED C C C SORENSON 2/81 C COMMON/UNIT/LUNCMD,LUNOUT,LUNTI,LUNFIL COMMON/FLAGS/STATE,ERROR,STKLFT,NEST,ANGLES,DIGITS,RADIX,FLAG(4) BYTE FLAG,STATE,ERROR,STKLFT,NEST,ANGLES,RADIX,DIGITS COMMON/COMAND/LENGTH,CMND(40) BYTE CMND COMMON/MEMORY/PC,P(1000) INTEGER PC BYTE P COMMON/STACK/X,Y,Z,T,XLST DOUBLE PRECISION X,Y,Z,T,XLST C C LOCAL VARIABLES C DOUBLE PRECISION DTEMP EQUIVALENCE (DBLEX,DTEMP) BYTE DBLEX(8),BUFFER(80),CNST,LCA,LCZ,AAA,ZZZ C C DEFINE SOME LOCAL CONSTANTS C DATA CNST/120/,NSTEPS/1000/,LCMND/40/,LCA/"141/,LCZ/"172/, 1AAA/'A'/,ZZZ/'Z'/ C C FETCH LINE FROM "LUNCMD" C 5 READ(LUNCMD,6,END=110)L,(BUFFER(I),I=1,80) 6 FORMAT(Q,80A1) IF(L.LE.0)GO TO 100 C C DELETE EMBEDDED SPACES--SPECIAL CASE: FOR STRING ENCLOSED BY "'S C SPACES WILL NOT BE REMOVED...SEE COMMENTS IN CMPRES.FTN C 10 CALL CMPRES(L,BUFFER) IF(L.LE.0)GO TO 100 C C SCAN FOR LEADING #, KEEP J AS POINTER TO NEXT CHARACTER IN C BUFFER FOR PROCESSING. THREE POTENTIAL RETURNS: 1) J < 0, ERROR; C 2)J = 1, NO # FIELD; 3) J > 1, NUMBER DECODED IN DTEMP. C 15 J=1 CALL GETX(L,J,BUFFER,DTEMP) IF(J.LT.1)GO TO 99 D WRITE(LUNTI,990)(BUFFER(I),I=1,L) D WRITE(LUNTI,991)L,J,(BUFFER(I),I=J,L) D WRITE(LUNTI,992) D990 FORMAT(' COMMAND = ',40A1) D991 FORMAT(' LENGTH = ',I3,2X,' POINTER = ', D 1I3/' REMAINING COMMAND = ',40A1) D992 FORMAT(' PRESS RETURN TO CONTINUE') D READ(LUNTI,997) D997 FORMAT() IF(J.EQ.1)GO TO 40 C C # IN DTEMP--CHECK CURRENT PROGRAM STATE. C 20 IF(STATE.EQ.0)GO TO 30 C C LOADING MEMORY--PLACE # IN "CMND" PRECEEDED BY THE CODE # FOR C "CONSTANT" COMMAND (CURRENTLY 120). SET LENGTH C -VE TO INDICATE COMMAND IN INTERNAL, CODED FORMAT. C LENGTH=-9 CMND(1)=CNST DO 23 I=1,8 23 CMND(I+1)=DBLEX(I) C C NOW ACTUALLY LOAD MEMORY BY CALLING REPLCE TO REPLACE CURRENT COMMAND C STORED IN "P" POINTED TO BY "PC" WITH THE "CONSTANT" COMMAND. CHECK C ERROR FLAG ON RETURN, IF -VE CAN'T STORE COMMAND. LAST THING C TO DO IS SEE IF STILL STUFF TO LOOK AT IN "BUFFER" C CALL REPLCE IF(ERROR.LT.0)GO TO 96 IF(J.GT.L)GO TO 100 GO TO 40 C C UNDER KEYBOARD CONTROL-LOAD X-CHECK CURRENT STATUS OF "STKLFT" C TO DETERMINE IF SHOULD (STKLFT > 0) OR SHOULDN'T (STKLFT = 0) LIFT C THE STACK BEFORE LOADING X. IN EITHER CASE, REENABLE STACK LIFT C WHEN DONE. ALSO, SET DATA ENTRY FLAG 3 (FLAG(4)). C 30 IF(STKLFT.NE.0)CALL PUSH X=DTEMP STKLFT=1 FLAG(4)=1 IF(J.GT.L)GO TO 100 C C ALMOST DONE, INTERCEPT ANY SINGLE ALPHABETIC COMMAND IN BUFFER (J) C WHEN UNDER KEYBOARD CONTROL ("STATE"=0) PRIOR TO CHECKING C COMMAND AGAINST MASTER LIST. WHEN THIS OCCURS, CALL JUMPTO C TO SCAN CURRENT PROGRAM MEMORY FOR A "LABEL" COMMAND WITH MATCHING C CHARACTER. IF THIS LABEL IS FOUND, PROGRAM CONTROL IS TRANSFERED C TO PROGRAM MEMORY AND EXECUTION BEGINS AT STEP FOLLOWING LABEL C ENTRY ("STATE" < 0). C 40 IF(STATE.NE.0)GO TO 50 D WRITE(LUNTI,990)(BUFFER(I),I=1,L) D WRITE(LUNTI,991)L,J,(BUFFER(I),I=J,L) D WRITE(LUNTI,992) D READ(LUNTI,997) IF(J.NE.L)GO TO 50 IF(BUFFER(J).LT.AAA.OR.BUFFER(J).GT.LCZ)GO TO 50 IF(BUFFER(J).GT.ZZZ.AND.BUFFER(J).LT.LCA)GO TO 50 C C JUMPTO NEEDS TO KNOW WHAT "TYPE" OF LABEL TO LOOK FOR--SCANNING C FOR ALPHA LABEL WHICH IS CURRENTLY ASSIGNED "TYPE"=1, USE DBLEX(1) C AS TEMPORARY VARIABLE FOR "TYPE". C D WRITE(LUNTI,998) D998 FORMAT(' TRYING TO JUMP TO LABEL') DBLEX(1)=1 CALL JUMPTO(DBLEX(1),BUFFER(J)) C C IF "TYPE" (DBLEX(1)) RETURNED = 0, FAILED TO FIND MATCHING LABEL. C OTHERWISE, LET PROGRAM IN /MEMORY/ TAKE OVER. C IF(DBLEX(1).EQ.0)GO TO 94 STATE=-1 GO TO 101 C C AT LAST, CAN NOW CHECK COMMAND AGAINST CURRENT MASTER LIST. TO C DO THIS, MOVE REMAINING COMMAND STRING TO "CMND" IN /COMAND/ C COMMON WITH "LENGTH" > 0, AND EXIT--SOMEBODY ELSE WILL HANDLE C THE ACTUAL LOOKUP OF COMMAND. C 50 LENGTH=L-J+1 IF(LENGTH.GT.40)GO TO 98 DO 55 I=1,LENGTH CMND(I)=BUFFER(J) 55 J=J+1 RETURN C C ERROR HANDLING SECTION C FOLLOWING POTENTIAL ERRORS WILL SET "ERROR" -VE, AND CLEAR LENGTH C C ERROR -7 = INVALID LABEL REFERENCE, NO MATCHING LABEL FOUND IN MEMORY C 94 ERROR=-7 GO TO 101 C ERROR -1 = INSUFFICIENT PROGRAM SPACE, DID NOT LOAD "CONSTANT" COMMAND C INTO MEMORY 96 ERROR=-1 GO TO 101 C ERROR -2 = INVALID COMMAND, COMMAND LINE TOO LONG 98 ERROR=-2 GO TO 101 C ERROR -3 = INVALID NUMERIC STRING, "GETX" FAILED TO DECODE # 99 ERROR=-3 GO TO 101 C C EXIT WITH LENGTH=0 C 100 LENGTH=0 101 RETURN C C END-OF-FILE ENCOUNTERED ON INPUT...HANDLE IN THREE DIFFERENT WAYS. C 1) IF READING KEYBOARD (LUNCMD=LUNTI), SIMPLY EXIT C 2) IF READING FILE, CHECK PROGRAM STATE. C 2A)IF STATE = 2, READING FILE AFTER "LOAD" INITIATED FROM C KEYBOARD. RESET STATE=0, PC=1 C 2B)IF STATE = 3, READING FILE AFTER "LOAD" INITIATED FROM C PROGRAM. RESET STATE=-1, PC=1 -- ALLOWS AUTOMATIC C EXECUTION STARTING AT FIRST STEP OF CHAINED PROGRAM. C C 110 IF(LUNCMD.EQ.LUNTI)STOP CLOSE(UNIT=LUNFIL) PC=1 IF(STATE.EQ.3)GO TO 114 STATE=0 GO TO 100 114 STATE=-1 GO TO 100 END