	.TITLE	.SS   <CALCULATE ADDRESS OF SUBSCRIPTED ELEMENT>
/ 
/ 
/                   FIRST PRINTING, FEBRUARY 1974
/ 
/ THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO 
/ CHANGE WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED
/ AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
/ DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPON-
/ SIBILITY FOR ANY ERRORS THAT MAY APPEAR IN THIS
/ DOCUMENT.
/ 
/ THE SOFTWARE DESCRIBED IN THIS DOCUMENT IS FUR-
/ NISHED TO THE PURCHASER UNDER A LICENSE FOR USE ON
/ A SINGLE COMPUTER SYSTEM AND CAN BE COPIED (WITH
/ INCLUSION OF DIGITAL'S COPYRIGHT NOTICE) ONLY FOR 
/ USE IN SUCH SYSTEM, EXCEPT AS MAY OTHERWISE BE PRO-
/ VIDED IN WRITING BY DIGITAL.
/ 
/ DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPONSIBILITY
/ FOR THE USE OR RELIABILITY OF ITS SOFTWARE ON EQUIP-
/ MENT THAT IS NOT SUPPLIED BY DIGITAL.
/ 
/ COPYRIGHT (C) 1974, BY DIGITAL EQUIPMENT CORPORATION
/ 
/ 
        .EJECT
/
/ EDIT #009	6 FEB 1973		T.A. MURRAY
/
/ COPYRIGHT 1973, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. 01754
/
/	THIS FORTRAN IV OTS ROUTINE CALCULATES THE ADDRESS OF AN
/ ELEMENT OF AN ARRAY, IN ADDITION TO RETURNING THE MODE OF THE ARRAY
/ IN THE ACCUMULATOR (ONE'S COMPLEMENT, RIGHT ADJUSTED).
/ NO SUBSCRIPT RANGE CHECKING IS PROVIDED.
/
/ CALLING SEQUENCE -
/
/	JMS*	.SS
/	.DSA	ADDRESS OF FIFTH WORD OF THE ARRAY DESCRIPTOR BLOCK (ADB)
/			/THERE IS NO INDIRECT BIT, AS ALL ARRAYS HAVE A
/			/LOCAL ADB.
/	LAC(*)	I	/WHERE I IS THE FIRST ARRAY SUBSCRIPT
/	LAC(*)	J	/OMITTED IF ONLY ONE DIMENSION, J IS THE SECOND SS
/	LAC(*)	K	/OMITTED IF ONLY TWO DIMENSIONS, K IS THE THIRD SS
/	DAC	$.	/WHERE $. IS A LOCATION AT WHICH THE ELEMENT 
/			/ADDRESS IS STORED (THIS INSTRUCTION IS XCT'D BY
/			/.SS, AND NEED NOT NECESSARILY BE A DAC, ALTHOUGH
/			/THE DAC ALWAYS APPEARS IN COMPILER GENERATED CODE.)
/	RETURN POINT	/THE AC CONTAINS THE ONES COMPLEMENT OF THE MODE,
/			OF THE ARRAY (FORMERLY THE MODE APPEARED IN BITS
/			1 AND 2 OF THE COMPUTED ADDRESS - THIS IS NO LONGER
/			DONE.)
/ 	THE ADDRESS PLACED INTO .SS AS A RESULT OF THE SUBROUTINE
/ CALL REMAINS UNCHANGED; THIS IS A BIT OF INFORMATION THAT DDIO
/ RELIES ON.
/
/ THE ADDRESS IS COMPUTED PER
/
/	ADDR = SA +[N*(I-1) + N*IMAX*(J-1) + N*IMAX*JMAX*(K-1)]
/
/ WHERE
/	SA IS THE STARTING ADDRESS OF THE ARRAY
/	IMAX IS THE DIMENSIONED SIZE OF THE FIRST DIMENSION
/	JMAX IS THE DIMENSIONED SIZE OF THE SECOND DIMENSION
/	I, J, AND K ARE AS ABOVE
/	N IS THE NUMBER OF WORDS PER DATA ELEMENT FOR VARIABLES OF THE
/ 	MODE OF THIS ARRAY
/ FOR 1 DIMENSIONAL ARRAYS, ONLY THE FIRST TERM IN BRACKETS IS COMPUTED;
/ FOR 2 DIMENSIONAL ARRAYS, THE FIRST TWO TERMS, AND FOR 3 DIMENSIONAL
/ ARRAYS, ALL TERMS ARE COMPUTED.
/
/ THE ARRAY DESCRIPTOR BLOCK (ADB) FOR THE ARRAY MUST BE OF THE FORM:
/
/	WD1: BITS 0-2 = NUMBER OF DIMENSIONS -1; BITS 16,17 = MODE
/	WD2: N*IMAX*JMAX*KMAX, THE ARRAY SIZE
/	WD3: N*IMAX
/	WD4: N*IMAX*JMAX
/	WD5: SA, ARRAY STARTING ADDRESS
/
	.GLOBL	.SS
/
	.IFDEF	TIME%
	.GLOBL	TIMON,TIMOFF
	.ENDC
/
/
.SS	CAL		/SET UP POINTERS.  LSTPTR WILL INDEX THROUGH
/
	.IFDEF	TIME%
	JMS*	TIMON
	.DSA	67
	.ENDC
/
	LAC	.SS	/THE PARAMETER LIST OF THE .SS CALL, AND ADBLST
	DAC	LSTPTR	/WILL ADDRESS THROUGH THE ADB.
	LAW	-4	/ REGRESS POINTER TO ADDRESS FIRST ADB WORD.
	TAD*	LSTPTR	/ADD IN POINTER TO LAST ADB WORD
	DAC	ADBPTR	/
	LAC*	ADBPTR	/GET CONTENTS OF FIRST ADB WORD
	LRSS	17	/ RIGHT JUSTIFY NO. OF DIMEN -1 (MUST BE < 4)
	CMA		/USE IT TO SET AN INDEX, -1 IF 2 DIMENSIONS,
	TAD	(1)	/ OR -2 IF 3 DIMENSIONS, AND 0 IF 1 DIMENSION
	DAC	COUNT
/
/ FIRST DIMENSION - COMPUTE (I-1) AND SAVE
/
	ISZ	LSTPTR	/BUMP TO POINT TO LAC(*) I
	XCT*	LSTPTR	/EXECUTE LOADING OF FIRST SUBSCRIPT
	TAD	(-1)	/SUBTRACT 1
	DAC	TEMP	/ (I-1)
/
/ SET UP TO PASS LAW 1'S COMPLEMENT OF MODE BITS ON RETURN
/
	LLSS!1000  17	/FIRST CLA WITH EAE, THEN RIGHT JUSTIFY MODE BITS IN AC	
	CMA		/FORM LAW
	DAC	LAWMOD	/PUT AT LAST LOCATION BEFORE RETURN
/
/COMPUTE EFFECTIVE N*(I-1), ON BASIS OF MODE
/MODE+1 = N, EXCEPT FOR MODE 3 (DBL. INTG.), WHEN N=2
/
	CMA		/RECOVER MODE
	SNA		/IF MODE IS ZERO, N=1, DONT'T MULTIPLY
	JMP	F1	/ELSE SET LINK ON IF MODE 1 OR 3 (N=2 FOR
	RAR		/EITHER), THEN COMPLEMENT LINK, S.T. LINK IS
	CML		/LEFT ON FOR MODE 2, N=3.
	LAC	TEMP	/GET (I-1), SHIFT LEFT TO MULT BY TWO
	ALS	1	/LINK IN, NO PROBLEM N=2, REMOVE BELOW IF N=3
	SNL		/OUT NOW IF LINK OFF, AS WAS MODE 1 OR 3, N=2
	JMP	F2	/..AND MULT BY 2 IS COMPLETE
	TAD	TEMP	/ELSE HAVE (I-1)*2+1+(I-1)=(I-1)*3+1
	TAD	(-1)	/REMOVE +1
F2	DAC	TEMP	/STASH ADDRESS DUE TO FIRST SUBSCRIPT
F1	ISZ	ADBPTR	/POINT TO ADB WORD 2
	ISZ	ADBPTR	/POINT TO ADB WORD 3
	CLA		/IF THERE IS ONLY ONE DIMENSION, GO TO ONE
	SAD	COUNT	/MORE INCREMENT OF ADBPTR, THEN TO EXIT
	JMP	F4	/COUNT IS ZERO FOR 1 DIMENSIONAL ARRAY
/
/ COMPUTE N*IMAX*(J-1)
/
	LAC*	ADBPTR	/GET ADB WORD 3, N*IMAX
	DAC	N.IMAX	/SET IT AS MULTIPLIER
	ISZ	LSTPTR	/POINT TO LAC(*) J
	XCT*	LSTPTR	/GET J VALUE
	TAD	(-1)	/COMPUTE (J-1)
	MUL!20000	/MICROCODE TO PUT AC0 INTO LINK BEFORE MUL, 
N.IMAX	XX		/WHERE A ZERO IS EXPECTED CAUSE SHOULD BE J .GE.0
	LACQ
	ISZ	COUNT	/GOES TO ZERO IF ONLY TWO SUBSCRIPTS
	JMP	F3
F4	ISZ	ADBPTR	/POINT TO ADB WORD 4
	JMP	F5	/GO DO FINAL COMPUTATION
/
/ COMPUTE N*IMAX*JMAX*(K-1)
/
F3	TAD	TEMP	/ADD INTERMEDIATE RESULTS FOR FIRST TWO
	DAC	TEMP	/DIMENSIONS
	ISZ	ADBPTR	/POINT TO ADB WORD 4
	LAC*	ADBPTR	/GET N*IMAX*JMAX
	DAC	N.JMAX	/SET IT AS MULTIPLIER
	ISZ	LSTPTR	/POINT TO LAC(*) K
	XCT*	LSTPTR	/GET K VALUE
	TAD	(-1)	/COMPUTE (K-1)
	MUL!20000	/ZERO LINK IF K .GE. 0 BY PUTTING SIGN INTO
N.JMAX	XX		/LINK, OTHERWISE ERROR ANYWAY.
	LACQ		/GET N*IMAX*JMAX*(K-1)
F5	TAD	TEMP	/ADD PREVIOUS (ENTERS HERE WITH ZERO IN AC IF 1 DIM.)
/
/ ADD BASE ADDRESS, AND XCT EXPECTED DAC; RETURN WITH LAW 1'S 
/ COMPLEMENT OF MODE IN AC
/
	ISZ	ADBPTR	/POINT TO ADB WORD 5
	TAD*	ADBPTR	/ADD ARRAY BASE ADDRESS
	ISZ	LSTPTR	/BUMP TO INSTR. FOLLOWING LAST SUBSCRIPT LAC
	XCT*	LSTPTR	/EXECUTE THIS INSTR, ALWAYS A DAC IN COMPILER
			/GENERATED CODE.
LAWMOD	LAW		/LAW 1'S COMPLEMENT OF MODE WAS PUT HERE
	ISZ	LSTPTR	/HAVE AVOIDED CHANGING CONTENT OF .SS ENTRY
			/S.T. IT CAN BE USED BY DDIO.
/
	.IFDEF	TIME%
	JMS*	TIMOFF
	.DSA	67
	.ENDC
/
	JMP*	LSTPTR	/TIMOFF IS ASSUMED TO SAVE & RESTORE AC
/
LSTPTR	0		/INDEX IN .SS CALL PARAMETER LIST
ADBPTR	0		/INDEX IN ADB OF THE ARRAY
COUNT	0		/COUNTDOWN INDEX OF NUMBER OF DIMENSIONS
TEMP	0		/STORAGE FOR INTERMEDIATE RESULTS
/
	.END
