Google
 

Trailing-Edge - PDP-10 Archives - BB-D480C-SB_1981 - listou.bli
There are 26 other files named listou.bli in the archive. Click here to see a list.
!THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
!  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.

!COPYRIGHT (C) 1973,1981 BY DIGITAL EQUIPMENT CORPORATION
!AUTHOR F.INFANTE/DCE/SJW/JNG/TFV

MODULE LISOUT(RESERVE(0,1,2,3),SREG=#17,FREG=#16,VREG=#15,DREGS=4,GLOROUTINES)=
BEGIN

!	REQUIRES FIRST, TABLES, REQREL

SWITCHES NOLIST;
REQUIRE FIRST.BLI;
REQUIRE TABLES.BLI;
REQUIRE REQREL.BLI;
SWITCHES LIST;

GLOBAL BIND LISTOV = 6^24 + 0^18 + 69;		! Version Date:	21-Jul-81

%(

***** Begin Revision History *****

39	-----	------	GENERATE SYMBOL TABLE ENTRIES FOR FORMAT STMNTS,
			USE THE SYMBOL "STMNT-NUMBER F"
40	-----	-----	FIX BUG IN EDIT 39
41	-----	-----	ADD ROUTINE "LSTFORMATS" TO LIST ALL FORMAT STMNTS
			AT THE END OF A MACRO-EXPANDED LISTING
42	-----	-----	FIX BUG IN LSTFORMATS TO LIST RELATIVE ADDRS
			CORRECTLY
43	-----	-----	CHANGE "OUTMDA" SO THAT WHEN PSYMPTR IS THE CODE
			"PBFFORMAT" WE EXPECT THE RIGHT HALF OF THE INSTR
			IN THE PEEPHOLE BUFFER TO CONTAIN A PTR TO THE
			FORMAT STMNT (RATHER THAN THE REL ADDR OF THE FORMAT STRING)
44	-----	-----	TAKE OUT DEFINITIONS OF LOADER BLOCK TYPES - PUT
			THEM INTO A SEPARATE "REQUIRE" FILE.
			ALSO REMOVE THE ROUTINES "ZOUTBLOCK" AND 
			"ZDMPBLK". ZOUTBLOCK HAS BEEN MOVED TO THE MODULE
			RELBUF. ZDMPBLK IS NO LONGER NEEDED.
			ALSO, EDIT "ZENDALL" TO OUTPUT ANY CODE
			LEFT IN THE BUFFERS SYMRLBF,LOCRLBF, AND MAINRLBF.
			ALSO REMOVE THE ROUTINE "DATAOUT", MAKE OUTDATA CALL
			ZOUTBLOCK INSTEAD.
			ALSO REMOVE THE ROUTINE DMPRELONLST.
			ALSO REMOVE ALL REFERENCES TO "RELOCPTR" AND "RELBLOCK"
			AND DELETE THEIR DEFINITIONS.
45	-----	-----	REMOVE THE ROUTINES: ZOUTMSG,ZOUTSYM,ZOUTOCT,RADIX50,
			ZOUDECIMAL,ZOUOFFSET.
			THESE HAVE BEEN PUT INTO THE MODULE "RELBUFF"
46	-----	-----	REMOVE THE ROUTINE LSTRLWD WHICH HAS BEEN
			PUT INTO THE MODULE RELBUF
47	-----	-----	TAKE OUT DEF OF THE MACRO "CRLF" - IT IS NOW
			IN THE REQUIRE FILE "REQREL"
48	-----	-----	REMOVE THE ROUTINE OUTDATA - ITS NOT NEEDED IN
			FORTG
49	-----	-----	IN ZENDALL - MUST CALL DMPMAINRLBF (TO DUMP
			ANY CODE IN THE BUFFER) BEFORE DUMPING
			THE CONTENTS OF THE FIXUP BUFFERS
50	-----	-----	IN LSTINST  MOVE THE OUTPUT OF THE MACRO
			LISTING HEADING TO PHA3 SO THAT THE SIXBIT FUNCTION
			NAME WILL COME OUT AFTER THE HEADING

			IN OUTMDA - CHANGE IT SO THAT IT PUTS OUT
			A CRLF AT THE BEGINNING OF EACH LINE INSTEAD OF
			AT THE END.  THIS WILL MATCH THE WAY LSTINST DOES
			IT AND STRAIGHTEN OUT THE LISTING

			PUT PAGEHEADING CHECKS IN BOTH OF THE ABOVE ROUTINES

51	-----	-----	PUT OUT F LABELS AT THE END OF FORMAT STRINGS IF
			THE FLAG "DBGLABL" IS SET; OUTPUT L LABELS FOR
			THE LINES IF THE FLAG "DBGLABL" IS SET. HAVE P
			LABELS AT START OF FORMAT STMNTS.
52	-----	-----	PUT OUT THE SYMBOL '.VEND' AFTER THE END
			OF THE SCALARS AND ARRAYS
53	-----	------	DO NOT PUT OUT THE EXIT UUO (HAVE CALL TO FOROTS
			EXIT.)
54	15349	247	CHANGE ALL REFERENCES TO FORMAT LABELS TO XXXXP, (JNT)
55	QAR	317	FIX 247 TO STILL PUT XXF ON END, FIX SYMBOL TABLE, (JNT)
56	18015	356	PUT OUT GLOBAL MAIN. FOR MAIN PROG, (DCE)
57	19477	461	CHECK SIZES OF HIGH AND LOW SEGMENTS FOR OVERFLOW, (DCE)
58	QA754	464	ADD LINE/OCTAL MAP OUTPUT IF NO MACRO LISTING, (SJW)
59	QA754	476	MAKE LINE/OCTAL MAP OPTIONAL UNDER /MAP=MAPFLG, (SJW)

***** Begin Version 5A *****

60	22281	555	FIX MAP WITH ENTRY POINTS, (DCE)
61	23760	614	OUTPUT ONLY NON-BLANK LINES IN /LNMAP, (SJW)

***** Begin Version 5B *****

62	23066	636	DON'T DUMP LABELS TO THE REL FILE THAT WE DON'T
			  KNOW THE VALUE OF.  ALSO SET SNDEFINED WHEN
			  WE FILL IN THE SNADDR FIELD., (JNG)
63	25249	645	ENTRY POINTS CAUSE LINE COUNT TO BE OFF BY ONE, (DCE)
64	25250	646	SIXBIT SUBROUTINE NAMES HAVE LOCATION 0, (DCE)
65	25247	650	IMPROVE LISTING FILE WITH RESPECT TO DOUBLE
			PRECISION AND STRING LITERAL CONSTANTS, (DCE)
66	26442	705	USE NAME FROM PROGRAM STATEMENT AS THE ENTRY 
			POINT FOR THE MAIN PROGRAM, (DCE)
67	-----	734	ONLY PRINT DP CONSTANTS IN LISTING WHEN APPROPRIATE,
			(DCE)

***** Begin Version 6 *****

68	761	TFV	1-Mar-80	-----
	Adjust mnemonic table offset to deal with GFAD, etc.
	Print double octal literals for GFAD, etc. (/GFLOATING)

69	1003	TFV	1-Jul-80
	Add global symbol ..GFL. if compiling /GFLOATING for FORDDT
	support.  Suppress DDT output of .VEND and ..GFL. .

***** End Revision History *****

)%

!THE ROUTINES IN THIS MODULE ARE FOR THE PURPOSE
!OF GENERATING THE FOLLOWING THINGS:
%	THE MACRO EXPANDED LISTING OF THE CODE GENERATED
I	.THE GENERATION OF THE RELOCATABLE BINARY INFORMATION IN THE
	 .REL FILE
%
EXTERNAL ZOUTMSG,ZOUTSYM,ZOUTOCT,RADIX50,ZOUDECIMAL,ZOUOFFSET;
EXTERNAL HEADCHK;	!CHECKS LINE COUNT AND OUTPUTS HEADINGS
EXTERNAL RDATWD,RELOUT;	!CONTAINS CURRENT REL DATA WD
EXTERNAL ZOUTBLOCK;

EXTERNAL LSTOUT,ERROUT,
	LOWLOC,	!CURRENT LOWSEG AVAILABLE LOCATION
	HILOC,	!CURRENT HISEG AVAILABLE LOCATION
	RELBLOCK,	!RELOCATABLE BINARY BLOCK
	RELDATA,	!DATA WORD <LEFT> = CURRENT BLOCK NUMBER
				   !<RIGHT> = CURRENT DATA COUNT
	RELOCWD;	!THE RELOCATION WORD FOR THE BLOCK
!
MACRO EXITUUO = #047000000012$;
!
!
ROUTINE DMPSYMTAB=	!DUMPS THE SYMBOL TABLE TO REL FILE
BEGIN
EXTERNAL SYMTBL,LABTBL,FRSTLNK,RADIX50,ZOUTBLOCK,PROGNAME;
EXTERNAL FORMPTR;	!PTR TO 1ST FORMAT STMNT IN PROGRAM
OWN LABL;
LOCAL BASE  SYMPTR;
EXTERNAL ENDSCAA;


	ROUTINE BLDLABL=
	%(***************************
		LOCAL ROUTINE TO BUILD THE SIXBIT FOR THE
		DECIMAL FORM OF THE STMNT NUMBER IN THE REG "R1".
		CALLED WITH THE VAR "LABL" CONTAINING ONE
		SIXBIT CHAR IN THE LEFTMOST SIX BITS. LEAVES "LABL" CONTAINING
		THE STMNT NUMBER FOLLOWED BY THAT CHAR.
	****************************)%
	BEGIN
			DO (
				LABL _ .LABL ^(-6);
				R2 _ .R1 MOD 10; R1 _ .R1/10;
				LABL<30,6> _ (#20[.R2]<0,0>); !MAKING ROOM FOR NEXT
				IF .R1 EQL 0 THEN EXITLOOP;
	   		   ) WHILE 1;
	END;



	%(**DUMP THE SYMBOL TABLE***)%
	DECR I FROM SSIZ-1 TO 0 DO
	BEGIN
		IF (SYMPTR _ .SYMTBL[.I]) NEQ 0
		THEN BEGIN
			DO BEGIN
				IF .FLGREG<DBGDIMN>	!IF USER SPECIFIED THE "DEBUG" SWITCH
				THEN		! THEN FOR ALL ARRAYS WE WANT TO
						! PUT A PTR IN THE SYMBOL TABLE ENTRY POINTING
						! TO THE DIMENSION INFORMATION FOR THE ARRAY
				BEGIN
					IF .SYMPTR[OPRSP1] EQL ARRAYNM1
						AND ((NOT .SYMPTR[IDATTRIBUT(NOALLOC)])
						OR .SYMPTR[IDATTRIBUT(INCOM)])	!PUT IN COMMON
					THEN
					BEGIN
						%(**USE THE KLUGE OF ADDING A 2ND ENTRY
						   FOR THE SAME SYMBOL IMMEDIATELY
							FOLLOWING ITS TRUE DEFINITION, WHERE THIS ENTRY
							POINTS TO THE DIMENSION INFORMATION**)%

						REGISTER BASE T1;
						R2_.SYMPTR[IDSYMBOL];
						RDATWD_RLOCDDTSUP+RADIX50();	!SUPPRESS THIS 2ND
								! DEF FROM DDT
						ZOUTBLOCK(RSYMBOL,RELN);
						T1_.SYMPTR[IDDIM];	!PTR TO DIMENS TABLE ENT
						T1_.T1[ARADLBL];	!PTR TO LABEL TABLE ENTRY FOR
								!LABEL ON DIMENS INFO ARG BLOCK
						RDATWD_.T1[SNADDR];	!REL ADDR OF LABEL
						ZOUTBLOCK(RSYMBOL,RELRI);
					END
				END;


				IF .SYMPTR[IDATTRIBUT(INCOM)]
				THEN
				  BEGIN
					MAP BASE R2;
					R2 _ .SYMPTR[IDSYMBOL]; RDATWD _ RLOCREQ+RADIX50();
					ZOUTBLOCK(RSYMBOL,RELN);
					RDATWD _ .SYMPTR[IDADDR];	!COMMON BLOCK OFFSET
					ZOUTBLOCK(RSYMBOL,RELN);
					R2 _ .SYMPTR[IDCOMMON]; R2 _ .R2[COMNAME];
					RDATWD _ RGLOBREQ + RADIX50();
					ZOUTBLOCK(RSYMBOL,RELN);
					R2 _ .SYMPTR[IDSYMBOL]; RDATWD _ RLOCFIX + RADIX50();
					ZOUTBLOCK(RSYMBOL,RELN);

				  END
				ELSE
				IF .SYMPTR[OPRSP1] NEQ FNNAME1 AND
				NOT .SYMPTR[IDATTRIBUT(NOALLOC)] THEN
				  BEGIN
					R2 _ .SYMPTR[IDSYMBOL];
					RDATWD _ RLOCREQ + RADIX50();
					ZOUTBLOCK(RSYMBOL,RELN);
					RDATWD _ .SYMPTR[IDADDR];
					ZOUTBLOCK(RSYMBOL,RELRI);

				  END;

			   END WHILE (SYMPTR _ .SYMPTR[CLINK]) NEQ 0;
		      END;
	END;
	!

	!OUTPUT A SYMBOL FOR THE WD AFTER THE END OF THE SCALARS AND ARRAYS
	R2_SIXBIT'.VEND';
![1003]	Suppress DDT output of .VEND
%[1003]%	RDATWD_RLOCDDTSUP+RADIX50();
	ZOUTBLOCK(RSYMBOL,RELN);
	RDATWD_.ENDSCAA;	!LOC AFTER END OF ARRAYS/SCALARS
				! (SET IN ALLSCA)
	ZOUTBLOCK(RSYMBOL,RELRI);

![1003]	Output the global symbol ..GFL. if compiling /GFLOAT for FORDDT support
%[1003]%	IF .GFLOAT
%[1003]%	THEN
%[1003]%	BEGIN
%[1003]%		R2_SIXBIT'..GFL.';
%[1003]%		RDATWD_RGLOBDDTSUP+RADIX50();
%[1003]%		ZOUTBLOCK(RSYMBOL,RELN);
%[1003]%		RDATWD_1;	! give it the value of 1
%[1003]%		ZOUTBLOCK(RSYMBOL,RELN);
%[1003]%	END;
	!
	!
	!DUMP THE LOCAL LABLES NOW
	!
	DECR I FROM LASIZ-1 TO 0 DO
	BEGIN
	  IF (SYMPTR _ .LABTBL[.I]) NEQ 0 THEN
		BEGIN
		  DO BEGIN
%[636]%			IF .SYMPTR[SNDEFINED]
%[636]%			THEN
%[636]%			BEGIN
				LABL _ 0;
				R1 _ .SYMPTR[SNUMBER];
				LABL<30,6> _ IF .R1 GTR 99999 THEN (R1 _ .R1-99999; SIXBIT "M" ) ELSE SIXBIT "P";
				BLDLABL();	!IN "LABL" BUILD THE SIXBIT FOR
						! THE STMNT NUMBER IN R1 (FOLLOWED BY THE CHAR
						! ALREADY IN "LABL"

				R2 _ .LABL;
				RDATWD _ RLOCREQ + RADIX50();
				ZOUTBLOCK(RSYMBOL,RELN);
				RDATWD _ .SYMPTR[SNADDR];
				ZOUTBLOCK(RSYMBOL,RELRI);
%[636]%			END;
!
		     END WHILE (SYMPTR _ .SYMPTR[CLINK]) NEQ 0;
		END;
	END;
!
!DUMP THE LOCAL TEMPORARIES NAMES
!
	WHILE .FRSTLNK NEQ 0
	DO (
		MAP BASE FRSTLNK;
		R2 _ .FRSTLNK[IDSYMBOL];
			RDATWD _ RLOCREQ + RADIX50();
			ZOUTBLOCK(RSYMBOL,RELN);
			RDATWD _ .FRSTLNK[IDADDR];
			ZOUTBLOCK(RSYMBOL,RELRI);
		FRSTLNK _ .FRSTLNK[CLINK]
	   );

	!
	!DEFINE A LABEL OF THE FORM <STMNT NUMBER>F ON THE LAST WD
	! OF EACH FORMAT SRING
	IF .FLGREG<DBGLABL>
	THEN
	!
	BEGIN
		REGISTER BASE FPTR;	!PTR TO FORMAT STMNT NODE
		FPTR_.FORMPTR<LEFT>;	!1ST FORMAT STMNT IN PROGRAM
		UNTIL .FPTR EQL 0
		DO
		BEGIN
			SYMPTR_.FPTR[SRCLBL];	!STMNT NUMBER TABLE
					! ENTRY FOR THE LABEL ON THE FORMAT
			R1_.SYMPTR[SNUMBER];	!STMNT NUMBER ON THE FORMAT STMNT
			LABL_0;
			LABL<30,6>_SIXBIT"F";
			BLDLABL();	!SET "LABL" TO THE SIXBIT FOR
					! <STMNT NUMBER>P
			R2_.LABL;
			RDATWD_RLOCREQ+RADIX50();
			ZOUTBLOCK(RSYMBOL,RELN);
			RDATWD_.FPTR[FORADDR]+.FPTR[FORSIZ]-1;	!ADDR OF LAST WD OF STRING
			ZOUTBLOCK(RSYMBOL,RELRI);
			FPTR_.FPTR[FMTLINK]	!GO ON TO NEXT FORMAT
		END;
	END;
END;	!OF DMPSYMTAB
ROUTINE ZSIXBIT(ZVAL)=	!CONVERT ZVAL TO SIXBIT SYMBOL
BEGIN
R2 _ SIXBIT 'P';
DECR I FROM 5 TO 0 DO
BEGIN
	R2 _ .R2^(-6); R2<30,6> _ (.ZVAL MOD 10) + #40; ZVAL _ .ZVAL/10;
	IF .ZVAL EQL 0 THEN EXITLOOP;
END;
RETURN .R2
END;
!
%[650]%	EXTERNAL STRNGOUT;
%[650]%	ROUTINE ZDOUTCON(WORD2)=
%[650]%	BEGIN
%[650]%		!LIST A DOUBLE WORD CONSTANT IN OCTAL
%[650]%		!WORD ONE IS IN R2; SECOND WORD IS IN WORD2
%[650]%	
%[650]%		STRNGOUT(PLIT ASCIZ '[EXP  ');
%[650]%	
%[650]%		DECR I FROM 11 TO 0 DO
%[650]%		BEGIN
%[650]%			R1_0; LSHC(R1,3);
%[650]%			CHR_.R1+#60; LSTOUT();
%[650]%		END;
%[650]%	
%[650]%		CHR_","; LSTOUT();
%[650]%	
%[650]%		R2_.WORD2;
%[650]%		DECR I FROM 11 TO 0 DO
%[650]%		BEGIN
%[650]%			R1_0; LSHC(R1,3);
%[650]%			CHR_.R1+#60; LSTOUT();
%[650]%		END;
%[650]%	
%[650]%		CHR_"]"; LSTOUT();
%[650]%	END;
%[650]%	ROUTINE ZSOUTCON(ADDR)=
%[650]%	BEGIN
%[650]%		!OUTPUT A STRING STARTING FROM ADDR AND BEING NO
%[650]%		!MORE THAN 10 CHARACTERS.   THE FORMAT WILL BE:
%[650]%		!    [ASCIZ /STRING/{...}]
%[650]%		MAP BASE ADDR;
%[650]%		LOCAL STRING[3];
%[650]%		MACRO LASTCHAR=1,7$;
%[650]%	
%[650]%		STRNGOUT(PLIT ASCIZ '[ASCIZ /');
%[650]%	
%[650]%		STRING[0]_.ADDR[CONST1];
%[650]%		STRING[1]_.ADDR[CONST2];
%[650]%		STRING[2]_0;
%[650]%	
%[650]%		STRNGOUT(STRING);
%[650]%	
%[650]%		!IS IT A LONG OR SHORT STRING?
%[650]%		IF .STRING[0]<LASTCHAR> NEQ 0 AND .STRING[1]<LASTCHAR> NEQ 0
%[650]%			AND .ADDR[CW5] NEQ 0
%[650]%			THEN STRNGOUT(PLIT ASCIZ '/...]')
%[650]%			ELSE STRNGOUT(PLIT ASCIZ '/]');
%[650]%	END;
ROUTINE ZOUTCON=
BEGIN
!LIST A CONSTANT IN OCTAL ; R2 CONTAINS VALUE
CHR _ "["; LSTOUT();
DECR I FROM 11 TO 0 DO
BEGIN
	R1 _ 0; LSHC(R1,3);
	CHR _ .R1 + #60; LSTOUT();
END;
CHR _ "]"; LSTOUT()
END;
ROUTINE COMCOM=
BEGIN
	EXTERNAL LSTOUT;
	CHR_",";LSTOUT();LSTOUT()
END;


ROUTINE LSTINST(IPTR)=
BEGIN
%
ROUTNE LISTS ON LISTING DEVICE THE MACRO -10 MNEMONICS OF THE INSTRUCTIONS BEING GENERATED
%
MACRO
	IISN	= (@IPTR)<FULL>$,	!LINENUMBER OF INSTRUCTION
	ILABEL	= (@IPTR+1)<LEFT>$,
	IADDRPTR	= (@IPTR+1)<RIGHT>$,
	IOPCODE	= (@IPTR+2)<27,9>$,
	IAC	= (@IPTR+2)<23,4>$,
	IINDIR = (@IPTR+2)<22,1>$,
	IINDEX = (@IPTR+2)<18,4>$,
	IEFFADDR = (@IPTR+2)<RIGHT>$;
EXTERNAL CODELINES;
MACRO HEADRSW = CODELINES<LEFT>$;
LOCAL OPPOINT;
EXTERNAL OPMNEM;
!
ROUTINE ZLABLMAK(ILABLPT)=
BEGIN
%R1 CONTAINS LABEL IN BINARY%
MAP BASE ILABLPT;
R1_.ILABLPT[SNUMBER];
IF .R1 GTR 99999 THEN R1 _ .R1-99999; !REDUCE TO NICE RANGE
ZOUDECIMAL(); !OUTPUT VALUE OF R1 IN DECIMAL
		  IF .ILABLPT[SNUMBER] GTR 99999
			THEN CHR _ "M" ELSE CHR _ "P";
		  LSTOUT(); .VREG
END;	!OF ROUTINE ZMAKLABL

%[734]%	LOCAL DINSTF; !DOUBLE WORD INSTRUCTION FLAG
EXTERNAL  HEADCHK;		!CHECK AND COUNT LINES ON PAGE
EXTERNAL ZOUDLB;	!ROUTINE TO ADD TO THE MACRO EXPANDED LISTING A
			! LABEL THAT IS INSERTED ON THE 1ST INSTR OF EACH STMNT WHEN
			! THE USER HAS SPECIFIED THE "DEBUG" SWITCH
%[645]%	EXTERNAL PAGELINE;
IF .HEADRSW NEQ #777777
	THEN(		CODELINES _ 0;
		HEADRSW _ #777777
	    );
CRLF;
HEADCHK();
IF (R1 _ .IISN) GEQ 0
	THEN IF .R1 EQL 0 THEN ( CHR _ "*"; LSTOUT()) ELSE ZOUDECIMAL();
CHR _ #11; LSTOUT(); !TAB
IF .IADDRPTR EQL PBFENTRY
	THEN(MAP BASE R2;
		!ENTRY NAME TAKES UP ONE LISTING LINE - ACCOUNT FOR IT
%[645]%		CRLF; PAGELINE_.PAGELINE-1; CHR_#11; LSTOUT();
		R2 _ .IEFFADDR; R2 _ .R2[IDSYMBOL]; ZOUTSYM();
		CHR _ ":"; LSTOUT();
		RETURN
	    );
!
!GEN THE RELATIVE LOCATION (OCTAL)
!
R2<LEFT> _ .CODELINES<RIGHT>; ZOUTOCT(); CHR _ #11; LSTOUT(); %TAB%
CODELINES _ .CODELINES + 1;
IF  .ILABEL NEQ 0 	!LIST A LABEL
  THEN 	(
	 LOCAL BASE LABPT;
	 LABPT _ .ILABEL;
	 DO
	 (
	 ZLABLMAK(.LABPT);
	 CHR _ ":"; LSTOUT(); CRLF; HEADCHK();
	 CHR _ #11; LSTOUT(); LSTOUT(); !TAB
         ) WHILE (LABPT _ .LABPT[SNNXTLAB]) NEQ 0;
	);

	IF (R1_.IISN) GTR 0 AND .FLGREG<DBGLABL>	!IF THE USER SPECIFIED THE "DEBUG" SWITCH
				! THEN IFTHIS INSTR STARTS A STMNT, LIST
				! AN "L" LABEL ON THIS INSTR
	THEN ZOUDLB();


CHR _ #11; LSTOUT();	!TAB
%[734]%	DINSTF_0;
!NOW DO THE INSTRUCTION LISTING
!
IF .IOPCODE NEQ 0
THEN(
!First mnemonic is now GFAD (#103)
%[761]%	OPPOINT _ (OPMNEM-#103)[.IOPCODE]<0,6>;	!MNEMONIC TABLE POINTER
	INCR I FROM 0 TO 5 DO
	  (CHR _SCANI(OPPOINT,CHR);	!GET A CHARACTER
	   IF(CHR _ .CHR + #40 ) LEQ #100 THEN EXITLOOP;
%[734]%	   IF .I EQL 0 THEN DINSTF_.CHR; ! PICK UP FIRST CHAR OF INSTRUCTION
	   LSTOUT()
	  )
    );
CHR _ #11;	LSTOUT();	!TAB
!AC FIELD
!
IF .IAC LEQ 7 
  THEN (CHR _ .IAC + #60; LSTOUT())
   ELSE (CHR _ "1"; LSTOUT();
	 CHR _ (.IAC + #50); LSTOUT()
 	);
CHR _ ","; LSTOUT();
!
!INDIRECT BIT
!
IF .IINDIR NEQ 0 THEN (CHR _ "@"; LSTOUT());
!
!ADDRESS
!
BEGIN BIND ZADDR = IADDRPTR; MAP BASE ZADDR;
  IF .IADDRPTR GTR PBF2LABREF
    THEN
	(IF SYMBOL(ZADDR)
	  THEN ( R2 _ .ZADDR[IDSYMBOL];
		ZOUTSYM()
		)
	  ELSE IF .ZADDR[OPERSP] EQL CONSTANT
		THEN ( IF .ZADDR[DBLFLG] OR .ZADDR[VALTYPE] EQL REAL
			THEN(IF .ZADDR[CONADDR] EQL .IEFFADDR
![650] IN THE CONSTANT CASE, DISTINGUISH BETWEEN SINGLE AND
![650] DOUBLE WORD CONSTANTS.
%[650]%				THEN (R2 _ .ZADDR[CONST1];
![734] ONLY PRINT AS DOUBLE OCTAL IF INSTRUCTION IS DOUBLE WORD, I. E.,
![734] THE FIRST CHARACTER BEGINS WITH "D" (AVOID CAMXX).
![761] also if instruction starts with "G" (GFAD, etc.)
%[761]%					IF .ZADDR[DBLFLG] AND
%[761]%					   (.DINSTF EQL "D" OR .DINSTF EQL "G")
%[761]%					THEN RETURN ZDOUTCON(.ZADDR[CONST2]))
				ELSE R2 _ .ZADDR[CONST2]
			    )
			ELSE R2 _ .ZADDR[CONST2]; !ELSE INTEGER OR LOGICAL OR BYTE
			RETURN ZOUTCON()
		     )
		ELSE
			(R2_.ZADDR[IDSYMBOL]; ZOUTSYM(););
	IF (R1 _ EXTSIGN(.IEFFADDR) -.ZADDR[IDADDR]) NEQ 0 THEN ZOUOFFSET();
       )
  ELSE IF .IADDRPTR GTR 3 THEN BEGIN END
    ELSE IF .IADDRPTR GTR 2
	THEN BEGIN MAP BASE R2;
		R2_.IEFFADDR; R2 _ .R2[IDSYMBOL];
		ZOUTSYM()
	     END
	ELSE IF .IADDRPTR GTR 1
		THEN !DOTTED FUNCTION NAME
		  (R2 _@(.IEFFADDR);
		   ZOUTSYM()
		  )
		ELSE  IF .IADDRPTR GTR 0	!NO SYMBOLIC ADDR
			THEN (R2<LEFT> _ .IEFFADDR; ZOUTOCT()) !IMMEDIATE MODE VALUE
			ELSE  ZLABLMAK(.IEFFADDR);
END;
!
!INDEX FIELD
!
IF .IINDEX NEQ 0
  THEN ( CHR _ "("; LSTOUT();
	IF .IINDEX LEQ 7
		THEN (CHR _ .IINDEX +#60; LSTOUT())
		ELSE (CHR _ "1"; LSTOUT();CHR _ .IINDEX +#50; LSTOUT()
		     );
	 CHR _ ")"; LSTOUT();
	);
END;	!OF ROUTINE LSTINST

ROUTINE  LINEMAP (IPTR) =
!LIST ON LISTING DEVICE A LINE-NUMBER/OCTAL-LOCATION MAP IF
! NO MACRO LISTING WAS REQUESTED

BEGIN

EXTERNAL  CODELINES, HEADCHK;
EXTERNAL  LMLINO,		! CURRENT SOURCE LINE NUMBER
	  LMRONO,		! CURRENT MAP ROW NUMBER
	  LMCONO;		! CURRENT MAP COLUMN NUMBER

MACRO	  IISN		= (@IPTR)<FULL>$,
	  IADDRPTR	= (@IPTR+1)<RIGHT>$,
	  HEADRSW	= CODELINES<LEFT>$;

	IF .HEADRSW NEQ #777777
	  THEN BEGIN
	    CODELINES _ 0;
	    HEADRSW _ #777777;
	  END;
	IF .IADDRPTR EQL PBFENTRY
	  THEN RETURN;
	IF .IISN GTR 0 AND
	   .LMLINO LSS .IISN	! BEWARE 1 LINE NUM FOR >1 OCTAL LOC
	  THEN BEGIN
	    DO 
	      BEGIN
		IF (LMCONO _ .LMCONO + 1) EQL 10
		  THEN BEGIN
		    LMCONO _ 0;
		    CRLF;
		    HEADCHK ();
		    CHR _ "0";
		    IF (LMRONO _ (.IISN DIV 10) - 1) LSS 999
		      THEN BEGIN
			LSTOUT ();
			IF .LMRONO LSS 99
			  THEN BEGIN
			    LSTOUT ();
			    IF .LMRONO LSS 9
			      THEN LSTOUT ();
			  END
		      END;
		    R1 _ LMRONO _ .LMRONO + 1;
		    ZOUDECIMAL ();
		    CHR _ "0";
		    LSTOUT ();
		    CHR _ " ";
		    LSTOUT ();
		    CHR _ ":";
		    LSTOUT ();
		    CHR _ " ";
		    LSTOUT ();
		    LMLINO _ .LMRONO * 10 - 1;
		  END
		  ELSE BEGIN
		    CHR _ #11;
		    LSTOUT ();
		  END
	      END
	      WHILE  (LMLINO _ .LMLINO + 1) LSS .IISN;
	    R2<LEFT> _ .CODELINES<RIGHT>;
	    ZOUTOCT ();
	  END;
	CODELINES _ .CODELINES + 1;
END;					! OF ROUTINE LINEMAP

ROUTINE ROUIMFUN(FUNCPTR,FUNAME)=	!OUTPUT FUNCTION REQUEST GLOBAL
BEGIN
			RDATWD_.FUNCPTR<LEFT>^18; ZOUTBLOCK(RCODE,RELN);
			R2 _ .FUNAME; !SIXBIT SYMBOL NAME
			RDATWD_(RGLOBREQ +RADIX50()); ZOUTBLOCK(RSYMBOL,RELN);
			RDATWD_RGLOB0^18 + .HILOC;
			ZOUTBLOCK(RSYMBOL,RELRI)
END;
ROUTINE ROURLABEL(LABLPTR)=
BEGIN
MAP BASE LABLPTR;
		 RDATWD<LEFT> _ .LABLPTR<LEFT>;
		IF .LABLPTR[SNSTATUS] NEQ OUTPBUFF  THEN 
%[636]%			IF NOT .LABLPTR[SNDEFINED]
%[636]%			THEN
%[636]%			BEGIN
%[636]%				LABLPTR[SNADDR]_0;
%[636]%				LABLPTR[SNDEFINED]_TRUE;
%[636]%			END;
		 RDATWD<RIGHT> _ .LABLPTR[SNADDR];
!
!AT THIS POINT RDATWD<RIGHT> CONTAINS EITHER 0 (IF FIRST TIME LABEL REFERENCED)
! OR A HI-SEG CHAIN ADDRESS IF NOT FIRST REFERENCE AND STILL UNDEFINED
! OR THE HI-SEG ADDRESS OF THE INSTRUCTION THE LABEL DEFINES
! THE VALUE OUTPBUFF MEANS THE LABEL HAS BEEN DEFINED TO LOADER
!
		 ZOUTBLOCK(RCODE,IF .LABLPTR[SNADDR] EQL 0 THEN RELN ELSE RELRI);
		!RELOCATE (RELRI) ONLY IF NOT FIRST REFERENCE
%[636]%		IF  .LABLPTR[SNSTATUS] NEQ OUTPBUFF
%[636]%		THEN
%[636]%		BEGIN
%[636]%			LABLPTR[SNADDR] _ .HILOC;	!CHAIN THE REQUEST
%[636]%			LABLPTR[SNDEFINED]_TRUE;
%[636]%		END;
END;	!END OF ROURLABEL
ROUTINE ROUSYM(INSTRUCTION,INSADDR)=	!RELOCATABLE SYMBOLIC OUTPUT
BEGIN
	MACRO ADD=3$,SUBT=4$;
	MACRO POLISHREL(OP,OPER1,RELOC1,OPER2,RELOC2,SYM)=
	BEGIN
		RDATWD _ OP;	!MEANS NEXT WD IS FULL WD OPERAND
		ZOUTBLOCK(RPOLISH,RELN);
		RDATWD _ OPER1;	!FULL WORD
		ZOUTBLOCK(RPOLISH,RELOC1);
		RDATWD _ OPER2;
		ZOUTBLOCK(RPOLISH,RELOC2);
		RDATWD _ #777777^18 + .HILOC;	!RIGHT HALF CHAINED FIXUP,, ADDRESS
		ZOUTBLOCK(RPOLISH,RELRI);
	END$;
		MAP BASE R2;
		LOCAL BASE SYMPTR; SYMPTR _ .INSADDR<RIGHT>;
		!NOW CHECK FOR SUBROUTINE OR FUNCTION CALL
		IF NOT SYMBOL(SYMPTR)
		THEN (RDATWD _ .INSTRUCTION;  ZOUTBLOCK(RCODE,RELRI);
			RETURN
		     );
		IF .SYMPTR[OPRSP1] EQL FNNAME1 
		  THEN 
			IF (NOT .SYMPTR[IDATTRIBUT(FENTRYNAME)])
				THEN IF (NOT .SYMPTR[IDATTRIBUT(DUMMY)])
					THEN (ROUIMFUN(.INSTRUCTION,.SYMPTR[IDSYMBOL]);
				RETURN
			);
		!HERE IF NOT A FUNCTION CALL OR SUBROUTINE CALL
		RDATWD _ .INSTRUCTION;
		IF ( EXTSIGN(.INSTRUCTION<RIGHT>)) LSS (-#400)
		THEN
			(RDATWD<RIGHT> _ 0;
			 ZOUTBLOCK(RCODE,RELN);
				IF NOT .SYMPTR[IDATTRIBUT(INCOM)] THEN
				 POLISHREL(ADD^18+1,EXTSIGN(.INSTRUCTION<RIGHT>),
					RELN,0,RELRI,.SYMPTR)	!GENERAT A POLISH FIXUP BLOCK
	   		ELSE
			   BEGIN
				RDATWD _ ADD^18+2;	!NEXT WD IS GLOBAL REQUEST
				ZOUTBLOCK(RPOLISH,RELN);
				R2 _ .SYMPTR[IDCOMMON]; R2 _ .R2[COMNAME];
				 RDATWD _ RGLOBDEF + RADIX50();  !A GLOBAL REQUEST POLISH FIXUP
				 ZOUTBLOCK(RPOLISH,RELN);
				  RDATWD _ #1777777;	!1^18 + -1
				 ZOUTBLOCK(RPOLISH,RELN);
				 RDATWD _ .INSTRUCTION<RIGHT>^18+#777777;
				 ZOUTBLOCK(RPOLISH,RELN);
				 RDATWD _ .HILOC^18;
				  ZOUTBLOCK(RPOLISH,RELL);  !FINALLY O/P THE FIXUP ADDRESS
			   END;
			   RETURN
			)
		ELSE
		IF .SYMPTR[IDATTRIBUT(INCOM)]
		    THEN	!GENERATE INSTRUCTION
		      (
			ZOUTBLOCK(RCODE,RELN);	!OUTPUT THE INSTRUCTION
			R2 _ .SYMPTR[IDCOMMON]; R2 _ .R2[COMNAME];
			RDATWD _ (RGLOBREQ + RADIX50());
			ZOUTBLOCK(RSYMBOL,RELN);	!OUTPUT SYMBOL BLOCK
			RDATWD _ RGLOB4^18 + .HILOC;	!THE FIXUP REQUEST
			ZOUTBLOCK(RSYMBOL,RELRI);
			RETURN
		      )
			ELSE ZOUTBLOCK(RCODE,RELRI);	!OUTPUT THE INSTRUCTION
 END;
FORWARD GMULENTRY;
ROUTINE OUTMOD(CODEPTR,	!PTR TO BLOCK OF CODE TO BE GENERATED
		COUNT)=		!#OF INSTRUCTIONS TO BE GENERATED
BEGIN
%
ROUTINE GENERATES THE RLOCATABLE BINARY INSTRUCTIONS FOR THE OMPILER. ALSO
RESPONSIBLE OFR CALLING ROUTINES THAT GENERATE THE MACRO CODE LISTING
AND THE ROUTINES THAT GENERATE SYMBOL INGORMATION FOR THE LOADER
%
EXTERNAL DEFISN;	!ROUTINE CALLED FOR 1ST INSTR OF EACH LINE TO
			! PUT OUT A LABEL CORRESPONDING TO THE LINE SEQ NUMBER
REGISTER CODEBLOCK;
MAP BASE R2;
MAP PEEPHOLE CODEPTR;
!
!LOOP ON COUNT WHERE COUNT IS THE NUMBER OF INSTRUCTIONS TO BE GENERATED
!BUT ONE-HALF THE SIZE OF THE CODE BLOCK
!
CODEBLOCK _ .CODEPTR<RIGHT>;
!OUTPUT LINE-NUMBER/OCTAL-LOCATION MAP IF NO MACRO LISTING
	IF .FLGREG<LISTING>
	  THEN 
	    INCR I FROM 0 TO .COUNT-1
	      DO BEGIN
		IF .FLGREG<MACROCODE>
		  THEN LSTINST ((.CODEBLOCK)[.I*3])
		  ELSE
		    IF .FLGREG<MAPFLG>
		      THEN LINEMAP ((.CODEBLOCK)[.I*3]);
	      END;
!START RELOCATABLE BINARY GENERATON IF REQUESTED
IF .FLGREG<OBJECT>
THEN 
     INCR I FROM 0 TO (.COUNT-1) DO
     BEGIN
	LABEL REL1;
  REL1: IF .CODEPTR[.I,PBFSYMPTR] GTR PBFENTRY
	  THEN (ROUSYM(.CODEPTR[.I,PBFINSTR],.CODEPTR[.I,PBFSYMPTR]); LEAVE REL1)	!SYMBOLIC- IDENTIFIER,CONSTANT OR TEMP
	  ELSE		!EITHER NOT SYMBOLIC, OR LABEL OR FUNCTION CALL OR LIBRARY FUNCTION CALL "DOTTED"
	   CASE .CODEPTR[.I,PBFSYMPTR] OF SET
	%
	0 - LABEL ADDRESS - PTR TO LABEL IN RH OF INSTRUCTION
	%
		ROURLABEL(.CODEPTR[.I,PBFINSTR]);	!RELOCATABLE LABEL O/P
	%
	1- NO SYMBOLIC ADDRESS OUTPUT THE INSTRUCTION
	%
		BEGIN
			RDATWD _ .CODEPTR[.I,PBFINSTR];
			ZOUTBLOCK(RCODE,RELN);
			LEAVE REL1
		END;
	%
	2- FUNCTION CALL DOTTED
	%
		ROUIMFUN(.CODEPTR[.I,PBFINSTR],@(.CODEPTR[.I,PBFADDR]));	!RELOCATABLE  IMPLICIT FUNCTION CALL
	%3- FUNCTION CALL NOT "DOTTED"
	%
		BEGIN MAP BASE R2;
			R2_.CODEPTR[.I,PBFADDR];
			ROUIMFUN(.CODEPTR[.I,PBFINSTR],.R2[IDSYMBOL]);
		END;
	%4-USED IN OUTMDA, NOT HERE
	%
	BEGIN END;
	%5-USED IN OUTMDA, NOT HERE
	%
	BEGIN END;
	%6-USED IN OUTMOD, NOT HERE
	%
	BEGIN END;
	%7-USED IN OUTMDA, NOT HERE
	%
	BEGIN END;
	%8-PBFENTRY, A GLOBAL ENTRY SYMBOL
	%
	BEGIN
		GMULENTRY(.CODEPTR[.I,PBFADDR]); !SPECIAL CASE FOR GLOBAL ENTRY DEFINITIONS(NOT AN INSTRUCTION)
		HILOC _ .HILOC-1; !DECREMENT HILOC TO OFFSET THE INCREMENT
					!COMING AT END OF LOOP SO THAT
					!NEXT INSTRUCTION WILL HAVE SAME ADDR
					!AS THAT ASSIGNED TO ENTRY SYMBOL
	END
	TES;
!
!LEAVE REL1 EXPRESSION COMES HERE
!
	IF .CODEPTR[.I,PBFLABEL] NEQ 0
	 THEN
	(LOCAL BASE LINLABEL;
	 LINLABEL _ .CODEPTR[.I,PBFLABEL];
	 DO
	 BEGIN
%[636]%	IF .LINLABEL[SNDEFINED]
	 THEN (
		RDATWD _ .LINLABEL[SNADDR]^18+.HILOC;
		ZOUTBLOCK(RLOCAL,RELB);
		);
	   LINLABEL[SNSTATUS]_OUTPBUFF;	!DEFINE IT (HAS PASSED THRU PBUFF)
	   LINLABEL[SNADDR] _ .HILOC;	!DEFINING THE SYMBOL NOW
%[636]%	   LINLABEL[SNDEFINED]_TRUE;
	 END WHILE (LINLABEL_.LINLABEL[SNNXTLAB]) NEQ 0;
	);

	%(***IF THIS INSTRUCTION STARTS A SOURCE LINE, THEN
		IF THE "DEBUG" SWITCH WAS SPECIFIED BY THE USER, OUPUT A LABEL FOR THIS INSTR**)%
	IF .CODEPTR[.I,PBFISN] GTR 0 AND .FLGREG<DBGLABL> THEN DEFISN(.CODEPTR[.I,PBFISN]);

	HILOC _ .HILOC + 1;	!INCREMENT HISEG AVAILABLE LOCATION
      END;	!END OF INCR LOOP
.VREG
END;	!OF ROUTINE
GLOBAL ROUTINE OUTMDA(ARPTR,ARCOUNT)=
BEGIN
%
	ROUTINE OUTPUTS TO THE REL FILE THE ARG BLOCKS
	FOR ALL STATEMENTS THAT USE THEM. THESE INCLUDE IOLISTS,
	FUNCTION OR SUBROUTINE ARGUMENTS LISTS, AND
	OTHER ARG LISTS.

	THE CALL IS MADE TO THIS ROUTINE WITH A PTR TO THE ARGUMENT
	CODE WORDS AND A COUNT OF THE NUMBER OF WORDS TO GENERATE.
	THE FORMAT OF THE BLOCK OF WORDS IS SIMILAR TO THAT USED
	IN A CAL TO OUTMOD TO OUTPUT INSTRUCTIONS.
%

EXTERNAL ZOUDECIMAL;
EXTERNAL ZOUOFFSET;
EXTERNAL CODELINES,LSTOUT,ZLABLMAK,ZOUTOCT,COMCOM,OUTMSG,ZOUTSYM;
MAP BASE R1:R2;
OWN HDRSW;
MACRO ILABEL = (@ARPTR)[.I+1]<LEFT>$,
	IADDRPTR = (@ARPTR)[.I+1]<RIGHT>$,
	ILADDR = (@ARPTR)[.I+2]<LEFT>$,
	IRADDR = (@ARPTR)[.I+2]<RIGHT>$,
	IARGWD = (@ARPTR)[.I+2]<FULL>$;

!
INCR I FROM 0 TO (.ARCOUNT-1)*3 BY 3 DO
  BEGIN
	IF .FLGREG<LISTING> THEN IF .FLGREG<MACROCODE> 
	THEN
	BEGIN
		EXTERNAL HEADCHK;
		CRLF;
		HEADCHK();
		CHR _ #11;LSTOUT();
		!SUBROUTINE SIXBIT NAME SHOULD NOT PRINT LOCATION 0 (NONE AT ALL!)
%[646]%		IF .CODELINES<RIGHT> NEQ 0 THEN (R2<LEFT>_.CODELINES<RIGHT>;
%[646]%			ZOUTOCT());
%[646]%		CHR_#11;	LSTOUT();
		CODELINES _ .CODELINES+1;
		IF .ILABEL NEQ 0 THEN(ZLABLMAK(.ILABEL); CHR_":"; LSTOUT());
		CHR_#11; LSTOUT(); !TAB
	!FOR VARIOUS DATA (ENTRY POINTS) UPDATE OCTAL LOCATION COUNTER
	END ELSE IF .FLGREG<MAPFLG> THEN CODELINES_.CODELINES+1;
	SELECT .IADDRPTR OF NSET
	PBFLABREF:	EXITSELECT
			(
			IF .FLGREG<LISTING> THEN IF .FLGREG<MACROCODE>  THEN
			BEGIN
			 R2<LEFT>_.ILADDR; ZOUTOCT();
			 COMCOM(); ! ",,"
			 ZLABLMAK(.IRADDR); 
			END;
			IF .FLGREG<OBJECT> THEN
				ROURLABEL(.IARGWD);
			);

	PBFNOSYM:	EXITSELECT
			(
			IF .FLGREG<LISTING> THEN IF .FLGREG<MACROCODE>  THEN
			BEGIN
			 R2<LEFT>_.ILADDR; ZOUTOCT();
			 COMCOM();
			 R2<LEFT>_.IRADDR; ZOUTOCT();
			END;
			IF .FLGREG<OBJECT> THEN
			 (RDATWD _ .IARGWD; ZOUTBLOCK(RCODE,RELN));
			);
	PBF2NOSYM:	EXITSELECT
			(
			IF .FLGREG<LISTING> THEN IF .FLGREG<MACROCODE>  THEN
			BEGIN
			 R2<LEFT>_.ILADDR; ZOUTOCT();
			 COMCOM();
			 R2<LEFT>_.IRADDR; ZOUTOCT();
			END;
			IF .FLGREG<OBJECT> THEN
			 (RDATWD _ .IARGWD; ZOUTBLOCK(RCODE,RELN));

			);
	PBFIMFN:	EXITSELECT
			(
			IF .FLGREG<LISTING> THEN IF .FLGREG<MACROCODE>  THEN
			BEGIN
			 R2<LEFT> _ .ILADDR; ZOUTOCT();
			 COMCOM();
			 R2 _ @.IRADDR; ZOUTSYM();
			END;
			IF .FLGREG<OBJECT> THEN
			  ROUIMFUN(.IARGWD,@.IRADDR);

			);
	PBFEXFN:	EXITSELECT
			(
			IF .FLGREG<LISTING> THEN IF .FLGREG<MACROCODE>  THEN
			BEGIN
			 R2<LEFT> _ .ILADDR; ZOUTOCT();
			 COMCOM();
			 R2 _ .IRADDR; R2 _ .R2[IDSYMBOL]; ZOUTSYM();
			END;
			IF .FLGREG<OBJECT> THEN
			 (R2_.IRADDR; ROUIMFUN(.IARGWD,.R2[IDSYMBOL]));
			);
	PBF2LABREF:	EXITSELECT
			(IF .FLGREG<LISTING> THEN IF .FLGREG<MACROCODE>  THEN
			BEGIN
			 ZLABLMAK(.ILADDR); COMCOM(); ZLABLMAK(.IRADDR);
			END;
			IF .FLGREG<OBJECT> THEN
			 (R1 _ .ILADDR; R2 _ .IRADDR;
			  RDATWD _ .R1[SNADDR]^18 +  .R2[SNADDR];
			  ZOUTBLOCK(RCODE,RELB);
			 );
			);
	PBFFORMAT:	EXITSELECT
			BEGIN
			  REGISTER BASE TPTR;	!TEMPORARY PTR
			  IF .FLGREG<LISTING> THEN IF .FLGREG<MACROCODE>  THEN
			   BEGIN
				R2<LEFT> _.ILADDR; ZOUTOCT();
				COMCOM();
				!TYPE THE P LABEL FOR THE RIGHT HALF
				TPTR_.IRADDR;	!PTR TO THE FORMAT STMNT
				TPTR_.TPTR[SRCLBL];	!STMNT NUMBER TABLE ENTRY FOR THE LABEL
				R1_.TPTR[SNUMBER]; ZOUDECIMAL();	!THE STMNT NUMBER OF THE FORMAT

				CHR_"P"; LSTOUT();	!FOLLOWED BY "P"
			   END;
			  IF .FLGREG<OBJECT> THEN
			   BEGIN
				TPTR_.IRADDR;	!PTR TO FORMAT STMNT
				RDATWD_.ILADDR^18	!LEFT HALF OF OUTPUT WD COMES DIRECTLY FROM PBUFF
					+ .TPTR[FORADDR];	!RIGHT HALF IS REL ADDR OF THE FORMAT STMNT
				 ZOUTBLOCK(RCODE,RELRI);
			   END;
			END;
	OTHERWISE:	BEGIN
			IF .FLGREG<LISTING> THEN IF .FLGREG<MACROCODE>  THEN
			(
			 R2<LEFT> _ .ILADDR; ZOUTOCT();
			 COMCOM();
			  R2 _ .IADDRPTR;
			   IF .R2[OPERSP] EQL CONSTANT
![650] IN ARGUMENT LISTS, TAKE CARE OF ARGUMENTS BASED ON THEIR TYPE.
%[650]%	THEN BEGIN
%[650]%			LOCAL TMP;
%[650]%			IF .(@ARPTR)[.I+2]<23,4> EQL #17 THEN %STRING% ZSOUTCON(.R2) ELSE
%[650]%			IF .R2[DBLFLG] THEN !DP OR COMPLEX CONSTANT
%[650]%				(TMP_.R2[CONST2];
%[650]%				R2_.R2[CONST1];
%[650]%				ZDOUTCON(.TMP))
%[650]%			ELSE (IF .R2[VALTYPE] EQL REAL
%[650]%				THEN R2_.R2[CONST1]
%[650]%				ELSE R2_.R2[CONST2];
%[650]%				ZOUTCON());
%[650]%			END
				ELSE (R2 _ .R2[IDSYMBOL]; ZOUTSYM();
					R2 _ .IADDRPTR;
					IF (R1 _ EXTSIGN(.IRADDR) - .R2[IDADDR]) NEQ 0 THEN ZOUOFFSET();
				     );
			);
			IF .FLGREG<OBJECT> THEN ROUSYM(.IARGWD,.IADDRPTR);
			END;
	TESN;
	IF .FLGREG<OBJECT> THEN
	(IF .ILABEL NEQ 0
	THEN
	BEGIN
		REGISTER BASE LABENT;
		LABENT_.ILABEL;
%[636]%		IF .LABENT[SNDEFINED]
		THEN (
			RDATWD _ .LABENT[SNADDR]^18+.HILOC;
			ZOUTBLOCK(RLOCAL,RELB);
		     );
		LABENT[SNSTATUS] _ OUTPBUFF;	!THRU THE OUTPUT BUFFFER
		LABENT[SNADDR] _ .HILOC;	!DEFINING THE SYMBOL NOW
%[636]%		LABENT[SNDEFINED]_TRUE;
	END;
	HILOC _ .HILOC + 1;	!INCREMENT HISEG AVAILABLE LOCATION
	);
  END; !OF INCR I DO
END;	!OF OUTMDA
GLOBAL ROUTINE ZENDALL(STADDR)=	!FINISHES OUTPUT OF REL FILE
			!FOR CURRENT PROGRAM
			!DUMPS SYMBOL DTABLE
			!DUMPS NEWLY DEFINED SYMBOLS
			!OUTPUTS "END" BLOCK
BEGIN
EXTERNAL ISN,E142; !NEW ERROR MESSAGE - PROGRAM TOO LARGE
EXTERNAL FATLER; !NEED THIS FOR PRINTING ERROR MESSAGE
EXTERNAL ENDISNRLBLK;
EXTERNAL DMPRLBLOCK;	!ROUTINE TO DUMP A BUFFERED REL-FILE BLOCK OUT
EXTERNAL ZOUTBLOCK,RADIX50,PROGNAME,DMPSYMTAB;
EXTERNAL SYMRLBF,LOCRLBF,MAINRLBF;	!REL FILE  BUFFERS
	EXTERNAL DMPMAINRLBF;	!TO DUMP THE MAIN REL-FILE BUFFER
MAP RELBUFF SYMRLBF:LOCRLBF:MAINRLBF;
	IF .FLGREG<DBGLABL> THEN ENDISNRLBLK();	!IF THE  USER SPECIFIED
					! THE "DEBUG" SWITCH, OUTPUT THE SYMBOL DEFS FOR ANY
					! LABELS REMAINING IN THE BUFFER OF LABELS TO BE INSERTED
					! ON EACH SOURCE LINE
	DMPSYMTAB();	!DUMP THE SYMBOL TABLE TO REL FILE

	%(**DUMP ANY LOCAL REQUESTS,GLOBAL REQUESTS, AND SYMBOL DEFS THAT
		ARE STILL IN THEIR BUFFERS**)%
	DMPMAINRLBF();	!MUST OUTPUT ANY CODE BLOCKS TO THE REL FILE
			! BEFORE DUMPING LOCAL AND G;LOBAL REQUESTS
	!PUT OUT GLOBAL SYMBOL FOR MAIN PROGRAM
	! SO LINK CAN WARN ABOUT TWO MAIN PROGRAMS
	IF .FLGREG<PROGTYP> EQL MAPROG THEN
	BEGIN
		R2 _ SIXBIT'MAIN.';
		RDATWD _ RGLOBDEF+RADIX50();
		ZOUTBLOCK(RSYMBOL,RELN);
		RDATWD _ .STADDR;
		ZOUTBLOCK(RSYMBOL,RELRI);
![705] IF A REAL PROGRAM NAME WAS GIVEN TO THE PROGRAM, USE IT AS
![705] AN ENTRY POINT FOR THE MAIN PROGRAM - THIS IS THE ONLY WAY
![705] (SHORT OF A MACRO PROGRAM) TO GET THIS EFFECT.
%[705]%		IF .PROGNAME NEQ SIXBIT'MAIN.' THEN
%[705]%		BEGIN
%[705]%			R2 _ .PROGNAME;
%[705]%			RDATWD _ RGLOBDEF+RADIX50();
%[705]%			ZOUTBLOCK(RSYMBOL,RELN);
%[705]%			RDATWD _ .STADDR;
%[705]%			ZOUTBLOCK(RSYMBOL,RELRI);
%[705]%		END
	END;
	IF .SYMRLBF[RDATCNT] NEQ 0 THEN DMPRLBLOCK(SYMRLBF,.SYMRLBF[RDATCNT]+2);
	IF .LOCRLBF[RDATCNT] NEQ 0 THEN DMPRLBLOCK(LOCRLBF,.LOCRLBF[RDATCNT]+2);

	IF .FLGREG<PROGTYP> EQL MAPROG  THEN (RDATWD _ .STADDR; ZOUTBLOCK(RSTART,RELRI)); !START ADDRESS BLOCK
	 RDATWD_.HILOC; ZOUTBLOCK(REND,RELRI);
	RDATWD _ .LOWLOC; ZOUTBLOCK(REND,RELRI);
	IF .MAINRLBF[RDATCNT] NEQ 0 THEN DMPRLBLOCK(MAINRLBF,.MAINRLBF[RDATCNT]+2);
	!CHECK FOR HIGH AND LOW OVERFLOWS IF PROGRAM TOO LARGE
		IF .HILOC GEQ 1^18 OR .LOWLOC GEQ 1^18
		THEN FATLER(.ISN,E142<0,0>);
END;
ROUTINE GMULENTRY(MULSYM)=
BEGIN
!GENERATE AN ENTRY DEFINITION (GLOBAL) IN REL FILE FOR MULTIPLE ENTRY
!NAMES; OUTMOD MUST HAVE  ALREADY BEEN CALLED TO DUMP ANY CODE IN PBUFF
!
MAP BASE MULSYM;
	R2 _ .MULSYM[IDSYMBOL];
	RDATWD _ (RGLOBDEF+RADIX50());
	ZOUTBLOCK(RSYMBOL,RELN);
	RDATWD _ .HILOC<RIGHT>;
	ZOUTBLOCK(RSYMBOL,RELRI)
END;



GLOBAL ROUTINE LSTFORMATS=
%(***************************************************************************
	ROUTINE TO LIST ALL THE FORMAT STMNTS IN A PROGRAM.
	ASSUMES THAT THE GLOBAL "FORMPTR" POINTS TO THE 1ST
	FORMAT STMNT. EACH FORMAT STMNT IS LINKED TO THE
	NEXT BY THE "FMTLINK" FIELD
***************************************************************************)%
BEGIN
	EXTERNAL PAGELINE,STRNGOUT,HEADING;
	EXTERNAL ZOUDECIMAL;
	EXTERNAL FORMPTR;
	LOCAL RLOC;	!RELATIVE LOC IN LOW SEG OF THE WD BEING LISTED
	LOCAL BASE SNENTRY;	!THE STMNT NUMBER TABLE ENTRY FOR
				! THE STMNT NUMBER FOR A GIVEN FORMAT STMNT
	REGISTER BASE FPTR;	!PTR TO THE FORMAT STMNT BEING PRINTED
	REGISTER CPTR;		!BYTE PTR TO THE CHARACTER IN THE STRING
				! TO BE LISTED



	IF (FPTR_.FORMPTR<LEFT> ) EQL 0	!IF THERE ARE NO FORMAT STMNTS IN THIS PROGRAM
	THEN RETURN;

	%(**PRINT HEADER**)%
	IF ( PAGELINE_.PAGELINE-4) LEQ 0
	THEN	( HEADING();  PAGELINE_.PAGELINE-4);
	STRNGOUT(PLIT ASCIZ'?M?J?M?JFORMAT STATEMENTS (IN LOW SEGMENT):?M?J?M?J');


	%(***LIST ALL FORMAT STMNTS IN PROGRAM**)%
	UNTIL .FPTR EQL 0
	DO 
	BEGIN
		R1_.FPTR[SRCISN]; ZOUDECIMAL();	!LINE NUMBER OF THIS FORMAT STMNT
		CHR_#11; LSTOUT();	!TAB
		RLOC_.FPTR[FORADDR];	!RELATIVE ADDRESS OF THE 1ST WD OF THE
					! STRING
		R2<LEFT>_.RLOC;  ZOUTOCT();	!LIST IT
		CHR_#11; LSTOUT();	!TAB

		!LIST THE "P" LABEL
		SNENTRY_.FPTR[SRCLBL];	!LABEL TABLE ENTRY FOR THE STMNT NUMBER
		R1_.SNENTRY[SNUMBER];	!STMNT NUMBER
		ZOUDECIMAL();		!LIST IT
		CHR_"P"; LSTOUT();	! FOLLOWED BY "P"
		CHR_":"; LSTOUT();	! FOLLOWED BY ":"
		CHR_#11;  LSTOUT();	!TAB


		!LIST THE 1ST WD OF THIS FORMAT STRING
		CPTR_(.FPTR[FORSTRING]-1)<0,7>;	!BYTE PTR TO CHAR PRECEEDING
					! THE 1ST CHAR OF THE STRING
		DECR I FROM 4 TO 0	!LIST 5 CHARS
		DO
		(CHR_SCANI(CPTR); LSTOUT());	!INCR BYTE PTR TO NEXT CHAR AND LIST THAT CHAR

		CRLF;
		HEADCHK();

		!LIST ALL WDS OF THE FORMAT STRING AFTER THE 1ST,
		! PRECEEDING EACH BY ITS RELATIVE ADDRESS
		DECR I FROM .FPTR[FORSIZ]-2 TO 0	
		DO
		BEGIN
			CHR_#11;  LSTOUT();	!TAB
			RLOC_.RLOC+1;		!RELATIVE LOC OF THIS WD
			R2<LEFT>_.RLOC;
			ZOUTOCT();		!LIST IT
			CHR_#11;  LSTOUT();	!TAB
			CHR_#11;  LSTOUT();
			DECR I FROM 4 TO 0	!LIST 5 CHARS
			DO
			(CHR_SCANI(CPTR); LSTOUT());	!INCR BYTE PTR TO NEXT CHAR AND LIST IT

			CRLF;
			HEADCHK();
		END;

		FPTR_.FPTR[FMTLINK];	!GO ON TO THE NEXT FORMAT STMNT
	END;
END;	!OF ROUTINE LSTFORMATS