.ENABL LSB ;ENABLE LOCAL SYMBOL BLOCK .TITLE SELECT .SBTTL DOCUMENTATION .IDENT /CS1.12/ ; ; *** CHANGES TO SELECT PROGRAM ; ; +----------------------------------------------------------+ ; | +------------------------------------------------------+ | ; | | | | ; | | P L E A S E | | ; | | | | ; | | IF YOU FIND AN ERROR, OR JUST WISH TO RELAY YOUR | | ; | | OPINIONS OR CRITICISMS TO THE AUTHOR OF THIS | | ; | | SOFTWARE, PLEASE FEEL FREE TO DO SO. I AM: | | ; | | | | ; | | CHARLIE SOUTH | | ; | | HUGHES RESEARCH LABS | | ; | | 3011 MALIBU CANYON ROAD | | ; | | MALIBU CA 90265 | | ; | | (213) 456-6411 | | ; | | | | ; | +------------------------------------------------------+ | ; +----------------------------------------------------------+ ; ; CS1.12 CHANGED 10/2/78 TO MODIFY SLIGHTLY THE PSECT DEFINITION TO ; BE COMPATIBLE WITH WHAT F4P EXPECTS TO SEE. THIS FIXES ; THE NUISANCE MESSAGE FROM TKB ABOUT "MULTIPLY DEFINED ; PSECT" SO THAT IT DOESN'T APPEAR (NEVER A FATAL ERROR). ; CS1.11 CHANGED 8/28/78 TO FIX ERROR WITH "$" LEADING CHARACTER AND THE ; ACTION TAKEN. PREVIOUSLY ASKED FOR CONFIRMATION, NOW DOES ; WHAT DOCUMENTATION SAYS (ACCEPTS WITH NO CR/LF). ; CS1.10 CHANGED 7/28/78 TO SKIP PRINTING THE PROMPT STRING IF THE SINGLE ; BYTE CHARACTER IN LABELLED COMMON BLOCK "SELCOM" CALLED ; "ENDCHR" IS AN OCTAL 377 (IE, "-1"). THIS ALLOWS THE ; FORTRAN USER TO EASILY HANDLE THE CASE WHERE HE WISHES ; TO ALLOW HIS USER TO TYPE THE SELECT ANSWER FOLLOWED BY ; A SPACE, FOLLOWED BY THE NEXT ANSWER WITH NO INTERVENING ; PROMPT...WHILE STILL GIVING THE PROMPT NORMALLY IF HE ; TERMINATES THE PRECEEDING SELECT ANSWER WITH ANYTHING ELSE. ; FOR INSTANCE, SUPPOSE THE USER HAS JUST FINISHED A SELECT ; ENTRY AND CONTROL HAS TRANSFERRED TO THE FOLLOWING PIECE ; OF CODE WHICH ALSO WANTS TO USE SELECT, BUT YOU WANT TO ; HANDLE THE PROMPT CORRECTLY: ; ... ; IF(ENDCHR.EQ.' ') ENDCHR = -1 ; CALL SELECT(IOPT,0,'PROMPT STRING: ', ...) ; ... ; IN THIS CASE, THE PROMPT STRING WOULD ONLY BE GIVEN IF ; THE USER TERMINATED THE PREVIOUS SELECT WITH SOMETHING ; OTHER THAN A BLANK, AND NO PROMPT STRING WOULD BE GIVEN ; IF HE DID USE A BLANK. ; CS1.09 CHANGED 7/12/78 TO CORRECTLY HANDLE A SPACE TERMINATING AN OPTION ; STRING (BEFORE WOULD FOLLOW LEADING CHAR CONVENTION FOR ; HAVING/SUPPRESSING CARRIAGE RETURNS, WHILE NOW IT IS ; ASSUMED THAT THE USER MUST KNOW WHAT HE'S DOING). ; CS1.08 CHANGED 7/11/78 TO ADD LABELLED COMMON BLOCK "SELCOM", CONTAINING ; THE SINGLE ITEM (ONE BYTE) "ENDCHR" TO RETURN THE CHARACTER ; CODE THAT THE USER ENDED HIS OPTION SELECTION WITH. ; CS1.07 CHANGED 7/7/78 TO ADD SIGN SWITCH TO "IDFLT" PARAMETER, SO THAT ; THE COMPLETE OPTION LIST CAN BE PRINTED ONCE (IF IDFLT ; IS NEGATIVE) BEFORE THE FIRST PROMPT IS GIVEN. THE ; CASE WHERE THE USER DOESN'T DESIRE A DEFAULT (AND THEREFORE ; WOULD NORMALLY SPECIFY ZERO AS A VALUE) AND YET WANTS ; THE INITIALIZING PRINTOUT OF OPTIONS CAN BE HANDLED BY ; SUPPLYING A LARGE NEGATIVE NUMBER GREATER THAN THE NUMBER ; OF OPTIONS SUPPLIED...-999 FOR INSTANCE. ; CS1.06 CHANGED 6/8/78 TO ADD "SELTBL" ENTRY POINT, SLIGHT CLEANUP OF ; COMMENTS, FIXED LATENT BUG ABOUT INITIALIZING LUN RIGHT ; AFTER ENTRY (TABLE OVERFLOW WOULD HAVE WRITTEN TO LUN 0). ; CS1.05 CHANGED 5/23/78 TO CORRECT BUG ON PROMPT STRING GENERATION (THE ; EFFECT WAS TO NOT PRINT STRING IN SPECIAL CASES) ; CS1.04 CHANGED 12/23/77 TO DETACH BEFORE SUSPENDING, THEN REATTACH ON ; RESUMING (OTHERWISE TERMINAL LOCKS UP AFTER SUSPENDING). ; CS1.03 CHANGED 10/26/77 TO ATTACH TO TERMINAL DURING SELECT CALL (THIS ; PREVENTS CHARACTERS FROM GOING TO MCR IF SLOW) ; CS1.02 CHANGED 10/18/77 TO LET AND ACT LIKE AN ON EXIT ; CS1.01 FIRST WORKING VERSION OF SELECT. ; CS1.00 PROTOTYPE VERSION OF SELECT, MANY BUGS. ; ; SELECT ; ; DESCRIPTION ; ALLOWS THE USER TO SPECIFY A SET OF "ACCEPTABLE" COMMANDS ; WHICH A USER COULD SELECT, AND THEN HANDLES ALL THE OVERHEAD ; OF REJECTING ILLEGAL CHARACTERS AND RESPONSES UNTIL A ; VALID AND UNIQUE STRING HAS BEEN TYPED BY THE USER. THE ; NUMBER OF THE OPTION STRING SELECTED IS THEN RETURNED TO ; THE CALLING PROGRAM. ; USAGE ; CALL SELECT(IOPT,IDFLT,'...PROMPT STRING...', ; + '...OPTION STRING #1...', ; + '...OPTION STRING #2...', ; + ... ; + '...OPTION STRING #N...') ; RESTRICTIONS ; 1. MAXIMUM OF 50 OPTIONS ALLOWED. ; PARAMETERS ; IOPT (RETURNED) THE OPTION STRING # THAT THE USER HAS ; SELECTED DURING THIS CALL TO SELECT. THIS NUMBER ; WILL BE IN THE RANGE 1 (ONE) TO N+1, WHERE THE ; USER HAS SUPPLIED "N" OPTION STRINGS. THE "N+1" ; VALUE OCCURS IF THE USER TYPES A CONTROL-Z (THIS ; EXIT IS ALWAYS POSSIBLE). ; IDFLT (SUPPLIED) THE NUMBER OF THE OPTION STRING THAT IS ; TO BE CONSIDERED AS THE "DEFAULT" OPTION STRING. ; THIS NUMBER WOULD BE IN THE RANGE OF 1 (ONE) TO "N" ; IF A DEFAULT OPTION IS DESIRED, AND EQUAL TO 0 (ZERO) ; IF A DEFAULT IS NOT DESIRED. THIS OPTION CAN ALSO ; BE "NULLED" OUT BY USING TWO CONSECUTIVE COMMAS AT ; THE APPROPRIATE PLACE IN THE CALLING PARAMETER LIST ; (EG, CALL SELECT(IOPT,,'...PROMPT STRING...',) ; ; *** 7/7/78 ENHANCED FEATURE *** ; ; IF THE VALUE OF IDFLT IS NEGATIVE (EG "-5"), THE ; COMPLETE OPTION LIST IS PRINTED ON INITIAL ENTRY TO ; THE SELECT ROUTINE AND BEFORE THE FIRST PROMPT. IF ; THE USER DOESN'T WANT A DEFAULT AND THEREFORE WANTS ; TO CHOOSE ZERO FOR THIS PARAMETER AND YET WANTS TO ; SEE THE COMPLETE SET OF OPTIONS IN THIS MANNER, ENTER ; A LARGE NEGATIVE NUMBER GREATER THAN THE HIGHEST OPTION ; NUMBER FOR THIS CALL (EG, "-999"). ; STRINGS (SUPPLIED) THE PROMPT STRING, AND THE OPTION STRINGS, ; HAVE THE SAME FORMAT--HOLLERITH LITERAL STRINGS IN ; EITHER THE FORM ; NHABCD... ; 'ABCD...' ; IBUF ; WHERE THE LAST IS AN ARRAY NAME, WITH THE LAST BYTE ; OF THE STRING BEING A ZERO (OR A ZERO WORD). THIS ; ARGUMENT CAN ALSO BE "NULLED" BY LEAVING IT OUT IF ; NO PROMPT STRING IS DESIRED. ; OPTION STRINGS CAN'T BE LEFT OUT, AND ARE NUMBERED IN ; ORDER OF THEIR APPEARANCE IN THE ARGUMENT LIST (WITH ; THE FIRST BEING #1). THE UTILITY OF THE OPTION STRINGS ; CAN BE ENHANCED BY INCLUDING "NOISE WORDS" IN ; PARENTHESES FOLLOWING THE ACTUAL CHOICE...THIS WAY, THE ; NOISE WORDS WILL APPEAR IF THE USER TYPES AN ESCAPE ; TO TERMINATE A UNIQUELY DEFINED OPTION, TO FURTHER ; EXPLAIN THE OPTION'S FUNCTION. ; SELTBL ; ; DESCRIPTION ; SELTBL IS AN ALTERNATE ENTRY POINT FOR THE SELECT PACKAGE WHICH ; ALLOWS THE USER TO SPECIFY A TWO-DIMENSIONAL TABLE OF OPTION ; STRINGS INSTEAD OF LISTING THEM INDIVIDUALLY. THE MAJOR ADVAN- ; TAGE OF THIS ENTRY IS THAT THE STRINGS CAN BE CHANGED DYNAMICALLY ; AT EXECUTION TIME (FOR INSTANCE, READ FROM A FILE) SUCH THAT ; THE SAME CALLING STATEMENT COULD BE USED FOR MULTIPLE CALLS TO ; SELECT WITH DIFFERENT OPTION STRINGS EACH TIME. ; USAGE ; CALL SELTBL(IOPT,IDFLT,'...PROMPT STRING...', ; + NOPT,NROWS,TABLE) ; PARAMETERS ; IOPT, IDFLT, AND '...PROMPT STRING...' ARE SAME AS "SELECT" ; NOPT # OF OPTION STRINGS CONTAINED IN THE TABLE ; NROWS # OF ROWS IN THE TABLE ; TABLE TWO DIMENSIONAL TABLE OF OPTION STRINGS (DIMENSIONED ; "NROW" BY AT LEAST "NOPT") ; EXAMPLE ; SUPPOSE A USER HAD AN ARRAY CALLED TABLE: ; BYTE TABLE(30,10) ; THEN THE USER COULD STORE UP TO 10 OPTION STRINGS, WHERE EACH ; OPTION STRING COULD HAVE A MAXIMUM LENGTH OF 29 CHARS (THE ; SELTBL ROUTINE WILL HAVE TO INSERT A NULL BYTE AT THE END OF ; EACH COLUMN, OR OPTION STRING, IN ORDER TO PROPERLY TERMINATE ; THE STRING). EITHER DATA STATEMENTS OR FILE READ STATEMENTS ; COULD BE USED TO INTIALIZE THIS ARRAY WITH ACTUAL STRINGS: ; DATA TABLE/'A','B',28*0,'C','D','E',27*0,'F',29*0,210*0/ ; THEN THE CALL MIGHT BE MADE LATER TO SELTBL AS FOLLOWS: ; CALL SELTBL(IOPT,1,'PROMPT: ', ; + 3,30,TABLE) ; THIS CALL WOULD RETURN IN "IOPT" THE NUMBER OF THE OPTION STRING ; SELECTED, WITH "AB" BEING THE DEFAULT OPTION TO "PROMPT: ", ; AND WITH POSSIBLE OPTION STRINGS "AB", "CDE", AND "F". ; NOTES ; 1) IF THE USER AT ANY POINT ATTEMPTS TO TYPE AN INVALID RESPONSE ; GIVEN THE OPTIONS POSSIBLE AT THAT POINT, THE CHARACTER ; WILL NEITHER BE ACCEPTED NOR PRINTED, BUT A "BELL" WILL SOUND ; AT THE USER'S TERMINAL TO TELL HIM THAT AN INVALID CHARACTER ; WAS TYPED. THIS WILL ALSO HAPPEN IF THE USER THINKS A RESPONSE ; HAS BEEN UNIQUELY QUALIFIED FOR THE NUMBER OF CHARACTERS HE ; HAS TYPED SO FAR AND HE TYPES A CARRIAGE RETURN...BUT ANOTHER ; OPTION EXISTS WHICH IS THE SAME THROUGH THE NUMBER OF CHARS ; SO FAR. THE TERMINAL WILL BEEP AND NOT ACCEPT THE CARRIAGE ; RETURN, AND THE USER WILL STILL BE INSIDE THE "SELECT" PACKAGE. ; 2) THE USER CAN TYPE AN "ESCAPE" CHARACTER AT ANY POINT, AT ; WHICH POINT THE SELECT PACKAGE WILL ATTEMPT TO "FINISH" THE ; STRING IN PROGRESS BY CHECKING WHETHER THE STRING IS UNIQUE ; COMPARED TO THE OPTIONS INITIALLY SUPPLIED. IF IT IS UNIQUE, ; THE REMAINING CHARACTERS IN THE OPTION WILL BE TYPED, AND THE ; SELECT PACKAGE WILL DO ONE OF THREE THINGS DEPENDING ON WHAT ; THE FIRST CHARACTER OF THE ORIGINAL OPTION STRING WAS: ; 1ST CHAR ACTION AFTER TYPING REMAINING CHARS ; --- ---- ------ ----- ------ --------- ----- ; # (NMBR SIGN) THE STRING "[CONFIRM]" IS TYPED, AND THE ; USER MUST EITHER CONFIRM THE OPTION BY ; TYPING A CARRIAGE RETURN, OR HE CANCELS ; THE OPTION BY TYPING ANY OTHER CHAR. IF ; HE CANCELS THE OPTION SO SELECTED, THE ; WHOLE LINE IS THROWN AWAY AND THE USER ; STARTS ON AN OPTION FROM SCRATCH. ; $ (DLR SIGN) AFTER THE TRAILING CHARACTERS OF THE OPTION ; ARE TYPED, NO CARRIAGE RETURN IS TYPED. THE ; EFFECT IS TO ALLOW A READ STATEMENT TO READ ; THE NEXT ITEM ON THE SAME LINE AS THE OPTION ; CHOSEN. ; % (PRCNT SIGN AFTER THE TRAILING CHARACTERS OF THE OPTION ; ARE TYPED, A CARRIAGE RETURN IS TYPED. IN ; THIS WAY, THE USER IS LEFT ON THE NEXT LINE ; DOWN FOR FURTHER INPUT/OUTPUT. ; NOTE THAT THE "#" LEADING CHARACTER REQUIRES ONE FURTHER LEVEL ; OF CONFIRMATION, WHILE BOTH THE "$" AND "%" LEADING CHARACTERS ; WILL IMMEDIATELY ACCEPT THE STRING IN PROGRESS (IF POSSIBLE) ; AND RETURN TO THE CALLER. ; 3) TYPING A "?" (QUESTION MARK) AT ANY POINT DURING AN OPTION WILL ; TYPE ON THE USER'S TERMINAL ALL THE OPTIONS STILL VALID AT THAT ; POINT FOR WHAT HAS BEEN TYPED SO FAR. TYPING IT AS THE FIRST ; CHARACTER OF THE OPTION RESPONSE WILL ADDITIONALLY INDICATE THAT ; "^Z" (CONTROL-Z) IS A VALID RESPONSE TO THE OPTION SELECTION. ; TYPING IT IN THE MIDDLE OF A RESPONSE WILL LIST ALL POSSIBLE ; RESPONSES VALID AT THAT POINT. ; 4) TYPING A ^Z (CONTROL-Z) AS THE 1ST CHARACTER OF THE LINE WILL ; ASK THE USER FOR CONFIRMATION, AND IF CONFIRMED, EXIT FROM ; SELECT WITH AN OPTION CODE OF "N+1", IF "N" OPTIONS WERE GIVEN. ; 5) THE STANDARD EDITING CHARACTERS OF "RUBOUT OR DEL", "^U", ; AND "^R" ARE SUPPORTED, WITH THE LAST RETYPING THE PROMPT ; STRING AS WELL AS THE CHARS TYPED SO FAR. ; 6) LOGICAL UNIT "5" IS ASSUMED FOR TERMINAL INPUT, BUT IF ; DESIRED, THIS CAN BE OVERRIDDEN. BEFORE ANY CALL TO EITHER ; "SELECT" OR "SELTBL", DO THIS: ; CALL SELECT(LUN) ; WHERE "LUN" HAS THE VALUE FOR THE LOGICAL UNIT TO BE USED FOR ; TERMINAL I/O. ; 7) THE CHARACTER THAT THE USER ENDS HIS OPTION STRING WITH CAN ; BE ACCESSED BY INCLUDING THE FOLLOWING STATEMENT IN THE ; CALLING ROUTINE: ; COMMON /SELCOM/ ENDCHR ; WHERE "ENDCHR" IS A SINGLE BYTE QUANTITY WHICH WILL CONTAIN ; EITHER: ; 13 CARRIAGE RETURN ENDED OPTION ; 26 ^Z WAS OPTION CHOSEN ; 27 ESCAPE ENDED OPTION ; 32 BLANK ENDED OPTION ; (ALL NUMBERS ABOVE ARE DECIMAL AND CORRESPOND TO THE ASCII ; VALUES THEMSELVES OF THE PARTICULAR CHARACTER) .SBTTL DATA STORAGE DEFINITION BLOCK ; .MCALL QIO$,WTSE$C,DIR$,SPND$S,QIO$C,QIOW$S ; ; ** DPB DEFINITIONS ; WLBQIO: QIO$ IO.WLB,5,1,,,,<0,0,0> ;WRITE-LOGICAL-BLOCK QIO DPB RALQIO: QIO$ IO.RAL!TF.RNE,5,1,,,, ;READ-PASS-ALL QIO (1 CHAR) ; NOTE !!!!!! THE ABOVE WAS MODIFIED FOR VERSION 3 TO NOT ECHO... ; ; ** DATA STORAGE--BYTE ORIENTED ; MAXOPT=50. ;MAXIMUM # OF OPTIONS ALLOWED OPTION: .BLKB MAXOPT ;RESERVES SPACE FOR BYTE TABLE FOR OPTIONS BUFFER: .BLKB 80. ;BUFFER FOR USER TYPED INPUT INIFLG: .BYTE 0 ;FLAG FOR WHETHER OPTIONS ARE TO BE ;PRINTED INITIALLY BEFORE PROMPT, OR NOT ; (=0 IS NO, =1 IS YES) TERR: .ASCII "Error has occurred on entering SELECT package" NERR=.-TERR TCONFM: .ASCII / [Confirm]/ ;MESSAGE (REQUEST FOR CONFIRMATION) NCONFM=.-TCONFM ;BYTE COUNT FOR TCONFM TDEL: .BYTE 134,0 ;BUFFER FOR QIO ON CHARACTER DELETE TCANCL: .ASCII / XXX/ ;MESSAGE (UPON CANCEL OF CURRENT LINE) NCANCL=.-TCANCL ;BYTE COUNT FOR TCANCL TSUSPD: .ASCII /(SUSPENDING TASK...)/<15><12>">" ;MESSAGE ON TASK SUSPEND NSUSPD=.-TSUSPD ;BYTE COUNT FOR TSUSPD TOFLOW: .ASCII /(WARNING!!! TOO MANY OPTIONS FOR SELECT...SOME LOST)/ ;MESSAGE (WHEN MORE THAN MAXOPT OPTIONS) NOFLOW=.-TOFLOW ;BYTE COUNT FOR TOFLOW TDFLT: .ASCII / *** DEFAULT ***/ ;MESSAGE (FLAG FOR DEFAULT STRING) NDFLT=.-TDFLT ;BYTE COUNT FOR TDFLT TCTRLZ: .ASCII /^Z (SPECIAL EXIT)/ ;MESSAGE (PRINTED DURING OPTION LISTING) NCTRLZ=.-TCTRLZ ;BYTE COUNT FOR TCTRLZ CRET: .BYTE 15 ;DEFINITION OF CARRIAGE RETURN LFD: .BYTE 12,40,40,40 ;DEFINITION OF LINE FEED AND 3 SPACES (FOR ?) BELL: .BYTE 7 ;DEFINITION OF "BELL" CHARACTER SPACE: .BYTE 40 ;DEFINITION OF "SPACE" CHARACTER IOPTCC: .BYTE 0 ;FLAG LOC FOR 1ST CHAR OF OPTION STRING .EVEN ;MAKE SURE WE'RE ON EVEN (WORD) BOUNDARY ; ; ** DATA STORAGE--WORD ORIENTED ; IOSB: .WORD 0 ;STORAGE FOR DIRECTIVE I/O STATUS BLOCK INBUF: .WORD 0 ;ONE WORD BUFFER FOR READ-PASS-ALL QIO LUN: .WORD 5 ;DEFAULT VALUE FOR TERMINAL LUN RETLOC: .WORD 0 ;SAVES ADDRESS OF 1ST ARG (RETURN LOCATION) DFAULT: .WORD 0 ;SAVES ADDRESS OF 2ND ARG (DEFAULT OPTION NO) PSTLOC: .WORD 0 ;SAVES ADDRESS OF 3RD ARG (PROMPT STRING) PSTNUM: .WORD 0 ;STORES # OF CHARS IN PROMPT STRING TMPLOC: .WORD 0 ;TEMPORARY STORAGE OPTLOC: .WORD 0 ;STORES ADDRESS OF START OF OPTION ADDRESSES OPTTBL: .BLKW MAXOPT ;RESERVES SPACE FOR SELTBL OPTION ADDRESSES NOPT: .WORD 0 ;SAVES # OF OPTIONS SUPPLIED BY USER DFOPT: .WORD 0 ;TEMP LOC FOR DEFAULT OPTION NUMBER ; ; ** MACROS ; .MACRO TYPWLB BUF,COUNT,FORMAT MOV BUF,Q.IOPL+WLBQIO ;SET BUFFER ADDRESS FOR QIO MOV COUNT,Q.IOPL+2+WLBQIO ;SET COUNT OF CHARACTERS IN BUF MOV FORMAT,Q.IOPL+4+WLBQIO ;SET TYPE OF FORMAT CONTROL DESIRED DIR$ #WLBQIO ;EXECUTE THE QIO WRITE REQUEST WTSE$C 1 ;WAIT FOR IT TO FINISH .ENDM ; ; ** REGISTER DEFINITIONS ; PCHAR=R4 ;POINTER TO CURRENT CHAR POSITION IN USER STRING .SBTTL ENTRY POINT(S) AND INITIALIZATION ; SELECT:: MOV (R5)+,R0 ;GET # OF ARG LIST PARAMETERS FOR THIS CALL SUB #3,R0 ;MAKE EQUAL TO # OF OPTIONS IN ARG LIST BGT 10$ ;IF AT LEAST ONE OPTION, GO ON TO NORMAL CODE ; ; ** SPECIAL ENTRY POINT TO CHANGE LUN (FROM DEFAULT OR LAST SETTING) ; MOV (R5),LUN ;SET THE NEW LUN MOV LUN,Q.IOLU+WLBQIO ;INITIALIZE LUN VALUE FOR THIS CALL MOV LUN,Q.IOLU+RALQIO ;SAME FOR OTHER QIO DPB RTS PC ;AND RETURN TO CALLER ; ; ** SELTBL ENTRY POINT ; SELTBL:: TST (R5)+ ;FIRST, BUMP PTR TO MAKE COMPATIBLE WITH SELECT MOV @10(R5),R1 ;SAVE # OF ROWS IN TABLE MOV 12(R5),R2 ;GET ADDRESS OF USER'S ARRAY MOV #OPTTBL,R3 ;GET OUR LOCAL TABLE ADDRESS MOV @6(R5),R0 ;GET # OF OPTIONS IN USER ARRAY BGT 13$ ;HAS TO BE >0 TO PROCEED FURTHER TYPWLB #TERR,#NERR,#40 ;ELSE PRINT ERROR MESSAGE AND RETURN RTS PC ;RETURN TO CALLER 13$: CMP R0,#MAXOPT ;DID HE SUPPLY TOO MANY OPTIONS? BLE 15$ ;NO IF LE MOV #MAXOPT,R0 ;YES. OVERRIDE FOR THIS ENTRY TYPWLB #TOFLOW,#NOFLOW,#40 ;WARN USER THAT WE'RE DOING IT 15$: MOV R2,(R3)+ ;SAVE AN OPTION STRING ADDRESS IN TABLE ADD R1,R2 ;INCREMENT COLUMN POINTER TO NEXT COL. LOC CLRB -1(R2) ;MAKE SURE LAST STRING TERMINATES WITH NULL SOB R0,15$ ;GO BACK IF MORE TO DO MOV #OPTTBL,OPTLOC ;SET POINTER TO START OF OPTION TABLE MOV @6(R5),R0 ;RESTORE # OF OPTIONS IN USER ARRAY BR 20$ ;PROCEED WITH NORMAL SELECT CODE ; ; ** SAVE ARGUMENT LIST ADDRESSES FOR LATER USE ; 10$: MOV R5,OPTLOC ;SAVE ADDRESS OF START OF OPTION ADDRESS TBL ADD #6,OPTLOC ;KLUDGE TO POINT TO ARG LIST PROMPT ADDRESSES CMP R0,#MAXOPT ;WERE TOO MANY OPTIONS SUPPLIED BY USER? BLE 20$ ;IF NOT, PROCEED MOV #MAXOPT,R0 ;ELSE OVERRIDE TO KEEP NUMBER IN BOUNDS TYPWLB #TOFLOW,#NOFLOW,#40 ;AND PRINT WARNING MESSAGE FOR USER ; 20$: MOV R0,NOPT ;SAVE NUMBER OF OPTIONS TO BE USED QIOW$S #IO.ATT,LUN,,,IOSB ;ATTACH TO TERMINAL TO PREVENT MCR FROM ;GRABBING CHARACTERS WHEN WE'RE NOT READY MOV (R5)+,RETLOC ;SAVE RETURN LOCATION FOR OPTION # FOUND MOV (R5)+,DFAULT ;SAVE ADDRESS OF DEFAULT OPTION # MOV (R5)+,PSTLOC ;SAVE ADDRESS OF PROMPT STRING CLR PCHAR ;CLEAR THE CHARACTER POINTER CLR PSTNUM ;CLEAR LOCATION STORING # OF CHARS IN PROMPT ; ; ** MAKE SURE DEFAULT INDICATOR (IF PRESENT) IS IN BOUNDS ; CLRB INIFLG ;MAKE SURE INITIAL PRINT FLAG IS CLEAR TO START CLR DFOPT ;ASSUMPTION IS THAT NO DEFAULT OPTION EXISTS TST DFAULT ;WAS A DEFAULT OPTION SUPPLIED AT ALL? BLE 25$ ;IF NOT, NO PROBLEM (HANDLE LATER) MOV @DFAULT,DFOPT ;IT EXISTS, SO MOVE IT INTO TEMPORARY HOME BEQ 25$ ;IF ZERO, NO DEFAULT WANTED OR INITIAL PRINT BGT 23$ ;IF >0, IT'S A STANDARD DEFAULT. TREAT NORMALLY NEG DFOPT ;ELSE, OPTION TO PRINT OPTIONS. MAKE RIGHT SIGN MOVB #1,INIFLG ;THEN SET FLAG TO FORCE OPTIONS TO PRINT 1ST CMP DFOPT,NOPT ;DID THE USER USE THE LRG NEG # KLUDGE? BLE 25$ ;NO, SO SELECTED A DEFAULT AS WELL AS THE SWITCH CLR DFOPT ;YES! RESET TO INDICATE NO DEFAULT AFTER ALL. BR 25$ ;AND GET ON WITH IT 23$: CMP DFOPT,NOPT ;WAS THE DEFAULT GREATER THAN # OPT'S GIVEN? BLE 25$ ;IF NOT, DEFAULT VALUE IS LEGAL..PROCEED CLR DFOPT ;ELSE, ILLEGAL VALUE...PRETEND NO DEFAULT. ;AND CONTINUE AS IF NOTHING WENT WRONG ; ; ** ONE-TIME DETERMINATION OF # OF CHARS IN PROMPT STRING (NULL ENDS IT) ; 25$: CLR PSTNUM ;SET # OF PROMPT CHARS TO ZERO INITIALLY CMP PSTLOC,#-1 ;WAS A PROMPT STRING PARAMETER IN ARG LIST? BEQ 35$ ;IF NOT, SKIP FOLLOWING CODE ABOUT LENGTH. MOV PSTLOC,R0 ;RETRIEVE PROMPT STRING ADDRESS 30$: TSTB (R0)+ ;IS THIS BYTE A NULL? BNE 30$ ;IF NOT, KEEP STEPPING THROUGH STRING. DEC R0 ;ELSE, READJUST POINTER VALUE FOR AUTO-INC SUB PSTLOC,R0 ;AND CALCULATE THE CHAR COUNT FOR STRING BLE 35$ ;IF NO CHARS TO PRINT, SKIP NEXT STATEMENT MOV R0,PSTNUM ;SAVE THE # OF CHARS FOR LATER REFERENCE 35$: TSTB INIFLG ;DO WE HAVE TO PRINT OPTIONS FIRST? BEQ 37$ ;NOPE IF EQ CMPB ENDCHR,#377 ;DID USER WANT TO SKIP PROMPT ON ENTRY? BEQ GETCHR ;IF EQ, YES. JMP QMARK ;YES. EASIEST WAY IS TO ASSUME A "?" TYPED 37$: TST PSTNUM ;DON'T TYPE OPTIONS. TYPE PROMPT STRING? BLE GETCHR ;NO IF LE CMPB ENDCHR,#377 ;DID USER WANT TO SKIP PROMPT ON ENTRY? BEQ GETCHR ;IF EQ, YES. TYPWLB PSTLOC,PSTNUM,#44 ;ELSE PRINT THE PROMPT STRING .SBTTL GETCHR ; ; GETCHR IS A ROUTINE THAT READS ONE CHARACTER FROM THE TERMINAL, ; AND THEN BRANCHES TO ONE OF A NUMBER OF ROUTINES DEPENDING ON ; WHAT KIND OF CHARACTER WAS READ. ; GETCHR: DIR$ #RALQIO ;ISSUE THE READ REQUEST WTSE$C 1 ;WAIT FOR USER TO TYPE A CHARACTER BIC #177600,INBUF ;MASK OFF LOW ORDER BYTE'S PARITY BIT MOV INBUF,R0 ;BRING THE CHAR INTO A REGISTER FOR COMPARES ; ; ** SWITCHING LOGIC TO FIGURE OUT WHAT CHARACTER WE HAVE READ ; CMPB R0,#3 ;COMPARE TO "^C" BNE 41$ JMP CTRLC 41$: CMPB R0,#15 ;COMPARE TO "CARRIAGE RETURN" BNE 42$ JMP CR 42$: CMPB R0,#22 ;COMPARE TO "^R" BNE 43$ JMP CTRLR 43$: CMPB R0,#25 ;COMPARE TO "^U" BNE 44$ JMP CTRLU 44$: CMPB R0,#32 ;COMPARE TO "^Z" BNE 45$ JMP CTRLZ 45$: CMPB R0,#33 ;COMPARE TO "ESCAPE" BNE 46$ JMP ESC 46$: CMPB R0,#40 ;COMPARE TO "SPACE" BNE 47$ JMP SPC 47$: CMPB R0,#77 ;COMPARE TO "?" BNE 48$ JMP QMARK 48$: CMPB R0,#175 ;COMPARE TO 1ST KIND OF "ALTMODE" BNE 49$ JMP ESC ;(NOTE THAT IT IS TREATED AS AN ESCAPE) 49$: CMPB R0,#176 ;COMPARE TO 2ND KIND OF "ALTMODE" BNE 50$ JMP ESC ;(NOTE THAT IT IS TREATED AS AN ESCAPE) 50$: CMPB R0,#177 ;COMPARE TO "RUBOUT" (DEL) BNE OTHER ;NOT ANYTHING ELSE, MUST HAVE BEEN VALID CHAR JMP RUBOUT .SBTTL OTHER (VALID CHARACTER) ; ; OTHER IS A ROUTINE THAT HANDLES THE TESTING OF A CHARACTER, WHICH IS ; NOT ONE OF THE SPECIAL CHARACTERS, AGAINST THE SET OF OPTIONS WHICH ; HAVE NOT BEEN ELIMINATED YET. ; OTHER: ; ; ** FIRST MAKE SURE THAT AT LEAST ONE OPTION FITS THE NEW CHARACTER ; BITB #100,INBUF ;IS BIT 7 ON? (IE UPPER HALF OF ASCII SET) BEQ 56$ ;IF NOT, DON'T HAVE TO WORRY ABOUT CHARS BICB #40,INBUF ;ELSE, CONVERT HIGHEST 1/4 OF TBL TO NEXT DOWN ;(THIS CONVERTS ANY LOWER CASE CHARS TO UPPER) 56$: CLR R0 ;START LOOKING FROM START OF OPTION LIST 58$: INC R0 ;GO ON TO NEXT OPTION CMP R0,NOPT ;OPTION TABLE EXHAUSTED? BLE 60$ ;IF NOT, CONTINUE WITH SEARCH JMP SNDBEL ;ELSE, SEND BELL TO USER (CHAR UNACCEPTABLE) 60$: CMPB OPTION-1(R0),PCHAR ;SEE IF OPTION IS "ALIVE" BLT 58$ ;IF NOT, GO ON WITH NEXT OPTION CALL GETSTG ;ELSE, COMPUTE ADDRESS OF OPTION STRING (R1) ADD PCHAR,R1 ;POINT TO CURRENT CHAR IN STRING CALL CMPCHR ;COMPARE OPTION CHAR (R1) WITH NEW CHAR (INBUF) BNE 58$ ;IF NOT EQUAL, GO ON TO NEXT OPTION ; ; ** VALID CHARACTER ENCOUNTERED. UPDATE THE OPTION TABLE ACCORDINGLY. ; 70$: MOV PCHAR,R2 ;ELSE, COPY PCHAR VALUE INC R2 ;INCREMENT IT TO CORRESPOND TO NEW POSITION MOVB INBUF,BUFFER(PCHAR) ;SAVE THE CHAR IN USER BUFFER TYPWLB #INBUF,#1,#0 ;ECHO THE CHARACTER TO THE TERMINAL CLR R0 ;RESET OPTION POINTER...HAVE TO START AGAIN 80$: INC R0 ;POINT TO NEXT OPTION CMP R0,NOPT ;OPTION TABLE EXHAUSTED? BLE 85$ ;IF NOT, TEST NEXT OPTION FOR MATCH INC PCHAR ;ELSE, UPDATE CHARACTER POINTER JMP GETCHR ;AND WAIT FOR ANOTHER USER CHARACTER 85$: CMPB OPTION-1(R0),PCHAR ;SEE IF THIS OPTION IS "ALIVE" BLT 80$ ;IF NOT, GO ON TO NEXT OPTION CALL GETSTG ;ELSE, SET R1 TO ADDRESS OF CURR. OPTION STRING ADD PCHAR,R1 ;POINT TO CURRENT CHARACTER IN STRING CALL CMPCHR ;COMPARE OPTION CHAR (R1) WITH NEW ONE (INBUF) BNE 90$ ;IF NOT EQUAL, "KILL" THIS OPTION MOVB R2,OPTION-1(R0) ;ELSE UPDATE THIS OPTION AS "ACCEPTED" BR 80$ ;AND GO BACK FOR ANOTHER OPTION 90$: MOVB PCHAR,OPTION-1(R0) ;MOVE OLD CHAR POSITION INTO OPTION BYTE ; ;(THAT'S THE WAY YOU "KILL" AN OPTION) BR 80$ ;AND GO BACK FOR ANOTHER OPTION .SBTTL RUBOUT ; ; RUBOUT HANDLES THE OCCURRENCE OF A "RUBOUT" AS AN INPUT CHARACTER. ; ITS EFFECT IS TO "DELETE" THE LAST TYPED (OR ACTIVE) CHARACTER. ; RUBOUT: TST PCHAR ;ARE WE AT BEGINNING OF LINE ALREADY? BGT 95$ ;IF NOT, GO AHEAD AND DELETE CHARACTER JMP SNDBEL ;ELSE, CAN'T DELETE...SEND BELL INSTEAD 95$: DEC PCHAR ;REVISE CHAR PTR BACKWARD ACCORDINGLY MOVB BUFFER(PCHAR),TDEL+1 ;MOVE CHAR TO BE DELETED TO QIO BUFFER ;(THE BUFFER CONTAINS A "BACKSLASH", AND A ; HOLE FOR THE CHAR TO BE ECHOED AS "DELETED") TYPWLB #TDEL,#2,#0 ;PRINT "\" FOLLOWED BY DELETED CHARACTER JMP GETCHR ;NOW GO BACK AND WAIT FOR ANOTHER CHAR. .SBTTL CTRLR (CONTROL-R) ; ; CTRLR IS THE ROUTINE THAT HANDLES A "^R" ON TYPEIN. ; IT RETYPES THE PROMPT STRING (IF IT EXISTS), AND THEN WHATEVER ; AMOUNT THE USER HAS TYPED SO FAR. ; CTRLR: TYPWLB #CRET,#2,#0 ;FORCE A CR/LF BEFORE RETYPING LINE TST PSTNUM ;WAS A PROMPT STRING SUPPLIED? BLE 100$ ;IF NOT, GO DIRECTLY TO PRINT OF USER BUFFER TYPWLB PSTLOC,PSTNUM,#0 ;PRINT THE PROMPT STRING (NO CR OR LF) 100$: TYPWLB #BUFFER,PCHAR,#0 ;TYPE BUFFER (NO CR OR LF) JMP GETCHR ;THEN WAIT FOR ANOTHER CHARACTER. .SBTTL CTRLU (CONTROL-U) ; ; CTRLU HANDLES AN OCCURRENCE OF A "^U" CHARACTER. ITS ; EFFECT IS TO DELETE THE LINE THAT THE USER IS TYPING. ; CTRLU: CLR PCHAR ;RESET THE CHAR PTR TO BEGINNING OF LINE TYPWLB #TCANCL,#NCANCL,#53 ;TYPE "XXX" ON CURRENT LINE TYPWLB #LFD,#1,#0 ;SEND LINEFEED SO THAT NEXT CHAR WON'T OVERPRT. JMP GETCHR ;THEN WAIT FOR ANOTHER CHARACTER. .SBTTL CTRLZ (CONTROL-Z) ; ; CTRLZ HANDLES THE OCCURRENCE OF A "^Z" CHARACTER. ITS ; EFFECT IS TO TAKE A SPECIAL EXIT FROM THE "SELECT" ; SUBROUTINE, WHERE THE RETURN CODE COMES BACK AS "N+1", ; WHERE "N" IS THE NUMBER OF OPTIONS SUPPLIED BY THE USER. ; CTRLZ: MOVB #32,ENDCHR ;SET LABELLED COMMON PARAMETER FOR EXIT TYPE TST PCHAR ;ARE WE AT BEGINNING OF LINE? BLE 105$ ;IF SO, TAKE ^Z EXIT JMP SNDBEL ;ELSE, SEND BELL TO USER. 105$: MOV NOPT,R0 ;RETRIEVE # OF OPTIONS SUPPLIED BY USER INC R0 ;ADD ONE TO SET TO OPTIONAL RETURN VALUE MOV R0,@RETLOC ;SAVE IN RETURN LOCATION ALSO TYPWLB #TCTRLZ,#NCTRLZ,#0 ;TYPE CTRLZ MESSAGE (NO CR OR LF) JMP CONFRM ;THEN ASK FOR CONFIRMATION FROM USER. .SBTTL CTRLC (CONTROL-C) ; ; CTRLC HANDLES THE OCCURRENCE OF A "^C" CHARACTER. ITS ; EFFECT IS TO SUSPEND THE TASK, ALLOWING THE USER TO DO ; OTHER THINGS BEFORE RESUMING THE TASK. ; CTRLC: TYPWLB #CRET,#1,#0 ;FORCE A CARRIAGE RETURN BEFORE NEXT MESSAGE TYPWLB #TSUSPD,#NSUSPD,#40 ;TYPE "SUSPENDING" MESSAGE ON NEXT LINE QIOW$S #IO.DET,LUN ;DETACH BEFORE SUSPENDING TO FREE TERMINAL SPND$S ;SUSPEND TASK FOR THE DURATION QIOW$S #IO.ATT,LUN,,,IOSB ;RE-ATTACH BEFORE RESUMING SELECT JMP GETCHR ;THEN CONTINUE AS IF NOTHING HAPPENED. .SBTTL SPC (SPACE) ; ; SPC HANDLES THE OCCURRENCE OF A "SPACE" CHARACTER. ITS ; EFFECT DEPENDS ON WHETHER THE SPACE OCCURS AS THE FIRST ; CHARACTER OF THE LINE OR NOT. IF THE FIRST CHAR ON THE ; LINE, IT IS SIMPLY IGNORED (AND NOT ENTERED IN THE BUFFER ; BEING BUILT...HENCE IT WON'T SHOW ON A ^R REQUEST). ; IF THE SPACE OCCURS ANYWHERE ELSE, IT IS INTERPRETED AS ; IF IT WERE A CARRIAGE RETURN, EXCEPT THAT A SPACE ; IS ECHOED INSTEAD OF A CARRIAGE RETURN. ; SPC: MOVB #40,ENDCHR ;SET LABELLED COMMON PARAMETER FOR EXIT TYPE TST PCHAR ;IS IT THE FIRST CHAR ON THE LINE? BGT 110$ ;IF NOT, HANDLE SOMETHING LIKE A CR. TYPWLB #SPACE,#1,#0 ;ELSE ECHO THE SPACE BUT DON'T ADD TO BUFFER JMP GETCHR ;THEN WAIT FOR ANOTHER CHAR. 110$: CALL TESTOP ;TEST THE OPTIONS FOR UNIQUENESS TST R0 ;IS THERE A UNIQUE OPTION YET? BGE 120$ ;IF SO, WRAPUP AND RETURN JMP SNDBEL ;ELSE, CAN'T END STRING YET (SEND BELL) 120$: MOV R0,@RETLOC ;MOVE OPTION CODE TO RETURN LOC. TYPWLB #SPACE,#1,#0 ;GIVE HIM THE SPACE JMP RETRN .SBTTL ESC (ESCAPE) ; ESC: MOVB #33,ENDCHR ;SET LABELLED COMMON PARAMETER FOR EXIT TYPE CALL TESTOP ;TEST OPTIONS FOR UNIQUENESS (RESULT IN R0) TST R0 ;IS THE CURRENT STRING UNIQUE? BGE 123$ ;IF SO, PROCESS THE STRING FOR THE USER. JMP SNDBEL ;ELSE, SEND BELL TO USER. 123$: MOV R0,@RETLOC ;SET UP THE RETURN VALUE, CALL GETSTG ;GET THE ADDRESS OF THE OPTION STRING (IN R1) ADD PCHAR,R1 ;ADD BIAS OF ALREADY TYPED CHARS, CALL TYPSTG ;TYPE THE REMAINDER OF THE OPTION STRING, ; ; ** WRAPUP ** (HANDLES LOGIC FOR DECIDING HOW TO END LINE) WRAPUP: CMPB IOPTCC,#'% ;CHECK 1ST CHAR OF STRING FOR TYPEOUT CONTROL BNE 125$ TYPWLB #CRET,#1,#0 ;"%"==>ACCEPT STRING, WITH CARRIAGE RETURN JMP RETRN ;AND RETURN TO CALLER 125$: CMPB IOPTCC,#'# BNE 126$ JMP CONFRM ;"#"==>DON'T ACCEPT YET (ASK FOR CONFIRM) 126$: TYPWLB #SPACE,#1,#0 ;"$"==>ACCEPT STRING, BUT NO CARRIAGE RETURN JMP RETRN .SBTTL CR (CARRIAGE RETURN) ; CR: MOVB #15,ENDCHR ;SET LABELLED COMMON PARAMETER FOR EXIT TYPE TST PCHAR ;ANY CHARS TYPED BY USER YET? BGT 130$ ;IF SO, DON'T WORRY ABOUT DEFAULT OPTION ; ; ** HANDLE CASE OF DEFAULT STRING ; TST DFOPT ;ELSE, DOES A DEFAULT OPTION EXIST? BGT 127$ ;IF SO, PROCESS THE DEFAULT CONDITION. JMP SNDBEL ;ELSE, SEND A BELL. 127$: MOV DFOPT,R0 ;SET UP THE RETURN CODE IN R0, CALL GETSTG ;GET THE ADDRESS OF THE DEFAULT STRING (IN R1) CALL TYPSTG ;AND TYPE IT ON USER'S TERMINAL BR 135$ ;WRAPUP AND RETURN TO CALLER ; ; ** HANDLE CASE OF CR AFTER 1ST CHAR POSITION (ABBREVIATION OF A COMMAND) ; 130$: CALL TESTOP ;TEST OPTIONS FOR UNIQUENESS TST R0 ;IS THE CURRENT STRING UNIQUE? BGE 135$ ;IF SO, WRAPUP AND RETURN TO CALLER JMP SNDBEL ;ELSE, SEND BELL TO USER. 135$: MOV R0,@RETLOC ;SET UP RETURN CODE IN RETURN LOCATION BR WRAPUP ;BRANCH TO DECISION LOGIC FOR END OF LINE .SBTTL QMARK (QUESTION MARK) ; QMARK: TYPWLB #CRET,#1,#0 ;SEND CARRIAGE RETURN BEFORE NEXT LINE. CLR R0 ;USE R0 TO STEP THROUGH OPTIONS REMAINING. 140$: INC R0 ;INCREMENT OPTION POINTER CMP R0,NOPT ;EXHAUSTED OPTIONS YET? BGT 160$ ;IF SO, EXIT THE OPTION SEARCH LOOP CMPB OPTION-1(R0),PCHAR ;ELSE, IS THIS OPTION ACCEPTABLE? BLT 140$ ;IF NOT, GO ON TO NEXT OPTION. TYPWLB #LFD,#3,#0 ;ELSE, PRINT A LF+3 SPACES BEFORE NEXT LINE. CALL GETSTG ;LOCATE THE OPTION STRING CONCERNED CALL TYPSTG ;THEN PRINT IT TST PCHAR ;ARE WE BEYOND 1ST CHAR? BGT 150$ ;IF SO, DON'T WORRY ABOUT "DEFAULT" STRING TST DFOPT ;ELSE, IS THERE A DEFAULT OPTION SPECIFIED? BLE 150$ ;IF NOT, GO DIRECTLY TO APPEND CARRIAGE RET. CMP DFOPT,R0 ;ELSE, IS THIS OPTION THE DEFAULT OPTION? BNE 150$ ;IF NOT, GO DIRECTLY TO APPEND CARRIAGE RET. TYPWLB #TDFLT,#NDFLT,#53 ;ELSE, APPEND "DEFAULT" FLAG TO LINE TYPED BR 140$ ;THEN GO BACK FOR MORE (CR FOLLOWED ABOVE LINE) 150$: TYPWLB #CRET,#1,#0 ;OUTPUT TERMINATING CR FOR LINE IN PROGRESS BR 140$ ;AND GO BACK FOR MORE OPTIONS ; ; ** ALL OPTIONS APPLICABLE HAVE BEEN TYPED, NOW TYPE THE "^Z" OPTION ; 160$: TST PCHAR ;ARE WE AT BEGINNING OF LINE? BLE 163$ ;IF NOT, PRINT ^Z OPTION MESSAGE JMP CTRLR ;ELSE, GO DIRECTLY TO ^R CODE 163$: TYPWLB #LFD,#4,#0 ;PRINT LF+3 SPACES BEFORE NEXT LINE TYPWLB #TCTRLZ,#NCTRLZ,#0 ;PRINT THE "^Z" OPT. STRING (SUPPRESS CR/LF) JMP CTRLR ;AND PRETEND A "^R" WAS TYPED TO PROMPT USER ;AGAIN, AND RETYPE THE STRING IN PROGRESS. .SBTTL UTILITY FUNCTIONS AND SUBROUTINES ; SNDBEL: TYPWLB #BELL,#1,#0 ;SEND BELL TO TERMINAL WTSE$C 1 ;WAIT FOR IT TO FINISH JMP GETCHR ;AND WAIT FOR THE NEXT CHARACTER. ; ; CONFRM: TYPWLB #TCONFM,#NCONFM,#0 ;SEND THE "CONFIRM" STRING DIR$ #RALQIO ;ASK FOR A CHAR FROM HIS TERMINAL WTSE$C 1 ;WAIT FOR IT BIC #177600,INBUF ;STRIP OFF THE PARITY BIT CMPB INBUF,#15 ;WAS IT A CARRIAGE RETURN? BEQ 165$ ;IF SO, REQUEST WAS CONFIRMED...RETURN. JMP CTRLU ;ELSE, HANDLE AS A "DELETE LINE" REQUEST. 165$: TYPWLB #CRET,#1,#0 ;ECHO CARRIAGE RETURN TO USER JMP RETRN ;AND RETURN TO CALLER (FUNCTION CODE TO BE ;RETURNED TO CALLER IS ASSUMED TO BE LOADED ;PRIOR TO ENTERING THIS ROUTINE). ; ; ; ** TESTOP ** ; THIS SUBROUTINE IS CALLED TO TEST WHETHER A PARTIAL STRING TYPED BY ; THE USER IS FULLY QUALIFIED YET (IE, IS A UNIQUE STRING WHEN COMPARED ; TO THE AVAILABLE OPTION STRINGS). ON EXIT, R0 CONTAINS EITHER "-1", ; IF THE STRING IS NOT UNIQUE, OR A POSITIVE NUMBER EQUAL TO THE NUMBER ; OF THE OPTION STRING TO WHICH IT IS UNIQUELY EQUIVALENT. TESTOP: TST PCHAR ;HAS HE TYPED ANYTHING YET? BGT 180$ ;IF SO, SEARCH ALL STRINGS ; ; TEST TO SEE WHETHER THE DEFAULT OPTION APPLIES ; TST DFOPT ;ELSE, WAS A DEFAULT OPTION SPECIFIED? BGT 170$ ;IF SO, SET UP THE DEFAULT RETURN CODE MOV #-1,R0 ;ELSE, SET UP "NOT UNIQUE" RETURN VALUE FOR USER RETURN ;AND RETURN TO CALLER 170$: MOV DFOPT,R0 ;SET UP THE OPTION'S NUMBER BEFORE RETURN RETURN ;AND RETURN TO CALLER ; ; HAVE TO SEARCH ALL OPTION STRINGS TO SEE IF REALLY UNIQUE ; 180$: CLR R0 ;GET READY FOR SEARCH FOR 1ST ACCEPTABLE ITEM 190$: CMPB OPTION(R0),PCHAR ;IS THIS OPTION ACCEPTABLE SO FAR? BGE 200$ ;IF SO, EXIT THIS FIRST LOOP AND SEE IF UNIQUE. INC R0 ;ELSE, GET READY TO INSPECT NEXT OPTION BR 190$ ;GO TEST NEXT OPTION (DON'T WORRY ABOUT RUNNING ;OVER END OF TABLE...ASSUME AT LEAST 1 EXISTS) 200$: INC R0 ;HAVE TO UPDATE OPTION POINTER CALL GETSTG ;GET ADDRESS OF START OF OPTION STRING(R1) ADD PCHAR,R1 ;OFFSET TO CURRENT CHAR INC R1 ;NOW POINT TO NEXT CHAR TSTB (R1) ;IS IT A NULL? BNE 203$ ;IF NOT, PROCEED WITH FURTHER TESTS RETURN ;ELSE, THIS OPTION IS "COMPLETE"--ACCEPT IT 203$: CMP R0,NOPT ;IS THIS ONE THE LAST ONE IN THE OPTION TABLE? BLT 205$ ;IF NOT, HAVE TO SEARCH THE REMAINDER OF TABLE. RETURN ;ELSE, R0 IS NOW SET UP, SO RETURN TO CALLER ;WITH "SUCCESS" INDICATION ON UNIQUENESS. 205$: MOV R0,R2 ;SAVE PREVIOUS VALUE OF OPTION PTR CLR R3 ;USE R3 AS FLAG--0 IS FULLY QUALIFIED INC R0 ;GET READY FOR CONTINUING SEARCH 210$: CMPB OPTION-1(R0),PCHAR ;IS THIS OPTION STRING STILL OK? BLT 215$ ;IF NOT, GO ON TO NEXT OPTION MOV #1,R3 ;SET R3 FOR NON-UNIQUE STRING SINCE AT LST 2 CALL GETSTG ;EXAMINE NEXT CHAR (IF NULL, ACCEPT THIS ONE) ADD PCHAR,R1 INC R1 TSTB (R1) BNE 215$ ;IF NOT NULL, GO ON TO EXAMINE NEXT OPTION RETURN ;ELSE, IF NULL--ACCEPT AS "COMPLETE" OPTION 215$: INC R0 ;GET READY FOR NEXT OPTION CMP R0,NOPT ;IS OPTION TABLE FINISHED YET? BLE 210$ ;IF NOT, GO BACK FOR MORE TST R3 ;ELSE, WAS MORE THAN ONE OPTION FOUND? BGT 220$ ;IF SO, SET UNSUCCESSFUL AND RETURN MOV R2,R0 ;ELSE, RESTORE THE ONE OPTION # AND RETURN RETURN ; WITH "SUCCESSFUL" (FULLY QUALIFIED) 220$: MOV #-1,R0 ;SET CODE IN R0 TO INDICATE "NOT UNIQUE" RETURN ;AND RETURN TO CALLER ; ; ; ; ***GETSTG*** ; FINDS THE ADDRESS OF THE START OF AN OPTION STRING, GIVEN THE OPTION ; NUMBER DESIRED IN R0. THE RETURNED ADDRESS COMES BACK IN R1. GETSTG: MOV R0,R1 ;COPY THE OPTION NUMBER... DEC R1 ;SUBTRACT ONE (PREPARING FOR BYTE OFFSET) ASL R1 ;MULTIPLY BY TWO (FOR BYTE OFFSET) ADD OPTLOC,R1 ;COMPUTE ADDRESS IN OPTION TABLE MOV (R1),R1 ;RETRIEVE ADDRESS OF OPTION STRING FROM TABLE MOVB #'%,IOPTCC ;ESTABLISH DEFAULT AS "%" TYPE OF OPTION CMPB (R1),#'% BNE 224$ MOVB (R1)+,IOPTCC ;"%" WAS 1ST CHAR OF STRING...SAVE IT BR 228$ 224$: CMPB (R1),#'# BNE 225$ MOVB (R1)+,IOPTCC ;"#" WAS 1ST CHAR OF STRING...SAVE IT BR 228$ 225$: CMPB (R1),#'$ BNE 228$ MOVB (R1)+,IOPTCC ;"$" WAS 1ST CHAR OF STRING...SAVE IT 228$: RETURN ; ; ; ; ***TYPSTG*** ; TYPES A STRING ON THE USER'S TERMINAL, AFTER FIRST EXAMINING THE ; STRING TO DETERMINE ITS LENGTH (NULL TERMINATES IT). ; NEITHER A PRECEEDING LINEFEED NOR FOLLOWING CARRIAGE RET. ARE PRINTED. TYPSTG: MOV R1,R2 ;COPY ADDRESS FOR SEARCH FOR TERMINATOR 230$: TSTB (R2)+ ;IS THE CHARACTER A "NULL"? BNE 230$ ;IF NOT, CONTINUE THE SEARCH. DEC R2 ;ELSE READJUST THE CHAR POINTER (AFTER AUTO-INC) 240$: SUB R1,R2 ;FIND # OF CHARS IN STRING BGT 250$ ;IF AT LEAST ONE CHAR, TYPE THE STRING. RETURN ;ELSE RETURN WITHOUT TYPING ANYTHING. 250$: TYPWLB R1,R2,#0 ;TYPE THE STRING, SUPPRESSING LF AND CR. RETURN ;AND RETURN TO CALLER. ; ; ; ; ***CMPCHR*** ; COMPARES A CHARACTER POINTED TO BY R1 WITH THE CHAR IN "INBUF". ; HANDLES (AS A SPECIAL CASE) THE CONVERSION OF CODES 140-177 IN ; THE ASCII TABLE TO CODES 100-137...THIS EFFECTIVELY CONVERTS THE ; CHAR FROM LOWER TO UPPER CASE, IF THAT'S THE WAY IT STARTED OUT. CMPCHR: MOVB (R1),R3 ;COPY THE OPTION CHAR TO TEMPORARY REG BITB #100,R3 ;IS THE BIT SET FOR UPPER 1/4 OF ASCII TBL? BEQ 260$ ;IF NOT, DO A NORMAL CHAR COMPARE BICB #40,R3 ;ELSE, CONVERT THE CHAR TO UPPER CASE 260$: CMPB R3,INBUF ;NOW, ARE THEY EQUAL? (LET CALLING ROUTINE ; ;HANDLE WHETHER THEY ARE OR NOT) RETURN ;AND RETURN TO CALLER ; ; ; ***RETRN*** ; HANDLES ANY WRAPUP CHORES NECESSARY BEFORE RETURNING TO CALLER RETRN: QIOW$S #IO.DET,LUN,,,IOSB ;DETACH FROM LUN BEFORE RETURNING CONTROL RTS PC ; ; *** LABELLED COMMON BLOCK FOR RETURNING CHAR TERMINATING OPTION SELECTION ; .PSECT SELCOM,RW,D,GBL,REL,OVR ENDCHR: .BYTE 0 ;THIS LOCATION WILL STORE THE ASCII CHAR VALUE .BYTE 0 ;THIS IS DUMMY FOR NOW, TO GET TO WORD BOUNDARY .EVEN .END