Annotation of researchv10no/cmd/spitbol/tokvms.spt, revision 1.1

1.1     ! root        1: -IN80
        !             2: -TITLE TOKVMS: TRANSLATE FROM TOKENS TO VMS ASSEMBLER
        !             3: -STITL REVISION HISTORY
        !             4: *
        !             5: *  12-AUG-82 (REG):
        !             6: *       Read tokenized input and remove EQUATES processing
        !             7: * 09-MAR-82 (SGD):
        !             8: *       CHK is back - better than ever...
        !             9: *       Copy .INI file to start of .MAR file
        !            10: * 10-SEP-81 (SGD):
        !            11: *       Read in problem label table from filename.PLB
        !            12: * 01-AUG-81 (SGD):
        !            13: *       Better encoding of CTB,CTW,BTW and WTB
        !            14: * 13-MAY-81 (SGD):
        !            15: *       Added logic in XOP to put a longword type displacement on displacement
        !            16: *       operands as VMS assembler assumes a word displacement. (Phhhhaaa - ed)
        !            17: * 15-MAR-81 (SGD):
        !            18: *       Made CHK a comment, as now handled as exception.
        !            19: * 10-SEP-80 (SGD):
        !            20: *       Made revisions to make XFER reflect VAX SBL capabilities.  Note that
        !            21: *       this version of XFER is no longer capable of running on PDP-11, since
        !            22: *       it will be too big.  [Major change was to substitute tables for LOOKUP
        !            23: *       strings, and corresponding addition of TINIT].
        !            24: * 02-AUG-80 (SGD):
        !            25: *       Altered translation of conditional branches to emit conditional
        !            26: *       branch directly.  Those which cause problems are listed in a
        !            27: *       table that inhibits the direct translation.
        !            28: * 18-MAY-80 (SGD):
        !            29: *       Fixed translation of vertical tab (CH$VT) from ASCII 011 to ASCII 012
        !            30: *       to conform to SOS Editor standard.
        !            31: *
        !            32: -STITL INTRODUCTION
        !            33: *                         < XFER >
        !            34: *               MINIMAL To VAX 11/780 Translator
        !            35: *               ________________________________
        !            36: *
        !            37: *                        Coded by:
        !            38: *                      Steven G. Duff
        !            39: *                 1345-M16 Cabrillo Park Dr.
        !            40: *                 Santa Ana, California 96701
        !            41: *                      (714) 541-9619
        !            42: *
        !            43: *      This is a Macro Spitbol program for translation of the Macro
        !            44: *      Spitbol Minimal Source to Vax 11/780 Macro Source.  The program
        !            45: *      is fairly simple in order that it be able to run in the limited
        !            46: *      address space of a PDP-11.  As a consequence, certain of the
        !            47: *      Minimal Opcodes are left untranslated, to be expanded as macros
        !            48: *      at assembly time.  These macros are:
        !            49: *
        !            50: *              AOV, BSW, CMC, CVD, CVM, ESW,
        !            51: *              IFF, LSX, MCB, MFI, MVC, MVW, MWB, RMI, SEC, TRC.
        !            52: *
        !            53: *      There are two principal parts of Minimal that make translation
        !            54: *      tricky vis-a-vis VAX MACRO-32:
        !            55: *
        !            56: *
        !            57: *      Tricky #1: BSW,IFF and ESW normally require buffering, sorting
        !            58: *              etc.  These can (and are) handled by macros though.  BSW
        !            59: *              emits a CASEL and a word table containing the default
        !            60: *              value.  IFF re-biases the location counter during assembly
        !            61: *              and overwrites the default word.  ESW resets the location
        !            62: *               counter back.  XFER is not capable of handling the needed
        !            63: *               computation without more working store.
        !            64: *
        !            65: *       V       V  NOW HANDLED BY TOKENIZER
        !            66: *       Tricky #2: Minimal operands of the form DLBL(X) must be translated
        !            67: *               to 4*DLBL(X) as called for by the language spec.  This
        !            68: *               requires that XFER be able to distinguish DLBLs from other
        !            69: *               stuff.  This in turn means that a record of all EQU labels
        !            70: *               must be kept.  This eats up a lot of working store, but
        !            71: *               can't be helped.
        !            72: *
        !            73: *       The other macro-ops are simple enough, and are omitted purely to
        !            74: *       avoid using up dynamic unnecessarily.
        !            75: -EJECT
        !            76: *       This program works with four files, with the same name, and
        !            77: *       different extensions.  Name.MIN is used as the source input
        !            78: *       file.  Name.MAR is created and becomes the source output file.
        !            79: *       Name.ERR is created, and is where the ERR and ERB messages and
        !            80: *       numbers are written.  Name.INI is a prefix (MACRO32) file
        !            81: *       that is read as input and copied to Name.MAR before translation
        !            82: *       begins.
        !            83: *
        !            84: *       The VAX assembler does not permit an equate to a register symbol
        !            85: *       for the purpose of creating symbolic register names.
        !            86: *       Thus this translator maps registers from Minimal to Vax thusly:
        !            87: *
        !            88: *                       RA  <=>  R2
        !            89: *                       CP  <=>  R3
        !            90: *                       IA  <=>  R5
        !            91: *                      WA  <=>  R6
        !            92: *                      WB  <=>  R7
        !            93: *                      WC  <=>  R8
        !            94: *                      XR  <=>  R9
        !            95: *                      XL  <=>  R10  (XT ALSO)
        !            96: *                      XS  <=>  SP   (R14)
        !            97: *
        !            98: *      Additionally, there are two other 'phantom' registers assumed
        !            99: *      by the translator - a scratch register (SR) which is used by
        !           100: *      a few instructions and by some of the character macros for
        !           101: *      holding temps, and EXI for returns.  For remaindering,
        !           102: *      a register (IA2) is presumed to be available immediately below IA.
        !           103: *      The mappings of these registers are:
        !           104: *
        !           105: *                      IA2 <=>  R4
        !           106: *                      SR  <=>  R11
        !           107: *
        !           108: *      Changes to this mapping are ill-advised and difficult.
        !           109: *
        !           110: *
        !           111: *      XFER aint got much smarts (it cant afford them).  Except for cursory
        !           112: *      syntax and opcode checks, almost anything will get through, so it
        !           113: *      should be said that it expects valid Minimal Source.  Simple errors
        !           114: *      are flagged on the listing (with a traceback) and a count given at
        !           115: *      the end, so they should not be too hard to find.
        !           116: -STITL INITIALIZATION
        !           117: *                       WARNING - POST NO LABELS!!!!!
        !           118: *                       -----------------------------
        !           119: *       No labels should appear in this initializing code that would prevent
        !           120: *       the code from being garbage-collected by SPITBOL.
        !           121: -SPACE 3
        !           122: *       Keyword initialization
        !           123: *
        !           124:         &ANCHOR = 1;    &TRIM = 1;      &STLIMIT = -1
        !           125: *
        !           126: *       Useful constants
        !           127: *
        !           128:         MINLETS = 'ABCDEFGHIJKLMNOPQRSTUVWXY$'
        !           129:         NOS     = '0123456789'
        !           130:         TAB     = SUBSTR( &ALPHABET,10,1 )
        !           131:         REGNAME = ('X' ANY('LSTR')) | ('W' ANY('ABC')) | 'IA' | 'RA' | 'CP'
        !           132:         LL      = 5000          ;*USED FOR LOCAL LABEL GENERATION
        !           133: *
        !           134: *       Zero the counts
        !           135: *
        !           136:         LABCNT = NOUTLINES = NLINES = NSTMTS = NTARGET = NERRORS = 0
        !           137: *
        !           138: *       Get file name
        !           139: *
        !           140:         TERMINAL = 'Enter Token Filename:'
        !           141:         FILENAMI = TERMINAL
        !           142:         TERMINAL =
        !           143:         TERMINAL = 'Enter Problem Label Filename:'
        !           144:         FILENAMP = TERMINAL
        !           145:         TERMINAL =
        !           146:         TERMINAL = 'Enter Front Section Filename:'
        !           147:         FILENAMF = TERMINAL
        !           148:         TERMINAL =
        !           149:         TERMINAL = 'Enter Assembler Filename:'
        !           150:         FILENAMO = TERMINAL
        !           151:         TERMINAL =
        !           152:         TERMINAL = 'Do you want full-line comments passed to the output? [Y/N]'
        !           153:         FLCFLAG  = TERMINAL
        !           154: *
        !           155: *       No page ejects without full line comments
        !           156: *
        !           157:         TERMINAL = DIFFER(FLCFLAG,'N')
        !           158:         TERMINAL = DIFFER(FLCFLAG,'N') 'Do you want EJC ops (Page Ejects)'
        !           159: +                                       'passed? [Y/N]'
        !           160:         EJCFLAG  = (DIFFER(FLCFLAG,'N') TERMINAL, 'N')
        !           161: -STITL XFER FUNCTIONS
        !           162: *       TINIT is used during initialization to take a string of the
        !           163: *       form  "index1[value1]index2[value2]...indexn[valuen]" and
        !           164: *       stuff the index/value pairs into a table which it returns.
        !           165: *
        !           166:        DEFINE('TINIT(STR)POS,CNT,INDEX,VAL,LASTVAL')
        !           167: *      CRACK parses STMT into a STMT data plex and returns it.
        !           168: *      It fails if there is a syntax error.
        !           169: *
        !           170:        DEFINE('CRACK(LINE)LABEL,OPCODE,OPERANDS,COMMENT,OPERAND,CHAR')
        !           171: *
        !           172: *      STMT is the common data plex used to hold the components of
        !           173: *      a statement (either Minimal or VAX) during processing.
        !           174: *
        !           175:        DATA('STMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)')
        !           176: *
        !           177: *      MINLABEL is a pattern matching a valid Minimal Source Label.
        !           178: *
        !           179:        MINLABEL = ANY(MINLETS) ANY(MINLETS) ANY(MINLETS NOS)
        !           180: +                 ANY(MINLETS NOS) ANY(MINLETS NOS)
        !           181: *
        !           182: *      MINCOND is a pattern that matches Minimal Conditional assembly ops
        !           183: *
        !           184:        MINCOND = 'IF' | 'THEN' | 'ELSE' | 'FI' | 'DEF' | 'UNDEF'
        !           185: *
        !           186: -EJECT
        !           187: *       DOSTMT is the driver routine that causes processing of the
        !           188: *       statement plex in THISSTMT.
        !           189: *
        !           190:         DEFINE('DOSTMT()LABEL,OPCODE,OP1,OP2,OP3,COMMENT,T')
        !           191: *
        !           192: *       HANDLER is a table providing the name of the processing appendage
        !           193: *       for every Minimal Op-Code.  The name in this table is prefixed with
        !           194: *       "H_" to get the string name of the appendage.  Every op must be
        !           195: *      in this string, including conditional ops.
        !           196: *
        !           197:        HANDLER = TINIT(
        !           198: +              'ADD[H]ADI[ADD2]ADR[ADD2]ANB[ANB]'
        !           199: +              'AOV[H]BCT[H]BEQ[BCMP]BGE[BCMP]'
        !           200: +              'BGT[BCMP]BHI[BCMP]BLE[BCMP]BLO[BCMP]'
        !           201: +              'BLT[BCMP]BNE[BCMP]BRN[H]BRI[BRI]'
        !           202: +              'BNZ[BTST]'
        !           203: +              'BSW[H]BTW[BTW]BZE[BTST]CEQ[BCMP]'
        !           204: +              'CHK[H]CMB[CMB]CMC[H]CNE[BCMP]'
        !           205: +              'CSC[NOOP]CTB[CTX]CTW[CTX]CVD[H]'
        !           206: +              'CVM[H]DAC[H]DBC[H]DCA[NEW1]'
        !           207: +              'DCV[H]DEF[DEF]DIC[H]DRC[H]'
        !           208: +              'DTC[DTC]DVI[ADD2]DVR[ADD2]EJC[EJC]'
        !           209: +              'ELSE[H]END[END]ENP[NOOP]ENT[ENT]'
        !           210: +              'EQU[EQU]ERB[ERX]ERR[ERX]ESW[H]'
        !           211: +              'EXI[EXI]EXP[NOOP]FI[H]ICA[NEW1]'
        !           212: +              'ICP[ICP]ICV[H]IEQ[ATST]IF[H]'
        !           213: +              'IFF[H]IGE[ATST]IGT[ATST]ILE[ATST]'
        !           214: +              'ILT[ATST]INE[ATST]INO[OVF]INP[NOOP]'
        !           215: +              'INR[NOOP]IOV[OVF]ITR[ITR]JSR[H]'
        !           216: +              'LCH[SWP12]LCT[LCT]LCP[ADD2]LCW[NEW1]'
        !           217: +              'LDI[ADD2]LDR[ADD2]LEI[LEI]LSH[XSH]'
        !           218: +              'LSX[H]MCB[H]MFI[H]MLI[ADD2]MLR[ADD2]'
        !           219: +              'MNZ[NEW1]MOV[H]MTI[ADD2]MVC[H]'
        !           220: +              'MVW[H]MWB[H]NGI[NGX]NGR[NGX]'
        !           221: +              'NZB[BTST]ORB[H]PLC[PXC]PPM[PPM]'
        !           222: +              'PRC[PRC]PSC[PXC]REQ[ATST]RGE[ATST]'
        !           223: +              'RGT[ATST]RLE[ATST]RLT[ATST]RMI[H]'
        !           224: +              'RNE[ATST]RNO[OVF]ROV[OVF]RSH[XSH]'
        !           225: +              'RSX[H]RTI[RTI]RTN[NOOP]SBI[ADD2]'
        !           226: +              'SBR[ADD2]SCH[H]SCP[NEW1]SEC[SEC]'
        !           227: +              'SSL[NOOP]SSS[NOOP]STI[STX]STR[STX]'
        !           228: +              'SUB[H]THEN[H]TRC[H]TTL[TTL]'
        !           229: +              'UNDEF[UNDEF]WTB[WTB]XOB[H]'
        !           230: +              'ZER[H]ZGB[NOOP]ZRB[BTST]')
        !           231: *
        !           232: *      H_ADD2.OPS is used by the H_ADD2 appendage to find
        !           233: *      the operand it is to insert.
        !           234: *
        !           235:        H_ADD2.OPS = TINIT(
        !           236: +              'ADI[R5]ADR[R2]DVI[R5]DVR[R2]LCP[R3]LDI[R5]'
        !           237: +              'LDR[R2]MLI[R5]MLR[R2]MTI[R5]SBI[R5]SBR[R2]')
        !           238: -EJECT
        !           239: *      H_BNCH.OPCS provides opcode translations for branch-type
        !           240: *      instructions.  Branches are emitted directly, unless they are
        !           241: *      in the H_BNCH.PLAB problem label table, in which case an inverted
        !           242: *      branch/jump combination is emitted.
        !           243: *
        !           244:        H_BNCH.OPCS = TINIT('BEQ[BEQLU]BGE[BGEQU]BGT[BGTRU]BHI[BGEQU]'
        !           245: +              'BLE[BLEQU]BLO[BLEQU]BLT[BLSSU]BNE[BNEQU]'
        !           246: +              'BNZ[BNEQU]BZE[BEQLU]CEQ[BEQLU]'
        !           247: +              'CNE[BNEQU]IEQ[BEQL]IGE[BGEQ]IGT[BGTR]'
        !           248: +              'ILE[BLEQ]ILT[BLSS]INE[BNEQ]INO[BVC]'
        !           249: +              'IOV[BVS]NZB[BNEQU]'
        !           250: +              'REQ[BEQL]RGE[BGEQ]RGT[BGTR]RLE[BLEQ]'
        !           251: +              'RLT[BLSS]RNE[BNEQ]RNO[BVC]ROV[BVS]'
        !           252: +              'ZRB[BEQLU]')
        !           253: *
        !           254: *      H_BNCH.PLAB is a list of problem labels which for which 'short'
        !           255: *      conditional jumps cannot be issued, because one or more instructions
        !           256: *      in the code cause range trouble.  Inverted branches are emitted
        !           257: *      instead.
        !           258: *
        !           259:        H_BNCH.PLAB = TABLE(101)
        !           260: *
        !           261: *      H_BNCH.IOCS is a translate list for the inverted branches needed
        !           262: *      for problem labels.
        !           263: *
        !           264:        H_BNCH.IOCS = TINIT('BEQ[BNEQU]BGE[BLSSU]BGT[BLEQU]BHI[BLSSU]'
        !           265: +              'BLE[BGTRU]BLO[BGTRU]BLT[BGEQU]BNE[BEQLU]'
        !           266: +              'BNZ[BEQLU]BZE[BNEQU]CEQ[BNEQU]'
        !           267: +              'CNE[BEQLU]IEQ[BNEQ]IGE[BLSS]IGT[BLEQ]'
        !           268: +              'ILE[BGTR]ILT[BGEQ]INE[BEQL]INO[BVS]'
        !           269: +              'IOV[BVC]NZB[BEQLU]'
        !           270: +              'REQ[BNEQ]RGE[BLSS]RGT[BLEQ]RLE[BGTR]'
        !           271: +              'RLT[BGEQ]RNE[BEQL]RNO[BVS]ROV[BVC]'
        !           272: +              'ZRB[BNEQU]')
        !           273: *
        !           274: *      H_EQU.DEFS is used by H_EQU to insert the fluid EQU
        !           275: *      definitions (...EQU *).
        !           276: *
        !           277:        H_EQU.DEFS = TINIT(
        !           278: +              'CFP$A[256]CFP$B[4]CFP$C[4]CFP$F[8]'
        !           279: +              'CFP$I[1]CFP$M[^X7FFFFFFF]CFP$N[32]'
        !           280: +              'NSTMX[10]CFP$R[1]CFP$S[6]CFP$X[2]'
        !           281: +              'E$SRS[50]E$STS[512]E$CBS[512]E$HNB[253]'
        !           282: +              'E$HNW[3]E$FSP[20]'
        !           283: +              'CH$LA[065]CH$LB[066]CH$LC[067]CH$LD[068]'
        !           284: +               'CH$LE[069]CH$LF[070]CH$LG[071]CH$LH[072]'
        !           285: +               'CH$LI[073]CH$LJ[074]CH$LK[075]CH$LL[076]'
        !           286: +               'CH$LM[077]CH$LN[078]CH$LO[079]CH$LP[080]'
        !           287: +               'CH$LQ[081]CH$LR[082]CH$LS[083]CH$LT[084]'
        !           288: +               'CH$LU[085]CH$LV[086]CH$LW[087]CH$LX[088]'
        !           289: +               'CH$LY[089]CH$L$[090]'
        !           290: +               'CH$D0[048]CH$D1[049]CH$D2[050]CH$D3[051]'
        !           291: +               'CH$D4[052]CH$D5[053]CH$D6[054]CH$D7[055]'
        !           292: +               'CH$D8[056]CH$D9[057]'
        !           293: +               'CH$$A[097]CH$$B[098]CH$$C[099]CH$$D[100]'
        !           294: +               'CH$$E[101]CH$$F[102]CH$$G[103]CH$$H[104]'
        !           295: +               'CH$$I[105]CH$$J[106]CH$$K[107]CH$$L[108]'
        !           296: +               'CH$$M[109]CH$$N[110]CH$$O[111]CH$$P[112]'
        !           297: +               'CH$$Q[113]CH$$R[114]CH$$S[115]CH$$T[116]'
        !           298: +               'CH$$U[117]CH$$V[118]CH$$W[119]CH$$X[120]'
        !           299: +               'CH$$Y[121]CH$$$[122]'
        !           300: +               'CH$AM[038]CH$AS[042]CH$AT[064]CH$BB[060]'
        !           301: +               'CH$BL[032]CH$BR[124]CH$CL[058]CH$CM[044]'
        !           302: +               'CH$DL[036]CH$DT[046]CH$DQ[034]CH$EQ[061]'
        !           303: +               'CH$EX[033]CH$MN[045]CH$NM[035]CH$NT[126]'
        !           304: +               'CH$PC[037]CH$PL[043]CH$PP[040]CH$RB[062]'
        !           305: +               'CH$RP[041]CH$QU[063]CH$SL[047]CH$SM[059]'
        !           306: +               'CH$SQ[039]CH$UN[095]CH$OB[091]CH$CB[093]'
        !           307: +               'CH$HT[009]CH$VT[012]IODEL[047]')
        !           308: -EJECT
        !           309: *       H_H.XOPS is a table that encodes opcode translation
        !           310: *       for H_H.
        !           311: *
        !           312:         H_H.XOPS =  TINIT(
        !           313: +               'ADD[ADDL2]ADI[ADDL2]ADR[ADDF2]ANB[BICL2]'
        !           314: +               'BCT[SOBGTR]'
        !           315: +               'BRN[JMP]'
        !           316: +               'CMB[MCOML]'
        !           317: +               'CTB[BICL2]CTW[ASHL]'
        !           318: +               'DAC[.LONG]DBC[.LONG]'
        !           319: +               'DCA[SUBL2]DCV[DECL]DIC[.LONG]DRC[.FLOAT]'
        !           320: +               'DVI[DIVL2]DVR[DIVF2]EJC[.PAGE]'
        !           321: +               'ELSE[.IF_FALSE]ERB[JMP]'
        !           322: +               'ERR[.ADDRESS]FI[.ENDC]'
        !           323: +               'ICA[ADDL2]ICP[TSTL]ICV[INCL]'
        !           324: +               'IF[.IF NOT_EQUAL]'
        !           325: +               'ITR[CVTLF]JSR[JSB]'
        !           326: +               'LCH[MOVZBL]LCT[MOVL]LCP[MOVL]LCW[MOVL]'
        !           327: +               'LDI[MOVL]LDR[MOVF]LEI[MOVZWL]LSH[ASHL]'
        !           328: +               'MLI[MULL2]MLR[MULF2]'
        !           329: +               'MNZ[MOVL]MOV[MOVL]MTI[MOVL]'
        !           330: +               'NGI[MNEGL]NGR[MNEGF]'
        !           331: +               'ORB[BISL2]PPM[.ADDRESS]'
        !           332: +               'RSH[ASHL]'
        !           333: +               'SBI[SUBL2]'
        !           334: +               'SBR[SUBF2]SCH[MOVB]SCP[MOVL]'
        !           335: +               'STI[MOVL]STR[MOVF]'
        !           336: +               'SUB[SUBL2]THEN[.IF_TRUE]'
        !           337: +               'TTL[.SUBTITLE]'
        !           338: +               'XOB[XORL2]ZER[CLRL]')
        !           339: *
        !           340: *       H_NEW1.OPS is a table used by the H_NEW1 appendage to find
        !           341: *       the operand to insert.  It is indexed by opcode.
        !           342: *
        !           343:         H_NEW1.OPS = TINIT(
        !           344: +               'ICA[#4]DCA[#4]'
        !           345: +               'LCW[(R3)+]MNZ[SP]SCP[R3]')
        !           346: *
        !           347: *       Associate file for ERB,ERR messages in H_ERX
        !           348: *
        !           349:         OUTPUT(.ERRFILE,4,(IDENT(FILENAMO) 'KB:',  'X.ERR'))
        !           350: -EJECT
        !           351: *       Error is used to report an error for THISSTMT
        !           352: *
        !           353:         DEFINE('ERROR(TEXT)')
        !           354: -SPACE 3
        !           355: *       OUTSTMT is used to send a target statement to the target code
        !           356: *       output file (OUTFILE <=> LU2)
        !           357: *
        !           358:         DEFINE('OUTSTMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)T,STMTOUT')
        !           359: *
        !           360: *       Associate output file
        !           361: *
        !           362:         OUTPUT(.OUTFILE,2,(IDENT(FILENAMO) 'KB:', FILENAMO))
        !           363: *
        !           364: *       OS.LLS is used by OUTSTMT to recognise local labels
        !           365: *
        !           366:         OS.LLS  = SPAN(NOS) '$' RPOS(0)
        !           367: *
        !           368: *       READLINE is called to return the next non-comment line from
        !           369: *       the Minimal input file (INFILE <=> LU1).   Note that it will
        !           370: *       not fail on EOF, but it will return a Minimal END statement
        !           371: *
        !           372:         DEFINE('READLINE()')
        !           373: *
        !           374: *       Associate input file to LU1
        !           375: *
        !           376:         INPUT(.INFILE,1,(IDENT(FILENAMI) 'KB:', FILENAMI))
        !           377: -EJECT
        !           378: *
        !           379: *       XOP.REGS is a pattern to match out register names for translation.
        !           380: *
        !           381:         XOP.REGS = (*REGNAME . VAL  RPOS(0) . PREFIX)  |
        !           382: +                  (BREAK('(') LEN(1)) . PREFIX   LEN(2) . VAL
        !           383: *
        !           384: *       XOP.XREGS is a table with register translations
        !           385: *
        !           386:         XOP.XREGS = TINIT('IA[R5]RA[R2]CP[R3]WA[R6]WB[R7]WC[R8]XR[R9]'
        !           387: +                   'XL[R10]XT[R10]XS[SP]')
        !           388: *
        !           389: *       XPINTX is a pattern that will match the INT(X) type operand
        !           390: *
        !           391:         XPINTX  = SPAN(NOS) . VAL  '('
        !           392: *
        !           393: *       XPDLBLX is a pattern that will match the DLBL(X) type operand
        !           394: *
        !           395:         XPDLBLX = MINLABEL . VAL  '('
        !           396: -STITL MAIN PROGRAM
        !           397: *       Here follows the driver code for the "main" program.
        !           398: -SPACE 3
        !           399: *       Read the problem label table
        !           400: *
        !           401:         INPUT(.PLTAB,.PLTAB,DIFFER(FILENAMP) FILENAMP)  :F(MN02)
        !           402: MN01    H_BNCH.PLAB[PLTAB] = 'X'                        :S(MN01)
        !           403:         ENDFILE(.PLTAB)
        !           404: *
        !           405: *       Read the prefix file and copy to the output side
        !           406: *
        !           407: MN02    INPUT(.PREFIXIN,.PREFIXIN,DIFFER(FILENAMF) FILENAMF) :F(MN03)
        !           408: MN02A   OUTFILE = PREFIXIN                              :S(MN02A)
        !           409: *
        !           410: *       Loop until program exits via H_END
        !           411: *
        !           412: MN03    DOSTMT()                                        :(MN03)
        !           413: -STITL CRACK(LINE)
        !           414: *       CRACK is called to create a STMT plex containing the various
        !           415: *       entrails of the Minimal Source statement in LINE.  For
        !           416: *       conditional assembly ops, the opcode is the op, and OP1
        !           417: *       is the symbol.  Note that DTC is handled as a special case to
        !           418: *       assure that the decomposition is correct.
        !           419: *
        !           420: *       CRACK will print an error and fail if a syntax error occurs.
        !           421: *
        !           422: CRACK   NSTMTS  = NSTMTS + 1
        !           423:         LINE    '{' BREAK( '{' ) . LABEL
        !           424: +               '{' BREAK( '{' ) . OPCODE
        !           425: +               '{' BREAK( '{' ) . OP1
        !           426: +               '{' BREAK( '{' ) . OP2
        !           427: +               '{' BREAK( '{' ) . OP3
        !           428: +               '{' REM          . COMMENT              :F(CS03)
        !           429:         CRACK   = STMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)
        !           430:         CRACKERR =
        !           431: *
        !           432: *       Operands all parsed out.  That's all folks.
        !           433: *
        !           434: CS01    :(RETURN)
        !           435: *
        !           436: *       Here on syntax error
        !           437: *
        !           438: CS03    ERROR('SOURCE LINE SYNTAX ERROR')               :(FRETURN)
        !           439: -STITL DOSTMT()
        !           440: *       DOSTMT is invoked to initiate processing of the next line from
        !           441: *       READLINE.  For efficient access
        !           442: *       DOSTMT puts name values corresponding to the components in
        !           443: *       variables with the same names (LABEL, OPCODE, OP1,OP2,OP3 and
        !           444: *       COMMENT) which allows the various handlers to $var to store/fetch
        !           445: *       the values of the statment.
        !           446: *
        !           447: *       After doing this, DOSTMT branches to the handler routine indicated
        !           448: *       for this opcode in the HANDLER table (there must be an entry or
        !           449: *       an error results).  The handlers all have entry points beginning
        !           450: *       with "H_", and can be considered a logical extension of the
        !           451: *       DOSTMT routine.  The handlers have the choice of branching back
        !           452: *       to DSGEN to cause the THISSTMT plex to be sent to OUTSTMT, or
        !           453: *       of RETURNing themselves, in which case the handler must output
        !           454: *       all needed code itself.
        !           455: *
        !           456: *       The handlers are listed in a separate section below.
        !           457: *
        !           458: DOSTMT  THISLINE = READLINE()
        !           459:         THISSTMT = CRACK(THISLINE)              :F(DOSTMT)
        !           460:         LABEL   = .LABEL(THISSTMT)
        !           461:         OPCODE  = .OPCODE(THISSTMT)
        !           462:        MINOP   = $OPCODE
        !           463:        OP1     = .OP1(THISSTMT)
        !           464:        OP2     = .OP2(THISSTMT)
        !           465:        OP3     = .OP3(THISSTMT)
        !           466:        COMMENT = .COMMENT(THISSTMT)
        !           467: *
        !           468: *      Get handler entry point (less "H_" prefix)
        !           469: *
        !           470:        DIFFER(T = HANDLER[$OPCODE])                    :F(DS01)
        !           471: *
        !           472: *      Jump to handler
        !           473: *
        !           474:        :($('H_' T))
        !           475: *
        !           476: *      Here if bad OpCode
        !           477: *
        !           478: DS01   ERROR('BAD OP-CODE')                            :(RETURN)
        !           479: *
        !           480: *      Handlers can come back here to cause code generation of THISSTMT
        !           481: *
        !           482: DSGEN  OUTSTMT($LABEL,$OPCODE,$OP1,$OP2,$OP3,$COMMENT) :(RETURN)
        !           483: -STITL ERROR(TEXT)
        !           484: *      This module handles reporting of errors with the offending
        !           485: *      statement text in THISLINE.  Comments explaining
        !           486: *      the error are written to the listing (including error chain), and
        !           487: *      the appropriate counts are updated.
        !           488: *
        !           489: ERROR  OUTFILE = '; *???* ' THISLINE
        !           490:        OUTFILE = ';       ' TEXT
        !           491: +                (IDENT(LASTERROR),'. LAST ERROR WAS LINE ' LASTERROR)
        !           492:        LASTERROR = NOUTLINES
        !           493:        NOUTLINES = NOUTLINES + 2
        !           494:        NERRORS = NERRORS + 1
        !           495: +                      :(RETURN)
        !           496: -STITL OUTSTMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)
        !           497: *      This module writes the components of the VAX MACRO statement
        !           498: *      passed in the argument list to the formatted .MAR file
        !           499: *
        !           500: OUTSTMT        STMTOUT = (IDENT(LABEL) TAB,
        !           501: +                      LABEL ':' (?(LABEL ? OS.LLS), ':')
        !           502: +                              (GT(SIZE(LABEL),5), TAB))
        !           503: +                OPCODE  (GT(SIZE(OPCODE),7) ' ', TAB)
        !           504: +                (IDENT(OP1), OP1
        !           505: +                      (IDENT(OP2), ',' OP2
        !           506: +                              (IDENT(OP3), ',' OP3)))
        !           507: +                (IDENT(COMMENT),
        !           508: +                      (GT(T = SIZE(OP1 OP2 OP3), 16) ' ',
        !           509: +                              DUPL(TAB, (22 - T) / 8))
        !           510: +                      ';' COMMENT)
        !           511: *
        !           512: *      Send text to OUTFILE
        !           513: *
        !           514:        OUTFILE = STMTOUT
        !           515:        NTARGET = NTARGET + 1
        !           516:        NOUTLINES = NOUTLINES + 1
        !           517: +                      :(RETURN)
        !           518: -STITL READLINE()
        !           519: *      This routine returns the next statement line in the input file
        !           520: *      to the caller.  It never fails.  If there is no more input,
        !           521: *      then a Minimal END statement is returned.
        !           522: *      Comments are passed through to the output file directly.
        !           523: *
        !           524: *
        !           525: READLINE READLINE = INFILE                     :F(RL02)
        !           526:        NLINES  = NLINES + 1
        !           527:        READLINE  ANY('*') = ';'                :F(RL01)
        !           528: *
        !           529: *      Only print comment if requested.
        !           530: *
        !           531:         OUTFILE = IDENT(FLCFLAG,'Y') READLINE   :F(READLINE)
        !           532:         NOUTLINES = NOUTLINES + 1               :(READLINE)
        !           533: *
        !           534: *       Here if not a comment line
        !           535: *
        !           536: RL01    :(RETURN)
        !           537: *
        !           538: *       Here on EOF
        !           539: *
        !           540: RL02    READLINE = '       END'
        !           541:                         :(RL01)
        !           542: -STITL TINIT(STR)
        !           543: *       This routine is called to initialize a table from a string of
        !           544: *       index/value pairs.
        !           545: *
        !           546: TINIT   POS     = 0
        !           547: *
        !           548: *       Count the number of "[" symbols to get an assessment of the table
        !           549: *       size we need.
        !           550: *
        !           551: TIN01   STR     (TAB(*POS) '[' BREAK(']') *?(CNT = CNT + 1) @POS)
        !           552: +                                       :S(TIN01)
        !           553: *
        !           554: *       Allocate the table, and then fill it. Note that a small memory
        !           555: *       optimisation is attempted here by trying to re-use the previous
        !           556: *       value string if it is the same as the present one.
        !           557: *
        !           558:         TINIT   = TABLE(CNT)
        !           559: TIN02   STR     (BREAK('[') $ INDEX LEN(1) BREAK(']') $ VAL LEN(1)) =
        !           560: +                                       :F(RETURN)
        !           561:         VAL     = CONVERT(VAL,'INTEGER')
        !           562:         VAL     = IDENT(VAL,LASTVAL) LASTVAL
        !           563:         LASTVAL = VAL
        !           564:         TINIT[INDEX] = VAL              :(TIN02)
        !           565: -STITL OPCODE HANDLER APPENDAGES
        !           566: *       Ops that need a second operand (get from table).
        !           567: *
        !           568: H_ADD2  $OP2    = H_ADD2.OPS[$OPCODE]           :(H_H)
        !           569: -SPACE 3
        !           570: *       Do ANB opcode
        !           571: *
        !           572: H_ANB   OUTSTMT($LABEL,'MCOML',$OP1,'R11',,$COMMENT)
        !           573:         $OP1    = 'R11'
        !           574:         $LABEL  = $COMMENT =                    :(H_H)
        !           575: -SPACE 3
        !           576: *       Real and Integer Branch tests
        !           577: *       CHANGE CALL OF XOP TO XOP.XREGS LOOKUP
        !           578: *
        !           579: H_ATST  OUTSTMT($LABEL,'TST' (IDENT(SUBSTR($OPCODE,1,1),'R') 'F', 'L'),
        !           580: +               XOP.XREGS[SUBSTR($OPCODE,1,1) 'A'],,,$COMMENT)
        !           581:         $OP2    = $OP1                          :(H_BNCH)
        !           582: -SPACE 3
        !           583: *       Comparison branches - emit a CMPL
        !           584: *
        !           585: H_BCMP  OUTSTMT($LABEL,'CMPL',$OP1,$OP2,,$COMMENT)
        !           586:         $OP2    = $OP3                          :(H_BNCH)
        !           587: -SPACE 3
        !           588: *       Entered via various handlers to generate conditional branch code
        !           589: *
        !           590: H_BNCH  DIFFER(H_BNCH.PLAB[$OP2])       :S(H_BNCH01)
        !           591:         OUTSTMT(,H_BNCH.OPCS[$OPCODE],$OP2)     :(RETURN)
        !           592: H_BNCH01 OUTSTMT(,H_BNCH.IOCS[$OPCODE],(LL = LL + 1) '$')
        !           593:         OUTSTMT(,'JMP',$OP2)
        !           594:         OUTSTMT(LL '$')                                 :(RETURN)
        !           595: -SPACE 3
        !           596: *       Handle BRI instruction with indirection
        !           597: *
        !           598: H_BRI   OUTSTMT($LABEL,'MOVL',$OP1,'R11',,$COMMENT)
        !           599:         OUTSTMT(,'JMP','(R11)')         :(RETURN)
        !           600: -SPACE 3
        !           601: *       Zero branch comparisons
        !           602: *
        !           603: H_BTST  OUTSTMT($LABEL,'TSTL',$OP1,,,$COMMENT)
        !           604: +                                               :(H_BNCH)
        !           605: -EJECT
        !           606: *       BTW opcode
        !           607: *
        !           608: H_BTW   OUTSTMT($LABEL,'ASHL','#-2',$OP1,$OP1,$COMMENT) :(RETURN)
        !           609: -SPACE 3
        !           610: *       Do CMB instruction by duping operand for MCOML
        !           611: *
        !           612: H_CMB  $OP2    = $OP1                          :(H_H)
        !           613: -SPACE 3
        !           614: *      Do CTB and CTW
        !           615: *
        !           616: H_CTX  OUTSTMT($LABEL,'MOVAB','3+<4*' $OP2 '>(' $OP1 ')',$OP1,,$COMMENT)
        !           617:        $LABEL  = $COMMENT =
        !           618:        $OP2    = $OP1
        !           619:        $OP1    = (IDENT($OPCODE,'CTB') '#3','#-2')
        !           620:        $OP3    = IDENT($OPCODE,'CTW') $OP2             :(H_H)
        !           621: -SPACE 3
        !           622: *      Do DEF Conditional op with an equate to 1 (to 'define')
        !           623: *
        !           624: H_DEF   $OPCODE = $OP1 '='
        !           625:         $OP1    = '1'                           :(DSGEN)
        !           626: -SPACE 3
        !           627: *       Handle DTC by emitting .ASCII and then alignment order
        !           628: *
        !           629: H_DTC   OUTSTMT($LABEL,'.ASCII',$OP1,,,$COMMENT)
        !           630:         OUTSTMT(,'.ALIGN','LONG','0')   :(RETURN)
        !           631: -SPACE 3
        !           632: *       EJC checks to see if page feeds are to be passed.
        !           633: *
        !           634: H_EJC   IDENT(EJCFLAG,'Y')                      :S(H_H)F(RETURN)
        !           635: -SPACE 3
        !           636: *       END prints statistics on terminal then exits program
        !           637: *
        !           638: H_END   OUTSTMT(,'.END',,,,$COMMENT)
        !           639:         TERMINAL = '*** TRANSLATION COMPLETE ***'
        !           640:         TERMINAL = NLINES ' LINES READ.'
        !           641:         TERMINAL = NSTMTS ' STATEMENTS PROCESSED.'
        !           642:         TERMINAL = NTARGET ' TARGET CODE LINES PRODUCED.'
        !           643:         TERMINAL = NERRORS ' ERRORS OCCURRED.'
        !           644:         TERMINAL = DIFFER(LASTERROR) 'THE LAST ERROR WAS IN LINE ' LASTERROR
        !           645:         &CODE   = NE(NERRORS) 2001
        !           646:         :(END)
        !           647: -EJECT
        !           648: *       ENT emits the word ID (if needed) and the entry label
        !           649: *
        !           650: H_ENT   IDENT($OP1)                     :S(H_ENT01)
        !           651:         OUTSTMT(,'.ALIGN','WORD')
        !           652:         OUTSTMT(,'.WORD',$OP1)
        !           653: *
        !           654: *       Merge here to emit label entry point
        !           655: *
        !           656: H_ENT01 OUTSTMT($LABEL,,,,,$COMMENT)    :(RETURN)
        !           657: *       Handle EQU by inserting label in EQUATES for DLBL routine, and
        !           658: *       substituting '*' operands from definitions table if necessary
        !           659: *
        !           660: H_EQU   $OP1    = IDENT($OP1,'*') H_EQU.DEFS[$LABEL]
        !           661:        $OPCODE = $LABEL '=='
        !           662:        $LABEL  =                                       :(DSGEN)
        !           663: -SPACE 3
        !           664: *      Handle ERB and ERR in essentially the same way.  First, send
        !           665: *      the message to the auxilliary .ERR file.  Then make sure to
        !           666: *      note if this is the highest error # seen so far, so branch
        !           667: *      table can be properly emitted (see SEC).  Then set OP1 to
        !           668: *      be "ERROR_" concatenated with the error number.  This label
        !           669: *      refers to a label in the jump table that will load this error
        !           670: *      code in WA and jump to ERROR$.
        !           671: *
        !           672: H_ERX  ERRFILE = LPAD($OP1,3,0) ($COMMENT = (IDENT($OP2), $OP2 ' ')
        !           673: +                      $COMMENT)
        !           674:        MAXERR  = GT($OP1,MAXERR) $OP1
        !           675:        $OP1    = 'ERROR_' LPAD($OP1,3,0)
        !           676:        $OP2    =                               :(H_H)
        !           677: -EJECT
        !           678: *      There are 8 cases to EXI, partitioned along 3 binary dimensions.
        !           679: *      These are: 1. OP1 given/not given,  2. PTYPE is R/E or N,
        !           680: *      3. OP1=1 (or #Ppms=0 if OP1 not given).  Each possibility generates
        !           681: *      slightly different code.
        !           682: *
        !           683: H_EXI  IDENT($OP1)                             :S(H_EXI00)
        !           684:        T       = (IDENT(PTYPE,'N') PNAME '_SAVE','(SP)+')
        !           685:        (EQ($OP1,1) OUTSTMT($LABEL,'MOVL',T,'R11',,$COMMENT),
        !           686: +               OUTSTMT($LABEL,'ADDL3','#4*' $OP1 - 1,T,'R11',$COMMENT))
        !           687:        OUTSTMT(,'JMP','@(R11)+')               :(H_EXI04)
        !           688: *
        !           689: *      Here if EXI has no OP1 given (normal exit)
        !           690: *
        !           691: H_EXI00        EQ(PPMS,0)                              :S(H_EXI02)
        !           692:        IDENT(PTYPE,'N')                        :S(H_EXI01)
        !           693: *
        !           694: *      No OP1, #PPMs>0 and R/E-type
        !           695: *
        !           696:        OUTSTMT($LABEL,'ADDL2','#4*' PPMS,'(SP)',,$COMMENT)
        !           697:        OUTSTMT(,'RSB')                 :(H_EXI04)
        !           698: *
        !           699: *      Here if N-type PRC with no OP1 given & #PPMs > 0
        !           700: *
        !           701: H_EXI01        OUTSTMT($LABEL,'ADDL3','#4*' PPMS,PNAME '_SAVE','R11',$COMMENT)
        !           702:        OUTSTMT(,'JMP','(R11)')         :(H_EXI04)
        !           703: *
        !           704: *      Here if no OP1, & #PPMs = 0
        !           705: *
        !           706: H_EXI02        IDENT(PTYPE,'N')                        :S(H_EXI03)
        !           707: *
        !           708: *      No OP1, #PPMs=0 and R/E-type
        !           709: *
        !           710:        OUTSTMT($LABEL,'RSB',,,,$COMMENT)       :(H_EXI04)
        !           711: *
        !           712: *      No OP1, #PPMs=0 and N-type
        !           713: *
        !           714: H_EXI03        OUTSTMT($LABEL,'JMP','@' PNAME '_SAVE',,,$COMMENT)
        !           715: *
        !           716: *      Merge to exit
        !           717: *
        !           718: H_EXI04        :(RETURN)
        !           719: -EJECT
        !           720: *      H is entered directly by some opcodes, and eventually by
        !           721: *      most others.  It performs an opcode translation if an entry exists
        !           722: *      for it (non-null) in the H_H.XOPS table and then goes to DSGEN to
        !           723: *      dump the statement.
        !           724: *
        !           725: H_H    $OPCODE = DIFFER(TEMP = H_H.XOPS[$OPCODE]) TEMP         :(DSGEN)
        !           726: -SPACE 3
        !           727: *      Handle ICP opcode with a TSTL on (CP)+
        !           728: *
        !           729: H_ICP  $OP1    = '(R3)+'                       :(H_H)
        !           730: -SPACE 3
        !           731: *      Handle ITR with a MOVLF on IA to RA
        !           732: *
        !           733: H_ITR  $OP1    = 'R5'
        !           734:        $OP2    = 'R2'                          :(H_H)
        !           735: -SPACE 3
        !           736: *      LCT does not emit if both operands are the same
        !           737: *
        !           738: H_LCT  DIFFER($OP1,$OP2)                               :S(H_SWP12)
        !           739:        OUTSTMT($LABEL,,,,,$COMMENT)                    :(RETURN)
        !           740: -SPACE 3
        !           741: *      LEI uses MOVZWL on the word just prior to the entry point
        !           742: *
        !           743: H_LEI  $OP2    = $OP1
        !           744:        $OP1    = '-2(' $OP1 ')'                        :(H_H)
        !           745: -EJECT
        !           746: *      Make operand 1 operand 2, and put in a new operand 1 according
        !           747: *      to the table.
        !           748: *
        !           749: H_NEW1 $OP2    = $OP1
        !           750:        $OP1    = H_NEW1.OPS[$OPCODE]   :(H_H)
        !           751: -SPACE 3
        !           752: *       No-op instructions.  Comment out the opcode
        !           753: *
        !           754: H_NOOP  (IDENT($OPCODE,'INP'), IDENT($OPCODE,'INR'), IDENT($OPCODE,'EXP'))
        !           755: +                                                       :S(RETURN)
        !           756:         $OPCODE = ';' $OPCODE                           :(DSGEN)
        !           757: -SPACE 3
        !           758: *       Do arithmetic negate ops
        !           759: *       CHANGE CALL OF XOP TO LOOKUP IN XOP.XREGS
        !           760: *
        !           761: H_NGX   $OP1    = $OP2 = XOP.XREGS[SUBSTR($OPCODE,3,1) 'A']
        !           762: +                                                       :(H_H)
        !           763: -SPACE 3
        !           764: *       Handle arithmetic overflow tests [IOV,INO,ROV,RNO]
        !           765: *
        !           766: H_OVF   $OP2    = $OP1
        !           767:         $OP1    =                                       :(H_BNCH)
        !           768: -SPACE 3
        !           769: *       Insert dummy PPM branch point if none given
        !           770: *
        !           771: H_PPM   $OP1    = IDENT($OP1) 'INVALID$'                :(H_H)
        !           772: -SPACE 3
        !           773: *       PRC notes the operands for later EXIs in global variables, and
        !           774: *       emits save area code if N-type.
        !           775: *
        !           776: H_PRC   PTYPE   = $OP1
        !           777:         PPMS    = $OP2
        !           778:         PNAME   = $LABEL
        !           779:         OUTSTMT(,'.ENABLE','LOCAL_BLOCK')
        !           780: *
        !           781: *       If N-type, then we need a save area word
        !           782: *
        !           783:         DIFFER(PTYPE,'N')                       :S(H_PRC01)
        !           784:         OUTSTMT($LABEL,'MOVL','(SP)+',PNAME '_SAVE',,$COMMENT)
        !           785:         OUTSTMT(,'.SAVE_PSECT','LOCAL_BLOCK')
        !           786:         OUTSTMT(,'.PSECT','PRC_SAVE','NOEXE')
        !           787:         OUTSTMT(PNAME '_SAVE','.LONG','0')
        !           788:         OUTSTMT(,'.RESTORE_PSECT')
        !           789:         :(H_PRC02)
        !           790: *
        !           791: *       Here if R/E type
        !           792: *
        !           793: H_PRC01 OUTSTMT($LABEL,';PRC',,,,$COMMENT)
        !           794: *
        !           795: *      Merge to exit
        !           796: *
        !           797: H_PRC02        :(RETURN)
        !           798: -EJECT
        !           799: *      Do PLC, PSC ops
        !           800: *
        !           801: H_PXC  (IDENT($OP2) OUTSTMT($LABEL,'MOVAB','CFP$F(' $OP1 ')',$OP1,,$COMMENT))
        !           802: +                                              :S(RETURN)
        !           803:        $OP2 ((('R' ANY(NOS) (ANY(NOS) | '')) | 'SP') RPOS(0))  :S(H_PXC1)
        !           804:        OUTSTMT($LABEL,'MOVL',$OP2,'R11',,'[GET IN SCRATCH REGISTER]')
        !           805:        $LABEL  =
        !           806:        $OP2    = 'R11'
        !           807: H_PXC1 OUTSTMT($LABEL,'MOVAB','CFP$F(' $OP1 ')[' $OP2 ']',$OP1,,$COMMENT)
        !           808: +                                              :(RETURN)
        !           809: -SPACE 3
        !           810: *      Handle RTI with CVTFL and then BVS if PLBL present
        !           811: *
        !           812: H_RTI  OUTSTMT($LABEL,'CVTFL','R2','R5',,$COMMENT)
        !           813:        (DIFFER($OP1) OUTSTMT(,'BVS',$OP1))     :(RETURN)
        !           814: -SPACE 3
        !           815: *
        !           816: *      SEC does various things depending on the current section
        !           817: *
        !           818: H_SEC  H_SEC.CNT = H_SEC.CNT + 1
        !           819: *
        !           820: *      Get rid of the extrinsic defs. if past defs. section (saves space)
        !           821: *
        !           822:        H_EQU.DEFS = EQ(H_SEC.CNT,3)
        !           823: *
        !           824: *      If we have reached the Stack Ovfl. sect. then dump the ERR list
        !           825: *
        !           826:        NE(H_SEC.CNT,6)                                 :S(H_SEC02)
        !           827:        OUTSTMT(,'.PAGE')
        !           828:        OUTSTMT('ERR_ADDR','.ADDRESS','ERROR$')
        !           829:        T       = 0
        !           830: *
        !           831: *      Loop here to emit code for saved up ERR objects.
        !           832: *
        !           833: H_SEC01 T       = LT(T,MAXERR) T + 1            :F(H_SEC02)
        !           834:         OUTSTMT('ERROR_' LPAD(T,3,'0'), 'MOVZWL', '#' T, 'R6')
        !           835:         OUTSTMT(,'JMP','@ERR_ADDR')             :(H_SEC01)
        !           836: *
        !           837: *       Merged when finished with ERRs list.
        !           838: *
        !           839: H_SEC02 :(H_H)
        !           840: -EJECT
        !           841: *       Arithmetic store ops (STI,STR)
        !           842: *       CHANGE CALL OF XOP TO LOOKUP OF XOP.XREGS
        !           843: *
        !           844: H_STX   $OP2    = $OP1
        !           845:         $OP1    = XOP.XREGS[SUBSTR($OPCODE,3,1) 'A']    :(H_H)
        !           846: -SPACE 3
        !           847: *       Ops that need to have op1 and op2 switched.
        !           848: *
        !           849: H_SWP12 T = $OP1
        !           850:         $OP1    = $OP2
        !           851:         $OP2    = T                                     :(H_H)
        !           852: -SPACE 3
        !           853: *
        !           854: *       TTL restores the title text from OP1 and COMMENT
        !           855: *
        !           856: H_TTL   OUTSTMT(,'.PAGE')
        !           857:         $OP1    = (IDENT($OP1), $OP1 ' ') $COMMENT
        !           858:         $COMMENT =                                      :(H_H)
        !           859: -SPACE 3
        !           860: *       UNDEF is done with an equate to 0, to "undefine" the symbol
        !           861: H_UNDEF $OPCODE = $OP1 '='
        !           862:         $OP1    = '0'                                   :(DSGEN)
        !           863: -SPACE 3
        !           864: *       Immediate mode shifts
        !           865: *
        !           866: H_XSH   $OP3    = $OP1
        !           867:         $OP1    = '#' (IDENT($OPCODE,'LSH'),'-') $OP2
        !           868:         $OP2    = $OP3                                  :(H_H)
        !           869: -SPACE 3
        !           870: *       WTB opcode
        !           871: H_WTB   OUTSTMT($LABEL,'MOVAL','0[' $OP1 ']',$OP1,,$COMMENT) :(RETURN)
        !           872: -EJECT
        !           873: END

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.