; -*-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 ; 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 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- ;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 .--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: 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,-1+ADR FOO==FOO+ 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 .--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)++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>,, 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* 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>,, 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 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 RETURNS RELOCATION OF ARG A.RELP: CALL AGETFD MOVE A,B JRST VALRET ;.ABSP 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* 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. PBY5: MOVE A,GLSPAS MOVEM A,GLSP1 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 ,4 ADD ,(+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 -1,0 ASHC -1,2 SUB ,(-1)CCOMPT!B TERMIN ;BP IN A RETURN CHAR ADR IN A+1, CLOBBERS A DEFINE CCOMP1 A,B/ MULI ,4 SUB +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 = 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: ; ,, ; ,, ; \<# GROUPS>,, ; ,,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 ,,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: *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, ;,, 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 &-2000 MXIMAC==./2000 ;FIRST PAGE ABOVE INITIAL MACTBA MAXMAC==/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