Trailing-Edge
-
PDP-10 Archives
-
BB-L014B-BM
-
autopatch/macsym.mac
There are 70 other files named macsym.mac in the archive.  Click here to see a list.
; UPD ID= 422, FARK:<4-WORKING-SOURCES.UTILITIES>MACSYM.MAC.2,  27-Mar-81 14:35:22 by HUIZENGA
;tco 5.1275 - Explicitly define absolute value of .JBVER as octal.
;<4.UTILITIES>MACSYM.MAC.31,  3-Jan-80 15:25:55, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
;<4.UTILITIES>MACSYM.MAC.30, 12-Nov-79 08:41:36, EDIT BY OSMAN
;MORE 4.2570 - Purge ..v1 and ..v22 after using them in macro
;<4.UTILITIES>MACSYM.MAC.29, 12-Nov-79 08:31:03, EDIT BY OSMAN
;MORE 4.2570 - Change V22 to ..V22
;<4.UTILITIES>MACSYM.MAC.28,  9-Nov-79 13:55:55, EDIT BY OSMAN
;<4.1.UTILITIES>MACSYM.MAC.3,  9-Nov-79 13:55:33, EDIT BY OSMAN
;tco 4.2570 - Change V1 to ..V1
;<4.UTILITIES>MACSYM.MAC.27, 19-Oct-79 13:39:11, EDIT BY ZIMA
;TCO 4.2536 - Make JSMSG0 external to prevent "undefined" errors
;  from MACRO when attempting to use PERSTR macro.
;<4.UTILITIES>MACSYM.MAC.19,  2-Oct-79 15:05:45, EDIT BY OSMAN
;tco 4.2506 - allow BRKCH. ","
;<4.UTILITIES>MACSYM.MAC.18, 21-Sep-79 15:37:58, EDIT BY ENGEL
;UNDO MAKING RETSKP AN OPDEF
;<4.UTILITIES>MACSYM.MAC.17, 11-Sep-79 07:17:32, EDIT BY R.ACE
;TCO 4.2453 - PREFIX "symbol IS NOT DEFINED" WITH A QUESTION MARK
;<4.UTILITIES>MACSYM.MAC.16, 19-Aug-79 20:35:06, EDIT BY GILBERT
;MAKE RETSKP, JSHLT, ETC. OPDEFS FOR DDT TYPEOUT.
;<4.UTILITIES>MACSYM.MAC.15, 22-Jun-79 07:16:13, EDIT BY R.ACE
;TCO 4.2307 - CHANGE FLDDB. TO USE 0,,LST INSTEAD OF Z LST
;<4.UTILITIES>MACSYM.MAC.14, 10-Mar-79 14:01:35, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.UTILITIES>MACSYM.MAC.13,  8-Feb-79 16:46:30, EDIT BY KIRSCHEN
;ADD ENTRY DECLARATION FOR .STKST FOR LIBRARY SEARCHING
;<4.UTILITIES>MACSYM.MAC.12,  6-Feb-79 10:59:13, EDIT BY GILBERT
;REPLACE XMOVEI -- MACRO DOESN'T KNOW ABOUT IT
;<4.UTILITIES>MACSYM.MAC.11,  5-Feb-79 00:51:10, EDIT BY GILBERT
;Remove extended addressing OPDEFs now in MACRO, change XBLT MACRO
;  to XBLT. to avoid conflict with MACRO's definition of 020000,,0.
;<4.UTILITIES>MACSYM.MAC.10, 22-Jan-79 16:29:04, EDIT BY DNEFF
;Make POINTR macro take addresses with indexing again.
;<4.UTILITIES>MACSYM.MAC.9, 22-Jan-79 13:31:23, EDIT BY DBELL
;MAKE POINTR, FLD, .RTJST, MASKB, AND MOD. IMMUNE TO STRANGE ARGUMENTS
;<4.UTILITIES>MACSYM.MAC.8, 25-Oct-78 12:22:59, EDIT BY GILBERT
;Suppress CALLRET to DDT typeout.
;<4.UTILITIES>MACSYM.MAC.7, 12-Sep-78 15:52:12, EDIT BY OSMAN
;FIX FLDBK.
;<4.UTILITIES>MACSYM.MAC.4,  6-Sep-78 16:51:29, EDIT BY OSMAN
;ADD FLDDB. AND FLDBK.
;<4.UTILITIES>MACSYM.MAC.3,  6-Sep-78 16:28:36, EDIT BY OSMAN
;CHANGE BREAK SET MACROS TO HAVE DOTS IN THEM.   ADD BRMSK.
;<4.UTILITIES>MACSYM.MAC.2,  3-Sep-78 12:35:16, EDIT BY OSMAN
;ADD MACROS FOR DEFINING 128-BIT CHARACTER BREAK MASKS
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;VERSION 1
IFNDEF REL,<REL==0>		;UNIVERSAL UNLESS OTHERWISE DECLARED
   IFE REL,<
	UNIVERSAL MACSYM	COMMON MACROS AND SYMBOLS
   >
   IFN REL,<
	TITLE MACREL		SUPPORT CODE FOR MACSYM
	SEARCH MONSYM
	SALL
	IFNDEF .PSECT,<
	.DIRECT .XTABM>
   >
;THE STANDARD VERSION WORD CONSTRUCTION
; VERS - PROGRAM VERSION NUMBER
; VUPDAT - PROGRAM UPDATE NUMBER (1=A, 2=B ...)
; VEDIT - PROGRAM EDIT NUMBER
; VCUST - CUSTOMER EDIT CODE (0=DEC DEVELOPMENT, 1=DEC SWS, 2-7 CUST)
;**;[Tco 5.1275] Change 1 line at PGVER.+2L	BAH	27-MAR-81
DEFINE PGVER.	(VERS,VUPDAT,VEDIT,VCUST)<
	..PGV0==.		;;SAVE CURRECT LOCATION AND MODE
	.JBVER=:^O137		;;[Tco 5.1275]WHERE TO PUT VERSION
	LOC	.JBVER		;;PUT VERSION IN STANDARD PLACE
	BYTE	(3)VCUST(9)VERS(6)VUPDAT(18)VEDIT
	.ORG	..PGV0		;;RESTORE LOCATION AND MODE
>
;MASKS FOR THE ABOVE
VI%WHO==:7B2			;Customer edit code
VI%MAJ==:777B11			;Major version number
VI%MIN==:77B17			;Minor version/update
VI%EDN==:777777B35		;Edit number
;ADDED VI%XXX
	SUBTTL MISC CONSTANTS
;MISC CONSTANTS
.INFIN==:377777,,777777		;PLUS INFINITY
.MINFI==:1B0			;MINUS INFINITY
.LHALF==:777777B17		;LEFT HALF
.RHALF==:777777			;RIGHT HALF
.FWORD==:-1			;FULL WORD
	SUBTTL	SYMBOLS FOR THE CONTROL CHARACTERS
.CHNUL==:000			;NULL
.CHCNA==:001
.CHCNB==:002
.CHCNC==:003
.CHCND==:004
.CHCNE==:005
.CHCNF==:006
.CHBEL==:007			;BELL
.CHBSP==:010			;BACKSPACE
.CHTAB==:011			;TAB
.CHLFD==:012			;LINE-FEED
.CHVTB==:013			;VERTICAL TAB
.CHFFD==:014			;FORM FEED
.CHCRT==:015			;CARRIAGE RETURN
.CHCNN==:016
.CHCNO==:017
.CHCNP==:020
.CHCNQ==:021
.CHCNR==:022
.CHCNS==:023
.CHCNT==:024
.CHCNU==:025
.CHCNV==:026
.CHCNW==:027
.CHCNX==:030
.CHCNY==:031
.CHCNZ==:032
.CHESC==:033			;ESCAPE
.CHCBS==:034			;CONTROL BACK SLASH
.CHCRB==:035			;CONTROL RIGHT BRACKET
.CHCCF==:036			;CONTROL CIRCONFLEX
.CHCUN==:037			;CONTROL UNDERLINE
.CHALT==:175			;OLD ALTMODE
.CHAL2==:176			;ALTERNATE OLD ALTMODE
.CHDEL==:177			;DELETE
	SUBTTL	HARDWARE BITS OF INTEREST TO USERS
;PC FLAGS
PC%OVF==:1B0			;OVERFLOW
PC%CY0==:1B1			;CARRY 0
PC%CY1==:1B2			;CARRY 1
PC%FOV==:1B3			;FLOATING OVERFLOW
PC%BIS==:1B4			;BYTE INCREMENT SUPPRESSION
PC%USR==:1B5			;USER MODE
PC%UIO==:1B6			;USER IOT MODE
PC%LIP==:1B7			;LAST INSTRUCTION PUBLIC
PC%AFI==:1B8			;ADDRESS FAILURE INHIBIT
PC%ATN==:3B10			;APR TRAP NUMBER
PC%FUF==:1B11			;FLOATING UNDERFLOW
PC%NDV==:1B12			;NO DIVIDE
	SUBTTL	MACROS FOR FIELD MASKS
;STANDARD MACROS
;MACROS TO HANDLE FIELD MASKS
;COMPUTE LENGTH OF MASK, I.E. LENGTH OF LEFTMOST STRING OF ONES
;REMEMBER THAT ^L DOES 'JFFO', I.E. HAS VALUE OF FIRST ONE BIT IN WORD
;COMPUTE WIDTH OF MASK, I.E. LENGTH OF LEFTMOST STRING OF ONES
DEFINE WID(MASK)<<^L<-<<MASK>_<^L<MASK>>>-1>>>
;COMPUTE POSITION OF MASK, I.E. BIT POSITION OF RIGHTMOST ONE IN MASK
DEFINE POS(MASK)<<^L<<MASK>&<-<MASK>>>>>
;CONSTRUCT BYTE POINTER TO MASK
DEFINE POINTR(LOC,MASK)<<POINT WID(MASK),LOC,POS(MASK)>>
;PUT RIGHT-JUSTIFIED VALUE INTO FIELD SPECIFIED BY MASK
DEFINE FLD(VAL,MSK)<<<<VAL>B<POS(MSK)>>&<MSK>>>
;MAKE VALUE BE RIGHT JUSTIFIED IN WORD.
DEFINE .RTJST(VAL,MSK)<<<<VAL>&<MSK>>B<^D70-POS(MSK)>>>
;CONSTRUCT MASK FROM BIT AA TO BIT BB. I.E. MASKB 0,8 = 777B8
DEFINE MASKB(AA,BB)<<1B<<AA>-1>-1B<BB>>>
;MODULE - GIVES REMAINDER OF DEND DIVIDED BY DSOR
DEFINE MOD.(DEND,DSOR)<<<DEND>-<<DEND>/<DSOR>>*<DSOR>>>
	SUBTTL MOVX
;MOVX - LOAD AC WITH CONSTANT
DEFINE MOVX (AC,MSK)<
   ..MX1==MSK			;;EVAL EXPRESSION IF ANY
IFDEF .PSECT,<
   .IFN ..MX1,ABSOLUTE,<
	MOVE AC,[MSK]>
   .IF ..MX1,ABSOLUTE,<
	..MX2==0		;;FLAG SAYS HAVEN'T DONE IT YET
	IFE <..MX1>B53,<
	  ..MX2==1
	  MOVEI AC,..MX1>	;;LH 0, DO AS RH
	IFE ..MX2,<		;;IF HAVEN'T DONE IT YET,
	IFE <..MX1>B17,<
	  ..MX2==1
	  MOVSI AC,(..MX1)>>	;;RH 0, DO AS LH
	IFE ..MX2,<		;;IF HAVEN'T DONE IT YET,
	IFE <<..MX1>B53-^O777777>,<
	  ..MX2==1
	  HRROI AC,<..MX1>>>	;;LH -1
	IFE ..MX2,<		;;IF HAVEN'T DONE IT YET,
	IFE <<..MX1>B17-^O777777B17>,<
	  ..MX2==1
	  HRLOI AC,(..MX1-^O777777)>> ;;RH -1
	IFE ..MX2,<		;;IF STILL HAVEN'T DONE IT,
	  MOVE AC,[..MX1]>	;;GIVE UP AND USE LITERAL
	>>
IFNDEF .PSECT,<
	..MX2==0		;;FLAG SAYS HAVEN'T DONE IT YET
	IFE <..MX1>B53,<
	  ..MX2==1
	  MOVEI AC,..MX1>	;;LH 0, DO AS RH
	IFE ..MX2,<		;;IF HAVEN'T DONE IT YET,
	IFE <..MX1>B17,<
	  ..MX2==1
	  MOVSI AC,(..MX1)>>	;;RH 0, DO AS LH
	IFE ..MX2,<		;;IF HAVEN'T DONE IT YET,
	IFE <<..MX1>B53-^O777777>,<
	  ..MX2==1
	  HRROI AC,<..MX1>>>	;;LH -1
	IFE ..MX2,<		;;IF HAVEN'T DONE IT YET,
	IFE <<..MX1>B17-^O777777B17>,<
	  ..MX2==1
	  HRLOI AC,(..MX1-^O777777)>> ;;RH -1
	IFE ..MX2,<		;;IF STILL HAVEN'T DONE IT,
	  MOVE AC,[..MX1]>	;;GIVE UP AND USE LITERAL
>
	PURGE ..MX1,..MX2>
;VARIENT MNEMONICS FOR TX DEFINITIONS
DEFINE IORX (AC,MSK)<
	TXO AC,<MSK>>
DEFINE ANDX (AC,MSK)<
	TXZ AC,<^-<MSK>>>
DEFINE XORX (AC,MSK)<
	TXC AC,<MSK>>
	SUBTTL TX -- TEST MASK
;CREATE THE TX MACRO DEFINITIONS
;THIS DOUBLE IRP CAUSES ALL COMBINATIONS OF MODIFICATION AND TESTING
;TO BE DEFINED
DEFINE ..DOTX (M,T)<
	IRP M,<
	IRP T,<
	  DEFINE TX'M'T (AC,MSK)<
		..TX(M'T,AC,<MSK>)>>>>
	..DOTX (<N,O,Z,C>,<,E,N,A>) ;DO ALL DEFINITIONS
	PURGE ..DOTX
;..TX
;ALL TX MACROS JUST CALL ..TX WHICH DOES ALL THE WORK
DEFINE ..TX(MT,AC,MSK)<
   ..TX1==MSK			;;EVAL EXPRESSION IF ANY
IFDEF .PSECT,<
   .IFN ..TX1,ABSOLUTE,<
	TD'MT AC,[MSK]>
   .IF ..TX1,ABSOLUTE,<		;;MASK MUST BE TESTABLE
	..TX2==0		;;FLAG SAYS HAVEN'T DONE IT YET
	IFE <..TX1&^O777777B17>,<
	  ..TX2==1		;;LH 0, DO AS RH
	  TR'MT AC,..TX1>
	IFE ..TX2,<		;;IF HAVEN'T DONE IT YET,
	IFE <..TX1&^O777777>,<
	  ..TX2==1		;;RH 0, DO AS LH
	  TL'MT AC,(..TX1)>>
	IFE ..TX2,<		;;IF HAVEN'T DONE IT YET,
	  IFE <<..TX1>B53-^O777777>,< ;;IF LH ALL ONES, 
	    ..TX3 (MT,AC)>>	;;TRY Z,O,C SPECIAL CASES
	IFE ..TX2,<		;;IF STILL HAVEN'T DONE IT,
	  TD'MT AC,[..TX1]>	;;MUST GIVE UP AND USE LITERAL
	PURGE ..TX1,..TX2>>
IFNDEF .PSECT,<
	..TX2==0		;;FLAG SAYS HAVEN'T DONE IT YET
	IFE <..TX1&^O777777B17>,<
	  ..TX2==1		;;LH 0, DO AS RH
	  TR'MT AC,..TX1>
	IFE ..TX2,<		;;IF HAVEN'T DONE IT YET,
	IFE <..TX1&^O777777>,<
	  ..TX2==1		;;RH 0, DO AS LH
	  TL'MT AC,(..TX1)>>
	IFE ..TX2,<		;;IF HAVEN'T DONE IT YET,
	  IFE <<..TX1>B53-^O777777>,< ;;IF LH ALL ONES, 
	    ..TX3 (MT,AC)>>	;;TRY Z,O,C SPECIAL CASES
	IFE ..TX2,<		;;IF STILL HAVEN'T DONE IT,
	  TD'MT AC,[..TX1]>	;;MUST GIVE UP AND USE LITERAL
	PURGE ..TX1,..TX2>>
;SPECIAL CASE FOR LH ALL ONES
DEFINE ..TX3 (MT,AC)<
	IFIDN <MT><Z>,<		;;IF ZEROING WANTED
	  ..TX2==1
	  ANDI AC,^-..TX1>	;;CAN DO IT WITH ANDI
	IFIDN <MT><O>,<		;;IF SET TO ONES WANTED
	  ..TX2==1
	  ORCMI AC,^-..TX1>	;;CAN DO IT WITH IORCM
	IFIDN <MT><C>,<		;;IF COMPLEMENT WANTED
	  ..TX2==1
	  EQVI AC,^-..TX1>>	;;CAN DO IT WITH EQV
	SUBTTL JX -- JUMP ON MASK
;JXE -- JUMP IF MASKED BITS ARE EQUAL TO 0
;JXN -- JUMP IF MASKED BITS ARE NOT EQUAL TO 0
;JXO -- JUMP IF MASKED BITS ARE ALL ONES
;JXF -- JUMP IF MASKED BITS ARE NOT ALL ONES (FALSE)
DEFINE JXE (AC,MSK,BA)<
	..JX1==MSK		;;EVAL EXPRESSION IF ANY
IFDEF .PSECT,<
	.IFN ..JX1,ABSOLUTE,<PRINTX MSK NOT ABSOLUTE
		..JX1==0>
	.IF ..JX1,ABSOLUTE,<
	.IF0 <<..JX1>-1B0>,<	;;IF MASK IS JUST B0,
		JUMPGE AC,BA>,<
	.IF0 <<..JX1>+1>,<	;;IF MASK IF FULL WORD,
	  JUMPE AC,BA>,<	;;USE GIVEN CONDITION
		TXNN (AC,..JX1)
		JRST BA>>>
	PURGE ..JX1>
IFNDEF .PSECT,<
	.IF0 <<..JX1>-1B0>,<	;;IF MASK IS JUST B0,
		JUMPGE AC,BA>,<
	.IF0 <<..JX1>+1>,<	;;IF MASK IF FULL WORD,
	  JUMPE AC,BA>,<	;;USE GIVEN CONDITION
		TXNN (AC,..JX1)
		JRST BA>>>
	PURGE ..JX1>
DEFINE JXN (AC,MSK,BA)<
	..JX1==MSK		;;EVAL EXPRESSION IF ANY
IFDEF .PSECT,<
	.IFN ..JX1,ABSOLUTE,<PRINTX MSK NOT ABSOLUTE
		..JX1==0>
	.IF ..JX1,ABSOLUTE,<
	.IF0 <<..JX1>-1B0>,<	;;IF MASK IS JUST B0,
		JUMPL AC,BA>,<
	.IF0 <<..JX1>+1>,<	;;IF MASK IF FULL WORD,
	  JUMPN AC,BA>,<	;;USE GIVEN CONDITION
		TXNE (AC,..JX1)
		JRST BA>>>
	PURGE ..JX1>
IFNDEF .PSECT,<
	.IF0 <<..JX1>-1B0>,<	;;IF MASK IS JUST B0,
		JUMPL AC,BA>,<
	.IF0 <<..JX1>+1>,<	;;IF MASK IF FULL WORD,
	  JUMPN AC,BA>,<	;;USE GIVEN CONDITION
		TXNE (AC,..JX1)
		JRST BA>>>
	PURGE ..JX1>
DEFINE JXO (AC,MSK,BA)<
	..JX1==MSK		;;EVAL EXPRESSION
IFDEF .PSECT,<
	.IFN ..JX1,ABSOLUTE,<PRINTX MSK NOT ABSOLUTE
		..JX1==0>
	.IF ..JX1,ABSOLUTE,<
	.IF0 <<..JX1>-1B0>,<
		JUMPL AC,BA>,<
	..ONEB (..BT,MSK)	;;TEST MASK FOR ONLY ONE BIT ON
	.IF0 ..BT,<
	  SETCM .SAC,AC		;;GENERAL CASE, GET COMPLEMENTS OF BITS
	  JXE (.SAC,..JX1,BA)>,< ;;JUMP IF BITS WERE ORIGINALLY ONES
	    TXNE AC,..JX1	;;TEST AND JUMP
	    JRST BA>>>
	PURGE ..JX1>
IFNDEF .PSECT,<
	.IF0 <<..JX1>-1B0>,<
		JUMPL AC,BA>,<
	..ONEB (..BT,MSK)	;;TEST MASK FOR ONLY ONE BIT ON
	.IF0 ..BT,<
	  SETCM .SAC,AC		;;GENERAL CASE, GET COMPLEMENTS OF BITS
	  JXE (.SAC,..JX1,BA)>,< ;;JUMP IF BITS WERE ORIGINALLY ONES
	    TXNE AC,..JX1	;;TEST AND JUMP
	    JRST BA>>>
	PURGE ..JX1>
DEFINE JXF (AC,MSK,BA)<
	..JX1==MSK		;;EVAL EXPRESSION
IFDEF .PSECT,<
	.IFN ..JX1,ABSOLUTE,<PRINTX MSK NOT ABSOLUTE
		..JX1==0>
	.IF ..JX1,ABSOLUTE,<
	.IF0 <<..JX1>-1B0>,<
		JUMPGE AC,BA>,<
	..ONEB (..BT,MSK)	;;TEST MASK FOR ONLY ONE BIT ON
	.IF0 ..BT,<
	  SETCM .SAC,AC		;;GENERAL CASE, GET COMPLEMENT OF BITS
	  JXN (.SAC,..JX1,BA)>,< ;;JUMP IF SOME ZEROS ORIGINALLY
	    TXNN AC,..JX1	;;TEST AND JUMP
	    JRST BA>>>
	PURGE ..JX1>
IFNDEF .PSECT,<
	.IF0 <<..JX1>-1B0>,<
		JUMPGE AC,BA>,<
	..ONEB (..BT,MSK)	;;TEST MASK FOR ONLY ONE BIT ON
	.IF0 ..BT,<
	  SETCM .SAC,AC		;;GENERAL CASE, GET COMPLEMENT OF BITS
	  JXN (.SAC,..JX1,BA)>,< ;;JUMP IF SOME ZEROS ORIGINALLY
	    TXNN AC,..JX1	;;TEST AND JUMP
	    JRST BA>>>
	PURGE ..JX1>
	SUBTTL SUBFUNCTION MACROS
;.IF0 CONDITION, ACTION IF CONDITION 0, ACTION OTHERWISE
DEFINE .IF0 (COND,THEN,ELSE)<
	..IFT==COND		;;GET LOCAL VALUE FOR CONDITION
	IFE ..IFT,<
	THEN
	..IFT==0>		;;RESTORE IN CASE CHANGED BY NESTED .IF0
	IFN ..IFT,<
	ELSE>>
;CASE (NUMBER,<FIRST,SECOND,...,NTH>)
DEFINE .CASE (NUM,LIST)<
	..CSN==NUM
	..CSC==0
	IRP LIST,<
	IFE ..CSN-..CSC,<
	  STOPI
	  ..CAS1 (LIST)>
	..CSC==..CSC+1>>
DEFINE ..CAS1 (LIST)<
	LIST>
;TEST FOR FULL WORD, RH, LH, OR ARBITRARY BYTE
DEFINE ..TSIZ (SYM,MSK)<
	SYM==3			;;ASSUME BYTE UNLESS...
	IFE <MSK>+1,<SYM=0>	;;FULL WORD IF MASK IS -1
	IFE <MSK>-^O777777,<SYM==1> ;;RH IF MASK IS 777777
	IFE <MSK>-^O777777B17,<SYM==2>> ;;LH IF MAST IS 777777,,0
;TEST FOR LOC BEING AN AC -- SET SYM TO 1 IF AC, 0 IF NOT AC
DEFINE ..TSAC (SYM,LOC)<
	IFNDEF .PSECT,<
	SYM==0			;;ASSUME NOT AC UNLESS...
	..TSA1==<Z LOC>		;;LOOK AT LOC
	  IFE ..TSA1&^O777777777760,<SYM==1> ;;AC IF VALUE IS 0-17
	>
	IFDEF .PSECT,<
	SYM==0			;;ASSUME NOT AC UNLESS...
	..TSA1==<Z LOC>		;;LOOK AT LOC
	.IF ..TSA1,ABSOLUTE,<	;;SEE IF WE CAN TEST VALUE
	  IFE ..TSA1&^O777777777760,<SYM==1>> ;;AC IF VALUE IS 0-17
	PURGE ..TSA1>>
;FUNCTION TO TEST FOR MASK CONTAINING EXACTLY ONE BIT. RETURNS
;1 IFF LEFTMOST BIT AND RIGHTMOST BIT ARE SAME
DEFINE ..ONEB (SYM,MSK)<
	SYM==<<<-<MSK>>&<MSK>>&<1B<^L<MSK>>>>>
;DEFAULT SCRACH AC
.SAC=16
	SUBTTL DEFSTR -- DEFINE DATA STRUCTURE
;DEFINE DATA STRUCTURE
; NAM - NAME OF STRUCTURE AS USED IN CODE
; LOCN - ADDRESS OF DATA
; POS - POSITION OF DATA WITHIN WORD (RIGHTMOST BIT NUMBER)
; SIZ - SIZE OF DATA (IN BITS) WITHIN WORD
DEFINE DEFSTR (NAM,LOCN,POS,SIZ)<
	NAM==<-1B<POS>+1B<POS-SIZ>> ;;ASSIGN SYMBOL TO HOLD MASK
	IF1,<IFDEF %'NAM,<PRINTX ?NAM ALREADY DEFINED>>
	DEFINE %'NAM (OP,AC,Y,MSK)<
	OP (<AC>,LOCN''Y,MSK)>>	;;DEFINE MACRO TO HOLD LOCATION
;ALTERNATE FORM OF DEFSTR -- TAKES MASK INSTEAD OF POS,SIZ
DEFINE MSKSTR (NAM,LOCN,MASK)<
	NAM==MASK		;;ASSIGN SYMBOL TO HOLD MASK
	IF1,<IFDEF %'NAM,<PRINTX ?NAM ALREADY DEFINED>>
	DEFINE %'NAM (OP,AC,Y,MSK)<
	OP (<AC>,LOCN''Y,MSK)>>	;;DEFINE MACRO TO HOLD LOCATION
;..STR0 - PROCESS INSTANCE OF STRUCTURE USAGE, SINGLE STRUCTURE CASE.
DEFINE ..STR0 (OP,AC,STR,Y)<
	IFNDEF STR,<PRINTX ?STR IS NOT DEFINED
	  OP (<AC>,Y,.FWORD)>	;;RESERVE A WORD, ASSUME WORD MASK
	IFDEF STR,<
	IFNDEF %'STR,<
	  OP (<AC>,Y,STR)>	;;ASSUME NO OTHER LOCN
	IFDEF %'STR,<
	  %'STR (OP,<AC>,Y,STR)>>> ;;DO IT
;..STR1, ..STR2, ..STR3, AND ..STR4 ARE INTERNAL MACROS FOR PROCESSING
;INSTANCES OF STRUCTURE USAGE.
DEFINE ..STR1 (OP,AC,STR,Y,CLL)<
	..NS==0			;;INIT COUNT OF STR'S
	IRP STR,<..NS=..NS+1>	;;COUNT STR'S
	IFE ..NS,<PRINTX ?EMPTY STRUCTURE LIST, OP>
	IFE ..NS-1,<		;;THE ONE CASE, CAN DO FAST
	  ..STR0 (OP,<AC>,<STR>,Y)>
	IFG ..NS-1,<		;;MORE THAN ONE, DO GENERAL CASE
	..ICNS			;;INIT REMOTE MACRO
	..CNS (<CLL (OP,<AC>,,>) ;;CONS ON CALL AND FIRST ARGS
	IRP STR,<		;;DO ALL NAMES IN LIST
	  IFNDEF STR,<PRINTX STR NOT DEFINED>
	  IFDEF STR,<
	  IFNDEF %'STR,<
	  ..CNS (<,STR,Y>)>	;;ASSUME NO OTHER LOCN
	  IFDEF %'STR,<
	  %'STR (..STR2,,Y,STR)> ;;STR MACRO WILL GIVE LOCN TO ..STR2
	  ..CNS (<)>)		;;CLOSE ARG LIST
	  ..GCNS		;;DO THIS AND PREVIOUS NAME
	  ..ICNS		;;REINIT CONS
	  ..CNS (<CLL (OP,<AC>>) ;;PUT ON FIRST ARGS
	  IFNDEF %'STR,<
	  ..CNS (<,STR,Y>)>	;;ASSUME NO OTHER LOCN
	  IFDEF %'STR,<
	  %'STR (..STR2,,Y,STR)>>> ;;PUT ON THIS ARG, END IRP
	..CNS (<,,)>)		;;CLOSE ARG LIST
	..GCNS>>		;;DO LAST CALL
;..STR2 -- CALLED BY ABOVE TO APPEND STRUCTURE NAME AND LOC TO ARG LIST
DEFINE ..STR2 (AA,LOC,STR)<
	..CNS (<,STR,LOC>)>	;;CONS ON NEXT ARG PAIR
;..STR3 -- CHECK FOR ALL STRUCTURES IN SAME REGISTER
DEFINE ..STR3 (OP,AC,S1,L1,S2,L2)<
	IFDIF <L1><L2>,<
	  IFNB <L1>,<
	    OP (<AC>,L1,..MSK)	;;DO ACCUMULATED STUFF
	    IFNB <L2>,<PRINTX S1 AND S2 ARE IN DIFFERENT WORDS>>
	  ..MSK==0>		;;INIT MASK
	IFNB <L2>,<
	  ..MSK=..MSK!<S2>>>
;..STR4 -- COMPARE SUCCESSIVE ITEMS, DO SEPARATE OPERATION IF
;DIFFERENT WORDS ENCOUNTERED
DEFINE ..STR4 (OP,AC,S1,L1,S2,L2)<
	IFDIF <L1><L2>,<	;;IF THIS DIFFERENT FROM PREVIOUS
	  IFNB <L1>,<
	    OP (<AC>,L1,..MSK)>	;;DO PREVIOUS
	  ..MSK==0>		;;REINIT MASK
	IFNB <L2>,<
	  ..MSK=..MSK!<S2>>>	;;ACCUMULATE MASK
;..STR5 - SAME AS ..STR4 EXCEPT GIVES EXTRA ARG IF MORE STUFF TO
;FOLLOW.
DEFINE ..STR5 (OP,AC,S1,L1,S2,L2)<
	IFDIF <L1><L2>,<	;;IF THIS DIFFERENT FROM PREVIOUS,
	  IFNB <L1>,<
	    IFNB <L2>,<		;;IF MORE TO COME,
		OP'1 (AC,L1,..MSK)> ;;DO VERSION 1
	    IFB <L2>,<		;;IF NO MORE,
		OP'2 (AC,L1,..MSK)>> ;;DO VERSION 2
	  ..MSK==0>		;;REINIT MASK
	IFNB <L2>,<
	  ..MSK=..MSK!<S2>>>	;;ACCUMULATE MASK
;'REMOTE' MACROS USED TO BUILD UP ARG LIST
;INITIALIZE CONS -- DEFINES CONS
DEFINE ..ICNS <
   DEFINE ..CNS (ARG)<
	..CNS2 <ARG>,>
   DEFINE ..CNS2 (NEW,OLD)<
	DEFINE ..CNS (ARG)<
	  ..CNS2 <ARG>,<OLD'NEW>>>
   >
;GET CONS -- EXECUTE STRING ACCUMULATED
DEFINE ..GCNS <
   DEFINE ..CNS2 (NEW,OLD)<
	  OLD>			;;MAKE ..CNS2 DO THE STUFF
	..CNS ()>		;;GET ..CNS2 CALLED WITH THE STUFF
;SPECIFIC CASES
;LOAD, STORE
; AC - AC OPERAND
; STR - STRUCTURE NAME
; Y - (OPTIONAL) ADDITIONAL SPECIFICATION OF DATA LOCATION
DEFINE LOAD (AC,STR,Y)<
	..STR0 (..LDB,AC,STR,Y)>
   DEFINE ..LDB (AC,LOC,MSK)<
	..TSIZ (..PST,MSK)
	.CASE ..PST,<<
		MOVE AC,LOC>,<
		HRRZ AC,LOC>,<
		HLRZ AC,LOC>,<
		LDB AC,[POINTR (LOC,MSK)]>>>
DEFINE STOR (AC,STR,Y)<
	..STR0 (..DPB,AC,STR,Y)>
   DEFINE ..DPB (AC,LOC,MSK)<
	..TSIZ (..PST,MSK)
	.CASE ..PST,<<
		MOVEM AC,LOC>,<
		HRRM AC,LOC>,<
		HRLM AC,LOC>,<
		DPB AC,[POINTR (LOC,MSK)]>>>
;SET TO ZERO
DEFINE SETZRO (STR,Y)<
	..STR1 (..TQZ,,<STR>,Y,..STR4)>
   DEFINE ..TQZ (AC,LOC,MSK)<
	..TSIZ (..PST,MSK)	;;SET ..PST TO CASE NUMBER
	.CASE ..PST,<<
		SETZM LOC>,<	;;FULL WORD
		HLLZS LOC>,<	;;RH
		HRRZS LOC>,<	;;LH
	  ..TSAC (..ACT,LOC)	;;SEE IF LOC IS AC
	  .IF0 ..ACT,<
		MOVX .SAC,MSK	;;NOT AC
		ANDCAM .SAC,LOC>,<
		..TX (Z,LOC,MSK)>>>>
;SET TO ONE
DEFINE SETONE (STR,Y)<
	..STR1 (..TQO,,<STR>,Y,..STR4)>
   DEFINE ..TQO (AC,LOC,MSK)<
	..TSIZ (..PST,MSK)
	.CASE ..PST,<<
		SETOM LOC>,<
		HLLOS LOC>,<
		HRROS LOC>,<
	  ..TSAC (..ACT,LOC)
	  .IF0 ..ACT,<
		MOVX .SAC,MSK
		IORM .SAC,LOC>,<
		..TX (O,LOC,MSK)>>>>
;SET TO COMPLEMENT
DEFINE SETCMP (STR,Y)<
	..STR1 (..TQC,,<STR>,Y,..STR4)>
   DEFINE ..TQC (AC,LOC,MSK)<
	..TSIZ (..PST,MSK)
	.IF0 ..PST,<		;;IF FULL WORD,
		SETCMM LOC>,<	;;CAN USE SETCMM
	  ..TSAC (..ACT,LOC)	;;OTHERWISE, CHECK FOR AC
	  .IF0 ..ACT,<
		MOVX .SAC,MSK
		XORM .SAC,LOC>,<
		..TX(C,LOC,MSK)>>>
;INCREMENT, DECREMENT FIELD
DEFINE INCR (STR,Y)<
	..STR0 (.INCR0,,<STR>,Y)>
   DEFINE .INCR0 (AC,LOC,MSK)<
	..PST==MSK&<-MSK>	;;GET LOWEST BIT
	.IF0 ..PST-1,<
		AOS LOC>,<	;;BIT 35, CAN USE AOS
		MOVX .SAC,..PST	;;LOAD A ONE IN THE APPROPRIATE POSITION
		ADDM .SAC,LOC>>
DEFINE DECR (STR,Y)<
	..STR0 (.DECR0,,<STR>,Y)>
   DEFINE .DECR0 (AC,LOC,MSK)<
	..PST==MSK&<-MSK>
	.IF0 ..PST-1,<
		SOS LOC>,<	;;BIT 35, CAN USE SOS
		MOVX .SAC,-..PST ;;LOAD -1 IN APPROPRIATE POSITION
		ADDM .SAC,LOC>>
;GENERAL DEFAULT, TAKES OPCODE
DEFINE OPSTR (OP,STR,Y)<
	..STR0 (.OPST1,<OP>,<STR>,Y)>
   DEFINE .OPST1 (OP,LOC,MSK)<
	..TSIZ (..PST,MSK)
	.IF0 ..PST,<
		OP LOC>,<	;;FULL WORD, USE GIVEN OP DIRECTLY
		..LDB .SAC,LOC,MSK ;;OTHERWISE, GET SPECIFIED BYTE
		OP .SAC>>
DEFINE OPSTRM (OP,STR,Y)<
	..STR0 (.OPST2,<OP>,<STR>,Y)>
   DEFINE .OPST2 (OP,LOC,MSK)<
	..TSIZ (..PST,MSK)
	.IF0 ..PST,<
		OP LOC>,<	;;FULL WORD, USE OP DIRECTLY
		..LDB .SAC,LOC,MSK
		OP .SAC
		..DPB .SAC,LOC,MSK>>
;JUMP IF ALL FIELDS ARE 0 (ONE REGISTER AT MOST)
DEFINE JE (STR,Y,BA)<
	..STR1 (..JE,<BA>,<STR>,Y,..STR3)>
   DEFINE ..JE (BA,LOC,MSK)<
	..TSAC (..ACT,LOC)	;;SEE IF AC
	.IF0 ..ACT,<
	  ..TSIZ (..PST,MSK)	;;SEE WHICH CASE
	  .CASE ..PST,<<
		SKIPN LOC	;;FULL WORD, TEST IN MEMORY
		JRST BA>,<
		HRRZ .SAC,LOC	;;RIGHT HALF, GET IT
		JUMPE .SAC,BA>,<
		HLRZ .SAC,LOC	;;LEFT HALF, GET IT
		JUMPE .SAC,BA>,<
		MOVE .SAC,LOC	;;NOTA, GET WORD
		JXE (.SAC,MSK,<BA>)>>>,<
	  JXE (LOC,MSK,<BA>)>>
;JUMP IF NOT ALL FIELDS ARE 0 (ONE REGISTER AT MOST)
DEFINE JN (STR,Y,BA)<
	..STR1 (..JN,<BA>,<STR>,Y,..STR3)>
   DEFINE ..JN (BA,LOC,MSK)<
	..TSAC (..ACT,LOC)	;;SEE IF AC
	.IF0 ..ACT,<
	  ..TSIZ (..PST,MSK)
	  .CASE ..PST,<<
		SKIPE LOC	;;FULL WORD, TEST IN MEMORY
		JRST BA>,<
		HRRZ .SAC,LOC	;;RIGHT HALF, GET IT
		JUMPN .SAC,BA>,<
		HLRZ .SAC,LOC	;;LEFT HALF, GET IT
		JUMPN .SAC,BA>,<
		MOVE .SAC,LOC	;;NOTA, GET WORD
		JXN (.SAC,MSK,<BA>)>>>,<
	  JXN (LOC,MSK,<BA>)>>
;JOR - JUMP ON 'OR' OF ALL FIELDS
DEFINE JOR (STR,Y,BA)<
	..STR1 (..JN,<BA>,<STR>,Y,..STR4)>
;JNAND - JUMP ON NOT 'AND' OF ALL FIELDS
DEFINE JNAND (STR,Y,BA)<
	..STR1 (..JNA3,<BA>,<STR>,Y,..STR4)>
   DEFINE ..JNA3 (BA,LOC,MSK)<
	..TSAC (..ACT,LOC)
	.IF0 ..ACT,<
	  SETCM .SAC,LOC	;;NOT AC, GET COMPLEMENT OF WORD
	  JXN (.SAC,MSK,<BA>)>,<	;;JUMP IF ANY BITS ORIGINALLY OFF
	  JXF (LOC,MSK,<BA>)>>	;;DO AC CASE
;JAND - JUMP ON 'AND' OF ALL FIELDS
DEFINE JAND (STR,Y,BA,%TG)<
	..STR1 (..JAN,<%TG,<BA>>,<STR>,Y,..STR5)
%TG:>
   DEFINE ..JAN1 (BA1,BA2,LOC,MSK)<
	..JNA3 (BA1,LOC,MSK)>	;;DO JUMP NAND TO LOCAL TAG
   DEFINE ..JAN2 (BA1,BA2,LOC,MSK)<
	..TSAC (..ACT,LOC)
	.IF0 ..ACT,<
	  SETCM .SAC,LOC	;;NOT AC, GET COMPLEMENT OF WORD
	  JXE (.SAC,MSK,<BA2>)>,<	;;JUMP IF ALL BITS ORIGINALLY ONES
	  JXO (LOC,MSK,<BA2>)>> ;;DO AC CASE
;JNOR - JUMP ON NOT 'OR' OF ALL FIELDS
DEFINE JNOR (STR,Y,BA,%TG)<
	..STR1 (..JNO,<%TG,<BA>>,<STR>,Y,..STR5)
%TG:>
   DEFINE ..JNO1 (BA1,BA2,LOC,MSK)<
	..JN (BA1,LOC,MSK)>	;;DO JUMP OR TO LOCAL TAG
   DEFINE ..JNO2 (BA1,BA2,LOC,MSK)<
	..JE (<BA2>,LOC,MSK)>	;;DO JUMP NOR TO GIVEN TAG
;TEST AND MODIFY GROUP USING DEFINED STRUCTURES.  TEST-ONLY AND
;MODIFY-ONLY PROVIDED FOR COMPLETENESS.
DEFINE ..DOTY (M,T)<		;;MACRO TO DEFINE ALL CASES
	IRP M,<
	IRP T,<
	  DEFINE TQ'M'T (STR,Y)<
	    ..STR1 (..TY,M'T,<STR>,Y,..STR3)>>>>
	..DOTY (<N,O,Z,C>,<,E,N,A>) ;DO 16 DEFINES
	PURGE ..DOTY
;ALL TY MACROS CALL ..TY AFTER INITIAL STRUCTURE PROCESSING
DEFINE ..TY (MT,LOC,MSK)<
	..TSAC (..ACT,LOC)	;;SEE IF LOC IS AC
	.IF0 ..ACT,<
		PRINTX ?TQ'MT - LOC NOT IN AC>,<
		TX'MT LOC,MSK>>
	SUBTTL CALL, RET, JSERR
   IFE REL,<
	EXTERN JSERR0,JSMSG0,JSHLT0,R,RSKP>
;CALL AND RETURN
.AC1==1				;ACS FOR JSYS ARGS
.AC2==2
.AC3==3
.A16==16			;TEMP FOR STKVAR AND TRVAR
P=17				;STACK POINTER
OPDEF CALL [PUSHJ P,0]
OPDEF RET [POPJ P,0]
;ABBREVIATION FOR  CALL, RET, RETSKP
OPDEF CALLRET [JRST]
.NODDT CALLRET
DEFINE RETSKP <JRST RSKP>
;MACRO TO PRINT MESSAGE ON TERMINAL
DEFINE TMSG ($MSG)<
	HRROI .AC1,[ASCIZ \$MSG\]
	PSOUT>
;MACRO TO OUTPUT MESSAGE TO FILE
; ASSUMES JFN ALREADY IN .AC1
DEFINE FMSG ($MSG)<
	HRROI .AC2,[ASCIZ \$MSG\]
	MOVEI .AC3,0
	SOUT>
;MACRO TO PRINT MESSAGE FOR LAST ERROR, RETURNS +1
DEFINE PERSTR ($MSG)<
   IFNB <$MSG>,<
	TMSG <$MSG>>
	CALL JSMSG0>
;MACRO TO PRINT JSYS ERROR MESSAGE, RETURNS +1 ALWAYS
OPDEF JSERR[<CALL JSERR0>]
;MACRO FOR FATAL JSYS ERROR, PRINTS MSG THEN HALTS
OPDEF JSHLT[<CALL JSHLT0>]
;PRINT ERROR MESSAGE IF JSYS FAILS
DEFINE ERMSG(TEXT),<
	ERJMP	[TMSG <? TEXT>
		 JSHLT]
>
;MAKE SYMBOLS EXTERN IF NOT ALREADY DEFINED
DEFINE EXT (SYM)<
   IF2,<
	IRP SYM,<
	IFNDEF SYM,<EXTERN SYM
	SUPPRE SYM>>>>
;MACRO TO ADD BREAK CHARACTER TO FOUR WORD BREAK MASK (W0., W1., W2., W3.)
DEFINE BRKCH. (%%V,V2)
<
%%FOO==%%V
	BRK0 (%%FOO,V2,0)
>
;MACRO TO REMOVE CHARACTER
DEFINE UNBRK. (%%V,V2)
<
%%FOO==%%V
	BRK0 (%%FOO,V2,1)
>
DEFINE BRK0 (%%11,V2,FLAVOR)
<	..V22==%%11
	..V1==%%11
	IFNB <V2>,<..V22==V2>
REPEAT ..V22-<%%11>+1,<	;;BRACKETS AROUND %%11 IN CASE ITS AN EXPRESSION
	%%W==..V1/^D32	;;DECIDE WHICH WORD CHARACTER GOES IN
	%%X==..V1-%%W*^D32	;;CALCULATE BIT POSITION WITHIN WORD
	IFE FLAVOR,BRKC1 \"<%%W+"0">	;;MODIFY CORRECT MASK WORD
	IFN FLAVOR,BRKC2 \"<%%W+"0">
	..V1==..V1+1
		   >
PURGE ..V1,..V22		;;DON'T LET THESE SYMBOLS APPEAR IN MONSYM
>
DEFINE BRKC1 (ARG1)
<	W'ARG1'.==W'ARG1'.!<1B<%%X>>
>
DEFINE BRKC2 (ARG1)
<	W'ARG1'.==W'ARG1'.&<-1-1B<%%X>>
>
;MACRO TO INITIALIZE 4-WORD 12-BIT CHARACTER BREAK MASK
DEFINE BRINI.(A0<0>,A1<0>,A2<0>,A3<0>)
<
W0.==A0
W1.==A1				;INITIALIZE BREAK MASK
W2.==A2
W3.==A3
>
;MACRO TO DEFINE A BREAK SET
DEFINE BRMSK. (INI0,INI1,INI2,INI3,ALLOW,DISALW)
<	BRINI. INI0,INI1,INI2,INI3	;;SET UP INITIAL MASK
	IRPC ALLOW,<	UNBRK. "ALLOW">	;;DON'T BREAK ON CHARS TO BE ALLOWED IN FIELD
	IRPC DISALW,<	BRKCH. "DISALW">	;;BREAK ON CHARACTERS NOT ALLOWED
	EXP W0.,W1.,W2.,W3.		;;STORE RESULTANT MASK IN MEMORY
>
;COMND - MACRO FOR BUILDING FUNCTION DESCRIPTOR BLOCK
;THIS IS THE OLD ONE, BEFORE .CMBRK EXISTED.  USE FLDBK. FOR SPECIFYING
;BREAK SETS
DEFINE FLDDB. (TYP,FLGS,DATA,HLPM,DEFM,LST)<
	..XX==<FLD(TYP,CM%FNC)>+FLGS+<0,,LST>
   IFNB <HLPM>,<..XX=CM%HPP!..XX>
   IFNB <DEFM>,<..XX=CM%DPP!..XX>
	..XX
   IFNB <DATA>,<DATA>
   IFB <DATA>,<0>
   IFNB <HLPM>,<POINT 7,[ASCIZ \HLPM\]>
   IFB <HLPM>,<IFNB <DEFM>,<0>>
   IFNB <DEFM>,<POINT 7,[ASCIZ \DEFM\]>>
;COMND - MACRO FOR BUILDING FUNCTION DESCRIPTOR BLOCK
DEFINE FLDBK. (TYP,FLGS,DATA,HLPM,DEFM,BRKADR,LST)<
	..XX==<FLD(TYP,CM%FNC)>+FLGS+<Z LST>
   IFNB <HLPM>,<..XX=CM%HPP!..XX>
   IFNB <DEFM>,<..XX=CM%DPP!..XX>
   IFNB <BRKADR>,<..XX=CM%BRK!..XX>
	..XX
   IFNB <DATA>,<DATA>
   IFB <DATA>,<0>
   IFNB <HLPM>,<POINT 7,[ASCIZ \HLPM\]>
   IFB <HLPM>,<IFNB <DEFM'BRKADR>,<0>>
   IFB <DEFM>,<IFNB <BRKADR>,<0>>
   IFNB <DEFM>,<POINT 7,[ASCIZ \DEFM\]>
   IFNB <BRKADR>,<BRKADR>
   >
;USEFUL EXTENDED ADDRESSING DEFINITIONS
OPDEF	XMOVEI [SETMI]		;EXTENDED MOVE IMMEDIATE
OPDEF	XHLLI [HLLI]		;NOT YET IN MACRO
DEFINE XBLT. (A)<
	EXTEND A,[XBLT]>
	SUBTTL SUPPORT CODE FOR JSERR
   IFN REL,<
A=1
B=2
C=3
D=4
;JSYS ERROR HANDLER
;	CALL JSERR0
; RETURNS +1: ALWAYS, CAN BE USED IN +1 RETURN OF JSYS'S
JSERR0::MOVEI A,.PRIIN
	CFIBF			;CLEAR TYPAHEAD
	MOVEI A,.PRIOU
	DOBE			;WAIT FOR PREVIOUS OUTPUT TO FINISH
	TMSG <
? JSYS ERROR: >
JSMSG0::MOVEI A,.PRIOU
	HRLOI B,.FHSLF		;SAY  THIS FORK ,, LAST ERROR
	SETZ C,
	ERSTR
	 JFCL
	 JFCL
	TMSG <
>
	RET
;FATAL JSYS ERROR - PRINT MESSAGE AND HALT
;	CALL JSHLT0
; RETURNS: NEVER
JSHLT0::CALL JSERR0		;PRINT THE MSG
JSHLT1:	HALTF
	TMSG <PROGRAM CANNOT CONTINUE
>
	JRST JSHLT1		;HALT AGAIN IF CONTINUED
   >				;END OF IFN REL,
	SUBTTL STKVAR - STACK VARIABLE FACILITY
;MACRO FOR ALLOCATING VARIABLES ON THE STACK. ITS ARGUMENT IS
;A LIST OF ITEMS.  EACH ITEM MAY BE:
; 1. A SINGLE VARIABLE WHICH WILL BE ALLOCATED ONE WORD
; 2. A VARIABLE AND SIZE PARAMETER WRITTEN AS <VAR,SIZ>.  THE
;	VARIABLE WILL BE ALLOCATED THE SPECIFIED NUMBER OF WORDS.
;RETURN FROM A SUBROUTINE USING THIS FACILITY MUST BE VIA
;RET OR RETSKP.  A DUMMY RETURN WHICH FIXES UP THE STACK IS PUT ON
;THE STACK AT THE POINT THE STKVAR IS ENCOUNTERED.
;WITHIN THE RANGE OF A STKVAR, PUSH/POP CANNOT BE USED AS THEY WILL
;CAUSE THE VARIABLES (WHICH ARE DEFINED AS RELATIVE STACK LOCATIONS)
;TO REFERENCE THE WRONG PLACE.
;TYPICAL USE:   STKVAR <AA,BB,<QQ,5>,ZZ>
   IFE REL,<
	EXTERN .STKST,.STKRT>
DEFINE STKVAR (ARGS)<
	..STKR==10		;;REMEMBER RADIX
	RADIX 8
	..STKN==0
	IRP ARGS,<
	  .STKV1 (ARGS)>
	JSP .A16,.STKST
	 ..STKN,,..STKN
	RADIX ..STKR
	PURGE ..STKN,..STKR,..STKQ
   >
;INTERMEDIATE MACRO TO PEAL OFF ANGLEBRACKETS IF ANY
DEFINE .STKV1 (ARG)<
	.STKV2 (ARG)>
;INTERMEDIATE MACRO TO CALCULATE OFFSET AND COUNT VARIABLES
DEFINE .STKV2 (VAR,SIZ)<
	IFB <SIZ>,<..STKN==..STKN+1>
	IFNB <SIZ>,<..STKN==..STKN+SIZ>
	..STKQ==..STKN+1
	.STKV3 (VAR,\..STKQ)>
;INNERMOST MACRO TO DEFINE VARIABLE
DEFINE .STKV3 (VAR,LOC)<
   IFDEF VAR,<.IF VAR,SYMBOL,<PRINTX STKVAR VAR ALREADY DEFINED>>
	DEFINE VAR<-^O'LOC(P)>
	$'VAR==<Z VAR>>		;SYMBOL FOR DDT
   IFN REL,<
;COMMON ENTRY AND EXIT ROUTINE FOR STACK VARIABLE
	ENTRY .STKST
.STKST::ADD P,0(.A16)		;BUMP STACK FOR VARIABLES USED
	JUMPGE P,STKSOV		;TEST FOR STACK OVERFLOW
STKSE1:	PUSH P,0(.A16)		;SAVE BLOCK SIZE FOR RETURN
	PUSHJ P,1(.A16)		;CONTINUE ROUTINE, EXIT TO .+1
.STKRT::JRST STKRT0		;NON-SKIP RETURN COMES HERE
	POP P,.A16		;SKIP RETURN COMES HERE-RECOVER COUNT
	SUB P,.A16		;ADJUST STACK TO REMOVE BLOCK
	AOS 0(P)		;NOW DO SKIP RETURN
	RET
STKRT0:	POP P,.A16		;RECOVER COUNT
	SUB P,.A16		;ADJUST STACK TO REMOVE BLOCK
	RET			;DO NON-SKIP RETURN
STKSOV:	SUB P,0(.A16)		;STACK OVERFLOW- UNDO ADD
	HLL .A16,0(.A16)	;SETUP TO DO MULTIPLE PUSH, GET COUNT
STKSO1:	PUSH P,[0]		;DO ONE PUSH AT A TIME, GET REGULAR
	SUB .A16,[1,,0]		; ACTION ON OVERFLOW
	TLNE .A16,777777	;COUNT DOWN TO 0?
	JRST STKSO1		;NO, KEEP PUSHING
	JRST STKSE1
   >				;END OF IFN REL,
	SUBTTL TRVAR - TRANSIENT VARIABLE FACILITY
;TRANSIENT (STACK) VARIABLE FACILITY - EQUIVALENT TO STKVAR
;EXCEPT ALLOWS VARIABLES TO BE USED WITHIN LOWER LEVEL ROUTINES
;AND AFTER OTHER THINGS HAVE BEEN PUSHED ON STACK.
;N.B. USES .FP AS FRAME POINTER - MUST NOT BE CHANGED WHILE
;VARIABLES IN USE.
.FP==15				;DEFAULT FRAME POINTER
   IFE REL,<
	EXTERN .TRSET,.TRRET,.ASSET,.ASRET>
DEFINE TRVAR (VARS)<
	..TRR==10		;;REMEMBER CURRENT RADIX
	RADIX 8
	..NV==1			;;INIT COUNT OF STACK WORDS
	IRP VARS,<
	  .TRV1 (VARS)>		;;PROCESS LIST
	JSP .A16,.TRSET		;;ALLOCATE STACK SPACE, SETUP .FP
	 ..NV-1,,..NV-1
	RADIX ..TRR		;;RESTORE RADIX
	PURGE ..TRR,..NV>	;;CLEAN UP
DEFINE .TRV1 (VAR)<
	.TRV2 (VAR)>		;;PEEL OFF ANGLEBRACKETS IF ANY
DEFINE .TRV2 (NAM,SIZ)<
	.TRV3 (NAM,\..NV)	;;DEFINE VARIABLE
	IFB <SIZ>,<..NV=..NV+1>
	IFNB <SIZ>,<..NV=..NV+SIZ>>
DEFINE .TRV3 (NAM,LOC)<
   IFDEF NAM,<.IF NAM,SYMBOL,<PRINTX TRVAR NAM ALREADY DEFINED>>
	DEFINE NAM<^O'LOC(.FP)>
	$'NAM==<Z NAM>>		;;SYMBOL FOR DDT
;AC SUBROUTINE - ENTRY FOR SUBROUTINE CALLED WITH 1-4 ARGS IN ACS T1-T4.
;USES .FP AS FRAME PTR LIKE TRVAR
DEFINE ASUBR (ARGS)<
	..TRR==10		;;SAVE RADIX
	RADIX 8
	..NV==1			;;INIT ARG COUNT
	IRP ARGS,<
	  .TRV1 (ARGS)>		;;DEFINE ARG SYMBOL
	IFG ..NV-5,<PRINTX ?TOO MANY ARGUMENTS: ARGS>
	JSP .A16,.ASSET		;;SETUP STACK
	RADIX ..TRR		;;RESTORE RADIX
	PURGE ..TRR,..NV>
   IFN REL,<
;SUPPORT ROUTINE FOR TRVAR
.TRSET::PUSH P,.FP		;PRESERVE OLD .FP
	MOVE .FP,P		;SETUP FRAME PTR
	ADD P,0(.A16)		;ALLOCATE SPACE
	JUMPGE P,TRSOV
TRSET1:	PUSHJ P,1(.A16)		;CONTINUE ROUTINE, EXIT VIA .+1
.TRRET::JRST [	MOVEM .FP,P	;CLEAR STACK
		POP P,.FP	;RESTORE OLD .FP
		POPJ P,]
	MOVEM .FP,P		;HERE IF SKIP RETURN
	POP P,.FP
	AOS 0(P)		;PASS SKIP RETURN
	POPJ P,
TRSOV:	SUB P,0(.A16)		;STACK OVERFLOW - UNDO ADD
	HLL .A16,0(.A16)	;GET COUNT
TRSOV1:	PUSH P,[0]		;DO ONE PUSH AT A TIME, GET REGULAR
	SUB .A16,[1,,0]		; ACTION ON OVERFLOW
	TLNE .A16,777777	;COUNT TO 0?
	JRST TRSOV1		;NO, KEEP PUSHING
	JRST TRSET1		;CONTINUE SETUP
;SUPPORT ROUTINE FOR ASUBR
.ASSET::PUSH P,.FP		;SAVE .FP
	MOVE .FP,P		;SETUP FRAME POINTER
	ADD P,[4,,4]		;ADJUST STACK
	JUMPGE P,[SUB P,[4,,4]	;PROBABLE OVERFLOW
		PUSH P,A	;DO WITH PUSH, GET INTERRUPT...
		PUSH P,B
		PUSH P,C
		PUSH P,D
		JRST ASSET1]
	DMOVEM A,1(.FP)	;SAVE ARGS
	DMOVEM C,3(.FP)
ASSET1:	PUSHJ P,0(.A16)		;CONTINUE ROUTINE
.ASRET:: JRST [	MOVEM .FP,P	;NO-SKIP RETURN, CLEAR STACK
		POP P,.FP
		POPJ P,]
	MOVEM .FP,P		;SKIP RETURN, CLEAR STZCK
	POP P,.FP
	AOS 0(P)
	POPJ P,
   >				;END OF IFN REL,
;AC VARIABLE FACILITY
   IFE REL,<
	EXTERN .SAV1,.SAV2,.SAV3,.SAV4,.SAV8>
.FPAC==5			;FIRST PRESERVED AC
.NPAC==10			;NUMBER OF PRESERVED ACS
DEFINE ACVAR (LIST)<
	..NAC==0		;;INIT NUMBER OF ACS USED
	IRP LIST,<
	  .ACV1 (LIST)>		;;PROCESS ITEMS
	.ACV3 (\..NAC)>		;;SAVE ACS USED
DEFINE .ACV1 (ITEM)<
	.ACV2 (ITEM)>		;;PEEL OFF ANGLEBRACKETS IF ANY
DEFINE .ACV2 (NAM,SIZ)<
	NAM=.FPAC+..NAC		;;DEFINE VARIABLE
	IFB <SIZ>,<..NAC=..NAC+1>
	IFNB <SIZ>,<..NAC=..NAC+SIZ>>
DEFINE .ACV3 (N)<
	IFG N-.NPAC,<PRINTX ?TOO MANY ACS USED>
	IFLE N-4,<
	  JSP .A16,.SAV'N>	;;SAVE ACTUAL NUMBER USED
	IFG N-4,<
	  JSP .A16,.SAV8>>	;;SAVE ALL
   IFN REL,<
;SUPPORT ROUTINES FOR AC VARIABLE FACILITY
.SAV1::	PUSH P,.FPAC
	PUSHJ P,0(.A16)		;CONTINUE PROGRAM
	 SKIPA
	AOS -1(P)
	POP P,.FPAC
	POPJ P,
.SAV2::	PUSH P,.FPAC
	PUSH P,.FPAC+1
	PUSHJ P,0(.A16)
	 SKIPA
	AOS -2(P)
	POP P,.FPAC+1
	POP P,.FPAC
	POPJ P,
.SAV3::
.SAV4::	PUSH P,.FPAC
	PUSH P,.FPAC+1
	PUSH P,.FPAC+2
	PUSH P,.FPAC+3
	PUSHJ P,0(.A16)
	 SKIPA
	AOS -4(P)
	POP P,.FPAC+3
	POP P,.FPAC+2
	POP P,.FPAC+1
	POP P,.FPAC
	POPJ P,
.SAV8::	ADD P,[10,,10]
	JUMPGE P,[HALT .]
	DMOVEM .FPAC,-7(P)
	DMOVEM .FPAC+2,-5(P)
	DMOVEM .FPAC+4,-3(P)
	DMOVEM .FPAC+6,-1(P)
	PUSHJ P,0(.A16)
	 SKIPA
	AOS -10(P)
	DMOVE .FPAC+6,-1(P)
	DMOVE .FPAC+4,-3(P)
	DMOVE .FPAC+2,-5(P)
	DMOVE .FPAC,-7(P)
	SUB P,[10,,10]
	POPJ P,
   >
;AC SAVE FACILITY - COMPILES OPEN PUSH'S
;	SAVEAC <LIST-OF-ACS>
;DUMMY ROUTINE PUT ON STACK TO CAUSE AUTOMATIC RESTORE. SUPPORTS
; +1 OR +2 RETURNS.
DEFINE SAVEAC (ACS)<
	.NAC==0
	IRP ACS,<
	  PUSH P,ACS		;;SAVE AN AC
	  .NAC=.NAC+1>		;;COUNT THEM
	.N1==.NAC
	SETMI .A16,[CAIA	;;STACK DUMMY RETURN
		AOS -.N1(P)	;;HANDLE SKIP RETURN
	  IRP ACS,<
		.N1=.N1-1
		MOVE ACS,-.N1(P)>  ;;RESTORE AN AC
		SUB P,[.NAC,,.NAC]  ;;CLEAR STACK
		POPJ P,]	;;FINAL RETURN
	PUSH P,.A16>
   IFN REL,<
;STANDARD RETURNS
RSKP::	AOS 0(P)
R::	RET
   >				;END OF IFN REL,
LIT				;MAKE SURE LITERALS COME BEFORE END MARK
   IFN REL,<
.RLEND==:.-1			;MARK END OF CODE IN MACREL
   >
  IF2,<PURGE REL>		;FLUSH REL FROM UNIV FILE
	END