Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_3_19910112
-
midas/midas.mid
There is 1 other file named midas.mid in the archive. Click here to see a list.
; -*-MIDAS-*-
; The canonical source for MIDAS (and directory of supporting files) is
; [MIT-MC] MIDAS;MIDAS >
IFE .OSMIDAS-SIXBIT/DEC/,.SYMTAB 4973.,2000. ;THIS MANY ON DEC SYSTEM
.ELSE .SYMTAB 10007. ;Assemble faster elsewhere.
TITLE MIDAS
SUBTTL Instructions and assembly conditionals
COMMENT | HOW TO ASSEMBLE MIDAS
The procedure for assembling MIDAS depends primarily on whether you are
building a new MIDAS for your own system, or for a different system. If
it is your own system, you can normally just assemble it, following the
directions below. Building MIDAS for a different system is more
complicated and you will have to read farther.
ITS
:MIDAS MIDAS;_MIDAS ; Assemble MIDAS
:JOB MIDAS
:LOAD MIDAS;MIDAS BIN
PURIFY$G ; This will dump to SYS;TS MIDAS
; if you confirm with CR.
TNX (TENEX, T20) ; This example is for TOPS-20
[@]CD <MIDAS> ; Connect to source file directory
[@]CVTUNV ; Run CVTUNV to generate TNXDFU.MID
[@]MIDAS MIDAS ; Assemble MIDAS
[@]GET MIDAS
[@]START PURIFY ; Optional - Start it at "PURIFY"
[@]SAVE <SUBSYS>MIDAS ; Then save as sharable file
DEC (SAIL, CMU, T10)
; This will have to be provided by those who do it.
HOW TO ASSEMBLE MIDAS FOR A DIFFERENT SYSTEM
To build MIDAS for a different system (not your own), you will need
to do two things. First, symbol definition files for the target system
must be provided; second, when assembling MIDAS the /T switch must be
given to enable initial input from the TTY, and the appropriate
conditional flag then defined. The allowed flags are listed below, along
with the files needed for each.
Target Flags Files needed Files needed
Op-System (set ==1) (if CVTSW==0) (if CVTSW==1)
ITS ITSSW ITSDFS,ITSBTS -
TENEX/TOPS-20 TNXSW TNXDFS,TWXBTS TNXDFU
TOPS-10 DECSW DECDFS,DECBTS DECDFU
SAIL " + SAILSW " , " ,SAIDFS "
CMU " + CMUSW " , " ,CMUDFS "
Other miscellaneous flags (all 1 to enable described action)
CVTSW makes a MIDAS using a DECDFU or TNXDFU file generated by the
CVTUNV program, which reads a MONSYM.UNV file and makes a TNXDFU.MID
file. There is no separate DECBTS or TWXBTS file when using CVTUNV.
NOTE: this should be hacked to read UUOSYM and make DECDFU too;
currently it does not, so CVTSW==1 will not yet work for TOPS-10!!
Normally on for TNX.
DECDBG (TOPS-10 only) leaves space for the assembler's symbol table
to be moved to after execution is started. This is useful when
debugging MIDAS with DEC DDT. Normally off.
DECBSW (TOPS-10 only) puts the DECBTS definitions in the predefined
symbol table. Normally on except for SAIL.
SMALSW builds a "small" MIDAS. This is normally only for random
TOPS-10 DEC sites which have severe core usage restrictions.
Some words about SYMBOLS and SYMBOL TABLES
When talking about "symbols" or "symbol tables", remember that
there can be several different contexts. Normally the reference is to
"THE" symbol table that MIDAS builds while assembling a program, which
contains all the symbols available to or defined by the program being
assembled. References to the "initial symbol table" also mean this
table; when starting to assemble a program, MIDAS has an unhashed table of
"initial symbols" which it uses to create an initial symtab for the
program.
However, MIDAS is itself a program and has its own symbol
table, which can be used by DDT to debug MIDAS. When talking about
this table the words "MSYMTAB" or "M symbol table" will be used, to
differentiate it from the symtab that MIDAS maintains for the program
it is assembling.
Remember that on ITS, a program's symbol table is (quite
rightly) NOT part of the program core image, although it is written
out in the same output file. On TNX and DEC however, the symbol table
must unfortunately be stored somewhere in the program's address space
and is pointed to by an AOBJN pointer at location 116 (.JBSYM). Generally
this area is set up by the linking loader, but MIDAS .DECSAV output can
force this to be wherever the location counter is when the "END" is seen.
|
IF1,[ ; Clean up initial flags defined from the TTY, if any
IFDEF SAILSW,IFN SAILSW,DECSW==1
IFDEF CMUSW,IFN CMUSW,DECSW==1
IFDEF DECDBG,IFN DECDBG,DECSW==1
IFDEF DECSW,IFN DECSW,DECSW==1 ? ITSSW==0 ? TNXSW==0
IFDEF ITSSW,IFN ITSSW,ITSSW==1 ? DECSW==0 ? TNXSW==0
IFDEF TNXSW,IFN TNXSW,TNXSW==1 ? DECSW==0 ? ITSSW==0
] ; IF1
; Select system to assemble for
IFNDEF ITSSW,ITSSW==IFDEF .IOT,[1] .ELSE 0 ;NON-ZERO => ITS VERSION
IFNDEF TNXSW,TNXSW==IFDEF GTJFN,[1] .ELSE 0 ;NON-ZERO => TENEX VERSION
IFNDEF DECSW,DECSW==IFDEF LOOKUP,[1-TNXSW] .ELSE 0 ;NON-ZERO => DEC VERSION
; COND. ON TNXSW SINCE OLD VERSIONS OF TENEX MIDAS HAD
; DEC UUOS DEFINED TOO ONCE UPON A TIME
IF1 IFN ITSSW+DECSW+TNXSW-1,.FATAL So what monitor is MIDAS supposed to run under?
IFN DECSW,[
IFNDEF SAILSW,SAILSW==IFDEF SPCWAR,[1] .ELSE 0 ;NON-ZERO => SAIL VERSION.
IFNDEF CMUSW,CMUSW==IFDEF CMUDEC,[1] .ELSE 0 ;NON-ZERO => CMU VERSION.
]
IFE DECSW,SAILSW==0 ? CMUSW==0 ;CAN'T BE SAIL OR CMU FOR ITS OR TENEX VERSION
IFNDEF CVTSW,CVTSW==TNXSW ;NON-ZERO => BITS DEFINITIONS COME FROM FILES
; MADE USING CVTUNV
IFNDEF SMALSW,SMALSW==DECSW-<CMUSW+SAILSW> ;NON-ZERO => SMALL MIDAS
; (NORMALLY FOR RANDOM DEC SITES ONLY)
IFNDEF DECBSW,DECBSW==DECSW*<1-SAILSW>*<1-SMALSW>
;NON-ZERO => INCLUDE DECBTS
IFNDEF DECDBG,DECDBG==0 ;NON-ZERO => DEC VERSION TO RUN WITH DEC DDT.
IFN ITSSW\DECSW\TNXSW,TS==1
IFNDEF TS,TS==1 ;NON-ZERO => TIME-SHARING VERSION
IFE TS,1PASS
IFNDEF A1PSW, A1PSW==TS ;NON-ZERO => 1PASS END-OF-PROGRAM AUTO-REASSEMBLY
IFNDEF BRCFLG, BRCFLG==0 ;NON-ZERO => BRACES { AND } ARE SPECIAL IN MACRO
; ARGS, ETC. JUST LIKE BRACKETS. BRACES ARE SPECIAL
; IN CONDITIONALS REGARDLESS OF BRCFLG.
IFNDEF CREFSW, CREFSW==ITSSW ;NON-ZERO => ALLOW C SWITCH TO CAUSE CREF OUTPUT.
IFNDEF LISTSW, LISTSW==1 ;NON-ZERO => ALLOW L SWITCH TO CAUSE A LISTING.
IFNDEF RCHASW, RCHASW==TS ;NON-ZERO => INCLUDE TTY AS POSSIBLE INPUT DEVICE
IFNDEF PURESW, PURESW==TS-SAILSW ;NON-ZERO => SEPARATE PURE CODING FROM IMPURE AND
; DO PAGE SKIPS. TWO SEGMENTS HURTS EFFICIENCY AT SAIL.
IFNDEF FASLP, FASLP==1-SMALSW ;NON-ZERO => INCLUDE FASL OUTPUT CAPABILITY
; NOTE!! IF RUNNING UNDER 10/50 THIS MAKES THINGS
; SEVERAL K BIGGER THAN OTHERWISE.
IFNDEF .I.FSW, .I.FSW==1-SMALSW;NON-ZERO => INCLUDE .I, .F
IFNDEF MACSW, MACSW==1 ;NON-ZERO => INCLUDE MACRO PROCESSOR (!)
IFNDEF RUNTSW, RUNTSW==1 ;NON-ZERO => TYPE OUT RUN TIME AT END OF ASSEMBLY
IFNDEF WRQTSW, WRQTSW==1 ;WRQOTE (MACRO DEFINITION READER) VERSION
; ^ 0 => SLOW, 1 => FAST; MAYBE 2 WILL EVENTUALLY BE CREATED
IFE TS,IFNDEF MACL,MACL==6*2000 ;MACRO TABLE SIZE
IFN TS,[
IFN ITSSW,IFNDEF MACL,MACL==6000;DEFAULT MACL SIZE FOR ITS. IF WE HAVE DECBTS OR
IFN TNXSW,IFNDEF MACL,MACL==16*2000 ; TWXBTS, THIS GETS INCREASED, CAUSE THEY ARE HUGE!
IFN DECSW,IFNDEF MACL,MACL==0 ;NON-ITS: WE WANT MACL TO JUST COVER THE INIT CODE.
IFNDEF MXMACL,MXMACL==32.*2000 ;MAXIMUM LENGTH MACTAB
]
IFNDEF MACRUM,MACRUM==4 ;# WORDS NOT USED AT END OF MACTAB
IFNDEF STRL,STRL==20 ;LENGTH OF STRING STORAGE (USED BY GSYL)
IFNDEF DMDEFL,DMDEFL==40 ;MAX NO OF DMY ARGS IN DEFINE
IFNDEF DMYAGL,DMYAGL==400 ;MAX NO COMBINED DMYARGS ALL MACROS CURRENTLY EXPANDING OR PUSHED
IFNDEF MPDLL,MPDLL==300 ;MACRO PDL LENGTH
IFNDEF DSSIZ,DSSIZ==40 ;MAX # ARGS MACRO WHOSE ARGS BEING SCANNED (SHOULD BE .GE. DMDEFL)
IFNDEF BKTABL,BKTABL==100 ;MAX NUM .BEGIN BLOCKS.
IFNDEF BKPDLS,BKPDLS==10 ;MAXIMUM .BEGIN BLOCK NESTING DEPTH.
IFNDEF BSIZE,BSIZE==37 ;PREFERRED SIZE BLOCK MAX SIZE-3
IFN SMALSW,IFNDEF LPDL,LPDL==200.
IFNDEF LPDL,LPDL==1500. ;LENGTH OF PDL
IFN SMALSW,IFNDEF CONMIN,CONMIN==1000
IFNDEF CONMIN,CONMIN==3300 ;MINIMUM AMT OF SPACE FOR CONSTANTS TABLES.
IFNDEF CONMAX,CONMAX==20000 ;MAXIMUM SPACE USER CAN ASK FOR.
IFNDEF NCONS,NCONS==100. ;MAXIMUM NUMBER OF CONSTANTS AREAS
IFNDEF NVARS,NVARS==25. ;MAX. NUM. VARIABLES AREAS.
;; MUST INCLUDE TONS OF SYSTEM DEFS
IFN DECBSW,IFNDEF SYMDSZ,SYMDSZ==4973. ;666.th prime
IFN TNXSW,IFNDEF SYMDSZ,SYMDSZ==7919. ;1000.th prime
IFN SMALSW,IFNDEF SYMDSZ,SYMDSZ==2003.
IFNDEF SYMDSZ,SYMDSZ==2707. ;DEFAULT # SYMS IN SYMTAB.
IFNDEF SYMMSZ,SYMMSZ==11657.*2 ;# SYMS IF JNAME IS MMIDAS.
IFNDEF SYMMAX,SYMMAX==60000 ;MAX SYMTAB SIZE (# SYMS)
IFNDEF FASBL,FASBL==400 ;WORDS USED FOR FASL OUTPUT BUFFER
; MUST HOLD STUFF ASSOC WITH ONE GROUP OF 9 CODE BYTES
IFNDEF FASATL,FASATL==2000 ;WORDS USED FOR FASL ATOM TABLE
; HOLDS PNAMES ETC OF ALL ATOMS AS WILL BE IN FASLOAD'S
; SYMTAB AT LOAD TIME
IFNDEF MINWPS,MINWPS==3 ;MIN # WORDS IN SYMTAB ENTRY
IFNDEF MAXWPS,MAXWPS==3 ;MAX # ALLOWED (WILL BE BIGGER SOME DAY)
IFNDEF NRMWPS,NRMWPS==3 ;DEFAULT #. 2 WDS FOR VALUE & FLAGS, 1 FOR NAME.
SUBTTL INITIAL DEFINITIONS
; AC definitions. FF and P must be 0 and 17 respectively, otherwise the
; only constraints are those expressed as sequential orderings, e.g. B+1 etc.
; Also,
.SEE R1
FF=:0 ; FLAGS. MUST BE AC 0.
AA=:1 ; GENERAL PURPOSE REGS, MUST BE SEQUENTIAL.
A=:AA+1 ; 2
B=:A+1 ; 3
C=:B+1 ; 4
D=:C+1 ; 5
T=:6 ; NOT SO TEMP AS IN MOST PROGS W/ T
TT=:T+1 ; 7
I=:10 ; INDICATOR FLAGS, CONTAIN INFO ON CURRENT SYL, FIELD, WORD; ALSO SEE UNRCHF
SYM=:11 ; FREQUENTLY CONTAINS SQUOZE SYM W/ FLAGS CLEAR
LINK=:SYM+1
F=:13
CH1=:14 ; MACRO PROCESSOR TEMP, CLOBBERED BY CALLS TO RCH
CH2=:CH1+1 ;" " "
TM=:16 ; SUPER TEMPORARY
P=:17 ; PDL AC, MUST BE 17. AS WELL AS RANDOM CROCKS IN PROGRAM, 20X ERCAL
; ASSUMES P=17.
IFDEF .XCREF, .XCREF FF,P,I,A,B,C,D,T
; VERSION, FLAGS, ETC.
IF1 [
IFNDEF MIDVRS,[
IFGE .FVERS,[
DEFINE XXX VRS
MIDVRS=SIXBIT/VRS/
TERMIN
RADIX 10.
XXX \.FVERS
RADIX 8
EXPUNGE XXX
]
.ELSE [
PRINTX /What is MIDAS version number? /
.TTYMAC VRS
MIDVRS=SIXBIT/VRS/
TERMIN
]
]
; OSMIDAS gets the sixbit name of the type of op. sys. this version of MIDAS
; is being assembled to run under. It will be the value of .OSMIDAS when
; programs are assembled with this MIDAS. Note that the TNX version actually
; sets it at runtime startup to "TENEX" or "TWENEX" as appropriate.
IFNDEF OSMIDAS,OSMIDAS==IFE TS,[SIXBIT/BARE/] .ELSE IFN ITSSW,[SIXBIT/ITS/] .ELSE IFN CMUSW,[SIXBIT/CMU/] .ELSE IFN SAILSW,[SIXBIT/SAIL/] .ELSE IFN TNXSW,[SIXBIT/TENEX/] .ELSE SIXBIT/DEC/
;FF FLAGS NOT PUSHED
;LEFT HALF
FL==1,,525252
FLPPSS==400000 ;ONE IF PUNCHING PASS; MUST BE SIGN
FLHKIL==100000 ;ONE IF SYM TO BE SEMI KILLED IN DDT
FLVOT== 40000 ;ALL RCH S MUST GO THRU RCH
; IE TYPCTL .NE. POPJ P, (SET/CLEARED BY MDSSET, MDSCLR)
FLMAC== 20000 ;ONE IF CHARS COMING FROM MACRO PROCESSOR, DON'T HACK CPGN/CLNN
FLTTY== 10000 ;ONE IF CHARS FROM SOMEWHERE ELSE BUT NOT HACKING CPGN/CLNN
$FLOUT== 4000 ;ONE IF OUTPUT HAS OCCURED IN CURRENT MODE (USED BY TS NED LOGIC)
FLPTPF== 2000 ;SET IF (TIME SHARING) OUTPUT DEVICE IS PTP
FLUNRD== 1000 ;=> RE-INPUT LAST CHARACTER (SEE RCH)
FL20X==400 ; IN TENEX VERSION, 1= RUNNING ON TOPS-20, 0 = TENEX.
;FF RIGHT HALF FLAGS
FR==525252
FRFIRWD==400000 ;ONE FOR FIRST WORD OF BLOCK
FRSYMS==200000 ;ONE IF SYM PUNCH DESIRED
FRLOC==100000 ;ONE BETWEEN ABS LOC ASSIGN AND
;FIRST BLOCK OUTPUT THEREAFTER (EBLK TO OUTPUT NULL BLOCK SO LINKING LOADER KNOWS $.)
FRNPSS==40000 ;ONE IF TWO PASS ASSEMBLY
FRPSS2==20000 ;ONE ON PASS 2
FRINVT==4000 ;USED BY PBITS AND OUTPUT TO OUTPUT WORDS OF CODE BITS IN CORRECT ORDER (STEAD LOGICAL)
FRNLIK==2000 ;TEMPORARILY SUPPRESS ADR LINKING
FRGLOL==1000 ;ONE IF LOCATION PLUS OFFSET IS GLOBAL
FRBIT7==400 ;SET IF LAST TIPLE OF CODEBITS WAS 7.
FRMRGO==200 ;MACRO PROC TO RETURN TO .GO HACKER W/O READING NEXT CHAR (SEE RCHSAV)
FRCMND==40 ;SET WHILE READING CMD, TELLS RFD TO NOTICE (, _, COMMA.
FRNNUL==20 ;SET ON RETURN FROM RFD IFF NONNULL SPEC.
FRARRO==10 ;TELLS RFD THAT 1ST NAME IS FN1, NOT FN2.
FRFN1==4 ; TELLS RFD THAT 1ST NAME WAS READ.
; FLAGS TO ZERO AT BEGINNING OF PASS 1 ONLY, BY $INIT.
FFINIT==<-1-FLVOT-FLPTPF-FLTTY-FL20X,,-1>
] ;END IF1
;INDICATOR REGISTER
IF1 [
;LEFT HALF
IL==1,,525252
ILGLI==1 ;SET ON " CLEARED EACH SYL
ILVAR==2 ;SET ON ' " " "
ILFLO==4 ;FLOATING NUM, SET ON DIGIT AFTER .
ILDECP==10 ;DECIMAL PREFER, SET WHEN . SEEN.
ILUARI==20 ;1 => RIGHT OPERAND TO UPARROW BEING READ
ILLSRT==40 ;RETURN FROM <
ILWORD==400 ;SET IF CURRENT WORD IS NOT NULL RETURNED BY GETWORD
ILNPRC==1000 ;ONE IF NUMBER ALREADY PROCESSED BY UPARROW
ILMWRD==4000 ;SET ON MULTIPLE WORD
ILPRN==10000 ;SET DURING MACCL IF MACRO NAME WAS FOLLOWED BY (.
ILMWR1==20000 ;SET BY LBRAK AS SIGNAL TO ITSELF THAT THIS NOT FIRST
;WORD OF MULTI-WORD CONSTANT
ILNOPT==40000 ;CONSTANTS OPTIMIZATION SUPPRESSION FLAG; SHOULD BE SET BY
;VALUE-RETURNING PSEUDO DURING NOT PUNCHING PASS TO KEEP ITSELF OUT OF
;CONSTANTS OPTIMIZATION
;RIGHT HALF
IR==525252
IRFLD==1 ;SET IF FLD NOT NULL
IRSYL==2 ;SET IF SYL NOT NULL
IRLET==4 ;SET IF SYL IS SYMBOL
IRDEF==10 ;SET IF CURRENT EXPR DEFINED
IRNOEQ==20 ;SET IF = ISN'T ALLOWED IN CURRENT CONTEXT.
IRCOM==40 ;SET IF CURRENT QUAN IS COMMON
IRPERI==100 ;SET IF PERIOD SEEN IN WHAT IS SO FAR (INCL .) A NUMBER
IREQL==200 ;ONE DURING READING WORD TO RIGHT OF =
IRIOINS==400 ;FIRST FIELD OF CURRENT WORD HAS IO INST
IRCONT==1000 ;SET IF NOT OK TO END BLOCK
IRPSUD==4000 ;SET IF ERROR COMMENTS WILL COME FROM PSEUDO
IRGMNS==20000 ;SET IF ILUARI OR BAKARI HAS GOBBLED MINUS
IROP==200000 ;SET IF OPERATOR SEEN IN CURRENT FIELD
CALL==PUSHJ P,
RET==POPJ P,
;SAVE=PUSH P, ;DON'T USE SAVE! IT'S A JSYS ON TENEX AND TWENEX
REST==POP P,
PJRST==JRST ; FOR JRST'ING TO A POPJ'ING ROUTINE.
ETSM=1000,, ;ERROR, TYPE SYM.
ETR=2000,, ;ERROR, ORDINARY MESSAGE.
ERJ=3000,, ;ERROR, NO MESSAGE, RETURN TO ADDR.
ETI=4000,, ;ERROR, IGNORE LINE, RET. TO ASSEM1.
ETA=5000,, ;ERROR, RET. TO ASSEM1.
ETASM=6000,, ;ERROR, TYPE SYM AND RETURN TO ASSEM1
ETF=7000,, ;FATAL ERROR.
TYPR=(37000) ;UUO, TYPE OUT ASCIZ STRING
TYPCR=(36000) ; LIKE TYPR BUT ADDS CR AT END.
] ;END IF1
IF1 [
;LINK TABLE (GLOTB), ACCUMULATES GLOBAL REFERENCES FOR CURRENT FROB (USUALLY WORD) TO OUTPUT
;GLSP2 POINTS TO (I.E. HAS ADR 1 LESS THAN) BOTTOM OF ACTIVE PART OF TABLE
;GLSP1 POINTS TO TOP (HAS ADR OF LAST ENTRY ACTIVE)
;ACTUAL ENTRIES IN GLOTB:
;IF ENTIRE WORD ZERO, ENTRY IS NULL, WILL (OR SHOULD) BE IGNORED
;RH ADR OF SQUOZE WITH INTERNAL MIDAS FLAGS (USUALLY IN SYMBOL TABLE, BUT MAY BE ANYWHERE IN CORE)
;LH: RIGHT 10. BITS MULTIPLICATION FACTOR OR 0 => 1
;GLOBAL SHOULD BE MULTIPLIED BY IT
;REST OF LH FLAGS:
;SIGN BIT => THIS NOT PART OF FIELD, DON'T PLAY WITH FLAGS AT GETFLD, INTFD
ACF==40000 ;AC LOW OR HIGH (SWAPF => HIGH)
HFWDF==100000 ;MASK GLOBAL TO HALFWORD
SWAPF==200000 ;SWAP
MINF==20000 ;NEGATIVE OF GLOBAL
IFNDEF LBRKT,LBRKT=="[ ;LEFT DELIMITER FOR EXPLICITLY GROUPED CONDITIONALS, MACRO ARGS, REPEAT BODY, ETC.
IFNDEF RBRKT,RBRKT=="] ;RIGHT "
IFNDEF WPS, WPS==3 ;# CONTIG. WDS /STE. IFNDEF FOR DEBUGGING.
IFNDEF BKWPB,BKWPB==3 ;# WDS/BKTAB ENTRY.
IFNDEF EOFCH,EOFCH==3 ;EOF CHAR, BEWARE DISPATCH TABLE ENTRIES.
IFNDEF LBRACE,LBRACE==173
IFNDEF RBRACE,RBRACE==175
;3RDWRD LH. SYM TAB BITS
3REL==600000 ;RELOC BITS, DO NOT CHANGE, SOMETIMES REFERENCED BY NUMERIC BYTE POINTERS
3RLL==400000 ;R(LH)
3RLR==200000 ;R(RH)
3RLNK==100000 ;R(LINK)
3KILL==40000 ;FULLY-KILLED SYM (DON'T GIVE TO DDT).
3VP==20000 ;VALUE PUNCHED
3SKILL==10000 ;SEMI KILL IN DDT
3LLV==4000 ;LINKING LOADER MUST INSERT VAL
3VAS2==2000 ;VAR SEEN ON PASS TWO WITH '
3VCNT==1000 ;USED IN CONSTANT
3MAS==400 ;THIS ISN'T THE LAST DEFINITION OF A SYM WITH THIS NAME
;(SO ES MUST KEEP SEARCHING).
3NCRF==200 ;DON'T CREF THIS SYMBOL.
3MACOK==100 ;OK TO (RE)DEFINE THIS SYM AS MACRO.
;(IE IS A MACRO OR SEEN ONLY IN .XCREF)
3LABEL==40 ;ILLEGAL TO REDEFINE THIS SYM TO DIFFERENT VALUE
3MULTI==20 ;THIS SYM IS MULTIPLY DEFINED, SO FLAG ALL DEFINITIONS.
3DOWN==10 ;THIS DEFINITION SHOULD BE SEEN BY SUBBLOCKS IN 1PASS MODE.
3DFCLR==737110 ;BITS IN LH TO CLEAR ON REDEFINITION.
; FLAGS IN "CONTROL" VARIABLE
.SEE CONTRL
;LEFT HALF
TRIV==400000 ; 1 IF OUTPUT FORMAT IS FOR TRIVIAL LOADER (ABSOLUTE)
; ELSE RELOCATABLE (NOTE THIS CROCKISHLY ONLY MEANS
; STINK FORMAT, SINCE DEC RELOC FORMAT HAS THIS FLAG SET)
;RIGHT HALF
ARIM== 2 ; 1 => OUTPUT FORMAT IS RIM
SBLKS== 10 ; 1 => OUTPUT FORMAT IS SBLK (SIMPLE BLOCKS)
ARIM10== 20 ; 1 => OUTPUT FORMAT IS PDP-10 RIM
DECREL== 40 ; 1 => DEC RELOCATABLE FORMAT (CONSIDERED "ABSOLUTE" INSIDE MIDAS)
FASL== 100 ; 1 => LISP FASL COMPATIBLE RELOCATABLE FORMAT ( " " ")
DECSAV==200 ; 1 => DEC SAV FORMAT (ABSOLUTE) ALSO WINS ON 10X, 20X
PTR==104 ;DEVICE CODE FOR PAPER TAPE READER.
] ;END IF1
IF1 [
;SQUOZE FLAG DEFINITIONS IN MIDAS SYMBOL TABLE
CMMN==0 ;COMMON (NOT USED)
PSUDO==40000 ;PSEUDO OR MACRO, VALUE RH ADDR OF RTN (MACCL FOR MACRO),
; LH WILL BE IN LH OF B WHEN RTN CALLED.
SYMC==100000 ;SYM, VALUE IS VALUE OF SYM.
LCUDF==140000 ;LOCAL UNDEF
DEFLVR==200000 ;DEF LOC VAR, VALUE IS VALUE.
UDEFLV==240000 ;UNDEF LOC VAR, VALUE IS 1+ IDX IN VARIAB. AREA, BUT IGNORD IF VAR AREA GLOB.
LGBLCB==300000 ;CODE BITS EQUAL TO THIS OR HIGHER REPRESENT GLOBAL QUANTITIES
DEFGVR==300000 ;DEF GLO VAR, VALUE IS VALUE
UDEFGV==340000 ;UNDEF GLO VAR, VALUE LIKE UNDEF LOCAL VAR.
GLOETY==400000 ;GLO ENTRY
GLOEXT==440000 ;GLO EXIT
NCDBTS==GLOEXT_<-18.+4>+1 ;# CODE BIT TYPES
DEFINE CDBCHK TBLNAM
IFN .-<TBLNAM>-NCDBTS,.ERR TBLNAM LOSES
TERMIN
;LOADER BLOCK TYPES LINK
LLDCM==1 ;LOADER COMMAND BLOCK
LABS==2 ;ABSOLUTE
LREL==3 ;RELOCATABLE
LPRGN==4 ;PROG NAME
LLIB==5 ;LIBRARY BLOCK
LCOMLOD==6 ;LOAD INTO COMMON
LGPA==7 ;GLOBAL PARAMETER ASSIGN
LDDSYM==10 ;LOCAL SYMS
LTCP==11 ;LOAD TIME COND ON PRESENCE
ELTCB==12 ;END LOAD TIME COND
LPLSH==22 ;POLISH FIXUP
;LOADER COMMANDS
;IN ADR OF LDCMD BLK
LCJMP==1 ;JUMP
LCGLO==2 ;GLOBAL LOC ASSIGN
LCCMST==3 ;SET COMMON BENCHMARK
LCEGLO==4 ;END OF GLOBAL BLOCK
LDCV==5 ;LOAD TIME COND ON VALUE
LDOFS==6 ;LOADER SET GLOBAL OFFSET
LD.OP==7 ;LOADER .OP
;LOADER CODEBITS SECOND SPEC AFTER 7
CDEF==0 ;DEF
CCOMN==1 ;COMMON REL
CLGLO==2 ;LOC-GLO REC
CLIBQ==3 ;LIBREQ
CRDF==4 ;GLO REDEF
CRPT==5 ;REPEAT GLOBAL VALUE
CDEFPT==6 ;DEFINE SYM AS $.
;DEC RELOCATABLE BLOCK TYPES.
DECWDS==1 ;STORAGE WORDS.
DECSYM==2 ;SYMBOL DEFS OR GLOBAL ADDITIVE RQS.
DECHSG==3 ;LOAD INTO HIGH SEG (FOR .DECTWO)
DECENT==4 ;ENTRY NAMES
DECEND==5 ;END BLOCK, HAS PROGRAM BREAK.
DECNAM==6 ;PROGRAM NAME.
DECSTA==7 ;STARTING ADDRESS BLOCK.
DECINT==10 ;INTERNAL REQUEST
DECRQF==16 ;REQUEST LOADING A FILE
DECRQL==17 ;REQUEST LOADING A LIBRARY
] ;END IF1
IF1 [
DEFINE GOHALT ; Instruction invoked for MIDAS internal error (fatal)
JSR HALTER
TERMIN
DEFINE TYPE &STR
TYPR [ASCIZ STR]
TERMIN
DEFINE TYPECR &STR
TYPCR [ASCIZ STR]
TERMIN
DEFINE PRINTA A,B,C,D,E,F
IF1,[PRINTC ~A!B!C!D!E!F
~]
TERMIN
IF1 [DEFINE BNKBLK OP
OP
TERMIN ]
;ADD A LINE TO BNKBLK, ACCUMULATED CONTENT OF
;WHICH IS DUMPED OUT AT END OF ASSEMBLY
;ARG TO BLCODE SHOULD BE FREE OF STORAGE WORDS
DEFINE BLCODE NEWCFT
IF1 [BNKBLK [DEFINE BNKBLK OP
OP]NEWCFT
TERMIN ]
IF2 [IRPW X,,[
NEWCFT
]
IRPS Y,,X
Y=Y
.ISTOP TERMIN TERMIN ] TERMIN
;3RDWRD MANIPULATING MACROS
;GET 3RDWRD INTO LH("A"), "B" HAS INDEX OF 1STWRD INTO SYMBOL TABLE
DEFINE 3GET A,B
MOVE A,ST+2(B)
TERMIN
;GET 3RDWRD INTO "A", "B" HAS ADR OF 1STWRD
DEFINE 3GET1 A,B
MOVE A,2(B)
TERMIN
;PUT "A" INTO 3RDWRD, "B" HAS INDEX OF 1STWRD INTO SYMBOL TABLE
DEFINE 3PUT A,B
MOVEM A,ST+2(B)
TERMIN
;PUT "A" INTO 3RDWRD, "B" HAS ADR OF 1STWRD
DEFINE 3PUT1 A,B
MOVEM A,2(B)
TERMIN
] ;END IF1
;RANDOM MACRO DEFINITIONS
IF1 [
;A HAS ADR OF SYM SQUOZE, SKIP IF IT'S IN SYMBOL TABLE
DEFINE SKPST A
CAIL A,ST
CAML A,MACTAD
TERMIN
;EXECUTE AN INSTRUCTION WITH VARIOUS ADDRESSES (USUALLY PUSH OR POP)
DEFINE INSIRP A,B
IRPS %ADR,,[B]
A,%ADR
TERMIN
TERMIN
DEFINE NOVAL
TDNE I,[ILWORD,,IRNOEQ\IRFLD]
ETSM ERRNVL
TERMIN
DEFINE NOABS
SKIPGE CONTRL
ETASM ERRABS
TERMIN
] ;END IF1
ERRNVL==[ASCIZ /Returns no value/]
ERRABS==[ASCIZ /Allowed only for STINK relocatable format/]
IF1 [
DEFINE MOVEIM B,C
MOVEI A,C
MOVEM A,B
TERMIN
DEFINE MOVEMM B,C
MOVE A,C
MOVEM A,B
TERMIN
] ;END IF1
IF1 [
IFN 0,[
;THESE ARE SOME MACRO DEFINITIONS FOR THE UNFINISHED MULTI-WORD
;SYMBOL NAME FEATURE. FOR COMPATIBILITY, THEY ALL NOW HAVE DEFINITIONS
;THAT ONLY HANDLE ONE WORD. THOSE OTHER DEFINITIONS COME AFTER THESE.
DEFINE TYPE2 X=SYM
MOVE A,X
CALL SYMTYP
IFSN X,SYM,SKIPE A,X+1
.ELSE SKIPE A,SYMX
CALL SYMTYP
TERMIN
DEFINE COPY2 X,Y,Z=USING A
MOVE Z,X
MOVEM Z,Y
MOVE Z,X+1
MOVEM Z,Y+1
TERMIN
DEFINE STORE2 AC,Y,Z=USING A
MOVEM AC,Y
MOVE Z,AC!X
MOVEM Z,Y+1
TERMIN
]
.ELSE [
;THESE ARE THE DEFINITIONS OF THE MACROS THAT DO NOT IMPLEMENT
;MULTI-WORD SYMBOL NAMES.
DEFINE TYPE2 X=SYM
MOVE A,X
CALL SYMTYP
TERMIN
DEFINE COPY2 X,Y,Z=USING A
MOVE Z,X
MOVEM Z,Y
TERMIN
DEFINE STORE2 AC,Y,Z=USING A
MOVEM AC,Y
TERMIN
]
DEFINE USING X
X,TERMIN
] ;END IF1
SUBTTL DEFINE SYS DEPENDENT SYMBOLS & SELECT OUTPUT FORMAT
; THIS DEFSYM MACRO IS FOR COMPILING MIDAS ON ANOTHER OPERATING SYSTEM. THIS
; AVOIDS SAME-NAME SCREWS (IE, "LOCK" IS SOMETHING DIFFERENT ON TWENEX, SAIL,
; AND DEC).
IF1 [
; Expunge symbol unless it's a pseudo or macro, in which case the redefinition
; will complain about it.
DEFINE DEFSYM X/
IRPS Z,,[X]
IFN <1-.TYPE Z,>, EXPUNGE Z
.ISTOP
TERMIN
X
TERMIN
]; IF1
IFN DECSW\TNXSW,[
IF1 [
IFN TNXSW, EQUALS TEM,.SYMTAB ; Preserve definition in case def files lose
; This is currently the only symbol conflict
; between MIDAS and TOPS-20.
IFE CVTSW,[
; INSERT UUO DEFINITIONS FILES AS APPROPRIATE.
IFE CMUSW\SAILSW\TNXSW,.INSRT DECDFS
IFN SAILSW, .INSRT SAIDFS
IFN CMUSW, .INSRT CMUDFS
IFN TNXSW, .INSRT TNXDFS
;ACTUALLY DEFINE THE UUOS USING THE MACROS READ FROM THE FILES.
IFN DECSW,.DECDF DEFSYM
IFN TNXSW,.TNXDF DEFSYM
;INSERT THE BITS DEFINITION FILES AS APPROPRIATE.
;THESE MUST BE INSERTED EVEN IF THEY ARE PREDEFINED, BECAUSE
;THE MIDAS SYMBOL TABLE IS CONSTRUCTED FROM THE DEFINITIONS IN THIS ASSEMBLY
;OF THOSE SYMBOLS, AND THAT MEANS WE NEED THE LATEST VERSION ASSEMBLED IN.
IFN TNXSW, .INSRT TWXBTS
IFN DECBSW,.INSRT DECBTS
];IFE CVTSW
; If using CVTUNV then there is just one file which is the converted
; contents of the MONSYM.UNV file for the system; the xxxDFS and xxxBTS files
; are not needed. There are no special SAIL or CMU versions.
IFN CVTSW,[
IFN DECSW, .INSRT DECDFU
IFN TNXSW, .INSRT TNXDFU
] ;IFN CVTSW
IFN TNXSW,[ ; AC DEFS FOR DIRECT REFERENCE TO JSYS ARGS
R1==:1 ; SOMEDAY MAYBE THE SYMBOLS A,B ETC WILL CORRESPOND...
R2==:2
R3==:3
R4==:4
R5==:5
]
IFN TNXSW, EQUALS .SYMTAB,TEM
] ;IF1
IFN DECSW,[ ; SELECT OUTPUT FORMAT FOR DEC VERSION
IFN PURESW,.DECTWO
IFE PURESW,.DECREL
RL0==.
]
IFN TNXSW,[ ; SELECT OUTPUT FORMAT FOR TNX VERSION
IFNDEF DECSVF,[ ; NORMALLY, USE .DECSAV IF AVAILABLE, ELSE .DECREL,
DECSVF==0 ; BUT USER CAN OVERRIDE THAT BY SPECIFYING DECSVF.
IFDEF .DECSAV,DECSVF==1
]
IFN DECSVF,.DECSAV
.ELSE [ IFN PURESW,.DECTWO
.ELSE .DECREL
]
RL0==0
]
] ;IFN DECSW\TNXSW
IFN ITSSW,[
IF1 [IFNDEF .IOT,[.INSRT SYS:ITSDFS
.ITSDF DEFSYM
] ;IFNDEF .IOT
IFNDEF %PIPDL,.INSRT SYS:ITSBTS
EXPUNG .JBTPC,.JBCNI
DEFINE SYSCAL A,B
.CALL [SETZ ? SIXBIT/A/ ? B ((SETZ))]
TERMIN
] ;IF1
IFDEF .SBLK,.SBLK ; SELECT OUTPUT FORMAT FOR ITS VERSION
RL0==0
] ;IFN ITSSW
IFE PURESW,[ ;FOLLOWING IF NOT ASSEMBLING PURE CODING
DEFINE PBLK
TERMIN
DEFINE VBLK
TERMIN
]
IFN PURESW,[ ;FOLLOWING IF ASSEMBLING PURE CODING
; MIDAS MEMORY ORGANIZATION
; General
; First come several pages of impure coding (no dynamic allocation).
; The BLCODE macro accumulates "blank" (zero wd) coding to be put at end of
; impure coding; no non-zero storage words allowed.
; Then comes the symbol table at ST, followed by the literals tables, followed
; by the macro table. The latter two are peculiar because they can both
; be shifted upwards if the symbol table size is increased at the start of
; assembly.
; The macro table initially starts at MACTBA (actual addr in MACTAD)
; and is even more peculiar because there is a lot of symbol initialization
; coding there, including a unhashed table of "initial symbols", which is
; wiped out by the first macro definition.
; Finally there is a "gap" of unused pages, followed by the pure
; code of MIDAS at location MINPUR*2000.
; Page(addr) End+1
; 0 (BBKCOD) Impure coding (VBLK)
; MINBNK 1st completely blank page (above BBKCOD)
; (BBKCOD) (EBKCOD) Blank code (BLCODE) all zeros
; (ST) varies Symbol table starts here
; *(CONTAB) Literal table
; MINMAC Page # that MACTBA starts in
; *(MACTBA) Start of initialization coding + initial syms
; MXICLR MXIMAC Empty pages above initial coding reserved
; for initial macro table.
; MXIMAC MAXMAC Unused pages but can expand into.
; MAXMAC 1st page macro table prevented from using
; "gap" Never-used pages between impure and pure
; MINPUR MAXPUR Pure code (PBLK)
; -
; 1STBFP/2 varies TNX only, input file page buffers
; * - the literal and macro tables are subject to being shifted by symtab
; expansion. The macro table can dynamically expand up to MAXMAC.
IFN DECSW\TNXSW,MINPUR==200
IFN ITSSW,MINPUR==200 ; Page number beginning pure coding
;PURE CODING UNTIL MAXPUR*2000-SOMETHING
;THE FOLLOWING MACROS AND BLCODE MAKE IT NOT COMPLETELY NECESSARY
;TO SEPARATE PURE CODING FROM IMPURE
CKPUR==0 ;0 => ASSEMBLING BELOW THE GAP, 1 ABOVE
; PBLK - SWITCH TO CODING ABOVE THE GAP
DEFINE PBLK
IFN CKPUR,.ERR PBLK
IFE CKPUR,[VAR.LC==.
LOC PUR.LC
]CKPUR==1
TERMIN
; SET INITIAL LOCATION COUNTER FOR ASSEMBLING PURE CODE ABOVE GAP.
IFN ITSSW, PUR.LC==MINPUR*2000
IFN DECSW, PUR.LC==MINPUR*2000+RL0
IFN TNXSW,[
IFN DECSVF,PUR.LC==MINPUR*2000
.ELSE PUR.LC==MINPUR*2000+20 ;SKIP VESTIGIAL JOBDAT AREA.
]
; VBLK - SWITCH TO CODING BELOW THE GAP
DEFINE VBLK
IFE CKPUR,.ERR VBLK
IFN CKPUR,[PUR.LC==.
LOC VAR.LC
]CKPUR==0
TERMIN
IFN TNXSW,IFE DECSVF,LOC 200
PBLK ;PBLK NORMAL MODE, VARIABLE AREAS BRACKETED WITH VBLK AND PBLK
] ;END PURESW CONDITIONAL
.YSTGW ;SET UP NOW, STORAGE WORDS OK
FOO==.
LOC 41
JSR ERROR
IFN ITSSW,JSR TSINT
IFN DECSW,[
LOC .JBAPR
TSINT1
]
LOC FOO
;DISPATCH TABLE FOR NON-SQUOZE CHARACTERS
;REFERENCED AS DTB-40(RH OF POPJ IN GDTAB)
;DTB ENTRY OF SYL TERMINATOR PUT IN CDISP BY GETSYL
DSYL==400000 ;SYL OPERATOR, DISPATCH INDEXED BY RH AT GETSYL (MUST BE SIGN)
DFLD==200000 ;FIELD OPERATOR, GETFD
DWRD==100000 ;WORD OP, GETWD
DSY1==1000 ;SET ONLY IF DSYL SET,
;SET IF OP MIGHT BE 1ST CHAR OF NONNULL SYL.
DSYL1==DSYL+DSY1
DSY2==400 ;SET FOR _ ONLY.
;ALL CLEAR => WORD TERMINATOR, NO DISPATCH
DTB: DWRD,,SPACE ;40 SP, TAB, RUBOUT
DSYL1,,RRL2 ;EXCLAIM AND OPEN-BRACE
DSYL1,,DQUOTE ;"
DFLD,,XORF ;NUM SIGN
DSYL,,RBRAK2 ;CLOSE-BRACE.
0 ;(USED TO BE PERCENT SIGN)
DFLD,,ANDF ;AMPERSAND
DSYL1,,SQUOTE ;'
DFLD,,LEFTP ;( 50
DSYL,,RPARN ;)
DFLD,,MULTP ; STAR TIMES
DFLD,,PLS ;+ PLUS
DWRD,,COMMA ; ,
DFLD,,MINUS ;-
DSYL1,,CTLAT ;^@ (56)
DFLD,,DIVID ;/
DSYL1,,COLON ;COLON 60
DSYL,,SEMIC ;SEMI
DFLD,,LSSTH ;<
DSYL1,,EQUAL ;=
DSYL,,GRTHN ;>
0 ;?
DSYL1,,ATSGN ;AT SIGN
DFLD,,LBRAK ;[
DFLD,,IORF ;BACKSLASH 70
DSYL,,RBRAK ;]
DSYL1,,UPARR ;^
DSYL+DSY2,,BAKAR ;BACKARR
0 ;CR
0 ;(USED TO BE TAB)
0 ;ALL OTHER
DSYL,,LINEF ;LF (DSYL TO HACK CLNN)
DSYL,,FORMF ;FORM FEED (") 100
;NOTE THAT POPJ P, IS VALID TEST FOR SQUOZENESS
;EXCEPT FOR EOFCH
GDTAB: POPJ P,56 ; ^@ GETS IGNORED.
REPEAT 2,POPJ P,76 ;(GDTAB GLOBAL SO OUT OF TS, AIO CAN CLOBBER GDTAB+141 WITH JRST RREOF
;ON OLD FILES)
IFN .-GDTAB-EOFCH,.ERR EOFCH DOESN'T AGREE WITH GDTAB.
IFE TS,[POPJ P,76] IFN TS,[JRST RREOF]
REPEAT 5,POPJ P,76
POPJ P,40 ; TAB
POPJ P,77 ; LF
POPJ P,76 ; VERT TAB
POPJ P,100 ; FORM FEED
POPJ P,74 ; CR
REPEAT "!-16-1,POPJ P,76
POPJ P,40 ; SPACE
POPJ P,41 ; !
POPJ P,42 ; "
POPJ P,43 ; #
ADD SYM,%$SQ(D) ; $
ADD SYM,%%SQ(D) ; %
POPJ P,46 ; &
POPJ P,47 ; '
POPJ P,50 ; (
POPJ P,51 ; )
POPJ P,52 ; *
POPJ P,53 ; +
POPJ P,54 ; ,
POPJ P,55 ; -
JSP CH1,POINT ; .
POPJ P,57 ; /
REPEAT 10.,JSP CH2,RR2 ; DIGITS
POPJ P,60 ; :
POPJ P,61 ; ;
POPJ P,62 ; <
POPJ P,63 ; =
POPJ P,64 ; >
POPJ P,65 ; ?
POPJ P,66 ; @
IFDEF .CRFOFF,.CRFOFF
IRPC Q,,ABCDEFGHIJKLMNOPQRSTUVWXYZ
ADD SYM,%!Q!SQ(D)
TERMIN
POPJ P,67 ; [
POPJ P,70 ; \
POPJ P,71 ; ]
POPJ P,72 ; ^
POPJ P,73 ; _
POPJ P,76 ; NOW LOWER CASE GRAVE ACCENT
IRPC Q,,ABCDEFGHIJKLMNOPQRSTUVWXYZ
ADD SYM,%!Q!SQ(D)
TERMIN
IFDEF .CRFON,.CRFON
POPJ P,41 ;{
POPJ P,76 ;|
POPJ P,44 ;}
POPJ P,76 ;~
POPJ P,40 ; RUBOUT, LIKE SPACE
IFN .-GDTAB-200,.ERR GDTAB LOSES
NSQTB: IFDEF .CRFOFF,.CRFOFF
IRPC Q,,0123456789
ADD SYM,%!Q!SQ(D)
TERMIN
IRPC Q,,ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$%.
%!Q!SQ: 0
SQUOZE 0,Q/50/50/50/50/50
SQUOZE 0,Q/50/50/50/50
SQUOZE 0,Q/50/50/50
SQUOZE 0,Q/50/50
SQUOZE 0,Q/50
SQUOZE 0,Q
TERMIN
IFDEF .CRFON,.CRFON
;FORMAT TABLE(S)
;4.9-4.4 ETC SPECIFY SHIFT
;4.4-3.6 ETC SPECIFY NUMBER BITS
;FIELD SPECS IN REVERSE ORDER
IFORTB: 0 ;NCNSN 10 ,
0 ;NCNSF 11 IMPOS
0 ;NCNCN 12 ,,
2200,, ;NCNCF 13 ,,C
2200000000 ;NCFSN 14 ,B
0 ;NCFSF 15 ,B C
0 ;NCFCN 16 ,B,
0 ;NCFCF 17 ,B,C
4400000000 ;FSNSN 20 A
0 ;FSNSF 21 IMPOS
0 ;FSNCN 22 IMPOS
0 ;FSNCF 23 IMPOS
2200440000 ;FSFSN 24 A B
2200220044 ;FSFSF 25 A B C
270400440000 ;FSFCN 26 A B,
2227040044 ;FSFCF 27 A B,C
4400000000 ;FCNSN 30 A,
0 ;FCNSF 31 IMPOS
22220000 ;FCNCN 32 A,,
2200002222 ;FCNCF 33 A,,B
2200440000 ;FCFSN 34 A,B
0 ;FCFSF 35 A,B C
0 ;FCFCN 36 A,B,
0 ;FCFCF 37 A,B,C
FRTBL==.-IFORTB ;LENGTH OF FORMAT TABLE
VBLK
FORTAB: BLOCK FRTBL ;ACTUAL FORMAT TABLE
FRTBE=.-1
PBLK
;VARIABLE STORAGE
VBLK
RETURN: JRST . ;RH HAS RETURN ADR FOR END OF MAJOR ROUTINE (E.G PASS 2)
CDISP: 0 ;CURRENT DISPATCH CODE
PPRIME: 0 ;PUSH DOWN LIST MARKER (GETFLD)
SCNDEP: 0 ;DEPTH IN SUCCESSFUL BRACKET CONDITIONALS INSIDE INNERMOST LITERAL.
CONDLN: 0 ;LINE NUMBER AT WHICH LAST TOP LEVEL SUCCESSFUL CONDITIONAL ENCOUNTERED
CONDPN: 0 ;PAGE NUMBER-- PRINT THESE IF REACH END AND CONDITIONAL NOT TERMINATED
CONDFI: 0 ;SIXBIT FN1 OF FILE CONTAINING LAST TOP LEVEL SUCCESSFUL CONDITIONAL.
A.SUCC: 0 ;NONZERO IFF LAST CONDITIONAL SUCCEEDED.
ASMOUT: 0 ;0 NORMAL, 1 WITHIN <>, 2 IN (), 3 IN [].
ASMDSP: ASSEM3 ;PLACE TO JUMP TO FROM ASSEM1 LOOP.
;ASSEM3 NORMAL. ASSEMC IF WITHIN <>, () OR []
;AND .MLLIT ISN'T POS. LSSTHA AFTER > OR ) SEEN.
;[ ;CONND AFTER ] SEEN.
ASMDS1: 0 ;ASMDSP SAVED HERE DURING ASCII, SIXBIT PSEUDOS.
ASSEMP: 0 ;RESTORE P FROM HERE AT ASSEM1. SAVED OVER LITERAL.
ASMI: 0 ;REINIT I AT ASSEM2 FROM ASMI.
GLSPAS: 0 ;RESTORE GLSP1 AT ASSEM1. SAVED OVER LITERAL.
GLSP1: 0 ;POINTER TO BOT OF LINKAGE TABLE IN USE HIGH ADR
GLSP2: 0 ;POINTER TO TOP OF LINKAGE TABLE IN USE LOW ADR
FORMAT: 0 ;ACCUMULATES FORMAT WORD
FORPNR: 0 ;POINTER INTO FORMAT WORD, SHOULD BE FORMAT+1 SO CLOBBERABLE BY LAST IDPB
FLDCNT: 0 ;NUMBER OF FIELDS PUSHED DOWN IN CURRENT WORD
WRD: 0 ;ACCUMULATES VALUE OF WORD
WRDRLC: 0 ;RELOC OF WRD, MUST COME RIGHT AFTER WRD.
T1: 0 ;TEMP
T2: 0 ;TEMP
PBITS1: 0 ;CURRENT CODE BITS
PBITS2: 0 ;NO OF SPECS LEFT IN CURRENT WORD
PBITS4: 0 ;POINTER TO WHERE CURRENT CODE BITS WILL GO
OPT1: 0 ;POINTER FOR STORING IN BKBUF (OUTPUT BUFFER)
CONTRL: 0 ;FLAG REG FOR IO CONTROL ETC, .GE. 0 => RELOCATABLE/1PASS
CDATBC: 0 ;CURRENT DATA BLOCK CODE TYPE
SCKSUM: 0 ;CKSUM FOR SIMPLE BLOCK FORMAT
IFN A1PSW,[
PRGC: -1 ;ONE LESS THAN # TIMES END HAS BEEN ENCOUNTERED
OUTN1: -1 ;.GE. 0 => OUTPUT HAS OCCURED IN OTHER THAN 1PASS MODE (NOT INITIALIZED)
OUTC: -1 ;.GE. 0 => OUTPUT HAS OCCURED DURING CURRENT ASSEMBLY
]
LINKL: 0 ;SAVE LIMIT OF GLOTB GETWRD
STRCNT: 0 ;COUNT OF CHARS READ (INCL. DELIM) BY GSYL
STRPNT: 0 ;TEMP AT GSYL, BYTE POINTER TO STRING STORAGE
ISYMF: -1 ;-1 IF ISYMS HAVE NOT BEEN SPREAD
SMSRTF: -1 ;-1 BEFORE SYMTAB IS COMPACTED AND SORTED.
;AFTER COMPACTING, HOLDS NUMBER OF SYMS THAT WERE THERE BEFORE COMPACTING.
BITP: 0 ;BYTE PNTR TO CODE BITS IN CURRENT (RELOC) BLOCK
LDCCC: 0 ;DEPTH IN LOADTIME CONDS
PARBIT: 0 ;0 OR 4 FOR : OR = (IN GENERAL, TEMP AT P7X)
LABELF: 0 ;-1 IN COLON, SOMETIMES IN EQUAL. CAUSES 3LABEL TO BE SET.
STGSW: 0 ;NON ZERO GIVES ERROR PRINT ON STORAGE WORDS
HKALL: 0 ;NONZERO => HALF-KILL ALL LABELS (.HKALL'S VALUE)
LITSW: 0 ;-1 => USING A LITERAL GIVES AN ERROR
QMTCH: 0 ;-1 => ' AND " NEED MATCHING CLOSINGS (A LA FAIL, MACRO-10)
STARTA: 0 ;STARTING ADDRESS FOR SBLK, RIM, DECSAV
DECSYA: 0 ; ADDRESS TO LOAD SYMBOLS AT (FOR DECSAV FORMAT)
DECBRK: 0 ;LARGEST RELOC. ADDR. LOADED INTO. (USED FOR DEC FMT)
DECBRA: 0 ;LARGEST ABS. ADDR LOADED INTO.
DECBRH: 0 ;LIKE DECBRK BUT FOR ADDRS IN HI SEG.
DECTWO: MOVE ;NOT = MOVE => .DECTWO WAS DONE, AND THIS WD HAS
;ADDR START OF HISEG.
ISAV: 0 ;I FROM FIELD AT AGETFLD
A.PASS: 0 ; .PASS INTSYM, # OF THIS PASS.
A.PPAS: 0 ;.PPASS INTSYM, # OF PASSES.
WPSTE: NRMWPS ;# WORDS PER SYMTAB ENTRY
WPSTE1: NRMWPS-1;ONE LESS THAN WPSTE - FOR SPEED.
WPSTEB: ,-NRMWPS(B) ;RH HAS - # WORDS PER SYMTAB ENTRY; LH HAS INDEX OF B.
SYMSIZ: 0 ;#WDS IN SYMTAB = WPS*<SYMLEN>
SYMLEN: SYMMSZ ;SYMTAB SIZE (# SYMS)
;ASSEMBLED-IN VALUE USED AS DEFAULT, ONLY IF NON-TS.
SYMAOB: 0 ;-<# SYMS>,,0
INICLB: 0 ;-1 IF INITIALIZATION CODE CLOBBERED.
TTYINS: 0 ;AT START OF ASSEMBLY, -1 => .INSRT TTY PASS1, -2 => PASS2 ALSO.
IFN FASLP,[
FASBP: 0 ;PNTR TO FASL OUTPUT BUFFER
FASATP: 0 ;PNTR TO FASL ATOM TABLE
FASAT1: 0 ;PNTR TO FASL ATOM TABLE AFTER READING IN NEW ATOM
; (MAYBE UPDATE FASATP TO THIS IF ATOM WAS UNIQUE9
FASAT2: 0 ;BYTE PNTR USED TO STORE ATOM IN
FASIDX: 0 ;INDEX NEXT ATOM LOADED INTO FASAT WILL BE
FASPCH: 0 ;AMOUNT OF FASAT "PUNCHED"
FASCBP: 440400,,FASB ;BYTE PNTR TO FASL CODE BIT WORD
FASPWB: 0 ;FASL CODE AT PWRD
FASBLC: 0 ;LOSING BLOCK "COUNT"
FASBLS: 0 ;LOSING BLOCK "SYMBOL"
AFRLD: 0 ;LIST READ CURRENT DEPTH
AFRLEN: 0 ;LIST READ CURRENT LENGTH
AFRDTF: 0 ;LIST READ DOT CONTEXT FLAG (0 NORMAL, 1 SAW DOT, 2 SAW "FROB AFTER DOT"
AFRFTP: 0 ;LIST READ SAVED STATE OF FASATP
AFLTYP: 0 ;TYPE LIST OP IN- 0 EVAL AND THROW AWAY VALUE
;1 "RETURN" LIST
;2 "RETURN" VALUE OF LIST
]
PBLK
;INFO CONVENIENT TO ANYONE GENERATING AN OUT OF TIME-SHARING MIDAS
;MIDAS OUT OF TIME-SHARING ASSEMBLES INTO A COLLECTION OF SUBROUTINES
;IO IS EXPECTED TO BE HANDLED BY OTHER PROGRAMS.
;EXITS FROM THE ASSEMBLER:
;TPPB OUTPUT BINARY WORD IN A
;TFEED IF OUTPUT DEVICE IS PTP, PUNCH OUT # FRAMES OF BLANK TAPE
;SPECIFIED BY B, MAY CLOBBER A AND B
;GO9 RETURN POINT FROM FATAL ERRORS
;TYO TYPE OUT CHARACTER IN A
;TAB TYPE OUT A TAB (MAY CLOBBER A OF COURSE)
;RCHTBL SEE THE RCH ROUTINES
;ENTRIES
;PDL, LPDL MAY BE USED BY COMMAND PROCESSOR BUT WILL BE CLOBBERED BY MAIN ROUTINES
;MAIN ROUTINES, CALLED WITH JSP A, , CLOBBER THE WHOLE WORLD (INCLUDING P)
;INIT INITIALIZE
;PS1 PASS 1
;PLOD IF APPROPRIATE, PUNCH OUT LOADER
;PS2 PASS 2 (DOES ITS OWN PARTIAL INITIALIZATION)
;PSYMS PUNCH OUT SYMBOL TABLE
;OTHER ENTRIES
;CONTRL AFTER ASSEMBLY, .GE. 0 => RELOCATABLE, .LT. 0 => ABSOLUTE
;ISYMF -1 IF SYMS HAVE NOT BEEN SPREAD, ELSE DON'T TRY TO ADD TO INITIAL SYMBOL TABLE
;SMSRTF -1 IF SYMTAB HASN'T BEEN SORTED, ELSE SYMTAB CLOBBERED, DON'T RE-ASSEMBLE
;MIDVRS .FNAM2 OF MIDAS ENGLISH
;SOME FF FLAGS ARE GLOBAL SO COMMAND PROCESSOR CAN KNOW WHAT'S HAPPENED ON RETURN
;COMMAND PROCESSOR MAY ADD TO INITIAL SYMBOL TABLE BEFORE CALLING INIT THE FIRST TIME
;EISYMT IS THE FIRST LOCATION OK TO DUMP INTO
;EISYMP RH SHOULD BE SET BY COMMAND PROCESSOR TO FIRST LOC NOT DUMPED INTO
;INTSYM RH OF SYMTAB VALUE TO RETURN VALUE ADDRESSED BY LH(SYMTAB ENTRY)
;RCH HAS AN ELABORATE SET OF GLOBALS, WHICH I DON'T FEEL LIKE PUTTING DOWN NOW, BUT THEY INCLUDE
;RCH (GET CHAR) SEMIC, RRL1, RREOF, SEMICR, SEMIC, TYPCTL, GDTAB, CPGN, CLNN,
;RCHMOD, MDSCLR, MDSSET, RCHSET, POPLMB, PSHLMB
;ALSO RCHTBL ONLY EXIT
;LISTING FEATURE GLOBALS:
;PILPT PRINT CHAR IN A
;LISTON LISTING ON/OFF FLAG, -1 => ON
;LISTP SAME WORD AS LISTON.
;LISTP1 POSITIVE => LIST EVEN ON NON-PUNCHING PASS.
;LPTCLS END OF LISTING, PRINT FORM FEED, IF TS THEN CLOSE LPT
;CREF FEATURE GLOBALS:
;CRFOUT OUTPUT WORD IN A.
;CREFP -1 => REQUEST GENERATION OF CREF OUTPUT.
;THE RUBOUT-B-^W HEADER, THE SET-SOURCE-FILE BLOCK, AND THE EOF BLOCK
;ARE THE RESPONSIBILITY OF THE COMMAND PROCESSOR.
;;RCH ;CHARACTER INPUT ROUTINES
IFN RCHASW\MACSW,[
;SAVE LIMBO1 STATUS AND RH(B)
;THEN SET UP FOR NEW INPUT MODE (DESCRIPTOR IN A)
;CALLED BY PUSHEM AND PUSHTT
PSHLMB: HRL B,LIMBO1 ;LAST CHARACTER INPUT
TLZE FF,FLUNRD ;RE-INPUT CHARACTER ON RETURN?
XCT LSTPLM ;SET B'S SIGN; IF LISTING, JRST PSHLML.
PSHLMN: EXCH A,RCHMOD ;GET OLD MODE IN A
DPB A,[360500,,B] ;STORE IN 5 OF HIGH 6 BITS IN B
PUSH F,B ;SAVE RESULTANT CRUD
CAMN A,RCHMOD ;COMPARE NEW WITH OLD
POPJ P, ;SAME => SKIP OVERHEAD OF SETTING NEW MODE
MOVE A,RCHMOD ;NOW GET NEW MODE
JRST PSHLM1 ;SET UP INSTRUCTIONS FOR NEW MODE
IFN LISTSW,[
;IF LISTING, LSTPLM HOLDS JRST PSHLML
PSHLML: AOSN PNTSW
JRST PSHLMM ;LAST WAS BREAK CHR
REPEAT 4,IBP PNTBP
SOSA PNTBP
PSHLMM: SETOM LISTBC
TLO B,400000
JRST PSHLMN
]
;UNDO A PSHLMB (NOTE: IN COMMENTS BELOW, "NEW" MODE IS ON PDL, OLD IN RCHMOD)
POPLMB: POP F,A ;GET WORD THAT PSHLMB PUSHED
HLRZS A ;JUST INTERESTED IN LEFT HALF
TRZE A,400000 ;SIGN BIT SET?
TLOA FF,FLUNRD ;YES, SET FLAG TO RE-INPUT LAST CHAR
TLZA FF,FLUNRD ;NO, CLEAR FLAG.
XCT POPLML ;JFCL\IDPB A,PNTBP ;THE LATTER IFF LISTING.
SETZM LIMBO1 ;INITIALIZE FOR DPB
DPB A,[700,,LIMBO1] ;RESTORE LIMBO1
LSH A,-<18.-6> ;RIGHT JUSTIFY RCHMOD DESCRIPTOR
CAMN A,RCHMOD ;COMPARE NEW MODE WITH OLD
POPJ P, ;SAME => SKIP OVERHEAD OF SETTING NEW MODE
JRST RCHSET ;SET UP FOR NEW MODE AND RETURN
]
FOO==0 ;INITIALIZE COUNTER FOR FOLLOWING
DEFINE RCHBLT SIZE,ADR/
MOVSI T,FOO(A)
HRRI T,ADR
BLT T,<SIZE>-1+ADR
FOO==FOO+<SIZE>
TERMIN
DEFINE RCHMOV ADR/
MOVE T,FOO(A)
MOVEM T,ADR
FOO==FOO+1
TERMIN
;SET UP FOR INPUT OF MODE TYPE SPECIFIED IN A, CLOBBER A ONLY
RCHSET: MOVEM A,RCHMOD ;STORE NEW RCHMOD
PSHLM1: TLZ FF,FLMAC\FLTTY ;CLEAR FLAGS (MAYBE DEVICE ROUTINE SETS ONE)
XCT RCHTBL(A) ;GET IN A A POINTER TO A DESCRIPTOR TABLE (MAYBE ALSO SET FLAG)
PUSH P,T ;SAVE T, NEED IT FOR TEMP
RCHBLT 3,RCH2 ;FIRST 3 WORDS RCH2
TLNE FF,FLVOT
JRST POPTJ ;ALL RCH'S TO GO THROUGH RCH, DON'T DO ANYTHING ELSE
MDSST1: RCHBLT 3,RR1 ;NEXT 3 RR1
RCHMOV RRL1 ;NEXT WORD RRL1
RCHPSN==FOO ;# WORDS IN ALL TABLES BUT LAST (NOT OF CONSTANT LENGTH)
RCHBLT 6,SEMIC ;LAST N SEMIC
POPTJ: POP P,T
POPJ P,
IFN LISTSW,[
;SET UP TO "DISPLAY" (ALL RCH'S THROUGH RCH)
MDSSET: TLO FF,FLVOT ;SET FLAG
MOVEI A,MDSSTB-3 ;SET UP AC
PUSH P,T ;SAVE T FOR RESTORATION
JRST MDSST1 ;NOW SET UP
MDSSTB: JRST RRL1 ;RR1
GOHALT
PUSHJ P,RCH ;RREOF
PUSHJ P,RCH ;RRL1
IFN .-<MDSSTB-3>-RCHPSN,.ERR LOSSAGE AT MDSSTB.
PUSHJ P,RCH ;SEMIC
CAIE A,15
JRST SEMIC
JRST SEMICR
;CLEAR OUT DISPLAY MODE
MDSCLR: TLZ FF,FLVOT ;CLEAR FLAG
MOVE A,RCHMOD
JRST RCHSET ;NOW SET UP FOR REAL IN CURRENT MODE
] ;END IFN LISTSW,
IFN TS,[ ;TABLE FOR RCHSET, INDEXED BY MODE
;MAYBE THIS CONDITIONAL WANTS TO BE CHANGED TO SOMETHING ELSE
RCHTBL: MOVEI A,RCHFIL ;0 => INPUT FROM FILE
IFN MACSW,PUSHJ P,RCHMAC ;1 => INPUT FROM MACRO (DO NOT CHANGE, USED BY MACRO PROCESSOR)
IFN RCHASW,[IFE MACSW,GOHALT
PUSHJ P,RCHTRC ;2 => TTY, QUIT ON CR
PUSHJ P,RCHARC ;3 => TTY, DON'T QUIT ON CR
]
;TABLE FOR INPUTTING FROM FILE
;MAYBE THIS CONDITIONAL ALSO WANTS TO BE CHANGED
RCHFIL: ILDB A,UREDP ;GETCHR, GET CHARACTER
CAIG A,14 ;SKIP IF TOO BIG TO BE SPECIAL
XCT RPATAB(A) ;SPECIAL, DO THE APPROPRIATE THING
JRST RRL1 ;RR1
GOHALT
PUSHJ P,[ MOVEI A,0 ;^C IN SYMBOL TREATED LIKE A ^@,
JRST INCHR3] ;BUT ALSO SEE IF REALLY END OF BUFFER. THIS GOES IN RREOF.
ILDB A,UREDP ;RRL1
IFN .-RCHPSN-RCHFIL,.ERR RCHFIL LOSES.
LDB CH1,[360600,,UREDP] ;SEMIC; FIND WHERE IN ITS WORD UREDP POINTS
IDIVI CH1,7
JRST @SEMIC3(CH1) ;AND ENTER THE CR-SCANNING LOOP AT THE APPROPRIATE
JFCL ;PLACE (IT IS A WORD-BY-WORD LOOP).
;TABLE FOR ABOVE, EXECUTED INDEXED BY CHAR, 15 ONLY FROM SEMIC ELSE ANYTHING
;NOTE: MANY OF THESE ROUTINES SUBTRACT 3 FROM THE PC BEFORE RETURNING.
;THE CALLER MUST MAKE SURE THAT THE ILDB UREDP IS WHAT THEY RETURN TO THAT WAY.
RPATAB:
IFN ITSSW, JFCL ;0, ON I.T.S. IS NORMAL CHARACTER
.ELSE CALL RPANUL ;0, ON DEC SYSTEM, IGNORE IT.
JFCL
JFCL
IFN .-RPATAB-EOFCH,.ERR EOFCH DOESN'T AGREE WITH ENTRY IN RPATAB.
PUSHJ P,INCHR3 ;3, EOFCH
REPEAT 6,JFCL
CALL RPALF ;LINE FEED
JFCL ;13
PUSHJ P,RPAFF ;FORM FEED
JRST SEMICR ;FROM SEMIC ONLY, EXIT FROM LOOP
RPAFF: SKIPE ASMOUT ;FORM FEED
SKIPL TEXT4 ;ALLOW FORMFEED WITHIN GROUPING ONLY IF IN A TEXT PSEUDO.
CAIA
ETR [ASCIZ/Formfeed within <>, () or []/]
AOS CH1,CPGN
SETOM CLNN
IFN ITSSW,[
ADD CH1,[SIXBIT /P0/+1]
MOVE CH2,A.PASS
DPB CH2,[300200,,CH1]
.SUSET [.SWHO3,,CH1] ;PUT THE NEW PAGE # IN THE WHO-LINE.
]
RPALF: AOS CH2,CLNN
CAME CH2,A.STPLN
RET
MOVE CH1,CPGN
CAMN CH1,A.STPPG
SETOM TTYBRF
RET
IFN DECSW\TNXSW,[
RPANUL: MOVE CH1,@UREDP ;SAW A NULL - IN A LINE NUMBER?
TRNN CH1,1
JRST RCHTRA ;NO, JUST IGNORE IT.
MOVEI CH1,010700
HRLM CH1,UREDP ;YES, SKIP THIS WHOLE WORD, THEN
CALL RCH ;SKIP THE 1ST CHAR AFTER THE LINE NUMBER
JRST RCHTRA ;RETURN THE NEXT CHAR FROM THIS CALL TO RCH.
]
] ;END IFN TS,
VBLK
LIMBO1: 0 ;LAST CHARACTER READ BY RCH
RCHMOD: 0 ;CURRENT INPUT MODE, 0 => INPUT FROM FILE, 1 => MACRO, ETC.
CLNN: 0 ;1 LESS THAN LINE # IN CURRENT INPUT FILE.
CPGN: 0 ;1 LESS THAN PAGE # IN CURRENT INPUT FILE
A.STPL: 0 ;1 LESS THAN LINE # TO STOP AT.
A.STPP: 0 ;1 LESS THAN PAGE # TO STOP AT.
;(STOPPING MEANS INSERTING THE TTY)
;READ CHARACTER INTO A FROM INPUT FILE, MACRO, OR WHATEVER (RCH)
;CLOBBERS A,CH1,CH2.
RCH: TLZE FF,FLUNRD
JRST RCH1 ;RE-INPUT LAST ONE
RCH2: GOHALT ;ILDB A,UREDP ;ILDB A,CPTR ;GET CHAR
0 ;CAIG A,14 ;TRZE A,200 ;CHECK FOR SPECIAL
0 ;XCT RPATAB(A) ;PUSHJ P,MACTRM ;SPECIAL, PROCESS
MOVEM A,LIMBO1 ;GOT CHAR, SAVE AS LAST CHAR GOTTEN
IFE TS,RCHLS1==JRST TYPCTL
IFN TS,RCHLS1==RET ;DEFAULT CONTENTS OF RCHLST (IF NOT LISTING)
RCHLST: RCHLS1 ;AOSN PNTSW IF LISTING.
IFN LISTSW,[
PUSHJ P,PNTR
CAIG A,15
JRST RCHL1
RCHL3: IDPB A,PNTBP
TYPCTL: POPJ P, ;OR JRST SOMEWHERE
PBLK
RCHL1: CAIE A,15
CAIN A,12
JRST RCHL2
CAIE A,14
JRST RCHL3
RCHL2: MOVEM A,LISTBC
SETOM PNTSW
JRST TYPCTL
VBLK
RCH1: MOVE A,LIMBO1
RCH1LS: RET ;OR CAILE A,15 IF LISTING.
RET ;NEEDED IN CASE LISTING.
CAIE A,15
CAIN A,12
JRST RCHL2
CAIE A,14
POPJ P,
JRST RCHL2
PBLK
] ;END IFN LISTSW,
IFE LISTSW,[
PBLK
RCH1: MOVE A,LIMBO1
RET
] ;END IFE LISTSW,
;;GETSYL ;VARIOUS SYLLABLE READING ROUTINES (BUT NOT ALL OF THEM)
GSYL: CLEARB SYM,STRCNT
GSYL1: MOVEI D,6
MOVE T,[440700,,STRSTO]
MOVEM T,STRPNT
GSYL3: AOSG A,STRCNT
JRST (F)
PUSHJ P,RCH
IDPB A,STRPNT ;STORE CHAR IN STRING EVEN IF DELIMITER (MINIMUM STRCNT = 1)
A.GSY2: CAIN A,".
JRST GSYL1C
HLRZ CH1,GDTAB(A)
CAIN CH1,(JSP CH2,)
JRST GSYL1A ;NUMBER
PUSHJ P,GSYL1B ;RETURN ONLY ON SYL SEP
HRRZ A,GDTAB(A)
MOVE T,LIMBO1
C%: POPJ P,"%
GSYL1B: XCT GDTAB(A) ;POPJ FOR SYL SEPS
SUB P,[1,,1]
GSYL1D: SOJGE D,GSYL3
AOJA D,GSYL3
GSYL1C: ADD SYM,%.SQ(D)
JRST GSYL1D
GSYL1A: XCT NSQTB-60(A)
JRST GSYL1D
;VERSION OF GETSYL TO TRY UNTIL SYL OR WORD TERMINATOR FOUND
;SKIPS IF NAME THERE (FOR .TYPE, SQUOZE)
GTSLD2: TLNN C,DWRD\DFLD
JRST GTSLD3 ;DELIMITER IS WORD TERMINATOR, TOLERATE THE NULL SYLLABLE
GETSLD: PUSHJ P,GETSYL ;ENTRY, GET A SYL
MOVE C,CDISP ;GET CDISP
TRNN I,IRSYL
JRST GTSLD2 ;NO SYL
AOS (P) ;GOT SYL, CAUSE RETURN TO SKIP
GTSLD3: TLNN C,DWRD\DFLD
TLO FF,FLUNRD ;CAUSE DELIMITER TO BE RE-INPUT
POPJ P,
PASSPS: SKIPA A,LIMBO1
GPASST: CALL RCH
CAIE A,40
CAIN A,^I
JRST GPASST
RET
GETSYL: TLZ I,ILUARI+ILNPRC+ILLSRT
GTSL1: CLEARB SYM,NUMTAB ;RECUR HERE FOR RIGHT ARG TO ^ AND _.
MOVE AA,[NUMTAB,,NUMTAB+1]
AOSN NTCLF
BLT AA,NUMTAB+10 ;NUMTAB NOT CLEAR, HAVE TO CLEAR IT
MOVEI D,6 ;CHARACTER COUNTER FOR BUILDING UP SYM
SETOM ESBK ;NO SPECIFIC BLOCK DESIRED.
TDZ I,[ILDECP+ILFLO+ILVAR+ILGLI,,IRPERI+IRLET+IRSYL]
RRL2: PUSHJ P,RR ;CALL MAIN LOOP ROUTINE, READ UNTIL NON-SQUOZE CHAR
SEMICR: ;RETURN HERE FROM SEMIC WITH CR IN A
MOVEM A,LIMBO1 ;SYLLABLE OPERATOR OR TERMINATOR IN A, SAVE
HRRZ A,GDTAB(A) ;NOW GET RIGHT HALF OF POPJ, INDEX INTO DTB
MOVE C,DTB-40(A) ;GET DTB ENTRY (FLAGS,,JUMP ADR)
MOVEM C,CDISP ;STORE AS DISPATCH CODE FOR LAST CHAR (SORT OF AN INTERPRETED LIMBO1)
RR8: TLNE C,DSYL ;NOW SEE IF SYL OPERATOR FLAG SET
JRST (C) ;SET => INTRA-SYLLABLE OPERATOR
RR10: TRNE I,IRLET ;NOT SET => SYLLABLE TERMINATOR: SYL?
POPJ P, ;SYL HAS LETTERS
TRNN I,IRSYL
JRST CABPOP ;NO SYL
CAMN SYM,[SQUOZE 0,.]
JRST PT1 ;SYM IS .
;NUMBER
RR5: TLNN I,ILNPRC
PUSHJ P,NUMSL
TLNN I,ILFLO
JRST RR9 ;NOT FLOATING POINT
MOVE A,B ;FLOATING, HIGH IN AA,LOW IN A,EXP IN B
ADDI A,306 ;201+105 TO ROUND
ADDI AA,200 ;CAUSE EXPONENT TO BE ACCEPTABLE TO MACHINE
JUMPGE AA,.+3 ;NOW CHECK FOR OVERFLOW ON ROUNDING
LSH AA,-1 ;OVERFLOW, SHIFT BACK ONE
AOS A ;INCREMENT EXPONENT TO COMPENSATE FOR SHIFT
EXCH A,AA ;GET EXPONENT IN AA, REST IN A
ASHC AA,-10 ;SHIFT TO MACHINE FLOATING POINT FORMAT
SKIPE AA ;NOW CHECK HIGH ORDER BITS OF EXPONENT NOT SHIFTED INTO NUMBER
ETR [ASCIZ /Exponent overflow/]
RR9: TLZ I,ILGLI+ILVAR ;NOT TRYING TO DEFINE NUMBER AS VARIABLE OR GLOBAL
CLBPOP: TDZA B,B ;CLEAR OUT B (RELOCATION BITS OF VALUE)
CABPOP: SETZB A,B ;DO JRST CABPOP TO RETURN ZERO AS VALUE
POPJ P,
RRU: MOVE A,LIMBO1 ;GET HERE WHEN FLUNRD SET AT RR, RETRIEVE CHARACTER FROM LIMBO1
CAIG A,14 ;IF TOO BIG,
CAIGE A,12 ;OR IF TOO SMALL,
JRST RR1B ;THEN JUST FALL BACK IN
TLNN FF,FLVOT\FLMAC\FLTTY ;SKIP IF NOT HACKING CPGN/CLNN
XCT RRUTAB-12(A) ;HACKING, UNHACK FOR HACK COMING UP
JRST RR1B ;FALL BACK IN
RRUTAB: SOS CLNN ;LINE FEED (TABLE FOR RRU)
JRST RR1B ;13
SOS CPGN ;FORM FEED
;MAIN LOOP ROUTINE FOR GETSYL, READ SYM OR NUMBER
VBLK
RR: TLZE FF,FLUNRD ;RE-INPUT LAST CHARACTER?
JRST RRU ;YES
RR1: JRST RRL1 ;ILDB A,CPTR ;GET CHAR (" " ")
GOHALT ;TRZE A,200 ;CHECK FOR END OF STRING
RREOF: PUSHJ P,RCH ;PUSHJ P,MACTRM ;PROCESS CONDITION, GET NEXT CHAR OR JRST RR1 OR RRU
.SEE RCHTRA ;SPECIAL HANDLING OF UNRCHF IN RCHTRA IF CALLED FROM HERE.
RR1B: XCT GDTAB(A) ;GOT CHAR, DO SOMETHING APPROPRIATE (POPJ ON NOT SQUOZE)
TROA I,IRLET\IRSYL ;LETTERS RETURN, JUST UPDATED SYM, SET FLAGS
TRO I,IRSYL ;NUMBERS RETURN, SET FEWER FLAGS
SOJGE D,RR1 ;DECREMENT SYM COUNTER AND LOOP
AOJA D,RR1 ;COUNTER EXHAUSTED, INCREMENT BACK TO 0 AND LOOP
RRL1: PUSHJ P,RCH ;ILDB A,UREDP ;GET CHAR
XCT GDTAB(A) ;NOW MAKE LIKE RR1B (EOFCH => JRST RREOF)
TROA I,IRLET\IRSYL
TRO I,IRSYL
SOJGE D,RRL1
AOJA D,RRL1
;SEMICOLON (GET HERE FROM RR8)
JRST SEMICL ;RETURN HERE FROM SEMIC+2 WHEN FLUNRD SET
;NEXT 4 INSNS ALTERED IN DIFFERENT INPUT MODES. SEE RCHFIL, ETC.
SEMIC: PUSHJ P,RCH ;GET CHAR
CAIE A,15 ;SEE IF SPECIAL
JRST SEMIC ;SPECIAL => DO SOMETHING (JRST SEMICR ON CR)
JRST SEMICR ;IF NOT SPECIAL THEN GO BACK FOR NEXT CHAR
LOC SEMIC+6 ;LEAVE A LITTLE EXTRA ROOM FOR BIG ROUTINES
PBLK
SEMICL: MOVE A,LIMBO1 ;HERE FROM SEMIC-1, RETRIEVE CHARACTER FROM LIMBO1
CAIE A,15 ;SKIP IF SHOULD TERMINATE SCAN
JRST SEMIC ;NOT CR, FALL BACK IN
JRST SEMICR ;DONE
SEMIC2:
REPEAT 5,[
ILDB A,UREDP
CAIG A,15
XCT RPATAB(A)
]
MOVE A,[ASCII /@@@@@/]
SEMIC1: AOS CH1,UREDP
MOVE CH1,(CH1) ;ANY CONTROL CHARS IN THE WORD UREDP POINTS AT?
MOVE CH2,CH1
AND CH1,A
AND CH2,[ASCII/ /]
LSH CH2,1
IOR CH1,CH2
CAMN CH1,A
JRST SEMIC1 ;NO, ADVANCE TO NEXT WORD AND TEST IT.
MOVEI A,440700
HRLM A,UREDP
JRST SEMIC2 ;YES, LOOK AT EACH CHAR AND PROCESS IT.
SEMIC3: REPEAT 6,JRST SEMIC2+3*<5-.RPCNT>
;JSP CH2,RR2 => DIGIT (FROM GDTAB)
;THIS ROUTINE IS GROSSLY SLOW, AND SHOULD BE SPEEDED UP SOMETIME
RR2: XCT NSQTB-"0(A) ;UPDATE SQUOZE.
TRNE I,IRLET
JRST 1(CH2) ;SYL IS SYM, DON'T WASTE TIME.
TRNE I,IRPERI
TLO I,ILFLO ;DIGIT AFTER . => FLOATING.
MAKNUM: SETOM NTCLF ;NUMTAB ABOUT TO NOT BE CLEAR, SET FLAG FOR GETSYL TO CLEAR IT OUT NEXT TIME
MOVEI AA,2 ;INDEX INTO NUMTAB ETC., SOJGE'D TO GET ALL RADICES
MAKNM1: MOVE T,ARADIX(AA) ;GET THIS RADIX,
CAMN T,ARADIX ;REDUNDANT => SKIP THIS PASS.
JUMPN AA,MAKNM4
SKIPGE CH1,HIGHPT(AA)
JRST MAKNM3
MUL T,LOWPT(AA) ;TT HAS OLD LOW TIMES RADIX, T HAS OVFLO TO HIGH.
ADDI TT,-"0(A) ;ADD DIGIT TO LOW PART
TLZE TT,400000
AOJ T, ;OVERFLOW, INCREMENT SPILLOVER FROM MUL OF LOWPT
JUMPE CH1,MAKNM5 ;OLG HIGHPT WAS 0 => SAVE TIME.
JFCL 17,.+1 ;NOW CLEAR OV, ETC.
IMUL CH1,ARADIX(AA) ;MULTIPLY HIGHPT BY RADIX
ADD T,CH1 ;ADD HIGH PARTS
JFCL 10,MAKNM2 ;JUMP ON OVERFLOW FROM IMUL OR ADD
MAKNM5: TLNE I,ILFLO
SOS NUMTAB(AA) ;FLOATING, DECREMENT EXP TO COMPENSATE FOR MULT OF HIGHPT/LOWPT
MOVEM T,HIGHPT(AA) ;NOW STORE STUFF BACK
MOVEM TT,LOWPT(AA)
MAKNM4: SOJGE AA,MAKNM1 ;NOW DO ALL THIS FOR NEXT RADIX
JRST 1(CH2)
MAKNM2: MOVSI B,400000 ;OVERFLOW FROM UPDATING HIGH PARTS
IORM B,HIGHPT(AA) ;SET SIGN BIT
MAKNM3: TLNN I,ILFLO
AOS NUMTAB(AA) ;NOT FLOATING, INCREMENT EXP, MAY NOT WANT TRAILING BITS
JRST MAKNM4
VBLK
NUMTAB: 0 ;EXPONENT
0
0
HIGHPT: 0 ;HIGH PART OF CURRENT NUMBER THIS RADIX
0 ;4.9 => OVERFLOW, TRAILING DIGITS DROPPED
0
LOWPT: 0 ;LOW PART OF CURRENT NUMBER THIS RADIX
0 ;HIGHPT/LOWPT TAKEN AS 70. BIT POSITIVE INTEGER EXCEPT 4.9(HIGHPT) IS FLAG INSTEAD OF
0 ;EXPONENTIATE 70. BIT INTEGER BY NUMTAB (WHICH MAY BE NEGATIVE) TO GET ACTUAL VALUE
ARADIX: 10 ;CURRENT RADIX
12
10
NTCLF: -1 ;-1 => NUMTAB NOT CLEAR (TO SAVE BLT AT GETSYL WHEN CLEAR)
PBLK
;JRST POINT => . (FROM GDTAB)
POINT: TLO I,ILDECP ;PREFER DECIMAL
TROE I,IRPERI ;SET PERIOD FLAG
TRO I,IRLET ;2 POINTS => NAME
ADD SYM,%.SQ(D) ;UPDATE SYM
JRST 1(CH1) ;RETURN
RBRAK: SOSL SCNDEP ;IF A CONDITIONAL TO TERMINATE,
JRST RBRAK2 ;HAVE DONE SO, IGNORE CHAR.
SETZM SCNDEP
;CLOSES OF ALL KINDS COME HERE.
RPARN:
GRTHN: MOVE A,LIMBO1
SKIPE CH1,ASMOUT ;WHAT KIND OF OPEN ARE WE IN?
CAIN CH1,4 ;WITHIN A .ASCII OR
JRST RBRAK1 ;NOT WITHIN GROUPING => THIS CLOSE IS STRAY.
CAME A,ASMOT1(CH1) ;RIGHT KIND OF CLOSE FOR THAT OPEN?
ERJ RBRAK3
RBRAK4: MOVE CH1,ASMOT2(CH1)
MOVEM CH1,ASMDSP ;ARRANGE FOR THIS ASSEM1 LEVEL TO EXIT
RBRAK5: SETZM CDISP
JRST RR10 ;AND GO TERMINATE WORD.
RBRAK3: CALL TYOERR ;COME HERE ON CLOSE WRONG FOR OPEN.
;(EG, ")" MATCHING "<").
TYPR [ASCIZ/ Seen when /]
MOVE A,ASMOT1(CH1)
CALL TYOERR
TYPR [ASCIZ/ expected
/]
JRST RBRAK4
RBRAK1: CAIN CH1,4 ;CLOSE INSIDE A .ASCII =>
JRST RBRAK5 ;TERMINATE WORD BUT DON'T CLOSE ANYTHING.
SKIPN CONSML ;COME HERE FOR STRAY CLOSE.
JRST RRL2
ERJ .+1
TYPR [ASCIZ/Stray /]
MOVE A,LIMBO1 ;GET THE CLOSE WE SAW.
CALL TYOERR
CALL CRRERR
JRST RRL2
;COME HERE FOR CLOSE-BRACE, AND CERTAIN CLOSE-BRACKETS.
RBRAK2: SETOM A.SUCC ;HAVE JUST ENDED SUCCESSFUL BRACKETED CONDIT,
JRST RRL2 ;REMEMBER THAT MOST RECENT CONDITIONAL WAS TRUE.
FORMF: TLNN FF,FLVOT\FLMAC\FLTTY ;FORM FEED SYLLABLE OPERATOR ROUTINE
PUSHJ P,RPAFF ;UNLESS ALREADY DONE, INCREMENT PAGE #.
JRST RR10
LINEF: TLNN FF,FLVOT\FLMAC\FLTTY ;LINE FEED SYLLABLE OPERATOR ROUTINE
CALL RPALF
JRST RR10
CTLAT:
IFN DECSW\TNXSW,[
TLNN FF,FLVOT\FLMAC\FLTTY ;^@ SYLLABLE OPERATOR ROUTINE.
CALL RPANUL
]
JRST RRL2
;DECIPHER A VALUE FROM NUMTABS
;LEAVES HIGH PART IN AA, LOW PART IN A, BINARY EXPONENT IN B
;AND RADIX USED IN D.
NUMSL: TLNN I,ILVAR\ILDECP\ILFLO
SKIPE B,HIGHPT
JRST NUMSLS
MOVE A,LOWPT ;BE VERY FAST IN CASE OF SMALL FIXNUM IN CURRENT RADIX.
MOVE D,ARADIX ;SAVE RADIX AND HIGH PART FOR ^.
SETZ AA,
RET
NUMSLS: CLEARB TT,D ;TT BIT EXPONENT, D INDEX INTO NUMTAB, ETC.
TLNE I,ILDECP+ILVAR ;NEITHER . NOR ', CURRENT RADIX.
TLNE I,ILGLI ;" => CURRENT RADIX DESPITE . OR '.
JRST NUMSL0
MOVEI D,1 ;DECIMAL UNLESS '
TLNE I,ILVAR ;WHICH FORCES OCTAL.
MOVEI D,2
MOVE A,ARADIX(D)
CAMN A,ARADIX ;IF REALLY SAME AS CURRENT RADIX,
MOVEI D,0 ;COMPUTATION WASN'T DONE FOR THIS VALUE OF D,
;SO USE COMPUTATIONS DONE FOR CURRENT RADIX.
NUMSL0: MOVE AA,HIGHPT(D) ;AA := HIGH PART
MOVE B,LOWPT(D) ;B := LOW PART
MOVE T,NUMTAB(D) ;T := EXPONENT
MOVE D,ARADIX(D) ;NO LONGER NEED IDX, GET RADIX VALUE.
TLNN I,ILFLO
JRST FIXNUM ;NOT FLOATING
TLZ AA,400000 ;FLOATING, DON'T NEED DIGITS LOST ON OVERFLOW
NUMC1: JUMPN AA,.+2 ;ENTRY FROM UPARR
JUMPE B,FIX0 ;COMPLETELY ZERO => RETURN FIXED ZERO
JUMPL T,NUMSL1 ;JUMP IF EXPONENT NEGATIVE
JUMPE T,NUMSL2 ;JUMP (SKIP FOLLOWING) IF EXPONENT ZERO
;EXPONENT POSITIVE, DO THE APPROPRIATE THING
NUMSL5: MULI B,(D) ;MULITIPLY LOW PART BY RADIX
MULI AA,(D) ;MULTIPLY HIGH PART BY RADIX
ADD A,B ;A := LOW PART OF HIGH + HIGH PART OF LOW
TLZE A,400000
ADDI AA,1 ;OVERFLOW ON ADDITION, INCREMENT HIGH PART OF HIGH
MOVE B,C ;NO LONGER NEED HIGH OF LOW, GET LOW OF LOW IN B
NUMSL3: JUMPE AA,NUMSL4 ;NOW CHECK FOR OVERFLOW INTO HIGH OF HIGH, JUMP ON NONE
ASHC A,-1 ;NEXT THREE INSTRUCTIONS TO DO ASH3 AA,-1
ASH A,1
ASHC AA,-1
AOJA TT,NUMSL3 ;INCREMENT BIT EXPONENT AND TRY AGAIN
NUMSL4: MOVE AA,A ;FLUSHED OVERFLOW, NOW GET (LOW PART OF) HIGH PART IN AA
SOJG T,NUMSL5 ;COUNT DOWN
NUMSL2: TLNN I,ILFLO
JRST NUMSL9 ;NOT FLOATING, DON'T WASTE TIME NORMALIZING.
SKIPA A,B ;EXPONENT NOW ZERO, GET LOW PART OF NUMBER IN A
NUMSL7: ASHC AA,1 ;NOW NORMALIZE
TLNN AA,200000
SOJA TT,NUMSL7
SKIPA B,TT ;DONE NORMALIZING, RETURN BINARY EXPONENT IN B
PT1: TRO I,IRLET
POPJ P,
NUMSL9: MOVE A,B
MOVEI B,0
ASHC AA,(TT) ;SHIFT 2-WD NUM. BY EXPONENT,
LSH A,1 ;PUT HIGH BIT IN WITH REST.
JRST FIX1
FIX0: TLZ I,ILFLO
FIXNUM: LSHC A,45
FIX1: LSHC AA,-1
JUMPE AA,.+2
ETR [ASCIZ /FIXNUM too big for 36 bits/]
POPJ P,
NUMSL1: SKIPA A,B ;EXPONENT NEGATIVE: NORMALIZE NOW
NUMSL8: ASHC AA,1
NUMSL6: TLNN AA,200000
SOJA TT,NUMSL8 ;NOT NORMALIZED YET
AOS T
MOVEI TM,(D)
TLNN TM,-1 ;GET CONVIENT POWER OF RADIX
JUMPL T,[ IMULI TM,(D)
AOJA T,.-1]
MOVE B,A ;GET NORMALIZED LOW PART IN B
IDIV AA,TM ;DIVIDE HIGH PART BY APPROPRIATE RADIX
DIV A,TM
JUMPL T,NUMSL6
MOVE B,A
JRST NUMSL2
UPARR: TRON I,IRSYL
JRST UPCTRC ;"UNARY UPARROW" => GOBBLE CHARS
TRNE I,IRLET
ETR [ASCIZ /Symbolic 1st arg to "^"/]
PUSHJ P,NUMSL ;DECIPHER NUMTABS
PUSHJ P,UA3 ;GET RIGHT OPERAND IN T
MOVE TT,B ;EXPONENT
MOVE B,A ;LOW PART
PUSHJ P,NUMC1 ;T EXP HIGH IN AA LOW IN B TT BIN EXP
MOVE C,CDISP ;IF A _ WAS DEFERRED WHILE ILUARI WAS SET,
TLO I,ILNPRC
CAME C,[DSYL,,BAKAR] ;DO IT NOW.
JRST RR10
BAKAR: TLNE I,ILUARI
JRST RR5 ;RETURN TO UPARROW (WILL COME BACK HERE LATER)
TRNE I,IRSYL
TRNE I,IRLET
JRST BAK1 ;NO SYL, OR SYL IS NAME
CAMN SYM,[SQUOZE 0,.]
JRST BAK1 ;. ALSO NAME
TLZN I,ILNPRC
PUSHJ P,NUMSL
PUSHJ P,UA3
ADD B,T
ASHC AA,(B)
LSH A,1
LSHC AA,-1
CLEARB B,AA
TLZ I,ILFLO
MOVE C,[DFLD,,CBAKAR]
EXCH C,CDISP ;IF 2ND ARG ENDED WITH A _, TURN INTO FIELD OP.
CAME C,[DSYL,,BAKAR]
EXCH C,CDISP
POPJ P,
UPCTRC: SETZ T,
UPCTR1: JSP F,QOTCOM ;UP ARROW TO GOBBLE SYL AND RETURN MASKED ASCII VALUE
LSH T,7 ;SHIFT ACCUMULATED VALUE OVER 7
CAIL A,140
SUBI A,40
ANDI A,77 ;NOW MASK CHARACTER IN TO TO BOTTOM 6 BITS
ADD T,A ;ADD TO ACCUMULATED
POPJ P,
BAK1: MOVE TT,[DFLD,,CBAKAR]
MOVEM TT,CDISP
JRST RR10
UA3: HRLM D,(P) ;SAVE RADIX (FOR UPARR)
JSP LINK,SGTSY ;PUSH I,AA,A,B
TLO I,ILUARI ;TELL _ TO WAIT TILL LATER (SEE UPARR, BAKARR)
PUSHJ P,RCH
CAIN A,"-
TROA I,IRGMNS
TLO FF,FLUNRD
PUSHJ P,RCH
CAIN A,"<
JRST UAR1
TLO FF,FLUNRD
UA3L: PUSHJ P,GTSL1 ;GOBBLE SYL, LOOP POINT FOR PSEUDO OR MACRO RETURNED WITHOUT VALUE
TRNE I,IRLET
JRST UA3S ;NAME
TLNE I,ILFLO
ETR [ASCIZ /Floating point 2nd arg to "_"/]
UAR2: TRZN I,IRGMNS
SKIPA T,A
MOVN T,A
JSP LINK,SGTSY1 ;RESTORE GETSYL TEMPS.
HLRZ D,(P)
POPJ P,
UA3S: PUSHJ P,GETVAL ;MAKE NUMBER_NAME WORK
JRST UA3SR ;GOT VALUE, PROCESS
JRST UA3L ;NO VALUE, TRY AGAIN
UAR1: TLO I,ILLSRT
TRZ I,IRSYL ;(OR ELSE LSSTH GIVES NOS ERROR.)
SETZB A,B
PUSHJ P,LSSTH
UA3SR: JUMPN B,RLCERR ;RELOC ERR
JRST UAR2
ATSGN: MOVSI A,20 ;ATSIGN
IORM A,WRD
TRO I,IRFLD ;SET IRFLD FLAG EVEN THOUGH NOT DIRECTLY RETURNING VALUE
; ^ CHANGED FROM SYL TO FIELD 9/6/70
JRST RRL2 ;FALL BACK IN
DQUOTE: TRON I,IRSYL
JRST DQUOT8
TRNN I,IRLET ;AFTER NUMBER => CURRENT RADIX.
JRST DQUOT7
PUSHJ P,RCH
TLO FF,FLUNRD ;NEXT CHAR. SQUOZE?
HLRZ A,GDTAB(A)
CAIN A,(POPJ P,)
JRST DQUOT7 ;NO => MAKE PREV. SYM. GLOBAL.
CAMN SYM,[SQUOZE 0,.M] ;SPECIAL BLOCK NAMES
JRST DQUOTM ;.M MEANS MAIN BLOCK,
CAMN SYM,[SQUOZE 0,.U]
JRST DQUOTU ;.U MEANS SUPERIOR.
CAMN SYM,[SQUOZE 0,.C]
JRST DQUOTC ;.C MEANS CURRENT BLOCK.
SKIPGE A,ESBK ;GET SPEC'D BLOCK OR CURRENT,
HRR A,BKCUR ;LOOK FOR SUBBLOCK OF THAT BLOCK.
HLL A,BKTAB+1(A)
ADD A,[1,,] ;LH HAS LEVEL SUBBLOCK OUGHT TO HAVE.
MOVEI T,0
SETO D, ;NO POSSIBLE ALTERNATE CHOICE YET.
DQUOT0: CAME SYM,BKTAB(T) ;LOOK AT ALL BLOCKS SEEN.
JRST DQUOT1 ;HAS THE NAME WE'RE LOOKING FOR?
SKIPGE ESBK ;IF LOOKING FOR A SUBBLOCK OF A PARTICULAR BLOCK,
JRST DQUOT4
CAMN A,BKTAB+1(T)
JRST DQUOT2 ;SUCH A BLOCK WINS; ALL OTHERS LOSE.
JRST DQUOT1
DQUOT4: SKIPN BKTAB+2(T) ;ELSE PREFER DEFINED BLOCKS TO UNDEFINED ONES.
JUMPGE D,DQUOT1
SKIPE BKTAB+2(T)
JUMPL D,DQUOT5
CAME D,[-1] ;THAT'S THE SAME EITHER WAY => PREFER AN INFERIOR
CAMN A,BKTAB+1(T) ;OF THE CURRENT BLOCK TO ONE THAT'S NOT.
JRST DQUOT5
JRST DQUOT1
DQUOT5: HRROI D,(T) ;FOUND A BLOCK WE LIKE BEST SO FAR.
SKIPE BKTAB+2(T)
ANDI D,-1 ;LEAVE SIGN OF D SET UNLESS THE BLOCK IS DEFINED.
DQUOT1: ADDI T,BKWPB
CAMGE T,BKTABP
JRST DQUOT0
HRRZI T,(D) ;NOW USE THE BEST BLOCK FOUND, IF THERE WAS ONE.
CAIE T,-1
JRST DQUOT2
MOVE T,BKTABP ;NOT FOUND, GET IDX OF 1ST UNUSED ENTRY.
CAIL T,BKTABS
ETF ERRTMB ;NO ROOM FOR MORE BLOCKS.
MOVEM SYM,BKTAB(T)
MOVEM A,BKTAB+1(T) ;ADD BLOCK AT END.
MOVEI A,BKWPB(T)
MOVEM A,BKTABP ;POINTS AFTER LAST USED ENTRY.
DQUOT2: MOVEM T,ESBK
SETZ SYM,
DQUOT3: MOVEI D,6 ;NEXT CHAR GOES IN 1ST SQUOZE POS.
JRST RRL2
DQUOTM: MOVEI T,BKWPB ;.M - MAIN BLOCK FOLLOWS INITIAL SYMS BLOCK.
JRST DQUOT2
DQUOTU: SKIPGE T,ESBK ;.U SPEC'D - GET SPEC'D OR CURRENT BLOCK,
MOVE T,BKCUR
HRRZ T,BKTAB+1(T)
JRST DQUOT2 ;SPEC. ITS SUPERIOR.
DQUOTC: SKIPGE T,ESBK ;.C => SPEC THE CURRENT BLOCK.
MOVE T,BKCUR
JRST DQUOT2
SQUOT1: TLOA I,ILVAR
DQUOT7: TLO I,ILGLI
MOVE A,BKCUR ;IF NO SPEC'D BLOCK,
SKIPGE ESBK
MOVEM A,ESBK ;SPEC. CURRENT BLOCK.
JRST RRL2
DQUOT8: SETZ T,
DQUOT9: JSP F,QOTCON ;DOUBLE QUOTE TO GOBBLE SYL AND RETURN ASCII VALUE
LSH T,7 ;SHIFT ACCUMULATED VALUE OVER 7
ADD T,A ;ADD IN ASCII CHARACTER IN A
POPJ P, ;RETURN TO SOMETHING
SQUOTE: TROE I,IRSYL
JRST SQUOT1
SETZ T,
SQUOT9: JSP F,QOTCON ;SIXBIT SYL
CAIGE A,40
ETR ERRN6B ;NOT SIXBIT
CAIL A,140
SUBI A,40 ;CONVERT TO UPPER CASE
LSH T,6 ;SHIFT OVER ACCUMULATED VALUE
ADDI T,-40(A) ;ADD IN SIXBIT FOR CHARACTER IN A
POPJ P,
;COMMON ROUTINE FOR RIGHT JUSTIFIED TEXT SYLS
;CALLED WITH JSP F,; ROUTINE PUSHJ'S BACK W/ CHAR IN T, ACCUM VALUE IN A
;SYL FLAG EXPECTED TO BE ALREADY SET
QOTCON: SKIPE QMTCH ;' AND " COME HERE, BUT NOT ^: IF IN QUOTES-MATCHING MODE, USE A
JRST QOTCO4 ;FAIL-LIKE ALGORITHM. HERE FOLLOWS THE OLD MIDAS WAY OF DOING IT
QOTCOM: CALL RCH ;USE AT LEAST 1 CHAR IN ANY CASE.
JRST QOTCO1
QOTCO2: CALL RCH ;USE SUCCEEDING CHARS IF SQUOZE CHARS.
HLRZ CH1,GDTAB(A)
CAIN CH1,(POPJ P,)
JRST QOTCO3
QOTCO1: CALL (F)
JRST QOTCO2
QOTCO3: CAIN A,"" ;NONSQUOZE: IF IT IS A TEXT SYL INDICATOR,
JRST DQUOT9 ;CONTINUE WITH WHATEVER TYPE OF TEXT
CAIN A,"'
JRST SQUOT9 ;IT INDICATES.
CAIN A,"^
JRST UPCTR1
QOTCO6: TLO FF,FLUNRD
JRST TEXT5
QOTCO4: MOVE B,LIMBO1 ;GET ' OR ", WHICHEVER STARTED THIS SYL, AS THE DELIMITER.
MOVE SYM,[SQUOZE 0,TEXT]
JSP TM,ERMARK
QOTCO5: CALL RCH
CAMN A,B ;FOUND ANOTHER EXAMPLE OF THE DELIMITER?
JRST [ CALL RCH ;IF DUPLICATED, IT PUTS THE DELIMITER IN THE CONSTANT.
CAMN A,B
JRST .+1
JRST QOTCO6] ;OTHERWISE UNREAD THE CHAR AFTER THE DELIMITER AND EXIT.
CALL (F) ;HAVE CHAR TO PUT IN STRING IN A; GO MERGE IT IN.
JRST QOTCO5
;RETURN A VALUE FROM A PSEUDO WHOSE ARGS CAN BE TERMINATED BY EITHER COMMA (GOBBLED)
;OR CR (NOT GOBBLED).
VALRET: MOVE T,A ;ROUTINE TO RETURN VALUE IN A AFTER LAST CHAR GOBBLED BY GETSYL
MOVE B,CDISP ;GET STORED DISPATCH CODE
TLNN B,DWRD\DFLD
JRST VALR1 ;WORD TERMINATOR
;COME HERE TO RETURN A VALUE, AND ALSO
;BARF IF THE NEXT CHARACTER ISN'T A SYLLABLE SEPARATOR
TEXT5: PUSH P,T ;ENTRY FROM TEXT ROUTINES (NLAST CHAR NOT GOBBLED BY GETSYL) TO RETURN VALUE IN T
PUSHJ P,GETSYL ;SEE IF IMMEDIATELY FOLLOWED BY SYL
TRNE I,IRSYL
ETR ERRNOS ;NO SEPARATOR BETWEEN TWO VALUES
POP P,A ;RESTORE VALUE TO RETURN
VALR1: TRO I,IRSYL
JRST CLBPOP
;VARIOUS PUSH AND POP ROUTINES, ALL CALLED W/ JSP LINK,
SGTSY: PUSH P,I
PUSH P,AA
PUSH P,A
PUSH P,B
JRST (LINK)
SGTSY1: POP P,B
POP P,A
POP P,AA
POP P,I
JRST (LINK)
;JSP LINK,SAVWD1 TO SAVE STUFF FOR < OR (, ETC.
SAVWD1: PUSH P,A ;SYLL. BEFORE GROUPING NOW STARTING.
PUSH P,B ;AND ITS RELOC.
SAVWLD: PUSH P,FORMAT
PUSH P,FORPNR
PUSH P,FLDCNT
PUSH P,GLSP2
PUSH P,I
PUSH P,WRD
PUSH P,WRDRLC
PUSH P,SYM
PUSH P,PPRIME
PUSHJ P,(LINK)
SAVL1==.
;POP OFF WHAT PUSHED BY SAVWLD. CLEARS FLUNRD, IN CASE THE > OR ) WAS UN-READ.
USVWLD: POP P,SYM
HRRZS SYM
CAIE SYM,SAVL1
GOHALT
TLZ FF,FLUNRD
POP P,PPRIME
POP P,SYM
POP P,WRDRLC
POP P,WRD
TDZ I,[-1-(ILWORD)]
IOR I,(P)
POP P,1(P)
POP P,GLSP2
POP P,FLDCNT
POP P,FORPNR
POP P,FORMAT
JRST (LINK)
;;GETFD ;GET FIELD (EXPRESSION); RETURN VALUE IN A, RELOC BITS IN B
;GET FIELD FOR PSEUDO
;SYM SHOULD CONTAIN THE SQUOZE NAME OF THE PSEUDO
;OR A POINTER TO AN INSN TO EXECUTE WHEN UNDEF
;SYMBOL SEEN. SYM IS NOT CLOBBERED.
AGETFD: PUSH P,I ;SAVE I
TRO I,IRPSUD+IRNOEQ ;SET FLAG TO GETVAL TO EXECUTE GTVER ON UNDEFINED SYM ON EITHER PASS
PUSH P,GTVER ;OLD VALUE OF GTVER
MOVEM SYM,GTVER ;ERROR MSG SHOULD GIVE NAME OF PSEUDO.
CALL YGETFD
MOVE SYM,GTVER
REST GTVER
MOVEM I,ISAV ;SAVE FLAGS FOR FIELD GOTTEN
POPIJ: POP P,I
POPJ P,
;READ A FIELD, NOT PART OF THE CURRENT WORD.
YGETFD: PUSH P,WRD
SETZM WRD
CALL XGETFD
TLNE I,ILMWRD
PUSHJ P,IGTXT ;SOAK UP MULTIPLE WORD
ADD A,WRD ;ADD IN INDEX, INDIRECT FIELDS
POP P,WRD
POPJ P,
IFN FASLP,[
FAGTFD: PUSHJ P,AGETFD ;DO AGETFD, COMPLAIN IF RELOCATABLE OR GLOBAL
MOVE TM,GLSP1
CAMN TM,GLSP2
SKIPE B
ETSM [ASCIZ /relocatable or external argument/]
POPJ P,
]
;READ A FIELD PART OF CURRENT WORD (FOR XWD, ETC).
XGETFD: PUSH P,PPRIME
AGTFD3: PUSHJ P,GETFLD
MOVE CH1,CDISP
TLNN CH1,DWRD
TLOA FF,FLUNRD ;DELIMITER IS WORD TERMINATOR => RE-READ IT.
TRNE I,IRFLD ;NON-NULL FIELD SUPPLIED => RETURN IT.
JRST AGTFD4
HRRZ C,CDISP ;ELSE COMMA => RETURN NULL VALUE (0)
CAIN C,SPACE ;SPACE => TRY AGAIN TO READ A FIELD.
JRST AGTFD3 ;NO FIELD, TRY AGAIN
AGTFD4: REST PPRIME
POPJ P,
;IN RELOCATABLE FORMAT
;READ FIELD AND COPY OUT AS WORD
RGETFD: SETZM WRD ;FIRST INITIALIZE SOME STUFF AS THOUGH AT GETWD
SETZM WRDRLC
MOVE A,GLSPAS
MOVEM A,GLSP1
MOVEM A,GLSP2
CALL XGETFD
ADDM A,WRD
ADDM B,WRDRLC
PUSHJ P,PWRDA ;OUTPUT WORD
TLNE I,ILMWRD
JRST IGTXT ;SOAK UP MULTI-WORD FIELD
POPJ P,
;READ IN A FIELD, RETURN IN A,B SETTING IRFLD IF FIELD NOT NULL.
GETFLD: PUSH P,GLSP1 ;REFERED TO AS GETFLB(P) WHEN ONLY 1 SYL PUSHED.
MOVEM P,PPRIME
TRZ I,IRFLD+IROP
GETFD1: TLNE I,ILMWRD
JRST GETFD9 ;MULTIPLE WORD, RE-CALL PSEUDO
PUSHJ P,GETSYL
TRNE I,IRLET
GETFD9: PUSHJ P,GETVAL ;GET OPERAND (MAYBE SKIPS)
GETFD6: SKIPA C,CDISP ;GET INFO ON SYLLABLE TERMINATOR
JRST GETFD1 ;GETVAL SKIPPED => PSEUDO/MACRO WITH NO VALUE, TRY AGAIN
TLNE C,DFLD
JRST (C) ;FIELD OPERATOR, GO PROCESS
TRNE I,IRSYL ;NO DISP MEANS FIELD TERMINATOR.
TRO I,IRFLD
CAME P,PPRIME ;IF ANY OPERATORS PUSHED,
JSP LINK,GETFD8 ;EVAL THEM.
SUB P,[1,,1] ;FLUSH GLSP1 SAVED AT GETFLD.
RET
GETFD8: MOVEI TT, ;END OF FIELD HAS VERY LOW PRIORITY.
JRST GETFD7
;PUSH AN OPERATOR, MAYBE EVALLING STUFF TO LEFT.
;A HAS LEFT OPERAND (IF ANY), B RELOCATION BITS,
;C ADR OF ROUTINE TO PERFORM OPERATION, LH OF TT HAS PRECEDANCE OF OPERATOR
GETFDL: MOVEI LINK,GETFD3 ;AFTER MAYBE EVALLING, GO PUSH OPERATOR.
TRO I,IRFLD+IROP
TRNN I,IRSYL
JRST GETFD5 ;UNARY, EVAL NOTHING, JUST PUSH WITH HIGH PRIO.
GETFD2: CAME P,PPRIME ;NO OPS TO LEFT => NOTHING TO EVAL.
CAMLE TT,GETFLP(P) ;COMPARE PRIO OF PREV. OP. AND CURRENT.
JRST (LINK) ;WAIT UNTIL LATER
GETFD7: HRRZ T,GETFLP(P) ;EVAL THE LAST OP ON STACK.
JRST (T) ;GO DO IT NOW (ROUTINE RETURNS TO GETFD4)
GETFD4: SUB P,[4,,4]
JRST GETFD2
GETFD5: MOVSI TT,200 ;GIVE UNARY OP HIGH PRIO. TO DO BEFORE NEXT BINARY.
GETFD3: PUSH P,B ;GETFLR(P)
PUSH P,A ;GETFLV(P)
HLL C,TT
PUSH P,C ;GETFLP(P)
PUSH P,GLSP1 ;GETFLG(P)
JRST GETFD1
GETFLB==,-4 ;PDL IDX OF GLSP1 BEFORE LEFT OPERAND.
GETFLR==,-3 ;PDL IDX OF RELOC OF LEFT OPERAND.
GETFLV==,-2 ;PDL IDX OF VALUE OF LEFT OPERAND.
GETFLP==,-1 ;PDL IDX OF PRIO,,DISPATCH
GETFLG==0 ;PDL IDX OF GLSP1 AFTER LEFT OPERAND (=BEFORE RIGHT)
PLS: MOVEI C,PLS1 ;PLUS SIGN, PLS1 IS ROUTINE TO PERFORM OPERATION
MINUS2: MOVSI TT,10 ;SET UP PRECEDENCE OF 10 FOR +, -
JRST GETFDL
MINUS: JSP C,MINUS2 ;MINUS SIGN
MOVNS A ;NEGATE VALUE OF RIGHT OPERAND
MOVNS B ;ALSO RELOCATION
;433 This instr was causing [foo] and [-foo] to be mistakenly
; constants-optimized to the same thing during pass1, resulting in a
; "more constants on pass2 than pass1" error.
; JUMPGE FF,PLS1
MOVE T,GETFLG(P)
PUSH P,B
HRLZI B,MINF
PUSH P,C
PUSHJ P,LNKTZ ;COMPLEMENT THE MINUS FLAG ON GLOBALS IN RIGHT OPERAND
POP P,C
POP P,B
PLS1: ADD A,GETFLV(P) ;ADD VALUES
ADD B,GETFLR(P) ;ADD RELOCATIONS
JRST GETFD4
LNKTZ: TDZA C,C
LNKTC1: MOVE T,GLSP2
LINKTC: CAML T,GLSP1
POPJ P,
SKIPL 1(T)
XORM B,1(T)
SKIPL 1(T)
IORM C,1(T)
AOJA T,LINKTC
MULTP: MOVEI C,MULTP1 ;ASTERISK, MULTP1 ROUTINE TO PERFORM MULTIPLICATION
DIVID2: MOVSI TT,20 ;20 PRECEDENCE OF MULTIPLICATION, DIVISION
JRST GETFDL
MULTP1: SKIPL CONTRL ;ELSE IN DECREL ASSEMBLY, TEST FOR EXTERNALS.
JUMPGE FF,MULTR
MOVE D,GETFLB(P) ;ACTUALLY, GET HERE FOR ABS ASSEMBLIES TOO, BUT SO WHAT?
CAMN D,GLSP1
JRST MULTR
SKIPGE FF
ETR [ASCIZ /Externals multiplied/]
TLO I,ILNOPT ;DON'T OPTIMIZE LITERALS CONTAINING UNDEFS ON PASS 1.
MULTR: JUMPE B,MULTP3 ;JUMP ON RIGHT OPERAND NOT RELOCATED
SKIPE GETFLR(P)
JRST MULTP4 ;BOTH OPERANDS RELOCATED
MOVE T,GETFLV(P) ;GET VALUE OF LEFT OPERAND AND FALL IN
JRST MULTP5
MULTP3: MOVE T,A ;RIGHT OPERAND NOT RELOCATED, GET VALUE IN T
MOVE B,GETFLR(P) ;RELOCATION BITS OF LEFT OPERAND
MULTP5: MOVE D,GETFLG(P) ;GLOTB POINTER TO BETWEEN OPERANDS
CAME D,GETFLB(P)
JRST GMUL1 ;LEFT OPERAND HAS GLOBALS
CAME D,GLSP1
JRST GMUL2 ;RIGHT OPERAND HAS GLOBALS
;AT THIS POINT, T HAS VALUE OF ABS OPERAND, B RELOC BITS OF OTHER
GMUL4: IMUL A,GETFLV(P) ;MULTIPLY VALUES
IMULB B,T ;MULTIPLY RELOCATION OF ONE BY VALUE OF OTHER
TRZ T,1
SKIPL CONTRL ;EXCEPT IN STINK ASSEMBLY, OBJECT TO RELOCATION
JRST GETFD4 ;OTHER THAN 0 OR 1 (ONLY AFFECTS DECREL, SINCE
JUMPE T,GETFD4 ;RELOCATION CAN'T BE NONZERO IN ABS ASSEMBLY).
MULTP4: ETR [ASCIZ+Relocatable arg to * or / or Boolean+]
JRST GETFD4
GMUL1: TLNE FF,FLPPSS ;LEFT OPERAND HAS GLOBALS, CHEK RIGHT OPERAND
CAMN D,GLSP1
SKIPA CH1,A ;LOOKS OK, GET VALUE IN CH1
ETR [ASCIZ /Multiplying two externals/]
SKIPA D,GETFLB(P) ;GET GLOTB POINTER TO BOTTOM OF LEFT OPERAND
GMUL2: MOVE CH1,GETFLV(P) ;GLOBALS IN RIGHT OPERAND ONLY, GET LEFT OPERAND
GMUL3: CAML D,GLSP1
JRST GMUL4 ;TABLE COUNTED OUT
SKIPGE 1(D)
AOJA D,GMUL3
JUMPE CH1,GMUL5 ;MULTIPLYING BY ZERO, CLEAR OUT GLOTB ENTRY AND LOOP BACK
LDB CH2,[221200,,1(D)] ;PICK UP MULTIPLICATION FIELD THIS GLOBAL
SKIPN CH2
MOVEI CH2,1 ;0 => 1
IMUL CH2,CH1
CAIN CH2,1
MOVEI CH2,0 ;IF ONE THEN USE ZERO
DPB CH2,[221200,,1(D)]
AOJA D,GMUL3
GMUL5: CLEARM 1(D)
AOJA D,GMUL3
DIVID: JSP C,DIVID2 ;SLASH, PRECEDENCE = 20
DIVID1: JUMPN B,MULTP4 ;JUMP IF RIGHT OPERAND RELOCATED
SKIPE GETFLR(P)
JRST MULTP4 ;LEFT OPERAND RELOCATED
EXCH A,GETFLV(P)
IDIV A,GETFLV(P)
MOVEI B,0
MOVE D,GETFLB(P)
CAMN D,GLSP1 ;IF THERE ARE EXTERNALS OR UNDEFINED SYMBOLS,
JRST GETFD4
SKIPGE FF ;ON PUNCHING PASS IT'S AN ERROR.
ETR [ASCIZ /Division involving externals/]
TLO I,ILNOPT ;ON PASS 1, DON'T OPTIMIZE THIS IF IN A LITERAL.
JRST GETFD4
;LOGIC OPERATORS & (PREC = 40), # (PREC = 34), \ (PREC = 30)
ANDF: MOVSI TT,40 ;&
JSP C,GETFDL
JSP D,LOGIC1 ;GO DO IT
AND A,GETFLV(P) ;INSTRUCTION ARGUMENT TO LOGIC1
XORF: MOVSI TT,34 ;#
TRNN I,IRSYL ;IF ABOUT TO BE UNARY,
MOVNI A,1 ;THEN TURN LEFT OPERAND INTO -1
JSP C,GETFDL
JSP D,LOGIC1
XOR A,GETFLV(P)
IORF: MOVSI TT,30 ;\
JSP C,GETFDL
JSP D,LOGIC1
IOR A,GETFLV(P)
;COMMON EXECUTION ROUTINE FOR LOGICAL OPERATORS
LOGIC1: JUMPN B,MULTP4 ;NO RELOCATION ALLOWED
SKIPE GETFLR(P) ;NOW CHECK RELOCATION OF LEFT OPERAND
JRST MULTP4
XCT (D) ;ALL TESTS PASSED, DO IT
MOVE D,GETFLB(P) ;ARE THERE ANY GLOBALS OR UNDEFINED SYMBOLS?
CAMN D,GLSP1
JRST GETFD4 ;NO.
SKIPGE FF ;YES. ON THE PUNCHING PASS, THAT'S AN ERROR.
ETR [ASCIZ /External in arg to \, & or #/]
TLO I,ILNOPT ;ON PASS 1, JUST DON'T OPTIMIZE IF IN LITERAL.
JRST GETFD4
CBAKAR: MOVSI TT,100 ;BACKARROW AS FIELD OPERATOR, PREC = 100
JSP C,GETFDL ;RETURN TO GETFLD TO READ 2ND ARGUMENT.
JSP D,LOGIC1 ;FOR EVALUATION, CALL LOGIC1
JSP D,.+1 ;WHICH EXECUTES THIS INSTRUCTION,
MOVE T,A ;TO CALL THIS SUBROUTINE.
MOVE A,GETFLV(P)
LSH A,(T)
JRST (D)
;D SHOULD HAVE 1 FOR <, 2 FOR (, 3 FOR [ ;]
LSSTH9: JSP LINK,SAVAS1 ;SAVE ASSEM1 PDL LEVELS, .BYTE MODE, ETC.
MOVEM D,ASMOUT ;SAY WHAT KIND OF OPEN WE JUST DID
JRST ASSEM3 ;REENTER ASSEM1 LOOP AT INNER LEVEL.
;COME HERE TO EXIT FROM AN ASSEM1 LEVEL THAT WAS ENTERED BY LSSTH9.
LSSTHA: SKIPE BYTM ;IN BYTE MODE, DO .WALGN. SINCE ASMDSP
JRST A.BY3 ;STILL POINTS HERE, WE'LL COME BACK.
MOVE P,CONSTP
JSP T,CONNDP ;POP STUFF SAVED BY SAVAS1
MOVE A,WRD ;RETURN THE WORD IN THE GROUPING
MOVE B,WRDRLC ;(OUR CALLER WILL USVWLD, CLOBBERING WRD)
POPJ P,
LSSTH: MOVEI D,1 ;1 FOR <.
JSP LINK,SAVWD1
PUSHJ P,LSSTH9
LSSTH3: JSP LINK,USVWLD ;POP OFF ALL BUTPREVIOUS SYLL.
;GROUPINGS EXCEPT (PARENS THAT ADD TO WORD)
;SYLL IMMEDIATELY BEFORE OR AFTER IS ERROR.
LSSTH2: ADDM A,-1(P) ;SYLL BEFORE GROUPING, PUSHED BY SAVWD1.
ADDM B,(P)
TRNE I,IRSYL ;IF WAS SYLL BEFORE GROUPING, ERROR.
ETR ERRNOS
LSSTH5: MOVE A,LIMBO1 ;CHECK FOR FOLLOWING SYLL.
CAIE A,15
CAIN A,12
JRST LSSTH6 ;DELIMITER CR OR LF
PUSHJ P,RCH ;NOT CR OR LF, GET NEXT CHAR
CAIN A,"! ;IGNORE EXCLAMATION POINT
JRST .-2
TLO FF,FLUNRD ;CAUSE IT TO BE RE-INPUT
HLRZ CH1,GDTAB(A)
CAIE CH1,(POPJ P,)
JRST LSSTH4 ;SQUOZE CHAR. MEANS FOLLOWING SYLL.
HRRZ CH1,GDTAB(A)
MOVE CH1,DTB-40(CH1) ;GET DISPATCH FOR CHAR.
TLNE CH1,DSY1 ;MIGHT START SYL => NOS ERROR.
JRST LSSTH4
LSSTH7: PUSHJ P,GTSL1
LSSTH6: TRO I,IRSYL
POP P,B
POP P,A ;VALUE OF GROUPING WAS ADDM'ED INTO THESE.
TLZE I,ILLSRT ?.SEE UA3
RET ;IF CALLED BY ^ OR _ AS SYL OP, RETURN TO IT.
JRST GETFD6
LSSTH1: TLO I,ILWORD ;A NUMBER IN PARENS BY ITSELF IS A NONNULL WORD.
ADDM A,WRD
ADDM B,WRDRLC
TRNE I,IRSYL ;IF SYLL BEFORE,
JRST LSSTH5 ;ERROR IF SYL AFTER.
JRST LSSTH8 ;ELSE NO ERROR.
LSSTH4: ETR ERRNOS ;FOLLOWING SYLL WHEN THAT IS ERROR.
LSSTH8: TLNE I,ILLSRT ?.SEE UA3
JRST LSSTH6
SUB P,[2,,2]
JRST GETFD1
ERRNOS: ASCIZ /Syllables not separated/
POP2J: SUB P,[2,,2]
POPJ P,
LEFTP: MOVEI D,2 ;2 FOR ).
JSP LINK,SAVWD1
MOVEI C,0
TRNE I,IROP
TRNE I,IRSYL
TLO C,400000 ;CAUSE IT TO GET ADDED INTO WORD STEAD HAVE VALUE AS SYL
PUSH P,C
PUSHJ P,LSSTH9
POP P,C
MOVSM A,T1 ;STORE SWAPPED VALUE
ADDI B,400000 ;NOW WANT TO SWAP RELOCATION, MAKE LH CORRECT
HLREM B,T2 ;STORE AS RH WITH SIGN EXTENDED
MOVSI B,400000(B) ;GET RIGHT HALF IN LEFT
ADDM B,T2 ;FINISH RELOCATION SWAP (THIS IS PAINLESS COMPARED TO THE HAIR EVERYWHERE
;ELSE WHEN KEEPING THE HALFWORDS SEPARATE)
MOVSI B,SWAPF
PUSHJ P,LNKTC1
JSP LINK,USVWLD
MOVE A,T1
MOVE B,T2
JUMPL C,LSSTH1 ;ADD TO WHOLE WORD
JRST LSSTH2
;VERSION OF GETWRD FOR PSEUDO,
;PSEUDO MUST EITHER SAVE I, PPRIME AND GTVER OR RETURN TO ASSEM1.
;SYM SHOULD HOLD NAME OF PSUEUDO.
AGETWD: MOVEM SYM,GTVER ;STORE NAME OF PSEUDO FOR UNDEF SYM MSGS.
TRO I,IRPSUD\IRDEF\IRNOEQ
PUSHJ P,GETWRD
MOVE SYM,GTVER ;RESTORE SYM.
TLNE I,ILMWRD
PUSHJ P,IGTXT ;SOAK UP MULTIPLE WORD
RET
;;GETWD ;READ A WORD, LEAVE VALUE IN A AND WRD, RELOC IN WRDRLC AND B
GETWRD: MOVE T,GLSP1
MOVEM T,GLSP2
CLEARM FORMAT ;CLEAR FORMAT, WILL ACCUMULATE FORMAT NUMBER BY IDPB
CLEARM WRD ;CLEAR WRD, WILL ACCUMULATE ABSOLUTE PART OF WORD
CLEARM WRDRLC ; " RELOCATION BITS, "
TDZ I,[ILWORD,,IRIOINS]
CLEARM FLDCNT ;NO FIELDS YET
MOVE T,[50100,,FORMAT] ;SET UP BIT POINTER TO FORMAT
MOVEM T,FORPNR
GTWD1: PUSHJ P,GETFLD ;READ NEXT FIELD
SPACE6: MOVEI T,1 ;SET T TO 1, AC FOR IDPB ON ROUTINE DISPATCHED TO
SKIPA C,CDISP
SPACE5: REST A
TLNE C,DWRD
JRST (C) ;NO DISPATCH MEANS WD TERMINATOR
MOVE C,GLSP1
MOVEM C,LINKL ;MARK END OF ACTIVE PART OF GLOTB
TRNN I,IRFLD
JRST GETWD2 ;LAST FIELD NULL, MAYBE HAVE TO POP STUFF OFF
IDPB T,FORPNR ;MARK NON-NULL FIELD IN FORMAT
GTWD4A: TLO I,ILWORD ;NON-NULL WORD
MOVE TT,FORMAT
SKIPN TT,FORTAB-10(TT) ;PICK UP BYTE POINTER POSITION/SIZE FIELDS FOR FIELDS IN WORD
ETR [ASCIZ /Undefined format/]
MOVEM TT,FORMAT ;STORE IN FORMAT
MOVE T,[301400,,FORMAT]
MOVEM T,FORPNR
;AT THIS POINT, FLDCNT HAS 1 LESS THAN # FIELDS; PUT FIELDS TOGETHER TO FORM WORD
GTWD3: LDB T,FORPNR
MOVE D,FLDCNT
CAIG D,2
IBP FORPNR ;HAVEN'T BACKED UP TO THIRD FIELD YET, INCREMENT TO DESC FOR PREV
TRNE I,IRIOINS
PUSHJ P,INTIOW
PUSHJ P,INTFLD ;PUT FIELD WHERE IT BELONGS
SOSGE FLDCNT
JRST GTWD5 ;THIS WAS LAST (FIRST) FIELD
POP P,GLSP2 ;NOT YET, POP OFF MORE
POP P,GLSP1
POP P,B
POP P,A
JRST GTWD3
GTWD5: MOVE A,WRD
MOVE B,WRDRLC
MOVE C,LINKL
MOVEM C,GLSP1
TRZ I,IRIOINS
POPJ P,
COMMA: TRNN I,IRFLD ;FIELD DELIMITER WAS COMMA (T HAS 1)
JRST COMMA1 ;NO FIELD
IDPB T,FORPNR ;MARK NON-NULL FIELD
COMMA4: IDPB T,FORPNR ;MARK FIELD TERMINATOR WAS COMMA
MOVE TT,FLDCNT
CAIL TT,2
ETR [ASCIZ /Comma past the 3rd field of a word/]
PUSHFD: PUSH P,A ;DONE WITH THIS FIELD, NOW TO GET NEXT
PUSH P,B
PUSH P,GLSP1
PUSH P,GLSP2
AOS FLDCNT ;ANOTHER FIELD
MOVE TT,GLSP1
MOVEM TT,GLSP2
HRRZ T,FORPNR
CAIE T,FORMAT
HRRZS FORPNR ;STABILIZE FORPNR
TLO I,ILWORD ;SAY WE HAVE A NON-NULL WORD IN PROGRESS (LOC, ETC. ILLEGAL).
JRST GTWD1
GETWD2: SKIPN FORMAT ;LAST FIELD OF WORD IS NULL
JRST GTWD5 ;ENTIRE WORD NULL, MAYBE WERE PARENS.
SOS FLDCNT
POP P,GLSP2
POP P,GLSP1
POP P,B
POP P,A
JRST GTWD4A
COMMA1: LDB TT,FORPNR ;COMMA TERMINATED NULL FOELD.
SKIPE FORMAT
JUMPE TT,COMMA2 ;NOT 1ST FIELD, JMP IF PREV WAS TERM BY SPACE.
IBP FORPNR ;ELSE MARK NULL FIELD IN FORMAT.
JRST COMMA4
;FIELD SPACE COMMA, PATHOLOGICAL CASE
;(EG MACRO STARTED WITH A COMMA)
COMMA2: DPB T,FORPNR ;REPLACE SPACE WITH COMMA.
JRST GTWD1
;FIELD TERMINATOR IS SPACE (T HAS 1)
SPACE: MOVE TT,LIMBO1
CAIE TT,^I ;HEURISTIC: REAL SPACES ARE LIKELY TO BE FOLLOWED BY SQUOZE,
JRST SPACE4 ;WHILE TABS ARE LIKELY TO BE FOLLOWED BY COMMENTS.
PUSH P,A
MOVE TT,GDTAB+40
PUSHJ P,RCH
CAMN TT,GDTAB(A)
JRST .-2 ;FLUSH OTHER LOGICAL SPACES
CAIN A,"; ;TAB WAS FOLLOWED BY SEMICOLON:
JRST [ PUSH P,B
TRZ I,IRSYL
CALL SEMIC ;FLUSH THE COMMENT
MOVEI T,1
REST B
JRST SPACE5] ;AND HANDLE THE C.R.
SPACE3: POP P,A
TLO FF,FLUNRD ;CAUSE CHAR TO BE RE-READ NEXT TIME
SPACE4: TRNN I,IRFLD
JRST GTWD1 ;NO FIELD
IDPB T,FORPNR ;T HAS 1, MARK NON-NULL FIELD IN FORMAT
IBP FORPNR ;MARK FIELD TERMINATOR WAS SPACE
JRST PUSHFD
;T HAS DESC BYTE, PUT FIELD IN ITS PLACE
;ALSO CALLED FROM PBYTE, MUSTN'T CLOBBER AA.
INTFLD: MOVE TT,GLSP2
CAMN TT,GLSP1
JUMPE B,INTFD1 ;NO GLOBALS, JUMP IF NO RELOCATION
CAIN T,2222 ;LH
JRST INTL
CAIN T,22 ;RH
JRST INTR
CAIN T,44 ;WHOLE WORD
JRST INTW
SKIPE B
ETR [ASCIZ/Relocation attempted in irrelocatable field/]
;(ASSUME) NO RELOCATION, CHECK FOR GLOBAL AC FIELDS
CAIN T,2704 ;HIGH AC
JRST INTACH
CAIN T,504 ;AC LOW
JRST INTACL
JUMPGE FF,INTFD1 ;JUMP ON NOT PUNCHING PASS
CAME TT,GLSP1
ETR [ASCIZ/Global symbol in illegal field/]
INTFD1: MOVEI TT,C_12.
ROTC T,-12. ;SHIFT BYTE POINTER INTO TT
MOVEI C,0 ;INITIALIZE C TO RECEIVE FIELD IN PROPER PLACE
DPB A,TT
CAMN TT,[2200,,C]
JRST INTFD2 ;RIGHT HALF, DON'T ALLOW CARRY INTO LH
ADDM C,WRD ;ALLOW CARRY
INTFD3: ADDM B,WRDRLC ;ADD RELOCATIONS, WILL BE BROKEN BACK INTO HALF-WORDS LATER
POPJ P,
INTFD2: ADD C,WRD ;ADD RIGHT HALVES
HRRM C,WRD
JRST INTFD3
INTIOW: CAIE T,2704
CAIN T,504
TRZA A,3 ;IO DEVICE FIELD
POPJ P, ;NOT "AC" FIELD
ADDI T,611-504
POPJ P,
INTR: HRRE D,B ;RH
MOVEI B,0
PUSH P,T
HRLZI C,HFWDF
PUSHJ P,LNKTC1 ;THIS IS A BUG WHICH SHOULD BE FIXED SOMETIME
PRTCL: MOVE B,D ;GET BACK MAPPED RELOCATION BITS
PRTCL2: POP P,T
INTW: MOVE D,GLSP2 ;WHOLE WORD
HRLOI LINK,377777
CAML D,GLSP1
JRST INTFD1
ANDM LINK,1(D)
AOJA D,.-3
INTL: HRLZ D,B ;LH
MOVSI B,SWAPF
MOVSI C,HFWDF
PUSH P,T
MOVE T,GLSP2
INTL2: CAML T,GLSP1
JRST PRTCL
SKIPGE 1(T)
AOJA T,INTL2 ;INDEX FIELD, ETC => LEAVE ALONE
IORM C,1(T) ;SET HFWDF
XORM B,1(T) ;COMPLEMENT SWAP STATUS
TDNN B,1(T)
SETZM 1(T) ;SWAPPED TO RH, FLUSH IT
AOJA T,INTL2
INTACL: TDZA B,B ;AC LOW
INTACH: HRLZI B,SWAPF ;AC HIGH
HRLZI C,ACF
PUSH P,T
PUSHJ P,LNKTC1
MOVEI B,0
JRST PRTCL2
IOINST: HLLZ A,B ;IO INSTRUCTION, GET WHICH ONE INTO A
SKIPN FLDCNT ;THIS FIRST FIELD OF WORD?
TRO I,IRIOINS ;YES
JRST CLBPOP ;RETURN VALUE
;TOP LEVEL LOOP, ASSEMBLE STORAGE WORDS
;LOTS OF PSEUDOS MEANINGLESS IN STORAGE WORDS
;(E.G. BLOCK, CONSTA) DO JRST ASSEM1 WHEN DONE
;THERE'S ALSO AN ERROR UUO WHICH RETURNS TO ASSEM1
ASSEM1: MOVE P,ASSEMP
JRST @ASMDSP
;COME HERE TO START THE NEXT EXPRESSION OR WHATEVER.
ASSEM3: PUSHJ P,RCH
CAIN A,^I
JRST ASSEM2 ;PROBABLY NOT PROFITABLE TO SKIP AFTER SEE A TAB.
CAIG A,40
JRST ASSEM3 ;FLUSH LEADING GARBAGE
TLO FF,FLUNRD ;CAUSE NON-GARBAGE CHAR FOUND TO BE RE-INPUT
;ASMDSP POINTS HERE WITHIN ASCII, SIXBIT ETC.
ASSEM2: TRZ I,IRFLD+IRSYL+IRLET+IRPSUD+IRCOM+IRCONT+IRGMNS+IROP+IRNOEQ+IREQL
TLZ I,ILGLI+ILVAR+ILFLO+ILDECP+ILUARI+ILWORD+ILNPRC+ILNOPT
IOR I,ASMI ;SET DEF AND RESTORE PSEUDF.
MOVE A,GLSPAS
SKIPL BYTM
MOVEM A,GLSP1
;GETWRD WILL COPY GLSP1 INTO GLSP2
IFN TS,[AOSN TTYBRF ;DO A ^H-BREAK IF REQUESTED.
CALL TTYBRK]
PUSHJ P,GETWRD
TLZN I,ILWORD
JRST @ASMDSP ;NO WORD ASSEMBLED,TRY AGAIN
SKIPGE BYTM
JRST PBYTE ;IN BYTE MODE, OUTPUT BYTE INSTEAD OF WORD, A,B MUST HAVE WRD,WRDRLC.
MOVE AA,ASMOUT ;OUTPUT WD AS APPRO. FOR GROUPING, IF ANY.
JRST @ASMOT0(AA)
ASSEM6: SKIPE STGSW ;ASMOT0 POINS HERE. COME IF NOT IN GROUPING.
ETR ERRSWD ;STORAGE WORD ASSEMBLED
PUSHJ P,PWRD ;OUTPUT THE WORD.
AOS CLOC
HRRZS CLOC ;INCREM. POINT .
JRST @ASMDSP ;ASSEM3 OR ASSEM2
ERRSWD: ASCIZ /Storage word assembled/
ASSEM4: JSP T,PCONST ;ASMOT0+3 POINTS HERE. COME IF IN CONSTANT.
JRST @ASMDSP
;ASMDSP POINTS HERE WITHIN GROUPING IF NOT IN MULTI-LINE MODE
;[ ;AND NO CLOSE (">)]") HAS BEEN SEEN.
ASSEMC: MOVE AA,ASMOUT
SKIPE CONSML ;IN ERROR MODE, GIVE APPROPRIATE ERROR MSG.
XCT ASMOT3(AA)
JRST @ASMOT2(AA) ;CLOSE WHATEVER TYPE GRPING WE'RE IN.
;JUMP THRU THIS TABLE TO OUTPUT A WORD.
ASMOT0: ASSEM6? ASSEM1? ASSEM1? ASSEM4? [GOHALT ]
;THIS TABLE GIVES APPRO. CLOSE FOR EACH TYPE OF GROUPING. ;[
ASMOT1: "? ? "> ? ") ? "] ? "?
;THIS TABLE SAYS WHERE TO GO TO END THE GROUPING.
ASMOT2: [GOHALT ]? LSSTHA? LSSTHA? CONND? [HALT ]
;APPROPRIATE ERROR MESSAGE FOR MISSING CLOSE OF GROUPING. [
ASMOT3: GOHALT
ETR [ASCIZ /Missing >/]
ETR [ASCIZ /Missing )/]
ETR [ASCIZ /Missing ]/]
GOHALT
;THIS TABLE TELLS PBYTE HOW TO HANDLE BYTE MODE.
ASMOT4: PBY4 ? PBY5 ? PBY5 ? PBY3 ? [GOHALT ]
;TABLE SAYING WHAT CHAR MUST HAVE OPENED THE GROUPING.
ASMOT5: "? ? "< ? "( ? "[ ? "? ;]
;;GETVAL ;GET VALUE OF SYM
;SKIPS ON PSEUDO NOT RETURNING VALUE (E.G. MACRO STARTING TO BE EXPANDED)
;ELSE RETURNS VALUE IN A, RELOCATION BITS IN B
VBLK
GTVER: 0 ;SQUOZE NAME OF CALLING PSEUDO, OR POINTER
;TO INSN TO EXECUTE WHEN IF SYM IS UNDEF.
PBLK
GETVAL: PUSHJ P,ES
JRST GVNF ;NO STE.
IFN CREFSW,XCT CRFINU ;JFCL OR CALL TO CREF RTN.
JRST @.+1(A) ;FOUND, DISPATCH ON SQUOZE FLAGS
GVTAB: GVCOM ;COMMON (UNUSED)
GVPSEU ;PSEUDO OR MACRO.
GVSYM ;LOCAL SYMBOL.
GVUL ;LOCAL UNDEF (MAYBE STINK KNOWS VALUE)
GVDLV ;DEFINED LOCAL VAR.
GVULV ;UNDEF LOC VAR.
GVDGV ;DEF GLO VAR
GVUGV ;UNDEF GLO VAR
GVDG ;DEF GLOBAL
GVUG ;UNDEF GLOBAL
;DEF LOCAL VAR.
GVDLV: PUSHJ P,GVDLGV ;IF PASS2 AND HAS ' THIS TIME, SET 3VAS2 FOR AVARIAB
TLZN I,ILGLI
JRST GVDLV2
MOVSI T,DEFGVR ;NOW DEF GLO VAR.
PUSHJ P,VSM2
JRST GVDG1 ;MAYBE OUTPUT GLOBAL DEF. TO STINK.
GVDGV: PUSHJ P,GVDLGV ;DEF GLO VAR; IF PASS 2 AND ' THIS TIME, SET 3VAS2
JRST GVDG2 ;MUSN'T PUNCH VALUE, AVARIAB WILL.
GVDLGV: TRNE FF,FRPSS2 ;IF PASS 2
TLNN I,ILVAR ;AND THIS TIME HAVE SINGLEQUOTE
POPJ P,
TLO C,3VAS2 ;TELL AVARIAB SEEN IN PASS 2 WITH '.
3PUT C,D
POPJ P,
GVULV: TLZN I,ILGLI ;UNDEF LOCAL VAR, MAYBE MAKE GLOBAL.
JRST GVUNDF
PUSHJ P,PLOGLO ;IF SO, TELL STINK SYM IS GLOBAL,
MOVSI T,UDEFGV ;SYM NOW UNDEF GLO VAR
PUSHJ P,VSM2
JRST GVUNDF ;IN EITHER CASE, HANDLE UNDEF SYM.
GVUL: TLZE C,3MACOK ;UNDEF LOCAL, PRESUMED NUMERIC
3PUT C,D ;DON'T LET IT BECOME MACRO AND SCREW PASS2.
TLNE C,3LLV
JRST GVGLTB ;(REALLY DEFINED BUT ONLY STINK KNOWS HOW)
TLNE I,ILGLI ;IF MAKING GLOBAL, TELL STINK.
PUSHJ P,PLOGLO
GVNF1: TLZE I,ILVAR ;IF ', MAKE VAR (WILL CHECK ILGLI)
JRST GVUL1
TLZN I,ILGLI ;NOT MAKING VAR, MAYBE GLOBAL?
JRST GVUNDF ;NO, MAYBE ERROR, MAKE GLOTB ENTRY.
MOVSI T,GLOEXT
PUSHJ P,VSM2 ;NOW GLOBAL UNDEF,
JRST GVGLTB ;NO ERROR, JUST GLOTB ENTRY.
GVUL1: TLZN I,ILGLI ;UNDEF LOCAL BECOMES
SKIPA T,[UDEFLV,,] ;UNDEF LOC VAR OR
GVGVAR: MOVSI T,UDEFGV ;UNDEF GLO VAR.
GVVAR: CALL ESDEF ;DEFINING SYM AS A VAR => INSIST ON DEFINING LOCAL TO INNERMOST BLOCK.
JFCL
AOS VARCNT
HRR B,VARCNT
PUSHJ P,VSM2 ;MAKE IT A VAR,
JRST GVUNDF ;PRETEND HAD ALREADY BEEN A VAR.
GVUG: TLZE I,ILVAR ;UNDEF GLOBAL: MAYBE MAKE UNDEF GLO VAR.
JRST GVGVAR
GVGLTB: SKIPGE CONTRL ;UNDEF GLO IN ABS ASSEM =>
JRST GVUND1 ;MAYBE TREAT AS UNDEF.
GVGLT1: AOS GLSP1 ;DON'T KNOW SYM'S VALUE, MAKE GLOTB ENTRY.
MOVEI T,ST(D)
HRRZM T,@GLSP1
JRST CABPOP ;RETURN 0 AS VALUE.
GVNF:
IFN CREFSW,XCT CRFINU ;ONLY IF NOT FOUND WOULD NOT CREF AFTER ES.
TLNE I,ILVAR+ILGLI ;MAKING VAR OR GLOBAL FORCED CURRENTBLOCK ALREADY
JRST GVNF1 ;AND WILL STORE NAME IN STE ANYWAY.
SKIPGE ESBK ;ELSE IF NO SPEC'D BLOCK,
TRNN FF,FRNPSS ;FORCE .MAIN BLOCK SO DON'T GET LOTS OF UNDEF ENTRIES.
CAIA ;BUT CAN'T DO THAT FOR 1PASS OR WOULD MISS FWD REFS.
HRRI C,BKWPB
MOVSI T,LCUDF
PUSHJ P,VSM2
JRST GVUNDF ;MAYBE ERROR, MAKE GLOTB ENTRY.
GVCOM: TRO I,IRCOM ;COMMON: SAY THIS WAS ONE.
HRRZ A,B ;RETURN RH OF VALUE, ABSOLUTE.
JRST CLBPOP
GVPSEU: TLNN I,ILVAR+ILGLI ;CAN'T MAKE PSEUD OR MACRO GLOBAL OR VAR.
JRST (B) ;OTHERWISE, DISPATCH TO IT.
TLZE I,ILVAR
ETSM ERRCBV
TLZE I,ILGLI
ETSM ERRCBG
JRST (B) ;DISPATCH TO PSEUDO (OR MACCL IF MACRO)
;EXPECTS LH OF VALUE IN LH OF B.
ERRCBV: ASCIZ /Can't be a variable/
ERRCBG: ASCIZ /Can't be global/
GTVL7B: TLNE C,3RLL ;R(LH)
TLO SYM,200000
TLNE C,3RLR ;R(RH)
TLO SYM,100000
POPJ P,
GVSYM: TLNN C,3REL
TLNE I,ILVAR\ILGLI
JRST GVSYM2
MOVE A,B ;THIS CODE DOES WHAT GVSYM2 WOULD DO, BUT FASTER.
SETZ B,
RET
GVSYM2: TLZE I,ILVAR ;LOCAL SYM: CAN'T MAKE VARIABLE.
ETSM ERRMDV
TLZN I,ILGLI
JRST GVSYM0 ;NOT MAKING GLOBAL, GET VALUE & RETURN.
GVSYM1: MOVSI T,GLOETY ;BECOMES DEF. GLOBAL.
PUSHJ P,VSM2
JRST GVDG1 ;HANDLE AS IF WAS DEF GLOBAL.
ERRMDV: ASCIZ /Multiply-defined variable/
GVDG: TLZE I,ILVAR ;GLOBAL ENTRY
ETSM ERRMDV
;COME HERE FOR DEF GLOBAL
GVDG1: SKIPGE CONTRL
JRST GVDLV2 ;DON'T PUNCH VALUE IF ABSOLUTE.
TLNE C,3VP
JRST GVDG2 ;VALUE PUNCHED ALREADY, NOT AGAIN.
JUMPGE FF,GVDG2
TLNN C,3LLV
TRNE I,IRPSUD+IREQL
JRST GVDG2
TLO SYM,40000
PUSH P,WRD
PUSHJ P,OUTDE2
POP P,WRD
GVDG2: TRNN I,IRPSUD\IREQL ;IF INSIDE AN ORDINARY STORAGE WORD,
TLNN C,3REL ;GENERATE A GLOBAL REF IF GLOBAL IS RELOCATABLE (HEURISTIC).
GVDLV2: TLNE C,3LLV ;IF VAL KNOWN ONLY BY STINK, MUST MAKE A GLOBAL REF.
JRST GVGLTB
GVSYM0: MOVE A,B ;USED IN LBRAK
LDB B,[.BP (3RLR),C]
TLNE C,3RLL
TLO B,1
POPJ P,
GVUND1: MOVE A,CONTRL
TRNE A,DECREL+FASL ;DEC FMT OR FASL => UNDEF GLOBALS OK.
JRST GVGLT1
GVUGV:
GVUNDF: TRZ I,IRDEF ;UNDEFINED, MAYBE ERROR, MAKE GLOTB ENTRY.
TRNE I,IRPSUD\IREQL
JRST GVUND2 ;PSEUDO
TRNN FF,FRPSS2
JRST GVGLT1 ;PASS 1
SKIPN CONDEP
ETSM [ASCIZ/Undefined/]
SKIPE CONDEP
ETSM [ASCIZ/Undefined in literal/]
JRST CABPOP
GVUND2: HLRZ A,GTVER ;DOES GTVER POINT TO AN INSN?
JUMPE A,[XCT @GTVER ? JRST CABPOP]
ERJ .+1 ;NO, IT IS NAME OF PSEUDO.
MOVE A,LINEL
CAIGE A,75. ;CR-LF-TAB NOW IF WHOLE MSG WON'T FIT ON A LINE.
CALL CRRTBX
TYPE2 SYM ;TYPE NAME OF UNDEF SYM.
TYPR [ASCIZ/ Undefined in /]
TYPE2 GTVER
CALL CRRERR
JRST CABPOP
;EVALUATE SYMBOL, SQUOZE (FLAGS OFF) IN SYM
;IDX OF BLOCK TO DEFINE IN IN ESBK (OR -1 => ANY BLOCK NOW IN PROGRESS).
;DOESN'T CLOBBER F (FOR WRQOTE)
;RETURNS SKIPPING IF SYM FOUND, WITH SQUOZE FLAGS IN BOTTOM OF A,
;VALUE OF SYM IN B, STE IDX IN D, AND 3RDWD IN C.
;IF NOT FOUND, RETURNS IN D THE IDX OF A PLACE TO DEFINE SYM.
;CALL ESDCHK TO GET THE FOLLOWING EXTRA INFO (WHETHER SYM FOUND OR NOT):
;ESLAST -> LAST STE WITH DESIRED NAME SEEN, REGARDLESS OF WHAT BLOCK IT'S IN
;ESL1 HAS LEVEL OF BLOCK OF BEST STE SEEN, -1 IF NOT FOUND
;ESL2 HAS 3RDWRD OF BEST.
;ESXPUN HAS -1 OR IDX OF A STE WHICH MIGHT BE USED TO DEFINE THE SYM.
;RH(TM) GETS BLOCK IDX TO DEFINE IN IF DEFINE THE SYM.
;TT HAS -<# STE NOT LOOKED AT YET>
;THEN IF SYM IS FOUND IN A CONTAINING BLOCK AND YOU WANT TO DEFINE
;IT IN THE CURRENT BLOCK, YOU CAN CALL DEFCHK TO FIND AN STE TO DO IT IN.
;CALLING ESDEF IS AS GOOD AS CALLING ESDCHK AND DEFCHK, BUT DOESN'T
;LET YOU SEE WHAT YOU ARE GOING TO SHADOW.
ESDEF: MOVE A,BKCUR ;EVAL SYM IN ORDER TO DEFINE IT:
SKIPGE ESBK ;IF NO SPEC'D BLOCK, SPEC THE CURRENT BLOCK,
MOVEM A,ESBK ;SO DEFS IN CONTAINING BLOCKS WON'T BE SEEN
ESDCHK: SETOM ESLAST ;CALL HERE IF WE MIGHT END UP CALLING DEFCHK,
SETOM ESL1 ;SINCE IN THAT CASE WE'LL NEED THESE VARS EVEN IF SYM IS FOUND
SETOM ESXPUN ;RIGHT AWAY.
MOVN TT,SYMLEN
ES: MOVE C,SYM ;HASH AWAY
TSC C,SYM ;THIS MAKES SURE THAT THE FIRST FEW CHARS OF SYMBOL DON'T GIVE
;A ZERO REMAINDER, IF SYMLEN IS A ROUND NUMBER.
MOVMS C ;THIS IS BECAUSE IDIV OF NEGATIVE NUMBER GIVES NEG. REMAINDER.
IDIV C,SYMLEN
IMUL D,WPSTE
SKIPGE TM,ESBK ;GET BKTAB IDX OF SPEC'D BLOCK
HRR TM,BKCUR ;OR -1,,BKTAB IDX OF CURRENT BLOCK.
;NOW CHECK FAST FOR AN IMMEDIATE MATCH - AVOID SETTING UP FLAGS NEEDED ONLY WHEN
;SYM APPEARS IN MULTIPLE BLOCKS OR ISN'T DEFINED.
SKIPN B,ST(D)
JRST ESEND0 ;SYM IS KNOWN NOT TO BE DEFINED.
TLZ B,740000
CAME B,SYM
JRST ESBAD0 ;NOT FOUND IN 1ST ENTRY - MUST SET UP INFO AND LOOP
3GET C,D
MOVEI A,(C)
CAIN A,(TM)
JRST ESGOOD ;IN THE DESIRED BLOCK => GOOD.
TDNN C,[3MAS,,-1] ;IN THE INITIAL SYMS BLOCK, NOT PRESENT IN ANY OTHER,
JUMPL TM,ESGOOD ;AND BLOCK WASN'T EXPLICITLY SPEC'D => GOOD.
MOVN TT,SYMLEN ;ELSE MUST KEEP LOOKING TO SEE IF THIS DEF IS REALLY ONE WE WANT.
SETOM ESLAST
SETOM ESL1
SETOM ESXPUN
JUMPGE TM,ESIGN
JRST ESLP1
;LOOK AT THE NEXT STE, WHILE LOOPING.
ESLP: SKIPN B,ST(D) ;GET SQUOZE IN THIS ST SLOT
JRST ESEND ;NOTHING WHERE SYM BELONGS, END SEARCH
TLZ B,740000 ;CLEAR OUT FLAGS
CAME B,SYM ;COMPARE WITH WANTED
JRST ESBAD ;NO MATCH BUT MAYBE KEEP GOING
3GET C,D ;FOUND SYM, GET 3RDWRD
MOVEI A,(C)
CAIN A,(TM) ;DEFINED IN DESIRED BLOCK
JRST ESGOOD ; => MUST BE GOOD.
ESLP0: JUMPGE TM,ESIGN ;BLOCK SPEC'D => ALLOW NO OTHERS.
TDNE C,[3MAS,,-1] ;IF IN INITIAL SYMS BLK, NO MORE DEFS,
JRST ESLP1
SKIPGE ESL1 ;AND NO PREVIOUS DEFS,
JRST ESGOOD ;UNREDEFINED INITL SYM MUST BE GOOD.
ESLP1: HLRZ B,BKTAB+1(C) ;GET LEVEL OF BLOCK DEF. IS IN.
CAMN A,BKPDL(B) ;SAME AS BLOCK WE'RE IN AT THAT LEVEL?
CAMLE B,BKLVL ;AND NOT A BLOCK WE'VE EXITED
JRST ESIGN
CAMG B,ESL1 ;OR HIGHER LEVEL THAN PREVIOUS BEST
JRST ESIGN
MOVEM C,ESL2 ;REPLACE BEST'S 3RDWRD, LEVEL, ADDR.
MOVEM B,ESL1
MOVEM D,SADR
ESIGN: HRRZM D,ESLAST ;THIS ENTRY LAST SEEN WITH THIS NAME.
TLNN C,3MAS ;MORE STE'S FOR THIS SYM =>
JRST ESEND1
JRST ESNXT ;KEEP LOOKING.
;COME HERE IF 1ST SYM SEEN ISN'T THE SAME NAME. SET UP TO LOOP.
ESBAD0: MOVN TT,SYMLEN
SETOM ESLAST
SETOM ESL1
SETOB C,ESXPUN
;HERE WHILE LOOPING WHEN SYM WITH WRONG NAME IS SEEN.
ESBAD: JUMPN B,ESNXT
SKIPGE A,ESXPUN ;IF THIS IS 1ST EXPUNGED ENTRY SEEN
MOVEM D,ESXPUN ;REMEMBER IT FOR DEFINITION.
SKIPGE A
HRROS ESLAST ;AND SET OLD ENTRY'S 3MAS.
ESNXT: ADD D,WPSTE
CAML D,SYMSIZ ;AT END => GO TO BEGINNING
MOVEI D,0
AOJN TT,ESLP
JRST ESEND1 ;NOT FOUND.
ESEND0: MOVEI C,(TM) ;COME HERE IF 1ST PLACE LOOKED AT SHOWS THE SYM ISN'T DEFINED
MOVEM D,ESXPUN
POPJ P,
ESEND: SKIPGE A,ESXPUN ;FREE ENTRY CAN BE USED TO DEFINE.
MOVEM D,ESXPUN
SKIPGE A
HRROS ESLAST
ESEND1: SKIPGE ESL1 ;NOT FOUND => FIND PLACE TO DEFINE IT.
JRST DEFCH1
MOVE D,SADR ;IDX OF BEST FOUND.
TRNN FF,FRNPSS
JRST ES1PS ;1-PASS, SPECIAL CHECK.
MOVE C,ESL2 ;GET BEST'S 3RDWRD.
ESGOOD: LDB A,[400400,,ST(D)] ;GET SQUOZE FLAGS IN A.
ES1POK: MOVE B,ST+1(D) ;VALUE OF SYM. IN B.
;D HAS IDX OF 1STWRD IN SYM TAB.
;C HAS 3RDWRD
POPJ1: AOS (P)
APOPJ:
CPOPJ: POPJ P,
;ESDCHK THEN DEFCHK IS SAME AS CALLING ESDEF.
;WE ASSUME THAT D AND TT ARE STILL SET UP FROM A CALL TO ESDCHK.
DEFCHK: SKIPGE ESL1 ;IF WE DIDN'T TAKE TIME TO SET ESLAST BEFORE,
HRRZM D,ESLAST ;DO IT NOW. (SEE BEFORE ESLP1)
JRST DEFCH1
ES1PS: LDB A,[400400,,ST(D)] ;1PASS & FOUND IN CONTAINING BLOCK:
MOVE C,ESL2
TRNN C,-1 ;INITIAL SYM, OK;
JRST ES1POK
CAIE A,1 ;PSEUDO OR MACRO
TLNE C,3DOWN ;OR .DOWN'D SYMBOL OK;
JRST ES1POK ;ELSE GET NEW STE TO DEF.
DEFCH1: MOVEI C,(TM) ;INITIALIZE NEW 3RDWRD WITH BLOCK TO DEF IN.
SKIPL D,ESXPUN ;IF FOUND EXPUNGED OR FREE ENTRY, USE IT.
JRST DEFCH2
SKIPGE D,ESLAST ;ELSE LOOK FOR ONE.
ETF ERRSCE
DEFCH4: MOVE B,ST(D)
TLZ B,740000
JUMPE B,DEFCH3 ;MUST RETURN 0 IN B IF DON'T SKIP.
ADD D,WPSTE
CAML D,SYMSIZ
MOVEI D,0
AOJL TT,DEFCH4 ;ASSUME TT LEFT AROUND FROM ES.
ETF ERRSCE
ERRSCE: ASCIZ /Symbol table full/
;ESLAST HAS -1 IF NO ENTRY SEEN; ELSE
;RH HAS IDX OF LAST SEEN, SIGN SET IF SEEN BEFORE PLACE TO DEFINE.
DEFCH3: MOVEM D,ESXPUN ;REMEMBER ADDR WHERE CAN DEFINE
HRROS ESLAST ;LAST PLACE SEEN MUST BE EARLIER.
DEFCH2: SKIPL A,ESLAST
JRST DEFCH5 ;LAST PLACE SEEN WAS SEEN AFTER PLACE TO DEFINE.
CAMN A,[-1]
POPJ P, ;REALLY NEVER SEEN.
MOVSI TM,3MAS
IORM TM,ST+2(A) ;PLACE SEEN IS EARLIER, SET ITS 3MAS.
POPJ P,
DEFCH5: TLO C,3MAS ;PLACE TO DEF BEFORE EXISTING STES.
POPJ P,
;ENTER A SYM IN SYMBOL TABLE
;B HAS VALUE
;C HAS 3RDWRD
;D HAS INDEX INTO ST (PROBABLY SET UP BY ES)
;T HAS SQUOZE FLAGS (ONLY) IN PLACE FOR IOR OF SQUOZE
;SYM HAS SQUOZE, FLAGS OF WHICH ARE IGNORED
VSM2LV: TLOA C,3LLV ;ENTRY FOR LINKING LOADER MUST SUPPLY VALUE
VSM2W: MOVE B,WRD ;ENTRY TO ENTER VALUE OF WRD STEAD B
VSM2: MOVE CH1,SYM
TLZ CH1,740000
IOR CH1,T ;CH1 := SQUOZE WITH FLAGS
MOVEM CH1,ST(D) ;STORE SQUOZE
MOVEM B,ST+1(D) ;STORE VALUE
VSM3A: 3PUT C,D ;STORE 3RDWRD
POPJ P,
;RETURN THE NUMBER OF SYMTAB SLOTS IN USE.
A.SYMCN:SKIPL A,SMSRTF ;IF SYMTAB HAS BEEN COMPACTED, GET # OF SYMS THAT IT HAD
JRST CLBPOP ;BEFORE COMPACTION AND RETURN THAT.
MOVE D,SYMAOB
SETZ A,
A.SYC1: MOVE B,ST(D)
TLZ B,740000
SKIPE B
AOS A
ADD D,WPSTE1
AOBJN D,A.SYC1
JRST CLBPOP
;;EQUAL ;EQUAL SIGN ENCOUNTERED, DO PARAMETER ASSIGNMENT
EQUAL: TLZ FF,FLHKIL
PUSHJ P,RCH
CAIE A,"= ;DECIDE WHETHER TO HALF-KILL THE SYM.
TLOA FF,FLUNRD
TLO FF,FLHKIL
SETZM LABELF
CALL RCH
CAIE A,": ;DECIDE WHETHER TO MARK SYM AS NOT REDEFINABLE.
TLOA FF,FLUNRD
SETOM LABELF
CAMN SYM,[SQUOZE 0,.] ;.=FOO, SAME AS LOC FOO
JRST PTEQ
TDNN I,[ILWORD,,IROP+IRNOEQ]
TRNN I,IRLET
ETR [ASCIZ/= With bad format or bad context/]
PUSH P,LABELF
PUSH P,SYM
PUSH P,ESBK
PUSH P,I
MOVEI A,[ETSM [ASCIZ/Undefined in =/]]
MOVEM A,GTVER
TRO I,IRNOEQ+IRDEF+IREQL
PUSHJ P,GETWRD
TRNN I,IRDEF
JRST ASEM1A ;UNDEFINED SYMS IN VALUE, IGNORE
IFN LISTSW,[
SKIPN LSTONP
JRST EQUAL1 ;NOT LISTING.
SKIPGE LISTPF
PUSHJ P,PNTR
MOVE SYM,WRD
MOVEM SYM,LISTWD
MOVE SYM,WRDRLC
MOVEM SYM,LSTRLC
SETOM LISTAD
SETOM LISTPF
EQUAL1:
] ;END IFN LISTSW,
TDZ I,[-1-(ILMWRD)]
IOR I,(P)
TLZ FF,FLUNRD
POP P,(P)
POP P,ESBK
POP P,SYM
POP P,LABELF
MOVE A,WRDRLC ;GET RELOCATION
TDNN A,[-2,,-2] ;SKIP ON NON-STANDARD RELOCATION BITS
SKIPE LDCCC
JRST EQG1 ;STRANGE RELOCATION OR IN LOAD TIME CONDITIONALS => HAND PROBLEM TO LOADER
MOVE A,GLSP1
CAMN A,GLSP2
JRST EQL1 ;NO GLOBALS IN DEFINITION
;FALLS THROUGH.
;FALLS THROUGH.
;GLOBALS TO RIGHT OF = OR WITHIN LOADER CONDIT.
EQG1: IFN CREFSW, XCT CRFLBL ;CREF DEF. OF NORMAL SYM,
SKIPGE CONTRL
JUMPL FF,[ETASM [ASCIZ /Externals in =/]]
CALL ESDCHK ;SEARCH SYM TAB.
JRST EQL2 ;NOT FOUND IN CURRENT OR CONTAINING BLKS.
HRRZI T,(C) ;GET BKTAB IDX OF BLOCK FOUND IN.
CAIE T,(TM)
JRST EQG1A
XCT EQG1TB(A) ;FOUND IN DESIRED BLOCK.
JRST ASSEM1
EQG1A: JUMPN T,EQG2
CAIN A,PSUDO_-16 ;FOUND AS INITIAL PSEUDO => ERROR.
ETSM ERRQPA
EQG2: CALL DEFCHK ;FIND FREE STE TO DEFINE IN DESIRED BLOCK.
JRST EQL2 ;PRETEND WASN'T FOUND.
ERRQPA: ASCIZ /Shadowing a pseudo-op/
ERRIPA: ASCIZ /Illegal =/
EQG1TB: ETSM ERRIPA ;COMMON
ETSM ERRIPA ;PSEUDO OR MACRO
JRST EQL2 ;SYM
JRST EQGUL ;LOCAL UNDEF
ETSM ERRIPA ;DEF LOC VAR
ETSM ERRIPA ;UNDEF LOC VAR
ETSM ERRIPA ;DEF GLO VAR
ETSM ERRIPA ;UNDEF GLO VAR
JRST EQL7 ;GLO ENTRY
JRST EQL8 ;GLO EXIT
EQL8: PUSHJ P,GLKPNR
TLZ C,3LABEL\3MULTI
EQL7: MOVSI T,GLOETY ;GLOBAL PARA ASSIGN
MOVEI B,0
TLO SYM,40000
LOPRA1: PUSH P,CASM1A ;RETURN TO ASSEM1A AFTER FOLLOWING.
TLNE C,3MULTI
ETSM ERRMDT
SKIPE LABELF
TLO C,3LABEL
TLNE FF,FLHKIL
TLOA SYM,400000 ;SET FLAG TO HALF-KILL SYM
TLZA C,3SKILL
TLO C,3SKILL ;SET CORRESPONDING FLAG IN 3RDWRD
PUSHJ P,VSM2LV
JUMPGE FF,CPOPJ ;JUMP ON NOT PUNCHING PASS
TRNN I,IREQL ;IF CAME FROM COLON ROUTINE,
JRST PDEFPT ;PUNCH "DEFINE SYM AS $.".
TLO C,3VP ;VALUE PUNCHED
3PUT C,D ;STORE UPDATED 3RDWRD
PUSHJ P,EBLK
MOVEI TT,LGPA
DPB TT,[310700,,BKBUF]
PUSHJ P,OUTSM0
PUSHJ P,PWRDA
JRST EBLK
EQGUL: PUSHJ P,LKPNRO ;LOCAL UNDEF, OUTPUT LINK REQUEST.
TLZ C,3LABEL\3MULTI ;CAN'T DETECT MDT'S WHEN ONLY STINK KNOWS FOR SURE.
EQL2: TLNE I,ILGLI
JRST EQL7 ;MAKE IT GLOBAL
MOVSI T,LCUDF ;LOCAL UNDEFINED
JRST LOPRA1
CASM1A: JRST ASEM1A
;MAYBE PUNCH OUT LINK REQUEST
;SYM HAS NAME OF SYM TO REQUEST, D STE IDX OF SYM, C 3RDWRD, B ADR OF REQUEST
;REQUEST WILL BE PUNCHED IF 3RLNK SET IN C OR IF ANYTHING SET IN LH(B)
GLKPNR: TLO SYM,40000 ;GLO BIT
LKPNRO: TLNN C,3RLNK
TLNE B,-1
TROA I,IRCONT
POPJ P, ;DON'T PUNCH REQUEST
MOVE A,CONTRL
TRNE A,DECREL
JRST LKPNDR ;DIFFERENT WAY TO OUTPUT THIS INFO IN DECREL FMT
MOVEI A,6
PUSHJ P,PBITS
PUSHJ P,OUTSM0 ;PUNCH SYM
HLRZ A,B
TLZE C,3RLNK ;RELOC OF LINK PNR
TLO A,100000
HRRZS B ;CLEAR OUT LH OF B
TRZ I,IRCONT ;OK TO END BLOCK NOW
JRST $OUTPT ;PUNCH OUT A AND RETURN
LKPNDR: MOVSI A,DECINT ;WRITE AN "INTERNAL REQUEST" WITH ONE DATA WORD.
CALL DECBLK
SETZ TM, ;COMPUTE RELOC OF ADDRESS AND DATA IN TM.
TLNE C,3RLNK
TRO TM,2
SKIPE WRDRLC
TRO TM,1
MOVE A,WRD ;ADDRESS TO LINK,,DATA
HRL A,B
CALL DECWR1
JRST EBLK
;THESE ASSUME STE IDX IN D, SQUOZE W/ FLAGS IN SYM.
;C HAS 3RDWRD, B OR WRD HAS VALUE TO DEF. WITH.
;CALL ONLY IN RELOCATABLE ASSEMBLY.
OUTDE2: MOVEM B,WRD
OUTDE1: TLNE FF,FLPPSS
TLO C,3VP ;VALUE PUNCHED
3PUT C,D
SKIPGE CONTRL
RET
TRO I,IRCONT
SETZ A,
TLNN C,3LABEL ;WHAT KIND OF DEFINITION DEPENDS ON WHETHER SYM IS REDEFINABLE.
MOVEI A,CRDF
CALL P7X ;PUNCH OUT CODE BITS
PUSHJ P,GTVL7B ;SET RELOCATION BITS IN SQUOZE
PUSHJ P,OUTSM0
TRZ I,IRCONT
JRST OUTWD ;OUTPUT VALUE
;PUNCH OUT LOCAL-GLOBAL RECOVERY BITS AND SYM
;I.E. TELL LOADER THAT SQUOZE IN SYM, FORMERLY CONSIDERED LOCAL, IS REALLY GLOBAL
PLOGLO: SKIPGE CONTRL
RET
PUSH P,A
PUSHJ P,PBITS7
MOVEI A,CLGLO
PUSHJ P,PBITS
TLO SYM,400000 ;SAY THIS IS NEW STYLE RQ,
PUSHJ P,OUTSM0 ;PUNCH "OLD NAME" = SYMTAB IDX,
TLC SYM,440000 ;SAY MAKE GLOBAL, OUTPUT ACTUAL NAME OF SYM.
PUSHJ P,OUTSM
JRST POPAJ
;NO GLOBALS TO RIGHT OF EQUAL SIGN
EQL1: PUSHJ P,ESDCHK
JRST EQL1A ;NOT FOUND
IFN CREFSW,XCT CRFEQL ;DEF. OCCUR. OF NORMAL SYM. OR INTSYM.
MOVEI T,(C) ;GET BKTAB IDX OF BLOCK FOUND IN.
CAIE T,(TM)
JRST EQL1F
SKIPE LABELF ;"=:" MEANS "SYM'S VALUE SHOULDN'T BE CHANGED".
TLO C,3LABEL
XCT EQL1TB(A) ;FOUND IN DESIRED BLOCK => NOW REDEFINE.
JRST ASSEM1
EQL1F: JUMPN T,EQL10
CAIE A,PSUDO_-16
JRST EQL10
MOVEI T,(B) ;FOUND AS PSEUDO IN INITIAL SYMS BLOCK,
CAIN T,INTSYM ;SPECIAL WAY TO REDEFINE IF LIKE .MLLIT, ETC.
JRST EQLINT
ETSM ERRQPA ;SHADOWING AN INITIAL PSEUDO, TELL USER.
EQL10: CALL DEFCHK ;FOUND IN OUTER BLOCK, GET NEW STE,
JRST EQL1A ;DEFINE THERE AS IF NOT FOUND.
EQL1TB: ETSM ERRIPA ;COMMON
JRST EQL1B2 ;PSEUDO OR MACRO
JRST EQL1B ;SYM
JRST EQL1C ;LOCAL UNDEF
ETSM ERRIPA ;DEF LOC VAR
ETSM ERRIPA ;UNDEF LOC VAR
ETSM ERRIPA ;DEF GLO VAR
ETSM ERRIPA ;UNDEF GLO VAR
JRST EQL1D ;GLO ENTRY
JRST EQL1E ;GLO EXIT
EQL1E: PUSHJ P,GLKPNR ;DUMP LINKING POINTER
CAIA
EQL1D: CALL MDTCHK
PUSHJ P,RCHKT ;GLO ENTRY
EQLB2: PUSHJ P,RMOVET
TLNE FF,FLHKIL
TLOA SYM,400000
TLZA C,3SKILL
TLO C,3SKILL
HRLZI T,GLOETY
SKIPE LDCCC ;IF IN LOADER CONDITIONAL,
TLO C,3LLV ;THEN LOADER MUST SUPPLY VALUE
PUSHJ P,VSM2W ;DEFINE SYM
TLO SYM,40000 ;SET GLOBAL BIT IN SQUOZE
EQL1CE: JUMPGE FF,ASEM1A
PUSHJ P,OUTDE1
ASEM1A: TLNE I,ILMWRD
PUSHJ P,IGTXT
JRST ASSEM1
;CHECK WHETHER DEFINING AN MDT, OR REDEFINING A LABEL (=> THIS IS AN MDT)
MDTCHK: TLNN C,3LABEL
JRST MDTCH1
CALL GVSYM0 ;MOVE VALUE OF SYM TO A, GET RELOC (WRDRLC STYLE) IN B
CAMN A,WRD
CAME B,WRDRLC ;IF WE'RE CHANGING THE VALUE, MARK SYM AS MDT
MDTCHL: TLO C,3MULTI
MDTCH1: TLNE C,3MULTI ;EVER ASSIGNING TO MDT, EVEN SAME VALUE, GIVES ERR MSG
ETSM ERRMDT
RET
EQL1C: TLNE I,ILGLI
JRST EQL1CA ;MAKE GLOBAL
PUSH P,C
PUSHJ P,LKPNRO ;MAYBE OUTPUT LINK REQUEST
PUSHJ P,RCHKT
PUSHJ P,RMOVET ;INITIALIZE 3RDWRD
MOVSI T,SYMC ;SYM
PUSHJ P,EQA2A ;ENTER DEF IN SYMTAB
TLNE C,3SKILL
TLO SYM,400000
POP P,AA
TLNE AA,3VCNT ;USED IN CONSTANT
PUSHJ P,CONBUG
JRST EQL1CE
;PUNCH OUT CODE BIT PAIR, FIRST OF WHICH IS 7
P7X: MOVEM A,PARBIT ;ENTRY FOR SECOND BYTE IN A
P70: PUSHJ P,PBITS7 ;ENTRY FOR SECOND BITE IN PARBIT, PUNCH OUT THE 7
SKIPA A,PARBIT ;GET SECOND BYTE BACK
PBITS7: MOVEI A,7 ;ENTRY TO JUST PUNCH OUT 7
JRST PBITS
EQL1CA: PUSHJ P,PLOGLO
JRST EQL1E
EQA2: PUSH P,CASM1A
EQA2A: TLNE FF,FLHKIL
TLO C,3SKILL
JRST VSM2W
EQL1B2: HRRZ A,B ;ATTEMPT TO ASSIGN PSEUDO-OP, IS IT AN INTSYM?
CAIN A,INTSYM
JRST EQLINT ;YES, GO SET WD IT POINTS TO.
ETSM [ASCIZ /Pseudo or macro ='D/]
EQL1B: CALL MDTCHK
PUSHJ P,RCHKT
TLNE I,ILGLI
JRST EQLB2 ;WAS LOCAL, MAKE IT GLOBAL
;WAS LOCAL, LEAVE IT LOCAL
PUSHJ P,RMOVET ;PUT RELOCATION BITS IN BITS 0 AND 1 OF C (I.E. START SETTING UP 3RDWRD)
MOVSI T,SYMC ;SYM
JRST EQA2
EQL1A1: PUSHJ P,RCHKT
PUSHJ P,RMOVET
HRLZI T,SYMC
JRST EQA2
EQL1A: SKIPE LABELF ;"=:" MEANS "SYM'S VALUE SHOULDN'T BE CHANGED".
TLO C,3LABEL
IFN CREFSW,XCT CRFLBL ;DEF. OCCUR. OF NORMAL SYM.
TLNN I,ILGLI
JRST EQL1A1
JRST EQL1E
EQLINT: HLRZS B ;GET ADDR OF WD HOLDING VALUE.
MOVEMM (B),WRD ;PUT NEW VALUE IN IT.
JRST ASEM1A
;;. ;ROUTINES DEALING WITH THE CURRENT LOCATION AND OFFSET
VBLK
CLOC: 0 ;PUNCHING LOC
CRLOC: 0 ;PUNCHING RELOC
OFLOC: 0 ;OFSET VAL
OFRLOC: 0 ;OFSET RELOC
;VAL OF PT=CLOC+OFLOC,CRLOC+OFLOC
SYLOC: 0 ;VAL OF LAST TAG
SYSYM: 0 ;LAST TAG
SYLOC1: 0 ;VALUE OF NEXT TO LAST TAG
SYSYM1: 0 ;NEXT TO LAST TAG
GLOCTP: 0 ;4.9 => CURRENT LOCATION GLOBAL, 2.9 => OFFSET GLOBAL
;FRGLOL (FLAG IN FF) IS IOR OF BITS 4.9 AND 2.9 OF GLOCTP
;EXCEPT AFTER .=NON-GLOBAL WITH GLOBAL OFFSET
;OTHER BITS USED ONLY WHEN IN LINK (NEVER SET IN GLOCTP):
;400 => ARG GLOBAL
PBLK
;POINT (.) AS PSEUDO-OP
GTVLP: TRNE FF,FRGLOL
JRST GTVLP2 ;LOCATION GLOBAL
MOVE B,OFRLOC ;GET RELOCATION OF OFFSET
ADD B,CRLOC ;ADD CURRENT RELOCATION
MOVE A,CLOC ;GET CURRENT LOCATION
SKIPGE BYTM1 ;IF IN BYTE MODE,
HLL A,BYTWP ;SET LEFT HALF TO BYTE POINTER LEFT HALF FOR ILDB
ADD A,OFLOC ;NOW ADD OFFSET
TLZ I,ILFLO+ILDECP+IRPERI ;CLEAR OUT FLAGS SET WHEN LOOKED LIKE FLOATING POINT NUMBER
POPJ P,
GTVLP2: MOVEI T,$.H ;LOCATION GLOBAL
AOS GLSP1
HRRZM T,@GLSP1 ;PUT $. ON GLOBAL LIST (INCLUDES OFFSET, WHETHER GLOBAL OR NOT)
SKIPL BYTM1 ;IN BYTE MODE?
TDZA A,A ;NO, CLEAR ABS PART OF VALUE
HLLZ A,BYTWP ;YES, USE LH(BP) AS ABS PART
JRST CLBPOP
$.H: (GLOETY)+SQUOZE 0,$. ;CURRENT LOCATION + OFFSET IN LOADER
$L.H: (GLOETY)+SQUOZE 0,$L. ;LOCATION BEING LOADED INTO BY LOADER, USED BY ABLOCK
$O.H: (GLOETY)+SQUOZE 0,$O. ;LOADER OFFSET
$R.H: (GLOEXT)+SQUOZE 0,$R. ;RELOCATION AS GLOBAL
COLON: TRNE I,IRLET
TRNN I,IRSYL
ETA [ASCIZ/Colon without preceding symbol/]
TLNN I,ILWORD
TRNE I,IROP+IRPSUD+IREQL+IRNOEQ
ETSM [ASCIZ/Label inside an expression/]
SKIPE ASMOUT
ETSM [ASCIZ /Label inside <>, () or []/]
TLZ FF,FLHKIL
PUSHJ P,RCH ;GET NEXT CHAR
CAIN A,": ;IF NEXT CHAR ANOTHER COLON,
TLOA FF,FLHKIL ;THEN SET FLAG TO HALF-KILL
TLO FF,FLUNRD ;NOT COLON, CAUSE IT TO BE RE-INPUT
SKIPE HKALL ;CHECK FOR HALF-KILL-ALL-LABELS MODE.
TLO FF,FLHKIL
MOVE T,CLOC ;GET CURRENT LOCATION
SKIPGE BYTM1
HLL T,BYTWP ;BYTE MODE, SET LEFT HALF OF VALUE TO LEFT HALF OF BYTE POINTER
ADD T,OFLOC ;ADD OFFSET
MOVEM T,WRD ;STORE RESULT AWAY FOR POSSIBLE PUNCHOUT
EXCH T,SYLOC ;NOW SET UP STUFF FOR ERROR PRINTOUT
MOVEM T,SYLOC1
EXCH SYM,SYSYM
MOVEM SYM,SYSYM1
MOVE SYM,SYSYM
MOVE A,CRLOC ;SET UP RELOCATION
ADD A,OFRLOC
MOVEM A,WRDRLC
SETOM LABELF ;SET FLAG CAUSING 3LABEL (DON'T REDEFINE) TO BE SET.
SKIPN LDCCC
TRNE FF,FRGLOL
JRST GCOL1 ;LOCATION VIRTUAL OR IN LOAD TIME CONDITIONAL
PUSHJ P,ESDCHK ;TRY FINDING CURRENT ENTRY IN ST
JRST EQL1A ;NOT ALREADY DEFINED
IFN CREFSW,XCT CRFLBL
COLON1: MOVEI T,(C) ;BKTAB IDX OF BLOCK FOUND IN,
CAIE T,(TM) ;FOUND IN DESIRED BLOCK => TRY REDEFINING.
JRST COLON3
TLO C,3LABEL ;CAUSE REDEFINING SYMBOL TO BARF
XCT COLON2(A) ;BUT MAYBE PRINT ERR MSG FIRST.
JRST EQL1B
CASSM1: JRST ASSEM1
COLON3: JUMPN T,EQL10 ;NOT INITIAL SYM => CAN SHADOW,
CAIN A,SYMC_-14. ;INITIAL SYM => CAN SHADOW IF IT'S AN ORDINARY LOCAL SYM
CAME B,WRD ;AND NEW VALUE SAME AS OLD VALUE.
CAIA
SKIPE WRDRLC
ETSM ERRRES ;ELSE GIVE ERROR MESSAGE BEFORE SHADOWING, TO WARN USER.
JRST EQL10
ERRRES: ASCIZ /Pseudo, macro or initial sym as label/
ERRMDT: ASCIZ /Multiply defined/
COLON2: TLO C,3MULTI ;COMMON
ETSM ERRRES ;MACRO OR PSEUDO
JRST EQL1B ;SYM
JRST EQL1C ;LOCAL UNDEF
TLO C,3MULTI
TLO C,3MULTI
TLO C,3MULTI
TLO C,3MULTI ;SETTING 3MULTI CAUSES EQL1B TO PRINT AN MDT ERROR.
JRST EQL1D ;GLOBAL ENTRY
JRST EQL1E ;GLO EXIT
;COLON WHEN LOCATION VIRTUAL, OR IN LOAD TIME CONDITIONAL
GCOL1: IFN CREFSW,XCT CRFLBL ;DEFINING ORDINARY SYM.
SKIPGE CONTRL
ETASM [ASCIZ /Virtual label in abs assembly/]
PUSHJ P,ESDCHK ;FIND ITS SLOT IN ST
JRST EQL2 ;JUST LIKE EQG1 EXCEPT FOR ERROR MESSAGES.
MOVEI T,(C)
CAIE T,(TM)
JRST COLON5
XCT GCOL1T(A) ;FOUND IN DESIRED BLOCK, REDEFINING.
JRST EQL2
COLON5: JUMPN T,EQG2 ;SHADOWING, OK UNLESS INITIAL SYM.
ETSM ERRRES
JRST EQG2
GCOL1T: TLO C,3MULTI ;COMMON
ETSM ERRRES ;PSEUDO.
JRST EQL2 ;SYM.
JRST EQGUL ;LOCAL UNDEF.
TLO C,3MULTI ;VAR
TLO C,3MULTI
TLO C,3MULTI
TLO C,3MULTI
JRST EQL7 ;DEF GLO
JRST EQL8 ;UNDEF GLO.
;PUNCH OUT "DEFINE SYM AS $."
PDEFPT: MOVEI A,CDEFPT
PUSHJ P,P7X ;OUTPUT 7 THEN PDEFPT
JRST OUTSM0 ;OUTPUT SYM, WITHOUT BITS
;LOC, BLOCK, .=
ALOC: PUSHJ P,ALOCRG ;LOC, GET ARG
ALOC1: SETZM SYLOC ;CLEAR OUT LOC OF LAST TAG
SETZM SYSYM ;CLEAR OUT LAST TAG SO ERROR MESSAGES DON'T PRINT OBSCENE INCREMENTS
IFN FASLP,[
SKIPGE TM,CONTRL
TRNN TM,FASL
JRST .+2
ETA [ASCIZ /LOC illegal in FASL assembly/]
]
TRZE LINK,400 ;GLOBALS IN ARG?
JRST ALOC2 ;YES
HRRZM A,CLOC ;STORE NEW ABSOLUTE PART OF CURRENT LOCATION
CALL SLOCF ;RE-INIT NEXT OUTPUT BLOCK'S HEADER; SET LOCF.
MOVEI A,LCEGLO ;=> RESET GLOBAL RELOCATION (BACK TO ORIGINAL NON-GLOBAL RELOCATION)
TLZE LINK,400000 ;IS CURRENT LOCATION NOW GLOBAL?
PUSHJ P,PLDCM ;YES, RESET IT
MOVE B,WRDRLC ;GET BACK NEW RELOCATION
ALOC2B: TRZE B,-2 ;NO BITS ALLOWED EXCEPT LOW ORDER
ETR [ASCIZ *Illegal relocation in LOC/BLOCK/.=*]
HRRZM B,CRLOC ;STORE NEW RELOCATION
SKIPGE CONTRL
JRST ASSEM1 ;DON'T BOTHER WITH REST IF ABS.
MOVEI B,2(B) ;LABS OR LREL
DPB B,[310700,,BKBUF] ;STORE NEW BLOCK TYPE
MOVEM B,CDATBC ;ALSO STORE AS NORMAL BLOCK TYPE
AOFSTX: TDNN LINK,[SETZ(SETZ)] ;ENTRY FROM AOFFSET, SKIP IF FRGLOL SHOULD BE SET
TRZA FF,FRGLOL ;CURRENT LOCATION PLUS OFFSET NOT GLOBAL, CLEAR FLAG
TRO FF,FRGLOL ;GLOBAL, SET FLAG
TRZ LINK,600 ;CLEAR OUT TEMPORARY FLAGS SO WON'T GET STORED IN GLOCTP
MOVEM LINK,GLOCTP ;STORE BACK STATUS FLAGS
JRST ASSEM1
PTEQ: MOVE SYM,[SQUOZE 0,LOC]
PUSHJ P,ALOCRG ;.=, GET ARG
MOVE T,[MINF+HFWDF,,$O.H] ;GLOTB ENTRY IF .+1 DOESN'T SKIP
TRNE LINK,400000 ;OFFSET GLOBAL?
JRST PTEQ2 ;YES, WANT TO DO LOC ARG-$O."
PUSHJ P,SBWDOF ;OFFSET IS LOCAL, SUBTRACT FROM ARG
JRST ALOC1
ABLOCK: PUSHJ P,ABLKRG ;GET ARG TO "BLOCK" PSEUDOOP.
TRNE LINK,400 ;GLOBALS IN ARG?
JRST ABLKG ;GLOBALS IN ARG
TLNE LINK,400000
JRST ABLKG ;JUMP IF LOSER CHANGING RELOCATION WHILE CLOC GLOBAL
IFN FASLP,[
MOVE D,CONTRL
TRNN D,FASL ;IN FASL FORMAT, CAN'T SET LOC. CTR.,
JRST ABLKF1
SKIPE B
ETA [ASCIZ /BLOCK size relocatable/]
JUMPGE FF,ABLKF1
CALL ABLKF ;SO ON PASS 2 OUTPUT A BUNCH OF ZEROS.
JRST ABLKF1
;OUTPUT C(A) ZEROS, IN FASL FORMAT. NO-OP ON PASS 1. DOESN'T SET THE LOCATION COUNTER.
ABLKF: JUMPE A,CPOPJ
JUMPGE FF,CPOPJ
SETZM WRD
SETZM WRDRLC
PUSH P,A
PUSH P,A
ABLKF2: CALL FASPW
MOVEMM GLSP2,GLSP1
SOSE (P)
JRST ABLKF2
JRST POPBAJ
]
ABLKF1: JUMPL A,[ETA [ASCIZ /BLOCK size negative/]]
ADD A,CLOC ;ARG TO BLOCK IS LOCAL, ADD DIRECTLY TO CLOC
ADD B,CRLOC ;ALSO ADD RELOCATIONS
HRRZM A,CLOC ;STORE NEW ABSOLUTE PART OF LOCATION
CALL SLOCF ;FALL INTO ALOC ROUTINE, MAKING SURE FRLOC GETS SET
JRST ALOC2B
SBWDOF: SUB A,OFLOC ;SUBTRACT OFFSET FROM WRD, ETC. IN A,B
HRRZM A,WRD ;MAKE SURE RESULT GETS STORED IN WRD, AS WELL AS AC'S
SUB B,OFRLOC ;NOW DO RELOCATIONS
HRRZM B,WRDRLC
POPJ P,
ABLKG: TRNE LINK,400000 ;GLOBAL BLOCK, IS OFFSET GLOBAL?
JRST ABLKG2 ;YES, OK TO REFERENCE $L.
PUSHJ P,SBWDOF ;NO, FOR COMPATIBILITY, DON'T REFERENCE $L.
SKIPA T,[HFWDF,,$.H]
ABLKG2: MOVE T,[HFWDF,,$L.H]
PTEQ2: AOS GLSP1 ;STORE T IN GLOTB
MOVEM T,@GLSP1
ALOC2: TLO LINK,400000 ;SET GLOBAL LOCATION FLAG
MOVEI A,LCGLO ;=> GLOBAL LOCATION ASSIGNMENT
PUSHJ P,PLDCM ;PUNCH OUT GLOBAL LOCATION ASSIGNMENT
SETZM CLOC ;CLEAR OUT CLOC, NEW RELOCATION NOW
SETZB B,BKBUF ;ALSO CLEAR OUT HEADER, JUST TO BE SURE
AOJA B,ALOC2B ;SET RELOCATION TO 1 AND FALL IN
AOFFSET: PUSHJ P,AOFFS2 ;OFFSET, GET ARG
MOVE A,T
MOVEM A,WRD ;RESTORE UNTRUNCATED ARG.
TRZE LINK,400 ;GLOBALS IN ARG?
TROA LINK,400000 ;GLOBALS IN ARG, SET GLOBAL OFFSET FLAG
TRZ LINK,400000 ;NO GLOBALS IN ARG
MOVEM A,OFLOC ;STORE NEW OFFSET
MOVEM B,OFRLOC ;ALSO STORE RELOCATION BITS
SKIPGE CONTRL ;IN RELOCATABLE,
JRST AOFSTX
MOVEI A,LDOFS ;LOADER OFFSET LOADER COMMAND TYPE
PUSHJ P,PLDCM ;PUNCH OUT LOADER COMMAND
JRST AOFSTX
;GET ARG TO LOC, BLOCK, .=, OFFSET
ALOCRG:
ABLKRG: MOVE A,CLOC
SKIPN CRLOC
JRST [ CAML A,DECBRA ;IF ADDR BEFORE THE LOC WAS ABS,
MOVEM A,DECBRA ;UPDATE HIGHEST ABS ADDR IF NEC.
JRST ABLKR1]
CAML A,DECTWO ;IT WAS RELOCA; UPDATE HIGHEST
JRST [ CAML A,DECBRH ;ADDR OF APPROPRIATE SEG.
MOVEM A,DECBRH
JRST ABLKR1]
CAML A,DECBRK
MOVEM A,DECBRK
AOFFS2:
ABLKR1: PUSH P,SYM
PUSHJ P,CONBAD ;ERROR IF IN GROUPING
REST SYM
TRNE I,IRNOEQ\IRPSUD\IREQL
ETSM [ASCIZ /Inside pseudo or =/]
TDNE I,[ILWORD,,IRFLD]
ETSM ERRNVL
PUSHJ P,EBLK ;MAYBE END CURRENT OUTPUT BLOCK
PUSHJ P,AGETWD ;GET ARG
MOVE LINK,GLOCTP ;GET GLOCTP FLAGS IN LINK, STAYS THERE UNTIL ALMOST DONE
MOVE T,GLSP2
CAME T,GLSP1
TROA LINK,400 ;SIGNAL GLOBAL ARG
TRZ LINK,400 ;LOCAL
MOVE T,A ;SAVE UNTRUNCATED FOR AOFFSET,
HRRZS A,WRD ;TRUNCATE FOR LOC, BLOCK, .=.
TRNN I,IRDEF ;ALL DEFINED?
JRST ASSEM1
SKIPGE CONTRL ;YES, RETURN SKIPPING OVER ARG
TRNN LINK,400
RET
MOVE SYM,GTVER
ETASM [ASCIZ *Argument has externals*]
;;CONSTANTS AND VARIABLES
;VARIABLES AREA
VBLK
LCNGLO==CONMIN/4
LCONTB==CONMIN
BLCODE [
PCNTB: BLOCK NCONS*3 ;CONSTANTS AREAS TABLE
VARTAB: BLOCK NVARS
]
CONTBA: CONTAB ;ADDRESS OF BEGINNING OF CONSTANTS TABLE.
CONTBE: CONTAB+LCONTB ;ADDRESS OF WORD AFTER END OF CONSTANTS TABLE.
PLIM: 0 ;POINTER TO FIRST UNUSED WORD IN CONSTANTS TABLE.
CONGLA: CONGLO ;ADDRESS OF BEGINNING OF CONSTANT-GLOBALS TABLE.
CONGLE: CONGLO+LCNGLO ;ADDRESS OF WORD AFTER END OF CONSTANT GLOBALS TABLE.
CONGOL: 0 ;HAS ADR OF FIRST WORD INACTIVE IN CONSTANT-GLOBALS TABLE.
CONBIA: CONBIT ;ADDRESS OF BEGINNING OF CONSTANT-RELOCATION-BITS TABLE.
CONLEN: CONMIN ;TOTAL SPACE ALLOCATED TO CONSTANTS TABLES.
;ALL THE HOOKS ARE IN FOR DYNAMIC ALLOCATION OF THESE TABLES
;(CONTAB, CONGLO, AND CONBIT). ALL THAT IS NEEDED IS TO GET
;THE SPACE AND INITIALIZE CONTBA, CONTBE, CONGLA, CONGLE, CONBIA.
;PCNTB STUFF
;EACH ENTRY 3 WORDS; FIRST WORD SQUOZE, NAME OF AREA IF GLOBAL
CSQZ: 0 ;SQUOZE COUNTER
;SECOND WORD RH LOC OF AREA (WITH OFFSET), LH LOC FIRST AFTER AREA (WITHOUT OFFSET)
;THIRD WORD LH FLAGS
CGBAL==100000 ;GLOBAL (INCLUDING OFFSET)
CTRL==200000 ;RELOCATED ( " )
CTDEF==400000 ;DEFINED (MUST BE SIGN)
PBCON: 0 ;POINTER INTO PCNTB, HAS ADR OF ENTRY FOR NEXT CONSTA
PBCONL: 0 ;POINTER TO ABSOLUTE TOP OF PCNTB
CONCNT: 0 ;NUMBER OF TIMES CONSTANTS CAN APPEAR (DECREMENTED BY CONSTA)
CONDEP: 0 ;DEPTH IN CONSTANTS (0 TOP LEVEL)
CONSAD: 0 ;ADDR IN CONSTANTS TABLE OF ENTRY FOR CURRENT CONST.
CONSML: 0 ;VALUE OF .MLLIT INTSYM.
;NEGATIVE => ERROR MODE (DEFAULT)
;ZERO => OLD MODE.
;POSITIVE => NEW (MULTI-LINE) MODE.
CONSTP: 0 ;PDL POINTER BELOW WDS FOR INNERMOST CONSTANT.
CONSP1: 0
;VARIABLES FOR VARIABLES CODING
VARCNT: 0 ;NO OF VAR IN CURRENT VAR AREA SO FAR
VARPNT: 0 ;POINTER TO CURRENT PLACE IN VARTAB
VARCNR: 0 ;NO OF TIMES VARIABLES MAY APPEAR
VCLOC: 0 ;TEM FOR VARIAB
VECSIZ: 0 ;DEFAULT SIZE FOR .VECTOR.
PBLK
;LEFT-BRACKET ENCOUNTERED; HERE ON DISPATCH FROM GETFD
;SAVE WORLD, BYTE MODE, ASSEM1 PDL LEVELS.
;THEN SET ASSEM1 PDL LEVELS TO CURRENT LEVELS
;SO ASSEM1 WON'T FLUSH PAST LEVEL OF CONSTANT.
;SET CONSTP _ CURRENT PDL LEVEL. PCONS WILL PUT WORDS
;OF CONSTANT ABOVE CONSTP, AND SET ASSEMP ABOVE THEM.
LBRAK: SKIPE LITSW
ETR [ASCIZ /Literal/]
TRO I,IRFLD ;LEFT BRACKET
JSP LINK,SAVWD1 ;SAVE CRUFT
PUSH P,SCNDEP ;SO THE NEXT RBRKT WON'T TRY TO CLOSE CONDIT.
JSP LINK,SAVAS1
MOVEIM ASMOUT,3
SETZM SCNDEP ;NOT WITHIN CONDITIONALS IN THIS LITERAL.
AOS CONDEP ;ONE DEEPER IN LITERALS.
MOVEI A,IRPSUD\IREQL
ANDCAM A,ASMI
JRST ASSEM3 ;GO ASSEMBLE THE WORDS OF THE CONSTANT.
;OUTPUT WORD TO CONSTANT. P MUST EQUAL ASSEMP HERE.
PCONS: SKIPL CONTRL ;IF RELOCATABLE,
PUSHJ P,$RSET ;HANDLE STRANGE RELOCATIONS.
MOVE B,GLSP1
SUB B,GLSP2 ;NUM. GLOBAL ENTRIES FOR THIS WD.
HLRZ A,WRDRLC ;ONLY 1.1 AND 3.1 BITS MATTER.
LSH A,1
IOR A,WRDRLC ;GET THEM INTO 1.1, 1.2 BITS.
TLNE I,ILNOPT ;REMEMBER ILNOPT ALSO.
IORI A,4
DPB B,[032200,,A] ;AND # GLBLS.
PUSH P,A ;SAVE THEM ALL.
HRLI B,(B) ;GET # GLBLS,,# GLBLS .
JUMPE B,PCONS1
MOVE A,GLSP2
MOVSI A,1(A)
HRRI A,1(P) ;SAVE THE GLBLS, IF ANY.
ADD P,B
JUMPGE P,CONFLP
BLT A,(P)
PCONS1: PUSH P,WRD
MOVEM P,ASSEMP ;ASSEMP -> ABOVE WDS FOR LIT.; CONSTP, BELOW.
JRST (T)
;JSP LINK,SAVAS1 TO PUSH DATA ON ASSEM1 LEVEL AND CALL ASSEM1
;LOOP RECURSIVELY.
.SEE CONNDP ;WHICH IS WHERE THESE THINGS ARE POPPED.
SAVAS1: SKIPN BYTM ;IF IN BYTM NOW (WILL PUSH AND TURN OFF)
JRST LBRAK1
MOVSI A,BYBYT ;SAVE ALL THE DETAILS.
HRRI A,1(P)
ADD P,[LBYBYT+BYTMCL,,LBYBYT+BYTMCL]
JUMPGE P,CONFLP ;(SOFTWARE-DETECTED PDL-OV)
BLT A,-BYTMCL(P)
MOVSI A,BYTMC
HRRI A,1-BYTMCL(P)
BLT A,(P)
LBRAK1: PUSH P,BYTM
SETZM BYTM
PUSH P,ASMOUT
PUSH P,ASMDSP
PUSH P,ASMI
PUSH P,GLSPAS ;SAVE ASSEM1 PDL LEVELS.
PUSH P,ASSEMP
PUSH P,CONSTP
MOVE A,I
ANDI A,IRPSUD+IREQL
IORI A,IRDEF
MOVEM A,ASMI ;ASMI IOR'D INTO I AT ASSEM2 LOOP.
HRRZ A,CPGN
HRL A,CLNN ;REMEMBER WHERE THIS LITERAL STARTS.
INSIRP PUSH P,[A SYSYM SYLOC]
MOVEM P,ASSEMP ;SO ASSEM1 WON'T FLUSH WHAT WE PUSHED.
MOVEM P,CONSTP ;SO CONND CAN FIND 1ST WD OF CONSTANT.
MOVEMM GLSPAS,GLSP1
SAVAS2: MOVEI A,ASSEM3 ;IF NOT MULTI-LINE MODE, ARRANGE TO
SKIPG CONSML ;END THE CONSTANT AFTER 1 WORD.
MOVEI A,ASSEMC
MOVEM A,ASMDSP
JRST (LINK)
PCONST: MOVE CH1,ASMDSP ;OUTPUT TO CONST. FROM ASSEM1
CAIN CH1,CONND ;LAST WD OF CONST?
CAME P,CONSTP ;1ST WD?
JRST PCONS ;NO, DO THE GENERAL THING.
SKIPL CONTRL ;THIS MUST BE ONLY WORD OF CONST,
PUSHJ P,$RSET ;DON'T BOTHER PUSHING, END CONST. NOW.
PUSH P,CONSTP
TLZ I,ILMWRD+ILMWR1 ;THIS IS 1ST WD, NO MORE WDS.
JRST CONND3 ;PRETEND JUST POPPED IT.
;COME HERE FROM ASSEM1 TO END A CONSTANT.
CONND: SKIPE BYTM ;IF IN BYTE MODE, LEAVE IT AND DO .WALGN
JRST A.BY3 ;(WILL COME BACK SINCE ASMDSP STILL SET)
CONNDW: MOVEMM CONSP1,CONSTP
TLZ I,ILMWR1 ;THIS IS 1ST WORD COMING UP.
CONND0: TLZ I,ILMWRD+ILNOPT
SETZM WRDRLC
MOVE F,CONSP1 ;ADDR IN IN PDL OF NEXT WD.
CAMN F,ASSEMP
JRST CONND2 ;J IF NO WORDS.
MOVE A,1(F) ;GET SAVED NUM GLBLS,,NUM GLBLS
DPB A,[100,,WRDRLC]
LSH A,-1 ;RESTORE WRDRLC BITS 1.1, 3.1
DPB A,[220100,,WRDRLC]
TRNE A,2
TLO I,ILNOPT ;RESTORE NOOPTF.
LSH A,-2 ;GET # GLBLS.
HRLI A,(A) ;# GLBLS,,# GLBLS.
AOBJN F,.+1
HRRZM F,GLSP2 ;ADDR BEFORE 1ST GLOBAL ENTRY.
ADD F,A
HRRZM F,GLSP1 ;ADDR OF LAST GLOBAL ENTRY.
MOVE A,1(F)
MOVEM A,WRD
AOBJN F,.+1 ;POINT TO NEXT CONST WD IF ANY,
MOVEM F,CONSP1
CAME F,ASSEMP ;IF MORE WORDS SET ILMWRD
TLO I,ILMWRD
JRST CONND3
CONND2: INSIRP SETZM,[WRD,GLSP1,GLSP2]
CONND3: MOVE F,GLSP1
SUB F,GLSP2
JUMPE F,SCON ;JUMP IF NOTHING VIRTUAL
MOVEI B,-1(F)
MOVN TT,B
JUMPE B,SCON ;JUMP IF ONLY ONE GLOBAL
;SORT GLOTB ENTRIES THIS CONSTANT
LSORT: HRL T,TT ;SET UP AOBJN POINTER TO GLOBALS REMAINING
HRR T,GLSP2
LSORT2: MOVE A,1(T)
CAMLE A,2(T)
EXCH A,2(T) ;INTERCHANGE
MOVEM A,1(T)
AOBJN T,LSORT2 ;INNER LOOP POINT
SOJG B,LSORT ;OUTER LOOP
;DROPS THROUGH
;DROPS THROUGH
SCON: PUSHJ P,RCHKT
PUSHJ P,RMOVET ;SET UP RELOACTION BITS.
ROT T,2 ;ROTATE TO BOTTOM TWO BITS OF T
TLNE I,ILMWRD+ILMWR1+ILNOPT
JRST NOCON ;MULTIPLE WORD OR OPTIMIZATION SUPPRESSED, DON'T TRY TO FIND MATCH
MOVE A,CONTBA
SCON1: CAML A,PLIM ;SEARCH CONSTANTS TABLE TO SEE IF ALREADY THERE
JRST NOCON ;END OF TABLE, NO MATCH
MOVE B,WRD
CAME B,(A)
SCON2: AOJA A,SCON1 ;VAL DISAGREES
PUSHJ P,CPTMK ;GET BP TO CONSTANTS-BIT TABLE IN C
LDB F,C ;GET RELOCATION BITS THIS CONSTANT
CAME F,T
JRST SCON2 ;RLC DIFFRS
MOVE B,CONGLA ;VALUE AND RELOCATION AGREE, NOW TO CHECK GLOBALS
SKIPA C,GLSP2
SCON2B: AOS B ;SEARCH FOR GLOBAL POINTING TO CONSTANT WHICH HAS MATCHED SO FAR
CAML B,CONGOL
JRST SCON3 ;GLOBALS MATCH SO FAR
CAME A,1(B) ;SKIP IF ONE FOUND
SCON7: AOJA B,SCON2B ;NOT YET
MOVE D,(B) ;FOUND ONE, GET GLOTB ENTRY
CAME D,1(C) ;COMPARE WITH THIS ENTRY IN GLOTB
JRST SCON2 ;NO MATCH, FLUSH THIS CONSTANT
AOJA C,SCON7 ;MATCH, TRY NEXT GLOBAL
SCON3: CAME C,GLSP1 ;GLOBALS MATCH, BUT ARE WE EXACTLY AT END OF GLOTB?
JRST SCON2 ;NO, BACK TO SEARCH
JRST NOCON4
NOCON: AOS A,PLIM ;CONSTANT NOT ALREADY IN TABLE
CAMLE A,CONTBE
ETF [ASCIZ/Literal table full/]
MOVE AA,WRD
MOVEM AA,-1(A)
SOS A
PUSHJ P,CPTMK
TLNE I,ILNOPT
TRO T,4 ;1.3 OF RELOCATION BITS => DON'T OPTIMIZE ON TOP OF ME
DPB T,C
MOVE B,GLSP2
NOCON3: CAML B,GLSP1
JRST NOCON4
SKIPN C,1(B)
AOJA B,NOCON3 ;THIS ENTRY NOT REALLY HERE
MOVEM C,@CONGOL
HRRZS C
PUSHJ P,NOCON5
MOVEM A,@CONGOL
PUSHJ P,NOCON5
SKPST C, ;SKIP IF IN SYMBOL TABLE
AOJA B,NOCON3
3GET1 D,C ;IN SYMBOL TABLE
TLO D,3VCNT ;THIS SYM USED IN CONSTANT
3PUT1 D,C ;UPDATE 3RDWRD TABLE ENTRY
AOJA B,NOCON3
NOCON5: AOS AA,CONGOL
CAML AA,CONGLE
ETF [ASCIZ/Constants-global table full/]
POPJ P,
;SET UP BYTE POINTER TO CONSTANTS-BIT TABLE
;A SHOULD HAVE ADR OF CONSTANTS TABLE ENTRY
;LEAVES ANSWER IN C
;BITS IN CONSTANTS-BIT TABLE PER ENTRY:
;1.2, 1.1 RELOCATION BITS
;1.3 ILNOPT BIT => DON'T OPTIMIZE ON TOP OF ME
CPTMK: PUSH P,A
SUB A,CONTBA
PUSH P,B
IDIVI A,12.
MOVEI C,(A)
ADD C,CONBIA ;SET UP ADDRESS PART
IMULI B,3
DPB B,[360600,,C] ;STORE POSITION FIELD FROM REMAINDER
TLO C,200 ;SET UP SIZE FIELD
POPBAJ: POP P,B
JRST POPAJ
NOCON4: TLON I,ILMWR1
MOVEM A,CONSAD ;IF 1ST WD SAVE ADDR.
TLNE I,ILMWRD ;IF MORE WORDS, HANDLE NEXT.
JRST CONND0
MOVE P,CONSTP ;VALUE OF CONSTP AT CONND.
MOVE C,GLSPAS ;TO RESTORE GLSP1
JSP T,CONNDP ;POP STUFF.
HRRZ A,CONSAD ;ADDR OF CONSTANTS TABLE ENTRY OF 1ST WD.
MOVE B,PBCON ;ADDR OF WDS DESCRIBING CONST. AREA.
SKIPL 2(B) ;CONST. AREA LOCATION DEFINITE?
AOJA C,CONND6 ;NO, USE GLOBAL.
MOVEM C,GLSP1
HRRZ C,1(B) ;ADD ACTUAL ADDR OF CONST. AREA.
ADDI A,(C) ;GET C(CONTBA) + ADDR OF CONSTANT.
LDB B,[420100,,2(B)]
JRST CONND7
CONND6: MOVEM C,GLSP1
MOVEM B,(C)
MOVEI B,0
CONND7: SUB A,CONTBA
JRST LSSTH3 ;POP OUT INTO OUTER WORD.
.SEE SAVAS1 ;WHICH IS WHAT PUSHES WHAT CONNDP POPS.
CONNDP: SUB P,[3,,3] ;FLUSH SAVED SYLOC AND SYSYM AND CLNN,,CPGN.
CONFL2: HRL T,ASMOUT ;REMEMBER IF POPPING A LITERAL OR NOT.
INSIRP POP P,[CONSTP,ASSEMP,GLSPAS,ASMI,ASMDSP,ASMOUT,BYTM]
SKIPN BYTM ;IF IN BYTE MODE, POP DETAILS.
JRST CONND5
MOVSI A,1-BYTMCL(P)
HRRI A,BYTMC
BLT A,BYTMC+BYTMCL-1
MOVSI A,1-BYTMCL-LBYBYT(P)
HRRI A,BYBYT
BLT A,BYBYT+LBYBYT-1
SUB P,[LBYBYT+BYTMCL,,LBYBYT+BYTMCL]
CONND5: HLRZ A,T
CAIE A,3
JRST (T)
POP P,A
ADDM A,SCNDEP ;DON'T FORGET ABOUT ANY CONDITIONALS.
SOS CONDEP ;HAVE POPPED ONE CONSTANT.
JRST (T)
CONFLS: MOVE P,ASSEMP ;FLUSH ALL CONSTANTS.
CAMN P,[-LPDL,,PDL] ;IF IN ANY,
JRST (LINK)
MOVE P,CONSTP ;POINT AFTER ITS PDL ENTRY,
JSP T,CONNDP ;POP IT,
JRST CONFLS ;TRY AGAIN.
CONBAD: SKIPN ASMOUT ;IF IN GROUPING, ERROR.
POPJ P,
ETSM [ASCIZ/Within <>, () or []/]
JRST ASSEM1
;COME HERE FOR PDL-OV ON P.
;IF IN A CONSTANT, FLUSH ALL OF THEM, SAYING WHERE EACH STARTED.
;THEN TYPE A PDL ERROR MSG AND RETURN TO ASSEM1.
;OTHERWISE FATAL ERROR.
CONFLP: MOVEI LINK,ASSEM1
MOVEI CH1,ERRPDL
SKIPE CONDEP
JRST CONFL3 ;IN A CONSTANT.
MOVEI P,PDL ;RE-INIT PDL SO NO MORE PDL-OV.
ETF ERRPDL
ERRPDL: ASCIZ /PDL overflow/
;JSP LINK,CONFLM TO FLUSH CONSTANTS, SAYING WHERE THEYY STARTED,
;AND GIVE ERROR MSG.
CONFLM: MOVE CH1,ASMOUT
SKIPA CH1,ASMOT3(CH1)
CONFLZ: SETZ CH1, ;LIKE CONFLM BUT NO ERR MSG AT END.
CONFL3: SETO C,
CONFL1: MOVE P,CONSTP ;GET STACK ABOVE INNERMOST LITERAL.
REST SYLOC
REST SYSYM
REST D ;GET INFO ON WHERE STARTED
AOSN C ;THE 1ST TIME ONLY, SAY WHAT'S GOING ON.
TYPR [ASCIZ/Within groupings: /]
SKIPE C
TYPR [ASCIZ/, /]
MOVE A,ASMOUT ;SAY WHAT KIND OF GROUPING IS BEING CLOSED
MOVE A,ASMOT5(A)
CALL TYOERR ;BY SAYING WHAT CHAR OPENED IT.
JSP T,CONFL2 ;POP REST OF WDS SAVED AT LBRAK.
TYPR [ASCIZ/ at /]
MOVEI A,1(D) ;PAGE # GROUPING STARTED ON.
CALL DPNT ;PRINT IN DECIMAL.
MOVEI A,"-
CALL TYOERR
HLRZ A,D ;LINE NUMBER IT STARTED ON.
ADDI A,1
CALL D3PNT2 ;PRINT W/ AT LEAST 3 CHARS, NO ZERO SUPPR.
MOVE A,ASSEMP
CAME A,[-LPDL,,PDL] ;MORE GROUPINGS TO POP => DO.
JRST CONFL1
CALL CRRERR
MOVE P,ASSEMP
JUMPE CH1,(LINK) ;IF CALLED CONFLZ, NO ERR MSG (CALLER WILL GIVE ONE)
ETR (CH1) ;[ NO] OR PDL.
CALL CRRERR
JRST (LINK)
;CONSTA
CNSTNT: NOVAL
SKIPE ASMOUT ;IF ANY GROUPNGS,
JSP LINK,CONFLM ;FLUSH THEM, GIVE ERROR.
PUSHJ P,CNSTN0
JRST ASSEM1
CNSTN0: SOSGE CONCNT ;ENTRY FROM AEND
ETF [ASCIZ /Too many constants areas/]
MOVE B,CLOC
ADD B,OFLOC
HRRZ T,PBCON
TRNN FF,FRPSS2
JRST CNST1 ;PASS 1
MOVSI A,CGBAL
TDZ A,2(T)
TRNE FF,FRGLOL
TLC A,CGBAL
SKIPN A
ETR [ASCIZ /Constants globality phase error/]
HRRZ B,1(T)
SUB B,OFLOC
HRRZS B
CAME B,CLOC
ETR [ASCIZ /Constants location phase error/]
MOVE B,2(T)
ROT B,2
XOR B,CRLOC
XOR B,OFRLOC
TRNE B,1
ETR [ASCIZ /Constants relocation phase error/]
;DROPS THROUGH
;DROPS THROUGH
CNST2: MOVEI D,(T) ;STE IDX IN D FOR OUTSM0
MOVE SYM,(T) ;GET NAME OF AREA
TLC SYM,400000#LCUDF ;CLEAR LCUDF, SET HALF-KILL
TRNE FF,FRGLOL
PUSHJ P,PDEFPT ;DEFINE SYM FOR BEGINNING OF CONSTANTS AREA
MOVE A,CONTBA
CNSTH: CAML A,PLIM
JRST CNSTA ;THRU
MOVE TT,(A)
MOVEM TT,WRD
PUSHJ P,CPTMK
LDB F,C ;GET THIS CONSTANT'S RELOCATION BITS
TRZE F,2
TLO F,1 ;RELOCATE LEFT HALF
MOVEM F,WRDRLC ;STORE RELOCATION
MOVEI D,GLOTB ;AND NOW TO SET UP GLOTB!
MOVEM D,GLSP2
MOVE C,CONGLA
CNSTC: CAML C,CONGOL
JRST CNSTB ;END OF CONSTANT-GLOBAL TABLE
CAMN A,1(C) ;POINTS TO THIS CONSTANT?
PUSH D,(C) ;YES, STORE ENTRY IN GLOTB
AOS C
AOJA C,CNSTC
CNSTB: HRRZM D,GLSP1 ;MARK END OF ACTIVE PART OF GLOTB
PUSH P,A
PUSHJ P,PWRD ;OUTPUT THIS CONSTANT
AOS CLOC ;INCREMENT CLOC TO NEXT
HRRZS CLOC ;MAKE SURE IT STAYS IN A HALF-WORD (IMPORTANT SINCE MAY BE LESS THAN RELOCATION)
POP P,A ;RESTORE POINTER INTO CONSTANTS TABLE
AOJA A,CNSTH
CNST3: HLRZ A,1(T) ;GET POINTER TO TOP OF AREA STORED DURING PASS 1
CAMN A,CLOC ;SAME AS CURRENT?
JRST CNSTE ;YES, NO HAIR
CAMGE A,CLOC ;DIFFERENT; LOWER?
ETR [ASCIZ /More constants on pass 2 than 1/]
;INSUFFICIENT CONSTANT SPACE; CONSTANTS AREA TRYING TO BE BIGGER
;IN PASS 2 THAN PASS 1; THE EXTRA CONSTANTS WERE BACKED OVER
MOVEM A,CLOC ;EITHER WAY, SET CLOC TO TOP OF AREA SO WON'T HAVE MDT TROUBLE
PUSHJ P,EBLK ;END CURRENT BLOCK
CALL SLOCF ;IF RELOCATABLE, MAKE SURE NEW VALUE OF $. GETS PUNCHED
JRST CNSTE
;CALL SLOCF WHENEVER "." IS CHANGED WITHOUT THE OUTPUTTING OF A STORAGE WORD.
SLOCF: MOVE A,CLOC ;STORE NEW "." IN HEADER FOR NEXT BLOCK OF OUTPUT.
SKIPGE TM,CONTRL
TRNN TM,DECREL+FASL ;BUT NOT IN DEC OR FASL OUTPUT FORMATS.
HRRM A,BKBUF
IORI FF,FRLOC ;MAKE SURE NULL BLOCK IS OUTPUT IF NEC. TO TELL LOADER "." HAS CHANGED.
RET
;CONSTA DURING PASS 1
CNST1: HRRM B,1(T) ;STORE LOCATION OF AREA
MOVEI D,0
MOVE A,CRLOC
ADD A,OFRLOC
TRNE A,1
TLO D,CTRL ;RELOCATED
TRNE FF,FRGLOL
TLO D,CGBAL ;GLOBAL
IORM D,2(T) ;STORE FLAGS DESCRIBING AREA
JUMPL FF,CNST2 ;JUMP ON PUNCHING PASS, PUNCH OUT AREA NOW
MOVE T,PLIM
SUB T,CONTBA
ADDM T,CLOC ;PASS 1, JUST UPDATE CLOC
HRRZS CLOC
CNSTA: HRRZ T,PBCON
TRNE FF,FRGLOL
JRST CNSTD ;LOCATION GLOBAL
TRNN FF,FRNPSS
SKIPGE 2(T)
JRST CNSTDA ;2 PASS ASSEMBLY OR AREA DEFINED
TRO I,IRCONT ;1PASS AND NOT DEFINED
SETZM PARBIT
PUSHJ P,P70 ;DEFINE SYM
MOVE A,(T)
TLC A,400000#LCUDF
SKIPE CRLOC
TLO A,100000 ;RELOCATE
PUSHJ P,$OUTPT
HRRZ A,1(T)
PUSHJ P,$OUTPT ;OUTPUT VALUE, FIRST LOCATION IN AREA
TRZ I,IRCONT
CNSTDA: MOVSI A,CTDEF
IORM A,2(T) ;CALL IT DEFINED
CNSTD: TRNE FF,FRPSS2
JRST CNST3 ;PASS 2
MOVE A,CLOC
HRLM A,1(T) ;MARK END OF AREA
CNSTE: MOVE A,CONTBA
MOVEM A,PLIM
MOVE A,CONGLA
MOVEM A,CONGOL
MOVEI T,3
ADDB T,PBCON
CAML T,PBCONL
MOVEM T,PBCONL
AOS A,CSQZ
MOVEM A,(T)
POPJ P,
;DEFINING SYM USED IN CONSTANT, DELETE REFERENCES FROM CONSTANT-GLOBAL TABLE
CONBUG: MOVE A,CONGLA ;B VAL C FLAGS ST(D) SADR
PUSH P,T
PUSH P,C ;SAVE FLAGS
CONBG2: MOVE C,(P) ;GET FLAGS
CAML A,CONGOL ;DONE WITH SCAN?
JRST CONBG1 ;YES
HRRZ F,(A) ;NO, GET CONSTANT-GLOBAL TABLE ENTRY
CAIE F,ST(D) ;POINT TO THIS SYM?
AOJA A,CONBG6
PUSH P,B ;YES, SAVE VALUE, ABOUT TO WORK WITH B
MOVE T,(A) ;GET ENTIRE CONSTANT-GLOBAL TABLE ENTRY
LDB CH2,[221200,,T] ;GET MULTIPLICATION FIELD
SKIPE CH2
IMUL B,CH2 ;NON-ZERO => MULTIPLY VALUE OF SYM
TLNE T,MINF
MOVNS B ;NEGATE VALUE
TLNE T,HFWDF
HRRZS B ;TRUNCATE TO HALFWORD
TLNE T,ACF
ANDI B,17 ;AC, MASK TO FOUR BITS
TLNE T,SWAPF
MOVSS B ;SWAP VALUE
TLNE T,ACF
LSH B,5 ;AC, SHIFT FIVE
ADD B,@1(A) ;ADD ABS PART OF VALUE
TLNN T,SWAPF
HRRM B,@1(A) ;NOT SWAPPED, STORE LH
TLNE T,SWAPF
HLLM B,@1(A) ;SWAPPED, STORE LH
TLNN T,HFWDF
MOVEM B,@1(A) ;FULL WORD, STORE VALUE
LDB CH1,[420200+P,,-1] ;GET HIGH BITS OF 3RDWRD, RELOCATION BITS
TLNE T,HFWDF ;NOW TO MAP RELOCATION BITS
TRZ CH1,2
TLNE T,SWAPF
LSH CH1,1
TRZE CH1,4
TRO CH1,1
PUSH P,A
HRRZ A,1(A) ;GET POINTER INTO CONSTANTS TABLE
PUSHJ P,CPTMK
LDB B,C ;GET RELOCATION BITS
TLNE T,MINF
JRST CONBG8 ;NEGATE
TRNE B,(CH1)
ETA ERRCRI
;ATTEMPTED MULTIPLE RELOCATION IN CONSTANT
; ^ ABOVE SHOULD BE REPLACED WITH A $RSET LIKE ROUTINE
;THAT ALSO SEARCHES CONSTANT-GLOBAL TABLE FOR $R. ALREADY THERE
IOR B,CH1 ;LOOKS OK, IOR IN BITS FOR GLOBAL
CONB8A: DPB B,C ;STORE BACK NEW RELOCATION BITS FOR CONSTANT
POP P,A
CLEARM (A) ;CLEAR OUT CONSTANT-GLOBAL TABLE ENTRY
CLEARM 1(A)
POP P,B
AOS A
CONBG6: AOJA A,CONBG2 ;BACK FOR NEXT CONSTANT, DON'T KNOW HOW MANY THIS SYM USED IN
CONBG1: MOVE A,CONGLA
PUSH P,B
MOVE B,CONGLA
CONBG7: CAML A,CONGOL
JRST CONBG3
SKIPN C,(A)
CONBG5: AOJA A,CONBG4
MOVEM C,(B)
MOVE C,1(A)
MOVEM C,1(B)
AOS B
AOJA B,CONBG5
CONBG4: AOJA A,CONBG7
CONBG3: MOVEM B,CONGOL
POP P,B
POP P,C
POP P,T
POPJ P,
CONBG8: XORI B,3
TRNE B,(CH1)
ETA ERRCRI
ANDCB B,CH1
JRST CONB8A
ERRCRI: ASCIZ /Multiple relocation in constant/
;VARIAB
AVARIAB: NOVAL
SKIPE ASMOUT ;FLUSH ANY GROUPINGS IN PROGRESS.
JSP LINK,CONFLM
PUSHJ P,AVARI0
JRST ASSEM1
AVARI0: SOSG VARCNR ;ENTRY FROM AEND
ETF [ASCIZ /Too many variable areas/]
MOVE D,SYMAOB ;SET UP AOBJN POINTER TO ST
MOVE T,CLOC
MOVEM T,VCLOC ;STORE AS LOCATION OF VARIABLE AREA
ADD T,OFLOC
MOVE C,CRLOC
ADD C,OFRLOC
TRNE FF,FRPSS2
JRST AVAR1 ;PASS 2
HRL T,VARCNT ;SIZE OF AREA
TRNE C,1
TLO T,400000 ;RELOCATED
MOVEM T,@VARPNT
JRST AVAR2E
AVAR1: HRRZ A,@VARPNT ;VARIAB DURING PASS 2
CAIE A,(T)
ETR [ASCIZ /Variables location phase error/]
HLRZ A,@VARPNT
TRZE A,400000
XORI C,1
TRNE C,1
ETR [ASCIZ /Variables relocation phase error/]
SKIPE VARCNT
ETR [ASCIZ /Variables area size phase error/]
AVAR2E: HLRZ T,@VARPNT
TRNN T,377777
JRST AVAR2C ;IF THIS VAR AREA IS EMPTY, DON'T SCAN SYMTAB.
AVAR2: HLRZ LINK,ST(D) ;SCAN, CHECKING EACH SYM FOR WHETHER IT'S A VARIABLE
CAIL LINK,DEFLVR
JRST AVAR2B
ADD D,WPSTE1
AOBJN D,AVAR2
JRST AVAR2C ;ALL SCANNED.
AVAR2B: 3GET C,D ;FOUND A VARIABLE; DECIDE WHAT TO DO WITH IT.
MOVE B,ST+1(D)
MOVE SYM,ST(D)
TLZ SYM,740000
LDB LINK,[400400,,ST(D)]
CAIE LINK,UDEFLV_-14.
CAIN LINK,UDEFGV_-14.
JRST AVAR3 ;UNDEFINED VARIABLE
CAIE LINK,DEFGVR_-14.
CAIN LINK,DEFLVR_-14.
JRST AVAR4 ;DEFINED VARIABLE
AVAR2A: ADD D,WPSTE1
AOBJN D,AVAR2 ;CHECK ENTIRE SYMTAB
AVAR2C: HLRZ A,@VARPNT ;NOW GET SIZE OF AREA
TRZ A,400000 ;CLEAR OUT RELOCATION CHECK BIT
IFN FASLP,[
MOVE D,CONTRL
TRNE D,FASL ;IN FASL ASSEMBLY, CAN'T JUST SET LOC CTR; MUST OUTPUT 0'S.
CALL ABLKF
]
ADD A,VCLOC ;ADD LOCATION OF BEGINNING OF VARIABLE AREA
MOVEM A,CLOC ;STORE AS NEW CURRENT LOCATION
PUSHJ P,EBLK
CALL SLOCF
CLEARM VARCNT ;INITIALIZE COUNT OF VARIABLES IN NEXT AREA
AOS VARPNT ;INCREMENT POINTER TO POINT TO NEXT AREA
POPJ P,
;UNDEFINED VARIABLE FOUND IN SYMTAB SCAN
AVAR3: CAIN LINK,UDEFGV_-14. ;GLOBAL?
TLO SYM,40000 ;GLOBAL
PUSHJ P,LKPNRO
MOVSI T,DEFLVR
CAIN LINK,UDEFGV_-14.
MOVSI T,DEFGVR
TRNE FF,FRGLOL
JRST AVAR3A ;LOCATION GLOBAL
MOVEI B,-1(B)
ADD B,VCLOC
ADD B,OFLOC
MOVE TT,CRLOC
ADD TT,OFRLOC
SKIPE TT
TLO C,3RLR
CAIE LINK,UDEFGV_-14.
TLZN C,3VCNT
SKIPA
PUSHJ P,CONBUG
AVAR4B: PUSHJ P,VSM2
JUMPGE FF,AVAR2A ;IF PUNCHING PASS, OUTPUT DEFINITION.
PUSHJ P,OUTDE2
JRST AVAR2A
AVAR4: TLNE C,3VAS2 ;DEFINED VARIABLE FOUND DURING SYMTAB SCAN
TLOE C,3VP
JRST AVAR2A
MOVSI T,(LINK) ;CAUSE AVAR4B TO REDEFINE AS SAME TYPE.
LSH T,14.
TRNN FF,FRGLOL
JRST AVAR4A
AVAR3A: PUSHJ P,VSM2LV
JUMPGE FF,AVAR2A
PUSHJ P,PDEFPT
MOVEI A,0
PUSHJ P,PBITS
PUSHJ P,$OUTPT
AOS CLOC
JRST AVAR2A
AVAR4A: CAIN LINK,DEFGVR_-14. ;DEF VAR, 3VAS2, POINT NOT GLOBAL.
JRST AVAR4B ;VAR GLOBAL, MUST PUNCH DEF SINCE DIDN'T ON PASS1.
3PUT C,D ;LOCAL, JUST SET 3VP SO DON'T SEE IT NEXT VARIAB.
JRST AVAR2A ;NO NEED TO PUNCH DEF SINCE WAS DEF ON PASS1.
;;MAIN ;"MAIN" MIDAS ROUTINES: INIT, PS1, PLOD, PS2, PSYMS
;ALL CALLED WITH JSP A,; ALL GLOBAL
;RETURN INSTRUCTION FROM JSP IN LOCATION RETURN
PS1: HRRM A,RETURN ;PASS 1, (PASS 1 INITIALIZATION ALREADY DONE), SAVE RETURN
PUSH P,[ASSEM1-1] ;SIMBLK WILL POPJ1.
IFN A1PSW,[SKIPL PRGC
JRST A1PAS1 ;THIS NOT FIRST PROGRAM THIS ASSEMBLY, SET MODE TO 1PASS
]
TRO FF,FRNPSS
IFN ITSSW,JRST SIMBLK ;SELECT SBLK AND ASSEMBLE
IFN DECSW\TNXSW,JRST A.DECRE ;SELECT .DECREL AND ASSEMBLE.
PS2: HRRM A,RETURN ;PASS 2 (MAIN ROUTINE, PASS 2 INITIALIZATION NOT ALREADY DONE), SAVE RETURN
JUMPL FF,PA2A ;JUMP IF PASS 1 ENDED IN 1PASS MODE
TDO FF,[FLPPSS,,FRPSS2] ;SET PUNCHING PASS AND PASS 2 FLAGS
PUSHJ P,P2INI ;INITIALIZE
JRST ASSEM1 ;START ASSEMBLING
PA2A: MOVE A,SYMAOB ;PASS 2 OF 1PASS ASSEMBLY, CHECK FOR UNDEFINED LOCALS
PA2C: MOVE SYM,ST(A) ;GET SQUOZE THIS SYMTAB ENTRY
LDB B,[400400,,SYM] ;GET FLAGS
CAIE B,LCUDF_-14. ;LOCAL UNDEFINED?
JRST PA2B ;NOT LOCAL UNDEFINED, DON'T COMPLAIN
3GET C,A ;LOCAL UNDEFINED, GET 3RDWRD ST ENTRY
TLZ SYM,740000 ;CLEAR OUT FLAGS IN SYM IN ANTICIPATION OF TYPING OUT COMPLAINT
TLNN C,3LLV ;PROBLEM HANDED TO LINKING LOADER?
ETSM [ASCIZ /Undefined/] ;NO
PA2B: ADD A,WPSTE1 ;NOW GO FOR NEXT ST ENTRY
AOBJN A,PA2C
JRST RETURN
$INIT: HRRM A,RETURN ;INITIALIZATION (BEFORE PASS 1 ONLY) ROUTINE, SAVE RETURN POINT
IFN CREFSW,PUSHJ P,CRFOFF ;DON'T CREF ON 1ST PASS.
IFN LISTSW,CALL LSTOFF ;DON'T LIST ON 1ST PASS.
SKIPGE ISYMF
JRST INIT1 ;SPREAD SYMS (RETURNS TO SP4)
MOVE A,SYMAOB ;ALREADY SPREAD, JUST FLUSH ALL BUT INITIAL SYMS
INIT4: SKIPN B,ST(A)
JRST INIT2
3GET C,A
TRNE C,-1 ;INITIAL SYM?
CLEARM ST(A) ;NO
INIT2: ADD A,WPSTE1
AOBJN A,INIT4
SETZM BBKCOD
MOVE A,[BBKCOD,,BBKCOD+1]
BLT A,EBKCOD ;CLEAR OUT BLANK CODE
SP4: PUSH P,CRETN
P1INI: CLEARB I, LDCCC
INSIRP SETZM,BKBUF ISYMF A.PASS
IFN FASLP,[
INSIRP SETZM,FASATP FASPCH
CLEARM FASIDX
]
MOVEMM DECTWO,[[MOVE]]
TDZ FF,[FFINIT] ;INITIALIZE MOST FF FLAGS
MOVEIM A.PPASS,2 ;DEFAULT IS 2-PASS.
PUSHJ P,MACINI ;INITIALIZE MACRO STATUS
MOVEI A,PCNTB
MOVEM A,PBCONL
MOVS A,[BKTAB,,P1INI1]
BLT A,BKTAB+4
MOVEIM BKTABP,BKWPB*2
;DROPS IN.
P2INI: INSIRP SETZM,[CPGN,CLNN,GENSM,OFLOC,OFRLOC,CRLOC,BKPDL
SYLOC,SYSYM,BYTW,BYTRLC,STGSW,DECBRK,DEFNPS,BYTM,BYTM1,HKALL,QMTCH]
AOS B,A.PASS
IFN ITSSW,[
CALL SETWH2 ;SET UP .WHO2, PREPARE .WHO3 IN A WITH PAGENUM=1.
.SUSET [.SWHO3,,A] ;'P1 ',,PAGENUM OR 'P2 ',,PAGENUM
.SUSET [.SWHO1,,[.BYTE 8 ? 166 ? 0 ? 165 ? 0]]
]
TDZ FF,[FLUNRD,,FRGLOL]
IRP X,,[BKWPB,BKCUR,,BKPDL+1,1,BKLVL,IRDEF,ASMI
NCONS,CONCNT,VARTAB,VARPNT,NVARS,VARCNR,1,VECSIZ]
IFE 1&.IRPCN,IFSN [X], MOVEI A,X
IFN 1&.IRPCN, MOVEM A,X
TERMIN
MOVE A,CONTBA
MOVEM A,PLIM
MOVE A,CONGLA
MOVEM A,CONGOL
CLEARM VARCNT
CLEARM PBITS2
MOVE A,[440300,,PBITS1]
MOVEM A,BITP
MOVEI A,PBITS4
HRRZM A,PBITS4
CLEARB I,PBITS1
MOVEI A,PCNTB
MOVEM A,PBCON
MOVE A,[(LCUDF)+<SQUOZE 0,$ >+1] ;< AND > FOR COMPATIBILITY WITH OLD
MOVEM A,PCNTB
MOVEM A,CSQZ
MOVEI A,8
MOVEM A,ARADIX
IFN ITSSW,[
MOVEI A,100
MOVEM A,CLOC
]
.ELSE [
SETZ A, ; SET LOC COUNTERS APPROPRIATELY
SKIPGE B,CONTRL
TRNE B,DECREL+FASL
JRST [SETZM CLOC ; ASSUME RELOCATABLE
AOS CRLOC ; CRLOC GETS 1
JRST P2INI5]
TRNE B,DECSAV ; ASSUME ABSOLUTE
MOVEI A,140
TRNE B,SBLKS
MOVEI A,100 ; IF SBLK FORMAT ASSUME FOR ITS.
MOVEM A,CLOC
P2INI5:
]
SETZM GLOCTP
MOVEI A,BKBUF+1
MOVEM A,OPT1
MOVE A,CONTRL ;IN DEC FORMAT, OUTPUT PROGRAM NAME.
TRNE A,DECREL
CALL DECPGN ;CLOBBERS A
IFN FASLP,[
SETOM FASBLC ;LOSING BLOCK COUNT
MOVE A,CONTRL ;IN FASL FORMAT, OUTPUT FASL HEADER
TRNE A,FASL
CALL FASOIN ;INITIALIZE FASL OUTPUT
]
SETZM DECBRH
TRO FF,FRSYMS+FRFIRWD
MOVE A,[IFORTB,,FORTAB] ;INITIALIZE FORMAT TABLE ON EACH PASS
BLT A,FRTBE
MOVEIM GLSPAS,GLOTB ;INIT. ASSEM1 PDL LEVELS TO BOTTOM.
MOVEMM ASSEMP,[[-LPDL,,PDL]]
MOVEIM ASMDSP,ASSEM3
SETZM ASMOUT
SETZM CONSTP
SETZM SCNDEP ;NOT IN CONDIT. OR CONSTANT.
SETZM CONDEP
HRRZM P,CONSML ;START OUT IN MULTI-LINE MODE.
IFN LISTSW,[
MOVE A,[440700,,LISTBF]
MOVEM A,PNTBP
CLEARM LISTPF
SETOM LISTBC
SKIPG LISTP1 ;IF LIST ON PASS 1
JUMPGE FF,CRETN ;OR PUNCHING PASS,
SKIPE LISTP ;IF WANT LISTING,
CALL LSTON ;TURN ON OUTPUT OF LISTING.
]
IFN CREFSW,[
JUMPGE FF,CRETN
SKIPE CREFP ;IF C SWITCH WAS SEEN,
PUSHJ P,CRFON ;TURN ON CREFFING,
]
CRETN: POPJ P,RETURN
P1INI1: SQUOZE 0,.INIT ? 0 ? 3
SQUOZE 0,.MAIN ? 1,,
PLOD: HRRM A,RETURN ;MAIN ROUTINE TO PUNCH LOADER, CALLED BEFORE PASS 2 (PS2"), SAVE RETURN POINT
PUSHJ P,PLOD1 ;PUNCH LOADER
JRST RETURN ;RETURN
;PUNCH OUT THE LOADER
PLOD1: PUSHJ P,FEED1 ;LEAVE LOTS OF BLANK PAPER TAPE
MOVE B,CONTRL
TRNE B,ARIM10
JRST PLOD2 ;RIM10 => PUNCH OUT SBLK LOADER FOR PDP10 READIN-MODE READIN
TRNN B,SBLKS
POPJ P, ;NOT SBLK => DON'T PUNCH LOADER
PLOD1A: MOVSI B,SLOAD-SLOADP ;PUNCH SBLK LOADER IN RIM FORMAT
MOVSI C,(DATAI PTR,)
PLOAD1: MOVE A,C
PUSHJ P,PPBA
CAMN C,[DATAI PTR,13]
HRRI C,27
MOVE A,SLOAD(B)
PUSHJ P,PPBA
AOS C
AOBJN B,PLOAD1
MOVE A,[JRST 1]
PUSHJ P, PPBA
JRST FEED1
PLOD2: MOVSI C,LDR10-ELDR10 ;PUNCH SBLK LOADER FOR PDP10 READIN
PLOD3: MOVE A,LDR10(C)
PUSHJ P,PPBA
AOBJN C,PLOD3
JRST FEED1
;SBLK LOADER NORMALLY PUNCHED OUT IN RIM FORMAT
SLOAD: CONO PTR,60 ;0 RESTART POINT (NEW BLOCK)
JSP 14,30 ;1 START POINT, LOOP POINT FOR NEW BLOCK; WAIT FOR DATA WORD READY
DATAI PTR,16 ;GET HEADER
MOVE 15,16 ;INITIALIZE CHECKSUM
JUMPGE 16,16 ;HEADER .GE. 0 => STARTING INSTRUCTION
JSP 14,30 ;5 LOOP POINT FOR NEXT DATA WORD: WAIT FOR READY
DATAI PTR,(16) ;READ IN DATA WORD
ROT 15,1 ;NOW UPDATE CHECKSUM
ADD 15,(16)
AOBJN 16,5 ;LOOP FOR ALL DATA WORDS THIS BLOCK
MOVEI 14,33 ;30 TO RETURN TO 33
JRST 30 ;WAIT FOR READY THEN GO TO 33
;14 JSP AC FOR ROUTINE AT 30
;15 CHECKSUM
;16 AOBJN POINTER (UPDATED HEADER)
CONSO PTR,10 ;30 ROUTINE TO WAIT FOR DATA WORD READY FOR DATAI
JRST 30
JRST (14)
DATAI PTR,16 ;33 GET CHECKSUM
CAMN 15,16 ;COMPARE WITH CALCULATED
JUMPA 1 ;OK, GO GET NEXT BLOCK (DON'T CHANGE TO JRST OR REAL LOADERS WILL GET CONFUSED)
JRST 4, ;CHECKSUM ERROR
SLOADP==.
;PDP10 SBLK LOADER
;FOLLOWING CODING ACTUAL WORDS TO BE OUTPUT
;BY ASSEMBLER, COMPILER, OR WHATEVER
;SHOULD BE EXECUTED BY PDP10 HARDWARE READIN FEATURE
;USES ONLY THE AC'S (BUT ALL OF THEM)
LDR10:
-17,,0 ;BLKI POINTER FOR READ SWITCH
LDRC=0 ;CHECKSUM (OK, SO YOU'RE NOT ALLOWED TO LOAD
;INTO IT DURING HARDWARE READIN, BUT WHO SAYS
;YOUR PROGRAM CAN'T USE IT?)
OFFSET -.+1 ;BEGIN LOADING INTO 1 AS PER HEADER
LDRGO==.
CONO PTR,60 ;START UP PTR (RESTART POINT)
LDRRD==.
HRRI LDRB,.+2 ;INITIALIZE INDEX
LDRW==.
CONSO PTR,10 ;WAIT FOR WORD TO BE AVAILABLE
JRST .-1
ROT LDRC,-LDRRD(LDRB) ;BEFORE READING IN HEADER, ROTATE 2 BITS (THEN IGNORE)
;BEFORE READING IN EACH DATA WORD, ROTATE 1 BIT (FOR UPDATING CHECKSUM)
;BEFORE READING IN CHECKSUM, ROTATE NOT AT ALL (DON'T ROTATE CALCULATED CHECKSUM)
DATAI PTR,@LDRT1-LDRRD(LDRB) ;READ WORD INTO RIGHT PLACE
;HEADER => READ INTO C
;STORAGE WORD => READ INDEXED BY AOBJN POINTER IN A
;CHECKSUM => READ INTO A FOR COMPARISON WITH C(C)
XCT LDRT1-LDRRD(LDRB) ;EXECUTE RELEVANT T1 ENTRY (MAYBE SKIPS)
XCT LDRT2-LDRRD(LDRB) ;EXECUTE RELEVANT T2 ENTRY (MAYBE JUMPS)
LDRB==.
SOJA ., ;-RD(B) IS 2, 1, AND 0 FOR SUCCESSIVE ENCOUNTERS OF THIS INSTRUCTION
;USED AS INDEX INTO TABLES, ETC.
;TABLE 1
;INDIRECTED THROUGH FOR DATAI
;THEN EXECUTED TO SEE WHAT TO DO WITH READ IN WORD
;ENTRIES EXECUTED IN REVERSE ORDER
LDRT1==.
CAME LDRC,LDRA ;COMPARE CHECKSUM WITH CALCULATED, SKIP TO B IF THEY AGREE
ADD LDRC,(LDRA) ;UPDATE CHECKSUM
SKIPL LDRA,LDRC ;INITIALIZE HEADER AND SKIP UNLESS JUMP BLOCK
;TABLE 2
;EXECUTED IF CORRESPONDING ENTRY IN TABLE 1 DIDN'T SKIP WHEN EXECUTED
LDRT2==.
JRST 4,LDRGO ;CHECKSUM ERROR
AOBJN LDRA,LDRW ;UPDATE AOBJN POINTER AND GO BACK FOR NEXT STORAGE WORD IF NOT EXHAUSTED
LDRA==.
JRST LDRRD ;WHEN INITIALLY LOADED IS JUMP BLOCK TO THIS LOADER
;DURING LOADING USED TO HOLD HEADER (AOBJN POINTER), WHICH MAY BE LOADED JUMP BLOCK
OFFSET 0
ELDR10==.
;FLAGS IN SQUOZE OF SYMS TO OUTPUT
ABSGLO==040000 ;SYM IS GLOBAL (IF RELOCA, SAYS THIS IS BLOCK NAME)
ABSLCL==100000 ;LOCAL
ABSDLI==200000 ;DELETE INPUT (DON'T RECOGNIZE IT IF TYPED IN)
ABSDLO==400000 ;DELETE OUTPUT (DON'T TYPE IT OUT)
PSYMS: HRRM A,RETURN ;PUNCH OUT SYMBOL TABLE, CALLED AFTER EVERYTHING ELSE, SAVE RETURN POINT
PUSH P,PSYMS ;AT END, POPJ TO RETURN.
TRNE FF,FRSYMS
JRST SYMDMP ;PUNCH SYMS IF NEC.
SKIPL A,CONTRL
JRST SYMDA ;IF RELOCA, PUNCH PROGRAM NAME.
TRNE A,DECSAV ;IF DEC SAVE FORMAT WITHOUT SYMBOLS
JRST SYMDSA ;STILL DUMP START ADDRESS
TRNN A,DECREL
POPJ P,
PSYMSD: MOVSI A,DECEND
PUSHJ P,DECBLK ;START AN END-BLOCK.
MOVE A,DECTWO ;IN 2-SEG PROGRAMS,
CAME A,[MOVE]
JRST [ CAMG A,DECBRH ;OUTPUT HISEG BREAK
MOVE A,DECBRH
MOVEM A,WRD
MOVEIM WRDRLC,1
CALL PWRD
MOVEMM WRD,DECBRK
CALL PWRD ;FOLLOWED BY LOSEG BREAK
JRST EBLK]
MOVEMM WRD,DECBRK ;OUTPUT THE PROGRAM BREAK.
MOVEIM WRDRLC,1
PUSHJ P,PWRD
MOVE A,DECBRA ;OUTPUT HIGHEST ABS. ADDR
CAIG A,140
SETZ A, ;IF IT'S ABOVE THE JOBDAT AREA.
PUSHJ P,DECWRD
JRST EBLK
SYMDA: MOVEI A,LPRGN ;NOW PUNCH PROGRAM NAME
DPB A,[310700,,BKBUF]
MOVE A,PRGNM
TLO A,40000
PUSHJ P,$OUTPT
PUSHJ P,EBLK
TLZ FF,$FLOUT
POPJ P,
;DUMP OUT THE SYMBOL TABLE
SYMDMP: TRZ I,IRCONT ;OK TO END BLOCK
CLEARM GLSP1
CLEARM GLSP2
CLEARM WRDRLC
MOVE T,CONTRL
MOVEI A,BKBUF+1
MOVEM A,OPT1
CLEARM CLOC
CLEARM BKBUF
IFN FASLP,[
TRNE T,FASL
JRST SYMDM1
]
IFN ITSSW,[
TRNE T,SBLKS ; ON ITS, IF OUTPUTTING IN SBLK FMT
CALL SYMDDB ; THEN OUTPUT A DEBUGGING INFO BLOCK.
]
TRNE T,DECREL
JRST SYMDMD
JUMPL T,SSYMD ;JUMP IF NOT STINK
MOVEI B,LDDSYM ;LOCAL SYMS BLOCK TYPE
DPB B,[310700,,BKBUF] ;SET BLOCK TYPE
MOVEM B,CDATBC
MOVE B,SYMAOB ;CAUSE SSYMD3 TO LOOK AT ENTIRE SYM TAB.
JRST SSYMDR
SYMDMD: MOVSI A,DECSYM ;IN DEC FMT, START SYMBOLS BLOCK.
PUSHJ P,DECBLK
SYMDM1: MOVE B,SYMAOB
JRST SSYMDR
IFN ITSSW,[
; OUTPUT DEBUGGING INFO BLOCK (ITS SBLK ONLY)
SYMDDB: MOVE A,[-7,,3] ;OUTPUT A "DEBUGGING INFORMATION" BLOCK
MOVE B,A ;UPDATING THE CHECKSUM IN B.
PUSHJ P,PPB
MOVE A,[-6,,1] ;THE BLOCK CONTAINS ONE SUBBLOCK - A "MIDAS INFO" SUBBLOCK.
PUSHJ P,PPBCK
.SUSET [.RXUNAME,,A] ;CONTAINING NAME OF USER, DATE IN DISK FORMAT,
PUSHJ P,PPBCK
SYSCAL RQDATE,[%CLOUT,,A]
.LOSE %LSSYS
PUSHJ P,PPBCK ;AND THE SOURCE FILE NAMES (DEV, FN1, FN2, SNAME).
REPEAT 4,[
MOVE A,INFB+$F6DEV+.RPCNT
PUSHJ P,PPBCK
]
MOVE A,B
PJRST PPB ; PUNCH OUT CHECKSUM & RETURN
] ;IFN ITSSW
IFN TNXSW,[
SYMDDB: HRROI 1,FILNAM
HRRZ 2,INFB+$FJFN
MOVE 3,[111110,,JS%PAF]
JFNS
MOVEI A,1
MOVE B,FILNAM-1(A)
TRNE B,376 ;Last byte empty?
AOJA A,.-2 ; No, so try next.
MOVEM A,FNAMLN ;# of words in filename.
MOVNI A,7
SUB A,UNAMLN
SUB A,FNAMLN
MOVSS A ;-total # words in outer block,,0
HRRI A,3 ;3 means a "debugging information block"
PUSH P,A
MOVE B,A
PUSHJ P,PPB
POP P,A
SUB A,[-1,,2] ;one less word in block, 3-2=1, "midas info"
PUSHJ P,PPBCK
MOVEI A,6 ;5 header words (including this one)
PUSHJ P,PPBCK
MOVE A,[.OSMIDAS] ;Machine type this was assembled on.
PUSHJ P,PPBCK
MOVE A,[SIXBIT "MIDAS"] ;Sixbit name of program creating this file
PUSHJ P,PPBCK
GTAD ;Current date and time
MOVE A,1
PUSHJ P,PPBCK
MOVEI A,6 ;Offset to start of username string
PUSHJ P,PPBCK
ADD A,UNAMLN
PUSHJ P,PPBCK ;Offset to start of filename string
MOVS C,UNAMLN
MOVNS C
MOVE A,USRNAM(C)
PUSHJ P,PPBCK
AOBJN C,.-2
MOVS C,FNAMLN
MOVNS C
MOVE A,FILNAM(C)
PUSHJ P,PPBCK
AOBJN C,.-2
MOVE A,B
PJRST PPB ;Punch out checksum and return
];IFN TNXSW
;AC ALLOCATIONS DURING PHASE 1 (COMPACTING THE SYMBOL TABLE):
;AA INITIALLY HAS -SMK,,; INPUT INDEX INTO ST
;A TEMP
;B SQUOZE
;D OUTPUT INDEX INTO SYMTAB
;CH1 VALUE OF SYM
;CH2 3RDWRD
SSYMD: MOVEI D,ST-1
SETZB C,SMSRTF ;SYMS SORTED => INITIAL SYMS CLOBBERED
MOVE AA,SYMAOB
SSYMD1: SKIPE B,ST(AA) ;GET SYM NAME FROM TABLE
TDNN B,[37777,,-1] ;MAKE SURE NOT EXPUNGED
JRST SSYMDL ;NOT (REALLY) THERE, TRY NEXT
AOS SMSRTF
MOVE CH1,ST+1(AA) ;GET VALUE OF SYM
3GET CH2,AA ;GET 3RDWRD
TRNE CH2,-1
TLNE CH2,3KILL+3LLV
JRST SSYMDL ;DON'T PUNCH INITIAL OR KILLED SYMS.
MOVEI A,0 ;INITIALIZE FOR SHIFTING IN FLAGS
LSHC A,4 ;SHIFT FLAGS INTO A
XCT SSYMDT(A) ;DO THE APPROPRIATE THING THIS KIND OF SYMTAB ENTRY
JRST SSYMDL
SSYMD2: LSH B,-4 ;SHIFT SQUOZE BACK TO WHERE IT BELONGS
TLO B,ABSLCL ;SET LOCAL BIT
TLNE CH2,3SKILL
TLO B,ABSDLO ;HALF-KILL SYM
CAIL A,DEFGVR_-16
TLC B,ABSGLO\ABSLCL ;FOR GLOBAL SYM, SET GLOBAL BIT INSTEAD OF LOCAL BIT,
CAIGE A,DEFGVR_-16 ;AND PUT IT IN THE GLOBAL BLOCK IN THE SYMTAB.
SKIPN PRGNM+BKWPB ;IF ONLY ONE BLOCK IN PROGRAM, PUT ALL SYMS IN GLOBAL BLOCK.
HRRI CH2,0
PUSH D,B ;STORE NAME OF SYM IN OUTPUT SLOT
PUSH D,CH1 ;STORE VALUE
PUSH D,CH2 ;STORE 3RDWRD
SSYMDL: ADD AA,WPSTE1
AOBJN AA,SSYMD1 ;LOOP FOR ALL SYMS IN TABLE
MOVSI CH2,4^5 ;1ST BIT TO SORT ON IS TOP BIT,
MOVEI A,ST ;SORT FROM BOTTOM OF SYMTAB
MOVEI B,1(D) ;TO WHERE WE FILLED UP TO.
MOVE CH1,[TDNE CH2,1(A)] ;SORT ON 2ND WD, WDS WITH BIT ON COME FIRST.
MOVE C,[TDNN CH2,1(B)]
JSP AA,SSYMD9
TLC C,(TDNE#TDNN) ;ON BITS AFTER 1ST, ENTRIES WITH BIT OFF COME FIRST.
TLC CH1,(TDNE#TDNN)
MOVEI AA,SSRTX ;NEED ONLY CHANGE C, CH1 THE FIRST TIME.
JRST SSRTX
SSYMD9: PUSHJ P,SSRTX ;SORT SYMS ARITHMETICALLY BY VALUE.
MOVNI B,(B)
ADDI B,ST ;SIZE OF AREA OF SYMTAB STILL IN USE.
IDIV B,WPSTE
HRLZI B,(B) ;-<# SYMTAB ENTRIES>,,
MOVE T,CONTRL ; GET CONTRL FOR OUTPUT FMT CHECKS
MOVE A,[SQUOZE 0,GLOBAL]
MOVEM A,BKTAB ;CALL THE .INIT BLOCK "GLOBAL" WHICH IS WHAT DDT WANTS AS TOP BLOCK.
MOVE C,BKTABP
IDIVI C,BKWPB ;# BLOCKS (INCL. GLOBAL BLOCK).
CAIN C,2 ;IF ONLY GLOBAL AND MAIN, TELL BKSRT TO IGNORE MAIN.
SETZM PRGNM+1
CAIN C,2
MOVEI C,1 ;IF ONLY GLOBAL AND MAIN, FILE WILL HAVE ONLY 1 BLOCK (GLOBAL).
CAILE C,1 ;IF MORE THAN ONE BLOCK IN FILE,
TRNN T,DECSAV ;AND OUTPUT FORMAT IS DECSAV,
CAIA
ADDI C,1 ;THEN ALLOW FOR ONE MORE "BLOCK" (PGM NAME).
;NOTE THAT DECSAV FMT REPLACES BLOCKNAME WITH PGM-NAME
;FOR SINGLE-BLOCK CASE, SO COUNT OF 1 WORKS OK.
MOVSI A,(C) ; <# BLOCKS TO OUTPUT>,,
SUBM B,A ;-<# ENTRIES IN SYMTAB IN FILE>,,
LSH A,1 ;-<# WDS IN SYMTAB IN FILE>,,
TRNE T,DECSAV ; IF OUTPUT FORMAT IS DEC SAV,
JRST [ HRR A,DECSYA ; GET LOC TO STORE SYMS AT
MOVE C,A
MOVE A,[-1,,116-1] ; STORE IT AT .JBSYM
CALL PPB
MOVE A,C
CALL PPB
HRRI A,-1(A) ; SET -<# WDS IN SYMTAB>,,<LOC-1 TO STORE AT>
JRST .+1]
MOVEM A,SCKSUM ;SAVE 1ST WD FOR CHECKSUM (DECSAV IGNORES IT)
PUSHJ P,PPB
PUSHJ P,BKCNT ;PUT -<# SYMS IN BLOCK> IN 3RD WD OF EACH BKTAB ENTRY.
;DROPS THROUGH.
;DROPS IN IF ABS, JUMPS HERE IF RELOC.
;NOTE THAT IN ABS ASSEMBLY, B WILL CONTAIN THE CHECKSUM AND
;SHOULD NOT BE CLOBBERED.
SSYMDR: PUSH P,B ;-<# SYMS>,,0 ;IT WILL BE -1(P)
PUSHJ P,BKSRT ;SORT BLOCKS INTO BKTAB1
MOVE A,BKTAB
CAME A,[SQUOZE 0,GLOBAL] ;IF ABS, WE RENAMED .INIT TO GLOBAL, SO LEAVE IT IN BKTAB1
SOS D ;ELSE FLUSH .INIT FROM THE END OF BKTAB1.
SETOM 1(D) ;PUT A -1 AT END OF BKTAB1.
MOVE B,SCKSUM ;GET CHKSUM AFTER 1ST WD. (PPBCK WILL UPDATE)
PUSH P,[-1] ;(P) WILL BE BKTAB1 IDX OF NEXT BLOCK TO OUTPUT.
SSYMD3: AOS F,(P) ;F HAS BKTAB1 IDX OF BLOCK.
SKIPGE C,BKTAB1(F) ;BKTAB1 ELT HAS BKTAB IDX OR
JRST SSYMDX ; -1 AFTER LAST BLOCK.
SKIPL LINK,CONTRL
JRST SSYMD7 ;DIFFERENT RTN TO OUTPUT BLOCK NAME IF RELOCA.
TRNE LINK,DECREL+FASL+DECSAV
JRST SSYMD6 ; ALL THESE SKIP OVER SBLK-TYPE BLOCKNAME OUTPUT
MOVE A,BKTAB(C)
PUSHJ P,PPBCK ;OUTPUT BLOCK NAME WITH NO FLAG BITS SET.
HLRZ A,BKTAB+1(C)
SKIPE A
ADDI A,1 ;A GETS 0 FOR GLOBAL BLOCK, ELSE DDT LEVEL (= 1 + MIDAS LEVEL).
HRL A,BKTAB+2(C) ;PUT IN -2*<NUM SYMS>
ADD A,[-2,,]
SSYMG2: PUSHJ P,PPBCK ;OUTPUT -SIZE,,LEVEL WORD OF BLOCK NAME ENTRY.
JRST SSYMD6
SSYMD7: MOVE A,BKTAB(C) ;OUTPUT BLOCK NAME IN RELOCATABLE.
TLO A,ABSGLO ;TELL STINK IT'S BLOCK NAME.
PUSHJ P,$OUTPT
HLRZ A,BKTAB+1(C)
SUBI A,1
PUSHJ P,$OUTPT
SSYMD6: SKIPL C,-1(P) ;AOBJN PTR TO SYMS.
JRST SSYMD8 ;IN CASE NO SYMS.
SSYMD4: HRRZ A,ST+2(C) ;OUPUT ONLY THE SYMS IN THE BLOCK
CAME A,BKTAB1(F) ;NOW BEING HANDLED.
JRST SSYMD5
SKIPGE LINK,CONTRL
TRNE LINK,DECREL+FASL
JRST SYMD2 ;SPECIAL IF RELOCA.
MOVE A,ST(C)
TRNE LINK,DECSAV
CALL RSQZA ; RIGHT-JUSTIFY THE SQUOZE (SIGH)
PUSHJ P,PPBCK ;1ST, SQUOZE WITH FLAGS.
MOVE A,ST+1(C)
PUSHJ P,PPBCK ;2ND, VALUE.
SSYMD5: ADD C,WPSTE1
AOBJN C,SSYMD4 ;HANDLE NEXT SYM.
SSYMD8: TRNN LINK,DECSAV
JRST SSYMD3 ;ALL SYMS FOR THIS BLOCK DONE, DO NEXT BLOCK.
; DECSAV FMT HAS BLOCK NAMES OUTPUT LAST.
SKIPN PRGNM+BKWPB ;IF ONLY ONE BLOCK IN PGM,
JRST SSYMD3 ; FORGET IT; PGM-NAME SUBSTITUTES FOR BLKNAME.
MOVE C,BKTAB1(F) ; GET IDX FOR BLOCK
MOVE A,BKTAB(C) ; GET BLOCKNAME WITH FLAGS CLEAR
TLO A,140000 ; SET FLAGS TO SAY SYM IS BLOCKNAME
CALL RSQZA ; RIGHT-JUSTIFY SQUOZE FOR DEC (UGH BLETCH)
CALL PPB
HLRZ A,BKTAB+1(C) ; GET LEVEL OF BLOCK (NO WD COUNTS)
CALL PPB
JRST SSYMD3
; RIGHT-JUSTIFY SQUOZE IN A, PRESERVING FLAGS.
; (WHICH ASQOZR RTN DOESN'T)
; CLOBBERS B.
RSQZA: PUSH P,A ; SAVE FLAGS
TLZA A,740000 ; ZAP
RSQZA2: DPB A,[004000,,(P)] ; UPDATE
IDIVI A,50
JUMPE B,RSQZA2
POP P,A
POPJ P,
;PUNCH OUT LOCAL SYM (RELOCATABLE ASSEMBLY)
;NORMALLY OUTPUT SQUOZE W/ FLAGS ? VALUE,
;IF 3LLV SET OUTPUT PHONY NAME (= STE ADDR) ? SQUOZE W/ FLAGS, STINK FIXES IT UP.
SYMD2: LDB A,[400400,,ST(C)]
MOVE CH1,ST+1(C) ;SSYMDT MAY CHANGE CH1.
MOVE CH2,ST+2(C)
XCT SSYMDT(A) ;SKIPS IF SHOULD OUTPUT SYM.
JRST SSYMD5
TLNE CH2,3KILL
JRST SSYMD5
MOVE B,ST(C)
TLZ B,740000
JUMPE B,SSYMD5 ;UNUSED ENTRY.
JUMPL LINK,SYMDEC ;J IF DEC OR FASL FMT
TLNE CH2,3RLL
TLO B,200000 ;RELOCATE LEFT HALF
TLNE CH2,3RLR
TLO B,100000 ;RELOCATE RIGHT HALF
TLNE CH2,3SKILL
TLO B,400000 ;HALF-KILL
MOVEI A,ST(C)
TLNE CH2,3LLV ;IF STINK HAS VALUE,
PUSHJ P,$OUTPT ;GIVE STINK NAME STINK KNOWS SYMBOL BY.
TLNE CH2,3LLV ;IF GIVING PHONY NAME, INSURE LOCAL FLAG SET
TLO B,ABSLCL ;(STINK WILL DO SO OTHERWISE)
MOVE A,B
PUSHJ P,$OUTPT ;OUTPUT SYM
MOVE A,CH1
TLNN CH2,3LLV ;DON'T OUTPUT VALUE IF DON'T KNOW IT.
PUSHJ P,$OUTPT ;OUTPUT VALUE
JRST SSYMD5
SYMDEC: IFN FASLP,[
TRNE LINK,FASL
JRST SYMFSL ;FASL ASSMBLY
]
PUSHJ P,ASQOZR ;RIGHT-JUSTIFY THE SQUOZE,
TLNE CH2,3SKILL
TLO B,ABSDLO ;MAYBE HALFKILL,
TLO B,ABSGLO
LDB A,[400400,,ST(C)]
CAIGE A,DEFGVR_-14.
TLC B,ABSGLO+ABSLCL ;LOCAL SYM, CHANGE GLO TO LCL.
MOVEM B,WRD
PUSH P,C
PUSHJ P,DECPW ;FIRST, THE NAME,
POP P,C
LDB TM,[420200,,ST+2(C)]
MOVE A,ST+1(C) ;THEN THE VALUE AND RELOCATION BITS.
PUSHJ P,DECWR1
JRST SSYMD5
IFN FASLP,[
SYMFSL: TLO B,400000 ;GET VALUE FROM SECOND WD
TLNE CH2,3RLL
TLO B,200000 ;RELOCATE LH
TLNE CH2,3RLR
TLO B,100000
CAIL A,LGBLCB_<-18.+4>
TLO B,40000 ;GLOBAL FLAG
MOVE A,B
MOVEI B,15 ;PUTDDTSYM
PUSHJ P,FASO
MOVE A,CH1
PUSHJ P,FASO1
JRST SSYMD5
]
;XCT INDEXED ON SQUOZE FLAGS; SHOULDN'T PUNCH SYM IF DOESN'T SKIP.
SSYMDT: JFCL ;COM
JFCL ;PSEUDO OR MACRO
CAIA ;SYM, PUNCH OUT
TLNN CH2,3LLV ;LOCAL UNDEFINED, OUTPUT IF STINK HAS VALUE TO TELL STINK WHERE TO PUT IT.
TLZA CH1,-1 ;DEFINED LOCAL VARIABLE, CLEAR OUT LH(VALUE)
JFCL ;UNDEFINED LOCAL VARIABLE
SKIPL CONTRL ;DEFINED GLOBAL VARIABLE, PUNCH OUT IF ABS.
JFCL ;UNDEFINED GLOBAL VARIABLE
SKIPL CONTRL ;GLOBAL ENTRY, PUNCH OUT IF ABS ASSEM.
JFCL ;GLOBAL EXIT, DON'T PUNCH OUT
IFN .-SSYMDT-NCDBTS,.ERR SSYMDT LOSES.
SSYMDX: SKIPGE LINK,CONTRL
TRNE LINK,DECREL+FASL
JRST SSYMG3
TRNE LINK,DECSAV ; IN DECSAV FORMAT,
JRST [ MOVE A,PRGNM ; PGM NAME IS LAST THING IN SYMTAB
CALL RSQZA
CALL PPB ; WITH FUNNY VALUE OF
SETZ A, ; -<# SYMTAB WDS USED BY PGM>,,<RELOC CONSTANT>
CALL PPB ; BUT LAST PGM IN SYMTAB MUST HAVE LH=0, SO...
JRST SSYMG3]
MOVE A,B ; SBLK OR RIM ASSEMBLY, OUTPUT CHKSUM.
PUSHJ P,PPB
SSYMG3: SUB P,[2,,2]
PUSHJ P,EBLK ;END CURRENT OUTPUT BLOCK
SKIPL A,CONTRL ;RELOCATABLE => OUTPUT PROG NAME.
JRST SYMDA
IFN FASLP,[
TRNE A,FASL
POPJ P,
]
TRNE A,DECREL ;DEC FMT => OUTPUT END BLOCK.
JRST PSYMSD
SYMDSA: MOVE A,STARTA ;NOW GET STARTING INSTRUCTION
CALL PPB ;PUNCH IT OUT
IFN TNXSW,[
; At moment, add assembly-info block feature ONLY if we are running
; on a TNX. This isn't quite the right thing to do, but helps to
; ensure that the additional info doesn't break TOPS-10 systems until
; we verify that it will work OK for them.
SETZ A, ;0 word after start instruction
CALL PPB
CALL SYMDDB ;then the assembly info block
MOVE A,STARTA
] ;IFN TNXSW
JRST PPB ;then another copy of the start and return
;PUT INTO BKTAB1 THE BKTAB IDXS OF ALL THE BLOCKS IN THE ORDER THEIR
;SYMS SHOULD BE PUNCHED (A BLOCK'S SUBBLOCKS PRECEDE IT)
;THE .INIT BLOCK (MAYBE BY NOW RENAMED "GLOBAL") GOES IN LAST. D POINTS AT WHERE IT WAS PUT.
; NOTE THAT FOR DECSAV FORMAT THE ORDERING IS REVERSED; A BLOCK'S SUBBLOCKS
; FOLLOW IT, AND THE .INIT BLOCK GOES IN FIRST.
BKSRT: MOVEI D,BKTAB1-1 ;D IS FOR PUSHING INTO BKTAB1.
MOVSI A,1 ;START WITH BLOCK 0 (OUTERMOST, .INIT).
MOVE LINK,CONTRL
;HANDLE BLOCK IN A: LOOK FOR ITS SUBBLOCKS.
BKSR1: TRNE LINK,DECSAV
JRST [ MOVEI C,(A) ? PUSH D,C ? JRST .+1]
SETZ C,
BKSR2: CAME A,BKTAB+1(C)
JRST BKSR3 ;THIS BLOCK ISN'T A SUBBLOCK.
ADD A,[1,,] ;LH HAS SUBBLOCK'S LEVEL.
HRRI A,(C) ;RH HAS SUBBLOCK.
PUSHJ P,BKSR1 ;HANDLE THE SUBBLOCK
MOVE A,BKTAB+1(C) ; RESTORE A (C IS PRESERVED OVER CALL)
BKSR3: ADDI C,BKWPB
CAMGE C,BKTABP
JRST BKSR2
MOVEI C,(A) ; RESTORE C INDEX BKSR1 WAS ENTERED WITH
TRNE LINK,DECSAV
POPJ P,
PUSH D,C ;PUT THE BLOCK IN BKTAB1 (AFTER SUBBLOCKS)
POPJ P,
PPBCK: ROT B,1 ;OUTPUT WD IN A, UPDATING CKSUM IN B.
ADD B,A
JRST PPB
;THE THIRD WORD OF EACH BLOCK'S ENTRY IN BKTAB GETS THE NUMBER OF
;SYMBOLS IN THAT BLOCK (OF THE SYMBOLS THAT WE WILL PUT IN THE SYMTAB).
BKCNT: PUSH P,B
MOVEI C,0
BKCNT0: SETZM BKTAB+2(C) ;ZERO 3RD WD OF EACH BKTAB ENTRY.
ADDI C,BKWPB
CAMGE C,BKTABP
JRST BKCNT0
BKCNT1: MOVE C,ST+2(B)
SOS BKTAB+2(C) ;ADD -2 FOR EACH SYM IN THE BLOCK.
SOS BKTAB+2(C)
ADD B,WPSTE1
AOBJN B,BKCNT1
POPBJ: POP P,B
POPJ P,
SSRTX: HRLM B,(P) ;DO ONE PASS OF RADIX-EXCHANGE. SAVE END.
CAIL A,@WPSTEB ;ONLY 1 ENTRY, NOTHING TO DO.
JRST SSRTX7
PUSH P,A ;SAVE START.
SSRTX3: XCT CH1
JRST SSRTX4 ;MOVE UP TO 1ST WITH BIT ON.
SUB B,WPSTE
XCT C ;MOVE DOWN TO LAST WITH BIT OFF.
JRST SSRTX5
MOVE D,WPSTE
CAIE D,MAXWPS
JRST .+4
REPEAT MAXWPS,[
MOVE D,.RPCNT(A) ;EXCHANGE THEM,
EXCH D,.RPCNT(B)
MOVEM D,.RPCNT(A)]
SSRTX4: ADD A,WPSTE
SSRTX5: CAME A,B ;ALL DONE => DO NEXT BIT.
JRST SSRTX3 ;MORE IN THIS PASS.
ROT CH2,-1 ;NEXT BIT DOWN.
POP P,A ;A -> START, B -> END OF 1ST HALF.
JUMPL CH2,SSRTX6 ;ALL BITS IN WD DONE, STOP.
PUSHJ P,(AA) ;DO NEXT BIT ON 1ST HALF.
HLRZ B,(P) ;A -> END OF 1ST HALF, B -> END OF ALL.
PUSHJ P,(AA) ;DO SECOND HALF.
SSRTX6: ROT CH2,1 ;LEAVE CH2 AS FOUND IT.
SSRTX7: HLRZ A,(P) ;LEAVE A -> END OF AREA SORTED.
POPJ P,
;ARITHMETIC CONDITIONALS (B HAS JUMP<COND> A,)
COND: PUSH P,B ;SAVE CONDITIONAL JUMP
PUSHJ P,AGETFD ;GET FIELD TO TEST VALUE OF
CONDPP: POP P,T ;RESTORE CONDITIONAL JUMP INSTRUCTION
HRRI T,COND2 ;HRRI IN JUMP ADDRESS, GO TO COND2 IF CONDITIONAL TRUE
XCT T ;JUMP IF COND T,ASSEMBLE STRING
COND4: SETZM A.SUCC ;MOST RECENT CONDIT. FAILED.
COND5: JSP TM,ERMARK ;ERROR MSGS SHOULD SAY WHAT PSEUDO WE'RE IN.
CALL RCH
JSP D,RARL4 ;INIT FOR THE CONDITIONALIZED STUFF.
CAIA
CALL RARFLS ;READ AND IGNORE THE ARG.
JRST MACCR
ANULL: TLO FF,FLUNRD
JRST COND5
;.ELSE, .ALSO - B'S LH WILL HAVE SKIPE OR SKIPN.
A.ELSE: HRRI B,A.SUCC
XCT B
JRST COND4 ;CONDITION FALSE.
JRST COND2 ;TRUE.
;IF1, IF2 - B'S LH WILL HAVE TRNE FF, OR TRNN FF,
COND1: HRRI B,FRPSS2
XCT B
JRST COND4 ;NO
;CONDITION TRUE, ASSEMBLE STRING
COND2: SETOM A.SUCC ;LAST CONDITIONAL SUCCEEDED.
COND6: PUSHJ P,RCH ;GET NEXT CHAR
CAIE A,LBRKT
JRST [ CAIE A,LBRACE
TLO FF,FLUNRD
JRST MACCR]
SKIPN SCNDEP ;BRACKET TYPE CONDITIONAL.
SKIPE CONDEP
JRST COND7
MOVEMM CONDLN,CLNN ;AT TOP LEVEL, SAVE IN CASE THIS UNTERMINATED
MOVEMM CONDPN,CPGN
IFN TS, MOVEMM CONDFI,INFFN1
COND7: AOS SCNDEP ;COUNT IT FOR RBRAK'S SAKE.
JRST MACCR
;IFB, IFNB
SBCND: PUSH P,B ;SAVE TEST JUMP
SETZB B,C ;C COUNTS SQUOZE CHARS FOR IFB/IFNB
;B COUNTS NONSQUOZE FOR IFSQ/IFNSQ
JSP D,RARG ;INIT FOR READING OF ARG WHOSE BLANKNESS
JRST CONDPP ;IS TO BE TESTED.
JSP D,RARGCH(T) ;READ 1 CHAR,
JRST CONDPP ;(NO MORE CHARS)
HLRZ A,GDTAB(A) ;GET GDTAB ENTRY
CAIE A,(POPJ P,) ;POPJ => NOT SQUOZE
AOJA C,RARGCH(T)
AOJA B,RARGCH(T)
;IFDEF, IFNDEF
DEFCND: PUSH P,SYM
PUSH P,B ;SAVE CONDITIONAL JUMP
PUSHJ P,GETSLD ;GET NAME
CALL NONAME
PUSHJ P,ES
MOVEI A,0 ;UNDEFINED
IFN CREFSW,XCT CRFINU
CAIN A,GLOEXT_-14. ;GLOBAL EXIT...
SKIPL CONTRL ;DURING ABSOLUTE ASSEMBLY?
CAIN A,3 ;NO, LOCAL UNDEF?
MOVEI A,0 ;ONE OF THESE => UNDEF
REST SYM
EXCH SYM,(P) ;POP SYM OUT FROM UNDER THE CONDITIONAL JUMP.
JRST CONDPP
;;PWRD ;ROUTINES TO OUTPUT ASSEMBLES WORDS AND PORTIONS THEREOF
;HERE FROM PBITS TO OUTPUT WORD OF CODE BITS
PBITS3: PUSH P,A
MOVEI A,14
MOVEM A,PBITS2 ;INITIALIZE PBITS2 FOR COUNTING DOWN THROUGH NEXT SET OF CODE BITS
MOVE A,[440300,,PBITS1]
MOVEM A,BITP ;SET UP BITP FOR RELOADING PBITS1 WITH CODE BITS
MOVE A,PBITS1 ;NOW GET ACCUMULATED WORD OF BITS
MOVEM A,@PBITS4 ;STORE IN BKBUF
AOS A,OPT1 ;RESERVE SPACE FOR NEW WORD
;IF FRBIT7 SET (LAST CALL TO PBITS HAD 7) THEN NEXT WORD OF CODE BITS GOES
;AFTER NEXT WORD OUTPUT (REALLY!), OTHERWISE BEFORE
TRNN FF,FRBIT7
SOSA A
TRO FF,FRINVT
HRRZM A,PBITS4
POP P,A
CLEARM PBITS1
;DROPS THROUGH
;OUTPUT RELOCATION CODE BITS IN A
PBITS: SKIPGE CONTRL
POPJ P, ;NOT RELOCATABLE
SOSGE PBITS2
JRST PBITS3 ;NO MORE ROOM IN WORD, OUTPUT IT AND TRY AGAIN
CAIN A,7
TROA FF,FRBIT7
TRZ FF,FRBIT7
IDPB A,BITP
POPJ P,
;FOLLOWING ROUTINES SAVE AC'S EXCEPT FOR A
OUTSM0: MOVE A,SYM ;OUTPUT NAME STINK KNOWS SYMBOL BY.
TLZ A,37777 ;FOR LOCALS, THAT'S THE STE ADDR,
HRRI A,ST(D)
TLNN SYM,40000 ;FOR GLOBALS, THAT'S THE SQUOZE.
JRST $OUTPT
OUTSM: SKIPA A,SYM
OUTWD: MOVE A,WRD
$OUTPT: SKIPGE CONTRL ;DIRECTLY PUNCH OUT WORD IN A IN RELOCATABLE ASSEMBLY ONLY
POPJ P, ;DO NOTHING IF ABSOLUTE ASSEMBLY
PUSH P,AA
MOVE AA,OPT1
TRZN FF,FRINVT ;SKIP IF BEING HACKED FROM PBITS3, PUT WORD BEFORE WHERE IT NORMALLY BELONGS
AOS AA
MOVEM A,-1(AA)
MOVE A,CLOC
TRZE FF,FRFIRWD
HRRM A,BKBUF
POP P,AA
AOS A,OPT1
CAIL A,BSIZE+BKBUF
TRNE I,IRCONT
POPJ P,
;MAY DROP THROUGH
;END CURRENT OUTPUT BLOCK
EBLK: PUSH P,T
PUSH P,TT
PUSH P,A
PUSH P,B
MOVE T,CONTRL
JUMPGE T,EBLK3 ;JUMP IF RELOCATABLE ASSEMBLY
TRNE T,ARIM10\SBLKS
JRST ESBLK
TRNE T,DECSAV
JRST EDSBLK
IFN FASLP,[
TRNE T,FASL
JRST FASLE ;FASL HAS NO BLOCKS TO END - IGNORE
]
TRNE T,DECREL
JRST DECEBL
JRST EBLK5
EBLK3: MOVE T,PBITS1
MOVEM T,@PBITS4
MOVEI T,PBITS4
MOVEM T,PBITS4
MOVE T,[440300,,PBITS1]
MOVEM T,BITP
CLEARB TT,PBITS2
CLEARM PBITS1
MOVEI T,BKBUF
MOVE B,OPT1 ;GET POINTER TO END OF BLOCK
SUBI B,BKBUF+1 ;CONVERT TO # WORDS IN BLOCK (EXCLUDING HEADER)
DPB B,[220700,,BKBUF] ;SET COUNT FIELD IN HEADER
TRZN FF,FRLOC
JUMPLE B,EBLK5 ;IGNORE NULL BLOCK UNLESS FRLOC SET
TLO FF,$FLOUT ;INDICATE THAT OUTPUT HAS OCCURED (FOR 1PASS MULTIPLE-ASSEMBLY HACKING)
PUSHJ P,FEED
EBK1: CAML T,OPT1 ;DONE WITH BLOCK?
JRST EBK2 ;YES
MOVE A,(T) ;NO, GET DATA WORD
JFCL 4,.+1 ;UPDATE CHECKSUM
ADD TT,A
JFCL 4,[AOJA TT,.+1]
PUSHJ P,PPB ;OUTPUT WORD
AOJA T,EBK1
EBK2: SETCM A,TT ;DONE OUTPUTTING BLOCK, NOW GET CHECKSUM
PUSHJ P,PPB ;OUTPUT CHECKSUM
MOVE T,CDATBC ;GET BLOCK TYPE
DPB T,[310700,,BKBUF] ;SET NE T BLOCK TYPE TO STORAGE WORDS BLOCK TYPE
MOVEI T,BKBUF+1
MOVEM T,OPT1
EBLK4: TLO FF,$FLOUT ;INDICATE THAT OUTPUT HAS OCCURED (FOR 1PASS MULTIPLE-ASSEMBLY HACKING)
EBLK5: TRO FF,FRFIRWD
FASLE: POP P,B
POP P,A
PTT.TJ: POP P,TT
POP P,T
POPJ P,
;PUNCH OUT WORD OF CODED DATA (E.G. STORAGE WORD); WRD, WRDRLC, GLOTB ENTRIES
PWRDA: TROA FF,FRNLIK ;SUPPRESS ADR LINKING
PWRD: TRZ FF,FRNLIK ;PERMIT ADR LINKING
IFN LISTSW,[
SKIPN LSTONP
JRST PWRDL ;NOT MAKING LISTING NOW.
SKIPGE LISTPF
PUSHJ P,PNTR
SETOM LISTPF
MOVE LINK,WRD
MOVEM LINK,LISTWD
MOVE LINK,WRDRLC
MOVEM LINK,LSTRLC
MOVE LINK,CLOC
MOVEM LINK,LISTAD
MOVE LINK,CRLOC
DPB LINK,[220100,,LISTAD]
PWRDL:
] ;END IFN LISTSW,
JUMPGE FF,CPOPJ ;IGNORE IF NOT PUNCHING PASS
SKIPGE LINK,CONTRL
JRST PWRD1 ;ABSOLUTE ASSEMBLY
;RELOCATABLE ASSEMBLY
PUSHJ P,$RSET ;CHECK VALIDITY OF RELOCATION, STANDARDIZE IF NON-STANDARD
MOVE A,GLSP2
CAMN A,GLSP1
JRST PWRD2 ;NO GLOBALS
;NOW TO SEE IF IT'S POSSIBLE OR DESIRABLE TO ADDRESS LINK
HRLZ B,WRD
HRR B,WRDRLC
JUMPN B,PWRD3 ;JUMP IF RH NON-ZERO
TRNN FF,FRNLIK
SKIPGE GLOCTP
JRST PWRD3 ;ADR LINKING SUPPRESSED OR CLOC GLOBAL
SKIPE LDCCC
JRST PWRD3 ;IN LOAD TIME CONDITIONALS
MOVNI T,1 ;INITIALIZE T FOR COUNTING
PWRD4: CAML A,GLSP1
JRST PWRD5 ;DONE
HRRZ TT,1(A) ;GET GLOTB ENTRY
JUMPE TT,PWRD7A
LDB TT,[400400,,(TT)] ;GET SQUOZE FLAGS FROM SYM
CAIE TT,DEFGVR_-14.
CAIN TT,GLOETY_-14.
JRST PWRD3 ;DEFINED, BUT MUST BE HERE FOR A REASON (SEE $.H)
HLRZ TT,1(A)
TRNE TT,1777+MINF
JRST PWRD3 ;NEGATED OR MULTIPLIED
TRNE TT,HFWDF
JRST PWRD7
TRNE TT,ACF
TRNN TT,SWAPF
JRST PWRD3 ;NOT HIGH AC
PWRD7A: AOJA A,PWRD4
PWRD7: TRNE TT,SWAPF
AOJA A,PWRD4 ;LEFT HALF
AOJN T,PWRD3 ;JUMP IF THIS NOT FIRST GLOBAL IN RIGHT HALF
MOVEI D,1(A) ;FIRST GLOBAL, SET UP POINTER TO GLOTB ENTRY
AOJA A,PWRD4
PWRD5: AOJE T,PWRD3 ;NO GLOBALS LOOK BAD AND THERE AREN'T TOO MANY; JUMP IF NONE IN RH
HRRZ T,(D) ;GET ADR OF SQUOZE
SKPST T, ;SKIP IF IN SYMBOL TABLE
JRST PWRD3 ;BELOW SYMBOL TABLE, DON'T ADDRESS LINK AFTER ALL
PUSH P,T ;HOORAY, WE CAN ADDRESS LINK
SETZM (D) ;CLEAR OUT GLOTB ENTRY, DON'T NEED IT ANY MORE
PUSHJ P,PWRD31 ;DUMP OUT THE OTHER GLOBALS
POP P,D ;GET ST ADR OF THIS AGAIN
3GET1 A,D
LDB A,[.BP (3RLNK),A]
MOVE B,WRDRLC
TLNE B,1
TRO A,2 ;RELOCATE LEFT HALF
PUSHJ P,PBITS ;PUNCH OUT APPROPRIATE BITS FOR LINK LIST ENTRY
HLR A,1(D) ;GET ADR OF LAST
HLL A,WRD
PUSHJ P,$OUTPT ;OUTPUT WORD WITH RH = ADR OF LAST RQ FOR SYM TO PUT IN RH'S
MOVE A,CLOC ;NOW UPDATE ST ENTRY
HRLM A,1(D)
3GET1 B,D
SKIPN CRLOC
TLZA B,3RLNK ;CLOC NOT RELOCATED LAST TIME THIS SYM USED
TLO B,3RLNK ;RELOCATED
3PUT1 B,D
POPJ P,
PWRD31: MOVE T,GLSP2 ;DUMP ALL GLO S IN GENERAL FORMAT
PWRD3A: CAML T,GLSP1
POPJ P,
MOVE B,1(T)
TRNN B,-1
AOJA T,PWRD3A
TLNE B,1777
JRST RPWRD ;REPEAT
RPWRD1: LDB A,[.BP (MINF),B]
TRO A,4
PUSHJ P,PBITS
MOVE A,(B) ;CODEBITS +SQUOZE FOR SYM
HLRZ C,A
TLZ A,740000
CAIL C,DEFGVR
TLOA A,40000 ;SYM IS GLO
JRST [
MOVEI C,(B) ;IF WE ARE OUTPUTTING A REFERENCE TO THE
CAIL C,PCNTB ;"LABEL" AT THE BEGINNING OF A CONSTANTS AREA
CAIL C,PCNTB+NCONS*3 ;(BECAUSE THIS IS A 1PASS ASSEMBLY) USE THE
MOVEI A,(B) ;NAME, SINCE THE SYMBOL ISN'T IN THE
JRST .+1] ;SYMTAB
TLNE B,SWAPF
TLO A,400000
TLNE B,ACF
JRST PWRD3E ;AC HIGH OR LOW
TLNN B,HFWDF
JRST PWRD3F ;ALL THROUGH
TLO A,100000
TLNE B,SWAPF
TLC A,300000
PWRD3F: PUSHJ P,$OUTPT
AOJA T,PWRD3A
RPWRD: PUSHJ P,PBITS7
MOVEI A,CRPT
PUSHJ P,PBITS
LDB A,[221200,,B]
PUSHJ P,$OUTPT
JRST RPWRD1
PWRD3E: TLO A,300000
JRST PWRD3F
PWRD3: PUSHJ P,PWRD31
PWRD2: PUSHJ P,RCHKT
HRRZ A,B
DPB T,[10100,,A]
PUSHJ P,PBITS
JRST OUTWD
;CHECK FOR VALIDITY OF RELOCATION BITS OF CURRENT WORD
;LEAVE RELOC (RH) IN B, RELOC (LH) IN T
RCHKT: HRRZ B,WRDRLC ;CHECK FOR RELOC. OTHER THAN 0 OR 1.
HLRZ T,WRDRLC
TRZN B,-2
TRZE T,-2
RLCERR: ETSM [ASCIZ /Illegal relocation/]
POPJ P,
RMOVET: ROT T,-1
DPB B,[420100,,T]
TLZ C,3DFCLR ;SET RELOC BITS IN C
IOR C,T ;FROM B AND T.
POPJ P,
;CHECK WRDRLC FOR VALIDITY (CAPABILITY OF BEING PUNCHED OUT)
;IF STANDARD THEN JUST RETURN
;IF NON-STANDARD BUT OTHERWISE OK, PUT $R. ON GLOBAL LIST, RESET WRDRLC, AND RETURN
;LEAVES B AND C SET UP WITH RH, LH OF WRDRLC.
$RSET: MOVE C,WRDRLC ;GET RELOCATION
ADDI C,400000 ;WANT TO SEPARATE HALFWORDS
HLRE B,C ;GET LH IN B
HRREI C,400000(C) ;GET RH IN C (WILL EXCHANGE LATER)
MOVE A,[SWAPF+HFWDF,,$R.H] ;PUT THIS ON GLOBAL LIST IF LH NEEDS $R.
TRNE B,-2 ;CHECK LH
PUSHJ P,$RSET1 ;LH NEEDS GLOBAL REFERENCE
EXCH B,C
HRLI A,HFWDF
TRNE B,-2 ;CHECK RH
PUSHJ P,$RSET1 ;RH NEEDS GLOBAL REFERENCE
HRLZM C,WRDRLC ;RELOC OF LH
ADDM B,WRDRLC ;COMPLETE SETTING UP WRDRLC
POPJ P,
$RSET1: JUMPGE B,$RSET2 ;STRANGE RELOCATION IN B, JUMP IF NON-NEGATIVE
MOVN T,B ;NEGATIVE, GET MAGNITUDE
TLOA A,MINF ;SET FLAG TO NEGATE GLOBAL
$RSET2: SOSA T,B ;POSITIVE, GET ONE LESS THAN IT IN T
TDZA B,B ;NEGATIVE, CLEAR B, RELOCATION LEFT OVER
MOVEI B,1 ;POSITIVE, SET RELOCATION LEFT OVER TO 1
CAIN T,1
MOVEI T,0 ;MULTIPLYING BY TWO OR SUBTRACTING TIMES 1
TRNE T,-2000
ETSM [ASCIZ /Relocation too large/] ;TOO BIG EVEN FOR $RSET
DPB T,[221200,,A] ;LOOKS OK, STORE TIMES FIELD IN $R. REFERENCE
AOS GLSP1 ;NOW PUT $R. ON GLOBAL LIST
MOVEM A,@GLSP1
POPJ P,
;PWRD DURING ABSOLUTE ASSEMBLY
PWRD1: TRNE LINK,DECREL ; DEC REL FMT IS CONSIDERED ABSOLUTE.
JRST DECPW
IFN FASLP,[
TRNE LINK,FASL
JRST FASPW ;SO IS FASL
]
MOVE A,GLSP1
CAME A,GLSP2
ETR ERRILG ;GLOBALS APPEARING ILLEGALLY
SKIPE WRDRLC
ETR ERRIRL ;RELOCATION APPEARING ILLEGALLY
TRNE LINK,ARIM
JRST PRIM ;RIM
TRNE LINK,DECSAV
JRST DSBLK1
SBLKS1: MOVE A,WRD ;SBLK
MOVEM A,@OPT1 ;STORE WRD IN BKBUF
MOVE A,CLOC
TRZE FF,FRFIRWD
MOVEM A,BKBUF ;FIRST WORD OF BLOCK, SET UP HEADER
AOS A,OPT1
CAIGE A,BKBUF+BSIZE
POPJ P, ;BKBUF NOT FULL YET
SBLKS2: SUBI A,BKBUF+1
JUMPE A,CPOPJ
MOVNS A
HRLM A,BKBUF
PUSHJ P,FEED
MOVEI T,BKBUF
CLEARM SCKSUM
SBLK1: CAML T,OPT1
JRST SBLK2
MOVE A,SCKSUM
ROT A,1
ADD A,(T)
MOVEM A,SCKSUM
MOVE A,(T)
PUSHJ P,PPB
AOJA T,SBLK1
SBLK2: TRO FF,FRFIRWD
MOVEI A,BKBUF+1
MOVEM A,OPT1
MOVE A,SCKSUM
JRST PPB
ESBLK: MOVE A,OPT1
CAIN A,BKBUF+1
JRST EBLK5 ;AVOID SETTING $FLOUT IF NULL BLOCK.
PUSHJ P,SBLKS2
JRST EBLK4
PRIM: MOVSI A,(DATAI PTR,)
HRR A,CLOC
PUSHJ P,PPB
MOVE A,WRD
JRST PPB
; COME HERE TO OUTPUT WD IN ABSOLUTE DEC FMT (DECSAV)
DSBLK1: MOVE A,WRD
MOVEM A,@OPT1 ;STORE WRD IN BKBUF
MOVE A,CLOC
TRZE FF,FRFIRWD
MOVEM A,BKBUF ;FIRST WORD OF BLOCK, SET UP HEADER
AOS A,OPT1
CAIGE A,BKBUF+BSIZE
POPJ P, ;BKBUF NOT FULL YET, RETURN
DSBLK2: SUBI A,BKBUF+1
JUMPE A,CPOPJ
MOVNS A
SOS BKBUF ; DEC "IOWD" FMT, POINT AT LOC-1
HRLM A,BKBUF
PUSHJ P,FEED
MOVEI T,BKBUF
DSBLK3: CAML T,OPT1
JRST DSBLK4
MOVE A,(T)
PUSHJ P,PPB
AOJA T,DSBLK3
DSBLK4: TRO FF,FRFIRWD
MOVEI A,BKBUF+1
MOVEM A,OPT1
POPJ P,
; END A BLOCK IN DEC SAV FMT, COME HERE FROM EBLK.
EDSBLK: MOVE A,OPT1
CAIN A,BKBUF+1
JRST EBLK5 ;AVOID SETTING $FLOUT IF NULL BLOCK.
PUSHJ P,DSBLK2
JRST EBLK4
;END A BLOCK IN DEC FMT. COME FROM EBLK.
DECEBL: PUSH P,[EBLK5]
DECEB1: MOVSI A,DECWDS ;JUST INIT. AN ORDINARY BLOCK,
;COME HERE TO OUTPUT PREVIOUS BLOCK AND START NEW BLOCK OF TYPE IN LH OF A.
DECBLK: PUSH P,A
HRRZ A,BKBUF ;GET DATA-WORD COUNT OF CURRENT BLOCK.
JUMPE A,DECB1 ;NO WORDS => CAN IGNORE.
MOVEI TT,BKBUF+1
DECB0: MOVE A,-1(TT) ;GET AND PUNCH NEXT WD OF BLOCK.
PUSHJ P,PPB
CAME TT,OPT1 ;STOP WHEN NEXT WD ISN'T IN BLOCK.
AOJA TT,DECB0
DECB1: POP P,A
HLLZM A,BKBUF ;PUT BLOCK TYPE IN LH OF HEADER, DATA WD COUNT IN RH IS 0.
MOVEI TT,BKBUF+2 ;ADDR OF PLACE FOR 1ST DATA WD
MOVEM TT,OPT1 ;(LEAVE SPACE FOR WD OF RELOC BITS)
MOVE TT,[440200,,BKBUF+1]
MOVEM TT,BITP ;BP FOR STORING PAIRS OF RELOC BITS.
SETZM BKBUF+1 ;CLEAR THE WD OF RELOC BITS.
TLO FF,$FLOUT
POPJ P,
;COME HERE TO OUTPUT A WORD IN DEC FORMAT.
DECPW: MOVS A,BKBUF
CAIE A,DECWDS ;BEFORE THE 1ST STORAGE WD IN ORDINARY BLOCK,
JRST DECPW0
MOVE A,CRLOC ;MUST GO THE LOCATION CTR.
IDPB A,BITP
MOVE A,CLOC
MOVEM A,@OPT1
AOS OPT1
AOS BKBUF ;IT COUNTS AS DATA WORD.
DECPW0: MOVE A,BITP
TLNE A,77^4 ;IF NO ROOM FOR MORE RELOC BITS,
JRST DECPW1
HLLZ A,BKBUF ;START A NEW BLOCK.
PUSHJ P,DECBLK
JRST DECPW
DECPW1: PUSHJ P,$RSET ;SET UP RELOC BITS OF HALVES IN B,C.
LSH C,1
IORI B,(C) ;COMBINE THEM.
MOVE A,GLSP1
CAME A,GLSP2
JRST DECPG ;GO HANDLE GLOBALS.
DECPW3: IDPB B,BITP ;STORE THE RELOC BITS
MOVE A,WRD
DECPW2: MOVEM A,@OPT1 ;AND THE VALUE.
AOS OPT1
AOS BKBUF
POPJ P,
;PUT A WORD DIRECTLY INTO DEC FMT BLOCK.
DECWRD: SETZ TM,
DECWR1: IDPB TM,BITP ;SKIP A PAIR OF RELOC BITS,
JRST DECPW2 ;STORE THE WORD.
;HANDLE GLOBAL REFS IN DEC FMT.
DECPG: PUSHJ P,DECPW3 ;FIRST, OUTPUT THE WORD,
DECPG0: MOVSI A,DECSYM
PUSHJ P,DECBLK ;THEN STRT A SYMBOLS BLOCK.
MOVE C,GLSP2
PUSH P,SYM
DECPG1: CAMN C,GLSP1 ;ALL DONE =>
JRST DECPG2 ;GO START AN ORDINARY BLOCK FOR NEXT WD.
MOVE A,BITP
TLNN A,77^4 ;BLOCK FULL => START ANOTHER.
JRST DECPG0
AOS C,GLSP2 ;GET ADDR OF NEXT GLOBAL REF.
MOVE B,(C)
MOVE B,(B) ;GET NAME OF SYM.
TLZ B,740000
CAMN B,[SQUOZE 0,$R.]
JRST DECPG3 ;(DEC'S LOADER HAS NO SUCH HACK.)
CALL ASQOZR ;RIGHT-JUSTIFY THE SQUOZE FOR DEC SYSTEM.
MOVE A,B
TLO A,600000 ;PUT IN FLAGS SAYING ADDITIVE GLOBAL RQ.
PUSHJ P,DECWRD ;OUTPUT NAME.
HRRZ A,CLOC ;GET ADDR OF RQ,
TLO A,400000 ;MACRO-10 SETS THIS BIT SO I WILL.
MOVE B,(C)
TLNE B,SWAPF ;SWAPPED => TELL LOADER..
TLO A,200000
TLNE B,ACF+MINF
ETSM ERRILG ;CAN'T NEGATE GLOBAL OR PUT IN AC.
MOVE TM,CRLOC
PUSHJ P,DECWR1 ;OUTPUT 2ND WD,
JRST DECPG1 ;GO BACK FOR MORE GLOBAL REFS.
DECPG2: REST SYM
JRST DECEB1
DECPG3: ETR ERRIRL ;WE NEEDED $R. BUT DIDN'T HAVE IT.
JRST DECPG1
ERRILG: ASCIZ /Illegal use of external/
ERRIRL: ASCIZ /Illegal use of relocatables/
;OUTPUT PROGRAM NAME BLOCK (AT START OF PASS 2)
;IF 2-SEG PROGRAM, ALSO OUTPUT A TYPE-3 BLOCK (LOAD INTO HISEG)
DECPGN: JUMPGE FF,CPOPJ ;ONLY ON PASS 2.
PUSH P,[EBLK]
MOVSI A,DECNAM
CALL DECBLK
MOVE B,PRGNM
CALL ASQOZR
MOVE A,B
CALL DECWRD
MOVSI A,14 ;IDENTIFY THIS REL FILE AS MADE BY MIDAS.
CALL DECWRD
MOVE A,DECTWO
CAMN A,[MOVE]
RET ;NOT A 2-SEG PROGRAM.
DECP2S: MOVSI A,DECHSG
CALL DECBLK ;START A LOAD-INTO-HISEG BLOCK.
MOVE A,DECTWO
HRL A,DECBRH ;HISEG BRK,,TWOSEG ORIGIN.
SKIPL A
HRLI A,(A)
MOVEI TM,1 ;RELOCATION IS 1.
JRST DECWR1
IFN FASLP,[
;INITIALIZE OUTPUT FOR FASL ASSEMBLY
FASOIN: JUMPGE FF,CPOPJ ;ONLY ON PASS 2
MOVE A,[SIXBIT /*FASL*/]
PUSHJ P,PPB
MOVE A,[MIDVRS]
LSH A,-6
TLO A,(SIXBIT /M/)
PUSHJ P,PPB ;"LISP" VERSION NUMBER (USE M AND MIDAS NUMBER)
MOVE A,[440400,,FASB] ;INITIALIZE FASL OUTPUT BUFFER
MOVEM A,FASCBP
MOVEI A,FASB+1
MOVEM A,FASBP
POPJ P,
;COME HERE TO OUTPUT A WORD IN FASL FORMAT
FASPW: MOVE C,FASPCH
CAME C,FASATP
PUSHJ P,FPATB ;"PUNCH" OUT ATOM TBL (IF MORE HAS APPEARED)
PUSHJ P,$RSET ;GET RELOC
PUSH P,C ;SAVE LH RELOC
MOVEM B,FASPWB ;B HAS RELOC, WHICH IS ALSO FASL CODE FOR RELOC =1
MOVE A,GLSP2
FASPW3: CAME A,GLSP1
JRST FASPW1 ;LOOK TO SEE ..
FASPW2: MOVE A,WRD ;B HAS RELOC, WHICH ALSO HAPPENS TO BE FASL CODE TYPE
MOVE B,FASPWB
PUSHJ P,FASO ;OUTPUT WORD IN A WITH FASL CODE IN B
POP P,TM
JUMPE TM,FASPW5 ;NO LEFT HALF RELOC, OK
MOVNI A,1 ;ACTIVATE FASL HACK FOR LH RELOC
MOVEI B,7 ;WOULD OTHERWISE BE GETDDTSYM
PUSHJ P,FASO
FASPW5: MOVE C,GLSP2
FASPW6: CAMN C,GLSP1
POPJ P,
HRRZ TM,1(C)
JUMPE TM,[AOJA C,FASPW6]
MOVE SYM,(TM) ;GET SQUOZE OF SYM
TLZ SYM,740000 ;CLEAR CODE BITS
HLRZ D,1(C)
TRZ D,400000 ;DONT WORRY ABOUT THAT BIT
TRZE D,MINF
TLO SYM,400000 ;NEGATE
CAIN D,SWAPF
JRST FSPWSW
CAIN D,HFWDF
JRST FSPWRH
CAIN D,ACF+SWAPF
JRST FSPWAC
JUMPE D,FSPWWD
ETSM [ASCIZ /Global in illegal FASL context/]
FSPWWD: TLOA SYM,140000
FSPWAC: TLOA SYM,100000
FSPWRH: TLO SYM,40000
FSPWSW: MOVE A,SYM
MOVEI B,7 ;DDT SYM
PUSHJ P,FASO
AOJA C,FASPW6
FASPW1: HRRZ TM,1(A) ;GLOTB ENTRY
JUMPE TM,FASPW4
CAIL TM,AFDMY1
CAIL TM,AFDMY2
FASPW4: AOJA A,FASPW3
MOVE C,1(A) ;ITS A LIST STRUCTURE REF
TLNN C,-1-HFWDF
SKIPE FASPWB
ETA [ASCIZ /Illegal LISP structure reference/]
MOVE TM,AFDMY2-AFDMY1(TM) ;GET FASL BITS
MOVEM TM,FASPWB ;FASL BITS
CLEARM 1(A) ;FLUSH THAT GUY
AOJA A,FASPW3
FPATB: CAMN C,FASATP ;PUNCH OUT ATOM TBL, AMT ALREADY PUNCHED IN C
POPJ P, ;THRU
MOVEI B,12 ;ATOM TBL INFO
MOVE A,FASAT(C)
TRNN A,-1
AOJA C,FPATB3 ;LIST WORD .. SHOULD HAVE PUNCHED ITSELF
PUSHJ P,FASO
HRRZ D,FASAT(C) ;ATOM "LENGTH"
AOS C
FPATB1: SOJL D,FPATB2
MOVE A,FASAT(C)
PUSHJ P,FASO1
AOJA C,FPATB1
FPATB3: ETR [ASCIZ /Internal loss at FPATB3/]
FPATB2: MOVEM C,FASPCH ;RECORD AMOUNT PUNCHED
JRST FPATB ;LOOP BACK IF MORE
FASO: PUSHJ P,FASBO ;WRITE BITS
FASO1: MOVEM A,@FASBP ;STORE A IN FASL OUTPUT BUFFER
AOS TM,FASBP
CAIL TM,FASB+FASBL
ETF [ASCIZ /.FASL output block too long/]
POPJ P,
FASBO: MOVE TM,FASCBP ;OUTPUT FASL CODEBITS IN B, WRITE PREV BLOCK IF NECC
TLNN TM,770000
PUSHJ P,FASBE ;WRITE PREV FASL BLOCK
IDPB B,FASCBP
POPJ P,
FASBE: PUSH P,A
PUSH P,B
MOVEI TT,FASB
FASBO2: CAML TT,FASBP
JRST FASBO3
MOVE A,(TT)
PUSHJ P,PPB
AOJA TT,FASBO2
FASBO3: POP P,B
POP P,A
CLEARM FASB ;NEW CODE WORD
MOVEI TM,FASB+1
MOVEM TM,FASBP
SOS FASCBP
POPJ P,
AFATOM: PUSH P,B ;SAVE CODEBITS
SKIPGE B,CONTRL
TRNN B,FASL
ETI [ASCIZ /.ATOM illegal except in FASL assembly/]
PUSHJ P,AFRATM ;READ "ATOM", RETURN INDEX IN A
POP P,B
HLRZS B
AFLST1: AOS GLSP1
MOVEI T,AFDMY1(B) ;DUMMY (STORE THIS INFO IN SYM SO CONSTANTS WILL WIN
HRRZM T,@GLSP1
MOVEI B,0 ;NO RELOCATION
POPJ P,
;GLOBALS IN THIS TABLE KEEP TRACK OF LIST REFS
;UNDEF GLOBAL GODEBITS
AFDMY1: SQUOZE 44,.%VCEL ;EVENTUALLY POINT TO VALUE CELL
SQUOZE 44,.%SCAL ;EVENTUALLY BECOME "SMASHABLE CALL"
SQUOZE 44,.%ATM ;EVENTUALLY POINT TO ATOM
SQUOZE 44,.%ARY ;EVENTUALLY POINT TO ARRAY
AFDMY2: 2 ;CODE BITS FOR VALUE CELL REF
3 ;CODE BITS FOR SMASHABLE CALL
4 ;CODE BITS FOR POINTER TO ATOM
10 ;CODE BITS FOR POINTER TO ARRAY
AFRATM: PUSHJ P,AFRTKN ;READ TOKEN, LEAVING IT AT END OF FASAT
PUSHJ P,AFRITN ;"INTERN" IT, SKIP IF NOT FOUND
POPJ P, ;IF FOUND, INDEX IN A
PUSHJ P,AFRENT ;ENTER IN FASAT
POPJ P,
AFRENT: MOVE A,FASAT1 ;STORE FASAT1 IN FASATP
MOVEM A,FASATP
AOS A,FASIDX ;RETURN LOAD TIME ATOM INDEX
POPJ P,
AFRTKN: MOVE A,FASATP
ADD A,[700,,FASAT]
MOVEM A,FASAT2 ;BYTE PNTR TO USE TO STORE ATOM
CLEARM (A)
CLEARM 1(A) ;MAKE SURE ALL LOW BITS CLEARED
PUSHJ P,RCH
CAIN A,"#
JRST AFRTK1 ;READ NUMBER INTO FIXNUM SPACE
CAIN A,"&
JRST AFRTK2 ;READ NUMBER INTO FLONUM SPACE
AFRTKL: IDPB A,FASAT2 ;STORE CHAR
HRRZ A,FASAT2
CAIL A,FASAT+FASATL-1
AFTERR: ETA [ASCIZ /LISP atom name table full/]
CLEARM 1(A)
AFRTL2: PUSHJ P,RCH
CAIN A,12
JRST AFRTL2 ;IGNORE LF IN ATOM NAMES (PRIMARILY SO /CR WINS WITH ONE
CAIN A,"/ ;SLASH
JRST AFRQT ;QUOTE CHAR
CAIE A,40
CAIN A,15
JRST AFREND
CAIE A,";
CAIN A,11
JRST AFREND
CAIE A,"(
CAIN A,")
JRST AFREN2
CAIL A,"A+40
CAILE A,"Z+40
JRST AFRTKL ;THAT CHAR WINS, SALT IT
SUBI A,40
JRST AFRTKL ;MAYBE MUST CONVERT TO L.C. BEFORE SALTING IT.
AFRQT: PUSHJ P,RCH ;TAKE NEXT CHR NO MATTER WHAT
JRST AFRTKL
AFRTK1: SKIPA TM,[100000,,1] ;PUT VAL IN FIXNUM SPACE
AFRTK2: MOVE TM,[200000,,1] ;PUT IT IN FLONUM SPACE
PUSH P,TM
MOVE SYM,[SQUOZE 0,ATOM]
PUSHJ P,FAGTFD
POP P,TM
MOVE B,FASATP
ADDI B,2
CAIL B,FASAT+FASATL
XCT AFTERR
MOVEM TM,FASAT-2(B)
MOVEM A,FASAT-1(B)
MOVEM B,FASAT1
POPJ P,
AFREN2: TLO FF,FLUNRD ;SAVE ( OR ) AS WELL AS FLUSHING
AFREND: MOVEI B,5 ;PAD END OF P.N. WITH 0 S
MOVEI TM,0
AFREN1: IDPB TM,FASAT2
HRRZ A,FASAT2
CAIL A,FASAT+FASATL-1
XCT AFTERR
CLEARM 1(A)
SOJG B,AFREN1
SUBI A,FASAT
MOVEM A,FASAT1 ;STORE PNTR TO WORD BEYOND ATOM
; MAYBE PUT THIS IN FASATP
MOVE B,FASATP ;ADR OF START OF ATOM READ
SUBI A,1(B) ;COMPUTE LENGTH OF FASAT
HRRZM A,FASAT(B) ;PN ATOM 4.8-4.7 =0 STORE LENGTH IN HEADER WD
POPJ P,
AFRITN: MOVEI B,0 ;"INTERN" LAST ATOM READ IN
MOVEI A,1 ;A CONTAINS RUNTIME ATOM TBL INDEX
;B INDEX WITHIN FASAT
AFRIT1: CAML B,FASATP
JRST POPJ1 ;NOT FOUND
MOVE C,FASATP ;POINTS AT HEADER OF WORD OF NEW (?) ATOM
HRRZ D,FASAT(B) ;HEADER WD OF GUY IN TBL(RIGHT HALF HAS LENGTH)
JUMPE D,AFRIT4 ;JUMP ON RESERVED FOR LIST
AFRIT2: MOVE TM,FASAT(C)
CAME TM,FASAT(B)
AOJA B,AFRIT3 ;THIS ONE LOSES
SOJL D,CPOPJ ;THIS ONE WINS!
AOS B
AOJA C,AFRIT2
AFRIT3: SOJL D,[AOJA A,AFRIT1] ;FINISH SPACING OVER THIS GUY
AFRIT4: AOJA B,AFRIT3
AFENTY: SKIPGE B,CONTRL
TRNN B,FASL
ETI [ASCIZ /.ENTRY in NON-FASL/]
SKIPN CRLOC
ETI [ASCIZ /.ENTRY when . is absolute/]
PUSHJ P,AFRATM ;READ FUNCTION NAME
HRLZS A
PUSH P,A
PUSHJ P,AFRATM ;READ TYPE (SUBR, LSUBR, ETC)
HRRM A,(P)
MOVE SYM,[SQUOZE 0,.ENTRY]
PUSHJ P,FAGTFD ;READ ARGS PROP
JUMPGE FF,ASSEM1 ;NOT PUNCHING PASS
PUSH P,A
MOVE C,FASPCH
CAME C,FASATP
PUSHJ P,FPATB ;MAKE SURE ANY NEW ATOMS OUT
POP P,C
POP P,A
MOVEI B,13
PUSHJ P,FASO
HRL A,C
HRR A,CLOC
PUSHJ P,FASO1
JRST ASSEM1
AFLIST: HLRZM B,AFLTYP
SKIPGE B,CONTRL
TRNN B,FASL
ETI [ASCIZ /.LIST illegal except in FASL assembly/]
PUSHJ P,AFRLST ;READ LIST, RTN ATM TBL INDEX IN A
SKIPN AFLTYP
JRST ASSEM1 ;JUST EVAL IN LISP AND THROW AWAY VALUE
MOVEI B,AFDMAI ;"ATOM" INDEX IN AFDMY1 TBL
JRST AFLST1 ;TREAT AS ATOM
AFRLST: CLEARM AFRLD ;"DEPTH"
CLEARM AFRLEN ;"LENGTH" OF LIST AT CURRENT LEVEL
CLEARM AFRDTF ;DOT CONTEXT FLAG
JUMPGE FF,AFRLI1
MOVE C,FASPCH
CAME C,FASATP
PUSHJ P,FPATB ;MAKE SURE ALL ATOMS "PUNCHED"
MOVE A,FASATP
MOVEM A,AFRFTP ;SAVED STATE OF FASAT POINTER
MOVE C,AFLTYP
MOVEI B,16 ;EVAL TYPE HACK
CAIN C,1
MOVEI B,5 ;LIST TYPE HACK
PUSHJ P,FASBO ;WRITE CODE BITS
AFRLI1:
AFRL1: PUSHJ P,RCH
CAIE A,40 ;PREV ATOM (OR WHATEVER) "DELIMITED", SO THESE MEANINGLESS
CAIN A,15 ;UNLESS AT TOP LEVEL AND HAVE READ SOMETHING
JRST AFRL1A
CAIE A,11
CAIN A,12
JRST AFRL1A
CAIN A,"(
JRST AFRLO
CAIN A,")
JRST AFRLC
CAIN A,".
JRST AFRDT ;DOT..
TLO FF,FLUNRD
SKIPE AFRLD
JRST AFRNXT ;READ NEXT GUY THIS LVL
SKIPE AFRLEN
AFRLO2: ETI [ASCIZ /LISP read context error/]
AFRNXT: SKIPN TM,AFRDTF
JRST AFRNX2 ;NOT HACKING DOTS, OK
AOS TM,AFRDTF
CAIE TM,2
JRST AFRLO2 ;DIDNT JUST SEE THE DOT
AFRNX2: PUSHJ P,AFRATM
JUMPGE FF,AFRNX1 ;XFER ON NOT PUNCHING PASS
PUSHJ P,FASO1 ;TELL LOADER TO PUSH THIS ON ITS STACK
AFRNX1: AOS AFRLEN ;LIST NOW ONE LONGER THIS LVL
JRST AFRL1
AFRLO: SKIPN TM,AFRDTF
JRST AFRLO3 ;NOT HACKING DOTS
SOJN TM,AFRLO2
CLEARM AFRDTF
JRST AFRL1 ;IGNORE BOTH . AND (
AFRLO3: SKIPE AFRLD ;(
JRST AFRLO1
SKIPE AFRLEN
JRST AFRLO2
AFRLO1: PUSH P,AFRLEN
CLEARM AFRLEN ;START NEW LVL
AOS AFRLD ;DEPTH NOW ONE GREATER
JRST AFRL1
AFRLC: SOSGE AFRLD ;)
JRST AFRLO2 ;AT TOP LEVEL, BARF
MOVE A,AFRLEN
SKIPN TM,AFRDTF
JRST AFRLC2 ;NOT HACKING DOTS
CAIE TM,2
JRST AFRLO2
SOS A ;MAIN LIST NOW ONE SHORTER
TLOA A,200000 ;DOT WITH LAST THING ON STACK
AFRLC2: TLO A,100000 ;TELL LOADER TO MAKE LIST THIS LONG
JUMPGE FF,AFRLC5
PUSHJ P,FASO1
AFRLC5: POP P,AFRLEN ;LENGTH AT PREV LVL
AOS AFRLEN ;NOW ONE MORE
CLEARM AFRDTF ;NOT HACKING DOTS NOW
SKIPE AFRLD ;RETURNING TO TOP LEVEL?
JRST AFRL1
JRST AFRX1 ;YES THRU
AFRDT: SKIPN AFRDTF
SKIPN AFRLEN
JRST AFRLO2 ;DOT IN FIRST POSITION OF LIST
AOS AFRDTF ;ENTER STATE 1 OF DOT HACKING
JRST AFRL1
AFRL1A: SKIPN AFRLD ;SPACER CHAR TERMINATES AT TOP LVL IF HAVE RD SOMETHING
SKIPN AFRLEN
JRST AFRL1
AFRX1: JUMPGE FF,AFRX2 ;NOT PUNCHING PASS
MOVE A,AFRFTP
CAME A,FASATP
ETR [ASCIZ /Saw atoms in list on pass 2 for first time/]
SKIPN B,AFLTYP ;TYP LIST OP
SKIPA A,[-1,,]
MOVSI A,-2 ;PUT LIST OR VALUE OF LIST IN ATOM TBL
PUSHJ P,FASO1 ;TERM OP AND PUT IT IN ATOM TBL
MOVEI A,0
MOVE B,AFLTYP
JUMPE B,CPOPJ ;JUST WANT VALUE OF LIST
CAIN B,1 ;ONLY WANT THIS FOR STRAIGHT LIST
PUSHJ P,FASO1 ;OUTPUT "SXHASH" WORD
AOS A,FASATP
CLEARM FASAT-1(A) ;RESERVE SLOT IN FASAT TBL
MOVEM A,FASPCH ;SAY ALREADY PUNCHED OUT
AOS A,FASIDX
POPJ P,
AFRX2: TLO I,ILNOPT ;DONT TRY TO OPTIMIZE IF IN CONSTANT
CLEARB A,B
POPJ P,
]
;.LIBRA, .LIFS, ETC.
A.LIB: NOVAL ? NOABS
HLRZM B,LIBTYP' ;STORE BLOCK TYPE TO OUTPUT
CLEARM LIBOP ;INITIALIZE SQUOZE FLAGS
PUSHJ P,EBLK ;END CURRENT OUTPUT BLOCK, MAKING SURE LOADER KNOWS $.
LIB1: PUSHJ P,GETSYL ;GET NAME
TRNN I,IRSYL
JRST LIB2 ;NO SYL, DON'T OUTPUT
IOR SYM,LIBOP
TLO SYM,40000
PUSHJ P,OUTSM
MOVSI A,400000
ANDCAM A,LIBOP
LIB2: MOVE B,CDISP ;GET CDISP
TLNN B,DWRD\DFLD ;CHECK FOR WORD TERMINATOR
JRST LIB3 ;WORD TERMINATOR => DONE
MOVE A,LIBOP
MOVE B,LIMBO1 ;RETRIEVE LAST CHAR READ
CAIN B,",
MOVSI A,400000
CAIN B,"+
TLZ A,200000
CAIN B,"-
TLO A,200000
MOVEM A,LIBOP' ;STORE SQUOZE FLAGS (LESS GLBL BIT) FOR NEXT SYM
JRST LIB1
LIB3: MOVE A,LIBTYP ;GET BLOCK TYPE TO OUTPUT
DPB A,[310700,,BKBUF]
PUSHJ P,EBLK
CAIN A,LLIB ;.LIBRA?
JRST ARELC1 ;.LIBRA, NOW PLAY LIKE RELOCA PSEUDO
JRST LIB5 ;SOMETHING ELSE (.LIFS), INCREMENT DEPTH IN LOAD TIME CONDITIONALS
A.ELDC: NOVAL ? NOABS
PUSHJ P,EBLK
MOVEI A,ELTCB
DPB A,[310700,,BKBUF]
TRO FF,FRLOC ;MAKE EBLK OUTPUT NULL BLOCK
PUSHJ P,EBLK
SOSGE LDCCC
CLEARM LDCCC ;LOADER CONDITIONAL UNDERFLOW
JRST ASSEM1
;LOADER CONDITIONAL ON VALUE
A.LDCV: NOVAL ? NOABS
LSH B,-27.
PUSH P,B
PUSHJ P,AGETWD
POP P,B
DPB B,[400300,,BKBUF]
MOVEI A,LDCV
PUSHJ P,PLDCM
MOVEI A,0
DPB A,[400300,,BKBUF]
LIB5: AOS LDCCC
CCASM1: JRST ASSEM1
;.GLOBAL, .SCALAR, .VECTOR
;LH(B) HAS ILGLI, ILVAR, ILVAR+ILFLO RESPECTIVELY.
; Note that use of ILFLO flag is a crock here.
A.GLOB: NOVAL
HLLZ LINK,B ;REMEMBER WHICH OF THE THREE PSEUDO'S THIS IS.
A.GLO2: MOVE A,GLSPAS
MOVEM A,GLSP1
SETOM FLDCNT
PUSHJ P,GETSLD ;GET NAME
JRST MACCR ;NO NAME => DONE
CALL ES
JRST A.GLO1
CAIE A,PSUDO_-14.
JRST A.GLO1
JSP B,GVPSEU ;TRYING TO .GLOBAL A PSEUDO => TYPE APPRO. ERR MSG AND RETURN.
JRST A.GLO2 ;DON'T DO ANYTHING TO IT; MOVE ON TO NEXT ARG.
A.GLO1: IOR I,LINK ;SET THE GLOBAL FLAG OR THE VARIABLE FLAG.
TLNE LINK,ILVAR ;FOR .VECTOR OR .SCALAR, SAVE # VARS CREATED BEFORE CREATING THIS ONE.
PUSH P,VARCNT ;SO WE CAN TELL IF THIS CALL TO GETVAL ACTUALY CREATES IT.
PUSHJ P,GETVAL ;NOW GET VALUE (CLOBBERS SQUOZE FLAGS)
CAIA
GOHALT
TLNN LINK,ILVAR ; THAT'S IT IF .GLOBAL, ELSE CONTINUE
JRST A.GLO2
PUSH P,LINK ;.VECTOR OR .SCALAR, MUST READ THE SIZE.
TLO FF,FLUNRD ;RE-READ THE TERMINATOR AFTER THE SYM, SO "FOO(1)" AND "FOO," WIN
MOVE SYM,[SQUOZE 0,.SCALAR]
TLNE LINK,ILFLO ; USE RIGHT SYM
MOVE SYM,[SQUOZE 0,.VECTOR]
CALL AGETFD
REST LINK
REST B ;GET PREV. VARCNT, SO WE CAN SEE IF IT WAS INCREMENTED.
TRNN A,-1 ;MAKE (N) WORK AS SIZE BY USIN L.H. IF R.H. IS 0.
HLRZS A
JUMPN A,A.GLO3 ;JUMP IF NONZERO SIZE SPEC'D
TLNN LINK,ILFLO ; ZERO, USE DEFAULT
JRST A.GLO2 ; WHICH IS ALWAYS 1 FOR .SCALAR
SKIPA A,VECSIZ ; AND VECSIZ FOR .VECTOR.
A.GLO3: TLNE LINK,ILFLO ;NONZERO SIZE, SO
MOVEM A,VECSIZ ;DEFAULT MUST BE REMEMBERED FOR .VECTOR.
SUBI A,1 ;1 WORD WAS ALLOCATED BY GETVAL - HOW MANY MORE WANTED?
CAME B,VARCNT ;(MAYBE SYM ALREADY DEFINED, MAYBE PASS2, ...)
ADDM A,VARCNT ;IF GETVAL REALLY ALLOCATED THE SPACE THIS TIME, ALLOCATE THE
JRST A.GLO2 ;RIGHT AMOUNT.
;.LOP
A.LOP: NOVAL ? NOABS
PUSHJ P,EBLK ;TERMINATE CURRENT BLOCK
REPEAT 3,PUSHJ P,RGETFD ;GET THE FIELDS
MOVEI A,LD.OP
PUSHJ P,PLDCN
JRST ASSEM1
;.LIBRQ
A.LIBRQ: NOVAL ? NOABS
A.LBR1: PUSHJ P,GETSLD
JRST MACCR
PUSHJ P,PBITS7
MOVEI A,3
PUSHJ P,PBITS
TLO SYM,40000
PUSHJ P,OUTSM
JRST A.LBR1
A.LNKOT: AOS (P) ;THIS PSEUDO RETURNS NO VALUE.
NOVAL
AEND5: JUMPGE FF,CPOPJ ;IGNORE FOLLOWING ON NOT PUNCHING PASS
MOVE D,SYMAOB
AEND5A: MOVE SYM,ST(D)
LDB T,[400400,,SYM]
CAIE T,DEFLVR_-14.
CAIN T,DEFGVR_-14.
JRST AEND5E
CAIE T,LCUDF_-14.
CAIN T,GLOEXT_-14.
JRST AEND5B
AEND5C: ADD D,WPSTE1
AOBJN D,AEND5A
POPJ P,
AEND5E: 3GET C,D
TLNN C,3LLV
JRST AEND5C
AEND5B: HLLZ B,ST+1(D)
3GET C,D
TLNN C,3RLNK
JUMPE B,AEND5C
TLZ SYM,740000
CAIE T,LCUDF_-14.
CAIN T,DEFLVR_-14.
SKIPA
TLO SYM,40000
PUSHJ P,LKPNRO
HRRZS ST+1(D) ;CLEAR OUT LIST HEAD POINTER.
TLZ C,3RLNK ;INDICATE NO LIST.
3PUT C,D
JRST AEND5C
;PUNCH OUT COMPLETE LOADER COMMAND, PUNCHING OUT WRD AS ONLY CONTENTS
PLDCM: PUSH P,LINK ;SAVE LINK FOR ALOC AND FRIENDS (CLOBBERS OTHER AC'S)
PUSH P,A ;SAVE LOADER COMMAND TYPE
PUSHJ P,EBLK ;TERMINATE PREV BLOCK, MAKING SURE LOADER KNOWS $.
PUSHJ P,PWRDA ;PUNCH OUT THE WORD
POP P,A ;GET BACK LOADER COMMAND TYPE FOR PLDCN
PUSHJ P,PLDCN ;OUTPUT THE RESULTING BLOCK
PLINKJ: POP P,LINK ;RESTORE LINK
POPJ P,
PLDCN: HRRM A,BKBUF ;STORE LOADER COMMAND TYPE IN BKBUF HEADER
MOVEI A,LLDCM ;LOADER COMMAND BLOCK TYPE
DPB A,[310700,,BKBUF] ;STORE BLOCK TYPE IN HEADER
TRO FF,FRLOC ;MAKE EBLK OUTPUT BLOCK EVEN IF EMPTY
JRST EBLK
;.RELP <ARG> RETURNS RELOCATION OF ARG
A.RELP: CALL AGETFD
MOVE A,B
JRST VALRET
;.ABSP <ARG> RETURNS ABSOLUTE PART OF ARG.
A.ABSP: CALL AGETFD
JRST VALRET
;.RL1 IN RELOCATABLE ASSEMBLY RETURNS ZERO WITH RELOCATION FACTOR ONE.
;IN ABSOLUTE ASSEMBLY, IT RETURNS JUST ZERO.
;IFN <.RELP .RL1>, IS A TEST FOR A RELOCATABLE ASSEMBLY.
A.RL1: SKIPGE A,CONTRL
TRNE A,DECREL\FASL
SKIPA B,[1]
SETZ B,
SETZ A,
RET
AEND: NOVAL
SKIPE ASMOUT ; ERROR IF IN GROUPING.
JSP LINK,CONFLM ;FLUSH CONSTANTS, GIVE ERROR MSG.
SKIPE SCNDEP ;IF THERE ARE UNTERMINATED SUCCESSFUL
CALL AENDM1 ;CONDITIONALS, MENTION THEM.
MOVE A,BKCUR
CAIE A,BKWPB ;NOT IN .MAIN BLOCK => ERROR.
ETR ERRUMB
MOVE A,CDISP
TLNN A,DWRD
TLO FF,FLUNRD ;IF LAST TERM. WAS WORD TERM., RE-READ.
IFN LISTSW,[
MOVE A,[440700,,LISTBF]
EXCH A,PNTBP
MOVEM A,LISTTM
]
PUSHJ P,AVARI0
PUSHJ P,CNSTN0
SKIPL A,CONTRL
JRST [ PUSHJ P,AEND5 ; STINK RELOCATABLE => .LNKOT
JRST AEND6]
TRNE A,DECSAV ; IF DECSAV FMT,
JRST [ MOVE A,CLOC ; USE LOC COUNTER AT END AS LOC OF SYMBOLS
SKIPN DECSYA ; UNLESS LOC ALREADY SPECIFIED.
MOVEM A,DECSYA
JRST AEND6]
TRNN A,DECREL
JRST AEND6
MOVE A,CLOC ;IN DEC FMT, UPDATE HIGHEST ADDR SEEN,
SKIPN CRLOC ;UPDATE EITHER THE HIGHEST ABS ADDR
JRST [ CAML A,DECBRA
MOVEM A,DECBRA
JRST AEND6]
CAML A,DECTWO ;OR THE HIGHEST REL ADDR IN THE
JRST [ CAML A,DECBRH ;APPROPRIATE SEG.
MOVEM A,DECBRH
JRST AEND6]
CAML A,DECBRK
MOVEM A,DECBRK
AEND6: JUMPL FF,AEND1 ;ON PUNCHING PASS, SPECIAL STUFF
PUSHJ P,GETWRD ;OTHERWISE EAT UP WORD,
JRST RETURN ;AND RETURN
AEND1: PUSHJ P,EBLK
IFN LISTSW,[
SKIPGE LISTPF
PUSHJ P,PNTR
MOVE A,LISTTM
MOVEM A,PNTBP
]
MOVE SYM,[SQUOZE 0,END]
TLZ I,ILWORD
PUSHJ P,AGETWD
IFN LISTSW,[
MOVEM A,LISTWD
MOVEM B,LSTRLC
SETOM LISTAD
SETOM LISTPF
SKIPE LSTONP
PUSHJ P,PNTR
SKIPE LISTP
PUSHJ P,LPTCLS ;DONE LISTING
MOVE A,LISTWD
] ;END IFN LISTSW,
SKIPL B,CONTRL
JRST AEND3 ;RELOCATABLE
IFN FASLP,[
TRNE B,FASL
JRST FASEN ;FASL FORM
]
TRNE B,DECSAV
JRST AEND4
TRNN B,DECREL ;IF DEC FORMAT,
JRST AEND1A
TLNN I,ILWORD ;THEN IF THERE7S A STARTING ADDRESS,
JRST AEND2
MOVSI A,DECSTA ;OUTPUT START-ADDRESS BLOCK.
PUSHJ P,DECBLK
PUSHJ P,PWRD
PUSHJ P,EBLK
JRST AEND2
IFN FASLP,[
FASEN: JRST AEND2
]
AEND3: HRRZ A,CLOC
HRRM A,BKBUF ;SET UP PROGRAM BREAK JUST IN CASE OUTPUTTING MORE NULL DATA BLOCKS
MOVEI A,LCJMP
PUSHJ P,PLDCM
JRST AEND2
; HERE FOR DECSAV FORMAT.
AEND4: TLNE A,-1
JRST AEND1B ; IF SOMETHING IN LH, MAY BE ENTRY VECTOR.
MOVE B,A
MOVE A,[-1,,120-1] ; NOTHING, SO ASSUME SIMPLE JRST. MUST
PUSHJ P,PPB ; FIRST SAVE S.A. IN .JBSA CROCK.
MOVE A,B
PUSHJ P,PPB
TLO A,(JRST) ; FURNISH JRST FOR PUTTING AT END OF OUTPUT.
JRST AEND1B
AEND1A: ; CHECK WORD AND MAYBE MAKE IT A JRST
TLNN A,777000 ; CHECK INSTRUCTION PART
TLO A,(JRST) ; WANTS JRST
PUSHJ P,PPB
AEND1B: JUMPG A,.+3
ETR [ASCIZ /Start instruction negative/]
HRLI A,(JRST) ;END SYMTAB WITH POSITIVE WORD
MOVEM A,STARTA ;SAVE FOR PUNCHOUT AT END OF SYMTAB
PUSHJ P,FEED1
AEND2: PUSH P,[RETURN]
CNARTP:
IFN DECSW\TNXSW,[
PUSH P,TTYFLG
SKIPE CCLFLG ;IN DEC VERSION, IF RUN BY CCL, DON'T PRINT
AOS TTYFLG ;THIS STUFF ON THE TTY - ONLY IN ERROR FILE AND LISTING.
CALL CNTPD
REST TTYFLG
RET
CNTPD:
]
MOVNI D,1
MOVEI TT,PCNTB
CNTP1: CAML TT,PBCONL
RET
HRRZ B,1(TT)
HLRZ A,1(TT)
CAMN A,B
JRST CNTP2
AOSN D
TYPR [ASCIZ /Constants area inclusive
From To
/]
LDB B,[.BP (CGBAL),2(TT)]
SKIPE B
TYPR [ASCIZ /Global+/]
HRRZ B,1(TT)
PUSHJ P,OCTPNT
PUSHJ P,TABERR
HLRZ B,1(TT)
SOS B
PUSHJ P,OCTPNT
PUSHJ P,CRRERR
CNTP2: ADDI TT,3
JRST CNTP1
AENDM1: TYPR [ASCIZ /Unterminated successful bracketed conditionals
The first was at /]
AOS A,CONDPN
CALL DPNT
MOVEI A,"-
CALL TYOERR
AOS A,CONDLN
CALL D3PNT2
IFN TS,[
TYPR [ASCIZ/ of file /]
MOVE B,CONDFI
CALL SIXTYO
]
JRST CRRERR
AXWORD: CALL XGETFD ;READ 1ST FIELD,
TLNE I,ILMWRD
CALL IGTXT ;SOAK UP REST OF TEXT PSEUDO.
HRLM A,WRD
HRLM B,WRDRLC
MOVSI C,HFWDF
MOVSI B,SWAPF
PUSHJ P,LNKTC1
PUSH P,GLSP1
CALL XGETFD ;NOW THE SECOND FIELD
HRRM A,WRD
HRRES B
ADDM B,WRDRLC
MOVSI C,HFWDF
MOVEI B,0
POP P,T
PUSHJ P,LINKTC
JRST CABPOP
A.NTHWD:CALL AGETFD ;READ THE NUMBER OF THE WORD WE WANT.
SOJL A,CABPOP ;NEGATIVE OR 0 => RETURN 0.
SOJL A,A.1STWD ;1 => TURN INTO .1STWD.
;ELSE SKIP APPRO. # OF WORDS, THEN DO .1STWD.
A.NTH1: PUSH P,A
PUSH P,WRD
CALL XGETFD
TLZ FF,FLUNRD
REST WRD
REST A
TLNN I,ILMWRD
JRST CABPOP ;IF STRING ENDS BEFORE DESIRED WORD, RETURN 0.
SOJGE A,A.NTH1
A.1STWD: CALL XGETFD ;GET THE 1ST WD OF FOLLOWING TEXT PSEUDO,
CALL IGTXT ;THROW AWAY THE REST.
MOVE T,A ;RETURN THE VALUE
JRST TEXT5 ;COMPLAINING IF FOLLOWED IMMEDIATELY BY SYLLABLE.
A.LENGTH: CALL PASSPS
PUSH P,[0]
PUSH P,A
A.LN1: PUSHJ P,RCH
AOS -1(P)
CAME A,(P)
JRST A.LN1
SOS T,-1(P)
SUB P,[2,,2]
JRST TEXT5 ;RETURN VALUE IN T
ARDIX: NOVAL
PUSHJ P,AGETFD ;GET FIELD ARG
MOVEM A,ARADIX
JRST MACCR ;RETURN WITHOUT CLOBBERING CURRENT VALUE
A.RADIX: CALL AGETFD ;READ THE TEMP. RADIX.
PUSH P,ARADIX ;LAMBDABIND RADIX TO THAT VALUE.
MOVEM A,ARADIX
CALL XGETFD ;READ IN THE NEXT FIELD USING THAT RADIX.
REST ARADIX
JRST VALRET
;READ A BIT-MASK AS ARG, RETURN THE LH OF BP. FOR THAT BYTE.
A.BP: CALL YGETFD
MOVEI C,SPACE
SKIPE CDISP ;IF ARG WAS ENDED BY A COMMA, TURN IT INTO A SPACE
HRRM C,CDISP ;SO THAT .BP FOO,BAR USES THE FLD SPACE FLD FORMAT.
JUMPE A,VALR1
PUSH P,A
JFFO A,.+2
MOVEI B,36.
EXCH B,(P) ;(P) HAS # LEADING ZEROS.
MOVN A,B
AND A,B ;A HAS ONLY THE LOW BIT OF THE BYTE.
JFFO A,.+2
MOVNI B,1 ;B HAS 35.-<# TRAILING ZREROS.>
MOVEI A,1(B)
SUB A,(P) ;A HAS SIZE OF BYTE
LSH A,30 ;PUT IN S FIELD OF BP.
SUB P,[1,,1]
MOVNS B
ADDI B,35. ;B HAS # TRAILING ZEROS.
DPB B,[360600,,A] ;PUT THAT IN P FIELD OF BP.
JRST VALR1
;READ IN BP, RETURN BIT MASK TO SPEC'D BYTE.
;THE ARG SHOULD BE JUST THE LH OF A BP, WHICH MAY BE IN EITHER HALF OF THE ARG.
A.BM: CALL GETBPT ;READ IN A BYTE POINTER ARG, IN A, POINTING AT T.
SETZ T,
SETO C,
A.DPB1: DPB C,A ;PUT 1'S IN SPEC'D PART OF ACCUM T
MOVE A,T
JRST VALRET
;READ IN A BYTE POINTER (REALLY JUST S AND P FIELDS) AND MAKE POINT AT AC T.
;RETURN IT IN AC A.
GETBPT: CALL YGETFD
TLNN A,-1 ;IF ARG ISN'T IN LH, USE RH.
HRLI A,(A)
TLZ A,77 ;MAKE BP. -> AC T
HRRI A,T
RET
;RETURN # TRAILING ZEROS IN ARGUMENT.
A.TZ: CALL YGETFD
MOVN B,A
AND A,B ;A HAS JUST LOW BIT OF ARG SET.
JFFO A,.+2
MOVNI B,1 ;# OF ZEROS BEFORE LOW BIT =
MOVN A,B ;35. - <# TRAILING ZEROS>
ADDI A,35.
JRST VALRET
;RETURN # LEADING ZEROS IN ARG.
A.LZ: CALL YGETFD
JFFO A,.+2
MOVEI B,36.
MOVE A,B
JRST VALRET
;.DPB STUFF,BP,WORD DOES A DPB OF STUFF INTO THE FIELD OF WORD SPEC'D BY BP,
;RETURNING THE RESULTING WORD.
A.DPB: CALL YGETFD ;READ STUFF.
PUSH P,A
CALL GETBPT ;READ BP AND TURN INTO ACTUAL BP POINTING AT T
PUSH P,A
CALL YGETFD ;READ IN WORD AND PUT IN T.
MOVE T,A
REST A ;A HAS BP
REST C ;C HAS STUFF
JRST A.DPB1 ;GO DO THE DEPOSIT AND RETURN THE ALTERED WORD.
;.LDB BP,WORD RETURNS THE CONTENTS OF THE BYTE IN WORD SELECTED BY BP
A.LDB: CALL GETBPT
PUSH P,A
CALL YGETFD
MOVE T,A
REST A
LDB A,A
JRST VALRET
;.IBP BP RETURNS AN INCREMENTED BP.
A.IBP: CALL YGETFD
TLNN A,-1 ;IF ARG ISN'T IN LH, USE RH.
HRLZS A
IBP A
JRST VALRET
AWORD: NOVAL
PUSHJ P,EBLK
PUSHJ P,GETWRD ;ON UNDEFINED SYM, WYB UNDEFINED SYM IN "WORD"?
PUSHJ P,PPB
JRST ASSEM1
;.BIND - MAKE SYMS BE DEFINED IN CURRENT (SPEC'D) BLOCK. LH(B) HAS 0.
;.KILL - FULLY KILL THE SYMS.LH(B) HAS 3KILL.
;.HKILL - HALFKILL THEM. LH(B) HAS 3SKILL.
;.XCREF - PREVENT CREFFING OF SYMS. LH(B) HAS 3NCRF.
;.DOWN - SET 3DOWN, MAKING SYM VISIBLE IN SUBBLOCKS IN 1 PASS ASSEMBLY.
A.KILL: NOVAL
HLLZ LINK,B ;REMEMBER BIT TO SET.
A.KIL1: CALL GETSLD ;READ NEXT SYMBOL NAME.
JRST MACCR ;NO MORE, EXIT.
SKIPE LINK ;EXCEPT FOR .BIND, DO NOTHING ON PASS 1.
JUMPGE FF,A.KIL1
CALL ESDEF ;DEFINE THE SYMBOL, D HAS STE IDX.
JRST A.KIL2 ;SYMBOL NEVER SEEN.
IORM LINK,ST+2(D) ;SET THE BIT IN 3RDWRD..
IOR C,LINK ;(IF .XCREF, PREVENT CREFFING THIS TIME)
IFN CREFSW,XCT CRFINU ;CREF THE SYMBOL
JRST A.KIL1
A.KIL2: MOVSI T,LCUDF ;SYMBOL UNDEFINED, MAKE UNDEF LOCAL.
IOR C,LINK ;WITH THE DESIRED BIT SET.
TLO C,3MACOK ;SHOULDN'T BE ERROR IF IT BECOMES MACRO.
CALL VSM2
IFN CREFSW,XCT CRFINU
JRST A.KIL1
;EXPUNG SYM1,SYM2 ... ;UNDEFINE THOSE SYMS.
AEXPUNG: NOVAL
AEXPU2: PUSHJ P,GETSLD ;GET NAME
JRST MACCR ;NO MORE NAMES
PUSH P,[AEXPU2] ;AFTER THIS SYM, POPJ TO READ ANOTHER.
;EXPUNGE 1 SYMBOL, SQUOZE IN SYM.
AEXPU1: PUSHJ P,ES
JFCL ;NOT FOUND, DON'T COMPLAIN, JUST CREF.
IFN CREFSW,XCT CRFDEF
HRLZI T,400000 ;EXPUNGED ZERO SYM
SKIPE ST(D)
MOVEM T,ST(D)
SKIPL CONTRL ;IF RELOCATABLE ANDLOCAL SYMBOL,
CAIL A,DEFGVR_-33.
RET
PUSHJ P,PBITS7 ;TELL STINK TO EXPUNGE SYM.
MOVEI A,CLGLO
PUSHJ P,PBITS
TLO SYM,400000 ;SAY IS NEW TYPE RQ,
PUSHJ P,OUTSM0
MOVSI A,400000 ;NEW NAME NULL => DELETE.
JRST $OUTPT
;EQUAL SYM1,SYM2 ;DEFINE SYM1 SAME AS SYM2.
AEQUAL: NOVAL
PUSHJ P,GETSLD
ETR ERRTFA
PUSH P,SYM ;REMEMBER SYM NAME AND BLOCK TO DEF. IN.
PUSH P,ESBK
PUSHJ P,GETSLD
ETR ERRTFA
IFN CREFSW,XCT CRFINU ;CREF SYM DEFINED AS.
CALL ES ;LOOK UP SYM TO EQUATE TO.
JRST [ REST ESBK ;NOT FOUND => EXPUNGE THE 1ST SYM.
REST SYM
JRST AEXPU1]
REST ESBK
REST SYM
IFN CREFSW,XCT CRFDEF
PUSH P,A
PUSH P,B ;SAVE INFO ON VALUE OF SYM TO EQUATE TO.
PUSH P,C
CALL ESDEF
MOVEM SYM,ST(D)
REST B ;3RDWRD OF 2ND SYMBOL.
REST ST+1(D) ;(WHAT WAS PUSHED FROM B)
REST A
DPB A,[400400,,ST(D)]
TLZ C,3DFCLR ;SAVE OLD 3MAS, 3NCRF OF 1ST SYMBOL (AND ITS BLOCK #).
AND B,[3DFCLR,,] ;SET REST OF 3RDWRD BITS FROM 2ND SYMBOL.
IOR B,C
3PUT B,D
JRST MACCR
ERRTFA: ASCIZ /Too few args - EQUAL/
;.SEE SYM1,SYM2,... ;CREF THOSE SYMS.
A.SEE: CALL GETSLD ;READ 1 SYMBOL.
JRST MACCR ;NONE TO BE READ.
IFN CREFSW,[
SKIPN CRFONP ;IF CREFFING,
JRST A.SEE
CALL ES
MOVEI A,SYMC_-33.
XCT CRFINU ;CREF THE SYMBOL.
]
JRST A.SEE
;UUO HANDLING ROUTINE
;41 HAS JSR ERROR
VBLK
ERRCNT: 0 ; NUMBER OF ERRORS HIT -- VALUE OF .ERRCNT
ERRCCT: 0 ;NUM CHARS OUTPUT ON LINE, FOR MAKING MSGS LINE UP.
ERRJPC: 0 ;JPC READ WHEN UUO.
ERROR: 0
IFN ITSSW, .SUSET [.RJPC,,ERRJPC]
JRST ERRH ;GO HANDLE IT
PBLK
ERRH: PUSH P,T
PUSH P,B ;NOT TYPR => ERROR OF SOME KIND
PUSH P,A
PUSH P,C
LDB T,[331100,,40] ;PICK UP OP CODE
CAIN T,TYPCR_-33 ; TYPCR?
JRST TYPCR1
CAIN T,TYPR_-33 ; OR TYPR?
JRST TYPR1 ; YES
;ERROR OF SOME KIND
CAIE T,ETASM_-33 ;CHECK FOR SPECIAL LOSSAGES AT COLON
CAIN T,ETSM_-33
CAME SYM,SYSYM ;ARE WE ABOUT TO MENTIO THIS LOSING LABEL AS THE LAST ONE?
JRST ERRH1
MOVE T,SYSYM1
MOVEM T,SYSYM ;COLON LOSSAGE, DE-MUNG TAG WORDS FOR PRINTOUT
MOVE T,SYLOC1
MOVEM T,SYLOC
ERRH1:
IFN TS,[
IFN LISTSW,[
CALL PNTR ;FORCE OUT BUFFERED LISTING OUTPUT
CALL PNTCRR ;AND CR, SO USER CAN SEE WHERE ERROR WAS.
]
PUSHJ P,ERRTFL ;IF NOT SAME FILE AS LAST, PRINT FILE NAME.
]
SETZM ERRCCT
AOS ERRCNT ; BUMP ERROR TOTAL
IFN DECSW,AOS .JBERR ; BUMP ERROR MESSAGE COUNTER FOR LOADER TO ABORT
MOVE A,SYSYM ;GET LAST TAG DEFINED
JUMPE A,ERR1 ;SKIP PRINTOUT IF NONE THERE
PUSHJ P,SYMTYP ;THERE, TYPE IT OUT
MOVE B,CLOC ;NOW GET CURRENT LOCATION
SUB B,SYLOC ;SUBTRACT VALUE OF LAST TAG
JUMPE B,ERR1 ;SKIP NUMERIC PRINTOUT IF RIGHT AT TAG
MOVEI A,"+ ;NOT AT TAG,
PUSHJ P,TYOERR ;TYPE OUT PLUS SIGN,
AOS ERRCCT ;(1 MORE CHAR TYPED)
PUSHJ P,OCTPNT ;THEN TYPE OUT DIFFERENCE IN OCTAL
ERR1: PUSHJ P,TABERR ;NOW SEPARATE WITH TAB
MOVE A,ERRCCT
CAIGE A,8 ;MAKE SURE MOVE TO COLUMN 16.
PUSHJ P,TABERR
MOVEI B,[ASCIZ/GL+/]
SKIPGE GLOCTP ;LOCATION GLOBAL?
PUSHJ P,TYPR3 ;YES, TYPE OUT THAT FACT.
MOVE B,CLOC ;GET CURRENT LOCATION
PUSHJ P,OCTPNT ;TYPE OUT IN OCTAL
;DROPS THROUGH
;DROPS THROUGH.
PUSHJ P,TABERR
MOVE A,MDEPTH ;NOW DEPTH IN MACRO (NOT IRP, REPEAT, ETC.) EXPANSIONS
MOVSI T,-2
CALL DPNT0 ;PRINT, IN 2-CHAR FIELD.
MOVEI A,".
CALL TYOERR ;(USED TO BE OCTAL)
MOVE A,CPGN ;CURRENT PAGE NUMBER (FIRST PAGE OF FILE => 0)
PUSHJ P,[AOJA A,D6PNT] ;TYPE IT OUT IN DECIMAL
MOVEI A,"-
CALL TYOERR
MOVE A,CLNN ;ALSO CURRENT LINE NUMBER
PUSHJ P,[AOJA A,D3PNT2]
PUSHJ P,TABERR
MOVEI A,48. ;ASSUME ALL THE STUFF WE'VE PRINTED TAKES 48. CHARS
MOVEM A,ERRCCT ;MAYBE SOMEDAY TABERR, ETC. WILL REALLY UPDATE ERRCCT PROPERLY.
LDB A,[331100,,40] ;PICK UP OP CODE AGAIN
CAIGE A,8 ;ERROR UUO MAX
JRST .+1(A)
JRST [GOHALT ? JRST .-1] ;OPCODE 0, OR TOO BIG.
JRST ERRSM ;ETSM => TYPE SYM AND MESSAGE.
JRST ERRR ;ETR => JUST PRINT MESSAGE
JRST ERRJ ;ERJ => RH(40) HAS JUMP ADR
JRST ERRI ;ETI => IGNORE LINE RET TO ASSEM1
JRST ERRA ;ETA => RET TO ASSEM1
JRST ERRASM ;ETASM => TYPE SYM AND GO TO ASSEM1
JRST IAE ;ERF => FATAL.
ERRJ: MOVE A,40 ;ERJ => RH(40) HAS JUMP ADR
HRRM A,ERROR
JRST ERRET1
ERRI: PUSHJ P,RCH ;ETI => IGNORE LINE, RETURN TO ASSEM1: EAT UP LINE
CAIE A,12
JRST .-2
ERRA: MOVEI A,ASSEM1 ;ETA => RETURN TO ASSEM1, DON'T TYPE SYM.
MOVEM A,ERROR
JRST ERRR
ERRASM: MOVEI A,ASSEM1 ;ETASM => TYPE SYM AND RETURN TO ASSEM1
MOVEM A,ERROR
ERRSM: MOVEI C,56. ;ETSM OR ETASM => TYPE OUT SYM THEN MESSAGE
CALL TYPE37 ;CR NOW IF WHOLE MSG WON'T FIT ON ONE LINE.
MOVE A,SYM
PUSHJ P,SYMTYP
PUSHJ P,TABERR
ERRR: CALL TYPE40 ;TYPE THE ERROR MESSAGE.
ERRET1: REST C
POP P,A ;COMMON RETURN POINT FROM UUOS
POP P,B
POP P,T
JRST 2,@ERROR
;FINISH UP AN ERROR UUO'S ERROR MESSAGE. PRINT THE SPECIFIED STRING
;AND ALSO "IN DEFINE AT ..." IF NECESSARY, ALONG WITH APPROPRIATE CR'S.
TYPE40: MOVE C,ERRCCT
CALL TYPE37
CALL TYPR4 ;PRINT THE ASCIZ STRING
CALL CRRERR
SKIPN A,DEFNPS ;IF INSIDE A LONG PSEUDO,
RET
MOVE A,DEFNLN
MOVE B,DEFNPN
CAMN A,CLNN ;WHICH DIDN'T START IN THIS VERY LINE,
CAME B,CPGN
JRST TYPE42
MOVE A,DEFNFI
CAMN A,INFFN1
JRST TYPE43
TYPE42: MOVEI B,[ASCIZ/ in /]
CALL TYPR3
MOVE A,DEFNPS
CALL SYMTYP ;SAY WHAT PSEUDO, AND WHERE IT STARTED.
MOVEI B,[ASCIZ/ Starting at /]
CALL TYPR3
MOVE A,DEFNPN ;PAGE # -1.
CALL [AOJA A,DPNT] ;PRINT PAGE #.
MOVEI A,"-
CALL TYOERR
AOS A,DEFNLN
CALL D3PNT2 ;PRINT LINE #.
IFN TS,[
MOVE B,DEFNFI ;PRINT FILE NAME IF IT ISN'T THE CURRENT FILE.
CAMN B,INFFN1
JRST TYPE41
MOVEI B,[ASCIZ/ of file /]
CALL TYPR3
MOVE B,DEFNFI
CALL SIXTYO
]
TYPE41: CALL CRRERR ;AND CRLF.
TYPE43: MOVE A,ERROR
CAIE A,ASSEM1 ;IF THIS ERROR IS EXITING THE PSEUDO,
RET
SETZM DEFNPS ;SAY WE'RE NOT IN IT ANY MORE.
SETOM TEXT4
RET
;JSP TM,ERMARK IN A PSEUDO, TO ARRANGE FOR ERROR MESSAGES TO MENTION
;THAT PSEUDO. SYM SHOULD CONTAIN THE NAME OF THE PSEUDO.
;PUSHES A WORD ON THE STACK SO THAT WHEN THE PSEUDO RETURNS DEFNPS WILL BE CLEARED.
;IF DEFNPS IS SET UP ALREADY, DOES NOTHING (DOESN'T SET DEFNPS; DOESN'T PUSH THE WORD)
ERMARK: SKIPE DEFNPS
JRST (TM)
MOVEM SYM,DEFNPS
MOVE SYM,CLNN
MOVEM SYM,DEFNLN
MOVE SYM,CPGN
MOVEM SYM,DEFNPN
MOVE SYM,INFFN1
MOVEM SYM,DEFNFI
MOVE SYM,DEFNPS
CALL (TM)
CAIA
AOS (P)
SETZM DEFNPS
RET
;C SHOULD HAVE CURRENT HORIZ POS. IF TYPING THE STRING 40 POINTS AT
;WOULD OVERFLOW THE LINE, TYPE A CRLF AND TAB NOW ON THE TTY ONLY.
TYPE37: HRRZ B,40
HRLI B,440700 ;FIRST, FIGURE OUT HOW FAR ON LINE WE'LL TYPE IF WE DON'T CR.
ILDB A,B
CAIE A, ;AND COUNT CHARS IN THE ERR MSG.
AOJA C,.-2
CAMGE C,LINEL
RET
CRRTBX: MOVEI A,10
MOVEM A,ERRCCT ;PREVENT THIS FROM BEING DONE TWICE.
SKIPE TTYFLG
RET
MOVEI A,^M ;IF THERE'S NO ROOM, CRLF ON THE TTY ONLY (NOT THE ERR FILE).
PUSHJ P,TYOX
MOVEI A,^J
PUSHJ P,TYOX
MOVEI A,^I
JRST TYOX
;TYPE OUT SQUOZE (FLAGS OFF) IN A
SYMTYP: PUSHJ P,SQCCV ;GET NEXT CHAR IN ASCII.
AOS ERRCCT
PUSHJ P,TYOERR ;TYPE IT OUT.
JUMPE B,CPOPJ ;RETURN IF NOTHING LEFT (TYPED OUT AT LEAST ONE CHAR THOUGH)
IMULI B,50 ;LEFT-JUSTIFY REMAINDER
MOVE A,B ;GET LEFT-JUSTIFIED REMAINDER IN A
JRST SYMTYP ;TYPE OUT REMAINDER OF SYM
;TYPE OUT SQUOZE CHARACTER (IN A)
SQCCV: IDIV A,[50*50*50*50*50]
CAIG A,10.
SOJA A,SQCDTO ;NUMBER (OR BLANK =>SLASH)
CAIL A,45
SKIPA A,SYTB-45(A) ;SPECIAL
ADDI A,"A-13 ;LETTER
POPJ P,
SQCDTO: ADDI A,"0
POPJ P,
SYTB: ".
"$
"%
D3PNT2: MOVE T,[-3,,400000] ;3 CHAR FIELD, NO ZERO SUPPRESSION.
JRST DPNT0
DPNT: TDZA T,T ;ORDINARY DECIMAL PRINT.
D6PNT: MOVSI T,-6 ;6 CHAR FIELD, ZERO SUPPRESSION.
DPNT0: IDIVI A,10.
HRLM B,(P)
TRNE T,377777 ;IF NOT LAST DIGIT,
TRNE T,400000 ;AND ZERO-SUPPR. WANTED,
JRST DPNT2
JUMPN A,DPNT2 ;IF THIS IS A LEADING 0,
JUMPN B,DPNT2
MOVEI B," -"0
HRLM B,(P) ;REPLACE WITH A SPACE.
DPNT2: AOBJN T,.+2 ;J IF NOT ENOUGH CHARS YET.
JUMPE A,DPNT1 ;ENOUGH, DON'T MAKE MORE IF NOT NEEDED.
CALL DPNT0
JRST DPNT1
;TYPE HALFWORD IN B IN OCTAL.
OCTPNT: HRRZ A,B
IDIVI A,10
HRLM B,(P)
JUMPE A,.+2
PUSHJ P,.-3
AOS ERRCCT
DPNT1: HLRZ A,(P)
ADGTYO: ADDI A,"0
JRST TYOERR
;TYPE OUT THE SIXBIT WORD IN B
SIXTYO: JUMPE B,CPOPJ
MOVEI A,0
ROTC A,6
ADDI A,40
PUSHJ P,TYOERR
JRST SIXTYO
;TYPE CRLF
CRR: MOVEI A,15
PUSHJ P,TYO
MOVEI A,12
JRST TYO
;OP CODE 0 => NO RECOVERY RETURN TO GO9
IAE: CALL TYPE40 ;PRINT THE ERROR MESSAGE.
SKIPE ASMOUT
JSP LINK,CONFLZ ;TELL USER ABOUT UNTERM. GROUPINGS.
SKIPE SCNDEP ;MENTION ANY UNTERMINATED SUCCESSFUL
CALL AENDM1 ;CONDITIONALS.
MOVEI B,[ASCIZ /Error is fatal.
/]
CALL TYPR3
IFN ITSSW,[
.SUSET [.RTTY,,A]
SKIPL A
.RESET TYIC,
]
JRST GO9
;TYPR [ASCIZ /STRING/] ;TYPE OUT STRING
TYPR1: PUSH P,[ERRET1]
TYPR4: HRRZ B,40 ;GET ADR OF BEGINNING OF STRING
TYPR3: HRLI B,440700 ;CONVERT TO BYTE POINTER
TYPR2: ILDB A,B ;GET NEXT CHAR
JUMPE A,CPOPJ ;JUMP IF ZERO, END OF STRING
PUSHJ P,TYOERR ;NON-ZERO, TYPE IT OUT
JRST TYPR2
; TYPCR [ASCIZ /STRING/] ; Type out string, followed by CRLF
TYPCR1: PUSH P,[ERRET1]
PUSHJ P,TYPR4 ; When done, fall thru.
CRRERR: MOVEI A,^M ;CRLF IN ERROR MESSAGE.
CALL TYOERR
SKIPA A,[^J]
TABERR: MOVEI A,^I ;TAB INN ERROR MESSAGE.
TYOERR:
IFN LISTSW,[
SKIPE LSTTTY ;OUTPUT TO LISTING UNLESS LSTTTY ZERO.
CALL PILPTX
]
SKIPG LSTTTY
JRST TYO ;TO TTY UNLESS LSTTTY POSITIVE.
RET
;OUTPUT-FORMAT SELECTING PSEUDOS:
;.SLDR -- ON PASS 2, PUNCH OUT SBLK LOADER AND SELECT SBLK FORMAT
A.SLDR: NOVAL
JUMPGE FF,MACCR ;DO NOTHING ON PASS 1.
PUSHJ P,FEED1 ;LEAVE LOTS OF BLANK PAPER TAPE FIRST
PUSHJ P,PLOD1A ;PUNCH OUT LOADER
SIMBLK: MOVSI B,SBLKS ;ENTRY FROM PS1, A.SLDR SELECT SBLK
JRST SIMBL1
SRIM: MOVE A,SYM ;ENTRY FROM GETVAL, LH(B) HAS RH(CONTRL)
PUSH P,B
CALL SYMTYP
TYPR [ASCIZ/ Encountered
/]
REST B
SIMBL1: TRO FF,FRNPSS
HRRI B,TRIV ;SET UP TRIV FLAG FOR LH(CONTRL)
MOVSS B
CAME B,CONTRL ;IF CHANGING MODES, END THE BLOCK IN THE OLD MODE
CALL EBLK
MOVE A,CONTRL ;IF OLD MODE WAS RELOCATABLE OF SOME KIND,
TRNN A,DECREL\FASL
JUMPL A,SIMBL2
SETZM CRLOC ;INITIALIZE LOCATION COUNTER.
MOVEI A,100 ; USE 100 ASSUMING ITS SBLK
TRNE B,DECSAV
MOVEI A,140 ; BUT USE 140 FOR DEC ABS.
MOVEM A,CLOC
SIMBL2: MOVEM B,CONTRL ;STORE NEW MODE.
TRNE B,ARIM\ARIM10
TRZ F,FRSYMS ;RIM AND RIM10 MODES IMPLY NO SYMBOLS.
AOS (P)
;ROUTINE TO SET VARIABLES FOR BENEFIT OF NED LOGIC
;CALLED BY OUTPUT SELECTING PSEUDOS
OUTUPD: NOVAL
IFN A1PSW,[
TRNE FF,FRNPSS ;IF PASS 1,
TLNN FF,$FLOUT
JRST OUTCHK
AOS OUTN1 ;INDICATE "OUTPUT" HAS OCCURED OTHER THAN IN 1PASS MODE
OUTCHK: TLZE FF,$FLOUT
AOS OUTC ;INDICATE "OUTPUT" HAS OCCURED DURING CURRENT ASSEMBLY
]
RET
ANOSYMS: NOVAL
TRZ FF,FRSYMS
JRST MACCR
A1PASS: PUSHJ P,OUTUPD
A1PAS1: TLO FF,FLPPSS
MOVEIM A.PPASS,1 ;SET .PPASS TO 1.
IFN CREFSW,[ SKIPE CREFP ;THIS NOW PUNCHING PASS,
PUSHJ P,CRFON ;MAYBE TURN ON CREFFING.
]
IFN LISTSW,[
SKIPE LISTP
CALL LSTON ;LIST NOW IF WANT LISTING AT ALL.
]
MOVE A,CONTRL
TRNE A,DECREL
CALL DECPGN
TRZA FF,FRNPSS
ARELOC: PUSHJ P,OUTUPD
ARELC1: PUSHJ P,EBLK ;FINISH CURRENT OUTPUT BLOCK
TRO FF,FRLOC ;DOING LOCATION ASSIGNMENT, MAKE SURE NEXT GETS OUTPUT
CLEARM CLOC
MOVEI A,1
MOVEM A,CRLOC
CLEARM CONTRL
SETZM BKBUF
MOVEI A,LREL
DPB A,[310700,,BKBUF]
MOVEM A,CDATBC
JRST MACCR
; .DECSAV - SELECT DEC ABSOLUTE ZERO-COMPRESSED (SAV) FORMAT
A.DECSAV: NOVAL
MOVSI B,DECSAV ; SET FLAG
JRST SIMBL1 ; THEN HANDLE ALMOST LIKE .SBLK
A.DECTWO: CALL AGETFD ;READ THE TWOSEG ORIGIN.
TRNN FF,FRNPSS
ETF [ASCIZ /.DECTWO follows 1PASS/]
MOVE C,ISAV
TRNN C,IRFLD ;NO ARG => DEFAULT IT TO 400000
MOVEI A,400000
MOVEM A,DECTWO
A.DECREL: PUSHJ P,OUTUPD
TRZ FF,FRLOC
PUSHJ P,EBLK ;FORCE OUT BLOCK IN OTHER FMT.
MOVE A,[SETZ DECREL]
CAME A,CONTRL ;SWITCHING TO .DECREL MODE FOR 1ST TIME
TRNE FF,FRNPSS ;IN A 1PASS ASSEMBLY
JRST A.FAS1
CALL A.FAS1 ;DO THE SWITCH
JFCL
CALL DECPGN ;THEN WRITE THE PROGRAM NAME
JRST MACCR
A.FAS1: MOVEM A,CONTRL ;DEC FMT COUNTS AS ABS ASSEMBLY.
SETZM BKBUF ;(SO EBLK W0N'T OUTPUT ANYTHING)
SETZM CLOC ;START ASSEMBLING FROM RELOCATABLE 0.
MOVEI A,1
MOVEM A,CRLOC
PUSHJ P,EBLK ;INITIALIZE AN ORDINARY (DECWDS) BLOCK.
JRST MACCR
IFN FASLP,[
A.FASL: PUSHJ P,OUTUPD
PUSHJ P,EBLK
MOVE A,[SETZ FASL] ;FASL ALSO COUNTS AS ABS
JRST A.FAS1
]
ATITLE: NOVAL
PUSH P,CASSM1 ;RETURN TO ASSEM1.
PUSHJ P,GSYL
SKIPE SYM
MOVEM SYM,PRGNM
MOVE T,[440700,,STRSTO]
ATIT2: ILDB A,T ;GET CHAR FROM TITLE STRING
SOSG STRCNT
JRST ATIT3 ;CHAR IS SYLLABLE TERMINATOR
IFE ITSSW,[
SKIPE CCLFLG
TRNN FF,FRPSS2
]
PUSHJ P,TYO ;NOT TERMINATOR, TYPE OUT AND LOOP BACK
JRST ATIT2
ATIT3: CALL ATIT1 ;PRINT THE REST OF THIS LINE.
MOVE A,CONTRL
TRNE A,DECREL
TRNE FF,FRNPSS
CAIA
ETF [ASCIZ /TITLE follows 1PASS/]
MOVE A,TTYINS
ADD A,A.PASS ;SHOULD WE .INSRT TTY: THIS PASS (T SWITCH)
JUMPG A,CPOPJ
IFDEF GTYIPA,JRST GTYIPA ;GO PUSH TO TTY IF CAN,
IFNDEF GTYIPA,GOHALT ;WHY DID YOU SET TTYINS IF CAN'T?
ATIT1: CAIE A,15 ;CR?
CAIN A,12 ;LF?
IFN ITSSW,JRST CRR ;ONE OF THESE, FINISH TYPEOUT WITH CR
.ELSE [ JRST [ SKIPE CCLFLG
TRNN FF,FRPSS2
JRST CRR
RET]
SKIPE CCLFLG ;NEITHER OF THESE, PRINT CHAR.
TRNN FF,FRPSS2 ;ON DEC SYS, DON'T PRINT THE TITLE ON P2, OR AT ALL IF RUN BY CCL.
]
PUSHJ P,TYO
A.ERR1: PUSHJ P,RCH ;GET NEXT CHAR IN TITLE
JRST ATIT1
;.ERR PSEUDO-OP -- FOLLOWED BY LINE WHICH IS ERROR MSG.
A.ERR: PUSH P,CASSM1 ;RETURN TO ASSEM1,
ERJ A.ERR1 ;AFTER NUMBERS AND USER'S STRING.
A.FATAL:PUSH P,[GO9] ;.FATAL - CAUSE A FATAL ERROR.
ERJ A.ERR1
APRINT: NOVAL
HLRZS B ;B SAYS WHETHER PRINTX, PRINTC OR COMMENT.
JSP TM,ERMARK
CALL PASSPS
MOVE T,A
APRIN1: PUSHJ P,RCH
CAME A,T
JRST (B) ;GO TO APRIN1 FOR COMMENT,
JRST MACCR
APRIN2: CAIE A,"! ;COME HERE FOR PRINTX
APRIN3: PUSHJ P,TYO ;HERE FOR PRINTC
JRST APRIN1
A.TYO: NOVAL
CALL AGETFD ;PSEUDO TO TYPE A CHARACTER (AS NUMERIC ARG).
CALL TYOERR
JRST MACCR
A.TYO6: NOVAL
CALL AGETFD ;PSEUDO TO TYPE A WORD OF SIXBIT.
MOVE B,A
CALL SIXTYO
JRST MACCR
;.BEGIN - START NEW BLOCK WITH NAME = ARG, OR LAST LABEL DEFINED.
A.BEGIN: NOVAL
SKIPE ASMOUT ;IF IN GROUPING, FLUSH IT & ERROR.
JSP LINK,CONFLM
PUSHJ P,GETSLD ;READ A NAME.
MOVE SYM,SYSYM ;NO ARG, USE NAME OF LAST LABEL.
MOVE A,SYM ;NAME TO USE FOR BLOCK.
MOVE B,BKLVL ;CURRENT LEVEL + 1
HRLZI B,1(B) ;IS LEVEL OF NEW BLOCK.
HRR B,BKCUR ;ITS SUPERIOR IS CURRENT BLOCK.
MOVEI C,0 ;SEE IF AN ENTRY EXISTS FOR THIS BLOCK.
MOVE AA,A.PASS
A.BEG0: CAMN A,BKTAB(C)
CAME B,BKTAB+1(C)
JRST A.BEG1 ;THIS ENTRY ISN'T FOR BLOCK BEING ENTERED.
TDNE AA,BKTAB+2(C) ;FOUND: DEFINED IN THIS PASS?
ETSM [ASCIZ /Multiply defined BLOCK/]
JRST A.BEG2 ;NO, SAY IT'S DEFINED.
A.BEG1: ADDI C,BKWPB ;LOOK THRU ALL ENTRIES.
CAMGE C,BKTABP
JRST A.BEG0
CAIL C,BKTABS ;ALL ENTRIES USED => ERROR.
ETF ERRTMB
MOVEM A,BKTAB(C) ;ALLOCATE NEW ENTRY
MOVEM B,BKTAB+1(C) ;STORE NAME, LEVEL, SUPPRO.
MOVEI A,BKWPB(C)
MOVEM A,BKTABP ;POINTS TO 1ST UNUSED ENTRY.
A.BEG2: IORM AA,BKTAB+2(C) ;INDICATE BLOCK SEEN THIS PASS.
MOVEM C,BKCUR ;NEW BLOCK NOW CURRENT BLOCK,
AOS A,BKLVL ;ITS LEVEL NOW CURRENT LEVEL,
CAIL A,BKPDLS ;PUSH IT ON BLOCK PDL
ETF [ASCIZ /.BEGIN nesting too deep/]
MOVEM C,BKPDL(A)
JRST ASSEM1
ERRTMB: ASCIZ /Too many symbol blocks/
ERRUMB: ASCIZ /Unmatched .BEGIN - .END/
;.END - POP CURRENT BLOCK.
A.END: NOVAL
SKIPE ASMOUT ;IN GROUPING => TERMINATE IT & ERROR.
JSP LINK,CONFLM
MOVE A,CDISP ;IF FOLLOWED BY WORD TERM,
TLNN A,DWRD ;CAUSE IT TO BE RE-READ
TLO FF,FLUNRD ;SO ARG WILL BE NULL.
PUSHJ P,GETSLD ;READ ARG.
JRST A.END0 ;NO ARG.
MOVE C,BKCUR ;ERROR UNLESS BLOCK BEING TERMINATED
MOVE A,BKTAB(C) ;HAS SAME NAME AS ARG.
EXCH A,SYM ;(MAKE SURE SYM NAME TYPED IS BLOCK'S NAME)
CAME A,SYM
ETSM ERRUMB ;ERROR, PRINT SYM (BLOCK'S NAME)
A.END0: MOVE C,BKCUR ;NOT OK TO END .MAIN BLOCK OR .INIT BLOCK.
CAIG C,BKWPB
ETA ERRUMB
HRRZ C,BKTAB+1(C)
MOVEM C,BKCUR ;POP INTO FATHER OF PREV. CURRENT BLOCK.
SOS BKLVL
JRST ASSEM1
;BKTAB: 3-WORD ENTRIES, 1 PER BLOCK, IN NO PARTICULAR ORDER.
;1ST WD HAS SQUOZE NAME OF BLOCK, FLAGS CLEAR.
;2ND WD HAS LEVEL,,BKTAB IDX OF CONTAINING BLOCK("FATHER", "SUPERIOR")
;3RD WD BIT 1.N ON => BLOCK ENTERED ON PASS N.
;SYMBOL TABLE OUTPUT RTN PUTS -2*<NUM SYMS IN BLOCK> IN 3RD WD.
;THE FIRST BKTAB ENTRY IS THAT OF THE OUTERMOST BLOCK (.INIT)
;IN WHICH INITIAL SYMS ARE DEFINED.
;THAT ENTRY'S 2ND AND 3RD WDS ARE 0.
;THE NEXT IS THAT OF THE MAIN BLOCK (.MAIN) IN WHICH
;ALL SYMBOLS ARE NORMALLY DEFINED (THAT IS, YOU ARE IN THAT BLOCK
;BEFORE YOU DO ANY .BEGIN'S).
;THAT ENTRY'S 2ND WD IS 1,, ; ITS 3RD, 0.
;THE BKPDL IS A TABLE OF BLOCKS CURRENTLY ENTERED & NOT ENDED.
;BKPDL'S 1ST ENTRY IS FOR OUTERMOST BLOCK.
;LAST ENTRY IS BKPDL+@BKLVL, FOR CURRENT BLOCK.
BKTABS==BKTABL*BKWPB
VBLK
BLCODE [
BKTAB: BLOCK 3 ;ENTRY FOR .INIT BLOCK.
PRGNM: BLOCK BKTABS-BKWPB ;PROGRAM NAME IS NAME OF MAIN BLOCK.
]
BKTABP: 0 ;IDX IN BKTAB OF 1ST UNUSED ENTRY.
BKPDL: BLOCK BKPDLS ;TABLE OF BLOCKS STARTED, NOT FINISHED.
BKLVL: 0 ;CURRENT BLOCK LEVEL, IDX OF LAST USED IN BKPDL.
BKCUR: 0 ;BKTAB IDX OF CURRENT BLOCK.
ESBK: 0 ;-1 OR BLOCK TO EVAL SYM. IN.
ESL1: 0 ;IN ES, LEVEL OF BLOCK OF BEST SYM SO FAR.
ESL2: 0 ;3RDWRD OF BEST SO FAR.
SADR: 0 ;SYM TAB IDX OF BEST SO FAR.
ESLAST: 0 ;RH IDX OF LAST DEF (EVEN IF NO GOOD) -1 IF NONE
;SIGN NEG. IF LAST DEF SEEN BEFORE @ESXPUN
ESXPUN: -1 ;IF SEE EXPUNGED OR FREE ENTRY, PUT IDX HERE.
BKTAB1: BLOCK BKTABL ;USED BY SSYMD.
PBLK
;.SYMTAB ARG ;SAY WANT AT LEAST ARG STE'S IN SYMTAB.
A.SYMTAB: NOVAL
PUSH P,[0] ;THIS WORD WILL BE SETOM'ED IF THERE IS REALLY ANY WORK NEEDED.
PUSHJ P,AGETFD ;GET DESIRED SYM TAB SIZE.
CAMG A,SYMLEN ;IF HAVE ENOGH ROOM ALREADY,
JRST A.SYM1 ;NO NEED TO RE-INIT.
CAILE A,SYMMAX ;IF WANTS MORE THAN MAXIMUM, ERROR.
ETF [ASCIZ/.SYMTAB 1st arg too big/]
MOVEM A,SYMLEN ;TELL INITS ABOUT NEW SIZE.
SETOM (P)
A.SYM1: CALL AGETFD ;READ DESIRED CONSTANTS TABLE SPACE ALLOCATION.
CAMG A,CONLEN ;IF TABLE ALREADY BUG ENOUGH, NOTHING TO DO.
JRST A.SYM2
CAILE A,CONMAX
ETF [ASCIZ/.SYMTAB 2nd arg too big/]
MOVEM A,CONLEN ;ELSE REMEMBER IT AND SAY REALLOCATION NECESSARY.
SETOM (P)
A.SYM2: CALL AGETFD ;3RD ARG IS # WORDS PER SYMBOL - BUT ONLY 3 IS ALLOWED NOW.
JUMPE A,A.SYM3 ;EVENTUALLY 4 WILL GET 12-CHARACTER SYMBOLS.
CAIL A,MINWPS
CAILE A,MAXWPS
ETF [ASCIZ/.SYMTAB 3rd arg out of range/]
CAME A,WPSTE
SETOM (P)
MOVEM A,WPSTE
A.SYM3: REST A ;IS THERE ANYTHING THAT ACTUALLY NEEDS TO BE CHANGED?
JUMPE A,ASSEM1 ;IF NOT, NEVER GIVE ERROR - ELSE WOULD ALWAYS LOSE ON PASS 2.
MOVE B,PLIM
CAMN B,CONTBA ;IF THERE HAVE BEEN ANY LITERALS
SKIPE INICLB ;OR ANY MACROS, IRPS, REPEATS, ETC., THEN ...
ETF [ASCIZ/Too late to do .SYMTAB/]
MOVE CH1,MACTAD ;SET UP AC -> START OF INIT CODE
SUBI CH1,MACTBA ;SO IT CAN REFER TO ITSELF.
PUSHJ P,INITS(CH1) ;RE-INIT, SET SYMSIZ, SYMAOB, ETC.
PUSHJ P,MACINI ;INIT PTRS TO END OF MACTAB.
JRST ASSEM1
A.OP: PUSHJ P,A.OP1 ;.OP,
JRST VALRET ;RETURNS VALUE
A.AOP: NOVAL
AOS (P) ;.AOP DOESN'T RETURN VALUE
A.OP1: PUSHJ P,AGETFD
PUSH P,A
PUSHJ P,AGETFD
PUSH P,A ;PDL NOW HAS FIELD 0 AND FIELD 1
PUSHJ P,AGETFD
POP P,B ;B NOW HAS FIELD 1, A HAS FIELD 2, PDL HAS FIELD 0
EXCH A,B
POP P,T ;T HAS FIELD 0, A HAS FIELD 1, B HAS FIELD 2
TLNN T,(0 17,) ;IF AC FIELD NOT PRESENT IN INSN, SUPPLY ONE.
TLO T,(0 A,)
TDNN T,[0 -1(17)] ;IF NO ADDR OR IDX FIELD IN INSTRUCTION,
HRRI T,B ;SUPPLY ONE.
SETOM A.ASKIP' ;.ASKIP WILL BE -1 IFF INSN SKIPPED, ELSE 0.
TLNE T,74000 ;AVOID EXECUTING OPCODE ZERO.
XCT T
SETZM A.ASKIP
MOVEM A,AVAL1' ;STORE C(AC) AS .AVAL1
MOVEM B,AVAL2' ;STORE C(E) FOR .AVAL2
POPJ P, ;RETURN TO WHATEVER
AASCIZ: TDZA T,T
A.ASCII: MOVEI T,1
MOVEM T,AASCF1 ;STORE TYPE
MOVE D,[440700,,T]
SETZM AASCFT
JRST AASC1
AASCII: SKIPA D,[440700,,T]
ASIXBI: MOVE D,[440600,,T]
SETZM AASCFT ;INDICATE NOT .DECTXT
SETOM AASCF1 ;INDICATE REGULAR (NOT ASCIZ)
JRST AASC1
A.DCTX: NOVAL
MOVE A,CONTRL
TRNN A,DECREL
ETA [ASCIZ /.DECTXT in non-DECREL assembly/]
CALL EBLK
SETZ B,
SETOM AASCFT
SETOM AASCF1 ;INDICATE ASCIZ-STYLE PADDING
MOVE D,[440700,,T]
AASC1: TLZE I,ILMWRD
JRST TEXT2 ;MULTIPLE WORD, FALL IN FOR NEXT SET OF CHARS
MOVEMM ASMDS1,ASMDSP
MOVEM SYM,DEFNPS ;REMEMBER LOCATION IN FILE OF PSEUDO
MOVEMM DEFNLN,CLNN ;IN CASE THE DELIMITER IS MISSING.
MOVEMM DEFNPN,CPGN
IFN TS, MOVEMM DEFNFI,INFFN1
HLRZ T,B ;GET FILL CHARACTER
IMUL T,[REPEAT 5,[1_<.RPCNT*7>+]0] ;CONVERT TO ASCII FILL WORD SHIFTED -1 (IMUL SCREW)
LSH T,1 ;SHIFT TO PROPER POSITION (EXTRA IN CASE WANT TO FILL W/ HIGH BIT SET)
MOVEM T,AASEFW ;STORE AS FILL WORD, T NOW SET UP TO ACCUMULATE VALUE
CALL PASSPS
MOVEM A,TEXT4 ;STORE TERMINATOR
TEXT7: PUSHJ P,RCH
AASC8: CAMN A,TEXT4
JRST AASC1A ;TERMINATOR
TLNN D,760000
JRST TEXT6 ;WORD FULL
TEXT9: TLNE D,100 ;CHECK BOTTOM BIT OF SIZE FIELD OF BP
JRST AASC2 ;SET => NOT SIXBIT
SUBI A,40
CAILE A,77
SUBI A,40 ;CONVERT LOWER CASE ASCII TO UPPER CASE
JUMPGE A,.+2
ETR ERRN6B
AASC3: IDPB A,D
TRO I,IRSYL
JRST TEXT7
ERRN6B: ASCIZ /Character not SIXBIT/
;TERMINATOR
AASC1A: TLNN D,760000 ;SKIP UNLESS END OF WORD
SKIPGE AASCF1 ;SKIP UNLESS REGULAR
JRST [ MOVE CH1,ASMDS1 ;REGULAR OR NOT END OF WORD
MOVEM CH1,ASMDSP ;RESTORE ASMDSP AS SAVED AT START OF PSEUDO.
JRST TEXTX]
MOVEI CH1,1 ;END OF WORD AND NOT REGULAR
JRST AASC1B ;EXTRA 0 NEED FOR Z FLAVOR
AASC2: CAIN A,"!
SKIPG AASCF1
JRST AASC3 ;NOT .ASCII OR NOT EXCL
PUSH P,T ;READ FIELD
PUSH P,TEXT4
PUSH P,D
PUSH P,SYM
PUSH P,ASMOUT ;PREVENT CLOSEBRACKETS FROM TRYING TO TAKE EFFECT.
MOVEIM ASMOUT,4 ;NOTE THIS LOSES IF CALL PSEUDO THAT RETURNS TO ASSEM1.
MOVEI SYM,[SETOM ASUDS1] ;NOW TO SET UP UNDEFINED SYM CONDITION
TLNE FF,FLPPSS
MOVE SYM,[SQUOZE 0,.ASCII] ;PUNCHING PASS, UNDEFINED => REAL ERROR
CLEARM ASUDS1
PUSHJ P,AGETFD
;"UNDEFINED IN .ASCII" ERROR INSTR, ERROR MESSAGE BUT ONLY ON PASS 2
;BUT NOTE THAT ON PASS 2 IT MIGHT ASSEMBLE DIFFERENT NUMBER OF WORDS,
;CAUSING LOSSAGE IF NOT IN CONSTANT
REST ASMOUT
POP P,SYM
POP P,D
POP P,TEXT4
POP P,T
SKIPGE ASUDS1
MOVNI A,1 ;HAD UNDEFINED SYMS SO ASSUME MAX
SKIPGE ASUDS1
TLO I,ILNOPT ;ALSO DON'T OPTIMIZE OVER IN CONSTANT
MOVE CH1,[440700,,AASBF]
MOVEM CH1,ASBP1
MOVEM CH1,ASBP2
PUSH P,[AASC5]
MOVE CH1,A
AASC6: LSHC CH1,-35.
LSH CH2,-1
DIV CH1,ARADIX
HRLM CH2,(P)
JUMPE CH1,.+2
PUSHJ P,AASC6
HLRZ A,(P)
ADDI A,"0
IDPB A,ASBP1
POPJ P,
AASC5: MOVEI A,0
IDPB A,ASBP1 ;END .ASCII NUMBER WITH ZERO
AASC8A: TLNN D,760000
JRST AASC7 ;END OF WORD
ILDB A,ASBP2
JUMPE A,AASC9
IDPB A,D
JRST AASC8A
AASC9: TLO FF,FLUNRD
JRST TEXT7
AASC7: TDZA CH1,CH1
TEXT6: MOVNI CH1,1 ;WORD FULL
AASC1B: MOVEM CH1,AASCF2
CLEARM CDISP
MOVEM A,TEXT8
MOVE A,T
SKIPE AASCFT ;FOR .DECTXT, OUTPUT WORD INSTEAD OF RETURNING IT.
JRST [ CALL PPB
MOVE D,[440700,,T]
JRST TEXT2A]
TLO I,ILMWRD ;ELSE ARRANGE TO BE CALLED BACK TO RETURN NEXT WORD.
MOVEI T,ASSEM2
MOVEM T,ASMDSP
SKIPLE CONSML ;IF NOT MULTI-LINE MODE,
JRST CLBPOP
MOVE T,ASMOUT ;IF THE TEXT IS IN <>'S OR ()'S,
HRRZ T,ASMOT2(T)
CAIE T,LSSTHA
JRST CLBPOP
CALL IGTXT ;USE ONLY THE FIRST WORD.
SKIPE CONSML ;AND ERROR IF IN ERROR MODE.
ETR [ASCIZ/Multi-word text pseudo in brackets/]
JRST CLBPOP
;GET NEXT WORD
TEXT2: TRO I,IRFLD
TEXT2A: MOVE T,AASEFW ;INITIALIZE T TO FILL WORD
MOVE A,TEXT8 ;GET NEXT CHAR (ALREADY READ BY RCH)
SKIPGE B,AASCF2
JRST TEXT9 ;REG OR HAVEN'T READ SECOND DELIMITER, FALL BACK IN
JUMPE B,AASC8A
TEXTX: SETZM DEFNPS
SETOM TEXT4
SKIPN AASCFT
JRST TEXT5 ;RETURNING FROM ASCIZ AFTER PUTTING THE TRAILING ZERO OUT.
MOVE A,T
CALL PPB ;FOR .DECTXT, OUTPUT THE FILL WORD INSTEAD.
JRST MACCR
VBLK
AASCF1: 0 ;-1 REG OR SIXBIT, 1 .ASCI 0 ASCIZ
AASCF2: 0 ;MULTIPLE WORD RETURN FLAG -1 REG 0 FINISH ! HACK 1 OUTPUT FILL WORD FOR Z
AASCFT: 0 ;0 REGULAR, -1 => .DECTXT (OUTPUT WORDS TO FILE INSTEAD OF RETURNING THEM)
TEXT4: -1 ;DELIMITER, OR -1 IF NOT INSIDE A TEXT PSEUDO.
TEXT8: 0 ;SAVED NEXT CHAR WHILE RETURNING BETWEEN WORDS
ASBP1: 0 ;IDPB TO AASBF ON .ASCII FIELD
ASBP2: 0 ;ILDB FROM AASBF "
AASBF: BLOCK 8 ;ACCUMULATED TYPEOUT OF NUMBER FOR .ASCII, EXTRA LONG FOR HACKERS TYPING OUT BINARY
ASUDS1: 0 ;UNDEFINED SYM FLAG FOR .ASCII DURING PASS 1
AASEFW: 0 ;FILL WORD
PBLK
IGTXT: TLNN I,ILMWRD
RET
PUSH P,A ;ROUTINE TO EAT UP TEXT OF UNDESIRED MULTIPLE WORD
SKIPLE AASCF2 ;DETECT SCREW CASE: AFTER ASCIZ OF 5 CHARS, DELIMITER IS
JRST IGTXT1 ;ALREADY GOBBLED, BUT SOME OF THE ASCIZ REMAINS.
PUSHJ P,RCH
CAME A,TEXT4
JRST .-2
IGTXT1: TLZ I,ILMWRD
MOVEMM ASMDSP,ASMDS1
SETZM DEFNPS
SETOM TEXT4
JRST POPAJ
;".ASCVL /X" RETURNS THE ASCII VALUE OF "X". NOTE THE DELIMITER IS NOT REPEATED
;AND SERVES ONLY TO ALLOW SPACES TO BE IGNORED WHILE WINNING IF X IS A SPACE.
A.ASCV: CALL PASSPS ;SKIP SPACES TO REACH THE DELIMITER.
CALL RCH ;READ THE CHAR AFTER THE DELIMITER
MOVE T,A
JRST TEXT5 ;AND RETURN ITS ASCII VALUE.
ASQOZ: HLLM B,(P) ;SAVE FLAG THAT'S 0 FOR SQUOZE, -1 FOR .RSQZ .
PUSH P,SYM
PUSHJ P,AGETFD
LSH A,36
PUSH P,A
PUSHJ P,GETSLD ;GET SYM, SAVE DELIMITER FOR REINPUT
CALL NONAME
REST A
LDB B,[4000,,SYM] ;GET JUST THE SQUOZE.
SKIPGE -1(P)
PUSHJ P,ASQOZR ;FOR .RSQZ, RIGHT-JUSTIFY IT.
SUB P,[1,,1]
ADD A,B
JRST CLBPOP
;RIGHT-JUSTIFY THE SQUOZE WORD IN B.
ASQOZR: MOVE SYM,B
IDIVI SYM,50
JUMPN LINK,CPOPJ ;LAST ISN'T BLANK, DONE.
MOVE B,SYM ;ELSE REPLACE BY WHAT'S SHIFTED RIGHT 1 CHAR.
JRST ASQOZR
;COMMON PSEUDO ROUTINE TO RETURN MIDAS INTERNAL QUANTITY
;ADR IN LH(B)) AS VALUE (EG. .RPCNT, .FNAM1, .AVAL2, ETC.
;INTSYMS MAY APPEAR TO LEFT OF =
INTSYM: MOVE A,B ;GET ADR IN LH(A)
JRA A,CLBPOP ;RETURN IT
;.YSTGW, .NSTGW ACCORDING TO WHAT'S IN LH(B)
STGWS: HLRES B ;.NSTGW INCREMENTS STGSW, .YSTGW DECREMENTS.
ADDB B,STGSW
SKIPGE B ;BUT DON'T DECREMENT PAST 0.
SETZM STGSW
JRST MACCR ;STORAGE WORDS ARE ALLOWED IF STGSW IS ZERO.
;.TYPE
A.TYPE: PUSH P,SYM
PUSH P,SYM
PUSHJ P,GETSLD ;GET NAME
CALL NONAME
SUB P,[2,,2]
TRNN I,IRLET ;IF SYLLABLE IS A NUMBER,
JRST [ SETO A, ;RETURN -1.
JRST CLBPOP]
PUSHJ P,ES ;EVALUATE SYM, INTERESTED IN SQUOZE FLAGS RETURNED IN A
MOVEI A,17 ;DIDN'T SKIP, RETURN 17 => UNSEEN
IFN CREFSW,XCT CRFINU
JRST CLBPOP
NONAME: MOVE SYM,-2(P)
ETSM [ASCIZ /No arg/]
SETZ SYM,
POPJ P,
;.FORMAT
A.FORMAT: PUSHJ P,AGETFD ;GET FIRST FIELD (FORMAT #)
MOVE B,CDISP ;WORD TERMINATOR ENDED 1ST ARG =>
TLNN B,DWRD
JRST A.FOR1 ;RETURN CURRENT SPEC FOR THAT FORMAT.
PUSH P,A
PUSHJ P,AGETFD ;GET SECOND FIELD (TABLE ENTRY FOR FORMAT NUMBER)
POP P,B
MOVEM A,FORTAB-10(B)
JRST ASSEM1
A.FOR1: MOVE A,FORTAB-10(A)
JRST CLBPOP
A.BYTE: NOVAL
CLEARM NBYTS ;# BYTES ASSEMBLED
CLEARM BYTMT ;TOTAL ACTIVE BYTES IN TABLE
MOVE A,[440700,,BYBYT] ;POINTER TO NEW TABLE
MOVEM A,BYTMP
A.BY1: PUSHJ P,AGETFD ;GET FIELD, .GE. 0 => BYTE, .LT. 0 => HOLE
MOVE C,ISAV
TRNN C,IRFLD
JRST A.BY2 ;NO FIELD
MOVM B,A
SKIPGE A
TRO B,100
IDPB B,BYTMP
AOS BYTMT
A.BY2: TLNE CH1,DWRD ;CDISP LEFT IN CH1 BY AGETFD
JRST A.BY1 ;NOT WORD TERMINATOR
SKIPN BYTMT ;WORD TERMINATOR, ANY FIELDS?
JRST A.BY3 ;NO, DO .WALGN AND RESET TO WORD MODE
SETOM BYTM ;ENTERING BYTE MODE
MOVE A,[-LPDL,,PDL]
CAMN A,ASSEMP
SETOM BYTM1
PUSHJ P,BYSET
MOVE A,GLSPAS
MOVEM A,GLSP1
JRST ASSEM1
;RESET THE BYTE DESCRIPTOR TABLE POINTERS TO POINT TO NEW WORD
BYSET: CLEARM BYTMC ;COUNT OF BYTES PROCESSED THIS TABLE SCAN
MOVE A,[440700,,BYBYT] ;POINTER TO DESCRIPTOR TABLE
MOVEM A,BYTMP
ILDB A,BYTMP ;FIRST DESCRIPTOR BYTE
AOS BYTMC
DPB A,[300600,,BYTWP] ;DEPOSIT AS FIRST BYTE SIZE
POPJ P,
A.BY3: CLEARM BYTM ;NO LONGER IN BYTE MODE
MOVE A,[-LPDL,,PDL]
CAMN A,ASSEMP
SETZM BYTM1
JRST A.WAL1
A.WALGN: NOVAL
A.WAL1: LDB A,[360600,,BYTWP]
CAIN A,44
JRST ASSEM1 ;ALREADY AT BEGINNING OF WORD
MOVEI A,44
DPB A,[360600,,BYTWP] ;MAKE IT POINT TO BEGINNING OF WORD
PUSHJ P,BYSET
CLEARM T1
JRST PBY1
BYTIN1: CLEARM BYTMC
MOVE A,[440700,,BYBYT]
MOVEM A,BYTMP
BYTINC: AOS A,BYTMC
CAMLE A,BYTMT
JRST BYTIN1
ILDB A,BYTMP
DPB A,[300600,,BYTWP]
MOVEM A,T1
HLLZ A,BYTWP
IBP A
TRNN A,-1
JRST BYTINR
;NEXT BYTE GOES IN NEXT WORD
PBY1: MOVE P,ASSEMP ;PCONS NEEDS THIS.
MOVEI A,WRD-1
PUSH A,BYTW ;INTO WRD,
PUSH A,BYTRLC ;INTO WRDRLC
CLEARM BYTW
SETZM BYTRLC
MOVEI A,44
DPB A,[360600,,BYTWP]
MOVE AA,ASMOUT
JRST @ASMOT4(AA) ;TO PBY4 OR PBY5 OR PBY3
PBY4: SKIPE STGSW
ETR ERRSWD
PUSHJ P,PWRD ;NOT IN CONST., OUTPUT WORD.
AOSA CLOC
PBY3: JSP T,PCONS ;OUTPUT INTO CONST.
MOVE A,GLSPAS ; 459 - PBY5 used to be here. Bad idea since jump to
MOVEM A,GLSP1 ; PBY5 means word is still being accumulated!
PBY5:
BYTINR: MOVE A,T1 ;CURRENT BYTE SIZE
TRNN A,100
JRST @ASMDSP
SETZB A,B ;ASSEMBLE HOLE (BLANK BYTE) IMMEDIATELY AFTER PREVIOUS BYTE
JRST PBY2
PBYTE: AOS NBYTS
PBY2: MOVEI AA,WRD-1
PUSH AA,BYTW ;INTO WRD
PUSH AA,BYTRLC ;INTO WRDRLC
IBP BYTWP
LDB T,[301400,,BYTWP]
PUSHJ P,INTFLD
POP AA,BYTRLC ;WRDRLC
POP AA,BYTW ;WRD
JRST BYTINC
;VARIABLES FOR .BYTE, .BYTC, .WALGN
VBLK
BYTM: 0 ;-1 FOR IN BYTE MODE, LAMBDA BOUND BY <'S, ('S, AND ['S ;]
BYTMC: 0 ;COUNT CORRESP WITH BYTMP
BYTMP: 0 ;POINTER TO BYTE DESC TABLE
BYTMT: 0 ;TOTAL ACTIVE BYTES IN TABLE
BYTM1: 0 ;GLOBAL VALUE OF BYTM - WHAT IT WAS OUTSIDE THE OUTERMOST BRACKET
;FORMAT OF BYTE DESC TABLE
;SEVEN BIT BYTES
;1.7=0 ASSEMBLE =1 BLANK
;1.1 - 1.6 NUMBER OF BITS
IFNDEF LBYBYT,LBYBYT==5 ;LENGTH OF BYBYT
BLCODE [BYBYT: BLOCK LBYBYT] ;BYTE DESC TABLE, 7 BITS PER DESC
BYTWP: 440000,,BYTW ;POINTER TO BYTW IDPB TO DEPOSIT CURRENT BYTE
BYTW: 0 ;WORD BEING ASSEMBLED IN BYTE MODE
BYTRLC: 0 ;RELOC OF BYTW.
NBYTS: 0 ;NUMBER BYTES ASSEMBLED (FOR .BYTC)
BYTMCL==.-BYTMC
PBLK
;;MACRO PROCESSOR
IFN MACSW,[
;GET IN B THE CHAR WHOSE ADR IS IN A, INCREMENT A
REDINC: MOVE CH1,A
IDIVI CH1,4
LDB B,PTAB(CH2)
AOJA A,CPOPJ
VBLK ;THIS STUFF ALL RELOCATED WHEN MACTAB ADDR CHANGED.
PTAB: (341000+CH1)MACTBA ;BYTE TABLE
(241000+CH1)MACTBA
(141000+CH1)MACTBA
(41000+CH1)MACTBA
(341000+CH1)MACTBA+1
;IN FOLLOWING MACROS, B = -1, 0, OR +1 (+ SIGN MUST BE GIVEN)
;0 => BP SAME AS CHAR ADR, -1 => BP FOR ILDB, 1 => BP ONE AHEAD
;CHAR ADR IN A, RETURNS BP IN A, CLOBBERS A+1
DEFINE BCOMP A,B/
IDIVI <A>,4
ADD <A>,(<A>+1)BCOMPT!B
TERMIN
STOPPT: 041000,,MACTBA-1
BCOMPT: 341000,,MACTBA
241000,,MACTBA
BCOMPU: 141000,,MACTBA
041000,,MACTBA
341000,,MACTBA+1
;BP IN A RETURN CHAR ADR IN A, CLOBBERS A-1 (YES, A MINUS 1)
;2ND ARG IS SUBTRACTED - -1 GIVES ADDR OF THE NEXT CHAR.
DEFINE CCOMP A,B/
MOVEI <A>-1,0
ASHC <A>-1,2
SUB <A>,(<A>-1)CCOMPT!B
TERMIN
;BP IN A RETURN CHAR ADR IN A+1, CLOBBERS A
DEFINE CCOMP1 A,B/
MULI <A>,4
SUB <A>+1,(A)CCOMPT!B
TERMIN
;FROM HERE THRU CCOMPE SET BY MACINI.
CCOMPB: 0 ;4*<41000,,MACTBA>-4
CCOMPT: REPEAT 5,0 ;4*<41000,,MACTBA>+.RPCNT-3
CCOMPE::PBLK
;BP IN A, DECREMENT IT
DEFINE DBPM A
ADD A,[100000,,]
SKIPGE A
SUB A,[400000,,1]
TERMIN
;SET UP CPTR FROM CHAR ADR IN A
ACPTRS: MOVEI CH1,(A) ;GET CHAR ADR IN CH1
BCOMP CH1,-1 ;CONVERT TO BYTE POINTER
MOVEM CH1,CPTR ;STORE COMPUTED CPTR
POPJ P,
AFCOMP: HRRZM A,FREEPT ;ENTRY TO STORE C(A) INTO FREEPT
FCOMP: MOVE CH1,FREEPT ;COMPUTE FREPTB FROM FREEPT
BCOMP CH1,-1
MOVEM CH1,FREPTB ;STORE CALCULATED BYTE POINTER
POPJ P,
STPWR: MOVEI A,375
JRST PUTREL
VBLK
PUT377: MOVEI A,377
PUTREL: JRST PUTRE1 ;IDPB A,FREPTB;STORE CHAR INTO FREE CHARACTER STORAGE
AOS A,FREEPT ;CLOBBERS ONLY A.
AOS PUTCNT
CAMGE A,MACHI
POPJ P,
JRST GCA
PBLK
PUTRE1: PUSH P,[IDPB A,FREPTB]
POP P,PUTREL ;COME HERE ONLY ON 1ST CALL TO PUTREL.
SETOM INICLB ;HAVE WRITTEN IN MACRO TAB & CLOBBERED INIT.
JRST PUTREL ;NOW GO BACK AND REALLY WRITE CHAR.
;200 BIT SET ON CHAR READ FROM MACTAB, PROCESS SPECIAL CONDITION
;CLOBBERS A,CH1,CH2.
MACTRM: CAIN A,176 ;376?
JRST RCHTRA ;376 => IGNORE, CHARACTER USED TO CLOBBER UNDESIRED CHARACTERS IN MACRO STORAGE
PUSH P,B ;SAVE B
CAIE A,177
CAIN A,175
JRST MRCH1 ;377, 375 => STOP
ADD A,BBASE ;DUMMY, RELOCATE TO POINT TO DUMMY TABLE
MOVEI B,RCHSAV ;RETURN TO RCHSAV ON END OF DUMMY
PUSHJ P,PUSHEM ;SAVE CURRENT STATUS
HRRZ A,(A) ;GET CHAR ADR OF DUMMY
BCOMP A,-1 ;CONVERT TO BYTE POINTER
MOVEM A,CPTR ;STORE AS NEW CPTR
MOVE A,TOPP
MOVEM A,BBASE
RCHTRB: POP P,B
RCHTRA: POP P,A ;POP RETURN
TLZN FF,FLUNRD ;IF NO CHAR TO RE-READ, JUST RETURN BACK TO THE ILDB A,UREDP.
JRST -3(A)
ANDI A,-1 ;IF A CHAR TO RE-READ, IF CALLED FROM RREOF, WE CAN RETURN TO RRU
CAIN A,RREOF+1
JRST RRU
PUSH P,A ;OTHERWISE, CALL RCH TO RE-READ THAT CHAR, AND RETURN IT FROM
JRST RCH1 ;THE CURRENT ATTEMPT TO READ A CHAR.
MRCH1: MOVE B,MACP
BPOPJ: POPJ B, ;RETURN AT END OF STRING EXPANSION
;RCHSET ROUTINE TO CAUSE INPUT FROM MACRO PROCESSOR
RCHMAC: TLO FF,FLMAC ;SET FLAG
JSP A,CPOPJ
RCHMC0: REPEAT 2,[ ;GETCHR, RR1
ILDB A,CPTR ;GET CHAR
TRZE A,200 ;200 BIT...
PUSHJ P,MACTRM ;=> SPECIAL, PROCESS
]
GOHALT
IFN .-RCHPSN-RCHMC0,.ERR RCHMC0 LOSES.
ILDB A,CPTR ;SEMIC
TRZE A,200
PUSHJ P,MACTRM
CAIE A,15
JRST SEMIC ;NOT YET
JRST SEMICR ;YET
;PUSH INPUT STATUS IN FAVOR OF MACRO
;B HAS RETURN ADR FOR END OF MACRO (OR WHATEVER)
;SEE ALSO PMACP
PUSHEM: PUSH P,A
PUSH P,F
MOVE F,MACP ;GET MACRO PDL POINTER
MOVE CH1,CPTR
CCOMP1 CH1,-1 ;CONVERT TO CHARACTER ADDRESS
HRL CH2,BBASE
PUSH F,CH2 ;PUSH BBASE,,CPTR
MOVEI A,1 ;=> EXPAND MACRO
PUSHJ P,PSHLMB ;SAVE LIMBO1 STATUS AND RETURN
JRST PSHM1
;UNDO A PUSHEM
;RETURNS BBASE,,CPTR IN B (CPTR RE-INITIALIZED, BBASE NOT)
POPEM: PUSH P,A
PUSH P,F
MOVE F,MACP
PUSHJ P,POPLMB ;RESTORE LIMBO1 STATUS
POP F,B ;BBASE,,CPTR
MOVEI CH1,(B) ;GET CHAR ADR IN CH1
BCOMP CH1,-1 ;CONVERT TO BYTE POINTER
MOVEM CH1,CPTR ;STORE NEW CPTR
PSHM1: MOVEM F,MACP ;STORE BACK MACRO PDL POINTER
POPFAJ: POP P,F
POPAJ: POP P,A
POPJ P,
PMACP: MOVE B,MACP ;POP MACRO PDL
HRRZ A,(B)
SUB B,[1,,1]
IFN RCHASW,CAIE A,A.TYM8
CAIN A,AIRR
JRST A.GO6 ;IRP OR .TTYMAC
CAIN A,REPT1
JRST A.GO4 ;REPEAT
CAIE A,RCHSV1 ;MACRO
CAIN A,RCHSAV ;ARG
JRST A.GO6
GOHALT ;DON'T HAVE RETURN,
JRST A.GO6 ;BUT TRY A.GO6 LIKE EVERYTHING BUT REPEAT
A.GO4: HLLZS -1(B) ;REPEAT, CLEAR OUT COUNT REMAINING
A.GO6: TRO FF,FRMRGO ;EVERYTHING ELSE, SET FLAG TO QUIT
JRST (A)
;4.9(B) => .STOP ELSE .ISTOP
A.STOP: HRRZ A,MACP
JUMPL B,A.STP1
HRRZ B,(A) ;.ISTOP
CAIN B,REPT1
HLLZS -2(A) ;REPEAT, STOP ALL INTERATIONS
CAIN B,AIRR
HRRZS -1(A) ;IRP TYPE, CLEAR OUT # GROUPS, DON'T ALLOW RECYCLE
A.STP1: MOVE A,STOPPT
MOVEM A,CPTR ;CAUSE STOP
JRST POPJ1
A.QOTE: JFCL
ATERMI: ETSM [ASCIZ/Not in macro/]
JRST MACCR ;MAYBE FLUSH MESSAGE IF PEOPLE HAVE PROBLEMS
;PDL STRUCTURE FOR REPEAT
;TWO TWO WORD ENTRIES
;BBASE,,CPTR
;LIMBO1 STATUS,,# TIMES LEFT
;OLD .RPCNT,,BEG OF BODY
;GARBAGE,,REPT1
AREPEAT: PUSHJ P,AGETFD
JUMPLE A,COND5 ;NO REPEAT PLAY LIKE STRING COND FALSE
PUSH P,A
MOVE A,FREEPT
MOVEM A,PRREPT ;CHAR ADR BEGINNING OF REPEAT
MOVEI A,373 ;CHECK CHAR FOR REPEAT
PUSHJ P,PUTREL ;STORE AS FIRST CHR OF BODY
JSP D,RARL1
CAIA
CALL RARGCP ;READ THE ARG & COPY INTO MACRO STORAGE.
MOVEI A,^M ;IF THE ARG WASN'T BRACKETED,
TLNE FF,FLUNRD
CALL PUTREL ;INCLUDE THE TERMINATING CR.
SWRET1: PUSHJ P,STPWR ;ALSO RETURN FROM STRING WRITE (.F .I)
POP P,B ;# TIMES TO GO THROUGH
PUSHJ P,PUSHEM
MOVE B,MACP ;NOW GET MACRO PDL POINTER FOR PUSH OF SECOND ENTRY
MOVNI T,1
EXCH T,CRPTCT ;GET OLD .RPCNT, INITIALIZE NEW ONE TO -1
CREPT1: SETZI TT,REPT1
EXCH TT,PRREPT ;GET LOC BEGINNING OF BODY, CLEAR OUT PRREPT, DON'T NEED IT ANYMORE
HRL TT,T
PUSH B,TT ;SAVE OLD .RPCNT,,ADDRESS OF BODY.
PUSH B,CREPT1 ;PUSH CRUD,,REPT1 FOR RETURN
MOVEM B,MACP ;STORE BACK UPDATED MACRO POINTER
MOVE A,STOPPT
MOVEM A,CPTR ;CAUSE IMMEDIATE CYCLE
JRST MACCR
IFN .I.FSW,[ ;CODING FOR .I, .F
SWINI: MOVE A,FREEPT ;INITIALIZE, WILL EVENTUALLY PLAY LIKE REPEAT 1
MOVEM A,PRREPT
MOVEI A,373
JRST PUTREL
SWRET: PUSH P,[1] ;REPEAT COUNT
JRST SWRET1
SWFLS: MOVE A,PRREPT ;FLUSH RETURN
PUSHJ P,AFCOMP
JRST MACCR
]
;RECYCLE AROUND REPEAT
REPT1: PUSH P,A
PUSH P,C
HRRZ A,(B) ;CHAR ADR BEG BODY
PUSHJ P,REDINC
CAIE B,373
GOHALT ;FIRST CHAR OF REPEAT BODY NOT 373
HRRZ C,MACP
HRRZ B,-2(C) ;# TIMES LEFT
SOJL B,REPT2 ;JUMP IF LAST TIME THROUGH WAS LAST TIME TO GO THROUGH
AOS CRPTCT
PUSHJ P,ACPTRS ;SET UP CPTR (CHAR ADR IN A)
HRRM B,-2(C) ;STORE UPDATED COUNTDOWN
REPT3: POP P,C
POP P,A
JRST REPT6
REPT2: SOS A ;MOVE BACK TO BEG OF REPEAT
;(IN CASE GETS STORED INTO FREEPT)
MOVE CH2,CPTR
CCOMP CH2,-1 ;CONVERT TO CHARACTER ADDRESS
CAMN CH2,FREEPT
PUSHJ P,AFCOMP
MOVE A,[-3,,-2]
ADDB A,MACP
HLRZ A,1(A)
MOVEM A,CRPTCT
PUSHJ P,POPEM
JRST REPT3
;STRING CONDITIONALS (IFSE, IFSN)
SCOND: MOVE A,FREEPT
MOVEM A,PRSCND
MOVEM A,PRSCN1
PUSH P,SYM
HRRI B,SCONDF
PUSH P,B ;REMEMBER TEST INSTRUCTION.
SETOB C,SCONDF
JSP D,RARG ;COPY THE 1ST OF THE 2 STRINGS
CAIA
CALL RARGCP ;INTO MACRO STORAGE, FOLLOWED BY 375.
CALL STPWR
JSP D,RARG ;THEN START READING THE 2ND ARG,
JRST SCOND3 ;GO TO SCOND3 WHEN REACH END OF 2ND ARG.
JSP D,RARGCH(T) ;READ NEXT CHAR OF 2ND ARG,
JRST SCOND3
EXCH A,PRSCND
PUSHJ P,REDINC ;RE-FETCH NEXT CHAR OF 1ST ARG
EXCH A,PRSCND
CAMN B,A ;COMPARE CHARACTERS
JRST RARGCH(T) ;CHARS EQUAL, KEEP COMPARING.
CAIL A,"A+40
CAILE A,"Z+40 ;NOT EQUAL => CONVERT BOTH TO UPPER CASE.
CAIA
SUBI A,40
CAIL B,"A+40
CAILE B,"Z+40
CAIA
SUBI B,40
CAMN B,A ;ARE THEY SAME EXCEPT FOR CASE?
JRST RARGCH(T) ;CHARS EQUAL, KEEP COMPARING.
CLEARM SCONDF ;STRINGS DIFFER
CALL RARFLS ;IGNORE REMAINDER OF 2ND ARG.
SCOND3: CLEARB A,C ;END OF (SECOND) STRING ARG ENCOUNTERED
EXCH C,PRSCN1
MOVEM C,FREEPT
PUSHJ P,FCOMP
EXCH A,PRSCND
PUSHJ P,REDINC
CAIE B,375
CLEARM SCONDF
REST B
REST SYM
XCT B ;DO THE TEST.
JRST COND4
JRST COND2
VBLK
BLCODE [DMYDEF: BLOCK DMDEFL] ;TABLE OF DUMMY NAMES FOR THING BEING DEFINED
DMYTOP: DMYDEF ;POINTER INTO DMYDEF, POINTS TO AVAILABLE WORD
;SINCE ONLY ONE THING CAN BE DEFINED AT ONCE, IT IS NOT NECESSARY TO SAVE AND RESTORE DMYTOP
DMYBOT: DMYDEF ;-> 1ST DMYDEF WD USED AT THIS LEVEL.
;RIGHT NOW, ALWAYS -> DMYDEF SINCE CAN'T HAVE DEFINITION
;WITHIN A DEFINITION YET.
PBLK
PDEF: PUSHJ P,GSYL ;READ IN SYL
CAIE T,", ;IF DELIMITING CHR NOT ,
JUMPE SYM,CPOPJ ;AND SYM NULL, RETURN
PDEF1: MOVEM SYM,@DMYTOP ;STORE SYM
AOS D,DMYTOP ;INCR PNTR
CAIL D,DMYDEF+DMDEFL ;CHECK FOR TABLE SIZE EXCEEDED
ETF [ASCIZ/Too many dummies in DEFINE or IRP/]
POPJ P,
VBLK
BLCODE [DSTG: BLOCK DSSIZ] ;TABLE OF CHAR ADRS OF DUMMIES BEING DEFINED PRIOR TO MACRO EXPANSION
RDWRDP: DSTG ;POINTER TO DSTG, POINTS TO FREE WORD
;NOTE THAT RDWRDP MUST BE SAVED AND RESTORED SINCE MORE MACROS CAN
;BE EXPANDED DURING FIELD READ FOR DUMMY
PBLK
ADDTR1: CLEARM PUTCNT
ADDTRN: MOVE A,FREEPT
ADDTR2: MOVEM A,@RDWRDP
AOS A,RDWRDP
CAIL A,DSTG+DSSIZ
ETF [ASCIZ/Too many dummies in all macros & IRPs being expanded/]
RET
VBLK
BLCODE [DMYAGT: BLOCK DMYAGL] ;TABLE OF CHAR ADRS OF DUMMYS OF MACROS BEING EXPANDED
;DMYAGT TRACKS WITH THE MACRO PDL;
;DMYAGT CAN'T BE COMBINED WITH DSTG SINCE DMYAGT CAN BE SHIFTING AROUND RANDOMLY DURING ARG SCAN
BBASE: DMYAGT ;POINTER TO BEGINNING OF ACTIVE DUMMY LIST (FOR DEEPEST-NESTED MACRO BEING EXPANDED)
;ADD TO DUMMY # TO GET LOCATION CONTAINING CHAR ADR OF DUMMY
TOPP: DMYAGT ;POINTER TO TOP OF DMYAGT ACTIVE, POINTS TO FREE REGISTER
PBLK
;ACTIVATE DUMMYS ON TOP OF DSTG TABLE
;A -> FIRST (LOWEST) DUMMY IN DSTG TO ACTIVATE
DMYTRN: MOVE B,TOPP
MOVEM B,BBASE
PUSH P,A
DMYTR2: CAML A,RDWRDP
JRST DMYTR1
MOVE B,(A)
MOVEM B,@TOPP
AOS B,TOPP
CAIL B,DMYAGT+DMYAGL
ETF [ASCIZ /Too many dummy args active/]
AOJA A,DMYTR2
DMYTR1: POP P,RDWRDP
POPJ P,
;THE MACRO TABLE IS FILLED MAINLY WITH 8-BIT BYTES.
;THE FIRST WORD'S ADDR IS IN MACTAD; THE LAST+1'S IN MACTND.
;THE CHARACTER NUMBER OF THE LAST+1ST CHAR IS IN MACHI.
;MACHIB IS BP. TO HIGHEST BYTE OK TO FILL (LAST IN C(MACTND)-1)
;IF A BYTE IN THE TABLE HAS ITS HIGH BIT OFF, IT IS AN ASCII CHARACTER.
;OTHERWISE, IT IS SPECIAL. IF THE 100 BIT IS OFF IT MEANS
;SUBSTITUTE A MACRO DUMMY ARG WHEN READ; THE CHAR IS THE NUMBER OF THE ARG+200 .
;377 AND 375 ARE STOP CODES, CAUSING A POP OUT OF THE CURRENT STRING.
;GC CONSIDERS THE CHAR. AFTER A 375 TO START A NEW STRING.
;376 IS IGNORED WHEN READ; USED TO CLOBBER UNWANTED CHARACTERS IN STRINHGS.
;374 STARTS EVERY MACRO-DEFINITION.
;373 STARTS THE BODY OF A REPEAT.
;370 STARTS A WORD STRING:
;THE WORD AFTER THAT WHICH CONTAINS THE 370
; HAS THE LENGTH IN WORDS OF THE STRING IN ITS LH,
; IN ITS RH, THE ADDRESS OF WD WHICH POINTS BACK TO THIS ONE.
; THEN FOLLOW RANDOM WDS HOLDING ANYTHING AT ALL.
; GC WILL MAKE SURE IT STAYS ON WD BOUNDARY.
; THE LENGTH INCLUDES THE WD HOLDING THE LENGTH.
; IF THE RH OF 1ST WD HAS 0, GC WILL FLUSH THE STRING
STRTYP: PUSHJ P,REDINC ;DEBUGGING AID ONLY
EXCH A,B
TRZE A,200
JRST STRTP1
STRTP2: PUSHJ P,TYO ;NORMAL CHAR, JUST TYPE OUT
MOVE A,B
JRST STRTYP
STRTP1: PUSH P,A
MOVEI A,"* ;SPECIAL CHAR, TYPE *
PUSHJ P,TYO
POP P,A
TRNE A,100
JRST STRTP3 ;CONTROL CHAR
ADDI A,260 ;DUMMY, CONVERT TO #
JRST STRTP2 ;TYPE OUT (SINGLE DIGIT) NUMBER
STRTP3: CAIN A,175
SKIPA A,C% ;STOP, TYPE %
MOVEI A,"/ ;SOMETHING ELSE, TYPE /
JRST STRTP2
;.GSSET, SET GENERATED SYM COUNTER
A.GSSET: CALL AGETFD
MOVEM A,GENSM
JRST ASSEM1
;GSYL-LIKE ROUTINE, READ A SYL FOR WRQOTE
WRQRR: PUSHJ P,RCH ;GET CHAR (MAYBE WANT THIS TO BE FASTER YET)
IDPB A,FREPTB ;DEPOSIT IN MACRO TABLE
CAMN F,FREPTB ;WAS THIS LAST CHAR IN TABLE?
JRST WRQRGC ;YES, NEED GARBAGE COLLECTION
WRQRR2: XCT GDTAB(A) ;DISPATCH ON CHAR
JFCL ;(MAYBE SKIPS)
SOJGE D,WRQRR ;LOOP FOR FIRST SEVEN CHARS
HRRI D,0
JRST WRQRR
;HERE FROM WRQRR WHEN NEED GARBAGE COLLECTION OF MACRO TABLE
WRQRGC: MOVEM C,WRQTBP ;PUT POINTER TO BEGINNING OF SYL WHERE IT WILL BE GC'D
MOVE A,MACHI
PUSHJ P,GCA ;GARBAGE COLLECT
MOVE F,MACHIB ;RESET F TO POINT TO NEW LAST CHAR IN MACTAB
MOVEI C,0
EXCH C,WRQTBP ;GET BACK POINTER TO CHAR BEFORE SYL
MOVE A,LIMBO1 ;RETRIEVE LAST CHAR READ
JRST WRQRR2 ;LOOP BACK, PROCESS CHAR
;HERE FROM WRQOTE IF .QUOTE SEEN
;.QUOTE TAKES ARG LIKE ASCII, PRINTC, ETC.
A.QOT1: MOVE A,WRQBEG(P) ;GET BACK BP TO CHAR BEFORE .QUOTE
PUSHJ P,A.QOTS ;SET UP FREEPT AND FREPTB PROPERLY
MOVE A,LIMBO1 ;NOW GET CHAR AFTER .QUOTE
CAIE A,^I
CAIN A,40 ;COMPARE WITH SPACE
PUSHJ P,RCH ;SPACE, GOBBLE NEXT CHAR FOR DELIMITER, ELSE THIS ONE
MOVEM A,A.QOT2 ;STORE AS TERMINATOR OF STRING
A.QOT3: PUSHJ P,RCH ;GET CHAR TO QUOTE
CAMN A,A.QOT2 ;TERMINATOR?
JRST WRQOT1 ;TERMINATOR, BACK FOR MORE DEFINITION
PUSHJ P,PUTREL ;DEPOSIT CHAR
JRST A.QOT3
;READ IN BODY OF MACRO, IRP, OR WHATEVER
WRQOTE: PUSH P,[0] ;USED FOR LENGTH OF SYMBOL (REALLY 6 MINUS IT).
WRQLEN==,-2
PUSH P,[0] ;THIS WD USED FOR DEFINE/TERMIN COUNT.
WRQLVL==,-1
PUSH P,[0] ;USED TO REMEMBER BEGINNING OF SYMBOL.
WRQBEG==0
SETOM INICLB ;CLOBBERED INITS, .SYMTAB NOW ILLEGAL.
PUSHJ P,RCH ;MAYBE POP UP A LEVEL IN EXPANSIONS, SAVE MACTAB SPACE
TLO FF,FLUNRD ;CAUSE CHAR TO BE RE-INPUT
MOVE F,MACHIB ;POINTER TO LAST CHAR OK TO PUT IN MACTAB, STAYS IN F
TRO I,IRSYL\IRLET ;MAKE SURE FLAGS SET SO WON'T WASTE TIME AT MAKNUM, POINT
WRQOT0:
WRQOT1: MOVEI D,6 ;SQUOZE COUNTER
MOVEI SYM,0 ;INITIALIZE SYM
MOVE C,FREPTB ;GET POINTER TO CHAR BEFORE SYL ABOUT TO READ
PUSHJ P,WRQRR ;READ SYL
JUMPE SYM,.-2 ;LOOP UNTIL NON-NULL
;NOW SEE IF DUMMY; **NOTE**: C STILL HAS BYTE POINTER, A SYL TERMINATOR
MOVE B,DMYBOT
CAML B,DMYTOP
JRST WRQOT2 ;NOT DUMMY
CAME SYM,(B) ;COMPARE WITH DUMMY NAME
AOJA B,.-3 ;LOOP ON NO MATCH
SUB B,DMYBOT ;DUMMY, CONVERT TO NUMBER + 200
SUBI B,200
LDB T,C ;GET LAST CHAR BEFORE SYL
CAIE T,"! ; ^ NOTE THAT THIS CAN LOSE IF MACRO HAS 33. ARGS
IDPB B,C ;NOT EXCLAMATION POINT, LEAVE THERE, DEPOSITING DUMMY CHAR
CAIN T,"!
DPB B,C ;EXCL, WIPE IT OUT
MOVEM C,FREPTB ;RESET FREPTB
CAIE A,"! ;A HAS DUMMY TERMINATOR, COMPARE WITH EXCL
TLO FF,FLUNRD ;NOT EXCLAMATION POINT, CAUSE IT TO BE RE-INPUT
JRST WRQOT1 ;LOOP BACK FOR NEXT SYL
;SYL ISN'T DUMMY, CHECK FOR PSEUDO
WRQOT2: MOVEM D,WRQLEN(P) ;REMEMBER START OF AND LENGHTH OF THE SYMBOL.
MOVEM C,WRQBEG(P)
SETOM ESBK ;EVAL IN CURRENT BLOCK.
PUSHJ P,ES ;EVALUATE SYM (DOESN'T CLOBBER F)
JRST WRQOT0 ;NOT SEEN
CAIE A,PSUDO/40000
JRST WRQOT0 ;NOT PSEUDO
TLZ B,-1 ;CLEAR OUT LH OF VALUE, ONLY INTERESTED IN RH
CAIN B,A.QOTE
JRST A.QOT1 ;.QUOTE
CAIE B,ADEFINE
CAIN B,AIRP
AOS WRQLVL(P) ;DEFINE OR IRP
IFN RCHASW,[CAIN B,A.TTYM
AOS WRQLVL(P) ;.TTYMAC
]
CAIE B,ATERMIN
JRST WRQOT0
SKIPGE WRQLEN(P)
ETR [ASCIZ /TERMIN longer than 6 chars/]
SOSL WRQLVL(P) ;TERMIN, SKIP IF THE TERMINATING ONE
JRST WRQOT0 ;NOT MATCHING TERMIN, BACK FOR NEXT SYL
POP P,A ;GET BACK BP TO LAST CHAR BEFORE TERMIN
SUB P,[2,,2] .SEE WRQLVL,WRQBEG
MOVE T,DMYBOT ;WE'RE NO LONGER USING SPACE IN DMYDEF.
MOVEM T,DMYTOP
A.QOTS: LDB T,A ;HERE ALSO FROM A.QOT1, GET CHAR BEFORE .QUOTE OR TERMIN
CAIE T,"!
JRST A.QTS2 ;NOT EXCLAMATION POINT => OK
DBPM A, ;EXCLAMATION POINT, DECREMENT POINTER
A.QTS2: MOVEM A,FREPTB ;STORE AS NEW FREPTB
CCOMP1 A,-1 ;CONVERT TO CHAR ADR
MOVEM B,FREEPT ;STORE CHAR ADR AS NEW FREEPT
POPJ P,
;FORMAT OF A MACRO:
;IT STARTS WITH A 374.
;THEN COME ARGUMENT DESCRIPTORS, ONE PER ARGUMENT.
MCF==777650 ;BITS AND FIELDS ARE:
MCFDEF==200 ;ARG IS DEFAULTED. MCFDEF AND MCFGEN NEVER BOTH SET.
MCFGEN==100 ;ARG SHOULD BE GENSYMMED IF NOT GIVEN IN CALL.
MCFKWD==40 ;ARG IS A KEYWORD ARG, SELECTED BY <ARGNAME>= RATHER THAN POSITION.
MCFSYN==7 ;FIELD THAT SPECIFIES THE ARGUMENT'S SYNTAX.
MCFNRM==1 ;MCFSYN CONTAINS MCFNRM => NORMAL-SYNTAX ARG
MCFLIN==2 ;MCFSYN CONTAINS MCFLIN => WHOLE LINE ARG
MCFBAL==3 ;MCFSYN CONTAINS MCFBAL => BALANCED ARG
MCFSTR==4 ;MCFSYN CONTAINS MCFSTR => ARG IS A DELIMITED STRING, AS IN "ASCIZ".
MCFKST==5 ;MCFSYN CONTAINS MCFKST => JUST LIKE MCFSTR, BUT DELIMITERS ARE RETAINED.
MCFEVL==6 ;MCFSYN CONTAINS MCFEVL => ARG IS BY VALUE (PREEVALUATED).
;IF MCFKWD IS SET, THE DESCRIPTOR IS FOLLOWED BY THE NAME OF THE ARGUMENT,
;TERMINATED BY A 377.
;IF MCFDEF IS SET, THE DESCRIPTOR IS FOLLOWED BY THE DEFAULT VALUE OF THE ARG,
;TERMINATED BY A 377.
;IF MCFKWD AND MCFDEF ARE BOTH SET, THE ARG NAME COMES FIRST.
;A ZERO BYTE ENDS THE DESCRIPTOR LIST.
;THEN COMES THE BODY OF THE MACRO, FOLLOWED BY A 375.
ADEFINE: NOVAL ;ERROR IF CONTEXT WANTS A VALUE.
PUSH P,CASSM1 ;RETURN TO ASSEM1 EVENTUALLY
JSP TM,ERMARK ;ERR MSGS SHOULD SAY WE'RE INSIDE A DEFINE.
PUSH P,SYM ;THESE 2 PUSHES ARE FOR NONAME'S SAKE.
PUSH P,SYM
CALL GETSLD
CALL NONAME
TLZ FF,FLUNRD
SUB P,[2,,2]
PUSH P,SYM
PUSH P,ESBK ;SAVE BLOCK TO DEFINE IN FOR ES'S SAKE.
IFN CREFSW,XCT CRFMCD
CALL A.TYM1
POP P,ESBK
REST SYM
PUSHJ P,ESDEF ;FIND SLOT IN SYMBOL TABLE FOR IT
TLO C,3MACOK ;NEVER SEEN, OK TO MAKE MACRO.
TLON C,3MACOK ;ELSE ERROR IF NUMERIC OR ALREADY USED.
ETSM [ASCIZ/Non-macro made macro/]
MOVEI B,MACCL ;RH(VALUE) = MACCL
HRL B,PRDEF ;LH(VALUE) = CHAR ADR OF MACRO
CLEARM PRDEF ;NO LONGER NEED PRDEF
MOVSI T,PSUDO ;SYMBOL TABLE ENTRY LOOKS LIKE PSEUDO
JRST VSM2
IFN RCHASW,[
;.TTYMAC NAME
;BODY
;TERMIN
;NAME DUMMY, CAUSES READIN OF CRUD FROM TTY -> CR (NOT INCLUSIVE)
A.TTYM: JSP TM,ERMARK ;ERROR MSGS SHOULD SAY WE'RE INSIDE A .TTYMAC
CALL A.TYM1 ;READ IN A MACRO-DEFINITION.
MOVEI A,40 ;DON'T LET THE CHAR ENDING THE TERMIN
MOVEM A,LIMBO1 ;MAKE MACCL THINK THERE ARE NO ARGS.
CALL GTYIP1 ;PUSH INTO TTY FOR INPUT
HRLZ B,PRDEF ;PHONY UP A MACRO WHOSE DEFN IS WHAT WE READ.
SETZM PRDEF
MOVEI A,A.TYM8
JRST A.TYM2 ;CALL THE MACRO:
;READ THE ARGS, POP OUT OF TTY, EXPAND THE MACRO
;AND THEN EXIT TO A.TYM8
]
A.TYM1: MOVE A,FREEPT
MOVEM A,PRDEF
MOVEI LINK,MCFNRM ;INITIALLY, DUMMIES ARE NORMAL.
MOVEI A,374
PUSHJ P,PUTREL ;MARK BEGINNING OF MACRO
DEFNI: MOVE T,LIMBO1
MOVE A,LINK
DEFNC: CAIE T,12
CAIN T,15
JRST DEFNA ;NO MORE ARGS (DONE WITH LINE)
CAIE T,LBRACE
CAIN T,LBRKT
JRST DEFNB1
CAIE T,RBRACE
CAIN T,RBRKT
JRST DEFNB2
CAIE T,"< ;OPENS TURN ON BALANCEDNESS.
CAIN T,"(
JRST DEFNB1
CAIE T,"> ;CLOSES TURN OFF BALANCEDNESS.
CAIN T,")
JRST DEFNB2
CAIN T,"? ;? TURNS BALANCEDNESS ON OR OFF.
JRST DEFBAL
CAIN T,"+ ;+ COMPLEMENTS KEYWORDNESS
XORI LINK,MCFKWD
CAIN T,"\ ;\ COMPLEMENTS GENSYMMEDNESS
XORI LINK,MCFGEN
CAIN T,"- ;- TURNS WHOLELINENESS ON OR OFF.
JRST DEFWHL
CAIN T,"* ;* TURNS ASCIZ-STYLE-NESS ON OR OFF.
JRST DEFASC
CAIN T,"& ;& TURNS KEEP-STRUNGNESS ON OR OFF.
JRST DEFKST
CAIN T,"# ;# TURNS EVALUATEDNESS ON OR OFF.
JRST DEFEVL
CAIN T,": ;: MAKES FOLLOWING ARGS NORMAL
MOVEI LINK,MCFNRM ;IN ALL RESPECTS
CAIN T,";
JRST DEFNSM ;ALLOW DEFINE LINE TO BE COMMENTED
DEFND: PUSH P,A
CALL GSYL ;READ IN SYMBOL AS SQUOZE IN SYM.
REST A
CAIN T,"/ ;/ MEANS PREVIOUS ARG IS WHOLE-LINE.
XORI LINK,MCFLIN#MCFNRM
JUMPE SYM,DEFNC ;JUMP IF SYMBOL NAME WAS NULL.
CALL PDEF1 ;ELSE PUSH IT ON LIST OF DUMMIES.
MOVE A,LINK
CAIE T,"=
JRST DEFNL
IORI A,MCFDEF ;ONE ARG, WITH DEFAULT VALUE.
ANDCMI A,MCFGEN ;NOT TO BE GENSYMMED.
DEFNL: CALL PUTREL ;OUTPUT A DESCRIPTOR FOR THIS ARG
TRNE LINK,MCFKWD
CALL DEFNM ;PUT OUT ARG NAME IF KWD ARG
CAIE T,"= ;THEN DEFAULT VALUE IF DEFAULTED.
JRST DEFNI
JSP D,RARG ;INIT. FOR READING THE DEFAULT VALUE.
CAIA
CALL RARGCP ;COPY THE ARG INTO MACRO SPACE,
CALL PUT377 ;TERMINATED BY A 377.
JRST DEFNI ;NOW FOR THE NEXT ARG.
DEFNM: MOVE D,[440700,,STRSTO]
DEFNM1: ILDB A,D
CAMN D,STRPNT
JRST PUT377
CALL PUTREL
JRST DEFNM1
DEFEVL: SKIPA A,[MCFEVL] ;TURN EVALUATEDNESS ON OR OFF.
DEFASC: MOVEI A,MCFSTR ;TURN ASCIINESS ON OR OFF.
JRST DEFN9
DEFKST: MOVEI A,MCFKST ;TURN KEEP-STRUNGNESS ON OR OFF.
JRST DEFN9
DEFBAL: SKIPA A,[MCFBAL] ;TURN ON BALANCEDNESS, BUT IF ALREADY ON TURN OFF.
DEFWHL: MOVEI A,MCFLIN ;SIMILAR FOR WHOLELINENESS.
DEFN9: LDB B,[.BP MCFSYN,LINK]
CAMN A,B ;IF CURRENT STATE IS SAME AS IN A,
MOVEI A,MCFNRM ;SWITCH TO NORMAL MODE INSTEAD.
DPB A,[.BP MCFSYN,LINK]
JRST DEFND
DEFNB2: SKIPA A,[MCFNRM] ;TURN OFF BALANCEDNESS
DEFNB1: MOVEI A,MCFBAL ;TURN ON BALANCEDNESS
DPB A,[.BP MCFSYN,LINK]
JRST DEFND
DEFNSM: PUSHJ P,RCH ;SEMICOLON IN DEFINE LINE
CAIE A,15
CAIN A,12
DEFNA: SKIPA A,LINK ;END OF DEFINE LINE, GET COUNT
JRST DEFNSM
MOVEI A,0
PUSHJ P,PUTREL ;DEPOSIT END-OF-DESCRIPTORS MARK
PUSHJ P,RCH
CAIE A,12
TLO FF,FLUNRD ;CHAR AFTER CR NOT LF
PUSHJ P,WRQOTE ;READ IN BODY
JRST STPWR
;COME HERE TO EXPAND MACRO; LH OF B POINTS TO STRING.
;SYM HOLDS NAME OF MACRO (USED BY CALL TO AGETFD IN MACEVL).
MACCL: JSP TM,ERMARK ;ERROR MESSAGE DURING ARG SCAN SHOULD SAY WE'RE IN IT.
MOVEI A,RCHSV1
A.TYM2: PUSH P,I
AOS PRCALP
AOS MDEPTH
PUSH P,RDWRDP
PUSH P,A ;RCHSV1 FOR MACRO, A.TYM8 FOR .TTYMA
MOVEI LINK,0
HLRZ A,B
PUSHJ P,REDINC
CAIE B,374
GOHALT
MOVEM A,@PRCALP
PUSHJ P,REDINC
TLZ I,ILPRN
JUMPE B,MACCLE ;MACRO TAKES NO ARGS => UN-READ NEXT CHARACTER.
MOVE A,LIMBO1
CAIE A,") ;MACRO NAME TERMINATED WITH A CLOSE-BRACKET OF SOME SORT
CAIN A,"> ;=> UN-READ THE FOLLOWING CHARACTER.
JRST MACCLE
CAIN A,RBRKT
JRST MACCLE
CAIE A,15 ;MACRO NAME ENDED BY A CR OR LF =>
CAIN A,12
JRST MACCLD ;NO ARGS IN THIS CALL; NULLIFY ALL ARGS.
CAIE A,"<
CAIN A,"(
TLO I,ILPRN ;BUT MAYBE THERE IS A (. IF SO, IT'S A PAREN'D CALL,
CAIN A,LBRKT ;AND WON'T END TILL THE MATCHING CLOSE.
TLO I,ILPRN
CAIE A,40 ;IF THE CHAR ENDING THE MACRO NAME ISN'T AN OPENPAREN,
CAIN A,^I ;EOL, OR SPACE, RE-READ IT AS PART OF 1ST MACRO ARG.
JRST MACNX0
TLNN I,ILPRN
TLO FF,FLUNRD
MACNX0: TDZ LINK,LINK
MACNXD: CALL MACDES ;FETCH NEXT DESCRIPTOR
JRST MACPUS ;NO MORE => THIS IS END OF THE CALL
TRNE LINK,MCFKWD
JRST MACK ;KEYWORD PARAM => SPECIAL SCANNER
;READ IN THE VALUE OF THE NEXT ARG, WHICH IS NORMAL (NOT KEYWORD)
MACNRM: CALL ADDTRN ;PUSH WORD TO HOLD VALUE OF ARG ONTO DSTG,
;INITIALIZED -> FREEPT, WHERE WE WILL NOW WRITE THE ARG.
SOS C,A ;TELL MACRED WHERE THAT WORD IS.
CALL MACRED ;READ IN THE ARGUMENT VALUE.
JRST MACNXD ;THEN HANDLE ANOTHER ARG
GOHALT
JRST MACCLD ;END OF ARG LIST => NULLIFY REMAINING ARGS.
MACCLE: TLO FF,FLUNRD ;SAVE CHR FOLLOWING MACRO W/NO ARGUMENTS
;AND IF THAT CHAR WAS A CLOSE-BRACKET,
SKIPE B,ASMOUT ;CLEAR OUT THE CHANGE IT MADE TO ASMDSP.
CAIN B,4
CAIA
JSP LINK,SAVAS2
SETZ LINK,
JRST MACCLD ;NOW GO NULLIFY ANY ARGS THE MACRO WANTED, AND EXIT.
;READ IN THE NEXT MACRO ARGUMENT ACC TO SYNTAX FLAGS IN LINK.
;C HAS ADDRESS OF WORD ON THE RDWRDP STACK WHICH HOLDS THE POINTER TO THIS ARG
;IN CASE WE WISH TO SET THE ARG TO THE NULL STRING. B AND LINK NOT CLOBBERED.
;RETURNS SKIPPING TWICE IF NO ARG BECAUSE END OF MACRO CALL SEEN.
MACRED: MOVEI D,MACNXR ;RARL3, RARB, RARGBR RETURN TO MACNXR
CALL RCH
CAIE A,^M
CAIN A,^J
JRST MACEND ;MAYBE WE HAVE REACHED THE END OF THE MACRO CALL.
LDB B,[.BP MCFSYN,LINK]
CAIN B,MCFLIN
JRST RARL3 ;ELSE, IF WHOLELINE ARG, NOTHING ELSE TO CHECK,
;SO INIT FOR READING IT IN.
CAIN A,",
JRST MACNUL ;NON-WHOLELINE ARG IS NULL IF NEXT CHAR IS COMMA
CAIN A,"; ;SEMICOLON ENDS ARG LIST UNLESS INSIDE WHOLELINE ARG
JRST MACEND
CAIN B,MCFBAL
JRST RARB ;FOR BALANCED ARG, NOTHING ELSE SPECIAL, SO INIT.
CAIE B,MCFSTR ;FOR BOTH FLAVORS OF STRUNGNESS,
CAIN B,MCFKST ;GO GOBBLE AN ASCIZ-STYLE ARGUMENT.
JRST MACSTR
CAIN B,MCFEVL ;FOR EVALUATED ARG, READ FIELD AND EXPRESS AS NUMERAL.
TLOA FF,FLUNRD ;AND THE CHAR WE JUST READ WAS THE 1ST CHAR OF THE FIELD.
CAIN A,"\ ;NORMAL ARG STARTING WITH "\" TREATED THE SAME WAY, BUT FIELD
JRST MACEVL ;STARTS WITH NEXT CHAR.
CAIN A,LBRKT
JRST RARGBR ;FOR ORDINARY ARG, OPEN-BRACKET MAKES IT SPECIAL
IFN BRCFLG,[
CAIN A,LBRACE
JRST RARGRR
]
MOVEI T,RARGN ;OTHERWISE IT'S A NORMAL ARG
TLOA FF,FLUNRD ;AND THE CHAR WE RCH'ED IS THE 1ST CHAR OF IT
MACNXR: JRST MACEN1 ;NON-SKIP RETURN FROM RARB, RARL3 OR RARGBR => ARG NULL
CALL RARGCP ;ARG NON-NULL => COPY IT INTO STRING SPACE
CAIE A,";
CSTPWR: JRST STPWR ;AND TERMINATE IT
MACSC: MOVE A,(C) ;EXCEPT THAT SEMICOLONS INVALIDATE ALL THE SPACES
CAME A,FREEPT ;AND TABS THAT PRECEDE THEM.
JRST STPWR ;IF, AS A RESULT OF THAT, THE ARG IS NULL, END THE ARGLIST.
;COME HERE WHEN THE END OF THE MACRO'S WHOLE ARGLIST IS SEEN.
MACEND: TLO FF,FLUNRD
MACEN1: AOS (P) ;2-SKIP RETURN FROM MACRED INDICATES END OF ARGLIST
AOS (P) ;END OF ARGLIST => THIS ARG IS NULL.
;COME HERE TO NULLIFY CURRENT ARG (WHERE C POINTS)
MACNUL: TRZE LINK,MCFDEF
JRST MACDEF ;MAYBE DEFAULT IT
TRNE LINK,MCFGEN
JRST MACGEN ;MAYBE GENSYM IT
SETZM (C) ;ELSE SET TO NULL STRING.
RET
MACST1: CALL RCH
CAIN A,",
JRST MACNUL
MACSTR: CAIE A,40 ;HERE FOR ARG DELIMITED LIKE TEXT STRINGS: /TEXT/.
CAIN A,^I ;SKIP ALL SPACES AND TABS BEFORE THE ARG.
JRST MACST1
JSP D,RARB ;FIND END OF LINE, COMMENT, OR CLOSEBRACKET =>
JRST MACEND ;NULLIFY ARG AND END MACRO CALL.
MOVEI T,(A) ;ELSE SAVE THIS CHAR; IT'S THE DELIMITER.
TLZ FF,FLUNRD ;DON'T RE-READ DELIMITER,
CAIN B,MCFKST ;BUT IF ARG IS KEEP-STRUNG, DROP THRU TO STORE IT.
MACST2: CALL PUTREL
CALL RCH ;READ ANOTHER CHARACTER. IF IT ISN'T THE DELIMITER,
CAIE A,(T)
JRST MACST2 ;STORE IT AND READ ANOTHER.
CAIN B,MCFKST ;HIT DELIMITER, DONE. BUT IF ARG IS KEEP-STRUNG,
CALL PUTREL ;KEEP DELIMITER BY STORING IT TOO.
CALL STPWR
MACST3: CALL RCH ;PASS BY SPACES AFTER THE CLOSING DELIMITER
CAIE A,40
CAIN A,^I
JRST MACST3
CAIE A,", ;COMMA HERE ENDS THE ARG BUT NOT THE MACRO CALL.
JSP D,RARB ;ELSE CHECK FOR OTHER TERMINATORS.
RET ;WE FOUND AN ACCEPTABLE ARG TERMINATOR.
ETR [ASCIZ /Garbage in ASCIZ-style macro arg/]
JRST RARFLS ;IF THERE'S ANYTHING ELSE, COMPLAIN AND SKIP IT.
;COME HERE TO GIVE AN ARG ITS DEFAULT VALUE.
;MCFDEF WAS CLEARED SO MACDES WILL KNOW THE DEFAULT VALUE HAS
;ALREADY BEEN PASSED OVER AND WON'T TRY TO SKIP OVER IT.
;IF MCFKWD IS SET, WE MUST SKIP OVER THE KWD ARG'S NAME FIRST.
MACDEF: TRZN LINK,MCFKWD
JRST MACDF1
MOVE A,@PRCALP
MACDF0: CALL REDINC ;SKIP ARG NAME IF KEYWORD ARG.
CAIE B,377
JRST MACDF0
MOVEM A,@PRCALP
MACDF1: MOVE A,@PRCALP ;COPY THE DEFAULT VALUE AS THE ARGUMENT VALUE.
CALL REDINC ;AS THE ARGUMENT STRING.
MOVEM A,@PRCALP
CAIN B,377
JRST STPWR ;END OF THE DEFAULT VALUE.
EXCH A,B
CALL PUTREL
EXCH A,B
JRST MACDF1
;COME HERE IF GENSYMMABLE ARG IS SPEC'D AS NULL.
MACGEN: MOVEI A,5
MOVEM A,SCKSUM
MOVEI A,"G
PUSHJ P,PUTREL
PUSH P,CSTPWR
AOS A,GENSM
IDIVI A,10
HRLM B,(P)
SOSLE SCKSUM
PUSHJ P,.-3
JRST MACEV2
;PROCESS ARG THAT STARTS WITH \, OR #-TYPE ARG.
MACEVL: CALL RCH ;FIRST, CHECK FOR IMMEDIATE END OF MACRO CALL.
JSP D,RARB
JRST MACEN1
PUSH P,C
PUSH P,LINK ;SAVE LINK, NEED FLAGS
PUSHJ P,AGETFD ;GET THE FIELD
SKIPE B
ETR [ASCIZ /Relocatable \'d macro arg/]
POP P,LINK
REST C ;IF AGETFD EXPANDED A MACRO, FREEPT HAS CHANGED, SO
MOVE CH1,FREEPT ;PUT NEW VALUE INTO THE POINTER TO THIS DUMMY.
MOVEM CH1,(C)
MOVE CH1,A ;SAVE VALUE OF FIELD FROM CLOBBERAGE
PUSH P,CSTPWR
MACEV1: LSHC CH1,-35. ;NOW "TYPE OUT" VALUE OF FIELD IN CURRENT RADIX
LSH CH2,-1
DIV CH1,ARADIX
HRLM CH2,(P)
JUMPE CH1,.+2
PUSHJ P,MACEV1
MACEV2: HLRZ A,(P)
ADDI A,60
JRST PUTREL ;OUTPUT TO MACTAB STRING BEING DEFINED
;HANDLE KEYWORD PARAMETERS. COME HERE WHEN A DESCRIPTOR IS SEEN
;THAT SPECIFIES A KEYWORD PARAMETER.
MACK: PUSH P,RDWRDP
MOVE A,@PRCALP ;PUSH A COPY OF POINTER TO 1ST KWD ARG'S DESCRIPTOR
AOS PRCALP ;SO WE CAN ADVANCE THE COPY WHILE KEEPING ORIGINAL FIXED.
MOVEM A,@PRCALP
PUSH P,LINK
;FIRST, PUSH A "NOT SET" MARKER FOR EACH OF THE KEYWORD PARAMS IN THIS RUN OF SUCH.
MACK2: SETO A,
CALL ADDTR2
CALL MACDES ;NOTE THAT THERE IS ONLY ONE PARAM PER DESCRIPTOR
JRST MACK1 ;FOR KEYWORD PARAMS, SO NO NEED TO COUNT DOWN.
TRNE LINK,MCFKWD
JRST MACK2
MACK1: MOVE LINK,(P) ;NOW GO BACK TO THE DESCRIPTOR OF THE FIRST KEYWORD PARAM.
MOVE B,PRCALP
MOVE B,-1(B)
MOVEM B,@PRCALP
MACKLP: CALL GPASST ;NOW SEE IF THERE'S AN ARGUMENT TO BE FOUND
CAIE A,^M ;IF SO, IT SHOULD START WITH A KEYWORD.
CAIN A,^J
JRST MACKND ;CR OR LF => NO KEYWORD, AND END SCAN.
CAIN A,";
JRST MACKND
CAIN A,",
JRST MACKN1 ;NULL ARG => NO KEYWORD, BUT DON'T END SCAN.
CAIE A,")
CAIN A,">
JRST MACKND ;DETECT END OF PARENTHESIZED CALLS, ETC.
CAIE A,RBRKT
CAIN A,RBRACE
JRST MACKND
TLO FF,FLUNRD
CALL GSYL ;THERE SHOULD BE ANOTHER ARG, SO TRY READING KEYWORD NAME
CALL PASSPS
MOVE C,-1(P) ;NOW SCAN THROUGH THIS RUN OF KEYWORD PARAMS FOR THE ONE
CAIE A,"= ;WHOSE NAME MATCHES WHAT GSYL READ.
JRST MACKL5 ;NOT FOLLOWED BY "="??
DPB A,STRPNT
MACKL4: MOVE D,[440700,,STRSTO]
MOVE A,@PRCALP
MACKL1: CALL REDINC
ILDB AA,D
CAIN B,377 ;IF REACHED END OF KEYWORD'S NAME, AND EQUAL SO FAR
JRST MACKL2 ;SEE IF ARG'S NAME ALSO OVER.
CAMN B,AA
JRST MACKL1 ;ELSE KEEP COMPARING IF NAMES STILL SAME SO FAR.
MACKL6: MOVEM A,@PRCALP
CALL MACDES ;THIS KEYWORD DOESN'T MATCH SO FIND THE NEXT
JRST MACKL3 ;THERE ARE NO MORE; LOSE - ARG WITH BAD KEYWORD.
TRNN LINK,MCFKWD
JRST MACKL3
AOJA C,MACKL4
MACKL5: ETR [ASCIZ /Bad format keyword argument/]
TLOA FF,FLUNRD ;INCLUDE THE BAD NON-"=" AS PART OF WHAT WE DISCARD
MACKL3: ETR [ASCIZ /Arg with undefined keyword/]
MOVEI T,RARGN
CALL RARFLS ;SKIP AN ORDINARY-SYNTAX MACRO ARG TO TRY TO RECOVER.
JRST MACK1
;COME HERE AFTER FINDING THE PARAM THAT MATCHES THIS ARG.
;C POINTS TO THE WORD IN DSTG FOR THAT ARG (DSTG IS WHAT ADDTRN PUSHES IN)
MACKL2: TRZ LINK,MCFKWD ;(IN CASE WE GO TO MACKL6, SINCE KWD NAME SKIPPED ALREADY)
CAIE AA,"=
JRST MACKL6 ;KWD NAME OVER BUT SPEC'D NAME NOT => MISMATCH
MOVEMM (C),FREEPT
CALL MACRED ;READ IN THE VALUE OF THE ARG, THUS SETTING THIS PARAM.
JRST MACK1 ;THERE ARE MORE ARGS => HANDLE THEM
GOHALT
MACKND: TLO FF,FLUNRD ;MACRO CALL TERMINATOR SEEN.
;NULL ARG SEEN; ENDS THIS RUN OF KEYWORD ARGS BUT NOT THE CALL.
MACKN1: REST LINK ;NOW GO BACK TO THE DESCRIPTOR OF THE FIRST KEYWORD PARAM.
SOS PRCALP
REST C ;GET PTR TO 1ST KWD ARG'S VALUE-WORD
MACKN2: MOVE A,(C)
AOJN A,MACKN4 ;IF THIS ARG WASN'T SPECIFIED,
MOVEMM (C),FREEPT
CALL MACNUL ;NULLIFY IT (MAYBE DEFAULT OR GENSYM)
MACKN4: CALL MACDES ;NOW SKIP OVER THE DESCRIPTORS OF THIS RUN OF KEYWORD PARAMS
JRST MACPUS ;EXHAUSTED ALL THE DESCR'S => END OF MACRO CALL.
TRNE LINK,MCFKWD ;SAME IF REACH A NON-KWD ARG.
AOJA C,MACKN2
TLNN FF,FLUNRD ;REACHED A NON-KEYWORD PARAM: IF TERMINATOR WAS A NULL ARG,
JRST MACNRM ;GO ON TO READ THE VALUE OF THE NON-KEYWORD PARAM.
JRST MACCLS ;ELSE CALL WAS REALLY ENDED, SO NULLIFY REMAINING ARGS.
;COME HERE TO FIND THE NEXT DESCRIPTOR.
;SKIPS OVER THE NAME AND DEFAULT VALUE OF THE PREVIOUS DESCRIPTOR, IF ANY.
;THE CONTENTS OF LINKK SAY WHETHER THEY EXIST TO BE SKIPPED OVER.
MACDES: MOVE A,@PRCALP
CALL REDINC ;READ NEXT CHAR OF MACRO
MOVEM A,@PRCALP
TRNE LINK,MCFKWD\MCFDEF
JRST [ CAIE B,377 ;IF THERE'S NAME OR DEFAULT TO SKIP, GO PAST TERMINATOR
JRST MACDES
TRZN LINK,MCFKWD ;AND SAY WE FOUND ONE
TRZ LINK,MCFDEF ;NOTE THERE MAY BE ANOTHER, IN WHICH CASE WE WILL
JRST MACDES] ;SKIP TILL ANOTHER 377
JUMPE B,CPOPJ ;THIS DESC IS TERMINATOR => RETURN NO SKIP.
MOVEI LINK,(B) ;ELSE PUT FLAGS IN LINK.
JRST POPJ1
;COME HERE WHEN A MACRO CALL TERMINATOR IS ENCOUNTERED, TO NULLIFY ALL
;THE REMAINING PARAMS THAT THE MACRO WANTS, THEN ENTER THE MACRO.
;ENTER AT MACCLS IF HAVE JUST READ A DESCRIPTOR AND NOT NULLIFIED THE ARG,
;OR AT MACCLD IF HAVE JUST PROCESSED AN ARG, TO READ THE NEXT DESCRIPTOR.
MACCLS: TRNE LINK,MCFDEF\MCFGEN
JRST MACCL2
SETZ A, ;NULLIFY NON-GENSYMMED, NON-DEFAULTED ARGS QUICKLY
CALL ADDTR2
MACCLD: CALL MACDES ;THEN READ THE NEXT DESCRIPTOR.
JRST MACPUS ;IF NO MORE ARGS, ENTER THE MACRO.
JRST MACCLS
MACCL2: CALL ADDTRN ;FOR GENSYMMED OR DEFAULTED ARG, PUSH PTR TO FREE STG
SOS C,A
CALL MACNUL ;THEN WRITE THE DESIRED VALUE THERE
JRST MACCLD ;THEN HANDLE NEXT DESCRIPTOR.
;COME TO MACPUS WHEN ALL THE PARAMS HAVE HAD VALUES PUT IN DSTG (USING ADDTRN)
;TO ENTER THE MACRO.
MACPUS: TLZE I,ILPRN ;SPECIAL PARENTHESIZED CALL?
CALL MACPRN ;YES, SKIP PAST THE CLOSING PAREN.
MOVE B,(P) ;IS THIS A .TTYMAC?
CAIN B,A.TYM8
CALL A.INEO ;YES, POP OUT OF TTY AFTER READING ARGS.
JFCL
REST B ;RCHSV1 OR A.TYM8
PUSHJ P,PUSHEM
MOVE A,@PRCALP
PUSHJ P,ACPTRS ;SET UP CPTR
POP P,A
PUSHJ P,DMYTRN
SOS PRCALP
REST I
MACCR: AOS (P) ;COMMON RETURN FROM PSEUDOS TO RETURN FROM GETVAL WITHOUT VALUE
CMACCR: POPJ P,MACCR
MACPRN: MOVEI TT,1 ;START PAREN-DEPTH AT 1
JSP D,RARBC ;AND READ CHARS, UPDATING THE DEPTH, UNTIL
GOHALT
JUMPN TT,.-2 ;THE DEPTH GETS TO BE 0.
RET
A.GOMC: ILDB B,A ;.GO ROUTINE TO SKIP PAST DESCRIPTORS
JUMPN B,A.GOMC ;IN HEADER OF MACRO DEFINITION.
JRST A.GORT
RCHSV1: SOS MDEPTH ;END OF MACRO EXPANSION, DECREMENT DEPTH IN MACRO EXPANSIONS
A.TYM8: PUSH P,A ;ENTRY FROM .TTYMAC END OF EXPANSION
MOVE B,TOPP
RCHSV3: CAMG B,BBASE
JRST RCHSV2
HLRZ A,-1(B)
ADD A,-1(B)
MOVEI A,1(A)
CAME A,FREEPT
JRST RCHSV2
HRRZ A,-1(B) ;GET NEW FREEPT
SOJA B,RCHSV3
RCHSV2: POP P,A
;RETURN ROUTINE FOR END OF DUMMY
RCHSAV: MOVE B,BBASE
MOVEM B,TOPP
PUSHJ P,POPEM
HLRM B,BBASE
REPT6: TRZE FF,FRMRGO
POPJ P, ;RETURN TO .GO
JRST RCHTRB
;IRP, IRPS, IRPC, IRPW, IRPNC ALL CALL HERE.
;ALL USE 2 FRAMES ON THE MACRO PDL:
; <OLD BBASE>,,<OLD CPTR>
; <SAVED LIMBO1 STATUS>,,<OUTER .IRPCNT>
; <IRP TYPE>\<# GROUPS>,,<CHAR ADDR START OF IRP BODY>
; <SAVED TOPP>,,AIRR
;THE 3RD WORD HAS IN BITS 4.1-4.3 THE IRP TYPE CODE
; (NIRPO, NIRPC, ETC)
;AND IN THE REST OF THE LH, THE NUMBER OF GROUPS
; (TRIPLES OF TWO DUMMIES AND A LIST)
.SEE NIRPO ;FOR DEFINITIONS OF IRP TYPE CODES.
AIRP: JSP TM,ERMARK ;ERROR MESSAGES SHOULD SAY WE'RE INSIDE IT.
PUSH P,I
PUSH P,RDWRDP
HLRZ LINK,B ;GET IRP TYPE CODE TO INDEX BY.
CAIE LINK,NIRPN
JRST AIRP0
CALL AGETFD ;IRPNC, READ THE 3 NUMERIC ARGS.
PUSH P,A
CALL AGETFD
PUSH P,A
CALL AGETFD
MOVEM A,AIRPN2 ;THE LAST ARG,
REST AIRPN1 ;THE MIDDLE,
REST AIRPN0 ;THE FIRST.
MOVEI LINK,NIRPN
AIRP0: SETZM IRPCR ;NO GROUPS SEEN YET.
;FALLS THROUGH.
;FALLS THROUGH.
;TRY TO READ IN ANOTHER GROUP.
AIRP1: CALL PDEF ;READ IN DUMMY NAME, PUSH ON DMYTOP.
CAIE T,", ;TERMINATOR WASN'T COMMA AND NAME WAS NULL
JUMPE SYM,AIRP2 ;=> NO MORE GROUPS.
CALL PDEF ;NONNULL GROUP, READ & PUSH 2ND NAME.
CAIN T,"[ ;] TRY TO DETECT "IRP X,[", ETC. ]
CALL [ETR [ASCIZ/Comma missing in IRP/]
TLO FF,FLUNRD ;GENERATE A COMMA.
RET]
CALL ADDTRN ;PUSH CHAR ADDR OF 1ST DUMMY,
CAIE LINK,NIRPS
CAIN LINK,NIRPC ;LEAVE SPACE FOR IRPC'S 1ST ARG, IRPS'S 2ND.
CALL PUT377
MOVE A,RDWRDP
CAIN LINK,NIRPS
AOS -1(A) ;IRPS - 1ST ARG GOES AFTER NEXT 377.
CALL ADDTRN ;PUSH CHAR ADDR OF 2ND DUMMY.
CALL PUT377
MOVE A,RDWRDP
XCT AIRP1T-1(LINK) ;MAYBE INCREMENT THAT ADDR.
AOS IRPCR ;ONE MORE GROUP SEEN.
JSP D,RARG ;INITIALIZE READING LIST.
JRST AIRP3 ;NO LIST.
JRST @.(LINK)
OFFSET 1-.
NIRPO:: AIRPO ;IRP
NIRPC:: AIRPC ;IRPC
NIRPS:: AIRPS ;IRPS
NIRPW:: AIRPW ;IRPW
NIRPN:: AIRPN ;IRPNC
OFFSET 0
AIRP1T: AOS -1(A)
AOS -1(A) ;INCR. THE 2ND DUMMY ADDR FOR IRP, IRPC.
SOS -1(A)
JFCL ;DECR. FOR IRPS, NOTHING FOR IRPW.
AOS -1(A) ;INCR. FOR IRPNC.
;READ LIST FOR IRPC OR IRP AND STUFF INTO STRING.
AIRPC:
AIRPO: CALL RARGCP ;COPY UP TO END OF ARG INTO MACRO SPACE.
JRST AIRP3
AIRPW3: CALL PUT377 ;END A LINE,
CAIGE C,
CALL PUT377 ;IF NO ; YET, MAKE NULL 2ND ARG.
;COME HERE FOR IRPW, LOOP BACK FOR NEXT LINE.
AIRPW: SETO C, ;NO ; SEEN YET IN LINE.
AIRPW1: JSP D,RARGCH(T)
JRST AIRP3 ;END OF LIST, GO WRITE 375.
CAIE A,^M
CAIN A,^J
JRST AIRPW1 ;IGNORE NULL LINES.
AIRPW4: CAIN A,";
AOJE C,AIRPW2 ;ON 1ST SEMI, SWITCH TO 2ND ARG.
CAIE A,^J
CAIN A,^M
JRST AIRPW3 ;END OF LINE => END BOTH ARGS, START OVER.
AIRPW5: CALL PUTREL
JSP D,RARGCH(T)
JRST AIRP3 ;END OF LIST.
JRST AIRPW4
AIRPW2: MOVEI A,377
JRST AIRPW5
AIRPS: SETO C, ;NO SQUOZE CHAR SEEN YET.
AIRPS2: JSP D,RARGCH(T)
JRST AIRP3
HLRZ CH1,GDTAB(A)
CAIN CH1,(RET)
CAIN A,"!
AOJA C,AIRPS0 ;A SQUOZE CHAR OR !.
JUMPL C,AIRPS2 ;NON SQUOZE FOLLOWING ANOTHER, FLUSH.
DPB A,AIRPSP ;NONSQUOZE ENDING NONNULL SYL, PUT BEFORE SYL.
SETZM AIRPSP
CALL PUT377 ;FOLLOW SYL WITH 377.
JRST AIRPS
AIRPS0: JUMPN C,AIRPS3 ;NOT 1ST CHAR IN SYL?
PUSH P,A
CALL PUT377 ;1ST, LEAVE A SPACE FOR THE SYL'S TERMINATOR.
MOVE A,FREPTB
MOVEM A,AIRPSP ;REMEMBER WHERE THE SPACE IS.
REST A
AIRPS3: CALL PUTREL
JRST AIRPS2
AIRPN: SKIPG C,AIRPN0 ;ANY CHARS TO IGNORE?
JRST AIRPN4
JSP D,RARGCH(T)
JRST AIRP3
SOJG C,.-2
AIRPN4: SKIPN C,AIRPN2 ;GET MAX # GRPS OF CHARS.
JRST AIRPN7 ;0 => IGNORE THE REST.
AIRPN5: MOVE B,AIRPN1 ;DO NEXT GRP, GET # CHARS/GRP.
AIRPN6: JSP D,RARGCH(T)
JRST AIRP3
CALL PUTREL ;STORE THE NEXT CHAR.
SOJG B,RARGCH(T) ;COUNT CHARS IN GRP.
MOVEI A,376
CALL PUTREL ;FOLLOW GRP BY 376.
SOJN C,AIRPN5 ;MAYBE CAN DO MORE GRPS.
AIRPN7: CALL RARFLS ;DID AS MANY GRPS AS CAN DO,
;IGNORE REMAINDER OF LIST.
;COME HERE WHEN EXHAUST THE LIST.
AIRP3: CALL STPWR
JRST AIRP1 ;READ ANOTHER GROUP.
;ALL GROUPS READ IN; NOW READ IN BODY.
AIRP2: CAIE T,"; ;IF A SEMICOLON ENDED THE ARGS, SKIP THE COMMENT.
JRST AIRP4
AIRP5: CALL RCH
CAIE A,^M
JRST AIRP5
AIRP4: PUSH P,LINK
MOVE A,FREEPT ;SAVE CHAR ADDR START OF BODY
MOVEM A,PRIRP ;WHERE GC WILL RELOCATE IT.
PUSHJ P,RCH ;IF NEXT CHAR LF, THEN FLUSH IT
CAIE A,12
TLO FF,FLUNRD
PUSHJ P,WRQOTE ;READ BODY OF IRP
PUSHJ P,STPWR ;WRITE STOP
PUSHJ P,PUSHEM ;SAVE WORLD
REST LINK
POP P,A ;RESTORE RDWRDP FROM LONG AGO
PUSH P,TOPP ;NOW SAVE TOPP
PUSHJ P,DMYTRN ;ACTIVATE DUMMYS
MOVE B,MACP ;NOW GET MACRO PDL POINTER
MOVE A,CIRPCT ;GET .IRPCNT
HRRM A,(B) ;CLOBBER "RETURN" ON PDL TO OLD IRPCNT
SETOM CIRPCT ;INITIALIZE IRPCNT
MOVS A,IRPCR ;GET # GROUPS
HRR A,PRIRP ;CHAR ADR OF BEGINNING OF BODY
SETZM PRIRP
DPB LINK,[410300,,A] ;PUT IN TYPE OF IRP.
PUSH B,A ;PUSH <SPECIFICATION BITS\# GROUPS>,,CHAR ADR BEGINNING
POP P,A ;NOW GET OLD TOPP
HRLS A ;MOVE TO LEFT HALF
HRRI A,AIRR ;RETURN TO AIRR ON END OF BODY
PUSH B,A ;PUSH OLD TOPP,,AIRP4
MOVEM B,MACP ;STORE BACK UPDATED MACRO PDL POINTER
MOVE A,STOPPT
MOVEM A,CPTR ;CAUSE STOP RIGHT AWAY TO CAUSE CYCLING
REST I
JRST MACCR
;RECYCLE THROUGH IRP
;AC ALLOCATIONS:
AIRR: PUSH P,A ;A GETS BP ILDBING THRU ARG LIST.
PUSH P,C ;C # GROUPS LEFT
PUSH P,T ;T ADR OF PAIR OF CHAR ADR'S OF DUMMYS
PUSH P,TT ;TT TYPE OF IRP (NIRPO, NIRPC, ETC)
AOS CIRPCT ;INCREMENT .IRPCNT
HRRZ A,(B) ;GET CHARACTER ADR BEG BODY FROM PDL
PUSHJ P,ACPTRS ;SET UP CPTR
SETOM AIRPT
TRNE FF,FRMRGO
JRST AIRR9 ;RETURN TO .GO
HLRZ T,1(B) ;DUMMY TAB ADR
LDB C,[220600,,(B)] ;# GROUPS
JUMPE C,AIRR9 ;JUMP IF NO GROUPS
LDB TT,[410300,,(B)] ;GET TYPE OF IRP (NIRPO, ETC)
AIRR6: JRST @.+1(TT)
AIRRER ? AIRRO ? AIRRC ? AIRRS ? AIRRW ? AIRRN ? AIRRER ? AIRRER
AIRRER: GOHALT
;MOVE 1 ARG THRU 1 GROUP OF IRP.
AIRRO: HRRZ A,1(T) ;THE 1ST ARG WILL START THIS TIME
HRRZM A,(T) ;WHERE THE "REST OF STRING" STARTED LAST TIME.
BCOMP A,-1 ;GET BP THAT'LL ILDB THAT CHAR.
SETO CH1, ;COUNT [-] DEPTH.
AIRRO1: ILDB B,A
CAIN B,375
JRST AIRRO4 ;END OF STRING IS END OF ARG.
SETZM AIRPT ;THIS GROUP NOT NULL.
CAIN B,"[
AOJE CH1,AIRRO3 ;FLUSH OUTERMOST [-] PAIRS.
CAIN B,"]
SOJL CH1,AIRRO3
JUMPGE CH1,AIRRO1 ;DON'T LOOK FOR , WITHIN [-].
CAIE B,^J
CAIN B,",
JRST AIRRO2 ;END OF ARG.
CAIE B,^M ;^M IS IGNORED (FLUSHED.)
JRST AIRRO1
AIRRO3: MOVEI B,376 ;FLUSH A CHAR BY REPLACING WITH 376
DPB B,A
JRST AIRRO1
AIRRC4: SUB P,[1,,1]
AIRRC3: SETZM (T) ;NULLIFY BOTH ARGS PERMANENTLY.
AIRRO4: SETZM 1(T) ;NULLIFY 2ND ARG PERMANENTLY
JRST AIRR8 ;DONE WITH THIS GROUP.
AIRRO2: MOVEI B,377 ;REPLACE CHAR THAT ENDED ARG WITH TERMINATOR.
DPB B,A
AIRRW3: CCOMP1 A,-1 ;GET ADDR OF CHAR AFTER.
HRRZM B,1(T) ;"REST OF STRING" STARTS THERE.
JRST AIRR8
AIRRN: MOVE A,1(T) ;NEW 1ST DUMMY STARTS AT OLD "REST OF STRING".
MOVEM A,(T)
BCOMP A,-1 ;NEW "REST OF STRING" STARTS AFTER 376,
JRST AIRRW2 ;WHICH WILL BECOME A 377.
AIRRW: MOVE A,1(T) ;GET CHAR ADDR START OF 2ND HALF OF PREV LINE.
CALL AIRRM ;SET 1ST DUMMY -> AFTER NEXT 376 OR 377 .
AIRRW2: ILDB B,A ;MOVE UP TO NEXT 377 OR END OF STRING.
CAIN B,375 ;END OF STRING ENDS 1ST DUMMY'S ARG =>
JRST AIRRO4 ;NULLIFY THE 2ND DUMMY.
SETZM AIRPT ;THIS GROUP NOT NULL.
CAIGE B,376
JRST AIRRW2
JRST AIRRO2 ;SET UP 2ND DUMMY -> NEXT CHAR.
;MOVE UP IN 1 GROUP OF IRPS.
AIRRS: MOVE A,(T) ;MOVE FROM 1ST DUMMY,
CALL AIRRM ;PUT 1ST DUMMY AFTER NEXT 377,
AOS (T) ;MOVE IT PAST THE SYL'S TERMINATING CHAR,
ILDB CH1,A ;GET THAT CHAR,
MOVE A,1(T)
JRST AIRRS2 ;STORE AS 2ND DUMMY.
AIRRM: BCOMP A,-1 ;A HAS CHAR ADDR; WILL ILDB THAT CHAR.
AIRRM1: ILDB B,A
CAIN B,375 ;END OF STRING => NULLIFY BOTH ARGS
JRST AIRRC4 ;AND FINISHED WITH GROUP.
CAIE B,377
JRST AIRRM1
MOVE CH1,A
CCOMP1 CH1,-1 ;GET CHAR ADDR OF CHAR AFTER 377
MOVEM CH2,(T) ;PUT 1ST DUMMY THERE.
RET ;NOTE A NOT CLOBBERED, CAN GO ON ILDB'ING.
;MOVE UP IN ONE GROUP OF IRPC.
AIRRC: AOS A,1(T) ;DELETE 1ST CHAR FROM "REST OF STRING".
BCOMP A,-1 ;GET BP -> THAT CHAR.
LDB CH1,A ;GET THE CHAR.
MOVE A,(T) ;GET CHAR ADDR OF PLACE TO PUT IT.
AIRRS2: CAIN CH1,375 ;REACHED END OF STRING =>
JRST AIRRC3 ;NULLIFY BOTH ARGS.
BCOMP A,0
DPB CH1,A ;STORE IT IN THE 1-CHAR ARG.
AIRR7: SETZM AIRPT ;THIS GROUP NOT EXHAUSTED YET.
AIRR8: ADDI T,2
SOJG C,AIRR6 ;MORE GROUPS => DO THE NEXT.
AIRR9: POP P,TT ;RETURN FROM AAIRPC
POP P,T
SKIPL AIRPT
JRST REPT3
MOVN A,[2,,2] ;ARGS EXHAUSTED, RETURN
ADDB A,MACP
HRRZ A,(A)
MOVEM A,CIRPCT
POP P,C
POP P,A
JRST RCHSAV
;IRP ARG-STRING READING COROUTINES: CALL WITH JSP D,
;INITIALIZE FOR READIN OF ARG BUT DON'T GET A CHAR.
;SKIPS IF NONNULL ARG AVAILABLE.
;COROUTINES REMEMBER INFO IN T AND TT BETWEEN CALLS.
;THE CALLER SHOULDN'T CLOBBER THEM.
RARG: CALL RCH ;DECIDE WHAT TYPE OF ARG FOLLOWS, IF ANY.
CAIN A,LBRKT ;RARG ALLOWS [-] AND MAYBE {-} ARGS AS WELL AS SIMPLE ONES.
JRST RARGBR
IFN BRCFLG,[
CAIN A,LBRACE
JRST RARGRR
]
TLO FF,FLUNRD
JSP T,RARGXT ;CAUSE FAILURE RETURN ON SEMI, CR, LF.
RARGN: CALL RCH ;RARGCH RTN FOR NORMAL ARG.
RARGX1: CAIN A,",
JRST (D) ;COMMA ENDS ARG.
RARGXT: CAIN A,";
JRST RARGSM ;SEMI ENDS SCAN.
RARGX2: CAIE A,^M
CAIN A,^J ;CR, LF END SCAN.
RARGSM: TLOA FF,FLUNRD
JRST 1(D)
JRST (D)
RARGBR: SETZ TT, ;TT USED AS BRACKET COUNTER.
JSP T,1(D) ;RETURN, WITH RARGCH RTN IN T.
;READ-CHAR RTN FOR [-] TYPE ARGS.
RARGBC: CALL RCH ;READ NEXT CHAR OF ARG.
CAIN A,LBRKT
AOJA TT,1(D)
CAIN A,RBRKT
SOJL TT,(D)
JRST 1(D) ;SKIP-RETURN UNLESS JUST READ THE FINAL CLOSEBRACKET.
RARGRR: SETZ TT, ;TT USED AS BRACE COUNTER.
JSP T,1(D) ;RETURN, WITH RARGCH RTN IN T.
;READ-CHAR RTN FOR {-} TYPE ARGS.
RARGRC: CALL RCH ;READ NEXT CHAR OF ARG.
CAIN A,LBRACE
AOJA TT,1(D)
CAIN A,RBRACE
SOJL TT,(D)
JRST 1(D) ;SKIP-RETURN UNLESS JUST READ THE FINAL CLOSEBRACE.
;TO GET THE NEXT CHAR OF THE ARG IN A, DO JSP D,RARGCH(T).
;SKIPS UNLESS NO MORE CHARS TO GET.
;NO SKIP AND SET => SCAN SHOULD BE TERMINATED.
;RARG SHOULD NOT BE CALLED AGAIN IN THAT CASE.
RARGCH==0 ;THIS SYMBOL IS FOR CREF'S SAKE.
;COPY THE ARG BEING READ INTO MACRO SPACE.
;ON RETURN, A WILL HOLD "; IF ARGUMENT WAS ENDED BY ";".
RARGCP: JSP D,RARGCH(T)
JRST RARGC1
CALL PUTREL
JRST RARGCH(T)
RARGC1: CAIE A,"; ;IF SEMI ENDED THE ARG, FLUSH THE
RET ;SPACES AND TABS BEFORE IT.
RARGC2: LDB A,FREPTB
CAIN A,^I
JRST RARGC3
CAIE A,40
JRST [ MOVEI A,"; ;LAST CHAR OF ARG ISN'T SP OR TAB.
RET] ;MAKE SURE A HAS ";" IF ARG WAS ENDED BY ";".
RARGC3: SOS FREEPT ;IT IS ONE; BACK OVER IT.
MOVE A,FREPTB
DBPM A
MOVEM A,FREPTB
JRST RARGC2
;IGNORE THE REST OF THE ARG NOW BEING READ.
RARFLS: JSP D,RARGCH(T)
RET
JRST RARGCH(T)
;COME HERE TO SET UP TO READ A BALANCED ARG.
;IF THERE'S NO ARG, RETURNS WOTH JRST (D).
;ELSE RETURNS WITH JRST 1(D) SETTING UNRCHF.
RARB: TLO FF,FLUNRD
SETZ TT, ;TT USED AS BRACKET COUNTER.
CAIE A,RBRACE
CAIN A,") ;IF 1ST CHAR IS A CLOSE,
JRST RARB4 ;THERE'S NO ARG.
CAIE A,">
CAIN A,RBRKT
JRST RARB4
JSP T,RARGXT ;CHECK FOR CR, LF, SEMI, AND RETURN.
;1-CHAR RTN FOR READING BALANCED ARG.
RARBC: CALL RCH
CAIE A,RBRACE
CAIN A,"> ;FOR CLOSES, MAYBE END ARG.
JRST RARB2
CAIE A,")
CAIN A,RBRKT
JRST RARB2
CAIE A,LBRACE
CAIN A,"< ;FOR OPEN BRACKETS, INCR. THE COUNT.
AOJA TT,1(D) ;OPENS CAN'T END THE ARG.
CAIE A,"(
CAIN A,LBRKT
AOJA TT,1(D)
JUMPN TT,1(D)
JRST RARGX1 ;NOT WITHIN BRACKETS, TEST FOR COMMA, ETC.
RARB2: SOJGE TT,1(D) ;COME HERE FOR CLOSEBRKTS.
RARB4: TLO FF,FLUNRD
JRST (D)
;COME HERE TO INIT FOR AN ARG FOR REPEAT, ETC.
;THAT IS, EITHER A BRACKETED ARG OR A 1-LINE ARG.
RARL1: CALL RCH
RARL2:
IFN BRCFLG,[
RARL4: CAIN A,LBRACE
JRST RARGRR ;1ST CHAR A BRACE => BRACED ARG.
]
CAIN A,LBRKT ;1ST CHAR A BRKT => BRKT ARG.
JRST RARGBR
TLO FF,FLUNRD
;INIT FOR A 1-LINE ARG.
RARL: JSP T,1(D)
;1-CHAR RTN FOR 1-LINE ARGS.
RARLC: CALL RCH
JRST RARGX2
IFE BRCFLG,[
;IF BRACES AREN'T USED BY MOST THINGS, THE NORMAL ROUTINE RARL1 DOESN'T
;CHECK FOR THEM, BUT RALR4 (CALLED BY CONDITIONALS) STILL MUST.
RARL4: CAIN A,LBRACE
JRST RARGRR
JRST RARL2
]
;1-LINE ARGS TO MACROS: DON'T TERMINATE THE SPEC,
;AND SKIP OVER THE CR AND LF.
RARL3: TLO FF,FLUNRD
JSP T,1(D)
CALL RCH
CAIN A,^J
JRST (D) ;LF IS THE END - SKIP IT.
CAIE A,^M
JRST 1(D)
CALL RCH ;CR => SKIP FOLLOWING LF, END ARG.
CAIE A,^J
TLO FF,FLUNRD
JRST (D)
;PUSHJ P,A.GST SEARCH CURRENT MACRO STRING FOR TAG (IN A.GST4)
;SKIP IF FOUND, RETURN ON END OF STRING ANYWAY
;BYTE POINTER (ILDB TO GET FIRST CHARACTER) IN A
A.GST: MOVEM A,A.GST3 ;SAVE BYTE POINTER
A.GST1: ILDB B,A.GST3 ;GET CHAR
CAIL B,300
POPJ P, ;END OF STRING => STOP
CAIE B,".
JRST A.GST1 ;WAIT FOR POINT
PUSHJ P,A.GSYL ;FOUND POINT, GET REST OF NAME
JUMPL T,CPOPJ ;RETURN ON END OF STRING
CAME SYM,[SQUOZE 0,TAG] ;TAG?
JRST A.GST1 ;NO, KEEP GOING
PUSHJ P,A.GSYL ;GET THE TAG
JUMPL T,CPOPJ ;RETURN ON END OF STRING (THERE MUST BE BREAK CHAR AFTER TAG BEFORE STOP)
CAME SYM,A.GST4
JRST A.GST1 ;NOT THE ONE BEING LOOKED FOR
MOVE A,A.GST3
LDB B,A ;GET DELIMITER
CAIE B,15 ;CR?
JRST POPJ1
ILDB B,A ;CR, GET NEXT CHAR
CAIE B,12 ;LINE FEED?
MOVE A,A.GST3 ;NO, DON'T FLUSH
JRST POPJ1
;LOOK BACKWARD FOR BEGINNING OF STRING, BYTE POINTER AN A
;LEAVES POINTER POINTING AT STOP CHAR (NOT BEFORE); ALSO LEAVES STOP CHAR IN B
AG.SP: MOVE B,(A) ;GET WORD FROM MACTAB
XOR B,[300_28.+300_20.+300_12.+300_4] ;DO XOR TO ANITIALLY SET UP
LDB CH1,[400400,,A] ;PICK UP 4 HIGH ORDER BITS OF POSITION FIELD
JRST A.GSP2-1(CH1) ;DISPATCH ON POSITION FIELD (-1 SINCE BIT SET IN POSITION FIELD)
AG.SP3: MOVE B,(A)
XOR B,[300_28.+300_20.+300_12.+300_4]
A.GSP2: TRNN B,300_4
JSP CH1,AG.SF
TLNN B,3
JSP CH1,AG.SF
TLNN B,300_2
JSP CH1,AG.SF
TLNN B,300_10.
JSP CH1,AG.SF
SOJA A,AG.SP3
AG.SF: SUBI CH1,A.GSP2-1 ;GET HERE WHEN STOP CHAR FOUND
DPB CH1,[400400,,A] ;CLOBBER POSITION FIELD OF BYTE POINTER AGAIN
ILDB B,A ;INCREMENT TO UNIVERSALLY ACCEPTABLE POINTER, GETTING STOP CHAR IN B AT SAME TIME
POPJ P, ;THAT'S ALL
A.TAG: PUSHJ P,GSYL
CAIE T,15
JRST MACCR
PUSHJ P,RCH
CAIE A,12
TLO FF,FLUNRD
JRST MACCR
A.GO: PUSHJ P,GSYL ;DOESN'T WORK RELIABLY FROM DUMMY
MOVEM SYM,A.GST4
A.GO1: TLNN FF,FLMAC
JRST MACCR ;NOT GETTING CHARS FROM MACRO => STOP
MOVE A,CPTR
PUSHJ P,AG.SP ;BACK TO BEGINNING
CAIN B,374
JRST A.GOMC ;MACRO, SKIP PAST HEADER
A.GORT: PUSHJ P,A.GST
JRST A.GO2 ;END OF STRING, TRY POPPING UP ONE
MOVEM A,CPTR
JRST MACCR
A.GO2: PUSHJ P,PMACP
JRST A.GO1
A.GSYL: MOVNI D,100000 ;GET SYL FOR .GO WHILE LOOKING FOR TAG
MOVEM D,STRCNT ;STRCNT .LT. 0 SIGNAL FOR GSYL TO JRST (F)
MOVEI SYM,0
JSP F,GSYL1
A.GSY3: ILDB A,A.GST3 ;GET CHAR
TRZN A,200 ;CHECK FOR SPECIAL
JRST A.GSY2 ;NO, FALL BACK IN
CAIG A,100 ;BIG ENOUGH TO BE SPECIAL?
JRST A.GSY3 ;NO, MUST BE DUMMY, IGNORE
HRROI T,(A) ;SPECIAL => ASSUME STOP: T .LT. 0 SIGNAL TO CALLING ROUTINE
POPJ P, ;RETURN TO CALLING ROUTINE
;INITIALIZE MACRO STATUS
MACINI: MOVEI A,3
MOVEM A,FREEPT ;FORGET ALL STRINGS IN MACTAB
PUSHJ P,FCOMP
MOVE A,MACTAD
HRLI A,41000 ;SET UP CCOMPB THRU CCOMPE
LSH A,2 ;(THEIR VALUES CAN'T BE ASSEMBLED IN BECAUSE
SUBI A,4 ;THEY ARE MUTLTIPLY RELOCATABLE, AND IN DEC
MOVSI AA,CCOMPB-CCOMPE ;VERSION THAT CAN'T BE DONE)
MACIN0: MOVEM A,CCOMPB(AA)
AOJ A,
AOBJN AA,MACIN0
MOVE A,MACTAD
ADDI A,MACL+1777
ANDI A,-2000 ;ADDR OF 1ST WD AFTER MACTAB.
CALL MACIN2 ;SET UP PTRS TO END OF MACTAB.
SETZM GCCNT ;CLEAR OUT GC COUNT SO WILL GET MORE CORE FIRST THREE
MACIN1: SETZM MDEPTH ;NOW INITIALIZE MACRO EXPANSION STATUS
SETZM PRSTG ;NOW TO CLEAR OUT BYTE POINTERS
MOVE A,[PRSTG,,PRSTG+1]
BLT A,EPRSTT-1
MOVEI A,DSTG
MOVEM A,RDWRDP
MOVEI A,DMYAGT
MOVEM A,TOPP
MOVEM A,BBASE
MOVE A,[-MPDLL,,MACPDL]
MOVEM A,MACP
POPJ P,
;A -> 1ST WD AFTER MACTAB, SET UP ALL POINTERS TO END OF MACTAB.
MACIN2: MOVEM A,MACTND
SUB A,MACTAD
LSH A,2 ;1ST BYTE MACTAB DOESN'T HAVE.
MOVEM A,MACHI
SUBI A,MACRUM*4
MOVEM A,GCRDHI
MOVE A,STOPPT
HRR A,MACTND
SOS A ;LAST WD IN MACTAB.
MOVEM A,MACHIB ;INITIALIZE BYTE POINTER TO HIGHEST BYTE OK TO FILL
RET
;MACRO VARIABLE AREA (MOST THEREOF)
VBLK
MACP: 0 ;MAC PDL POINTER
BLCODE [MACPDL: BLOCK MPDLL+1] ;MACRO PDL
FREEPT: 0 ;MACRO STG PNTR POINTS TO FREE CHAR
FREPTB: 0 ;FREEPT IN BYTE POINTER FORM
MACTAD: MACTBA ;ADDR OF START OF MACRO TABLE.
MACTND: 0 ;ADDR OF 1ST WD AFTER MACTAB.
MACHI: 0 ;CHAR ADR ONE ABOVE ACTIVE MACTAB
MACHIB: 0 ;POINTS TO LAST BYTE IN MACTAB
SCONDF: 0 ;STRING CONDITIONAL FLAG, -1 => IDENTICAL, 0 DIFFERENT
GENSM: 0 ;GENERATED SYM COUNT
DEFNPS: 0 ;NONZERO => NAME OF PSEUDO NOW READING ITS ARG.
;A FATAL ERROR WILL TYPE THE PSEUDO'S NAME.
DEFNPN: 0 ;PAGE # -1 OF THAT PSEUDO. ALSO TYPED BY FATAL ERRORS.
DEFNLN: 0 ;LINE # -1.
DEFNFI: 0 ;SIXBIT FN1 OF FILE CONTAINING PSEUDO THAT DEFNPS REFERS TO.
MDEPTH: 0 ;DEPTH IN MACRO (NOT IRP OR REPEAT) EXPANSIONS
PUTCNT: 0 ;AOS'D BY PUTREL, USED BY CALLING ROUTINE, USUALLY TO COUNT ACTIVE CHARS (DURING DEFINITION)
IRPCR: 0 ;COUNT OF A,B,[LIST] GROUPS IN IRP IRPC IRPS, " " "
AIRPT: 0 ;IRP EXPANSION TEMP, -1 => NO NON-NULL DUMMYS YET, ELSE 0
AIRPN0: 0 ;1ST NUMERIC ARG TO IRPNC
AIRPN1: 0 ;2ND,
AIRPN2: 0 ;3RD.
A.QOT2: 0 ;DELIMITER FOR .QUOTE
CRPTCT: -1 ;COUNT THROUGH CURRENT REPEAT (FOR .RPCNT)
CIRPCT: -1 ;COUNT THOUGH CURRENT IRP (FOR .IRPCNT)
A.GST3: 0 ;ON .GO, NAME (IN SQUOZE) OF TAG BEING SEARCHED FOR
A.GST4: 0 ;BYTE POINTER FOR ILDB WHILE SEARCHING FOR TAG
PRCALP: PRCAL-1 ;POINTER INTO PRCALP, POINTS TO LAST ACTIVE ENTRY
PRSTG: ;BEGIN WORDS GARBAGE COLLECTED: FIRST BYTE POINTERS ILDB'D
CPTR: 0 ;ILDB TO GET NEXT CHAR FROM MACRO OR WHATEVER
IFE WRQTSW-1,WRQTBP: 0 ;POINTS TO LAST CHAR BEFORE CURRENT SYL AT WRQOTE
AIRPSP: 0 ;-> PLACE TO STORE SYL-TERMINATOR, IN IRPS READIN.
GCBPL==.-PRSTG ;END BYTE POINTERS, BEGIN CHARACTER ADDRESSES
PRSCND: 0 ;CHARACTER ADDRESS OF CURRENT LOCATION IN FIRST STRING OF IFSE,IFSN WHILE COMPARING WITH SECOND
PRSCN1: 0 ;CHAR ADR BEG OF FIRST STRING IFSE, IFSN
PRREPT: 0 ;CHAR ADR BEG OF BODY OF REPT
PRIRP: 0 ;CHAR ADR BEG OF IRP BODY
PRDEF: 0 ;CHAR ADR BEG OF MACRO BEING DEFINED
PRCAL: REPEAT 10,0 ;TEMP STORAGE FOR CHAR ADR BEG MACRO BODY, USED TO READ DUMMY SPECS
EPRSTT: ;END CHAR ADR WORDS GARBAGE COLLECTED
;BEGIN GARBAGE COLLECTOR VARIABLES
GCCNT: 0 ;CNT OF GC'S
SYMSTR: 0 ;PNTR TO CHAIN OF MACRO PNTRS IN SYM TABLE (DURING GC), LINKED THROUGH RH'S OF "VALUE"
REDPT: 0 ;CHAR ADR READING FROM WHEN MOVING STRING DOWN
REDPTB: 0 ;REDPT IN BYTE POINTER FORM
;GC WRITES WITH FREEPT/FREPTB
COFST: 0 ;AMOUNT CHARS MOVED DOWN BY, SUBTRACTED FROM CHAR ADR TO RELOCATE
SVF: 0 ;FLAG, .GE. 0 => NO POINTERS FOUND POINTING TO CURRENT STRING
FREPTS: 0 ;-> BEGINNING OF CURRENT STRING BEING COPIED DOWN
FRPTBS: 0 ;FREPTS IN BYTE POINTER FORM
GCENDF: 0 ;-1 => END OF LAST STRING FOUND, AFTER RELOCATING POINTERS, MSTG2 SHOULD EXIT
GCHI: 0 ;GC HIGH POINTER, CHAR ADR FIRST NOT TO GARBAGE COLLECT
GCRDHI: <MACL-MACRUM>*4 ;GC DROPS DEAD (MACTAB FULL) IFWRITING INTO THIS CHAR ADR
BLCODE [GCSV: BLOCK 16] ;AC SAVE AREA FOR GC
PBLK
;GARBAGE COLLECT THE MACRO TABLE
GCA1: MOVE A,FREEPT ;GC ALL IN MACTAB.
GCA: MOVEM A,GCHI ;ENTRY TO STORE A IN GCHI -> FIRST CHAR NOT TO GARBAGE COLLECT
IFN 17-P+FF,.ERR GC ac saver wants FF=0, P=17!
GC: MOVEM 16,GCSV+15 ; Save all ACs except FF and P.
MOVE 16,[1,,GCSV]
BLT 16,GCSV+14
IFN TS,[AOS A,GCCNT
CAIGE A,4
PUSHJ P,GCCORQ ;EXPAND CORE ON FIRST THREE GC'S
] CLEARB T,GCENDF
MOVEI A,3
MOVEM A,REDPT ;SET UP FOR READING
MOVEM A,FREEPT ;ALSO FOR WRITING
MOVE A,BCOMPU ;ALSO SET UP CORRESPINDING BYTE POINTERS
MOVEM A,FREPTB
MOVEM A,REDPTB
MOVE C,[-GCBPL,,PRSTG]
GCLP1: SKIPN B,(C) ;NOW CONVERT BYTE POINTERS...
JRST GCLP1B ;(INACTIVE)
CCOMP B,-1 ;TO CHARACTER ADDRESSES
MOVEM B,(C) ;STORE BACK CHARACTER ADDRESS
GCLP1B: AOBJN C,GCLP1 ;LOOP FOR ALL SUCH BYTE POINTERS
MOVE A,SYMAOB ;NOW SET UP MACRO LIST; T INITIALLY HAS 0 => END OF LIST DURING COMPUTATION
SYMMG: ;POINTS TO FIRST MACRO SYMTAB ENTRY ON LIST
LDB B,[400400,,ST(A)] ;GET SQUOZE FLAGS THIS SYM
CAIN B,PSUDO_-14. ;PSEUDO? (=> MAYBE MACRO)
JRST SYMMG1 ;YES, MAYBE PUT ON LIST (RETURNS TO SYMMG2)
SYMMG2: ADD A,WPSTE1
AOBJN A,SYMMG ;LOOP FOR ENTIRE SYMTAB
MOVEM T,SYMSTR ;STORE INITIAL LIST ENTRY FOR MACROS
;DROPS THROUGH
;GC DEALS WITH "UNIT STRINGS", EACH STRING ENDS WITH 375
;GENERAL PROCEDURE IS TO COPY A STRING DOWN THEN SEARCH FOR POINTERS TO WHERE STRING USED TO BE
;IF POINTERS FOUND THEY ARE RELOCATED TO POINT TO COPIED DOWN STRING
;IF POINTERS ARE NOT FOUND THE STRING IS WIPED OUT
;DROPS THROUGH
MSTG: MOVE C,REDPT ;SET UP C TO POINT TO BEG OF STRING BEING READ
;(FOR EVENTUALLY SEARCHING FOR POINTERS TO STRING, NOTE C STAYS AROUND FOR AWHILE)
MOVE TT,FREEPT
CAML TT,GCHI ;IF ALL OF ACTIVE PART OF MACTAB ALREAD GC'D, STOP NOW.
JRST GCEND
MOVEM TT,FREPTS ;-> BEGINNING OF WRITTEN STRING
MOVE TT,FREPTB
MOVEM TT,FRPTBS ;BYTE POINTER -> BEGINNING OF WRITTEN STRING
PUSHJ P,RDTRNS ;COPY CHARACTER
CAIN B,370
JRST MSTGB ;THAT WAS NO STRING, THAT WAS MY IO-BUFFER!
MOVE TT,B ;SAVE CHARACTER JUST COPIED
MSTG1: CAML LINK,GCHI
JRST GCEND ;JUST READ LAST CHAR IN PART OF MACTAB TO GARBAGE COLLECT => DONE
CAIN B,375
JRST MSTG2 ;END THIS STRING, NOW SEARCH FOR POINTERS, RETURNS TO MSTG
PUSHJ P,RDTRNS ;STRING NOT EXHAUSTED, COPY NEXT CHAR
JRST MSTG1
SYMMG1: HRRZ B,ST+1(A) ;PSEUDO FOUND IN SYMTAB, GET "VALUE"
CAIE B,MACCL ;MACCL? (=> MACRO, CHAR ADR OF BODY IN LH)
JRST SYMMG2 ;NO, JUST FALL BACK INTO LOOP
HRRM T,ST+1(A) ;MACRO, REPLACE MACCL PART OF VALUE WITH POINTER TO NEXT
MOVEI T,ST+1(A) ;UPDATE T (INITIAL LIST ENTRY) TO POINT TO WORD JUST CLOBBERED
PUSH P,A
HLRZ A,ST+1(A)
PUSHJ P,REDINC
CAIE B,374
GOHALT
POP P,A
JRST SYMMG2
;COPY CHARACTER DOWN (REDPTB -> FREPTB)
;LEAVE INCREMENTED REDPT IN LINK, FREEPT IN A, CHAR IN B
RDTRNS: ILDB B,REDPTB
IDPB B,FREPTB
AOS LINK,REDPT
AOS A,FREEPT
POPJ P,
MSTGB: ADDI A,3 ;COPY AN IO-BUFFER:
TRZ A,3
MOVEM A,FREEPT ;WRITE INTO WORD BOUNDARY.
ADDI LINK,3
TRZ LINK,3
MOVEM LINK,REDPT ;READ FROM WORD BOUNDARY.
MOVEI B,041000
HRLM B,REDPTB
HRLM B,FREPTB
MOVE B,FREPTB
MOVE A,REDPTB
ADDI B,1 ;NEW ADDR OF 1ST WD.
HRRZ LINK,1(A) ;GET ADDR OF POINTER TO STRING.
MOVEM LINK,SVF ;REMEMBER WHETHER TO FLUSH STRING.
SKIPE LINK
HRRM B,(LINK) ;RELOCATE THAT POINTER (IF ANY)
HRLI B,1(A) ;SET UP AC FOR BLT.
HLRZ LINK,1(A) ;GET LENGTH OF STRING.
ADDM LINK,REDPTB
LSH LINK,2
ADDM LINK,FREEPT
ADDM LINK,REDPT
LSH LINK,-2
ADDB LINK,FREPTB
BLT B,(LINK)
MOVE LINK,REDPT
CAML LINK,GCHI ;IF THIS IO-BUFFER IS LAST THING IN MACRO SPACE,
SETOM GCENDF ;DON'T LOOK FOR ANYTHING FOLLOWING IT.
JRST MSTGB1 ;NOW MAYBE FLUSH THIS STRING, COPY NEXT.
;GET HERE WHEN MSTG2 FINISHES WITH FLAG SET TO EXIT: UNDO INITIALIZATION AND RETURN
GCEND1: IFN TS,[
MOVE A,FREEPT
ADDI A,2000*4
CAML A,MACHI
PUSHJ P,GCCORQ
] MOVE A,FREEPT
CAML A,GCRDHI
ETF [ASCIZ /Macro space full/]
SKIPN T,SYMSTR
JRST USYMG1 ;EMPTY LIST
MOVEI C,MACCL ;SET UP C FOR HRRM'ING
USYMG: HRRZ TT,(T) ;GET ADR ON LIST
HRRM C,(T) ;CLOBBER RH JUST GOT NEXT POINTER FROM TO MACCL
HLRZ A,(T)
PUSHJ P,REDINC
CAIE B,374
GOHALT
SKIPE T,TT ;MAKE NEXT POINTER CURRENT, SKIP IF END OF LIST
JRST USYMG
USYMG1: MOVE C,[-GCBPL,,PRSTG]
GCLP2: MOVE A,(C) ;NOW CONVERT CHARACTER ADDRESSES...
BCOMP A,-1 ;BACK TO BYTE POINTERS
MOVEM A,(C)
AOBJN C,GCLP2
IFN 17-P+FF,.ERR GC AC restorer wants FF=0 and P=17!
MOVS 16,[1,,GCSV] ; Restore all ACs except FF and P.
BLT 16,16
POPJ P, ;EXIT FROM GARBAGE COLLECTOR
;GC ROUTINE TO SCAN TABLE AREA FOR POINTERS TO CURRENT STRING
;CH1 -> BEGINNING OF TABLE, 4.9 => LOOK AT PAIRS SKIPPING SECOND OF EACH PAIR
;T POINTS TO LAST WORD IN TABLE + 1
;RELOCATE POINTERS IN TABLE POINTED TO
;C POINTS TO BEGINNING OF STRING, B -> END + 1
MSCN: CAIG T,(CH1)
POPJ P, ;TABLE EXHAUSTED
HRRZ TT,-1(T) ;GET LAST ENTRY IN TABLE (UPPER POINTER UPDATED TO COUNT DOWN)
CAML TT,C
CAML TT,B
JRST MSCN1 ;DOESN'T POINT TO CURRENT STRING
SUB TT,COFST ;POINTS TO STRING, RELOCATE
HRRM TT,-1(T) ;STORE BACK RELOCATED POINTER
SETOM SVF ;SET FLAG TO SAVE STRING
MSCN1: SKIPGE CH1
SOS T ;CH1 NEGATIVE => SKIP A WORD
SOJA T,MSCN
GCEND: SETOM GCENDF ;DONE READING FROM MACTAB, BUT FIRST HAVE TO RELOCATE POINTERS TO LAST STRING
MSTG2: CLEARM SVF ;NO POINTERS FOUND TO STRING YET
MOVE D,REDPT
SUB D,FREEPT
MOVEM D,COFST ;STORE AMOUNT CHARS COPIED DOWN BY FOR CHAR ADR RELOCATION
MOVE B,REDPT
CAIE TT,374
JRST MSTG3 ;NOT A MACRO
MOVE T,SYMSTR
JUMPE T,MSTG3 ;JUMP IF NO MACROS ON LIST
MSTG5: HLRZ TT,(T) ;GET CHAR ADR THIS MACRO
CAML TT,C ;SKIP IF POINTS BELOW BEGINNING THIS STRING
CAML TT,B ;SKIP UNLESS POINTS TO OR ABOVE FIRST CHAR NOT YET READ
JRST MSTG4 ;DOESN'T POINT TO THIS STRING
SETOM SVF ;POINTS TO THIS STRING, SET FLAG TO SAVE STRING
SUB TT,COFST ;RELOCATE
HRLM TT,(T) ;STORE BACK UPDATED CHAR ADR THIS MACRO
MSTG4: HRRZ T,(T) ;NOW GET POINTER TO NEXT MACRO
JUMPN T,MSTG5 ;LOOP FOR ALL MACROS ON LIST
MSTG3: MOVE T,TOPP
MOVEI CH1,DMYAGT
PUSHJ P,MSCN ;RELOCATE POINTERS IN DUMMY ARG TABLE
HRRZ T,MACP
HRROI CH1,MACPDL
PUSHJ P,MSCN ;RELOCATE POINTERS IN MACRO PDL
HRRZ T,PRCALP
AOS T
MOVEI CH1,PRSTG
PUSHJ P,MSCN ;RELOCATE POINTERS IN PRSTG
HRRZ T,RDWRDP
MOVEI CH1,DSTG
PUSHJ P,MSCN ;RELOCATE DUMMY ARGS READ (OR BEING READ) IN BUT NOT YET ACTIVATED
SKIPGE GCENDF
JRST GCEND1 ;EXIT
MSTGB1: SKIPE SVF
JRST MSTGB2 ;FOUND POINTERS TO THIS STRING, DON'T FLUSH
MOVE TT,FREPTS ;NO POINTERS FOUND, FLUSH STRING
MOVEM TT,FREEPT
MOVE TT,FRPTBS
MOVEM TT,FREPTB
MSTGB2: SKIPGE GCENDF ;IF WE JUST HACKED AN I-O BUFFER, MAYBE IT'S THE LAST
JRST GCEND1 ;THING IN MACRO SPACE.
JRST MSTG
] ;END MACSW CONDITIONAL (AND MACRO PROCESSOR ROUTINES)
IFN .I.FSW,[ ;;.I.F ;ALGEBRAIC COMPILER ROUTINE
; 'ALGEBRAIC' CRUFT MARO DEFINITIONS
DEFINE MOAN ARG/
MOVEI D,[SIXBIT /ARG!!/]
JRST ERRCON
TERMIN
DEFINE RETLIN
MOVEI A,15 ;CARRIAGE RETURN
PUSHJ P,PUTREL
MOVEI A,12 ;LINE FEED
PUSHJ P,PUTREL
TERMIN
DEFINE NUMBER
MOVE A,BTPNT
ILDB I,A
CAIE I,"#
CAIGE I,"@
TERMIN
DEFINE RESTOR
MOVE D,BTPNT
SETZM STRING
SETZM STRING+1
SETZM STRING+2
TERMIN
DEFINE SPECN
POP P,RANDM
MOVE A,ENN
SUB A,RANDM
MOVEM A,ENN
TERMIN
DEFINE $GET
EXCH I,ACSVI
PUSHJ P,RCH
EXCH I,ACSVI
TERMIN
DEFINE GETT
EXCH I,ACSVI
PUSHJ P,RCH
EXCH I,ACSVI
IDPB A,TPN
TERMIN
; START OF COMPILER PROPER
OPDL: CH?CH?CH?CH?CH?CH?CH?CH ;COMMUTATOR
CH?SP?CH?CH?CH?CR?CH?CH
CH?CH?CH?CH?CH?CH?CH?CH
CH?CH?CH?CH?CH?CH?CH?CH
SP?CH?CH?CH?DL?CH?CH?CH
LP?RP?TX?PL?CM?MN?CH?DV
CH?CH?CH?CH?CH?CH?CH?CH
CH?CH?CH?KL?LB?EQ?RB?CH
; CH?CH?CH?CH?CH?CH?CH?CH
; CH?CH?CH?CH?CH?CH?CH?CH
; CH?CH?CH?CH?CH?CH?CH?CH
; CH?CH?CH?CH?CH?CH?UP?CH
; CH?CH?CH?CH?CH?CH?CH?CH
; CH?CH?CH?CH?CH?CH?CH?CH
; CH?CH?CH?CH?CH?CH?CH?CH
; CH?CH?CH?CH?CH?CH?CH?CH
VBLK
ENN: 60 ;ACCUMULATOR NUMBER - TROUBLE IF GOES PAST 9
BTPNT: 440700,,STRING ;D
STRING: BLOCK 10 ;CHARACTER ASSEMBLY (D) - TROUBLE IF OVERFLOWS
TPN: 0
DIRPNT: 440700,,DIROUT ;TPN
DIROUT: BLOCK 40 ;COPY OF LINE IN PROGRESS (TPN) - TROUBLE IF OVERFLOWS
OPSTKL==40
0
OPSTK: BLOCK OPSTKL ;OPERATOR STACK (R) - TROUBLE IF OVERFLOWS
0
ENDSTT: 0 ;ON IF END OF STATEMENT ENCOUNTERED
CHARF: 0 ;LAST WAS NOT OPERATOR
NUMFL: 0 ;STRING IS NUMERIC CONSTANT (NEEDS [ AND ])
R1SV: 0 ;SAVED A
R2SV: 0 ;SAVED I, CALLED V EARLIER ON
INTEGR: 0 ;INTEGER ARITHMETIC
WARN: 0 ;ON AFTER ) TO STOP NON-OPERATOR
RANDM: 0 ;DUMP COMMA COUNT HERE
TEMP: 440600,,(D) ;INDIRECT VIA D
BYTPNT: 0
; Save 7 acs here, done by move(m)s for robustness
IRP AC,,[AA,A,B,C,D,I,P]
ACSV!AC: 0
TERMIN
PBLK
; ENTRANCE TO 'ALGEBRAIC' TRANSLATOR
A.I: SETOM INTEGR
SKIPA
A.F: SETZM INTEGR
PUSHJ P,SWINI ;INITIALISE PASSAGE TO MIDAS ASSEMBLER
IRP AC,,[AA,A,B,C,D,I,P]
MOVEM AC,ACSV!AC
TERMIN
SETZM ENDSTT ;RESET END OF STMNT FLAG
SETZM EQHIT' ;RESET LAST CHAR WAS= FLAG
SETZM WARN ;SET OFF ERROR DETECTOR
MOVEI A,"0 ;INITIALISE POINTERS
MOVEM A,ENN
MOVE A,DIRPNT
MOVEM A,TPN ;POINTER TO SAVED INPUT
MOVE SYM,[-OPSTKL,,OPSTK]
PUSH SYM,[0,,ENDSAT]
PUSH P,[0] ;INITIALISE COMMA-COUNTER
SETZM CHARF
CLSTR: RESTOR
RDITTS: SKIPE ENDSTT
JRST BDEND
RDITA: GETT
CAIGE A,100 ;FOR ABBREVIATED DISPATCH TABLE
JRST @OPDL(A)
CAIN A,"\
JRST AB
CAIN A,"^
JRST UP
CH: SETZM EQHIT
SKIPE WARN
JRST CHBRT
CHEY: IDPB A,D
SETOM CHARF ;NON UNARY FLAG
JRST RDITA
GAMB: RESTOR
COMMT: MOVE I,R2SV
JRST GOPURT
SHORT: ;DECIDES IF STRING CAN BE USED IN IMMEDIATE TYPE OPS
SETZM IMMED'
SKIPN STRING
POPJ P, ;NO STRING
MOVE A,BTPNT
ILDB I,A
CAIN I,"#
JRST APUPJ ;YEPE HE ASKED FOR IT
SKIPE STRING+1
POPJ P, ;STRING IS LONG
SKIPA
TSTSHL: ILDB I,A
JUMPE I,APUPJ ;ITS OK FOUND ONLY NUMBERS
CAILE I,"@
POPJ P, ;NON-NUMBER IN STRING
CAIE I,".
JRST TSTSHL
ILDB I,A
SKIPN I ;ANYTHING FOLLOW '.' QST
APUPJ: SETOM IMMED' ;INDICATE IMMEDIATE USAGE IS POSSIBLE
POPJ P,
SZPRT: SETZM CHARF
GOPRT: SETZM WARN
GOPART: MOVEM I,R2SV
GOPURT: HLRZ B,I
HLRZ C,(SYM)
CAMLE B,C
JRST PSOPR ;GO PUSH OPERATOR
SKIPN INTEGR
SETOM IMMED ;FOR ARITH OPS ONLY FIXED WILL DO IMMEDIATE
PUSHJ P,SHORT ;ESTABLISH IF STRING CAN BE IMMEDIFIED
POP SYM,A ;POP AN OPERATOR
JUMPN A,(A)
MOAN OVERPOPPED OPERATOR STACK
CHEX: MOVE A,R1SV
JRST CHEY
RP: SKIPE EQHIT
AOS ENN ;TAKE CARE OF UNSATISFIED = AT END
SKIPN CHARF
JRST RTONOP
SETOM CHARF
BUDDY: SETOM WARN
MOVEI I,RPAR
JRST GOPART
RTONOP: MOVE I,(SYM)
CAIN I,FUNCT
JRST BUDDY ;NO ARGUMENT FUNCTION
MOAN ) FOLLOWS OPERATOR
BDEND: MOAN TOO MANY ('S
CHBRT: MOAN NON-OPERATOR FOLLOWS )
CR: SKIPE EQHIT
AOS ENN ;HANDLES UNSATISFIED = AT END
SETOM ENDSTT
MOVEI I,RCAR
JRST GOPRT
LP: SETZM EQHIT
SKIPE WARN
JRST LFRHT
SETZM CHARF
SKIPE STRING
JRST INDX
PUSH P,[0] ;INITIALISE COMMA-COUNTER
PUSH SYM,[0,,LFTPR]
JRST RDITA
INDX: NUMBER
JRST NUSTRB
GETT
CAIG A,"9
JRST NMRINX
MOVEI I,"(
IDPB I,D
INDY: IDPB A,D
GETT
CAIN A,"+ ;IS IT COMPOUND SUBSCRIPT
JRST CMPNDN
CAIN A,"-
JRST CMPNDN
CAIE A,") ;SEARCH FOR NEXT RP
JRST INDY
IDPB A,D
CMBAN: SETOM CHARF ;MAKE BELIEVE CHARATER LAST
SETOM WARN ;YET SET ) TRAP
JRST RDITA
NMRINX: CAIN A,"- ;IS IT A MINUS
JRST INDZ
CAIN A,"+
JRST INDZ
MOVEI I,"+ ;NUMERICAL SUBSCRIPT
IDPB I,D
INDZ: IDPB A,D
GETT
CAIN A,"+ ;IS IT COMPOUND SUBSCRIPT
JRST CMPNDC
CAIE A,")
JRST INDZ
JRST CMBAN
CMPNDN: MOVEI I,")
IDPB I,D
JRST INDZ
CMPNDC: MOVEI I,"(
IDPB I,D
JRST INDY
LFRHT: MOAN ( FOLLOWS DIRECTLY ON )
SP=RDITA ;USE FOR NON ARITH STATS
CM: MOVE I,[1,,COMMX]
SKIPN CHARF
AOS ENN
JRST SZPRT
EQ: SETOM EQHIT
SETZM WARN
SKIPN CHARF ;TEST FOR EXISTANCE OF L H S
JRST EQFLOP
NUMBER ;IS L H S A NUMBER
JRST EQNUMB
MOVEI I,EQAAL
EQVAL: SETZM CHARF
PUSH SYM,I
PUSH P,STRING
PUSH P,STRING+1
PUSH P,STRING+2
PUSH P,[0]
JRST CLSTR
PL: MOVE I,[2,,PLUS]
SKIPN CHARF
JRST RDITA ;UNARY PLUS
JRST SZPRT
MN: MOVE I,[2,,MINUX]
SKIPN CHARF
MOVE I,[5,,UMINU]
JRST SZPRT
AB: SKIPE CHARF ;ABSOLUTE VALUE
JRST ABERR ;NOT UNARY
MOVE I,[5,,UABS]
JRST SZPRT
LB: SKIPN CHARF
JRST LP ;TREAT LIKE (
NUMBER
JRST NUBRST
MOVEI I,FUNCT
JRST EQVAL
RB=RP
NUBRST: MOAN '<' FOLLOWS NUMBER
NUSTRB: MOAN '(' FOLLOWS NUMBER
EQFLOP: MOAN '=' FOLLOWS OPERATOR
EQNUMB: MOAN '=' FOLLOWS NUMBER
ABERR: MOAN NON-UNARY ABS
TX: MOVE I,[4,,TIMES]
SKIPN CHARF
JRST RDITA ;UNARY TIMES
JRST SZPRT
DL: $GET ;CONTINUE STATEMENT RC
$GET ;LF
$GET ;.
CAIE A,". ;DOT
JRST BDCONT
$GET ;F OR I
$GET ;CONTROL I OR SPACE
MOVE A,DIRPNT
MOVEM A,TPN ;RESET SAVED INPUT POINTER TO AVOID FILLING ITS BUFFER
MOVEI A,"$
IDPB A,TPN
MOVEI A,40
IDPB A,TPN
JRST RDITA
ERRCON: TRNE FF,FRPSS2 ;NO OUTPUT ON SECOND PASS
JRST CONRBT
;MAY ALSO WANT TO USE STATEMENT PLUS LINE NUMBER TYPE TACTIC
MOVE B,DIRPNT
OUTRR: ILDB A,B
PUSHJ P,TYO
CAME B,TPN
JRST OUTRR
SKIPE ENDSTT
JRST CONERT
DORSTL: MOVEI A,40
PUSHJ P,TYO
MOVEI A,"? ;POINT AT ERROR
PUSHJ P,TYO
MOVEI A,40
PUSHJ P,TYO
DORSAL: $GET ;COPY UP TO LINE FEED
PUSHJ P,TYO
CAIE A,12 ;LF
JRST DORSAL
CONERT: PUSHJ P,TIPIS
PUSHJ P,CRR
CONRAT:
IRP AC,,[AA,A,B,C,D,I,P]
MOVE AC,ACSV!AC
TERMIN
JRST SWFLS ;GO BACK AND FLUSH
CONRBT: $GET
CAIE A,12 ;LF
JRST CONRBT
JRST CONRAT
UP: SKIPN WARN ;FOR (NUMBER)^N
SKIPN STRING
JRST ITSEX
MOVEM A,R1SV ;SAVE THE ARROW
NUMBER
JRST CHEX ;ITS PART OF A NUMBER
ITSEX: MOVE I,[6,,STRSTR]
SKIPN CHARF
JRST EXMB
JRST SZPRT
EXMB: MOAN UNARY ^
BDCONT: MOAN BAD CONTINUATION
KL=CR ;SEMICOLON ACTS LIKE CR IN TERMINATING
STRSTR: SKIPN STRING
JRST EXLS
NUMBER
SKIPA
JRST EXLS
SUBI I,61
TDNE I,[-1,,777774]
JRST EXLS
MOVE A,STRING
TDNE A,[3777,,-1]
JRST EXLS
ADDI I,POWR
JRST @(I)
EXLS: PUSH P,[ASCII !EXPLO!]
PUSH P,[ASCII !G !]
PUSH P,[0]
PUSH P,[1]
SETOM EXRET'
JRST FUNET
DV: MOVE I,[4,,DIVIX]
SKIPN CHARF
MOVE I,[5,,UDIVI]
JRST SZPRT
PSOPR: PUSH SYM,I ;PUSH OPERATOR FOR LATER EXCECUTION
SKIPN STRING
JRST RDITTS
PUSHJ P,SHORT ;CAN WE IMMEDIFY
PUSHJ P,MVOI ;AND MOVE OPERAND INTO STACK
JRST CLSTR
PRODB: NUMBER ;OUTPUT WHAT IS IN STRING
SKIPE IMMED ;NO [ & ] IF IMMEDIATE USE
JRST OVNM
PUSH P,A
MOVEI A,"[ ;[ FOR CONSTANT
PUSHJ P,PUTREL
POP P,A
SETOM NUMFL
OVNM: CAIN I,"#
JRST PRDOC
EXCH A,I
PUSHJ P,PUTREL
MOVE A,I
PRDOC: ILDB I,A
JUMPN I,OVNM
SKIPN NUMFL
POPJ P,
MOVEI A,"] ;] FOR CONSTANT
PUSHJ P,PUTREL
SETZM NUMFL
POPJ P,
PRODC: HRLI A,440700 ;MAKE BYTE POINTER
JRST PRDOC
LFTPR: SPECN
JRST RDITTS ;IGNORE LP ON STACK
RCAR: GOHALT ;IMPOSSIBLE FOR THESE TO BE ON STACK
RPAR: GOHALT
EQAAL: SPECN
SKIPE STRING
PUSHJ P,MVOI
MOVEI A,[ASCIZ ! MOVEM A!]
PUSHJ P,PRODC
POP P,STRING+2
POP P,STRING+1
POP P,STRING
MOVE A,ENN
SOS A
PUSHJ P,FINOF
JRST GAMB
ENDSAT: SPECN
SKIPN ENDSTT
JRST TOEARL
SKIPE STRING
PUSHJ P,MVOI
GETLF: $GET
CAIE A,12 ;LF
JRST GETLF
IRP AC,,[AA,A,B,C,D,I,P]
MOVE AC,ACSV!AC
TERMIN
JRST SWRET ;GO BACK
MVOI: MOVE A,BTPNT
ILDB I,A
CAIN I,"&
JRST MVOALR ;OPERAND ALREADY THERE
MOVEI A,[ASCIZ ! MOVE A!]
SKIPE IMMED
MOVEI A,[ASCIZ ! MOVEI A!]
MVOIK: PUSHJ P,PRODC
MOVE A,ENN
AOS ENN
FINOF: PUSHJ P,PUTREL
MOVEI A,",
PUSHJ P,PUTREL
PUSHJ P,PRODB
RETLIN
POPJ P,
MVOALR: AOS ENN
POPJ P,
TOEARL: MOAN TOO MANY )'S
PLUS: MOVEI A,[ASCIZ ! FADR A!]
SKIPE INTEGR
MOVEI A,[ASCIZ ! ADD A!]
SKIPE IMMED
MOVEI A,[ASCIZ ! ADDI A!]
OPERT: PUSHJ P,PRODC
SKIPE STRING
JRST GAINS
SOS ENN
OPRTE: MOVE A,ENN
SOS A
PUSHJ P,PUTREL
PUSHJ P,COMMAA
MOVE A,ENN
PUSHJ P,PUTREL
RETLIN
JRST COMMT
COMMAA: MOVEI A,",
PUSHJ P,PUTREL
MOVEI A,"A
JRST PUTREL
GAINS: MOVE A,ENN
SOS A
PUSHJ P,FINOF
JRST GAMB
MINUX: MOVEI A,[ASCIZ ! FSBR A!]
SKIPE INTEGR
MOVEI A,[ASCIZ ! SUB A!]
SKIPE IMMED
MOVEI A,[ASCIZ ! SUBI A!]
JRST OPERT
TIMES: PUSHJ P,TMSTR
SKIPE IMMED
MOVEI A,[ASCIZ ! IMULI A!]
JRST OPERT
DIVIX: MOVEI A,[ASCIZ ! FDVR A!]
SKIPE INTEGR
MOVEI A,[ASCIZ ! IDIV A!]
SKIPE IMMED
MOVEI A,[ASCIZ ! IDIVI A!]
JRST OPERT
UMINU: CAMN B,C
JRST BAKWD ;THESE HAVE TO BE STACKED REVERSE
SKIPE STRING
JRST MOABC
MOVEI A,[ASCIZ ! MOVNS A!]
UMINUC: PUSHJ P,PRODC
MOVE A,ENN
SOS A
PUSHJ P,PUTREL
RETLIN
JRST COMMT
MOABC: MOVEI A,[ASCIZ ! MOVN A!]
SKIPE IMMED
MOVEI A,[ASCIZ ! MOVNI A!]
PUSHJ P,MVOIK
JRST GAMB
UABS: CAMN B,C
JRST BAKWD
SKIPE STRING
JRST MOABS
MOVEI A,[ASCIZ ! MOVMS A!]
JRST UMINUC
MOABS: MOVEI A,[ASCIZ ! MOVM A!]
SKIPE IMMED
MOVEI A,[ASCIZ ! MOVMI A!]
PUSHJ P,MVOIK
JRST GAMB
MVONT: MOVEI A,[ASCIZ ! MOVE A!]
PUSHJ P,PRODC
MOVE A,ENN
JRST ONMVS
TMSTR: MOVEI A,[ASCIZ ! FMPR A!]
SKIPE INTEGR
MOVEI A,[ASCIZ ! IMUL A!]
POPJ P,
BAKWD: PUSH SYM,A
JRST PSOPR
UDIVI: CAMN B,C
JRST BAKWD ;THESE HAVE TO BE STACKED REVERSE
SKIPE INTEGR
JRST UINDV
SKIPN STRING
PUSHJ P,MVONT
MOVEI A,[ASCIZ ! HRLZI A!]
PUSHJ P,PRODC
MOVE A,ENN
SKIPN STRING
SOS A
PUSHJ P,PUTREL
MOVEI A,[ASCIZ !,201400!]
PUSHJ P,PRODC
RETLIN
AOS ENN
JRST DIVIX
ONTMS: PUSHJ P,TMSTR
PUSHJ P,PRODC
MOVE A,ENN
SOS A
ONMVS: PUSHJ P,PUTREL
PUSHJ P,COMMAA
MOVE A,ENN
SOS A
LSTCHX: PUSHJ P,PUTREL
RETLIN
POPJ P,
POWR: GAMB?POWR2?POWAA?POWR4
POWR4: PUSHJ P,ONTMS
POWR2: PUSHJ P,ONTMS
JRST GAMB
POWAA: PUSHJ P,MVONT
AOS ENN
PUSHJ P,ONTMS
SOS ENN
PUSHJ P,TMSTR
PUSHJ P,PRODC
RESTOR
JRST OPRTE
COMMX: AOS (P)
SKIPE STRING
PUSHJ P,MVOI
JRST GAMB
UINDV: MOAN INTEGER UNARY DIVIDE
FUNCT: SETZM EXRET
FUNET: SKIPE STRING
PUSHJ P,MVOI
SPECN
PUSHJ P,MORFMC
MOVEI A,[ASCIZ ! PUSHJ P,!]
POP P,STRING+2
POP P,STRING+1
POP P,STRING
PUSHJ P,PRODC
PUSHJ P,PRODB
RESTOR
RETLIN
PUSHJ P,MORFNC
SKIPN EXRET
JRST RDITTS ;AS USED FROM FUNCT
JRST COMMT ;AS USED FROM STRSTR
MORFMC: MOVE A,RANDM
MOVEM A,RANSV'
SKIPN CHARF ;NO ARGUMENTS
AOS ENN
SETOM CHARF
MOVEI A,"1
CAMN A,ENN ;ARE ARGUMENT ALREADY IN A0 AND UP
POPJ P,
SETZM CORDM
MORYLP: PUSHJ P,ZENBD
AOS CORDM
SOSL RANSV
JRST MORYLP
POPJ P,
MORFNC: MOVEI A,"1
CAMN A,ENN
POPJ P,
MOVE A,RANDM
MOVEM A,CORDM'
MORXLP: PUSHJ P,ZENBD
SOSL CORDM
JRST MORXLP
POPJ P,
ZENBD: MOVEI A,[ASCIZ ! EXCH A!]
PUSHJ P,PRODC
MOVE A,CORDM
ADDI A,"0
PUSHJ P,PUTREL
PUSHJ P,COMMAA
MOVE A,ENN
SOS A
ADD A,CORDM
JRST LSTCHX
TIPIS: MOVE A,TEMP
MOVEM A,BYTPNT
MORTP: ILDB A,BYTPNT
CAIN A,1 ;EXCLAMATION
POPJ P,
ADDI A," ;SPACE
PUSHJ P,TYO
JRST MORTP
] ;END .I.FSW CONDITIONAL
IFN LISTSW,[
;LISTING ROUTINES.
PNTR: MOVEM 17,PNTSA+17
MOVEI 17,PNTSA
BLT 17,PNTSA+16
MOVE P,PNTSA+P ; P = 17 so must restore.
IFN P-17, .ERR P=17 assumption at PNTR!
SKIPL LSTONP
JRST PNTR5
AOSE LISTPF
JRST PNTR1
SKIPGE T,LISTAD
JRST PNTR2
PUSHJ P,P6OD
HLRZS T
PUSHJ P,PSOS ;PRINT SPACE OR '
PUSHJ P,PILPTS
PNTR3: HLRZ T,LISTWD
PUSHJ P,P6OD
MOVS T,LSTRLC
TLNE T,400000
AOJ T,
PUSHJ P,PSOS
HRRZ T,LISTWD
PUSHJ P,P6OD
HRRZ T,LSTRLC
PUSHJ P,PSOS
PUSHJ P,PILPTS
PUSHJ P,PILPTS
PNTR4: MOVE TT,[440700,,LISTBF]
PNTR6: CAMN TT,PNTBP
JRST PNTR5A
ILDB A,TT
PUSHJ P,PILPT
JRST PNTR6
PNTR5A: CALL PNTCR
MOVE A,LISTBC
CAIE A,14
JRST PNTR7
PNTR5C: CALL PILPT ;OUTPUT THE ^L,
CALL PNTHDR ;AND THE PAGE NUMBER.
JRST PNTR5D
PNTR7: MOVEI A,12
PUSHJ P,PILPT
PNTR5D: SETOM LISTBC
PNTR5: MOVNI A,LISTBS*5-1
MOVEM A,PNTSW ;DETECT OVERFLOW OF LISTBF
MOVE TT,[440700,,LISTBF]
MOVEM TT,PNTBP
MOVSI 17,PNTSA
BLT 17,17
POPJ P,
PNTR5B: MOVE A,LISTBC
CAIN A,14
JRST PNTR5C
JRST PNTR5D
PNTR2: MOVEI T,8
MOVEI A,40
PUSHJ P,PILPT
SOJG T,.-1
JRST PNTR3
PNTR1: MOVE TT,[440700,,LISTBF]
CAMN TT,PNTBP
JRST PNTR5B
MOVEI T,25.
MOVEI A,40
PUSHJ P,PILPT
SOJG T,.-1
JRST PNTR4
PSOS: MOVEI A,"'
TRNN T,-1
PILPTS: MOVEI A,40
JRST PILPT
P6OD: MOVE TT,[220300,,T]
P6OD1: ILDB A,TT
ADDI A,"0
PUSHJ P,PILPT
TLNE TT,770000
JRST P6OD1
POPJ P,
PNTCR: MOVEI A,^M ;OUTPUT ^M TO LST IF OPEN.
PILPTX: SKIPE LSTONP;OUTPUT CHAR TO LST IF LSTING.
JRST PILPT
RET
PNTHDR: MOVEI A,^I
MOVEI B,10. ;MOVE TO COLUMN 80.,
CALL PILPT
SOJG B,.-1
PUSH P,LSTTTY
HLLOM B,LSTTTY ;POSITIVE SO TYOERR GOES ONLY TO LST.
TYPR [ASCIZ/Page /]
MOVE A,CPGN
CALL [AOJA A,DPNT]
REST LSTTTY
PNTCRR: CALL PNTCR ;OUTPUT CRLF TO LST IF OPEN.
PNTLF: MOVEI A,^J
JRST PILPTX
DEFINE LSTM %A,B,C
IF1 [ [B] ? [C] ]
IF2 [ MOVE A,[B]
MOVEM A,%A
.=.+LSTM0-2
MOVE A,[C]
MOVEM A,%A
.=.-LSTM0
]
TERMIN
A.LSTFF: AOS (P) ;RETURN NO VALUE.
; ADDR, CONTENTS IF NOT LISTING, CONTENTS IF LISTING.
LSTOFF: LSTM LSTONP,0,-1
LSTM LSTPLM,[TLO B,4^5][JRST PSHLML]
LSTM RCHLST,RCHLS1,AOSN PNTSW
LSTM RCH1LS,RET,[CAILE A,^M]
LSTM POPLML,JFCL,[IDPB A,PNTBP]
JRST MDSCLR
LSTM0==.-LSTOFF
LSTON: BLOCK LSTM0-1
JRST MDSSET
A.LSTN: SKIPN LISTP1 ;IF SHOULD LIST THIS PASS
JUMPGE FF,MACCR
SKIPE LISTP ;AND WANT LISTING,
CALL LSTON ;TURN ON LISTING OUTPUT.
JRST MACCR
IFNDEF LISTBS,LISTBS==50. ;LISTBF SIZE IN WORDS.
VBLK ;LISTING FEATURE VARIABLES
PNTBP: 0 ;POINTER TO LISTING LINE BUFFER
LSTONP: 0 ;NONZERO WHEN OUTPUTTING TO LISTING FILE.
LISTP:
LISTON: 0 ;-1 IF LISTING ON
PNTSW: 0 ;-1 IF LAST CHR CR OR LF, OR -<# CHARS SPACE LEFT IN LISTBF>
LISTBF: BLOCK LISTBS
LISTAD: 0 ;ADDRESS OR -1 NONE 3.1 RELOC
LISTWD: 0 ;WORD
LSTRLC: 0 ;RELOCATION
LISTPF: 0 ;-1 OTHERS CONTAIN SOMETHING
LISTBC: 0 ;BREAK CHR CR LF OR FF OR -1 IF NONE SINCE LAST PNTR
LISTTM: 0 ;TEMP AT AEND
PNTSA: BLOCK 20 ;AC SAVE AREA FOR LISTING FEATURE
LISTP1: 0 ;POSITIVE => WANT TO LIST EVEN ON PASS 1.
] ;END IFN LISTSW,
IFE LISTSW,VBLK
;THESE VARIABLES ARE REFERENCED EVEN IF LISTSW IS 0.
LSTTTY: 0 ;TYOERR TYPES ON TTY IFF LE 0, ON LST IF NOT 0.
LSTPLM: TLO B,4^5 ;OR JRST PSHLML ;XCT'D BY PSHLMB.
POPLML: JFCL ;OR IDPB A,PNTSW ;XCT'D IN POPLMB.
PBLK
IFE LISTSW, A.LSTN: A.LSTF: RET
VBLK
IFN CREFSW,[
CREFP: 0 ;SET BY C SWITCH TO REQUEST CREFFING.
CRFONP: 0 ;SET WHILE CREFFING.
CRFLFL: 0 ;LAST PAGNUM,,LINENUM OUTPUT.
CRFINU: JFCL\PUSHJ P,CRFUSE ;XCT THIS TO CREF NON-DEF OCCUR.
CRFLBL: JFCL\PUSHJ P,CRFLB1 ;XCT FOR DEF. OF NORMAL SYM.
CRFEQL: JFCL\PUSHJ P,CRFEQ1 ; FOR DEF. OF NORMAL SYM. OR INTSYM.
CRFMCD: JFCL\PUSHJ P,CRFMC1 ; FOR DEF. OF MACRO.
CRFDEF: JFCL\PUSHJ P,CRFDF1 ; FOR RANDOM DEF, CHECK FLAGS.
]
CRFILE: 0 ;SET => SHOULDN'T OUTPUT PAGNUM,,LINENUM'S
;USED BY .CRFILE INTSYM SO CAN'T BE IN CONDIT.
PBLK
IFN CREFSW,[
CRFEQ1: MOVEI T,(B)
CAIN A,1 ;IF NOT PSEUDO OR NOT INTSYM,
CAIE T,INTSYM
JRST CRFLB1 ;IS NORMAL SYM.
CRFOD1: MOVSI T,600000 ;ELSE DEFINING INSN.
JRST CRFEQ2
CRFDF2: MOVEI T,(B) ;DECIDE WHETHER DEFINING MACRO OR PSEUDO.
CAIE T,MACCL
JRST CRFOD1
CRFMC1: SKIPA T,[500000,,] ;DEFINING MACRO.
CRFLB1: MOVSI T,440000 ;DEFINING NORMAL SYM.
CRFEQ2: PUSH P,A
MOVE A,T
JRST CRFMA1
;COME HERE FOR NON-DEF; MUST DECIDE WHAT TYPE SYM.
CRFUSE: TLNE C,3NCRF ;SYM MAY HAVE CREFFING SUPPRESSED.
POPJ P,
PUSH P,A
CAIN A,1
JRST CRFMAC ;PSEUDOS, MACROS.
MOVSI A,40000 ;FLAG FOR NORMAL SYM.
TRNN C,-1
MOVSI A,200000 ;FLAG FOR INSNS.
CRFMA1: PUSH P,A
MOVE A,CLNN
HRL A,CPGN
AOBJN A,.+1 ;A HAS PAGNUM,,LINENUM .
SKIPGE CRFILE ;IF SHOULD OUTPUT IT,
JRST CRFUS1
CAME A,CRFLFL ;AND HAS CHANGED, DO SO.
PUSHJ P,CRFOUT
MOVEM A,CRFLFL
CRFUS1: POP P,A
IOR A,SYM ;COMBINE SYM AND CREF FLAG.
PUSHJ P,CRFOUT
JRST POPAJ
CRFMAC: MOVEI A,(B)
CAIN A,MACCL
SKIPA A,[100000,,] ;MACRO
MOVSI A,200000 ;PSEUDO-OP.
JRST CRFMA1
;DEFINING OCCURRENCE, MIGHT BE ANY TYPE SYM.
CRFDF1: CAIN A,1 ;TYPE 1 => MACRO OR PSEUDO.
JRST CRFDF2
TRNE C,-1 ;ELSE INSN OR NORMAL SYM.
JRST CRFLB1
JRST CRFOD1
DEFINE CRFM %A,B,C
IF1 [ [B]
[C] ]
IF2 [ MOVE A,[B]
MOVEM A,%A
.=.+CRFM0-2
MOVE A,[C]
MOVEM A,%A
.=.-CRFM0]
TERMIN
A.CRFFF: AOS (P) ;.CRFOFF - STOP CREFFING. NO VAUE.
; LOCATION, NORMAL VALUE, VALUE WHILE CREFFING
CRFOFF: CRFM CRFONP,0,-1
CRFM CRFLBL,JFCL,[PUSHJ P,CRFLB1]
CRFM CRFEQL,JFCL,[PUSHJ P,CRFEQ1]
CRFM CRFMCD,JFCL,[PUSHJ P,CRFMC1]
CRFM CRFINU,JFCL,[PUSHJ P,CRFUSE]
CRFM CRFDEF,JFCL,[PUSHJ P,CRFDF1]
POPJ P,
CRFM0==.-CRFOFF
CRFON: BLOCK CRFM0-1
POPJ P,
A.CRFN: JUMPGE FF,MACCR
SKIPE CREFP ;.CRFON, IF HAVE CREF FILE, START CREFFING.
PUSHJ P,CRFON
JRST MACCR
] ;END IFN CREFSW,
SUBTTL TS Routines for I/O & overall control
IFN TS,.INSRT TSRTNS
FEED1: SKIPA B,[40]
FEED: MOVEI B,5
JRST TFEED
VBLK
IFG PURESW-DECSW,[ ;PURIFICATION ROUTINE
PURIFG: -1 ;-1 IF NOT (YET) PURIFIED
]
VARIAB
VPAT:
VPATCH: BLOCK 20
VPATCE=.-1
PBLK
CONSTANTS
PAT:
PATCH: BLOCK 100
PATCHE: -1
IFG PURESW-DECSW,[LOC <.+1777>&-2000 ;SKIP TO NEXT PAGE
MAXPUR==._-10. ;FIRST PAGE ABOVE PURE PAGES
PRINTA Pure pages = ,\MAXPUR-MINPUR
]
VBLK
PDL: BLOCK LPDL+1
IFN DECDBG, DECDBB: BLOCK 8000. ;SPACE FOR DEC DDT'S SYMS.
.NSTGW
BBKCOD==. ;BEGIN BLANK CODING, CLEARED OUT DURING INITIALIZATION
IFG PURESW-DECSW,MINBNK==<.+1777>_-10. ;FIRST PAGE OF BLANK CODE
BNKBLK ;DUMP OUT ACCUMULATED BLANK CODING
;NOW MORE BLANK CODING
BKBUF: BLOCK BSIZE+5 ;CURRENT BLOCK TO OUTPUT
GLOTB: BLOCK 20 ;GLOBAL TABLE, EACH ENTRY FLAGS,,ADR OF SQUOZE (SEE COMMENTS NEAR BEGINNING)
STRSTO: BLOCK STRL ;STRING STORAGE FOR GSYL AND FRIENDS
IFN FASLP,[
FASB: BLOCK FASBL ;OUTPUT BUFFER FOR FASL MODE
;FIRST WD 9 FOUR BIT CODE GROUPS, REST ASSOC STUFF
FASAT: BLOCK FASATL ;ATOM TABLE FOR FASL MODE
;EACH ENTRY CONSISTS OF ATOM IN FORMAT DESIRED BY FASLOAD,
;NAMELY:
; HEADER WD. RH LENGTH IN WDS
; 4.8-4.7 TYPE 0-PN 1 FIX 2 FLO 3 BIG (NOT IMPLEMENTED)
; FOLLOWED BY PN OR VALUE
;-EXCEPT- IF RH OF HEADER =0, THIS SLOT RESERVED FOR LIST
]
EBKCOD==. ;END BLANK CODING
.YSTGW
PRINTA ST = ,\.-RL0
ST: ;SYMBOL TABLE 3 WORDS/SYM FIRST SQUOZE, SECOND "VALUE", 3RD FLAGS,,BLOCK.
BLOCK NRMWPS*SYMDSZ
;LITERALS TABLES - CAN MOVE AND GROW. THESE TAGS & LENGTHS ARE JUST THE DEFAULTS
.SEE CONTBA ;ETC, WHICH CONTAIN THE ACTUAL ADDRESSES. SO DON'T USE THEM!
CONTAB: BLOCK LCONTB ;CONSTANTS TABLE, VALUES OF CONSTANTS THIS CONSTANTS AREA
CONGLO: BLOCK LCNGLO ;CONSTANTS GLOBAL TABLE, EACH ENTRY TWO WORDS
;FIRST WD GLOTB ENTRY. SECOND WD ADR IN CONTAB OF CONSTANT TO WHICH IT REFERS
CONBIT: BLOCK LCONTB/12.+1 ;RELOCATION BITS AND ILNOPT BIT(SEE CPTMK)
;3 BITS FOR EACH WORD OF CONTAB.
;;INIT ;INITIALIZATION ROUTINES (IN MACRO TABLE, GET WIPED OUT)
IFN ITSSW\TNXSW,MINMAC==./2000 ;# OF 1ST PAGE HOLDING PART OF MACTAB.
;NOTE THAT THIS CODE IS COPIED UPWARD WHEN MACTAB IS MOVED
;DUE TO SYMTAB EXPANSION. THEREFOR IT MUST REFER TO ITSELF
;INDEXED BY THE OFFSET OF WHERE IT IS FROM WHERE IT WAS ASSEMBLED.
;THAT IS KEPT IN CH1. ALL LITERALS MUST BE USED INDEX OF CH1, TOO.
;MAC PROC TABLES
MACTBA: 773767750000 ;MACRO CHARACTER STORAGE (FIRST WORD 3 375'S)
INIT1: MOVE CH1,MACTAD ;GET ADDR THIS CODE REALLY STARTS AT.
SUBI CH1,MACTBA ;GET OFFSET FROM WHERE ASSEMBLED.
SETZM BBKCOD
MOVE A,[BBKCOD,,BBKCOD+1](CH1)
BLT A,EBKCOD-1 ;CLEAR OUT BLANK CODING
PUSH P,[SP4](CH1) ;NOW INIT THE SYMTAB & FINISHED.
;INITIALIZE THE SYMTAB, EXPECT SIZE IN SYMLEN.
INITS: MOVE AA,SYMLEN ;SET UP THE OTHER VARS
IMUL AA,WPSTE ;DEALING WITH SYMTAB SIZE.
MOVEM AA,SYMSIZ
ADDI AA,ST ;ADDR OF START OF CONTAB.
MOVEM AA,CONTBA
MOVEM AA,PLIM
ADD AA,CONLEN ;ADD LENGTH OF CONTAB TO GET ADDR OF CONGLO TAB.
MOVEM AA,CONTBE ;WHICH IS ALSO THE END OF CONTAB.
MOVEM AA,CONGLA
MOVEM AA,CONGOL
MOVE A,CONLEN ;ADD IN LENGTH OF CONGLO (1/4 OF CONLEN)
LSH A,-2
ADD AA,A
MOVEM AA,CONGLE ;TO GET END OF CONGLO, AND START OF CONBIT TABLE.
MOVEM AA,CONBIA
MOVE A,CONLEN
ADDI A,11.
IDIVI A,12.
ADD AA,A ;ADD LENGTH OF CONBIT (1/12 OF CONLEN) GETTING ADDR OF MACTAB.
IFN DECSW,[
PUSH P,AA
ADDI AA,MACL-1
IORI AA,1777 ;FIX ALLOCATION PROBLEMS ON KI-10
CORE AA,
ETF [ASCIZ /No core for symbols/](CH1)
REST AA
]
MOVN A,SYMLEN
HRLZM A,SYMAOB ;AOBJN -> SYMTAB.
MOVE A,WPSTE
SUBI A,1
MOVEM A,WPSTE1
MOVN A,WPSTE
HRRM A,WPSTEB
CAMG AA,MACTAD ;MOVED MACTAB UP?
JRST INITS1(CH1)
IFN ITSSW\TNXSW,[ ;YES, GET CORE FOR INCREASE.
PUSH P,AA
MOVEI AA,MACL+1777(AA)
LSH AA,-10. ;1ST PAGE NOT NEEDED BY MACTAB.
MOVEI A,MACL+1777+MACTBA(CH1)
LSH A,-10. ;1ST PAGE MACTAB DOESN'T YET HAVE.
SUBM A,AA ;# PAGES NEEDED.
HRLZI AA,(AA)
HRRI AA,(A) ;-<# PAGES>,,<1ST NEEDED>
CAIGE AA, ; Don't call if don't need any pages.
CALL CORGET ; Get the pages
REST AA
]
SUBM AA,MACTAD ;MACTAD _ SHIFT IN START OF MACTAB.
EXCH AA,MACTAD ;MACTAD GETS NEW START, AA HAS SHIFT.
MOVSI A,PTAB-CCOMPB
ADDM AA,PTAB(A) ;RELOCATE BYTE-PTRS INTO MACTAB.
AOBJN A,.-1(CH1)
MOVNI B,INITS2(CH1)
HRROI A,@EISYMP(CH1)
ADDI B,1(A) ;GET # WDS IN SECOND HALF OF INIT CODE.
HRRM AA,.+1(CH1) ;COPY 2ND HALF UPWARD WITH POP-LOOP.
POP A,(A) ;THIS INSN IMPURE.
SOJG B,.-1(CH1)
ADDI CH1,(AA) ;CHANGE OFFSET TO PT. TO NEW LOCATIONN OF INIT CODE.
JRST INITS2(CH1) ;JUMP INTO 2ND HALF, WHERE IT'S BEEN COPIED TO.
INITS2: HRROI A,INITS2-1(CH1) ;THEN COPY 1ST HALF (WHICH ENNDS BEFORE INITS2)
SUBI A,(AA) ;GET WHERE NOW ENDS, NOT WHERE WILL END.
MOVEI B,INITS2-MACTBA ;UP UNDERNEATH THE 2ND HALF.
HRRM AA,.+1(CH1) ;(THIS TWO-STEP COPYING HANDLES ALL OVERLAPS)
POP A,(A)
SOJG B,.-1(CH1)
INITS1: MOVE AA,SYMSIZ
SETZM ST
MOVE A,[ST,,ST+1](CH1)
BLT A,ST-1(AA) ;CLEAR OUT SYMBOL TABLE
SETZM ESBK ;DEFINE THEM IN OUTER BLOCK.
MOVEI AA,ISYMTB(CH1)
MOVS F,ISMTBB(CH1) ;GET SWAPPED VALUE OF FIRST INSTRUCTION
SP3: CAIL AA,EISYM1(CH1)
JRST SP1(CH1) ;DONE WITH INSTRUCTIONS
MOVE SYM,(AA)
JUMPE SYM,SP2(CH1)
TLZ SYM,740000
PUSHJ P,ES ;WON'T SKIP
CAIA
GOHALT ;INSTRUCTION PRESENT TWICE IN TABLE!!?!?
HRLZI T,SYMC
HRLZ B,F
MOVSI C,3KILL
PUSH P,CH1
PUSHJ P,VSM2
POP P,CH1
SP2: ADDI F,1000
AOJA AA,SP3(CH1)
;AFTER HACKING ALL THE INSTRUCTIONS, STORED AS JUST THE NAMES IN NUMERIC ORDER,
;HACK ALL THE OTHER PREDEFINED SYMS, STORED AS 2 WORDS (NAME ? VALUE).
EISYMP: ;MAY BE MUNGED IF MORE SYMBOLS ARE ADDED AFTER EISYMT.
SP1: CAIL AA,EISYMT(CH1)
POPJ P,
MOVE SYM,(AA)
LDB T,[400400,,SYM](CH1)
ROT T,-4
TLZ SYM,740000
PUSHJ P,ES
CAIA
JRST SP5(CH1) ;SYM ALREADY DEFINED? (MIGHT BE .UAI, IN ITS AND IN MIDAS).
MOVE B,1(AA)
MOVSI C,3KILL
CAME T,[GLOETY,,](CH1) ;GLOBAL ENTRIES REALLY EXITS, HACKED TO DEFEAT ADDRESS LINKING
CAMN T,[GLOEXT,,](CH1)
TLO C,3LLV
PUSH P,CH1
PUSHJ P,VSM2
POP P,CH1
SP5: AOS AA
AOJA AA,SP1(CH1)
CONSTANTS ; Constants for init code above
;;ISYMS ;INITIAL SYMBOL TABLE - NOT HASHED
IFNDEF JSYS,JSYS=104_33 ;ALLOW FOR BOOTSTRAP, EVENTUALLY FLUSH, MAYBE
ISMTBB: JSYS ;FIRST OP. CODE IN ISYMTB
ISYMTB:
; 104-177 (JSYS - FDVRB)
SQUOZE 10,JSYS ;BBN PAGER INSTRUCTION
SQUOZE 10,ADJSP ;KL10 INSTRUCTION
0
0
SQUOZE 10,DFAD ;KI10 INSTRUCTION
SQUOZE 10,DFSB ;KI10 INSTRUCTION
SQUOZE 10,DFMP ;KI10 INSTRUCTION
SQUOZE 10,DFDV ;KI10 INSTRUCTION
SQUOZE 10,DADD ;KL10 INSTRUCTION
SQUOZE 10,DSUB ;KL10 INSTRUCTION
SQUOZE 10,DMUL ;KL10 INSTRUCTION
SQUOZE 10,DDIV ;KL10 INSTRUCTION
SQUOZE 10,DMOVE ;KI10 INSTRUCTION
SQUOZE 10,DMOVN ;KI10 INSTRUCTION
SQUOZE 10,FIX ;KI10 INSTRUCTION
SQUOZE 10,EXTEND ;KL10 INSTRUCTION
SQUOZE 10,DMOVEM ;KI10 INSTRUCTION
SQUOZE 10,DMOVNM ;KI10 INSTRUCTION
SQUOZE 10,FIXR ;KI10 INSTRUCTION
SQUOZE 10,FLTR ;KI10 INSTRUCTION
SQUOZE 10,UFA ;KA/KI10 INSTRUCTION
SQUOZE 10,DFN ;KA/KI10 INSTRUCTION
SQUOZE 10,FSC
SQUOZE 10,IBP
SQUOZE 10,ILDB
SQUOZE 10,LDB
SQUOZE 10,IDPB
SQUOZE 10,DPB
SQUOZE 10,FAD
SQUOZE 10,FADL ;PDP6/KA/KI INSTRUCTION
SQUOZE 10,FADM
SQUOZE 10,FADB
SQUOZE 10,FADR
SQUOZE 10,FADRI ;PDP10 INSTRUCTION
SQUOZE 10,FADRM
SQUOZE 10,FADRB
SQUOZE 10,FSB
SQUOZE 10,FSBL ;PDP6/KA/KI INSTRUCTION
SQUOZE 10,FSBM
SQUOZE 10,FSBB
SQUOZE 10,FSBR
SQUOZE 10,FSBRI ;PDP10 INSTRUCTION
SQUOZE 10,FSBRM
SQUOZE 10,FSBRB
SQUOZE 10,FMP
SQUOZE 10,FMPL ;PDP6/KA/KI INSTRUCTION
SQUOZE 10,FMPM
SQUOZE 10,FMPB
SQUOZE 10,FMPR
SQUOZE 10,FMPRI ;PDP10 INSTRUCTION
SQUOZE 10,FMPRM
SQUOZE 10,FMPRB
SQUOZE 10,FDV
SQUOZE 10,FDVL ;PDP6/KA/KI INSTRUCTION
SQUOZE 10,FDVM
SQUOZE 10,FDVB
SQUOZE 10,FDVR
SQUOZE 10,FDVRI ;PDP10 INSTRUCTION
SQUOZE 10,FDVRM
SQUOZE 10,FDVRB
; 200-277 (MOVE - SUBB)
SQUOZE 10,MOVE
SQUOZE 10,MOVEI
SQUOZE 10,MOVEM
SQUOZE 10,MOVES
SQUOZE 10,MOVS
SQUOZE 10,MOVSI
SQUOZE 10,MOVSM
SQUOZE 10,MOVSS
SQUOZE 10,MOVN
SQUOZE 10,MOVNI
SQUOZE 10,MOVNM
SQUOZE 10,MOVNS
SQUOZE 10,MOVM
SQUOZE 10,MOVMI
SQUOZE 10,MOVMM
SQUOZE 10,MOVMS
SQUOZE 10,IMUL
SQUOZE 10,IMULI
SQUOZE 10,IMULM
SQUOZE 10,IMULB
SQUOZE 10,MUL
SQUOZE 10,MULI
SQUOZE 10,MULM
SQUOZE 10,MULB
SQUOZE 10,IDIV
SQUOZE 10,IDIVI
SQUOZE 10,IDIVM
SQUOZE 10,IDIVB
SQUOZE 10,DIV
SQUOZE 10,DIVI
SQUOZE 10,DIVM
SQUOZE 10,DIVB
SQUOZE 10,ASH
SQUOZE 10,ROT
SQUOZE 10,LSH
SQUOZE 10,JFFO ;PDP10 INSTRUCTION
SQUOZE 10,ASHC
SQUOZE 10,ROTC
SQUOZE 10,LSHC
SQUOZE 10,CIRC ;AI PDP10 INST. CIRCULATE: ROTC WITH AC+1 GOING THE WRONG WAY
SQUOZE 10,EXCH
SQUOZE 10,BLT
SQUOZE 10,AOBJP
SQUOZE 10,AOBJN
SQUOZE 10,JRST
SQUOZE 10,JFCL
SQUOZE 10,XCT
SQUOZE 10,MAP ;KI10 INSTRUCTION
SQUOZE 10,PUSHJ
SQUOZE 10,PUSH
SQUOZE 10,POP
SQUOZE 10,POPJ
SQUOZE 10,JSR
SQUOZE 10,JSP
SQUOZE 10,JSA
SQUOZE 10,JRA
SQUOZE 10,ADD
SQUOZE 10,ADDI
SQUOZE 10,ADDM
SQUOZE 10,ADDB
SQUOZE 10,SUB
SQUOZE 10,SUBI
SQUOZE 10,SUBM
SQUOZE 10,SUBB
; 300-377 (CAI - SOSG)
SQUOZE 10,CAI
SQUOZE 10,CAIL
SQUOZE 10,CAIE
SQUOZE 10,CAILE
SQUOZE 10,CAIA
SQUOZE 10,CAIGE
SQUOZE 10,CAIN
SQUOZE 10,CAIG
SQUOZE 10,CAM
SQUOZE 10,CAML
SQUOZE 10,CAME
SQUOZE 10,CAMLE
SQUOZE 10,CAMA
SQUOZE 10,CAMGE
SQUOZE 10,CAMN
SQUOZE 10,CAMG
SQUOZE 10,JUMP
SQUOZE 10,JUMPL
SQUOZE 10,JUMPE
SQUOZE 10,JUMPLE
SQUOZE 10,JUMPA
SQUOZE 10,JUMPGE
SQUOZE 10,JUMPN
SQUOZE 10,JUMPG
SQUOZE 10,SKIP
SQUOZE 10,SKIPL
SQUOZE 10,SKIPE
SQUOZE 10,SKIPLE
SQUOZE 10,SKIPA
SQUOZE 10,SKIPGE
SQUOZE 10,SKIPN
SQUOZE 10,SKIPG
SQUOZE 10,AOJ
SQUOZE 10,AOJL
SQUOZE 10,AOJE
SQUOZE 10,AOJLE
SQUOZE 10,AOJA
SQUOZE 10,AOJGE
SQUOZE 10,AOJN
SQUOZE 10,AOJG
SQUOZE 10,AOS
SQUOZE 10,AOSL
SQUOZE 10,AOSE
SQUOZE 10,AOSLE
SQUOZE 10,AOSA
SQUOZE 10,AOSGE
SQUOZE 10,AOSN
SQUOZE 10,AOSG
SQUOZE 10,SOJ
SQUOZE 10,SOJL
SQUOZE 10,SOJE
SQUOZE 10,SOJLE
SQUOZE 10,SOJA
SQUOZE 10,SOJGE
SQUOZE 10,SOJN
SQUOZE 10,SOJG
SQUOZE 10,SOS
SQUOZE 10,SOSL
SQUOZE 10,SOSE
SQUOZE 10,SOSLE
SQUOZE 10,SOSA
SQUOZE 10,SOSGE
SQUOZE 10,SOSN
SQUOZE 10,SOSG
; 400-477 (SETZ - SETOB)
SQUOZE 10,SETZ
SQUOZE 10,SETZI
SQUOZE 10,SETZM
SQUOZE 10,SETZB
SQUOZE 10,AND
SQUOZE 10,ANDI
SQUOZE 10,ANDM
SQUOZE 10,ANDB
SQUOZE 10,ANDCA
SQUOZE 10,ANDCAI
SQUOZE 10,ANDCAM
SQUOZE 10,ANDCAB
SQUOZE 10,SETM
SQUOZE 10,SETMI
SQUOZE 10,SETMM
SQUOZE 10,SETMB
SQUOZE 10,ANDCM
SQUOZE 10,ANDCMI
SQUOZE 10,ANDCMM
SQUOZE 10,ANDCMB
SQUOZE 10,SETA
SQUOZE 10,SETAI
SQUOZE 10,SETAM
SQUOZE 10,SETAB
SQUOZE 10,XOR
SQUOZE 10,XORI
SQUOZE 10,XORM
SQUOZE 10,XORB
SQUOZE 10,IOR
SQUOZE 10,IORI
SQUOZE 10,IORM
SQUOZE 10,IORB
SQUOZE 10,ANDCB
SQUOZE 10,ANDCBI
SQUOZE 10,ANDCBM
SQUOZE 10,ANDCBB
SQUOZE 10,EQV
SQUOZE 10,EQVI
SQUOZE 10,EQVM
SQUOZE 10,EQVB
SQUOZE 10,SETCA
SQUOZE 10,SETCAI
SQUOZE 10,SETCAM
SQUOZE 10,SETCAB
SQUOZE 10,ORCA
SQUOZE 10,ORCAI
SQUOZE 10,ORCAM
SQUOZE 10,ORCAB
SQUOZE 10,SETCM
SQUOZE 10,SETCMI
SQUOZE 10,SETCMM
SQUOZE 10,SETCMB
SQUOZE 10,ORCM
SQUOZE 10,ORCMI
SQUOZE 10,ORCMM
SQUOZE 10,ORCMB
SQUOZE 10,ORCB
SQUOZE 10,ORCBI
SQUOZE 10,ORCBM
SQUOZE 10,ORCBB
SQUOZE 10,SETO
SQUOZE 10,SETOI
SQUOZE 10,SETOM
SQUOZE 10,SETOB
; 500-577 (HLL - HLRES)
SQUOZE 10,HLL
SQUOZE 10,HLLI
SQUOZE 10,HLLM
SQUOZE 10,HLLS
SQUOZE 10,HRL
SQUOZE 10,HRLI
SQUOZE 10,HRLM
SQUOZE 10,HRLS
SQUOZE 10,HLLZ
SQUOZE 10,HLLZI
SQUOZE 10,HLLZM
SQUOZE 10,HLLZS
SQUOZE 10,HRLZ
SQUOZE 10,HRLZI
SQUOZE 10,HRLZM
SQUOZE 10,HRLZS
SQUOZE 10,HLLO
SQUOZE 10,HLLOI
SQUOZE 10,HLLOM
SQUOZE 10,HLLOS
SQUOZE 10,HRLO
SQUOZE 10,HRLOI
SQUOZE 10,HRLOM
SQUOZE 10,HRLOS
SQUOZE 10,HLLE
SQUOZE 10,HLLEI
SQUOZE 10,HLLEM
SQUOZE 10,HLLES
SQUOZE 10,HRLE
SQUOZE 10,HRLEI
SQUOZE 10,HRLEM
SQUOZE 10,HRLES
SQUOZE 10,HRR
SQUOZE 10,HRRI
SQUOZE 10,HRRM
SQUOZE 10,HRRS
SQUOZE 10,HLR
SQUOZE 10,HLRI
SQUOZE 10,HLRM
SQUOZE 10,HLRS
SQUOZE 10,HRRZ
SQUOZE 10,HRRZI
SQUOZE 10,HRRZM
SQUOZE 10,HRRZS
SQUOZE 10,HLRZ
SQUOZE 10,HLRZI
SQUOZE 10,HLRZM
SQUOZE 10,HLRZS
SQUOZE 10,HRRO
SQUOZE 10,HRROI
SQUOZE 10,HRROM
SQUOZE 10,HRROS
SQUOZE 10,HLRO
SQUOZE 10,HLROI
SQUOZE 10,HLROM
SQUOZE 10,HLROS
SQUOZE 10,HRRE
SQUOZE 10,HRREI
SQUOZE 10,HRREM
SQUOZE 10,HRRES
SQUOZE 10,HLRE
SQUOZE 10,HLREI
SQUOZE 10,HLREM
SQUOZE 10,HLRES
; 600-677 (TRN - TSON)
SQUOZE 10,TRN
SQUOZE 10,TLN
SQUOZE 10,TRNE
SQUOZE 10,TLNE
SQUOZE 10,TRNA
SQUOZE 10,TLNA
SQUOZE 10,TRNN
SQUOZE 10,TLNN
SQUOZE 10,TDN
SQUOZE 10,TSN
SQUOZE 10,TDNE
SQUOZE 10,TSNE
SQUOZE 10,TDNA
SQUOZE 10,TSNA
SQUOZE 10,TDNN
SQUOZE 10,TSNN
SQUOZE 10,TRZ
SQUOZE 10,TLZ
SQUOZE 10,TRZE
SQUOZE 10,TLZE
SQUOZE 10,TRZA
SQUOZE 10,TLZA
SQUOZE 10,TRZN
SQUOZE 10,TLZN
SQUOZE 10,TDZ
SQUOZE 10,TSZ
SQUOZE 10,TDZE
SQUOZE 10,TSZE
SQUOZE 10,TDZA
SQUOZE 10,TSZA
SQUOZE 10,TDZN
SQUOZE 10,TSZN
SQUOZE 10,TRC
SQUOZE 10,TLC
SQUOZE 10,TRCE
SQUOZE 10,TLCE
SQUOZE 10,TRCA
SQUOZE 10,TLCA
SQUOZE 10,TRCN
SQUOZE 10,TLCN
SQUOZE 10,TDC
SQUOZE 10,TSC
SQUOZE 10,TDCE
SQUOZE 10,TSCE
SQUOZE 10,TDCA
SQUOZE 10,TSCA
SQUOZE 10,TDCN
SQUOZE 10,TSCN
SQUOZE 10,TRO
SQUOZE 10,TLO
SQUOZE 10,TROE
SQUOZE 10,TLOE
SQUOZE 10,TROA
SQUOZE 10,TLOA
SQUOZE 10,TRON
SQUOZE 10,TLON
SQUOZE 10,TDO
SQUOZE 10,TSO
SQUOZE 10,TDOE
SQUOZE 10,TSOE
SQUOZE 10,TDOA
SQUOZE 10,TSOA
SQUOZE 10,TDON
SQUOZE 10,TSON
EISYM1:
; I/O INSTRUCTIONS
SQUOZE 4,BLKI
BLKI IOINST
SQUOZE 4,DATAI
DATAI IOINST
SQUOZE 4,BLKO
BLKO IOINST
SQUOZE 4,DATAO
DATAO IOINST
SQUOZE 4,CONO
CONO IOINST
SQUOZE 4,CONI
CONI IOINST
SQUOZE 4,CONSZ
CONSZ IOINST
SQUOZE 4,CONSO
CONSO IOINST
;EXTEND MNEMONICS
SQUOZE 10,CMPSL
001000,,
SQUOZE 10,CMPSE
002000,,
SQUOZE 10,CMPSLE
003000,,
SQUOZE 10,EDIT
004000,,
SQUOZE 10,CMPSGE
005000,,
SQUOZE 10,CMPSN
006000,,
SQUOZE 10,CMPSG
007000,,
SQUOZE 10,CVTDBO
010000,,
SQUOZE 10,CVTDBT
011000,,
SQUOZE 10,CVTBDO
012000,,
SQUOZE 10,CBTBDT
013000,,
SQUOZE 10,MOVSO
014000,,
SQUOZE 10,MOVST
015000,,
SQUOZE 10,MOVSLJ
016000,,
SQUOZE 10,MOVSRJ
017000,,
SQUOZE 10,XBLT
020000,,
;OLD PROGRAMS USE THESE NAMES
SQUOZE 10,CLEAR
SETZ
SQUOZE 10,CLEARI
SETZI
SQUOZE 10,CLEARM
SETZM
SQUOZE 10,CLEARB
SETZB
;RANDOM ALIAS NAMES
SQUOZE 10,ERJMP ; TOPS-20 JSYS-error dispatch (becomes JRST)
JUMP 16,
SQUOZE 10,ERCAL ; TOPS-20 JSYS-error call (becomes PUSHJ 17,)
JUMP 17,
SQUOZE 10,ADJBP ;KL10 FORM OF IBP WITH VARIABLE NUMBER TO INCREMENT
IBP
SQUOZE 10,JFOV ;PDP10 INSTRUCTION (PC CHANGE ON PDP6)
JFCL 1,
SQUOZE 10,JCRY1
JFCL 2,
SQUOZE 10,JCRY0
JFCL 4,
SQUOZE 10,JCRY
JFCL 6,
SQUOZE 10,JOV
JFCL 10,
SQUOZE 10,PORTAL ;KI10 INSTRUCTION
JRST 1,
SQUOZE 10,JRSTF
JRST 2,
SQUOZE 10,HALT
JRST 4,
SQUOZE 10,XJRSTF ;KL10 INSTRUCTION
JRST 5,
SQUOZE 10,XJEN ;KL10 INSTRUCTION
JRST 6,
SQUOZE 10,XPCW ;KL10 INSTRUCTION
JRST 7,
SQUOZE 10,JEN
JRST 12,
SQUOZE 10,SFM ;KL10 INSTRUCTION
JRST 14,
SQUOZE 10,XMOVEI ;KL10 INSTRUCTION
SETMI
SQUOZE 10,XHLLI ;KL10 INSTRUCTION
HLLI
;PDP6 HAS LONG FORM ROUNDED INSTEAD OF IMMEDIATES
IRPS INST,,FAD FSB FMP FDV
SQUOZE 10,INST!RL
INST!RI
TERMIN
; MIDAS pseudo definitions
SQUOZE 10,.OSMID ; Crock here - in TNX version, SITINI sets value at
OSMID: OSMIDAS ; runtime before syms spread.
SQUOZE 4,.SITE
A.SITE
SQUOZE 4,RIM10
ARIM10,,SRIM
SQUOZE 4,SBLK
SBLKS,,SRIM
SQUOZE 4,RIM
ARIM,,SRIM
SQUOZE 4,SQUOZE
ASQOZ
SQUOZE 4,.RSQZ
-1,,ASQOZ
SQUOZE 4,XWD
AXWORD
SQUOZE 4,CONSTA
CNSTNT
SQUOZE 4,ASCIC
EOFCH,,AASCIZ
SQUOZE 4,RADIX
ARDIX
SQUOZE 4,END
AEND
SQUOZE 4,TITLE
ATITLE
SQUOZE 4,.BEGIN
A.BEGIN
SQUOZE 4,.END
A.END
SQUOZE 4,VARIAB
AVARIAB
SQUOZE 4,SIXBIT
ASIXBIT
SQUOZE 4,ASCII
AASCII
SQUOZE 4,ASCIZ
AASCIZ
SQUOZE 4,.ASCII
A.ASCII
SQUOZE 4,.ASCVL
A.ASCV
SQUOZE 4,BLOCK
ABLOCK
SQUOZE 4,LOC
ALOC
SQUOZE 4,OFFSET
AOFFSET
SQUOZE 4,.SBLK
SIMBLK
SQUOZE 4,RELOCA
ARELOCA
SQUOZE 4,1PASS
A1PASS
SQUOZE 4,.DECSA
A.DECSA
SQUOZE 4,.DECRE
A.DECRE
SQUOZE 4,.DECTX
A.DCTX
SQUOZE 4,.DECTW
A.DECTW
SQUOZE 4,NOSYMS
ANOSYMS
SQUOZE 4,EXPUNGE
AEXPUNGE
SQUOZE 4,EQUALS
AEQUALS
SQUOZE 4,NULL
ANULL
SQUOZE 4,SUBTTL
ANULL
SQUOZE 4,WORD
AWORD
SQUOZE 4,.SYMTAB
A.SYMTAB
SQUOZE 4,.SEE
A.SEE
SQUOZE 4,.AUXIL
MACCR
SQUOZE 4,.MRUNT
A.MRUNT
SQUOZE 4,.SYMCN
A.SYMC
SQUOZE 4,.TYPE
A.TYPE
SQUOZE 4,.FORMAT
A.FORMAT
SQUOZE 4,.OP
A.OP
SQUOZE 4,.AOP
A.AOP
SQUOZE 4,.RADIX
A.RADIX
SQUOZE 4,.FATAL
A.FATAL
SQUOZE 4,.BP
A.BP
SQUOZE 4,.BM
A.BM
SQUOZE 4,.LZ
A.LZ
SQUOZE 4,.TZ
A.TZ
SQUOZE 4,.DPB
A.DPB
SQUOZE 4,.LDB
A.LDB
SQUOZE 4,.IBP
A.IBP
SQUOZE 4,.1STWD
A.1STWD
SQUOZE 4,.NTHWD
A.NTHWD
IRPS X,,[.BIND=0,.KILL=3KILL,.HKILL=3SKILL,.XCREF=3NCRF,.DOWN=3DOWN]
IFE 1&.IRPCN, SQUOZE 4,X
IFN 1&.IRPCN, X,,A.KILL
TERMIN
SQUOZE 4,.LSTON
A.LSTN
SQUOZE 4,.LSTOF
A.LSTF
IRPS X,,[.MLLIT=CONSML,.PASS=A.PASS,.PPASS=A.PPASS,.SUCCESS=A.SUCCESS
.HKALL=HKALL,.STGSW=STGSW,.LITSW=LITSW,.AVAL1=AVAL1,.AVAL2=AVAL2,.ERRCNT=ERRCNT
.ASKIP=A.ASKIP,.CURLN=CLNN,.CURPG=CPGN,.QMTCH=QMTCH,.STPLN=A.STPLN,.STPPG=A.STPPG]
IFE 1&.IRPCN, SQUOZE 4,X
IFN 1&.IRPCN, X,,INTSYM
TERMIN
;CONDITIONALS (SEE ALSO IFSE, IFSN)
SQUOZE 4,IFG
JUMPG A,COND
SQUOZE 4,IFGE
JUMPGE A,COND
SQUOZE 4,IFE
JUMPE A,COND
SQUOZE 4,IFLE
JUMPLE A,COND
SQUOZE 4,IFL
JUMPL A,COND
SQUOZE 4,IFN
JUMPN A,COND
SQUOZE 4,.ELSE
SKIPE A.ELSE
SQUOZE 4,.ALSO
SKIPN A.ELSE
SQUOZE 4,IF1
TRNE FF,COND1
SQUOZE 4,IF2
TRNN FF,COND1
SQUOZE 4,IFDEF ;ASSEMBLE IF SYM DEFINED
JUMPG A,DEFCND
SQUOZE 4,IFNDEF ;ASSEMBLE IF SYM NOT DEFINED
JUMPE A,DEFCND
SQUOZE 4,IFB ;ASSEMBLE IF STRING BLANK (HAS NO SQUOZE CHARS)
JUMPLE C,SBCND
SQUOZE 4,IFNB ;ASSEMBLE IF STRING NOT BLANK
JUMPG C,SBCND
SQUOZE 4,IFSQ ;ASSEMBLE IF STRING ARG IS ALL SQUOZE
JUMPLE B,SBCND
SQUOZE 4,IFNSQ ;ASSEMBLE IF STRING ARG IS NOT ALL SQUOZE.
JUMPG B,SBCND
SQUOZE 4,PRINTX
APRIN2,,APRINT
SQUOZE 4,PRINTC
APRIN3,,APRINT
SQUOZE 4,COMMEN
APRIN1,,APRINT
SQUOZE 4,.TYO
A.TYO
SQUOZE 4,.TYO6
A.TYO6
SQUOZE 4,.ERR
A.ERR
SQUOZE 4,.RELP
A.RELP
SQUOZE 4,.ABSP
A.ABSP
SQUOZE 4,.RL1
A.RL1
SQUOZE 4,.LIBRA
LLIB,,A.LIB
SQUOZE 4,.LENGTH
A.LENGTH
SQUOZE 4,.LIFS
LTCP,,A.LIB
SQUOZE 4,.ELDC
A.ELDC
IRPS A,,E N G LE GE L
SQUOZE 4,.LIF!A
JUMP!A A.LDCV
TERMIN
SQUOZE 4,.SLDR
A.SLDR
SQUOZE 4,.
GTVLP
SQUOZE 4,.LOP
A.LOP
SQUOZE 40,$.
0
SQUOZE 44,$R.
0
SQUOZE 40,$O. ;(OH) GLOBAL OFFSET
0
SQUOZE 40,$L. ;REAL LOCATION (WITHOUT OFFSET)
0
SQUOZE 40,.LVAL1
0
SQUOZE 40,.LVAL2
0
SQUOZE 4,.LNKOT
A.LNKOT
SQUOZE 4,.NSTGW
1,,STGWS
SQUOZE 4,.YSTGW
-1,,STGWS
SQUOZE 4,.LIBRQ
A.LIBRQ
SQUOZE 4,.GLOBAL
ILGLI,,A.GLOB
SQUOZE 4,.SCALAR
ILVAR,,A.GLOB
SQUOZE 4,.VECTOR
ILVAR\ILFLO,,A.GLOB
SQUOZE 4,.BYTC
NBYTS,,INTSYM
SQUOZE 4,.BYTE
A.BYTE
SQUOZE 4,.WALGN
A.WALGN
;CREF PSEUDO-OPS.
SQUOZE 4,.CRFON
A.CRFN ;START CREFFING.
SQUOZE 4,.CRFOFF
A.CRFFF ;STOP CREFFING.
SQUOZE 4,.CRFIL
CRFILE,,INTSYM
IFE CREFSW,[
A.CRFN==ASSEM1 ;THESE DO NOTHING IF CAN'T CREF.
A.CRFFF==ASSEM1
]
IFN MACSW,[ ;MACRO PROCESSOR PSEUDOS
;MACROS GET DEFINED AS
;SQUOZE 4, <MACRO NAME>
;<CHAR ADR>,, MACCL
SQUOZE 4,REPEAT
AREPEAT
SQUOZE 4,DEFINE
ADEFINE
SQUOZE 4,IRP
NIRPO,,AIRP
SQUOZE 4,IRPC
NIRPC,,AIRP
SQUOZE 4,IRPS
NIRPS,,AIRP
SQUOZE 4,IRPW
NIRPW,,AIRP
SQUOZE 4,IRPNC
NIRPN,,AIRP
SQUOZE 4,TERMIN
ATERMIN
SQUOZE 4,.QUOTE
A.QOTE
SQUOZE 4,.STOP
(400000)A.STOP
SQUOZE 4,.ISTOP
A.STOP
SQUOZE 4,.RPCNT
CRPTCT,,INTSYM
SQUOZE 4,.GSSET
A.GSSET
SQUOZE 4,.GSCNT
GENSM,,INTSYM
SQUOZE 4,.GO
A.GO
SQUOZE 4,.TAG
A.TAG
SQUOZE 4,.IRPCNT
CIRPCT,,INTSYM
IFN RCHASW,[SQUOZE 4,.TTYMAC
A.TTYM
]
SQUOZE 4,IFSE
SKIPN SCOND
SQUOZE 4,IFSN
SKIPE SCOND
]
IFN FASLP,[
SQUOZE 4,.FASL
A.FASL
SQUOZE 4,.ARRAY ;3 INDEX TO AFDMY1 TBL
AFATOM(3)
SQUOZE 4,.ATOM
AFATOM(AFDMAI) ;2 INDEX TO AFDMY1 TBL
AFDMAI==2 ;INDEX OF ATOM IN AFDMY1 TBL
SQUOZE 4,.FUNCT
AFATOM(1) ;1 " " " "
SQUOZE 4,.SPECI
AFATOM(0) ;0 " " " "
SQUOZE 4,.SX
AFLIST(1) ;NORMAL LIST
SQUOZE 4,.SXEVA
AFLIST ;EVAL LIST AND THROW VALUE AWAY
SQUOZE 4,.SXE
AFLIST(2) ;EVAL LIST AND "RETURN" VALUE
SQUOZE 4,.ENTRY
AFENTY ;DECLARE LISP ENTRY POINT (SUBR ETC)
]
IFN TS,[
SQUOZE 4,.FNAM1
RFNAM1,,INTSYM
SQUOZE 4,.FNAM2
RFNAM2,,INTSYM
SQUOZE 4,.FVERS
RFVERS,,INTSYM
SQUOZE 4,.INSRT
A.INSRT
SQUOZE 4,.INEOF
A.INEO
IRPS X,,I O
IRPS Y,,1 2
SQUOZE 4,.!X!FNM!Y
X!FNM!Y,,INTSYM
TERMIN TERMIN
SQUOZE 4,.IFVRS
IFVRS,,INTSYM
SQUOZE 4,.TTYFLG
A.TTYFLG,,INTSYM
] ;IFN TS
IFN .I.FSW,[
SQUOZE 4,.F
A.F
SQUOZE 4,.I
A.I
]
; Finally insert system-dependent initial symbols and wrap everything up.
IFN ITSSW,[
IRPS X,,UAI UAO BAI BAO UII UIO BII BIO
SQUOZE 10,.!X
.IRPCN
TERMIN
IRPS X,Y,START LFILE STP+SYM JCL PFILE STB CONV+XUNAME XJNAME LJB+
SQUOZE 10,..R!X
.IRPCN+1
IFSN Y,+,[
SQUOZE 10,..S!X
400000+.IRPCN+1
] TERMIN
] ;IFN ITSSW
; Now re-insert system-dependent symbol definition files so that they
; become part of the initial symtab that MIDAS knows about. This does
; not need to be done for ITS since those symbols are acquired from the
; system at run time (and thus are always current).
ISYSYM: ; Remember start of system symbols
; Redefine DEFSYM so as to make entry into initial symbol table.
; Note that this will lose if the code for MIDAS has re-defined any
; of the symbols inserted from these files at the beginning of MIDAS.
; Everything in these files should use =: or ==: to catch redefinitions!
DEFINE DEFSYM X/
IRPS Z,,[X]
SQUOZE 8.,Z
Z
.ISTOP
TERMIN
TERMIN
IFN DECSW,[ ; Define UUOs for DEC version
IFE CVTSW,[
.DECDF DEFSYM
IFN DECBSW,.INSRT DECBTS
];IFE CVTSW
IFN CVTSW, .INSRT DECDFU
] ;IFN DECSW
IFN TNXSW,[ ; Define JSYSes for TENEX/TOPS-20 version
IFE CVTSW,[
.TNXJS DEFSYM
.INSRT TWXBTS
];IFE CVTSW
IFN CVTSW, .INSRT TNXDFU
] ;IFN TNXSW
; Simple check to help verify that all system symbol entries were 2 wds long.
IFN <.-ISYSYM>&1,.ERR System symbol def error
EISYMT: PRINTA \.-MACTBA-1, words initialization coding.
VARIAB
IFN .-EISYMT,.ERR Non-empty variables area
IFN DECSW,[
IFGE .-MACTBA-MACL,[
IFN MACL, PRINTA [MACL too small, set to ]\.-MACTBA
MACL==.-MACTBA
]]
IFN ITSSW\TNXSW,[
IFGE .+2400-MACTBA-MACL,.ERR MACL too small
LOC <.+1777>&-2000
MXICLR==./2000 ;FIRST PAGE ABOVE INITIALIZING CODING
LOC <MACTBA+MACL+1777>&-2000
MXIMAC==./2000 ;FIRST PAGE ABOVE INITIAL MACTBA
MAXMAC==<CONMAX+CONMAX/4+CONMAX/12+1+MXMACL+SYMMAX*MAXWPS+ST+1777>/2000
;1ST PAGE MACRO TABLE CAN'T POSSIBLY USE.
IFLE MINPUR-MAXMAC,.ERR Pure too low.
PRINTA Wasted gap pages (MINPUR-MAXMAC) = ,\MINPUR-MAXMAC
PBLK ; Must end assembly at end of pure, so that when doing .DECSAV type
; assembly the msymtab for MIDAS itself will be in high core.
]
IFN TS,END BEG
END