Trailing-Edge
-
PDP-10 Archives
-
BB-H506D-SM_1983
-
cobol/source/ostrng.mac
There are 4 other files named ostrng.mac in the archive. Click here to see a list.
; UPD ID= 2265 on 12/20/79 at 12:05 PM by NIXON
TITLE OSTRNG FOR LIBOL
SUBTTL OLD STRING/UNSTRING ROUTINES /ACK
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1975, 1981 BY DIGITAL EQUIPMENT CORPORATION
SEARCH LBLPRM
%%LBLP==:%%LBLP
;REVISION HISTORY:
;V12 *****
;DMN 19-SEP-78 [537] FIX EDIT 521, USE TMP.DP (NEEDS FIX TO COMUNI)
;V10 *****
; EHM 14-DEC-77 [521] FIX UNSTRING INTO FIELD WITH DECIMAL PLACES.
; 10-DEC-76 [464] FIX FOR SUBSCRIPTED DESTINATIONS IN REENTRANT COBOL PROGRAM.
; 20-JUN-75 /ACK CREATION.
;*****
ENTRY STR. ;STRING WITHOUT OVERFLOW.
ENTRY STR.O ;STRING WITH OVERFLOW.
ENTRY UNS. ;UNSTRING WITHOUT OVERFLOW.
ENTRY UNS.O ;UNSTRING WITH OVERFLOW.
SALL
HISEG
SUBTTL DEFINITIONS.
;ACCUMULATORS:
ERR==0 ;ERROR STATUS.
T1==S1 ;TEMPS.
T2==S2
T3==S3
DSTPTR==4 ;DESTINATION BYTE POINTER.
DSTCNT==5 ;DESTINATION CHARACTER COUNT.
DLMPTR==6 ;DELIMITER BYTE POINTER.
DLMCNT==7 ;DELIMITER CHARACTER COUNT.
SRCPTR==10 ;SOURCE BYTE POINTER.
SRCCNT==11 ;SOURCE CHARACTER COUNT.
SW==12 ;SWITCHES.
CVTSDL==13 ;INSTRUCTION WHICH CONVERTS EITHER THE
; SOURCE OR DELIMITER CHAR.
CMPSDL==14 ;INSTRUCTION WHICH COMPARES THE SOURCE
; TO THE DELIMITER.
CVTSDS==15 ;INSTRUCTION WHICH CONVERTS THE SOURCE
; CHARACTER TO THE DESTINATION'S MODE.
AP==16 ;POINTER TO ARG LIST.
PP==17 ;PUSH DOWN POINTER.
;OTHER NAMES FOR THE ACCUMULATORS:
SRCH==T2 ;HOLDS A CHAR FROM THE SOURCE.
DLCH==T3 ;HOLDS A CHAR FROM THE DELIMITER.
T4==4 ;MORE TEMPS USED BY SUBROUTINES.
T5==5
T6==6
SXR==12 ;WHERE SUBSCRIPTING ROUTINE RETURNS THE
; BYTE POINTER.
;SWITCHES AND FLAGS:
; SWITCHES IN SW:
ALL==(1B1) ;ALL WAS SPECIFIED FOR THE CURRENT DELIMITER.
MATCH==(1B2) ;WE MATCHED A DELIMITER.
JST==(1B3) ;THE CURRENT OUTPUT ARG IS RIGHT JUSTIFIED.
NODLMS==(1B4) ;THERE WERE NO DELIMITERS FOR THE UNSTRING.
NUM==(1B5) ;THE CURRENT ARG IS NUMERIC.
SGN==(1B6) ;THE CURRENT ARG IS SIGNED.
NOSTOR==(1B7) ;DON'T STORE THE POINTER ITEM AND TALLY
; ITEM EVEN IF THE CURRENT ITEM IS SUBSCRIPTED.
OJST==(1B8) ;THE OUTPUT ARG IS RIGHT JUSTIFIED.
ONUM==(1B9) ;THE OUTPUT ARG IS NUMERIC.
SEP==(1B10) ;THE SIGN IS SEPARATE
; FLAGS IN THE ARG LIST:
SUBS==(1B8) ;THE ARG IS SUBSCRIPTED.
ALLFLG==1B35 ;THE DELIMITER HAD ALL SPECIFIED.
; FLAGS IN THE PARAMETERS:
SEPFLG==(1B6) ;THE SIGN IS SEPARATE
NUMFLG==(1B7) ;THE ARG IS NUMERIC.
SGNFLG==(1B8) ;THE ARG IS SIGNED.
JSTFLG==(1B10) ;THE ARG IS RIGHT JUSTIFIED.
NEGDEC==(1B12) ;NEGATIVE DECIMAL PLACES
; FLAGS IN THE SECOND WORD OF THE SUBSCRIPT BLOCK.
SUB1DF==1B18 ;FIRST SUBSCRIPT'S DEPENDING ITEM IS NOT COMP.
SUB1SF==1B19 ;FIRST SUBSCRIPT IS NOT COMP.
SUB2DF==1B20 ;SECOND SUBSCRIPT'S DEPENDING ITEM IS NOT COMP.
SUB2SF==1B21 ;SECOND SUBSCRIPT IS NOT COMP.
SUB3DF==1B22 ;THIRD SUBSCRIPT'S DEPENDING ITEM IS NOT COMP.
SUB3SF==1B23 ;THIRD SUBSCRIPT IS NOT COMP.
;MISCELLANEOUS SYMBOLS:
; ERROR RETURNS:
FTLERR==-1 ;HAD A FATAL ERROR WHICH HAS ALREADY
; BEEN PROCESSED.
ENDARG==1 ;HIT THE END OF THE ARGLIST.
NULARG==2 ;GOT AN ARG, BUT ITS SIZE WAS 0.
OMTARG==3 ;THE ARG WAS OMMITTED.
; NAMES FOR TEMPORARY STORAGE:
DLMTMP==0 ;PLACE TO STORE NUMERIC DELIMITERS.
SRCTMP==1 ;PLACE TO STORE NUMERIC SOURCES.
DSTTMP==2 ;PLACE TO STORE NUMERIC DESTINATIONS.
; DATA MODES:
D6MODE==0 ;DISPLAY-6.
D7MODE==1 ;DISPLAY-7.
D9MODE==2 ;DISPLAY-9.
DSMODE==2 ;HIGHEST DISPLAY MODE.
C1MODE==3 ;ONE WORD COMP.
C2MODE==4 ;TWO WORD COMP.
FPMODE==5 ;COMP-1.
C3MODE==6 ;COMP-3.
;OPDEFS:
OPDEF PJRST [JRST]
DLM.AC==SRC.MD## ;USE RHS TO HOLD COUNT OF REPETITION IN ALL "?"
SUBTTL STRING ROUTINES.
;STRING WITH OVERFLOW CLAUSE:
STR.O: PUSHJ PP, STR. ;GO DO THE STRING.
JUMPL DSTCNT, RET.2## ;IF THE DESTINATION IS FULL AND
; WE HAD TRIED TO PUT MORE IN IT,
; IT'S AN OVERFLOW, RETURN TO CALL+2.
POPJ PP, ;OTHERWISE, RETURN TO CALL+1.
;STRING ROUTINE:
STR.: PUSHJ PP, INITL ;GO INITIALIZE.
SETZM TL.ARG## ;DON'T TRY TO STORE INTO THE
; TALLYING ITEM (WHAT TALLYING ITEM?)
;SET UP THE RECEIVING ITEM AND POINTER ITEM.
PUSHJ PP, GTDOUT ;GO GET A DISPLAY OUTPUT ARG.
JUMPN ERR, STRUBL ;IF THERE WERE PROBLEMS, DIE.
MOVEM T3, DST.MD## ;SAVE THE MODE.
PUSHJ PP, SETF2 ;GO SET UP THE POINTER ITEM AND
; ADJUST THE RECEIVING ITEM'S
; PARAMETERS.
JUMPN ERR, STRUBL ;IF THERE WERE PROBLEMS, DIE.
JUMPL T2, SOVFLO ;IF THERE IS NOTHING LEFT TO
; THE RECEIVING ITEM, IT'S
; AN OVERFLOW.
MOVE DSTPTR, T1 ;SET UP DESTINATION PARAMS.
MOVEI DSTCNT, 1(T2) ;BUMP CHAR COUNT BY 1 BECAUSE
; WE WILL TEST IT BEFORE WE STORE
; INTO IT.
;TRANSFER A SET OF SOURCES TO THE DESTINATION.
SXTDL: HRRI SW, DLMTMP ;WHICH TEMP TO USE, IF WE NEED ONE.
PUSHJ PP, GTDIN ;GO GET A DELIMITER.
JUMPE ERR, SXTDLD ;IF NOTHING UNUSUAL HAPPENED, GO ON.
CAIN ERR, ENDARG ;IF THERE ARE NO MORE ARGS,
JRST DONE ; GO CLEAN UP AND RETURN.
CAIE ERR, OMTARG ;IF THE ARG WAS OMMITTED
CAIN ERR, NULARG ; OR NULL,
TRNA ; DELIMIT BY SIZE.
JRST STRUBL ;OTHERWISE, DIE.
SETZB ERR, T1 ;CLEAR ERROR CONDITION AND
SETOB T2, T3 ; SET UP DUMMY DELIMITER PARAM.
SXTDLD:
IFN BIS,<
DMOVEM T1, DLM.BP## ;SAVE DELIMITER PARAMS.
>
IFE BIS,<
MOVEM T1, DLM.BP##
MOVEM T2, DLM.CC##
>
MOVEM T3, DLM.MD##
;INITIALIZE FOR A SET OF SOURCES.
AOS T1, PT.AGL## ;GET ARG POINTER.
MOVE T1, -1(T1) ;GET COUNT OF SOURCES.
MOVEM T1, SU.AGL## ;SAVE IT.
;PICK UP THE NEXT SOURCE.
SXTSR: SOSGE T1, SU.AGL## ;ANY MORE SOURCES?
JRST SXTDL ;NO, GO SEE IF THERE ARE MORE
; DELIMITERS.
HRRI SW, SRCTMP ;WHICH TEMP TO USE, IF NECESSARY.
PUSHJ PP, GTDIN ;GO GET THE SOURCE'S PARAMS.
JUMPE ERR, SXTSRD ;IF NOTHING HAPPENED, GO ON.
CAIE ERR, NULARG ;IF IT WASN'T A NULL ARG,
JRST STRUBL ; WE 'RE IN TROUBLE.
SETZI ERR, ;OTHERWISE, IGNORE IT.
JRST SXTSR
SXTSRD:
IFN BIS,<
DMOVE SRCPTR,T1
>
IFE BIS,<
MOVE SRCPTR, T1 ;SAVE SOURCE'S PARAMS.
MOVE SRCCNT, T2
>
HRLZM T3, SRC.MD##
;SET UP CONVERSION/COMPARISON INSTRUCTIONS.
HRLZI CVTSDL, (<JFCL>) ;MAKE CONVERSION A NO-OP.
HRLZI CMPSDL, (<TRNA>) ;MAKE COMPARISON A NO-OP THAT SKIPS.
SKIPL DLM.MD## ;IS THERE A DELIMITER?
PUSHJ PP, SCVSDL ;YES, GO SET UP SOURCE/DELIMITER INSTR'S.
PUSHJ PP, SCVSDS ;GO SET UP SOURCE/DESTINATION INSTR.
;MAIN LOOP FOR STRING ROUTINE.
MOVE DLMPTR, DLM.BP## ;GET THE FIRST CHARACTER OF THE
ILDB DLCH, DLMPTR ; DELIMITER.
SMLD: ILDB SRCH, SRCPTR ;GET A SOURCE CHAR.
XCT CVTSDL ;CONVERT, IF NECESSARY.
XCT CMPSDL ;COMPARE SOURCE/DELIMITER.
JRST SMLL ;EQUAL, GO TRY TO MATCH MORE.
SMLH: SOJL DSTCNT, DONE ;IF THE DESTINATION IS FULL,
; IT'S AN OVERFLOW.
XCT CVTSDS ;CONVERT, IF NECESSARY.
IDPB SRCH, DSTPTR ;STASH THE CHAR.
AOS PT.VLU## ;BUMP THE POINTER.
SOJGE SRCCNT, SMLD ;IF THERE ARE MORE SOURCE
; CHAR'S GO TRY TO MATCH AGAIN.
JRST SXTSR ;OTHERWISE, GO GET THE NEXT SOURCE.
;FIRST CHAR OF DELIMITER MATCHES A SOURCE CHAR.
SMLL: SKIPG DLMCNT, DLM.CC## ;SET UP DELIMITER.
JRST SXTSR ;IF IT'S ONLY ONE CHAR LONG, GO
; GET THE NEXT SOURCE.
IFN BIS,<
DMOVEM SRCPTR,SRC.PT##
>
IFE BIS,<
MOVEM SRCPTR, SRC.PT## ;SAVE SOURCE INFO.
MOVEM SRCCNT, SRC.CT##
>
SMLP: SOJL DLMCNT, SXTSR ;IF THERE IS NO MORE DELIMITER,
; IT'S A MATCH.
SOJL SRCCNT, SMLT ;IF THERE IS NO MORE SOURCE, IT'S
; NOT A MATCH.
ILDB DLCH, DLMPTR ;GET THE NEXT DELIMITER CHAR.
ILDB SRCH, SRCPTR ;GET THE NEXT SOURCE CHAR.
XCT CVTSDL ;CONVERT IF NECESSARY.
XCT CMPSDL ;COMPARE SOURCE/DELIMITER.
JRST SMLP ;GO SEE IF THERE IS ANY MORE.
;DELIMITER DOESN'T MATCH SOURCE.
SMLT:
IFN BIS,<
DMOVE SRCPTR,SRC.PT
>
IFE BIS,<
MOVE SRCPTR, SRC.PT## ;RESTORE SOURCE INFO.
MOVE SRCCNT, SRC.CT##
>
LDB SRCH, SRCPTR
MOVE DLMPTR, DLM.BP## ;GET THE FIRST CHAR OF THE
ILDB DLCH, DLMPTR ; DELIMITER AGAIN.
JRST SMLH ;PICK UP WHERE WE LEFT OFF.
;OVERFLOW ON INITIAL POINTER VALUE.
SOVFLO: SETOI DSTCNT, ;MAKE THE COUNT NEGATIVE.
POPJ PP,
SUBTTL UNSTRING ROUTINES.
;UNSTRING WITH OVERFLOW CLAUSE.
UNS.O: PUSHJ PP, UNS. ;GO DO THE UNSTRING.
JUMPGE SRCCNT, RET.2## ;IF THERE ARE SOURCE
; CHAR'S LEFT, OVERFLOW.
POPJ PP, ;OTHERWISE, RETURN TO CALL+1.
;UNSTRING ROUTINE:
UNS.: PUSHJ PP, INITL ;INITIALIZE.
;SET UP SENDING ITEM, POINTER ITEM AND TALLYING ITEM.
HRRI SW, SRCTMP ;WHICH TEMP TO USE IF NECESSARY.
PUSHJ PP, GTDIN ;GO GET AN ARG.
JUMPN ERR, UTRUBL ;IF THERE WERE PROBLEMS, GO DIE.
HRLZM T3, SRC.MD## ;SAVE THE SOURCE'S MODE.
PUSHJ PP, SETF2 ;GO GET THE POINTER ITEM AND
; ADJUST THE SENDING ITEM'S PARAM'S.
JUMPN ERR, UTRUBL ;IF THERE WERE PROBLEMS, GO DIE.
JUMPL T2, UOVFLO ;IF THERE IS NOTHING LEFT TO THE
; SOURCE, IT'S AN OVERFLOW.
IFN BIS,<
DMOVE SRCPTR,T1
DMOVEM SRCPTR,SRC.BP##
>
IFE BIS,<
MOVE SRCPTR, T1 ;SET UP SOURCE'S PARAMS.
MOVE SRCCNT, T2
MOVEM SRCPTR, SRC.BP## ;NOTE WHERE WE ARE IN THE SOURECE.
MOVEM SRCCNT, SRC.CC##
>
AOS T1, PT.AGL## ;BUMP UP TO NEXT ARG.
MOVE T1, -1(T1) ;PICK UP THE TALLYING ITEM'S ARG.
MOVEM T1, TL.ARG## ;SAVE IT.
SETZM TL.VLU## ;CLEAR THE TALLY COUNT.
;SET UP POINTER TO DELIMITERS AND BUMP THE ARG POINTER OVER THEM.
AOS T1, PT.AGL## ;GET THE POINTER TO THE ARGS.
SKIPN T2, -1(T1) ;GET NUMBER OF WORDS USED FOR
; DELIMITERS.
TLO SW, NODLMS ;IF THERE AREN'T ANY DELIMITERS,
; NOTE IT.
ADDB T2, PT.AGL## ;MOVE POINTER OVER DELIMITERS.
IFN BIS,<
DMOVEM T1, BS.DLM##
>
IFE BIS,<
MOVEM T1, BS.DLM## ;SAVE BASE OF DELIMITER ARGS.
MOVEM T2, TP.DLM## ;SAVE TOP OF DELIMITER ARGS.
>
;MAIN UNSTRING LOOP.
UML: JUMPL SRCCNT, DONE ;IF THERE IS NO MORE SOURCE,
; WE'RE THROUGH.
MOVE T1, PT.AGL## ;GET THE POINTER TO THE ARG LIST.
MOVE T2, (T1) ;GET THE DELIMITER STORE'S
; ARG POINTER.
IOR T2, 1(T1) ;GET THE COUNT ITEM'S ARG POINTER.
TLNE T2, SUBS ;IF EITHER OF THEM ARE SUBSCRIPTED
PUSHJ PP, SPTATL ; GO STORE THE POINTER AND TALLY
; ITEMS.
PUSHJ PP, GTDOUT ;GO GET A DESTINATION.
JUMPE ERR, UMLD ;IF NOTHING SPECIAL HAPPENED, GO ON.
CAIN ERR, ENDARG ;IF THERE ARE NO MORE DESTINATIONS
JRST DONE ; WE'RE THROUGH.
CAIE ERR, NULARG ;IF IT WASN'T A NULL ARG,
JRST UTRUBL ; WE'RE IN TROUBLE.
SETZI ERR, ;CLEAR THE ERROR INDICATOR.
SETOI T2, ;SET UP A DUMMY DESTINATION.
SETZB T1, T3
UMLD:
IFN BIS,<
DMOVE DSTPTR, T1
>
IFE BIS,<
MOVE DSTPTR, T1 ;SET UP DESTINATION PARAMS.
MOVE DSTCNT, T2
>
MOVEM T3, DST.MD##
TLNN SW, NODLMS ;WERE THERE ANY DELIMITERS?
JRST UMLH ;YES, GO EXAMINE THE SOURCE.
;THERE WEREN'T ANY DELIMITERS, MOVE AS MUCH AS WE CAN INTO THE DESTINATION.
CAILE DSTCNT, (SRCCNT) ;IF THE DESTINATION IS LARGER
SKIPA T1, SRC.CC## ; THAN THE SOURCE, MOVE ALL OF
; THE CHARS IN THE SOURCE.
MOVE T1, DSTCNT ;OTHERWISE, ONLY MOVE ENOUGH TO
; FILL THE DESTINATION.
EXCH T1, SRC.CC## ;SET NUMBER OF CHARS TO MOVE.
SUBI T1, 1(DSTCNT) ;SEE HOW MANY CHARS WILL BE
; LEFT IN THE SOURCE.
PUSH PP, T1 ;SAVE IT.
SETOM SE.DLM## ;SET NUMBER OF CHARS TO BE MOVED
; TO THE DELIMITER STORE TO ZERO.
PUSHJ PP, STOREM ;GO DO THE MOVE.
POP PP, SRCCNT ;SET NUMBER OF CHARS REMAINING
; IN THE SOURCE.
JUMPN ERR, UTRUBL ;IF WE HAD PROBLEMS DURING THE
; MOVE, GO DIE.
MOVEM SRCCNT, SRC.CC## ;NOTE WHERE WE ARE IN THE SOURCE.
JRST UML ;GO DO THE NEXT DESTINATION.
;THERE WERE DELIMITERS, WE HAVE TO EXAMINE THE SOURCE.
UMLH: MOVE T1, BS.DLM## ;SET UP POINTER TO DELIMITERS.
MOVEM T1, SU.AGL##
UMLL: HRLM SRCCNT, SE.DLM## ;INITIALIZE START AND END OF
HRRM SRCCNT, SE.DLM## ; DELIMITER.
AOS SU.AGL## ;BUMP UP TO NEXT DELIMITER.
AOS T1, SU.AGL##
CAMG T1, TP.DLM## ;HAVE WE GONE TOO FAR?
JRST UMLDS ;NO, GO CHECK THIS DELIMITER.
;CHECKED THE CURRENT SOURCE CHAR AGAINST ALL DELIMITERS.
IBP SRCPTR ;BUMP UP TO NEXT SOURCE CHAR.
SOJGE SRCCNT, UMLH ;IF THERE ARE MORE SOURCE CHARS, LOOP.
SETOM SE.DLM## ;FORCE EVERYTHING INTO THE
; CURRENT SOURCE.
UMLP: PUSHJ PP, STOREM ;GO DO THE MOVE.
JUMPN ERR, UTRUBL ;IF THERE WERE PROBLEMS, DIE.
JRST UML ;GO SEE IF THERE ARE MORE SOURCE CHARS.
;CHECK A DELIMITER AGAINST THE CURRENT SOURCE CHAR.
UMLDS: MOVE T2, -1(T1) ;GET THE ALL FLAG.
TRNE T2, ALLFLG ;REMEMBER ITS SETTING.
TLOA SW, ALL
TLZ SW, ALL
MOVE T1, -2(T1) ;GET THE ARG.
HRRI SW, DLMTMP ;WHICH TEMP TO USE IF NECESSARY.
PUSHJ PP, GTPRMT ;GO GET THE PARAMS.
JUMPE ERR, UMLDSD ;IF THERE WEREN'T ANY PROBLEMS, GO ON.
CAIE ERR, NULARG ;IF IT WAS A NULL ARG, IGNORE IT.
JRST UTRUBL ;OTHERWISE, DIE.
SETZI ERR,
JRST UMLL
UMLDSD:
IFN BIS,<
DMOVEM T1, DLM.BP## ;SAVE DELIMITER INFO.
>
IFE BIS,<
MOVEM T1, DLM.BP## ;SAVE DELIMITER INFO.
MOVEM T2, DLM.CC##
>
MOVEM T3, DLM.MD##
PUSHJ PP, SCVSDL ;SET UP CONVERSION/COMPARISON INSTR.
;COMPARE SOURCE AND DELIMITER.
TLZ SW, MATCH ;TURN OFF MATCH FLAG.
IFN BIS,<
DMOVEM SRCPTR, SRC.PT
>
IFE BIS,<
MOVEM SRCPTR, SRC.PT## ;SAVE SOURCE INFO.
MOVEM SRCCNT, SRC.CT##
>
UMLDSH:
IFN BIS,<
DMOVE DLMPTR,DLM.BP
>
IFE BIS,<
MOVE DLMPTR, DLM.BP## ;SET UP DELIMITER.
MOVE DLMCNT, DLM.CC##
>
SKIPGE SRCCNT ;IF THE SOURCE ISN'T NULL,
UMLDSP: SOJL SRCCNT, UMLDST ;DON'T DECREMENT THE FIRST TIME.
ILDB SRCH, SRCPTR ;GET A SOURCE CHAR.
ILDB DLCH, DLMPTR ;GET A DELIMITER CHAR.
XCT CVTSDL ;CONVERT, IF NECESSARY.
XCT CMPSDL ;COMPARE THEM.
JRST UMLDSX ;EQUAL, GO TRY TO MATCH MORE.
UMLDST: TLNE SW, MATCH ;DID WE HAVE A MATCH?
JRST UMLP ;YES, GO DO THE MOVE AND LOOP.
;SOURCE DOESN'T MATCH DELIMITER.
IFN BIS,<
DMOVE SRCPTR,SRC.PT
>
IFE BIS,<
MOVE SRCPTR, SRC.PT## ;RESTORE SOURCE INFO.
MOVE SRCCNT, SRC.CT##
>
JRST UMLL ;GO LOOK FOR ANOTHER DELIMITER.
;SOURCE CHAR MATCHES DELIMITER CHAR.
UMLDSX: SOJGE DLMCNT, UMLDSP ;IF THERE IS MORE TO THIS DELIMITER,
; GO LOOK AT MORE OF THE SOURCE.
SUBI SRCCNT, 1 ;UPDATE THE SOURCE COUNT.
IFN ANS74,<
TLC SW,ALL!MATCH ;WAS ALL SPECIFIED
TLCN SW,ALL!MATCH ;AND DO WE ALREADY HAVE A MATCH?
PUSHJ PP,[ AOS DLM.AC ;YES, COUNT REPETITIONS
HRLZS SE.DLM ;PRETEND LAST OCCURRENCE OF
POPJ PP,] ; DELIMITER STRING IS ONLY ONE
>
HRRM SRCCNT, SE.DLM## ;REMEMBER WHERE THE DELIMITER ENDS.
TLNN SW, ALL ;WAS ALL SPECIFIED?
JRST UMLP ;NO, GO DO THE MOVE.
TLO SW, MATCH ;NOTE THAT WE HAD A MATCH.
JRST UMLDSH ;GO TRY TO MATCH AGAIN.
;WE HAD AN OVERFLOW ON THE INITIAL POINTER VALUE.
UOVFLO: SETZI SRCCNT, ;MAKE THE COUNT NON NEGATIVE.
POPJ PP, ;RETURN.
SUBTTL COMMON SUBROUTINES FOR STRING/UNSTRING.
;INITIALIZATION ROUTINE.
INITL: MOVEM AP, BS.AGL## ;SET BASE OF ARG LIST.
MOVEM AP, PT.AGL## ;SET POINTER TO CURRENT ARG.
HLRE T1, -1(AP) ;GET ARG COUNT.
SUBI AP, (T1) ;FORM ADDR OF LAST ARG+1.
HRRZM AP, TP.AGL## ;SAVE IT.
SETZB SW, ERR ;CLEAR THE SWITCH AND ERROR REGS.
MOVE T1, D6MODE ;SET THE PREFERED MODE TO
MOVEM T1, PF.MDE## ; DISPLAY-6.
CPOPJ: POPJ PP, ;RETURN.
;ROUTINE TO PICK UP THE POINTER ITEM AND ADJUST THE ITEM IN T1 AND T2.
SETF2: PUSH PP, T1 ;SAVE THE ITEM'S PARAMS.
PUSH PP, T2
MOVEM T3, PF.MDE## ;MAKE THE PREFERED MODE THIS
; ITEM'S MODE.
MOVE T1, @PT.AGL## ;GET THE POINTER ARG.
MOVEM T1, PT.ARG## ;SAVE IT.
PUSHJ PP, GTNIN ;GET A NUMERIC INPUT ARG'S VALUE.
JUMPE ERR, SETF2D ;IF NOTHING UNUSUAL HAPPEND, GO ON.
CAIE ERR, OMTARG ;IF IT WASN'T AN OMMITTED ARG,
JRST SETF2L ; LET THE CALLER WORRY ABOUT IT.
; POINTER WAS OMMITTED.
SETZB ERR, T1 ;DEFAULT VALUE TO 1.
MOVEI T2, 1
; POINTER VALUE IS IN T1 AND T2 AS A DOUBLE PRECISION NUMBER.
SETF2D: JUMPN T1, SETF2H ;IF THE HIGH ORDER WORD ISN'T
JUMPLE T2, SETF2H ; ZERO OR THE VALUE WAS LESS THAN
; ONE, IT'S AN OVERFLOW.
MOVEM T2, PT.VLU## ;SAVE THE POINTER VALUE.
MOVE T3, T2
; ADJUST THE BYTE POINTER AND COUNT OF THE ITEM.
POP PP, T2 ;GET THE COUNT AND
POP PP, T1 ; BYTE POINTER BACK.
SOJLE T3, CPOPJ ;IF WE DON'T HAVE TO ADJUST IT, LEAVE.
SUBI T2, (T3) ;ADJUST THE COUNT.
JUMPL T2, CPOPJ ;IF IT WENT NEGATIVE LEAVE.
IFN BIS,<
ADJBP T3,T1
MOVE T1,T3 ;PUT BYTE PTR BACK
>
IFE BIS,<
IBP T1 ;BUMP THE BYTE POINTER OVER THE
SOJG T3, .-1 ; UNWANTED BYTES.
>
POPJ PP, ;RETURN.
; OVERFLOW ON POINTER'S INITIAL VALUE.
SETF2H: SETOI T2, ;SET THE COUNT TO -1 TO FORCE OVERFLOW.
SETF2L: POP PP, T1 ;CLEAN UP THE STACK.
POP PP, T1
POPJ PP, ;RETURN
;SET UP COMPARISON/CONVERSION INSTRUCTIONS FOR SOURCE/DELIMITER.
SCVSDL: HLRE T1, SRC.MD## ;GET THE SOURCE MODE.
HRLZI CVTSDL, (<JFCL>) ;ASSUME SOURCE AND DELIMITER ARE
; THE SAME MODE.
CAME T1, DLM.MD## ;ARE THEY?
HRLI CVTSDL, (<LDB T1,0>) ;NO, HAVE TO DO A LDB THEN.
IMULI T1, 3 ;FORM INDEX.
ADD T1, DLM.MD
HRR CVTSDL, SCVDLT(T1) ;SELECT A BYTE POINTER.
HLLZ CMPSDL, SCVDLT(T1) ;SELECT A COMPARISON INSTRUCTION.
POPJ PP, ;RETURN.
; TABLE OF INSTRUCTIONS. LEFT HALF IS THE COMPARISON INSTRUCTION, RIGHT
; HALF IS THE ADDRESS OF THE BYTE POINTER FOR THE CONVERSION INSTRUCTION.
SCVDLT: CAIN SRCH, (DLCH)
CAIN T1, SU.S67##(DLCH)
CAIN T1, SU.S69##(DLCH)
CAIN T1, SU.D67##(SRCH)
CAIN SRCH, (DLCH)
CAIN T1, SU.S79##(DLCH)
CAIN T1, SU.D69##(SRCH)
CAIN T1, SU.D79##(SRCH)
CAIN SRCH, (DLCH)
;SET UP THE CONVERSION INSTRUCTION FOR SOURCE DESTINATION.
SCVSDS: HLRE T1, SRC.MD## ;GET THE SOURCE MODE.
IMULI T1, 3 ;FORM THE TABLE INDEX.
ADD T1, DST.MD##
MOVE CVTSDS, SCVSST(T1) ;GET THE INSTRUCTION.
POPJ PP, ;RETURN.
SCVSST: JFCL
LDB SRCH, SU.S67##
LDB SRCH, SU.S69##
LDB SRCH, SU.S76##
JFCL
LDB SRCH, SU.S79##
LDB SRCH, SU.S96##
LDB SRCH, SU.S97##
JFCL
;ROUTINE TO SET UP A DISPLAY OUTPUT ARG'S PARAMS. IF THE ARG IS NUMERIC
; WE WILL RETURN PARAMETERS WHICH WILL CAUSE THE ITEM TO BE STORED IN A
; TEMP. THEN WHEN THE ROUTINE CLRTMP IS CALLED WE WILL STORE THE ARG.
GTDOUT: PUSHJ PP, GTPRMS ;GET THE PARAMETERS.
JUMPN ERR, CPOPJ ;PASS ERRORS BACK TO CALLER.
TLZ SW, ONUM!OJST ;SAVE THE NUMERIC AND
TLNE SW, NUM ; JUSTIFIED SWITCHES.
TLO SW, ONUM
TLNE SW, JST
TLO SW, OJST
TLNN SW, NUM ;IF THE ARG ISN'T NUMERIC,
POPJ PP, ; RETURN.
; THE ARG IS NUMERIC.
MOVE T1, PT.AGL## ;REMEMBER WHICH ARG WE ARE
MOVEM T1, OU.ARP## ; WORKING ON.
HRRI T1, OU.TMP## ;SET UP PARAMS TO POINT TO THE TEMP.
MOVE T3, PF.MDE## ;USE THE PREFERED MODE.
HLL T1, TMPTRS(T3) ;SELECT THE APPROPRIATE BYTE SIZE.
MOVEM T3, OU.MDE## ;SAVE THE MODE (IT CAN CHANGE).
TLO SW, JST!OJST!NUM ;MAKE SURE THE RIGHT JUSTIFIED
; AND NUMERIC FLAGS ARE ON.
POPJ PP, ;RETURN.
;ROUTINE TO STORE THE NUMERIC ARG CURRENTLY STORED IN A TEMP.
CLRTMP: SKIPN T1, OU.ARP## ;ANYTHING THERE?
POPJ PP, ;NO, RETURN.
MOVE T1, -1(T1) ;GET THE POINTER TO THE PARAMS.
PUSHJ PP, GTPRMT ;GET THE PARAMS.
PUSHJ PP, SVACS ;SAVE NON-TEMP AC'S.
PUSH PP, T1 ;SAVE THE PARAMS.
PUSH PP, T2
PUSH PP, T3
HRRI T1, OU.TMP## ;SET UP PARAMS.
MOVE T3, OU.MDE##
HLL T1, TMPTRS(T3)
MOVE T4, TMP.DP## ;[537] NUM OF DECIMAL PLACES
PUSHJ PP, GTNUM ;GO CONVERT THE DISPLAY NUMERIC
; TO A TWO WORD COMP ITEM.
JUMPLE T4, CLRTM1 ;[521] DOES IT HAVE DECIMAL PLACES?
CAIG T4, ^D10 ;[521] MORE THAN 10 DECIMAL PLACES
JRST CLRTMB ;[521] NO GET ONE WORD POWER OF 10
SUBI T4, ^D11 ;[521] GET INDEX INTO DPWR10
LSH T4, 1 ;[521]
IFE BIS,<
MOVE T5, DC.TB2+1(T4) ;[521] GET 2-WORD POWER
MOVE T4, DC.TB2(T4) ;[521] OF 10 IN 4 & 5
>
IFN BIS,<
DMOVE T4,DC.TB2(T4) ;[521]
>
JRST CLRTMC ;[521] GO DO MULTIPLY
CLRTMB: MOVE T5, DC.TB1(T4) ;[521] GET ONE WORD POWER OF 10
SETZ T4, ;[521] MAKE IT A 2 WORD
CLRTMC:
IFN BIS,<
DMUL T1,T4 ;[521] RESULT IN 1 & 2 & 3 & 4
DMOVE T1,T3 ;[521] PUT RESULT IN AC 1 & 2
>
IFE BIS,<
;MULTIPLY HIGH-B BY LOW-A, LEAVING A 1-WORD PRODUCT IN T4.
IMUL T4,T2
;THEN MULTIPLY LOW-A BY LOW-B, LEAVING A 2-WORD PRODUCT IN AC'S T2 & T3
MUL T2,T5
;AND MULTIPLY HIGH-A BY LOW-B, LEAVING A 1-WORD PRODUCT IN T1.
IMUL T1,T5
;THE LOW-ORDER WORD OF THE FINAL PRODUCT NOW APPEARS IN T3. FIX UP
;HIGH-ORDER HALF.
ADD T1,T2 ;ADD HIGH HALF OF RESULT OF MUL2
ADD T1,T4 ; AND RESULT OF MUL1 TO GIVE FINAL HIGH HALF.
TLZ T1,1B18 ;IGNORE OVERFLOW
MOVE T2,T3 ;GET RESULT IN T1 & T2
>
CLRTM1: POP PP, T5 ;[521]GET THE ORIGIONAL PARAMS BACK.
POP PP, T4
POP PP, T3
PUSHJ PP, PUTNUM ;GO STORE THE NUMBER.
SETZM OU.ARP## ;REMEMBER THAT WE HAVE STORED IT.
POPJ PP, ;RETURN.
;ROUTINE TO GET A DISPLAY INPUT ARG. IF IT IS NUMERIC, MAKE IT DISPLAY.
GTDIN: PUSHJ PP, GTPRMS ;GET THE PARAMS.
JUMPN ERR, CPOPJ ;PASS ERRORS BACK TO CALLER.
TLZN SW, NUM ;IF THE ARG ISN'T NUMERIC,
POPJ PP, ; RETURN.
TLZE SW, SEP ;IF SEPARATE SIGN,
POPJ PP, ; LEAVE IT DISPLAY
; THE ARG IS NUMERIC. MAKE IT DISPLAY.
PUSHJ PP, SVACS ;SAVE NON-TEMP AC'S.
PUSH PP, T2 ;SAVE THE ITEM'S SIZE.
PUSHJ PP, GTNUM ;GO GET THE NUMBER INTO T1 & T2.
HRR T3, TMPTRS(SW) ;GET THE TEMP'S ADDRESS.
MOVE T4, (PP) ;SET THE ITEM'S SIZE.
MOVE T5, PF.MDE## ;USE THE PREFERED MODE.
HLL T3, TMPTRS(T5) ;SET THE BYTE SIZE.
TLZ SW, SGN ;MAKE IT UNSIGNED.
PUSHJ PP, PUTNUM ;MOVE THE NUMBER TO TEMP.
HRR T1, TMPTRS(SW) ;RECONSTRUCT PARAMS FOR CALLER.
POP PP, T2
MOVE T3, PF.MDE##
HLL T1, TMPTRS(T3)
POPJ PP, ;RETURN.
; POINTERS TO TEMPORARY STORAGE. LEFT HALF IS INDEXED BY MODE, RIGHT
; HALF IS INDEXED BY THE TEMP AREA DESIRED.
TMPTRS: POINT 6,TMP.DL## ;DISPLAY-6 - DELIMITER.
POINT 7,SR.TMP## ;DISPLAY-7 - SOURCE.
POINT 9,OU.TMP## ;DISPLAY-9 - DESTINATION.
;ROUTINE TO GET THE PARAMS FOR THE NEXT ARG.
GTPRMS: PUSHJ PP, NXTARG ;GO GET THE ARG POINTER.
JUMPN ERR, CPOPJ ;PASS ERRORS BACK TO CALLER.
GTPRMT: PUSHJ PP, GSETP ;GO GET THE PARAMETERS.
JUMPN ERR, CPOPJ ;PASS ERRORS BACK TO CALLER.
; PUT THE PARAMS IN A MORE AMINABLE FORMAT.
TLZ SW, NUM!SGN!JST!SEP ;TRANSFER FLAGS TO THE SWITCH REGISTER.
TLNE T2, SEPFLG
TLO SW, SEP
TLNE T2, NUMFLG
TLO SW, NUM
TLNE T2, SGNFLG
TLO SW, SGN
TLNE T2, JSTFLG
TLO SW, JST
LDB T3, [POINT 5,T2,17] ;[521] GET NO. DECIMAL PLACES
TLNE T2, NEGDEC ;NEGATIVE DECIMAL PLACES?
MOVNS T3 ; YES, NEGATE
MOVEM T3, TMP.DP## ;[537] REMEMBER THAT
LDB T3, [POINT 4,T2,4] ;GET THE MODE.
HRRZI T2, (T2) ;ISOLATE THE SIZE.
SOJGE T2, CPOPJ ;USE ZERO ORIGN INDEXING.
MOVEI ERR, NULARG ;IF THE ARG IS NULL,
POPJ PP, ; TELL THE CALLER ABOUT IT.
;ROUTINE TO PICK UP THE NEXT ARG POINTER.
NXTARG: AOS T1, PT.AGL## ;GET THE POINTER TO THE ARG POINTERS.
CAMG T1, TP.AGL## ;HAVE WE GONE TOO FAR?
JRST NXTARK ;NO, GO GET THE ARG POINTER.
MOVEI ERR, ENDARG ;TELL CALLER.
POPJ PP,
NXTARK: SKIPE T1, -1(T1) ;WAS THE ARG OMMITTED?
POPJ PP, ;NO, RETURN WITH ARG POINTER IN T1.
MOVEI ERR, OMTARG ;TELL CALLER.
POPJ PP,
;ROUTINE TO PICK UP A NUMERIC INPUT ARG.
GTNIN: PUSHJ PP, GTPRMS ;GO GET THE PARAMETERS.
JUMPN ERR, CPOPJ ;PASS ERRORS BACK TO CALLER.
GTNUM: MOVE T3, GTNUMD(T3) ;PICK UP THE ADDRESSES OF SOME ROUTINES.
AOJA T2, (T3) ;CORRECT THE SIZE AND DISPATCH.
GTNUMD: XWD GD6.##, GTNUMH ;DISPLAY-6.
XWD GD7.##, GTNUMH ;DISPLAY-7.
XWD GD9.##, GTNUMH ;DISPLAY-9.
XWD 0, GTNUML ;ONE WORD COMP.
XWD 0, GTNUMP ;TWO WORD COMP.
XWD 0, GTNUMT ;COMP-1.
XWD GC3.##, GTNUMH ;COMP-3.
; DISPLAY OR COMP-3.
GTNUMH: PUSH PP, T2 ;SAVE THE SIZE.
HLRZS T3 ;PUT LIBOL ROUTINE'S ADDRESS
; IN THE RIGHT PLACE.
PUSHJ PP, CLRTNI ;GO BUILD PARAMETER AND CALL ROUTINE.
POP PP, T3 ;GET THE SIZE BACK.
CAIG T3, ^D10 ;ONE OR TWO WORD COMP.
MULI T1, 1 ;ONE, MAKE IT TWO.
POPJ PP, ;RETURN.
; ONE WORD COMP.
GTNUML: MOVE T1, (T1) ;PICK IT UP.
MULI T1, 1 ;MAKE IT TWO WORDS.
POPJ PP, ;RETURN.
; TWO WORD COMP.
GTNUMP:
IFN BIS,<
DMOVE T1,0(T1)
>
IFE BIS,<
MOVE T2, 1(T1) ;PICK IT UP.
MOVE T1, (T1)
>
POPJ PP, ;RETURN.
; COMP-1.
GTNUMT: PUSHJ PP, SVACS ;SAVE ALL NON-TEMP AC'S.
MOVE T1, (T1) ;GET THE FLOATING POINT NUMBER.
MOVE AP, [Z T1,T1] ;SET UP THE PARAM.
PJRST FIX.## ;GO CONVERT IT AND RETURN.
;ROUTINE TO CALL AN EXTERNAL LIBOL ROUTINE TO PICK UP A NUMBER.
CLRTNI: PUSHJ PP, SVACS ;SAVE ALL NON TEMP AC'S.
DPB T2, [POINT 12,T1,17] ;BUILD THE PARAM.
TLNE SW, SGN
TLO T1, (1B6)
MOVE AP, [Z T1,T1] ;SET UP THE ARG POINTER.
PJRST (T3) ;GO DO THE CONVERSION AND RETURN.
;ROUTINE TO STORE THE DOUBLE PRECISION NUMBER IN T1 & T2 INTO THE ITEM
; WHOSE PARAMETERS ARE IN T3, T4 & T5.
PUTNUM: AOS T4 ;CORRECT THE SIZE.
DPB T4, [POINT 12,T3,17] ;BUILD A PARAMETER FOR
TLNE SW, SGN ; A CALL TO AN EXTERNAL
TLO T3, (1B6) ; LIBOL ROUTINE.
PUSH PP, T3 ;SAVE IT.
PUSH PP, T5 ;SAVE THE MODE.
; LEFT TRUNCATE.
HRLI AP, (<Z T1,0>) ;SET UP LEFT HALF OF ARG.
CAILE T4, ^D10 ;DO WE WANT A ONE OR TWO WORD COMP.
JRST PUTNUD ;TWO WORDS, GO ON.
HRRI AP, DC.TB1##(T4) ;GET THE ADDRESS OF THE NUMBER
PUSHJ PP, DIV.21## ; TO DIVIDE BY AND GO DO THE DIVISION.
JRST PUTNUF
PUTNUD: SUBI T4, ^D11 ;GET THE ADDRES OF THE NUMBER
LSH T4, 1 ; TO DIVIDE BY.
HRRI AP, DC.TB2##(T4)
PUSHJ PP, DIV.22## ;GO DO THE DIVISION.
MOVE T2, T1+3 ;PUT THE RESULTS WHERE WE CAN
PUTNUF: MOVE T1, T1+2 ; FIND THEM.
POP PP, T5 ;RESTORE THE PARAMS.
POP PP, T3
MOVE T5, PUTNUJ(T5) ;SELECT SOME ROUTINES.
JRST (T5) ;DISPATCH.
PUTNUJ: XWD PD6.##, PUTNUP ;DISPLAY-6.
XWD PD7.##, PUTNUP ;DISPLAY-7.
XWD PD9.##, PUTNUP ;DISPLAY-9.
XWD 0, PUTNUT ;ONE WORD COMP.
XWD 0, PUTNUR ;TWO WORD COMP.
XWD 0, PUTNUV ;COMP-1.
XWD PC3.##, PUTNUP ;COMP-3.
; DISPLAY OR COMP-3.
PUTNUP: HLRZS T5 ;GET THE ROUTINE TO USE.
MOVE AP, [Z T1,T3] ;SET UP THE PARAM.
PJRST (T5) ;GO STORE THE NUMBER AND RETURN.
; TWO WORD COMP.
PUTNUR:
IFN BIS,<
DMOVEM T1, (T3)
>
IFE BIS,<
MOVEM T2, 1(T3) ;STORE THE NUMBER.
MOVEM T1, (T3)
>
POPJ PP, ;RETURN.
; FLOATING POINT & ONE WORD COMP.
PUTNUV:
IFN BIS,<
FLTR T1,T1
>
IFE BIS,<
PUSH PP, T3 ;SAVE THE PARAM.
MOVE AP, [Z T1,T1] ;SET UP CALL TO FLOT.1.
PUSHJ PP, FLOT.1## ;GO GET THE NUMBER IN FLOATING POINT.
POP PP, T3 ;GET THE PARAM BACK.
>
PUTNUT: MOVEM T1, (T3) ;STORE RESULT.
POPJ PP, ;RETURN.
;ROUTINE TO GET A SET OF PARAMETERS.
GSETP: TLNE T1, SUBS ;IS THE ARG SUBSCRIPTED?
JRST GSETPD ;YES, GO WORRY OVER IT.
IFN BIS,<
DMOVE T1, (T1)
>
IFE BIS,<
MOVE T2, 1(T1) ;PICK UP THE PARAMS.
MOVE T1, (T1)
>
POPJ PP, ;RETURN.
; WORRY ABOUT SUBSCRIPTING.
GSETPD: MOVEM T1, AP.TMP## ;SAVE THE ARG POINTER.
TLNN SW, NOSTOR ;SHOULD WE STORE THE POINTER
; AND TALLY ITEM?
PUSHJ PP, SPTATL ;YES, GO DO SO.
MOVE T1, AP.TMP## ;GET THE ARG POINTER BACK.
HLRZ T2, 1(T1) ;GET THE NUMBER OF SUBSCRIPTS.
LSH T2, 1 ;FIGURE OUT THE ADDRESS OF THE
ADDI T2, 2(T1) ; DESCRIPTOR WORD.
MOVE T3, (T2) ;GET THE DESCRIPTOR WORD.
MOVEM T3, DW.TMP## ;SAVE IT.
HRL T2, 1(T1) ;PICK UP THE FLAGS.
PUSH PP, T2 ;SAVE FLAGS AND CONVERSION
; PARAMETER ADDRESS-1.
MOVE T3, 2(T1) ;[464]GET THE TEMP ADDRS FOR THE
; DEPENDING VARIABLE AND SUBSCRIPT.
TLNE T2, SUB1DF ;FIRST SUBSCRIPT'S DEPENDING ITEM COMP?
PUSHJ PP, MNUTMP ;NO, GO GET THE NUMBER.
TLNE T2, SUB1SF ;FIRST SUBSCRIPT COMP?
PUSHJ PP, MNUTMP ;NO, GO GET THE NUMBER.
MOVE T3, 4(T1) ;[464]REPEAT FOR SUBSEQUENT SUBSCRIPTS.
TLNE T2, SUB2DF
PUSHJ PP, MNUTMP
TLNE T2, SUB2SF
PUSHJ PP, MNUTMP
MOVE T3, 6(T1) ;[464]
TLNE T2, SUB3DF
PUSHJ PP, MNUTMP
TLNE T2, SUB3SF
PUSHJ PP, MNUTMP
; ALL SUBSCRIPTS ARE NOW COMP ITEMS.
GSETPT: POP PP, T2 ;GET RID OF CONVERSION JUNK.
PUSHJ PP, SVACS ;SAVE THE NON TEMP AC'S.
HRRZ AP, AP.TMP## ;SET UP PARAM FOR SUBSCRIPT RTN.
PUSHJ PP, SUBSC.## ;GO EVALUATE THE SUBSCRIPT.
MOVE T1, SXR ;GET THE BYTE POINTER.
TLZ T1, 77
MOVE T2, DW.TMP## ;GET THE DESCRIPTOR WORD.
POPJ PP, ;RETURN.
; ROUTINE TO GET A NUMBER INTO A TEMP.
MNUTMP: AOS T2, -1(PP) ;GET PARAMETER ADDRESS.
MOVE T1, (T2) ;GET MODE AND POINTER.
PUSH PP, T3 ;SAVE TEMP ADDRESS.
HLRZ T3, T1 ;GET THE MODE.
MOVE T1, @(T1) ;GET THE PARAM.
LDB T2, [POINT 5,T1,17] ;PUT THE SIZE WHERE
; GTNUM LIKES IT TO BE.
SUBI T2, 1 ;GTNUM ALSO LIKES THE SIZE TO
; BE ONE LESS THAN IT REALLY IS.
PUSHJ PP, GTNUM ;GO GET THE NUMBER.
POP PP, T3 ;GET THE TEMP ADDRESS BACK.
MOVEM T2, (T3) ;STORE THE NUMBER.
MOVE T2, -1(PP) ;SET UP AC'S.
MOVE T1, AP.TMP##
MOVS T3, T3
POPJ PP, ;RETURN.
;ROUTINE TO STORE THE POINTER AND TALLY ITEMS.
DONE: SETZI ERR, ;COME HERE WHEN WE ARE DONE TO
; STORE THE POINTER AND/OR TALLY.
SPTATL: PUSHJ PP, SVACS ;SAVE NON TEMP AC'S.
SKIPN T1, PT.ARG## ;GET THE POINTER ITEM'S ARG.
JRST SPTATD ;IF THERE ISN'T A POINTER ITEM,
; GO ON.
MOVE T4, PT.VLU## ;SAVE THE POINTER'S VALUE.
SETZI T6,
PUSHJ PP, SPTATH ;GO STORE IT.
SPTATD: SKIPN T1, TL.ARG## ;GET THE TALLYING ITEM'S ARG.
POPJ PP, ;IF THERE ISN'T A TALLYING ITEM,
; LEAVE.
PUSHJ PP, GTPRMT ;GO GET ITS PARAMS.
PUSHJ PP, GTNUM ;GO GET ITS VALUE.
JFCL 17, .+1 ;CLEAR ARITHMETIC FLAGS.
ADD T2, TL.VLU## ;ADD IN THE TEMP TALLY.
JCRY1 [AOJA T1, .+1] ;IF WE HAD A CARRY BUMP THE HIGH
; ORDER WORD.
TLNE T1, (1B0) ;MAKE SURE THE SIGNS AGREE.
TLOA T2, (1B0)
TLZ T2, (1B0)
SETZM TL.VLU## ;CLEAR THE TEMP TALLY.
MOVE T4, T2 ;SAVE THE TALLYING ITEM'S VALUE.
MOVE T6, T1
MOVE T1, TL.ARG## ;GET THE TALLYING ITEM'S ARG AGAIN.
; STORE THE VALUE.
SPTATH: PUSHJ PP, GTPRMT ;GO GET PARAMS.
MOVE T5, T3 ;SET UP THE PARAMS
EXCH T2, T4 ; AND SET UP THE NUMBER.
MOVE T3, T1
MOVE T1, T6
PJRST PUTNUM ;GO STORE IT AND RETURN.
;ROUTINE TO TRANSFER SOURCE TO DESTINATION AND DELIMITER STORE,
; STORE THE COUNT AND BUMP THE TALLYING ITEM.
;
;SOME HINTS TO ANY POOR UNFORTUNATES WHO HAVE TO READ THIS CODE:
; POINTERS TO VARIOUS FIELDS IN THE SOURCE STRING ARE KEPT IN
; TERMS OF THE NUMBER OF CHARACTERS TO THE RIGHTMOST END OF
; THE STRING. SRC.CC CONTAINS A POINTER TO THE END OF THE
; NEXT STRING TO BE MOVED. SE.DLM CONTAINS, IN THE LEFT HALF,
; A POINTER TO THE BEGINNING OF THE DELIMITER, AND IN THE RIGHT
; HALF A POINTER TO THE END. WHEN MOVING THE SELECTED STRING
; FROM THE SOURCE (NOT THE DELIMITER), THE BEGINNING OF THE
; STRING IS DETERMINED BY THE BYTE POINTER IN SRCPTR. FOR
; EXAMPLE, THE FOLLOWING UNSTRING STATEMENT:
; UNSTRING "ABCDEFGHI" DELIMITED BY "DEF"
; WOULD RESULT, AT THE TIME OF THE CALL TO STOREM, IN SE.DLM
; CONTAINING 5,,2 (CHARACTERS ARE COUNTED RIGHT TO LEFT STARTING
; AT ZERO), SRCPTR WOULD POINT AT THE "A", AND SRC.CC WOULD
; CONTAIN 5. UMOVE, THE ROUTINE THAT ACTUALLY DOES THE DATA
; MOVING, PAYS ATTENTION ONLY TO SRCPTR AND SRCCNT. SRC.CC
; IS USED LATER ON (BACK AT UMLP) TO DETERMINE WHERE TO BEGIN
; SCANNING AGAIN AFTER THIS STORE. THE RIGHT HALF OF DLM.AC
; CONTAINS THE NUMBER OF TIMES EXTRA DELIMITER STRINGS WERE
; SKIPPED DUE TO THE PRESENCE OF AN "ALL" CLAUSE IN THE UNSTRING
; STATEMENT, AND DLM.CC CONTAINS THE SIZE OF THE DELIMITER MINUS ONE.
; /DLC
STOREM: TLO SW, NOSTOR ;DON'T STORE POINTER OR TALLY.
; MOVE SOURCE TO DESTINATION.
IFN BIS,<
DMOVE SRCPTR, SRC.BP
>
IFE BIS,<
MOVE SRCPTR, SRC.BP## ;POINT AT FIRST CHAR TO BE TRANSFERED.
MOVE SRCCNT, SRC.CC## ;GET NUMBER OF CHARS LEFT IN SOURCE.
>
IFN ANS74,<
MOVE T2,DLM.CC ;BACKTRACK OVER ANY EXTRA
ADDI T2,1 ; DELIMITERS SKIPPED BECAUSE
HRRZ T1,DLM.AC ; OF "ALL" CLAUSE
IMULI T2,(T1)
>
HLRE T1, SE.DLM## ;GET NUMBER OF CHARS TO REMAIN
IFN ANS74,<
ADD T1,T2
>
MOVEM T1, SRC.CC## ; AFTER THE TRANSFER AND SAVE IT.
SUB SRCCNT, T1 ;GET NUMBER OF CHARS TO MOVE.
MOVEM SRCCNT, CT.VAL## ;SAVE IT FOR THE COUNT ITEM.
ADDM SRCCNT, PT.VLU## ;BUMP POINTER ITEM.
PUSHJ PP, UMOVE ;GO DO THE MOVE.
PUSHJ PP, CLRTMP
IFN ANS74,<
MOVE T2,DLM.CC ;NOW MAKE SRC.CC AGAIN POINT
ADDI T2,1 ; TO BEGINNING OF LAST
HRRZ T1,DLM.AC ; OCCURRENCE OF DELIMITER STRING
IMULI T2,(T1)
MOVE T1,SRC.CC ; ..
SUB T1,T2 ; ..
MOVEM T1,SRC.CC ; ..
JUMPE T2,STORMA ;DON'T ADJUST BYTE POINTER IF UNNECESSARY
IFN BIS,<
ADJBP T2,SRCPTR ;SKIP OVER REDUNDANT DELIMITERS
MOVE SRCPTR,T2 ; ..
>
IFE BIS,<
IBP SRCPTR
SOJG T2,.-1
>
STORMA:
>;END IFN ANS74
; MOVE SOURCE TO DELIMITER STORE.
MOVE SRCCNT, SRC.CC## ;GET NUMBER OF CHARS REMAINING.
HRRE T1, SE.DLM## ;GET NUMBER OF CHARS TO REMAIN
MOVEM T1, SRC.CC## ; AFTER THE TRANSFER AND SAVE IT.
SUB SRCCNT, T1 ;GET NUMBER OF CHARS TO MOVE.
ADDM SRCCNT, PT.VLU## ;BUMP POINTER ITEM.
IFN ANS74,<
HRRZ T1,DLM.AC ;GET EXTRA REPETITIONS OF ALL
HRRZ T2,DLM.CC ;GET SIZE OF DELIMITER
ADDI T2,1 ;ACCOUNT FOR ZERO-ORIGIN INDEX
IMULI T1,(T2) ;COMPUTE TOTAL DELIMITER SIZE
ADDM T1,PT.VLU ;BUMP POINTER ITEM
HLLZS DLM.AC ;JUST IN CASE
>
PUSHJ PP, GTDOUT ;GO GET DELIMITER STORE'S PARAMS.
JUMPE ERR, STORMD ;IF THERE WERE NO PROBLEMS, GO ON.
CAIE ERR, OMTARG ;IF THE ARG WAS NULL OR OMITTED
CAIN ERR, NULARG ; OR NULL, SET UP DUMMY PARAMS.
TRNA
JRST UTRUBL ;OTHERWISE DIE.
; DELIMITER STORE IS NULL OR OMITTED.
SETZB ERR, T1 ;CLEAR ERROR REGISTER AND
SETZB T2, T3 ; SET UP DUMMY PARAMS.
; SAVE DELIMITER STORE'S PARAMS.
STORMD:
IFN BIS,<
DMOVE DSTPTR, T1
>
IFE BIS,<
MOVE DSTPTR, T1
MOVE DSTCNT, T2
>
MOVEM T3, DST.MD##
PUSHJ PP, UMOVE ;GO DO THE MOVE.
PUSHJ PP, CLRTMP
AOS TL.VLU## ;BUMP THE TALLY ITEM
MOVEM SRCPTR, SRC.BP## ;SET UP POINTER TO CURRENT
; SOURCE POSITION.
MOVE SRCCNT, SRC.CC## ;GET NUMBER OF CHARS LEFT IN SOURCE.
; NOW DO THE COUNT ITEM.
PUSHJ PP, GTPRMS ;GO GET IT'S PARAMS.
TLZ SW, NOSTOR ;ALLOW POINTER AND TALLYING ITEM
; TO BE STORED.
JUMPE ERR, STORMH ;IF THERE WERE NO PROBLEMS GETTING
; THE COUNT ITEM'S PARAMS, GO ON.
CAIE ERR, OMTARG ;IF THE COUNT ITEM WAS OMITTED
CAIN ERR, NULARG ; OR NULL,
TDZA ERR, ERR ; RETURN.
JRST UTRUBL ;OTHERWISE DIE.
POPJ PP,
STORMH: PUSHJ PP, SVACS ;SAVE ALL NON TEMP AC'S.
IFN BIS,<
DMOVE T4, T2
>
IFE BIS,<
MOVE T5, T3 ;SET UP PARAMS.
MOVE T4, T2
>
MOVE T3, T1
SETZI T1, ;GET THE COUNT ITEM'S VALUE.
MOVE T2, CT.VAL##
PJRST PUTNUM ;GO STORE THE NUMBER AND RETURN.
;ROUTINE TO TRANSFER CHARS FROM THE SOURCE TO THE DESTINATION.
UMOVE: PUSHJ PP, SCVSDS ;SET UP THE CONVERSION INSTRUCTION.
MOVE DLCH, DST.MD## ;SELECT A PADD CHAR.
;ALWAYS PADD WITH SPACES SO THAT THE CONVERSION ROUTINES WILL PROCESS
; LEADING SIGNS ON ALPHANUMERIC FIELDS. /ACK 28-OCT-75
; TLNE SW, ONUM ;NUMERIC OUTPUT?
; SKIPA DLCH, PADDCH(DLCH) ;YES, USE ZEROES.
HLR DLCH, PADDCH(DLCH) ;NO, USE SPACES.
SOJL SRCCNT, UMOVEP ;IF THE SOURCE IS NULL,
; GO PADD THE WHOLE THING.
TLNN SW, OJST ;RIGHT JUSTIFICATION WANTED?
JRST UMOVEH ;NO, GO ON.
MOVE T1, SRCCNT ;SEE IF WE HAVE TO PADD OR TRUNCATE.
SUB T1, DSTCNT
JUMPE T1, UMOVEH ;NEITHER, GO ON.
JUMPG T1, UMOVED ;IF THE SOURCE IS LARGER, GO TRUNCATE.
; DESTINATION IS LARGER THAN SOURCE - PADD.
ADD DSTCNT, T1 ;DECREMENT THE DESTINATION COUNT.
IDPB DLCH, DSTPTR ;PADD THE ITEM.
AOJL T1, .-1
JRST UMOVEH
; SOURCE IS LARGER THAN DESTINATION - TRUNCATE.
UMOVED: SUB SRCCNT, T1 ;DECREMENT THE SOURCE COUNT.
IFN BIS,<
ADJBP T1,SRCPTR
MOVE SRCPTR,T1
>
IFE BIS,<
IBP SRCPTR ;SKIP OVER SOME CHARS.
SOJG T1, .-1
>
; MOVE CHARS FROM SOURCE TO DESTINATION.
UMOVEH: JUMPL DSTCNT, UMOVEL ;IF THERE ISN'T ANY MORE ROOM IN
; THE DESTINATION, GO ON.
TRNA ;DON'T DECREMENT THE FIRST TIME.
UMOVEJ: SOJL SRCCNT, UMOVEP ;IF THERE AREN'T ANY MORE CHARS
; IN THE SOURCE, GO ON.
ILDB SRCH, SRCPTR ;GET THE NEXT SOURCE CHAR.
XCT CVTSDS ;CONVERT IT.
IDPB SRCH, DSTPTR ;STASH IT.
SOJGE DSTCNT, UMOVEJ ;IF THERE IS MORE ROOM IN THE
; DESTINATION LOOP.
; DESTINATION IS FULL.
UMOVEL:
IFE BIS,<
SOJL SRCCNT, CPOPJ ;ANY SOURCE LEFT?
IBP SRCPTR ;YES, SKIP OVER IT.
SOJGE SRCCNT, .-1
>
IFN BIS,<
JUMPLE SRCCNT,.+3 ;ANY SOURCE LEFT?
ADJBP SRCCNT,SRCPTR
MOVE SRCPTR,SRCCNT ;PUT BYTE PTR BACK
SETO SRCCNT, ;JUST INCASE
>
POPJ PP, ;RETURN.
; NO MORE SOURCE.
UMOVEP: JUMPL DSTCNT, CPOPJ ;ANY MORE ROOM IN THE DESTINATION?
IDPB DLCH, DSTPTR ;YES, PADD THE ITEM.
SOJGE DSTCNT, .-1
POPJ PP, ;RETURN.
; TABLE OF PADD CHARS. INDEX BY MODE. LEFT HALVES ARE SPACES, RIGHT
; HALVES ARE ZEROES.
PADDCH: XWD 0, 20 ;DISPLAY-6.
XWD 40, 60 ;DISPLAY-7.
XWD 100, 360 ;DISPLAY-9.
;ROUTINE TO SAVE AND RESTORE NON-TEMP AC'S.
SVACS: EXCH AP, (PP)
PUSH PP, CVTSDS
PUSH PP, CMPSDL
PUSH PP, CVTSDL
PUSH PP, SW
PUSH PP, SRCCNT
PUSH PP, SRCPTR
PUSH PP, DLMCNT
PUSH PP, DLMPTR
PUSH PP, DSTCNT
PUSH PP, DSTPTR
PUSH PP, .+3
PUSH PP, AP
MOVE AP, -14(PP)
POPJ PP, .+1
POP PP, DSTPTR
POP PP, DSTCNT
POP PP, DLMPTR
POP PP, DLMCNT
POP PP, SRCPTR
POP PP, SRCCNT
POP PP, SW
POP PP, CVTSDL
POP PP, CMPSDL
POP PP, CVTSDS
POP PP, AP
POPJ PP,
;ERROR ROUTINES:
STRUBL: JUMPL ERR, CPOPJ
SETZI T2,
JRST TRUBLE
UTRUBL: JUMPL ERR, CPOPJ
SETOI T2,
TRUBLE: JUMPL ERR, CPOPJ
OUTSTR [ASCIZ /
?Bad error code returned to /]
SKIPE T2
OUTSTR [ASCIZ /UN/]
OUTSTR [ASCIZ /STRING - continuing
/]
SETOI ERR,
POPJ PP,
END