Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-01 - decus/20-0003/pascmp.pas
There are 4 other files named pascmp.pas in the archive. Click here to see a list.
  %$L-,C-,D-,T-,V:001200000214B\
program pascmp;
 include 'pasprm.pas';   (* set up tops10 and tops20 *)
  %*********************************************************
   *							   *
   *							   *
   *	 STEP-WISE DEVELOPMENT OF A PASCAL COMPILER	   *
   *	 ******************************************	   *
   *							   *
   *							   *
   *	 STEP 5:   SYNTAX ANALYSIS INCLUDING ERROR	   *
   *		   HANDLING; CHECKS BASED ON DECLARA-	   *
   *	 15/3/73   TIONS; ADDRESS AND CODE GENERATION	   *
   *		   FOR A HYPOTHETICAL STACK COMPUTER	   *
   *							   *
   *							   *
   *	 AUTHOR:   URS AMMANN				   *
   *		   FACHGRUPPE COMPUTERWISSENSCHAFTEN	   *
   *		   EIDG. TECHNISCHE HOCHSCHULE		   *
   *	   CH-8006 ZUERICH				   *
   *							   *
   *	 CODE GENERATION FOR DECSYSTEM 10 BY		   *
   *	 C.-O. GROSSE-LINDEMANN, F.-W. LORENZ,		   *
   *	 H.-H. NAGEL, P.J. STIRL			   *
   *							   *
   *	 MODIFICATIONS TO GENERATE RELOCATABLE OBJECT CODE *
   *	 BY E. KISICKI (DEC 74) 			   *
   *							   *
   *	 DEBUG SYSTEM BY P. PUTFARKEN (DEC 74)		   *
   *							   *
   *	 INSTITUT FUER INFORMATIK, D-2 HAMBURG 13,	   *
   *	 SCHLUETERSTRASSE 70 / GERMANY			   *
   *							   *
   *							   *
   *********************************************************\



  %	  HOW  TO  GENERATE  A	NEW  PASCAL  COMPILER

   SOURCES:
   A) ASCII:	  PASREL.PAS
		  RUNTIM.MAC
		  DEBSUP.MAC
		  DEBUG .PAS
   B) BINARY:	  PASREL.SHR
		  PASREL.LOW
		  PASLIB.REL (CHECK INITPROCEDURE "SEARCH LIBRARIES")

   !              IF THE NEW COMPILER SHOULD NOT BE MADE AVAILABLE FOR GENERAL USE ON SYS,
   !		  ENTER THE APPROPIATE DIRECTORY SPECIFICATIONS IN INITPROCEDURE "SEARCH LIBRARIES"


  STEP			  ACTION

  0	  SAVE ALL SOURCE FILES ON DECTAPES!!
  1	  .COPY PASLBN.REL=PASLIB.REL
  2	  IF THERE ARE NO CHANGES TO RUNTIM.MAC, DEBSUP.MAC, OR DEBUG.PAS
	  THEN GOTO STEP 9
  3	  UPDATE RUNTIM.MAC
  4	  ASSEMBLE   "		  -->	  RUNTIM.REL
  5	  UPDATE DEBSUP.MAC
  6	  ASSEMBLE   "		  -->	  DEBSUP.REL
  7	  UPDATE DEBUG.PAS
	  .RUN PASREL
	  *DEBUG.PAS		  -->	  DEBUG.REL
  8	  .R FUDGE2
	  *PASLBN.REL=PASLBN.REL<RUNSP>,RUNTIM.REL<RUNSP>(R)$
	  *PASLBN.REL=PASLBN.REL<DEBSP>,DEBSUP.REL<DEBSP>(R)$
	  *PASLBN.REL=PASLBN.REL<DEBUG>,DEBUG.REL<DEBUG>(R)$
	  *^C
				  -->	  PASLBN.REL
  9	  UPDATE PASREL.PAS
	  UPDATE "HEADER" IN PASREL.PAS
	  IF THERE ARE NEW ENTRIES TO RUNSP OR DEBSP
	  CHECK
	  INITPROCEDURE "RUNTIME-, DEBUG-SUPPORTS", "SUPPORTS"
	    AND
	  PROCEDURE "SUPPORT"
  10		.RUN PASREL
	      	*PASREL.PAS	      -->     PASREL.REL
  11      	.LOAD PASREL,/SEARCH PASLBN.REL
      		.SSAVE PASREL 36      -->     PASREL.SHR
      					      PASREL.LOW

			      36 K CORE ONLY IF NO RUNTIMECHECK (C-) AND NO DEBUG OPTION (D-) , OTHERWISE MORE !

  12      	.RENAME PAS1.PAS=PASREL.PAS
  13      	.RUN PASREL
      		*PAS1.PAS 	      -->     PAS1.REL
  14      	.LOAD PAS1,/SEARCH PASLBN.REL
      		.SSAVE PAS1 36	      -->     PAS1.SHR
      					      PAS1.LOW
  14.1    	.RENAME PAS2.PAS=PAS1.PAS
  14.2    	.RUN PAS1
      		*PAS2.PAS 	      -->      PAS2.REL
  14.3    	.LOAD PAS2,/SEARCH PASLBN.REL
      		.SSAVE PAS2 36	      -->      PAS2.SHR
      				      -->      PAS2.LOW
  15      	.R FILCOM
      		*TTY:=PAS2.LOW,PAS1.LOW
      		NO DIFFERENCES ENCOUNTERED
      		*TTY:=PAS2.SHR,PAS1.SHR
      		FILE 1) DSK:PAS2.SHR  CREATED: XXX
      		FILE 2) DSK:PAS1.SHR  CREATED: XXX
      		400005  604163 XXXXXX   604163 XXXXXX	     XXXXXX
      		%FILES ARE DIFFERENT

  16      	.DELETE PASREL.*,PAS1.*,PAS2.REL,PASLIB.REL
       		.PRINT PAS2.LST
       		.RENAME PASREL.*=PAS2.*
		.RENAME PASLIB.REL=PASLBN.REL


  *******************************************************************\

       %HINTS FOR INTERPRETING ABBREVIATED IDENTIFIERS
       BRACK  : BRACKET "[ ]"	       IX  : INDEX
       C  : CURRENT		       L  : LOCAL
       C  : COUNTER		       L  : LEFT
       CST  : CONSTANT		       PARENT  : "( )"
       CTP  : IDENTIFIER POINTER       P/PTR  : POINTER
       EL  : ELEMENT		       P/PROC  : PROCEDURE
       F  : FORMAL		       R  : RIGHT
       F  : FIRST		       S  : STRING
       F  : FILE		       SY  : SYMBOL
       F/FUNC  : FUNCTION	       V  : VARIABLE
       G  : GLOBAL		       V  : VALUE
       ID  : IDENTIFIER
       REL  : RELATIVE		       REL  : RELOCATION\

(*LOCAL CHANGE HISTORY
	1	CLEAN UP COMMENT SCANNING AND ALLOW /* */ BRACKETS.
		NOTE THAT THIS \ WOULD HAVE TERMINATED THIS COMMENT
		PRIOR TO FIX.
	2	INCREASE STACKANDHEAP, GET CORE IF NEEDED ON PROGRAM
		ENTRY, FIX PARAMETER PASSING BUG, LOAD PASREL FROM
		SYS: INSTEAD OF DSK:, GENERATE FLOAT AND FIX INLINE.
		(FROM HEDRICK)
	NB:	RUNTIM has now been modified to pass all characters,
		including control characters as well as lower case.
		It no longer turns tabs into spaces.  Thus it was
		necessary to put this file through a program that
		expanded tabs into spaces when they were in strings.
		Thus FILCOM with the old version should specify /S
		or lots of irrelevant differences will be found.
	3	MAP LOWER CASE TO UPPER EXCEPT IN STRINGS.  (DOESN'T
		SOLVE THE PROBLEM ABOUT SETS, THOUGH.)  HEDRICK.
	4	use SCAN for file spec's, and fix to be called by
		COMPIL.  Hedrick.
	5	add /CREF switch.  Hedrick.
	6	allow PROGRAM statement.  Syntax check but ignore it.
		fix bug that caused lower case char. after a string to put compiler in loop
		allow <> for #
		allow LABEL declaration.  Syntax check bug ignore it.
		with /CREF/OBJ put only 3 instructions per line (4
		  overflow a LPT line)
		use standard PACK and UNPACK
		catch illegal characters
	7	add /HEAP switch for size of stack and heap
		treat lower case as upper in sets
	10	Add STRSET and STRWRITE - equivalent to RESET and
		REWRITE, but sets I/O into string
		also GETINDEX, CLOSE, ROUND, CALLI
		ALSO REDID RESET/REWRITE TO TAKE GOOD FILE NAMES
	11	Modify compiler to use new RESET/REWRITE.
	12	Make PASCAL programs self-expanding
	13	ADD DDT SYMBOL NAMES FOR ROUTINES(BLOCK-STRUCTURED)
		use PROGRAM name as module and entry name
		allow strset/write on non-TEXT files
		add opt. 4th arg to strset/write: limit
	14	allow read of string - gets rest of line
				add rename,dismiss,update,dumpin/out,useti/o, and xblock arg to
		reset and friends
	15	a few more arg's to some runtimes
	16	detect unexpected EOF
	17	DECUS VERSION - CHANGE DDT SYMBOLS TO BE OK FOR DEC DDT
	20	CMU patch: do packed struct. correctly. Did not adopt:
		(1) replace CAMG, etc., for text (their fix did unnecessary work for
		  the most common cases, and didn't get all of the obscure ones)
		(2) use Knuth's defn of MOD (the one here is so much faster, who care about
		  negative numbers?)
		(3) clean up variants in NEW (they say it is unnecessary)
		Also: fix ill mem ref if undef var first after READ
	21	allow PROGRAM <name>; (i.e. no file list)
		allow null field list in record (for null variant, mainly)
		fix MOD.  Much cleaner fix than CMUs.  Usually adds just one instruction
		fix compare of PACKED ARRAY OF CHAR.  Get it all (I hope)
		keep new from storing tag if no id (CMU's fix)
		implement +,*,- as set operators
	22	restore MOD to be REM (Cyber does it that way)
		fix all my added file things to use GETFN to scan
		  file name, so we properly handle external files, etc.
		fix callnonstandard to pass external files
		fix writewriteln so doesn't ill mem ref on undef file
	23	change enterbody to always zero locals.  Needed to ensure
		  that certain comparisons work, but a good thing anyway.
		if typechecking is on, check for following nil or 0 pointer
	24	do not allow comparisons except those in manual.
		 means we don't have to zero locals on proc entry, ever.
		add LOC(<proc>) that returns address of proc or ftn
		add S:<integer> and H:<integer> comments, to set starting
		  addr of stack and heap respectively
		change starting code to not disturb %rndev, etc. on restart
	25	add /ZERO (and $z) to control whether locals initialized
		  to zero.  Useful mostly to help find uninit.'ed pointers.
	26	allow record as extended lookup block
		add error message's for ext. lookup block
		don't check file pointers as if they were pointers!
		use getfn instead of getfilename in break,breakin,
		  and close, to allow non-ascii files
	27	add NEWZ that does what NEW used to (zeros what it gets)
	30	fix NEW with : syntax, per Nagel.
	31	FIX ILL MEM REF IN READREADLN
		ADD ERR MSG FOR ASSIGN TO FTN NAME OUTSIDE BODY
	32	add APPEND
	33	full implementation of PROGRAM statement
		version numbering of output files and program
		allow proc and func as parameters
		remove LOC (subsumed by above)
		add $V directive for version number
	34	allow list of entry points in PROGRAM statement
	35	fix error recovery in BLOCK, especially for /NOMAIN
	36	ALLOW DEBUGGING MULTIPLE FILES
		remove T- option
		NB: I have not removed the variables for T-, and also
		  supports exist for indeb. and exdeb., though they
		  are no longer used in PASCMP.
	37	fix bug in static link for level one proc's
	40	use RESDEV as external name for DISMISS
		by default put request for PASLIB before FORLIB
		improve format of /OBJECT listing
		fix arg's to predefined functions
		fix comparison of unpacked strings
	41	make it restartable
		change kludge for file OUTPUT
	42	allow variable records for GET,PUT,and DUMPx
		Currently DUMPx implemented in kludgey way.
	43	add 5 locations to file block for new runtimes
		add PUTX
		add optional arg to useti
		allow 12 digit octal number
	44	Add SETPOS and CURPOS to compiler
	45	Add NEXTBLOCK to compiler and make check for
		AC overlap with APPEND,UPDATE
	46	Repair CALLI to use 1 for true, and accept all
		 possible argument formats.
	47	Add some more functions
		Repair calculations for NEW with packed arrays
	50	Generate correct code for 400000,,0
		Reinitialize file ctl blocks at start
		Don't open INPUT or OUTPUT unless asked
	51	Allow mismatch of byte size for SETSTRING
		Fix GETLINENR
	52	Fixes from CMU:
		To CALLNONSTANDARD: when depositing directly into
		  display, moved 2 ac's for all arg's of size 2,
		  without checking to see if VAR.  Assumed AC was
		  unchanged by BLT.
		To SIMPLEEXPRESSION: optimization sometimes negated
		  a real constant.  If had been declared by CONST,
		  future ref's were to the negated quantity!
	53	Problems with dynamic memory expansion:
		Arbitrarily asked for 40b more locations above
		  end of stack (for runtimes).  But some odd
		  procedure calls use more.  Need to figure out
		  how much memory is used.
		CORERR just allocated memory up to (P).  Should
		  be 40(P), or however much is really needed.
		So add STKOFFMAX, to keep track of how much
		  really needed.  CORALLOC is addr of the test for
		  sufficient memory, fixed up.
	54	More dynamic memory: Need to accumulate offsets
		  above top of stack, in case of
		  x(1,2,3,4,5,f(1,2,3,4,5,6)), etc., though an
		  actual problem seems a bit unlikely.
	55	Add require source file feature
	56	Clean up syntax for require file
	57	add tops20 version
	60	make tops20 strings work more like tops10
	61	add jsys pseudo-runtime
		add tops20 runtimes and restrict runtimes that work only on one system
		add +*@ after file name to control gtfjn in tops20
	62	make sure there is never data above the stack pointer
	63	convert time, runtime, setuwp for tops20
	64	input:/ for tops-20
		empty entry in record
		non-local goto's
		fix procedure param's if not in ac's
	65	allow extra semicolon in case
		remove references to exit labels
	66	speed up non-local goto's
	67	fix external proc's as proc param's
	70	fix ill mem ref if certain errors in type decl
	71	make file name in fcb be 7 bit for tops20
	72	make two fixup chains for 2 word constants, to
		prevent giving LINK an ill mem ref
	73	make new use getfn for file names, to get EXTERN files
	74	allow new init. so tops10 version can work with emulator
	75	fix non-loc goto's - typo made goto chain bad
	76	allow a set in reset/rewrite to specify bits.
		allow break char set in read/readln
	77	fix jsys and reset set arguments
	100	fix ac usage in readreadln from strings
        101	fix fltr and fix code generation
	102	Add klcpu - put improved packed array code under it
	103	Fix pointer to global symbol table in case that level
		has already been output by some inner procedure
	104	Check stack overflow
		Check to be sure structures aren't too big
		Range check subranges in for loop and value parameters
	105	Use tables instead of -40B to convert from lower case
	106	Make subranges of reals illegal
	107	Abort creation of .REL file on all errors
	110	Allow [x..y] set construct
	111	Allow STRING and POINTER parameters to EXTERN proc's
	112	Clrbfi when error detected.  Bounds check sets [a..b]
	113	Make real number reader handle exact things exactly
		Don't demand foward type ref's resolved at end of require file
	114	Write local fixups even if only non-loc gotos
		Make CREF not say .FIELDID. for local gotos
		maxint = 377777777777B
	115	Make tops10=false, kl=false work (tenex)
	116	IDRECSIZE entries for param, labelt type
		Make NEXT NIL instead of 0 when not used, for COPYCTP
	117	Fix enumerated type in record
	120	Make initialization routine use JSP, for T20/Tenex so
		don't have ill mem ref if emulator present
	121	Initialize CODEARRAY: fix bollixed INITPROC's
	122	KA's.  This includes fixing COPYSTP so it doesn't
		 try to follow NIL pointers.  Harmless if 377777 is a
		 legal address, but it isn't for KA's.
	123	Do POPF when can't find included file, so close gets done.
	124	Limit initprocedures to top level.
		Initialize CREF off
	125	Do POPF when expected eof inside included file.
	126	Detect procedures not beginning with BEGIN
	127	INit CREF to FALSE, fix [const..var] set construct
	130	Fix KA bug wherein random word in core image is garbage
	131	Move cixmax to pasprm.pas so tops20 can use big value
	132	Replace KA10 with KACPU for op codes and NOVM for old
		memory allocation.
	133	Fix JSYS to allow functions within it.  Garbaged stack.
	134	Allow DELETE in Tops-10, too.
	135	Fix LOG2 for big numbers.  Prevent ill mem ref's in
		PACK and UNPACK with syntax errors.
	136	Add header line at top of each page with pg. number
	137	Reset line no. to 1 at start of page.
		Fix bug in set constructors for CHAR
	140	Chnage order of SETMAP to closer to ASCII collating seq.
	141	Fix problem where REGC gets messed up by array subscript
		 calculations when ONFIXEDREGC is in effect.
		Detect overflow in number scanning with JFCL.
	142	Make real number scanner scan anything legitimate
	143	Redo I/O to string in Tops-10 for new runtimes and fix
		 onfixedregc code for packed arrays
	144	Allow :/ in program and :@ in reset for Tops-10
	145	Change external name of GET to GET. for Wharton
	146	Reinit count in putrelcode to avoid garbage in .REL file
	147	Lines start with 2 on new pages.
	150	Fix bug in forward type references,
		error recovery in fieldlist if garbage case type
		symbol table in forward proc's for debugger
	151	Fix reversed args in I,J:INTEGER in procedure decl.
	152	Add DISPOSE
	153	Fix some reg usage problems with DISPOSE
	154	More reg usage problems with DISPOSE
	155	Source file name in DEBUG block
	156	Detect FTNNAME^.field := value.  Only bare ftn name
		allowed on LHS of assignment.
	157	Add $A- to turn off arith check
	160	Add compiler switch /ARITHCHECK
	161	fix STRINg and POINTER
	162	fix REGSIZE
	163	fix TIME for Tops-20
	164	use Polish fixups in CASE
	165	in type decl, make sure ^THING gets local defn of THING,
		even if it happens later and there is a higher level defn.
		(This requires treating ^THING as forward always.)
	166	make assignment to func id from inner func work
		initialize frecvar in fieldlist, to prevent ill mem ref
		  with null record decl.
	167	improvements to edit 165
	170	more improvements to 165 (this time to error handling)
	171	allow read into packed objects
		allow read and write of binary files
		make sure default file names don't use user-declared INPUT,
		   and OUTPUT
		fix NEW of pointer that is part of packed array
	172	option string as third arg of RESET, etc.
		evaluate upper bound of FOR statement only once
	173	allow files in any context; internal files
	174	fix to initprocedures from Hisgen
	175	make getfn take a param telling runtime validity check
		needed.  SETSTRING, etc., do not
	176	better unterminated-comment error messages
	177	fix AC allocation in GETFILENAME
	200	fix addressing problem in loading file pointers
	201	make most manipulation of zero size objects be no-op.
		Previously one might stomp on the next variable.
	202	insufficient initialization before RESET(TTY), etc.
		fix POINTER passed by ref
	203	fix glitch in edit 202
	204	don't validity check the FCB for CLOSE, RCLOSE, and DISMISS
	205	fix AC in RENAME
	206	allow constants in WRITE statements for FILE OF INTEGER, etc.
	207	fix AC in GETFILENAME (again...)
	210	Allow 9 digit HEX numbers
	211	Fix output of string constants in .REL file
	212	Better error message if INPUT or OUTPUT redefined
	213	Fix procedure exit code if there is local variable
	214	Make debugger see locals of forward declared proc's
*)

    CONST
      HEADER = 'PASCAL %12(214)';

      DISPLIMIT = 20; MAXLEVEL = 8;
      STRGLGTH = 120; BITMAX = 36;
(* 43 - longer file block for new runtimes *)
      SIZEOFFILEBLOCK=43B ;  {plus size of component}
      OFFSET=40B;	%FUER SETVERARBEITUNG DER ASCIICHARACTER\
      CHCNTMAX = 132;	%MAXIMUM OF CHARACTERS IN ONE LINE\
      LEFT = 2;RIGHT = 1;BOTH = 3;NO = 0;

      %KONSTANTEN VON BODY: \
      %*********************\

(* move cixmax to param file *)
      HWCSTMAX = 377777B;		  LABMAX = 20;
(* 2 - increase default stack space *)
(* 7 - stackandheap now set by switch *)
(* 137 - fix set constructor for CHAR *)
      MAXERR = 4;		  BASEMAX = 71;		CHARMAX = 177B;

      %ADDRESSES:
       **********\

      HAC=0;		%HILFSREGISTER\
      TAC=1;		%HILFSREGISTER AUCH FUER BYTEPOINTER\
      REGIN=1;		%INITIALISE REGC\
      PARREGCMAX=6;	%HIGHEST REGISTER USED FOR PARAMETERS\
      WITHIN=12;	%FIRST REGISTER FOR WITHSTACK\
      NEWREG=13;	%LAST PLACE OF NEW-STACK\
      BASIS=14; 	%BASIS ADDRESS STACK\
      TOPP=15;		%FIRST FREE PLACE IN DATASTACK\
      PROGRST = 145B;	%LOC 140B..144B RESERVED FOR DEBUG-PROGR.\
      HIGHSTART=400000B;
      MAXADDR=777777B;





    TYPE
      %DESCRIBING:\
      %***********\


      %BASIC SYMBOLS\
      %*************\

      SYMBOL = (IDENT,INTCONST,REALCONST,STRINGCONST,NOTSY,MULOP,ADDOP,RELOP,
		LPARENT,RPARENT,LBRACK,RBRACK,COMMA,SEMICOLON,PERIOD,ARROW,
		COLON,BECOMES,LABELSY,CONSTSY,TYPESY,VARSY,VALUESY,FUNCTIONSY,
(* 6 - add PROGRAM statement *)
(* 56 - ADD INCLUDE *)
		PROCEDURESY,SETSY,PACKEDSY,ARRAYSY,RECORDSY,FILESY,FORWARDSY,PROGRAMSY,INCLUDESY,
		BEGINSY,IFSY,CASESY,REPEATSY,WHILESY,FORSY,WITHSY,LOOPSY,
		GOTOSY,EXITSY,ENDSY,ELSESY,UNTILSY,OFSY,DOSY,TOSY,DOWNTOSY,
		EXTERNSY,PASCALSY,FORTRANSY,ALGOLSY,COBOLSY,
		THENSY,OTHERSY,INITPROCSY,OTHERSSY);

      OPERATOR = (MUL,RDIV,ANDOP,IDIV,IMOD,PLUS,MINUS,OROP,LTOP,LEOP,GEOP,GTOP,
		  NEOP,EQOP,INOP,NOOP);

      SETOFSYS = SET OF SYMBOL;

(* 23 - check for bad pointer *)
(* 24 - ONLY CLEAR NEW WHEN TYPECHECKING *)
(* 104 - new tops10 stackoverflow *)
(* 152 - DISPOSE *)
      SUPPORTS = (FIRSTSUPPORT,STACKOVERFLOW,DEBSTACK,BADPOINT,ALLOCATE,CLEARALLOC,DEALLOCATE,
(* 173 - internal files *)
		  WITHFILEDEALLOCATE,
(* 43 - add PUTX *)
(* 64 - non-loc goto *)
		  EXITGOTO,EXITPROGRAM,GETLINE,GETFILE,PUTLINE,PUTFILE,PUTXFILE,
(* 57 - Add strset and strwrite external routines *)
		  RESETFILE,REWRITEFILE,RESETSTRING,REWRITESTRING,GETCHARACTER,PUTPAGE,ERRORINASSIGNMENT,
(* 173 - internal files *)
		  FILEUNINITIALIZED,INITFILEBLOCK,
		  WRITEPACKEDSTRING,WRITESTRING,WRITEBOOLEAN,READCHARACTER,READINTEGER,READREAL,
(* 171 - RECORD READ/WRITE *)
(* 206 - extend for constants *)
		  READRECORD,WRITERECORD,WRITESCALAR,
		  BREAKOUTPUT,OPENTTY,INITIALIZEDEBUG,ENTERDEBUG,INDEXERROR,WRITEOCTAL,WRITEINTEGER,WRITEREAL,
(* 10 add CLOSE *)
		  WRITEHEXADECIMAL,WRITECHARACTER,CONVERTINTEGERTOREAL,
(* 14 and lots more *)
(* 33 - PROGRAM statement *)
		  CONVERTREALTOINTEGER,CLOSEFILE,READSTRING,READPACKEDSTRING,READFILENAME,
		  NAMEFILE,DISFILE,UPFILE,APFILE,READDUMP,WRITEDUMP,SETIN,SETOUT,BREAKINPUT,
(* 74 - tops20 routines *)
		  SETPOSF,CURPOSF,NEXTBLOCKF,SPACELEFTF,GETXF,DELFILE,RELFILE,INITMEM,INITFILES,
(* 163 - tops20 TIME function *)
		  GETDAYTIME,LASTSUPPORT);

      %CONSTANTS\
      %*********\

      CSTCLASS = (INT,REEL,PSET,STRD,STRG);
      CSP = ^ CONSTNT;
(* 55 - add require files *)
      STRGARR = PACKED ARRAY[1..STRGLGTH] OF CHAR;
      CONSTNT = RECORD
		  SELFCSP: CSP; NOCODE: BOOLEAN;
		  CASE CCLASS: CSTCLASS OF
		       INT : (INTVAL: INTEGER; INTVAL1:INTEGER %TO ACCESS SECOND WORD OF PVAL\ );
		       REEL: (RVAL: REAL);
		       PSET: (PVAL: SET OF 0..71);
		       STRD,
		       STRG: (SLGTH: 0..STRGLGTH;
			      SVAL: PACKED ARRAY [1..STRGLGTH] OF CHAR)
		END;

      VALU = RECORD
	       CASE BOOLEAN OF
		    TRUE:   (IVAL: INTEGER);
		    FALSE:  (VALP: CSP)
	     END;

      %DATA STRUCTURES\
      %***************\

      LEVRANGE = 0..MAXLEVEL; ADDRRANGE = 0..MAXADDR; INSTRANGE = 0..677B ;
      RADIXRANGE = 0..37777777777B; FLAGRANGE = 0..17B;
      BITRANGE = 0..BITMAX; ACRANGE = 0..15; IBRANGE = 0..1; CODERANGE = 0..CIXMAX ;
(* 173 - internal files *)
      BITS5 = 0..37B; BITS6 = 0..77B;  BITS7 = 0..177B;
      STRUCTFORM = (SCALAR,SUBRANGE,POINTER,POWER,ARRAYS,RECORDS,FILES,TAGFWITHID,TAGFWITHOUTID,VARIANT);
      DECLKIND = (STANDARD,DECLARED);
      STP = ^ STRUCTURE; CTP = ^ IDENTIFIER; BTP = ^BYTEPOINT;
      FTP = ^FILBLCK;
      GTP = ^GLOBPTR ;

      STRUCTURE = PACKED RECORD
			   SELFSTP: STP; SIZE: ADDRRANGE;
			   NOCODE: BOOLEAN; BITSIZE: BITRANGE;
(* 173 - internal files *)
			   HASFILE: BOOLEAN;
			   CASE FORM: STRUCTFORM OF
				SCALAR:   (CASE SCALKIND: DECLKIND OF
						DECLARED: (DB0: BITS5; FCONST: CTP));
				SUBRANGE: (DB1: BITS6; RANGETYPE: STP; MIN,MAX: VALU);
				POINTER:  (DB2: BITS6; ELTYPE: STP);
				POWER:	  (DB3: BITS6; ELSET: STP);
				ARRAYS:   (ARRAYPF: BOOLEAN; DB4: BITS5; ARRAYBPADDR: ADDRRANGE;
					   AELTYPE,INXTYPE: STP);
				RECORDS:  (RECORDPF: BOOLEAN; DB5: BITS5;
					   FSTFLD: CTP; RECVAR: STP);
				FILES:	  (DB6: BITS5; FILEPF: BOOLEAN;FILTYPE: STP);
				TAGFWITHID,
				TAGFWITHOUTID: (DB7: BITS6; FSTVAR: STP;
						CASE BOOLEAN OF
						TRUE : (TAGFIELDP: CTP);
						FALSE  : (TAGFIELDTYPE: STP));
				VARIANT:  (DB9: BITS6; NXTVAR,SUBVAR: STP; FIRSTFIELD: CTP; VARVAL: VALU; QXLYPRTWRR: BOOLEAN)
			 END;

      BPOINTER = PACKED RECORD
			  SBITS,PBITS: BITRANGE;
			  IBIT,DUMMYBIT: IBRANGE;
			  IREG: ACRANGE;
			  RELADDR: ADDRRANGE
			END;

      BPKIND = (RECORDD,ARRAYY);

      BYTEPOINT = PACKED RECORD
			   BYTE: BPOINTER;
			   LAST   :BTP;
			   CASE BKIND:BPKIND OF
				RECORDD: (FIELDCP: CTP);
				ARRAYY : (ARRAYSP: STP)
			 END;
      GLOBPTR = RECORD
		  NEXTGLOBPTR: GTP ;
		  FIRSTGLOB,
		  LASTGLOB   : ADDRRANGE ;
		  FCIX	     : CODERANGE
		END ;

      FILBLCK = PACKED RECORD
			 NEXTFTP : FTP ;
			 FILEIDENT : CTP
		       END ;

      %NAMES\
      %*****\

(* 64 - non-loc goto *)
(* 111 - STRING, POINTER *)
	(* PARAMS is a special kind of TYPES.  It is used only for
	   predeclared identifiers describing kludgey types that are
	   valid only in procedure parameter lists. *)
      IDCLASS = (TYPES,KONST,VARS,FIELD,PROC,FUNC,LABELT,PARAMS);
      SETOFIDS = SET OF IDCLASS;
      IDKIND = (ACTUAL,FORMAL);
      PACKKIND = (NOTPACK,PACKK,HWORDR,HWORDL);
      CHARWORD = PACKED ARRAY [1..5] OF CHAR;
      %ALFA = PACKED ARRAY [1..ALFALENG] OF CHAR;\

      IDENTIFIER = PACKED RECORD
			    NAME: ALFA;
			    LLINK, RLINK: CTP;
			    IDTYPE: STP; NEXT: CTP;
			    SELFCTP: CTP; NOCODE: BOOLEAN;
			    CASE KLASS: IDCLASS OF
				 KONST: (VALUES: VALU);
				 VARS:	(VKIND: IDKIND; VLEV: LEVRANGE;
					 CHANNEL: ACRANGE; VDUMMY: 0..31; VADDR: ADDRRANGE);
				 FIELD: (PACKF: PACKKIND; FDUMMY: 0..7777B;
					 FLDADDR: ADDRRANGE);
				 %IF PACKF=PACKK THEN FLDADDR CONTAINS THE
				  ABSOLUTE ADDRESS OF THE CORRESPONDING BYTEPOINTER
				  -----> ENTERBODY\
				 PROC,
				 FUNC:	(PFCHAIN: CTP; CASE PFDECKIND: DECLKIND OF
							    STANDARD: (KEY: 1..44);
							    DECLARED: (PFLEV: LEVRANGE; PFADDR: ADDRRANGE;
								       CASE PFKIND: IDKIND OF
									    ACTUAL: (FORWDECL: BOOLEAN; TESTFWDPTR: CTP;
										     EXTERNDECL: BOOLEAN; LANGUAGE: SYMBOL;
										     EXTERNALNAME: ALFA;
										     LINKCHAIN: PACKED ARRAY[LEVRANGE] OF ADDRRANGE;
(* 62 - clean of stack offsets *)
										     POFFSET:ADDRRANGE)));
(* 66 - non-local goto's *)
			         LABELT: (SCOPE:LEVRANGE;NONLOCGOTO:BOOLEAN;
					  GOTOCHAIN:ADDRRANGE;LABELADDRESS:ADDRRANGE)
			  END;


      DISPRANGE = 0..DISPLIMIT;
      WHERE = (BLCK,CREC);
(* 61 - new type to separate tops10 and tops20 ftns *)
      machine = (okname,t10name,t20name);

      %RELOCATION\
      %**********\

      RELBYTE = 0..3B %(NO,RIGHT,LEFT,BOTH)\;

      RELWORD = PACKED ARRAY[0..17] OF RELBYTE;

      %EXPRESSIONS\
      %***********\

      ATTRKIND = (CST,VARBL,EXPR);

      ATTR = RECORD
	       TYPTR: STP;
	       CASE KIND: ATTRKIND OF
		    CST:   (CVAL: VALU);
		    VARBL: (PACKFG: PACKKIND; INDEXR: ACRANGE; INDBIT: IBRANGE;
			    VLEVEL: LEVRANGE; BPADDR,DPLMT: ADDRRANGE; VRELBYTE: RELBYTE; SUBKIND: STP);
		    EXPR:  (REG:ACRANGE)
	     END;

      TESTP = ^ TESTPOINTER;
      TESTPOINTER = PACKED RECORD
			     ELT1,ELT2: STP;
			     LASTTESTP: TESTP
			   END;

(* 65 - remove exit labels *)

      %TYPES FROM BODY \
      %****************\

(* 13 - ADD WRITEBLOCK FOR DDT SYMBOLS *)
      WRITEFORM = (WRITEENTRY,WRITENAME,WRITEHISEG,WRITEGLOBALS,WRITECODE,WRITEINTERNALS,
(* 164 - add Polish fixups *)
		   WRITEPOLISH,WRITELIBRARY,
(* 173 - remove writefileblock *)
		   WRITESYMBOLS,WRITEBLK,WRITESTART,WRITEEND);

      UPDATEFORM = (C,D);
      ETP = ^ ERRORUPDATE;
      ERRORUPDATE = PACKED RECORD
			     NUMBER: INTEGER;
			     NEXT: ETP;
			     CASE FORM: UPDATEFORM OF
				  C:  (STRING: ALFA);
				  D: (INTVAL: INTEGER)
			   END;

      KSP = ^ KONSTREC;
      KONSTREC = PACKED RECORD
(* 72 - two fixup chains for 2 word consts *)
			  ADDR, ADDR1, KADDR: ADDRRANGE;
			  CONSTPTR: CSP;
			  NEXTKONST: KSP
			END;
(* 164 - Polish fixups for CASE *)
      POLPT = ^ POLREC;
{This record indicates a Polish fixup to be done at address WHERE in
 the code.  The RH of WHERE is to get the BASE (assumed relocatable),
 adjusted by OFFSET (a constant).  This is needed because the loader
 assumes that any address < 400000B is in the lowseg.  So to get the
 virtual start of the CASE statement branch table we need to use
 this to adjust the physical start of the table by the first case
 index}
      POLREC = PACKED RECORD
			  WHERE: ADDRRANGE;
			  BASE:  ADDRRANGE;
			  OFFSET: INTEGER;
			  NEXTPOL: POLPT
			END;

      PDP10INSTR = PACKED RECORD
			    INSTR   : INSTRANGE ;
			    AC	    : ACRANGE;
			    INDBIT  : IBRANGE;
			    INXREG  : ACRANGE;
			    ADDRESS : ADDRRANGE
			  END ;

      HALFS = PACKED RECORD
		       LEFTHALF: ADDRRANGE;
		       RIGHTHALF: ADDRRANGE
		     END;

      PAGEELEM = PACKED RECORD
			  WORD1: PDP10INSTR;
			  LHALF: ADDRRANGE; RHALF: ADDRRANGE
			END;
      DEBENTRY = RECORD
(* 36 - ALLOW MULTIPLE MODULES *)
		   NEXTDEB: INTEGER;  %WILL BE PTR TO NEXT ENTRY\
		   LASTPAGEELEM: PAGEELEM;
(* 103 - fix global id tree *)
		   GLOBALIDTREE: CTP;
		   STANDARDIDTREE: CTP;
		   INTPOINT:  STP;
		   REALPOINT: STP;
		   CHARPOINT: STP;
		   MODNAME: ALFA;
(* 155 - add source information *)
		   SOURCE: PACKED ARRAY[1..167]OF CHAR;
		 END;

(* 4 - add data structure for SCAN to return *)
(* 11 - modify structure and add type for the REL file *)
INTFILE = FILE OF INTEGER;
RPGDATA = RECORD
(* 7 - add /HEAP switch *)
	RELNAME:ALFA;
(* 24 - allow user to set first loc of stack and heap *)
	STACKVAL:INTEGER;
	HEAPVAL:INTEGER;
(* 33 - version no. *)
	VERVAL:INTEGER;
(* 25 - add /ZERO *)
(* 160 - add /ARITHCHECK *)
	ASW,ZSW,LSW,TSW,MSW,CSW,DSW,CRSW,RPGSW:BOOLEAN
	END;
RPGPT = ^ RPGDATA;
(* 33 - PROGRAM statement *)
(* 61 - allow +* in tops20 *)
PROGFILE = PACKED RECORD
	FILID:ALFA;
	NEXT:^PROGFILE;
(* 64 - INPUT:/ *)
	wild,newgen,oldfile,interact,seeeol:Boolean
	END;
(* 157 - See if we need INITTTY *)
PROGFILEPT = ^ PROGFILE;

      %------------------------------------------------------------------------------\


    VAR
      %RETURNED BY SOURCE PROGRAM SCANNER INSYMBOL:\
      %********************************************\

      SY: SYMBOL;		      %LAST SYMBOL\
      OP: OPERATOR;		      %CLASSIFICATION OF LAST SYMBOL\
      VAL: VALU;		      %VALUE OF LAST CONSTANT\
      LGTH: INTEGER;		      %LENGTH OF LAST STRING CONSTANT\
      ID: ALFA; 		      %LAST IDENTIFIER (POSSIBLY TRUNCATED)\
      CH: CHAR; 		      %LAST CHARACTER\


      %COUNTERS:\
      %*********\

      RTIME,
      I: INTEGER;
      SUPPORTIX: SUPPORTS;
      LANGUAGEIX: SYMBOL;
      CHCNT: 0..132;		      %CHARACTER COUNTER\
      CODEEND,			      %FIRST LOCATION NOT USED FOR INSTRUCTIONS\
      LCMAIN,
(* 5 - some new variables for CREF *)
      LC,IC,BEGLC,BEGIC: ADDRRANGE; 	      %DATA LOCATION AND INSTRUCTION COUNTER\
(* 176 - new vars for unterminated comment *)
      comment_page, comment_line: integer;

      %SWITCHES:\
      %*********\

(* 25 - ADD /ZERO *)
      ZERO,				%ON TO INITIALIZE LOCAL VAR'S\
(* 4 - variable for COMPIL linkage *)
      RPGENTRY,				%ON IF CALLED CALLED BY COMPIL\
(* 5 - new variables for CREF *)
      CREF,				%ON IF CREF LISTING BEING MADE\
      DP,BEGDP,			      %DECLARATION PART\
      RESETFLAG,		      %TO IGNORE SWITCHES WHICH MUST NOT BE RESET\
      PRTERR,			      %TO ALLOW FORWARD REFERENCES IN POINTER TYPE
				       DECLARATION BY SUPPRESSING ERROR MESSAGE\
      MAIN,			      %IF FALSE COMPILER PRODUCES EXTERNAL PROCEDURE OR FUNCTION\
      doinitTTY,		      %TTYOPEN needed\
      TTYINUSE, 		      %no longer used ?\
      TTYSEEEOL,		      %TTY:# in program state\
      DEBUG,			      %ENABLE DEBUGGING\
      DEBUGSWITCH,		      %INSERT DEBUGINFORMATION\
      LISTCODE, 		      %LIST MACRO CODE\
      INITGLOBALS,		      %INITIALIZE GLOBAL VARIABLES\
      LOADNOPTR,		      %TRUE IF NO POINTERVARIABLE SHALL BE LOADED\
(* 157 - separate control for arith overflow *)
      ARITHCHECK,		      %SWITCH FOR DETECTING ARITH ERRORS\
      RUNTMCHECK: BOOLEAN;	      %SWITCH FOR RUNTIME-TESTS\
(* 24 - ALLOW USER TO SET FIRST LOC OF STACK AND HEAP *)
      STACK,HEAP: ADDRRANGE;		%FIRST ADDR OF STACK AND HEAP\
(* 12 - stackandheap no longer needed *)
(* 33 - VERSION NO. *)
      version:packed record			%version no. for output\
	case boolean of
	  true:(word:integer);
	  false:(who:0..7B;major:0..777B;minor:0..77B;edit:0..777777B)
	end;


      %POINTERS:\
      %*********\

      LOCALPFPTR, EXTERNPFPTR: CTP;   %PTRS TO LOCAL/EXTERNAL PROC/FUNC-CHAIN\
(* 111 - STRING, POINTER *)
(* 202 - POINTER by ref *)
      INTPTR,REALPTR,CHARPTR,ANYFILEPTR,STRINGPTR,POINTERPTR,POINTERREF,
      BOOLPTR,NILPTR,TEXTPTR: STP;    %POINTERS TO ENTRIES OF STANDARD IDS\
(* 135 - ill mem ref in PACK, UNPACK *)
      UARRTYP:STP;
      UTYPPTR,UCSTPTR,UVARPTR,
      UFLDPTR,UPRCPTR,UFCTPTR,	      %POINTERS TO ENTRIES FOR UNDECLARED IDS\
(* 64 - non-loc goto *)
      ulblptr,
      FWPTR: CTP;		      %HEAD OF CHAIN OF FORW DECL TYPE IDS\
      ERRMPTR,ERRMPTR1: ETP;	      %TO CHAIN ERROR-UPDATES\
(* 65 - remove exit labels *)
      LASTBTP: BTP;		      %HEAD OF BYTEPOINTERTABLE\
      SFILEPTR,
      FILEPTR: FTP;
      FIRSTKONST: KSP;
(* 164 - Polish fixups for CASE *)
      FIRSTPOL: POLPT;
      ALFAPTR, DATEPTR: STP;
      FGLOBPTR,CGLOBPTR : GTP ;       %POINTER TO FIRST AND CURRENT GLOBAL INITIALISATION RECORD\
      GLOBTESTP : TESTP ;	      %POINTER TO LAST PAIR OF POINTERTYPES\
(* 4 - Here is the main structure for the SCAN linkage *)
      SCANDATA : RPGPT ;		%DATA FROM SCAN OF FILE NAMES\
(* 33 - PROGRAM STATEMENT *)
      NPROGFILE,			%NEW FILE NAME\
      LPROGFILE,			%LAST FILE NAME IN LIST\
      FPROGFILE:PROGFILEPT;		%FIRST FILE NAME IN LIST\
(* 64 - non-loc goto *)
      lastlabel:ctp;
(* 171 - treat file names as special *)
      infile,outfile,ttyfile,ttyoutfile:ctp;    {Pointers to ID's for 
	INPUT, OUTPUT, TTY,    TTYOUT}

      %BOOKKEEPING OF DECLARATION LEVELS:\
      %**********************************\

(* 5 - new variable for CREF *)
      LEVEL,BEGLEVEL: LEVRANGE;		      %CURRENT STATIC LEVEL\
      DISX,			      %LEVEL OF LAST ID SEARCHED BY SEARCHID\
      TOP: DISPRANGE;		      %TOP OF DISPLAY\

      DISPLAY:				    %WHERE:   MEANS:\
      ARRAY[DISPRANGE] OF
      PACKED RECORD
	       %=BLCK:	 ID IS VARIABLE ID\
(* 5 - new variable for CREF *)
	       BLKNAME: ALFA;		    %NAME OF BLOCK\
	       FNAME: CTP;		    %=CREC:   ID IS FIELD ID IN RECORD WITH\
	       CASE OCCUR: WHERE OF	    %	      CONSTANT ADDRESS\
		    CREC: (CLEV: LEVRANGE;  %=VREC:   ID IS FIELD ID IN RECORD WITH\
			   CINDR: ACRANGE;  %	      VARIABLE ADDRESS\
			   CINDB: IBRANGE;
			   CRELBYTE: RELBYTE;
			   CDSPL,
			   CLC	: ADDRRANGE)
	     END;
      %ERROR MESSAGES:\
      %***************\

      ERRORFLAG: BOOLEAN;	      %TRUE IF SYNTACTIC ERRORS DETECTED\
      ERRINX: 0..MAXERR ;	      %NR OF ERRORS IN CURRENT SOURCE LINE\
      ERRLIST:
      ARRAY [1..MAXERR] OF
      PACKED RECORD
	       ARW : 1..4;
	       POS: 1..CHCNTMAX;
	       NMR: 1..600;
	       TIC: CHAR
	     END;

      ERRMESS15 : ARRAY [1..24] OF PACKED ARRAY [1..15] OF CHAR;
(* 6 - add error msg for illegal character *)
      ERRMESS20 : ARRAY [1..16] OF PACKED ARRAY [1..20] OF CHAR;
(* 104 - error message for too much data for address space *)
      ERRMESS25 : ARRAY [1..16] OF PACKED ARRAY [1..25] OF CHAR;
      ERRMESS30 : ARRAY [1..17] OF PACKED ARRAY [1..30] OF CHAR;
(* 156 - ftnname^ := *)
      ERRMESS35 : ARRAY [1..18] OF PACKED ARRAY [1..35] OF CHAR;
(* 31 - ADD MESSAGE  FOR BAD ASSIGN TO FTN. NAME *)
      ERRMESS40 : ARRAY [1..13] OF PACKED ARRAY [1..40] OF CHAR;
(* 24 - NEW ERROR MSG FOR LOC *)
      ERRMESS45 : ARRAY [1..16] OF PACKED ARRAY [1..45] OF CHAR;
(* 33 - PROGRAM STATEMENT *)
      ERRMESS50 : ARRAY [1.. 9] OF PACKED ARRAY [1..50] OF CHAR;
(* 124 - bad initprocedure *)
      ERRMESS55 : ARRAY [1.. 7] OF PACKED ARRAY [1..55] OF CHAR;
      ERRORINLINE,
      FOLLOWERROR : BOOLEAN;
      ERRLINE,
      BUFFER: ARRAY [1..CHCNTMAX] OF CHAR;
(* 136 - listing format *)
      PAGECNT,SUBPAGE,CURLINE,
      LINECNT: INTEGER;
      LINENR: PACKED ARRAY [1..5] OF CHAR;




      %EXPRESSION COMPILATION:\
      %***********************\

      GATTR: ATTR;		      %DESCRIBES THE EXPR CURRENTLY COMPILED\
(* 105 - character mapping from lower case *)
      charmap,setmap:array[0..177B]of integer;	%fast mapping to upper case\
      setmapchain:addrrange;		%for external reference to runtime version of setmap\


      %COUNTERS FOR TESTS:\
      %*******************\



      %DEBUG-SYSTEM:\
      %*************\

      LASTSTOP: ADDRRANGE;	      %LAST BREAKPOINT\
      LASTLINE, 		      %LINENUMBER FOR BREAKPOINTS\
      LINEDIFF, 		      %DIFFERENCE BETWEEN ^ AND LINECNT\
      LASTPAGE:INTEGER; 	      %LAST PAGE THAT CONTAINS A STOP\
      PAGEHEADADR,		      %OVERGIVE TO DEBUG.PAS\
      LASTPAGER: ADDRRANGE;	      %POINTS AT LAST PAGERECORD\
      PAGER: PAGEELEM;		      %ACTUAL PAGERECORD\
      DEBUGENTRY: DEBENTRY;
      IDRECSIZE: ARRAY[IDCLASS] OF INTEGER;
      STRECSIZE: ARRAY[STRUCTFORM] OF INTEGER;



      %STRUCTURED CONSTANTS:\
      %*********************\

      LETTERSORDIGITS,LETTERS,DIGITS,LETTERSDIGITSORLEFTARROW,HEXADIGITS: SET OF CHAR;
      CONSTBEGSYS,SIMPTYPEBEGSYS,TYPEBEGSYS,BLOCKBEGSYS,SELECTSYS,FACBEGSYS,
      LANGUAGESYS,STATBEGSYS,TYPEDELS: SETOFSYS;
(* 6 - add PROGRAM statement *)
(* 56 - ADD INCLUDE *)
      RW:  ARRAY [1..45%NR. OF RES. WORDS\] OF ALFA;
      FRW: ARRAY [1..11%ALFALENG+1\] OF 1..46%NR. OF RES. WORDS + 1\;
      RSY: ARRAY [1..45%NR. OF RES. WORDS\] OF SYMBOL;
      SSY: ARRAY [' '..'_'] OF SYMBOL;
      ROP: ARRAY [1..45%NR. OF RES. WORDS\] OF OPERATOR;
      SOP: ARRAY [' '..'_'] OF OPERATOR;
(* 10 make room for 12 more proc's, 8 more ftn's *)
      NA:  ARRAY [1..81] OF ALFA;
(* 61 - new array to declare which are tops10 and tops20 *)
      machna: array[1..81] of machine;
      othermachine: machine;
      EXTNA: ARRAY[39..53] OF ALFA;
      EXTLANGUAGE: ARRAY[39..53] OF SYMBOL;
      MNEMONICS : ARRAY[1..45] OF PACKED ARRAY[1..60] OF CHAR ;


      %VARIABLES FROM BODY\
      %*******************\


(* 173 - internal files *)
{Chantab is very strange.  It is used as a kludge because we need
 two global request chains for each of INPUT, OUTPUT, TTY, and TTYOUTPUT.
 So the second one is stored here.  From an identifier record, you can
 look at CHANNEL to find which of these corresponds to that one.}
      CHANTAB:ARRAY[1..4] OF ADDRRANGE;
      FILEINBLOCK:ARRAY[LEVRANGE]OF BOOLEAN;   {True is there is a local file}
(* 12 - VAR'S FOR GLOBAL REF TO RUNTIMES. FOR DYNAMIC ALLOC *)
      LSTNEW,NEWBND: ADDRRANGE;	%references to these global variables\
(* 13 - ADD DATA FOR DDT SYMBOLS *)
      PFPOINT,PFDISP:ADDRRANGE;	%ADDRESS OF FIRST CODE IN PROCEDURE\
      RELBLOCK: PACKED RECORD
			 CASE BOOLEAN OF
			      TRUE: (COMPONENT: ARRAY[1..20] OF INTEGER);
			      FALSE: (ITEM: ADDRRANGE; COUNT: ADDRRANGE;
				      RELOCATOR: RELWORD;
				      CODE: ARRAY[0..17] OF INTEGER)
		       END;

      RNTS: RECORD
	      NAME: ARRAY[SUPPORTS] OF ALFA;
	      LINK: PACKED ARRAY[SUPPORTS] OF ADDRRANGE
	    END;

      CODE: PACKED RECORD
		     RELOCATION:  PACKED ARRAY[CODERANGE] OF RELBYTE;
		     INFORMATION: PACKED ARRAY[CODERANGE] OF CHAR;
		     CASE INTEGER OF
			  1: (INSTRUCTION: PACKED ARRAY[CODERANGE] OF PDP10INSTR);
			  2: (WORD:	   PACKED ARRAY[CODERANGE] OF INTEGER);
			  3: (HALFWORD:    PACKED ARRAY[CODERANGE] OF HALFS)
		   END;

      LABELS: ARRAY [1:LABMAX] OF
      RECORD
	LABSVAL,LABSADDR: INTEGER
      END;
      GOTOS: ARRAY [1:LABMAX] OF
      RECORD
	GOTOVAL,GOTOADDR: INTEGER
      END;

      REGC,				%TOP OF REGISTERSTACK\
      REGCMAX: ACRANGE; 		%MAXIMUM OF REGISTERS FOR EXPRESSION STACK\
      LIX,JIX,CIX,
      INSERTSIZE,			%TOO INSERT LCMAX IN ENTRYCODE\
      PFSTART: INTEGER; 		%START OF NORMAL ENTRYCODE OF EACH FUNC. OR PROC.\
      IX: INTEGER;
(* 54 - var's needed to keep track of stack space needed *)
      STKOFF, STKOFFMAX, CORALLOC: INTEGER;	%STACK SPACE NEEDED ABOVE LOCALS\
      LCMAX: ADDRRANGE; LCP: CTP;
      OUTPUTREL: FILE OF INTEGER;	%RELOCATABLE BINARY OUTPUT\
      WITHIX,				%TOP OF WITH-REG STACK\
      HIGHESTCODE,			%MAXIMUM OF HIGH SEGMENTS ADDRESS\
      MAINSTART,			%FIRST CODE OF BODY OF MAIN\
(* 16 - add CCLSW set by entry with offset=1 *)
      CCLSW,
(* 66 - nonloc goto's *)
      globtopp,globbasis,
      STARTADDR: INTEGER;		%STARTADDRESSE\

(* 33 - VERSION NO. *)
      LOOKBLOCK: ARRAY[0..6] OF INTEGER;
      LST,REL: PACKED ARRAY[1..3] OF CHAR ;
(* 34 - entry no longer needed *)
      FILENAME: ALFA;
      DAY: PACKED ARRAY[1..9] OF CHAR;
(* 125 - moved to global so insymbol can see it *)
      REQFILE,ENTRYDONE: BOOLEAN;
(* 171 - read/write of records *)
      THISFILE: STP;
      GOTARG: BOOLEAN;

      LIBIX: INTEGER;
      LIBORDER: PACKED ARRAY[1..4] OF SYMBOL;
      LIBRARY: ARRAY[PASCALSY..COBOLSY] OF RECORD
					     INORDER, CALLED: BOOLEAN;
					     NAME: ALFA;
					     PROJNR: ADDRRANGE;
					     PROGNR: ADDRRANGE;
					     DEVICE: ALFA
					   END;

      %------------------------------------------------------------------------------\

      INITPROCEDURE ;
       BEGIN

(* 33 - VERSION NO. *)
(* 34 - using filename instead of entry *)
	LST:= 'LST'  ;	REL:= 'REL'  ;	FILENAME:= '          '  ;  LOOKBLOCK[0] := 6;

	MNEMONICS[ 1] := '***001***002***003***004***005***006***007***010***011***012' ;
	MNEMONICS[ 2] := '***013***014***015***016***017***020***021***022***023***024' ;
	MNEMONICS[ 3] := '***025***026***027***030***031***032***033***034***035***036' ;
	MNEMONICS[ 4] := '***037CALL  INIT  ***042***043***044***045***046CALLI OPEN  ' ;
	MNEMONICS[ 5] := 'TTCALL***052***053***054RENAMEIN    OUT   SETSTSSTATO STATUS' ;
	MNEMONICS[ 6] := 'STATZ INBUF OUTBUFINPUT OUTPUTCLOSE RELEASMTAPE UGETF USETI ' ;
(* 133 - add mnemonics for ADJSP and JSYS *)
	MNEMONICS[ 7] := 'USETO LOOKUPENTER UJEN  ***101***102***103JSYS  ADJSP ***106' ;
	MNEMONICS[ 8] := '***107***110***111***112***113***114***115***116***117***120' ;
(* 2 - add mnemonics for KI-10, since we are using some of them *)
	MNEMONICS[ 9] := '***121FIX   ***123***124***125FIXR  FLTR  UFA   DFN   FSC   ' ;
	MNEMONICS[10] := 'IBP   ILDB  LDB   IDPB  DPB   FAD   FADL  FADM  FADB  FADR  ' ;
	MNEMONICS[11] := 'FADRI FADRM FADRB FSB   FSBL  FSBM  FSBB  FSBR  FSBRI FSBRM ' ;
	MNEMONICS[12] := 'FSBRB FMP   FMPL  FMPM  FMPB  FMPR  FMPRI FMPRM FMPRB FDV   ' ;
	MNEMONICS[13] := 'FDVL  FDVM  FDVB  FDVR  FDVRI FDVRM FDVRB MOVE  MOVEI MOVEM ' ;
	MNEMONICS[14] := 'MOVES MOVS  MOVSI MOVSM MOVSS MOVN  MOVNI MOVNM MOVNS MOVM  ' ;
	MNEMONICS[15] := 'MOVMI MOVMM MOVMS IMUL  IMULI IMULM IMULB MUL   MULI  MULM  ' ;
	MNEMONICS[16] := 'MULB  IDIV  IDIVI IDIVM IDIVB DIV   DIVI  DIVM  DIVB  ASH   ' ;
	MNEMONICS[17] := 'ROT   LSH   JFFO  ASHC  ROTC  LSHC  ***247EXCH  BLT   AOBJP ' ;
	MNEMONICS[18] := 'AOBJN JRST  JFCL  XCT   ***257PUSHJ PUSH  POP   POPJ  JSR   ' ;
	MNEMONICS[19] := 'JSP   JSA   JRA   ADD   ADDI  ADDM  ADDB  SUB   SUBI  SUBM  ' ;
	MNEMONICS[20] := 'SUBB  CAI   CAIL  CAIE  CAILE CAIA  CAIGE CAIN  CAIG  CAM   ' ;
	MNEMONICS[21] := 'CAML  CAME  CAMLE CAMA  CAMGE CAMN  CAMG  JUMP  JUMPL JUMPE ' ;
	MNEMONICS[22] := 'JUMPLEJUMPA JUMPGEJUMPN JUMPG SKIP  SKIPL SKIPE SKIPLESKIPA ' ;
	MNEMONICS[23] := 'SKIPGESKIPN SKIPG AOJ   AOJL  AOJE  AOJLE AOJA  AOJGE AOJN  ' ;
	MNEMONICS[24] := 'AOJG  AOS   AOSL  AOSE  AOSLE AOSA  AOSGE AOSN  AOSG  SOJ   ' ;
	MNEMONICS[25] := 'SOJL  SOJE  SOJLE SOJA  SOJGE SOJN  SOJG  SOS   SOSL  SOSE  ' ;
	MNEMONICS[26] := 'SOSLE SOSA  SOSGE SOSN  SOSG  SETZ  SETZI SETZM SETZB AND   ' ;
	MNEMONICS[27] := 'ANDI  ANDM  ANDB  ANDCA ANDCAIANDCAMANDCABSETM  SETMI SETMM ' ;
	MNEMONICS[28] := 'SETMB ANDCM ANDCMIANDCMMANDCMBSETA  SETAI SETAM SETAB XOR   ' ;
	MNEMONICS[29] := 'XORI  XORM  XORB  IOR   IORI  IORM  IORB  ANDCB ANDCBIANDCBM' ;
	MNEMONICS[30] := 'ANDCBBEQV   EQVI  EQVM  EQVB  SETCA SETCAISETCAMSETCABORCA  ' ;
	MNEMONICS[31] := 'ORCAI ORCAM ORCAB SETCM SETCMISETCMMSETCMBORCM  ORCMI ORCMM ' ;
	MNEMONICS[32] := 'ORCMB ORCB  ORCBI ORCBM ORCBB SETO  SETOI SETOM SETOB HLL   ' ;
	MNEMONICS[33] := 'HLLI  HLLM  HLLS  HRL   HRLI  HRLM  HRLS  HLLZ  HLLZI HLLZM ' ;
	MNEMONICS[34] := 'HLLZS HRLZ  HRLZI HRLZM HRLZS HLLO  HLLOI HLLOM HLLOS HRLO  ' ;
	MNEMONICS[35] := 'HRLOI HRLOM HRLOS HLLE  HLLEI HLLEM HLLES HRLE  HRLEI HRLEM ' ;
	MNEMONICS[36] := 'HRLES HRR   HRRI  HRRM  HRRS  HLR   HLRI  HLRM  HLRS  HRRZ  ' ;
	MNEMONICS[37] := 'HRRZI HRRZM HRRZS HLRZ  HLRZI HLRZM HLRZS HRRO  HRROI HRROM ' ;
	MNEMONICS[38] := 'HRROS HLRO  HLROI HLROM HLROS HRRE  HRREI HRREM HRRES HLRE  ' ;
	MNEMONICS[39] := 'HLREI HLREM HLRES TRN   TLN   TRNE  TLNE  TRNA  TLNA  TRNN  ' ;
	MNEMONICS[40] := 'TLNN  TDN   TSN   TDNE  TSNE  TDNA  TSNA  TDNN  TSNN  TRZ   ' ;
	MNEMONICS[41] := 'TLZ   TRZE  TLZE  TRZA  TLZA  TRZN  TLZN  TDZ   TSZ   TDZE  ' ;
	MNEMONICS[42] := 'TSZE  TDZA  TSZA  TDZN  TSZN  TRC   TLC   TRCE  TLZE  TRCA  ' ;
	MNEMONICS[43] := 'TLCA  TRCN  TLCN  TDC   TSC   TDCE  TSCE  TDCA  TSCA  TDCN  ' ;
	MNEMONICS[44] := 'TSCN  TRO   TLO   TROE  TLOE  TROA  TLOA  TRON  TLON  TDO   ' ;
	MNEMONICS[45] := 'TSO   TDOE  TSOE  TDOA  TSOA  TDON  TSON  ***700            ' ;
       END;

      INITPROCEDURE %SEARCH LIBRARIES\ ;
       BEGIN
	LIBRARY[PASCALSY].INORDER   := FALSE;
	LIBRARY[FORTRANSY].INORDER  := FALSE;
	LIBRARY[ALGOLSY].INORDER    := FALSE;
	LIBRARY[COBOLSY].INORDER    := FALSE;
	LIBRARY[PASCALSY].CALLED    := FALSE;
	LIBRARY[FORTRANSY].CALLED   := FALSE;
	LIBRARY[ALGOLSY].CALLED     := FALSE;
	LIBRARY[COBOLSY].CALLED     := FALSE;
(* 57 - Make library a parameter *)
	LIBRARY[PASCALSY].NAME	    := PASLIB;
	LIBRARY[FORTRANSY].NAME     := 'FORLIB    ';
	LIBRARY[ALGOLSY].NAME	    := 'ALGLIB    ';
	LIBRARY[COBOLSY].NAME	    := 'LIBOL     ';
(* 2 - library now on SYS: *)
(* 57 *)
	LIBRARY[PASCALSY].DEVICE    := PASDEV;
	LIBRARY[FORTRANSY].DEVICE   := 'SYS       ';
	LIBRARY[ALGOLSY].DEVICE     := 'SYS       ';
	LIBRARY[COBOLSY].DEVICE     := 'SYS       ';
(* 57 *)
	LIBRARY[PASCALSY].PROJNR    := PASPROJ;
	LIBRARY[FORTRANSY].PROJNR   := 0;
	LIBRARY[ALGOLSY].PROJNR     := 0;
	LIBRARY[COBOLSY].PROJNR     := 0;
(* 57 *)
	LIBRARY[PASCALSY].PROGNR    := PASPROG;
	LIBRARY[FORTRANSY].PROGNR   := 0;
	LIBRARY[ALGOLSY].PROGNR     := 0;
	LIBRARY[COBOLSY].PROGNR     := 0;
       END %SEARCH LIBRARIES\ ;

      INITPROCEDURE %STANDARDNAMES\ ;
       BEGIN
	NA[ 1] := 'FALSE     '; NA[ 2] := 'TRUE      '; NA[ 3] := 'INPUT     ';
	NA[ 4] := 'OUTPUT    '; NA[ 5] := 'TTY       '; NA[ 6] := 'TTYOUTPUT ';
	NA[ 7] := 'GET       '; NA[ 8] := 'GETLN     '; NA[ 9] := 'PUT       ';
	NA[10] := 'PUTLN     '; NA[11] := 'RESET     '; NA[12] := 'REWRITE   ';
	NA[13] := 'READ      '; NA[14] := 'READLN    '; NA[15] := 'BREAK     ';
	NA[16] := 'WRITE     '; NA[17] := 'WRITELN   '; NA[18] := 'PACK      ';
	NA[19] := 'UNPACK    '; NA[20] := 'NEW       '; NA[21] := 'MARK      ';
	NA[22] := 'RELEASE   '; NA[23] := 'GETLINENR '; NA[24] := 'PUT8BITSTO';
	NA[25] := 'PAGE      '; NA[26] := 'DATE      '; NA[27] := 'RUNTIME   ';
	NA[28] := 'TIME      '; NA[29] := 'ABS       '; NA[30] := 'SQR       ';
	NA[31] := 'TRUNC     '; NA[32] := 'ODD       '; NA[33] := 'ORD       ';
	NA[34] := 'CHR       '; NA[35] := 'PRED      '; NA[36] := 'SUCC      ';
	NA[37] := 'EOF       '; NA[38] := 'EOLN      '; NA[39] := 'SIN       ';
	NA[40] := 'COS       '; NA[41] := 'EXP       '; NA[42] := 'SQRT      ';
	NA[43] := 'LN        '; NA[44] := 'ARCTAN    '; NA[45] := 'LOG       ';
	NA[46] := 'SIND      '; NA[47] := 'COSD      '; NA[48] := 'SINH      ';
	NA[49] := 'COSH      '; NA[50] := 'TANH      '; NA[51] := 'ARCSIN    ';
	NA[52] := 'ARCCOS    '; NA[53] := 'RANDOM    ';
(* 10 make room for 12 more proc's, 8 more ftn's *)
	NA[54] := 'STRSET    '; NA[55] := 'STRWRITE  ';
	NA[56] := 'GETINDEX  '; NA[57] := 'CLOSE     ';
	NA[58] := 'CALLI     '; NA[59] := 'RENAME    ';
	NA[60] := 'DISMISS   '; NA[61] := 'UPDATE    ';
	NA[62] := 'DUMPIN    '; NA[63] := 'DUMPOUT   ';
	NA[64] := 'USETI     '; NA[65] := 'USETO     ';
(* 27 - add NEWZ *)
	NA[66] := 'BREAKIN   '; NA[67] := 'NEWZ      ';
	NA[68] := 'APPEND    '; NA[69] := 'PUTX      ';
(* 44 - SETPOS,CURPOS, SKIP *)
	NA[70] := 'SETPOS    '; NA[71] := 'NEXTBLOCK ';
(* 61 - tops20 system version *)
	na[72] := 'GETX      '; na[73] := 'DELETE    ';
	na[74] := 'RCLOSE    '; na[75] := 'JSYS      ';
(* 152 - add DISPOSE *)
	na[76] := 'DISPOSE   '; na[77] := 'NEXTFILE  ';
	na[78] := 'CURPOS    '; na[79] := 'SPACELEFT ';
	na[80] := 'ROUND     '; na[81] := 'RECSIZE   ';
	machna[24] := t10name; machna[58] := t10name;
	machna[62] := t10name; machna[63] := t10name;
	machna[64] := t10name; machna[65] := t10name;
(* 134 - remove t20name entry for DELETE *)
	machna[71] := t10name; 
	machna[74] := t20name; machna[75] := t20name;
	machna[77] := t20name; machna[79] := t10name;
       END %STANDARDNAMES\ ;

      INITPROCEDURE %EXTERNAL NAMES\;
       BEGIN
	EXTNA[39] := 'SIN       '; EXTLANGUAGE[39] := FORTRANSY;
	EXTNA[40] := 'COS       '; EXTLANGUAGE[40] := FORTRANSY;
	EXTNA[41] := 'EXP       '; EXTLANGUAGE[41] := FORTRANSY;
	EXTNA[42] := 'SQRT      '; EXTLANGUAGE[42] := FORTRANSY;
	EXTNA[43] := 'ALOG      '; EXTLANGUAGE[43] := FORTRANSY;
	EXTNA[44] := 'ATAN      '; EXTLANGUAGE[44] := FORTRANSY;
	EXTNA[45] := 'ALOG10    '; EXTLANGUAGE[45] := FORTRANSY;
	EXTNA[46] := 'SIND      '; EXTLANGUAGE[46] := FORTRANSY;
	EXTNA[47] := 'COSD      '; EXTLANGUAGE[47] := FORTRANSY;
	EXTNA[48] := 'SINH      '; EXTLANGUAGE[48] := FORTRANSY;
	EXTNA[49] := 'COSH      '; EXTLANGUAGE[49] := FORTRANSY;
	EXTNA[50] := 'TANH      '; EXTLANGUAGE[50] := FORTRANSY;
	EXTNA[51] := 'ASIN      '; EXTLANGUAGE[51] := FORTRANSY;
	EXTNA[52] := 'ACOS      '; EXTLANGUAGE[52] := FORTRANSY;
	EXTNA[53] := 'RAN       '; EXTLANGUAGE[53] := FORTRANSY;

       END %EXTERNAL NAMES\;

      INITPROCEDURE %RUNTIME-, DEBUG-SUPPORTS\ ;
       BEGIN

	RNTS.NAME[STACKOVERFLOW]	     := 'CORERR    ';
(* 104 - new tops10 stackoverflow for better checking *)
	RNTS.NAME[DEBSTACK]		     := 'DCORER    ';
(* 23 - check for bad pointer *)
        RNTS.NAME[BADPOINT]		     := 'PTRER.    ';
	RNTS.NAME[ALLOCATE]		     := 'NEW       ';
	RNTS.NAME[CLEARALLOC]		     := 'NEWCL.    ';
(* 152 - DISPOSE *)
	RNTS.NAME[DEALLOCATE]		     := 'DISPOS    ';
(* 173 - internal file *)
	RNTS.NAME[WITHFILEDEALLOCATE]	     := 'DISPF.    ';
(* 64 - non-loc goto *)
	rnts.name[exitgoto]		     := 'GOTOC.    ';
	RNTS.NAME[EXITPROGRAM]		     := 'END       ';
	RNTS.NAME[GETLINE]		     := 'GETLN     ';
	RNTS.NAME[GETFILE]		     := 'GET.      ';
	RNTS.NAME[PUTLINE]		     := 'PUTLN     ';
	RNTS.NAME[PUTFILE]		     := 'PUT       ';
(* 43 - add PUTX *)
	RNTS.NAME[PUTXFILE]		     := 'PUTX      ';
	RNTS.NAME[RESETFILE]		     := 'RESETF    ';
	RNTS.NAME[REWRITEFILE]		     := 'REWRIT    ';
(* 57 - do strset and strwrite at runtime *)
	RNTS.NAME[RESETSTRING]		     := 'STSET.    ';
	RNTS.NAME[REWRITESTRING]	     := 'STWR.     ';
	RNTS.NAME[WRITEOCTAL]		     := 'WRTOCT    ';
	RNTS.NAME[WRITEHEXADECIMAL]	     := 'WRTHEX    ';
	RNTS.NAME[WRITEINTEGER] 	     := 'WRTINT    ';
	RNTS.NAME[WRITECHARACTER]	     := 'WRITEC    ';
	RNTS.NAME[WRITEREAL]		     := 'WRTREA    ';
	RNTS.NAME[WRITEBOOLEAN] 	     := 'WRTBOL    ';
	RNTS.NAME[WRITESTRING]		     := 'WRTUST    ';
	RNTS.NAME[WRITEPACKEDSTRING]	     := 'WRTPST    ';
        RNTS.NAME[WRITERECORD]   	     := '.WRREC    ';
	RNTS.NAME[WRITESCALAR]		     := '.WRSCA    ';
	RNTS.NAME[READINTEGER]		     := '.READI    ';
	RNTS.NAME[READCHARACTER]	     := '.READC    ';
	RNTS.NAME[READREAL]		     := '.READR    ';
        RNTS.NAME[READRECORD]		     := '.READD    ';
	RNTS.NAME[CONVERTINTEGERTOREAL]      := 'INTREA    ';
	RNTS.NAME[CONVERTREALTOINTEGER]      := 'TRUNC     ';
	RNTS.NAME[BREAKOUTPUT]		     := 'BREAK     ';
	RNTS.NAME[OPENTTY]		     := 'TTYPR.    ';
	RNTS.NAME[INITIALIZEDEBUG]	     := 'INDEB.    ';
	RNTS.NAME[ENTERDEBUG]		     := 'EXDEB.    ';
	RNTS.NAME[GETCHARACTER] 	     := 'GETCH     ';
	RNTS.NAME[PUTPAGE]		     := 'PUTPG     ';
	RNTS.NAME[INDEXERROR]		     := 'INXERR    ';
	RNTS.NAME[ERRORINASSIGNMENT]	     := 'SRERR     ';
	RNTS.NAME[FILEUNINITIALIZED]	     := 'ILFIL.    ';
	RNTS.NAME[INITFILEBLOCK]	     := 'INITB.    ';
(* 10 ADD CLOSE *)
	RNTS.NAME[CLOSEFILE]		     := 'CLOFIL    ';
(* 14 AND STRING READERS *)
	RNTS.NAME[READSTRING]		     := 'READUS    ';
	RNTS.NAME[READPACKEDSTRING]	     := 'READPS    ';
	RNTS.NAME[READFILENAME]		     := 'GETFN.    ';
	RNTS.NAME[NAMEFILE]		     := 'RENAME    ';
(* 40 - change name so won't conflict with FORTRAN *)
	RNTS.NAME[DISFILE]		     := 'RESDEV    ';
	RNTS.NAME[UPFILE]		     := 'UPDATE    ';
	RNTS.NAME[APFILE]		     := 'APPEND    ';
	RNTS.NAME[READDUMP]		     := 'DUMPIN    ';
	RNTS.NAME[WRITEDUMP]		     := 'DUMPOU    ';
	RNTS.NAME[SETIN]		     := 'USETIN    ';
	RNTS.NAME[SETOUT]		     := 'USETOU    ';
	RNTS.NAME[BREAKINPUT]		     := 'BREAKI    ';
	RNTS.NAME[SETPOSF]		     := 'SETPOS    ';
	RNTS.NAME[CURPOSF]		     := 'CURPOS    ';
	RNTS.NAME[NEXTBLOCKF]		     := 'NEXTBL    ';
	rnts.name[spaceleftf]		     := 'SPCLF.    ';
	rnts.name[getxf]		     := 'GETX.     ';
(* 74 - Tops20 runtimes *)
	rnts.name[delfile]		     := 'DELF.     ';
	rnts.name[relfile]		     := 'RELF.     ';
	rnts.name[initmem]		     := 'PASIM.    ';
(* 120 - New calling convention, so changed name *)
	rnts.name[initfiles]		     := 'PASIF.    ';
	rnts.name[getdaytime]		     := 'DAYTM.    ';

       END %RUNTIME-, DEBUG-SUPPORTS\ ;

      INITPROCEDURE %INITSCALARS\ ;
       BEGIN
	CHANTAB[1] := 0; CHANTAB[2] := 0; CHANTAB[3] := 0; CHANTAB[4] := 0;
(* 65 - remove exit labels *)
	FWPTR := NIL; LASTBTP := NIL;  FGLOBPTR := NIL ; FILEPTR := NIL ;
	LOCALPFPTR:=NIL; EXTERNPFPTR:= NIL; GLOBTESTP := NIL; ERRMPTR := NIL;
(* 24 - INITIALZE HEAP AND STACK *)
	HEAP := 0; STACK := 0;

	LISTCODE := FALSE; LOADNOPTR := TRUE; INITGLOBALS := FALSE ; RUNTMCHECK := TRUE;
(* 157 - separate control for arith error *)
	ARITHCHECK := TRUE;
	TTYINUSE := TRUE; FOLLOWERROR := FALSE; ERRORINLINE := FALSE; RESETFLAG := TRUE;
(* 172 *)
	TTYSEEEOL := FALSE;
	DP := TRUE; PRTERR := TRUE; ERRORFLAG := FALSE ; MAIN := TRUE;
	ENTRYDONE := FALSE; DEBUG := FALSE; DEBUGSWITCH := FALSE; 
(* 176 *)
	comment_page := 0;
(* 33 - PROGRAM *)
	FPROGFILE := NIL; LPROGFILE := NIL;
(* 64 - non-loc goto *)
	lastlabel := nil;

	IC := HIGHSTART;     %START OF HIGHSEGMENT\
	LC := PROGRST;	     %START OF LOWSEGMENT AVAILABLE TO PROGRAM\
(* 136 - listing format *)
	CHCNT := 0; LINECNT := 1; PAGECNT := 1; SUBPAGE := 0; 
	LASTLINE := -1; LASTPAGE := 0;
(* 12 - initialize new variables for dynamic core *)
	LIBIX := 0; ERRINX := 0; LSTNEW := 0; NEWBND := 0;
       END %INITSCALARS\ ;

      INITPROCEDURE %INITSETS\ ;
       BEGIN
	DIGITS := ['0'..'9'];
	LETTERS := ['A'..'Z'];
	HEXADIGITS := ['0'..'9','A'..'F'];
	LETTERSORDIGITS := [ '0'..'9','A'..'Z'];
	LETTERSDIGITSORLEFTARROW := ['0'..'9','A'..'Z','_'];
	LANGUAGESYS := [FORTRANSY,ALGOLSY,COBOLSY,PASCALSY];
	CONSTBEGSYS := [ADDOP,INTCONST,REALCONST,STRINGCONST,IDENT];
	SIMPTYPEBEGSYS := [ADDOP,INTCONST,REALCONST,STRINGCONST,IDENT,LPARENT] ;
	TYPEBEGSYS := [ADDOP,INTCONST,REALCONST,STRINGCONST,IDENT,LPARENT,ARROW,PACKEDSY,ARRAYSY,RECORDSY,SETSY,FILESY] ;
	TYPEDELS := [ARRAYSY,RECORDSY,SETSY,FILESY];
(* 56 - add require files *)
	BLOCKBEGSYS := [INCLUDESY,LABELSY,CONSTSY,TYPESY,VARSY,INITPROCSY,PROCEDURESY,FUNCTIONSY,BEGINSY];
	SELECTSYS := [ARROW,PERIOD,LBRACK];
	FACBEGSYS := [INTCONST,REALCONST,STRINGCONST,IDENT,LPARENT,LBRACK,NOTSY];
	STATBEGSYS := [BEGINSY,GOTOSY,IFSY,WHILESY,REPEATSY,LOOPSY,FORSY,WITHSY,CASESY]
       END %INITSETS\ ;

      INITPROCEDURE %RESWORDS\ ;
       BEGIN
	RW[ 1] := 'IF        '; RW[ 2] := 'DO        '; RW[ 3] := 'OF        ';
	RW[ 4] := 'TO        '; RW[ 5] := 'IN        '; RW[ 6] := 'OR        ';
	RW[ 7] := 'END       '; RW[ 8] := 'FOR       '; RW[ 9] := 'VAR       ';
	RW[10] := 'DIV       '; RW[11] := 'MOD       '; RW[12] := 'SET       ';
	RW[13] := 'AND       '; RW[14] := 'NOT       '; RW[15] := 'THEN      ';
	RW[16] := 'ELSE      '; RW[17] := 'WITH      '; RW[18] := 'GOTO      ';
	RW[19] := 'LOOP      '; RW[20] := 'CASE      '; RW[21] := 'TYPE      ';
	RW[22] := 'FILE      '; RW[23] := 'EXIT      '; RW[24] := 'BEGIN     ';
	RW[25] := 'UNTIL     '; RW[26] := 'WHILE     '; RW[27] := 'ARRAY     ';
	RW[28] := 'CONST     '; RW[29] := 'LABEL     '; RW[30] := 'ALGOL     ';
	RW[31] := 'COBOL     '; RW[32] := 'EXTERN    '; RW[33] := 'PASCAL    ';
	RW[34] := 'RECORD    '; RW[35] := 'DOWNTO    '; RW[36] := 'PACKED    ';
	RW[37] := 'OTHERS    '; RW[38] := 'REPEAT    '; RW[39] := 'FORTRAN   ';
(* 6 - add PROGRAM statement *)
(* 56 - ADD INCLUDE *)
	RW[40] := 'FORWARD   '; RW[41] := 'PROGRAM   '; RW[42] := 'INCLUDE   ';
        RW[43] := 'FUNCTION  '; RW[44] := 'PROCEDURE ';
	RW[45] := 'INITPROCED';
	FRW[1] :=  1; FRW[2] :=  1; FRW[3] :=  7; FRW[4] := 15; FRW[5] := 24;
	FRW[6] := 32; FRW[7] := 39; FRW[8] := 43; FRW[9] := 44; FRW[10] := 45;
	FRW[11] := 46;
       END %RESWORDS\ ;

      INITPROCEDURE %SYMBOLS\ ;
       BEGIN
	RSY[1] := IFSY; RSY[2] := DOSY; RSY[3] := OFSY; RSY[4] := TOSY;
	RSY[5] := RELOP; RSY[6] := ADDOP; RSY[7] := ENDSY; RSY[8] := FORSY;
	RSY[9] := VARSY; RSY[10] := MULOP; RSY[11] := MULOP; RSY[12] := SETSY;
	RSY[13] := MULOP; RSY[14] := NOTSY; RSY[15] := THENSY;
	RSY[16] := ELSESY; RSY[17] := WITHSY; RSY[18] := GOTOSY;
	RSY[19] := LOOPSY; RSY[20] := CASESY; RSY[21] := TYPESY;
	RSY[22] := FILESY; RSY[23] := EXITSY; RSY[24] := BEGINSY;
	RSY[25] := UNTILSY; RSY[26] := WHILESY; RSY[27] := ARRAYSY;
	RSY[28] := CONSTSY; RSY[29] := LABELSY;
	RSY[30] := ALGOLSY; RSY[31] := COBOLSY;
	RSY[32] := EXTERNSY; RSY[33] := PASCALSY; RSY[34] := FORTRANSY;
	RSY[34] := RECORDSY; RSY[35]:= DOWNTOSY; RSY[36] := PACKEDSY;
	RSY[37] := OTHERSSY; RSY[38]:= REPEATSY; RSY[39] := FORTRANSY;
(* 6 - add PROGRAM statement *)
(* 56 - ADD INCLUDE *)
	RSY[40] := FORWARDSY; RSY[41] := PROGRAMSY; RSY[42] := INCLUDESY; RSY[43] := FUNCTIONSY;
	RSY[44] := PROCEDURESY; RSY[45] := INITPROCSY;

	SSY['A'] := OTHERSY; SSY['B'] := OTHERSY; SSY['C'] := OTHERSY;
	SSY['D'] := OTHERSY; SSY['E'] := OTHERSY; SSY['F'] := OTHERSY;
	SSY['G'] := OTHERSY; SSY['H'] := OTHERSY; SSY['I'] := OTHERSY;
	SSY['J'] := OTHERSY; SSY['K'] := OTHERSY; SSY['L'] := OTHERSY;
	SSY['M'] := OTHERSY; SSY['N'] := OTHERSY; SSY['O'] := OTHERSY;
	SSY['P'] := OTHERSY; SSY['Q'] := OTHERSY; SSY['R'] := OTHERSY;
	SSY['S'] := OTHERSY; SSY['T'] := OTHERSY; SSY['U'] := OTHERSY;
	SSY['V'] := OTHERSY; SSY['W'] := OTHERSY; SSY['X'] := OTHERSY;
	SSY['Y'] := OTHERSY; SSY['Z'] := OTHERSY; SSY['0'] := OTHERSY;
	SSY['1'] := OTHERSY; SSY['2'] := OTHERSY; SSY['3'] := OTHERSY;
	SSY['4'] := OTHERSY; SSY['5'] := OTHERSY; SSY['6'] := OTHERSY;
	SSY['7'] := OTHERSY; SSY['8'] := OTHERSY; SSY['9'] := OTHERSY;
	SSY['_'] := OTHERSY;
	SSY['+'] := ADDOP;   SSY['-'] := ADDOP;   SSY['*'] := MULOP;
	SSY['/'] := MULOP;   SSY['('] := LPARENT; SSY[')'] := RPARENT;
	SSY['$'] := OTHERSY; SSY['='] := RELOP;   SSY[' '] := OTHERSY;
	SSY[','] := COMMA;   SSY['.'] := PERIOD;  SSY[''''] := OTHERSY;
	SSY['['] := LBRACK;  SSY[']'] := RBRACK;  SSY[':'] := COLON;
	SSY['#'] := RELOP;   SSY['%'] := OTHERSY; SSY['!'] := ADDOP;
	SSY['&'] := MULOP;   SSY['^'] := ARROW;   SSY['\'] := OTHERSY;
	SSY['<'] := RELOP;   SSY['>'] := RELOP;   SSY['@'] := RELOP;
	SSY['"'] := RELOP;   SSY['?'] := NOTSY;   SSY[';'] := SEMICOLON;
       END %SYMBOLS\ ;

      INITPROCEDURE %OPERATORS\ ;
       BEGIN
	ROP[ 1] := NOOP; ROP[ 2] := NOOP; ROP[ 3] := NOOP; ROP[ 4] := NOOP;
	ROP[ 5] := INOP; ROP[ 6] := OROP; ROP[ 7] := NOOP; ROP[ 8] := NOOP;
	ROP[ 9] := NOOP; ROP[10] := IDIV; ROP[11] := IMOD; ROP[12] := NOOP;
	ROP[13] :=ANDOP; ROP[14] := NOOP; ROP[15] := NOOP; ROP[16] := NOOP;
	ROP[17] := NOOP; ROP[18] := NOOP; ROP[19] := NOOP; ROP[20] := NOOP;
	ROP[21] := NOOP; ROP[22] := NOOP; ROP[23] := NOOP; ROP[24] := NOOP;
	ROP[25] := NOOP; ROP[26] := NOOP; ROP[27] := NOOP; ROP[28] := NOOP;
	ROP[29] := NOOP; ROP[30] := NOOP; ROP[31] := NOOP; ROP[32] := NOOP;
	ROP[33] := NOOP; ROP[34] := NOOP; ROP[35] := NOOP; ROP[36] := NOOP;
	ROP[37] := NOOP; ROP[38] := NOOP; ROP[39] := NOOP; ROP[40] := NOOP;
(* 6 - add PROGRAM statement *)
(* 56 - ADD INCLUDE *)
	ROP[41] := NOOP; ROP[42] := NOOP; ROP[43] := NOOP; ROP[44] := NOOP; ROP[45] := NOOP;

	SOP['+'] := PLUS; SOP['-'] := MINUS; SOP['*'] := MUL;  SOP['/'] := RDIV;
	SOP['='] := EQOP; SOP['#'] := NEOP;  SOP['!'] := OROP; SOP['&'] := ANDOP;
	SOP['<'] := LTOP; SOP['>'] := GTOP;  SOP['@'] := LEOP; SOP['"'] := GEOP;
	SOP[' '] := NOOP; SOP['$'] := NOOP; SOP['%'] := NOOP; SOP['('] := NOOP;
	SOP[')'] := NOOP; SOP[','] := NOOP; SOP['.'] := NOOP; SOP['0'] := NOOP;
	SOP['1'] := NOOP; SOP['2'] := NOOP; SOP['3'] := NOOP; SOP['4'] := NOOP;
	SOP['5'] := NOOP; SOP['6'] := NOOP; SOP['7'] := NOOP; SOP['8'] := NOOP;
	SOP['9'] := NOOP; SOP[':'] := NOOP; SOP[';'] := NOOP; SOP['?'] := NOOP;
	SOP['A'] := NOOP; SOP['B'] := NOOP; SOP['C'] := NOOP; SOP['D'] := NOOP;
	SOP['E'] := NOOP; SOP['F'] := NOOP; SOP['G'] := NOOP; SOP['H'] := NOOP;
	SOP['I'] := NOOP; SOP['J'] := NOOP; SOP['K'] := NOOP; SOP['L'] := NOOP;
	SOP['M'] := NOOP; SOP['N'] := NOOP; SOP['O'] := NOOP; SOP['P'] := NOOP;
	SOP['Q'] := NOOP; SOP['R'] := NOOP; SOP['S'] := NOOP; SOP['T'] := NOOP;
	SOP['U'] := NOOP; SOP['V'] := NOOP; SOP['W'] := NOOP; SOP['X'] := NOOP;
	SOP['Y'] := NOOP; SOP['Z'] := NOOP; SOP['['] := NOOP; SOP['\'] := NOOP;
	SOP[']'] := NOOP; SOP['^'] := NOOP; SOP['_'] := NOOP; SOP[''''] := NOOP;
       END %OPERATORS\ ;

      INITPROCEDURE %RECORDSIZES\;
       BEGIN
	IDRECSIZE[TYPES]  := 5;
	IDRECSIZE[KONST]  := 6;
	IDRECSIZE[VARS]   := 6;
	IDRECSIZE[FIELD]  := 6;
	IDRECSIZE[PROC]   := 5;
	IDRECSIZE[FUNC]   := 8;
(* 116 - define size of the new types for copyctp *)
	IDRECSIZE[PARAMS] := 5;
	IDRECSIZE[LABELT] := 6;
	STRECSIZE[SCALAR] := 2;
	STRECSIZE[SUBRANGE]:=4;
	STRECSIZE[POINTER]:= 2;
	STRECSIZE[POWER]  := 2;
	STRECSIZE[ARRAYS] := 3;
	STRECSIZE[RECORDS]:= 3;
	STRECSIZE[FILES]  := 2;
	STRECSIZE[TAGFWITHID]:=3;
	STRECSIZE[TAGFWITHOUTID] := 3;
	STRECSIZE[VARIANT] :=4
       END;

      INITPROCEDURE %ERRORMESSAGES\ ;
       BEGIN
	ERRMESS15[ 1] := '":" expected   ';
	ERRMESS15[ 2] := '")" expected   ';
	ERRMESS15[ 3] := '"(" expected   ';
	ERRMESS15[ 4] := '"[" expected   ';
	ERRMESS15[ 5] := '"]" expected   ';
	ERRMESS15[ 6] := '";" expected   ';
	ERRMESS15[ 7] := '"=" expected   ';
	ERRMESS15[ 8] := '"," expected   ';
	ERRMESS15[ 9] := '":=" expected  ';
	ERRMESS15[10] := '"OF" expected  ';
	ERRMESS15[11] := '"DO" expected  ';
	ERRMESS15[12] := '"IF" expected  ';
	ERRMESS15[13] := '"END" expected ';
	ERRMESS15[14] := '"THEN" expected';
	ERRMESS15[15] := '"EXIT" expected';
	ERRMESS15[16] := 'Illegal symbol ';
	ERRMESS15[17] := 'No sign allowed';
	ERRMESS15[18] := 'Number expected';
	ERRMESS15[19] := 'Not implemented';
	ERRMESS15[20] := 'Error in type  ';
(* 35 - new error - no longer need old one, so we replaced*)
	ERRMESS15[21] := 'Compiler error ';
	ERRMESS15[22] := '"." expected   ';
	ERRMESS15[23] := 'Error in factor';
	ERRMESS15[24] := 'Too many digits';

	ERRMESS20[ 1] := '"BEGIN" expected    ';
	ERRMESS20[ 2] := '"UNTIL" expected    ';
	ERRMESS20[ 3] := 'Error in options    ';
	ERRMESS20[ 4] := 'Constant too large  ';
	ERRMESS20[ 5] := 'Digit must follow   ';
	ERRMESS20[ 6] := 'Exponent too large  ';
	ERRMESS20[ 7] := 'Constant expected   ';
	ERRMESS20[ 8] := 'Simple type expected';
	ERRMESS20[ 9] := 'Identifier expected ';
	ERRMESS20[10] := 'Realtype not allowed';
	ERRMESS20[11] := 'Multidefined label  ';
	ERRMESS20[12] := 'Filename expected   ';
	ERRMESS20[13] := 'Set type expected   ';
	ERRMESS20[14] := 'Undeclared exitlabel';
	ERRMESS20[15] := 'Undeclared label    ';
(* 6 - add error msg for illegal character *)
	ERRMESS20[16] := 'Illegal character   ';

	ERRMESS25[ 1] := '"TO"/"DOWNTO" expected   ';
	ERRMESS25[ 2] := '8 OR 9 in octal number   ';
	ERRMESS25[ 3] := 'Identifier not declared  ';
	ERRMESS25[ 4] := 'File not allowed here    ';
	ERRMESS25[ 5] := 'Integer constant expected';
	ERRMESS25[ 6] := 'Error in parameterlist   ';
	ERRMESS25[ 7] := 'Already forward declared ';
	ERRMESS25[ 8] := 'This format for real only';
	ERRMESS25[ 9] := 'Varianttype must be array';
	ERRMESS25[10] := 'Type conflict of operands';
	ERRMESS25[11] := 'Multidefined case label  ';
	ERRMESS25[12] := 'Octal for integer only   ';
	ERRMESS25[13] := 'Array index out of bounds';
(* 26 - two new error messages for reset/rewrite/update *)
	ERRMESS25[14] := 'Must be array or record  ';
	ERRMESS25[15] := 'Must be at least 5 words ';
(* 104 - error message for too much data for address space *)
	ERRMESS25[16] := 'Data won''t fit in memory ';

	ERRMESS30[ 1] := 'String constant is too long   ';
	ERRMESS30[ 2] := 'Identifier already declared   ';
	ERRMESS30[ 3] := 'Subrange bounds must be scalar';
	ERRMESS30[ 4] := 'Incompatible subrange types   ';
	ERRMESS30[ 5] := 'Incompatible with tagfieldtype';
	ERRMESS30[ 6] := 'Index type may not be integer ';
	ERRMESS30[ 7] := 'Type of variable is not array ';
	ERRMESS30[ 8] := 'Type of variable is not record';
	ERRMESS30[ 9] := 'No such field in this record  ';
	ERRMESS30[10] := 'Expression too complicated    ';
	ERRMESS30[11] := 'Illegal type of operand(s)    ';
	ERRMESS30[12] := 'Tests on equality allowed only';
	ERRMESS30[13] := 'Strict inclusion not allowed  ';
(* 24 - CAN'T COMPARE RECORDS OR ARRAYS NOW *)
	ERRMESS30[14] := 'Structure comparison illegal  ';
	ERRMESS30[15] := 'Illegal type of expression    ';
	ERRMESS30[16] := 'Value of case label too large ';
	ERRMESS30[17] := 'Too many nested withstatements';

	ERRMESS35[ 1] := 'String constant contains "<CR><LF>"';
	ERRMESS35[ 2] := 'Basetype requires more than 72 bits';
	ERRMESS35[ 3] := 'Basetype must be scalar or subrange';
	ERRMESS35[ 4] := 'More than 12 files declared by user';
	ERRMESS35[ 5] := 'File as value parameter not allowed';
	ERRMESS35[ 6] := 'Procedure too long (too much code) ';
	ERRMESS35[ 7] := 'No packed structure allowed here   ';
	ERRMESS35[ 8] := 'Variant must belong to tagfieldtype';
	ERRMESS35[ 9] := 'Type of operand(s) must be boolean ';
	ERRMESS35[10] := 'Set element types not compatible   ';
	ERRMESS35[11] := 'Assignment to files not allowed    ';
	ERRMESS35[12] := 'Too many labels in this procedure  ';
	ERRMESS35[13] := 'Too many cases in case statement   ';
	ERRMESS35[14] := 'Control variable may not be formal ';
	ERRMESS35[15] := 'Illegal type of for-controlvariable';
	ERRMESS35[16] := 'Type of filecomponent must be char ';
	ERRMESS35[17] := 'Constant not in bounds of subrange ';
(* 156 ftn^ := *)
	ERRMESS35[18] := 'Illegal when assigning to function ';

	ERRMESS40[ 1] := 'Identifier is not of appropriate class  ';
	ERRMESS40[ 2] := 'Tagfield type must be scalar or subrange';
	ERRMESS40[ 3] := 'Index type must be scalar or subrange   ';
	ERRMESS40[ 4] := 'Too many nested scopes of identifiers   ';
	ERRMESS40[ 5] := 'Pointer forward reference unsatisfied   ';
	ERRMESS40[ 6] := 'Previous declaration was not forward    ';
	ERRMESS40[ 7] := 'Type of variable must be file or pointer';
	ERRMESS40[ 8] := 'Missing corresponding variantdeclaration';
	ERRMESS40[ 9] := 'Too many variants in call of NEW (max 6)';
	ERRMESS40[10] := 'More than four errors in this sourceline';
	ERRMESS40[11] := 'No initialisation on records or files   ';
(* 31 - new message *)
	ERRMESS40[12] := 'Assignment to func. must be in its body ';
	ERRMESS40[13] := 'Too many parameters (must fit in AC''s)  ';

	ERRMESS45[ 1] := 'Low bound may not be greater than high bound ';
	ERRMESS45[ 2] := 'Identifier or "CASE" expected in fieldlist   ';
	ERRMESS45[ 3] := 'Too many nested procedures and/or functions  ';
	ERRMESS45[ 4] := 'File declaration in procedures not allowed   ';
	ERRMESS45[ 5] := 'Missing result type in function declaration  ';
	ERRMESS45[ 6] := 'Assignment to formal function is not allowed ';
	ERRMESS45[ 7] := 'Index type is not compatible with declaration';
	ERRMESS45[ 8] := 'Error in type of standard procedure parameter';
	ERRMESS45[ 9] := 'Error in type of standard function parameter ';
	ERRMESS45[10] := 'Real and string tagfields not implemented    ';
	ERRMESS45[11] := 'Set element type must be scalar or subrange  ';
	ERRMESS45[12] := 'In initprocedure only assignments possible   ';
	ERRMESS45[13] := 'No constant or expression for VAR argument   ';
	ERRMESS45[14] := 'EXTERN declaration not allowed in procedures ';
	ERRMESS45[15] := 'Body of forward declared procedure missing   ';
(* 24 - NEW ERROR MSG FOR LOC *)
	ERRMESS45[16] := 'Must be user-declared PASCAL proc. or func.  ';

	ERRMESS50[ 1] := 'Too many forward references of procedure entries  ';
	ERRMESS50[ 2] := 'Assignment to standard function is not allowed    ';
	ERRMESS50[ 3] := 'Parameter type does not agree with declaration    ';
	ERRMESS50[ 4] := 'Initialisation only by assignment of constants    ';
	ERRMESS50[ 5] := 'Label type incompatible with selecting expression ';
	ERRMESS50[ 6] := 'Statement must end with ";","END","ELSE"or"UNTIL" ';
	ERRMESS50[ 7] := 'Not allowed in initprocedures (packed structure?) ';
(* 33 - PROGRAM *)
        ERRMESS50[ 8] := 'File mentioned in PROGRAM statement not declared  ';
(* 211 - better err msg *)
	ERRMESS50[ 9] := 'Variable mentioned in PROGRAM statement not a file';

	ERRMESS55[ 1] := 'Function result type must be scalar,subrange or pointer';
	ERRMESS55[ 2] := 'Forward decl. func:repetition of resulttype not allowed';
	ERRMESS55[ 3] := 'Forward decl.: repetition of parameter list not allowed';
	ERRMESS55[ 4] := 'Number of parameters does not agree with declaration   ';
	ERRMESS55[ 5] := 'Resulttype of parameter func. does not agree with decl.';
	ERRMESS55[ 6] := 'Selected expression must have type of control variable ';
(* 124 - detect bad initproc *)
	ERRMESS55[ 7] := 'INITPROCEDURE can''t be within a procedure or function  ';
       END %ERROR MESSAGES\ ;

(* 105 - new mapping from lower case *)
     initprocedure  %character mapping tables\ ;
	begin
	charmap[0B] := 0B;	charmap[1B] := 1B;	charmap[2B] := 2B;	charmap[3B] := 3B;
	charmap[4B] := 4B;	charmap[5B] := 5B;	charmap[6B] := 6B;	charmap[7B] := 7B;
	charmap[10B] := 10B;	charmap[11B] := 11B;	charmap[12B] := 12B;	charmap[13B] := 13B;
	charmap[14B] := 14B;	charmap[15B] := 15B;	charmap[16B] := 16B;	charmap[17B] := 17B;
	charmap[20B] := 20B;	charmap[21B] := 21B;	charmap[22B] := 22B;	charmap[23B] := 23B;
	charmap[24B] := 24B;	charmap[25B] := 25B;	charmap[26B] := 26B;	charmap[27B] := 27B;
	charmap[30B] := 30B;	charmap[31B] := 31B;	charmap[32B] := 32B;	charmap[33B] := 33B;
	charmap[34B] := 34B;	charmap[35B] := 35B;	charmap[36B] := 36B;	charmap[37B] := 37B;
	charmap[40B] := 40B;	charmap[41B] := 41B;	charmap[42B] := 42B;	charmap[43B] := 43B;
	charmap[44B] := 44B;	charmap[45B] := 45B;	charmap[46B] := 46B;	charmap[47B] := 47B;
	charmap[50B] := 50B;	charmap[51B] := 51B;	charmap[52B] := 52B;	charmap[53B] := 53B;
	charmap[54B] := 54B;	charmap[55B] := 55B;	charmap[56B] := 56B;	charmap[57B] := 57B;
	charmap[60B] := 60B;	charmap[61B] := 61B;	charmap[62B] := 62B;	charmap[63B] := 63B;
	charmap[64B] := 64B;	charmap[65B] := 65B;	charmap[66B] := 66B;	charmap[67B] := 67B;
	charmap[70B] := 70B;	charmap[71B] := 71B;	charmap[72B] := 72B;	charmap[73B] := 73B;
	charmap[74B] := 74B;	charmap[75B] := 75B;	charmap[76B] := 76B;	charmap[77B] := 77B;
	charmap[100B] := 100B;	charmap[101B] := 101B;	charmap[102B] := 102B;	charmap[103B] := 103B;
	charmap[104B] := 104B;	charmap[105B] := 105B;	charmap[106B] := 106B;	charmap[107B] := 107B;
	charmap[110B] := 110B;	charmap[111B] := 111B;	charmap[112B] := 112B;	charmap[113B] := 113B;
	charmap[114B] := 114B;	charmap[115B] := 115B;	charmap[116B] := 116B;	charmap[117B] := 117B;
	charmap[120B] := 120B;	charmap[121B] := 121B;	charmap[122B] := 122B;	charmap[123B] := 123B;
	charmap[124B] := 124B;	charmap[125B] := 125B;	charmap[126B] := 126B;	charmap[127B] := 127B;
	charmap[130B] := 130B;	charmap[131B] := 131B;	charmap[132B] := 132B;	charmap[133B] := 133B;
	charmap[134B] := 134B;	charmap[135B] := 135B;	charmap[136B] := 136B;	charmap[137B] := 137B;
	charmap[140B] := 140B;	charmap[141B] := 101B;	charmap[142B] := 102B;	charmap[143B] := 103B;
	charmap[144B] := 104B;	charmap[145B] := 105B;	charmap[146B] := 106B;	charmap[147B] := 107B;
	charmap[150B] := 110B;	charmap[151B] := 111B;	charmap[152B] := 112B;	charmap[153B] := 113B;
	charmap[154B] := 114B;	charmap[155B] := 115B;	charmap[156B] := 116B;	charmap[157B] := 117B;
	charmap[160B] := 120B;	charmap[161B] := 121B;	charmap[162B] := 122B;	charmap[163B] := 123B;
	charmap[164B] := 124B;	charmap[165B] := 125B;	charmap[166B] := 126B;	charmap[167B] := 127B;
	charmap[170B] := 130B;	charmap[171B] := 131B;	charmap[172B] := 132B;	charmap[173B] := 173B;
	charmap[174B] := 174B;	charmap[175B] := 175B;	charmap[176B] := 176B;	charmap[177B] := 177B;
(* 140 - redid numbers to make it come in the same order as ASCII *)
	setmap[0B] := 0B;	setmap[1B] := 0B;	setmap[2B] := 0B;	setmap[3B] := 0B;
	setmap[4B] := 0B;	setmap[5B] := 0B;	setmap[6B] := 0B;	setmap[7B] := 0B;
	setmap[10B] := 0B;	setmap[11B] := 1B;	setmap[12B] := 0B;	setmap[13B] := 0B;
	setmap[14B] := 0B;	setmap[15B] := 0B;	setmap[16B] := 0B;	setmap[17B] := 0B;
	setmap[20B] := 0B;	setmap[21B] := 0B;	setmap[22B] := 0B;	setmap[23B] := 0B;
	setmap[24B] := 0B;	setmap[25B] := 0B;	setmap[26B] := 0B;	setmap[27B] := 0B;
	setmap[30B] := 0B;	setmap[31B] := 0B;	setmap[32B] := 0B;	setmap[33B] := 0B;
	setmap[34B] := 0B;	setmap[35B] := 0B;	setmap[36B] := 0B;	setmap[37B] := 0B;
	setmap[40B] := 2B;	setmap[41B] := 3B;	setmap[42B] := 4B;	setmap[43B] := 5B;
	setmap[44B] := 6B;	setmap[45B] := 7B;	setmap[46B] := 10B;	setmap[47B] := 11B;
	setmap[50B] := 12B;	setmap[51B] := 13B;	setmap[52B] := 14B;	setmap[53B] := 15B;
	setmap[54B] := 16B;	setmap[55B] := 17B;	setmap[56B] := 20B;	setmap[57B] := 21B;
	setmap[60B] := 22B;	setmap[61B] := 23B;	setmap[62B] := 24B;	setmap[63B] := 25B;
	setmap[64B] := 26B;	setmap[65B] := 27B;	setmap[66B] := 30B;	setmap[67B] := 31B;
	setmap[70B] := 32B;	setmap[71B] := 33B;	setmap[72B] := 34B;	setmap[73B] := 35B;
	setmap[74B] := 36B;	setmap[75B] := 37B;	setmap[76B] := 40B;	setmap[77B] := 41B;
	setmap[100B] := 42B;	setmap[101B] := 43B;	setmap[102B] := 44B;	setmap[103B] := 45B;
	setmap[104B] := 46B;	setmap[105B] := 47B;	setmap[106B] := 50B;	setmap[107B] := 51B;
	setmap[110B] := 52B;	setmap[111B] := 53B;	setmap[112B] := 54B;	setmap[113B] := 55B;
	setmap[114B] := 56B;	setmap[115B] := 57B;	setmap[116B] := 60B;	setmap[117B] := 61B;
	setmap[120B] := 62B;	setmap[121B] := 63B;	setmap[122B] := 64B;	setmap[123B] := 65B;
	setmap[124B] := 66B;	setmap[125B] := 67B;	setmap[126B] := 70B;	setmap[127B] := 71B;
	setmap[130B] := 72B;	setmap[131B] := 73B;	setmap[132B] := 74B;	setmap[133B] := 75B;
	setmap[134B] := 76B;	setmap[135B] := 77B;	setmap[136B] := 100B;	setmap[137B] := 101B;
	setmap[140B] := 102B;	setmap[141B] := 43B;	setmap[142B] := 44B;	setmap[143B] := 45B;
	setmap[144B] := 46B;	setmap[145B] := 47B;	setmap[146B] := 50B;	setmap[147B] := 51B;
	setmap[150B] := 52B;	setmap[151B] := 53B;	setmap[152B] := 54B;	setmap[153B] := 55B;
	setmap[154B] := 56B;	setmap[155B] := 57B;	setmap[156B] := 60B;	setmap[157B] := 61B;
	setmap[160B] := 62B;	setmap[161B] := 63B;	setmap[162B] := 64B;	setmap[163B] := 65B;
	setmap[164B] := 66B;	setmap[165B] := 67B;	setmap[166B] := 70B;	setmap[167B] := 71B;
	setmap[170B] := 72B;	setmap[171B] := 73B;	setmap[172B] := 74B;	setmap[173B] := 103B;
	setmap[174B] := 104B;	setmap[175B] := 105B;	setmap[176B] := 106B;	setmap[177B] := 107B;
	end; %character mapping tables\

      %-------------------------------------------------------------------------------\

(* 40 - make it restartable *)
      procedure reinit;
	begin
	CHANTAB[1] := 0; CHANTAB[2] := 0; CHANTAB[3] := 0; CHANTAB[4] := 0;
(* 65 - remove exit labels *)
	FWPTR := NIL; LASTBTP := NIL;  FGLOBPTR := NIL ; FILEPTR := NIL ;
	LOCALPFPTR:=NIL; EXTERNPFPTR:= NIL; GLOBTESTP := NIL; ERRMPTR := NIL;
(* 24 - INITIALZE HEAP AND STACK *)
	HEAP := 0; STACK := 0;
(* 124 - initialize CREF *)
(* 125 - and REQFILE *)
	CREF := false;  reqfile := false;

	LISTCODE := FALSE; LOADNOPTR := TRUE; INITGLOBALS := FALSE ; RUNTMCHECK := TRUE;
(* 157 - separate check for arith error *)
	ARITHCHECK := TRUE;
	TTYINUSE := TRUE; FOLLOWERROR := FALSE; ERRORINLINE := FALSE; RESETFLAG := TRUE;
(* 172 - end of line *)
	TTYSEEEOL := FALSE;
	DP := TRUE; PRTERR := TRUE; ERRORFLAG := FALSE ; MAIN := TRUE;
	ENTRYDONE := FALSE; DEBUG := FALSE; DEBUGSWITCH := FALSE;
(* 176 *)
        comment_page := 0;
(* 33 - PROGRAM *)
	FPROGFILE := NIL; LPROGFILE := NIL;

	IC := HIGHSTART;     %START OF HIGHSEGMENT\
	LC := PROGRST;	     %START OF LOWSEGMENT AVAILABLE TO PROGRAM\
(* 136 - listing format *)
	CHCNT := 0; LINECNT := 1; PAGECNT := 1; SUBPAGE := 0; CURLINE := 1;
	LASTLINE := -1; LASTPAGE := 0;
(* 12 - initialize new variables for dynamic core *)
	LIBIX := 0; ERRINX := 0; LSTNEW := 0; NEWBND := 0;
	with pager.word1 do
	  begin instr:=0;ac:=0;indbit:=0;inxreg:=0;address:=0 end;
	pager.lhalf := 0; pager.rhalf := 0;
	debugentry.lastpageelem := pager;
	laststop := 0; lastpager := 0;
(* 103 - changed type for idtree's *)
	debugentry.standardidtree := nil;
	debugentry.globalidtree := nil;
	filename := '          ';
	LIBRARY[PASCALSY].INORDER   := FALSE;
	LIBRARY[FORTRANSY].INORDER  := FALSE;
	LIBRARY[ALGOLSY].INORDER    := FALSE;
	LIBRARY[COBOLSY].INORDER    := FALSE;
	LIBRARY[PASCALSY].CALLED    := FALSE;
	LIBRARY[FORTRANSY].CALLED   := FALSE;
	LIBRARY[ALGOLSY].CALLED     := FALSE;
	LIBRARY[COBOLSY].CALLED     := FALSE;
(* 105 - map lower case better *)
	setmapchain := 0;
	end;

(* 136 - new listing format *)

      procedure pagehead;
	  begin
	  page;
	  write(header,'  ',day,'     ',scandata^.relname);
	  if reqfile
	    then write('  ****Included file****');
	  write('     Page ',pagecnt:0);
	  if subpage > 0
	    then write('-',subpage:0);
	  writeln;
	  writeln;
	  curline := 1;
	  end;

      procedure newline;
	begin
	writeln;	
	curline := curline+1;
	if curline > 53
	  then begin
	  subpage := subpage + 1;
	  pagehead;
	  end
	end;

      PROCEDURE NEWPAGER;
       BEGIN
	WITH PAGER, WORD1 DO
	 BEGIN
	  AC := PAGECNT DIV 16;
	  INXREG := PAGECNT MOD 16; ADDRESS := LASTPAGER;
	  LHALF := LASTLINE; RHALF := LASTSTOP;
	  LASTLINE := -1
	 END
       END;

(* 5 - reorganized printing somewhat for CREF *)
(* The FILCOM is a bit misleading here, as global changes have been made *)
      PROCEDURE BEGOFLINE;
	BEGIN
	IF CREF THEN WRITE(CHR(177B),'A');
	IF CHCNT > CHCNTMAX THEN CHCNT := CHCNTMAX;
	 IF LISTCODE
	 THEN
	   BEGIN
(* 5 - more of the CREF change *)
	     IF BEGDP
	     THEN
	       BEGIN
		WRITE(BEGLC:6:O);
		 IF (BEGLC < PROGRST) OR (BEGLEVEL > 1)
		 THEN WRITE(' ')
		 ELSE WRITE('''')
	       END
	     ELSE WRITE(BEGIC:6:O,'''');
	    WRITE(' ':2)
	   END;
	 IF LINENR='-----'
	 THEN  WRITE(LINECNT:5)
	 ELSE  WRITE(LINENR) ;
	WRITE(' ':3);
        END;

      PROCEDURE WRITEBUFFER;
       BEGIN
	 IF LISTCODE
	 THEN
	   BEGIN
(* 5 - more CREF *)
	   IF CREF THEN WRITE(CHR(177B),'B'); BEGOFLINE;
(* 136 - listing format *)
	    WRITE(BUFFER:CHCNT); FOR CHCNT := 1 TO 17 DO BUFFER[CHCNT] := ' '; CHCNT := 17;
	   newline;
	   END
       END;

      PROCEDURE GETNEXTLINE;
       BEGIN
	 LOOP
	  GETLINENR(LINENR);
         EXIT IF INPUT^ # CHR(14B);    %TEST END OF PAGE\
	   IF DEBUG AND (LASTLINE > -1)
	   THEN NEWPAGER;
(* 136 - listing format *)
	  PAGECNT := PAGECNT + 1; SUBPAGE := 0;
	  pagehead;
(* 137 - reset line to 1 on each page *)
	  linecnt := 1;
	  READLN;  %TO OVERREAD SECOND CARRIAGE RETURN IN PAGE MARK\
	 END;
	 IF CREF
	   THEN WRITE(CHR(177B),'B');
	 BEGIC:=IC;BEGLC:=LC;BEGDP:=DP;BEGLEVEL:=LEVEL;
       END;

(* 56 - needed for file switch *)
      PROCEDURE BEGSTUFF;
	BEGIN
	IF CREF
	  THEN WRITE(CHR(177B),'B');
	BEGIC:=IC;BEGLC:=LC;BEGDP:=DP;BEGLEVEL:=LEVEL;
	CHCNT:=0
	END;

(* 16 - DETECT UNEXPECTED EOF *)
(* 41 - make restartable *)
     PROCEDURE PASXIT(VAR A,B,C:FILE); EXTERN;
(* 55 - ADD PROC'S FOR REQUIRE FILES *)
     PROCEDURE PUSHF(VAR F:FILE;S:STRGARR;L:INTEGER); EXTERN;
     PROCEDURE POPF(VAR F:FILE); EXTERN;
(* 107 - moved declaration of analys so can be used several places *)
     procedure analys(var f:file); extern;
(* 112 - clrbfi when error detected *)
     procedure clribf; extern;
(* 141 - better detection of number overflow *)
     function overflow:Boolean; extern;
(* 155 - source file name *)
     procedure curname(var f:file;var s:string); extern;

(* 56 - SEPARATE OUT STUFF NEEDED FOR FILE SWITCH *)
      PROCEDURE ENDSTUFF;
      VAR
	I,K: INTEGER;
       BEGIN
(* 5 - more CREF *)
	BEGOFLINE;
(* 136 - listing format *)
	WRITE(BUFFER:CHCNT); NEWLINE;
	 IF ERRORINLINE
	 THEN  %OUTPUT ERROR MESSAGES\
	   BEGIN
	     IF LISTCODE
	     THEN K := 11
	     ELSE K := 2;
	    WRITE(' ':K,'***** '); LISTCODE := FALSE;
	     IF LINENR = '-----'
	     THEN WRITE(TTY,LINECNT:5)
	     ELSE WRITE(TTY,LINENR);
	    WRITELN(TTY,' ':3,BUFFER:CHCNT); WRITE(TTY,'P*',PAGECNT:3,'** ');
(* 5 - more CREF *)
	    FOR K:=1 TO CHCNT DO
	     IF BUFFER[K] = CHR(11B)
	      THEN ERRLINE[K] := CHR(11B);
(* 136 - LISTING FORMAT *)
	    WRITE(ERRLINE :  CHCNT); WRITELN(TTY,ERRLINE : CHCNT); NEWLINE;
	    FOR K := 1 TO ERRINX DO
	    WITH ERRLIST[K] DO
	     BEGIN
	      WRITE(' ':15,ARW:1,'.',TIC,':  '); WRITE(TTY,ARW:1,'.',TIC,':  ');
	       IF ERRMPTR # NIL
	       THEN
		 BEGIN
		  ERRMPTR1 := ERRMPTR;
		  WHILE ERRMPTR1 # NIL DO
		  WITH ERRMPTR1^ DO
		   BEGIN
		     IF NMR = NUMBER
		     THEN
		       BEGIN
			 CASE FORM OF
			  C:
			     BEGIN
			      WRITE(STRING:10,' --> ');WRITE(TTY,STRING:10,' --> ')
			     END;
			  D:
			     BEGIN
			      WRITE(INTVAL:5,' --> ');WRITE(TTY,INTVAL:5,' --> ')
			     END
			 END;
			NUMBER := 0; ERRMPTR1 := NIL
		       END
		     ELSE ERRMPTR1 := NEXT
		   END
		 END;
	      I := NMR MOD 50;
	       CASE NMR DIV 50 OF
		3:
		   BEGIN
		    WRITE(ERRMESS15[I]); WRITE(TTY,ERRMESS15[I])
		   END;
		4:
		   BEGIN
		    WRITE(ERRMESS20[I]); WRITE(TTY,ERRMESS20[I])
		   END;
		5:
		   BEGIN
		    WRITE(ERRMESS25[I]); WRITE(TTY,ERRMESS25[I])
		   END;
		6:
		   BEGIN
		    WRITE(ERRMESS30[I]); WRITE(TTY,ERRMESS30[I])
		   END;
		7:
		   BEGIN
		    WRITE(ERRMESS35[I]); WRITE(TTY,ERRMESS35[I])
		   END;
		8:
		   BEGIN
		    WRITE(ERRMESS40[I]); WRITE(TTY,ERRMESS40[I])
		   END;
		9:
		   BEGIN
		    WRITE(ERRMESS45[I]); WRITE(TTY,ERRMESS45[I])
		   END;
		10:
		    BEGIN
		     WRITE(ERRMESS50[I]); WRITE(TTY,ERRMESS50[I])
		    END;
		11:
		    BEGIN
		     WRITE(ERRMESS55[I]); WRITE(TTY,ERRMESS55[I])
		    END
	       END;
(* 136 - LISTING FORMAT *)
	      newline; WRITELN(TTY)
	     END;
(* 26 - break not needed for TTY *)
	    ERRINX := 0; ERRORINLINE := FALSE;
	    FOR I := 1 TO CHCNT DO ERRLINE [I] := ' ';
	    ERRMPTR := NIL
	   END;
(* 56 -SEPARATE OUT STUFF NEEDED FOR FILE SWITCH *)
        END;

      PROCEDURE ENDOFLINE(OKEOF:BOOLEAN);
	BEGIN
	ENDSTUFF;
(* 16 - DETECT UNEXPECTED EOF *)
        IF EOF(INPUT) AND NOT OKEOF
	  THEN BEGIN
(* 136 - LISTING FORMAT *)
	  WRITE('Unexpected end of file'); NEWLINE;
	  WRITELN(TTY,'?  Unexpected end of file');
(* 176 - error for unexpected EOF in a comment *)
          if comment_page <> 0 then	(* we're in a comment *)
                 begin
                    write('Unterminated Comment at ',comment_page:0,
			  '/',comment_line:0); NEWLINE;
                    writeln(tty,'?  Unterminated Comment at ',comment_page:0,
			    '/',comment_line:0)
		 end;
(* 41 - make restartable *)
(* 107 - abort creation of rel file on error *)
	  rewrite(outputrel);
(* 112 - clrbfi when error *)
	  clribf;
(* 125 - popf to be sure we get main file closed in reqfile *)
	  if reqfile
	    then begin
	    close(input);
	    popf(input)
	    end;
	  PASXIT(INPUT,OUTPUT,OUTPUTREL)
	  END;
	READLN;
(* 147 - move incr linecnt here so first line of new page is 1 *)
	LINECNT := LINECNT + 1;
	 IF NOT EOF(INPUT)
	 THEN GETNEXTLINE;
(* 136 - listing format *)
        CHCNT := 0
       END  %ENDOFLINE\ ;

      PROCEDURE ERROR(FERRNR: INTEGER);
      VAR
	LPOS,LARW : INTEGER;
       BEGIN
	 IF NOT FOLLOWERROR
	 THEN
	   BEGIN
	    ERRORFLAG := TRUE ;
	     IF ERRINX >= MAXERR
	     THEN
	       BEGIN
		ERRLIST[MAXERR].NMR := 410; ERRINX := MAXERR
	       END
	     ELSE
	       BEGIN
		ERRINX := ERRINX + 1;
	        WITH ERRLIST[ERRINX] DO BEGIN NMR := FERRNR; TIC := '^' END
	       END;
	    FOLLOWERROR := TRUE; ERRORINLINE := TRUE;
	    IF (FERRNR # 215)
	    AND (FERRNR # 356)
	    AND (FERRNR # 405)
	    AND (FERRNR # 464)
	    THEN
	     IF EOLN(INPUT)
	     THEN ERRLINE [CHCNT] := '^'
	     ELSE ERRLINE [CHCNT-1] := '^'
	    ELSE ERRLIST[ERRINX].TIC := ' ';
	     IF ERRINX > 1
	     THEN
	      WITH ERRLIST [ ERRINX-1] DO
	       BEGIN
		LPOS := POS; LARW := ARW
	       END;
	    WITH ERRLIST [ERRINX] DO
	     BEGIN
	      POS := CHCNT;
	       IF ERRINX = 1
	       THEN ARW := 1
	       ELSE
		 IF LPOS = CHCNT
		 THEN ARW := LARW
		 ELSE ARW := LARW + 1
	     END;
	   END;
       END %ERROR\ ;

      PROCEDURE ERRORWITHTEXT ( FERRNR: INTEGER; FTEXT: ALFA ) ;
       BEGIN
	ERROR(FERRNR); NEWZ(ERRMPTR1,C);
	WITH ERRMPTR1^ DO
	 BEGIN
	  NUMBER := FERRNR; STRING := FTEXT;
	  NEXT := ERRMPTR
	 END;
	ERRMPTR := ERRMPTR1
       END %ERROR WITH TEXT\ ;

      PROCEDURE INSYMBOL;
	%READ NEXT BASIC SYMBOL OF SOURCE PROGRAM AND RETURN ITS
	 DESCRIPTION IN THE GLOBAL VARIABLES SY, OP, ID, VAL AND LGTH\
(* 114 - prevent recursive comment scanning *)
      LABEL 2;
      CONST
(* 210 - allow 9 digit hex numbers *)
	hexmax = 9;
	DIGMAX = 12; MAX8 =  37777777777B;
	TEST8 =  40000000000B;
	MIN8 = 400000000000B;
(* 142 - better real number scanning *)
	MAX10 = 3435973836; {maximum number, sans last digit}
	MAX16 = 17777777777B;
	MAXEXP = 35;
      type
(* 43 - allow 12 digit octal no. *)
	numconv=record case Boolean of
		true:(oct:packed array[1:digmax]of 0..7);
		false:(int:integer)
		       end;
(* 210 - allow 9 digit hex numbers *)
	hexconv=record case Boolean of
		true:(hex:packed array[1..hexmax] of 0..15);
		false:(int:integer)
		       end;
      VAR
(* 133 - make real numbers be read exactly *)
	I,K,ASCALE,SCALE,EXP,IVAL: INTEGER;
	RVAL,R,FAC: REAL; STRINGTOOLONG,SIGN: BOOLEAN;
	DIGIT: ARRAY [1..DIGMAX] OF 0..9;
	STRING: ARRAY [1..STRGLGTH] OF CHAR;
	LVP: CSP;
(* 43 - allow 12 digit octal no. *)
	nc:numconv;
(* 210 - allow 9 digit hex numbers *)
	hc:hexconv;

	PROCEDURE NEXTCH;
	 BEGIN
	   IF EOLN(INPUT)
	   THEN CH := ' '
	   ELSE
	     BEGIN
	      %READ(CH);\  CH := INPUT^; GET(INPUT); %THIS CHANGE SAVES 3 INSTRUCTIONS AT RUN-TIME\
	      CHCNT := CHCNT + 1;
	       IF CHCNT <= CHCNTMAX
	       THEN BUFFER[CHCNT] := CH
(* 3 - map lower case to upper.  Need separate NEXTCH for strings now,
       since we don't do mapping there. *)
	     END;
(* 105 - improve lower case mapping *)
	   ch := chr(charmap[ord(ch)]);
	 END;

	PROCEDURE NEXTSTRCH;
	 BEGIN
	   IF EOLN(INPUT)
	   THEN CH := ' '
	   ELSE
	     BEGIN
	      CH := INPUT^; GET(INPUT);
	      CHCNT := CHCNT + 1;
	       IF CHCNT <= CHCNTMAX
	       THEN BUFFER[CHCNT] := CH
	     END
	 END;

	PROCEDURE OPTIONS;
	VAR
	  LCH : CHAR; LSWITCH : BOOLEAN;
	 BEGIN
	   REPEAT
	    NEXTCH; LCH := CH;
	     IF NOT (CH IN ['\','*'])
	     THEN NEXTCH;
	     IF NOT (CH IN ['+','-'])
(* 24 - S AND H FOR STACK AND HEAP *)
(* 33 - version *)
	     THEN IF (LCH IN ['H','S','V']) AND (CH = ':')
		THEN BEGIN
		     NEXTCH;
		     INSYMBOL;
		     IF SY # INTCONST
			THEN ERROR(203)
(* 24 - S AND H FOR STACK AND HEAP *)
			ELSE BEGIN
(* 33 - version *)
			IF LCH IN ['H','S']
			  THEN BEGIN
			  IF (VAL.IVAL MOD 1000B) = 0
			    THEN VAL.IVAL := VAL.IVAL -1;
			  VAL.IVAL := (VAL.IVAL DIV 1000B)*1000B + 777B;
			  END;
		          IF LCH = 'S'
		            THEN STACK := VAL.IVAL
(* 33 - version *)
			  ELSE IF LCH = 'H'
			    THEN HEAP := VAL.IVAL
			  ELSE VERSION.WORD := VAL.IVAL
			  END
		     END
		ELSE ERROR(203)
	     ELSE
	       BEGIN
		LSWITCH := CH = '+';
(* 157 - use CASE instead of IF nest *)
		CASE LCH OF
		  'L':  LISTCODE := LSWITCH;
		  'T':  IF RESETFLAG THEN TTYINUSE := LSWITCH;
		  'M':  IF RESETFLAG THEN MAIN := LSWITCH;
		  'C':  BEGIN RUNTMCHECK := LSWITCH; ARITHCHECK := LSWITCH END;
		  'A':  ARITHCHECK := LSWITCH;
		  'Z':  ZERO := LSWITCH;
		  'D':  BEGIN
			    DEBUGSWITCH := LSWITCH;
(* 36 - allow us to reset debug at beginning *)
			    if resetflag
			      then debug := lswitch
			      else IF LSWITCH
			        THEN DEBUG := TRUE
			END
		  END
	       END;
	     IF EOLN(INPUT)
(* 16 - EOF *)
	     THEN ENDOFLINE(FALSE);
	     IF NOT ((CH IN ['\','*']) OR (LCH = 'H'))
	     THEN NEXTCH
	   UNTIL CH # ','
	 END   %OPTIONS\ ;

(* 1 - reorganized a bit here, mainly to improve comment scanning *)
	PROCEDURE NEWCH;
	BEGIN
(* 16 - EOF *)
	  IF EOLN(INPUT) THEN ENDOFLINE(FALSE);
	  NEXTCH
	END;

	PROCEDURE SCANCOMMENT(STOPCH:CHAR);
	BEGIN
(* 176 - error for unexpected EOF in a comment *)
	  comment_page := pagecnt; { pagecnt had better not be 0 }
	  comment_line := linecnt;
	  NEWCH;
	  IF CH='$' THEN OPTIONS;
(* 105 - curly brackets are now comments *)
	  if (stopch = '\') or (stopch = '}')
	    then while ch # stopch do newch
	  ELSE REPEAT WHILE CH#'*' DO NEWCH; NEXTCH UNTIL CH=STOPCH;
(* 176 - error for unexpected EOF in a comment *)
	  comment_page := 0;
(* 114 - prevent deep recursion in comment scanning *)
	  NEWCH;
	END;

       BEGIN    2:
	%INSYMBOL\
          WHILE (CH = ' ') OR (ORD(CH) = 11B) DO
	   BEGIN
	     IF EOLN(INPUT)
(* 16 - EOF *)
	     THEN ENDOFLINE(FALSE);
	    NEXTCH;
	   END;
(* 1 - code removed here for comments.  Handled better elsewhere *)
	 CASE CH OF
	  'A','B','C','D','E','F','G','H','I',
	  'J','K','L','M','N','O','P','Q','R',
	  'S','T','U','V','W','X','Y','Z':
					   BEGIN
					    K := 0 ; ID := '          ';
					     REPEAT
					       IF K < ALFALENG
					       THEN
						 BEGIN
						  K := K + 1; ID[K] := CH
						 END ;
					      NEXTCH
					     UNTIL  NOT (CH IN LETTERSDIGITSORLEFTARROW);
					    FOR I := FRW[K] TO FRW[K+1] - 1 DO
					     IF RW[I] = ID
					     THEN
					       BEGIN
						SY := RSY[I]; OP := ROP[I]; GOTO 1
					       END;
					    SY := IDENT; OP := NOOP;
1:
					   END;
	  '0','1','2','3','4','5','6','7','8','9':
						   BEGIN
(* 141 - better way to check overflow *)
						    if overflow then; {clear old errors}
						    SY := INTCONST; OP := NOOP;
(* 64 - non-loc goto *)
						    id := '          ';
						    I := 0;
						     REPEAT
						      I := I + 1;
						      if i <= alfaleng
							then id[i] := ch;
						       IF I <= DIGMAX
(* 142 - better real scanning *)
						       THEN DIGIT[I] := ORD(CH) - ORD('0');
						      NEXTCH
						     UNTIL  NOT (CH IN DIGITS);
						    IVAL := 0;
						     IF CH = 'B'
						     THEN
						       BEGIN
(* 43 - allow 12 digit octal no. *)
(* 142 - better real number scanning *)
							if i > digmax
							  then begin
							  error(174);
							  i := digmax
							  end;
							nc.int:=0;
							FOR K := 1 TO I DO
							     IF DIGIT[K] IN [8,9]
							     THEN ERROR(252)
							     else nc.oct[k+digmax-i]:=digit[k];
							val.ival := nc.int;
							NEXTCH
						       END
						     ELSE
						       BEGIN
(* 142 - better real number scanning *)
						       scale := 0;
							FOR K := 1 TO I DO
							  if scale > 0
							    then scale := scale + 1
							  else if ival < max10
							    then ival := 10*ival + digit[k]
							  else if (ival = max10) and (digit[k] <= 7)
							    then ival := 10*ival + digit[k]
							  else scale := scale + 1;
							 IF CH = '.'
							 THEN
							   BEGIN
							    NEXTCH;
							     IF CH = '.'
							     THEN CH := ':'
							     ELSE
							       BEGIN
(* 142 - better real scanning *)
								 SY := REALCONST;
								 IF  NOT (CH IN DIGITS)
								 THEN ERROR(205)
								 ELSE
								   REPEAT
							           if scale > 0
							             then scale := scale + 1
							           else if ival < max10
							             then ival := 10*ival + (ord(ch)-ord('0'))
							           else if (ival = max10) and (ch <= '7')
							             then ival := 10*ival + (ord(ch)-ord('0'))
							           else scale := scale + 1;
								    SCALE := SCALE - 1; NEXTCH
								   UNTIL  NOT (CH IN DIGITS);
							       END
							   END;
							 IF CH = 'E'
							 THEN
							   BEGIN
(* 142 - better real scan *)
							    sy := realconst;
							    NEXTCH;
							    SIGN := CH='-';
							     IF (CH='+') OR (CH='-')
							     THEN NEXTCH;
							    EXP := 0;
							     IF  NOT (CH IN DIGITS)
							     THEN ERROR(205)
							     ELSE
							       REPEAT
								EXP := 10*EXP + (ORD(CH) - ORD('0'));
								NEXTCH
							       UNTIL  NOT (CH IN DIGITS);
							     IF SIGN
							     THEN SCALE := SCALE - EXP
							     ELSE SCALE := SCALE + EXP;
							   END;
(* 142 - better real scan *)
							 if sy = realconst
							 then begin
							 rval := ival;
							 IF SCALE # 0
							 THEN
							   BEGIN
(* 113 - reorganized to handle exact fractions exactly *)
							    FAC := 10.0;
							    ASCALE := ABS(SCALE);
(* 141 - prevent overflow for exp > 32 *)
							     LOOP
							       IF ODD(ASCALE)
							       THEN if scale > 0
								 then rval := rval*FAC
								 else rval := rval/fac;
							      ASCALE := ASCALE DIV 2;
							     EXIT IF ASCALE=0;
							      FAC := SQR(FAC);
							     END;
(* 141 - better overflow error handling *)
							   IF OVERFLOW
							     THEN BEGIN
							     ERROR(206);
							     RVAL := 0.0
							     END;
							   END;
(* 142 - better real scanning *)
							 newz(lvp,reel);
							 lvp^.rval := rval;
							 val.valp := lvp
							 end {real}
							else {integer}
							 if scale = 0
							   then VAL.IVAL := IVAL
							   else begin
							     error(204);
							     val.ival := 0
							     end;
						       END
						   END;
	  '"':
	       BEGIN
		SY := INTCONST; OP := NOOP; IVAL := 0; I := 0; hc.int := 0;
		NEXTCH;
		WHILE CH IN HEXADIGITS DO
		 BEGIN
		     i := i + 1;
		     if i <= hexmax then
			 IF CH IN DIGITS
			     THEN  digit[i] := 16*IVAL + ORD(CH) - ORD('0')
			     ELSE  digit[i] := 16*IVAL + ORD(CH) - 67B;
		     NEXTCH
		 END;
		if i > hexmax then
		    begin
			error(174);
			i := hexmax
		    end;
		for k := 1 to i do
		    hc.hex[k+hexmax-i] := digit[k];
		VAL.IVAL := hc.int;
	       END;
	  '''':
		BEGIN
		 LGTH := 0; SY := STRINGCONST;	OP := NOOP;STRINGTOOLONG := FALSE;
		  REPEAT
		    REPEAT
(* 3 - different NEXTCH so don't map lower case, etc. *)
		     NEXTSTRCH;
		      IF LGTH < STRGLGTH
		      THEN
			BEGIN
			 LGTH := LGTH + 1; STRING[LGTH] := CH
			END
		      ELSE STRINGTOOLONG := TRUE
		    UNTIL (EOLN(INPUT)) OR (CH = '''');
		    IF STRINGTOOLONG
		    THEN ERROR(301);
		    IF EOLN(INPUT)  AND  (CH#'''')
		    THEN ERROR(351)
(* 3 - different NEXTCH so don't map lower case, etc. *)
(* 6 - don't use nextstrch for char after end of string[caused loop] *)
		    ELSE NEXTCH  %this is embedded ' or char after string\
		  UNTIL CH # '''';
		 LGTH := LGTH - 1;   %NOW LGTH = NR OF CHARS IN STRING\
		  IF LGTH = 1
		  THEN VAL.IVAL := ORD(STRING[1])
		  ELSE
		    BEGIN
		     NEWZ(LVP,STRG:LGTH);
		     WITH LVP^ DO
		      BEGIN
		       SLGTH := LGTH;
		       FOR I := 1 TO LGTH DO SVAL[I] := STRING[I]
		      END;
		     VAL.VALP := LVP
		    END
		END;
	  ':':
	       BEGIN
		OP := NOOP; NEXTCH;
		 IF CH = '='
		 THEN
		   BEGIN
		    SY := BECOMES; NEXTCH
		   END
		 ELSE SY := COLON
	       END;
	  '.':
	       BEGIN
		OP := NOOP; NEXTCH;
		 IF CH = '.'
		 THEN
		   BEGIN
		    SY := COLON; NEXTCH
		   END
		 ELSE SY := PERIOD
	       END;
	  '?','*','&','+','-','!','\',
(* 1 - / now handled elsewhere *)
	  '@','#','=',
	  ')','[',']',',',';','^','_','$':
					   BEGIN
					    SY := SSY[CH]; OP := SOP[CH];
					    NEXTCH
					   END;

	  '(':
	       BEGIN
		NEXTCH;
(* 1 - improved comment scanning *)
		IF CH='*' THEN BEGIN SCANCOMMENT(')'); GOTO 2 END
		ELSE BEGIN SY := LPARENT; OP := NOOP END
	       END;


	  '{':
	        BEGIN SCANCOMMENT('}'); GOTO 2 END;
	  '%':
		BEGIN SCANCOMMENT('\'); GOTO 2 END;

	  '/':
		BEGIN
		  NEXTCH;
		  IF CH='*' THEN BEGIN SCANCOMMENT('/'); GOTO 2 END
		  ELSE BEGIN SY := MULOP; OP := RDIV END
		END;


	  '<','>':
		   BEGIN
		    SY := SSY[CH]; OP := SOP[CH]; NEXTCH;
		     IF CH = '='
		     THEN
		       BEGIN
			 IF OP = LTOP
			 THEN OP := LEOP
			 ELSE OP := GEOP;
			NEXTCH
		       END
(* 6 - allow <> for not equals *)
		     ELSE IF (CH = '>') AND (OP = LTOP)
		       THEN
			BEGIN
			OP := NEOP;
			NEXTCH
			END
		   END;
(* 6 - add error msg in case of illegal character *)
	  OTHERS:
		BEGIN
		ERROR(216);
		NEWCH;
		INSYMBOL
		END
	 END %CASE\
       END %INSYMBOL\ ;

      PROCEDURE ENTERID(FCP: CTP);
	%ENTER ID POINTED AT BY FCP INTO THE NAME-TABLE,
	 WHICH ON EACH DECLARATION LEVEL IS ORGANISED AS
	 AN UNBALANCED BINARY TREE\
      VAR
	NAM: ALFA; LCP, LCP1: CTP; LLEFT: BOOLEAN;
       BEGIN
	NAM := FCP^.NAME;
(* 5 - CREF *)
        IF CREF
	  THEN WRITE(CHR(1B),CHR(21),NAM,' ',DISPLAY[TOP].BLKNAME,CHR(2B));
	LCP := DISPLAY[TOP].FNAME;
	 IF LCP = NIL
	 THEN
	  DISPLAY[TOP].FNAME := FCP
	 ELSE
	   BEGIN
	     REPEAT
	      LCP1 := LCP;
	       IF LCP^.NAME <= NAM
	       THEN
		 BEGIN
		   IF LCP^.NAME = NAM
		   THEN ERROR(302) %NAME CONFLICT\;
		  LCP := LCP^.RLINK; LLEFT := FALSE
		 END
	       ELSE
		 BEGIN
		  LCP := LCP^.LLINK; LLEFT := TRUE
		 END
	     UNTIL LCP = NIL;
	     IF LLEFT
	     THEN LCP1^.LLINK := FCP
	     ELSE LCP1^.RLINK := FCP
	   END;
	WITH FCP^ DO
	 BEGIN
	  LLINK := NIL; RLINK := NIL; SELFCTP := NIL
	 END
       END %ENTERID\ ;

      PROCEDURE SEARCHSECTION(FCP: CTP; VAR FCP1: CTP);
	%TO FIND RECORD FIELDS AND FORWARD DECLARED PROCEDURE ID'S
	 --> PROCEDURE PROCEDUREDECLARATION
	 --> PROCEDURE SELECTOR\
       BEGIN
	WHILE FCP # NIL DO
	WITH FCP^ DO
	 BEGIN
	   IF NAME = ID
	   THEN GOTO 1;
	   IF NAME < ID
	   THEN FCP := RLINK
	   ELSE FCP := LLINK
	 END;
1:
	FCP1 := FCP
       END %SEARCHSECTION\ ;

      PROCEDURE SEARCHID(FIDCLS: SETOFIDS; VAR FCP: CTP);
      VAR
	LCP: CTP;
       BEGIN
	FOR DISX := TOP DOWNTO 0 DO
	 BEGIN
	  LCP := DISPLAY[DISX].FNAME;
	  WHILE LCP # NIL DO
	  WITH LCP^ DO
	   IF NAME = ID
	   THEN
	     IF KLASS IN FIDCLS
	     THEN GOTO 1
	     ELSE
	       BEGIN
		 IF PRTERR
		 THEN ERROR(401);
(* 170 - fix error handling for forwards *)
		GOTO 2
	       END
	   ELSE
	     IF NAME < ID
	     THEN
	      LCP := RLINK
	     ELSE LCP := LLINK
	 END;
2:	 LCP := NIL;  {Use NIL if don't find something better below}
(* 5 - save some info for so CREF will know the block name *)
	 DISX := TOP; %IF FORWARD, WILL BE IN THIS BLOCK\
(* 114 - use only real block names *)
(* 116 - more elegant way to do this *)
         WHILE DISPLAY[DISX].OCCUR <> BLCK DO
	   DISX := DISX - 1;
	%SEARCH NOT SUCCSESSFUL; SUPPRESS ERROR MESSAGE IN CASE
	 OF FORWARD REFERENCED TYPE ID IN POINTER TYPE DEFINITION
	 --> PROCEDURE SIMPLETYPE\
	 IF PRTERR
	 THEN
	   BEGIN
	    ERROR(253);
	    %TO AVOID RETURNING NIL, REFERENCE AN ENTRY
	     FOR AN UNDECLARED ID OF APPROPRIATE CLASS
	     --> PROCEDURE ENTERUNDECL\
	     IF TYPES IN FIDCLS
	     THEN LCP := UTYPPTR
	     ELSE
	       IF VARS IN FIDCLS
	       THEN LCP := UVARPTR
	       ELSE
		 IF FIELD IN FIDCLS
		 THEN LCP := UFLDPTR
		 ELSE
		   IF KONST IN FIDCLS
		   THEN LCP := UCSTPTR
		   ELSE
		     IF PROC IN FIDCLS
		     THEN LCP := UPRCPTR
(* 64 - non-loc gotos *)
		     ELSE IF FUNC IN FIDCLS
			THEN LCP := UFCTPTR
			ELSE LCP := ULBLPTR;
	   END;
1:
(* 5 - CREF *)
	IF CREF
	  THEN WRITE(CHR(1B),CHR(21),ID,' ',DISPLAY[DISX].BLKNAME);
	FCP := LCP
       END %SEARCHID\ ;

      PROCEDURE GETBOUNDS(FSP: STP; VAR FMIN,FMAX: INTEGER);
	%GET INTERNAL BOUNDS OF SUBRANGE OR SCALAR TYPE\
	%ASSUME (FSP # NIL) AND (FSP^.FORM <= SUBRANGE) AND (FSP # INTPTR)
	 AND  NOT COMPTYPES(REALPTR,FSP)\
       BEGIN
	WITH FSP^ DO
	 IF FORM = SUBRANGE
	 THEN
	   BEGIN
	    FMIN := MIN.IVAL; FMAX := MAX.IVAL
	   END
	 ELSE
	   BEGIN
	    FMIN := 0;
	     IF FSP = CHARPTR
	     THEN FMAX := 177B
	     ELSE
	       IF FCONST # NIL
	       THEN
		FMAX := FCONST^.VALUES.IVAL
	       ELSE FMAX := 0
	   END
       END %GETBOUNDS\ ;

(* 6 - move error stuff outside BLOCK so PROGSTAT can use it *)
	PROCEDURE SKIPIFERR(FSYINSYS:SETOFSYS; FERRNR:INTEGER; FSKIPSYS: SETOFSYS);
	VAR
	  I,OLDCHCNT,OLDLINECNT : INTEGER;
	 BEGIN
	   IF NOT (SY IN FSYINSYS)
	   THEN
	     BEGIN
	      ERROR(FERRNR);
	      OLDLINECNT := LINECNT; OLDCHCNT := CHCNT;
	      WHILE NOT (SY IN FSKIPSYS OR FSYINSYS) DO
	       BEGIN
		 IF OLDLINECNT # LINECNT
		 THEN OLDCHCNT := 1;
		FOR I := OLDCHCNT TO CHCNT-1 DO
		 IF I <= CHCNTMAX
		 THEN ERRLINE [I] := '*';
		OLDCHCNT := CHCNT; OLDLINECNT := LINECNT; ERRORINLINE := TRUE;
		INSYMBOL
	       END;
	      %SKIP INPUT STRING UNTIL RELEVANT SYMBOL FOUND\
	     END;
	  FOLLOWERROR := FALSE
	 END;

	PROCEDURE IFERRSKIP(FERRNR: INTEGER; FSYS: SETOFSYS);
	 BEGIN
	  SKIPIFERR(FSYS,FERRNR,FSYS)
	 END;

	PROCEDURE ERRANDSKIP(FERRNR: INTEGER; FSYS: SETOFSYS);
	 BEGIN
	  SKIPIFERR([ ],FERRNR,FSYS)
	 END;

(* 6 - add PROGRAM statement *)
      PROCEDURE PROGSTAT;
(* 34 - allow list of entry point names *)
	  VAR STSYM,ENDSYM:SYMBOL;
        BEGIN
	IF SY=PROGRAMSY
	  THEN
	    BEGIN
(* 34 - allow entry point names *)
	    IF MAIN
	      THEN BEGIN STSYM:=LPARENT; ENDSYM := RPARENT END
	      ELSE BEGIN STSYM:=COMMA; ENDSYM := SEMICOLON END;
	    INSYMBOL;
	    IF SY # IDENT THEN ERROR(209);
(* 33 NO LONGER NEED ENTRY *)
	    FILENAME := ID;
	    INSYMBOL;
(* 34 - DIFFERENT SYNTAX FOR ENTRY POINTS *)
	    IF SY = STSYM
	     THEN BEGIN
	      REPEAT
	      INSYMBOL;
	      IF NOT (SY = IDENT)
		THEN ERROR(209);
(* 33 - USE FILE NAMES *)
	      NEWZ(NPROGFILE);
	      NPROGFILE^.FILID := ID;
	      NPROGFILE^.NEXT := NIL;
	      IF FPROGFILE = NIL
		THEN BEGIN
		FPROGFILE := NPROGFILE;
		LPROGFILE := NPROGFILE
		END
	       ELSE BEGIN
		LPROGFILE^.NEXT := NPROGFILE;
		LPROGFILE := NPROGFILE
		END;
	      INSYMBOL;
(* 61 - allow +* in tops20 *)
(* 144 - allow this stuff in tops10, too *)
	      if (sy=colon) and main
		then begin
		insymbol;
		while sy in [addop,mulop,relop] do
		  begin
		  if (op = mul) and (not tops10)
		    then nprogfile^.wild := true
		  else if op = plus
		    then nprogfile^.newgen := true
		  else if op = minus
		    then nprogfile^.oldfile := true
(* 64 - input:/ *)
		  else if op = rdiv
		    then nprogfile^.interact := true
(* 172 - new EOLN treatment *)
		  else if op = neop
		    then nprogfile^.seeeol := true
		  else error(158);
		  insymbol
		  end;
		end;
(* 34 - DIFFERENT SYNTAX FOR ENTRY POINTS *)
	      IFERRSKIP(158,[ENDSYM,COMMA])
	      UNTIL SY=ENDSYM;
	     IF MAIN THEN INSYMBOL
	     END;
(* 21 - Allow null file list in prog. statement *)
	    IFERRSKIP(156,[SEMICOLON]);
	    INSYMBOL
	    END
	END;

      PROCEDURE BLOCK(FPROCP: CTP; FSYS,LEAVEBLOCKSYS: SETOFSYS);
      VAR
(* 56 - add reqfile for require files *)
(* 125 - reqfile moved *)
(* 65 - remove exit labels *)
	LSY: SYMBOL;
(* 136 - listing format *)
	ORIGLINENR:PACKED ARRAY[1:5]OF CHAR;
	ORIGPAGECNT,ORIGSUBPAGE,ORIGLINECNT:INTEGER; 
	ORIGPAGE:PAGEELEM; ORIGCH:CHAR;
(* 24 - testpacked no longer needed *)
	LCPAR: ADDRRANGE;%SAVES LOCATION FROM WHERE
			  LOCAL AREAS ARE SET TO ZERO\
	HEAPMARK,GLOBMARK: INTEGER;
	FORWPTR : CTP;		 %TEST FOR FORWORD DECLARED PROCEDURES\


	PROCEDURE CONSTANT(FSYS: SETOFSYS; VAR FSP: STP; VAR FVALU: VALU);
	VAR
	  LSP,LSP1: STP; LCP: CTP; SIGN: (NONE,POS,NEG);
	 BEGIN
	  LSP := NIL; FVALU.IVAL := 0;
	  SKIPIFERR(CONSTBEGSYS,207,FSYS);
	   IF SY IN CONSTBEGSYS
	   THEN
	     BEGIN
	       IF SY = STRINGCONST
	       THEN
		 BEGIN
		   IF LGTH = 1
		   THEN LSP := CHARPTR
		   ELSE
		     IF LGTH = ALFALENG
		     THEN LSP := ALFAPTR
		     ELSE
		       BEGIN
			NEWZ(LSP,ARRAYS); NEWZ(LSP1,SUBRANGE);
			WITH LSP^ DO
			 BEGIN
			  AELTYPE := CHARPTR; INXTYPE := LSP1;
			  SIZE := (LGTH+4) DIV 5; ARRAYPF := TRUE;
(* 211 - make PASDDT able to see this *)
			  BITSIZE := BITMAX; SELFSTP := NIL
			 END;
			WITH LSP1^ DO
			 BEGIN
			  SIZE := 1; BITSIZE := BITMAX;
			  MIN.IVAL := 1; MAX.IVAL := LGTH; RANGETYPE  := NIL
			 END
		       END;
		  FVALU := VAL; INSYMBOL
		 END
	       ELSE
		 BEGIN
		  SIGN := NONE;
		   IF (SY = ADDOP) AND (OP IN [PLUS,MINUS])
		   THEN
		     BEGIN
		       IF OP = PLUS
		       THEN SIGN := POS
		       ELSE SIGN := NEG;
		      INSYMBOL
		     END;
		   IF SY = IDENT
		   THEN
		     BEGIN
		      SEARCHID([KONST],LCP);
		      WITH LCP^ DO
		       BEGIN
			LSP := IDTYPE; FVALU := VALUES
		       END;
		       IF SIGN # NONE
		       THEN
			 IF LSP = INTPTR
			 THEN
			   BEGIN
			     IF SIGN = NEG
			     THEN FVALU.IVAL := -FVALU.IVAL
			   END
			 ELSE
			   IF LSP = REALPTR
			   THEN
			     BEGIN
			       IF SIGN = NEG
			       THEN
				FVALU.VALP^.RVAL := -FVALU.VALP^.RVAL
			     END
			   ELSE ERROR(167);
		      INSYMBOL;
		     END
		   ELSE
		     IF SY = INTCONST
		     THEN
		       BEGIN
			 IF SIGN = NEG
			 THEN VAL.IVAL := -VAL.IVAL;
			LSP := INTPTR; FVALU := VAL; INSYMBOL
		       END
		     ELSE
		       IF SY = REALCONST
		       THEN
			 BEGIN
			   IF SIGN = NEG
			   THEN VAL.VALP^.RVAL := -VAL.VALP^.RVAL;
			  LSP := REALPTR; FVALU := VAL; INSYMBOL
			 END
		       ELSE ERRANDSKIP(168,FSYS)
		 END;
	      IFERRSKIP(166,FSYS);
	     END;
	  FSP := LSP
	 END %CONSTANT\ ;

	FUNCTION COMPTYPES(FSP1,FSP2: STP) : BOOLEAN;
	  %DECIDE WHETHER STRUCTURES POINTED AT BY FSP1 AND FSP2 ARE COMPATIBLE\
	VAR
	  NXT1,NXT2: CTP; COMP: BOOLEAN; LMIN,LMAX,I: INTEGER;
	  LTESTP1,LTESTP2: TESTP;
	 BEGIN
	   IF FSP1 = FSP2
	   THEN COMPTYPES := TRUE
	   ELSE
	     IF (FSP1 # NIL) AND (FSP2 # NIL)
	     THEN
	       IF FSP1^.FORM = FSP2^.FORM
	       THEN
		 CASE FSP1^.FORM OF
		  SCALAR:
			 COMPTYPES := FALSE;
			 % IDENTICAL SCALARS DECLARED ON DIFFERENT LEVELS ARE
			  NOT RECOGNIZED TO BE COMPATIBLE\
		  SUBRANGE:
			   COMPTYPES := COMPTYPES(FSP1^.RANGETYPE,FSP2^.RANGETYPE);
		  POINTER:
			   BEGIN
			    COMP := FALSE; LTESTP1 := GLOBTESTP; LTESTP2 := GLOBTESTP;
			    WHILE LTESTP1 # NIL DO
			    WITH LTESTP1^ DO
			     BEGIN
			       IF (ELT1 = FSP1^.ELTYPE) AND (ELT2 = FSP2^.ELTYPE)
			       THEN COMP := TRUE;
			      LTESTP1 := LASTTESTP
			     END;
			     IF NOT COMP
			     THEN
			       BEGIN
				NEWZ(LTESTP1);
				WITH LTESTP1^ DO
				 BEGIN
				  ELT1 := FSP1^.ELTYPE;
				  ELT2 := FSP2^.ELTYPE;
				  LASTTESTP := GLOBTESTP
				 END;
				GLOBTESTP := LTESTP1; COMP := COMPTYPES(FSP1^.ELTYPE,FSP2^.ELTYPE)
			       END;
			    COMPTYPES := COMP; GLOBTESTP := LTESTP2
			   END;
		  POWER:
			COMPTYPES := COMPTYPES(FSP1^.ELSET,FSP2^.ELSET);
		  ARRAYS:
			  BEGIN
			   GETBOUNDS (FSP1^.INXTYPE,LMIN,LMAX);
			   I := LMAX-LMIN;
			   GETBOUNDS (FSP2^.INXTYPE,LMIN,LMAX);
			   COMPTYPES := COMPTYPES(FSP1^.AELTYPE,FSP2^.AELTYPE)
			   AND (FSP1^.ARRAYPF = FSP2^.ARRAYPF) AND ( I = LMAX - LMIN ) ;
			  END;
			 %ALTERNATIVES: -- ADD A THIRD BOOLEAN TERM: INDEXTYPE MUST
			  BE COMPATIBLE. MAY GIVE TROUBLE FOR ASSIGNMENT OF STRINGCONSTANTS
			  -- ADD A FOURTH BOOLEAN TERM: LOWBOUNDS MUST
			  BE THE SAME\
		  RECORDS:
			   BEGIN
			    NXT1 := FSP1^.FSTFLD; NXT2 := FSP2^.FSTFLD; COMP := TRUE;
			    WHILE (NXT1 # NIL) AND (NXT2 # NIL) DO
			     BEGIN
			      COMP := COMPTYPES(NXT1^.IDTYPE,NXT2^.IDTYPE) AND COMP;
			      NXT1 := NXT1^.NEXT; NXT2 := NXT2^.NEXT
			     END;
			    COMPTYPES := COMP AND (NXT1 = NIL) AND (NXT2 = NIL)
			    AND (FSP1^.RECVAR = NIL) AND (FSP2^.RECVAR = NIL)
			   END;
			  %IDENTICAL RECORDS ARE RECOGNIZED TO BE COMPATIBLE
			   IFF NO VARIANTS OCCUR\
		  FILES:
			COMPTYPES := COMPTYPES(FSP1^.FILTYPE,FSP2^.FILTYPE)
		 END %CASE\
	       ELSE %FSP1^.FORM # FSP2^.FORM\
		 IF FSP1^.FORM = SUBRANGE
		 THEN
		  COMPTYPES := COMPTYPES(FSP1^.RANGETYPE,FSP2)
		 ELSE
		   IF FSP2^.FORM = SUBRANGE
		   THEN
		    COMPTYPES := COMPTYPES(FSP1,FSP2^.RANGETYPE)
		   ELSE COMPTYPES := FALSE
	     ELSE COMPTYPES := TRUE
	 END %COMPTYPES\ ;

	FUNCTION STRING(FSP: STP) : BOOLEAN;
	 BEGIN
	  STRING := FALSE;
	   IF FSP # NIL
	   THEN
	     IF FSP^.FORM = ARRAYS
	     THEN
	       IF COMPTYPES(FSP^.AELTYPE,CHARPTR)
	       THEN STRING := TRUE
	 END %STRING\ ;

	PROCEDURE TYP(FSYS: SETOFSYS; VAR FSP: STP; VAR FSIZE: ADDRRANGE;
		      VAR FBITSIZE: BITRANGE);
	VAR
(* 173 - internal files *)
	  FHASFILE,LHASFILE:BOOLEAN;
	  LSP,LSP1,LSP2: STP; OLDTOP: DISPRANGE; LCP: CTP;
	  LSIZE,DISPL: ADDRRANGE; I,LMIN,LMAX: INTEGER;
	  PACKFLAG: BOOLEAN; LBITSIZE: BITRANGE;
	  LBTP: BTP; BITCOUNT:INTEGER;

(* 104 - check structure sizes *)
	  function checksize(i:addrrange):addrrange;
	    begin
	    if abs(i) <= 377777B
	      then checksize := i
	      else begin
	      error(266);
	      checksize := 0
	      end
	    end;

	  FUNCTION LOG2(FVAL: INTEGER): BITRANGE;
	  VAR
	    E: BITRANGE; H: INTEGER;
	   BEGIN
	    E :=0;
	    H := 1;
(* 135 - numbers > 200 000 000 000B didn't work. *)
	      {There are two complicating issues here:
		1 - 200 000 000 000 is the highest power of 2, so the
		  loop below goes forever for them
		2 - the caller has often added 1, thus making 377 777 777 777
		  into 400 000 000 000, which is negative!!
		In both of these cases we want to return 35}
	    IF (FVAL-1) >= 200000000000B 
	      THEN E := 35
	      ELSE REPEAT
	        E := E + 1; H := H * 2
	       UNTIL FVAL <= H;
	    LOG2 := E
	   END %LOG2\;

	  PROCEDURE SIMPLETYPE(FSYS: SETOFSYS; VAR FSP: STP; VAR FSIZE: ADDRRANGE;
			       VAR FBITSIZE: BITRANGE);
	  VAR
	    LSP,LSP1: STP; LCP,LCP1: CTP; TTOP: DISPRANGE;
	    LCNT: INTEGER; LVALU: VALU; LBITSIZE: BITRANGE;
	   BEGIN
	    FSIZE := 1;
	    SKIPIFERR(SIMPTYPEBEGSYS,208,FSYS);
	     IF SY IN SIMPTYPEBEGSYS
	     THEN
	       BEGIN
		 IF SY = LPARENT
		 THEN
		   BEGIN
		    TTOP := TOP;   %DECL. CONSTS LOCAL TO INNERMOST BLOCK\
		    WHILE DISPLAY[TOP].OCCUR # BLCK DO TOP := TOP - 1;
		    NEWZ(LSP,SCALAR,DECLARED);
		    LSP^.SIZE := 1;
		    LCP1 := NIL; LCNT := 0;
		     REPEAT
		      INSYMBOL;
		       IF SY = IDENT
		       THEN
			 BEGIN
			  NEWZ(LCP,KONST);
			  WITH LCP^ DO
			   BEGIN
			    NAME := ID; IDTYPE := LSP; NEXT := LCP1;
			    VALUES.IVAL := LCNT;
			   END;
			  ENTERID(LCP);
			  LCNT := LCNT + 1;
			  LCP1 := LCP; INSYMBOL
			 END
		       ELSE ERROR(209);
		      IFERRSKIP(166,FSYS OR [COMMA,RPARENT])
		     UNTIL SY # COMMA;
		    TOP := TTOP;
		    WITH LSP^ DO
		     BEGIN
		      SELFSTP := NIL; FCONST := LCP1; BITSIZE := LOG2(LCNT)
		     END;
		     IF SY = RPARENT
		     THEN INSYMBOL
		     ELSE ERROR(152)
		   END
		 ELSE
		   BEGIN
		     IF SY = IDENT
		     THEN
		       BEGIN
			SEARCHID([TYPES,KONST],LCP);
			INSYMBOL;
			 IF LCP^.KLASS = KONST
			 THEN
			   BEGIN
			    NEWZ(LSP,SUBRANGE);
			    WITH LSP^, LCP^ DO
			     BEGIN
			      SELFSTP := NIL; RANGETYPE := IDTYPE;
			       IF STRING(RANGETYPE)
			       THEN
				 BEGIN
				  ERROR(303); RANGETYPE := NIL
				 END;
			      MIN := VALUES; SIZE := 1
			     END;
			     IF SY = COLON
			     THEN INSYMBOL
			     ELSE ERROR(151);
			    CONSTANT(FSYS,LSP1,LVALU);
			    WITH LSP^ DO
			     BEGIN
			      MAX := LVALU;
			       IF MIN.IVAL<0
			       THEN BITSIZE := BITMAX
			       ELSE BITSIZE := LOG2(MAX.IVAL + 1);
			       IF RANGETYPE # LSP1
			       THEN ERROR(304)
			     END;
			   END
			 ELSE
			   BEGIN
			    LSP := LCP^.IDTYPE;
			     IF LSP # NIL
			     THEN FSIZE := LSP^.SIZE;
			   END
		       END %SY = IDENT\
		     ELSE
		       BEGIN
			NEWZ(LSP,SUBRANGE);
			CONSTANT(FSYS OR [COLON],LSP1,LVALU);
			 IF STRING(LSP1)
			 THEN
			   BEGIN
			    ERROR(303); LSP1 := NIL
			   END;
			WITH LSP^ DO
			 BEGIN
			  RANGETYPE := LSP1; MIN := LVALU; SIZE := 1
			 END;
			 IF SY = COLON
			 THEN INSYMBOL
			 ELSE ERROR(151);
			CONSTANT(FSYS,LSP1,LVALU);
			WITH LSP^ DO
			 BEGIN
			  SELFSTP := NIL; MAX := LVALU;
			   IF MIN.IVAL<0
			   THEN BITSIZE := BITMAX
			   ELSE BITSIZE := LOG2(MAX.IVAL + 1);
			   IF RANGETYPE # LSP1
			   THEN ERROR(304)
			 END
		       END;
		     IF LSP # NIL
		     THEN
		      WITH LSP^ DO
		       IF FORM = SUBRANGE
		       THEN
			 IF RANGETYPE # NIL
			 THEN
			   IF RANGETYPE = REALPTR
			   THEN
(* 106 - make subranges of real illegal *)
			     error(210)
			   ELSE
			     IF MIN.IVAL > MAX.IVAL
			     THEN ERROR(451)
		   END;
		FSP := LSP;
		 IF LSP#NIL
		 THEN FBITSIZE := LSP^.BITSIZE
		 ELSE FBITSIZE := 0;
		IFERRSKIP(166,FSYS)
	       END
	     ELSE
	       BEGIN
		FSP := NIL; FBITSIZE := 0
	       END
	   END %SIMPLETYPE\ ;

(* 173 - internal files *)
	  PROCEDURE FIELDLIST(FSYS: SETOFSYS; VAR FRECVAR: STP; VAR FFIRSTFIELD: CTP; VAR FHASFILE:BOOLEAN);
	  VAR
	    LHASFILE:BOOLEAN;
	    LCP,LCP1,NXT,NXT1: CTP; LSP,LSP1,LSP2,LSP3,LSP4,TAGSP: STP;
	    MINSIZE,MAXSIZE,LSIZE: ADDRRANGE; LVALU: VALU;
	    LBITSIZE: BITRANGE;
	    LBTP: BTP; MINBITCOUNT:INTEGER;
	    LID : ALFA ;

	    PROCEDURE RECSECTION( VAR FCP: CTP; FSP: STP );
	     BEGIN
	       IF NOT PACKFLAG OR (LSIZE > 1)  OR  (LBITSIZE = 36)
	       THEN
		 BEGIN
		   IF BITCOUNT > 0
		   THEN
		     BEGIN
		      DISPL := DISPL + 1; BITCOUNT := 0
		     END;
		  WITH FCP^ DO
		   BEGIN
		    IDTYPE := FSP; FLDADDR := DISPL;
		    PACKF := NOTPACK; FCP := NEXT;
		    DISPL := DISPL + LSIZE
		   END
		 END
	       ELSE %PACK RECORD-SECTION\

		 BEGIN
		  BITCOUNT := BITCOUNT + LBITSIZE;
		   IF BITCOUNT>BITMAX
		   THEN
		     BEGIN
		      DISPL := DISPL + 1;
		      BITCOUNT := LBITSIZE
		     END;
		   IF (LBITSIZE = 18)  AND  (BITCOUNT IN [18,36])
		   THEN
		     BEGIN
		      WITH FCP^ DO
		       BEGIN
			IDTYPE := FSP;
			FLDADDR := DISPL;
			 IF BITCOUNT = 18
			 THEN PACKF := HWORDL
			 ELSE PACKF := HWORDR;
			FCP := NEXT
		       END
		     END
		   ELSE
		     BEGIN
		      NEWZ(LBTP,RECORDD);
		      WITH LBTP^.BYTE DO
		       BEGIN
			SBITS := LBITSIZE;
			PBITS := BITMAX - BITCOUNT;
			RELADDR := DISPL;
			DUMMYBIT := 0;
			IBIT := 0;
			IREG := TAC
		       END;
		      WITH LBTP^ DO
		       BEGIN
			LAST := LASTBTP; FIELDCP := FCP
		       END;
		      LASTBTP := LBTP;
		      WITH FCP^ DO
		       BEGIN
			IDTYPE := FSP;
			PACKF := PACKK;
			FCP := NEXT
		       END
		     END
		 END
	     END % RECSECTION \ ;
	   BEGIN
(* 173 - internal files *)
(* 166 - In case of null record declaration, FRECVAR was getting junk.
	I don't understand the logic of this routine, but initializing
	it to NIL seems safe enough *)
	    NXT1 := NIL; LSP := NIL; FRECVAR := NIL; FHASFILE := FALSE;
(* 21 - Allow null fieldlist (added FSYS OR to next statement) *)
(* 65 - allow extra semicolons *)
	    while sy=semicolon do
		insymbol;
	    SKIPIFERR(FSYS OR [IDENT,CASESY],452,FSYS);
	    WHILE SY = IDENT DO
	     BEGIN
	      NXT := NXT1;
	       LOOP
		 IF SY = IDENT
		 THEN
		   BEGIN
		    NEWZ(LCP,FIELD);
		    WITH LCP^ DO
		     BEGIN
		      NAME := ID; IDTYPE := NIL; NEXT := NXT
		     END;
		    NXT := LCP;
		    ENTERID(LCP);
		    INSYMBOL
		   END
		 ELSE ERROR(209);
		SKIPIFERR([COMMA,COLON],166,FSYS OR [SEMICOLON,CASESY]);
	       EXIT IF SY # COMMA;
		INSYMBOL
	       END;
	       IF SY = COLON
	       THEN INSYMBOL
	       ELSE ERROR(151);
	      TYP(FSYS OR [CASESY,SEMICOLON],LSP,LSIZE,LBITSIZE);
	       IF LSP # NIL
	       THEN
(* internal files *)
		 IF (LSP^.FORM = FILES) OR LSP^.HASFILE
		 THEN FHASFILE := TRUE;
	      WHILE NXT # NXT1 DO    RECSECTION(NXT,LSP); %RESERVES SPACE FOR ONE RECORDSECTION \
	      NXT1 := LCP;
(* 64 - allow null entry *)
	       WHILE SY = SEMICOLON DO
		 BEGIN
		  INSYMBOL;
		  SKIPIFERR(FSYS OR [IDENT,CASESY,SEMICOLON],452,FSYS)
		 END
	     END %WHILE\;
	    NXT := NIL;
	    WHILE NXT1 # NIL DO
	    WITH NXT1^ DO
	     BEGIN
	      LCP := NEXT; NEXT := NXT; NXT := NXT1; NXT1 := LCP
	     END;
	    FFIRSTFIELD := NXT;
	     IF SY = CASESY
	     THEN
	       BEGIN
		LCP:=NIL;  %POSSIBILITY OF NO TAGFIELDIDENTIFIER\
		INSYMBOL;
		 IF SY = IDENT
		 THEN
		   BEGIN
		    LID := ID ;
		    INSYMBOL ;
		     IF (SY#COLON) AND (SY#OFSY)
		     THEN
		       BEGIN
			ERROR(151) ;
			ERRANDSKIP(160,FSYS OR [LPARENT])
		       END
		     ELSE
		       BEGIN
			 IF SY = COLON
			 THEN
			   BEGIN
			    NEWZ(LSP,TAGFWITHID);
			    NEWZ(LCP,FIELD) ;
			    WITH LCP^ DO
			     BEGIN
			      NAME := LID ; IDTYPE := NIL ; NEXT := NIL
			     END ;
			    ENTERID(LCP) ;
			    INSYMBOL ;
			     IF SY # IDENT
			     THEN
			       BEGIN
				ERRANDSKIP(209,FSYS OR [LPARENT]) ; GOTO 1
			       END
			     ELSE
			       BEGIN
				LID := ID ;
				INSYMBOL ;
				 IF SY # OFSY
				 THEN
				   BEGIN
				    ERRANDSKIP(160,FSYS OR [LPARENT]) ; GOTO 1
				   END
			       END
			   END
			 ELSE NEWZ(LSP,TAGFWITHOUTID) ;
			WITH LSP^ DO
			 BEGIN
			  SIZE:= 0 ; SELFSTP := NIL ;
			  FSTVAR := NIL;
			   IF FORM=TAGFWITHID
			   THEN TAGFIELDP:=NIL
			   ELSE TAGFIELDTYPE := NIL
			 END;
			FRECVAR := LSP;
			ID := LID ;
			SEARCHID([TYPES],LCP1) ;
			TAGSP := LCP1^.IDTYPE;
			 IF TAGSP # NIL
			 THEN
			   IF (TAGSP^.FORM <= SUBRANGE) OR STRING(TAGSP)
			   THEN
			     BEGIN
			       IF COMPTYPES(REALPTR,TAGSP)
			       THEN ERROR(210)
			       ELSE
				 IF STRING(TAGSP)
				 THEN ERROR(169);
			      WITH LSP^ DO
			       BEGIN
				BITSIZE := TAGSP^.BITSIZE;
				 IF FORM = TAGFWITHID
				 THEN TAGFIELDP := LCP
				 ELSE TAGFIELDTYPE := TAGSP;
			       END;
			       IF LCP # NIL
			       THEN
				 BEGIN
				  LBITSIZE :=TAGSP^.BITSIZE;
				  LSIZE := TAGSP^.SIZE;
				  RECSECTION(LCP,TAGSP); %RESERVES SPACE FOR THE TAGFIELD \
				   IF BITCOUNT > 0
(* 104 - check structure sizes *)
				   THEN LSP^.SIZE:=CHECKSIZE(DISPL + 1)
				   ELSE LSP^.SIZE:= CHECKSIZE(DISPL);
				 END
			     END
			   ELSE ERROR(402);

			INSYMBOL;
		       END
		   END
(* 150 - fix ill mem ref trying to follow tagsp if not set *)
		 ELSE BEGIN TAGSP := NIL; ERRANDSKIP(209,FSYS OR [LPARENT]) END ;
1:
		LSP1 := NIL; MINSIZE := DISPL; MAXSIZE := DISPL; MINBITCOUNT:=BITCOUNT;
(* 65 - allow extra semicolons *)
		while sy=semicolon do
		 insymbol;
		 LOOP
		  LSP2 := NIL;
		   LOOP
		    CONSTANT(FSYS OR [COMMA,COLON,LPARENT],LSP3,LVALU);
		     IF  NOT COMPTYPES(TAGSP,LSP3)
		     THEN ERROR(305);
		    NEWZ(LSP3,VARIANT);
		    WITH LSP3^ DO
		     BEGIN
		      NXTVAR := LSP1; SUBVAR := LSP2; VARVAL := LVALU;
		      BITSIZE := LSP^.BITSIZE; SELFSTP := NIL
		     END;
		    LSP1 := LSP3; LSP2 := LSP3;
		   EXIT IF SY # COMMA;
		    INSYMBOL;
		   END;
		   IF SY = COLON
		   THEN INSYMBOL
		   ELSE ERROR(151);
		   IF SY = LPARENT
		   THEN INSYMBOL
		   ELSE ERROR(153);
(* 173 - internal files *)
		  FIELDLIST(FSYS OR [RPARENT,SEMICOLON],LSP2,LCP,LHASFILE);
		  FHASFILE := FHASFILE OR LHASFILE;
		   IF DISPL > MAXSIZE
		   THEN MAXSIZE := DISPL;
		  WHILE LSP3 # NIL DO
		   BEGIN
		    LSP4 := LSP3^.SUBVAR; LSP3^.SUBVAR := LSP2; LSP3^.FIRSTFIELD := LCP;
(* 20 - deleted if bitcount>0 use displ+1 - done in fieldlist *)
(* 104 - check structure sizes *)
		     LSP3^.SIZE := CHECKSIZE(DISPL) ;
		    LSP3 := LSP4
		   END;
		   IF SY = RPARENT
		   THEN
		     BEGIN
		      INSYMBOL;
		      IFERRSKIP(166,FSYS OR [SEMICOLON])
		     END
		   ELSE ERROR(152);
(* 65 - allow extra semicolons *)
		  while sy=semicolon
		   do insymbol;
		 exit if sy in fsys;
		  DISPL := MINSIZE;
		  BITCOUNT:=MINBITCOUNT; %RESTAURATION \
		 END;
		DISPL := MAXSIZE;
		LSP^.FSTVAR := LSP1;
	       END  %IF SY = CASESY\
	     ELSE
	       IF LSP # NIL
	       THEN
		 IF LSP^.FORM = ARRAYS
		 THEN FRECVAR := LSP
		 ELSE FRECVAR := NIL;
(* 20 - fix packed records - from CMU *)
	   IF BITCOUNT > 0 THEN
	     BEGIN DISPL:=DISPL+1; BITCOUNT := 0 END
	   END %FIELDLIST\ ;

	 BEGIN
	  %TYP\
(* 173 - internal files *)
	  FHASFILE := FALSE;
	  SKIPIFERR(TYPEBEGSYS,170,FSYS);
	  PACKFLAG := FALSE;
	   IF SY IN TYPEBEGSYS
	   THEN
	     BEGIN
	       IF SY IN SIMPTYPEBEGSYS
	       THEN SIMPLETYPE(FSYS,FSP,FSIZE,FBITSIZE)
	       ELSE
		%^\
		 IF SY = ARROW
		 THEN
		   BEGIN
		    NEWZ(LSP,POINTER); FSP := LSP;
		    LBITSIZE := 18;
		    WITH LSP^ DO
		     BEGIN
		      SELFSTP := NIL;  ELTYPE := NIL; SIZE := 1; BITSIZE := LBITSIZE
		     END;
		    INSYMBOL;
		     IF SY = IDENT
		     THEN
		       BEGIN
(* 165 - fix scoping problem with pointer ref's *)
{All declarations of the form ^THING must be treated as forward references.
 The problem is that we want to use the local declaration of THING if there
 is any.  So we have to wait til we have seen all type declarations before
 we can look up pointer references.}
			NEWZ(LCP,TYPES);
			WITH LCP^ DO
			  BEGIN
			   NAME := ID; IDTYPE := LSP;
			   NEXT := FWPTR
			  END;
			FWPTR := LCP;
			INSYMBOL;
			FBITSIZE:=18
		       END
		     ELSE ERROR(209);
		   END
		 ELSE
		   BEGIN
		     IF SY = PACKEDSY
		     THEN
		       BEGIN
			INSYMBOL;
			SKIPIFERR(TYPEDELS,170,FSYS);
			PACKFLAG := TRUE
		       END;
		      %ARRAY\
		     IF SY = ARRAYSY
		     THEN
		       BEGIN
			INSYMBOL;
			 IF SY = LBRACK
			 THEN INSYMBOL
			 ELSE ERROR(154);
			LSP1 := NIL;
			 LOOP
			  NEWZ(LSP,ARRAYS);
			  WITH LSP^ DO
			   BEGIN
			    AELTYPE := LSP1; INXTYPE := NIL; SELFSTP := NIL;
			    ARRAYPF := PACKFLAG; SIZE := 1
			   END;
			  LSP1 := LSP;
			  SIMPLETYPE(FSYS OR [COMMA,RBRACK,OFSY],LSP2,LSIZE,LBITSIZE);
			   IF LSP2 # NIL
			   THEN
			     IF LSP2^.FORM <= SUBRANGE
			     THEN
			       BEGIN
				 IF LSP2 = REALPTR
				 THEN
				   BEGIN
				    ERROR(210); LSP2 := NIL
				   END
				 ELSE
				   IF LSP2 = INTPTR
				   THEN
				     BEGIN
				      ERROR(306); LSP2 := NIL
				     END;
				LSP^.INXTYPE := LSP2
			       END
			     ELSE
			       BEGIN
				ERROR(403); LSP2 := NIL
			       END;
			 EXIT IF SY # COMMA;
			  INSYMBOL
			 END;
			 IF SY = RBRACK
			 THEN INSYMBOL
			 ELSE ERROR(155);
			 IF SY = OFSY
			 THEN INSYMBOL
			 ELSE ERROR(160);
			TYP(FSYS,LSP,LSIZE,LBITSIZE);
			 IF  LSP # NIL
			 THEN
(* 173 - internal files *)
			   IF  (LSP^.FORM = FILES) OR (LSP^.HASFILE)
			   THEN  FHASFILE := TRUE;
			 REPEAT
			  WITH LSP1^ DO
			   BEGIN
			    LSP2 := AELTYPE; AELTYPE := LSP;
			     IF INXTYPE # NIL
			     THEN
			       BEGIN
				GETBOUNDS(INXTYPE,LMIN,LMAX);
(* 104 - check structure sizes *)
				lmin := checksize(lmin);
				lmax := checksize(lmax);
				I := LMAX - LMIN + 1;
				 IF ARRAYPF AND (LBITSIZE<=18)
				 THEN
				   BEGIN
				    NEWZ(LBTP,ARRAYY);
				    WITH LBTP^,BYTE DO
				     BEGIN
				      SBITS := LBITSIZE;
				      PBITS := BITMAX; DUMMYBIT := 0;
				      IBIT := 0; IREG := TAC; RELADDR := 0;
				      LAST := LASTBTP; LASTBTP := LBTP;
				      ARRAYSP := LSP1;
				     END;
				    LSIZE := (I+(BITMAX DIV LBITSIZE)-1) DIV (BITMAX DIV LBITSIZE);
				   END
				 ELSE
				   BEGIN
				    LSIZE := LSIZE * I;
				    ARRAYPF := FALSE
				   END;
				LBITSIZE := BITMAX;
				BITSIZE := LBITSIZE;
(* 104 - check structure sizes *)
				SIZE := CHECKSIZE(LSIZE);
			       END
			   END;
			  LSP := LSP1; LSP1 := LSP2
			 UNTIL LSP1 = NIL
		       END
		     ELSE
		      %RECORD\
		       IF SY = RECORDSY
		       THEN
			 BEGIN
			  INSYMBOL;
			  OLDTOP := TOP;
			   IF TOP < DISPLIMIT
			   THEN
			     BEGIN
(* 5 - save block name for CREF *)
			      TOP := TOP + 1; DISPLAY[TOP].FNAME := NIL;
			     DISPLAY[TOP].BLKNAME := '.FIELDID. ';
(* 117 - fix enumerated types in record *)
			     DISPLAY[TOP].OCCUR := CREC
			     END
			   ELSE ERROR(404);
			  DISPL := 0;
			  BITCOUNT:=0;
(* 173 - internal files *)
			  FIELDLIST(FSYS-[SEMICOLON] OR [ENDSY],LSP1,LCP,LHASFILE);
			  FHASFILE := FHASFILE OR LHASFILE;
			  
			  LBITSIZE := BITMAX;
			  NEWZ(LSP,RECORDS);
			  WITH LSP^ DO
			   BEGIN
			    SELFSTP := NIL;
			    FSTFLD := %LCP;\ DISPLAY[TOP].FNAME;
			    RECVAR := LSP1;
(* 20 - FIX PACKED RECORDS - FROM CMU - DELETED CODE NOW IN FIELDLIST *)
(* 104 - check structure sizes *)
			     SIZE := CHECKSIZE(DISPL);
			    BITSIZE := LBITSIZE; RECORDPF := PACKFLAG;
			   END;
			  TOP := OLDTOP;
			   IF SY = ENDSY
			   THEN INSYMBOL
			   ELSE ERROR(163)
			 END
		       ELSE
			%SET\
			 IF SY = SETSY
			 THEN
			   BEGIN
			    INSYMBOL;
			     IF SY = OFSY
			     THEN INSYMBOL
			     ELSE ERROR(160);
			    SIMPLETYPE(FSYS,LSP1,LSIZE,LBITSIZE);
			     IF LSP1 # NIL
			     THEN
			      WITH LSP1^ DO
			       CASE FORM OF
				SCALAR:
					IF (LSP1=REALPTR) OR (LSP1=INTPTR)
					THEN ERROR(352)
					ELSE
					  IF SCALKIND =DECLARED
					  THEN
					    IF FCONST^.VALUES.IVAL > BASEMAX
					    THEN ERROR(352);
				SUBRANGE:
					  IF ( RANGETYPE = REALPTR )
					   OR ( ( RANGETYPE # CHARPTR ) AND ((MAX.IVAL > BASEMAX) OR (MIN.IVAL < 0) ) )
					  THEN ERROR(352);
				OTHERS:
					BEGIN
					 ERROR(353); LSP1 := NIL
					END
			       END;
			    LBITSIZE := BITMAX;
			    NEWZ(LSP,POWER);
			    WITH LSP^ DO
			     BEGIN
			      SELFSTP := NIL; ELSET := LSP1; SIZE:=2; BITSIZE := LBITSIZE
			     END;
			   END
			 ELSE
			  %FILE\
			   IF SY = FILESY
			   THEN
			     BEGIN
			      FHASFILE := TRUE;
			      INSYMBOL;
			       IF SY = OFSY
			       THEN INSYMBOL
			       ELSE ERROR(160);
			      TYP(FSYS,LSP1,LSIZE,LBITSIZE);
			      NEWZ(LSP,FILES);
			      LBITSIZE := BITMAX;
			      WITH LSP^ DO
			       BEGIN
				SELFSTP := NIL;
(* 104 - check structure sizes *)
				FILTYPE := LSP1; 
(* 173 - internal files *)
				SIZE := CHECKSIZE(LSIZE) + SIZEOFFILEBLOCK;
				FILEPF := PACKFLAG; BITSIZE := LBITSIZE
			       END;
			       IF LSP1 # NIL
			       THEN
				 IF (LSP1^.FORM = FILES) OR (LSP1^.HASFILE)
				 THEN
				   BEGIN
				    ERROR(254); LSP^.FILTYPE := NIL
				   END;
(* 70 - fix ill mem ref if type error *)
			     END
			   ELSE LSP := NIL;
		    FSP := LSP; FBITSIZE := LBITSIZE
		   END;
	      IFERRSKIP(166,FSYS)
	     END
	   ELSE FSP := NIL;
	   IF FSP = NIL
	   THEN
	     BEGIN
	      FSIZE := 1;FBITSIZE := 0
	     END
(* 173 - internal files *)
	   ELSE BEGIN
	   FSIZE := FSP^.SIZE;
	   FSP^.HASFILE := FHASFILE
	   END
	 END %TYP\ ;

	PROCEDURE LABELDECLARATION;
	VAR
(* 64 - NON-LOCAL GOTOS *)
	  lcp:ctp;
	 BEGIN
(* 6 - remove error message. Allow LABEL declaration but ignore it *)
	   LOOP
	     IF SY = INTCONST
	     THEN
	       BEGIN
		newz(lcp,labelt);
		with lcp^ do
		  begin
		  scope := level; name := id; idtype := nil;
		  next := lastlabel; lastlabel := lcp;
		  gotochain := 0; labeladdress := 0
		  end;
		enterid(lcp);
1:
		INSYMBOL
	       END
	     ELSE ERROR(255);
	    IFERRSKIP(166,FSYS OR [COMMA,SEMICOLON]);
	   EXIT IF SY # COMMA;
	    INSYMBOL
	   END;
	   IF SY = SEMICOLON
	   THEN INSYMBOL
	   ELSE ERROR(156)
	 END %LABELDECLARATION\ ;

	PROCEDURE CONSTANTDECLARATION;
	VAR
	  LCP: CTP; LSP: STP; LVALU: VALU;
	 BEGIN
	  SKIPIFERR([IDENT],209,FSYS);
	  WHILE SY = IDENT DO
	   BEGIN
	    NEWZ(LCP,KONST);
	    WITH LCP^ DO
	     BEGIN
	      NAME := ID; IDTYPE := NIL; NEXT := NIL
	     END;
	    INSYMBOL;
	     IF (SY = RELOP) AND (OP = EQOP)
	     THEN INSYMBOL
	     ELSE ERROR(157);
(* 56 - REQ FILE SYNTAX *)
	    CONSTANT(FSYS OR [SEMICOLON,PERIOD],LSP,LVALU);
	    ENTERID(LCP);
	    LCP^.IDTYPE := LSP; LCP^.VALUES := LVALU;
	     IF SY = SEMICOLON
	     THEN
	       BEGIN
		INSYMBOL;
		IFERRSKIP(166,FSYS OR [IDENT])
	       END
(* 56 - REQ FILE SYNTAX *)
	     ELSE IF NOT ((SY=PERIOD) AND REQFILE)
	       THEN ERROR(156)
	   END
	 END %CONSTANTDECLARATION\ ;

	PROCEDURE TYPEDECLARATION;
	VAR
	  LCP,LCP1,LCP2: CTP; LSP: STP; LSIZE: ADDRRANGE;
	  LBITSIZE: BITRANGE;
	 BEGIN
	  SKIPIFERR([IDENT],209,FSYS);
	  WHILE SY = IDENT DO
	   BEGIN
	    NEWZ(LCP,TYPES);
	    WITH LCP^ DO
	     BEGIN
(* 116 - be sure NEXT is NIL when unused, for COPYCTP *)
	      NAME := ID; IDTYPE := NIL; NEXT := NIL;
	     END;
	    INSYMBOL;
	     IF (SY = RELOP) AND (OP = EQOP)
	     THEN INSYMBOL
	     ELSE ERROR(157);
(* 56 - REQ FILE SYNTAX *)
	    TYP(FSYS OR [SEMICOLON,PERIOD],LSP,LSIZE,LBITSIZE);
	    ENTERID(LCP);
	    WITH LCP^ DO
	     BEGIN
	      IDTYPE := LSP;
(* 165 - fix scoping for pointer ref's *)
	     END;
	     IF SY = SEMICOLON
	     THEN
	       BEGIN
		INSYMBOL;
		IFERRSKIP(166,FSYS OR [IDENT]);
	       END
(* 56 - REQ FILE SYNTAX *)
	     ELSE IF NOT ((SY=PERIOD) AND REQFILE)
	       THEN ERROR(156)
	   END;
(* 113 - don't check for forw. ref's satisfied in req. file *)
	 END %TYPEDECLARATION\ ;

(* 166 - must resolve forwards separately, in case of TYPE section
         in required file but none in main *)
	PROCEDURE FWDRESOLVE;
	  BEGIN
{For each forward request, look up the variable requested.  If
 you find the request, use it.  Note that all declarations of
 the form ^THING produce forward requests.  This is to force
 THING to be looked up after all type declarations have been
 processed, so we get the local definition if there is one.}
	  WHILE FWPTR # NIL DO
 	    BEGIN
(* 165 - fix scoping problem with pointers *)
	     ID := FWPTR^.NAME;
	     PRTERR := FALSE;   %NO ERROR IF SEARCH NOT SUCCESSFUL\
	     SEARCHID([TYPES],LCP); PRTERR := TRUE;
	     IF LCP <> NIL
	       THEN IF LCP^.IDTYPE # NIL
		      THEN IF LCP^.IDTYPE^.FORM = FILES
			     THEN ERROR(254)
			     ELSE FWPTR^.IDTYPE^.ELTYPE := LCP^.IDTYPE
		      ELSE
	       ELSE ERRORWITHTEXT(405,FWPTR^.NAME);
	     FWPTR := FWPTR^.NEXT
	    END
	 END %FWDRESOLVE\ ;

	PROCEDURE VARIABLEDECLARATION;
	VAR
	  LCP,NXT: CTP; LSP: STP; LSIZE: ADDRRANGE;
	  LBITSIZE: BITRANGE; II: INTEGER;
(* 173 - removed lfileptr *)
	 BEGIN
	  NXT := NIL;
	   REPEAT
	     LOOP
	       IF SY = IDENT
	       THEN
		 BEGIN
		  NEWZ(LCP,VARS);
		  WITH LCP^ DO
		   BEGIN
		    NAME := ID; NEXT := NXT;
		    IDTYPE := NIL; VKIND := ACTUAL; VLEV := LEVEL
		   END;
		  ENTERID(LCP);
		  NXT := LCP;
		  INSYMBOL;
		 END
	       ELSE ERROR(209);
	      SKIPIFERR(FSYS OR [COMMA,COLON] OR TYPEDELS,166,[SEMICOLON]);
	     EXIT IF SY # COMMA;
	      INSYMBOL
	     END;
	     IF SY = COLON
	     THEN INSYMBOL
	     ELSE ERROR(151);
	    TYP(FSYS OR [SEMICOLON] OR TYPEDELS,LSP,LSIZE,LBITSIZE);
(* 24 - testpacked no longer needed *)
(* 173 - internal files *)
	    IF LSP <> NIL
	      THEN IF (LSP^.FORM = FILES) OR LSP^.HASFILE
		THEN FILEINBLOCK[LEVEL] := TRUE;
	    WHILE NXT # NIL DO
	    WITH  NXT^ DO
	     BEGIN
	      IDTYPE := LSP; VADDR := LC;
	      LC := LC + LSIZE ;
(* 173 - internal files - removed file code here *)
	      NXT := NEXT ;
	     END;
	     IF SY = SEMICOLON
	     THEN
	       BEGIN
		INSYMBOL;
		IFERRSKIP(166,FSYS OR [IDENT])
	       END
	     ELSE ERROR(156)
	   UNTIL (SY # IDENT) AND  NOT (SY IN TYPEDELS);
(* 167 - code removed from here.  It is now part of FWDRESOLVE,
	which is called right after this procedure *)
	 END %VARIABLEDECLARATION\ ;

	PROCEDURE PROCEDUREDECLARATION(FSY: SYMBOL);
	VAR
	  OLDLEV: 0..MAXLEVEL; LSY: SYMBOL; LCP,LCP1: CTP; LSP: STP;
	  FORW: BOOLEAN; OLDTOP: DISPRANGE; LNXT: CTP;
(* 62 - clean up stack offsets *)
	  LLC,LCM: ADDRRANGE;  TOPPOFFSET: ADDRRANGE;

	  PROCEDURE PARAMETERLIST(FSY: SETOFSYS; VAR FPAR: CTP; VAR TOPPOFFSET: ADDRRANGE);
	  VAR
	    LCP,LCP1,LCP2,LCP3: CTP; LSP: STP; LKIND: IDKIND;
(* 62 - clean up stack offset *)
	    REGC:INTEGER;
	   BEGIN
	    LCP1 := NIL; REGC := REGIN+1;
	    SKIPIFERR(FSY OR [LPARENT],256,FSYS);
	     IF SY = LPARENT
	     THEN
	       BEGIN
		 IF FORW
		 THEN ERROR(553);
		INSYMBOL;
		SKIPIFERR([IDENT,VARSY,PROCEDURESY,FUNCTIONSY],256,FSYS OR [RPARENT]);
		WHILE SY IN [IDENT,VARSY,PROCEDURESY,FUNCTIONSY] DO
		 BEGIN
		   IF SY = PROCEDURESY
		   THEN
		     BEGIN
(* 33 - PROC PARAM.S *)
		       REPEAT
			INSYMBOL;
			 IF SY = IDENT
			 THEN
			   BEGIN
			    NEWZ(LCP,PROC,DECLARED,FORMAL);
			    WITH LCP^ DO
			     BEGIN
			      NAME := ID; IDTYPE := NIL; NEXT := LCP1;
			      PFLEV := LEVEL; PFADDR := LC
			     END;
			    ENTERID(LCP);
(* 62 - clean up stack offset *)
			    LCP1 := LCP; LC := LC + 1; REGC := REGC+1;
			    INSYMBOL
			   END
			 ELSE ERROR(209);
			IFERRSKIP(256,FSYS OR [COMMA,SEMICOLON,RPARENT])
		       UNTIL SY # COMMA
		     END
		   ELSE
		     IF SY = FUNCTIONSY
		     THEN
		       BEGIN
(* 33 - PROC PARAM.S *)
			LCP2 := NIL;
			 REPEAT
			  INSYMBOL;
			   IF SY = IDENT
			   THEN
			     BEGIN
			      NEWZ(LCP,FUNC,DECLARED,FORMAL);
			      WITH LCP^ DO
			       BEGIN
				NAME := ID; IDTYPE := NIL; NEXT := LCP2;
				PFLEV := LEVEL; PFADDR := LC
			       END;
			      ENTERID(LCP);
(* 62 - clean up stack offset *)
			      LCP2 := LCP; LC := LC + 1; REGC := REGC+1;
			      INSYMBOL;
			     END;
			   IF  NOT (SY IN [COMMA,COLON] OR FSYS)
			   THEN
			    ERRANDSKIP(256,FSYS OR [COMMA,SEMICOLON,RPARENT])
			 UNTIL SY # COMMA;
			 IF SY = COLON
			 THEN
			   BEGIN
			    INSYMBOL;
			     IF SY = IDENT
			     THEN
			       BEGIN
				SEARCHID([TYPES],LCP);
				LSP := LCP^.IDTYPE;
				 IF LSP # NIL
				 THEN
				   IF  NOT (LSP^.FORM IN [SCALAR,SUBRANGE,POINTER])
				   THEN
				     BEGIN
				      ERROR(551); LSP := NIL
				     END;
				LCP3 := LCP2;
				WHILE LCP2 # NIL DO
				 BEGIN
				  LCP2^.IDTYPE := LSP; LCP := LCP2;
				  LCP2 := LCP2^.NEXT
				 END;
				LCP^.NEXT := LCP1; LCP1 := LCP3;
				INSYMBOL
			       END
			     ELSE ERROR(209);
			    IFERRSKIP(256,FSYS OR [SEMICOLON,RPARENT])
			   END
			 ELSE ERROR(151)
		       END
		     ELSE
		       BEGIN
			 IF SY = VARSY
			 THEN
			   BEGIN
			    LKIND := FORMAL; INSYMBOL
			   END
			 ELSE LKIND := ACTUAL;
			LCP2 := NIL;
			 LOOP
			   IF SY = IDENT
			   THEN
			     BEGIN
			      NEWZ(LCP,VARS);
			      WITH LCP^ DO
			       BEGIN
				NAME := ID; IDTYPE := NIL;
				VKIND := LKIND; NEXT := LCP2; VLEV := LEVEL;
			       END;
			      ENTERID(LCP);
			      LCP2 := LCP;
			      INSYMBOL;
			     END
			   ELSE ERROR(256);
			   IF  NOT (SY IN [COMMA,COLON] OR FSYS)
			   THEN
			    ERRANDSKIP(256,FSYS OR [COMMA,SEMICOLON,RPARENT])
			 EXIT IF SY # COMMA;
			  INSYMBOL
			 END;
			 IF SY = COLON
			 THEN
			   BEGIN
			    INSYMBOL;
(* 15 - ALLOW :FILE AS KLUDGEY THING THAT MATCHES ALL FILES *)
			     IF SY IN [IDENT,FILESY]
			     THEN
			       BEGIN
				IF SY=IDENT
				THEN BEGIN
(* 111 - STRING, POINTER *)
				SEARCHID([TYPES,PARAMS],LCP);
				  (* PARAMS IS A PREDECLARED IDENTIFIER DESCRIBING
				     A CLASS OF PARAMETERS WITH REDUCED TYPE CHECKING,
				     E.G. STRING OR POINTER *)
				LSP := LCP^.IDTYPE;
				END
				 ELSE LSP:=ANYFILEPTR;
				 IF LSP # NIL
				 THEN
				   IF (LKIND = ACTUAL) AND (LSP^.FORM = FILES)
				   THEN
				    ERROR(355);
(* 151 - fix reversed args in case I,J:INTEGER *)
{LCP2 is reversed at the moment.  Put it forwards so memory alloc is right}
				LCP3 := NIL;
				WHILE LCP2 # NIL DO
				 BEGIN
				 LCP := LCP2;
				 LCP2 := LCP2^.NEXT;
				 LCP^.NEXT := LCP3;
				 LCP3 := LCP;
				 END;
				WHILE LCP3 # NIL DO
				 BEGIN
				  WITH LCP3^ DO
				   BEGIN
				    IDTYPE := LSP;
				    VADDR := LC;
(* 161 - fix POINTER and STRING *)
(* 202 - pointer by ref *)
{POINTER and STRING are passed by a kludgey mechanism.  Since it uses 2 AC's
 we choose to call this thing call by value, with a size of 2.  STRING
 works the same for value and ref anyway.  POINTER doesn't, so we
 use pointerref instead of pointerptr to distinguish. If we call these
 things 2-word quantities passed by value, then mostly the right thing
 happens automatically.   The only other place special code is required
 is in CALLNONSTANDARD where by use a special routine in place of LOAD,
 to do the actually funny passing.}
 				    if (lsp = stringptr) or (lsp = pointerptr)
				      then if (lsp = pointerptr) and
					      (vkind = formal)
{If it is POINTER called by ref, use a special tag, POINTERREF }
				             then begin 
				              idtype := pointerref;
				              vkind := actual
				              end
{In any case, consider it actual so the size = 2 works }
					     else vkind := actual;
				     IF VKIND = FORMAL
				     THEN LC := LC + 1
				     ELSE
				       IF IDTYPE # NIL
				       THEN LC := LC + IDTYPE^.SIZE;
(* 62 - clean up stack offset *)
				    IF IDTYPE = NIL
				      THEN REGC := REGC+1
				      ELSE IF (VKIND = ACTUAL) AND (IDTYPE^.SIZE = 2)
					THEN REGC := REGC+2
					ELSE REGC := REGC+1
				   END;
				  LCP := LCP3;
				  LCP3 := LCP3^.NEXT;
(* 151 - CONS the new thing on individually instead of APPENDing the whole
   string, in order to avoid getting I and J reversed in I,J:INTEGER *)
{Note that we are here reversing the order again.  This is because the
 whole thing gets reversed below.}
				  LCP^.NEXT := LCP1;
				  LCP1 := LCP;
				 END;
				INSYMBOL
			       END
			     ELSE ERROR(209);
			    IFERRSKIP(256,FSYS OR [SEMICOLON,RPARENT])
			   END
			 ELSE ERROR(151);
		       END;
		   IF SY = SEMICOLON
		   THEN
		     BEGIN
		      INSYMBOL;
		      SKIPIFERR(FSYS OR [IDENT,VARSY,PROCEDURESY,FUNCTIONSY],256,[RPARENT])
		     END
		 END %WHILE\ ;
		 IF SY = RPARENT
		 THEN
		   BEGIN
		    INSYMBOL;
		    IFERRSKIP(166,FSY OR FSYS)
		   END
		 ELSE ERROR(152);
		LCP3 := NIL;
		%REVERSE POINTERS\
		WHILE LCP1 # NIL DO
		WITH LCP1^ DO
		 BEGIN
		  LCP2 := NEXT; NEXT := LCP3;
		  LCP3 := LCP1; LCP1 := LCP2
		 END;
		FPAR := LCP3
	       END
	     ELSE FPAR := NIL;
(* 62 - clean up stack offset *)
	   IF (REGC - 1) > PARREGCMAX
	     THEN TOPPOFFSET := LC - 1
	     ELSE TOPPOFFSET := 0;
	   END %PARAMETERLIST\ ;

	 BEGIN
	  %PROCEDUREDECLARATION\
	  LLC := LC;
	   IF FSY = PROCEDURESY
	   THEN LC := 1
	   ELSE LC := 2;
	   IF SY = IDENT
	   THEN
	     BEGIN
(* 5 - CREF *)
	      IF CREF
	        THEN WRITE(CHR(15B),CHR(10),ID);
	      SEARCHSECTION(DISPLAY[TOP].FNAME,LCP);   %DECIDE WHETHER FORW.\
	       IF LCP # NIL
	       THEN
		WITH LCP^ DO
		 BEGIN
		   IF KLASS = PROC
		   THEN
		    FORW := FORWDECL AND (FSY = PROCEDURESY) AND (PFKIND = ACTUAL)
		   ELSE
		     IF KLASS = FUNC
		     THEN
		      FORW := FORWDECL AND (FSY = FUNCTIONSY) AND (PFKIND = ACTUAL)
		     ELSE FORW := FALSE;
		   IF  NOT FORW
		   THEN ERROR(406)
		 END
	       ELSE FORW := FALSE;
	       IF  NOT FORW
	       THEN
		 BEGIN
		   IF FSY = PROCEDURESY
		   THEN NEWZ(LCP,PROC,DECLARED,ACTUAL)
		   ELSE NEWZ(LCP,FUNC,DECLARED,ACTUAL);
		  WITH LCP^ DO
		   BEGIN
(* 116 - be sure NEXT is NIL when unused, for COPYCTP *)
		    NAME := ID; IDTYPE := NIL; TESTFWDPTR := NIL; NEXT := NIL;
		    FORWDECL := FALSE; EXTERNDECL := FALSE; LANGUAGE := PASCALSY;
		    PFLEV := LEVEL; PFADDR := 0; FOR I := 0 TO MAXLEVEL DO LINKCHAIN[I] := 0
		   END;
		  ENTERID(LCP)
		 END
	       ELSE
		 BEGIN
		  LCP1 := LCP^.NEXT;
		  WHILE LCP1 # NIL DO
		   BEGIN
		    WITH LCP1^ DO
		     IF KLASS = VARS
		     THEN
		       IF IDTYPE # NIL
		       THEN
			 BEGIN
			  LCM := VADDR + IDTYPE^.SIZE;
			   IF LCM > LC
			   THEN LC := LCM
			 END;
		    LCP1 := LCP1^.NEXT
		   END
		 END;
	      INSYMBOL
	     END
	   ELSE
	     BEGIN
	      ERROR(209);
	       IF FSY = PROCEDURESY
	       THEN LCP := UPRCPTR
	       ELSE LCP := UFCTPTR
	     END;
	  OLDLEV := LEVEL; OLDTOP := TOP;
	   IF LEVEL < MAXLEVEL
	   THEN LEVEL := LEVEL + 1
	   ELSE ERROR(453);
	   IF TOP < DISPLIMIT
	   THEN
	     BEGIN
	      TOP := TOP + 1;
	      WITH DISPLAY[TOP] DO
	       BEGIN
(* 5 - save block name for CREF *)
		FNAME := NIL; OCCUR := BLCK; BLKNAME := LCP^.NAME;
		 IF DEBUG THEN BEGIN
(* 214 - use ULBLPTR because UPRCPTR will not have NEXT treated
	properly *)
{This is a dummy entry in the symbol table strictly for the debugger.
 The debugger looks at its NEXT field to find the procedure name}
				NEWZ(LCP1); LCP1^ := ULBLPTR^;
				LCP1^.NEXT := LCP;
				ENTERID(LCP1);
				IF FORW AND (LCP^.NEXT # NIL)
				THEN BEGIN
(* 150 - removed lcp1^.llink := lcp^.next.  LCP^.NEXT is a tree containing
         the parameters.  It needs to be put into the symbol table.  Since
         all legal symbols > blanks, just put it in Rlink.  Previously got
         all symbols twice in debugger! *)
				  LCP1^.RLINK := LCP^.NEXT
				  END
			       END
			  ELSE IF FORW THEN FNAME := LCP^.NEXT
		END %WITH DISPLAY[TOP]\
	     END
	   ELSE ERROR(404);
	   IF FSY = PROCEDURESY
	   THEN
	     BEGIN
(* 62 - clean up stack offset *)
	      PARAMETERLIST([SEMICOLON],LCP1,TOPPOFFSET);
	       IF  NOT FORW
		THEN WITH LCP^ DO
		  BEGIN NEXT := LCP1; POFFSET := TOPPOFFSET END
	     END
	   ELSE
	     BEGIN
(* 62 - clean up stack offset *)
	      PARAMETERLIST([SEMICOLON,COLON],LCP1,TOPPOFFSET);
	       IF  NOT FORW
		THEN WITH LCP^ DO
		  BEGIN NEXT := LCP1; POFFSET := TOPPOFFSET END;
	       IF SY = COLON
	       THEN
		 BEGIN
		  INSYMBOL;
		   IF SY = IDENT
		   THEN
		     BEGIN
		       IF FORW
		       THEN ERROR(552);
		      SEARCHID([TYPES],LCP1);
		      LSP := LCP1^.IDTYPE;
		      LCP^.IDTYPE := LSP;
		       IF LSP # NIL
		       THEN
			 IF  NOT (LSP^.FORM IN [SCALAR,SUBRANGE,POINTER])
			 THEN
			   BEGIN
			    ERROR(551); LCP^.IDTYPE := NIL
			   END;
		      INSYMBOL
		     END
		   ELSE ERRANDSKIP(209,FSYS OR [SEMICOLON])
		 END
	       ELSE
		 IF  NOT FORW
		 THEN ERROR(455)
	     END;
	   IF SY = SEMICOLON
	   THEN INSYMBOL
	   ELSE ERROR(156);
	   IF SY = FORWARDSY
	   THEN
	     BEGIN
	       IF FORW
	       THEN ERROR(257)
	       ELSE
		WITH LCP^ DO
		 BEGIN
		  TESTFWDPTR := FORWPTR; FORWPTR := LCP; FORWDECL := TRUE
		 END;
	      INSYMBOL;
	       IF SY = SEMICOLON
	       THEN INSYMBOL
	       ELSE ERROR(156);
	      IFERRSKIP(166,FSYS)
	     END % SY = FORWARDSY \
	   ELSE
	    WITH LCP^ DO
	     BEGIN
	       IF SY = EXTERNSY
	       THEN
		 BEGIN
		   IF FORW
		   THEN ERROR(257)
		   ELSE EXTERNDECL := TRUE;
		  INSYMBOL;
		   IF LEVEL # 2
		   THEN ERROR(464);
		   IF SY IN LANGUAGESYS
		   THEN
		     BEGIN
		      LANGUAGE := SY;
		      INSYMBOL
		     END;
		   IF (LIBIX = 0) OR (NOT LIBRARY[LANGUAGE].INORDER)
		   THEN
		     BEGIN
		      LIBIX:= LIBIX+1;
		      LIBORDER[LIBIX]:= LANGUAGE;
		      LIBRARY[LANGUAGE].INORDER:= TRUE
		     END;
		  PFLEV := 1; PFCHAIN := EXTERNPFPTR; EXTERNPFPTR := LCP;
		   IF SY = SEMICOLON
(* 56 - ACCEPT SYNTAX OF REQUIRE FILE *)
		     THEN BEGIN
		     INSYMBOL;
		     IFERRSKIP(166,FSYS)
		     END
		    ELSE IF NOT((SY=PERIOD) AND REQFILE)
		     THEN ERROR(166)
		 END % SY = EXTERNSY \
	       ELSE
		 BEGIN
(* 55 - ONLY EXTERN DECL'S ALLOWED IN REQUIRE FILE *)
		  IF REQFILE
		    THEN ERROR(169);
		  PFCHAIN := LOCALPFPTR; LOCALPFPTR := LCP; FORWDECL := FALSE;
		  BLOCK(LCP,FSYS,[BEGINSY,FUNCTIONSY,PROCEDURESY,PERIOD,SEMICOLON]);
		   IF SY = SEMICOLON
		   THEN
		     BEGIN
		      INSYMBOL;
		      SKIPIFERR([BEGINSY,PROCEDURESY,FUNCTIONSY],166,FSYS)
		     END
		   ELSE
		     IF MAIN OR (LEVEL > 2) OR (SY # PERIOD)
		     THEN ERROR(156)
		 END % SY # EXTERNSY \
	     END % SY # FORWARDSY \ ;
	  LEVEL := OLDLEV; TOP := OLDTOP; LC := LLC;
(* 5 - CREF *)
	  IF CREF
	    THEN WRITE(CHR(16B),CHR(10),LCP^.NAME)
	 END %PROCEDUREDECLARATION\ ;

	PROCEDURE BODY(FSYS: SETOFSYS);
	CONST
(* 173 - rework for internal files *)
	  FILEOF = 1B; FILEOL = 2B; FILSTA = 11B;  FILTST=40B;
	  FILBFH =26B; FILLNR = 31B;
(* 43 - new stuff for blocked files *)
(* 50 - new labels for reinit *)
	  FILCMP =43B; filbll=36b; 
(* 61 - tops20 *)
	  filjfn =4b;
	VAR
	  LASTFILE: CTP;
	  IDTREE: ADDRRANGE; %POINTER(IN THE USER'S CODE) TO THE IDENTIFIER-TREE\

	  PROCEDURE FULLWORD(FRELBYTE: RELBYTE; FLEFTH: ADDRRANGE; FRIGHTH: ADDRRANGE);
	   BEGIN
	    %FULLWORD\
	    CIX := CIX + 1;
	     IF CIX > CIXMAX
	     THEN
	       BEGIN
		IF FPROCP = NIL THEN ERRORWITHTEXT(356,'MAIN      ')
				ELSE ERRORWITHTEXT(356, FPROCP^.NAME);
		CIX := 0
	       END;
	    WITH CODE, HALFWORD[CIX] DO
	     BEGIN
	      LEFTHALF := FLEFTH;
	      RIGHTHALF := FRIGHTH;
	      INFORMATION[CIX] := 'W'; RELOCATION[CIX] := FRELBYTE
	     END;
	    IC := IC + 1
	   END %FULLWORD\ ;

(* 164 - routine to allow Polish fixup in case ADDR can't be done by compiler *)

	procedure insertpolish(place,original:addrrange;adjust:integer);
	    var pol:polpt;
{This routine requests the loader to fix up the right half of PLACE, by
 putting in ORIGINAL (assumed relocatable) + ADJUST (assumed absolute).
 A POLREC is created, and the actual request is put in the file by
 WRITEMC(WRITEPOLISH).}
	  begin
	  if abs(adjust) > 377777B
	    then error(266)
	    else begin
	    new(pol);
	    with pol^ do
	      begin
	      where := place;
	      base := original;
	      offset := adjust;
	      nextpol := firstpol  {Link into chain of requests - FIRSTPOL}
	      end;
	    firstpol := pol
	    end;
	  end;

	  PROCEDURE INSERTADDR(FRELBYTE: RELBYTE; FCIX:CODERANGE;FIC:ADDRRANGE);
	   BEGIN
	     IF NOT ERRORFLAG
	     THEN
	      WITH CODE DO
	       BEGIN
		INSTRUCTION[FCIX].ADDRESS := FIC;
		RELOCATION[FCIX] := FRELBYTE
	       END
	   END;

	  PROCEDURE INCREMENTREGC;
	   BEGIN
	    REGC := REGC + 1 ;
	     IF REGC > REGCMAX
	     THEN
	       BEGIN
		ERROR(310) ; REGC := REGIN
	       END
	   END ;

	  PROCEDURE DEPCST(KONSTTYP:CSTCLASS; FATTR:ATTR);
	  VAR
	    II:INTEGER; LKSP,LLKSP: KSP; LCSP: CSP;
	    NEUEKONSTANTE,GLEICH:BOOLEAN; LCIX: CODERANGE;
	   BEGIN
	    I:=1;
	    NEUEKONSTANTE:=TRUE; LKSP := FIRSTKONST;
	    WHILE (LKSP#NIL) AND NEUEKONSTANTE DO
	    WITH LKSP^,CONSTPTR^ DO
	     BEGIN
	       IF CCLASS = KONSTTYP
	       THEN
		 CASE KONSTTYP OF
		  REEL:
			IF RVAL = FATTR.CVAL.VALP^.RVAL
			THEN
			 NEUEKONSTANTE := FALSE;
		  INT:
		       IF INTVAL = FATTR.CVAL.IVAL
		       THEN
			NEUEKONSTANTE := FALSE;
		  PSET:
			IF PVAL = FATTR.CVAL.VALP^.PVAL
			THEN
			 NEUEKONSTANTE := FALSE;
		  STRD,
		  STRG:
			IF FATTR.CVAL.VALP^.SLGTH = SLGTH
			THEN
			  BEGIN
			   GLEICH := TRUE;
			   II := 1;
			    REPEAT
			      IF FATTR.CVAL.VALP^.SVAL[II] # SVAL[II]
			      THEN
			       GLEICH := FALSE;
			     II:=II+1
			    UNTIL (II>SLGTH) OR NOT GLEICH;
			    IF GLEICH
			    THEN NEUEKONSTANTE := FALSE
			  END
		 END %CASE\;
	      LLKSP := LKSP; LKSP := NEXTKONST
	     END %WHILE\;
	     IF NOT NEUEKONSTANTE
	     THEN
	      WITH LLKSP^ DO
	       BEGIN
		INSERTADDR(RIGHT,CIX,ADDR); CODE.INFORMATION[CIX]:= 'C';
		 IF KONSTTYP IN [PSET,STRD]
		 THEN
		   BEGIN
		    INSERTADDR(RIGHT,CIX-1,ADDR1); CODE.INFORMATION[CIX-1]:= 'C'; ADDR1 := IC-2;
		   END;
		ADDR:= IC-1
	       END
	     ELSE
	       BEGIN
		 IF KONSTTYP = INT
		 THEN
		   BEGIN
		    NEWZ(LCSP,INT); LCSP^.INTVAL := FATTR.CVAL.IVAL
		   END
		 ELSE
		  LCSP := FATTR.CVAL.VALP;
		CODE.INFORMATION[CIX] := 'C';
		 IF KONSTTYP IN [PSET,STRD]
		 THEN CODE.INFORMATION[CIX-1] := 'C';
		NEWZ(LKSP);
		WITH LKSP^ DO
		 BEGIN
		  ADDR := IC-1;
(* 72 - two fixup chains for 2 word consts *)
		  if konsttyp in [strd,pset]
		    then addr1 := ic-2;
		  CONSTPTR := LCSP; NEXTKONST := NIL
		 END;
		 IF FIRSTKONST = NIL
		 THEN FIRSTKONST := LKSP
		 ELSE LLKSP^.NEXTKONST := LKSP
	       END
	   END %DEPCST\;

	  PROCEDURE MACRO(FRELBYTE : RELBYTE;
			  FINSTR   : INSTRANGE;
			  FAC	   : ACRANGE;
			  FINDBIT  : IBRANGE;
			  FINXREG  : ACRANGE;
			  FADDRESS : INTEGER);
	   BEGIN
	     IF NOT INITGLOBALS
	     THEN
	       BEGIN
		CIX := CIX + 1;
		 IF CIX > CIXMAX
		 THEN
		   BEGIN
		     IF FPROCP = NIL
		     THEN ERRORWITHTEXT(356,'MAIN      ')
		     ELSE ERRORWITHTEXT(356, FPROCP^.NAME);
		    CIX := 0
		   END;
		WITH CODE, INSTRUCTION[CIX] DO
		 BEGIN
		  INSTR    :=FINSTR;
		  AC	   :=FAC;
		  INDBIT   :=FINDBIT;
		  INXREG   :=FINXREG;
		  ADDRESS  :=FADDRESS;
		  INFORMATION[CIX]:= ' '; RELOCATION[CIX] := FRELBYTE
		 END;
		IC := IC + 1
	       END
	     ELSE ERROR(507)
	   END %MACRO\;

	  PROCEDURE MACRO5(FRELBYTE: RELBYTE; FINSTR : INSTRANGE; FAC,FINXREG : ACRANGE; FADDRESS : INTEGER);
	   BEGIN
	    MACRO(FRELBYTE,FINSTR,FAC,0,FINXREG,FADDRESS)
	   END;

	  PROCEDURE MACRO4(FINSTR: INSTRANGE;FAC, FINXREG: ACRANGE;FADDRESS: INTEGER);
	   BEGIN
	    MACRO(NO,FINSTR,FAC,0,FINXREG,FADDRESS)
	   END;

	  PROCEDURE MACRO3(FINSTR : INSTRANGE; FAC:ACRANGE; FADDRESS: INTEGER);
	   BEGIN
	    MACRO(NO,FINSTR,FAC,0,0,FADDRESS)
	   END;

	  PROCEDURE MACRO4R(FINSTR : INSTRANGE; FAC,FINXREG : ACRANGE; FADDRESS : INTEGER);
	   BEGIN
	    MACRO(RIGHT,FINSTR,FAC,0,FINXREG,FADDRESS)
	   END;

	  PROCEDURE MACRO3R(FINSTR : INSTRANGE; FAC:ACRANGE; FADDRESS: INTEGER);
	   BEGIN
	    MACRO(RIGHT,FINSTR,FAC,0,0,FADDRESS)
	   END;

	  PROCEDURE PUTPAGER;
	   BEGIN
	    WITH PAGER DO
	     BEGIN
	      LASTPAGER := IC;
	      WITH WORD1 DO MACRO4R(304B%CAIA\,AC,INXREG,ADDRESS);
	      FULLWORD(RIGHT,LHALF,RHALF);
	      LASTPAGE := PAGECNT
	     END
	   END;

	  PROCEDURE PUTLINER;
	   BEGIN
	     IF PAGECNT # LASTPAGE
	     THEN PUTPAGER;
	     IF LINECNT # LASTLINE
	     THEN %BREAKPOINT\
	       BEGIN
		 IF LINENR # '-----'
		 THEN
		   BEGIN
		    LINECNT := 0;
		    FOR I := 1 TO 5 DO	LINECNT := 10*LINECNT + ORD(LINENR[I]) - ORD('0')
		   END;
		LINEDIFF := LINECNT - LASTLINE;
		 IF LINEDIFF > 255
		 THEN
		   BEGIN
		    MACRO3R(334B%SKIPA\,0,LASTSTOP);
		    LASTSTOP := IC-1;
		    MACRO3(320B%JUMP\,0,LASTLINE)
		   END
		 ELSE
		   BEGIN
		    MACRO4R(320B%JUMP\,LINEDIFF MOD 16,LINEDIFF DIV 16, LASTSTOP); %NOOP\
		    LASTSTOP := IC - 1
		   END;
		LASTLINE := LINECNT
	       END
	   END;

	  PROCEDURE SUPPORT(FSUPPORT: SUPPORTS);
	   BEGIN
	     CASE FSUPPORT OF
(* 23 - check for bad pointer *)
	      BADPOINT,
	      ERRORINASSIGNMENT,
	      INDEXERROR    : MACRO3R(265B%JSA\,HAC,RNTS.LINK[FSUPPORT]);
(* 12 - NOW STACKOVERFLOW IS NOT AN ERROR - GETS MORE MEMORY *)
(* 74 - add initmem for 10 version under emulator *)
(* 104 - debstack for tops-10 debugging stack check *)
(* 120 - new calling method for INITFILES, for T20/Tenex *)
	      INITFILES,INITMEM,STACKOVERFLOW,DEBSTACK: MACRO3R(265B%JSP\,TAC,RNTS.LINK[FSUPPORT]);
(* 64 - non-local gotos *)
	      EXITPROGRAM   : MACRO3R(254B%JRST\,0,RNTS.LINK[FSUPPORT]);
	      OTHERS	    : MACRO3R(260B%PUSHJ\,TOPP,RNTS.LINK[FSUPPORT])
	     END;
	    CODE.INFORMATION[CIX]:= 'E';
	    RNTS.LINK[FSUPPORT]:= IC-1
	   END;

	  PROCEDURE ENTERBODY;
	  VAR
	    I: INTEGER; LCP : CTP;
(* 66 - NON-LOC GOTO *)
	    LBTP: BTP; NONLOC,INLEVEL: BOOLEAN;
	   BEGIN
	    LBTP := LASTBTP;
(* 13 - ADD DATA FOR DDT SYMBOLS *)
	    PFPOINT := IC;
	    WHILE LBTP # NIL DO
	     BEGIN
	      WITH LBTP^ DO
	       CASE BKIND OF
		RECORDD: FIELDCP^.FLDADDR := IC;
		ARRAYY : ARRAYSP^.ARRAYBPADDR := IC
	       END;
	      LBTP := LBTP^.LAST;
	      IC := IC + 1
	     END;
(* 66 - NON-LOC GOTO *)
	     LCP:=LASTLABEL;
	     INLEVEL:=TRUE; NONLOC:=FALSE;
	     WHILE(LCP#NIL) AND INLEVEL DO
		WITH LCP^ DO
		  IF SCOPE=LEVEL
		    THEN BEGIN
		    NONLOC := NONLOC OR NONLOCGOTO;
		    LCP := NEXT
		    END
		   ELSE INLEVEL := FALSE;
	     IF FPROCP # NIL
	     THEN
	       BEGIN
		FULLWORD(NO,0,377777B); IDTREE := CIX; %IF DEBUG, INSERT TREEPOINTER HERE\
(* 13 - SAVE START ADDRESS FOR DDT SYMBOL *)
		PFDISP := IC;
		WITH FPROCP^ DO
		 IF PFLEV > 1
		 THEN
		  FOR I := MAXLEVEL DOWNTO PFLEV+1 DO
		  MACRO4(540B%HRR\,BASIS,BASIS,-1);
		PFSTART := IC;
(* 62 - clean up stack offset *)
	        if fprocp^.poffset # 0
		  then macro4(262B%pop\,topp,topp,-fprocp^.poffset-1);
(* 37 - fix static link for level one procedures *)
		if fprocp^.pflev = 1
		  then macro4(512b%hllzm\,basis,topp,-fprocp^.poffset-1)
		  ELSE MACRO4(202B%MOVEM\,BASIS,TOPP,-FPROCP^.POFFSET-1);
		if fprocp^.poffset # 0
		  then begin
		  macro4(201B%movei\,basis,topp,-fprocp^.poffset);
(* 104 - several changes below to allow detection stack overflow *)
		  macro3(504B%hrl\,basis,basis);
		  end
		 ELSE MACRO3(507B%HRLS\,BASIS,TOPP);
(* 115 - tenex *)
		IF KLCPU AND NOT TOPS10
		  THEN MACRO3(105B%ADJSP\,TOPP,0)
		  ELSE MACRO4(541B%HRRI\,TOPP,TOPP,0);
		INSERTSIZE := CIX;
(* 66 - NONLOC GOTO *)
		IF NONLOC
		  THEN MACRO4(506B%HRLM\,TOPP,BASIS,0);
(* If anyone has done a non-local goto into this block, save the
   stack pointer here where the goto can recover it. *)
(* 53 - figure out later how many loc's above stack we need *)
(* 57 - LIMIT CORE ALLOCATION TO TOPS-10 VERSION *)
		IF TOPS10 THEN BEGIN
		IF RUNTMCHECK
		  THEN BEGIN
		  MACRO4(201B%MOVEI\,HAC,TOPP,0); CORALLOC := CIX;
		   %Will be fixed up - get highest core needed \
		  MACRO4(301B%CAIL\,HAC,BASIS,0); %check wraparound > 777777\
		  MACRO4(303B%CAILE\,HAC,NEWREG,0); %see if need more\
		  SUPPORT(DEBSTACK)
		  END
		 ELSE BEGIN %NOT DEBUG\
		  MACRO4(307B%CAIG\,NEWREG,TOPP,0); CORALLOC := CIX;
		    %will be fixed up - fails if wrap around 777777\
		  SUPPORT(STACKOVERFLOW);
		  END
		END;
(* 24 - NOW ZERO ONLY IF RUNTIME CHECKING ON *)
(* 25 - SEPARATE SWITCH /ZERO FOR THIS NOW *)
		IF ZERO
		THEN BEGIN
		IF LCPAR < LC  %ANY VARIABLES?\
		  THEN MACRO4(402B%SETZM\,0,BASIS,LCPAR);
		IF LCPAR < (LC-1) %MORE THAN ONE?\
		  THEN BEGIN
		  MACRO4(505B%HRLI\,TAC,BASIS,LCPAR);
		  MACRO4(541B%HRRI\,TAC,BASIS,LCPAR+1);
		  MACRO4(251B%BLT\,TAC,BASIS,LC-1)
		  END
		END;
		REGC := REGIN+1;
		LCP := FPROCP^.NEXT;
		WHILE LCP # NIL DO
		WITH LCP^ DO
		 BEGIN
(* 33 - proc param.'s*)
		   IF KLASS # VARS
		   THEN
		     BEGIN
		     IF REGC <= PARREGCMAX
			THEN BEGIN
			MACRO4(202B%MOVEM\,REGC,BASIS,PFADDR);
			REGC := REGC+1
			END
		     END
		   ELSE
		     IF IDTYPE # NIL
		     THEN
		       IF (VKIND=FORMAL) OR (IDTYPE^.SIZE=1)
		       THEN   %COPY PARAMETERS FROM REGISTERS INTO LOCAL CELLS\
			 BEGIN
			   IF REGC <= PARREGCMAX
			   THEN
			     BEGIN
			      MACRO4(202B%MOVEM\,REGC,BASIS,VADDR); REGC := REGC + 1
			     END
			 END
		       ELSE
			 IF IDTYPE^.SIZE=2
			 THEN
			   BEGIN
			     IF REGC < PARREGCMAX
			     THEN
			       BEGIN
				MACRO4(202B%MOVEM\,REGC,BASIS,VADDR);
				MACRO4(202B%MOVEM\,REGC+1,BASIS,VADDR+1);
				REGC:=REGC+2
			       END
(* 2 - bug fix for parameter passing *)
			     ELSE REGC:=PARREGCMAX+1
			   END
(* 201 - zero size things *)
			 ELSE IF IDTYPE^.SIZE > 0
			   THEN BEGIN
			     IF REGC <= PARREGCMAX
			     THEN  %COPY MULTIPLE VALUES INTO LOCAL CELLS\
			       BEGIN
				MACRO3(504B%HRL\,TAC,REGC); REGC := REGC + 1
			       END
			     ELSE
			      MACRO4(504B%HRL\,TAC,BASIS,VADDR);
			    MACRO4(541B%HRRI\,TAC,BASIS,VADDR);
			    MACRO4(251B%BLT\,TAC,BASIS,VADDR+IDTYPE^.SIZE-1)
			   END
(* 201 - zero size things *)
			 ELSE {zero size}
			  REGC := REGC + 1;
		  LCP := LCP^.NEXT;
		 END
	       END
	     ELSE  MAINSTART := IC
	   END %ENTERBODY\;

	  PROCEDURE LEAVEBODY;
	  VAR
	    J,K : ADDRRANGE ;
	    LFILEPTR: FTP; LKSP: KSP ;
(* 33 - PROGRAM *)
	    LCP : CTP; OLDID : ALFA;
	   PROCEDURE ALFACONSTANT(FSTRING:ALFA);
	   VAR LCSP:CSP;
	     BEGIN
	     NEW(LCSP,STRG);
	     WITH LCSP^ DO
	       BEGIN
	       SLGTH := 10; FOR I := 1 TO 10 DO SVAL[I] := FSTRING[I]
	       END;
	     WITH GATTR DO
	       BEGIN
	       TYPTR := ALFAPTR;
	       KIND := CST; CVAL.VALP := LCSP
	       END
	     END;
	   BEGIN
	     IF DEBUG
	     THEN PUTLINER;
	     IF  FPROCP # NIL
	     THEN
(* 173 - internal files - close them *)
	      if fileinblock[level]
	       then begin
{We have to close any files in this block before we can change TOPP,
 or we might be playing with locals above the stack!  So this is
 coded like a non-local goto - new basis in regc, new topp in regc+1}
		regc := regin+1;
(* 213 - forgot to subtract 1 from TOPP to simulate POPJ *)
		  {simulate HRLS TOPP,BASIS.  But have to subtract 1
		   since there would have been a POPJ TOPP, later.
		   Because of this, things that would be -1(TOPP) are
		   now (TOPP)}
		macro4(505B%hrli\,regc+1,basis,-1);
		macro3(544B%hlr\,regc+1,regc+1);
		  {simulate HLRS BASIS,-1(TOPP), but note that -1 has
		   already been done}
		macro4(544B%hlr\,regc,regc+1,0);
		macro3(504B%hrl\,regc,regc);
		  {now get return address from where POPJ TOPP, would
		   get it, i.e. (TOPP).  However note that -1 has been
		   done}
		macro4(550B%hrrz\,regc+2,regc+1,1);
		support(exitgoto)
		end
	      else
	       BEGIN
(* 104 - keep LH=RH in topp for tops20 adjsp *)
		MACRO3(507B%HRLS\,TOPP,BASIS);
		MACRO4(547B%HLRS\,BASIS,TOPP,-1);
		MACRO3(263B%POPJ\,TOPP,0);
	       END
	     ELSE
	       BEGIN
		 IF MAIN
		 THEN
		   BEGIN
		    SUPPORT(EXITPROGRAM);
		    STARTADDR := IC;
(* 2 - get some core by default if none there *)
(* 12 - REDO INITIALIZATION FOR DYNAMIC EXPANDING CORE *)
(* 16 - change entry code in case execute-only or entry at +1 *)
(* 24 - CHANGE AGAIN TO ALLOW ST. ADDR OF HEAP AND STACK SPECIFIED *)
		MACRO3R(254B%JRST\,1,IC+2); %PORTAL - IN CASE EXEC-ONLY\
		MACRO3R(254B%JRST\,1,IC+2); %IN CASE OFFSET =1\
		MACRO3(634B%TDZA\,1,1); %NORMAL ENTRY - ZERO AND SKIP\
		MACRO3(201B%MOVEI\,1,1); %CCL ENTRY - SET TO ONE\
		MACRO3R(202B%MOVEM\,1,CCLSW); %STORE CCL VALUE\
		MACRO3R(200B%MOVE\,1,CCLSW+4); %SEE IF INIT DONE\
		MACRO3R(326B%JUMPN\,1,IC+5); %YES - DON'T RESAVE AC'S\
		MACRO3R(202B%MOVEM\,0,CCLSW+1); %RUNNAME\
		MACRO3R(202B%MOVEM\,7B,CCLSW+2); %RUNPPN\
		MACRO3R(202B%MOVEM\,11B,CCLSW+3); %RUNDEV\
		MACRO3R(476B%SETOM\,0,CCLSW+4); %SAY WE HAVE DONE IT\
(* 132 - separate KA10 into NOVM and KACPU *)
		IF (HEAP = 0) AND (NOT NOVM)
		  THEN HEAP := 377777B;
		MACRO3(201B%MOVEI\,BASIS,HEAP); %LSTNEW_377777\
		MACRO3R(202B%MOVEM\,BASIS,LSTNEW); %WILL GET GLOBAL FIXUP\
		LSTNEW := IC-1;
		MACRO3(201B%MOVEI\,BASIS,HEAP+1); %NEWBND_400000\
		MACRO3R(202B%MOVEM\,BASIS,NEWBND); %GLOBAL FIXUP\
		NEWBND := IC-1;
		IF STACK#0
		  THEN MACRO3(201B%MOVEI\,BASIS,STACK)
		  ELSE MACRO3(550B%HRRZ\,BASIS,115B); %BASIS_.JBHRL\
		MACRO3(306B%CAIN\,BASIS,0); %IF NO HISEG\
		MACRO3(201B%MOVEI\,BASIS,377777B); %START STACK 400000\
		MACRO3(200B%MOVE\,NEWREG,BASIS); %NEWREG=HIGHEST ALLOC\
		MACRO3(271B%ADDI\,BASIS,1); %BASIS=NEXT TO USE\
		    MACRO4(505B%HRLI\,BASIS,BASIS,0);
		    MACRO4(541B%HRRI\,TOPP,BASIS,0); %GETS FIXED UP\
		    INSERTSIZE:= CIX;
(* 104 - KEEP LH=RH FOR TOPS20 ADJSP *)
		    MACRO3(504B%HRL\,TOPP,TOPP);
(* 66 - nonloc goto's *)
		    macro3r(202B%movem\,basis,globbasis);
		    macro3r(202B%movem\,topp,globtopp);
(* 17 - LEAVE .JBFF ALONE, SINCE BUFFER HEADERS POINT INTO FREE AREA *)
(* 57 - LIMIT UUO'S AND CORE ALLOC TO TOPS-10 VERSION *)
		IF TOPS10 THEN BEGIN
(* 122 - seem not to need to save .jbff any more *)
	  {	    MACRO3(550B%HRRZ\,1,121B); %.JBFF\
		    MACRO3(506B%HRLM\,1,120B); %TO LH(.JBSA)\
	  }	    MACRO3(047B,0,0%RESET-UUO\); %.JBFF=.JBSA\
(* 74 - new init stuff for tops10 under emulator *)
		    support(initmem);
(* 53 - figure out later how many loc's above stack we need *)
(* 130 - leave in dummy CAI in KA version so there is some place for the CORALLOC fixup to go *)
		  MACRO4(300B%CAI\,NEWREG,TOPP,0); CORALLOC := CIX;  %Will be fixed up later\
(* 122 - already get core in initmem for KA *)
(* 132 - separate KA10 into novm and kacpu *)
		  if not novm 
		    THEN SUPPORT(STACKOVERFLOW);	% GET CORE FOR STACK\
(* 34 - TRAP ARITH EXCEPTIONS WHEN CHECKING *)
		IF ARITHCHECK
		  THEN BEGIN
		  MACRO3(201B%MOVEI\,1,110B); %TRAP ALL ARITH. EXCEPTIONS\
		  MACRO3(047B%CALLI\,1,16B); %APRENB - TURN ON APR SYS\
		  END;
(* 57 - INIT ALL IN RUNTIMES FOR NON-TOPS10 *)
		END
		 ELSE MACRO3(201B%MOVEI\,2,ORD(ARITHCHECK));
(* 50 - reinit file ctl. blocks *)
		support(initfiles);
		doinitTTY := false;
		    LFILEPTR := SFILEPTR ;
		    REGC := REGIN + 1 ;
(* 33 - PROGRAM *)
(* 50 - changed logic to only open INPUT and OUTPUT if in pgm state *)
		    LPROGFILE := FPROGFILE;
		    WHILE LPROGFILE # NIL DO
		      BEGIN
		      PRTERR := FALSE; OLDID := ID; ID := LPROGFILE^.FILID;
		      SEARCHID([VARS],LCP);
		      PRTERR := TRUE; ID := OLDID;
		      IF LCP = NIL
			THEN ERRORWITHTEXT(508,LPROGFILE^.FILID)
			ELSE
			  WITH LCP^ DO
			  BEGIN
			  IF IDTYPE#NIL THEN IF IDTYPE^.FORM#FILES
			    THEN ERRORWITHTEXT(509,LPROGFILE^.FILID);
			  MACRO3R(201B%MOVEI\,REGC,VADDR);
			  IF (VLEV = 0) AND (NOT MAIN)
			    THEN BEGIN
			    VADDR := IC -1;
			    CODE.INFORMATION[CIX] := 'E'
			    END;
		          ALFACONSTANT(LPROGFILE^.FILID);
			  MACRO3(551B%HRRZI\,REGC+1,0);DEPCST(STRG,GATTR);
(* 61 - set up flags for gtjfn *)
			  i := 60023b; %mandatory flags for gtjfn\
			  if lprogfile^.wild
			    then i := i + 100B;
			  if lprogfile^.newgen
			    then i := i + 400000B;
			  if lprogfile^.oldfile
			    then i := i + 100000B;
			  macro3(505B%hrli\,regc+1,i);
(* 172 - end of line proc *)
			  if lcp = ttyfile
			    then ttyseeeol := lprogfile^.seeeol;
			  if not ((lcp = ttyfile) or (lcp = ttyoutfile))
			    then SUPPORT(READFILENAME)
			  END;
(* 171 - handle input and output as special - many changes to lcp = in/outfile *)
		      if (lcp = infile)
			and not lprogfile^.interact
			  then doinitTTY := true;
		      if (lcp = infile) or (lcp = outfile)
			then begin
			macro3(201B%movei\,regc-1,0);  {AC1=0 for text file}
			macro3(403B%setzb\,regc+1,regc+2);
			macro3(403B%setzb\,regc+3,regc+4);
(* 64 - input:/ *)
(* 157 - always open INPUT interactive - do GET below *)
			if lcp = infile
			  then macro3(201B%movei\,regc+3,1);
			macro3(403B%setzb\,regc+5,regc+6);
(* 172 - new eoln handling *)
			if (lcp = infile) and lprogfile^.seeeol
			  then if tops10
				 then macro3(201B%movei\,regc+5,40000B)
				 else macro3(201B%movei\,regc+6,20B);
			if lcp = infile
			  then support(resetfile)
			  else support(rewritefile)
			end;
		      LPROGFILE := LPROGFILE^.NEXT
		      END;
(* 15 - ZERO ALL ARGS TO OPEN *)
		    TTYINUSE := TTYINUSE OR DEBUG;
		    WHILE LFILEPTR # NIL DO
		    WITH LFILEPTR^ , FILEIDENT^ DO
(* 50 - only open TTY here, as INPUT and OUTPUT done above *)
		    begin
		    if (fileident = ttyfile) or (fileident = ttyoutfile)
			then
		     BEGIN
		      MACRO3R(201B%MOVEI\,REGC,VADDR) ;
		      macro3(201B%movei\,regc-1,0);  {0=text file}
(* 202 - fix illegal option *)
		      macro3(403B%setzb\,regc+1,regc+2);
		      macro3(403B%setzb\,regc+3,regc+4);
(* 172 - new EOL *)
		      macro3(403B%setzb\,regc+5,regc+6);
		      if (fileident = ttyfile) and ttyseeeol
			  then if tops10
				 then macro3(201B%movei\,regc+5,40000B)
				 else macro3(201B%movei\,regc+6,20B);
(* 36 - allow debugging non-main modules *)
		       IF fileident = ttyfile
		       THEN
			SUPPORT(RESETFILE)
		       ELSE
			  SUPPORT(REWRITEFILE) ;
		     end;
(* 3 - Removed OPENTTY because of RUNTIM changes *)
		      LFILEPTR := NEXTFTP ;
		    END ;
		    if doinitTTY
		      then support(opentty);
		    macro3(200b%move\,tac,74b);  %get .jbddt\
		    macro3(602b%trne\,tac,777777b);  %if zero RH\
		    macro3(603b%tlne\,tac,777777b);  %or non-0 LH\
		    macro3r(254b%jrst\,0,mainstart); %isn't PASDDT\
		    macro4(260b%pushj\,topp,tac,-2); %init pt. is start-2\
		    MACRO3R(254B%JRST\,0,MAINSTART);
		   END;
	       END;
	    CODEEND := IC;
	    LKSP:= FIRSTKONST;
	    WHILE LKSP # NIL DO
	    WITH LKSP^,CONSTPTR^ DO
	     BEGIN
	      KADDR:= IC;
	       CASE  CCLASS OF
		INT,
		REEL: IC := IC + 1 ;
		PSET: IC := IC + 2 ;
		STRD,
		STRG: IC := IC + (SLGTH+4) DIV 5
	       END ;
	      %CASE\
	      LKSP := NEXTKONST
	     END  %WITH , WHILE\;
	     IF DEBUGSWITCH
	     THEN
	       BEGIN
		 IF (LEVEL > 1) AND ( DISPLAY[TOP].FNAME # NIL )
		 THEN INSERTADDR(RIGHT,IDTREE,IC)
	       END
	     ELSE
	       IF LEVEL = 1
	       THEN HIGHESTCODE := IC
	   END%LEAVEBODY\;

	  PROCEDURE FETCHBASIS(VAR FATTR: ATTR);
	  VAR
	    P,Q: INTEGER;
	   BEGIN
	    WITH FATTR DO
	     IF VLEVEL>1
	     THEN
	       BEGIN
		P := LEVEL - VLEVEL;
		 IF P=0
		 THEN
		   IF INDEXR=0
		   THEN INDEXR := BASIS
		   ELSE MACRO3(270B%ADD\,INDEXR,BASIS)
		 ELSE
		   BEGIN
		    MACRO4(540B%HRR\,TAC,BASIS,-1);
		    FOR Q := P DOWNTO 2 DO
		    MACRO4(540B%HRR\,TAC,TAC,-1);
		     IF INDEXR=0
		     THEN INDEXR := TAC
		     ELSE MACRO3(270B%ADD\,INDEXR,TAC)
		   END;
		VLEVEL:=1	%DA IN WITHSTATEMENT DIE MOEGLICHKEIT BESTEHT,
				 DASS ES 2-MAL DURCH FETCHBASIS LAEUFT\
	       END
	   END;
	  %FETCHBASIS\

	  PROCEDURE GETPARADDR;
	   BEGIN
	    FETCHBASIS(GATTR);
	    WITH GATTR DO
	     BEGIN
	      INCREMENTREGC;
	      MACRO5(VRELBYTE,200B%MOVE\,REGC,INDEXR,DPLMT);
	      INDEXR := REGC; VRELBYTE:= NO;
	      INDBIT := 0; VLEVEL := 1; DPLMT := 0;
	     END
	   END;

{Warning to future modifiers: At the end of EXPRESSION, there is code that
 second-guesses the register allocation in this procedure.  If you change
 the register allocation here, please look at that code.}
	  PROCEDURE MAKECODE(FINSTR: INSTRANGE; FAC: ACRANGE; VAR FATTR: ATTR);
	  VAR
	    LINSTR: INSTRANGE; LREGC: ACRANGE;
	   BEGIN
	    WITH FATTR DO
	     IF TYPTR#NIL
	     THEN
	       BEGIN
		 CASE KIND OF
		  CST:
		       IF TYPTR=REALPTR
		       THEN
			 BEGIN
			  MACRO3(FINSTR,FAC,0); DEPCST(REEL,FATTR)
			 END
		       ELSE
			 IF TYPTR^.FORM=SCALAR
			 THEN
			  WITH CVAL DO
			   IF ((IVAL >= 0) AND (IVAL <= MAXADDR))
			    OR
(* 50 - correct code for 400000,,0 *)
			    ((ABS(IVAL) <= HWCSTMAX+1) AND (IVAL # 400000000000B)
			     AND
			     ((FINSTR = 200B%MOVE\) OR (IVAL >= 0)))
			   THEN
			     BEGIN
			       IF FINSTR=200B%MOVE\
			       THEN
				 IF IVAL < 0
				 THEN FINSTR := 571B%HRREI\
				 ELSE FINSTR := 551B%HRRZI\
			       ELSE
				 IF (FINSTR>=311B) AND (FINSTR <= 317B)
				 THEN FINSTR := FINSTR - 10B %E.G. CAML --> CAIL\
				 ELSE FINSTR := FINSTR+1;
			      MACRO3(FINSTR,FAC,IVAL);
			     END
			   ELSE
			     BEGIN
			      MACRO3(FINSTR,FAC,0); DEPCST(INT,FATTR)
			     END
			 ELSE
			   IF TYPTR=NILPTR
			   THEN
			     BEGIN
			       IF FINSTR=200B%MOVE\
			       THEN FINSTR := 571B%HRREI\
			       ELSE
				 IF (FINSTR>=311B) AND (FINSTR<=317B)
				 THEN FINSTR := FINSTR-10B
				 ELSE FINSTR := FINSTR+1;
			      MACRO3(FINSTR,FAC,377777B);
			     END
			   ELSE
			     IF TYPTR^.FORM=POWER
			     THEN
			       BEGIN
				MACRO3(FINSTR,FAC,0); MACRO3(FINSTR,FAC-1,0); DEPCST(PSET,FATTR);
			       END
			     ELSE
			       IF TYPTR^.FORM=ARRAYS
			       THEN
				 IF TYPTR^.SIZE = 1
				 THEN
				   BEGIN
				    MACRO3(FINSTR,FAC,0); DEPCST(STRG,FATTR)
				   END
				 ELSE
				   IF TYPTR^.SIZE = 2
				   THEN
				     BEGIN
				      FATTR.CVAL.VALP^.CCLASS := STRD;
				      MACRO3(FINSTR,FAC,0); MACRO3(FINSTR,FAC-1,0); DEPCST(STRD,FATTR);
				     END;
		  VARBL:
			 BEGIN
			  FETCHBASIS(FATTR); LREGC := FAC;
			   IF (INDEXR>REGIN) AND (INDEXR<=REGCMAX) AND ((PACKFG#NOTPACK) OR (FINSTR=200B%MOVE\))
			   THEN
			     IF (TYPTR^.SIZE = 2) AND LOADNOPTR
			     THEN LREGC := INDEXR+1
			     ELSE LREGC := INDEXR
			   ELSE
			     IF (PACKFG#NOTPACK) AND (FINSTR#200B%MOVE\)
			     THEN
			       BEGIN
				INCREMENTREGC; LREGC := REGC
			       END;
			   CASE PACKFG OF
			    NOTPACK:
				     BEGIN
				       IF (TYPTR^.SIZE = 2) AND LOADNOPTR
				       THEN
(* 141 - protect against obscure case where INDEXR = LREGC *)
					IF LREGC <> INDEXR
					 THEN BEGIN
					  MACRO5(VRELBYTE,FINSTR,LREGC,INDEXR,DPLMT+1);
					  MACRO5(VRELBYTE,FINSTR,LREGC-1,INDEXR,DPLMT)
					  END
					 ELSE BEGIN
					  MACRO5(VRELBYTE,FINSTR,LREGC-1,INDEXR,DPLMT);
					  MACRO5(VRELBYTE,FINSTR,LREGC,INDEXR,DPLMT+1)
					  END
				       ELSE MACRO(VRELBYTE,FINSTR,LREGC,INDBIT,INDEXR,DPLMT);
				     END;
			    PACKK:
				   BEGIN
				    MACRO5(VRELBYTE,201B%MOVEI\,TAC,INDEXR,DPLMT);
				     IF (BPADDR>REGIN) AND (BPADDR<=REGCMAX)
				     THEN
				       IF (INDEXR<=REGIN) OR (BPADDR<INDEXR)
				       THEN LREGC := BPADDR
				       ELSE LREGC := INDEXR;
				    MACRO3R(135B%LDB\,LREGC,BPADDR);
				   END;
			    HWORDL:  MACRO5(VRELBYTE,554B%HLRZ\,LREGC,INDEXR,DPLMT);
			    HWORDR:  MACRO5(VRELBYTE,550B%HRRZ\,LREGC,INDEXR,DPLMT)
			   END %CASE\;
			   IF (FINSTR#200B%MOVE\) AND (PACKFG#NOTPACK)
			   THEN
			    MACRO3(FINSTR,FAC,LREGC)
			   ELSE FAC := LREGC
			 END;
		  EXPR:
			IF FINSTR#200B%MOVE\
			THEN
			  IF TYPTR^.SIZE = 2
			  THEN
			    BEGIN
			     MACRO3(FINSTR,FAC,REG); MACRO3(FINSTR,FAC-1,REG-1)
			    END
			  ELSE MACRO3(FINSTR,FAC,REG)
		 END %CASE\;
		KIND := EXPR; REG := FAC;
	       END;
	   END;

	  PROCEDURE LOAD(VAR FATTR: ATTR);
	   BEGIN
	    WITH FATTR DO
	     IF TYPTR#NIL
	     THEN
	       IF KIND#EXPR
	       THEN
		 BEGIN
		  INCREMENTREGC ;
		   IF (TYPTR^.SIZE = 2) AND LOADNOPTR
		   THEN INCREMENTREGC ;
		  MAKECODE(200B%MOVE\,REGC,FATTR);REGC := REG
		 END;
	   END;
	  %LOAD\

(* 104 - common procedure for improved range check on subranges *)
	  procedure loadsubrange(var gattr:attr;lsp:stp);
	    var slattr:attr; srmin,srmax:integer;
	    begin
            GETBOUNDS(LSP,SRMIN,SRMAX);
	    IF (GATTR.KIND=CST)
	    THEN
	      IF (GATTR.CVAL.IVAL >= SRMIN) AND (GATTR.CVAL.IVAL <=SRMAX)
	      THEN LOAD (GATTR)
	      ELSE ERROR (367)
	    ELSE
	      BEGIN
	        IF RUNTMCHECK AND (( GATTR.KIND#VARBL) OR (GATTR.SUBKIND # LSP))
	        THEN
	          BEGIN
	           LOAD (GATTR);
	           WITH SLATTR DO
			BEGIN
			 TYPTR:=INTPTR;
			 KIND :=CST;
			 CVAL.IVAL:=SRMAX
			END;
	           MAKECODE(317B%CAMG\,REGC,SLATTR);
	           SLATTR.KIND:=CST;
	           SLATTR.CVAL.IVAL:=SRMIN;
	           MAKECODE(315B%CAMGE\,REGC,SLATTR);
	           SUPPORT(ERRORINASSIGNMENT)
	          END
	        ELSE LOAD (GATTR);
	      END
	    end;

	  PROCEDURE STORE(FAC: ACRANGE; VAR FATTR: ATTR);
	  VAR
	    LATTR: ATTR;
	   BEGIN
	    LATTR := FATTR;
	    WITH LATTR DO
	     IF TYPTR # NIL
	     THEN
	       BEGIN
		FETCHBASIS(LATTR);
		 CASE PACKFG OF
		  NOTPACK:
			   BEGIN
			     IF TYPTR^.SIZE = 2
			     THEN
			       BEGIN
				MACRO5(VRELBYTE,202B%MOVEM\,FAC,INDEXR,DPLMT+1); FAC := FAC-1
			       END;
			    MACRO(VRELBYTE,202B%MOVEM\,FAC,INDBIT,INDEXR,DPLMT)
			   END;
		  PACKK:
			 BEGIN
			  MACRO5(VRELBYTE,201B%MOVEI\,TAC,INDEXR,DPLMT);
			  MACRO3R(137B%DPB\,FAC,BPADDR);
			 END;
		  HWORDL:  MACRO5(VRELBYTE,506B%HRLM\,FAC,INDEXR,DPLMT);
		  HWORDR:  MACRO5(VRELBYTE,542B%HRRM\,FAC,INDEXR,DPLMT)
		 END  %CASE\ ;
	       END %WITH\ ;
	   END %STORE\ ;

{Warning to future modifiers: At the end of EXPRESSION, there is code that
 second-guesses the register allocation in this procedure.  If you change
 the register allocation here, please look at that code.}
	  PROCEDURE LOADADDRESS;
	   BEGIN
	    INCREMENTREGC ;
	     BEGIN
	      WITH GATTR DO
	       IF TYPTR # NIL
	       THEN
		 BEGIN
		   CASE KIND OF
		    CST:
			 IF STRING(TYPTR)
			 THEN
			   BEGIN
			    MACRO3(201B%MOVEI\,REGC,0);
			    DEPCST(STRG,GATTR)
			   END
			 ELSE ERROR(171);
		    VARBL:
			   BEGIN
			     IF (INDEXR>REGIN)	AND  (INDEXR <= REGCMAX)
			     THEN REGC := INDEXR;
			    FETCHBASIS(GATTR);
			     CASE PACKFG OF
			      NOTPACK: MACRO(VRELBYTE,201B%MOVEI\,REGC,INDBIT,INDEXR,DPLMT);
			      PACKK,HWORDL,HWORDR: ERROR(357)
			     END;
			   END;
		    EXPR:  ERROR(171)
		   END;
		  KIND := VARBL;  DPLMT := 0; INDEXR:=REGC; INDBIT:=0; VRELBYTE := NO
		 END
	     END
	   END %LOADADDRESS\ ;

	  PROCEDURE WRITEMC(WRITEFLAG:WRITEFORM);
	  CONST
(* 155 *)
	    MAXSIZE %OF CONSTANT-, STRUCTURE-, AND ID.-RECORD\ = 44 %WORDS\ ;
	  TYPE
	    WANDELFORM=(KONSTANTE,PDP10CODE,REALCST,STRCST,SIXBITCST,HALFWD,PDP10BP,RADIX) ;
	    RECORDFORM=(NONE,CONSTNTREC,STRUCTUREREC,IDENTIFREC,DEBUGREC);
	    BIGALFA = PACKED ARRAY[1..15] OF CHAR ;
	  VAR
	    I,J,L  : INTEGER; LLISTCODE: BOOLEAN; CHECKER: CTP;
	    LIC  : ADDRRANGE; LFIRSTKONST: KSP; LRELBYTE: RELBYTE;
	    STRING: ARRAY[1..6] OF CHAR; LFILEPTR: FTP; SWITCHFLAG: FLAGRANGE;
	    FILBLOCKADR : ADDRRANGE ; CODEARRAY: BOOLEAN; LICMOD4: ADDRRANGE;
	    LSIZE: 1..MAXSIZE; RUN1: BOOLEAN; SAVELISTCODE: BOOLEAN;
	    CSP0: CSP; %INSTEAD OF NIL\
	    RELARRAY, RELEMPTY: ARRAY[1..MAXSIZE] OF RELBYTE;
	    WANDLUNG : PACKED RECORD
				CASE WANDELFORM  OF
				     KONSTANTE:(WKONST :INTEGER);
				     PDP10CODE:(WINSTR :PDP10INSTR);
				     REALCST  :(WREAL: REAL);
				     STRCST   :(WSTRING:CHARWORD);
				     SIXBITCST:(WSIXBIT:PACKED ARRAY[1..6] OF 0..77B);
				     HALFWD   :(WLEFTHALF:ADDRRANGE ; WRIGHTHALF : ADDRRANGE);
				     PDP10BP  :(WBYTE: BPOINTER);
				     RADIX    :(FLAG: FLAGRANGE; SYMBOL: RADIXRANGE)

			      END;
	    ICWANDEL: PACKED RECORD
			       CASE VARIANTE:INTEGER OF
				    1:(ICVAL: ADDRRANGE);
				    2:(ICCSP: CSP);
				    3:(ICCTP: CTP);
				    4:(ICSTP: STP)
			     END;
	    RECORDWANDEL: PACKED RECORD
				   CASE RECORDFORM OF
					NONE:  (WORD:ARRAY[1..MAXSIZE] OF INTEGER);
					CONSTNTREC:(CONSTREC: CONSTNT);
					STRUCTUREREC:(STRUCTREC: STRUCTURE);
					IDENTIFREC:(IDENTREC: IDENTIFIER);
					DEBUGREC:(DEBUGREC: DEBENTRY)
				 END;

	    PROCEDURE NEUEZEILE;
	     BEGIN
(* 6 - if CREFing, less stuff fits on a line *)
	      IF CREF
		THEN LICMOD4 := LIC MOD 3
		ELSE LICMOD4 := LIC MOD 4;
	       IF (LICMOD4 = 0) AND LISTCODE AND (LIC > 0)
	       THEN
		 BEGIN
(* 136 - LISTING FORMAT *)
		  newline ;
		   IF RELBLOCK.ITEM = 1
		   THEN
		     BEGIN
		      WRITE(LIC:6:O);
		       IF LIC >= PROGRST
		       THEN WRITE('''')
		       ELSE WRITE(' ')
		     END
		   ELSE WRITE(' ':7)
		 END
	     END %NEUEZEILE\ ;

	    PROCEDURE PUTRELCODE;
	    VAR
	      I: INTEGER;

	     BEGIN
	      WITH RELBLOCK DO
(* 146 - Move count := 0 outside the test, since we must zero count in
   the case where COUNT = 1 and ITEM = 1. *)
	       BEGIN
	       IF ((COUNT > 1) OR (ITEM # 1)) AND (COUNT > 0)
	       THEN
		 BEGIN
		  FOR I:= COUNT+1 TO 18 DO RELOCATOR[I-1] := NO;
		  FOR I:= 1 TO COUNT+2 DO
		   BEGIN
		    OUTPUTREL^:= COMPONENT[I];
		    PUT(OUTPUTREL)
		   END;
		 END;
(* 146 *)
	       COUNT := 0;
	       END;
	     END;

	    PROCEDURE SHOWRELOCATION(FSIDE: RELBYTE; FRELBYTE: RELBYTE);
	     BEGIN
	       IF (FRELBYTE = FSIDE) OR (FRELBYTE = BOTH)
	       THEN WRITE('''')
	       ELSE WRITE(' ')
	     END;

	    PROCEDURE WRITEBLOCKST( FITEM: ADDRRANGE);
	    VAR
	      WANDLUNG: PACKED RECORD
				 CASE BOOLEAN OF
				      TRUE: (WKONST: INTEGER);
				      FALSE: (WLEFTHALF: ADDRRANGE;WRIGHTHALF: ADDRRANGE)
			       END;
	     BEGIN
	      WITH RELBLOCK , WANDLUNG DO
	       BEGIN
		 IF COUNT # 0
		 THEN PUTRELCODE;
		ITEM:= FITEM;
		 IF ITEM = 1
		 THEN
		   BEGIN
		    WLEFTHALF:= 0;
		    WRIGHTHALF:= LIC;
		    CODE[0]:= WKONST;
		     IF WRIGHTHALF < PROGRST
		     THEN RELOCATOR[0] := NO
		     ELSE RELOCATOR[0] := RIGHT;
		    COUNT:= 1
		   END
	       END
	     END;

	    PROCEDURE WRITEWORD(FRELBYTE: RELBYTE; FWORD: INTEGER);
	    VAR
	      WANDLUNG: PACKED RECORD
				 CASE BOOLEAN OF
				      TRUE: (WKONST: INTEGER);
				      FALSE: (WLEFTHALF: ADDRRANGE; WRIGHTHALF: ADDRRANGE)
			       END;
	     BEGIN
	      WITH WANDLUNG DO
	       BEGIN
		WKONST := FWORD;
		WITH RELBLOCK DO
		 BEGIN
		   IF COUNT = 0
		   THEN WRITEBLOCKST(ITEM);
		  CODE[COUNT]:= FWORD;
		   IF FRELBYTE IN [LEFT,BOTH]
		   THEN
		     IF (WLEFTHALF < PROGRST) OR (WLEFTHALF = 377777B)
		     THEN FRELBYTE := FRELBYTE - LEFT;
		   IF FRELBYTE IN [RIGHT,BOTH]
		   THEN
		     IF (WRIGHTHALF < PROGRST) OR (WRIGHTHALF = 377777B)
		     THEN FRELBYTE := FRELBYTE - RIGHT;
		  RELOCATOR[COUNT]:= FRELBYTE; LRELBYTE := FRELBYTE;
		  COUNT := COUNT+1;
		   IF COUNT = 18
		   THEN PUTRELCODE
		 END;
		 IF LLISTCODE
		 THEN
		   BEGIN
		    NEUEZEILE;
		     IF LIC > 0
		     THEN WRITE(' ':13);
(* 173 - remove writefileblocks *)
		     IF WRITEFLAG > WRITELIBRARY
		     THEN WRITE(' ':7)
		     ELSE
		       BEGIN
			WRITE(WLEFTHALF:6:O); SHOWRELOCATION(LEFT,FRELBYTE)
		       END;
		    WRITE(WRIGHTHALF:6:O); SHOWRELOCATION(RIGHT,FRELBYTE); WRITE(' ':3)
		   END;
		 IF NOT CODEARRAY
		 THEN LIC := LIC + 1
	       END
	     END;

	    FUNCTION RADIX50( FNAME: ALFA): RADIXRANGE;
	    VAR
	      I: INTEGER; OCTALCODE, RADIXVALUE: RADIXRANGE;

	     BEGIN
	      RADIXVALUE:= 0;
	      I:=1;
	      WHILE (FNAME[I] # ' ') AND (I <= 6) DO
	       BEGIN
		 IF FNAME[I] IN DIGITS
		 THEN OCTALCODE:= ORD(FNAME[I])-ORD('0')+1
		 ELSE
		   IF FNAME[I] IN LETTERS
		   THEN OCTALCODE:= ORD(FNAME[I])-ORD('A')+11
		   ELSE
		     CASE FNAME[I] OF
		      '.': OCTALCODE:= 37;
		      '$': OCTALCODE:= 38;
		      '%': OCTALCODE:= 39
		     END;
		RADIXVALUE:= RADIXVALUE*50B; RADIXVALUE:= RADIXVALUE+OCTALCODE; I:=I+1
	       END;
	      RADIX50:= RADIXVALUE
	     END;

	    PROCEDURE WRITEPAIR( FRELBYTE: RELBYTE; FADDR1, FADDR2: ADDRRANGE);
	     BEGIN
	      WITH WANDLUNG DO
	       BEGIN
		WLEFTHALF:= FADDR1;
		WRIGHTHALF:= FADDR2;
		WRITEWORD(FRELBYTE,WKONST)
	       END
	     END;

	    PROCEDURE WRITEIDENTIFIER( FFLAG: FLAGRANGE; FSYMBOL: ALFA);
	     BEGIN
	      LLISTCODE := FALSE;
	      WITH WANDLUNG DO
	       BEGIN
		 IF LISTCODE AND (WRITEFLAG > WRITEHISEG)
		 THEN
		   BEGIN
(* 40 - if CREFing, less stuff fits on a line *)
		     IF ((NOT CREF) AND (LIC MOD 4 = 0) OR
			 CREF AND (LIC MOD 3 = 0)) AND (LIC > 0)
		     THEN
		       BEGIN
(* 136 - LISTING FORMAT *)
			NEWLINE;
			WRITE(' ':7)
		       END;
		     IF LIC > 0
		     THEN WRITE(' ':13); WRITE(FSYMBOL:6,' ':11)
		   END;
(* 40 - print format *)
		 if listcode and cref then lic := lic+1;
		 IF FFLAG # 6B
		 THEN
		   BEGIN
		    FLAG:= FFLAG; SYMBOL:= RADIX50(FSYMBOL)
		   END;
		WRITEWORD(NO,WKONST); LLISTCODE := LISTCODE
	       END
	     END;

	    PROCEDURE WRITEFIRSTLINE ;
	     BEGIN
	       IF LISTCODE
	       THEN
		 BEGIN
(* 136 - LISTING FORMAT *)
		  NEWLINE;
(* 6 - if CREFing, less stuff fits on a line *)
		  IF CREF
		    THEN LICMOD4 := LIC MOD 3
		    ELSE LICMOD4 := LIC MOD 4;
		   IF LICMOD4 > 0
		   THEN
		     BEGIN
		      WRITE(LIC-LICMOD4:6:O);
		       IF LIC >= PROGRST
		       THEN WRITE('''')
		       ELSE WRITE(' ');
		      WRITE(' ':LICMOD4*30);
		       IF (WRITEFLAG = WRITECODE) AND CODEARRAY
		       THEN WRITE(' ':2)
		     END
		 END
	     END ;

	    PROCEDURE WRITEHEADER(FTEXT: BIGALFA);
	     BEGIN
	      LIC := 0;
	       IF LISTCODE
	       THEN
		 BEGIN
(* 136 - LISTING FORMAT *)
		  NEWLINE;
		  WRITE(FTEXT:15,':',' ':4)
		 END
	     END;

(*173 - remove writefileblocks *)

	    PROCEDURE MCGLOBALS;
	     BEGIN
	      %MCGLOBALS\
	       IF LISTCODE AND (FGLOBPTR # NIL)
	       THEN WRITEBUFFER;
	      WHILE FGLOBPTR # NIL DO
	      WITH FGLOBPTR^ DO
	       BEGIN
		LIC := FIRSTGLOB ; WRITEFIRSTLINE ;
		J := FCIX ;
		WRITEBLOCKST(1);
		FOR I := FIRSTGLOB TO LASTGLOB DO
		 BEGIN
		  WANDLUNG.WINSTR := CODE.INSTRUCTION[J] ; J := J + 1 ;
		  WRITEWORD(NO,WANDLUNG.WKONST) ;
		 END ;
		FGLOBPTR := NEXTGLOBPTR
	       END;
	     END %MCGLOBALS\;

	    PROCEDURE MCCODE;

	      PROCEDURE WRITERECORD;
	       BEGIN
		FOR I := 1 TO LSIZE DO WRITEWORD(RELARRAY[I], RECORDWANDEL.WORD[I] )
	       END;

(* 211 - MAKE CONSTANTS WORK IN THE DEBUGGER *)
	      FUNCTION CONSTRECSIZE(FCSP: CSP): INTEGER;
	       BEGIN
		WITH FCSP^ DO
		 CASE CCLASS OF
		  INT,PSET: CONSTRECSIZE := 5;
		  REEL	  : CONSTRECSIZE := 4;
		  STRD,STRG:CONSTRECSIZE := 4 + (SLGTH+4) DIV 5
		 END
	       END;

	      PROCEDURE COPYCSP(FCSP:CSP);
	       BEGIN
		 IF FCSP # NIL
		 THEN  WITH FCSP^ DO
		   IF RUN1
		   THEN
		     BEGIN
		       IF SELFCSP = CSP0%NIL\
		       THEN WITH ICWANDEL DO
			 BEGIN
			  ICVAL := IC; SELFCSP := ICCSP;
			  NOCODE := TRUE;
			  IC := IC + CONSTRECSIZE(FCSP)
			 END
		     END
		   ELSE
		     IF NOCODE
		     THEN
		       BEGIN
			RECORDWANDEL.CONSTREC := FCSP^;
			LSIZE := CONSTRECSIZE(FCSP);
			RELARRAY := RELEMPTY;
			WRITERECORD; NOCODE := FALSE
		       END
	       END %COPYCSP\;

	      PROCEDURE COPYSTP(FSP:STP); FORWARD;

	      PROCEDURE COPYCTP(FCP:CTP);
	       BEGIN
		 IF FCP # NIL
		 THEN WITH FCP^ DO
		   IF RUN1 AND (SELFCTP=NIL) OR NOT RUN1 AND NOCODE
		   THEN
		     BEGIN
		       IF RUN1
		       THEN
			WITH ICWANDEL DO
			 BEGIN
			  ICVAL := IC;
			  SELFCTP := ICCTP; NOCODE := TRUE;
			  IC := IC + IDRECSIZE[KLASS]
			 END %WITH\
		       ELSE %NOW RUN 2\
			WITH RECORDWANDEL DO
			 BEGIN
			  RELARRAY := RELEMPTY;
			  IDENTREC := FCP^;
			  WITH IDENTREC DO
			   BEGIN
			     IF LLINK#NIL
			     THEN
			       BEGIN
				LLINK:=LLINK^.SELFCTP; RELARRAY[3] := 1
			       END;
			     IF RLINK#NIL
			     THEN
			       BEGIN
				RLINK:=RLINK^.SELFCTP; RELARRAY[3] := RELARRAY[3] + 2
			       END;
			     IF NEXT #NIL
			     THEN
			       BEGIN
				NEXT := NEXT^.SELFCTP; RELARRAY[4] := 1B
			       END;
			     IF IDTYPE # NIL
			     THEN
			       BEGIN
				 IF KLASS = KONST
				 THEN
				   IF IDTYPE^.FORM > POINTER
				   THEN
(* 211 - FIX CONSTANT PRINTING *)
				     BEGIN
				     VALUES.VALP := VALUES.VALP^.SELFCSP;
				     RELARRAY[6] := 1B
				     END
				   ELSE
				     IF IDTYPE = REALPTR
				     THEN
				       BEGIN
					WANDLUNG.WREAL := VALUES.VALP^.RVAL;
					VALUES.IVAL := WANDLUNG.WKONST
				       END;
				 IF KLASS=VARS
				 THEN
				   IF VLEV<2
				   THEN RELARRAY[6] := 2;
				 IF KLASS = FIELD
				 THEN
				   IF PACKF = PACKK
				   THEN RELARRAY[6] := 2;
				IDTYPE:=IDTYPE^.SELFSTP; RELARRAY[4] := RELARRAY[4] + 2
			       END
			   END;
			  LSIZE := IDRECSIZE[KLASS]; WRITERECORD;
			  NOCODE := FALSE
			 END %WITH RECORDWANDEL\;
		      COPYCTP(LLINK);
		      COPYCTP(RLINK);
		      COPYSTP(IDTYPE);
(* 214 - fix debugger problem with foward declared proc's *)
{The following is somewhat of a kludge. We don't want to do COPYCTP
 on the NEXT field of a procedure.  If we did, the following could
 happen:
	procedure foo(x:integer); forward;
	...
	  foo(1);
	...
	procedure foo;
	  var i,j;
 When the final declaration of FOO is supplied, the symbol table is
 initialized from symboltable(FOO)^.NEXT, which contains the parameters,
 as supplied in the forward decl.  Then I and J are added to the symbol
 table.  The result is that X points to I and J in the symbol table
 tree.  This is all fine.  The problem comes when the identifier
 record for FOO is put into the .REL file before the final declaration.
 If COPYCTP traces the NEXT field, then the identifier records for all
 the parameters are also put out.  Since a given identifier is put out
 only once, this means that X is put into the .REL file before pointers
 to I and J are added to it.  The effect is that the debugger can't
 see I and J.
    It turns out that the  debugger never uses the NEXT field of a
 procedure entry.  Thus it is not crucial to have a correctly mapped
 value when the identifier record for the procedure is put out.
 If we don't call COPYCTP on NEXT, then the NEXT field put into the
 .REL file will be junk, but at least records for the parameters won't
 be put out prematurely.  They will get put out eventually even without
 tracing NEXT, since they will show up in the symbol table for the
 procedure when it is finally declared.  That should suffice.}

		      IF NOT (KLASS IN [PROC,FUNC])
		        THEN COPYCTP(NEXT);
		       IF (KLASS = KONST)  AND (IDTYPE # NIL)
		       THEN
			 IF IDTYPE^.FORM > POINTER
			 THEN COPYCSP(VALUES.VALP)
		     END %WITH FCP^\
	       END %COPYCTP\;

	      PROCEDURE COPYSTP;
	       BEGIN
		 IF FSP # NIL
		 THEN WITH FSP^ DO
		   IF RUN1 AND (SELFSTP = NIL)	OR  NOT RUN1 AND NOCODE
		   THEN
		     BEGIN
		       IF RUN1
		       THEN
			WITH ICWANDEL DO
			 BEGIN
			  NOCODE:=TRUE;
			  ICVAL := IC; SELFSTP := ICSTP;
			  IC := IC + STRECSIZE[FORM]
			 END
		       ELSE %NOW RUN 2\
			 IF NOCODE
			 THEN WITH RECORDWANDEL DO
			   BEGIN
			    RELARRAY := RELEMPTY; RELARRAY[2] := 1;
			    STRUCTREC := FSP^;
			    WITH STRUCTREC DO
			     CASE FORM OF
			      SCALAR:
				      IF SCALKIND = DECLARED
				      THEN
					IF FCONST#NIL
					THEN FCONST:=FCONST^.SELFCTP;
			      SUBRANGE:
					BEGIN
					 RANGETYPE:=RANGETYPE^.SELFSTP; RELARRAY[2]:=1
					END;
			      POINTER:
				       IF ELTYPE # NIL
				       THEN ELTYPE := ELTYPE^.SELFSTP;
			      POWER:	ELSET := ELSET^.SELFSTP;
			      ARRAYS:
				      BEGIN
(* 122 - DON'T FOLLOW NILS ON FUDGED TYPES *)
				      IF AELTYPE#NIL
				        THEN AELTYPE := AELTYPE^.SELFSTP;
				      IF INXTYPE#NIL
					THEN INXTYPE := INXTYPE^.SELFSTP; 
				      RELARRAY[3] := 3
				      END;
			      RECORDS:
				       BEGIN
					 IF FSTFLD # NIL
					 THEN FSTFLD := FSTFLD^.SELFCTP;
					 IF RECVAR # NIL
					 THEN
					   BEGIN
					    RECVAR := RECVAR^.SELFSTP; RELARRAY[3] := 2
					   END
				       END;
			      FILES:	IF FILTYPE # NIL 
					  THEN FILTYPE := FILTYPE^.SELFSTP;
			      TAGFWITHID,
			      TAGFWITHOUTID:
					     BEGIN
					      FSTVAR := FSTVAR^.SELFSTP;
					       IF FORM = TAGFWITHID
					       THEN TAGFIELDP := TAGFIELDP^.SELFCTP
					       ELSE TAGFIELDTYPE := TAGFIELDTYPE^.SELFSTP;
					      RELARRAY[3] := 2
					     END;
			      VARIANT:
				       BEGIN
					 IF SUBVAR # NIL
					 THEN SUBVAR := SUBVAR^.SELFSTP;
					 IF FIRSTFIELD # NIL
					 THEN
					   BEGIN
					    FIRSTFIELD := FIRSTFIELD^.SELFCTP; RELARRAY[3]:=1
					   END;
					 IF NXTVAR # NIL
					 THEN
					   BEGIN
					    NXTVAR := NXTVAR^.SELFSTP; RELARRAY[3] :=RELARRAY[3] + 2
					   END;
				       END
			     END %CASE\;
			    LSIZE := STRECSIZE[FORM]; WRITERECORD;
			    NOCODE := FALSE
			   END %RUN 2\;
		       CASE FORM OF
			SCALAR:
				IF SCALKIND = DECLARED
				THEN COPYCTP(FCONST);
			SUBRANGE:COPYSTP(RANGETYPE);
			POINTER: COPYSTP(ELTYPE);
			POWER:	 COPYSTP(ELSET);
			ARRAYS:
				BEGIN
				 COPYSTP(AELTYPE);
				 COPYSTP(INXTYPE)
				END;
			RECORDS:
				 BEGIN
				  COPYCTP(FSTFLD);
				  COPYSTP(RECVAR)
				 END;
			FILES:	 COPYSTP(FILTYPE);
			TAGFWITHID,
			TAGFWITHOUTID:
				       BEGIN
					COPYSTP(FSTVAR);
					 IF FORM = TAGFWITHID
					 THEN COPYCTP(TAGFIELDP)
					 ELSE COPYSTP(TAGFIELDTYPE)
				       END;
			VARIANT:
				 BEGIN
				  COPYSTP(NXTVAR);
				  COPYSTP(SUBVAR);
				  COPYCTP(FIRSTFIELD)
				 END
		       END %CASE\
		     END %WITH\
	       END %COPYSTP\;

	     BEGIN
	      %MCCODE\
	      CODEARRAY := FALSE; LLISTCODE:= FALSE;
	       IF LISTCODE
	       THEN WRITEBUFFER;
	       IF LASTBTP # NIL
	       THEN
		WITH LASTBTP^ DO
		 CASE BKIND OF
		  RECORDD:  LIC := FIELDCP^.FLDADDR ;
		  ARRAYY :  LIC := ARRAYSP^.ARRAYBPADDR
		 END ;
	      WRITEFIRSTLINE ; WRITEBLOCKST(1);
	      WHILE LASTBTP # NIL DO
	       BEGIN
		WITH  LASTBTP^,BYTE  DO
		 BEGIN
		   IF LISTCODE
		   THEN
		     BEGIN
		      NEUEZEILE;
		       IF LICMOD4 = 0
		       THEN WRITE(' ':7)
		       ELSE WRITE(' ':5);
		      WRITE(' POINT  ',SBITS:2,',') ;
		       IF IBIT = 0
		       THEN WRITE('  ')
		       ELSE WRITE(' @') ;
		      WRITE(RELADDR:5:O,'(',IREG:2:O,'),',35-PBITS:2) ;
		     END;
		  WITH WANDLUNG DO
		   BEGIN
		    WBYTE := BYTE;
		    WRITEWORD(NO,WKONST)
		   END;
		  LASTBTP := LAST
		 END
	       END % WHILE\ ;
	      LIC := CODEEND - CIX - 1 ; CODEARRAY := TRUE;
	      WRITEBLOCKST(1); WRITEFIRSTLINE;
	      FOR  I := 0 TO  CIX  DO
	      WITH CODE, INSTRUCTION[I], HALFWORD[I] DO
	       BEGIN
		LRELBYTE := RELOCATION[I]; WRITEWORD(LRELBYTE,WORD[I]);
		 IF LISTCODE
		 THEN
		   BEGIN
		    NEUEZEILE;
		     IF LICMOD4 = 0
		     THEN WRITE(' ':7)
		     ELSE WRITE(' ':5);
		     CASE INFORMATION[I] OF
		      'W':
			   BEGIN
			    WRITE(' ':6,LEFTHALF :6:O); SHOWRELOCATION(LEFT,LRELBYTE);
			    WRITE(RIGHTHALF:6:O); SHOWRELOCATION(RIGHT,LRELBYTE);
			    WRITE(' ':5)
			   END;
			  %'B': WITH WANDLUNG.WBYTE DO
			   BEGIN
			   WANDLUNG.WKONST := WORD[I];
			   WRITE(' POINT  ',SBITS:2,',');
			   IF IBIT = 0 THEN WRITE('  ') ELSE WRITE(' @');
			   WRITE(RELADDR:5:O,'(',IREG:2:O,'),',35-PBITS:2)
			   END;\
		      OTHERS:
			      BEGIN
(* 6 - UNPACK CAN'T DO THIS NOW *)
			       %UNPACK(MNEMONICS[(INSTR+9) DIV 10],((INSTR+9) MOD 10)*6+1,STRING,6);\
			       FOR J := 1 TO 6 DO
				STRING[J] := MNEMONICS[(INSTR+9) DIV 10, ((INSTR+9) MOD 10)*6 + J];
			       WRITE(' ',STRING:6, ' ',AC:2:O,', ');
				IF INDBIT = 0
				THEN WRITE(' ')
				ELSE WRITE('@');
			       WRITE(ADDRESS:6:O); SHOWRELOCATION(RIGHT,LRELBYTE);
				IF INXREG > 0
				THEN WRITE('(',INXREG:2:O,')',INFORMATION[I]:1)
				ELSE WRITE(' ':4,INFORMATION[I]:1)
			      END
		     END
		   END;
		LIC := LIC + 1
	       END  %FOR \ ;
	      CODEARRAY := FALSE; LLISTCODE := LISTCODE;
	       IF FIRSTKONST # NIL
	       THEN
		 BEGIN
		  LFIRSTKONST := FIRSTKONST; WRITEFIRSTLINE; WRITEBLOCKST(1);
		  WHILE LFIRSTKONST # NIL DO
		   BEGIN
		    WITH LFIRSTKONST^.CONSTPTR^ DO
		     CASE  CCLASS  OF
		      INT,
		      REEL: WRITEWORD(NO,INTVAL) ;
		      PSET:
			    BEGIN
			     % THE SET IS PICKED UP
			      AND WRITTEN OUT AS TWO OCTAL NUMBERS \
			     WRITEWORD(NO,INTVAL) ;
			     WRITEWORD(NO,INTVAL1) ;
			    END ;
		      STRD,
		      STRG: WITH WANDLUNG DO
			    BEGIN
			     J :=0; WKONST := 0;
			     FOR I := 1 TO SLGTH DO
			      BEGIN
			       J := J+1;
			       WSTRING[J] := SVAL[I];
				IF J=5
				THEN
				  BEGIN
				   J := 0;
				   WRITEWORD(NO,WKONST);
				   WKONST := 0
				  END
			      END;
			      IF J#0
			      THEN
			       WRITEWORD(NO,WKONST)
			    END
		     END;
		    LFIRSTKONST := LFIRSTKONST^.NEXTKONST
		   END	%WHILE\
		 END;
	       IF DEBUG
	       THEN
		 BEGIN
		   IF DEBUGSWITCH
		   THEN
		     BEGIN
(* 103 - globalidtree moved below *)
		      WRITEFIRSTLINE;
		      FOR RUN1 := TRUE DOWNTO FALSE DO COPYCTP(DISPLAY[TOP].FNAME);
		       IF LEVEL = 1
		       THEN
			 BEGIN
(* 103 - new way to set globalidtree and standardidtree *)
			  FOR RUN1 := TRUE DOWNTO FALSE DO COPYCTP(DISPLAY[0].FNAME);
			  if display[top].fname = nil
			    then debugentry.globalidtree := nil
			    else debugentry.globalidtree := display[top].fname^.selfctp;
			  debugentry.standardidtree := display[0].fname^.selfctp;
			 END;
		     END %DEBUGSWITCH\;
		   IF LEVEL = 1
		   THEN
		     BEGIN
		      WITH DEBUGENTRY DO
		       BEGIN
			NEWPAGER; LASTPAGEELEM := PAGER;
			INTPOINT  := INTPTR^. SELFSTP;
			REALPOINT := REALPTR^.SELFSTP;
			CHARPOINT := CHARPTR^.SELFSTP;
(* 36 - ALLOW MULTIPLE MODULES *)
			NEXTDEB := 0; %LINK WILL MAKE THIS PTR TO SIMILAR ENTRY IN NEXT MODULE\
			MODNAME := FILENAME;
		       CURNAME(INPUT,SOURCE);
		       END;
		      PAGEHEADADR := IC;
		      LSIZE := 44; %LENGTH OF DEBUGENTRY-RECORD\
		      RELARRAY[1] := 0;
		      FOR I:=2 TO 8 DO RELARRAY[I] := 1;
		      FOR I:= 9 TO LSIZE DO RELARRAY[I] := 0;
		      RECORDWANDEL.DEBUGREC := DEBUGENTRY;
		      IC := IC + LSIZE;
		      WRITERECORD;
		      HIGHESTCODE := IC;
(* 40 - fix printing format *)
(* 136 - LISTING FORMAT *)
		      if listcode then NEWLINE;
		      WRITEHEADER('LINK IN CHAIN 1');
		      LLISTCODE := FALSE;
		      WRITEBLOCKST(12B); %LINK BLOCK\
		      WRITEPAIR(NO,0,1); %LINK NUMBER 1\
		      LLISTCODE := LISTCODE;
		      WRITEPAIR(RIGHT,0,PAGEHEADADR); %NEXTDEB FIELD\
(* NB: LOCATION 141/2 ARE NOW HANDLED BY DEBSUP. 143 GETS .LNKEND FOR THE
      LINK SET UP ABOVE *)
		     END;
(* 5 - CREF *)
		 END;
(* 136 - LISTING FORMAT *)
	     IF LISTCODE THEN NEWLINE;
	     END %MCCODE\;

	    PROCEDURE MCVARIOUS;
	    VAR
(* 17 - MAKE SYMBOLS ACCEPTABLE TO DEC DDT *)
	      INLEVEL: BOOLEAN; PNAME:ALFA;
	     BEGIN
	      %MCVARIOUS\
	       CASE WRITEFLAG OF

(* 13 - ADD WRITEBLOCK FOR DDT SYMBOLS *)
(* 16 - MAKE ACCEPTABLE TO DEC DDT *)
		WRITEBLK:
				BEGIN
				PNAME := DISPLAY[TOP].BLKNAME;
(* 40 - fix print format *)
			        WRITEHEADER('LOCAL SYMBOLS  ');
				WRITEBLOCKST(2);
				WRITEIDENTIFIER(2B,PNAME);
				WRITEPAIR(RIGHT,0,PFSTART);
				I:=5;
				WHILE PNAME[I]=' ' DO I:=I-1;
				IF PFDISP#PFSTART
				 THEN BEGIN
				 PNAME[I+1]:='.';
				 WRITEIDENTIFIER(2B,PNAME);
				 WRITEPAIR(RIGHT,0,PFDISP)
				 END;
				IF PFPOINT#PFDISP
				 THEN BEGIN
				 PNAME[I+1]:='%';
				 WRITEIDENTIFIER(2B,PNAME);
				 WRITEPAIR(RIGHT,0,PFPOINT)
				 END
				END;
(* 164 - add Polish fixups *)
		WRITEPOLISH:
				BEGIN
				WRITEHEADER('POLISH FIXUPS  ');
				WHILE FIRSTPOL <> NIL DO
				  WITH FIRSTPOL^ DO
				    BEGIN
{A Polish fixup block looks like this:
   type 11
   operator,,0		0 means next half word is operand
   operand1,,0
   operand2,,-1		-1 means put in RH of result addr
   place to put result,,0
}
				    WRITEBLOCKST(11B);
				    IF OFFSET < 0
				      THEN WRITEPAIR(NO,4,0)  {4 - SUB}
				      ELSE WRITEPAIR(NO,3,0); {3 - ADD}
				    WRITEPAIR(LEFT,BASE,0);
				    WRITEPAIR(NO,ABS(OFFSET),777777B);
				    WRITEPAIR(LEFT,WHERE,0);
				    PUTRELCODE;
				    FIRSTPOL := NEXTPOL;  {CDR down list}
				    END;
				if cref and listcode then NEWLINE;
				END;
				    
		WRITEINTERNALS:
				BEGIN
				 WRITEHEADER('LOCAL REQUESTS '); INLEVEL := TRUE;
				 WRITEBLOCKST(8); CHECKER := LOCALPFPTR;
				 WHILE (CHECKER # NIL) AND INLEVEL DO
				 WITH CHECKER^ DO
				  IF PFLEV = LEVEL
				  THEN
				    BEGIN
				      IF PFADDR # 0
				      THEN
				       FOR I := 0 TO MAXLEVEL DO
					IF LINKCHAIN[I] # 0
					THEN WRITEPAIR(BOTH,LINKCHAIN[I],PFADDR-I);
				     CHECKER:= PFCHAIN
				    END
				  ELSE INLEVEL := FALSE;
				  IF LEVEL > 1
				  THEN LOCALPFPTR := CHECKER;
				 WHILE FIRSTKONST # NIL DO
				 WITH FIRSTKONST^, CONSTPTR^ DO
				  BEGIN
				   WRITEPAIR(BOTH,ADDR,KADDR);
(* 72 - two fixup chains for 2 word consts *)
				    IF (CCLASS IN [PSET,STRD]) AND (ADDR1 <> 0)
				    THEN WRITEPAIR(BOTH,ADDR1,KADDR+1);
				   FIRSTKONST:= NEXTKONST
				  END;
(* 64 - non-local gotos *)
				inlevel := true;
				while (lastlabel # nil) and inlevel do
				  with lastlabel^ do
				    if scope = level
				      then begin
				      if gotochain # 0
					then if labeladdress = 0
					  then errorwithtext(215,name)
					  else writepair(both,gotochain,labeladdress);
				      lastlabel := next
				      end
				     else inlevel := false;
(* 40 - print format *)
(* 136 - LISTING FORMAT *)
				if cref and listcode then NEWLINE;
				END;
		WRITEEND:
			  BEGIN
			   WRITEHEADER('HIGHSEG-BREAK  ');
			   WRITEBLOCKST(5);
			   WRITEPAIR(RIGHT,0,HIGHESTCODE);
			   WRITEHEADER('LOWSEG-BREAK   ');
			   WRITEPAIR(RIGHT,0,LCMAIN); PUTRELCODE
			  END;

		WRITESTART:
			    IF MAIN
			    THEN
			      BEGIN
(* 33 - VERSION NO. *)
				WRITEHEADER('VERSION NUMBER ');
				LIC := 137B;
(* 40 - fix print format *)
				WRITEBLOCKST(1);
			  	if listcode then with version do
				  write('    ',who:1:o,'  ',major:3:o,'  ',minor:2:o,'  ',edit:6:o);
				llistcode := false;
				WRITEWORD(NO,VERSION.WORD);
				llistcode := listcode;
			       WRITEHEADER('STARTADDRESS   ');
			       WRITEBLOCKST(7);
			       WRITEPAIR(RIGHT,0,STARTADDR)
			      END;

		WRITEENTRY:
			    BEGIN
			     WRITEBLOCKST(4);
(* 34 - USE LIST OF ENTRIES IN PROGRAM IF APPROPRIATE *)
			     IF MAIN OR (FPROGFILE = NIL)
			       THEN WRITEIDENTIFIER(0,FILENAME)
			       ELSE
				 BEGIN
				 NPROGFILE := FPROGFILE;
				 WHILE NPROGFILE # NIL DO
				   BEGIN
				   WRITEIDENTIFIER(0,NPROGFILE^.FILID);
				   NPROGFILE := NPROGFILE^.NEXT
				   END
				 END
			    END;

		WRITENAME:
			   BEGIN
			    WRITEBLOCKST(6);
			    WRITEIDENTIFIER(0,FILENAME)
			   END;

		WRITEHISEG:
			    BEGIN
			     LLISTCODE := FALSE;
			     WRITEBLOCKST(3);
			     WRITEPAIR(NO,400000B,400000B);
			    END
	       END %CASE\
	     END %MCVARIOUS\ ;

	    PROCEDURE MCSYMBOLS;
	    VAR
	      ENTRYFOUND: BOOLEAN; POLHEADERDONE:Boolean; chan:integer;
	     BEGIN
	      %MCSYMBOLS\
	      WRITEHEADER('ENTRYPOINT(S)  ');
	      WRITEBLOCKST(2);
	      SAVELISTCODE := LISTCODE;
	      LISTCODE := FALSE;
	      FOR SWITCHFLAG := 1B TO 2B DO
	       BEGIN
		 IF MAIN
		 THEN
		   BEGIN
		    WRITEIDENTIFIER(SWITCHFLAG,FILENAME);
		    WRITEPAIR(RIGHT,0,STARTADDR)
		   END
		 ELSE
		   BEGIN
(* 34 - LOOK FOR FTN=FILENAME ONLY IF NOT SPEC. IN PROGRAM STATE. *)
		    CHECKER := LOCALPFPTR;
		    IF FPROGFILE=NIL
		      THEN ENTRYFOUND := FALSE
		      ELSE ENTRYFOUND := TRUE;
		    WHILE CHECKER # NIL DO
		    WITH CHECKER^ DO
		     BEGIN
		       IF PFADDR # 0
		       THEN
			 BEGIN
			   IF NOT ENTRYFOUND
(* 34 - USING FILENAME FOR ENTRY NOW *)
			   THEN ENTRYFOUND := FILENAME = NAME;
			  WRITEIDENTIFIER(SWITCHFLAG,NAME);
			  WRITEPAIR(RIGHT,0,PFADDR);
			   IF PFCHAIN = NIL
			   THEN
			     IF NOT ENTRYFOUND
			     THEN
			       BEGIN
(* 34 - USING FILENAME FOR ENTRY NOW *)
				WRITEIDENTIFIER(SWITCHFLAG,FILENAME);
				WRITEPAIR(RIGHT,0,PFADDR)
			       END
			 END;
		      CHECKER:= PFCHAIN
		     END
		   END;
		LISTCODE := SAVELISTCODE; LIC := 0
	       END;
	       IF MAIN
	       THEN
		 BEGIN
		  SWITCHFLAG:= 1B; WRITEHEADER('GLOBAL SYMBOLS ');
(* 16 - ADD CCL SWITCH *)
		  WRITEIDENTIFIER(SWITCHFLAG,'%CCLSW    ');
		  WRITEPAIR(RIGHT,0,CCLSW);
		  WRITEIDENTIFIER(SWITCHFLAG,'%RNNAM    ');
		  WRITEPAIR(RIGHT,0,CCLSW+1);
		  WRITEIDENTIFIER(SWITCHFLAG,'%RNPPN    ');
		  WRITEPAIR(RIGHT,0,CCLSW+2);
		  WRITEIDENTIFIER(SWITCHFLAG,'%RNDEV    ');
		  WRITEPAIR(RIGHT,0,CCLSW+3);
		 END
	       ELSE
		 BEGIN
		  SWITCHFLAG:= 14B; WRITEHEADER('GLOBAL REQUESTS')
		 END;
	      FILEPTR := SFILEPTR;
	      WHILE FILEPTR # NIL DO
	      WITH FILEPTR^, FILEIDENT^ DO
	       BEGIN
		 IF VADDR # 0
		 THEN
		   BEGIN
		    WRITEIDENTIFIER(SWITCHFLAG,NAME);
		    WRITEPAIR(RIGHT,0,VADDR)
		   END;
		FILEPTR:= NEXTFTP
	       END;
	       IF MAIN
	       THEN WRITEHEADER('GLOBAL REQUESTS');
	      CHECKER:= EXTERNPFPTR;
	      WHILE CHECKER # NIL DO
	      WITH CHECKER^ DO
	       BEGIN
		 IF LINKCHAIN[0] # 0
		 THEN
		   BEGIN
		     IF PFLEV = 0
		     THEN WRITEIDENTIFIER(14B,EXTERNALNAME)
		     ELSE WRITEIDENTIFIER(14B,NAME);
		    WRITEPAIR(RIGHT,0,LINKCHAIN[0])
		   END;
		CHECKER:= PFCHAIN
	       END;
(* 12 - ADD EXTERNAL REF TO RUNTIMES FOR DYNAMIC CORE ALLOC *)
	      IF LSTNEW # 0
	       THEN BEGIN
	       WRITEIDENTIFIER(14B,'LSTNEW    ');
	       WRITEPAIR(RIGHT,0,LSTNEW); % GLOBAL FIXUP TO INIT. CODE\
	       END;
	      IF NEWBND # 0
	       THEN BEGIN
	       WRITEIDENTIFIER(14B,'NEWBND    ');
	       WRITEPAIR(RIGHT,0,NEWBND); % DITTO \
	       END;
(* 105 - improve lower case mapping in sets *)
	      if setmapchain # 0
		then begin
		writeidentifier (14B,'.STCHM    ');
		writepair (right,0,setmapchain)
		end;
	      FOR SUPPORTIX:= SUCC(FIRSTSUPPORT) TO PRED(LASTSUPPORT) DO
	       IF RNTS.LINK[SUPPORTIX] # 0
	       THEN
		 BEGIN
		  WRITEIDENTIFIER(14B,RNTS.NAME[SUPPORTIX]);
		  WRITEPAIR(RIGHT,0,RNTS.LINK[SUPPORTIX])
		 END;
(* 36 - 141 is now set up elsewhere *)
{In non-main modules, if there are references to TTY^, etc., a
 Polish fixup may be needed to resolve them.}
	      polheaderdone := false;
	      FILEPTR := SFILEPTR;
	      IF NOT MAIN THEN WHILE FILEPTR # NIL DO
	      WITH FILEPTR^, FILEIDENT^ DO
	       begin
	       if chantab[channel] <> 0
		then begin
		if not polheaderdone
		  then begin
		  writeheader('SYMBOLIC POLISH');
		  polheaderdone := true;
		  end;
{A Polish fixup block looks like this:
   type 11
   operator,,2		2 means next word is global req - that is operand
   operand1
   0,,operand2		0 means next half word is operand
   -1,,place to put	-1 means put in RH of result addr
}
		writeblockst(11B);
		writepair(no,3,2);  {add}
		writeidentifier(0,name);
		writepair(no,0,filcmp);
		writepair(right,777777B,chantab[channel]);
		putrelcode;
		end;
		FILEPTR:= NEXTFTP
	       END;
	     if polheaderdone and cref and listcode then NEWLINE;
	     END %MCSYMBOLS\ ;

	    PROCEDURE MCLIBRARY;
	     BEGIN
	      %MCLIBRARY\
	      WRITEHEADER('LINK LIBRARIES ');
	      WRITEBLOCKST(15);
	      FOR L := 1 TO 2 DO
	       BEGIN
		FOR I := 1 TO LIBIX DO
		WITH LIBRARY[LIBORDER[I]] DO
		 IF CALLED
		 THEN WITH WANDLUNG DO
		   BEGIN
		    FOR J := 1 TO 6 DO WSIXBIT[J] := ORD(NAME[J]) - 40B;
		    WRITEIDENTIFIER(6B,NAME);
		    WRITEPAIR(NO,PROJNR,PROGNR);
		    FOR J := 1 TO 6 DO WSIXBIT[J] := ORD(DEVICE[J]) - 40B;
		    WRITEIDENTIFIER(6B,DEVICE); LIC := LIC + 1
		   END;
		I := 1;
(* 40 - load PASLIB first *)
		for languageix := pascalsy to fortransy do
		WITH LIBRARY[LANGUAGEIX] DO
		 BEGIN
		  CALLED := (NOT INORDER AND CALLED) OR (LANGUAGEIX = PASCALSY);
		  LIBORDER[I] := LANGUAGEIX; I := I + 1
		 END;
		LIBIX := 2
	       END;
	     END %MCLIBRARY\;

	   BEGIN
	    %WRITEMC\
(* 121 - missing initialization - fix bollixed INITPROC's *)
	     CODEARRAY := FALSE;
	     IF NOT ERRORFLAG
	     THEN
	       BEGIN
(* 5 - CREF *)
		IF CREF AND LISTCODE
		  THEN WRITE(CHR(177B),'F');
		FOR I:=1 TO MAXSIZE DO RELEMPTY[I] := 0;
		WITH ICWANDEL DO
		 BEGIN
		  ICVAL := 0;
		  CSP0 := ICCSP
		 END;
		LLISTCODE := LISTCODE;
		 CASE WRITEFLAG OF
		  WRITEGLOBALS	 : MCGLOBALS;	 %LINK-ITEM 01B\
		  WRITECODE	 : MCCODE;	 %LINK-ITEM 01B\
		  WRITESYMBOLS	 : MCSYMBOLS;	 %LINK-ITEM 02B\
		  WRITEBLK,			 %LINK-ITEM 02B\
		  WRITEINTERNALS,		 %LINK-ITEM 10B\
(* 164 - Polish fixups *)
		  WRITEPOLISH,			 %LINK-ITEM 11B\
		  WRITEENTRY,			 %LINK-ITEM 04B\
		  WRITEEND,			 %LINK-ITEM 05B\
		  WRITESTART,			 %LINK-ITEM 07B\
		  WRITEHISEG,			 %LINK-ITEM 03B\
		  WRITENAME	 : MCVARIOUS;	 %LINK-ITEM 06B\
		  WRITELIBRARY	 : MCLIBRARY	 %LINK-ITEM 17B\
		 END %CASE\;
		 IF LISTCODE AND (WRITEFLAG > WRITEHISEG)
(* 5 - CREF *)
(* 136 - LISTING FORMAT *)
		 THEN NEWLINE;
	       IF CREF AND LISTCODE
	         THEN WRITE(CHR(177B),'B')
	       END %IF ERRORFLAG\
	     ELSE
	       IF WRITEFLAG = WRITECODE
	       THEN LASTBTP := NIL
	   END %WRITEMC\;

	  PROCEDURE STATEMENT(FSYS,STATENDS: SETOFSYS);
	  TYPE
	    VALUEKIND = (ONREGC,ONFIXEDREGC,TRUEJMP,FALSEJMP);
	  VAR
	    LCP: CTP;	  IX,J: INTEGER;

	    PROCEDURE EXPRESSION(FSYS: SETOFSYS; FVALUE:VALUEKIND); FORWARD;

	    PROCEDURE MAKEREAL(VAR FATTR: ATTR);
	     BEGIN
	       IF FATTR.TYPTR=INTPTR
	       THEN
		 BEGIN
		  LOAD(FATTR);
(* 2 - hard code FLOAT using KI-10 op code *)
(* 101 - fix code generation for fltr *)
(* 122 - add back KA-10 code *)
(* 132 - separate KA10 into NOVM and KACPU *)
		  if kacpu
		    then begin
		    macro3(201B%movei\,tac,fattr.reg);
		    support(convertintegertoreal);
		    end
		   ELSE WITH CODE.INSTRUCTION[CIX] DO
		    IF (INSTR = 200B%MOVE\) AND (AC = FATTR.REG)
		      THEN INSTR := 127B%FLTR\
		      ELSE MACRO3(127B%FLTR\,FATTR.REG,FATTR.REG);
		  FATTR.TYPTR := REALPTR
		 END;
	       IF GATTR.TYPTR=INTPTR
	       THEN MAKEREAL(GATTR)
	     END;

	    PROCEDURE SELECTOR(FSYS: SETOFSYS; FCP: CTP);
	    VAR
	      LATTR: ATTR; LCP: CTP; LSP: STP;
	      LMIN,LMAX,INDEXVALUE,INDEXOFFSET: INTEGER;
	      OLDIC: ACRANGE;

	      PROCEDURE SUBLOWBOUND;
	       BEGIN
		 IF LMIN > 0
		 THEN MACRO3(275B%SUBI\,REGC,LMIN)
		 ELSE
		   IF LMIN < 0
		   THEN MACRO3(271B%ADDI\,REGC,-LMIN);
		 IF RUNTMCHECK
		 THEN
		   BEGIN
		    MACRO3(301B%CAIL\,REGC,0);
		    MACRO3(303B%CAILE\,REGC,LMAX-LMIN);
		    SUPPORT(INDEXERROR)
		   END
	       END;

	     BEGIN
	      WITH FCP^, GATTR DO
	       BEGIN
		TYPTR := IDTYPE; KIND := VARBL; PACKFG := NOTPACK;
		 CASE KLASS OF
		  VARS:
			BEGIN
			 VLEVEL := VLEV;  DPLMT := VADDR; INDEXR := 0;
			  IF VLEV > 1
			  THEN VRELBYTE:= NO
			  ELSE VRELBYTE:= RIGHT;
			  IF IDTYPE^.FORM = FILES
			  THEN LASTFILE:= FCP
			  ELSE LASTFILE:= NIL;
			  IF VKIND=ACTUAL
			  THEN INDBIT:=0
			  ELSE INDBIT:=1
			END;
		  FIELD:
			WITH DISPLAY[DISX] DO
			 IF OCCUR = CREC
			 THEN
			   BEGIN
			    VLEVEL := CLEV; PACKFG := PACKF; VRELBYTE:= CRELBYTE;
			     IF PACKFG = PACKK
			     THEN
			       BEGIN
				BPADDR := FLDADDR;
				DPLMT := CDSPL
			       END
			     ELSE DPLMT := CDSPL+FLDADDR;
			    INDEXR := CINDR; INDBIT:=CINDB
			   END
			 ELSE
			  ERROR(171);
		  FUNC:
			IF PFDECKIND = STANDARD
			THEN ERROR(502)
			ELSE
			  IF PFLEV = 0
			  THEN ERROR(502)   %EXTERNAL FCT\
			  ELSE
			    IF PFKIND = FORMAL
			    THEN ERROR(456)
(* 31 - BE SURE WE'RE IN THE BODY OF THE FTN *)
			    ELSE IF (LEVEL <= PFLEV) OR (DISPLAY[PFLEV+1].BLKNAME # NAME)
				THEN ERROR(412)
			    ELSE
			      BEGIN
(* 166 - use pflev+1 for vlevel, to allow assignment from inner function *)
			       VLEVEL := PFLEV + 1; VRELBYTE := NO;
			       DPLMT := 1;   %IMPL. RELAT. ADDR. OF FCT. RESULT\
			       INDEXR :=0; INDBIT :=0
			      END
		 END;
		%CASE\
	       END %WITH\;
	      IFERRSKIP(166,SELECTSYS OR FSYS);
	      WHILE SY IN SELECTSYS DO
	       BEGIN
(* 156 - error for selector on ftn name *)
	       IF FCP^.KLASS = FUNC
		 THEN ERROR(368);
		%[\
		 IF SY = LBRACK
		 THEN
		   BEGIN
		     IF GATTR.INDBIT = 1
		     THEN GETPARADDR;
		    OLDIC := GATTR.INDEXR;
		    INDEXOFFSET := 0 ;
		     LOOP
		      LATTR := GATTR; INDEXVALUE := 0 ;
		      WITH LATTR DO
		       IF TYPTR # NIL
		       THEN
			 BEGIN
			   IF TYPTR^.FORM # ARRAYS
			   THEN
			     BEGIN
			      ERROR(307); TYPTR := NIL
			     END;
			  LSP := TYPTR
			 END;
		      INSYMBOL;
		      EXPRESSION(FSYS OR [COMMA,RBRACK],ONREGC);
		       IF  GATTR.KIND#CST
		       THEN  LOAD(GATTR)
		       ELSE  INDEXVALUE := GATTR.CVAL.IVAL ;
		       IF GATTR.TYPTR # NIL
		       THEN
			 IF GATTR.TYPTR^.FORM # SCALAR
			 THEN ERROR(403);
		       IF LATTR.TYPTR # NIL
		       THEN
			WITH LATTR,TYPTR^ DO
			 BEGIN
			   IF COMPTYPES(INXTYPE,GATTR.TYPTR)
			   THEN
			     BEGIN
			       IF INXTYPE # NIL
			       THEN
				 BEGIN
				  GETBOUNDS(INXTYPE,LMIN,LMAX);
				   IF GATTR.KIND = CST
				   THEN
				     IF (INDEXVALUE < LMIN) OR (INDEXVALUE > LMAX)
				     THEN ERROR(263)
				 END
			     END
			   ELSE ERROR(457);
			  TYPTR := AELTYPE ;
			 END ;
		     EXIT IF SY # COMMA;
		      WITH LATTR DO
		       IF TYPTR#NIL
		       THEN
			 IF  GATTR.KIND = CST
			 THEN DPLMT := DPLMT +( INDEXVALUE - LMIN ) * TYPTR^.SIZE
			 ELSE
			   BEGIN
			    SUBLOWBOUND;
			     IF TYPTR^.SIZE > 1
			     THEN MACRO3(221B%IMULI\,REGC,TYPTR^.SIZE);
			     IF OLDIC = 0
			     THEN OLDIC := REGC
			     ELSE
			       IF OLDIC > REGCMAX
			       THEN
				 BEGIN
				  MACRO3(270B%ADD\,REGC,OLDIC);
				  OLDIC := REGC
				 END
			       ELSE
				 BEGIN
				  MACRO3(270B%ADD\,OLDIC,REGC) ;
				  REGC := REGC - 1
				 END;
			    INDEXR := OLDIC
			   END ;
		      GATTR := LATTR ;
		     END;
		    %LOOP\
		    WITH LATTR DO
		     IF  TYPTR # NIL
		     THEN
		       BEGIN
			 IF GATTR.KIND = CST
			 THEN INDEXOFFSET :=  ( INDEXVALUE - LMIN ) * TYPTR^.SIZE
			 ELSE
			   BEGIN
			     IF (TYPTR^.SIZE > 1) OR RUNTMCHECK
			     THEN SUBLOWBOUND
			     ELSE INDEXOFFSET := -LMIN;
			     IF TYPTR^.SIZE > 1
			     THEN MACRO3(221B%IMULI\,REGC,TYPTR^.SIZE);
			    INDEXR := REGC ;
			   END ;
			 IF LSP^.ARRAYPF
			 THEN
			   BEGIN
(* 102 - kl array code *)
			     if not klcpu
			       THEN INCREMENTREGC;
			     IF INDEXR=OLDIC
			     THEN
			       BEGIN
				INCREMENTREGC; INDEXR := 0
			       END;
(* 102 - kl adjbp code *)
			    if not klcpu then begin
			    MACRO4(571B%HRREI\,REGC,INDEXR,INDEXOFFSET);
			    INCREMENTREGC;   %TEST FOR IDIVI-INSTRUCTION\
			    REGC := REGC-1; INDEXOFFSET := 0;
			    MACRO3R(200B%MOVE\,REGC-1,LSP^.ARRAYBPADDR);
			    MACRO3(231B%IDIVI\,REGC,BITMAX DIV LSP^.AELTYPE^.BITSIZE);
			    MACRO3(133B%IBP\,0,REGC-1);
			    MACRO3R(365B%SOJGE\,REGC+1,IC-1);
			    BPADDR := REGC-1;  PACKFG := PACKK; INDEXR := REGC;
(* 102 - kl adjbp code *)
			    end
			     else begin (* kl code*)
			     macro4(571B%hrrei\,regc,indexr,indexoffset+1);
			     macro3r(133B%adjbp\,regc,lsp^.arraybpaddr);
			     bpaddr := regc; packfg := packk; indexr := 0;
			     indexoffset := 0;
			     end;
			   END;
			DPLMT := DPLMT + INDEXOFFSET ;
			KIND := VARBL ;
			 IF ( OLDIC # INDEXR )	AND  ( OLDIC # 0 )
			 THEN
			   BEGIN
(* 102 - new packed array code *)
			   if indexr = 0
			     then indexr := oldic
			     ELSE IF OLDIC > REGCMAX
			     THEN  MACRO3(270B%ADD\,INDEXR,OLDIC)
			     ELSE
			       BEGIN
				MACRO3(270B%ADD\,OLDIC,INDEXR);
				REGC := REGC - 1;
				INDEXR := OLDIC
			       END
			   END
		       END %WITH.. IF TYPTR # NIL\ ;
		    GATTR := LATTR ;
		     IF SY = RBRACK
		     THEN INSYMBOL
		     ELSE ERROR(155)
		   END %IF SY = LBRACK\
		 ELSE
		  %.\
		   IF SY = PERIOD
		   THEN
		     BEGIN
		      WITH GATTR DO
		       BEGIN
			 IF TYPTR # NIL
			 THEN
			   IF TYPTR^.FORM # RECORDS
			   THEN
			     BEGIN
			      ERROR(308); TYPTR := NIL
			     END;
			 IF INDBIT=1
			 THEN GETPARADDR;
			INSYMBOL;
			 IF SY = IDENT
			 THEN
			   BEGIN
			     IF TYPTR # NIL
			     THEN
			       BEGIN
				SEARCHSECTION(TYPTR^.FSTFLD,LCP);
(* 5 - CREF *)
				IF CREF
			          THEN WRITE(CHR(1B),CHR(21),ID,' .FIELDID. ');
				 IF LCP = NIL
				 THEN
				   BEGIN
				    ERROR(309); TYPTR := NIL
				   END
				 ELSE
				  WITH LCP^ DO
				   BEGIN
				    TYPTR := IDTYPE;PACKFG := PACKF;
				     IF PACKFG = PACKK
				     THEN
				      BPADDR := FLDADDR
				     ELSE
				      DPLMT := DPLMT + FLDADDR;
				   END
			       END;
			    INSYMBOL
			   END %SY = IDENT\
			 ELSE ERROR(209)
		       END %WITH GATTR\
		     END %IF SY = PERIOD\
		   ELSE
		    %^\
		     BEGIN
		       IF GATTR.TYPTR # NIL
		       THEN
			WITH GATTR,TYPTR^ DO
(* 173 - changes for internal files, since we can't assume FILPTR is set up *)
			 IF FORM = FILES
			   THEN BEGIN
			    TYPTR := FILTYPE;
{What we are trying to do here is to generate code like
	MOVEI 2,INPUT+FILCMP
 In the usual case, we just do a loadaddress on the file, after add
 filcmp to the displacement.  There are two cases where this won't
 work:
   - when the address is an external reference, since it then
	becomes an address in a fixup chain, and can't have FILCMP
	added to it at compile time.  Thus we have a separate
	fixup chain stored in CHANTAB which the loader will add
	FILCMP to after fixing up.
   - when the thing is indirect, since we have to add the displacemtn
	after doing the indirection.  The only solution there is 
	an ADDI, as far as I can see.
 Hamburg used to just do a LOAD, which works because at INPUT there
 is a pointer to INPUT+FILCMP.  I can't do that because if the
 FCB isn't initialized that will be garbage, and I need the real
 address to do the validity check}
			    WITH FCP^ DO
			     IF (VLEV = 0) AND (NOT MAIN)
			      THEN BEGIN
			      INCREMENTREGC;
			      MACRO3R(201B%MOVEI\,REGC,CHANTAB[CHANNEL]);
			      CHANTAB[CHANNEL] := IC-1;
			      CODE.INFORMATION[CIX] := 'E';
		  	      WITH GATTR DO
				BEGIN
				KIND := VARBL;  DPLMT := 0; INDEXR:=REGC;
				INDBIT:=0; VRELBYTE := NO
				END
			      END
(* 200 - fix addressing *)
			     ELSE IF INDBIT = 0
			      THEN BEGIN
			      DPLMT := DPLMT + FILCMP;
			      LOADADDRESS;
			      END
			     ELSE BEGIN
			     LOADADDRESS;
			     MACRO3(271B%ADDI\,REGC,FILCMP)
			     END;
			    IF RUNTMCHECK
			      THEN BEGIN
{See if the file is open.  A magic value of 314157 is left in FILTST if so }
			      MACRO4(200B%MOVE\,HAC,REGC,FILTST-FILCMP);
			      MACRO3(302B%CAIE\,HAC,314157B);
			      SUPPORT(FILEUNINITIALIZED)
			      END
			   END
			 ELSE IF FORM = POINTER
			  THEN
			   BEGIN
			    TYPTR := ELTYPE;
			     IF TYPTR # NIL
			     THEN WITH GATTR DO
			       BEGIN
				LOADNOPTR := FALSE;
				LOAD(GATTR); LOADNOPTR := TRUE;
(* 23 - check for bad pointer *)
(* 26 - but not for file *)
				IF RUNTMCHECK
				  THEN BEGIN
				  MACRO3(302B%CAIE\,REG,0);
				  MACRO3(306B%CAIN\,REG,377777B);
				  SUPPORT(BADPOINT)
				  END;
				INDEXR := REG; DPLMT := 0; INDBIT:=0; 
				PACKFG := NOTPACK; KIND := VARBL; 
				VRELBYTE:= NO
			       END
			   END
			 ELSE ERROR(407);
		      INSYMBOL
		     END;
		IFERRSKIP(166,FSYS OR SELECTSYS)
	       END;
	      %WHILE\
	      WITH GATTR DO
	       IF TYPTR#NIL
	       THEN
		 IF TYPTR^.SIZE = 2
		 THEN
		   BEGIN
		     IF INDBIT = 1
		     THEN GETPARADDR;
		     IF (INDEXR>REGIN) AND (INDEXR<=REGCMAX)
		     THEN INCREMENTREGC
		   END
	     END %SELECTOR\ ;

	    PROCEDURE CALL(FSYS: SETOFSYS; FCP: CTP);
	    VAR
(* 10 - ALLOW MORE RUNTIMES *)
	      LKEY: 1..44;
	      LFOLLOWERROR, NORIGHTPARENT : BOOLEAN;

(* 33 - allow use with non-TEXT files *)
(* 171 - allow read/write of records *)
(* 173 - completely new getfilename *)
(* 204 - don't check validty of file to be closed *)
	      PROCEDURE GETFILENAME(DEFAULTFILE:CTP;TEXTPROC:BOOLEAN;
			VAR FILETYPE:STP;VAR GOTARG:BOOLEAN;CHECK:BOOLEAN);
	      VAR
(* 177 - fix AC *)
		GOTFILE : BOOLEAN;  FILEREGC: ACRANGE;
{When we are finished we will have loaded a file into REGC, and parsed
 the next parameter if there is one, using EXPRESSION with REGC incremented}
	       BEGIN
		INCREMENTREGC;  {by default we will load into 3}
		FILEREGC := REGC;  {but file goes into 2, which this still is}
    {REGC = 2}
		GOTARG := FALSE; NORIGHTPARENT := TRUE; GOTFILE := FALSE;
		IF SY = LPARENT
		 THEN BEGIN
		 NORIGHTPARENT := FALSE;
		 INSYMBOL;
		 EXPRESSION(FSYS OR [COMMA,RPARENT,COLON],ONFIXEDREGC);
   {REGC = 3 if expression (file can't be), 2 otherwise}
		 GOTFILE := FALSE;
{We have an expression, see if it is a legal file.  If so, load it into
 REGC (note: no incrementregc first) and do a few tests.  We have to do
 our own loading mostly to avoid the INCREMENTREGC done by LOADADDRESS}
		 WITH GATTR DO
		  IF TYPTR <> NIL
		   THEN WITH TYPTR^ DO
		    IF FORM = FILES
		     THEN BEGIN
		     IF TEXTPROC
		      THEN IF NOT (COMPTYPES(FILTYPE,CHARPTR))
		      	     THEN ERROR(366);
{Yes, it is a legal file.  Now load it}
{If TTY that is supposed to be mapped to TTYOUTPUT, handle that}
		     IF (LASTFILE = TTYFILE) AND (DEFAULTFILE = OUTFILE)
		       THEN BEGIN
		       LASTFILE := TTYOUTFILE;
		       MACRO3R(201B%MOVEI\,REGC,TTYOUTFILE^.VADDR);
		       END
		      ELSE BEGIN
		       FETCHBASIS(GATTR);
		       MACRO(VRELBYTE,201B%MOVEI\,REGC,INDBIT,INDEXR,DPLMT);
		       END;
		     KIND := VARBL;  DPLMT := 0; INDEXR:=REGC; 
		     INDBIT:=0; VRELBYTE := NO;
		     WITH LASTFILE^ DO
		      IF (VLEV=0) AND (NOT MAIN)
		       THEN BEGIN VADDR:=IC-1; CODE.INFORMATION[CIX]:='E' END;
		     GOTFILE := TRUE;
		     FILETYPE := TYPTR;
{Runtime checks if appropriate}
(* 204 - don't check for CLOSE *)
		     if runtmcheck and check
		      then begin
		      macro4(200B%MOVE\,hac,regc,filtst);  {File test word}
		      macro3(302B%CAIE\,hac,314157B);  {True if file is open}
		      support(fileuninitialized);   {Not open}
		      end;
{Now see if there is an arg}
		     IF SY <> RPARENT
		      THEN BEGIN
		      IF SY = COMMA
		       THEN INSYMBOL
		       ELSE ERROR(158);
    {Note that this is guaranteed not to change REGC unless it sees an
     expression, in which case it advances to 3.  We can't have two
     advances (i.e. due to the EXPRESSION above and this one), since
     this is done only if the one above saw a file, which can't have
     advanced REGC}
		      EXPRESSION(FSYS OR [COMMA,RPARENT,COLON],ONFIXEDREGC);
		      GOTARG := TRUE
		      END
		     END;
{Now we are done processing a file arg}
		 IF NOT GOTFILE  {If expression wasn't a file, use it as arg}
		  THEN GOTARG := TRUE
		 END;
{End of IF RPARENT}
   {At this point REGC = 2 unless what we saw was an expr (which a file
	can't be), in which case REGC = 3 and it is loaded}
		IF NOT GOTFILE
		 THEN WITH DEFAULTFILE^ DO
{If we didn't get a file above, here is the code to do it}
		  BEGIN
(* 177 - fix AC *)
		  MACRO3R(201B%MOVEI\,FILEREGC,VADDR);
		  IF NOT GOTARG
		   THEN WITH GATTR DO
		    BEGIN
		    KIND := VARBL;  DPLMT := 0; INDEXR:=REGC; 
		    INDBIT:=0; VRELBYTE := NO;
		    END;
		  IF (VLEV=0) AND (NOT MAIN)
		   THEN BEGIN VADDR:=IC-1; CODE.INFORMATION[CIX]:='E' END;
		  FILETYPE := IDTYPE;
(* 204 - don't check for CLOSE *)
		  if runtmcheck and check
		   then begin
(* 207 - more bad AC's *)
		    macro4(200B%MOVE\,hac,fileregc,filtst);  {File test word}
		    macro3(302B%CAIE\,hac,314157B);  {True if file is open}
		    support(fileuninitialized);   {Not open}
		    end;
		  END;		 
  {If we saw an arg, REGC is exactly like it would have been with a
   simple   INCREMENTREGC;  EXPRESSION;  which is the whole point.
   That is,it is 2 unless an expression was seen, in which case the
   expression is loaded into 3.  If we didn't see an expression, then
   REGC is guaranteed to be 2.  Very shady...}
	       END %GETFILENAME\ ;

	      PROCEDURE VARIABLE(FSYS: SETOFSYS);
	      VAR
		LCP: CTP;
	       BEGIN
		 IF SY = IDENT
		 THEN
		   BEGIN
		    SEARCHID([VARS,FIELD],LCP); INSYMBOL
		   END
		 ELSE
		   BEGIN
		    ERROR(209); LCP := UVARPTR
		   END;
		SELECTOR(FSYS,LCP)
	       END %VARIABLE\ ;
(* 22 - add GETFN - common non-defaulting file name scanner *)
(* 73 - add ,COLON since used in NEW *)
(* 175 - internal files *)
	      PROCEDURE GETFN(TEST:BOOLEAN);
	        BEGIN
		VARIABLE(FSYS OR [RPARENT,COLON,COMMA]);
		LOADADDRESS;
		IF GATTR.TYPTR#NIL
		  THEN IF GATTR.TYPTR^.FORM#FILES
		    THEN ERROR(212)
		    ELSE WITH LASTFILE^ DO
		      IF (VLEV=0) AND (NOT MAIN)
			THEN BEGIN VADDR:=IC-1; CODE.INFORMATION[CIX]:='E' END;
(* 175 - internal files *)
		if test and runtmcheck
		  then begin
		  macro4(200B%MOVE\,hac,regc,filtst);  {File test word}
		  macro3(302B%CAIE\,hac,314157B);  {Magic value if it is open}
		  support(fileuninitialized);   {Not open}
		  end;
		END;

(* 14 - SEVERAL CHANGES IN THIS PROC TO ADD NEW RUNTIMES AND ADD OPTIONAL XBLOCK ARG *)
	      PROCEDURE GETPUTRESETREWRITE;
	      VAR
(* 172 - new options string *)
		LMAX,LMIN: INTEGER;
(* 173 - internal files *)
		LATTR: ATTR;
		ADR : SUPPORTS ; 
		DEFAULT : ARRAY [1..6] OF BOOLEAN;
		I,J : INTEGER;

		PROCEDURE GETSTRINGADDRESS ;

		 VAR LMAX,LMIN: INTEGER;
(* 61 - allow flags for gtjfn in tops20 *)
		    flagbits: packed record case Boolean of
			true: (dum:0..777777B;usetty:Boolean;wildok:Boolean);
			false: (dum2:0..777777B; rh:0..777777B)
			end;
		 BEGIN
		   IF SY=COMMA
		   THEN
		     BEGIN
		      INSYMBOL;
		      EXPRESSION(FSYS OR [COMMA,RPARENT,COLON],ONFIXEDREGC);
		      WITH GATTR DO
		       IF TYPTR#NIL
		       THEN
			WITH TYPTR^ DO
			 IF(FORM=ARRAYS) AND ARRAYPF
			 THEN
			   IF COMPTYPES(AELTYPE,CHARPTR)
			   THEN
			     BEGIN
(* 15 - CHANGE DUE TO SLIGHTLY DIFFERENT LOGIC IN MAIN PROC *)
			      DEFAULT[I] := FALSE;
			      I:=I+1;DEFAULT[I]:=FALSE;
			      LOADADDRESS;
				GETBOUNDS(INXTYPE,LMIN,LMAX);
				LMAX := LMAX-LMIN+1;
				INCREMENTREGC;
				MACRO3(201B%MOVEI\,REGC,LMAX);
			     END
			   ELSE ERROR(212)
			 ELSE ERROR(212);
(* 61 - implement extra syntax for tops20 *)
(* 144 - allow it for tops10, too *)
		     if (sy=colon)
		      then begin
		      insymbol;
		      flagbits.rh := 0;
		      while sy in [relop,addop,mulop] do
			begin
			if op = leop (* @ *)
			  then flagbits.usetty := true
			else if (op = mul) and (not tops10)
			  then flagbits.wildok := true
			else error(158);
			insymbol
			end;
		      macro3(505b%hrli\,regc-1,flagbits.rh);
		      end;
		     END;
		 END ;

	       BEGIN
		VARIABLE( FSYS OR [RPARENT,COMMA] ) ;
		LOADADDRESS ;
(* 173 - internal files *)
		LATTR := GATTR;
		 IF GATTR.TYPTR # NIL
		 THEN
		   IF GATTR.TYPTR^.FORM # FILES
		   THEN ERRANDSKIP(458,FSYS OR [RPARENT])
		   ELSE
		     BEGIN
		      WITH LASTFILE^ DO
		       IF (VLEV = 0) AND (NOT MAIN)
		       THEN
			 BEGIN
			  VADDR:= IC-1; CODE.INFORMATION[CIX] := 'E'
			 END;
		       IF (LKEY>=5) AND (LKEY#28)
		       THEN
			 BEGIN
			  FOR I := 1 TO 6 DO DEFAULT[I] := TRUE;
			  I := 1;
			  GETSTRINGADDRESS % OF FILENAME \ ;
(* 15 - ADD NEW PARAMETERS AND ALLOW OMITTING BLOCK *)
			  WHILE NOT DEFAULT[I] AND (SY=COMMA) DO
			   BEGIN
			    I := I+1;
			    INSYMBOL;
(* 172 - ADD OPTION STRING AS 3RD ARG *)
			    IF I = 3
			      THEN BEGIN
			      EXPRESSION(FSYS OR [COMMA,RPARENT],ONFIXEDREGC);
		      	      WITH GATTR DO
		       	       IF TYPTR#NIL
				THEN WITH TYPTR^ DO
			 	IF(FORM=ARRAYS) AND ARRAYPF
			 	 THEN IF COMPTYPES(AELTYPE,CHARPTR)
			   	  THEN BEGIN
			          DEFAULT[I] := FALSE;
			          LOADADDRESS;
				  GETBOUNDS(INXTYPE,LMIN,LMAX);
				  LMAX := LMAX-LMIN+1;
				  MACRO3(505B%HRLI\,REGC,LMAX);
				  END
				  ELSE ERROR(212)  {not CHAR array}
				 ELSE BEGIN  {not packed array}
				 LOAD(GATTR); DEFAULT[I] := FALSE
				 END
			      END {I=3}
(* 57 - ONLY TOPS10 HAS XBLOCK ARG *)
			    ELSE IF (NOT TOPS10) OR (I # 4) OR ((SY=INTCONST)AND(VAL.IVAL=0))
			      THEN BEGIN
			      EXPRESSION(FSYS OR [COMMA,RPARENT],ONFIXEDREGC);
			       IF GATTR.TYPTR#NIL
			       THEN
			       BEGIN
				LOAD(GATTR); DEFAULT[I] := FALSE;
(* 77 - allow sets, since they are elegant for specifying bits *)
				if gattr.typtr^.form = power
				  then regc := regc-1;
			       END
			      END
			     ELSE BEGIN
			     VARIABLE(FSYS OR[COMMA,RPARENT]);
			     IF GATTR.TYPTR # NIL
(* 26 - allow record as lookup block *)
				THEN IF NOT (GATTR.TYPTR^.FORM IN [ARRAYS,RECORDS])
				  THEN ERROR(264)
				  ELSE IF GATTR.TYPTR^.SIZE<5
				    THEN ERROR(265)
				    ELSE BEGIN LOADADDRESS; DEFAULT[I]:=FALSE END
				ELSE ERROR(458)
			     END;
			   END;
			  FOR I := 1 TO 6 DO
			   IF DEFAULT[I]
			   THEN
			     BEGIN
			      INCREMENTREGC;
			      IF I=6
				THEN MACRO3(474B%SETO\,REGC,0)
			        ELSE MACRO3(201B%MOVEI\,REGC,0)
			     END;
			 END;
(* 173 - internal files *)
		       if lkey in [5,6,29,36]  {openning}
			 then begin
			 if lattr.typtr <> nil
			   then if lattr.typtr^.form = files
			     then if comptypes(lattr.typtr^.filtype,charptr)
{In AC1, put size of component, or 0 if text file}
			       then macro3(201B%movei\,tac,0)
			       else macro3(201B%movei\,tac,
{Normally we would have to type filtype^ for nil, but if it is nil, the
 comptypes above will succeed, and this code will never happen.}
					   lattr.typtr^.filtype^.size)
			 end
(* 204 - don't validty check for DISMISS *)
(* 205 - fix AC for RENAME *)
			else if runtmcheck and (lkey <> 28)
			 then begin
		         macro4(200B%MOVE\,hac,regin+1,filtst);{File test word}
		         macro3(302B%CAIE\,hac,314157B); {Magic value if open}
		         support(fileuninitialized);   {Not open}
		         end;
		       CASE LKEY OF
			2: ADR:= GETLINE ;
			4: ADR:= PUTLINE ;
			5: ADR:= RESETFILE ;
			6: ADR:= REWRITEFILE;
			27:ADR:=NAMEFILE;
			28:ADR:=DISFILE;
			29:ADR:=UPFILE;
			36:ADR:=APFILE
		       END ;
		      SUPPORT(ADR) ;
		     END ;
	       END;

(* 10 - ADD SETSTRING, TO ALLOW I/O TO STRINGS *)
(* 13 - CODE MODIFIED TO ALLOW 4TH ARG, LIMIT *)
(* 51 - allow any file type, any packed array *)
	      PROCEDURE SETSTRING;
	      VAR
		LREGC:ACRANGE;
		LMIN,LMAX:ADDRRANGE;
		ARRAY1,OFFSET,FILEP,LIMIT:ATTR;
		NOOFF,NOLIM: BOOLEAN;

		BEGIN
		LREGC := REGC;  NOOFF := FALSE;  NOLIM:=FALSE;
(* 175 - if not inited, do it *)
	        GETFN(FALSE);
{If the file block is not legal yet, call routine to make it so}
		macro4(200B%MOVE\,hac,regc,filtst);  {File test word}
		macro3(302B%CAIE\,hac,314157B);  {Magic value if it is open}
		support(initfileblock);
		FILEP := GATTR;
		IF SY = COMMA
		  THEN INSYMBOL
		  ELSE ERROR(158);
		VARIABLE(FSYS OR [RPARENT,COMMA]);
		LOADADDRESS;
		WITH GATTR DO
		  BEGIN
		  KIND := EXPR; REG := INDEXR;
		  IF TYPTR # NIL
		    THEN WITH TYPTR^ DO
		      IF FORM # ARRAYS
			THEN ERROR(458)
			ELSE IF FILEP.TYPTR#NIL
			  THEN IF NOT ARRAYPF
			    THEN ERROR(458)
		  END;
		ARRAY1 := GATTR;
		IF SY = RPARENT
		  THEN NOOFF := TRUE
		ELSE IF SY = COMMA
		  THEN BEGIN
		  INSYMBOL;
		  EXPRESSION(FSYS OR [RPARENT,COMMA],ONREGC);
		  IF GATTR.TYPTR # NIL
		    THEN IF GATTR.TYPTR^.FORM # SCALAR
		      THEN ERROR(458)
		      ELSE IF NOT COMPTYPES(ARRAY1.TYPTR^.INXTYPE,GATTR.TYPTR)
			THEN ERROR(458);
		  OFFSET := GATTR;
		  IF OFFSET.KIND = EXPR
		    THEN INCREMENTREGC
		  END
		ELSE ERROR(158);
		IF SY = RPARENT
		  THEN NOLIM := TRUE
		ELSE IF SY = COMMA
		  THEN BEGIN
		  INSYMBOL;
		  EXPRESSION(FSYS OR [RPARENT],ONREGC);
		  IF GATTR.TYPTR # NIL
		    THEN IF GATTR.TYPTR^.FORM # SCALAR
		      THEN ERROR(458)
		      ELSE IF NOT COMPTYPES(ARRAY1.TYPTR^.INXTYPE,GATTR.TYPTR)
			THEN ERROR(458);
		  LIMIT := GATTR;
		  IF LIMIT.KIND = EXPR
		    THEN INCREMENTREGC
		  END
		ELSE ERROR(158);
		IF NOT ERRORFLAG
		  THEN BEGIN
		  GETBOUNDS(ARRAY1.TYPTR^.INXTYPE,LMIN,LMAX);
		  LMAX := LMAX - LMIN;
		  IF NOT NOLIM
		    THEN BEGIN
		    IF LIMIT.KIND # EXPR
		      THEN BEGIN LOAD(LIMIT); INCREMENTREGC END;
		    WITH LIMIT DO
		      BEGIN
		      IF LMIN > 0
			THEN MACRO3(275B%SUBI\,REG,LMIN)
		      ELSE IF LMIN < 0
			THEN MACRO3(271B%ADDI\,REG,-LMIN);
		      IF RUNTMCHECK
			THEN BEGIN
			MACRO3(307B%CAIG\,REG,LMAX);
			MACRO3(305B%CAIGE\,REG,0);
			SUPPORT(INDEXERROR)
			END;
		      END;
		    END;
		  IF NOT NOOFF
		    THEN BEGIN
		    IF OFFSET.KIND # EXPR
		      THEN BEGIN LOAD(OFFSET); INCREMENTREGC END;
		    WITH OFFSET DO
		      BEGIN
		      IF LMIN > 0
			THEN MACRO3(275B%SUBI\,REG,LMIN)
		      ELSE IF LMIN < 0
			THEN MACRO3(271B%ADDI\,REG,-LMIN);
		      IF RUNTMCHECK
			THEN BEGIN
			MACRO3(301B%CAIL\,REG,0);
			MACRO3(303B%CAILE\,REG,LMAX+1);
			SUPPORT(INDEXERROR)
			END;
		      END;
		    INCREMENTREGC;
		    IF NOLIM
		      THEN MACRO4(211B%MOVNI\,REGC,OFFSET.REG,-LMAX-1)
		      ELSE BEGIN
		      MACRO4(201B%MOVEI\,REGC,LIMIT.REG,1);
		      MACRO4(275B%SUBI\,REGC,OFFSET.REG,0);
		      IF RUNTMCHECK
			THEN BEGIN
			MACRO3(305B%CAIGE\,REGC,0);
			SUPPORT(INDEXERROR)
			END
		      END;
		    MACRO4(552B%HRRZM\,REGC,FILEP.INDEXR,FILBFH+2);
		    MACRO3R(200B%MOVE\,REGC,ARRAY1.TYPTR^.ARRAYBPADDR);
		    MACRO3(621B%TLZ\,REGC,17B);
		    MACRO3(231B%IDIVI\,OFFSET.REG,BITMAX DIV ARRAY1.TYPTR^.AELTYPE^.BITSIZE);
		    MACRO3(270B%ADD\,ARRAY1.REG,OFFSET.REG);
		    MACRO3(540B%HRR\,REGC,ARRAY1.REG);
		    MACRO3(303B%CAILE\,OFFSET.REG+1,0);
		    MACRO3(133B%IBP\,0,REGC);
		    MACRO3R(367B%SOJG\,OFFSET.REG+1,IC-1);
		    MACRO4(202B%MOVEM\,REGC,FILEP.INDEXR,FILBFH+1)
		    END
		   ELSE BEGIN
		    INCREMENTREGC;
		    IF NOLIM
		      THEN MACRO3(201B%MOVEI\,REGC,LMAX+1)
		      ELSE MACRO4(201B%MOVEI\,REGC,LIMIT.REG,1);
		    MACRO4(202B%MOVEM\,REGC,FILEP.INDEXR,FILBFH+2);
		    MACRO3R(200B%MOVE\,REGC,ARRAY1.TYPTR^.ARRAYBPADDR);
		    MACRO3(621B%TLZ\,REGC,17B);
		    MACRO3(540B%HRR\,REGC,ARRAY1.REG);
		    MACRO4(202B%MOVEM\,REGC,FILEP.INDEXR,FILBFH+1)
		    END;
		  IF NOLIM
		    THEN MACRO3(505B%HRLI\,REGC,LMIN+LMAX+400001B)
		    ELSE MACRO4(505B%HRLI\,REGC,LIMIT.REG,LMIN+400001B);
(* 60 - DON'T PUT IN LH(0) FOR TOPS-20.  "FILBFH" IS FREE *)
(* 143 - Tops10 now like Tops20 *)
		  IF TOPS10
		    THEN MACRO4(556B%HLRZM\,REGC,FILEP.INDEXR,FILBLL)
		    ELSE MACRO4(556B%HLRZM\,REGC,FILEP.INDEXR,FILBFH);
(* 43 - setzm to avoid blocked or dump mode I/O *)
(* 60 - kludge needed only for tops10 *)
(* 143 - tops10 now like tops20 *)
		  CASE LKEY OF
(* 60 - TOPS20 USES RUNTIME TO INIT *)
(* 143 - so does Tops10 *)
		    22: SUPPORT(RESETSTRING);
		    23: SUPPORT(REWRITESTRING)
		    END;
		  END;
		REGC := LREGC
		END;

(* 57 - ADD SET20STRING FOR 20 STRSET,STRWRITE *)
(* 60 - on further thought, use normal one *)

	      PROCEDURE GETINDEX;
		  VAR LREGC:ACRANGE;
		      FILEP:ATTR;
		BEGIN
		LREGC := REGC;
(* 175 *)
		GETFN(TRUE);
		FILEP := GATTR;
		IF SY = COMMA
		  THEN INSYMBOL
		  ELSE ERROR(158);
		VARIABLE(FSYS OR [RPARENT]);
		LOADADDRESS;
		WITH GATTR DO
		  BEGIN
		  IF TYPTR # NIL
		    THEN WITH TYPTR^ DO
		      IF (FORM # SCALAR) AND (FORM # SUBRANGE)
			THEN ERROR(458)
		  END;
		IF NOT ERRORFLAG
		  THEN BEGIN
		  INCREMENTREGC;
		  WITH FILEP DO
		    BEGIN
(* 60 - TOPS20 HAS MAGIC NO. IN DIFFERENT PLACE *)
(* 143 - tops10 now the same *)
		    IF TOPS10
		      THEN MACRO4(200B%MOVE\,REGC,INDEXR,FILBLL)
		      ELSE MACRO4(200B%MOVE\,REGC,INDEXR,FILBFH);
		    MACRO3(620B%TRZ\,REGC,400000B);
		    MACRO4(274B%SUB\,REGC,INDEXR,FILBFH+2);
		    MACRO4(202B%MOVEM\,REGC,GATTR.INDEXR,0);
		    END
		  END;
		REGC := LREGC
		END;
	      PROCEDURE READREADLN;
	      VAR
(* 14 ADD READING OF STRING *)
(* 171 read into packed objects, ALLOW READ OF RECORDS *)
		LADDR : SUPPORTS;  LMIN,LMAX:INTEGER; LATTR:ATTR;
		READREC: BOOLEAN; LREGC: ACRANGE;
{This procedure is complicated by a number of special cases.  The first is
 the question of whether the file is text or binary.  The code for a binary
 file is more or less completely different.  (Note also that only READLN
 is not legal for a binary file.)  The second question is whether the
 address is passed to the runtimes or whether they return a value.  For
 binary files we must pass the address of the variable to be filled, since
 it can be arbitrarily big.  Similarly for strings.  For simple values,
 the runtimes return the value in AC 3, and we must do a store.  This is
 to allow for storing into packed objects (what kind of address could be
 pass for that?)  We do LOADADDRESS for binary files and strings, and
 for simple objects we do STORE afterwards.}
	       BEGIN
(* 33 - ALLOW GETFILENAME WITH NON-TEXT FILES *)
(* 171 - PREDECL FILES ARE GLOBAL, ALSO ALLOW READ OF RECORD *)
		IF LKEY = 7  {read?}
		  THEN GETFILENAME(INFILE,FALSE,THISFILE,GOTARG,TRUE)  {might be binary}
		  ELSE GETFILENAME(INFILE,TRUE,THISFILE,GOTARG,TRUE);  {must be text}
		IF (LKEY = 7) AND NOT GOTARG
		  THEN ERROR(554);   {READ must have args}
		READREC := FALSE;   {now see if a binary file}
	        IF LKEY = 7
		  THEN IF NOT COMPTYPES(CHARPTR,THISFILE^.FILTYPE)
		    THEN READREC := TRUE;
	        LREGC := REGC;
		 IF GOTARG
		 THEN
		   LOOP
(* 14 ADD READING OF STRING *)
(* 171 read into packed objects *)
		    LATTR := GATTR;
(* 31 - INITIALIZE LADDR IN CASE OF ERROR - PREVENT ILL MEM REF *)
		    IF READREC
		      THEN BEGIN {separate code for binary files}
		      LADDR := READRECORD;
		      IF GATTR.TYPTR#NIL
		        THEN IF NOT COMPTYPES(THISFILE^.FILTYPE,GATTR.TYPTR)
			  THEN ERROR(260);
		      LOADADDRESS
		      END
		    ELSE BEGIN  {Here is the code for TEXT files}
		    LADDR := READCHARACTER;
		     IF GATTR.TYPTR#NIL
		     THEN
		       IF GATTR.TYPTR^.FORM<=SUBRANGE
		       THEN
			 IF COMPTYPES(INTPTR,GATTR.TYPTR)
			 THEN
			  LADDR := READINTEGER
			 ELSE
			   IF COMPTYPES(REALPTR,GATTR.TYPTR)
			   THEN
			    LADDR := READREAL
			   ELSE
			     IF COMPTYPES(CHARPTR,GATTR.TYPTR)
			     THEN
			      LADDR := READCHARACTER
			     ELSE ERROR(169)
		       ELSE WITH GATTR.TYPTR^ DO
			  IF FORM = ARRAYS
			    THEN IF COMPTYPES(CHARPTR,AELTYPE)
			      THEN
				BEGIN
(* 171 - read into packed objects *)
				LOADADDRESS;  {of array}
				GETBOUNDS(INXTYPE,LMIN,LMAX);
				INCREMENTREGC;
				MACRO3(201B%MOVEI\,REGC,LMAX-LMIN+1);
				IF ARRAYPF
				  THEN LADDR := READPACKEDSTRING
				  ELSE LADDR := READSTRING;
				IF SY = COLON
				 THEN BEGIN
				  INSYMBOL;
(* 76 - allow set of break characters *)
				  VARIABLE(FSYS OR [COMMA,RPARENT,COLON]);
				  LOADADDRESS;
				  IF NOT COMPTYPES(INTPTR,GATTR.TYPTR)
				    THEN ERROR(458);
				  END
				 else begin
				  incrementregc;
				  MACRO3(201B%MOVEI\,REGC,0);
				  end;
				if sy = colon
				  then begin
				  insymbol;
				  expression(fsys or [comma,rparent],onfixedregc);
				  if gattr.typtr#nil
				    then if (gattr.typtr^.form = power)
				     then if comptypes(gattr.typtr^.elset, charptr)
				      then begin
				      load(gattr);
				      regc := regc-2;
				      end
				     else error(458)
				    else error(458)
				   end
				  else macro3(403B%SETZB\,regc+1,regc+2);
				END
			      ELSE ERROR(458)
			    ELSE ERROR(458);
		    END; {of TEXT file case}
(* 171 - read into packed objects *)
		    REGC := LREGC;
		    if not (readrec or (laddr in [readstring,readpackedstring]))
		      then begin
  {This is for reading single words, which may go into packed structures.
   Note that we have to redo the ac allocation because the read routine
   will return a value in AC 3, which quite likely is used as INDEXR or
   BPADDR.  Since we are pushing the active AC's anyway, we might as well
   pop them back into a different place.}
		      incrementregc;  {place that read will return the value}
		      if (lattr.indexr > regin) and (lattr.indexr <= 10B)
		        then begin
			macro3(261B%PUSH\,topp,lattr.indexr);
			incrementregc;
			lattr.indexr := regc;  {Place to put this value afterwards}
			end;
		      if (lattr.packfg = packk) and (lattr.bpaddr > regin)
					        and (lattr.bpaddr <= 10B)
			then begin
		        macro3(261B%PUSH\,topp,lattr.bpaddr);
			incrementregc;
			lattr.bpaddr := regc;
			end;
		      regc := lregc;  {restore regc}
		      support(laddr);
		      if (lattr.packfg = packk) and (lattr.bpaddr > regin) 
				          	and (lattr.bpaddr <= 10B)
		        then macro3(262B%POP\,topp,lattr.bpaddr);
		      if (lattr.indexr > regin) and (lattr.indexr <= 10B)
		        then macro3(262B%POP\,topp,lattr.indexr);
		      fetchbasis(lattr);   {Now do the store}
		      store(regc+1,lattr)
		      end
		     else SUPPORT(LADDR);
		   EXIT IF SY # COMMA;
		    INSYMBOL;
		   VARIABLE(FSYS OR [COMMA,COLON,RPARENT]); 
		   END;
		 IF LKEY = 8
		 THEN SUPPORT(GETLINE)
	       END %READREADLN\ ;

(* 42 - move breakin to close *)
(* 43 - add putx *)
	      procedure putx;
		begin
(* 175 *)
		getfn(true);
(* 61 - add delete *)
		case lkey of
		  37: support(putxfile);
		  41: support(delfile)
		  end;
		end;

	      PROCEDURE BREAK;
	       BEGIN
(* 26 - allow non-text files *)
(* 171 - PREDECL FILES ARE SPECIAL *)
		GETFILENAME(OUTFILE,FALSE,THISFILE,GOTARG,TRUE);
		IF GOTARG THEN ERROR(554);
		SUPPORT(BREAKOUTPUT) ;
	       END ;

(* 10 - ADD CLOSE *)
(* 15 - AND ALLOW OPT. PARAM FOR CLOSE BITS *)
(* 42 - move breakin here, to allow param to suppress get *)
	      PROCEDURE CLOSE;
	       BEGIN
(* 26 - allow non-text files *)
(* 61 - rclose for tops20 *)
		if (lkey = 25) or (lkey = 42)
(* 171 - PREDECL FILES ARE SPECIAL *)
(* 204 - don't validity check CLOSE and RCLOSE *)
		  THEN GETFILENAME(OUTFILE,FALSE,THISFILE,GOTARG,FALSE)
		  else getfilename(INFILE,false,THISFILE,GOTARG,FALSE);
		IF GOTARG
		 THEN LOAD(GATTR)
		 ELSE BEGIN
		  INCREMENTREGC;
		  MACRO3(201B%MOVEI\,REGC,0)
		  END;
(* 45 - add NEXTBLOCK *)
(* 61 - add RCLOSE *)
		case lkey of
		  25: support(closefile);
		  34: support(breakinput);
		  39: support(nextblockf);
		  42: support(relfile)
		  end;
	       END;

(* 14 - ADD DUMP MODE STUFF *)
(* 42 - allow variable size *)
	     PROCEDURE DUMP;
		VAR FILEP:ATTR; s:integer;
	      BEGIN
(* 175 *)
	      GETFN(TRUE);
	      FILEP:=GATTR;
	      IF SY=COMMA
	        THEN INSYMBOL
		ELSE ERROR(158);
	      EXPRESSION(FSYS OR[COMMA,RPARENT],ONFIXEDREGC);
	      LOADADDRESS;
	      if gattr.typtr#nil
	       then s:=gattr.typtr^.size;
	      if sy=comma
	       then
		begin
		insymbol;
		expression(fsys or [rparent],onfixedregc);
		if comptypes(intptr,gattr.typtr)
		 then load(gattr)
		 else error(458);
		if runtmcheck
		 then begin
		 macro3(303b%caile\,regc,s);
		 support(indexerror)
		 end
		end
               else
		begin
	        INCREMENTREGC;
		MACRO3(201B%MOVEI\,REGC,GATTR.TYPTR^.SIZE)
	        end;
	      IF LKEY=30
		THEN SUPPORT(READDUMP)
		ELSE SUPPORT(WRITEDUMP)
	      END;

	    PROCEDURE USET;
		VAR FILEP:ATTR;
	      BEGIN
(* 175 *)
	      GETFN(TRUE);
	      FILEP:=GATTR;
	      IF SY = COMMA
		THEN INSYMBOL
		ELSE ERROR(158);
(* 43 - new optional arg for useti *)
	      EXPRESSION(FSYS OR [COMMA,RPARENT],ONFIXEDREGC);
	      LOAD(GATTR);
	      IF GATTR.TYPTR=NIL
		THEN ERROR(458)
		ELSE IF GATTR.TYPTR#INTPTR
		  THEN ERROR(458);
(* 44 - add SETPOS and SKIP *)
	      IF LKEY # 33
(* 43 - new optional arg for useti *)
		then begin
		  if sy=comma
		    then begin
		    insymbol;
		    expression(fsys or [rparent],onfixedregc);
		    load(gattr);
		    end
		  else begin
		    incrementregc;
		    macro3(201b%movei\,regc,0)
		    end;
		  case lkey of
			32:support(setin);
			38:support(setposf)
			end
		  end
		ELSE SUPPORT(SETOUT)
	      END;

	      PROCEDURE WRITEWRITELN;
	      VAR
		LSP: STP; DEFAULT,REALFORMAT,WRITEOCT: BOOLEAN; LSIZE,LMIN,LMAX: INTEGER; LADDR: SUPPORTS;
(* 171 - write records *)
		writerec: Boolean;
	       BEGIN
(* 171 - PREDECL FILES ARE GLOBAL, ALSO ALLOW READ OF RECORD *)
{First scan file name and see if binary file}
		IF LKEY = 10   {WRITE?}
		  THEN GETFILENAME(OUTFILE,FALSE,THISFILE,GOTARG,TRUE)  {Yes, might be binary}
		  ELSE GETFILENAME(OUTFILE,TRUE,THISFILE,GOTARG,TRUE);  {No, WRITELN not legal for binary files}
		IF (LKEY = 10) AND NOT GOTARG
		  THEN ERROR(554);
		WRITEREC := FALSE;
	        IF LKEY = 10   {Now see if it was a binary file}
		  THEN IF NOT COMPTYPES(CHARPTR,THISFILE^.FILTYPE)
		    THEN WRITEREC := TRUE;
		 IF GOTARG
		 THEN
		   LOOP
(* 22 - INITIALIZE LADDR IN CASE OF ERRORS.  PREVENTS ILL MEM REF *)
(* 206 - moved initialization below *)
		    LSP := GATTR.TYPTR; LSIZE := LGTH; WRITEOCT := FALSE;
		     IF LSP # NIL
		     THEN
(* 206 - make non-text files work for constants *)
{Note that the values of LADDR set here are used only for binary files.
 LADDR is reset below for text files.  Only in case of error will these
 values remain for a text file, and in that case having them prevents
 an ill mem ref}
		       IF LSP^.FORM <= POWER
		       THEN BEGIN LOAD(GATTR); LADDR := WRITESCALAR END
		       ELSE
			 BEGIN
			   IF (GATTR.KIND = VARBL)
			    AND
			    (GATTR.INDEXR = TOPP)
			   THEN ERROR(458);
			  LOADADDRESS;
			  LADDR := WRITERECORD;
			 END;
(* 206 - make non-text files work for constants *)
		     IF WRITEREC
		       THEN BEGIN {For binary files, make sure of type match}
		       IF GATTR.TYPTR#NIL
		         THEN IF NOT COMPTYPES(THISFILE^.FILTYPE,GATTR.TYPTR)
			   THEN ERROR(260);
		       END  {end binary}
		     ELSE BEGIN
		     IF SY = COLON
		     THEN
		       BEGIN
			INSYMBOL; EXPRESSION(FSYS OR [COMMA,COLON,RPARENT],ONFIXEDREGC);
			 IF GATTR.TYPTR # NIL
			 THEN
			   IF GATTR.TYPTR # INTPTR
			   THEN ERROR(458);
			LOAD(GATTR); DEFAULT := FALSE;
		       END
		     ELSE
		       BEGIN
			DEFAULT := TRUE; INCREMENTREGC %RESERVE REGISTER FOR DEFAULT VALUE\
		       END ;
		     IF LSP = INTPTR
		     THEN
		       BEGIN
			LADDR := WRITEINTEGER ; LSIZE := 12
		       END;
		     IF SY = COLON
		     THEN
		       BEGIN
			INSYMBOL;
			 IF (SY = IDENT) AND ((ID='O         ') OR (ID='H         '))
			 THEN
			   BEGIN
			     IF NOT COMPTYPES(LSP,INTPTR)
			     THEN ERROR(262);
			     IF ID = 'O         '
			     THEN LADDR := WRITEOCTAL
			     ELSE
			       BEGIN
				LADDR := WRITEHEXADECIMAL; LSIZE := 11
			       END;
			    INSYMBOL
			   END
			 ELSE
			   BEGIN
			    EXPRESSION(FSYS OR [COMMA,RPARENT],ONFIXEDREGC);
			     IF GATTR.TYPTR # NIL
			     THEN
			       IF GATTR.TYPTR # INTPTR
			       THEN ERROR(458);
			     IF LSP # REALPTR
			     THEN ERROR(258);
			    LOAD(GATTR); REALFORMAT := FALSE
			   END
		       END
		     ELSE REALFORMAT := TRUE;
		     IF LSP = INTPTR
		     THEN GOTO 1;
		     IF LSP = CHARPTR
		     THEN
		       BEGIN
			LSIZE := 1; LADDR := WRITECHARACTER
		       END
		     ELSE
		       IF LSP = REALPTR
		       THEN
			 BEGIN
			  LSIZE := 16; LADDR := WRITEREAL;
			   IF REALFORMAT
			   THEN MACRO3(201B%MOVEI\,REGIN+4,123456B);
			 END
		       ELSE
			 IF LSP = BOOLPTR
			 THEN
			   BEGIN
			    LSIZE := 6; LADDR := WRITEBOOLEAN
			   END
			 ELSE
			   IF LSP # NIL
			   THEN
			     BEGIN
			       IF LSP^.FORM = SCALAR
			       THEN ERROR(169)
			       ELSE
				 IF STRING(LSP)
				 THEN
				   BEGIN
				     IF LSP^.INXTYPE#NIL
				     THEN
				       BEGIN
					GETBOUNDS(LSP^.INXTYPE,LMIN,LMAX);
					LSIZE := LMAX-LMIN+1;
				       END;
				    MACRO3(201B%MOVEI\,REGIN+4,LSIZE);
				     IF LSP^.ARRAYPF
				     THEN LADDR := WRITEPACKEDSTRING
				     ELSE LADDR := WRITESTRING ;
				   END
				 ELSE ERROR(458)
			     END;
1:
		     IF DEFAULT
		     THEN MACRO3(201B%MOVEI\,REGIN+3,LSIZE);
		    END;  {of IF WRITEREC}
		    SUPPORT(LADDR);
		    REGC :=REGIN + 1;
		   EXIT IF SY # COMMA;
		    INSYMBOL;
(* 206 - allow constants for records *)
		    EXPRESSION(FSYS OR [COMMA,COLON,RPARENT],ONFIXEDREGC);
		   END;
		 IF LKEY = 11
		 THEN SUPPORT(PUTLINE) ;
	       END %WRITE\ ;

(* 6 - PACK and UNPACK have been rewritten to be as described in Jensen and Wirth *)
	      PROCEDURE PACK;

		% PACK(A,I,Z) MEANS:
		 FOR L := LMIN(Z) TO LMAX(Z) DO Z[L] := A[L-LMIN(Z)+I] \

	      VAR
		ARRAY1,OFFSET1,ARRAY2,OFFSET2: ATTR;
		LADDR,START,STOP,LMIN1,LMAX1,LMIN2,LMAX2: ADDRRANGE;
		LREGC: ACRANGE;

	       BEGIN
		LREGC := REGC; START := 0;
		VARIABLE(FSYS OR [COMMA,RPARENT]);
		LOADADDRESS;
		WITH GATTR DO
		 BEGIN
		  KIND := EXPR; REG := INDEXR;
(* 135 prevent ill mem ref if not a variable *)
		   IF TYPTR = NIL
		   THEN TYPTR := UARRTYP
		   ELSE WITH TYPTR^ DO
		     IF FORM # ARRAYS
		     THEN ERROR(458)
		     ELSE
		       IF ARRAYPF
		       THEN ERROR(458)
		 END;
		ARRAY1 := GATTR;
		 IF SY = COMMA
		 THEN INSYMBOL
		 ELSE ERROR(158);
		EXPRESSION(FSYS OR [COMMA,RPARENT],ONREGC);
		 IF GATTR.TYPTR # NIL
		 THEN
		   IF GATTR.TYPTR^.FORM # SCALAR
		   THEN ERROR(458)
		   ELSE
		     IF NOT COMPTYPES(ARRAY1.TYPTR^.INXTYPE,GATTR.TYPTR)
		     THEN ERROR(458);
		OFFSET1 := GATTR;
		 IF SY = COMMA
		 THEN INSYMBOL
		 ELSE ERROR(158);
		VARIABLE(FSYS OR [RPARENT]);
		LOADADDRESS;
		WITH GATTR DO
		 BEGIN
		  KIND := EXPR; REG := INDEXR;
		   IF TYPTR # NIL
		   THEN WITH TYPTR^ DO
		     IF FORM # ARRAYS
		     THEN ERROR(458)
		     ELSE
		       IF NOT ARRAYPF
			OR
			NOT (COMPTYPES(AELTYPE,ARRAY1.TYPTR^.AELTYPE)
			     AND
			     COMPTYPES(INXTYPE,ARRAY1.TYPTR^.INXTYPE))
		       THEN ERROR(458)
		 END;
		ARRAY2 := GATTR;

		 IF NOT ERRORFLAG
		 THEN
		   BEGIN
		    GETBOUNDS(ARRAY1.TYPTR^.INXTYPE,LMIN1,LMAX1); LMAX1 := LMAX1 - LMIN1;
		    GETBOUNDS(ARRAY2.TYPTR^.INXTYPE,LMIN2,LMAX2); LMAX2 := LMAX2 - LMIN2;
		    WITH OFFSET2 DO  %MAKE OFFSET2 A CONST = LMAX2+1 \
			BEGIN
			TYPTR := INTPTR;
			KIND := CST;
			CVAL.IVAL := LMAX2 + 1
			END;
		     IF (OFFSET1.KIND = CST)
		     THEN
		       BEGIN
			STOP := OFFSET2.CVAL.IVAL;
			START := OFFSET1.CVAL.IVAL - LMIN1;
			 IF (START < 0) OR (START > (LMAX1+1-STOP))
			 THEN ERROR(263);
			MACRO3(505B%HRLI\,ARRAY1.REG,-STOP);
		       END
		     ELSE
		       BEGIN
			LOAD(OFFSET2);
			WITH OFFSET2 DO
			  MACRO3(210B%MOVN\,REG,REG);
			LOAD(OFFSET1);
			WITH OFFSET1 DO
			 BEGIN
			   IF LMIN1 > 0
			   THEN MACRO3(275B%SUBI\,REG,LMIN1)
			   ELSE
			     IF LMIN1 < 0
			     THEN MACRO3(271B%ADDI\,REG,-LMIN1);
			   IF RUNTMCHECK
			   THEN
			     BEGIN
			      MACRO3(301B%CAIL\,REG,0);
			      MACRO4(303B%CAILE\,REG,OFFSET2.REG,LMAX1+1);
			      SUPPORT(INDEXERROR)
			     END;
			  MACRO3(270B%ADD\,ARRAY1.REG,REG);
			  MACRO4(505B%HRLI\,ARRAY1.REG,OFFSET2.REG,0)
			 END
		       END;
		    INCREMENTREGC;
		    MACRO3(540B%HRR\,TAC,ARRAY2.REG);
		    MACRO3R(200B%MOVE\,REGC,ARRAY2.TYPTR^.ARRAYBPADDR);
		    LADDR := IC;
		    MACRO4(200B%MOVE\,HAC,ARRAY1.REG,START);
		    MACRO3(136B%IDPB\,HAC,REGC);
		    MACRO3R(253B%AOBJN\,ARRAY1.REG,LADDR)
		   END;
		REGC := LREGC
	       END;

	      PROCEDURE UNPACK;

		% UNPACK(Z,A,I) MEANS:
		 FOR L := LMIN(Z) TO LMAX(Z) DO A[L-LMIN(Z)+I] := Z[L] \

	      VAR
		ARRAY1,OFFSET1,ARRAY2,OFFSET2: ATTR;
		LADDR,START,STOP,LMIN1,LMAX1,LMIN2,LMAX2: ADDRRANGE;
		LREGC: ACRANGE;

	       BEGIN
		LREGC := REGC; START := 0;
		VARIABLE(FSYS OR [COMMA,RPARENT]);
		LOADADDRESS;
		WITH GATTR DO
		 BEGIN
		  KIND := EXPR; REG := INDEXR;
(* 135 - prevent ill mem ref if not a variable *)
		   IF TYPTR = NIL
		   THEN TYPTR := UARRTYP
		   ELSE WITH TYPTR^ DO
		     IF FORM # ARRAYS
		     THEN ERROR(458)
		     ELSE
		       IF NOT ARRAYPF
		       THEN ERROR(458)
		 END;
		ARRAY1 := GATTR;
		 IF SY = COMMA
		 THEN INSYMBOL
		 ELSE ERROR(158);
		VARIABLE(FSYS OR [COMMA,RPARENT]);
		LOADADDRESS;
		WITH GATTR DO
		 BEGIN
		  KIND := EXPR; REG := INDEXR;
(* 135 - prevent ill mem ref if not a variable *)
		   IF TYPTR = NIL
		   THEN TYPTR := UARRTYP
		   ELSE WITH TYPTR^ DO
		     IF FORM # ARRAYS
		     THEN ERROR(458)
		     ELSE
		       IF ARRAYPF
			OR
			NOT (COMPTYPES(AELTYPE,ARRAY1.TYPTR^.AELTYPE)
			     AND
			     COMPTYPES(INXTYPE,ARRAY1.TYPTR^.INXTYPE))
		       THEN ERROR(458)
		 END;
		ARRAY2 := GATTR;
		 IF SY = COMMA
		 THEN INSYMBOL
		 ELSE ERROR(158);
		EXPRESSION(FSYS OR [RPARENT],ONREGC);
		 IF GATTR.TYPTR # NIL
		 THEN
		   IF GATTR.TYPTR^.FORM # SCALAR
		   THEN ERROR(458)
		   ELSE
		     IF NOT COMPTYPES(ARRAY2.TYPTR^.INXTYPE,GATTR.TYPTR)
		     THEN ERROR(458);
		OFFSET2 := GATTR;

		 IF NOT ERRORFLAG
		 THEN
		   BEGIN
		    GETBOUNDS(ARRAY1.TYPTR^.INXTYPE,LMIN1,LMAX1); LMAX1 := LMAX1 - LMIN1;
		    GETBOUNDS(ARRAY2.TYPTR^.INXTYPE,LMIN2,LMAX2); LMAX2 := LMAX2 - LMIN2;
		    WITH OFFSET1 DO  %MAKE OFFSET1 A CONST = LMAX1+1 \
			BEGIN
			TYPTR := INTPTR;
			KIND := CST;
			CVAL.IVAL := LMAX1 + 1
			END;
		     IF (OFFSET2.KIND = CST)
		     THEN
		       BEGIN
			STOP := OFFSET1.CVAL.IVAL;
			START := OFFSET2.CVAL.IVAL - LMIN2;
			 IF (START < 0) OR (START > (LMAX2+1-STOP))
			 THEN ERROR(263);
			MACRO3(505B%HRLI\,ARRAY2.REG,-STOP);
		       END
		     ELSE
		       BEGIN
			LOAD(OFFSET1);
			WITH OFFSET1 DO
			  MACRO3(210B%MOVN\,REG,REG);
			LOAD(OFFSET2);
			WITH OFFSET2 DO
			 BEGIN
			   IF LMIN2 > 0
			   THEN MACRO3(275B%SUBI\,REG,LMIN2)
			   ELSE
			     IF LMIN2 < 0
			     THEN MACRO3(271B%ADDI\,REG,-LMIN2);
			   IF RUNTMCHECK
			   THEN
			     BEGIN
			      MACRO3(301B%CAIL\,REG,0);
			      MACRO4(303B%CAILE\,REG,OFFSET1.REG,LMAX2+1);
			      SUPPORT(INDEXERROR)
			     END;
			  MACRO3(270B%ADD\,ARRAY2.REG,REG);
			  MACRO4(505B%HRLI\,ARRAY2.REG,OFFSET1.REG,0)
			 END
		       END;
		    INCREMENTREGC;
		    MACRO3(540B%HRR\,TAC,ARRAY1.REG);
		    MACRO3R(200B%MOVE\,REGC,ARRAY1.TYPTR^.ARRAYBPADDR);
		    LADDR := IC;
		    MACRO3(134B%ILDB\,HAC,REGC);
		    MACRO4(202B%MOVEM\,HAC,ARRAY2.REG,START);
		    MACRO3R(253B%AOBJN\,ARRAY2.REG,LADDR)
		   END;
		REGC := LREGC
	       END;


	      PROCEDURE NEW;
	      CONST
		TAGFMAX=5;
	      VAR
(* 42 - move GET and PUT here *)
(* 47 - add GETX and RECSIZE - no other comments in body *)
		adr:supports; sizereg:acrange;
		LSP,LSP1: STP; VARTS,LMIN,LMAX: INTEGER;
		FIRSTLOAD:BOOLEAN;
		LSIZE,LSZ: ADDRRANGE; LVAL: VALU;
		LATTR: ATTR; I,TAGFC: INTEGER;
		TAGFSAV: ARRAY[0..TAGFMAX] OF RECORD
						TAGFVAL: INTEGER;
						TAGFADDR: ADDRRANGE;
						LPACKKIND:PACKKIND;
(* 21 - KEEP FROM STORING TAG VALUE IF NO PLACE TO PUT IT *)
						TAGWITHID:BOOLEAN
					      END;
	       BEGIN
		FOR I:=0 TO TAGFMAX DO TAGFSAV[I].TAGWITHID := FALSE;
(* 42 - move GET and PUT in here *)
(* 73 - restructure to use GETFN for file names, to allow extern files *)
(* 152 - DISPOSE *)
(* 153 - repair AC usage in DISPOSE *)
		if lkey = 44 {dispose}
		  then begin
		       incrementregc; incrementregc;
		       sizereg := regc;
		       variable(fsys or [comma,colon,rparent]);
		       lattr := gattr;  {We have to use a local copy so that
					 if AC1 is loaded here, that fact is
					 not saved for the store later.}
		       fetchbasis(lattr);
		       with lattr do  {modelled after loadaddress}
			 macro(vrelbyte,200B%MOVE\,sizereg-1,indbit,indexr,dplmt);
		       end
(* 162 - fix RECSIZE *)
		else if lkey in [14,35]
		  then begin   (* all except file names *)
		       incrementregc; sizereg := regc ;
		       VARIABLE(FSYS OR [COMMA,COLON,RPARENT]);
		       end
(* 175 - validate files for get and put stuff, but not for RECSIZE,
	which seems OK even if the file isn't open yet *)
		else begin getfn(lkey in [1,3,40]); sizereg := regin+2 end;
		LSP := NIL; VARTS := 0; LSIZE := 0; TAGFC := -1;
		LATTR := GATTR;
		 IF GATTR.TYPTR # NIL
		 THEN
		  WITH GATTR.TYPTR^ DO
(* 42 - move GET and PUT in here *)
(* 152 - dispose *)
(* 162 - fix RECSIZE *)
		   if (lkey in [14,35,44]) and (form=pointer) or
		      (lkey in [1,3,15,40]) and (form=files)
		   THEN
		     BEGIN  %WARNING: This code depends upon fact that ELTYPE and FILTYPE are in the same place\
		       IF ELTYPE # NIL
		       THEN
			 BEGIN
			  LSIZE := ELTYPE^.SIZE;
			   IF ELTYPE^.FORM = RECORDS
			   THEN
			     BEGIN
			      LSP := ELTYPE^.RECVAR;
			     END
			   ELSE
			     IF ELTYPE^.FORM = ARRAYS
			     THEN LSP := ELTYPE
			 END
		     END
		   ELSE ERROR(458);
		WHILE SY = COMMA DO
		 BEGIN
		  INSYMBOL; CONSTANT(FSYS OR [COMMA,COLON,RPARENT],LSP1,LVAL);
		  VARTS := VARTS + 1;
		  %CHECK TO INSERTADDR HERE: IS CONSTANT IN TAGFIELDTYPE RANGE\
		   IF LSP = NIL
		   THEN ERROR(408)
		   ELSE
		     IF STRING(LSP1) OR (LSP1=REALPTR)
		     THEN ERROR(460)
		     ELSE
		       BEGIN
			TAGFC := TAGFC + 1;
			 IF TAGFC > TAGFMAX
			 THEN
			   BEGIN
			    ERROR(409);TAGFC := TAGFMAX; GOTO 1
			   END;
			 IF LSP^.FORM = TAGFWITHID
			 THEN
			   BEGIN
			     IF LSP^.TAGFIELDP # NIL
			     THEN
			       IF COMPTYPES(LSP^.TAGFIELDP^.IDTYPE,LSP1)
			       THEN
				WITH TAGFSAV[TAGFC],LSP^.TAGFIELDP^ DO
				 BEGIN
				  TAGFVAL := LVAL.IVAL;
				  TAGFADDR:= FLDADDR;
				  LPACKKIND:= PACKF;
(* 21 - KEEP FROM STORING TAG VALUE INTO NON-EXISTENT FIELD *)
				  TAGWITHID:=TRUE
				 END
			       ELSE
				 BEGIN
				  ERROR(458);GOTO 1
				 END
			   END
			 ELSE
			   IF LSP^.FORM=TAGFWITHOUTID
			   THEN
			     BEGIN
			       IF NOT COMPTYPES(LSP^.TAGFIELDTYPE,LSP1)
			       THEN
				 BEGIN
				  ERROR(458); GOTO 1
				 END
			     END
			   ELSE
			     BEGIN
			      ERROR(358);GOTO 1
			     END;
			LSP1 := LSP^.FSTVAR;
			WHILE LSP1 # NIL DO
			WITH LSP1^ DO
			 IF VARVAL.IVAL = LVAL.IVAL
			 THEN
			   BEGIN
			    LSIZE :=SIZE; LSP := SUBVAR; GOTO 1
			   END
			 ELSE LSP1:=NXTVAR;
			LSIZE := LSP^.SIZE; LSP := NIL
		       END;
1:
		 END %WHILE\ ;
		 IF SY = COLON
		 THEN
		   BEGIN
		    INSYMBOL;
		    EXPRESSION(FSYS OR [RPARENT],ONREGC);
		     IF LSP = NIL
		     THEN ERROR(408)
		     ELSE
		       IF LSP^.FORM # ARRAYS
		       THEN ERROR(259)
		       ELSE
			 BEGIN
			   IF  NOT COMPTYPES(GATTR.TYPTR,LSP^.INXTYPE)
			   THEN
			    ERROR(458);
			  LSZ := 1; LMIN := 1;
			   IF LSP^.INXTYPE # NIL
			   THEN
			    GETBOUNDS(LSP^.INXTYPE,LMIN,LMAX);
			   IF LSP^.AELTYPE # NIL
			   THEN LSZ := LSP^.AELTYPE^.SIZE;
			  LOAD(GATTR);
(* 47 - add bounds checking *)
			  if runtmcheck
			    then begin
			    macro3(301B%cail\,regc,lmin);
			    macro3(303B%caile\,regc,lmax);
			    support(indexerror)
			    end;
			   IF LSZ # 1
			   THEN
			    MACRO3(221B%IMULI\,REGC,LSZ);
			   IF LSP^.ARRAYPF
			   THEN
			     BEGIN
(* 30 - added BITMAX DIV, per Nagel's instructions *)
(* 47 - repair calculation, and adjust for LMIN *)
			      lsz := bitmax div lsp^.aeltype^.bitsize-1-(lmin-1);
			      if lsz > 0
				then macro3(271B%addi\,regc,lsz)
			      else if lsz < 0
				then macro3(275B%subi\,regc,-lsz);
			      INCREMENTREGC; REGC := REGC - 1;
			      %FOR TESTING BECAUSE IDIV WORKS ON AC+1 TOO\
			      MACRO3(231B%IDIVI\,REGC,BITMAX DIV LSP^.AELTYPE^.BITSIZE);
			      LSZ := LSIZE - LSP^.SIZE;
			     END
			   ELSE
			    LSZ := LSIZE - LSP^.SIZE - LSZ*(LMIN - 1);
(* 42 - change for GET and PUT *)
			    MACRO4(201B%MOVEI\,SIZEREG,REGC,LSZ);
			 END
		   END
		 ELSE MACRO3(201B%MOVEI\,SIZEREG,LSIZE);
(* 24 - DON'T ZERO CORE UNLESS CHECKING *)
(* 25 - USE /ZERO NOW INSTEAD *)
(* 27 - add NEWZ *)
(* 42 - move get and put in here *)
		if lattr.typtr # nil
		  then begin
		  case lkey of
		    1:if comptypes(lattr.typtr^.filtype,charptr)
		        then adr := getcharacter
			else adr := getfile;
		    3:adr := putfile;
		    14:if zero
			then adr := clearalloc
			else adr := allocate;
		    15:with gattr do
			begin typtr:=intptr; reg:=sizereg;kind:=expr;regc:=sizereg end;
		    35:adr := clearallocate;
		    40:if comptypes(lattr.typtr^.filtype,charptr)
			then error(458)
			else adr:=getxf;
(* 173 - internal files *)
		    44:if lattr.typtr^.eltype <> nil
			 then if lattr.typtr^.eltype^.hasfile
			        then adr := withfiledeallocate
			        else adr := deallocate
			 else adr := deallocate
		    end;
{Perhaps this is premature optimization, but NEW and DISPOSE do not save any
 ac's.  Hence any that are active here have to be saved by the caller.  Since
 only ac's 1 to 6 are used by the NEW and DISPOSE, we save only things <= 6:
   any WITH ac's <= 6  (a fairly rare case)
   lattr.indexr, if it is <= 6.  This is used in cases such as
	new(a^.b^.c)
     to save information needed to get to C again after the call.
   ac 1 sometimes contains the display pointer for a higher-level block.
     However by gerrymandering LATTR, we force this to be recomputed after
     the call by FETCHBASIS, so it is not saved.
}
(* 154 - don't clobber With AC's *)
		  if (lkey in [14,35,44]) and (regcmax < 6)
		    then for i := 0 to withix do
		      with display[top-i] do
		        if (cindr#0) and (cindr <= 6)
			  then macro4(202B%MOVEM\,cindr,basis,clc);
(* 153 - save AC's *)
(* 154 - don't need to save WITH acs *)
(* 171 - more AC saving *)
		  if (lkey in [14,35,44])
		   then begin
		   if (lattr.indexr > regin) and (lattr.indexr <= 6)
		     then macro3(261B%PUSH\,topp,lattr.indexr);
		   if (lattr.packfg = packk) and (lattr.bpaddr > regin)
					     and (lattr.bpaddr <= 6)
		     then macro3(261B%PUSH\,topp,lattr.bpaddr);
		   support(adr);
		   if (lattr.packfg = packk) and (lattr.bpaddr > regin)
					     and (lattr.bpaddr <= 6)
		     then macro3(262B%POP\,topp,lattr.bpaddr);
		   if (lattr.indexr > regin) and (lattr.indexr <= 6)
		     then macro3(262B%POP\,topp,lattr.indexr);
		   end
		  else if lkey#15
		   then support(adr);
(* 154 - restore WITH ac's *)
		  if (lkey in [14,35,44]) and (regcmax < 6)
		    then for i := 0 to withix do
		      with display[top-i] do
		        if (cindr#0) and (cindr <= 6)
			  then macro4(200B%MOVE\,cindr,basis,clc);
		  end;
		if (lkey=14)or(lkey=35)
		then begin
		REGC := REGIN+1;
		FIRSTLOAD := TRUE;
		FOR I := 0 TO TAGFC DO
		WITH TAGFSAV[I] DO
(* 21 - KEEP FROM STORING TAG VALUE INTO NON-EXISTENT FIELD *)
		IF TAGWITHID THEN
		 BEGIN
		  MACRO3(201B%MOVEI\,HAC,TAGFVAL);
		   CASE LPACKKIND OF
		    NOTPACK:  MACRO4(202B%MOVEM\,HAC,REGC,TAGFADDR);
		    HWORDR:MACRO4(542B%HRRM\,HAC,REGC,TAGFADDR);
		    HWORDL:MACRO4(506B%HRLM\,HAC,REGC,TAGFADDR);
		    PACKK :
			    BEGIN
			      IF FIRSTLOAD
			      THEN
				BEGIN
				 MACRO3(200B%MOVE\,TAC,REGC);
				 FIRSTLOAD := FALSE
				END;
			     MACRO3R(137B%DPB\,HAC,TAGFADDR)
			    END
		   END%CASE\
		 END;
		STORE(REGC,LATTR)
(* 42 - move GET and PUT in here *)
		end
(* 152 - DISPOSE *)
(* 153 - make reg usage safer *)
	       else if lkey=44
		then begin
	        incrementregc;
	        macro3(201B%MOVEI\,regc,377777B%nil\);
		store(regc,lattr)
	        end
	       END %NEW\ ;

(* 46 - major reorganization to handle all arg formats *)
	      PROCEDURE CALLI;
		type argform=(bareac,xwd,twowords,oneword);
		VAR LSP:STP; LVAL,acval:VALU;
		    LH,RH,BOOL,RESUL:ATTR;
		    arg:argform;
		BEGIN
		arg := xwd;  %default format\
		CONSTANT(FSYS OR [RPARENT,COMMA],LSP,LVAL);
		IF NOT(COMPTYPES(INTPTR,LSP))
		  THEN ERROR(458);
		IF SY = COMMA
		  THEN INSYMBOL
		  ELSE ERROR(158);
		if sy=comma %,,word\
		  then begin
		  insymbol;
		  arg := oneword;
		  expression(fsys or [rparent,comma],onregc);
		  load(gattr);
		  lh := gattr
		  end
		else if sy=colon  %:ac\
		  then begin
		  arg := bareac;
		  insymbol;
		  constant(fsys or [rparent,comma],lsp,acval);
		  if not(comptypes(intptr,lsp))
		    then error(458)
		  end
		else begin  %lh,rh   or w1:w2\
		EXPRESSION(FSYS OR [RPARENT,COMMA,COLON],ONREGC);
		LOAD(GATTR);
		LH := GATTR;
		IF SY = COMMA
		  THEN INSYMBOL
		else if sy=colon
		  then begin arg:=twowords; insymbol end
		else error(158);
		  EXPRESSION(FSYS OR [RPARENT,COMMA],ONREGC);
		  IF GATTR.TYPTR # NIL
		    THEN IF (GATTR.TYPTR^.FORM <= POWER) or (arg=twowords)
		      THEN LOAD(GATTR)
		      ELSE BEGIN
		      LOADADDRESS;
		      GATTR.KIND:=EXPR;
		      GATTR.REG:=GATTR.INDEXR
		      END;
		  RH := GATTR;
		  end  %of lh,rh and w1:w2\;
		IF SY = COMMA
		  THEN INSYMBOL
		  ELSE ERROR(158);
		VARIABLE(FSYS OR [RPARENT,COMMA]);
		IF GATTR.TYPTR = NIL
		  THEN ERROR(458)
		  ELSE IF NOT(GATTR.TYPTR^.FORM IN [SUBRANGE,SCALAR])
		    THEN ERROR(458)
		    ELSE LOADADDRESS;
		RESUL:=GATTR;
		IF SY = COMMA
		  THEN INSYMBOL
		  ELSE ERROR(158);
		VARIABLE(FSYS OR [RPARENT]);
		IF NOT COMPTYPES(BOOLPTR,GATTR.TYPTR)
		  THEN ERROR(158)
		  ELSE LOADADDRESS;
		BOOL := GATTR;
		IF NOT ERRORFLAG
		  THEN BEGIN
		  case arg of
		    bareac: regc := acval.ival;
		    xwd: begin regc := rh.reg; macro3(504B%hrl\,rh.reg,lh.reg) end;
		    oneword: regc := lh.reg;
		    twowords: begin
			      regc := lh.reg;
			      if (regc+1) # rh.reg
			        then macro3(200B%move\,regc+1,rh.reg)
			      end
		  end %case\;
		  macro3(201B%movei\,tac,1);
		  macro4(202B%movem\,tac,bool.indexr,0);
		  MACRO3(047B%CALLI\,REGC,LVAL.IVAL);
		  MACRO4(402B%SETZM\,0,BOOL.INDEXR,0);
		  MACRO4(202B%MOVEM\,REGC,RESUL.INDEXR,0)
		  END
		END;

(* 61 - tops20 system version *)
	      procedure jsys;
		var
		lval:valu; lsp:stp; jsysnum,numrets,i:integer;
		retsave:attr; saveret,ercal,done1: Boolean;
		realregc:acrange;
(* 133 - add variable to allow saving stuff in display *)
		savelc:addrrange;
	       procedure loadarg;
		(* Handles input args for jsys:
		    simple vars - use their values
		    sets - use LH word only
		    files - use jfn word
		    packed arrays - make byte ptr to it
		    other - make pointer to it
		*)
		 begin
		 expression (fsys or [rparent,comma,semicolon,colon],onfixedregc);
		 if gattr.typtr # nil
		  then if (gattr.typtr^.form < power)
			then load(gattr)
		       else if (gattr.typtr^.form = power)
			then begin
(* 77 - can't treat as integer. have to load both words and throw away 2nd *)
			load(gattr);
			regc := regc-1;
			end
		       else if (gattr.typtr^.form = files)
			then begin
			loadaddress;
			with lastfile^ do
			 if (vlev = 0) and (not main)
			  then begin vaddr := ic-1; code.information[cix] := 'E' end;
			macro4(200b%move\,regc,regc,filjfn)
			end
		       else if (gattr.typtr^.form = arrays) and gattr.typtr^.arraypf
			then begin
			loadaddress;
			macro3r(500b%hll\,regc,gattr.typtr^.arraybpaddr);
			macro3(621b%tlz\,regc,17b)
			end
		       else loadaddress
		 end;
	       procedure storearg;
		(* stores results of jsys.  As above, but error for
		   anything bigger than a word *)
		 begin
		 variable(fsys or [rparent,comma]);
		 if gattr.typtr # nil
		  then if (gattr.typtr^.form < power)
			then store(realregc,gattr)
		       else if (gattr.typtr^.form = power)
			then begin
			gattr.typtr := intptr;
			store(realregc,gattr)
			end
		       else if (gattr.typtr^.form = files)
			then begin
			loadaddress;  {addr of file now in REGC}
			with lastfile^ do
			 if (vlev = 0) and (not main)
			  then begin vaddr:=ic-1; code.information[cix] := 'E' end;
(* 173 - internal files *)
{We have to compile code to see if the file is initialized.  If not,
 call INITB. to do so.  INITB. needs the file in AC 2.  Note that
 the AC use here is such that REGC is always above 2, so the only
 reason for 2 not to be free is that realregc is using it.  This is
 certainly not the best possible code, but at this point I am going
 for the last code in the compiler to implement it.}
			macro3(250b%exch\,2,regc);
			macro4(200b%move\,0,2,filtst);
			macro3(302b%caie\,0,314157B);
			support(initfileblock);
			if realregc = 2
			  then macro4(202b%movem\,regc,2,filjfn)
			  else macro4(202b%movem\,realregc,2,filjfn)
			end
		       else error(458)
		 end;
		begin (* jsys *)
		ercal := false; saveret := false; numrets := 0; done1 := false;
		constant(fsys or [rparent,comma,semicolon],lsp,lval);
		jsysnum := lval.ival;
		if not comptypes (intptr, lsp)
		  then error(458);
		if sy = comma
		  then begin (* return spec *)
		  insymbol;
		  constant(fsys or [rparent,comma,semicolon],lsp,lval);
		  if lval.ival < 0
		    then ercal := true;
		  numrets := abs(lval.ival);
		  if not comptypes (intptr, lsp)
		    then error(458);
		  if sy = comma
		    then begin (* return var *)
		    insymbol;
		    variable(fsys or [rparent,semicolon]);
		    if comptypes (intptr,gattr.typtr)
		      then begin saveret := true; retsave := gattr end
		      else error (459)
		    end
		  end; (* return spec *)
		if sy = semicolon
		  then begin (* prolog *)
		  insymbol;
		  regc := 1;
		  if sy # semicolon
		    then loop (* non-empty prolog *)
		    loadarg;
		    if sy = colon
		      then begin
		      insymbol;
		      realregc := regc;
		      loadarg;
		      macro3(504b%hrl\,realregc,realregc);
		      macro3(540b%hrr\,realregc,regc);
		      regc := realregc
		      end;
		    if not done1
		      then begin
(* 133 - save in display instead of PUSH P, *)
		      {Here we prepared a place on the display to store the value}
		      savelc := lc;
		      lc := lc+1;
		      if lc > lcmax
			then lcmax := lc;
		      macro4(202B%movem\,2,basis,savelc);
		      done1 := true;
		      regc := 1
		      end;
		    exit if sy # comma;
		    insymbol
		    end (* non-empty prolog *)
		  end; (* prolog *)
		(* main call *)
		if done1
(* 133 - save in display instead of POP P, *)
		  then begin
		  macro4(200B%move\,1,basis,savelc);
		  lc := savelc
		  end;
		if saveret
		  then macro3(201b%movei\,0,numrets+1);
		macro3(104b%jsys\,0,jsysnum);
		if ercal
		  then begin
		  macro3r(320b%jump\,16b,ic+numrets);
		  numrets := numrets -1
		  end;
		for i := 1 to numrets do
		  if saveret then
		    macro3(275b%subi\,0,1)
		    else macro3(255b%jfcl\,0,0);
		if sy = semicolon (* if epilog, save reg a over store *)
		  then begin
(* 133 - use display instead of stack to save *)
		  {find a place in the display to save ac 2}
		  savelc := lc;
		  lc := lc + 1;
		  if lc > lcmax
		    then lcmax := lc;
		  macro4(202B%movem\,2,basis,savelc);
		  macro3(200b%move\,2,1);
		  done1 := true
		  end
		 else done1 := false;
		if saveret
		  then store(0,retsave);
		if sy = semicolon
		  then begin (* epilog *)
		  realregc := 1;
		  repeat
		    insymbol;
		    regc := 4; (* so temp ac's start at 5 *)
		    realregc := realregc + 1;
		    if realregc > 4
		      then error(458);
		    storearg;
		    if done1
		      then begin
(* 133 - use display instead of stack to store ac 2 *)
		      macro4(200B%move\,2,basis,savelc);
		      lc := savelc;
		      realregc := 1;
		      done1 := false
		      end
		   until sy # comma
		  end (* epilog *)
		end; (* jsys *)

	      PROCEDURE MARK;
	       BEGIN
		VARIABLE(FSYS OR [RPARENT]);
		 IF COMPTYPES(INTPTR,GATTR.TYPTR)
		 THEN
(* 12 - REWRITE FOR NEW DYNAMIC MEMORY *)
(* 122 - retrofit KA code *)
(* 132 - separate KA10 into NOVM and KACPU *)
		 if novm
		   then begin
		   loadaddress;
		   macro4(202B%movem\,newreg,gattr.indexr,0)
		   end
		  else
		   BEGIN
		   LOADADDRESS;
		   INCREMENTREGC;
	 	   MACRO3R(200B%MOVE\,REGC,LSTNEW);
		   LSTNEW:=IC-1;  %GLOBAL FIXUP\
		   MACRO4(202B%MOVEM\,REGC,GATTR.INDEXR,0)
		   END
		 ELSE ERROR(459)
	       END %MARK\ ;

	      PROCEDURE RELEASE;
	       BEGIN
		EXPRESSION(FSYS OR [RPARENT],ONREGC);
		 IF GATTR.TYPTR = INTPTR
		 THEN
		   BEGIN
(* 12 - RECODE FOR NEW DYNAMIC MEMORY *)
		   LOAD(GATTR);
(* 122 - retrofit for KA *)
(* 132 - separate KA10 into NOVM and KACPU *)
		   if novm
		     then macro3(200B%move\,newreg,regc)
		     ELSE BEGIN
		     MACRO3R(202B%MOVEM\,REGC,LSTNEW);
		     LSTNEW := IC-1;  % GLOBAL FIXUP \
		     end
		   END
		 ELSE ERROR(458)
	       END %RELEASE\ ;

	      PROCEDURE GETLINENR;
	       BEGIN
(* 33 - ALLOW GETFILENAME WITH NON-TEXT *)
(* 171 - PREDECL FILES ARE SPECIAL *)
		GETFILENAME(INFILE,TRUE,THISFILE,GOTARG,TRUE);
		IF NOT GOTARG
		  THEN ERROR(554);
		IF GATTR.KIND <> VARBL
		 THEN ERROR(458)
		 ELSE IF  GATTR.TYPTR # NIL
		 THEN
		   IF COMPTYPES(CHARPTR,GATTR.TYPTR^.AELTYPE) AND (GATTR.TYPTR^.FORM = ARRAYS)
		   THEN
		     BEGIN
		      MACRO4(200B%MOVE\,REGC,REGC,FILLNR); STORE(REGC,GATTR)
		     END
		   ELSE ERROR(458);
	       END;

	      PROCEDURE GETINTEGERFILENAME(DEFAULTNAME : ALFA);
	      VAR
		LCP : CTP; LID : ALFA;
	       BEGIN
		LID := ID;
		ID := DEFAULTNAME; SEARCHID([VARS],LCP);
		SELECTOR(FSYS OR FACBEGSYS OR [COMMA], LCP); LOADADDRESS;
		WITH LCP^, IDTYPE^ DO
		 IF (FORM = FILES) AND (VLEV = 0) AND (NOT MAIN)
		 THEN
		   BEGIN
		    VADDR:= IC-1; CODE.INFORMATION[CIX] := 'E'
		   END;
		ID := LID
	       END;

	      PROCEDURE PUT8BITSTOTTY;
	       BEGIN
		EXPRESSION(FSYS OR [RPARENT],ONREGC) ;
		LOAD(GATTR);
		MACRO3(051B%TTCALL\,15B%IONEOU\,GATTR.REG)
	       END %PUT8BITSTOTTY\ ;

	      PROCEDURE PAGE;
	       BEGIN
(* 33 - ALLOW GETFILENAME WITH NON-TEXT *)
(* 171 - PREDECL FILES ARE SPECIAL *)
		GETFILENAME(OUTFILE,TRUE,THISFILE,GOTARG,TRUE);
		IF GOTARG
		  THEN ERROR(554);
		SUPPORT(PUTPAGE)
	       END;
(* 63 - support for tops-20 time and runtime *)
	      procedure jsysf(jsysnum,hireg:integer);
		var i:integer;
		begin
		if hireg > regc
		  then hireg := regc;
		for i := 2 to hireg do
		  macro3(261B%push\,topp,i);
		if jsysnum = 15B
		  then macro3(211B%movni\,1,5);
		macro3(104B%jsys\,0,jsysnum);
		with gattr do
		  begin
		  incrementregc; typtr := intptr; reg := regc; kind := expr;
		  macro3(200B%move\,regc,1)
		  end;
		for i := hireg downto 2 do
		  macro3(262B%pop\,topp,i)
		end;


	      PROCEDURE RUNTIME;
	       BEGIN
(* 63 - TOPS20 *)
	       IF TOPS10
		THEN WITH GATTR DO
		 BEGIN
		  INCREMENTREGC; TYPTR := INTPTR; REG := REGC; KIND := EXPR;
		  MACRO3(047B,REGC,30B%PJOB-UUO\);
		  MACRO3(047B,REGC,27B%RUNTIM-UUO\)
		 END
	        ELSE JSYSF(15B%RUNTM\,3)
	       END;

	      PROCEDURE ABS;
	       BEGIN
		WITH GATTR DO
		 IF (TYPTR = INTPTR) OR (TYPTR = REALPTR)
		 THEN
		  WITH CODE.INSTRUCTION[CIX] DO
		   IF INSTR = 200B%MOVE\
		   THEN INSTR := 214B%MOVM\
		   ELSE MACRO3(214B%MOVM\,REG,REG)
		 ELSE
		   BEGIN
		    ERROR(459); TYPTR:= INTPTR
		   END
	       END %ABS\ ;

	      PROCEDURE TIME;
	       BEGIN
(* 63 - TOPS20 *)
		WITH GATTR DO
		 BEGIN
		  INCREMENTREGC; TYPTR := INTPTR; REG := REGC; KIND := EXPR;
		  if tops10
		    then MACRO3(047B,REGC,23B%MSTIME-UUO\)
		   else begin
		   support(getdaytime);
		   macro3(262B%POP\,17B,regc)
		   end
		 END
	       END;

	      PROCEDURE SQR;
	       BEGIN
		WITH GATTR DO
		 IF TYPTR = INTPTR
		 THEN MACRO3(220B%IMUL\,REG,REG)
		 ELSE
		   IF TYPTR = REALPTR
		   THEN MACRO3(164B%FMPR\,REG,REG)
		   ELSE
		     BEGIN
		      ERROR(459); TYPTR := INTPTR
		     END
	       END %SQR\ ;

	      PROCEDURE TRUNC;
		VAR INSTRUC:1..777;
	       BEGIN
		IF LKEY = 5
		  THEN INSTRUC := 122B%FIX\
		  ELSE INSTRUC := 126B%FIXR\;
		 IF GATTR.TYPTR # REALPTR
		 THEN ERROR(459)
		 ELSE
(* 2 - hard code TRUNC using KI-10 op code *)
(* 10 - ADD ROUND *)
(* 101 - fix bad code generation for fix and fixr *)
(* 122 - put back KA code *)	 
(* 132 - separate KA10 into NOVM and KACPU *)
		 if kacpu
		   then begin
		   if lkey=5
		     then macro3(551B%hrrzi\,tac,gattr.reg)
		     else macro3(561B%hrroi\,tac,gattr.reg);
		   support(convertrealtointeger);
		   end
		  ELSE WITH CODE.INSTRUCTION[CIX] DO
		    IF (INSTR = 200B%MOVE\) AND (AC = GATTR.REG)
		      THEN INSTR := INSTRUC
		      ELSE MACRO3(INSTRUC,GATTR.REG,GATTR.REG);
		GATTR.TYPTR := INTPTR
	       END %TRUNC\ ;

	      PROCEDURE ODD;
	       BEGIN
		WITH GATTR DO
		 BEGIN
		   IF TYPTR # INTPTR
		   THEN ERROR(459);
		  MACRO3(405B%ANDI\,REG,1);
		  TYPTR := BOOLPTR
		 END
	       END %ODD\ ;

	      PROCEDURE ORD;
	       BEGIN
		 IF GATTR.TYPTR # NIL
		 THEN
		   IF GATTR.TYPTR^.FORM >= POWER
		   THEN ERROR(459);
		GATTR.TYPTR := INTPTR
	       END %ORD\ ;

	      PROCEDURE CHR;
	       BEGIN
		 IF GATTR.TYPTR # INTPTR
		 THEN ERROR(459);
		GATTR.TYPTR := CHARPTR
	       END %CHR\ ;

	      PROCEDURE PREDSUCC;
	      VAR
		LSTRPTR:STP; LATTR: ATTR;
	       BEGIN
		 IF GATTR.TYPTR # NIL
		 THEN
		   IF (GATTR.TYPTR^.FORM>SUBRANGE) OR (GATTR.TYPTR=REALPTR)
		   THEN ERROR(459)
		   ELSE
		     IF RUNTMCHECK
		     THEN
		       BEGIN
			LSTRPTR:=GATTR.TYPTR;
			 IF (LSTRPTR^.FORM=SUBRANGE) AND (LSTRPTR^.RANGETYPE #NIL)
			 THEN LSTRPTR:=LSTRPTR^.RANGETYPE;
			 IF LKEY=9
			 THEN
			   BEGIN
			     IF LSTRPTR=INTPTR
			     THEN
			       BEGIN
				MACRO3R(255B%JFCL\,10B,IC+1);
				MACRO3(275B%SUBI\,REGC,1  );
				MACRO3R(255B%JFCL\,10B,IC+2);
				MACRO3(334B%SKIPA\,0,0	  );
				SUPPORT(ERRORINASSIGNMENT)
			       END
			     ELSE%  CHAR OR DECLARED \
			       BEGIN
				MACRO3R(365B%SOJGE\,REGC,IC+2);
				SUPPORT(ERRORINASSIGNMENT)
			       END
			   END % LKEY = 9 \
			 ELSE % LKEY = 10 \
			   BEGIN
			     IF LSTRPTR=INTPTR
			     THEN
			       BEGIN
				MACRO3R(255B%JFCL \,10B,IC+1);
				MACRO3(271B%ADDI \,REGC,1  );
				MACRO3R(255B%JFCL \,10B,IC+2);
				MACRO3(334B%SKIPA\,0,0	   );
				SUPPORT(ERRORINASSIGNMENT)
			       END
			     ELSE %CHAR OR DECLARED\
			       BEGIN
				WITH LATTR DO
				 BEGIN
				  TYPTR := LSTRPTR; KIND := CST; CVAL.IVAL := 0;
				   IF LSTRPTR=CHARPTR
				   THEN CVAL.IVAL := 177B
				   ELSE
				     IF LSTRPTR^.FCONST # NIL
				     THEN CVAL.IVAL:=LSTRPTR^.FCONST^.VALUES.IVAL;
				  MAKECODE(311B%CAML\,REGC,LATTR);
				  SUPPORT(ERRORINASSIGNMENT);
				  MACRO3(271B%ADDI \,REGC,1 );
				 END
			       END
			   END % LKEY = 10 \;
		       END % RUNTMCHECK \
		     ELSE
		       IF LKEY = 9
		       THEN MACRO3(275B%SUBI\,REGC,1)
		       ELSE MACRO3(271B%ADDI\,REGC,1)
	       END %PREDSUCC\ ;

	      PROCEDURE EOFEOLN;
	       BEGIN
(* 33 - USE GETFILENAME, SO DEFAULTS TO INPUT *)
(* 171 - PREDECL FILES ARE SPECIAL *)
	       GETFILENAME(INFILE,FALSE,THISFILE,GOTARG,TRUE);
	       IF GOTARG
		 THEN ERROR(554);
		WITH GATTR DO
		 BEGIN
		  KIND := EXPR; REG := INDEXR;
		   IF LKEY=11
		   THEN
		     BEGIN
		      MACRO4(332B%SKIPE\,REG,REG,FILEOF) ;
		      MACRO3(201B%MOVEI\,REG,1) ;
		     END
		   ELSE MACRO4(200B%MOVE\,REG,REG,FILEOL);
		  TYPTR := BOOLPTR
		 END
	       END %EOF\ ;

	      PROCEDURE PROTECTION;
		(* FOR DETAILS SEE  DEC-SYSTEM-10 MONITOR CALLS MANUAL, 3.2.4 *)
	       BEGIN
		EXPRESSION ( FSYS OR [RPARENT], ONREGC );
		 IF GATTR.TYPTR = BOOLPTR
(* 63 - TOPS20 *)
		 THEN IF TOPS10
		  THEN
		   BEGIN
		    LOAD(GATTR);
		    MACRO3(047B%CALLI\,REGC,36B%SETUWP\);
		    MACRO3(254B%HALT\,4,0)
		   END
		  ELSE
		 ELSE ERROR(458)
	       END;

	      PROCEDURE CALLNONSTANDARD;
	      VAR
		NXT,LNXT,LCP: CTP;
		LSP: STP;
(* 33 - PROC PARAM.S*)
		PKIND,LKIND: IDKIND;	LB: BOOLEAN;
		SAVECOUNT,P,I,NOFPAR: INTEGER;
		TOPPOFFSET,OFFSET,PARLIST,ACTUALPAR,FIRSTPAR,LLC: ADDRRANGE;
		LREGC: ACRANGE;

(* 111 - STRING, POINTER *)
		procedure paramfudge;
		  var lmin,lmax:integer;
		(* This is used to handle special parameter types with
		   reduced type checking, such as STRING, POINTER.  They
		   are always one of STRINGPTR, POINTERPTR, or POINTERREF.
		   STRINGPTR is for STRING, the other two for POINTER.
		   POINTERREF is for call by ref *)
		begin
		with gattr.typtr^ do
		  if lsp=stringptr
		    then if (form=arrays) and arraypf
		      then if comptypes(aeltype,charptr)
			then begin  (* STRING *)
			getbounds (gattr.typtr^.inxtype, lmin, lmax);
			loadaddress;
			incrementregc;
			macro3(201B%movei\,regc,lmax-lmin+1);
			end
		       else error(503)
		      else error(503)
		    else if form=pointer  {pointerptr or pointerref}
		      then if eltype <> nil
			then begin (* POINTER *)
(* 202 - fix up pointer by ref *)
			if lsp = pointerptr
			  then load(gattr)
			  else loadaddress;
			incrementregc;
			macro3(201B%movei\,regc,eltype^.size)
			end
		       else  (* bad type decl - already have error *)
		      else error(503);
		gattr.typtr := lsp  (* so comptypes later succeeds *)
		end;

	       BEGIN
		NOFPAR:= 0; TOPPOFFSET := 0; PARLIST := 0; ACTUALPAR := 0;
		WITH FCP^ DO
		 BEGIN
		  NXT := NEXT; LKIND := PFKIND;
		   IF KLASS = FUNC
		   THEN FIRSTPAR := 2
		   ELSE FIRSTPAR := 1;
(* 33 - PROC PARAM.S *)
		   IF LKIND = ACTUAL
		   THEN IF EXTERNDECL
		   THEN LIBRARY[LANGUAGE].CALLED:= TRUE;
		  SAVECOUNT := REGC - REGIN;
		   IF  SAVECOUNT > 0
		   THEN
		     BEGIN
		      LLC := LC ;
		      LC := LC + SAVECOUNT ;
		       IF LC > LCMAX
		       THEN  LCMAX := LC ;
		       IF SAVECOUNT > 3
		       THEN
			 BEGIN
			  MACRO3(505B%HRLI\,TAC,2);
			  MACRO4(541B%HRRI\,TAC,BASIS,LLC);
			  MACRO4(251B%BLT\,TAC,BASIS,LLC+SAVECOUNT-1)
			 END
		       ELSE FOR  I := 1 TO SAVECOUNT DO  MACRO4(202B%MOVEM\,REGIN+I,BASIS,LLC+I-1)
		     END;
		  LREGC:= REGC;
		  IF LKIND = FORMAL
		    THEN REGC := REGIN
		  ELSE IF LANGUAGE # PASCALSY
		    THEN REGC:= PARREGCMAX
		  ELSE REGC:= REGIN
		 END;
		 IF SY = LPARENT
		 THEN
		   BEGIN
		     REPEAT
		      LB := FALSE;  %DECIDE WHETHER PROC/FUNC MUST BE PASSED\
		       IF LKIND = ACTUAL
		       THEN
			 BEGIN
			   IF NXT = NIL
			   THEN ERROR(554)
			   ELSE LB := NXT^.KLASS IN [PROC,FUNC]
			 END
(* 33 - PROC PARAM.S *)
		       ELSE LB := FALSE;
			%FOR FORMAL PROC/FUNC LB IS FALSE AND EXPRESSION
			 WILL BE CALLED, WHICH WILL ALLWAYS INTERPRET A PROC/FUNC ID
			 AT ITS BEGINNING AS A CALL RATHER THAN A PARAMETER PASSING.
			 IN THIS IMPLEMENTATION, PARAMETER PROCEDURES/FUNCTIONS
			 ARE THEREFORE NOT ALLOWED TO HAVE PROCEDURE/FUNCTION
			 PARAMETERS\
		      INSYMBOL;
		       IF LB
		       THEN   %PASS FUNCTION OR PROCEDURE\
			 BEGIN
			   IF SY # IDENT
			   THEN
			    ERRANDSKIP(209,FSYS OR [COMMA,RPARENT])
			   ELSE
			     BEGIN
			       IF NXT^.KLASS = PROC
			       THEN SEARCHID([PROC],LCP)
			       ELSE
				 BEGIN
				  SEARCHID([FUNC],LCP);
				   IF  NOT COMPTYPES(LCP^.IDTYPE,NXT^.IDTYPE)
				   THEN
				    ERROR(555)
				 END;
			      INSYMBOL;
			      IFERRSKIP(166,FSYS OR [COMMA,RPARENT])
			     END;
(* 33 - PROC PARAM.S *)
			 WITH LCP^ DO
			  IF (PFDECKIND = STANDARD) OR (PFKIND = ACTUAL) AND (LANGUAGE # PASCALSY)
			    THEN ERROR (466)
			    ELSE BEGIN
			    INCREMENTREGC;
(* 67 - fix proc param's *)
			   if pflev > 1
			     then p := level - pflev
			     else p := 0;
			    IF PFKIND = ACTUAL
			      THEN BEGIN
			      IF P = 0
				THEN MACRO3(514B%HRLZ\,REGC,BASIS)
			      ELSE IF P=1
				THEN MACRO4(514B%HRLZ\,REGC,BASIS,-1)
			      ELSE %P>1\
				BEGIN
				MACRO4(550B%HRRZ\,REGC,BASIS,-1);
				FOR I := 3 TO P DO MACRO4(550B%HRRZ\,REGC,REGC,-1);
				MACRO4(514B%HRLZ\,REGC,REGC,-1)
				END;
			    IF PFADDR = 0
			      THEN BEGIN
(* 67 - fix typo: R in macro3r omitted *)
			      MACRO3R(541B%HRRI\,REGC,LINKCHAIN[P]);
			      LINKCHAIN[P] := IC - 1;
			      IF EXTERNDECL
				THEN CODE.INFORMATION[CIX] := 'E'
				ELSE CODE.INFORMATION[CIX] := 'F'
			      END
			     ELSE MACRO3R(541B%HRRI\,REGC,PFADDR);
			    END %OF PFKIND = ACTUAL \
			    ELSE %PFKIND = FORMAL \
			      IF P = 0
				THEN MACRO4(200B%MOVE\,REGC,BASIS,PFADDR)
				ELSE
				  BEGIN
				  MACRO4(200B%MOVE\,REGC,BASIS,-1);
				  FOR I := 2 TO P DO MACRO4(200B%MOVE\,REGC,REGC,-1);
				  MACRO4(200B%MOVE\,REGC,REGC,PFADDR)
				  END
			    END;
			 END %IF LB\
		       ELSE
			 BEGIN
			  EXPRESSION(FSYS OR [COMMA,RPARENT],ONFIXEDREGC);
			   IF GATTR.TYPTR # NIL
			   THEN
(* 33 - PROC PARAM.S *)
			       BEGIN
%NOTE : WE TREAT ALL PARAM'S OF A FORMAL PROC AS ACTUAL\
				 IF (NXT # NIL) OR (LKIND = FORMAL)
				 THEN
				   BEGIN
(*33 - PROC PARAM.S *)
				    IF LKIND = FORMAL
				      THEN BEGIN LSP := GATTR.TYPTR; PKIND := ACTUAL END
				      ELSE BEGIN LSP := NXT^.IDTYPE; PKIND := NXT^.VKIND END;
				     IF LSP # NIL
				     THEN
				       BEGIN
(* 33 - PROC PARAM.S *)
(* 161 - fix STRING,POINTER *)
					IF  (PKIND = ACTUAL)
					 THEN
					   IF LSP^.SIZE <= 2
					   THEN
					     BEGIN
(* 104 - more range checking for subrange things *)
(* 202 - pointer by ref *)
					       if (lsp = stringptr) or
						  (lsp = pointerptr) or
						  (lsp = pointerref)
						     then paramfudge
					       else if lsp^.form = subrange
						then loadsubrange(gattr,lsp)
					       else load(gattr);
					       IF COMPTYPES(REALPTR,LSP)
						AND (GATTR.TYPTR = INTPTR)
					       THEN MAKEREAL(GATTR)
					     END
					   ELSE
					     BEGIN
					      LOADADDRESS;
(* 33 - PROC PARAM.S *)
					       IF (LKIND = ACTUAL) AND (FCP^.LANGUAGE # PASCALSY)
					       THEN CODE.INSTRUCTION[CIX].INSTR := 505B%HRLI\
					     END
					 ELSE
					   IF GATTR.KIND = VARBL
					   THEN LOADADDRESS
					   ELSE ERROR(463) ;
(* 22 - ALLOW EXTERNAL FILE REFERENCES *)
					 IF GATTR.TYPTR#NIL
					  THEN IF GATTR.TYPTR^.FORM=FILES
					    THEN WITH LASTFILE^ DO
					     IF (VLEV=0) AND (NOT MAIN)
					      THEN BEGIN VADDR:=IC-1;CODE.INFORMATION[CIX]:='E' END;
(* 64 - fix proc param's that don't fit in ac's *)
					 IF  NOT COMPTYPES(LSP,GATTR.TYPTR)
					 THEN ERROR(503)
				       END
				   END
			       END
(* 33 - PROC PARAM.S *)
			 END;
			 IF REGC>PARREGCMAX
			 THEN
(* 33 - PROC PARAM.S *)
(* NOTE: CURRENTLY WE PUNT IF ARG'S DON'T FIT IN AC'S IN FORMAL PROC*)
			  IF LKIND=FORMAL
			   THEN ERROR(413)
			   ELSE BEGIN
			     IF TOPPOFFSET = 0
			     THEN
			       BEGIN
				LNXT := FCP^.NEXT ;
				 IF FCP^.LANGUAGE = PASCALSY
(* 62 - clean up offset *)
				 then toppoffset := fcp^.poffset + 1
				 ELSE
				   BEGIN
				    TOPPOFFSET := 1 + FIRSTPAR;
				     REPEAT
				      WITH LNXT^ DO
				       BEGIN
					NOFPAR := NOFPAR +1;
					TOPPOFFSET := TOPPOFFSET + 1;
					 IF VKIND = ACTUAL
					 THEN TOPPOFFSET := TOPPOFFSET + IDTYPE^.SIZE;
					 IF LKIND = ACTUAL
					 THEN LNXT := NEXT
				       END;
				     UNTIL LNXT = NIL;
				    PARLIST := 1 + FIRSTPAR;
				    ACTUALPAR := PARLIST + NOFPAR
				   END;
(* 104 - TOPS20 DETECTION OF STACK OVERFLOW *)
(* 115 - TENEX *)
				IF KLCPU AND NOT TOPS10
				  THEN MACRO3(105B%ADJSP\,TOPP,TOPPOFFSET)
				  ELSE MACRO3(271B%ADDI\,TOPP,TOPPOFFSET);
(* 54 - keep track of how many loc's above stack are used *)
				stkoff := stkoff + toppoffset;
				if stkoff > stkoffmax
				  then stkoffmax := stkoff
			       END ;
			    WITH NXT^ DO
			     BEGIN
			       IF FCP^.LANGUAGE = PASCALSY
			       THEN
(* 64 - fix parameter proc's that don't fit in ac's *)
			       if klass # vars
				 then macro4(202b%movem\,regc,topp,pfaddr+1-toppoffset)
				 ELSE BEGIN
(* 52 - if VAR, size is always 1 *)
				   IF (VKIND=ACTUAL) AND (IDTYPE^.SIZE=2)
				   THEN
				     BEGIN
				      MACRO4(202B%MOVEM\,REGC,TOPP,VADDR+2-TOPPOFFSET);
				      REGC := REGC - 1
				     END;
(* 201 - zero size things *)
				  IF (IDTYPE^.SIZE > 0) OR (VKIND <> ACTUAL)
				    THEN MACRO4(202B%MOVEM\,REGC,TOPP,VADDR+1-TOPPOFFSET)
				 END
			       ELSE
(* 64 - proc param's that don't fit in ac's *)
				if klass # vars
				 then error(466)
				 ELSE BEGIN
				   IF VKIND = ACTUAL
				   THEN
				     BEGIN
				       IF IDTYPE^.SIZE <= 2
				       THEN
					 BEGIN
					   IF IDTYPE^.SIZE = 2
					   THEN
					     BEGIN
					      MACRO4(202B%MOVEM\,REGC,TOPP,ACTUALPAR+1-TOPPOFFSET);
					      REGC := REGC - 1
					     END;
(* 201 - zero size objects *)
					  IF IDTYPE^.SIZE > 0
					    THEN MACRO4(202B%MOVEM\,REGC,TOPP,ACTUALPAR-TOPPOFFSET);
					  MACRO4(541B%HRRI\,REGC,TOPP,ACTUALPAR-TOPPOFFSET)
					 END
				       ELSE
					 BEGIN
					  MACRO4(541B%HRRI\,REGC,TOPP,ACTUALPAR-TOPPOFFSET);
					  MACRO4(251B%BLT\,REGC,TOPP,ACTUALPAR+IDTYPE^.SIZE-1-TOPPOFFSET);
(* 52 - BLT may change REGC, so reset it since used below *)
					  MACRO4(541B%HRRI\,REGC,TOPP,ACTUALPAR-TOPPOFFSET)
					 END;
				      ACTUALPAR := ACTUALPAR + IDTYPE^.SIZE
				     END;
				  MACRO4(552B%HRRZM\,REGC,TOPP,PARLIST-TOPPOFFSET);
				  PARLIST := PARLIST + 1
				 END;
			      REGC := PARREGCMAX
			     END
			   END;
		       IF (LKIND = ACTUAL) AND (NXT # NIL)
		       THEN NXT := NXT^.NEXT
		     UNTIL SY # COMMA;
		     IF SY = RPARENT
		     THEN INSYMBOL
		     ELSE ERROR(152)
		   END %IF LPARENT\;
		FOR I := 0 TO WITHIX DO
		WITH DISPLAY[TOP-I] DO
		 IF (CINDR#0)  AND  (CINDR#BASIS)
		 THEN
		  MACRO4(202B%MOVEM\,CINDR,BASIS,CLC);
		WITH FCP^ DO
		 BEGIN
(* 33 - PROC. PARAM.S *)
		   IF LKIND = FORMAL
		     THEN BEGIN END %TOPOFFSET=0 ALWAYS AT THE MOMENT\
		   ELSE IF  (LANGUAGE = PASCALSY) AND (TOPPOFFSET # 0)
(* 54 - keep track of offsets above top of stack *)
(* 62 - clean up offset *)
		     THEN STKOFF := STKOFF - TOPPOFFSET
		   ELSE IF (LANGUAGE # PASCALSY) AND (TOPPOFFSET = 0)
		     THEN
		     BEGIN
		      TOPPOFFSET:= FIRSTPAR+2;
(* 104 - TOPS20 ADJSP *)
(* 115 - TENEX *)
		      IF KLCPU AND NOT TOPS10
			THEN MACRO3(105B%ADJSP\,TOPP,TOPPOFFSET)
		        ELSE MACRO3(271B%ADDI\,TOPP,TOPPOFFSET);
(* 54 - keep track of how many loc's above stack are used *)
		      STKOFF := STKOFF + TOPPOFFSET;
		      IF STKOFF > STKOFFMAX
		        THEN STKOFFMAX := STKOFF
		     END;
		   IF PFLEV > 1
		   THEN P := LEVEL - PFLEV
		   ELSE P:= 0;
		   IF LKIND = ACTUAL
		   THEN
		     BEGIN
		       IF NXT # NIL
		       THEN ERROR(554);
		       IF LANGUAGE # PASCALSY
		       THEN
			 BEGIN
			  MACRO3(515B%HRLZI\,HAC,-NOFPAR);
			  MACRO4(202B%MOVEM\,HAC,TOPP,FIRSTPAR-TOPPOFFSET);
			  MACRO4(202B%MOVEM\,BASIS,TOPP,-TOPPOFFSET);
			  MACRO4(201B%MOVEI\,BASIS,TOPP,FIRSTPAR-TOPPOFFSET+1);
			   IF NOFPAR = 0
			   THEN MACRO4(402B%SETZM\,0,TOPP,FIRSTPAR-TOPPOFFSET+1)
			 END;
		       IF PFADDR = 0
		       THEN
			 BEGIN
			  MACRO3R(260B%PUSHJ\,TOPP,LINKCHAIN[P]); LINKCHAIN[P]:= IC-1;
			   IF EXTERNDECL
			   THEN CODE.INFORMATION[CIX] := 'E'
			   ELSE CODE.INFORMATION[CIX] := 'F'
			 END
		       ELSE MACRO3R(260B%PUSHJ\,TOPP,PFADDR-P);
(* 33 - PROC PARAM.S *)
		   IF LANGUAGE # PASCALSY
		   THEN
		     BEGIN
(* 104 - TOPS20 ADJSP *)
		      IF KLCPU AND NOT TOPS10
			THEN MACRO3(105B%ADJSP\,TOPP,-TOPPOFFSET)
		        ELSE MACRO3(275B%SUBI\,TOPP,TOPPOFFSET);
(* 54 - keep track of how many loc's above stack are used *)
		      STKOFF := STKOFF - TOPPOFFSET;
		       IF KLASS = FUNC
		       THEN
			 BEGIN
			  MACRO4(202B%MOVEM\,HAC,TOPP,2);
			   IF IDTYPE^.SIZE = 2
			   THEN MACRO4(202B%MOVEM\,TAC,TOPP,3)
			 END;
		      MACRO4(200B%MOVE\,BASIS,TOPP,0)
		     END
(* 33 - PROC PARAM.S *)
		     END  (* OF LKIND = ACTUAL *)
		   ELSE
		     BEGIN
		     IF P = 0
		      THEN BEGIN
		       MACRO4(550B%HRRZ\,TAC,BASIS,PFADDR);
		       MACRO4(544B%HLR\,BASIS,BASIS,PFADDR)
		       END
		      ELSE BEGIN
		       MACRO4(550B%HRRZ\,TAC,BASIS,-1);
		       FOR I := 2 TO P DO MACRO4(550B%HRRZ\,TAC,TAC,-1);
		       MACRO4(544B%HLR\,BASIS,TAC,PFADDR);
		       MACRO4(550B%HRRZ\,TAC,TAC,PFADDR)
		       END;
		     MACRO4(260B%PUSHJ\,TOPP,TAC,0)
		     END
		 END;
		FOR I := 0 TO WITHIX DO
		WITH DISPLAY[TOP-I] DO
		 IF (CINDR#0)  AND  (CINDR#BASIS)
		 THEN MACRO4(200B%MOVE\,CINDR,BASIS,CLC) ;
		 IF  SAVECOUNT > 0
		 THEN
		   BEGIN
		     IF SAVECOUNT > 3
		     THEN
		       BEGIN
			MACRO4(505B%HRLI\,TAC,BASIS,LLC);
			MACRO3(541B%HRRI\,TAC,2);
			MACRO3(251B%BLT\,TAC,SAVECOUNT+1)
		       END
		     ELSE FOR  I := 1 TO SAVECOUNT  DO	MACRO4(200B%MOVE\,REGIN+I,BASIS,LLC+I-1) ;
		    LC := LLC
		   END ;
		GATTR.TYPTR := FCP^.IDTYPE; REGC := LREGC
	       END %CALLNONSTANDARD\ ;

	     BEGIN
	      %CALL\
	       IF FCP^.PFDECKIND = STANDARD
	       THEN
		 BEGIN
		  LKEY := FCP^.KEY;
		   IF FCP^.KLASS = PROC
		   THEN
		     BEGIN
(* 26 - allow non-text files *)
(* 61 - rclose *)
		       IF NOT (LKEY IN [7,8,9,10,11,17,19,25,34,39,42] )
		       THEN
			 IF SY = LPARENT
			 THEN INSYMBOL
			 ELSE ERROR(153);
(* 45 - APPEND, UPDATE, RENAME, use REG5 and REG6 *)
		       IF (LKEY IN [5,6,7,8,10,11,27,29,36]) AND (REGCMAX <= 8)
		       THEN ERROR(317);
			%REGISTER USED BY RUNTIME SUPPORT FREE OR NOT  \
		       CASE LKEY OF
(* 42 - move GET and PUT to NEW *)
			2,4,
(* 14 - NEW DUMP MODE I/O *)
			5,6,27,28,29,36:  GETPUTRESETREWRITE;
			7,
			8:
			   BEGIN
			    READREADLN;
			     IF NORIGHTPARENT
			     THEN GOTO 9
			   END;
			9:
			   BEGIN
			    BREAK;
			     IF NORIGHTPARENT
			     THEN GOTO 9
			   END;
			10,
			11:
			    BEGIN
			     WRITEWRITELN;
			      IF NORIGHTPARENT
			      THEN GOTO 9
			    END;
			12:    PACK;
			13:    UNPACK;
(* 27 - add NEWZ *)
(* 42 - move GET and PUT to NEW *)
(* 152 - add DISPOSE *)
			1,3,14,35,40,44:    NEW;
			15:    MARK;
			16:    RELEASE;
			17:    GETLINENR;
			18:    PUT8BITSTOTTY;
			19:
			    BEGIN
			     PAGE;
			      IF NORIGHTPARENT
			      THEN GOTO 9
			    END;
			21:    PROTECTION;
(* 10 - ADD SETSTRING *)
			22,23:  SETSTRING;
			24:	GETINDEX;
(* 26 - allow non-text files *)
(* 42 - move breakin to close *)
(* 61 - rclose *)
			25,34,39,42:	BEGIN CLOSE;IF NORIGHTPARENT THEN GOTO 9 END;
			26:CALLI;
(* 14 - NEW DUMP MODE I/O *)
			30,31:DUMP;
			32,33,38:USET;
(* 61 - delete *)
			37,41:PUTX;
(* 61 - tops20 system version *)
		        43:JSYS
		       END
		     END
		   ELSE
		     BEGIN
		       IF NOT (LKEY IN [1,2,11,12])
		       THEN
			 BEGIN
			   IF SY = LPARENT
			   THEN INSYMBOL
			   ELSE ERROR(153);
			  if lkey#15
			    then EXPRESSION(FSYS OR [RPARENT],ONREGC);
			   IF NOT (LKEY IN [7,8,11,12,15])
			   THEN LOAD(GATTR)
			 END;
		       CASE LKEY OF
			1:    RUNTIME;
			2:    TIME;
			3:    ABS;
			4:    SQR;
			5,14:    TRUNC;
			6:    ODD;
			7:    ORD;
			8:    CHR;
			9,10:  PREDSUCC;
			11,12: BEGIN EOFEOLN; IF NORIGHTPARENT THEN GOTO 9 END;
			15: NEW
		       END;
		       IF LKEY < 3
		       THEN GOTO 9
		     END;
		   IF SY = RPARENT
		   THEN INSYMBOL
		   ELSE ERROR(152);
9:
		 END %STANDARD PROCEDURES AND FUNCTIONS\
	       ELSE CALLNONSTANDARD
	     END %CALL\ ;

	    PROCEDURE EXPRESSION;
	    VAR
	      LATTR: ATTR; LOP: OPERATOR; LSIZE: ADDRRANGE; LOFFSET: INTEGER; DEFAULT,NEEDSHIFT: BOOLEAN;
	      BOOLREGC,TESTREGC:ACRANGE; LINSTR,LINSTR1: INSTRANGE; LREGC1,LREGC2: ACRANGE;
	      SETINCLUSION : BOOLEAN; JMPADRIFALLEQUAL : INTEGER;

	      PROCEDURE CHANGEBOOL(VAR FINSTR: INSTRANGE);
	       BEGIN
		 IF (FINSTR>=311B) AND (FINSTR<=313B)
		 THEN FINSTR := FINSTR+4  %CAML,CAME,CAMLE --> CAMGE,CAMN,CAMG\
		 ELSE
		   IF (FINSTR>=315B) AND (FINSTR<=317B)
		   THEN FINSTR := FINSTR-4  %SAME IN THE OTHER WAY\;
	       END;

	      PROCEDURE SEARCHCODE(FINSTR:INSTRANGE; FATTR: ATTR);
		PROCEDURE CHANGEOPERANDS(VAR FINSTR:INSTRANGE);
		 BEGIN
		   IF FINSTR=311B%CAML\
		   THEN FINSTR := 317B%CAMG\
		   ELSE
		     IF FINSTR = 313B%CAMLE\
		     THEN FINSTR := 315B%CAMGE\
		     ELSE
		       IF FINSTR=315B%CAMGE\
		       THEN FINSTR := 313B%CAMLE\
		       ELSE
			 IF FINSTR = 317B%CAMG\
			 THEN FINSTR := 311B%CAML\
			 ELSE
			   IF FINSTR = 420B%ANDCM\
			   THEN FINSTR := 410B%ANDCA\
			   ELSE
			     IF FINSTR = 410B%ANDCA\
			     THEN FINSTR := 420B%ANDCM\;
		 END;

	       BEGIN
		WITH GATTR DO
		 IF FATTR.KIND = EXPR
		 THEN
		   BEGIN
		    MAKECODE(FINSTR,FATTR.REG,GATTR); REG := FATTR.REG
		   END
		 ELSE
		   IF KIND = EXPR
		   THEN
		     BEGIN
		      CHANGEOPERANDS(FINSTR); MAKECODE(FINSTR,REG,FATTR)
		     END
		   ELSE
		     IF (KIND=VARBL) AND ((PACKFG#NOTPACK)
					  OR (INDEXR>REGIN) AND (INDEXR<=REGCMAX) AND
					  ((FATTR.INDEXR<=REGIN) OR (FATTR.INDEXR>REGCMAX)))
		     THEN
		       BEGIN
			LOAD(GATTR); CHANGEOPERANDS(FINSTR); MAKECODE(FINSTR,REG,FATTR)
		       END
		     ELSE
		       BEGIN
			LOAD(FATTR); MAKECODE(FINSTR,FATTR.REG,GATTR); REG := FATTR.REG
		       END;
	       END;

	      PROCEDURE SIMPLEEXPRESSION(FSYS: SETOFSYS);
	      VAR
		LATTR: ATTR; LOP: OPERATOR; SIGNED : BOOLEAN;
(* 52 - new var needed to prevent clobbering CONST decl. *)
		NEWREALCSP: CSP;

		PROCEDURE TERM(FSYS: SETOFSYS);
		VAR
		  LATTR: ATTR; LOP: OPERATOR;

		  PROCEDURE FACTOR(FSYS: SETOFSYS);
		  VAR
		    LCP: CTP; LVP: CSP; VARPART: BOOLEAN;
		    CSTPART: SET OF 0..71; LSP: STP;
		    RANGEPART: BOOLEAN;LRMIN: INTEGER;
		   BEGIN
		     IF NOT (SY IN FACBEGSYS)
		     THEN
		       BEGIN
			ERRANDSKIP(173,FSYS OR FACBEGSYS);
			GATTR.TYPTR := NIL
		       END;
		     IF SY IN FACBEGSYS
		     THEN
		       BEGIN
			 CASE SY OF
			  %ID\	  IDENT:
					 BEGIN
					  SEARCHID([KONST,VARS,FIELD,FUNC],LCP);
					  INSYMBOL;
					   IF LCP^.KLASS = FUNC
					   THEN
					     BEGIN
					      CALL(FSYS,LCP);
					       IF LCP^.PFDECKIND=DECLARED
					       THEN
						 BEGIN
						  WITH LCP^,GATTR DO
						   BEGIN
						    TYPTR :=IDTYPE; KIND :=VARBL; PACKFG :=NOTPACK;
						    VRELBYTE := NO;
						    VLEVEL :=1; DPLMT :=2;
						    INDEXR := TOPP; INDBIT :=0;
						     IF TYPTR # NIL
						     THEN
						       IF TYPTR^.SIZE = 1
						       THEN LOAD(GATTR)
						   END
						 END
					     END
					   ELSE
					     IF LCP^.KLASS = KONST
					     THEN
					      WITH GATTR, LCP^ DO
					       BEGIN
						TYPTR := IDTYPE; KIND := CST;
						CVAL := VALUES
					       END
					     ELSE
					      SELECTOR(FSYS,LCP);
					   IF GATTR.TYPTR # NIL
					   THEN       %ELIM. SUBR. TYPES TO\
					    WITH GATTR, TYPTR^ DO	  %SIMPLIFY LATER TESTS\
					     IF FORM = SUBRANGE
					     THEN  TYPTR := RANGETYPE
					 END;
			  %CST\   INTCONST:
					    BEGIN
					     WITH GATTR DO
					      BEGIN
					       TYPTR := INTPTR; KIND := CST;
					       CVAL := VAL;
					      END;
					     INSYMBOL
					    END;
			  REALCONST:
				     BEGIN
				      WITH GATTR DO
				       BEGIN
					TYPTR := REALPTR; KIND := CST;
					CVAL := VAL
				       END;
				      INSYMBOL
				     END;
			  STRINGCONST:
				       BEGIN
					WITH GATTR DO
					 BEGIN
					  CONSTANT(FSYS,TYPTR,CVAL) ; KIND := CST ;
					 END;
				       END;
			  %(\	  LPARENT:
					   BEGIN
					    INSYMBOL; EXPRESSION(FSYS OR [RPARENT],ONREGC);
					     IF SY = RPARENT
					     THEN INSYMBOL
					     ELSE ERROR(152)
					   END;
			  % NOT \ NOTSY:
					 BEGIN
					  INSYMBOL; FACTOR(FSYS);
					   IF GATTR.TYPTR = BOOLPTR
					   THEN
					     BEGIN
					      LOAD(GATTR); MACRO3(411B%ANDCAI\,REGC,1)
					     END
					   ELSE
					     BEGIN
					      ERROR(359); GATTR.TYPTR := NIL
					     END;
					 END;
			  %[\	  LBRACK:
					  BEGIN
					   INSYMBOL; CSTPART := [ ]; VARPART := FALSE;
(* 110 - MOVED RANGEPART INITIALIZATION INSIDE LOOP *)
					   NEWZ(LSP,POWER);
					   WITH LSP^ DO
					    BEGIN
					     ELSET:=NIL; SIZE:= 2
					    END;
					    IF SY = RBRACK
					    THEN
					      BEGIN
					       WITH GATTR DO
						BEGIN
						 TYPTR:=LSP; KIND:=CST;
						 NEWZ(LVP,PSET); LVP^.PVAL := CSTPART; CVAL.VALP := LVP
						END;
					       INSYMBOL
					      END
					    ELSE
					      BEGIN
(* 110 - THIS ROUTINE LARGELY RECODED *)
(* AC usage in the following is documented at the end.  In order to provide
   any sanity at all, REGC has to be kept the same whatever the expression
   types found.  Since an expression will advance REGC in most cases, we
   have to be sure it gets advanced in others.  This means incrementregc
   for constants and LOAD otherwise.  We don't LOAD constants because if
   the other half of the range is also constant we will just remember it
   as constant and not do a load at all. *)
						LOOP
		(* RANGEPART IS FLAG: 1ST EXPRESSION IS VARIABLE *)
						 RANGEPART := FALSE;
						 INCREMENTREGC; INCREMENTREGC;  (* FIRST EXPR *)
						 EXPRESSION(FSYS OR [COMMA,RBRACK,COLON],ONFIXEDREGC);
						  IF GATTR.TYPTR # NIL
						  THEN
						    IF GATTR.TYPTR^.FORM # SCALAR
						    THEN
						      BEGIN
						       ERROR(461); GATTR.TYPTR := NIL
						      END
						    ELSE
						      IF COMPTYPES(LSP^.ELSET,GATTR.TYPTR)
						      THEN
							BEGIN (* LOAD IF VAR, SAVE IN LRMIN IF CONST *)
							  IF GATTR.KIND = CST
							  THEN
							    BEGIN (* FIRST EXPR IS CONST *)
(* 127 - fix reversed AC's *)
							    INCREMENTREGC;
(* 137 - CHAR needs different test *)
							    IF (GATTR.CVAL.IVAL<0)
							      OR (GATTR.CVAL.IVAL>BASEMAX) AND (GATTR.TYPTR<>CHARPTR)
							      OR (GATTR.CVAL.IVAL>CHARMAX) AND (GATTR.TYPTR=CHARPTR)
							     THEN BEGIN ERROR(352) ; GATTR.CVAL.IVAL := 0 END;
							    IF GATTR.TYPTR=CHARPTR
							      THEN
(* 7 - TREAT LOWER CASE AS UPPER IN SETS *)
(* 105 - improve lower case mapping in sets *)
								GATTR.CVAL.IVAL := SETMAP[GATTR.CVAL.IVAL];
							    LRMIN := GATTR.CVAL.IVAL;
							    END
							  ELSE
							    BEGIN (* FIRST EXPR IS NOT A CONSTANT *)
							    RANGEPART := TRUE; (* SIGNAL VARIABLE *)
							    LOAD(GATTR);
(* 112 - range check sets *)
							    if runtmcheck
							      then begin
(* 137 - different range check for char *)
							      if gattr.typtr = charptr
								then macro3(307B%caig\,regc,charmax)
							        else macro3(307B%caig\,regc,basemax);
							      macro3(305B%caige\,regc,0);
							      support(errorinassignment)
							      end;
							    IF GATTR.TYPTR = CHARPTR
							       THEN BEGIN
(* 105 - improve lower case mapping in sets *)
								    macro4r(200B%MOVE\,regc,regc,setmapchain);
								    code.information[cix] := 'E';
								    setmapchain := ic-1;
								    END;
							     END;
							  IF SY <> COLON
							   THEN (* ONLY ONE EXPR *)
							    IF NOT RANGEPART
							     THEN (* CONSTANT *)
							      BEGIN
							      CSTPART := CSTPART OR [LRMIN];
(* 127 - fixed reversed AC's *)
							      REGC := REGC - 3;
							      END
							     ELSE (* ONE VARIABLE *)
							      BEGIN
							      IF GATTR.TYPTR = CHARPTR
								THEN CODE.INSTRUCTION[CIX].INSTR := 210B%MOVN\
							        ELSE MACRO3(210B%MOVN\,REGC,REGC);
							      REGC := REGC - 1;
							      MACRO3(515B%HRLZI\,REGC-1,400000B);
							      MACRO3(400B%SETZ\,REGC,0);
(* 105 - more improvements for lower case mapping *)
							      MACRO4(246B%LSHC\,REGC-1,REGC+1,0);
							      IF VARPART
							      THEN
								BEGIN
								 MACRO3(434B%IOR\,REGC-3,REGC-1);
								 MACRO3(434B%IOR\,REGC-2,REGC);
								 REGC := REGC-2;
								END
							      ELSE VARPART := TRUE;
							      GATTR.KIND := EXPR; GATTR.REG := REGC
							      END
							   ELSE (* RANGE *)
							    BEGIN
							    INSYMBOL;
							    EXPRESSION(FSYS OR [COMMA,RBRACK],ONFIXEDREGC);
							    IF GATTR.TYPTR <> NIL (* 2ND EXPR *)
							     THEN
							      IF GATTR.TYPTR^.FORM <> SCALAR
							       THEN BEGIN
							       ERROR(461);
							       GATTR.TYPTR := NIL
							       END
							       ELSE
								IF COMPTYPES(LSP^.ELSET,GATTR.TYPTR)
								THEN
								 BEGIN
								 IF GATTR.KIND = CST
								   THEN BEGIN
(* 137 - different test for CHAR, fix AC mess *)
								   INCREMENTREGC;
								   IF (GATTR.CVAL.IVAL < 0)
								      OR (GATTR.CVAL.IVAL > BASEMAX) AND (GATTR.TYPTR<>CHARPTR)
								      OR (GATTR.CVAL.IVAL > CHARMAX) AND (GATTR.TYPTR=CHARPTR)
								     THEN BEGIN ERROR(352); GATTR.CVAL.IVAL := 0 END;
								   IF GATTR.TYPTR = CHARPTR
								     THEN GATTR.CVAL.IVAL := SETMAP[GATTR.CVAL.IVAL]
								   END
(* 137 - more AC confusion *)
								  ELSE LOAD(GATTR);
								 IF (GATTR.KIND = CST) AND (NOT RANGEPART)
								  THEN (* CONSTANT RANGE *)
								   BEGIN
								   WHILE(LRMIN <= GATTR.CVAL.IVAL) DO
								    BEGIN
								    CSTPART := CSTPART OR [LRMIN];
								    LRMIN := LRMIN+1
								    END;
(* 127 - fix reversed AC's *)
(* 137 - once again *)
								   REGC := REGC - 4
								   END
								  ELSE
								   BEGIN (* VARIABLE LIMITS ON RANGE *)
								   IF NOT RANGEPART (* FIRST PART IS CONSTANT *)
								    THEN
								     BEGIN (* SO NOT IN AC YET *)
(* 127 - fix reversed AC's *)
(* 137 - once again *)
								     MACRO3(201B%MOVEI\,REGC-1,LRMIN)
								     END;
								   if gattr.kind = cst  (* same for second *)
								     then macro3(201B%movei\,regc,gattr.cval.ival);
(* 112 - range check sets *)
(* 137 - different test needed for CHAR *)
								   if (gattr.kind <> cst) and runtmcheck
									then begin
									if gattr.typtr = charptr
									  then macro3(307B%caig\,regc,charmax)
									  else macro3(307B%caig\,regc,basemax);
									macro3(305B%caige\,regc,0);
									support(errorinassignment);
									end;
							           IF (GATTR.TYPTR=CHARPTR) AND (GATTR.KIND <> CST)
							            THEN BEGIN
(* 105 - improve lower case mapping in sets *)
								    macro4r(200B%MOVE\,regc,regc,setmapchain);
								    code.information[cix] := 'E';
								    setmapchain := ic-1;
								    END;
		(* HERE IS WHAT IS IN THE AC'S:
			REGC    - RH LIMIT
			REGC-1	- LH LIMIT
			REGC-2  - DOUBLE WORD OF BITS
			REGC-3         "
		*)
								   MACRO3(477B%SETOB\,REGC-3,REGC-2);
								   MACRO4(246B%LSHC\,REGC-3,REGC-1,0);
								   MACRO3(275B%SUBI\,REGC,71);
								   MACRO3(210B%MOVN\,REGC,REGC);
								   MACRO3(270B%ADD\,REGC-1,REGC);
								   MACRO3(210B%MOVN\,REGC-1,REGC-1);
								   MACRO4(246B%LSHC\,REGC-3,REGC-1,0);
								   MACRO4(246B%LSHC\,REGC-3,REGC,0);
								   REGC := REGC -2;
							           IF VARPART
							            THEN
								     BEGIN
								     MACRO3(434B%IOR\,REGC-3,REGC-1);
								     MACRO3(434B%IOR\,REGC-2,REGC);
								     REGC := REGC-2;
								     END
							            ELSE VARPART := TRUE;
							           GATTR.KIND := EXPR; GATTR.REG := REGC
							           END
								 END
							    END;
							 LSP^.ELSET := GATTR.TYPTR;
							 GATTR.TYPTR :=LSP
							END
						      ELSE ERROR(360);
						EXIT IF NOT(SY IN [COMMA]);
						 INSYMBOL
						END;
						IF SY = RBRACK
						THEN INSYMBOL
						ELSE ERROR(155);
						IF VARPART
						THEN
						  BEGIN
						    IF CSTPART # [ ]
						    THEN
						      BEGIN
(* 34 - BUG FIX FROM HAMBURG - NEEDED FOR PROGSTAT *)
							NEW(LVP,PSET);LVP^.PVAL := CSTPART;
							GATTR.KIND:=CST; GATTR.CVAL.VALP := LVP;
							MAKECODE(434B%IOR\,REGC,GATTR)
						      END
						  END
						ELSE
						  BEGIN
						   NEWZ(LVP,PSET); LVP^.PVAL := CSTPART; GATTR.CVAL.VALP := LVP
						  END
					      END;
					  END
			 END %CASE\ ;
			IFERRSKIP(166,FSYS)
		       END;
		      %IF SY IN FACBEGSYS\
		   END %FACTOR\ ;

		 BEGIN
		  %TERM\
		  FACTOR(FSYS OR [MULOP]);
		  WHILE SY = MULOP DO
		   BEGIN
		     IF OP IN [RDIV,IDIV,IMOD]
		     THEN LOAD(GATTR);	%BECAUSE OPERANDS ARE NOT
					 ALLOWED TO BE CHOSEN\
		    LATTR := GATTR; LOP := OP;
		    INSYMBOL; FACTOR(FSYS OR [MULOP]);
		     IF (LATTR.TYPTR # NIL) AND (GATTR.TYPTR # NIL)
		     THEN
		       CASE LOP OF
			%*\	  MUL:
				       IF (LATTR.TYPTR = INTPTR) AND (GATTR.TYPTR = INTPTR)
				       THEN SEARCHCODE(220B%IMUL\,LATTR)
(* 21 - * with sets is and *)
				       ELSE IF (LATTR.TYPTR^.FORM=POWER) AND COMPTYPES(LATTR.TYPTR,GATTR.TYPTR)
					 THEN SEARCHCODE(404B%AND\,LATTR)
				       ELSE
					 BEGIN
					  MAKEREAL(LATTR);
					   IF (LATTR.TYPTR = REALPTR)
					    AND (GATTR.TYPTR = REALPTR)
					   THEN SEARCHCODE(164B%FMPR\,LATTR)
					   ELSE
					     BEGIN
					      ERROR(311); GATTR.TYPTR := NIL
					     END
					 END;
			%/\	  RDIV:
					BEGIN
					 MAKEREAL(LATTR);
					  IF (LATTR.TYPTR = REALPTR)
					   AND (GATTR.TYPTR = REALPTR)
					  THEN SEARCHCODE(174B%FDVR\,LATTR)
					  ELSE
					    BEGIN
					     ERROR(311); GATTR.TYPTR := NIL
					    END
					END;
			%DIV\	  IDIV:
					IF (LATTR.TYPTR = INTPTR)
					 AND (GATTR.TYPTR = INTPTR)
					THEN SEARCHCODE(230B%IDIV\,LATTR)
					ELSE
					  BEGIN
					   ERROR(311); GATTR.TYPTR := NIL
					  END;
			%MOD\	  IMOD:
					IF (LATTR.TYPTR = INTPTR)
					 AND (GATTR.TYPTR = INTPTR)
					THEN
					  BEGIN
					   SEARCHCODE(230B%IDIV\,LATTR);GATTR.REG := GATTR.REG+1
					  END
					ELSE
					  BEGIN
					   ERROR(311); GATTR.TYPTR := NIL
					  END;
			% AND \  ANDOP:
					IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR)
					 AND ( (LATTR.TYPTR^.FORM = POWER) OR (GATTR.TYPTR = BOOLPTR) )
					THEN SEARCHCODE(404B%AND\,LATTR)
					ELSE
					  BEGIN
					   ERROR(311); GATTR.TYPTR := NIL
					  END
		       END %CASE\
		     ELSE GATTR.TYPTR := NIL;
		    REGC:=GATTR.REG
		   END %WHILE\
		 END %TERM\ ;

	       BEGIN
		%SIMPLEEXPRESSION\
		SIGNED := FALSE;
		 IF (SY = ADDOP) AND (OP IN [PLUS,MINUS])
		 THEN
		   BEGIN
		    SIGNED := OP = MINUS; INSYMBOL
		   END;
		TERM(FSYS OR [ADDOP]);
		 IF SIGNED
		 THEN WITH GATTR DO
		   IF TYPTR # NIL
		   THEN
		     IF (TYPTR = INTPTR) OR (TYPTR = REALPTR)
		     THEN
		       IF KIND = CST
		       THEN
			 IF TYPTR = INTPTR
			 THEN CVAL.IVAL := - CVAL.IVAL
(* 52 - have to put negated value in new place, since old one might be a CONST declaration used elsewhere *)
			 ELSE
			   BEGIN
			   NEW(NEWREALCSP);
			   NEWREALCSP^.CCLASS := REEL;
			   NEWREALCSP^.RVAL := -CVAL.VALP^.RVAL;
			   CVAL.VALP := NEWREALCSP
			   END
		       ELSE
			 BEGIN
			  LOAD(GATTR) ;
			  WITH CODE, INSTRUCTION[CIX] DO
			   IF INSTR=200B%MOVE\
			   THEN INSTR := 210B%MOVN\
			   ELSE MACRO3(210B%MOVN\,GATTR.REG,GATTR.REG)
			 END
		     ELSE
		       BEGIN
			ERROR(311) ; GATTR.TYPTR := NIL
		       END ;
		WHILE SY = ADDOP DO
		 BEGIN
		   IF OP=MINUS
		   THEN LOAD(GATTR); %BECAUSE OPD MAY NOT BE CHOSEN\
		  LATTR := GATTR; LOP := OP;
		  INSYMBOL; TERM(FSYS OR [ADDOP]);
		   IF (LATTR.TYPTR # NIL) AND (GATTR.TYPTR # NIL)
		   THEN
		     CASE LOP OF
		      %+\	PLUS:
				      IF (LATTR.TYPTR = INTPTR) AND (GATTR.TYPTR = INTPTR)
				      THEN
				       SEARCHCODE(270B%ADD\,LATTR)
(* 21 - ALLOW + AS SET UNION *)
				      ELSE IF(LATTR.TYPTR^.FORM=POWER) AND COMPTYPES(LATTR.TYPTR,GATTR.TYPTR)
					THEN SEARCHCODE(434B%IOR\,LATTR)
				      ELSE
					BEGIN
					 MAKEREAL(LATTR);
					  IF (LATTR.TYPTR = REALPTR) AND (GATTR.TYPTR = REALPTR)
					  THEN SEARCHCODE(144B%FADR\,LATTR)
					  ELSE
					    BEGIN
					     ERROR(311); GATTR.TYPTR := NIL
					    END
					END;
		      %-\	MINUS:
				       IF (LATTR.TYPTR = INTPTR) AND (GATTR.TYPTR = INTPTR)
				       THEN
					SEARCHCODE(274B%SUB\,LATTR)
(* 21 - ALLOW - AS SET DIFFERENCE *)
				       ELSE IF (LATTR.TYPTR^.FORM = POWER) AND COMPTYPES(LATTR.TYPTR,GATTR.TYPTR)
					 THEN SEARCHCODE(420B%ANDCM\,LATTR)
				       ELSE
					 BEGIN
					  MAKEREAL(LATTR);
					   IF (LATTR.TYPTR = REALPTR) AND (GATTR.TYPTR = REALPTR)
					   THEN SEARCHCODE(154B%FSBR\,LATTR)
					   ELSE
					     IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR)
					      AND (LATTR.TYPTR^.FORM = POWER)
					     THEN SEARCHCODE(420B%ANDCM\,LATTR)
					     ELSE
					       BEGIN
						ERROR(311); GATTR.TYPTR := NIL
					       END
					 END;
		      % OR \	OROP:
				      IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR)
				       AND ( (GATTR.TYPTR = BOOLPTR) OR (LATTR.TYPTR^.FORM = POWER) )
				      THEN SEARCHCODE(434B%IOR\,LATTR)
				      ELSE
					BEGIN
					 ERROR(311); GATTR.TYPTR := NIL
					END
		     END %CASE\
		   ELSE GATTR.TYPTR := NIL;
		  REGC:=GATTR.REG
		 END %WHILE\
	       END %SIMPLEEXPRESSION\ ;

	     BEGIN
	      %EXPRESSION\
	      TESTREGC := REGC+1;
	      SIMPLEEXPRESSION(FSYS OR [RELOP]);
	       IF SY = RELOP
	       THEN
		 BEGIN
		   IF FVALUE IN [ONREGC,ONFIXEDREGC]
		   THEN
		     BEGIN
		      INCREMENTREGC; MACRO3(201B%MOVEI\,REGC,1); BOOLREGC := REGC
		     END;
		   IF GATTR.TYPTR # NIL
		   THEN
(* 24 - STRING IS ONLY STRUCTURE ALLOWED *)
		     IF STRING(GATTR.TYPTR)
		     THEN LOADADDRESS; LREGC1 := REGC;
		  LATTR := GATTR; LOP := OP;
		   IF (FVALUE IN [ONREGC,ONFIXEDREGC]) AND (REGC < BOOLREGC)
		   THEN REGC := BOOLREGC;
		  INSYMBOL; SIMPLEEXPRESSION(FSYS);
		   IF GATTR.TYPTR # NIL
		   THEN
(* 24 - STRING IS ONLY STRUCTURE ALLOWED *)
		     IF STRING(GATTR.TYPTR)
		     THEN LOADADDRESS; LREGC2 := REGC;
		   IF (LATTR.TYPTR # NIL) AND (GATTR.TYPTR # NIL)
		   THEN
		     BEGIN
		       IF LOP = INOP
		       THEN
			 IF GATTR.TYPTR^.FORM = POWER
			 THEN
			   IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR^.ELSET)
			   THEN
			     BEGIN
			      LOAD(LATTR);
			       IF (FVALUE IN [ONREGC,ONFIXEDREGC]) AND (REGC < BOOLREGC)
			       THEN REGC := BOOLREGC;
			      LOAD(GATTR); REGC := GATTR.REG - 1;
			       IF LATTR.TYPTR=CHARPTR
			       THEN
(* 7 - TREAT LOWER CASE AS UPPER IN SETS *)
				BEGIN
(* 105 - improve lower case mapping in sets *)
				macro4r(200B%move\,lattr.reg,lattr.reg,setmapchain);
				code.information[cix] := 'E';
				setmapchain := ic-1;
				END;
			      MACRO4(246B%LSHC\,REGC,LATTR.REG,0);
			       IF FVALUE = TRUEJMP
			       THEN LINSTR := 305B%CAIGE\
			       ELSE LINSTR := 301B%CAIL\;
			      MACRO3(LINSTR,REGC,0);
			     END
			   ELSE
			     BEGIN
			      ERROR(260); GATTR.TYPTR := NIL
			     END
			 ELSE
			   BEGIN
			    ERROR(213); GATTR.TYPTR := NIL
			   END
		       ELSE
			 BEGIN
			   IF LATTR.TYPTR # GATTR.TYPTR
			   THEN
			    MAKEREAL(LATTR);
			   IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR)
			   THEN
			     BEGIN
			      LSIZE := LATTR.TYPTR^.SIZE;
			       CASE LATTR.TYPTR^.FORM OF
				POINTER:
					 IF LOP IN [LTOP,LEOP,GTOP,GEOP]
					 THEN ERROR (312);
				POWER:
				       IF LOP IN [LTOP,GTOP]
				       THEN ERROR(313);
				ARRAYS:
					IF  NOT STRING(LATTR.TYPTR)
(* 24 - STRING IS ONLY STRUCT. ALLOWED *)
					THEN ERROR(312);
				RECORDS,
				FILES:
				      ERROR(314)
			       END;
			      WITH LATTR.TYPTR^ DO
			       BEGIN
				    DEFAULT := TRUE; LOFFSET := 3; SETINCLUSION := FALSE;
				     CASE LOP OF
				      LTOP:
					    BEGIN
					     LINSTR := 311B%CAML\; LINSTR1 := 313B
					    END;
				      LEOP:
					    IF FORM = POWER
					    THEN
					      BEGIN
					       SEARCHCODE(420B%ANDCM\,LATTR);
					       SETINCLUSION := TRUE
					      END
					    ELSE
					      BEGIN
					       LINSTR := 313B%CAMLE\; LINSTR1 := 313B
					      END;
				      GTOP:
					    BEGIN
					     LINSTR := 317B%CAMG\; LINSTR1 := 315B
					    END;
				      GEOP:
					    IF FORM = POWER
					    THEN
					      BEGIN
					       SEARCHCODE(410B%ANDCA\,LATTR);
					       SETINCLUSION := TRUE
					      END
					    ELSE
					      BEGIN
					       LINSTR := 315B%CAMGE\; LINSTR1 := 315B
					      END;
				      NEOP:
					    BEGIN
					     LINSTR := 316B%CAMN\;DEFAULT := FALSE
					    END;
				      EQOP:
					    BEGIN
					     LINSTR := 312B%CAME\; DEFAULT := FALSE; LOFFSET := 2
					    END
				     END;
				     IF FVALUE = TRUEJMP
				     THEN CHANGEBOOL(LINSTR);
(* 24 - STRING IS ONLY STRUCTURE *)
				   IF FORM#ARRAYS THEN BEGIN
				     IF SIZE = 1
				     THEN SEARCHCODE(LINSTR,LATTR)
				     ELSE
				       IF SETINCLUSION
				       THEN
					 BEGIN
					  MACRO3(336B%SKIPN\,0,GATTR.REG);
					  MACRO3(332B%SKIPE\,0,GATTR.REG-1);
					   IF FVALUE = TRUEJMP
					   THEN
					    MACRO3R(254B%JRST\,0,IC+2)
					 END
				       ELSE
					 BEGIN
					  LOAD(LATTR);
					   IF (FVALUE IN [ONREGC,ONFIXEDREGC]) AND (REGC<BOOLREGC)
					   THEN
					    REGC := BOOLREGC;
					  LOAD(GATTR);
					   IF DEFAULT
					   THEN
					     BEGIN
					      MACRO3(LINSTR1,LATTR.REG-1,GATTR.REG-1);
					      MACRO3R(254B%JRST\,0,IC+4)	  %FALSE\
					     END;
					  MACRO3(312B%CAME\,LATTR.REG-1,GATTR.REG-1);
					  MACRO3R(254B%JRST\,0,IC+LOFFSET);
					  MACRO3(LINSTR,LATTR.REG,GATTR.REG)
					 END
				   END
				 ELSE
(* 24 - THIS CODE IS NOW ONLY FOR STRINGS *)
				   BEGIN (*STRING*)
				   GETBOUNDS(INXTYPE,LOFFSET,LSIZE);
				   LSIZE:=LSIZE-LOFFSET+1;
(* 40 - fix this code for unpacked strings, too *)
				 if arraypf
				  then begin
				   LOFFSET:=(LSIZE MOD 5)*700B;
				   LSIZE:=LSIZE DIV 5;
				   end
				  else loffset:=0;
				   IF (LSIZE=0) AND (LOFFSET=0)
				     THEN MACRO3(403B%SETZB\,TAC,HAC)
				   ELSE IF (LSIZE=0)
				     THEN BEGIN
				     MACRO3(505B%HRLI\,LREGC1,LOFFSET+440000B);
				     MACRO3(505B%HRLI\,LREGC2,LOFFSET+440000B);
				     MACRO3(134B%ILDB\,TAC,LREGC1);
				     MACRO3(134B%ILDB\,HAC,LREGC2)
				     END
				   ELSE
				     BEGIN
(* 40 - fix for nonpacked arrays *)
				   if arraypf
				    then begin
				     MACRO3(505B%HRLI\,LREGC1,444300B);
				     MACRO3(505B%HRLI\,LREGC2,444300B);
				     end
				    else begin
				     macro3(505b%hrli\,lregc1,444400b);
				     macro3(505b%hrli\,lregc2,444400b)
				     end;
				     INCREMENTREGC;
				     IF LSIZE > 1
					THEN MACRO3(201B%MOVEI\,REGC,LSIZE);
				     MACRO3(134B%ILDB\,TAC,LREGC1);
				     MACRO3(134B%ILDB\,HAC,LREGC2);
				     IF (LOFFSET=0)
				       THEN BEGIN
				       IF LSIZE>1
					 THEN BEGIN
					 MACRO3(316B%CAMN\,TAC,HAC);
					 MACRO3R(367B%SOJG\,REGC,IC-3)
					 END
				       END
				      ELSE %OFFSET NOT 0\ BEGIN
				       MACRO3(312B%CAME\,TAC,HAC);
				       IF LSIZE>1
					 THEN BEGIN
					 MACRO3R(254B%JRST\,0,IC+6);
					 MACRO3R(367B%SOJG\,REGC,IC-4)
					 END
				        ELSE MACRO3R(254B%JRST\,0,IC+5);
				       MACRO3(505B%HRLI\,LREGC1,LOFFSET);
				       MACRO3(505B%HRLI\,LREGC2,LOFFSET);
				       MACRO3(134B%ILDB\,TAC,LREGC1);
				       MACRO3(134B%ILDB\,HAC,LREGC2)
				       END;
				     REGC:=REGC-1
				     END;
				   MACRO3(LINSTR,TAC,HAC);
				    REGC:=REGC-2
				   END
			       END
			     END
			   ELSE ERROR(260)
			 END;
		       IF FVALUE IN [ONREGC,ONFIXEDREGC]
		       THEN
			 BEGIN
			  MACRO3(400B%SETZ\,BOOLREGC,0); REGC := BOOLREGC
			 END
		       ELSE MACRO3(254B%JRST\,0,0);
		     END;
		    %(IF LATTR.TYPTR#NIL) AND (GATTR.TYPTR#NIL) THEN \
		  GATTR.TYPTR := BOOLPTR; GATTR.KIND := EXPR; GATTR.REG := REGC
		 END %SY = RELOP\
	       ELSE
		 IF FVALUE IN [TRUEJMP,FALSEJMP]
		 THEN
		   BEGIN
		    LOAD(GATTR);
		     IF GATTR.TYPTR#BOOLPTR
		     THEN ERROR (359);
		     IF FVALUE = TRUEJMP
		     THEN LINSTR := 326B%JUMPN\
		     ELSE LINSTR := 322B%JUMPE\;
		    MACRO3(LINSTR,GATTR.REG,0)
		   END
		 ELSE
		   IF GATTR.KIND=EXPR
		   THEN REGC := GATTR.REG;
	       IF GATTR.TYPTR # NIL
	       THEN
		WITH GATTR,TYPTR^ DO
(* 141 - fix bollixed AC allocation in complex array calculations *)
(* 143 - fixed code below for Tops-10 packed arrays *)
{Warning to modifiers:  the following code depends upon the register
 allocation in MAKECODE for the case where opcode=MOVE, and in
 LOADADDRESS.  Please be sure to keep them consistent!}
{Onfixedregc means we are in a context where the result has to go in
 a particular AC.  So if we had a complex calculation that ended up
 with it in a higher AC, we have to move it down.  That is for
 KIND=EXPR.  For KIND=CST or VARBL (the only other cases), we have
 to make sure REGC was not changed, as the caller will expect that.
 It could be changed by an array with a complex subscript calculation.
 Note that we in the case KIND=VARBL we may leave AC's set up with
 info needed to access arrays (in the fieldS INDEXR and/or BPADDR).
 So in that case this amounts to second-guessing LOAD and MAKECODE
 to make sure that whichever place the result will be loaded
 (usually INDEXR or BPADDR) is pointing to the fixed AC.}

		 IF FVALUE = ONFIXEDREGC
		 THEN
		   BEGIN
		     IF KIND=EXPR
		       THEN BEGIN
		       IF SIZE = 2
		         THEN TESTREGC := TESTREGC + 1;
		       IF TESTREGC # REGC
		         THEN BEGIN
		         IF SIZE = 2
			   THEN MACRO3(200B%MOVE\,TESTREGC-1,REGC-1);
		         MACRO3(200B%MOVE\,TESTREGC,REGC);
		         REG := TESTREGC; REGC := TESTREGC;
		         END
		       END
		     ELSE IF KIND=VARBL
		       THEN BEGIN
		       IF (PACKFG = PACKK) AND (BPADDR>REGIN) AND (BPADDR<=REGCMAX)
			 THEN IF (INDEXR <= REGIN) OR (BPADDR<INDEXR)
				THEN IF BPADDR<> TESTREGC
				       THEN BEGIN
				       MACRO3(200B%MOVE\,TESTREGC,BPADDR);
				       BPADDR := TESTREGC
				       END
				      ELSE
				ELSE IF INDEXR<>TESTREGC
				       THEN BEGIN
				       MACRO3(200B%MOVE\,TESTREGC,INDEXR);
				       INDEXR := TESTREGC
				       END
				      ELSE
		       ELSE IF (INDEXR>REGIN) AND (INDEXR<=REGCMAX) AND (INDEXR<>TESTREGC)
			 THEN BEGIN
			 MACRO3(200B%MOVE\,TESTREGC,INDEXR);
			 INDEXR := TESTREGC
			 END;
		       REGC := TESTREGC - 1;
		       END
		     ELSE REGC := TESTREGC-1
		   END
	     END %EXPRESSION\ ;

	    PROCEDURE ASSIGNMENT(FCP: CTP);
	    VAR
	      LATTR,SLATTR: ATTR;
	      SRMIN,SRMAX: INTEGER;

	      PROCEDURE STOREGLOBALS ;
	      TYPE
		WANDELFORM = (PTRW,INTW,REELW,PSETW,STRGW,INSTW) ;
	      VAR
		WANDEL : RECORD
			   CASE KW : WANDELFORM OF
				PTRW: (WPTR :GTP %TO ALLOW NIL\) ;
				INTW: (WINT : INTEGER ; WINT1 : INTEGER %TO PICK UP SECOND WORD OF SET\) ;
				REELW: (WREEL: REAL) ;
				PSETW: (WSET : SET OF 0..71) ;
				STRGW: (WSTRG: CHARWORD) ;
				INSTW: (WINST: PDP10INSTR)
			 END ;
		I,J : INTEGER ;
		PROCEDURE STOREWORD ;
		 BEGIN
		  CIX := CIX + 1 ;
		   IF CIX > CIXMAX
		   THEN
		     BEGIN
		      CIX := 0 ; ERRORWITHTEXT(356,'INITPROCD.')
		     END ;
		  WITH CGLOBPTR^ DO
		   BEGIN
		    CODE.INSTRUCTION[CIX] := WANDEL.WINST ;
		    LASTGLOB := LASTGLOB + 1 ;
		   END ;
		 END ;
		PROCEDURE GETNEWGLOBPTR ;
		VAR
		  LGLOBPTR : GTP ;
		 BEGIN
		  NEWZ(LGLOBPTR) ;
		  WITH LGLOBPTR^ DO
		   BEGIN
		    NEXTGLOBPTR := NIL ;
		    FIRSTGLOB	:= 0 ;
		   END ;
		   IF CGLOBPTR # NIL
		   THEN CGLOBPTR^.NEXTGLOBPTR := LGLOBPTR ;
		  CGLOBPTR := LGLOBPTR ;
		 END;
	       BEGIN
		%STOREGLOBALS\
		 IF FGLOBPTR = NIL
		 THEN
		   BEGIN
		    GETNEWGLOBPTR ;
		    FGLOBPTR := CGLOBPTR ;

		   END
		 ELSE
		   IF LATTR.DPLMT # CGLOBPTR^.LASTGLOB + 1
		   THEN GETNEWGLOBPTR ;
		WITH WANDEL,CGLOBPTR^,GATTR,CVAL DO
		 BEGIN
		   IF FIRSTGLOB = 0
		   THEN
		     BEGIN
		      FIRSTGLOB := LATTR.DPLMT ;
		      LASTGLOB := FIRSTGLOB - 1 ;
		      FCIX := CIX + 1 ;
		     END ;
		   CASE TYPTR^.FORM OF
		    SCALAR,
		    SUBRANGE:
		      BEGIN
(* 174 30-Sep-80 Andy Hisgen, CMU,  Problems with xreal:=xinteger, 
   				    and with subranges.
The lines below used to read --
	        IF TYPTR = REALPTR
		THEN
		  IF LATTR.TYPTR=INTPTR
		  THEN WREEL := IVAL
		  ELSE WREEL := VALP^.RVAL
		ELSE WINT  := IVAL ;
Unfortunately, that was testing to see if the RightHandSide (GATTR) was
a real, and if so doing weird things.  For example, that let the
assignment "x:=2", where x is a real, go thru, but without doing
any conversion, thus x contained the bit pattern for the integer 2.
The problem here seems to have been that the roles of LATTR and
GATTR got reversed in the coder's mind.  Below, we have reversed
them back.
    A second unrelated problem was that subrange checking was not
being done.  In the code below, we now handle this.
*)
				IF lattr.typtr = realptr
				THEN
				  IF gattr.typtr = intptr
				  THEN WREEL := IVAL
				  ELSE WREEL := VALP^.RVAL
				ELSE BEGIN (*left isn't real*)
				      IF lattr.typtr^.form = subrange
				      THEN
					BEGIN (*left is subrange*)
					 getBounds(lattr.typtr,srmin,srmax);
					 IF NOT( (srmin <= ival) AND
					         (ival <= srmax) )
					 THEN error(367);
					END; (*left is subrange*)
				      WINT := IVAL;
				     END; (*left isn't real*)
(*30-Sep-80 end of changes for xreal:=integer and for subranges*)

			       STOREWORD ;
			      END ;
		    POINTER:
			     BEGIN
			      WPTR := NIL ; STOREWORD
			     END ;
		    POWER   :
			      BEGIN
			       WSET := VALP^.PVAL ; STOREWORD ;
			       WINT := WINT1 %GET SECOND WORD OF SET\ ;
			       STOREWORD ;
			      END ;
		    ARRAYS   : WITH VALP^,WANDEL DO
			       BEGIN
				J := 0; WINT := 0;
				FOR I := 1 TO SLGTH DO
				 BEGIN
				  J := J + 1;
				  WSTRG[J] := SVAL[I];
				   IF J=5
				   THEN
				     BEGIN
				      J := 0;
				      STOREWORD; WINT := 0
				     END
				 END;
				 IF J#0
				 THEN STOREWORD
			       END;

		    RECORDS,
		    FILES    :	ERROR(411)
		   END %CASE\ ;
		 END % WITH \ ;
	       END % STOREGLOBALS \ ;

	     BEGIN
	      %ASSIGNMENT\
	      SELECTOR(FSYS OR [BECOMES],FCP);
	       IF SY = BECOMES
	       THEN
		 BEGIN
		  LATTR := GATTR;
		  INSYMBOL;
		  EXPRESSION(FSYS,ONREGC);
		   IF (LATTR.TYPTR # NIL) AND (GATTR.TYPTR # NIL)
		   THEN
		     IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR) OR
		      (REALPTR=LATTR.TYPTR) AND (GATTR.TYPTR=INTPTR)
		     THEN
		       IF INITGLOBALS
		       THEN
			 IF GATTR.KIND = CST
			 THEN STOREGLOBALS
			 ELSE ERROR(504)
		       ELSE
			 IF (GATTR.KIND=CST) AND (GATTR.CVAL.IVAL=0)
			  AND (LATTR.PACKFG=NOTPACK)
			 THEN
			   BEGIN
			    FETCHBASIS(LATTR);
			    WITH LATTR DO
			     BEGIN
(* 104 - check subranges *)
			      if lattr.typtr^.form = subrange
				then begin
				getbounds(lattr.typtr,srmin,srmax);
				if (0 < srmin) or (0 > srmax)
				  then error(367)
				end;
			      MACRO(VRELBYTE,402B%SETZM\,0,INDBIT,INDEXR,DPLMT)
			     END
			   END
			 ELSE
			   CASE LATTR.TYPTR^.FORM OF
			    SCALAR,
			    POINTER,
			    POWER:
				   BEGIN
				    LOAD(GATTR);
				     IF COMPTYPES(REALPTR,LATTR.TYPTR) AND (GATTR.TYPTR=INTPTR)
				     THEN
				      MAKEREAL(GATTR);
				    STORE(GATTR.REG,LATTR)
				   END;
			    SUBRANGE:
				      BEGIN
(* 104 - moved code into procedure for use elsewhere *)
				       loadsubrange(gattr,lattr.typtr);
				       STORE(GATTR.REG,LATTR)
				      END;

			    ARRAYS,
			    RECORDS:
(* 201 - zero size objects *)
				     IF GATTR.TYPTR^.SIZE = 0
				      THEN
				     ELSE IF GATTR.TYPTR^.SIZE = 1
				      THEN
				       BEGIN
					LOAD(GATTR) ; STORE(GATTR.REG,LATTR)
				       END
				     ELSE WITH LATTR DO
				       BEGIN
					LOADADDRESS ;
					CODE.INSTRUCTION[CIX].INSTR := 505B%HRLI\ ;
					FETCHBASIS(LATTR);
					MACRO(VRELBYTE,541B%HRRI\,REGC,INDBIT,INDEXR,DPLMT) ;
					 IF INDBIT=0
					 THEN MACRO5(VRELBYTE,251B%BLT \,REGC,INDEXR,DPLMT+TYPTR^.SIZE-1)
					 ELSE
					   BEGIN
					    INCREMENTREGC ;
					    MACRO3(200B%MOVE\,REGC,REGC-1);
					    MACRO4(251B%BLT \,REGC,REGC-1,TYPTR^.SIZE-1)
					   END;
				       END;
			    FILES: ERROR(361)
			   END
		     ELSE ERROR(260)
		 END %SY = BECOMES\
	       ELSE ERROR(159);
	     END %ASSIGNMENT\ ;

	    PROCEDURE GOTOSTATEMENT;
	    VAR
(* 64 - non-local gotos *)
(* 65 - remove exit labels *)
	      I,J,JJ:INTEGER; lcp:ctp;
	     BEGIN
		 IF SY = INTCONST
		 THEN
		   BEGIN
		    prterr := false;
		    searchid([labelt],lcp);
		    prterr := true;
		    if lcp # nil
		      then with lcp^ do
(* See if the goto is out of the current block.  If so, handle
 specially, since we have to restore the basis and topp.  Except
 for the global level, we recover the basis by tracing the static
 links.  Then we arranged for topp's RH to be stored in the LH
 of word 0 of the display.  Global labels are odd because the
 static link will be 0.  So the global topp and basis are stored
 in special variables. *)
(* 173 - As of this edit, we have to call GOTOC. in order to
 close files in the blocks exited.  In order to prevent problems
 if we are interrupted while this is happening, we can't really
 change BASIS or TOPP until after the files are closed, else we
 might be trying to close a file whose control block is above TOPP.
 So we REGC is the new BASIS and REGC+1 is the new TOPP *)
		        if scope # level
			  then begin
			  incrementregc;
			  if scope = 1
			    then begin
			    macro3r(200B%move\,regc,globbasis);
			    macro3r(200B%move\,regc+1,globtopp)
			    end
			   else begin
			    macro4(504B%hrl\,regc,basis,-1);
			    macro3(544B%hlr\,regc,regc);
			    for i := scope to level - 2 do
			      macro4(507B%hrls\,regc,regc,-1);
			    macro4(544B%hlr\,regc+1,regc,0);
			    macro3(504B%hrl\,regc+1,regc+1);
			    end;
(* 75 - following was macro3 due to typo *)
			  macro3r(201B%movei\,regc+2,gotochain);
			  gotochain := ic-1;
			  code.information[cix] := 'F';
			  nonlocgoto := true;
			  support(exitgoto);
			  goto 2
			  end;
		    FOR I:=1 TO LIX DO
		     BEGIN
		      WITH LABELS[I] DO
		       IF LABSVAL = VAL.IVAL
		       THEN
			 BEGIN
			  MACRO3R(254B%JRST\,0,LABSADDR);
			  GOTO 2
			 END
		     END;
		    MACRO3(254B%JRST\,0,0);
		    FOR I:=1 TO JIX DO
		     BEGIN
		      WITH GOTOS[I] DO
		       IF GOTOVAL = VAL.IVAL
		       THEN
			 BEGIN
			  J:= CODE.INSTRUCTION[GOTOADDR].ADDRESS;
			  JJ:= GOTOADDR;
			  WHILE J#0 DO
			   BEGIN
			    JJ:=J;
			    J:= CODE.INSTRUCTION[J].ADDRESS
			   END;
			  INSERTADDR(NO,JJ,CIX);
			  GOTO 2
			 END
		     END;
		    FOR I:=1 TO JIX DO
		     BEGIN
		      WITH GOTOS[I] DO
		       IF GOTOVAL = -1
		       THEN
			 BEGIN
			  GOTOVAL:=VAL.IVAL;
			  GOTOADDR:=CIX;
			  GOTO 2
			 END
		     END;
		    JIX :=JIX+1;
		     IF JIX > LABMAX
		     THEN
		       BEGIN
			ERROR(362);
			JIX := LABMAX
		       END;
		    WITH GOTOS[JIX] DO
		     BEGIN
		      GOTOVAL := VAL.IVAL;
		      GOTOADDR:=CIX
		     END;
2:
		    INSYMBOL
		   END
		 ELSE ERROR(255)
	     END %GOTOSTATEMENT\ ;

	    PROCEDURE COMPOUNDSTATEMENT;
	     BEGIN
	       LOOP
		 REPEAT
		  STATEMENT(FSYS,STATENDS)
		 UNTIL	NOT (SY IN STATBEGSYS);
	       EXIT IF SY # SEMICOLON;
		INSYMBOL
	       END;
	       IF SY = ENDSY
	       THEN INSYMBOL
	       ELSE ERROR(163)
	     END %COMPOUNDSTATEMENET\ ;

	    PROCEDURE IFSTATEMENT;
	    VAR
	      LCIX1,LCIX2: CODERANGE;
	     BEGIN
	      EXPRESSION(FSYS OR [THENSY],FALSEJMP);
	      LCIX1 := CIX;
	       IF SY = THENSY
	       THEN INSYMBOL
	       ELSE ERROR(164);
	      STATEMENT(FSYS OR [ELSESY],STATENDS OR [ELSESY]);
	       IF SY = ELSESY
	       THEN
		 BEGIN
		  MACRO3(254B%JRST\,0,0); LCIX2 := CIX;
		  INSERTADDR(RIGHT,LCIX1,IC);
		  INSYMBOL; STATEMENT(FSYS,STATENDS);
		  INSERTADDR(RIGHT,LCIX2,IC)
		 END
	       ELSE INSERTADDR(RIGHT,LCIX1,IC)
	     END %IFSTATEMENT\ ;

	    PROCEDURE CASESTATEMENT;
	    TYPE
	      CIP = ^CASEINFO;
	      CASEINFO = PACKED
	      RECORD
		NEXT: CIP;
		CSSTART: ADDRRANGE;
		CSEND: CODERANGE;
		CSLAB: INTEGER
	      END;
	    VAR
	      LSP,LSP1: STP; FSTPTR,LPT1,LPT2,LPT3,OTHERSPTR: CIP; LVAL: VALU;
	      LIC,LADDR,JUMPADDR: ADDRRANGE; LCIX: CODERANGE; LMIN,LMAX: INTEGER;

	      PROCEDURE INSERTBOUND(FCIX:CODERANGE;FIC: ADDRRANGE;BOUND:INTEGER);
	      VAR
		LCIX1:CODERANGE; LIC1: ADDRRANGE;
		LATTR:ATTR;
	       BEGIN
		 IF BOUND>=0
		 THEN INSERTADDR(NO,FCIX,BOUND)
		 ELSE
		   BEGIN
		    LCIX1:=CIX; LIC1 := IC;
		    CIX:=FCIX; IC := FIC;
		    WITH LATTR DO
		     BEGIN
		      KIND:=CST;
		      CVAL.IVAL:=BOUND;
		      TYPTR:=NIL
		     END;
		    DEPCST(INT,LATTR);
		    CIX:=LCIX1; IC:= LIC1;
		    WITH CODE.INSTRUCTION[FCIX] DO
		    INSTR:=INSTR+10B  %CAILE-->CAMLE, CAIL-->CAML\
		   END
	       END;

	     BEGIN
	      OTHERSPTR:=NIL;
	      EXPRESSION(FSYS OR [OFSY,COMMA,COLON],ONREGC);
	      LOAD(GATTR);
	      MACRO3(301B%CAIL\,REGC,0);%<<<---------- LMIN IS INSERTED HERE\
	      MACRO3(303B%CAILE\,REGC,0);%<<<--------- LMAX IS INSERTED HERE\
	      MACRO3(254B%JRST\,0,0);%<<<------------- START OF "OTHERS" IS INSERTED HERE\
	      MACRO(NO,254B%JRST\,0,1,REGC,0);%<<<---- START OF JUMP TABLE IS INSERTED HERE\
	      LCIX := CIX; LIC := IC;
	      LSP := GATTR.TYPTR;
	       IF LSP # NIL
	       THEN
		 IF (LSP^.FORM # SCALAR) OR (LSP = REALPTR)
		 THEN
		   BEGIN
		    ERROR(315); LSP := NIL
		   END;
	       IF SY = OFSY
	       THEN INSYMBOL
	       ELSE ERROR(160);
(* 65 - allow extra semicolon *)
	      while sy=semicolon do
		insymbol;
	      FSTPTR := NIL; LPT3 := NIL;
	       LOOP
		 LOOP
		  CONSTANT(FSYS OR [COMMA,COLON],LSP1,LVAL);
		   IF LSP # NIL
		   THEN
		     IF COMPTYPES(LSP,LSP1)
		     THEN
		       BEGIN
			LPT1 := FSTPTR; LPT2 := NIL;
			 IF ABS(LVAL.IVAL) > HWCSTMAX
			 THEN ERROR(316);
			WHILE LPT1 # NIL DO
			WITH LPT1^ DO
			 BEGIN
			   IF CSLAB <= LVAL.IVAL
			   THEN
			     BEGIN
			       IF CSLAB = LVAL.IVAL
			       THEN ERROR(261);
			      GOTO 1
			     END;
			  LPT2 := LPT1; LPT1 := NEXT
			 END;
1:
			NEWZ(LPT3);
			WITH LPT3^ DO
			 BEGIN
			  NEXT := LPT1; CSLAB := LVAL.IVAL;
			  CSSTART := IC; CSEND := 0
			 END;
			 IF LPT2 = NIL
			 THEN FSTPTR := LPT3
			 ELSE LPT2^.NEXT := LPT3
		       END
		     ELSE ERROR(505);
		 EXIT IF SY # COMMA;
		  INSYMBOL
		 END;
		 IF SY = COLON
		 THEN INSYMBOL
		 ELSE ERROR(151);
		 REPEAT
		  STATEMENT(FSYS,STATENDS)
		 UNTIL	NOT (SY IN STATBEGSYS);
		 IF LPT3 # NIL
		 THEN
		   BEGIN
		    MACRO3(254B%JRST\,0,0); LPT3^.CSEND := CIX
		   END;
(* 65 - allow extra semicolons *)
		while sy = semicolon
		  do insymbol;
	       exit if sy in (fsys or statends);
		 IF SY=OTHERSSY
		 THEN
		   BEGIN
		    INSYMBOL;
		     IF SY=COLON
		     THEN INSYMBOL
		     ELSE ERROR(151);
		    NEWZ(OTHERSPTR);
		    WITH OTHERSPTR^ DO
		     BEGIN
		      CSSTART:=IC;
		       REPEAT
			STATEMENT(FSYS,STATENDS)
		       UNTIL NOT(SY IN STATBEGSYS);
		      MACRO3(254B %JRST\,0,0);
		      CSEND:=CIX;
(* 65 - allow extra semicolons *)
		      while sy=semicolon do
			insymbol;
		      GOTO 2
		     END
		   END
	       END;
2:
	       IF FSTPTR # NIL
	       THEN
		 BEGIN
		  LMAX := FSTPTR^.CSLAB;
		  %REVERSE POINTERS\
		  LPT1 := FSTPTR; FSTPTR := NIL;
		   REPEAT
		    LPT2 := LPT1^.NEXT; LPT1^.NEXT := FSTPTR;
		    FSTPTR := LPT1; LPT1 := LPT2
		   UNTIL LPT1 = NIL;
		  LMIN := FSTPTR^.CSLAB;
		  INSERTBOUND(LCIX-2,LIC-2,LMAX);
		  INSERTBOUND(LCIX-3,LIC-3,LMIN);
(* 164 - Polish fixups to avoid problem with LOADER *)
		  INSERTPOLISH(LIC-1,IC,-LMIN);  {put IC-LMIN at LIC-1}
		   IF LMAX - LMIN < CIXMAX-CIX
		   THEN
		     BEGIN
		      LADDR := IC + LMAX - LMIN + 1;
		       IF OTHERSPTR=NIL
		       THEN JUMPADDR:=LADDR
		       ELSE
			 BEGIN
			  INSERTADDR(RIGHT,OTHERSPTR^.CSEND,LADDR);
			  JUMPADDR:=OTHERSPTR^.CSSTART
			 END;
		      INSERTADDR(RIGHT,LCIX-1,JUMPADDR);
		       REPEAT
			WITH FSTPTR^ DO
			 BEGIN
			  WHILE CSLAB > LMIN DO
			   BEGIN
			    FULLWORD(RIGHT,0,JUMPADDR); LMIN := LMIN + 1
			   END;
			  FULLWORD(RIGHT,0,CSSTART);
			   IF CSEND # 0
			   THEN INSERTADDR(RIGHT,CSEND,LADDR);
			  FSTPTR := NEXT; LMIN := LMIN + 1
			 END
		       UNTIL FSTPTR = NIL
		     END
		   ELSE ERROR(363)
		 END;
	       IF SY = ENDSY
	       THEN INSYMBOL
	       ELSE ERROR(163)
	     END %CASESTATEMENT\ ;

	    PROCEDURE REPEATSTATEMENT;
	    VAR
	      LADDR: ADDRRANGE;
	     BEGIN
	      LADDR := IC;
	       LOOP
		 REPEAT
		  STATEMENT(FSYS OR [UNTILSY],STATENDS OR [UNTILSY])
		 UNTIL	NOT (SY IN STATBEGSYS);
	       EXIT IF SY # SEMICOLON;
		INSYMBOL
	       END;
	       IF SY = UNTILSY
	       THEN
		 BEGIN
		  INSYMBOL; EXPRESSION(FSYS,FALSEJMP); INSERTADDR(RIGHT,CIX,LADDR);
		 END
	       ELSE ERROR(202)
	     END %REPEATSTATEMENT\ ;

	    PROCEDURE WHILESTATEMENT;
	    VAR
	      LADDR: ADDRRANGE; LCIX: CODERANGE;
	     BEGIN
	      LADDR := IC;
	      EXPRESSION(FSYS OR [DOSY],FALSEJMP);
	      LCIX := CIX;
	       IF SY = DOSY
	       THEN INSYMBOL
	       ELSE ERROR(161);
	      STATEMENT(FSYS,STATENDS);
	      MACRO3R(254B%JRST\,0,LADDR);
	      INSERTADDR(RIGHT,LCIX,IC)
	     END %WHILESTATEMENT\ ;

	    PROCEDURE FORSTATEMENT;
	    VAR
(* 104 - check subranges *)
	      LATTR,SATTR: ATTR; LSP: STP; LSY: SYMBOL;
	      LCIX: CODERANGE; LADDR,LDPLMT: ADDRRANGE; LINSTR: INSTRANGE;
	      LREGC,LINDREG: ACRANGE; LINDBIT: IBRANGE; LRELBYTE: RELBYTE;
	      ADDTOLC: INTEGER;
	     BEGIN
	       IF SY = IDENT
	       THEN
		 BEGIN
		  SEARCHID([VARS],LCP);
		  WITH LCP^, LATTR DO
		   BEGIN
		    TYPTR := IDTYPE; KIND := VARBL;
		     IF VKIND = ACTUAL
		     THEN
		       BEGIN
			VLEVEL := VLEV;
			 IF VLEV > 1
			 THEN VRELBYTE := NO
			 ELSE VRELBYTE := RIGHT;
			DPLMT := VADDR; INDEXR :=0; PACKFG := NOTPACK;
			INDBIT:=0
		       END
		     ELSE
		       BEGIN
			ERROR(364); TYPTR := NIL
		       END
		   END;
		   IF LATTR.TYPTR # NIL
		   THEN
		     IF COMPTYPES(REALPTR,LATTR.TYPTR) OR (LATTR.TYPTR^.FORM > SUBRANGE)
		     THEN
		       BEGIN
			ERROR(365); LATTR.TYPTR := NIL
		       END;
		  INSYMBOL
		 END
	       ELSE
		BEGIN
		 ERRANDSKIP(209,FSYS OR [BECOMES,TOSY,DOWNTOSY,DOSY]);
		 LATTR.TYPTR := NIL
		END;
	       IF SY = BECOMES
	       THEN
		 BEGIN
		  INSYMBOL; EXPRESSION(FSYS OR [TOSY,DOWNTOSY,DOSY],ONREGC);
		   IF GATTR.TYPTR # NIL
		   THEN
		     IF GATTR.TYPTR^.FORM # SCALAR
		     THEN ERROR(315)
		     ELSE
		       IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR)
(* 104 - range check subranges *)
		       then begin
		       if lattr.typtr # nil
		       then if lattr.typtr^.form = subrange
			    then loadsubrange(gattr,lattr.typtr)
			    else load(gattr)
		       end
		       ELSE ERROR(556);
		  LREGC := GATTR.REG
		 END
	       ELSE ERRANDSKIP(159,FSYS OR [TOSY,DOWNTOSY,DOSY]);
	       IF SY IN [TOSY,DOWNTOSY]
	       THEN
		 BEGIN
		  LSY := SY; INSYMBOL; EXPRESSION(FSYS OR [DOSY],ONREGC);
		   IF GATTR.TYPTR # NIL
		   THEN
		     IF GATTR.TYPTR^.FORM # SCALAR
		     THEN ERROR(315)
		     ELSE
		       IF COMPTYPES(LATTR.TYPTR,GATTR.TYPTR)
		       THEN
			 BEGIN
			  ADDTOLC := 0 ;
			  WITH GATTR DO
{This test checks for forms of upper bound that must be copied into a local
 variable. Originally, they tried to use variables in place instead of
 copying, to save the MOVE, MOVEM.  The problem is that if the user changes
 the variable inside the loop, you have the wrong upper bound.  We
 interpret the language spec as requiring the bound to be evaluated only
 once, at the start.  The following test, commented out, was the original
 test, to see whether the object could be used in place for a CAMGE, or
 needed to be copied.  Now we copy all variables, as just discussed.}
{IF ( (KIND = VARBL) AND ( (VLEVEL > 1) AND (VLEVEL < LEVEL) OR
 (PACKFG # NOTPACK) OR (INDEXR > 0) AND (INDEXR <=   REGCMAX) ) ) OR
 (KIND = EXPR) }
			  IF (KIND = VARBL) OR (KIND = EXPR)
			   THEN
			     BEGIN
(* 104 - add range checking for subrange types *)
			      if lattr.typtr # nil
			      then if lattr.typtr^.form = subrange
				   then loadsubrange(gattr,lattr.typtr)
				   else load(gattr);
			      MACRO4(202B%MOVEM\,REGC,BASIS,LC); ADDTOLC := 1;
			      KIND := VARBL ; INDBIT := 0  ; INDEXR := BASIS ; VLEVEL := 1;
			      DPLMT := LC ; PACKFG := NOTPACK ; VRELBYTE := NO
			     END
			  else if lattr.typtr # nil
			       then if (lattr.typtr^.form = subrange) and runtmcheck
				    then begin
				     (* must copy, since otherwise at end of loop
				        makecode will think it is in an AC *)
				    sattr := gattr;
				    loadsubrange(sattr,lattr.typtr)
				    end;
			  FETCHBASIS(LATTR);
			  WITH LATTR DO
			   BEGIN
			     IF (INDEXR>0) AND (INDEXR<=REGCMAX)
			     THEN
			       BEGIN
				MACRO(NO,201B%MOVEI\,INDEXR,INDBIT,INDEXR,DPLMT);
				LINDBIT := 1; LDPLMT := LC+ADDTOLC; LINDREG := BASIS ;
				MACRO4(202B%MOVEM\,INDEXR,BASIS,LDPLMT);
				ADDTOLC := ADDTOLC + 1 ;
			       END
			     ELSE
			       BEGIN
				LINDBIT := INDBIT; LINDREG := INDEXR; LDPLMT := DPLMT
			       END;
			    LRELBYTE:= VRELBYTE
			   END;
			  MACRO(LRELBYTE,202B%MOVEM\,LREGC,LINDBIT,LINDREG,LDPLMT);
			   IF LSY = TOSY
			   THEN LINSTR := 313B%CAMLE\
			   ELSE LINSTR := 315B%CAMGE\;
			  LADDR := IC;
			  MAKECODE(LINSTR,LREGC,GATTR) ;
			 END
		       ELSE ERROR(556)
		 END
	       ELSE ERRANDSKIP(251,FSYS OR [DOSY]);
	      MACRO3(254B%JRST\,0,0); LCIX :=CIX;
	       IF SY = DOSY
	       THEN INSYMBOL
	       ELSE ERROR(161);
	      LC := LC + ADDTOLC;
	       IF LC > LCMAX
	       THEN LCMAX:=LC;
	      STATEMENT(FSYS,STATENDS);
	      LC := LC - ADDTOLC;
	       IF LSY = TOSY
	       THEN LINSTR  := 350B%AOS\
	       ELSE LINSTR := 370B%SOS\;
	      MACRO(LRELBYTE,LINSTR,LREGC,LINDBIT,LINDREG,LDPLMT);
	      MACRO3R(254B%JRST\,0,LADDR); INSERTADDR(RIGHT,LCIX,IC)
	     END %FORSTATEMENT\ ;

	    PROCEDURE LOOPSTATEMENT;
	    VAR
	      LADDR: ADDRRANGE; LCIX: CODERANGE;
	     BEGIN
	      LADDR := IC;
	       LOOP
		 REPEAT
		  STATEMENT(FSYS OR [EXITSY],STATENDS OR [EXITSY])
		 UNTIL	NOT (SY IN STATBEGSYS);
	       EXIT IF SY # SEMICOLON;
		INSYMBOL
	       END;
	       IF SY = EXITSY
	       THEN
		 BEGIN
		  INSYMBOL;
		   IF SY = IFSY
		   THEN
		     BEGIN
		      INSYMBOL; EXPRESSION(FSYS OR [SEMICOLON,ENDSY],TRUEJMP);
		     END
		   ELSE ERRANDSKIP(162,FSYS OR [SEMICOLON,ENDSY]);
		  LCIX := CIX;
		   LOOP
		     REPEAT
		      STATEMENT(FSYS,STATENDS)
		     UNTIL  NOT (SY IN STATBEGSYS);
		   EXIT IF SY # SEMICOLON;
		    INSYMBOL
		   END;
		  MACRO3R(254B%JRST\,0,LADDR); INSERTADDR(RIGHT,LCIX,IC)
		 END
	       ELSE ERROR(165);
	       IF SY = ENDSY
	       THEN INSYMBOL
	       ELSE ERROR(163)
	     END %LOOPSTATEMENT\ ;

	    PROCEDURE WITHSTATEMENT;
	    VAR
	      LCP: CTP; OLDLC: ADDRRANGE; LCNT1: DISPRANGE; OLDREGC: ACRANGE;
	     BEGIN
	      LCNT1 := 0; OLDREGC := REGCMAX; OLDLC := LC;
	       LOOP
		 IF SY = IDENT
		 THEN
		   BEGIN
		    SEARCHID([VARS,FIELD],LCP); INSYMBOL
		   END
		 ELSE
		   BEGIN
		    ERROR(209); LCP := UVARPTR
		   END;
		SELECTOR(FSYS OR [COMMA,DOSY],LCP);
		 IF GATTR.TYPTR # NIL
		 THEN
		   IF GATTR.TYPTR^.FORM = RECORDS
		   THEN
		     IF TOP < DISPLIMIT
		     THEN
		       BEGIN
			TOP := TOP + 1; LCNT1 := LCNT1 + 1; WITHIX := WITHIX + 1;
			DISPLAY[TOP].FNAME := GATTR.TYPTR^.FSTFLD;
			WITH DISPLAY[TOP],GATTR DO
			 BEGIN
			  OCCUR := CREC;
(* 5 - create block name for CREF *)
			  BLKNAME := '.FIELDID. ';
			   IF INDBIT = 1
			   THEN GETPARADDR;
			  FETCHBASIS(GATTR);
			   IF (INDEXR#0) AND (INDEXR # BASIS)
			   THEN
			     BEGIN
			      MACRO3(200B%MOVE\,REGCMAX,INDEXR);
			      INDEXR := REGCMAX;
			      REGCMAX := REGCMAX-1;
			       IF REGCMAX<REGC
			       THEN
				 BEGIN
				  ERROR(317);
				  REGC := REGCMAX
				 END
			     END;
			  CLEV := VLEVEL; CRELBYTE := VRELBYTE;
			  CINDR := INDEXR; CINDB:=INDBIT;
			  CDSPL := DPLMT;
			  CLC := LC;
			   IF (CINDR#0)  AND  (CINDR#BASIS)
			   THEN
			     BEGIN
			      LC := LC + 1;
			       IF LC>LCMAX
			       THEN LCMAX := LC;
			     END
			 END
		       END
		     ELSE ERROR(404)
		   ELSE ERROR(308);
	       EXIT IF SY # COMMA;
		INSYMBOL
	       END;
	       IF SY = DOSY
	       THEN INSYMBOL
	       ELSE ERROR(161);
	      STATEMENT(FSYS,STATENDS);
	      REGCMAX:=OLDREGC;
	      TOP := TOP - LCNT1; LC := OLDLC; WITHIX := WITHIX - LCNT1;
	     END %WITHSTATEMENT\ ;

	   BEGIN
	    %STATEMENT\
	     IF SY = INTCONST
	     THEN %LABEL\
	       BEGIN
(* 64 - non-loc gotos *)
		prterr := false;
		searchid([labelt],lcp);
		prterr := true;
		if lcp # nil
		  then with lcp^ do
		    if scope = level
		      then labeladdress := ic;
		FOR IX:=1 TO LIX DO
		 BEGIN
		  WITH LABELS[IX] DO
		   IF LABSVAL = VAL.IVAL
		   THEN
		     BEGIN
		      ERROR(211);
		      GOTO 1
		     END
		 END;
		LIX := LIX+1;
		 IF LIX > LABMAX
		 THEN
		   BEGIN
		    ERROR(362);
		    LIX:=LABMAX
		   END;
		WITH LABELS[LIX] DO
		 BEGIN
		  LABSVAL:=VAL.IVAL;
		  LABSADDR:=IC
		 END;
		FOR IX:=1 TO JIX DO
		 BEGIN
		  WITH GOTOS[IX] DO
		   IF GOTOVAL = VAL.IVAL
		   THEN
		     BEGIN
		      J:=CODE.INSTRUCTION[GOTOADDR].ADDRESS;
		      INSERTADDR(RIGHT,GOTOADDR,IC);
		      WHILE J#0 DO
		       BEGIN
			GOTOADDR:=J;
			J:=CODE.INSTRUCTION[GOTOADDR].ADDRESS;
			INSERTADDR(RIGHT,GOTOADDR,IC)
		       END;
		      GOTOVAL:=-1;
		      GOTO 1
		     END
		 END;
1:
		INSYMBOL;
		 IF SY = COLON
		 THEN INSYMBOL
		 ELSE ERROR(151)
	       END;
	     IF DEBUG AND NOT INITGLOBALS
	     THEN PUTLINER;
	     IF  NOT (SY IN FSYS OR [IDENT])
	     THEN ERRANDSKIP(166,FSYS);
	     IF SY IN STATBEGSYS OR [IDENT]
	     THEN
	       BEGIN
		REGC:=REGIN ;
		 IF INITGLOBALS AND (SY # IDENT)
		 THEN ERROR(462)
		 ELSE
		   CASE SY OF
		    IDENT:
			   BEGIN
			    SEARCHID([VARS,FIELD,FUNC,PROC],LCP); INSYMBOL;
			     IF LCP^.KLASS = PROC
			     THEN
			       IF INITGLOBALS
			       THEN ERROR(462)
			       ELSE CALL(FSYS,LCP)
			     ELSE ASSIGNMENT(LCP)
			   END;
		    BEGINSY:
			     BEGIN
			      INSYMBOL; COMPOUNDSTATEMENT
			     END;
		    GOTOSY:
			    BEGIN
			     INSYMBOL; GOTOSTATEMENT
			    END;
		    IFSY:
			  BEGIN
			   INSYMBOL; IFSTATEMENT
			  END;
		    CASESY:
			    BEGIN
			     INSYMBOL; CASESTATEMENT
			    END;
		    WHILESY:
			     BEGIN
			      INSYMBOL; WHILESTATEMENT
			     END;
		    REPEATSY:
			      BEGIN
			       INSYMBOL; REPEATSTATEMENT
			      END;
		    LOOPSY:
			    BEGIN
			     INSYMBOL; LOOPSTATEMENT
			    END;
		    FORSY:
			   BEGIN
			    INSYMBOL; FORSTATEMENT
			   END;
		    WITHSY:
			    BEGIN
			     INSYMBOL; WITHSTATEMENT
			    END
		   END;
		SKIPIFERR(STATENDS,506,FSYS)
	       END;
	    REGC := REGIN  %RE-INITIALIZE REGISTER COUNTER TO AVOID OVERFLOW DURING SUBSEQUENT
			    EXPRESSION EVALUATIONS IN REPEATSTATEMENT OR LOOPSTATEMENT \  ;
	   END %STATEMENT\ ;

	 BEGIN
	  %BODY\
	  LIX:=0;JIX:=0;REGCMAX:=WITHIN;WITHIX := -1; FIRSTKONST := NIL;
(* 164 - Polish fixups for CASE *)
	  FIRSTPOL := NIL;
	   IF NOT ENTRYDONE
	   THEN
	     BEGIN
	      ENTRYDONE:= TRUE;
	      WRITEMC(WRITEENTRY);
	      WRITEMC(WRITENAME);
	      WRITEMC(WRITEHISEG)
	     END;
	  CIX := -1 ;
	   IF INITGLOBALS
	   THEN
	     BEGIN
	      CGLOBPTR := NIL ;
	       LOOP
		 IF SY # ENDSY
		 THEN STATEMENT([SEMICOLON,ENDSY],[SEMICOLON,ENDSY]) ;
	       EXIT IF	SY # SEMICOLON ;
		INSYMBOL
	       END ;
	       IF SY = ENDSY
	       THEN INSYMBOL
	       ELSE ERROR(163) ;
	      WRITEMC(WRITEGLOBALS)
	     END
	   ELSE
	     BEGIN
	      %BODY PROPER\
	      ENTERBODY;
	       IF FPROCP # NIL
(* 40 - fix print format *)
	       THEN FPROCP^.PFADDR:= PFSTART
	       ELSE LC:= 1;
	      LCMAX:=LC;
(* 54 - keep track of how many loc's above stack are used *)
	      STKOFFMAX := 0;
	      STKOFF := 0;
	       IF MAIN OR (LEVEL > 1)
	       THEN
		 BEGIN
		   LOOP
		     REPEAT
		      STATEMENT(FSYS OR [SEMICOLON,ENDSY],[SEMICOLON,ENDSY])
		     UNTIL  NOT (SY IN STATBEGSYS);
		   EXIT IF SY # SEMICOLON;
		    INSYMBOL
		   END;
		   IF SY = ENDSY
		   THEN INSYMBOL
		   ELSE ERROR(163);
		  FOR IX:=1 TO JIX DO %TEST ON UNDEFINED LABELS\
		   BEGIN
		    WITH GOTOS[IX] DO
		     IF GOTOVAL # -1
		     THEN
		       BEGIN
			ERROR(215);
			NEWZ(ERRMPTR1,D);
			WITH ERRMPTR1^ DO
			 BEGIN
			  NUMBER := 215; INTVAL := GOTOVAL; NEXT := ERRMPTR
			 END;
			ERRMPTR := ERRMPTR1;
		       END
		   END

		    %	 WHILE FSTEXP # FEXP DO %TEST ON UNDEFINED EXIT LABELS\

		 END;

	      LEAVEBODY;
	       IF MAIN OR (LEVEL > 1)
(* 53 - allocate core for loc's above stack *)
	       then
		 begin
(* 104 - check for overflow of address space *)
		 if lcmax > 377777B (* else adjsp will see it negative *)
		   then error(266);
(* 62 - clean up stack offsets *)
		 if fprocp # nil
		   then insertaddr(no,insertsize,lcmax-fprocp^.poffset)
		   else insertaddr(no,insertsize,lcmax);  %below the stack\
(* 57 - coralloc only needed for tops10 *)
		 if tops10
		   then insertaddr(no,coralloc,stkoffmax+40B); %above the stack\
		 end;
	      WRITEMC(WRITECODE);
(* 40 - fix print format *)
	      if fprocp # nil
	        then writemc(writeblk);
(* 64 - Polish fixups for CASE *)
	      if firstpol # NIL
		then writemc(writepolish);
	       IF FIRSTKONST # NIL
	       THEN WRITEMC(WRITEINTERNALS)
	       ELSE
		 IF LOCALPFPTR # NIL
		 THEN
		   IF LOCALPFPTR^.PFLEV = LEVEL
		   THEN WRITEMC(WRITEINTERNALS)
(* 114 - ALWAYS WRITE INTERNALS IF REF TO NON-LOC GOTO *)
		   ELSE IF LASTLABEL # NIL
		     THEN IF LASTLABEL^.SCOPE = LEVEL
			THEN WRITEMC(WRITEINTERNALS)
			ELSE
		     ELSE
	 	 ELSE  IF LASTLABEL # NIL
		   THEN IF LASTLABEL^.SCOPE = LEVEL
		     THEN WRITEMC(WRITEINTERNALS);
	       IF LEVEL = 1
	       THEN
		 BEGIN
		  WRITEMC(WRITESYMBOLS);
		  WRITEMC(WRITELIBRARY);
		  WRITEMC(WRITESTART);
		  WRITEMC(WRITEEND)
		 END
	     END % BODY PROPER\
	 END %BODY\ ;

(* 56 - PROCEDURES FOR FILE SWITCHING *)
	PROCEDURE OPENALT;
	  BEGIN
	  REQFILE := TRUE;
(* 136 - listing format *)
	  ORIGPAGECNT := PAGECNT; ORIGSUBPAGE := SUBPAGE; ORIGLINENR := LINENR;
	  ORIGPAGE := PAGER; ORIGLINECNT := LINECNT; ORIGCH := CH;
	  ENDSTUFF;
	  PUSHF(INPUT,VAL.VALP^.SVAL,VAL.VALP^.SLGTH);
(* 107 - error check openning of subfile *)
	  if eof
	    then begin (* nb: on the 20, analys does not show the file name in most cases *)
(* 136 - LISTING FORMAT *)
	    write('Failure to open INCLUDEd file: ',val.valp^.sval:val.valp^.slgth);
	    NEWLINE;
	    writeln(tty,'Failure to open INCLUDEd file: ',val.valp^.sval:val.valp^.slgth);
	    analys(input); writeln(tty);
	    rewrite(outputrel);
(* 112 - clrbfi when error *)
	    clribf;
(* 123 - restore input so close gets done by pasxit *)
	    close(input);
	    popf(input);
	    pasxit(input,output,outputrel)
	    end;
(* 136 - listing format *)
	  PAGECNT := 1; SUBPAGE := 0; LINECNT := 1; CH := ' ';
	  READLN;  {because pushf does an interactive open}
	  GETLINENR(LINENR);
	  pagehead;
	  WRITE(VAL.VALP^.SVAL:VAL.VALP^.SLGTH);
	  newline; newline;
	  BEGSTUFF
	  END;

	PROCEDURE CLOSEALT;
	  BEGIN
	  ENDSTUFF;
	  POPF(INPUT);
(* 136 - listing format *)
	  PAGECNT := ORIGPAGECNT; SUBPAGE := ORIGSUBPAGE + 1;
	  pagehead;
	  write('Main file continued'); newline; newline;
	  LINENR := ORIGLINENR; CH := ORIGCH;
	  PAGER := ORIGPAGE; LINECNT := ORIGLINECNT;
	  BEGSTUFF
	  END;

	PROCEDURE INCLUSION;
	  BEGIN
	  IF NOT (SY = STRINGCONST)
	    THEN BEGIN ERROR(212); REQFILE := FALSE END
	    ELSE BEGIN
	      OPENALT;
	      INSYMBOL
	      END
	  END;


       BEGIN
	%BLOCK\
	MARK(HEAPMARK);
(* 24 - testpacked no longer needed *)
(* 55 - ALL 55 PATCHES ARE FOR REQUIRE FILES - INITIALIZE REQFILE *)
(* 65 - remove exit labels *)
(* 125 - reqfile init moved *)
(* 173 - internal files *)
	FILEINBLOCK[LEVEL] := FALSE;
	DP := TRUE; FORWPTR := NIL; 
	 REPEAT
(* 23 - be sure LCPAR is set even when no VAR part *)
	  LCPAR := LC;
(* 56 - INCLUDE SYNTAX *)
(* 126 - turn while into repeat for better to force check for BEGIN *)
	  REPEAT
(* 56 - SCAN REQUIRE FILE SYNTAX *)
	   IF (SY=INCLUDESY) OR REQFILE
	     THEN BEGIN
	     INSYMBOL;
	     INCLUSION;
	     END;
(* 55 - LABELS NOT LEGAL IN REQUIRE FILE *)
	     IF (SY = LABELSY) AND NOT REQFILE
	     THEN
	       BEGIN
		INSYMBOL; LABELDECLARATION
	       END;
	     IF SY = CONSTSY
	     THEN
	       BEGIN
		INSYMBOL; CONSTANTDECLARATION
	       END;
	     IF SY = TYPESY
	     THEN
	       BEGIN
		INSYMBOL; TYPEDECLARATION
	       END;
(* 55 - NO VARIABLES OR INITPROC'S IN REQUIRE FILE *)
	    IF NOT REQFILE THEN BEGIN
	    LCPAR := LC;
	     IF SY = VARSY
	     THEN
	       BEGIN
		INSYMBOL; VARIABLEDECLARATION
	       END;
(* 167 - resolve fwd type ref's *)
{Note that FWDRESOLVE must be called after the VAR section because
 ^FOO in the VAR section is treated as a forward reference to FOO.
 We can't resolve this until after the end of the var section, 
 since otherwise we might accept ^FOO where FOO is a type in an
 outer block, but a local variable in the current block.  This seems
 to be illegal}
	    FWDRESOLVE;
(* 124 - detect initproc's when not at level 1 *)
	     WHILE SY = INITPROCSY DO
		 BEGIN
		  IF LEVEL # 1
		    THEN ERROR(557);
		  INSYMBOL ;
		   IF SY # SEMICOLON
		   THEN ERRANDSKIP(156,[BEGINSY])
		   ELSE INSYMBOL ;
		   IF SY = BEGINSY
		   THEN
		     BEGIN
		      MARK(GLOBMARK) ; INITGLOBALS := TRUE ;
		      INSYMBOL ; BODY(FSYS OR [SEMICOLON,ENDSY]) ;
		       IF SY = SEMICOLON
		       THEN INSYMBOL
		       ELSE ERROR(166) ;
		      INITGLOBALS := FALSE ; RELEASE(GLOBMARK) ;
		     END
		   ELSE ERROR(201) ;
		 END ;
	     IF LEVEL=1
	     THEN
		LCMAIN := LC;
	    END;
	    WHILE SY IN [PROCEDURESY,FUNCTIONSY] DO
	     BEGIN
	      LSY := SY; INSYMBOL; PROCEDUREDECLARATION(LSY)
	     END;
	    WHILE FORWPTR # NIL DO
	    WITH FORWPTR^ DO
	     BEGIN
	       IF FORWDECL
	       THEN ERRORWITHTEXT(465,NAME);
	      FORWPTR := TESTFWDPTR
	     END;
(* 56 - REQ FILE ENDS IN PERIOD *)
	     IF (MAIN OR (LEVEL > 1)) AND NOT REQFILE
(* 126 - TWEAK ERROR RECOVER AGAIN *)
	     THEN BEGIN IF SY # BEGINSY THEN ERROR(201) END
(* 35 - fix error recovery, especially for /NOMAIN *)
		%This else is top level of /NOMAIN.  If anything is here
		 other than a period we have to turn on /MAIN, since otherwise
		 BODY will refuse to scan anything.\
	     ELSE IF SY # PERIOD
	       THEN BEGIN
	       ERROR(172);
(* 56 - DON'T SET MAIN TO TRUE IN REQ FILE *)
	        IF NOT REQFILE
		  THEN MAIN := TRUE
	       END;
(* 55 - CLOSE REQFILE *)
	   IF REQFILE
	     THEN BEGIN
(* 136 - listing format *)
	     REQFILE := FALSE;
	     CLOSEALT;
	     INSYMBOL;
	     IF SY = SEMICOLON
	       THEN INSYMBOL
	     ELSE IF SY = COMMA
	       THEN REQFILE := TRUE
	     ELSE
	       ERROR(166);
	     END;
(* 126 - make it an UNTIL to force always check for BEGIN, etc. *)
	   UNTIL NOT ( (SY IN BLOCKBEGSYS - [BEGINSY]) OR REQFILE);
	  DP := FALSE;
	     IF SY = BEGINSY
	     THEN INSYMBOL;
		%ELSE ERROR(201) REDUNDANT HERE - MSG PRINTED ABOVE\
	  BODY(FSYS OR [CASESY]);
	  SKIPIFERR(LEAVEBLOCKSYS,166,FSYS)
	 UNTIL SY IN LEAVEBLOCKSYS;
	RELEASE(HEAPMARK);
       END %BLOCK\ ;



      PROCEDURE ENTERSTDTYPES;
      VAR
	LBTP: BTP; LSP: STP;
       BEGIN
	%TYPE UNDERLIEING:\
	%*****************\

	NEWZ(INTPTR,SCALAR,STANDARD);	  %INTEGER\
	WITH INTPTR^ DO
	 BEGIN
	  SIZE := 1;BITSIZE := BITMAX; SELFSTP := NIL
	 END;
	NEWZ(REALPTR,SCALAR,STANDARD);	  %REAL\
	WITH REALPTR^ DO
	 BEGIN
	  SIZE := 1;BITSIZE := BITMAX; SELFSTP := NIL
	 END;
	NEWZ(CHARPTR,SCALAR,STANDARD);	  %CHAR\
	WITH CHARPTR^ DO
	 BEGIN
	  SIZE := 1;BITSIZE := 7; SELFSTP := NIL
	 END;
	NEWZ(BOOLPTR,SCALAR,DECLARED);	  %BOOLEAN\
	WITH BOOLPTR^ DO
	 BEGIN
	  SIZE := 1;BITSIZE := 1; SELFSTP := NIL
	 END;
	NEWZ(NILPTR,POINTER);		  %NIL\
	WITH NILPTR^ DO
	 BEGIN
	  ELTYPE := NIL; SIZE := 1; BITSIZE := 18; SELFSTP := NIL
	 END;
	NEWZ(TEXTPTR,FILES);					  %TEXT\
	WITH TEXTPTR^ DO
	 BEGIN
	  FILTYPE := CHARPTR; SIZE := SIZEOFFILEBLOCK + 1; BITSIZE := BITMAX;
	  FILEPF := FALSE; SELFSTP := NIL; HASFILE := TRUE;
	 END;
(* 15 - ALLOW "FILE" AS TYPE IN PROC DECL - ANY TYPE OF FILE *)
       NEWZ(ANYFILEPTR,FILES);
      WITH ANYFILEPTR^ DO
	BEGIN
	 FILTYPE := NIL; SIZE := SIZEOFFILEBLOCK + 1; BITSIZE := BITMAX;
	 FILEPF := FALSE; SELFSTP := NIL; HASFILE := TRUE;
	END;
	NEWZ(LSP,SUBRANGE);
	WITH LSP^ DO
	 BEGIN
	  RANGETYPE := INTPTR; MIN.IVAL := 1; MAX.IVAL := 9; SELFSTP := NIL
	 END;
	NEWZ(DATEPTR,ARRAYS);
	WITH DATEPTR^ DO
	 BEGIN
	  ARRAYPF := TRUE; ARRAYBPADDR := 0;
	  SELFSTP := NIL; AELTYPE := CHARPTR; INXTYPE := LSP;
	  SIZE := 2; BITSIZE := 36
	 END;
	NEWZ(LBTP,ARRAYY);
	WITH LBTP^, BYTE DO
	 BEGIN
	  SBITS := 7; PBITS := BITMAX; DUMMYBIT := 0;
	  IBIT := 0; IREG := TAC; RELADDR := 0;
	  LAST := LASTBTP; LASTBTP := LBTP; ARRAYSP := DATEPTR
	 END;
	NEWZ(LSP,SUBRANGE);
	WITH LSP^ DO
	 BEGIN
	  RANGETYPE := INTPTR; MIN.IVAL := 1; MAX.IVAL := ALFALENG; SELFSTP := NIL
	 END;
	NEWZ(ALFAPTR,ARRAYS);
	WITH ALFAPTR^ DO
	 BEGIN
	  ARRAYPF := TRUE; ARRAYBPADDR := 0;
	  SELFSTP := NIL; AELTYPE := CHARPTR; INXTYPE := LSP;
	  SIZE := 2; BITSIZE := 36
	 END;
(* 111 - STRING, POINTER *)
	NEWZ(STRINGPTR,ARRAYS);
	WITH STRINGPTR^ DO
	  BEGIN
	  ARRAYPF := TRUE; SELFSTP := NIL; AELTYPE := CHARPTR;
(* 161 - fix string and pointer *)
	  INXTYPE := NIL; SIZE := 2; BITSIZE := 36
	  END;
	NEWZ(POINTERPTR,POINTER);
	WITH POINTERPTR^ DO
	  BEGIN
(* 161 - fix string and pointer *)
	  ELTYPE := NIL; SIZE := 2; BITSIZE := 36; SELFSTP := NIL
	  END;
(* 202 - fix VAR POINTER *)
	NEWZ(POINTERREF,POINTER);
(* 203 - had done pointerref^ := pointerptr^ - This copied too much *)
	WITH POINTERREF^ DO
	  BEGIN
(* 161 - fix string and pointer *)
	  ELTYPE := NIL; SIZE := 2; BITSIZE := 36; SELFSTP := NIL
	  END;
	NEWZ(LBTP,ARRAYY);
	WITH LBTP^, BYTE DO
	 BEGIN
	  SBITS := 7; PBITS := BITMAX; DUMMYBIT := 0;
	  IBIT := 0; IREG := TAC; RELADDR := 0;
	  LAST := LASTBTP; LASTBTP := LBTP; ARRAYSP := ALFAPTR
	 END;
       END %ENTERSTDTYPES\ ;

      PROCEDURE ENTERSTDNAMES;
      VAR
	CP,CP1: CTP; I,J: INTEGER; LFILEPTR :FTP ;
       BEGIN
	%NAME:\
	%*****\

	NEWZ(CP,TYPES);						  %INTEGER\
	WITH CP^ DO
	 BEGIN
(* 116 - here and following: add next := nil for copyctp *)
	  NAME := 'INTEGER   '; IDTYPE := INTPTR; NEXT := NIL;
	 END;
	ENTERID(CP);
	NEWZ(CP,TYPES);						  %REAL\
	WITH CP^ DO
	 BEGIN
	  NAME := 'REAL      ';IDTYPE := REALPTR; NEXT := NIL;
	 END;
	ENTERID(CP);
	NEWZ(CP, TYPES); 					   %CHAR\
	WITH CP^ DO
	 BEGIN
	  NAME := 'CHAR      '; IDTYPE := CHARPTR; NEXT := NIL;
	 END;
	ENTERID(CP);
	NEWZ(CP,TYPES);						  %BOOLEAN\
	WITH CP^ DO
	 BEGIN
	  NAME := 'BOOLEAN   '; IDTYPE := BOOLPTR; NEXT := NIL;
	 END;
	ENTERID(CP);
	NEWZ(CP,TYPES);						  %TEXT\
	WITH CP^ DO
	 BEGIN
	  NAME := 'TEXT      '; IDTYPE := TEXTPTR; NEXT := NIL;
	 END;
	ENTERID(CP);
	NEWZ(CP,TYPES);
	WITH CP^ DO
	 BEGIN
	  NAME := 'ALFA      '; IDTYPE := ALFAPTR; NEXT := NIL;
	 END;
	ENTERID(CP);
(* 111 - STRING, POINTER *)
	NEWZ(CP,PARAMS);
	WITH CP^ DO
	  BEGIN
	  NAME := 'STRING    ';  IDTYPE := STRINGPTR; NEXT := NIL;
	  END;
	ENTERID(CP);
	NEWZ(CP,PARAMS);
	WITH CP^ DO
	  BEGIN
	  NAME := 'POINTER   ';  IDTYPE := POINTERPTR; NEXT := NIL;
	  END;
	ENTERID(CP);
	NEWZ(CP,KONST);						  %NIL\
	WITH CP^ DO
	 BEGIN
	  NAME := 'NIL       '; IDTYPE := NILPTR;
	  NEXT := NIL; VALUES.IVAL := 377777B;
	 END;
	ENTERID(CP);
	NEWZ(CP,KONST);						  %ALFALENG\
	WITH CP^ DO
	 BEGIN
	  NAME := 'ALFALENG  ';  IDTYPE := INTPTR;
	  NEXT := NIL; VALUES.IVAL := 10;
	 END;
	ENTERID(CP);
(* 112 - maxint *)
	newz(cp,konst);
	with cp^ do
	  begin
	  name := 'MAXINT    '; idtype := intptr;
	  next := nil; values.ival := 377777777777B;
	  end;
	enterid(cp);
	CP1 := NIL;
	FOR I := 1 TO 2 DO
	 BEGIN
	  NEWZ(CP,KONST);				    %FALSE,TRUE\
	  WITH CP^ DO
	   BEGIN
	    NAME := NA[I]; IDTYPE := BOOLPTR;
	    NEXT := CP1; VALUES.IVAL := I - 1;
	   END;
	  ENTERID(CP); CP1 := CP
	 END;
	BOOLPTR^.FCONST := CP;
	FOR I := 3 TO 6 DO
	 BEGIN
	  NEWZ(CP,VARS); 	    %INPUT,OUTPUT,TTY,TTYOUTPUT\
(* 171 - treat files as special *)
          case i of
	  3:infile := cp; 4:outfile := cp; 5:ttyfile := cp; 6:ttyoutfile := cp
	  end;
	  WITH CP^ DO
	   BEGIN
(* 173 - no channels any more *)
	    NAME := NA[I]; IDTYPE := TEXTPTR; CHANNEL := I-2;
	    VKIND := ACTUAL; NEXT := NIL; VLEV := 0;
	    VADDR:= LC;
	    LC := LC + 1 %BUFFERSIZE FOR TYPE CHAR\ + SIZEOFFILEBLOCK;
	    NEWZ(LFILEPTR) ;
	    WITH LFILEPTR^ DO
	     BEGIN
	      NEXTFTP := FILEPTR ;
	      FILEIDENT := CP ;
	     END ;
	    FILEPTR := LFILEPTR ;
	   END;
	  ENTERID(CP)
	 END;
	SFILEPTR := FILEPTR;	   %REMEMBER TOP OF STANDARD FILES\
(* 16 - ADD DATA AT ENTRY *)
	CCLSW := LC; LC := LC+5;
(* 66 - nonloc gotos *)
	globtopp := lc; lc:=lc+1; globbasis := lc; lc:=lc+1;
(* 61 - allow us to distinguish tops10 and tops20 specific ftns *)
	if tops10
	  then othermachine := t20name
	  else othermachine := t10name;

	% GET,GETLN,PUT,PUTLN,RESET,REWRITE,READ,READLN,
	 WRITE,WRITELN,PACK,UNPACK,NEW,MARK,RELEASE,GETLINR,
	 PUT8BITSTOTTY,PAGE\

	FOR I := 7 TO 25 DO
(* 61 - restrict tops10 and tops20 specific *)
	 if machna[i] # othermachine then
	 BEGIN
	  NEWZ(CP,PROC,STANDARD);
	  WITH CP^ DO
	   BEGIN
	    NAME := NA[I]; IDTYPE := NIL;
	    NEXT := NIL; KEY := I - 6;
	   END;

	  ENTERID(CP)
	 END;
(* 10 - ADD SETSTRING *)
(* 14 - AND OTHERS *)

(* 27 - add NEWZ *)
(* 61 - restrict tops10 and tops20 defn's *)
(* 152 - DISPOSE *)
	FOR I := 54 TO 76 DO
	 if machna[i] # othermachine then
	 BEGIN
	  NEWZ(CP,PROC,STANDARD);
	  WITH CP^ DO
	   BEGIN
	    NAME := NA[I]; IDTYPE := NIL;
	    NEXT := NIL; KEY := I - 32;
	   END;

	 ENTERID(CP)
	END;

(* 44 - add curpos and its arg *)
        (* arg for CURPOS *)
	newz(cp1,vars);
	with cp1^ do
	  begin
	  name:='          ';idtype:=anyfileptr;
	  vkind:=formal;next:=nil;vlev:=1;vaddr:=2
	  end;

	(* CURPOS *)
(* 47 - more of this kind now *)
(* 61 - tops10 and tops20 specific functions *)
	FOR I:=77 TO 79 DO
	if machna[i] # othermachine then
	begin
	newz(cp,func,declared,actual);
	with cp^ do
	  begin
	  name := na[i]; idtype:=intptr; next:=cp1; forwdecl:=false;
	  externdecl := true; pflev:=0; pfaddr:=0; pfchain:=externpfptr;
	  externpfptr:=cp; for j:=0 to maxlevel do linkchain[j]:=0; externalname:=na[i];
	  language:=pascalsy
	  end;
	enterid(cp);
	end;

	NEWZ(CP,FUNC,DECLARED,ACTUAL);
	WITH CP^ DO
	 BEGIN
	  NAME := NA[26]; IDTYPE := DATEPTR; NEXT := NIL; FORWDECL := FALSE;
	  EXTERNDECL := TRUE; PFLEV := 0; PFADDR := 0; PFCHAIN := EXTERNPFPTR;
	  EXTERNPFPTR := CP; FOR I := 0 TO MAXLEVEL DO LINKCHAIN[I] := 0; EXTERNALNAME := NA[26];
	  LANGUAGE := FORTRANSY
	 END;
	ENTERID(CP);

	% RUNTIME,TIME,ABS,SQR,TRUNC,ODD,ORD,CHR,PRED,SUCC,EOF,EOLN \

	FOR I := 27 TO 38 DO
	 BEGIN
	  NEWZ(CP,FUNC,STANDARD);
	  WITH CP^ DO
	   BEGIN
	    NAME := NA[I]; IDTYPE := NIL;
	    NEXT := NIL; KEY := I - 26;
	   END;
	  ENTERID(CP)
	 END;

	FOR I := 80 TO 81 DO
	 BEGIN
	  NEWZ(CP,FUNC,STANDARD);
	  WITH CP^ DO
	   BEGIN
	    NAME := NA[I]; IDTYPE := NIL;
	    NEXT := NIL; KEY := I - 66;
	   END;
	  ENTERID(CP)
	 END;
	NEWZ(CP,VARS); %PARAMETER OF PREDECLARED FUNCTIONS\
	WITH CP^ DO
	 BEGIN
	  NAME := '          '; IDTYPE := REALPTR;
	  VKIND := ACTUAL; NEXT := NIL; VLEV := 1; VADDR := 2
	 END;

	% SIN,COS,EXP,SQRT,ALOG,ATAN,ALOG10,
	 SIND,COSD,SINH,COSH,TANH,ASIN,ACOS,RAN \

	FOR I := 39 TO 53 DO
	 BEGIN
	  NEWZ(CP1,FUNC,DECLARED,ACTUAL);
	  WITH CP1^ DO
	   BEGIN
	    NAME := NA[I]; IDTYPE := REALPTR; NEXT := CP;
	    FORWDECL := FALSE; EXTERNDECL := TRUE; PFLEV := 0; PFADDR := 0;
	    PFCHAIN:= EXTERNPFPTR; EXTERNPFPTR:= CP1; EXTERNALNAME := EXTNA[I];
	    FOR J := 0 TO MAXLEVEL DO LINKCHAIN[J] := 0; LANGUAGE := EXTLANGUAGE[I]
	   END;
	  ENTERID(CP1)
	 END;
	LCMAIN := LC;
       END %ENTERSTDNAMES\ ;

      PROCEDURE ENTERUNDECL;
      VAR
	I: INTEGER;
       BEGIN
	NEWZ(UTYPPTR,TYPES);
	WITH UTYPPTR^ DO
	 BEGIN
	  NAME := '          '; IDTYPE := NIL; NEXT := NIL;
	 END;
	NEWZ(UCSTPTR,KONST);
	WITH UCSTPTR^ DO
	 BEGIN
	  NAME := '          '; IDTYPE := NIL; NEXT := NIL;
	  VALUES.IVAL := 0
	 END;
	NEWZ(UVARPTR,VARS);
	WITH UVARPTR^ DO
	 BEGIN
	  NAME := '          '; IDTYPE := NIL; VKIND := ACTUAL;
	  NEXT := NIL; VLEV := 0; VADDR := 0
	 END;
(* 135 - UARRPTR is needed as dummy to prevent ill mem ref in PACK/UNPACK *)
	NEWZ(UARRTYP,ARRAYS);
	WITH UARRTYP^ DO
	  BEGIN
	  ARRAYPF := FALSE; SELFSTP := NIL; AELTYPE := NIL;
	  INXTYPE := NIL; SIZE := 777777B; BITSIZE := 36
	  END;
	NEWZ(UFLDPTR,FIELD);
	WITH UFLDPTR^ DO
	 BEGIN
	  NAME := '          '; IDTYPE := NIL; NEXT := NIL; FLDADDR := 0;
	  PACKF := NOTPACK
	 END;
	NEWZ(UPRCPTR,PROC,DECLARED,ACTUAL);
	WITH UPRCPTR^ DO
	 BEGIN
	  NAME := '          '; IDTYPE := NIL; FORWDECL := FALSE;
	  FOR I := 0 TO MAXLEVEL DO LINKCHAIN[I] := 0;
	  NEXT := NIL; EXTERNDECL := FALSE; PFLEV := 0; PFADDR := 0
	 END;
	NEWZ(UFCTPTR,FUNC,DECLARED,ACTUAL);
	WITH UFCTPTR^ DO
	 BEGIN
	  NAME := '          '; IDTYPE := NIL; NEXT := NIL;
	  FOR I := 0 TO MAXLEVEL DO LINKCHAIN[I] := 0;
	  FORWDECL := FALSE; EXTERNDECL := FALSE; PFLEV := 0; PFADDR := 0
	 END;
(* 64 - non-loc gotos *)
	newz(ulblptr,labelt);
	with ulblptr^ do
	  begin
	  name := '          '; idtype := nil; next := nil;
	  scope := 0; gotochain := 0; labeladdress := 0;
	  end;
       END %ENTERUNDECL\ ;

      PROCEDURE ENTERDEBNAMES;
      VAR
	CP:CTP;
       BEGIN
	NEWZ(CP,PROC,STANDARD);
	WITH CP^ DO
	 BEGIN
	  NAME := 'PROTECTION';
	  IDTYPE := NIL; NEXT := NIL; KEY:= 21
	 END;
	ENTERID(CP);
       END;

(* 4 - replace file name scanner with call to SCAN *)
(* 11 - new definition of PASPRM *)
     FUNCTION PASPRM(VAR I,O:TEXT;VAR R:INTFILE):RPGPT; EXTERN;

(* 104 - improved error detection in tops10 *)
(* 107 - moved declaration of analys earlier *)

     BEGIN
      %ENTER STANDARD NAMES AND STANDARD TYPES:\
      %****************************************\

(* 41 - make restartable *)
      reinit;

      RTIME := RUNTIME; DAY := DATE;
      LEVEL := 0; TOP := 0;
      WITH DISPLAY[0] DO
       BEGIN
(* 5 - create block name for CREF *)
	FNAME := NIL; OCCUR := BLCK; BLKNAME := '.PREDEFIN.';
       END;
      ENTERSTDTYPES; ENTERSTDNAMES; ENTERUNDECL; ENTERDEBNAMES;

      TOP := 1; LEVEL := 1;
      WITH DISPLAY[1] DO
       BEGIN
(* 5 - create block name for CREF *)
	FNAME := NIL; OCCUR := BLCK; BLKNAME := '.GLOBAL.  ';
       END;

      %OPEN COMPILER FILES\
      %*******************\

(* 4 - here we open the files that SCAN gave us *)
      REWRITE(TTYOUTPUT);
      SCANDATA := PASPRM(INPUT,OUTPUT,OUTPUTREL);
      WITH SCANDATA ^ DO
       BEGIN
(* 33 - VERSION NO *)
       VERSION.WORD := VERVAL;
(* I haven't figured out what to do about lookup blocks.  Commented out for now *)
(* 104 - fix error detection on tops10 *)
       if tops10 
         then reset(input%,'',true,lookblock,40000B,4000B\)  {tag for SOS}
 	 else reset(input,'',0,0,0,20B);  {see EOL char's}
       %if eof		{tag for SOS}
	 then begin
	 analys(input);
	 pasxit(input,output,outputrel);
	 end;
       get(input);\		     {tag for SOS}
       IF VERSION.WORD = 0 THEN VERSION.WORD := LOOKBLOCK[6];
       LOOKBLOCK[6] := VERSION.WORD;
       FOR I := 1 TO 5 DO LOOKBLOCK[I] := 0;
       REWRITE(OUTPUT%,'',0,LOOKBLOCK\);  {tag for SOS}
       FOR I := 1 TO 5 DO LOOKBLOCK[I] := 0;
       REWRITE(OUTPUTREL%,'',0,LOOKBLOCK\);  {tag for SOS}
       FILENAME := RELNAME;
(* 34 - DON'T NEED ENTRY NOW *)
       IF FILENAME = '          '
         THEN FILENAME := '.NONAM    '; %A BLANK ENTRY NAME IS BAD NEWS\
       LISTCODE := LSW;
       TTYINUSE := TSW;
       MAIN := MSW;
       RUNTMCHECK := CSW;
(* 160 - compiler switch /ARITHCHECK *)
       ARITHCHECK := ASW;
       DEBUGSWITCH := DSW;
       CREF:=CRSW;
       DEBUG := DSW;
       RPGENTRY := RPGSW;
(* 7 - ADD /HEAP SWITCH *)
(* 12 - /heap no longer needed *)
(* 24 - /HEAP AND /STACK NOW USED FOR START ADDR *)
	
       HEAP := HEAPVAL;
       STACK := STACKVAL;
(* 25 - /ZERO *)
       ZERO := ZSW
       END;

      %WRITE HEADER\
      %************\

(* 136 - listing format *)
      pagehead;
      %NEW LINE FOR ERROR MESSAGES OR PROCEDURENAMES\
      GETNEXTLINE;     %GETS FIRST LINENUMBER IF ANY\
      CH := ' '; INSYMBOL; RESETFLAG := FALSE;
       IF NOT MAIN
       THEN
	 BEGIN
	  LC := PROGRST; LCMAIN := LC;
	  WHILE SFILEPTR # NIL DO
	  WITH SFILEPTR^, FILEIDENT^ DO
	   BEGIN
	    VADDR:= 0; SFILEPTR:= NEXTFTP
	   END;
	  SFILEPTR := FILEPTR;
	 END;

	%COMPILE:\
	%********\

(* 5 - CREF *)
      IF CREF
        THEN WRITE(CHR(15B),CHR(10),'.GLOBAL.  ');

      FOR I := 1 TO CHCNTMAX DO ERRLINE[I] := ' '; RELBLOCK.COUNT:= 0;
      FOR SUPPORTIX := FIRSTSUPPORT TO LASTSUPPORT DO RNTS.LINK[SUPPORTIX] := 0;

(* 6 - allow PROGRAM statement *)
      PROGSTAT;
(* 13 - PRINT HEADER NOW THAT HAD PROG STATEMENT SCANNED *)
      IF RPGENTRY
       THEN WRITELN(TTY,'PASCAL:',CHR(11B),FILENAME:6);
(* 41 - Don't print header *)
(* 26 - break not needed for TTY *)
      BLOCK(NIL,BLOCKBEGSYS OR STATBEGSYS-[CASESY],[PERIOD]);

(* 104 - detect programs that don't fit in address space *)
      if (highestcode > 777777B) or (lcmain > 377777B)
	then error(266);

(* 5 - CREF *)
      IF CREF
        THEN WRITE(CHR(16B),CHR(10),'.GLOBAL.  ');

(* 16 - EOF *)
      ENDOFLINE(TRUE);
(* 5 - CREF *)
      if cref and not eof(input)
	then write(chr(177B),'A'); %balances <ro>B from ENDOFLINE\
(* 136 - LISTING FORMAT *)
      NEWLINE ; NEWLINE ;
       IF NOT ERRORFLAG
       THEN
	 BEGIN
(* 4 - Make us look normal if called by COMPIL *)
	  WRITE('No ') ; IF NOT RPGENTRY THEN WRITE(TTY,'No ')
	 END
       ELSE WRITE(TTY,'?');
(* 136 - LISTING FORMAT *)
      WRITE('error detected') ; NEWLINE;
      IF (NOT RPGENTRY) OR ERRORFLAG 
        THEN
(* 26 - break not needed for TTY *)
          WRITELN(TTY,'error detected');
       IF ERRORFLAG
(* 112 - clrbfi when error *)
	THEN BEGIN
	REWRITE(OUTPUTREL);
        clribf;
        end
       ELSE IF NOT RPGENTRY THEN
	 BEGIN
(* 136 - LISTING FORMAT *)
	  WRITELN(TTY); NEWLINE;
	  I := (HIGHESTCODE - 400000B + 1023) DIV 1024;
	  WRITELN(TTY,'Highseg: ',I:3,'K'); WRITELN('Highseg: ',I:3,'K');
	  I := (LCMAIN + 1023) DIV 1024;
	  WRITELN(TTY,'Lowseg : ',I:3,'K'); WRITELN('Lowseg : ',I:3,'K');
	 END;
(* 4 - Make us look normal if called by COMPIL *)
      IF  NOT RPGENTRY THEN BEGIN
      RTIME := RUNTIME - RTIME;
      WRITE(TTY,'Runtime: ',(RTIME DIV 60000):3,':');
      RTIME := RTIME MOD 60000;
      WRITE(TTY,(RTIME DIV 1000):2,'.');
      RTIME := RTIME MOD 1000;
      WRITELN(TTY,RTIME:3)
(* 4 - get back to SCAN if appropriate *)
      END;
     PASXIT(INPUT,OUTPUT,OUTPUTREL)
     END.