;MAC80 - An 8085 cross assembler for the DECsystem-10 ; Copyright 1976,1977,1978,1983 ; Bruce Tanner / Cerritos College ; 11110 Alondra Blvd. ; Norwalk, CA 90650 SEARCH M80UNV .TITLE (MAC80A,\M80MAJ,\M80EDT) TWOSEG RELOC 400000 EXTERN IBUF,OBUF,LBUF,NOFILE,FILNAM,FILEXT,PPN,OPNOBJ MAC80A::MOVE T1,[PUSHJ P,UUO] MOVEM T1,.JB41## MOVE T1,[IOWD 20,MACSTK] MOVEM T1,MACPDL MOVEI T1,-1 MOVEM T1,INVECT MOVEI T1,1 MOVEM T1,PAGENO SETOM STARTA SETZB E,LBTP SETZB BC,OX TDO F,[FL.LNR,,FR.PS1!FR.HEX] RESTAR: TRNE F,FR.PS1 ;PASS1? JRST PASS1 ;YES OUTSTR [ASCIZ/Pass 2 /] SETZM PC SETZM LINENO PUSHJ P,GTDATE PUSHJ P,DOHEAD ;OUTPUT THE HEADINGS ; JRST MAIN. ;JUMP TO THE MAIN LINE MAIN.: TRZ F,FR.LOP!FR.LOW ;CLEAR LIST OP FLAG TRZE F,FR.END ;IF END JRST ENDIT ;FINI PUSHJ P,INCH ;SNEAK A LOOK FOR FF PUSHJ P,DOLINO ;PRINT LINE # PUSHJ P,TOKEN1 ;GET TOKEN WITH 1ST CHAR IN I JRST MAIN1 DUNTAG: TRZE F,FR.END ;DONE? JRST ENDIT ;YES PUSHJ P,TOKEN ;GET A TOKEN MAIN1: PUSHJ P,IFPOP ;AN "IF" TYPE PSEUDO OP? JRST NOTEST ;YES TRNE F,FR.OFF ;ASSEMBLING? JRST FLUSHX ;NO NOTEST: JUMPN TOK,.+4 ;SKIP IF SOMETHING CAIE I,CR ;EOL? CAIN I,SEMICO ;COMMENT? JRST FLUSHX ;YES CAIN I,COLON ;TAG? JRST DOTAG ;YES PUSHJ P,SRCHOP ;SEARCH OPCODE JRST [PUSHJ P,SETMAC JRST MAIN.] MOVE OP,OPCTAB(X) ;STORE THE OPCODE MOVE P1,TYPLSH(X) ;GET TYPE,,SHIFT TLNN P1,T.POP ;PSEUDO OP? JRST .+3 ;NO, SKIP PUSHJ P,PSEUDO ;YUP JRST MAIN. TLNE P1,T.1BYT ;JUST OPCODE? JRST ONEOP ;1 BYTE INSTRUCTION TLNE P1,T.NREG ;USES REGISTER? JRST BYTE3 ;NO REGISTER DOREG: PUSHJ P,TOKEN ;GET THE NEXT TOKEN PUSHJ P,EVAL ;EVALUATE THE TOKEN CAIL T1,10 ;LEGAL REGISTER? WARN W.REG ;NO. ANDI T1,7 ;MAKE LEGAL TRNE P1,4 ;REGISTER PAIR? LSH T1,-1 ;YES, MAKE 2 BITS WIDE LSH T1,(P1) ;SHIFT ACCORDING TO LSH(X) OR OP,T1 ;MERGE TLZE P1,T.MOV ;A MOVE? JRST [TRZ P1,-1 ;YES - CLEAR LSH JRST DOREG] ;AND MERGE OTHER REG TLNE P1,T.2BYT!T.3BYT ;2 OR 3 BYTE INSTR? JRST BYTE3 ;GO ON AND DO DATA BYTES ONEOP: PUSHJ P,OUTOP ;OUTPUT THE ONE BYTE PUSHJ P,SPACE4 PUSHJ P,SPACE4 FLUSHX: PUSHJ P,FLUSH ;FLUSH THE REST OF THE LINE JRST MAIN. BYTE3: PUSHJ P,LSTPC ;OUTPUT THE OPCODE MOVE T1,OP PUSHJ P,LSTOP PUSHJ P,TOKEN ;GET THE DATA BYTE(S) JUMPN TOK,NOTMT ;NOT EMPTY CAIE I,15 ;BREAK ON EOL? CAIN I,SEMICO WARN W.MT ;DEFENSIVE CODE NOTMT: PUSHJ P,DODATA ;COMP. EFFECTIVE ADDR MOVE T1,OP PUSHJ P,LSTOP ;OUTPUT THE LOWER 8 BITS LSH OP,-10 ;SHIFT DOWN TLNE P1,T.2BYT ;JUST 1 DATA BYTE? JRST NOP1 MOVE T1,OP PUSHJ P,LSTOP ;OUTPUT UPPER 8 BITS NOP1: IFN FTREL,< SETZ T1, ;CLEAR FOR TEST TRZE F,FR.REL ;RELOCATABLE? MOVEI T1,"'" ;FLAG AS TRZE F,FR.EXT ;EXTERNAL? MOVEI T1,"*" ;INDICATOR SKIPE T1 ;ANYTHING THERE? PUSHJ P,LOUCH ;YES, PRINT IT > ;END IFN FTREL TLNE P1,T.2BYT ;NEED SPACES? PUSHJ P,SPACE4 ;YES JRST FLUSHX ;LOOP SPACE4: TRNE F,FR.HEX POPJ P, MOVEI T1,SPACE REPEAT 4,< PUSHJ P,LOUCH> POPJ P, ;EVAL TOKEN IN TOK (AND REST OF EXPR IF ANY) RETURN VALUE IN OP DODATA: TRZ F,FR.UND ;CLEAR STATUS SETZM EXPLVL ;INIT EXPR LEVEL MOVE T4,[IOWD 20,OPSTK] PUSH T4,["$"] ;FLAG TOP OF STACK SETZ T2, ;CLEAR FLAG PUSH P,T2 JRST DODT12 ;JUMP IN DODAT1: CAIE I,COMMA CAIN I,SEMICO ;KNOWN TERMINATORS? JRST DODAT4 ;YES CAIE I,")" ;END OF EXPR CAIN I,CR ;OR EOL? JRST DODAT4 ;YES PUSH T4,I ;SAVE ON OP STACK CAIE I,SPACE CAIN I,TAB ;IF SPACE OR TAB CAIA ;KEEP LOOKING FOR OP JRST DODT10 ;HAVE OP ON STACK, GET 2ND ARG POP T4,(T4) ;OP IS JUST SPACE OR TAB PUSHJ P,TOKEN ;GET OP TOKEN JUMPE TOK,DODAT1 ;OP IS BREAK, DODAT1 WILL DO IT PUSH T4,TOK ;SAVE OP AS 6BIT TOKEN ;AT THIS POINT I MAY CONTAIN UNARY OP. CAIE I,SPACE CAIN I,TAB ;BETTER CONTAIN SPACE JRST DODT10 CAIN I,MINUS ;UNARY MINUS? JRST [PUSH P,T2 JRST DODT21] ;YES CAIE I,"(" ;THIS IS THE ONLY NON BLANK THING ALLOWED ERROR F.ILEX DODT10: PUSH P,T2 CAIE I,"(" ;DON'T LET TOKEN BUST INTO EXPR PUSHJ P,TOKEN ;GET NEXT TOKEN DODT12: SKIPE TOK ;IF NO TOKEN JRST DODT20 CAIN I,MINUS ;THEN THIS IS A UNARY MINUS DODT21: MOVEI I,"@" ;SPECIAL SYMBOL FOR UNARY MINUS DODT20: CAMN TOK,[SIXBIT/NOT/] ;THE OTHER UNARY OPERATOR? JRST DODT23 ;YES CAME TOK,[SIXBIT/HIGH/] CAMN TOK,[SIXBIT/LOW/] JRST DODT23 JRST DODT22 ;NO, SKIP DODT23: POP P,T2 ;RESTORE T2 PUSH T4,TOK ;SAVE OP SETZB T1,TOK ;CLEAR TOK IN CASE NOT(EXPR) PUSH P,T1 ;SAVE DUMMY ARG (DUMMY NOT FOO) JRST DODT10 ;NOW GET A TOKEN DODT22: PUSHJ P,EVALD ;EVAL TOKEN (OR EXPR) POP P,T2 DODT13: PUSH P,I ;SAVE I MOVE I,(T4) ;GET LAST OP CAIN I,"$" ;NO LAST OP? JRST DODT14 ;SKIP PUSHJ P,DINDEX ;GET INDEX IN T3 MOVE OP,PRIOR(T3) ;GET PRIORITY OF LAST OP IN T3 (1 IS HIGEST) MOVE I,-1(T4) ;GET OP PREVIOUS TO LAST OP CAIN I,"$" ;NOT THERE? JRST DODT14 ;SKIP PUSHJ P,DINDEX ;GET INDEX OF THIS ONE CAML OP,PRIOR(T3) ;CAN WE EVAL YET? JRST DODT15 ;YES ;NOTE: THIS IMPLIES LEFT-TO-RIGHT SCAN OF EQUAL PRI. UNARY OPS MAY NOT BE PUT TOGETHER. DODT14: POP P,I ;DONE WITH I PUSH P,T1 ;SAVE VALUE ON STACK TRNN F,FR.REL!FR.EXT ;ABS? TRO T2,1 ;FLAG ABS TRNE F,FR.REL ;RELOC? TRC T2,2 ;ABS & REL = REL; REL & REL = ABS TRNE F,FR.EXT ;EXTERNAL? ADDI T2,10 JRST DODAT1 ;KEEP GOING DODT15: POP P,I ;DONE WITH I (DODT13) MOVEM T1,SAVREG ;SAVE T1 POP T4,SAVREG+1 ;& LAST OPERATOR POP P,T1 POP P,OP MOVEM I,SAVREG+2 POP T4,I ;GET CURRENT OP PUSHJ P,DINDEX XCT EXPXCT(T3) ;DOIT TOIT PUSH P,OP ;SAVE NEW VALUE BACK ON STACK MOVE I,SAVREG+2 ;RESTORE I PUSH T4,SAVREG+1 ;PUT BACK LAST OP MOVE T1,SAVREG ;RESTORE LAST ARG JRST DODT13 ;SEE IF WE CAN COMPRESS MORE DODAT4: CAIE I,")" ;IF EOE JRST .+4 SOSGE EXPLVL ;IF WE WERE AT TOP LEVEL.. ERROR F.PARN JRST .+3 SKIPE EXPLVL ;THE REST BETTER BE AT TOP LEVEL ERROR F.PARN POP P,OP ;GET VALUE MOVEM I,SAVREG+3 ;SAVE I DODAT5: POP T4,I ;GET OP CAIN I,"$" ;ALL DONE? JRST DODATX ;YES MOVE T1,OP POP P,OP ;GET 2ND ARG PUSHJ P,DINDEX ;GET INDEX IN T3 XCT EXPXCT(T3) ;DO IT JRST DODAT5 ;LOOP DODATX: MOVE I,SAVREG+3 ;RESTORE I ANDI OP,177777 ;JUST 16 BITS MOVE T1,OP ;GET NUMBER CAIN T2,10 ;ONE EXTERN? JRST DODAT3 ;YES CAILE T2,3 ;1 (ABS) OR 2 OR 3 (REL) ? ERROR F.EXT ;NO POLISH FIXUPS IN THIS ASSEMBLER DODAT3: TRZ F,FR.REL!FR.EXT ;CLEAR STATUS OF LAST TOKEN IFN FTREL,< TRNE T2,2 ;IF REL TRO F,FR.REL ;FLAG CAIN T2,10 ;IF EXTERN TRO F,FR.EXT ;FLAG TRNN F,FR.PS1 ;IF PASS1 SKIPN T2 ;OR NON-RELOCATABLE POPJ P, ;RETURN TRNE F,FR.HEX ;IF OCTAL FORMAT TRNE F,FR.EXT ;OR EXTERN POPJ P, ;EXIT CAIE T2,1 ;IF FLAGED AS ABS, TRNE F,FR.ORG ;OR NOT RELOCATING POPJ P, EXCH T1,RELPTR MOVE T2,PC MOVEM T2,RELTAB(T1) ;SAVE PC FOR NEXT LINK AOJ T1, ;BUMP POINTER EXCH T1,RELPTR > ;END IFN FTREL POPJ P, ;RETURN DEFINE OPRMAC,< E "+",,3 E "-",,3 E "@",,1 E "*",,2 E "/",,2 E "\",,2 E "&",,4 E "!",,5 E "_",,2 E "#",,1 E 'AND ',,4 E 'OR ',,5 E 'MOD ',,2 E 'XOR ',,5 E 'SHR ',,2 E 'SHL ',,2 E 'NOT ',,1 E 'HIGH ', E 'LOW ', > DEFINE E(CHAR,INSTR,PRI),< CHAR> SALL OPRTAB: OPRMAC OPRTBL==.-OPRTAB DEFINE E(CHAR,INSTR,PRI),< INSTR> EXPXCT: OPRMAC ERROR F.ILEX ;EXECUTED IF OP IS NOT IN OPRMAC DEFINE E(CHAR,INSTR,PRI),< EXP PRI> PRIOR: OPRMAC EXDIV: PUSH P,OP+1 IDIV OP,T1 POP P,OP+1 POPJ P, EXMOD: PUSH P,OP+1 IDIV OP,T1 MOVE OP,OP+1 POP P,OP+1 POPJ P, EXSHR: MOVNS T1 LSH OP,(T1) POPJ P, EVALD: CAIE I,"(" ;A WHOLE EXPR? JRST EVAL ;NO, JUST EVAL AOS EXPLVL ;FLAG WHICH LEVEL WE'RE IN SETZ I, ;GET RID IF PAREN FOR TEST @ DODT10+1 PUSH T4,["$"] ;DON'T PLOW THROUGH UPPER LEVEL STUFF PUSHJ P,DODT10 ;MUNCH ON (EXPR) CAIE I,CR CAIN I,SEMICO ;IF ERROR ON EOL, DODAT4 ALREADY HOLLERED POPJ P, ;RETAIN THIS BREAK FOR ANY OTHER LEVELS CAIE I,")" ;SHOULD END ON ) ERROR F.ILEX JRST INCH ;GET THE BREAK CHAR DINDEX: MOVSI T3,-OPRTBL CAME I,OPRTAB(T3) AOBJN T3,.-1 SKIPL T3 ERROR F.ILEX ;NOT IN TABLE POPJ P, TOKEN: TRZ F,FR.LOW ;MAKE ASCII TO SIXBIT WORK RIGHT CAIE I,CR PUSHJ P,INCH TOKEN1: CAIE I,SPACE ;FLUSH LEADING SPACES & TABS CAIN I,TAB JRST TOKEN SETZ TOK, MOVE T1,[POINT 6,TOK] CAIA TOKENL: PUSHJ P,INCH PUSHJ P,BREAK ;BREAK CHARACTER? POPJ P, SUBI I,40 ;CONVERT TO SIXBIT TLNN T1,770000 ;TOK FULL? JRST TOKENW ;YES, THROW OUT READ OF TOKEN IDPB I,T1 ;PUT IN TOK JRST TOKENL TOKENW: PUSHJ P,INCH ;WASTE REST OF TOKEN PUSHJ P,BREAK CAIA JRST TOKENW WARN W.TOK POPJ P, BREAK: CAIG I,"Z" CAIGE I,"A" ;A-Z? CAIA JRST SCPOPJ CAIG I,"9" CAIGE I,"0" ;0-9? CAIA JRST SCPOPJ ;YES CAIG I,"Z"+40 ;LC? CAIGE I,"A"+40 POPJ P, JRST SCPOPJ FLUSHL: CAIN I,LF ;IF ALREADY FLUSHED.. JRST LCRLF ;NEW LINE FLUSH: TRZ F,FR.LOW ;ASSUME STANDARD CASE CAIN I,LF POPJ P, PUSHJ P,INCH ;GET NEXT CHARACTER JRST FLUSH ;LOOP ;BINARY SEARCH OPNTAB SRCHOP: SETO T1, ;RANGE START MOVEI T2,OPTABL ;RANGE END SRCH1: MOVE T3,T2 ;GET END SUB T3,T1 ;GET LENGTH OF RANGE IDIVI T3,2 ;GET 1/2 RANGE JUMPE T3,SRCH10 ;NOT THERE ADD T3,T1 ;GET OFFSET INTO RANGE MOVE X,T3 ;GET IN X CAMN TOK,OPNTAB(X) ;MATCH? JRST SCPOPJ ;YES, SKIP RET CAML TOK,OPNTAB(X) MOVE T1,T3 ;SET NEW RANGE CAMG TOK,OPNTAB(X) MOVE T2,T3 JRST SRCH1 ;NO, LOOP SRCH10: MOVEI X,OPTABL ;POINT TO NULL ENTRY TRZE F,FR.EVL ;FROM EVAL? POPJ P, ;YES, QUIT NOW. MOVE T2,TOK ;SAVE TOKEN PUSHJ P,SNEAK ;SEE IF MACRO DEFINITION CAMN TOK,[SIXBIT/MACRO/] ;IS IT? JRST SRCHOK CAME TOK,[SIXBIT/EQU/] CAMN TOK,[SIXBIT/SET/] JRST SRCHOK JRST TSTMAC ;NO, SEE IF IT IS A MACRO ITSELF SRCHOK: PUSHJ P,TOKEN ;GET NEXT TOKEN CAME TOK,[SIXBIT/EQU/] ;NOTE: EQU & SET ARE IDENTICAL CAMN TOK,[SIXBIT/SET/] ;GOOD GUYS? JRST EQUAL ;YES CAMN TOK,[SIXBIT/MACRO/] JRST DOMAC TSTMAC: MOVE TOK,T2 ;PUT BACK TOKEN PUSHJ P,SRCSYM ;CHECK FOR MACRO JRST SRCERR ;NO MACRO TLNE T1,S.MAC ;MACRO? POPJ P, ;YES, SET UP MACRO SRCERR: ERROR F.ILOP ;NO. UNKNOWN OPCODE PUSHJ P,FLUSH ;WASTE REST JRST SCPOPJ PSEUDO: MOVSI X,-PTABL ;TABLE LENGTH CAME TOK,PTAB(X) ;MATCH? AOBJN X,.-1 ;LOOP JRST @PDISP(X) ;DISPATCH DEFINE PMAC,< PX ORG PX DS PX DB,DC PX DZ,DC PX DW,DC PX OPT,OPTION PX PHASE PX IFE,DOIFE PX IFN,DOIFN PX IF,DOIFN PX ELSE PX ENDIF PX PRINTX PX TITLE,DOTITL PX SUBTTL,DOSUBT PX INT,DOINT PX EXT,DOEXT PX END,DOEND > DEFINE PX(NAME,ADDR),< SIXBIT/NAME/> PTAB: XLIST PMAC LIST PTABL==.-PTAB DEFINE PX(NAME,ADDR),< IFB , IFNB ,> PDISP: XLIST PMAC JRST CPOPJ ;IN CASE UNDEF OPCODE LIST IFPOP: CAME TOK,[SIXBIT/IFE/] CAMN TOK,[SIXBIT/IFN/] POPJ P, CAME TOK,[SIXBIT/ENDIF/] CAMN TOK,[SIXBIT/END/] POPJ P, CAME TOK,[SIXBIT/IF/] CAMN TOK,[SIXBIT/ELSE/] POPJ P, AOS (P) POPJ P, ORG: TRO F,FR.ORG ;FLAG NO RELOCATION PUSHJ P,TOKEN ;GET ORG ARG PUSHJ P,DODATA ;GET THE NUMBER MOVEM OP,PC ;RESET PC TRNN F,FR.PS1 ;SKIP IF PASS1 JRST FLUSH ;NOPE, DONE MOVEM BC,ORGBLK(OX) ;STORE BYTE COUNT SKIPE BC ;IF BLOCK WAS VALID, ADDI OX,2 ;BUMP ORIGIN INDEX MOVEM OP,ORGBLK+1(OX) ;SAVE NEW START ADDRESS SETZ BC, ;NO BYTES IN NEW BLOCK JRST FLUSH ;FLUSH DOEND: TRO F,FR.END ;SAY WE'RE DONE CAIN I,CR ;JUST "END" & NO START ADDRESS? JRST FLUSH ;YES, FLUSH LINE. PUSHJ P,TOKEN ;GET END ADDRESS PUSHJ P,DODATA ;GET VALUE IF ANY MOVEM OP,STARTA PUSHJ P,NOPC ;LIST START ADDRESS IFN FTREL,< MOVEI T1,"'" TRZE F,FR.REL ;RELOC? PUSHJ P,LOUCH ;YES TRZN F,FR.EXT ;EXTERNAL? JRST FLUSH ;NO, DONE SETOM STARTA ;YES. THIS IS ILLEGAL WARN W.EXSA > ;END IFN FTREL JRST FLUSH DS: PUSHJ P,TOKEN ;GET BLOCK ARG PUSHJ P,DODATA PUSHJ P,LSTPC TRO F,FR.LOP MOVEI T1,TAB TRNN F,FR.HEX PUSHJ P,LOUCH MOVE T1,PC ;SAVE OLD PC ADDM T1,OP ;NEW PC JRST ORG+3 ;DS MEANS NEW BLOCK PHASE: PUSHJ P,TOKEN PUSHJ P,DODATA MOVEM OP,PC TRO F,FR.ORG ;NO RELOCATION JRST FLUSH PRINTX: TRNE F,FR.PS1 ;IF ON PASS1 JRST FLUSH ;SKIP IT TRO F,FR.LOW ;ENABLE LC PX1: PUSHJ P,INCH OUTCHR I CAIE I,LF JRST PX1 POPJ P, DC: MOVE T4,[POINT 10,STRING] ;SET UP OPCODE OUTPUT MOVE T2,T4 ;AND INPUT PUSH P,T2 ;SAVE IT DC0: PUSHJ P,TOKEN ;GET ARG(S) CAIE I,"'" CAIN I,QUOTE JRST [MOVEM I,DELIM ;SAVE QUOTE JRST DC4] ;DO QUOTED STRING PUSH P,T4 ;DODATA DESTROYS T4 PUSHJ P,DODATA POP P,T4 MOVE T2,OP ;SAVE IT ANDI OP,377 ;LOWER 8 BITS IDPB OP,T4 ;SAVE OP MOVE OP,T2 ;GET BACK ALL OF OP AOS BYTCNT ;COUNT TOTAL BYTES IN AOS PC ;FIX PC FOR EVAL AOS XTRAPC ;FOR FIXUP TLNN P1,T.DW ;WHOLE WORD? JRST DC1 ;NO LSH OP,-10 ANDI OP,377 ;JUST DATA BITS TRZE F,FR.REL ;IF RELOC TRO OP,400 ;FLAG TRZE F,FR.EXT ;IF EXT TRO OP,1000 ;FLAG IDPB OP,T4 AOS BYTCNT AOS PC AOS XTRAPC DC1: CAIN I,COMMA ;CONTINUE? JRST DC0 ;YES CAIE I,TAB ;LEADING SPACE? CAIN I,SPACE JRST [PUSHJ P,INCH JRST DC1] ;YES, EAT IT POP P,OP ;GET START BYTE POINTER SETZ TOK, ;RESET COUNTER SKIPN BYTCNT ;ANY BYTES IN THERE? JRST DCX0 ;NO SOSGE XTRAPC JRST DC2 SOS PC JRST .-3 DC2: SETZM XTRAPC PUSHJ P,LSTPC ;LIST PC MOVEI TOK,3 ;TOKEN NOT INUSE NOW TLNE P1,T.DW ;WORDS? MOVEI TOK,2 ;YES DC3: ILDB T1,OP PUSH P,T1 ;SAVE IT PUSHJ P,LSTOP ;OUTPUT OP WITHOUT UPDATING PC POP P,T1 SOSG BYTCNT ;ONE LESS BYTE IN STRING JRST DCX ;ALL GONE SOJG TOK,DC3 ;LOOP FOR 2 OR 3 BYTES TRNE T1,400 ;IF RELOCATABLE JRST [MOVEI T1,"'" ;FLAG PUSHJ P,LOUCH JRST .+1] TRNE T1,1000 ;IF EXTERNAL JRST [MOVEI T1,"*" PUSHJ P,LOUCH JRST .+1] PUSHJ P,FLUSHL ;PRINT LINE OF SOURCE (OR NEW LINE) JRST DC2 ;DO ANOTHER LINE DCX: SOJ TOK, ;COUNT BYTE PRINTED IFN FTREL,< MOVE T3,T1 ;GET FLAGS SETZ T1, TRNE T3,400 ;RELOC WORD? MOVEI T1,"'" TRNE T3,1000 ;EXTERN? MOVEI T1,"*" CAIE T1,"'" CAIN T1,"*" PUSHJ P,LOUCH ;OUTPUT IF ' OR * > ;END IFN FTREL DCX0: TLNN P1,T.DZ ;NEED A LAST ZERO? JRST DCX2 ;NO JUMPN TOK,DCX1 ;JUMP IF PC ALREADY PRINTED CAIN I,LF PUSHJ P,LCRLF CAIN I,CR ;ON A CR? PUSHJ P,INCH ;FLUSH LINE PUSHJ P,LSTPC ;LIST PC MOVEI TOK,3 TLNE P1,T.DW ;WORDS? MOVEI TOK,2 DCX1: SETZ T1, PUSHJ P,LSTOP ;LIST ZERO SOJ TOK, ;COUNT DOWN DCX2: JUMPE TOK,FLUSHL ;DONE PUSHJ P,SPACE4 ;SPACE OUT SOJG TOK,.-1 ;LOOP JRST FLUSHL ;DONE DC4: TRO F,FR.LOW ;enable lower case input PUSHJ P,INCH ;GET LIT CAMN I,DELIM ;END QUOTE? JRST [TRZ F,FR.LOW ;disable lc PUSHJ P,INCH JRST DC1] IDPB I,T4 ;SAVE CHAR AOS BYTCNT CAIE I,CR ;EOL? CAIN I,LF CAIA ;YES JRST DC4 ;NO DC6: MOVE TOK,BYTCNT ;GET COUNT OF BYTES READY TO GO CAIGE TOK,3 ;ENOUGH FOR A LINE? JRST DC4 ;NO MOVEI TOK,3 ;SET UP BYTES/LINE PUSHJ P,LSTPC ;DO PC POP P,OP ;GET BYTE POINTER DC7: ILDB T1,OP ;GET BYTE SOS BYTCNT ;COUNT DOWN PUSH P,T1 PUSHJ P,LSTOP ;LIST IT POP P,T1 SOJG TOK,DC7 PUSH P,OP ;SAVE IT CAIN I,CR ;GOT HERE VIA CR? JRST DC4 ;YES, CAUSE LINE TO BE PRINTED JRST DC6 ;JUST BYTES FOR A WHILE DOINT: SKIPA T2,[XWD S.INT,0] DOEXT: MOVSI T2,S.EXT PUSHJ P,TOKEN ;GET TOKEN PUSHJ P,SRCSYM ;FIND IT (OR EMPTY LOC) MOVEM TOK,(S) ;NOT THERE, STUFF IT IORM T2,1(S) ;FLAG SYMBOL TLNE T2,S.EXT ;EXTERNAL? HLLOS 1(S) ;YES, MAKE RH -1 (FOR END OF CHAIN) CAIN I,COMMA ;MORE TO COME? JRST DOEXT+1 ;YES JRST FLUSH ;NO DOMAC: MOVE TOK,T2 ;GET MACRO NAME DOMAC0: POP P,(P) ;CAME VIA JRST FROM SUBROUTINE TRO F,FR.NRF ;WE WANT TO KNOW IF MACRO WAS NEVER REFERENCED PUSHJ P,SRCSYM ;FIND IN SYMBOL TABLE MOVEM TOK,(S) ;SAVE IT PUSHJ P,SYMDEF ;LINE DEFINED ON MOVSI T1,S.MAC ;FLAG AS A MACRO REFERENCE IORM T1,1(S) ;PUT IN SYMBOL TABLE SETZ T2, PUSH P,S DOMAC4: PUSHJ P,TOKEN MOVEM TOK,MACDUM(T2) ;SAVE DUMMY ARG NAME JUMPE TOK,.+3 ;SINCE NULL ENTRY MEANS END, IGNORE REST CAIN I,COMMA ;MORE? AOJA T2,DOMAC4 ;LOOP UNTIL NO MORE ARGS POP P,S PUSHJ P,FLUSH ;WASTE REST OF THE LINE MOVE T1,.JBFF## ;GET JOBFF HRRM T1,1(S) ;SAVE HOME OF MACRO MOVE T2,T1 HRLI T2,(POINT 7,0) ;POINTER TO MACRO BODY DOMAC1: TRO F,FR.LOW ;ENABLE LC PUSHJ P,INCH DOMAC3: HRRZI T1,1(T2) ;GET ADDRESS PART OF POINTER (+1) PUSHJ P,MEMXPN ;SEE IF MEMORY NEEDS TO BE EXPANDED CAIE I,SEMICO ;";"? JRST DOM10 ;NO LDB I,T2 ;GET LAST CHAR CAIE I,SEMICO ;DOUBLE ;;? JRST DOM11 ;NO SOJ T2, ;BACKUP BTP DOM9: ILDB I,T2 CAIN I,SEMICO JRST DOM12 ;FOUND IT CAIE I,TAB ;TRY TO ELIMINATE TRAILING TABS CAIN SPACE ;OR SPACES JRST DOM9 MOVEM T2,SAVREG ;SAVE FOR A WHILE JRST DOM9 MEMXPN: CAMG T1,.JBREL## ;WILL T1 FIT IN CORE? POPJ P, ;YES, EXIT PUSH P,T1 ;SAVE T1 CORE T1, ERROR F.NCOR POP P,T1 ;RESTORE T1 POPJ P, DOM12: PUSHJ P,FLUSH ;WASTE COMMENT MOVE T2,SAVREG ;GET POINTER MOVEI I,CR IDPB I,T2 ;STUFF CR SKIPA I,[LF] ;SET UP LF DOM11: MOVEI I,SEMICO ;PUT BACK ; DOM10: CAIE I,"'" ;CONCATENATE? IDPB I,T2 ;STUFF IT CAIE I,LF ;END OF LINE JRST DOMAC6 TRZ F,FR.MCM ;FLAG END OF ANY POSSIBLE COMMENT MOVE T4,T2 ;SAVE POINTER FOR END OF MACRO PUSHJ P,SNEAK ;TAKE A SNEAKY LOOK AT THE NEXT TOKEN CAMN TOK,[SIXBIT/ENDM/];END OF MACRO? JRST DOMAC5 ;YES JRST DOMAC7 ;NO, SEE IF A DUMMY ARG DOMAC6: PUSHJ P,BREAK ;IS IT WORTHWHILE TO LOOK FOR NEXT TOKEN? JRST DOMAC2 ;YES JRST DOMAC1 ;NO DOMAC5: MOVEI I,177 IDPB I,T4 MOVEI I,1 ;177,1 IS END OF MACRO IDPB I,T4 SETZ I, IDPB I,T4 ;END WITH NULL AOJ T4, ;POINT TO 1ST FREE WORD HRRM T4,.JBFF## ;UPDATE JOBFF TRNE F,FR.PS1 ;PASS1? JRST FPASS1 ;FLUSH REST OF LINE, RETURN TO NORMAL INPUT JRST FLUSHX ;FOR PASS2 DOMAC2: CAIN I,SEMICO TRO F,FR.MCM ;FLAG IGNORE REST OF LINE TRNE F,FR.MCM ;IN COMMENT? JRST DOMAC1 ;YES PUSHJ P,SNEAK ;LOOK AT NEXT TOKEN DOMAC7: JUMPE TOK,DOMAC1 ;NOTHING THERE MOVSI T3,-MACDML SKIPN MACDUM(T3) JRST DOMAC1 CAME TOK,MACDUM(T3) AOBJN T3,DOMAC7+2 JUMPGE T3,DOMAC1 PUSHJ P,TOKEN PUSH P,I MOVEI I,177 IDPB I,T2 MOVEI I,100(T3) IDPB I,T2 POP P,I JRST DOMAC3 EQUAL: MOVE TOK,T2 ;RESET TOKEN TRO F,FR.NRF ;DEFINITION IS NOT REFERENCE PUSHJ P,SRCSYM MOVEM TOK,(S) ;LOAD SYMBOL IF NOT THERE PUSH P,S ;SAVE S PUSHJ P,TOKEN ;GET ARG PUSHJ P,DODATA ;GET VALUE POP P,S ;RESTORE S HRRM OP,1(S) ;SET SYMBOL TABLE VALUE PUSHJ P,SYMDEF ;FLAG LINE DEFINED ON TRNN F,FR.UND ;IS EXPR UNDEFINED? JRST EQU1 ;NO, SKIP MOVE T1,1(S) ;GET FLAGS TLO T1,S.UNDF ;FLAG UNDEFINED HLLZM T1,1(S) ;PUT BACK, CLEAR VALUE OF EQU SETZ OP, ;A LITTLE HINT THAT ALL IS NOT OK JRST EQU2 ;SKIP EQU1: MOVE T1,1(S) ;GET FLAGS &C TLZ T1,S.UNDF ;MAKE SURE THAT THIS SYMBOL IS NOT UNDEFINED MOVEM T1,1(S) ;FOR CIRCULAR EQU MESS EQU2: POP P,(P) ;CAME VIA PUSHJ,.. PUSHJ P,NOPC TRNE F,FR.PS1 ;PASS1? JRST FPASS1 ;YES JRST FLUSHX ;NO OPTION: PUSHJ P,TOKEN CAMN TOK,[SIXBIT/HEX/] TRO F,FR.HEX CAMN TOK,[SIXBIT/OCT/] TRZ F,FR.HEX CAMN TOK,[SIXBIT/SMAC/] TLO F,FL.SUP CAMN TOK,[SIXBIT/LMAC/] TLZ F,FL.SUP CAIN I,COMMA JRST OPTION JRST FLUSH DOIFN: PUSHJ P,TOKEN PUSHJ P,DODATA AOS IFLEVL ;ONE MORE IF TRNE F,FR.OFF ;ALREADY OFF? JRST FLUSH SKIPE OP ;GOING OFF? JRST FLUSH ;NO TRNOFF: MOVE T1,IFLEVL MOVEM T1,OFFLVL ;YES, SAVE LEVEL OF OFF TRO F,FR.OFF ;SHUT OFF JRST FLUSH ;RETURN DOIFE: PUSHJ P,TOKEN PUSHJ P,DODATA AOS IFLEVL TRNE F,FR.OFF JRST FLUSH SKIPN OP JRST FLUSH JRST TRNOFF ;TURN OFF ELSE: TRNN F,FR.OFF ;ARE WE OFF? JRST TRNOFF ;NO, TURN OFF MOVE T1,OFFLVL ;GET OFF LEVEL CAMN T1,IFLEVL ;TURNED OFF AT THIS LEVEL? TRZ F,FR.OFF ;YES, TURN BACK ON JRST FLUSH ;FLUSH & RETURN ENDIF: TRNN F,FR.OFF ;OFF ALREADY? JRST ENDI2 ;NO, JUST DECR. & LEAVE MOVE T1,OFFLVL ;GET OFF LEVEL CAMN T1,IFLEVL ;WAS TURNED OFF AT THIS LEVEL? TRZ F,FR.OFF ;YES, TURN BACK ON ENDI2: SOSGE IFLEVL ;COUNT DOWN IF LEVELS WARN W.IF1 ;THERE WERE NO LEVELS! SKIPGE IFLEVL ;IF MESSED UP, SETZM IFLEVL ;FIX JRST FLUSH DOTITL: MOVE T1,[POINT 7,TITL] MOVEI T2,^D66 TRO F,FR.LOW PUSHJ P,INCH CAIN I,15 JRST FLUSH IDPB I,T1 SOJG T2,.-4 JRST FLUSH DOSUBT: CAIA ;TRY BREAK CHARACTER FIRST PUSHJ P,INCH ;GET DELIMITER CAIE I,TAB CAIN I,SPACE JRST .-3 ;FORGET SPACES MOVE T2,I MOVE T3,[POINT 7,SUBTTL] TRO F,FR.LOW MOVEI T4,SUBTLN SUB2: PUSHJ P,INCH CAMN I,T2 ;END OF STRING? JRST FLUSH ;YES SOSLE T4 IDPB I,T3 ;STUFF JRST SUB2 EVAL: TRZ F,FR.REL!FR.EXT ;INIT SETZ T1, ;CLEAR OUTPUT JUMPN TOK,DOSYM ;JUMP IF TOK NOT ZERO CAIE I,"'" ;INTEL QUOTE CAIN I,QUOTE JRST DOQUOT ;LITERAL CHARACTER CAIE I,DOLLAR POPJ P, ;MUST BE ZERO MOVE T1,PC ;DOLLAR IS PC TRO F,FR.REL ;DOLLAR IS ALSO RELOCATABLE PUSH P,T2 LDB T2,[POINT 3,P1,11] SKIPN T2 ;SKIP IF SOME FLAVOR OF DB SOJ T1, ;MINUS 1 (IT SEEMS BETTER THIS WAY) POP P,T2 JRST INCH ;EAT DOLLAR DOSYM: PUSHJ P,GETNUM ;EVALUATE NUMERICALLY POPJ P, ;RETURN WITH NUMBER IN T1 PUSHJ P,SRCSYM ;NOT NUMBER,SEARCH SYMBOL TABLE JRST .+3 ;NOT THERE HRRZS T1 POPJ P, ;RETURN WITH VALUE IN T1 PUSH P,T2 PUSH P,T3 PUSH P,T4 TRO F,FR.EVL ;TELL SRCHOP NOT TO FLAG ERROR PUSHJ P,SRCHOP ;CHECK FOR OPCODE JRST DOSYM3 ;NO OP TRZ F,FR.EVL ;CLEAR FLAG MOVE T2,OPCTAB(X) ;GET OPCODE MOVE T3,TYPLSH(X) ;GET TYPE TLNE T3,T.POP ;PSEUDO OP? JRST DOSYM3 ;YES, DONE TLNE T3,T.NREG ;USES REGISTER? JRST DOSYM1 ;NO ;CONT. DOSYM2: CAIN I,")" ;END OF EXPR? JRST DOSYM1 ;YES PUSH P,T2 PUSH P,T3 PUSHJ P,TOKEN PUSHJ P,EVAL CAILE T1,7 WARN W.REG ANDI T1,7 POP P,T3 POP P,T2 TRNE T3,4 LSH T1,-1 LSH T1,(T3) OR T2,T1 TLZE T3,T.MOV ;A MOVE? JRST [TRZ T3,-1 JRST DOSYM2] DOSYM1: CAIN I,")" ;EOE? JRST DOSYM4 ;YES WARN W.ILO1 ;ONLY GENERATE 1 BYTE OF DATA DOSYM5: PUSHJ P,INCH CAIE I,")" CAIN I,CR ;DEFENSIVE CODE CAIA JRST DOSYM5 DOSYM4: MOVE T1,T2 POP P,T4 POP P,T3 POP P,T2 POPJ P, DOSYM3: POP P,T4 POP P,T3 POP P,T2 SKIPE (S) ;NO SYMBOL? JRST FLUNDF ;SYMBOL ALREADY UNDEFINED MOVEM TOK,(S) ;SAVE SYMBOL MOVSI T1,S.UNDF ;FLAG UNDEFINED MOVEM T1,1(S) PUSHJ P,SRCSYM ;REFERENCE SYMBOL JFCL ;NOT FOUND? FLUNDF: TRO F,FR.UND ;FLAG UNDEFINED SYMBOL TRNN F,FR.PS1 ;SKIP IF PASS1 ERROR F.UNDF ;REALLY IS UNDEFINED POPJ P, ;BURP UP DOQUOT: TRO F,FR.LOW ;ENABLE LOWER CASE PUSHJ P,INCH ;GET THE NEXT CHARACTER MOVE T1,I ;JUST SAVE IT PUSHJ P,INCH ;EAT TRAILING QUOTE CAIE I,"'" CAIN I,QUOTE JRST .+4 ;OK THEN LSH T1,10 ;SHIFT OVER ADD T1,I ;MERGE JRST .-6 TRZ F,FR.LOW ;DISABLE LOWER CASE PUSH P,T1 ;SAVE T1 PUSHJ P,TOKEN ;LOAD UP LIKE TOKEN POP P,T1 ;RESTORE T1 POPJ P, ;RETURN ;SEARCH SYMBOL TABLE FOR ENTRY IN TOK. ;NON-SKIP RETURN: SYMBOL UNDEFINED. S CONTAINS 1ST FREE ENTRY ;SKIP RETURN: T1 CONTAINS VALUE OF SYMBOL. S POINTS TO ENTRY IN SYMTAB ;SYMTAB ENTRY: SIXBIT/NAME/ ; FLAGS,,VALUE ;SEE M80UNV FOR FLAGS (S.????) ; LINE#,,LINK TO NEXT LINE# ;1B0 SET IF DEFINED ON LINE# ; 0,,LINK TO OVERFLOW ; 0 IF NO MORE ENTRIES SRCSYM: TRZ F,FR.REL!FR.EXT MOVSI S,-PRELEN ;GET LENGTH OF PRE DEFINED TABLE HRRI S,PRETAB ;ADDRESS OF PERMANENT SYMBOLS CAMN TOK,(S) ;MATCH? JRST PREMAT AOBJN S,.+1 AOBJN S,.-3 ;NO, LOOP ;LOOK IN REGULAR SYMBOL TABLE PUSH P,T2 ;DON'T DESTROY T2 MOVE T2,[POINT 6,TOK];THIS ASSUMES SYMSIZ IS FAIRLY CLOSE TO 64 SETZ T1, TLNN T2,770000 JRST .+4 ILDB S,T2 ADD T1,S JRST .-4 IDIVI T1,SYMSIZ ;GET TOKEN MODULO TABLE LENGTH MOVE T1,T2 POP P,T2 IMULI T1,4 ;4 WORDS/ENTRY MOVEI S,SYMTAB(T1) ;GET HASHED TABLE LOCATION SRCL: CAMN TOK,(S) JRST SRCF SKIPN (S) ;EMPTY? POPJ P, ;YES, RETURN WITH S SET UP SKIPN 3(S) ;LINK THERE? JRST MAKLNK ;NO. MAKE NEW ENTRY & RETURN HRRZ S,3(S) ;NEW LINK JRST SRCL ;LOOP PREMAT: MOVE T1,1(S) ;GET FLAGS,VALUE JRST SCPOPJ ;SKIP RETURN MAKLNK: MOVE T1,.JBFF## ;GET JOBFF HRRM T1,3(S) ;MAKE NEW LINK HRRM T1,S ADDI T1,4 ;MAKE NEW JOBFF PUSHJ P,MEMXPN ;EXPAND CORE IF NECESSARY MOVEM T1,.JBFF## ;STUFF IT POPJ P, ;DONE SRCF: MOVE T1,1(S) ;GET FLAGS,VALUE PUSH P,T2 ;SAVE T2 MOVE T2,T1 ;IN T2 TLNE T2,S.EXT ;EXTERNAL? HRR T2,PC ;YES, SAVE CURRENT PC FOR NEXT SYMBOL TRZN F,FR.NRF ;A REFERENCEABLE SYMBOL? TLO T2,S.REF ;YES, REFERENCE SYMBOL MOVEM T2,1(S) ;SAVE FLAGS,VALUE TRNE F,FR.PS1 ;PASS1? JRST SRCX ;YES, NO REF ON PASS1 TRNN F,FR.LST ;LISTING REFERENCES? JRST SRCX ;NO USE GATHERING THEM THEN SKIPE 2(S) ;NO REFERENCE? JRST NXTREF ;NO HRLZ T2,LINENO ;GET CURRENT LINENO MOVEM T2,2(S) ;SAVE IN LH JRST SRCX ;DONE NXTREF: PUSH P,T1 ;SAVE T1 PUSH P,T3 ;AND T3 MOVEI T1,2(S) ;GET ADDRESS MOVE T2,2(S) ;GET LINE,,LINK SRCLNK: HLRZ T3,T2 ;GET LINE NUMBER IN CHAIN ANDI T3,377777 ;JUST LINE NUMBER CAMN T3,LINENO ;IS LINENO ALREADY IN CHAIN? JRST SRCX0 ;YES, QUIT NOW TRNN T2,-1 ;ANY LINK? JRST SRCI ;NO, END OF CHAIN HRRZ T1,T2 ;SAVE LINK MOVE T2,(T1) ;FOLLOW LINK JRST SRCLNK ;LOOP TO END OF CHAIN SRCI: HRR T2,.JBFF## ;GET FIRST FREE AS LINK MOVEM T2,(T1) ;SAVE WITH NEW LINK HRRZ T1,T2 ;LINK ADDRESS IN T1 MOVE T2,LINENO ;GET LINE NUMBER HRLZM T2,(T1) ;STORE IT AOJ T1, ;NEW JOBFF PUSHJ P,MEMXPN ;EXPAND CORE MOVEM T1,.JBFF## SRCX0: POP P,T3 ;RESTORE T3 POP P,T1 ;RESTORE T1 SRCX: POP P,T2 TLNE T1,S.UNDF ;UNDEFINED SYMBOL? POPJ P, ;YES, TIME TO LEAVE TLZE T1,S.REL ;RELOCATABLE? TRO F,FR.REL ;YES, FLAG IT TLZE T1,S.EXT ;EXTERNAL? TRO F,FR.EXT ;YES SCPOPJ: AOS (P) ;CAUSE SKIP RETURN CPOPJ: POPJ P, ;RETURN ;SNEAK ROUTINE. WHILE FR.SNK IS ON INCH WILL COPY ALL INPUT VIA BAKPTR ;WHEN DONE, SNEAK WILL TELL INCH THAT THE PREVIOUS INPUT IS NOW A MACRO ;IN EFFECT, NO INPUT WAS DONE (EXCEPT THAT TOK CONTAINS THE NEXT TOKEN) SNEAK: TRO F,FR.SNK ;SAY WE'RE SNEAKING AROUND PUSH P,I PUSH P,T1 PUSH P,T2 MOVE T2,[POINT 7,BAKBUF] ;SET UP POINTER FOR INCH MOVEM T2,BAKPTR ;SAVE IT PUSHJ P,TOKEN ;GET TOKEN MOVEI T1,177 IDPB T1,BAKPTR ;STORE "END OF MACRO" MOVEI T1,1 IDPB T1,BAKPTR MOVE T1,MACPDL ;GET MACPDL HRRZ T2,INVECT ;GET INVECT POINTER CAIL T2,ENDHGH ;POINTS TO BAKBUF?? (IF SO, DON'T SAVE) PUSH T1,INVECT ;SAVE OLD POINTER MOVE T2,[POINT 7,BAKBUF] ;POINT TO BACKUP BUFFER MOVEM T2,INVECT ;SOURCE IS NOW IN BAKBUF MOVEM T1,MACPDL ;PUT PDL BACK IN STORAGE TRZ F,FR.SNK ;DONE SNEAKING POP P,T2 POP P,T1 POP P,I POPJ P, ;DONE GETNUM: MOVE T3,[POINT 6,TOK] SETZ T1, ;CLEAR TOTAL ILDB T2,T3 ;GET THE 1ST CHARACTER CAIG T2,'9' CAIGE T2,'0' ;NUMERIC? JRST SCPOPJ ;NO - SHOULDN'T BE HERE JRST GETNL1 ;YES, JUMP INTO ROUTINE GETNL: TLNN T3,770000 POPJ P, ILDB T2,T3 ;GET A CHARACTER GETNL1: JUMPE T2,CPOPJ ;DONE. NORMAL RETURN CAIE T2,'Q' CAIN T2,'O' ;REALLY OCTAL? JRST DECOCT CAIN T2,'H' ;HEX? JRST DOHEX ;YES CAIN T2,'D' ;EXPLICIT DECIMAL? JRST GETNL ;YES, IGNORE IT IMULI T1,12 ;ASSUME DECIMAL ADDI T1,-20(T2) JRST GETNL DECOCT: IDIVI T1,12 ;BREAK DECIMAL TO BINARY JUMPE T1,DECOCX PUSH P,T2 PUSHJ P,DECOCT POP P,T2 DECOCX: IMULI T1,10 ;BINARY TO OCTAL ADD T1,T2 POPJ P, ;RETURN DOHEX: MOVE T3,[POINT 6,TOK] SETZ T1, DOHEX1: ILDB T2,T3 CAIN T2,'H' POPJ P, IMULI T1,20 ADDI T1,-20(T2) CAIL T2,'A' SUBI T1,7 JRST DOHEX1 SETMAC: MOVE T1,[POINT 7,MACARG] TRO F,FR.LOW ;ALLOW LC IN MACRO ARG, HAS TO GO THRU INCHX AGAIN CAIE I,TAB CAIN I,SPACE JRST [PUSHJ P,INCH JRST SETMAC+2] CAIA SETM0: PUSHJ P,INCH PUSHJ P,BREAK JRST SETM1 IDPB I,T1 JRST SETM0 SETM1: CAIE I,QUOTE CAIN I,"'" JRST SETM3 ;DO QUOTED STRING CAIN I,"<" ;START EXPR? JRST SETM4 ;YES STM1.5: PUSH P,I MOVEI I,177 IDPB I,T1 MOVEI I,1 IDPB I,T1 POP P,I CAIE I,CR CAIN I,SEMICO JRST SETM2 JRST SETM0 SETM2: PUSHJ P,FLUSH MOVE T1,MACPDL PUSH T1,INVECT ;SAVE INPUT VECTOR ON SPECIAL STACK MOVE T2,1(S) ;GET POINTER TO MACRO HRLI T2,(POINT 7,0) MOVEM T2,INVECT MOVEM T1,MACPDL POPJ P, SETM3: MOVEM I,DELIM IDPB I,T1 PUSHJ P,INCH CAIE I,CR CAIN I,LF JRST SETM1 CAME I,DELIM JRST SETM3 IDPB I,T1 JRST STM1.5 SETM4: PUSHJ P,INCH TRNE F,FR.END ;END IS ONLY ABNORMAL EXIT JRST STM1.5 CAIE I,">" JRST .+3 PUSHJ P,INCH JRST STM1.5 IDPB I,T1 JRST SETM4 INCH: PUSH P,T1 ;SAVE T1 INCH1: MOVE T1,INVECT ;GET VECTOR CAIN T1,-1 ;DEFAULT TO SOURCE? JRST INCHS ;YES INCHM0: ILDB I,INVECT ;GET CHARACTER FROM MACRO BODY JUMPE I,INCHM1 ;IMPROBABLE, BUT TRY TO LOOK NICE CAIN I,177 JRST INCHM3 POP P,T1 TLNN F,FL.SUP ;IS FL.SUP ON? JRST INCHX ;NO IDPB I,BAKPTR ;YES, SAVE CHAR HERE POPJ P, ;SUPPRESS ALL THIS FOOLISHNESS INCHM3: ILDB I,INVECT ;GET CODE CAIN I,1 ;END OF MACRO JRST INCHM1 ;YES MOVE T1,MACPDL PUSH T1,INVECT ;SAVE OLD INVECT MOVEM T1,MACPDL MOVE T1,[POINT 7,MACARG] MOVEM T1,INVECT MOVE T1,I ;PUT ARG POSITION IN T1 ANDI T1,77 INCHM2: JUMPE T1,INCHM0 ;INVECT NOW POINTS TO RIGHT SPOT ILDB I,INVECT JUMPE I,INCHM1 ;NOT ENOUGH ARGS SUPPLIED. LEAVE NULL. CAIE I,177 ;END OF ARG? JRST INCHM2+1 ;NO, LOOP ILDB I,INVECT ;GET ^A SOJA T1,INCHM2 ;SEE IF WE'RE AT THE RIGHT SPOT INCHM1: MOVE T1,MACPDL POP T1,INVECT ;RESTORE OLD POINTER MOVEM T1,MACPDL JRST INCH1 INCHS: POP P,T1 INCHS1: SOSGE IBUF+2 JRST .+3 ILDB I,IBUF+1 JRST INCHX IN SRC, JRST INCHS1 ENDIT: TRZN F,FR.PS1 ;PASS1? JRST WRAPUP ;NO TRZ F,FR.END ;TURN OFF END FROM PASS1 (SHOULD ALREADY BE OFF BUT ...) SETZ E, ;FORGET ALL PASS1 ERRORS TRZE F,FR.OFF ;ARE WE ASSEMBLING? WARN W.IF2 ;NO SETZM IFLEVL SETZM OFFLVL MOVEM BC,ORGBLK(OX) ;STORE COUNT SETZ T1, ;YES PUSHJ P,OPNOBJ ;OPEN OBJECT DEVICE SETZ OX, ;RESET FOR OUTPUT MOVE T2,[POINT 7,TITL] PUSHJ P,NOALT3 MOVE T2,[POINT 7,SUBTTL] PUSHJ P,NOALT3 NOALT1: PUSHJ P,HEXHED ;DO HEDDER MOVE T1,FILNAM## MOVE T2,FILEXT## SETZ T3, MOVE T4,PPN## LOOKUP SRC,T1 JRST NOFILE## JRST RESTAR NOALT3: ILDB T1,T2 JUMPE T1,.+3 PUSHJ P,HEXOX JRST .-3 BCRLF: MOVEI T1,15 PUSHJ P,HEXOX MOVEI T1,12 JRST HEXOX HEXHED: PUSHJ P,BCRLF IFN FTREL,< MOVE T1,RELPTR ;GET SIZE OF RELTAB CAIGE T1,^D15 ;ENOUGH TO DO A LINE? JRST HEXH2 ;NO MOVEI T2,^D15 ;YES, DO 15 PUSHJ P,TYPE04 ;DO RELOCATABLE TYPE HEXH2:> ;END IFN FTREL MOVE T1,ORGBLK(OX) ;GET BYTE COUNT LEFT IN BLOCK SUBI T1,^D30 ;SUBTRACT WHAT WE'RE GOING TO USE JUMPLE T1,.+4 ;<= 30 MOVEM T1,ORGBLK(OX) ;SAVE REST MOVEI T1,^D30 ;30 BYTES JRST .+3 MOVE T1,ORGBLK(OX) ;GET WHAT'S LEFT SETZM ORGBLK(OX) ;FLAG BLOCK EMPTY MOVEM T1,CHECK MOVE BC,T1 ;SAVE BYTES TO OUTPUT JUMPE BC,EOFBYT ;JUMP IF TIME TO DO EOF STUFF MOVEI T1,":" ;DO TYPE00 HEADER PUSHJ P,HEXOX MOVE T1,BC ;GET BYTE COUNT PUSHJ P,HEXBYT ;OUTPUT BYTE COUNT MOVE T1,ORGBLK+1(OX) ;GET START ADDRESS OF BLOCK LSH T1,-10 ;GET HIGH BYTE ADDM T1,CHECK PUSHJ P,HEXBYT ;OUTPUT HIGH ADDRESS MOVE T1,ORGBLK+1(OX) ADDM T1,CHECK PUSHJ P,HEXBYT ;OUTPUT LOW BYTE MOVE T1,ORGBLK+1(OX) ADD T1,BC ;LAST S.A. + BYTE COUNT MOVEM T1,ORGBLK+1(OX) ;= NEW S.A. SETZ T1, ;DATA (TYPE 00) SKIPN BC ;IF DATA, SKIP MOVEI T1,1 ;IF EOF, (TYPE 01) JRST HEXBYT ;OUTPUT RECORD TYPE IFN FTREL,< TYPE04: TRNE F,FR.ORG ;RELOCATING? POPJ P, ;NO MOVEI T1,"$" ;FLAG NON-INTEL RECORD PUSHJ P,HEXOX MOVE T1,T2 ;GET WORD COUNT IMULI T1,2 ;MAKE BYTE COUNT MOVEM T1,CHECK ;CHECKSUM PUSHJ P,HEXBYT ;OUTPUT SETZ T1, ;NO START ADDRESS PUSHJ P,HEXBYT PUSHJ P,HEXBYT MOVEI T1,4 ;TYPE 04 (RELOCATABLE) ADDM T1,CHECK PUSHJ P,HEXBYT SETZ T3, ;ZERO XR T04.1: MOVE T1,RELTAB(T3) ;GET ADDRESS LSH T1,-10 ADDM T1,CHECK PUSHJ P,HEXBYT MOVE T1,RELTAB(T3) ;GET LO ADDRESS ANDI T1,377 ADDM T1,CHECK PUSHJ P,HEXBYT AOJ T3, SOJG T2,T04.1 ;LOOP MOVE T1,CHECK ANDI T1,377 MOVNS T1 PUSHJ P,HEXBYT ;OUTPUT CHECKSUM PUSHJ P,BCRLF ;CRLF ;SHUFFLE CONTENTS OF RELTAB BACK TO BOTTOM SETZ T2, SKIPN T1,RELTAB(T3) JRST T04.2 MOVEM T1,RELTAB(T2) AOJ T2, AOJA T3,.-4 T04.2: MOVEM T2,RELPTR ;RESET POINTER MOVSI T3,RELTAB(T2) HRRI T3,RELTAB+1(T2) SETZM RELTAB(T2) BLT T3,RELEND POPJ P, > ;END IFN FTREL EOFBYT: IFN FTREL,< TRNN F,FR.ORG ;RELOCATING? SKIPN RELPTR ;RELTAB EMPTY? JRST DOSYMT ;DO SYMBOL TYPE MOVE T2,RELPTR ;GET COUNT CAIL T2,^D15 MOVEI T2,^D15 ;MAX 15 AT A TIME PUSHJ P,TYPE04 ;DO A LINE OF TYPE 04 JRST EOFBYT ;LOOP DOSYMT: MOVEI S,SYMTAB ;XR EOFL: CAIL S,SYMEND ;END ON SYMTAB? JRST TYPE01 ;YES SKIPN (S) ;EMPTY? JRST EOFX ;YES, SKIP PUSH P,S ;SAVE POINTER MOVE T3,1(S) TLNE T3,S.INT!S.EXT ;GOOD STUFF? PUSHJ P,TYPE02 ;YES SKIPE S,3(S) JRST .-4 POP P,S EOFX: ADDI S,4 JRST EOFL ;LOOP TYPE02: MOVEI T1,"$" ;TYPE 2 OR 3 LEADER PUSHJ P,HEXOX SETZM CHECK MOVE T2,(S) ;GET NAME MOVE T4,[POINT 6,T2] T02.1: ILDB T1,T4 ;GET BYTE ADDI T1,40 ;TO ASCII ADDM T1,CHECK PUSHJ P,HEXOX TLNE T4,770000 ;ALL 6? JRST T02.1 ;NO TLNE T3,S.INT ;INTERNAL MOVEI T1,2 ;IS TYPE 02 TLNE T3,S.EXT ;EXTERNAL MOVEI T1,3 ;IS TYPE 03 PUSHJ P,HEXBYT ;OUTPUT SYMBOL TYPE ADDM T1,CHECK HRRZ T1,T3 ;GET VALUE LSH T1,-10 ;GET HIGH PART ADDM T1,CHECK PUSHJ P,HEXBYT HRRZ T1,T3 ANDI T1,377 ADDM T1,CHECK PUSHJ P,HEXBYT MOVE T1,CHECK ANDI T1,377 MOVNS T1 PUSHJ P,HEXBYT PUSHJ P,BCRLF POPJ P, > ;END IFN FTREL TYPE01: MOVEI T1,":" ;OUTPUT HEADER PUSHJ P,HEXOX SETZ T1, ;LENGTH 0 PUSHJ P,HEXBYT MOVE T1,STARTA ;GET START ADDRESS LSH T1,-10 PUSHJ P,HEXBYT MOVE T1,STARTA ANDI T1,377 PUSHJ P,HEXBYT MOVEI T1,1 ;TYPE 01 PUSHJ P,HEXBYT JRST BCRLF ;CRLF INCHX: JUMPE I,INCH ;CAST OFF NULLS TRNE F,FR.SNK ;IF SNEAKING, IDPB I,BAKPTR ;SAVE CHARACTER TRNE F,FR.LOW ;enable lower case? JRST INCHX2 CAIL I,"A"+40 CAILE I,"Z"+40 JRST INCHX2 SUBI I,40 ;force upper case INCHX2: TRNE F,FR.SNK ;IF SNEAKING, POPJ P, ;DON'T PRINT TWICE TRNE F,FR.PS1 JRST PAS1IX ;SKIP ALL PROCESSING OF CHARACTER IF PASS1 JUMPN LBTP,.+2 MOVE LBTP,[POINT 7,LINBLK] CAIE I,FF ;DON'T GO PUTTING FF IN LINBLK! IDPB I,LBTP CAIE I,LF ;IF LF, CAIN I,FF ;OR FF, CAIA ;SKIP INTO EOL ROUTINE POPJ P, ;ELSE WE'RE DONE PUSH P,T1 PUSH P,T2 CAIN I,FF JRST DOFFX ;IF FF, SKIP SOME STUFF MOVEI T1,TAB TRNE F,FR.LOP ;IF CODE GENERATED JRST INCHX1 ;JUST ONE TAB PUSHJ P,DOLINO ;PRINT LINE # AS A LAST RESORT TRNE F,FR.HEX JRST INCHX0 PUSHJ P,LOUCH PUSHJ P,LOUCH INCHX0: PUSHJ P,LOUCH INCHX1: PUSHJ P,LOUCH TRZ F,FR.LIN ;CLEAR LINE # PRINTED FLAG FOR NEXT LINE MOVE LBTP,[POINT 7,LINBLK] ILDB T1,LBTP JUMPE T1,CHKERR PUSHJ P,LOUCH SKIPE E OUTCHR T1 JRST .-5 CHKERR: JUMPE E,NOERR HLRZ T1,E OUTCHR T1 PUSHJ P,LOUCH MOVE T2,ERRTAB-1(E) MOVE LBTP,[POINT 7,(T2)] ILDB T1,LBTP JUMPE T1,.+4 PUSHJ P,LOUCH OUTCHR T1 JRST .-4 PUSHJ P,LCRLF OUTSTR CRLF SETZ E, NOERR: SETZM LINBLK MOVE T1,[LINBLK,,LINBLK+1] BLT T1,LINEND SETZ LBTP, MOVE T1,LINCTR CAIG T1,LPP ;ON NEW PAGE? JRST NOFF ;NO JRST DOFF ;YES, WRITE HEADER DOFFX: AOS PAGENO SETZM SUBPAG ;REAL PAGES HAVE NO SUB PAGE MARK DOFF: PUSHJ P,DOHDFF ;GO DO THE HEADING NOFF: POP P,T2 POP P,T1 PAS1IX: CAIN I,FF ;IF FF, JRST INCH ;EAT IT POPJ P, ;OR ELSE RETURN LOUCH: TRNE F,FR.LST ;IF NOT LISTING TRNE F,FR.PS1 ;OR ON PASS 1 POPJ P, ;FORGET IT SOSGE LBUF+2 JRST LOUCH1 IDPB T1,LBUF+1 CAIN T1,LF AOS LINCTR CAIN T1,LF ;LF DOESN'T CHANGE BOL POPJ P, TRZ F,FR.BOL ;ASSUME REGULAR CHAR CAIN T1,CR ;IF CR TRO F,FR.BOL ;FLAG BOL POPJ P, LOUCH1: OUTPUT LST, JRST LOUCH OUTOP: PUSHJ P,LSTPC MOVE T1,OP PUSHJ P,LSTOP POPJ P, ;RETURN NOPC: MOVEI T1,TAB PUSHJ P,LOUCH TRNN F,FR.HEX PUSHJ P,LOUCH MOVE T1,OP SKIPGE T1 ;IF NEGATIVE SETZ T1, ;MAKE ZERO MOVEI T3,6 TRO F,FR.LOP PUSHJ P,LSTNUM TRNE F,FR.HEX POPJ P, MOVEI T1,TAB JRST LOUCH HEXOX: SOSGE OBUF+2 JRST .+3 IDPB T1,OBUF+1 POPJ P, OUTPUT OBJ, JRST HEXOX HEXOUT: ADDM T1,CHECK PUSHJ P,HEXBYT SOJG BC,CPOPJ PUSH P,T1 PUSH P,T2 PUSH P,T3 PUSH P,T4 MOVE T1,CHECK ANDI T1,377 MOVNS T1 PUSHJ P,HEXBYT SKIPN ORGBLK(OX) ;STILL GOOD BYTE COUNT? ADDI OX,2 ;NEXT BLOCK PUSHJ P,HEXHED ;DO HEADER POP P,T4 POP P,T3 POP P,T2 POP P,T1 POPJ P, HEXBYT: PUSH P,T1 LSH T1,-4 PUSHJ P,NYBBLE ;OUTPUT HIGH NYBBLE POP P,T1 PUSH P,T1 PUSHJ P,NYBBLE POP P,T1 POPJ P, NYBBLE: ANDI T1,17 CAILE T1,^D9 JRST .+3 ADDI T1,60 JRST HEXOX ADDI T1,"A"-^D10 JRST HEXOX WRAPUP: IFN FTCREF,< PUSHJ P,PRTSYM ;PRINT SYMBOL TABLE > RELEAS LST, RELEAS OBJ, IFN FTSTAT,< TLNE F,FL.LNR ;LIST NON-REF SYMBOLS? PUSHJ P,REFLOP ;YES > AND F,[XWD FL.CCL,0];CLEAR ALL FLAGS BUT FL.CCL JRST START## IFN FTSTAT,< ;PRINT ALL DEFINED BUT NOT REFERENCED SYMBOLS REFLOP: MOVEI S,SYMTAB RLOOP4: CAIN S,SYMEND ;END OF TABLE? POPJ P, ;DONE SKIPN (S) ;IF EMPTY JRST RLOOP5 ;GET NEXT PUSH P,S ;SAVE IT PUSHJ P,RLINK ;RUN OUT THIS BRANCH POP P,S ;DONE RLOOP5: ADDI S,4 ;GET NEXT JRST RLOOP4 ;LOOP RLINK: MOVE T2,1(S) TLNN T2,S.REF ;IS SYMBOL REFERENCED JRST RLOOP0 ;NO RLOOP: SKIPN S,3(S) ;IS THERE A LINK? POPJ P, ;NO JRST RLINK RLOOP0: TRON F,FL.HED OUTSTR [ASCIZ/Unreferenced labels: /] MOVE T3,(S) MOVE T4,[POINT 6,T3] RLOOP1: ILDB T2,T4 JUMPE T2,RLOOP2 ADDI T2,40 OUTCHR T2 TLNE T4,770000 JRST RLOOP1 RLOOP2: OUTSTR [ASCIZ/ /] JRST RLOOP > ;END IFN FTSTAT IFN FTCREF,< PRTSYM: TRNN F,FR.LST ;LISTING? POPJ P, ;DON'T BE SILLY THEN SETZB BC,E ;CLEAR COUNTER SETOM PAGENO ;FLAG SYMBOL TABLE PAGE MOVEI T1,1 ;SYMBOL TABLE ALWAYS STARTS WITH SUBPAGE MOVEM T1,SUBPAG ;NUMBER 1 PUSHJ P,DOHDFF ;PRINT NEW HEADER PRTS: SETZB T1,T2 SETZ P1, MOVEI S,SYMTAB PRT0: SKIPN (S) ;EMPTY? AOJA P1,PRT1 ;YES PUSH P,S ;SAVE S PUSHJ P,PRT10 ;CHECK OUT THIS BRANCH POP P,S PRT1: ADDI S,4 ;NEXT LINK CAIE S,SYMEND ;ALL DONE? JRST PRT0 ;NO, LOOP JUMPE T1,PRTX ;DONE AOJ BC, ;COUNT IT MOVE S,T2 MOVE T2,(S) ;GET SMALLEST SYMBOL PUSHJ P,PUTSIX MOVEI T1,TAB PUSHJ P,LOUCH MOVE T1,1(S) ;GET FLAGS,VALUE TLNN T1,S.UNDF ;UNDEFINED? JRST .+4 MOVEI T2,[ASCIZ/Undf/] PUSHJ P,PUTSTR JRST PRT4 TLNN T1,S.MAC JRST .+3 MOVEI T2,[ASCIZ/Macro/] JRST .-5 HRRZS T1 ;JUST VALUE MOVEI T3,6 PUSHJ P,LSTNUM ;PRINT IT IFN FTREL,< SETZ T1, MOVE T2,1(S) ;GET FLAGS TLNE T2,S.REL MOVEI T1,"'" ;FLAG RELOC TLNE T2,S.EXT!S.INT MOVEI T1,"*" SKIPE T1 PUSHJ P,LOUCH > ;END IFN FTREL PRT4: MOVE T2,2(S) ;GET LINE,,LINK PRT3: MOVEI T4,^D13 ;MAX ENTRIES/LINE PRT2: PUSH P,T2 MOVEI T1,TAB PUSHJ P,LOUCH HLRZS T2 TRZ T2,(1B0) ;CLEAR FLAG MOVEI T1,SPACE CAIG T2,^D999 PUSHJ P,LOUCH CAIG T2,^D99 PUSHJ P,LOUCH CAIG T2,^D9 PUSHJ P,LOUCH MOVE T1,T2 PUSHJ P,PUTDEC POP P,T2 TLNN T2,(1B0) ;FLAG? JRST .+3 ;NO MOVEI T1,"#" PUSHJ P,LOUCH HRRZS T2 ;GET LINK JUMPE T2,PRT9 ;DONE WITH CHAIN MOVE T2,(T2) ;GET LINE,,LINK SOJG T4,PRT2 ;LOOP FOR LINE PUSHJ P,LCRLF ;END THE LINE MOVE T1,LINCTR CAILE T1,LPP ;IF ON NEW PAGE, PUSHJ P,DOHDFF ;DO HEADER MOVEI T1,TAB PUSHJ P,LOUCH JRST PRT3 PRT9: PUSHJ P,LCRLF MOVE T1,LINCTR CAILE T1,LPP ;IF ON NEW PAGE, PUSHJ P,DOHDFF ;DO HEADER MOVE T3,1(S) ;GET FLAGS TLO T3,S.PRT ;FLAG SYMBOL PRINTED MOVEM T3,1(S) JRST PRTS PRTX: IFN FTSTAT,< PUSHJ P,LCRLF ;NEW LINE MOVE T1,BC ;GET COUNT OF SYMBOLS USED PUSHJ P,PUTDEC MOVEI T2,[ASCIZ/ symbols used /] PUSHJ P,PUTSTR MOVE T1,P1 PUSHJ P,PUTDEC MOVEI T2,[ASCIZ/ empty slots in SYMTAB /] PUSHJ P,PUTSTR CAIG E,1 POPJ P, MOVE T1,E PUSHJ P,PUTDEC MOVEI T2,[ASCIZ/ links in longest symbol search/] PUSHJ P,PUTSTR > ;END IFN FTSTAT JRST LCRLF ;CRLF PRT10: SETZ OX, ;COUNT OF LINKS IN THIS BRANCH MOVE T3,1(S) ;GET FLAGS TLNE T3,S.PRT ;WAS ALREADY USED? JRST PRT11 ;YES CAMG T1,(S) ;GET SYMBOL JRST PRT11 MOVE T2,S ;SAVE INDEX OF LEAST ALPHABETICAL SYMBOL MOVE T1,(S) ;NEW MATCH SYMBOL PRT11: AOJ OX, SKIPE S,3(S) ;GET NEXT LINK JRST PRT10+1 ;GO ON CAMLE OX,E ;GT MAX? MOVE E,OX ;NEW MAX POPJ P, ;NO LINK > ;END IFN FTCREF LSTNUM: TRNE F,FR.HEX ;HEX OUTPUT? JRST LSTHEX ;YES IDIVI T1,10 ;NO SOJLE T3,.+4 PUSH P,T2 PUSHJ P,LSTNUM POP P,T2 MOVEI T1,60(T2) LSTN1: PUSHJ P,LOUCH POPJ P, LSTHEX: IMULI T3,2 ;MULT BY 2/3 PUSH P,T4 IDIVI T3,3 POP P,T4 LSTH1: IDIVI T1,20 SOJLE T3,LSTH2 PUSH P,T2 PUSHJ P,LSTH1 POP P,T2 LSTH2: CAILE T2,11 JRST LSTH3 MOVEI T1,60(T2) JRST LSTN1 LSTH3: MOVEI T1,"A"-^D10(T2) JRST LSTN1 ;LSTPC LIST THE PC AND A TAB LSTPC: TRNE F,FR.PS1 ;PASS1? POPJ P, ;YES PUSHJ P,DOLINO ;IN CASE AT DC? TRZ F,FR.LIN ;LISTING PC CLEARS FR.LIN MOVEI T3,6 MOVE T1,PC PUSHJ P,LSTNUM TRNE F,FR.HEX ;HEX? JRST LSTPC1 ;YES MOVEI T1,"=" PUSHJ P,LOUCH MOVEI T3,3 ;3 FIGURES MOVE T1,PC ;GET PC LSH T1,-10 PUSHJ P,LSTNUM ;OUTPUT THE PC MOVEI T1,"/" PUSHJ P,LOUCH MOVE T1,PC ANDI T1,377 MOVEI T3,3 PUSHJ P,LSTNUM LSTPC1: IFN FTREL,< TRNE F,FR.ORG ;RELOCATING? JRST LSTPC2 ;NO MOVEI T1,"'" PUSHJ P,LOUCH > ;END IFN FTREL LSTPC2: MOVEI T1,TAB PUSHJ P,LOUCH ;OUTPUT ANOTHER TAB POPJ P, LCRLF: TRNE F,FR.PS1 POPJ P, MOVEI T1,CR PUSHJ P,LOUCH MOVEI T1,LF JRST LOUCH ;LSTOP ENTER THE BYTE IN T1 IN THE OBJ FILE ; PRINT THE BYTE [AND A SPACE IF OCT] LSTOP: TRNE F,FR.PS1 JRST LSTOP1 TRO F,FR.LOP MOVEI T3,3 PUSH P,T2 ANDI T1,377 PUSHJ P,HEXOUT PUSHJ P,LSTNUM ;OUTPUT BYTE MOVEI T1,SPACE TRNN F,FR.HEX PUSHJ P,LOUCH POP P,T2 LSTOP1: AOS PC TRNE F,FR.PS1 AOJ BC, POPJ P, DOTAG: TRO F,FR.NRF ;DEFINITION IS NOT REFERENCE PUSHJ P,EVAL PUSHJ P,SYMDEF ;FLAG DEFINITION HRRZS T1 ;CLEAR FLAGS CAME T1,PC ERROR F.MULT JRST DUNTAG SYMDEF: TRNE F,FR.PS1 ;PASS1? POPJ P, ;YES TRNN F,FR.LST ;LISTING? POPJ P, ;NO CAIGE S,SYMTAB ;POINTS TO SYMTAB? POPJ P, ;NO. PROB POINTS TO PRETAB PUSH P,T1 PUSH P,T2 MOVE T1,2(S) ;GET LINE,,LINK MOVEI T2,2(S) ;GET 1ST POINTER DEFS0: TRNN T1,-1 ;END OF CHAIN? JRST DEFS1 ;YES MOVE T2,T1 MOVE T1,(T2) ;LINK JRST DEFS0 ;LOOP DEFS1: TLO T1,(1B0) ;FLAG DEFINITION MOVEM T1,(T2) ;PUT BACK POP P,T2 POP P,T1 POPJ P, DOHDFF: MOVEI T1,FF PUSHJ P,LOUCH ;FORCE NEW PAGE DOHEAD: PUSH P,T1 ;SAVE ACS PUSH P,T2 PUSH P,T3 MOVEI T1,1 MOVEM T1,LINCTR ;SET LINE COUNT TO 1 MOVE T2,[POINT 7,TITL] MOVEI T3,^D66 ILDB T1,T2 JUMPE T1,.+3 PUSHJ P,LOUCH SOJG T3,.-3 MOVEI T1,11 ;LOAD A SKIPE TITL ;NOT IF NO TITLE PUSHJ P,LOUCH ;OUTPUT IT MOVEI T2,HEAD0 PUSHJ P,PUTSTR MOVEI T2,M80MAJ PUSHJ P,PUTOCT MOVEI T1,M80MIN JUMPE T1,.+3 MOVEI T1,"@"(T1) PUSHJ P,LOUCH MOVEI T1,"(" PUSHJ P,LOUCH MOVEI T2,M80EDT PUSHJ P,PUTOCT MOVEI T2,[ASCIZ/) /] PUSHJ P,PUTSTR SKIPL PAGENO MOVEI T2,HEAD1 SKIPG PAGENO MOVEI T2,HEAD3 PUSHJ P,PUTSTR MOVEI T2,DATE ;SO WHAT IF WE STARTED AT 11:59 DEC 31 PUSHJ P,PUTSTR ;WE STILL USE THE DATE OF THE START OF THE RUN MOVEI T2,HEAD2 PUSHJ P,PUTSTR SKIPL T1,PAGENO PUSHJ P,PUTDEC SKIPL PAGENO JRST .+3 MOVEI T1,"S" ;INDICATE SYMBOL TABLE PAGE PUSHJ P,LOUCH SKIPN SUBPAG JRST NOSUB MOVEI T1,"-" PUSHJ P,LOUCH MOVE T1,SUBPAG PUSHJ P,PUTDEC NOSUB: AOS SUBPAG ;BUMP SUBPAGE COUNTER HERE PUSHJ P,LCRLF MOVE T2,[POINT 6,FILNAM] ;LOAD THE SOURCE FILE NAME DOH1: ILDB T1,T2 JUMPE T1,.+5 ADDI T1,40 PUSHJ P,LOUCH TLNE T2,770K JRST DOH1 MOVEI T1,"." ;LOAD A "." PUSHJ P,LOUCH ;AND OUTPUT IT HLLZ T2,FILEXT ;LOAD THE SOURCE FILE EXT. PUSHJ P,PUTSIX ;PRINT IT PUSHJ P,LCRLF PUSHJ P,LCRLF POP P,T3 POP P,T2 POP P,T1 POPJ P, PUTSTR: HRLI T2,(POINT 7,0) ;MAKE A BTP ILDB T1,T2 ;LOAD THE BYTE JUMPE T1,.+3 ;IF LAST BYTE, RETURN PUSHJ P,LOUCH ;OUTPUT IT JRST .-3 ;AND LOOP POPJ P, ;RETURN PUTOCT: MOVE T3,[POINT 3,T2] ;LOAD THE BTP ILDB T1,T3 ;LOAD THE BYTE JUMPE T1,.-1 ;IGNORE LEADING ZEROS CAIA ILDB T1,T3 ADDI T1,60 ;MAKE IT ASCII PUSHJ P,LOUCH ;OUTPUT IT TLNE T3,770K ;LAST BYTE? JRST .-4 ;NO, THEN LOOP POPJ P, ;YES, RETURN PUTDEC: IDIVI T1,^D10 ;DIVIDE BY RADIX JUMPE T1,.+4 ;IF NULL, DO RETURN LOOP PUSH P,T2 ;SAVE T2 PUSHJ P,PUTDEC ;RECURSIVE CALL POP P,T2 ;RESTORE T2 MOVEI T1,60(T2) ;MAKE ASCII JRST LOUCH ;OUTPUT AND LOOP RETURN CRLF: ASCIZ/ / HEAD0: ASCIZ \MAC80 \ HEAD1: ASCIZ \8085 Cross Assembler \ HEAD2: ASCIZ \ Page \ HEAD3: ASCIZ \Symbol Table \ GTDATE: MOVE T3,[POINT 7,DATE] PUSH P,I ;SAVE I MOVE T1,[60,,11] ;LOAD THE DAY GETTAB T1, ;NOW JFCL PUSHJ P,GETDEC ;MAKE DECIMAL ASCII MOVEI T1,"-" IDPB T1,T3 ;DEPOSIT A HYPHEN MOVE I,[57,,11] ;LOAD THE MONTH GETTAB I, JFCL MOVE T2,[POINT 7,MONTAB-1(I)] ;SET BTP ILDB T1,T2 ;LOAD THE BYTE JUMPE T1,.+3 IDPB T1,T3 ;DEPOSIT THE BYTE JRST .-3 ;AND LOOP MOVEI T1,"-" IDPB T1,T3 ;DEPOSIT ANOTHER BYTE MOVE T1,[56,,11] ;LOAD THE YEAR GETTAB T1, JFCL SUBI T1,^D1900 ;LAST TWO ONLY PUSHJ P,GETDEC ;DEPOSIT IT MOVEI T1,SPACE ;LOAD AND OUTPUT A SPACE IDPB T1,T3 IDPB T1,T3 ;2 SPACES MOVE T1,[61,,11] ;LOAD THE HOUR GETTAB T1, JFCL PUSHJ P,GETDEC ;AND DEPOSIT IT MOVEI T1,":" ;LOAD AND OUTPUT A COLON IDPB T1,T3 MOVE T1,[62,,11] ;LOAD MINUTES GETTAB T1, JFCL CAIL T1,^D10 ;TWO DIGITS? JRST .+5 ;YES, THEN DO IT PUSH P,T1 ;SAVE T1 MOVEI T1,"0" ;LOAD AND OUTPUT A ZERO IDPB T1,T3 POP P,T1 ;RESTORE T1 PUSHJ P,GETDEC ;AND OUTPUT IT POP P,I ;RESTORE I POPJ P, ;RETURN GETDEC: IDIVI T1,^D10 ;DIVIDE BY RADIX JUMPE T1,.+4 ;IF DONE, JUMP OUT OF LOOP PUSH P,T2 ;SAVE T2 PUSHJ P,GETDEC ;AND LOOP POP P,T2 ;RESTORE T2 MOVEI T1,60(T2) ;MAKE ASCII IDPB T1,T3 ;DEPOSIT IT POPJ P, ;LOOP RETURN PUTSIX: MOVE T3,[POINT 6,T2] ILDB T1,T3 ADDI T1,40 PUSHJ P,LOUCH TLNE T3,770K JRST .-4 POPJ P, DOLINO: TROE F,FR.LIN ;ALREADY PRINTED? POPJ P, ;YES, DONE PUSH P,T1 PUSH P,T2 TRNN F,FR.BOL ;AT START OF LINE? PUSHJ P,LCRLF ;FIXUP BUG IN DC LOGIC (HORRORS) MOVE T1,LINCTR ;GET LINE COUNT CAILE T1,LPP ;TEST IN CASE IN DC? CODE PUSHJ P,DOHDFF ;IF EXPANSION OF DB OVERFLOWS PAGE AOS T1,LINENO ;GET LINE # MOVEI T2,SPACE EXCH T1,T2 CAIG T2,^D999 PUSHJ P,LOUCH CAIG T2,^D99 PUSHJ P,LOUCH CAIG T2,^D9 PUSHJ P,LOUCH EXCH T1,T2 PUSHJ P,PUTDEC ;PRINT IT HRRZ T1,INVECT ;IS THIS A SOURCE LINE? CAIN T1,-1 ;.. JRST DOLIN1 ;YES, SKIP CAIG T1,ENDHGH ;CAME FROM BAKBUF? JRST DOLIN1 ;YES, THAT'S NOT A MACRO MOVEI T1,"M" ;FLAG AS A MACRO EXPANSION LINE PUSHJ P,LOUCH DOLIN1: MOVEI T1,TAB PUSHJ P,LOUCH ;& A TAB POP P,T2 POP P,T1 POPJ P, MONTAB: ASCIZ /Jan/ ASCIZ /Feb/ ASCIZ /Mar/ ASCIZ /Apr/ ASCIZ /May/ ASCIZ /Jun/ ASCIZ /Jul/ ASCIZ /Aug/ ASCIZ /Sep/ ASCIZ /Oct/ ASCIZ /Nov/ ASCIZ /Dec/ ;ADD NEW MONTHS HERE PASS1: TRZE F,FR.END ;DONE? JRST ENDIT ;YES PUSHJ P,TOKEN PUSHJ P,IFPOP ;IF OR FRIENDS? JRST NOP1T ;YES TRNE F,FR.OFF JRST FPASS1 NOP1T: JUMPN TOK,.+4 CAIE I,CR CAIN I,SEMICO ;END OF LINE? JRST FPASS1 ;YES, DONE CAIN I,COLON ;BEFORE A COLON? JRST LOASYM ;YES, ITS A LABEL PUSHJ P,SRCHOP ;GET INDEX TO OPCODE JRST [PUSHJ P,SETMAC;SETUP MACRO JRST PASS1] MOVE P1,TYPLSH(X) TLNN P1,T.POP ;PSEUDO OP? JRST .+3 ;NO SKIP PUSHJ P,PSEUDO ;DOIT JRST PASS1 ;LOOP BACK AOS PC ;ONE BYTE AOJ BC, TLNN P1,T.2BYT!T.3BYT JRST .+3 AOS PC ;TWO BYTES AOJ BC, TLNN P1,T.3BYTE JRST .+3 AOS PC ;THREE BYTES AOJ BC, FPASS1: PUSHJ P,FLUSH JRST PASS1 LOASYM: PUSHJ P,SRCSYM MOVEM TOK,(S) HRR T1,PC ;FLAGS,PC TRNN F,FR.ORG ;IF RELOCATING, TLO T1,S.REL ;FLAG AS RELOCATABLE TLZ T1,S.UNDF ;CLEAR UNDEFINED FLAG CAIL S,SYMTAB ;SKIP IF ILLEGAL MOVEM T1,1(S) JRST PASS1 UUO: LDB E,[POINT 9,.JBUUO##,8] JRST @UUOTAB-1(E) UUOTAB: EUUO WUUO WUUO: MOVSI E,"%" JRST EUUO+1 EUUO: MOVSI E,"?" HRR E,.JBUUO POPJ P, DEFINE X(A,B,C,D),< SIXBIT /A/ > OPNTAB: XLIST OPTYPE LIST OPTABL==.-OPNTAB DEFINE X(A,B,C,D),< EXP B > OPCTAB: XLIST OPTYPE LIST DEFINE X(A,B,C,D),< XWD C,D > TYPLSH: XLIST OPTYPE T.POP,,0 ;SO THAT UNDEF OPCODES DON'T BUMP PC LIST DEFINE W(A,B),< [ASCIZ/B/]> ERRTAB: EFLAGS LIT LIST RELOC 0 PRETAB: SIXBIT /A/ EXP 7 SIXBIT /B/ EXP 0 SIXBIT /C/ EXP 1 SIXBIT /D/ EXP 2 SIXBIT /E/ EXP 3 SIXBIT /H/ EXP 4 SIXBIT /L/ EXP 5 SIXBIT /M/ EXP 6 SIXBIT /SP/ EXP 6 SIXBIT /PSW/ EXP 6 PRELEN==.-PRETAB SYMTAB::BLOCK 4*SYMSIZ SYMEND==. LINBLK: BLOCK ^D40 ;HOLDS MAX OF 200 CHARACTER LINE LINEND==.-1 STRING: BLOCK 200 ;ROOM FOR 384 BYTES - 2 FULL PAGES OF GENERATED OUTPUT MACDUM: BLOCK 20 ;HOLDS 80 CHARACTERS OF MACRO DEF DUMMYS MACDML==.-MACDUM MACARG: BLOCK 20 ;80 CHARACTERS OF MACRO ARGS PC: 0 BYTCNT: 0 XTRAPC: 0 ORGBLK: BLOCK 100 ;BYTE COUNT OF BLOCK ;START ADDRESS OF BLOCK MACSTK: BLOCK 20 ;INVECT GETS PUSHED ON THIS WHEN A MACRO IS CALLED MACPDL: 0 ;POINTER TO MACSTK OPSTK: BLOCK 20 ;PDL FOR POLISH STACK (ENOUGH?) INVECT: 0 ;POINTS TO THE MACRO FROM WHICH INCH WILL GET ITS SOURCE BAKBUF: BLOCK 20 ;HOLDS NEXT 20 WORDS IN BUFFER WHILE DOING SNEAK BAKPTR: 0 ;POINTER TO BAKBUF SAVREG: BLOCK 5 ;MISC. STORAGE WHEN STACK IS BUSY IFLEVL: 0 ;LEVEL OF CURRENT NESTED IF EXPLVL: 0 ;LEVEL OF CURRENT PAREN IN EXPRESSION OFFLVL: 0 ;IFLEVL THAT ASSEMBLY WAS TURNED OFF CHECK: 0 ;CHECKSUM STARTA: 0 ;START ADDRESS TITL: BLOCK 20 ;TITLE BUFFER SUBTTL: BLOCK 40 SUBTLN==<.-SUBTTL>*5 IFN FTREL,< RELPTR: 0 RELTAB: BLOCK ^D50 ;50 RELOC ADDRESSES (DUMPED WHEN GT 15) RELEND==.-1 > LINENO: 0 LINCTR: 0 DELIM: 0 ;USED TO TELL " FROM ' IN DC & SETMAC CODE PAGENO: 0 SUBPAG: 0 DATE: 0 0 0 ENDHGH::0 END