BEGIN; !HAL-7502 ! INPUT/OUTPUT STREAMS OWNINTEGER MAIN=1, PRE=2; !INPUT OWNINTEGER BIN=1, LIS=2; !OUTPUT ! OPERAND TYPES OWNINTEGER OPMASK=16_F000; !MACHINE INSTRUCTION OR MACRO OWNINTEGER MACRO=16_A000 OWNINTEGER FMASK=16_0800; !FORWARD REF OWNINTEGER UMASK=16_0200; !UNDEF (FORWARD REF) OWNINTEGER REG=16_0080; !REGISTER OWNINTEGER MEMMASK=16_0040; !MEM REF OWNINTEGER RELMASK=16_0020; !RELOCATABLE OWNINTEGER XMASK=16_0010; !INDEXED OWNINTEGER REGXMASK=16_0090; !=REG+XMASK OWNINTEGER RELUXMASK=16_0230; !=RELMASK+UMASK+XMASK ! TEXT POINTERS (BYTE ADDRESSES) OWNINTEGER CODEPOS; !(NOT ACTUALLY BYTE) OWNINTEGER STARTPOS; !START OF CURRENT LINE OWNINTEGER GETPOS; !INPUT POINTER (NEXT) OWNINTEGER PUTPOS OWNINTEGER PSEUDOLIM OWNINTEGER PRINTPOS; !START OF PRINT LINE OWNINTEGER FAULTPOS OWNINTEGER MACLIM; !MACRO DEF LIMIT ! OTHER POINTERS (WORD ADDRESSES) OWNINTEGER MP; !MACRO-CALL PARAMETERS OWNINTEGER QBASE,QSTART,QLIM,TRANSF; !OPERAND QUEUE OWNINTEGER DEFMIN; !TAG MIN (DOWN - RESET) OWNINTEGER DEFLIM; !TAG LIM (FIXED) OWNINTEGER ALMAX; !ASSEMBLER LAB MAX (UP - RESET) OWNINTEGER LABMIN; !USER LAB MIN (DOWN - RESET) OWNINTEGER LABLIM; !USER LAB LIM (FIXED) OWNINTEGER BP; !BLOCK POINTER (UP - DOWN) OWNINTEGER NP; !NEST POINTER (DOWN - UP) OWNINTEGER STORELIM; !(FIXED) INTEGER SYM; !CURRENT SYMBOL INTEGER TERM; !TAG TERMINATOR INTEGER FSYM; !FAULT FLAG SYMBOL OWNINTEGER CHARS=0; !PRINT CHAR COUNT OWNINTEGER LINES=0; !PRINT LINE COUNT OWNINTEGER PASS=-1; !CURRENT PASS (-1,0,1) OWNINTEGER LIST=-1; !LISTING CONTROL INTEGER ASSCOND,SKIP; !ASSEMBLY CONDITIONS (BIT NEST) OWNINTEGER SAVE=1; !REG SAVE DISPLACEMENT OWNINTEGER TEMPS=12; !TEMPORARY REGISTER SET OWNINTEGER CONTROL=16_40; !OBJECT CODE CONTROL FIELD OWNINTEGER CHECK=0; !BINARY CHECKSUM INTEGER LOCTYPE,LOC; !LOCATION COUNTER INTEGER ACC,ATYPE,AVAL; !MAIN TEMP REGISTER INTEGER CREG; !CONDITION CODE INTEGER COND; !CONDITION CODE MASK INTEGER DREG,DUSE; !DESTINATION REGISTER INTEGER TYPE,VAL; !CURRENT TYPE,VALUE INTEGER TAG1,TAG2; !TAG (CHARS 1:3, 4:6) INTEGER MODE; !ASSEMBLY MODE INTEGER PEND; !TAG ALREADY RECOGNISED INTEGER FLAG; !JUMPS INTEGER SBOUND SBOUND = FREESTORE-260; !ALLOW FOR INPUT BUFFER SBOUND = SBOUND-256 IF OUTDEV = 2 SELECT OUTPUT(LIS) SBOUND = SBOUND-256 IF OUTDEV = 2 INTEGERARRAY STORE(1:SBOUND) INTEGERFN CHAR(INTEGER P) !BYTE FETCH END ROUTINE PUT CHAR(INTEGER K) !AT PUTPOS WITH POST-INCREMENT END ROUTINE FAULT(INTEGER K) !RECORD (FIRST) FAULT !NOT NECESSARILY CULPABLE IN PASS 0 FSYM = K IF FSYM = ' ' END ROUTINE PRINT(INTEGER K) INTEGER(CODEPOS+CHARS) = K CHARS = CHARS+1 END ROUTINE PRINT WORD(INTEGER V) ROUTINE PRINT HIT(INTEGER V) V = V&15+'0'; V = V+7 IF V > '9' PRINT(V) END ROUTINE PRINT1(INTEGER V) PRINT HIT(V>>4); PRINT HIT(V) END PRINT1(V>>8); PRINT1(V) END ROUTINE PRINT LOC PRINT WORD(LOC) IF LOCTYPE&RELMASK # 0 THEN PRINT('''') ELSE PRINT(' ') PRINT(' ') END ROUTINE DO NEWLINE NEWLINE; LINES = LINES+1 NEWLINES(2) AND LINES = 0 IF LINES = 61 END ROUTINE PRINT LINE ROUTINE PRINTIT(INTEGER SUB) OWNINTEGER MARKER=124; !VERTICAL BAR INTEGER P,Q,K RETURN IF CHARS = 0 AND CHAR(PRINTPOS) = NL PRINT SYMBOL(FSYM); SPACE P = CODEPOS; Q = P+CHARS PRINT SYMBOL(INTEGER(P)) AND P=P+1 WHILE P # Q RETURN IF PRINTPOS = 0 SPACES(17-CHARS) P = PRINTPOS; Q = 0 CYCLE PRINT SYMBOL(MARKER) IF P = FAULTPOS K = CHAR(P); K = SUB IF P = PSEUDOLIM PRINT SYMBOL('''') IF (K!!Q)&128 # 0 RETURN IF K = NL PRINT SYMBOL(K&127) P = P+1; Q = K REPEAT END RETURN IF PASS = 0 UNLESS LIST < 0 OR (PRINTPOS=0 AND FSYM=' ' AND LIST&1=0) START NEWLINES(3) IF LINES = 0 PRINTIT(' ') DO NEWLINE FINISH IF FSYM # ' ' AND OUTDEV # 1 START SELECT OUTPUT(0) PRINTPOS = STARTPOS IF PRINTPOS = 0 PRINT LOC IF CHARS = 0 PRINTIT(NL) NEWLINE SELECT OUTPUT(LIS) FINISH FSYM = ' '; PRINTPOS = 0; CHARS = 0 END ROUTINE PUT WORD(INTEGER V) CHECK = CHECK!!V SELECT OUTPUT(BIN) PRINT CH(V>>12&15+CONTROL) PRINT CH(V>>8&15+16_40) PRINT CH(V>>4&15+16_40) PRINT CH(V&15+16_40) CONTROL = 16_50 SELECT OUTPUT(LIS) END ROUTINE PLANT VAL IF PASS > 0 START IF CHARS = 0 START IF PRINTPOS#0 THEN PRINT LOC ELSE START PRINT(' '); PRINT(' '); PRINT(' ') PRINT(' '); PRINT(' '); PRINT(' ') FINISH FINISH PRINT(' ') IF CHARS = 10 PRINT WORD(VAL); PUT WORD(VAL) PRINT('''') IF TYPE&RELMASK # 0 PRINT LINE IF CHARS >= 15 FINISH LOC = LOC+1 END ROUTINE PLANT(INTEGER V) INTEGER THOLD,VHOLD THOLD = TYPE; VHOLD = VAL TYPE = 0; VAL = V PLANT VAL TYPE = THOLD; VAL = THOLD END ROUTINE NEST(INTEGER K) NP = NP-1; !!%MONITOR 23 %IF NP = BP INTEGER(NP) = K END ROUTINE SET LAB(INTEGER DEST) INTEGER P,Q Q = 0 CYCLE TYPE = INTEGER(NP); P = TYPE&16_3FF+DEFLIM; !DEST SLOT NP = NP+1 VAL = INTEGER(NP); !LOC OF JUMP NP = NP+1 ATYPE = -1; CREG = -1 FLAG = 0; IF TYPE&16_800 = 0 START FLAG = 1 IF DEST-VAL+PASS <= 128 finish ELSE IF TYPE&16_400 # 0 START FLAG = 2 IF DEST-VAL+PASS+PASS = 1 FINISH IF PASS = 0 START DEST = DEST-FLAG; INTEGER(P) = DEST IF FLAG # 0 START LOC = LOC-FLAG WHILE P # ALMAX CYCLE P = P+1; INTEGER(P) = INTEGER(P)-FLAG REPEAT FINISH finish ELSE START FAULT('P') IF INTEGER(P) # DEST FINISH RETURN IF INTEGER(NP)&16_1000 = 0 IF INTEGER(NP)&16_2000 # 0 AND Q = 0 START; !OR DEST = VAL+1 DEST = VAL+2-FLAG UNLESS TYPE&16_C00 = 16_C00 Q = 1 FINISH REPEAT END ROUTINE ASSEMBLE ! 7502 OP-CODES OWNINTEGER ADD=16_F400, SUB=16_F500, AND=16_F100 OWNINTEGER OR=16_F000, XOR=16_F700, COMP=16_F200 OWNINTEGER COPY=16_F300 OWNINTEGER LOADI=16_6000, SKIDI=16_7000, ADDI=16_8000 OWNINTEGER ANDI=16_9000 OWNINTEGER BOC=16_5800, BOCR=16_5000, JUM=16_4000 OWNINTEGER SKIP=16_4002, LOADC=16_20F2, ROT=16_3000 OWNINTEGER LOAD=16_2000, STORE=16_2008 INTEGER Q,NQ,OP,K,LITVAL,TYPE1,VAL1,FREE SWITCH ASS(-30:-1) ROUTINE COMBINE INTEGER I,J,K I = 11; K = 2048 I=I-1 AND K=K>>1 WHILE K&TYPE1 = 0 AND I # 0 J = K I =I-1 AND J=J>>1 WHILE J&VAL1 = 0 AND I # 0 VAL = VAL<<I & (K<<1-1) TYPE = TYPE1-K VAL = VAL1-J+VAL END ROUTINE PLANT JUMP INTEGER I,V I = VAL-LOC IF COND&6 = 0 START IF COND = 8 START RETURN IF I=1 PLANT(SKIP) FINISH finish ELSE START FAULT('J') AND I=0 IF FLAG # 0 AND |I| > 127 IF |I| <= 127 START IF TYPE&UMASK = 0 OR FLAG # 0 START PLANT(BOC+(COND!!1)<<8+I&255) RETURN FINISH FAULT('S') IF LIST >= 0 AND LIST&8 # 0 FINISH PLANT(BOC+COND<<8+2) FINISH PLANT(JUM+(VAL-LOC)&4095) END ROUTINE SET JUMP(INTEGER CASE) INTEGER THOLD,VHOLD,FHOLD CASE = CASE+16_0800 IF COND&6 = 0 CASE = CASE+16_0400 IF COND&1 # 0 ALMAX = ALMAX+1; !!%MONITOR 22 %IF ALMAX = LABMIN NEST(LOC); NEST(ALMAX-DEFLIM+CASE) THOLD = TYPE; VHOLD = VAL; FHOLD = FLAG TYPE = LOCTYPE; VAL = INTEGER(ALMAX); FLAG = 0 TYPE = TYPE+UMASK IF PASS = 0 COND = COND!!1 PLANT JUMP; COND = 0 TYPE = THOLD; VAL = VHOLD; FLAG = FHOLD END ROUTINE PLANT INST(INTEGER CODE) SET JUMP(16_1000) IF COND # 0 PLANT(CODE) END ROUTINE RELEASE INTEGER I RETURN IF TYPE®XMASK = 0 I = TYPE&15; I = VAL IF TYPE = REG IF I = DREG START DUSE = DUSE-1 finish ELSE START I = 1<<I FREE = FREE!I IF TEMPS&I # 0 FINISH END INTEGERFN TREG INTEGER I,J IF DREG >= 0 AND DUSE = 0 START DUSE = 1 RESULT = DREG FINISH J = 1 CYCLE I = 0,1,15 ->OK IF FREE&J # 0 AND I # DREG J = J<<1 REPEAT FAULT('R') OK: FREE = FREE-J RESULT = I END ROUTINE LOAD CONST(INTEGER R) INTEGER I,J I = LOADI+R<<8 IF VAL&(¬255) = 0 AND TYPE&UMASK = 0 START PLANT INST(I+VAL) finish ELSE IF ¬VAL&(¬255) = 0 AND TYPE&UMASK = 0 START PLANT INST(I+(¬VAL)) PLANT INST(COMP+R<<4+R) CREG = R finish ELSE START ! PLANT INST(LOADC+R<<8) ! PLANT INST(SKIP) ! PLANT VAL J = VAL>>8&255 J = J+1 IF VAL&128 # 0 PLANT INST(I+J) PLANT INST(ROT+R<<8+7<<4+R) PLANT INST(ADDI+R<<8+VAL&255) IF VAL&255 # 0 FINISH END ROUTINE LOAD REG(INTEGER R) INTEGER OP IF ATYPE = TYPE AND AVAL = VAL START TYPE = REG; VAL = ACC RETURN IF R = ACC FINISH ATYPE = TYPE AND AVAL = VAL IF R = ACC ATYPE = -1 IF (ATYPE=REG AND AVAL=R) ATYPE = -1 IF ATYPE&XMASK # 0 AND ATYPE&15 = R IF TYPE = REG START PLANT INST(COPY+R<<4+VAL) CREG = R finish ELSE IF TYPE&XMASK = 0 START LOAD CONST(R) PLANT INST(LOAD+R<<8+R<<4) IF TYPE&MEMMASK # 0 finish ELSE START IF VAL&(¬3) # 0 OR TYPE&MEMMASK = 0 START IF TYPE&15 # R START IF |VAL| <= 127 START PLANT INST(COPY+R<<4+TYPE&15) PLANT INST(ADDI+R<<8+VAL&255) IF VAL # 0 finish ELSE START LOAD CONST(R) PLANT INST(ADD+R<<4+TYPE&15) FINISH CREG = R finish ELSE START IF |VAL| <= 127 START IF VAL # 0 START PLANT INST(ADDI+R<<8+VAL&255) CREG = R FINISH finish ELSE START OP = TREG LOAD CONST(OP) TYPE = REG; VAL = OP RELEASE PLANT INST(ADD+R<<4+OP) CREG = R FINISH FINISH TYPE = TYPE&MEMMASK+XMASK+R; VAL = 0 FINISH IF TYPE&MEMMASK # 0 START PLANT INST(LOAD+R<<8+(TYPE&15)<<4+VAL) CREG = -1 ! %FINISH -- commenting out this line allows the program to compile finish ELSE START LOAD CONST(R) PLANT INST(LOAD+R<<8+R<<4) FINISH FINISH TYPE = REG; VAL = R END ROUTINE LOAD TEMP RELEASE LOAD REG(TREG) END ROUTINE SWOP INTEGER K K = TYPE1; TYPE1 = TYPE; TYPE = K K = VAL1; VAL1 = VAL; VAL = K END Q = QSTART NEW:NQ = QSTART; FREE = TEMPS TYPE = INTEGER(Q); Q = Q+1 VAL = INTEGER(Q); Q = Q+1 GET:CYCLE RETURN IF Q = QLIM K = INTEGER(Q); Q = Q+1 ->ASS(K) IF K < 0 INTEGER(NQ) = TYPE1; INTEGER(NQ+1) = VAL1 NQ = NQ+2 TYPE1 = TYPE; VAL1 = VAL TYPE = K; VAL = INTEGER(Q); Q = Q+1 REPEAT PREDICATE TEMP FALSE IF TYPE1 # REG IF VAL1 = DREG START FALSE IF DUSE # 1 finish ELSE START FALSE IF 1<<VAL1&TEMPS = 0 FINISH TRUE END NOP: K = 0; !NOT SYMMETRIC BOP:IF MODE <= 0 OR (TYPE = 0 AND TYPE1 = 0) START FAULT('A') IF TYPE # 0 TYPE = TYPE1; VAL = LITVAL finish ELSE START IF NOT TEMP OR (TYPE=REG AND VAL=DREG AND DUSE=1 AND K#0) START SWOP IF K = 0 OR NOT TEMP START LOAD TEMP; SWOP FINISH FINISH IF OP = AND AND TYPE = 0 AND VAL&(¬255) = 0 START PLANT INST(ANDI+VAL1<<8+VAL) finish ELSE START LOAD TEMP IF TYPE # REG RELEASE PLANT INST(OP+VAL1<<4+VAL) FINISH TYPE = REG; VAL = VAL1 CREG = VAL ATYPE = -1 IF ACC = VAL ATYPE = -1 IF ATYPE&XMASK # 0 AND ATYPE&15 = VAL ATYPE = -1 IF ATYPE = REG AND AVAL = VAL FINISH POP:NQ = NQ-2 TYPE1 = INTEGER(NQ); VAL1 = INTEGER(NQ+1) ->GET ASS(-2): OP = SUB ->NOP IF MODE > 0 AND TYPE # 0 TYPE1 = 0 AND TYPE = 0 IF MODE <= 0 AND TYPE1 = TYPE VAL = -VAL ASS(-1): OP = ADD; LITVAL = VAL1+VAL ->BOP UNLESS TYPE = 0 IF TYPE1&MEMMASK # 0 AND MODE > 0 START SWOP; LOAD TEMP; SWOP FINISH IF TYPE1 = REG AND NOT TYPE=VAL=0 START TYPE1 = XMASK+VAL1; LITVAL = VAL FINISH TYPE = TYPE1; VAL = LITVAL ->POP ASS(-6): LITVAL = VAL1<<VAL; K = (-1)<<VAL VAL = 16-VAL ->AS7 ASS(-7): LITVAL = VAL1>>VAL; K = (16_FFFF)>>VAL AS7:K=0 AND ->BOP IF MODE <= 0 FAULT('I') IF TYPE # 0 OR VAL&(¬15) # 0 IF NOT TEMP START SWOP; LOAD TEMP; SWOP FINISH OP = ROT+VAL1<<8+VAL1 PLANT INST(OP+16_0070) IF VAL > 8 PLANT INST(OP+(VAL-1)<<4) IF VAL # 0 TYPE = 0; VAL = K; K = -3 ASS(-3): OP = AND; LITVAL = VAL1&VAL ->BOP ASS(-4): OP = OR; LITVAL = VAL1!VAL ->BOP ASS(-5): OP = XOR; LITVAL = VAL1!!VAL ->BOP ASS(-8): !TYPE_VAL TYPE = VAL1 TYPE = 0 IF TYPE&OPMASK = MACRO; !SAFETY TYPE = 0 IF TYPE&(OPMASK+FMASK) = FMASK ->POP ASS(-11): !COMPARE K = INTEGER(Q); Q = Q+1 IF MODE <= 0 START LITVAL = 2_01011000 LITVAL = 2_01100100 IF VAL < 0 LITVAL = 2_10101000 IF VAL1 > VAL K = LITVAL>>K&1; finish ELSE START UNLESS K&6=4 AND -256<VAL<0 AND TYPE&XMASK#0 START LOAD TEMP IF TYPE # REG PLANT INST(COPY+VAL<<4+VAL) IF CREG # VAL CREG = VAL finish ELSE START PLANT INST(SKIDI+(TYPE&15)<<8-VAL) K = K+4; !8,9 FINISH FINISH COND = K ->GET ASS(-12): !TEST CC COND = VAL!!1 ->GET ASS(-13): !AND IF MODE > 0 START SET JUMP(16_1000) finish ELSE START RETURN IF COND = 0 FINISH RETURN IF Q = QLIM ->NEW ASS(-14): !OR IF MODE > 0 START COND = COND!!1 SET JUMP(16_3000) finish ELSE START RETURN IF COND # 0 FINISH ->NEW ASS(-15): !IF SET JUMP(16_2000) RETURN ASS(-16): !ELSE COND = 1 SET JUMP(16_4000) RETURN ASS(-17): !IF AFTER ELSE SET JUMP(16_6000) RETURN ASS(-18): !MACCALL IF SET JUMP(16_8000) RETURN ASS(-20): !HASH TYPE = TYPE&(UMASK+63) ->GET ASS(-21): !INDEX FAULT('I') IF TYPE1®XMASK # 0 IF TYPE&MEMMASK # 0 START IF MODE > 0 THEN LOAD TEMP ELSE FAULT('A') FINISH IF TYPE = REG START TYPE = XMASK+VAL; VAL = 0 FINISH FAULT('I') IF TYPE1&TYPE&RELMASK # 0 TYPE = TYPE1!TYPE!MEMMASK; VAL = VAL1+VAL ->POP ASS(-22): !MINST SEPARATOR COMBINE ->POP ASS(-23): !PLANT INST MODE = 1 PLANT INST(VAL) CREG = -1; ATYPE = -1 RETURN ASS(-24): !LOAD LOAD TEMP IF TYPE # REG Q = QBASE ->GET ASS(-25): !STORE (TYPE1,VAL1 -> TYPE,VAL) IF TYPE = REG START SWOP AND LOAD REG(VAL1) IF VAL1 # VAL finish ELSE START ATYPE = -1 IF ATYPE&MEMMASK # 0 IF VAL1 = ACC AND ATYPE < 0 START K = TYPE&15 ATYPE = TYPE AND AVAL = VAL IF TYPE&XMASK = 0 OR 1<<K&TEMPS = 0 FINISH IF TYPE&XMASK = 0 OR VAL&(¬3) # 0 START TYPE = TYPE&(¬MEMMASK) LOAD TEMP TYPE = MEMMASK+XMASK+VAL; VAL = 0 FINISH PLANT INST(STORE+VAL1<<8+(TYPE&15)<<4+VAL) FINISH RETURN ASS(-26): !JUMP SET JUMP(16_1000) IF INTEGER(NP)&16_F000 = 16_3000; !OR TYPE = TYPE!MEMMASK IF TYPE # REG IF TYPE&(¬UMASK) = LOCTYPE START PLANT JUMP finish ELSE START TYPE = XMASK+VAL AND VAL=0 IF TYPE = REG FAULT('I') IF TYPE&XMASK = 0 OR VAL&(¬15) # 0 IF COND&8 # 0 START PLANT(SKIP) IF COND = 8 COND = 1 FINISH PLANT(BOCR+COND<<8+(TYPE&15)<<4+VAL) FINISH COND = 0 RETURN END ROUTINE GET SYM CYCLE SYM = CHAR(GETPOS); GETPOS = GETPOS+1 RETURN IF SYM # ' ' REPEAT END PREDICATE S(INTEGER K) FALSE UNLESS K = SYM GET SYM TRUE END PREDICATE SS(INTEGER K) FALSE UNLESS K = SYM = CHAR(GETPOS) GETPOS = GETPOS+1 GET SYM TRUE END PREDICATE TAG INTEGER J,K ROUTINE CODE SYM SYM = CHAR(GETPOS); GETPOS = GETPOS+1 K = SYM-'0' IF K >= 0 START TERM = -1 AND RETURN IF K < 10 K = SYM-'A' RETURN IF K >= 0 AND K < 26 AND TERM = 0 FINISH TERM = SYM END ROUTINE PACK TRIPLE ->T1 IF TERM < 0 J = ((K<<5+K)<<1+K)<<4+K+1111; !K*1073+1111 CODE SYM ->T2 IF TERM # 0 J = (K<<3+K)<<2+K+111+J; !J+K*37+111 CODE SYM ->T3 IF TERM # 0 J = J+K+11 CODE SYM RETURN T1: J = ((K<<1+K)<<1+K)<<4-K+1; !K*111+1 CODE SYM T2: RETURN IF TERM > 0 J = (K<<2+K)<<1+K+1+J; !J+K*11+1 CODE SYM T3: RETURN IF TERM > 0 J = J+K+1 CODE SYM END K = SYM-'A' FALSE UNLESS K >= 0 AND K < 26 FALSE IF SYM = 'X' AND CHAR(GETPOS)&128 # 0 TERM = 0 PACK TRIPLE TAG1 = J; J = 0 PACK TRIPLE IF TERM <= 0 TAG2 = J CODE SYM WHILE TERM <= 0 GET SYM IF TERM = ' ' TRUE END PREDICATE TAGIF FALSE UNLESS SYM='I' AND CHAR(GETPOS)='F' AND CHAR(GETPOS+1)=' ' GETPOS = GETPOS+2 GET SYM TRUE END ROUTINE LOOKUP(INTEGER CONTROL) !ALL DICT OPERATIONS LOCALISED HERE !CONTROL = 0 (LOOKUP ONLY), 1 (FORWARD OK), ! 2 (REDEF), 3 (DEF), ! 4 (MACPARM), 7 (LABEL) INTEGER DP DP = DEFMIN; DP = MP+5 IF CONTROL = 4 WHILE INTEGER(DP) # 0 CYCLE ->YES IF INTEGER(DP) = TAG1 AND INTEGER(DP+1) = TAG2 DP = DP+4 REPEAT !!%OWNINTEGER P !! DP = DP-4 !!REP:DP = DP+4 !! %LAC* DP; %OPR 640;!SNA; %JMP NO !! %SAD TAG1; %OPR 512; %JMP REP !! %LAC DP; %TAD #1; %DAC P !! %LAC* P; %SAD TAG2; %JMP YES !! ->REP NO: RETURN IF CONTROL&1 = 0; !NO CREATION NEW:DEFMIN = DEFMIN-4; DP = DEFMIN !!%MONITOR 21 %IF DP-QLIM <= 0 INTEGER(DP) = TAG1; INTEGER(DP+1) = TAG2 SET:INTEGER(DP+2) = TYPE; INTEGER(DP+3) = VAL RETURN YES:->NEW IF CONTROL = 3 AND DP-INTEGER(BP) >= 0 IF CONTROL&2 = 0 START; !NOT DEF CLASS TYPE = INTEGER(DP+2); VAL = INTEGER(DP+3) RETURN UNLESS TYPE&OPMASK = MACRO AND CONTROL = 0 IF TYPE&31#25 THEN INTEGER(DP+2)=TYPE+1 ELSE INTEGER(DP+2) = TYPE+7 RETURN FINISH FAULT('D') IF CONTROL = 3 ->SET IF CONTROL # 7 IF INTEGER(DP+2)&(OPMASK+FMASK) = FMASK START VAL = INTEGER(DP+3) IF PASS = 0 START INTEGER(VAL) = LOC finish ELSE START FAULT('P') AND LOC=INTEGER(VAL) IF INTEGER(VAL) # LOC FINISH VAL = LOC finish ELSE START ->NEW IF DP-INTEGER(BP) >= 0 FAULT('D') FINISH ->SET END ROUTINE QUEUE(INTEGER K) INTEGER(QLIM) = K QLIM = QLIM+1; !!%MONITOR 21 %IF QLIM = DEFMIN END ROUTINE GET EXP OWNINTEGER W=24717 INTEGER I,NBASE NBASE = NP ->E3 IF PEND # 0 E1: NEST(0) WHILE S('(') NEST(-20) IF S('#') IF TAG START E3: IF TAG1 = W START; !W TYPE = 0; VAL = 0 finish ELSE START IF PEND >= 0 START TYPE = LOCTYPE+FMASK+UMASK; VAL = LABMIN-1 LOOKUP(1) IF TYPE&(OPMASK+FMASK) = FMASK START IF VAL = LABMIN-1 START LABMIN = VAL; !!%MONITOR 22 %IF LABMIN = ALMAX FINISH VAL = INTEGER(VAL) FAULT('U') IF VAL = 0 TYPE = TYPE-FMASK FINISH FINISH FINISH PEND = 0 IF TYPE = REG AND TERM = '(' START TYPE = 0 IF SAVE&1 = 0; VAL = VAL+SAVE; !? FINISH IF MODE # 0 START FAULT('I') AND TYPE=0 IF TYPE&OPMASK # 0 IF TYPE®XMASK # 0 START I = TYPE&15; I = VAL IF I = 0 DUSE = DUSE+1 IF I = DREG FINISH FINISH IF TERM = '(' START GET SYM I = TYPE&31 QUEUE(TYPE-I); QUEUE(VAL) NEST(-21); NEST(0) IF I # 0 START QUEUE(REG); QUEUE(I&15) NEST(-1) FINISH ->E1 FINISH finish ELSE IF '0' <= SYM <= '9' START TYPE = 0; VAL = SYM-'0' CYCLE SYM = CHAR(GETPOS)-'0' EXIT UNLESS 0 <= SYM <= 9 VAL = (VAL<<2+VAL)<<1+SYM GETPOS = GETPOS+1 REPEAT GET SYM finish ELSE IF SYM = 'X' START TYPE = 0; VAL = 0 CYCLE SYM = CHAR(GETPOS)-128 EXIT IF SYM < 0 SYM = SYM-32 IF SYM >= 96; !ENSURE UPPER-CASE IF '0' <= SYM <= '9' OR 'A' <= SYM <= 'F' START VAL = VAL<<4+SYM-'0' VAL = VAL-7 IF SYM >= 'A' finish ELSE FAULT('H') GETPOS = GETPOS+1 REPEAT GET SYM finish ELSE IF SYM&128 # 0 START TYPE = 0; VAL = SYM-128 GET SYM IF MODE >= 0 AND SYM&128 # 0 START VAL = VAL<<8+SYM-128; GET SYM FINISH finish ELSE IF S('.') START ->ERR IF NOT TAG TYPE = 0; VAL = TAG1 finish ELSE IF S('*') START TYPE = LOCTYPE&63; VAL = LOC IF SYM = 'L' START; !FOR NOW TYPE = 0; VAL = LIST IF TAG FINISH finish ELSE IF SYM = '-' START TYPE = 0; VAL = 0 finish ELSE IF SYM = '¬' START TYPE = 0; VAL = ¬0 finish ELSE ->ERR QUEUE(TYPE); QUEUE(VAL) WHILE NP # NBASE CYCLE IF INTEGER(NP) < 0 START QUEUE(INTEGER(NP)) finish ELSE START EXIT IF NOT S(')') FINISH NP = NP+1 REPEAT NEST(-1) AND ->E1 IF S('+') NEST(-2) AND ->E1 IF S('-') NEST(-3) AND ->E1 IF S('&') NEST(-4) AND ->E1 IF S('!') NEST(-5) AND ->E1 IF S('¬') NEST(-6) AND ->E1 IF SS('<') NEST(-7) AND ->E1 IF SS('>') NEST(-8) AND ->E1 IF S('_') RETURN IF NP = NBASE ERR:NP = NBASE !!%MONITOR 19 END ROUTINE GET COND OWNINTEGER AND=1717, OR=16873 INTEGER J,K TRANSF = QSTART; QSTART = QLIM J = 0 CYCLE GET EXP IF S('=') START K = 5 finish ELSE IF S('#') START K = 4 finish ELSE IF S('<') START K = 3; K = 7 IF S('=') finish ELSE IF S('>') START K = 6; K = 2 IF S('=') finish ELSE START QUEUE(-12) RETURN FINISH GET EXP QUEUE(-2); !SUBTRACT QUEUE(-11); QUEUE(K) RETURN IF NOT TAG IF TAG1 = AND AND TAG2 = 0 START !!%MONITOR 19 %IF J < 0 J = 1; QUEUE(-13) finish ELSE START !!%MONITOR 19 %IF TAG1 # OR %OR J > 0 J = -1; QUEUE(-14) FINISH REPEAT END ROUTINE GET INST INTEGER I QUEUE(TYPE); QUEUE(VAL) RETURN IF TERM # ' '; !NO OPERAND FOLLOWING => CYCLE GET EXP QUEUE(-22) RETURN IF NOT S(',') REPEAT END ROUTINE READ LINE INTEGER Q PUTPOS = STARTPOS IF MP = 0 START Q = 0; PSEUDOLIM = 0 CYCLE READ SYMBOL(SYM) READ SYMBOL(SYM) AND Q=Q!!128 IF SYM = '''' EXIT IF SYM = NL SYM = SYM-32 IF SYM-Q >= 96; !LOWER-CASE -> UPPER-CASE SYM = SYM+Q EXIT IF SYM = '/' AND PSEUDOLIM # 0 IF SYM = ' ' START PSEUDOLIM = PUTPOS IF PSEUDOLIM = 0 finish ELSE PSEUDOLIM = 0 PUT CHAR(SYM) REPEAT IF PSEUDOLIM # 0 START Q = PUTPOS; PUTPOS = PSEUDOLIM PUT CHAR(NL) PUTPOS = Q FINISH CYCLE PUT CHAR(SYM) EXIT IF SYM = NL READ SYMBOL(SYM) REPEAT PRINTPOS = STARTPOS finish ELSE START GETPOS = INTEGER(MP) IF CHAR(GETPOS) = 0 START QBASE = MP IF INTEGER(MP+1)&16_8000 # 0 START WHILE INTEGER(NP)&16_8000 = 0 CYCLE FAULT('C'); NP = NP+2 REPEAT SET LAB(LOC) FINISH GETPOS = INTEGER(MP+2) STARTPOS = INTEGER(MP+3) MP = INTEGER(MP+4) PRINTPOS = 0 IF LIST&2 # 0 GET SYM; !TERMINATOR GET SYM IF SYM = ';' RETURN FINISH PRINTPOS = STARTPOS IF LIST&2 # 0 CYCLE SYM = CHAR(GETPOS); GETPOS = GETPOS+1 IF TAG START SYM=TERM AND GETPOS=GETPOS-1 IF TERM = ' ' TYPE = INTEGER(MP); VAL = GETPOS-1 LOOKUP(4) WHILE TYPE # VAL CYCLE PUT CHAR(CHAR(TYPE)) TYPE = TYPE+1 REPEAT FINISH IF SYM = '?' START PUT CHAR(INTEGER(MP+1)>>5&31+'A') SYM = INTEGER(MP+1)&31+'A' FINISH PUT CHAR(SYM) INTEGER(MP) = GETPOS EXIT IF SYM = NL REPEAT FINISH QBASE = (PUTPOS+1)>>1 GETPOS = STARTPOS; GET SYM END ROUTINE SCAN ARG ! SET TYPE,VAL TO START,LIM OF ARG IF NOT NULL INTEGER I,J RETURN IF SYM='I' AND CHAR(GETPOS)='F' AND CHAR(GETPOS+1)=' ' I = GETPOS-1; I = GETPOS IF SYM = '[' J = 0 CYCLE EXIT IF SYM = NL EXIT IF (SYM=' ' OR SYM=',' OR SYM=';') AND J<=0 J = J+1 IF SYM = '[' IF SYM = ']' START J = J-1; EXIT IF J = 0 FINISH SYM = CHAR(GETPOS); GETPOS = GETPOS+1 REPEAT IF GETPOS-1 # I START TYPE = I; VAL = GETPOS-1 FINISH GET SYM IF SYM = ']' END ROUTINE SET ACC INTEGER I ACC = -1; ATYPE = -1; CREG = -1 I = TEMPS RETURN IF I = 0 CYCLE ACC = ACC+1 RETURN IF I&1 # 0 I = I>>1 REPEAT END !MAIN PROGRAM !RADIX 36 CONSTANTS OWNINTEGER B=2184, IF=9991, ELS=5950, E=5403, FIN=6907, ISH=10490 OWNINTEGER JUM=11642, P=17206, PS=17983, DEF=4605, END=6009 INTEGER I,J,K !!%FAULT 19 ->ERR; !RECOGNITION ERROR !!%FAULT 9 ->BEND; !INPUT ENDED CYCLE I = 1,1,SBOUND STORE(I) = 0 REPEAT CODEPOS = ADDR(STORE(1)) MACLIM = (CODEPOS+20)<<1 STORELIM = ADDR(STORE(SBOUND)) NP = STORELIM LABLIM = NP-60 BP = LABLIM DEFLIM = STORELIM-(SBOUND>>2) DEFMIN = DEFLIM INTEGER(BP) = DEFLIM SELECT INPUT(PRE) DO PASS: PUT WORD(0) AND CONTROL=16_20 IF PASS > 0 STARTPOS = MACLIM MP = 0 ALMAX = DEFLIM LABMIN = LABLIM ASSCOND = 1; SKIP = 0 LOCTYPE = MEMMASK+RELMASK; LOC = 0 SET ACC READ: FSYM = ' '; FAULTPOS = 0 READ LINE NEXT: DREG = -1 MODE = 0 PEND = 0; COND = 0 QSTART = QBASE; QLIM = QSTART FLAG = 0 IF S('$') START ->NEWPAGE IF SYM = '/' ->ERR IF NOT TAG ->ASSIF IF TAG1 = IF ->ASSELSE IF TAG1 = ELS ->ASSFIN IF TAG1 = FIN ->LEND IF SKIP # 0 ->DEFINE IF TAG1 = DEF ->DEFINE IF TAG1 = 19625; !RED ->LISTC IF TAG1 = 13350; !LIS ->TEMP IF TAG1 = 21780; !TEM ->LOCC IF TAG1 = 13556; !LOC ->LOCC IF TAG1 = 1917; !ASS ->SAVC IF TAG1 = 20568; !SAV ->MACDEF IF TAG1 = 14111; !MAC ->BEGIN IF TAG1 = 2460; !BEG ->BEND IF TAG1 = END FAULT('U') ->LEND FINISH ->LEND IF SKIP # 0 OR SYM = '/' IF SYM = NL START ->LEND IF LINES < 54 DO NEWLINE WHILE LINES # 0 ->READ FINISH IF TAG START ->LABDEF IF TERM = ':' MODE = 1 ->ASSIGN IF TERM = '(' OR SYM = '=' ->JUMP IF TAG1 = JUM AND (TAG2=P OR TAG2=PS) ->IFC IF TAG1 = IF ->ELSE IF TAG1 = ELS AND TAG2 = E ->FINISH IF TAG1 = FIN AND TAG2 = ISH ->WHILE IF TAG1 = 25106 AND TAG2 = 13173 ->CYCLE IF TAG1 = 4269 AND TAG2 = 13173 ->REPEAT IF TAG1 = 19637 AND TAG2 = 5544 MODE=-2 AND ->DATA IF TAG1 = B TYPE = UMASK; LOOKUP(0) ->MACCALL IF TYPE&OPMASK = MACRO ->MINST IF TYPE&OPMASK # 0 FAULT('U') AND ->LEND IF TYPE&UMASK # 0 PEND = -1 FINISH MODE = -1 DATA: CYCLE GET EXP; ASSEMBLE FAULT('I') IF TYPE®XMASK # 0 I = 1 IF S('$') START I = VAL IF VAL < 1000 QLIM = QSTART GET EXP; ASSEMBLE FINISH WHILE I > 0 CYCLE IF MODE # -1 START FAULT('T') IF VAL&16_FF00 # 0 IF MODE = -2 START J = VAL<<8; MODE = -3 finish ELSE START VAL = VAL+J; MODE = -2 PLANT VAL FINISH finish ELSE START PLANT VAL; VAL = VAL&255 FINISH I = I-1 REPEAT EXIT UNLESS S(',') OR SYM&128 # 0 IF SYM = NL START PRINT LINE IF PRINTPOS # 0; READ LINE QSTART = QBASE FINISH QLIM = QSTART REPEAT VAL=J AND PLANT VAL IF MODE = -3 ->SEND LABDEF: CREG = -1; ATYPE = -1 GET SYM FAULT('C') AND NP=STORELIM IF NP # STORELIM TYPE = LOCTYPE; VAL = LOC LOOKUP(7) ->NEXT ASSIGN: PEND = 1 GET EXP ->ERR IF NOT S('=') QUEUE(-25); !'STORE' IF INTEGER(QBASE) = REG START DREG = INTEGER(QBASE+1) DUSE = 0 FINISH QSTART = QLIM; MODE = 2 GET EXP QUEUE(-24); !'LOAD' CONDQ: IF TAGIF START MODE = MODE+4; DREG = DREG-16; !SCARIFY GET COND; ASSEMBLE MODE = MODE-4; DREG = DREG+16; !RESTORE QLIM = QSTART; QSTART = TRANSF FINISH ASSEMBLE ->SEND JUMP: FLAG = TAG2-P; !POSITIVE IF SHORT GET EXP QUEUE(-26); !'JUMP' ->CONDQ MINST: MODE = -1 GET INST QUEUE(-23); !'PLANT' ->CONDQ MACCALL: QUEUE(VAL); !DEFPOS QUEUE(TYPE&1023); !JOKER QUEUE(0); !(CALLPOS) QUEUE(STARTPOS) QUEUE(MP) CYCLE EXIT IF CHAR(INTEGER(QBASE)) = NL; !END OF MAC DEF I = GETPOS-1; !SAVE CALLPOS GETPOS = INTEGER(QBASE); GET SYM !!%MONITOR 24 %IF %NOT TAG TYPE = 0; VAL = 0 SCAN ARG GET SYM IF SYM = ',' INTEGER(QBASE) = GETPOS-1; !UPDATE DEFPOS GETPOS = I; GET SYM; !RESTORE CALLPOS SCAN ARG GET SYM IF SYM = ',' QUEUE(TAG1); QUEUE(TAG2) QUEUE(TYPE); QUEUE(VAL) REPEAT GET SYM IF SYM = ' ' IF TAGIF START GET COND; QUEUE(-18); ASSEMBLE QLIM = QSTART INTEGER(QBASE+1) = INTEGER(QBASE+1)+16_8000 FINISH QUEUE(0) MP = QBASE; STARTPOS = QLIM<<1 INTEGER(MP) = INTEGER(MP)+1 INTEGER(MP+2) = GETPOS-1 PRINT LINE IF PRINTPOS # 0 AND LIST&2 # 0 ->READ !CODING OF JUMPS: 1000 (SINGLE INST), 2000 (MAIN IF) ! 4000 (ELSE), 6000 (IF AFTER ELSE) IFC: GET COND; QUEUE(-15); ASSEMBLE ->SEND ELSE: ->CERR IF INTEGER(NP)&16_2000 = 0 QUEUE(0); QUEUE(0) QUEUE(-16); ASSEMBLE ATYPE = -1; CREG = -1 IF TAGIF START GET COND; QUEUE(-17); ASSEMBLE FINISH ->SEND FINISH: ->CERR IF INTEGER(NP)&16_6000 = 0 I = LOC WHILE INTEGER(NP)&16_4000 # 0 CYCLE IF INTEGER(NP)&16_2000 # 0 START; !IF AFTER ELSE SET LAB(I) finish ELSE START SET LAB(LOC) I = VAL+1 FINISH REPEAT SET LAB(I) ->SEND WHILE: I = LOC; ATYPE = -1; CREG = -1 GET COND; QUEUE(-13); ASSEMBLE NEST(I); NEST(1) ->SEND CYCLE: NEST(LOC); NEST(1) ->SEND REPEAT: ->CERR IF INTEGER(NP) # 1 QUEUE(LOCTYPE); QUEUE(INTEGER(NP+1)) NP = NP+2 QUEUE(-26); !'JUMP' FLAG = -1 ->CONDQ CERR: FAULT('C') ->LEND SEND: SET LAB(LOC) IF INTEGER(NP)&16_1000 # 0 ->LEND IF SYM = NL ->NEXT IF S(';') ERR:FSYM = 'F'; FAULTPOS = GETPOS-1 PRINTPOS = STARTPOS LEND: ->READ IF SKIP # 0 AND LIST&4 = 0 ->READ IF FSYM = ' ' AND CHARS = 0 AND C (PRINTPOS = 0 OR (MP#0 AND LIST&2=0)) PRINT LINE ->READ ASSIF: ASSCOND = ASSCOND<<1 ->LEND IF SKIP # 0 A1: GET COND; ASSEMBLE SKIP = ASSCOND IF COND # 0 PRINT LINE IF PRINTPOS # 0 ->LEND ASSELSE: IF SKIP = 0 START ->CERR IF ASSCOND&1 # 0 SKIP = ASSCOND finish ELSE START ->LEND IF SKIP # ASSCOND SKIP = 0 ->A1 IF TAGIF FINISH ASSCOND = ASSCOND+1 ->LEND ASSFIN: ->CERR IF ASSCOND = 1 ASSCOND = ASSCOND>>1 SKIP = 0 IF SKIP>>1 = ASSCOND ->LEND DEFINE: FAULT('C') IF NP # STORELIM I = TAG1 CYCLE ->ERR IF NOT (TAG AND S('=')) J = TAG1; K = TAG2 IF TAG START TYPE = UMASK; LOOKUP(0) IF TYPE&OPMASK # 0 START GET INST finish ELSE START PEND = -1; GET EXP FINISH finish ELSE GET EXP ASSEMBLE TAG1 = J; TAG2 = K IF I=DEF THEN LOOKUP(3) ELSE LOOKUP(2) EXIT UNLESS S(',') QLIM = QSTART REPEAT ->SEND NEWPAGE: DO NEWLINE WHILE LINES # 0 ->LEND LISTC: GET EXP; ASSEMBLE LIST = VAL ->SEND TEMP: I = 0 IF SYM # NL START CYCLE GET EXP FAULT('I') IF TYPE # REG I = I!1<<VAL EXIT UNLESS S(',') REPEAT FINISH TEMPS = I SET ACC ->SEND LOCC: I = TAG1 GET EXP; ASSEMBLE IF TYPE&16_FF9F = 0 START LOCTYPE = TYPE&RELMASK+MEMMASK; LOC = VAL PUT WORD(VAL-1) AND CONTROL=16_30 IF PASS > 0 finish ELSE FAULT('I') ->SEND SAVC: GET EXP; ASSEMBLE SAVE = VAL ->SEND MACDEF: ->CERR IF MP # 0 ->ERR IF NOT TAG J = TAG1; K = TAG2 I = GETPOS-1 IF SYM # NL START CYCLE ->ERR IF NOT TAG SCAN ARG EXIT IF NOT S(',') REPEAT FINISH ->ERR IF SYM # NL TAG1 = J; TAG2 = K TYPE = MACRO; VAL = I LOOKUP(3) CYCLE PRINT LINE EXIT IF S('$') AND TAG AND TAG1 = END STARTPOS = PUTPOS STARTPOS = PSEUDOLIM+1 IF PSEUDOLIM # 0 READ LINE REPEAT PUTPOS = STARTPOS; PUT CHAR(0) STARTPOS = PUTPOS MACLIM = STARTPOS ->LEND ROUTINE BNEST BP = BP+4; !!%MONITOR 23 %IF BP-NP >= 0 INTEGER(BP-3) = SAVE; INTEGER(BP-2) = TEMPS INTEGER(BP-1) = MACLIM; INTEGER(BP) = DEFMIN END BEGIN: BNEST ->NEWPAGE IF SYM # NL ->LEND BEND: FAULT('C') IF NP # STORELIM OR MP # 0 MP = 0; NP = STORELIM IF BP # LABLIM START SAVE = INTEGER(BP-3); TEMPS = INTEGER(BP-2) MACLIM = INTEGER(BP-1); STARTPOS = MACLIM DEFMIN = INTEGER(BP) SET ACC BP = BP-4 ->LEND IF BP # LABLIM FINISH CLOSE INPUT; SELECT INPUT(MAIN) BNEST LIST = 5 PASS = PASS+1 ->DO PASS IF PASS # 2 PUT WORD(CHECK!!16_0100); CONTROL = 16_30 PUT WORD(16_0100) SELECT OUTPUT(BIN); PRINT CH(16_60); SELECT OUTPUT(LIS) FAULT('$') PRINT LOC; PRINT LINE LINES = 60 IF OUTDEV = 1 DO NEWLINE WHILE LINES # 0 ENDOFPROGRAM