!** * * * * * ** ******* ** ** ***** * * * !** ** ** * * ** ** ** ** ** ** ** * * ** ** !** *** *** ** ** *** ** ** ** ** ** * * *** *** !** ** * ** **** ** * ** ***** ** ** ***** ** ** ** * ** !** ** ** ** ** *** ** ** * ** ** ******* ** ** !** ** ** ** ** ** ** *** *** ** ** ** ** ** ** !** ** ** ** ** ** ******* * * ***** ** ** ** ** %ENDOFLIST %CONTROL X'8000' %CONSTSHORTINTEGERARRAY SMAIN(1: 150) = %C 1, 0, 4, 8, 12, 15, 19, 25, 30, 35, 39, 43, 47, 50, 54, 58, 63, 69, 74, 79, 84, 88, 92, 96, 100, 104, 108, 112, 116, 121, 125, 128, 129, 133, 0, 135, 138, 0, 141, 144, 0, 148, 150, 0, 152, 154, 0, 156, 160, 0, 162, 167, 0, 169, 0, 172, 177, 0, 179, 182, 0, 184, 187, 190, 193, 196, 199, 0, 202, 207, 0, 209, 211, 0, 213, 215, 0, 217, 220, 223, 0, 226, 228, 0, 230, 234, 235, 238, 239, 243, 0, 245, 251, 255, 0, 258, 262, 266, 273, 0, 275, 0, 278, 281, 0, 283, 286, 289, 292, 0, 295, 299, 302, 305, 308, 311, 0, 313, 318, 0, 320, 323, 326, 0, 329, 335, 0, 337, 0, 343, 348, 0, 350, 353, 356, 359, 362, 365, 368, 0, 371, 373, 376, 0, 378, 381, 384, 387, 390, 0 %CONSTSHORTINTEGERARRAY SSUB(2: 392) = %C 4098,-32768, 0, 1, 8193, 4167, 0, 10, 8193, 4167, 0, 12, 8195, 0, 15, 8196, 4134, 0, 21, 8198, 4187, 4164, 4170, 0, 25, 8199, 4149, 4151, 0, 27, 8201, 4131, 4164, 0, 29, 8203, 4170, 0, 34, 8204, 4137, 0, 41, 8205, 4137, 0, 49, 8206, 0, 58, 8207, 4128, 0, 65, 8208, 4143, 0, 71, 8209, 4140, 4146, 0, 8194, 4131, 4177, 4236, 12288, 0, 8197, 4216, 20481, 4220, 0, 76, 8200, 16385, 4180, 0, 81, 8202, 4223, 4225, 0, 88, 8210, 12288, 0, 96, 8210, 8192, 0, 101, 8210, 8198, 0, 107, 8210, 8199, 0, 113, 8210, 8196, 0, 119, 8210, 8197, 0, 124, 130, 8213, 0, 134, 8215, 4240, 0, 140, 8216, 16385, 8192, 0, 143, 8217, 4170, 0, 150, 8218, 4170, 0, 8193, 4131, 4164, 0, 8192, 0, 8192, 4187, 0, 8193, 156, 0, 160, 8192, 0, 164, 8193, 4170, 0, 20481, 0, 8192, 0, 12288, 0, 8192, 0, 8193, 12288, 4146, 0, 8192, 0, 167, 8193, 12288, 4146, 0, 8192, 0, 4131, 4154, 0, 167, 8193, 4149, 4151, 0, 8192, 0, 4157, 12288, 0, 8192, 0, 169, 8193, 0, 171, 8194, 0, 174, 8195, 0, 177, 8196, 0, 180, 8197, 0, 182, 8198, 0, 167, 8193, 4131, 4164, 0, 8192, 0, 12288, 0, 8192, 0, 4173, 0, 8192, 0, 184, 8193, 0, 188, 8194, 0, 8195, 16384, 0, 192, 0, 169, 0, 195, 12288, 4182, 197, 0, 167, 12288, 4182, 0, 10, 8193, 12288, 0, 8192, 0, 199, 8192, 16385, 4184, 201, 0, 8193, 16385, 4191, 0, 8194, 4206, 0, 203, 8193, 4228, 0, 27, 8194, 12288, 0, 180, 8195, 12288, 10, 12288, 182, 0, 8192, 0, 16385, 4198, 0, 203, 4228, 0, 8192, 0, 205, 8201, 0, 209, 8202, 0, 212, 8203, 0, 215, 8204, 0, 8192, 4196, 4213, 0, 218, 8202, 0, 223, 8203, 0, 232, 8204, 0, 241, 8201, 0, 4201, 0, 180, 8193, 12288, 182, 0, 8192, 0, 250, 8195, 0, 124, 8196, 0, 254, 8197, 0, 265, 8193, 4216, 20480, 4220, 0, 8192, 0, 16384, 169, 16385, 4191, 4213, 0, 167, 8193, 4223, 4225, 0, 8192, 0, 269, 8210, 0, 271, 8211, 0, 273, 8213, 0, 276, 8214, 0, 279, 8218, 0, 282, 8219, 0, 286, 8223, 0, 293, 0, 295, 8193, 0, 8192, 0, 297, 8208, 0, 301, 8202, 0, 305, 8200, 0, 309, 8194, 0, 12288, 0 %CONSTBYTEINTEGERARRAY SLITERAL(1: 312) = %C 8, 99, 111, 110, 116, 105, 110, 117, 101, 1, 58, 2, 103, 111, 5, 116, 114, 97, 99, 101, 3, 109, 97, 112, 1, 63, 1, 35, 4, 100, 117, 109, 112, 6, 105, 103, 110, 111, 114, 101, 7, 114, 101, 112, 108, 97, 99, 101, 8, 101, 110, 100, 111, 102, 115, 105, 109, 6, 99, 97, 110, 99, 101, 108, 5, 98, 114, 101, 97, 107, 4, 102, 114, 101, 101, 4, 116, 114, 101, 103, 6, 100, 101, 102, 105, 110, 101, 7, 99, 111, 110, 116, 114, 111, 108, 4, 102, 117, 108, 108, 5, 113, 117, 105, 101, 116, 5, 110, 97, 109, 101, 115, 5, 116, 114, 97, 112, 115, 4, 116, 105, 109, 101, 5, 99, 108, 101, 97, 114, 3, 98, 117, 115, 5, 114, 97, 100, 105, 120, 2, 45, 62, 6, 100, 101, 99, 111, 100, 101, 5, 105, 110, 112, 117, 116, 3, 66, 85, 83, 3, 111, 102, 102, 2, 111, 110, 1, 44, 1, 61, 2, 92, 61, 2, 62, 61, 2, 60, 61, 1, 60, 1, 62, 3, 46, 84, 84, 3, 46, 76, 80, 2, 60, 45, 1, 40, 1, 41, 1, 91, 1, 93, 1, 95, 3, 79, 86, 70, 2, 68, 90, 2, 68, 80, 2, 68, 78, 4, 90, 69, 82, 79, 8, 80, 79, 83, 73, 84, 73, 86, 69, 8, 78, 69, 71, 65, 84, 73, 86, 69, 8, 79, 86, 69, 82, 70, 76, 79, 87, 3, 115, 101, 116, 10, 99, 111, 109, 112, 108, 101, 109, 101, 110, 116, 3, 97, 110, 100, 1, 65, 1, 66, 2, 75, 70, 2, 80, 70, 2, 73, 78, 3, 79, 85, 84, 6, 79, 86, 69, 82, 85, 78, 1, 43, 1, 45, 3, 104, 101, 120, 3, 100, 101, 99, 3, 111, 99, 116, 3, 98, 105, 110 %LIST %CONSTSTRING (31) VERSION = ' SAM : VERSION 4.1' ! EXTERNAL SPECS %EXTERNALREALFNSPEC CPUTIME %EXTERNALROUTINESPEC DESTROY(%STRING (63) K) %EXTERNALROUTINESPEC PROMPT(%STRING (15) S) %EXTERNALROUTINESPEC DEFINE(%STRING (63) X) %EXTERNALINTEGERFNSPEC TESTINT(%INTEGER C, %STRING (15) X) %EXTERNALROUTINESPEC MOVE(%INTEGER LENGTH, FROM, TO) %SYSTEMROUTINESPEC CLEARUSE(%STRING (15) S, %INTEGERNAME FLAG) %SYSTEMROUTINESPEC OUTFILE(%STRING (15) S, %C %INTEGER LENGTH, MAXBYTES, PROTECTION, %C %INTEGERNAME CONAD, FLAG) ! RECORDFORMATS %RECORDFORMAT HEADERFM( %C %INTEGER IDEN, USEAGE, NNAMES, NAMES, TEXT, CODE, CONSTANTS, %C OLD FILE, TXTLNG, STARTAD, EXTERNS, TABS) %RECORDFORMAT TABFM(%SHORTINTEGERARRAY W(0 : 7)) %RECORDFORMAT EXTERNFM(%BYTEINTEGER FROM, FBITS, TO, TOBITS) %RECORDFORMAT SYSHEADFM(%INTEGER SIZE, HEADSIZE, MAX, LD, %C EXTRA, FOR, SYSTEM, USE) %RECORDFORMAT OLDCODEFM(%BYTEINTEGER CODE, NAME, OPRN, MODULE, %C %SHORTINTEGER ADDR, STAT) %RECORDFORMAT CODEFM(%BYTEINTEGER CODE, NAME, OPRN, MODULE, %C %SHORTINTEGER ADDR, %SHORTINTEGERARRAY PC(0 : 1)) %RECORDFORMAT TAGFM(%INTEGER MASTER, %SHORTINTEGER TYPE, %C %BYTEINTEGER USED, BITS, %INTEGER USE, DEFN, SIZE, WHERE) %RECORDFORMAT NAMEFM(%STRINGNAME TEXT, %RECORD TAGS(TAGFM)) %RECORDFORMAT IOBUFFM(%BYTEINTEGER OWNER, TYPE, %C %SHORTINTEGER PT, SYMS, %BYTEINTEGERARRAY TEXT(1 : 64)) %RECORDFORMAT MODFM(%SHORTINTEGER A, B, F1, F2, F3, F4, FLAG) %RECORDFORMAT MEMODFM(%SHORTINTEGER MEMADDR, LIMIT, %C %SHORTINTEGERARRAYNAME STORE) %RECORDFORMAT RTFM(%INTEGER RA, LASTRT,NAME) %RECORDFORMAT CONDFM(%SHORTINTEGERNAME W, %C %SHORTINTEGER TEST, COUNT, %C %BYTEINTEGER COND, FLAG, FIRED, SET, %RECORD DESC(NAMEFM)) %RECORDFORMAT BUSFM(%SHORTINTEGER BUSREG, OVF, DZ, DN, DP) %RECORDFORMAT TREG LIST FM(%BYTEINTEGERARRAY BIT(0 : 15)) ! EXTERNAL ARRAYS CONTAINING PHRASE STRUCTURE ! CONSTS %CONSTBYTEINTEGERARRAY Q(0 : 40) = %C 0,0,1,1,1,0,1,1,0,0,1,1,1,0(5),1,1,0,1,1,1,1,1,1,1,1,1, 1,1,0(9) %CONSTSHORTINTEGERARRAY MTYPE(0 : 40) = %C %C 0,1,14,13,12,7,11,10,0,3,5,4, 6,9,0(10),12,2,0(15) %CONSTBYTEINTEGERARRAY DEST(0 : 40) = %C %C 0,0,0,1,0,0,1,1,0,1, 1,1,1,1,0,0,0,0,1,1, 0,1,1,1,1,1,1,1,0(13) %CONSTBYTEINTEGERARRAY MODTY(0 : 40) = %C %C 0,1,1,2,2,2,1,1,0,1,1,1,1,2,0(11),1,0,0,0(13) %CONSTINTEGER MAX NAMES = 100; ! MAX NUMBER OF NAMES %CONSTINTEGER MAX TEXT = 600; ! MAX LENGTH OF TEXT ARRAY %CONSTINTEGER EXTERNAL LENGTH = 100; ! MAX LENGTH FOR EXTERNAL EVENT ARRAY %CONSTSTRING (7) WORK FILE = 'SS#WORK' %CONSTSTRING (8) DATA BUS = 'DATA BUS' %CONSTSTRING (31) %ARRAY MODNAMES(0 : 40) = %C '','%GPA','%FLAG','%MEMORY','%SPM','%CGEN','%BREG', '%TREG','8-WAY BRANCH','%GPINT','%ININT','%OUTINT', '%SINT','%ROM','PROGRAM LABEL','%ROUTINE','%MACRO', '%BREAKPOINT','%GPA ''A'' REG','%GPA ''B'' REG', '%MODULE','%SINT KB FLAG','%SINT PUNCH FLAG', 'REGISTER','%SPM REG','%BUS','%GPINT INPUT REG', '%GPINT OUTPUT REG','SWITCH','DATA SWITCH','LIGHT', '%SINT OVERUN FLAG','%REGFORMAT',''(8) %CONSTSTRING (3) %ARRAY BUSFLNM(9 : 12) = %C 'OVF','DZ','DP','DN'; ! BUS FLAG NAMES %CONSTSTRING (6) %ARRAY WHUN(0 : 1) = %C 'WHILE ','UNTIL '; ! %WAIT MESSAGES %CONSTSTRING (4) %ARRAY EXTENSION(0 : 40) = %C ''(18),'_A','_B','','_KF','_PF',''(3), '_IN','_OUT',''(3),'_OVR',''(9); ! NAME EXTENSION %CONSTSTRING (2) %ARRAY OP(1 : 6) = %C '=','#','>=','<=','<','>'; ! COMPARATORS ! OWNS %OWNRECORD DUMMY NAME(NAMEFM) %OWNINTEGER RADIX = 16 %OWNSTRING (63) OBJECT FILE = 'SS#ARTH' %ROUTINE CONNEKT(%STRING (17) FILE, %INTEGERNAME AD, FLAG) %SYSTEMROUTINESPEC CONNECT(%STRING (15) S, %C %INTEGER ACCESS, MAXBYTES, PROTECTION, %C %RECORDNAME R, %INTEGERNAME FLAG) %RECORDFORMAT FINFO(%INTEGER CONAD, FILESIZE, %C %BYTEINTEGER DUM1, DUM2, MODE, DUM3, DUM4, %C %STRING (6) DUM5, %SHORTINTEGER FILETYPE, DUM6, %C %INTEGER DATASTART, DATAEND, DUM7) %RECORD R(FINFO) %CONSTINTEGER READ UNSHARED = 2 CONNECT(FILE,READ UNSHARED,0,4,R,FLAG) AD = R_CONAD %IF FLAG = 0 %END ! SAM STARTS HERE %EXTERNALROUTINE SAM(%STRING (63) FILES) %INTEGER NNAMES, N, FLAG, TEXTPT, NAMEFAULT, NAME FLAG, BUFFERS, %C BLIST, TOT STATS, PC, TPC %INTEGER RC, BC, LP, RP, J, SM, PP, CONS, FAULTS, CONNECT, HEAD ADDR %SHORTINTEGER NMT, MT, MQ %BYTEINTEGER CONTROL %INTEGERARRAY REC(0 : 100); ! ANALYSIS RECORD ARRAY %BYTEINTEGERARRAY LINE(0 : 200); ! SOURCE LINE (MAPPED AS STRING 'SOURCE') %SHORTINTEGERARRAYFORMAT MEMODAFM(0 : 4095) %SHORTINTEGERARRAYFORMAT MUFM(0 : 21) %SHORTINTEGERARRAYFORMAT CONFM(0 : 50) %BYTEINTEGERARRAYFORMAT TXT1(0 : MAX TEXT) %RECORDARRAYFORMAT NAFM(1 : MAX NAMES)(NAMEFM) %RECORDARRAYFORMAT EXTARFM(1 : EXTERNAL LENGTH)(EXTERNFM) %RECORDARRAYFORMAT CFM(0 : 2000)(OLDCODEFM) %RECORDARRAYFORMAT TBAFM(1 : 50)(TABFM) %RECORDNAME HEADER(HEADERFM) %RECORDNAME SYS HEADER(SYS HEAD FM) %STRINGNAME CURRENT, SOURCE %RECORDNAME V1, V2(TAGFM) %RECORDNAME V(NAMEFM) %SHORTINTEGERARRAYNAME CONSTANTS %SHORTINTEGERARRAYNAME MODUSEAGE %BYTEINTEGERARRAYNAME TEXT %RECORDARRAYNAME NAME(NAMEFM) %RECORDARRAYNAME OBJECT(OLDCODEFM) %RECORDARRAYNAME TABLES(TABFM) %RECORDARRAYNAME EXTERNALS(EXTERNFM) %STRING (63) INPUT %REAL START TIME %ROUTINE PSYM(%INTEGER N) ! PRINTS OUT NUMBERS AS SYMBOLS %SHORTROUTINE %IF N > 9 %THEN N = N+'A'-10 %ELSE N = N+'0' PRINTSYMBOL(N) %END %ROUTINE NUMBER(%INTEGER N, PLACES) ! 'WRITE' ROUTINE FOR CURRENT BASE %SHORTROUTINE %ROUTINESPEC PUT(%INTEGER N) %INTEGER SIGN %IF N < 0 %AND RADIX = 10 %THEN SIGN = '-' %AND N = -N %C %ELSE %START ! HANDLE NEGATIVE NUMBERS SIGN = ' ' N = N&X'FFFF' %FINISH PUT(N) %ROUTINE PUT(%INTEGER N) ! OUTPUT NUMBER IN BASE 'RADIX' WITH 'PLACES' PLACES %SHORTROUTINE PLACES = PLACES-1 %AND PUT(N//RADIX) %IF N >= RADIX SPACES(PLACES) %IF PLACES > 0 PLACES = 0 PRINTSYMBOL(SIGN) %IF SIGN # 0; SIGN = 0 PSYM(N-N//RADIX*RADIX) %END %END %ROUTINE DISPLAY %INTEGER I %RECORDNAME V(NAMEFM) %STRING (8) TEXT I = NNAMES %WHILE I # 0 %CYCLE V == NAME(I) TEXT <- V_TEXT; ! TRUNCATE NAME NEWLINE PRINTSTRING(TEXT) SPACES(10-LENGTH(TEXT)) PRINTSTRING(MODNAMES(V_TAGS_TYPE)) I = I-1 %REPEAT NEWLINE %END %ROUTINE SDISPLAY ! PRINTS OUT ALL THE TAGS STORED FOR EACH NAMED ELEMENT ! IN THE SYSTEM. %NAMES OR %CONTROL 7 INITIATES THIS FACILITY %SHORTROUTINE %INTEGER J %RECORDNAME V(NAMEFM) %STRING (8) TEXT J = NNAMES %WHILE J > 0 %CYCLE V == NAME(J) TEXT <- V_TEXT; ! TRUNCATE NAME TO 8 CHARACTERS PRINTSTRING(TEXT) SPACES(10-LENGTH(TEXT)) NUMBER(V_TAGS_MASTER,5) NUMBER(V_TAGS_TYPE,3) NUMBER(V_TAGS_USED,3) NUMBER(V_TAGS_BITS,3) NUMBER(V_TAGS_USE,3) NUMBER(V_TAGS_DEFN,3) NUMBER(V_TAGS_SIZE,3) NUMBER(V_TAGS_WHERE,3) NEWLINE J = J-1 %REPEAT %END %ROUTINE FAULT(%INTEGER NUMBER) ! PRINT OUT FAULT MESSAGES %SHORTROUTINE %SWITCH FT(0 : 8) PRINTSTRING( '? ') -> FT(NUMBER) FT(0): -> OUT %IF NAMEFLAG # SM; ! SYNTAX FAULT OR COMMAND ERROR PRINTSTRING( ' NAME '); ! NAME FAULT SM = NAMEFAULT PRINTSTRING(SOURCE) SPACES(SM+10) PRINTSTRING ('! ') -> OUT FT(1): PRINTSTRING('ILLEGAL SUBNAME'); -> OUT FT(2): PRINTSTRING( 'ILLEGAL INDEX'); -> OUT FT(3): PRINTSTRING( 'ILLEGAL EXTRACTION'); -> OUT FT(4): PRINTSTRING( 'INVALID ADDRESS'); -> OUT FT(5): PRINTSTRING( 'NOT A BREAKPOINT'); -> BODY FT(6): PRINTSTRING( 'NOT AN ADDRESS'); -> BODY FT(7): PRINTSTRING( 'DUPLICATE BREAKPOINT ON LINE'); -> OUT FT(8): PRINTSTRING( 'TOO MANY CONDITIONAL BREAKPOINTS'); -> OUT BODY: SPACE PRINTSTRING(CURRENT) OUT: NEWLINE FAULTS = FAULTS+1 %END ! *********************************************************************** ! THE FOLLOWING ROUTINES ARE DEALT WITH IN PDP16S,THE SOURCE TEXT ! FOR ARTHUR. %ENDOFLIST %INTEGERFN LETTER(%INTEGER N) %SHORTROUTINE %RESULT = 1 %IF 'A' <= N <= 'Z' %RESULT = 0 %END %ROUTINE RECONSTRUCT(%INTEGER PP) %SHORTROUTINE %INTEGER S LP = 0 PROMPT(' :') %IF PP = 0 CONT1: %CYCLE READSYMBOL(S) 2: -> CONT1 %IF S = ' ' %IF S = '%' %START %CYCLE READSYMBOL(S) -> 2 %UNLESS LETTER(S) = 1 LP = LP+1 LINE(LP) = S+32 %REPEAT %FINISH %IF S = NL %START NEWL: -> CONT1 %IF LP = 0 LP = LP+1 LINE(LP) = NL LINE(0) = LP %EXIT %FINISH %IF S = '$' %START; ! COMMENT MARKER READSYMBOL(S) %UNTIL S = NL -> NEWL %FINISH %ELSE %START LP = LP+1 LINE(LP) = S %FINISH %REPEAT %END %INTEGERFN DIGIT(%INTEGER N) %SHORTROUTINE %RESULT = 1 %IF '0' <= N <= '9' %RESULT = 0 %END %INTEGERFN NAME FOUND(%BYTEINTEGER OLD) %SHORTROUTINE %INTEGER P, R, L SAVE %RESULT = 0 %UNLESS LETTER(LINE(LP)) = 1 L SAVE = LP P = TEXTPT %UNTIL (LETTER(LINE(LP)) = 0 %AND DIGIT(LINE(LP)) = 0) %CYCLE P = P+1 TEXT(P) = LINE(LP) LP = LP+1 %REPEAT TEXT(TEXTPT) = P-TEXTPT R = NNAMES CURRENT == STRING(ADDR(TEXT(TEXTPT))) %WHILE R > 0 %CYCLE %EXIT %IF NAME(R)_TEXT = CURRENT R = R-1 %REPEAT %IF R = 0 %START %IF OLD # 0 %START 1: NAMEFLAG = LP NAMEFAULT = L SAVE %RESULT = 0 %FINISH R = NNAMES+1 NNAMES = R NAME(NNAMES)_TEXT == CURRENT TEXTPT = P+1 %FINISH %ELSE %START -> 1 %IF OLD # 0 %AND NAME(R)_TAGS_TYPE = 0 %FINISH RP = RP+1 REC(RP) = R %RESULT = 1 %END %INTEGERFN NEXT LINE %RESULT = LINE(LP) %END %INTEGERFN CONSTANT FOUND(%INTEGERFNNAME NEXT) %SHORTROUTINE %BYTEINTEGER PERMIT %SPEC NEXT %BYTEINTEGER SIGN %INTEGER F, S, BASE, N SIGN <- LP S = NEXT %UNTIL LP # 0 %OR (' ' # S # NL) %IF (S = '+' %OR S = '-') %AND SIGN = 0 %START SIGN = S; S = NEXT %FINISH %ELSE SIGN = 0 F = 0 PERMIT = 0; ! NO CONSTANT FOUND YET BASE = RADIX N = 0 %IF S = '''' %START LP = LP+1 S = NEXT LP = LP+1 N = S ! TRANSPARENT DATA S = NEXT LP = LP+1 PERMIT = 1 %IF S = '''' %FINISH %ELSE %START %CYCLE %IF DIGIT(S) = 1 %THEN S = S-'0' %ELSE %START -> 3 %UNLESS LETTER(S) = 1 S = S-'A'+10 %FINISH %IF S < BASE %START PERMIT = 1; ! NUMBER FOUND N = N*BASE+S LP = LP+1 %FINISH %ELSE %START 3: %EXIT %IF S # '_' %RESULT = 0 %IF F = LP %EXIT %IF F # 0 LP = LP+1 BASE = N N = 0 F = LP %FINISH S = NEXT %REPEAT %FINISH %RESULT = 0 %IF PERMIT = 0 SIGN = 0 %IF 0 # N>>16 # X'FFFF' N = -N %IF SIGN = '-' RP = RP+1 REC(RP) = N %RESULT = 1 %END %INTEGERFN PARSE(%INTEGER ENTRY) %SHORTROUTINE %INTEGER SP, S, TRP, TLP, P, N, ON %SWITCH BIP(0 : 15) TRP = RP TLP = LP FAILURE: SM = LP %IF LP > SM RP = TRP LP = TLP ENTRY = ENTRY+1 SP = SMAIN(ENTRY) %RESULT = 0 %IF SP = 0 SUCCESS: SP = SP+1 S = SSUB(SP) %RESULT = 1 %IF S = 0 -> BIP(S>>12&15) BIP(1): ! SUB-PHRASE -> SUCCESS %IF PARSE(S&X'FFF') = 1 -> FAILURE BIP(0): ! LITERAL P = SLITERAL(S) %CYCLE P = S+1,1,S+P -> FAILURE %IF LINE(LP) # SLITERAL(P) LP = LP+1 %REPEAT -> SUCCESS BIP(4): ! [NAME] -> SUCCESS %IF NAME FOUND(S&7) = 1 -> FAILURE BIP(3): ! [CONSTANT] -> SUCCESS %IF CONSTANT FOUND(NEXT LINE) = 1 -> FAILURE BIP(5): ! [NAMELIST] RP = RP+1 P = RP ON = S&7 N = 0 -> FAILURE %UNLESS NAME FOUND(ON) = 1 %CYCLE N = N+1 %EXIT %IF LINE(LP) # ',' LP = LP+1 LP = LP-1 %AND %EXIT %UNLESS NAME FOUND(ON) = 1 %REPEAT REC(P) = N -> SUCCESS BIP(8): ! [SEPARATOR] -> FAILURE %UNLESS LINE(LP) = NL RP = RP+1 REC(RP) = -1 -> SUCCESS BIP(2): ! <> RP = RP+1 REC(RP) = S&X'FFF' -> SUCCESS %END %LIST ! *********************************************************************** ! ******** START OF SIMULATION ******* START TIME = CPUTIME INPUT = '' %UNLESS FILES -> FILES.(',').INPUT %IF INPUT = '' %THEN INPUT = '.TT' %ELSE INPUT = INPUT.'+.TT' DEFINE('ST74,'.INPUT) SELECTINPUT(74) OBJECT FILE = FILES %UNLESS FILES = '' CONNEKT(OBJECTFILE,CONNECT,FLAG) %IF FLAG # 0 %START; ! CONNECT ERROR . ABORT RUN. PRINTSTRING('CANNOT CONNECT '.OBJECT FILE) NUMBER(FLAG,4) NEWLINES(2) %RETURN %FINISH SYS HEADER == RECORD(CONNECT); ! SYSTEM HEADER OF FILE HEADER == RECORD(CONNECT+32); ! ARTHUR HEADER OF FILE %IF HEADER_IDEN # M'ARTH' %START; ! FILE NOT AN ARTHUR OBJECT FILE. ABORT. PRINTSTRING(OBJECT FILE.' IS NOT AN ARTHUR OBJECT FILE ! ') %RETURN %FINISH PP = SYS HEADER_SIZE %IF PP = 0 %START; ! FILE IS FAULTY !!!! PRINTSTRING(OBJECT FILE.' FAULTY ') PROMPT('CONTINUE? '); ! ALLOW USER TO PROCEED AT HIS PERIL! ! ! ! ! READSYMBOL(J); ! GET USER'S ANSWER %RETURN %IF J # 'Y'; ! RETURN IF NOT YES READSYMBOL(J) %WHILE J # NL; ! SKIP REST OF LINE PP = 4096*16; ! MAX SIZE %FINISH DUMMY NAME = 0; ! SET UP FAKE TAGS FOR BUS DUMMY NAME_TEXT == DATA BUS; ! NAME DUMMY NAME_TAGS_TYPE = 25; ! TYPE ! NOW COPY ARTHUR OBJECT FILE SO AS TO BE ABLE TO MODIFY IT %BEGIN %CONSTINTEGER ONE SEGMENT = 65536 %INTEGER WORK AD OUTFILE(WORKFILE,ONE SEGMENT,ONE SEGMENT,0,WORK AD,FLAG) %IF FLAG # 0 %START PRINTSTRING('CREATE '.WORK FILE.' FAILS ') %MONITORSTOP %FINISH MOVE(PP,CONNECT,WORKAD); ! PERFORM COPY CONNECT = WORK AD; ! ADJUST CONNECT ADDRESS TO POINT TO NEW FILE. SYSHEADER == RECORD(CONNECT); ! REDIRECT HEADER POINTERS TO NEW FILE HEADER == RECORD(CONNECT+32) CLEARUSE(OBJECT FILE,FLAG); ! DISCONNECT FILE %END SOURCE == STRING(ADDR(LINE(0))); ! MAP 'SOURCE' ONTO ARRAY 'LINE' NNAMES = HEADER_NNAMES; ! GET NU,BER OF NAMES DECLARED HEAD ADDR = ADDR(HEADER) NAME == ARRAY(HEADER_NAMES+HEAD ADDR,NAFM) ! NAME TAGS HEADER_IDEN = 0; ! CAN NOT BE USED AS OBJECT FILE %CYCLE J = 1,1,NNAMES ! ADJUST STRINGNAMES SO THAT THEY POINT TO CORRECT ADDRESSES NAME(J)_TEXT == STRING(ADDR(NAME(J)_TEXT)-HEADER_OLDFILE+ %C CONNECT) %REPEAT MODUSEAGE == ARRAY(HEADER_USEAGE+HEAD ADDR,MUFM) ! MODULE USEAGE TEXT == ARRAY(HEADER_TEXT+HEAD ADDR,TXT1) ! NAME TEXTS EXTERNALS == ARRAY(HEADER_EXTERNS+HEAD ADDR,EXTARFM) ! EXTERNAL EVENTS TABLES == ARRAY(HEADER_TABS+HEAD ADDR,TBAFM) ! 8-WAY BRANCHES & REGFORMATS OBJECT == ARRAY(HEADER_CODE+HEAD ADDR,CFM) ! OBJECT CODE CONSTANTS == ARRAY(HEADER_CONSTANTS+HEAD ADDR,CONFM) ! CONSTANTS PRINTSTRING(' '.VERSION.' '); ! IDENTIFY PROGRAM CONS = 0; ! CLEAR SYSTEM VARIABLES FAULTS = 0 TEXTPT = HEADER_TXTLNG; ! GET ADDRESSS OF NEXT FREE CELL IN TEXT ARRAY FLAG = 0 CONTROL = 0 ! SET UP MODULE COUNTS J = NNAMES NMT = 0; ! 'NON-MEMORY' MODULE TOTAL MT = 0; ! %MEMORY,%ROM,%SPM TOTALS MQ = 0; ! ACCUMULATE MEMORY SPACE NEEDED FOR MEMORIES ETC. RC = 0; ! ROUTINE COUNT BC = 0; ! BREAKPOINT COUNT BLIST = 0; BUFFERS = 0; ! BUFFER COUNT ! EVALUATE BOUNDS FOR DYNAMIC DECLARATIONS OF INNER BLOCK %WHILE J # 0 %CYCLE; ! ROUND ALL NAMES ! NO SPACE ASSIGNED FOR UNUSED NAMES (TASG_USED=0),NAMES DECLARED ! IN %DEFINE STATEMENTS(TAGS_MASTER # INDEX OF NAME), OR ! FOR NAMES NOT ASSOCIATED WITH MODULES (MODTY(TAGS_TYPE)=0) ! IF SPACE IS ASSIGNED THE INDEX TO IT IS ENTERED INTO ! TAGS_USED V1 == NAME(J)_TAGS %IF V1_USED # 0 %AND 9 <= V1_TYPE <= 12 %START ! NEEDS AN I/O BUFFER ASSIGNED : SINT ININT,OUTINT,GPINT BUFFERS = BUFFERS+1; ! INCR BUFFER COUNT BUFFERS = BUFFERS+1 %UNLESS 10 <= V1_TYPE <= 11 ! GPINT AND SINT NEED TWO BUFFERS V1_WHERE = BLIST; BLIST = J; ! CHAIN NAMES %FINISH RC = RC+1 %AND V1_USED = RC %AND -> CONT1 %IF V1_TYPE = 15 ! COUNT ROUTINES BC = BC+1 %AND V1_USED = BC %AND -> CONT1 %IF V1_TYPE = 17 ! COUNT BREAKPOINTS V1_TYPE = 0 %IF V1_USED = 0 ! ALL UNUSED NAMES HAVE NULL TYPE -> CONT1 %IF V1_USED = 0 %OR MODTY(V1_TYPE) = 0 %C %OR V1_MASTER # J ! DONT ALLOCATE SPACE(SEE ABOVE) %IF MODTY(V1_TYPE) = 1 %START; ! 'NON-MEMORY' MODULE NMT = NMT+1; ! INCR COUNT V1_USED = NMT; ! STORE INDEX %FINISH %ELSE %START; ! %MEMORY %ROM %SPM MT = MT+1; ! INCR COUNT V1_USED = MT; ! STORE INDEX ! ACCUMULATE MEMORY SPACE (INCLUDES SPM) %IF V1_TYPE = 4 %THEN MQ = MQ+16 %ELSE %START ! NOT AN SPM SO MUST BE A MEMORY OR ROM V1_SIZE = 1024 %IF V1_SIZE = 0; ! IF SIZE NOT SPECIFIED MAKE IT 1K MQ = MQ+V1_SIZE; ! TOTAL MEMORY SPACE NEEDED %FINISH %FINISH CONT1: J = J-1; ! DECR INDEX %REPEAT BUFFERS = 1 %IF BUFFERS = 0; ! DECLARE AT LEAST ONE OF ALL TYPES OF SPACE TO MT = 1 %AND MQ = 1 %IF MT = 0; ! PREVENT PROGRAM ERRORS BC = 1 %IF BC = 0 RC = 1 %IF RC = 0 NMT = 1 %IF NMT = 0 PC = (HEADER_CONSTANTS-HEADER_CODE)//8-2; ! SIZE CODE TPC = PC; ! TOTAL SIZE OF CODE ALONE TOTSTATS = OBJECT(PC)_STAT; ! LAST INSTRUCTION OF CODE PC = PC+TOT STATS; ! FOR BREAKPOINTS %BEGIN %INTEGER NK, LSBR, L, STATEMENT, NNPC, NPC, EN %SHORTINTEGER BCOUNT, CCOUNT %BYTEINTEGER STPFLAG, SINGLE SHOT, CONDBR, SAVED OVF %RECORD BUS1(BUSFM) %RECORDARRAY CODE(0 : PC)(CODEFM); ! ARRAY FOR NEW MODIFIED CODE %SHORTINTEGERARRAY STATPTRY(1 : TOT STATS) %SHORTINTEGERARRAY STR(1 : MQ) %RECORDNAME WORD, KWORD(CODEFM) %OWNINTEGER SINGLE STEPS COUNT %RECORDARRAY CONPT(0 : NNAMES)(CONDFM); ! CONDITIONAL BREAKS %RECORDARRAY MODS(0 : NMT)(MODFM); ! NON-MEMORY MODULES %RECORDARRAY MMODS(1 : MT)(MEMODFM); ! %MEMORY %ROM %SPM %RECORDARRAY RETAD(1 : RC)(RTFM); ! ROUTINES %RECORDARRAY BUFFER(1 : BUFFERS)(IOBUFFM);! IO BUFFERS %ROUTINE PRINTNAME(%RECORDNAME V) ! THIS ROUTINE PRINTS OUT THE NAME OF A MODULE ! EXTENDED AS THE TYPE REQUIRES FOLLOWED BY SPACES %SHORTROUTINE %RECORDSPEC V(NAMEFM) %STRING (8) TEXT, EXT %INTEGER I TEXT <- V_TEXT; ! TRUNCATE NAME PRINTSTRING(TEXT) I = LENGTH(TEXT) %IF V_TAGS_MASTER = 0 %START; ! DATA BUS %IF V_TAGS_DEFN # 0 %START; ! BUS FLAG WANTED PRINTSTRING(' '.BUSFLNM(V_TAGS_DEFN)) I = I+3 %FINISH %FINISH %ELSE %START %IF NAME(V_TAGS_MASTER)_TEXT = V_TEXT %START ! DONT PRINT AN EXTENSION IF NAME DECLARED IN A %DEFINE EXT = EXTENSION(V_TAGS_TYPE) PRINTSTRING(EXT) I = I+LENGTH(EXT) %FINISH %FINISH SPACES(14-I); ! GET SPACING RIGHT %END %ROUTINE CDISP ! THIS ROUTINE DISPLAYS THE STATUS OF CONDITIONAL BREAKPOINTS %SHORTROUTINE %RECORDNAME C(CONDFM) %INTEGER I NEWLINE %IF CCOUNT = 0 %C %THEN PRINTSTRING('NO CONDITIONAL BREAKS ') %ELSE %START %CYCLE I = 0,1,NNAMES C == CONPT(I) %IF C_FIRED # 0 %START; ! COND SET %IF I = 0 %THEN PRINTSTRING('BUS ') %ELSE %C PRINTNAME(C_DESC); ! PRINT NAME TRAP IS ON %IF C_COND = 0 %C %THEN PRINTSTRING('ON VALUE CHANGE') %ELSE %START ! VALUE CHANGE OR CONSTANT COMPARISON ? PRINTSTRING(OP(C_COND)); ! PRINT COMPARITOR NUMBER(C_TEST,1) %FINISH PRINTSTRING(' HELD FOR') %AND NUMBER(C_COUNT,1) %C %IF C_COUNT # 0 ! PRINT OUT HOLD COUNT IF ANY NEWLINE %FINISH %REPEAT %FINISH %END %ROUTINE BDISP ! THIS ROUTINE DISPLAYS THE STATUS OF BREAKPOINTS ! IN RESPONSE TO %TRAPS OR %CONTROL 4 %SHORTROUTINE %INTEGER I, J %RECORD WORD(CODEFM) NEWLINE %IF SINGLE SHOT # 0 %START PRINTSTRING('SINGLE SHOT MODE') %IF SINGLE STEPS COUNT # 0 %START PRINTSTRING(' HELD FOR ') NUMBER(SINGLE STEPS COUNT,1) %FINISH NEWLINE %FINISH %ELSE %START %IF BCOUNT = 0 %C %THEN PRINTSTRING('NO STATEMENT BREAKS ') %C %ELSE %START I = BCOUNT>>16 %CYCLE J = 1,1,BCOUNT&X'FFFF' PRINTSTRING('LINE') WORD = CODE(NPC+I) %AND I = I+1 %C %UNTIL WORD_CODE = 11 %OR I = TOTSTATS NUMBER(I-1,1); ! WRITE STATEMENT NUMBER %IF WORD_ADDR # 0 %START; ! WRITE HOLD COUNT IF ANY PRINTSTRING(' HELD FOR ') NUMBER(WORD_ADDR,1) %FINISH NEWLINE %REPEAT %FINISH %FINISH CDISP; ! SHOW COND TRAPS %END %ROUTINE FQUAL(%RECORDNAME V) ! THIS ROUTINE HANDLES NAME EXTENSIONS FOR LOCATION %SHORTROUTINE %RECORDSPEC V(NAMEFM) %INTEGER N, M %SHORTINTEGERNAME TYP %SWITCH FQ(0 : 3) TYP == V_TAGS_TYPE RP = RP+1; -> FQ(REC(RP)) FQ(1): ! '_' RP = RP+1; N = REC(RP) %IF (N < 20 %AND TYP # 1) %OR (23 > N > 20 %C %AND TYP # 12) %OR (N > 25 %AND TYP # 9) %START ! FAULT IF _A OR _B NOT ON A GPA NAME,_IN OR _OUT NOTON ! GPINT, _KF,_PF,_OVRUN NOT ON SINT FAULT(1); ! ILLEGAL SUBNAME %RETURN %FINISH TYP = N; ! INSERT TYPE %RETURN FQ(2): ! '#' RP = RP+1; N = REC(RP) %UNLESS TYP = 4 %AND 0 <= N <= 15 %START FAULT(2) V_TAGS_USED = 41 ! ILLEGAL INDEX, IF NOT SPM OR INDEX <0 OR >15 %FINISH %ELSE %START V_TAGS_BITS = N; ! INSERT INDEX VALUE TYP = 24; ! SPM REG TYPE %FINISH %RETURN FQ(3): ! N = REC(RP+1); M = REC(RP+2) RP = RP+2 N = 5 %UNLESS 6 <= TYP <= 7; ! FORCE ERROR IF NOT BREG OR TREG %IF N = 0 %START N = M>>2 FAULT(3) %UNLESS M&3 = 3 %AND 0 <= N <= 3 ! ILLEGAL EXTRACTION IF M# 3,7,11,15 %FINISH %ELSE %START FAULT(3) %UNLESS N = 8 %AND M = 15 ! ILLEGAL EXTRACTION IF NOT <8:15> N = 4 %FINISH V_TAGS_BITS = N+4; ! SET UP FLAG FOR EXTRACT THATS WANTED FQ(0): %END %ROUTINE FLAG NAME(%RECORDNAME V) %RECORDSPEC V(NAMEFM) ! THIS ROUTINE SET UPS PSEUDO TAGS FOR BUS FLAGS V = DUMMY NAME RP = RP+1 V_TAGS_DEFN = REC(RP); ! WHICH FLAG %END %ROUTINE LOCATION(%RECORDNAME V) %RECORDSPEC V(NAMEFM) RP = RP+1; NK = REC(RP) FLAGNAME(V) %AND %RETURN %IF NK = 2;! BUS FLAG WANTED RP = RP+1; V = NAME(REC(RP)) %IF NK = 0 %START; ! CONTENTS OF %MEMORY %ROM WANTED V_TAGS_BITS = 9; ! FLAG FOR 'CONTENTS' CURRENT == V_TEXT %AND FAULT(6) %C %IF 13 # V_TAGS_TYPE # 3 ! GIVE 'NOT AN ADDRESS' IF NAME IS NOT A %MEMORY OR %ROM RP = RP+1 %IF REC(RP) # 0 %START; ! [(NAME):(CONSTANT)] RP = RP+1 ! NOT CONSTNAT SO THAT LOC 0 CAN BE ADDRESSED ! AS TAGS_WHERE=0 MEANS NOT A DIRECT ADDRESS V_TAGS_WHERE = \REC(RP); ! GET CONSTANT %FINISH %ELSE V_TAGS_WHERE = 0 %FINISH %ELSE %START FQUAL(V); ! GET EXTENSION, IF ANY %FINISH %END %SHORTINTEGERMAP BUS FLAG(%INTEGER I) ! THIS MAPS THE BUS FLAGS %SHORTROUTINE %SWITCH FL(9 : 12) -> FL(I) FL(9): ! OVERFLOW %RESULT == BUS1_OVF FL(10): ! DZ %RESULT == BUS1_DZ FL(11): ! DP %RESULT == BUS1_DP FL(12): ! DN %RESULT == BUS1_DN %END %SHORTINTEGERMAP SET FLAG(%RECORDNAME FLAG, V) ! THID MAP RETURNS THE ADDRESS OF A LOCATION ! CONTAINING THE VALUE OF THE FLAG REQUESTED ! THIS _F1 IF THE VARIABLE IS A FLAG MODULE , BUT IF THE ! FLAG REQUESTED IS A BIT EXTRACT THE _FLAG FIELD HAS ! THE VALUE PLACED IN IT AND THE MAP POINTS TO IT ! THIS PRESERVES THE READ ONLY NATURE OF BIT EXTRACTS ! IN THE FACE OF ERRORS %SHORTROUTINE %RECORDSPEC V(NAMEFM) %RECORDSPEC FLAG(MODFM) %INTEGER X %RESULT == BUS FLAG(V_TAGS_DEFN) %C %IF V_TAGS_TYPE = 25 %AND V_TAGS_DEFN # 0 ! DZ,DN,DP,OVF WANTED %RESULT == FLAG_F1 %IF V_TAGS_BITS = 0; ! MODULE FLAG %IF V_TAGS_BITS = 1 %THEN X = FLAG_A %ELSE X = FLAG_B ! 'A' REG OR 'B' REG X = (X>>(V_TAGS_WHERE&15))&1; ! EXTRACT REQUIRED BIT FLAG_FLAG = X; ! STORE IN SPECIAL LOCATION %RESULT == FLAG_FLAG; ! MAP RESULT ONTO SPECIAL %END %INTEGERFN BREAKHERE ! THIS FUNCTION LOOKS FOR BREAKPOINTS ! RESULT =0 IF NO BREAK ! RESULT =1 IF STATEMENT BREAK ! RESULT =2 IF PROGRAM BREAK ! RESULT =3 IF TESTINT BREAK ! RESULT =4 IF CONDITIONAL BREAK %SHORTROUTINE %RESULT = 3 %IF TESTINT(0,'WAIT') # 0; ! USER HAS INTERRUPTED %RESULT = 0 %IF LSBR = STATEMENT; ! THIS STATEMENT ALREADY CHECKED %IF SINGLE SHOT # 0 %START; ! SINGLE SHOT ENABLED %RESULT = 1 %IF SINGLE STEPS COUNT <= 0 ! BREAK IF SINGLE SHOT NOT HELD BY REPEAT COUNT SINGLE STEPS COUNT = SINGLE STEPS COUNT-1 ! DECR HOLD COUNT %FINISH %RESULT = EN; ! FOR CONDITIONALS %END %INTEGERFN SETBREAK(%INTEGER J) %RECORDNAME V(NAMEFM) %RECORDNAME C(CONDFM) %SWITCH CND(0:6) C == CONPT(J) %RESULT = EN %IF CCOUNT = 0 %OR C_FIRED = 0 C_COUNT = C_COUNT-1 %AND -> CONT %IF C_COUNT # 0 ! DECR REPEAT COUNT IF ANY V == C_DESC ->CND(C_COND) CND(0): ! HAS VARIABLE CHANGED? C_W = SET FLAG(MODS(V_TAGS_USED),V) %IF C_FLAG # 0 ! GET VALUE IF BIT EXTRACT -> CONT %IF C_W = C_TEST;! VALUE HAS NOT CHANGED C_TEST = C_W; ! TO KEEP UP TO DATE! PRINTNAME(V); ! WRITE OUT VARIABLE NAME PRINTSTRING('HAS CHANGED VALUE TO ') %IF V_TAGS_TYPE = 2 %OR (V_TAGS_TYPE = 25 %C %AND V_TAGS_DEFN # 0) %START ! SET OR CLEAR FOR A FLAG OR BUS FLAG %IF C_W # 0 %THEN PRINTSTRING('SET') %C %ELSE PRINTSTRING('CLEAR') %FINISH %ELSE NUMBER(C_W,1); ! ELSE WRITE OUT VALUE TO CURRENT BASE -> SET CND(1): ! = -> BRK %IF C_W = C_TEST -> CONT CND(2): ! # -> BRK %IF C_W # C_TEST -> CONT CND(3): ! >= -> BRK %IF C_W >= C_TEST -> CONT CND(4): ! <= -> BRK %IF C_W <= C_TEST -> CONT CND(5): ! < -> BRK %IF C_W < C_TEST -> CONT CND(6): ! > -> CONT %IF C_W <= C_TEST BRK: PRINTNAME(V); ! WRITE OUT VARIABLE NAME PRINTSTRING(OP(C_COND)); ! CONDITION SATISFIED NUMBER(C_TEST,1); ! WRITE VALUE TEST WAS AGAINST SET: NEWLINE C_SET = 1 CONDBR = 1 %RESULT = 4 CONT: %RESULT = EN %END %ROUTINE COMPILE BLOCK %ROUTINESPEC SET BUS %SHORTINTEGERNAME STP %RECORDNAME TEMP NAME(NAMEFM) %ROUTINESPEC MONITOR(%INTEGER M, %STRING (127) ETXT) %OWNINTEGER GOFLAG %OWNBYTEINTEGER SINT MODE = 0 %OWNSTRING (14) INDEV = 'INPUT' %OWNSTRING (16) %ARRAY OUT(1 : 3) = %C %C '.TT','.LP','' %CONSTBYTEINTEGERARRAY PERMIT(0 : 36) = %C 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0; ! IS TYPE VALID? %INTEGER T, N, J, MI, FLG, SELECT, INDEX %INTEGER K, LAST, RESULT, CRRNT, LAST RT, TIME %SHORTINTEGER SHRT %BYTEINTEGER TRACE, MGPA %RECORD STORE WORD(CODEFM) %RECORD DUM COND(CONDFM) %RECORD DV(NAMEFM) %RECORD DUMMY BUF(IOBUFFM) %RECORDNAME NP, V(NAMEFM) %RECORDNAME RT(RTFM) %RECORDNAME C(CONDFM) %RECORDNAME BUF(IOBUFFM) %SHORTINTEGERARRAYNAME DUM1 %INTEGERFNSPEC SYMBOL(%INTEGER BUFNO) %ROUTINESPEC PRINT(%INTEGER BUFNO, SYM) %INTEGERFNSPEC GET TREG(%INTEGER TABLE ADDR, VALUE) %SHORTINTEGERMAPSPEC SMAP(%RECORDNAME X) %REAL TM %SWITCH PHRASE(-1 : 26) %BYTEINTEGERMAP BREAKPOINT %RESULT == CODE(DV_TAGS_WHERE)_MODULE %END %INTEGERFN CGEN OUT(%RECORDNAME C) %SHORTROUTINE %RECORDSPEC C(CODEFM) ! GET BYTE OR WORD FROM CONSTANT GENERATOR %INTEGER R %SWITCH CON(3:6) R = CONSTANTS(C_NAME) -> CON (C_ADDR) CON(3): ! FULL WORD %RESULT = R CON(4): ! LOWER BYTE %RESULT = R&X'FF' CON(5): ! UPPER BYTE TO LOWER %RESULT = R>>8 CON(6): ! UPPER BYTE %RESULT = R&X'FF00' %END %ROUTINESPEC DECODE(%INTEGER N) %ROUTINE MODIFY CODE %RECORDNAME WORD, OLDWORD(CODEFM) %OWNINTEGER PC %INTEGER I, STAT, LASTSTAT %BYTEINTEGERNAME OP, MOD %SHORTINTEGERNAME PC0, PC1, AD, PTR %RECORDNAME TAB(TABFM) %ROUTINESPEC SETPC(%INTEGER N) %SWITCH OLDCODE(0 : 15) NPC = 1 LAST STAT = 0 ROUND: PC = PC+1 WORD == CODE(NPC) WORD <- OBJECT(PC) STAT = WORD_PC(0) -> ROUND %IF STAT < 0; ! DUFF STATEMENT %IF STAT # LASTSTAT %START; ! NEW STATEMENT LASTSTAT = STAT OLDWORD == CODE(NPC-1) PC0 == OLDWORD_PC(0) PC1 == OLDWORD_PC(1) %IF PC0 > 0 %START; ! WITH NO MERGE STATEMENT BETWEEN %IF PC1 = PC0 %START %IF PC0 = NPC %THEN PC0 = -STAT %C %ELSE PC0 = -OBJECT(PC0)_STAT PC1 = PC0 %FINISH %ELSE %START %IF PC0 = NPC %THEN PC0 = -STAT %C %ELSE PC0 = -OBJECT(PC0)_STAT PC1 = -OBJECT(PC1)_STAT %FINISH %FINISH STATPTRY(STAT) = NPC %FINISH NPC = NPC+1 SETPC(NPC) -> OLDCODE(WORD_CODE) OLDCODE(2): ! BUSOP 413: ! MERGE AND CMERGE SEE LATER NPC = NPC-1; ! OVERWRITE WITH NEXT OLDCODE(0): ! NOP OLDCODE(14): ! +FLAG -> ROUND OLDCODE(11): ! BREAKPOINT V == NAME(WORD_NAME) V_TAGS_WHERE = NPC-1 -> ROUND OLDCODE(9): ! 8-WAY BRANCH & T-LINES %CYCLE I = 1,1,3 WORD <- OBJECT(PC+I); ! PUTTING T-LINES FIRST SETPC(NPC) J = WORD_ADDR>>8; ! FLAG TYPE %IF WORD_NAME = 0 = WORD_MODULE %AND 1<=J<=2 %C %THEN WORD_OPRN = J %ELSE WORD_OPRN = 0 WORD == CODE(NPC) NPC = NPC+1 %REPEAT WORD <- OBJECT(PC) SETPC(NPC) PC = PC+3 TAB == TABLES(NAME(WORD_NAME)_TAGS_WHERE) %CYCLE I = 0,1,7 PTR == TAB_W(I) PTR = OBJECT(PTR)_STAT %REPEAT -> ROUND OLDCODE(3): ! COND %IF 3 <= WORD_OPRN <= 4 %START; ! WAIT UNTIL CONDITION SETPC(NPC-1) WORD_OPRN = WORD_OPRN-3 WORD_ADDR = WORD_ADDR>>8&X'FF' CODE(NPC-2) = WORD PC = PC+1 ! THROW OUT PROCEDING JUMP SINCE ONLY LOOP WITHIN STATEMENT -> 413 %FINISH WORD_OPRN = WORD_OPRN-1 WORD_CODE = 4 -> ROUND ! THROW OUT PRECEDING NOP UNNECESSARY MORE EFFICIENTLY DONE INSIDE COND OLDCODE(5): ! ROUTINE CALL SETPC(WORD_ADDR) -> ROUND OLDCODE(6): ! RETURN WORD_NAME <- WORD_ADDR -> ROUND OLDCODE(7): ! JUMP OLDWORD == CODE(NPC-2) I = WORD_ADDR %IF OLDWORD_PC(0) >= 0 %START OLDWORD_PC(0) = I %UNLESS OLDWORD_CODE = 4 OLDWORD_PC(1) = I ! JUMP AFTER WHILE UNTIL ALREADY REMOVED %FINISH %ELSE STATPTRY(STAT) = -OBJECT(I)_STAT ! UNCONDITIONAL JUMP -> 413 OLDCODE(1): ! ARITHMETIC OPERATION MOD == WORD_MODULE OP == WORD_OPRN OP = 24+MOD %IF OP = 36 OP = 0 %IF OP = 35 %AND MOD = 12 -> ROUND OLDCODE(12): ! CEVOKE OLDCODE(15): ! EXTRA EVOKE MOD == WORD_MODULE -> 413 %IF MOD = 25; ! BUS OP OP == WORD_OPRN AD == WORD_ADDR WORD_CODE = 2 %IF 12 # MOD # 24 %AND AD # 0 %THEN OP = AD %C %ELSE OP = MOD+8 -> ROUND OLDCODE(4): ! MERGE OLDCODE(13): ! CMERGE %IF WORD_NAME > 0 %START V == NAME(WORD_NAME) V_TAGS_WHERE = -STAT %IF V_TAGS_TYPE = 14 %FINISH ! PLAIN LABEL -> 413 OLDCODE(8): ! STOP -> ROUND %IF WORD_OPRN # 0 ! =0 FOR FINAL STOP,=1FOR CONDITIONAL STOP STATEMENT = 0 GOFLAG = 1 WORD == CODE(0) WORD_PC(0) = -OBJECT(HEADER_STARTAD)_STAT WORD_PC(1) = WORD_PC(0) NPC = NPC-1 LASTSTAT = STATPTRY(TOTSTATS) %CYCLE I = TOTSTATS-1,-1,1 PTR == STATPTRY(I) %IF PTR = 0 %THEN PTR = LASTSTAT %C %ELSE LASTSTAT = PTR ! UPDATE POINTERS %REPEAT %ROUTINE SETPC(%INTEGER I) WORD_PC(0) = I WORD_PC(1) = I %END %END; ! OF MODIFY CODE %ROUTINE HSYM(%INTEGER N) %CONSTBYTEINTEGERARRAY SS(0 : 15) = %C '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' PRINTSYMBOL(SS(N)) %END %ROUTINE HB(%INTEGER N) HSYM(N>>4) HSYM(N&15) %END %ROUTINE HS(%INTEGER N) HB(N>>8&255) HB(N&255) %END %ROUTINE PS(%STRING (255) S) PRINTSTRING(S) SPACES(10-LENGTH(S)) %END %ROUTINE DECODE(%INTEGER N) %RECORDNAME WORD(CODEFM) %INTEGER J J = 0 WORD == CODE(N) HS(N) J = J+1 %UNTIL N <= STATPTRY(J) <= NNPC J = J-1 %IF STATPTRY(J) # N WRITE(J,3) PRINTSYMBOL('/') HS(J) SPACES(2) HSYM(WORD_CODE) SPACES(2) HB(WORD_NAME) SPACES(2) HB(WORD_OPRN) SPACES(2) HB(WORD_MODULE) SPACES(2) HS(WORD_ADDR) SPACES(2) HS(WORD_PC(0)) SPACES(2) HS(WORD_PC(1)) NEWLINE %END %ROUTINE DUMP CODE %CONSTSTRING (6) %ARRAY OPCD(0 : 15) = %C 'NOP','EVOKE',' CONT','COND'(2),'RTCALL','RETURN','', 'STOP','BRANCH','T-LINE','BREAK',''(2),'+FLAG','' %INTEGER I, J %BYTEINTEGERNAME OB, NM, MD %SHORTINTEGERNAME PC0, PC1 %RECORD CD(CODEFM) PRINTSTRING(' CODE LOCN STAT CD NM OP MD ADDR PC0 PC1 ') J = 0 PC0 == CD_PC(0) PC1 == CD_PC(1) NM == CD_NAME MD == CD_MODULE OB == CD_CODE %CYCLE I = 1,1,NPC HS(I) %IF PC0 < 0 %START; ! NEW STATEMENT J = J+1 %UNTIL I <= STATPTRY(J) <= NNPC ! FIND POINTER J = J-1 %IF STATPTRY(J) # I WRITE(J,5) PRINTSYMBOL('/') HS(J) SPACES(3) %FINISH %ELSE SPACES(14) CD = CODE(I) HSYM(OB); SPACES(2) HB(NM); SPACES(2) HB(CD_OPRN); SPACES(2) HB(MD); SPACES(2) HS(CD_ADDR); SPACE %IF PC0 < 0 %START PRINTSYMBOL('-') HS(-PC0) SPACE PRINTSYMBOL('-') HS(-PC1) %FINISH %ELSE %START SPACE HS(PC0) SPACE %IF PC1 < 0 %START PRINTSYMBOL('-') HS(-PC1) %FINISH %ELSE SPACE %AND HS(PC1) %FINISH SPACES(2) %IF MD = 5 %THEN HS(CGEN OUT(CD)) %C %AND SPACES(6) %ELSE %START %IF 0 < NM <= NNAMES %C %THEN PS(NAME(NM)_TEXT) %ELSE SPACES(10) %FINISH SPACES(2) PRINTSTRING(OPCD(OB)) NEWLINE %REPEAT PRINTSTRING( ' STATEMENT POINTERS ') %CYCLE I=1,1,5 PRINTSTRING(' STAT PTR') %REPEAT NEWLINE %CYCLE I = 1,1,TOTSTATS J = STATPTRY(I) %IF J # 0 %START WRITE(I,6) %IF J # K %START K = J SPACES(2) %IF J < 0 %C %THEN PRINTSYMBOL('-') %AND J = -J %C %ELSE SPACE HS(J) %FINISH %ELSE SPACES(7) NEWLINE %IF I//5*5 = I %FINISH %REPEAT %END %SHORTINTEGERMAP FMAP(%INTEGER N) ! THIS MAPS FLAGS AND BIT EXTRACTS ! FOR USE IN CONDITIONS %SHORTROUTINE %SHORTINTEGERNAME PP %SWITCH TY(1 : 12) -> TY(N) TY(3): ! %BUS %RESULT == BUS1_BUSREG TY(2): ! %FLAG OR BIT EXTRACT V == NAME(WORD_NAME) %RESULT == SET FLAG(MODS(V_TAGS_USED),V) TY(4): ! _KF TY(5): ! _PF TY(6): ! _OVERUN PP == MODS(NAME(WORD_NAME)_TAGS_USED)_F1 ! GET APPROPRIATE FLAG %RESULT = ADDR(PP)+(N-4)<<1 TY(9): ! OVF %RESULT == BUS1_OVF TY(10): ! DZ %RESULT == BUS1_DZ TY(12): ! DP %RESULT == BUS1_DP TY(11): ! DN %RESULT == BUS1_DN %END %INTEGERFN EXTRACT ! THIS GETS BITS AND SWITCHES %SHORTROUTINE %INTEGER MODE, RES %RECORDNAME DV(NAMEFM) MODE = WORD_ADDR>>8&X'FF' %IF MODE = 3 %START ! BIT EXTRACT %IF WORD_NAME = 0 %THEN RES = BUS1_BUSREG %C %ELSE %START ! BUS WANTED DV == NAME(WORD_NAME) KWORD == WORD RES = SMAP(DV); ! GET REGISTER VALUE ! ! ! RES = GET TREG(DV_TAGS_WHERE, RES) %C ! ! ! %IF WORD_MODULE = 7 %OR WORD_MODULE = 6 ! FIDDLE BITS IF TREG OR BREG %FINISH %RESULT = RES>>(WORD_ADDR&15)&1 ! PICK OFF BIT %FINISH %ELSE %START ! %IF 5 <= MODE <= 6 %START; ! SWITCHES ! ************************ ! NOT YET IMPLEMENTED ! ************************** ! MONITOR(0,'') ! %FINISH %ELSE %C. %RESULT = FMAP(MODE);! OTHERWISE USE FMAP %FINISH %END %ROUTINE TEST ADDRESS(%INTEGER LIMIT, %C %INTEGERNAME ADDR, %STRINGNAME NAME) ! THIS ROUTINE CHECKS FOR INVALID ADDRESSING OF %MEMORY %ROM %SHORTROUTINE %UNLESS 0 <= ADDR <= LIMIT %START; ! CHECK ADDRESS ADDR = 0 MONITOR(1,NAME); ! GIVE TRACE BACK %FINISH %END %SHORTINTEGERMAP SMAP(%RECORDNAME V) ! THIS ROUTINE RETURNS POINTERS TO REGISTERS AND NAMED FLAGS ! LIKE KF,PF OVR ETC. %SHORTROUTINE %RECORDSPEC V(NAMEFM) %OWNSHORTINTEGER DUMP %INTEGER J, K %SHORTINTEGERARRAYNAME Z %SWITCH TYPE(0 : 41) J = V_TAGS_USED -> TYPE(KWORD_MODULE) TYPE(3): ! %MEMORY %RESULT == MMODS(J)_MEMADDR %IF V_TAGS_BITS # 9 ! ADDRESS REG WANTED Z == MMODS(J)_STORE %IF V_TAGS_WHERE < 0 %THEN K = \V_TAGS_WHERE %C %ELSE K = MMODS(J)_MEMADDR ! DIRECT ADDRESS SPECIFIED? TEST ADDRESS(MMODS(J)_LIMIT,K,V_TEXT) %RESULT == Z(K); ! RETURN LOCATION TYPE(2): ! %FLAG %RESULT == SET FLAG(MODS(J),V) TYPE(6): ! BREG TYPE(7): ! TREG TYPE(10): ! %IPINT TYPE(11): ! %IPINT TYPE(18): ! _A TYPE(26): ! _IN %RESULT == MODS(J)_A TYPE(19): ! _B TYPE(27): ! _OUT %RESULT == MODS(J)_B TYPE(21): ! _KF %RESULT == MODS(J)_F1 TYPE(22): ! _PF %RESULT == MODS(J)_F2 TYPE(31): ! _OVRUN %RESULT == MODS(J)_F3 TYPE(24): ! SPM REGISTER Z == MMODS(J)_STORE %RESULT == Z(V_TAGS_BITS); ! INDEX IN TAGS_BITS TYPE(25): ! THE BUS %RESULT == BUS FLAG(V_TAGS_DEFN) %IF V_TAGS_DEFN # 0 ! DZ DP DN OVF WANTED %RESULT == BUS1_BUSREG; ! BUS WANTED TYPE(0): ! NOT USED MONITOR(2,V_TEXT); ! PRINT TRACE BACK TYPE(41): ! DUMMY %RESULT == DUMP %END ! THIS CONVERTS SYMBOLS AND VALUES TO STRINGS ! %SHORTROUTINE %STRINGFN CHAR(%INTEGER S) %RESULT = TOSTRING(S) %IF 32 < S <= 127 ! ALPHANUMERIC %RESULT = 'SP' %IF S = ' '; ! SPACE %RESULT = 'NL' %IF S = NL; ! NEWLINE %RESULT = TOSTRING(S//10+'0').TOSTRING(S-S//10*10+'0') ! CONTROL CHAR %END %ROUTINE SHOW(%RECORDNAME V) ! THIS ROUTINE PRINTS OUT THE VALUES OF THE CONTENTS OF ! REGISTERS AND FLAGS WITH THEIR NAMES %SHORTROUTINE %RECORDSPEC V(NAMEFM) %ROUTINESPEC CS(%INTEGER FLAG) %RECORDNAME MMOD(MEMODFM) %RECORDNAME MOD(MODFM) %INTEGER ADDR, J, K, A %SHORTINTEGERARRAYNAME Z %STRING (7) FIDDLE %SWITCH TYPE(0 : 36) J = V_TAGS_USED; K = V_TAGS_TYPE FAULT(0) %AND %RETURN %IF (J = 0 %AND K # 25) %C %OR PERMIT(K) = 0 ! RETURN IF TYPE IS INVALID OR NAME UNUSED(EXCEPT WHEN THE BUS ! IS REQUIRED) PRINTNAME(V); ! OUTPUT NAME -> TYPE(K) TYPE(25): ! SPECIAL FOR THE BUS CS(BUSFLAG(V_TAGS_DEFN)) %AND -> OUT %C %IF V_TAGS_DEFN # 0 ! BUS FLAG WANTED NUMBER(BUS1_BUSREG,4) NEWLINE PRINTSTRING(' OVF:'); CS(BUS1_OVF) PRINTSTRING(' DZ:'); CS(BUS1_DZ) PRINTSTRING(' DN:'); CS(BUS1_DN) PRINTSTRING(' DP:'); CS(BUS1_DP) -> OUT TYPE(9): TYPE(1): ! %GPINT & %GPA FIDDLE = EXTENSION(17+K).':' FIDDLE = FROMSTRING(FIDDLE,2,LENGTH(FIDDLE)) SPACES(3-LENGTH(FIDDLE)) PRINTSTRING(FIDDLE) MOD == MODS(J) NUMBER(MOD_A,4); ! WRITE OUT A OR IN SPACES(3) FIDDLE = EXTENSION(18+K).':' FIDDLE = FROMSTRING(FIDDLE,2,LENGTH(FIDDLE)) SPACES(4-LENGTH(FIDDLE)) PRINTSTRING(FIDDLE) NUMBER(MOD_B,4); ! WRITE OUT B OR OUT -> OUT TYPE(2): ! %FLAG K = SET FLAG(MODS(J),V); ! GET FLAG VALUE SC: CS(K) -> OUT TYPE(3): ! %MEMORY MOD == MMODS(J) %IF V_TAGS_WHERE < 0 %THEN ADDR = \V_TAGS_WHERE %C %ELSE ADDR = MMOD_MEMADDR ! DIRECT ADDRESS? Z == MMOD_STORE NUMBER(ADDR,4); ! WRITE OUT ADDRESS %IF 0 <= ADDR <= MMOD_LIMIT %START ! CHECK ADDRESS PRINTSTRING(' ['); NUMBER(Z(ADDR),0) PRINTSTRING(' ]') ! WRITE OUT CONTENTS %FINISH %ELSE PRINTSTRING(' INVALID ADDRESS') V_TAGS_WHERE = 0; ! REMOVE DIRECT ADDRESS -> OUT TYPE(4): ! %SPM Z == MMODS(J)_STORE %CYCLE K = 0,1,15 NEWLINE %IF K&3 = 0; ! NEWLINE IF LINE FILLED NUMBER(K,4); ! WRITE SPM INDEX NUMBER(Z(K),4); ! WRITE SPM VALUE %REPEAT -> OUT TYPE(6): ! %BREG TYPE(7): ! %TREG A = MODS(J)_A PRINTSTRING('IN:'); NUMBER(A,4) ! CONTENTS STORED PRINTSTRING(' OUT:') NUMBER(GET TREG(V_TAGS_WHERE,A),4) ! TRANSFORMED CONTENTS -> OUT TYPE(10): TYPE(11): ! %IPINT,%OPINT TYPE(18): ! _A TYPE(26): ! _IN NUMBER(MODS(J)_A,4) -> OUT TYPE(19): ! _B TYPE(27): ! _OUT NUMBER(MODS(J)_B,4) -> OUT TYPE(21): ! _KF CS(MODS(J)_F1) -> OUT TYPE(22): ! _PF CS(MODS(J)_F2) -> OUT TYPE(31): ! _OVERUN CS(MODS(J)_F3) -> OUT TYPE(12): ! %SINT MOD == MODS(J) PRINTSTRING(''''.CHAR(MOD_A).''' : '''.CHAR(MOD_B). %C ''' KF:') CS(MOD_F1); ! KF PRINTSTRING(' PF:'); CS(MOD_F2); ! PF PRINTSTRING(' OVR:'); CS(MOD_F3); ! OVR PRINTSTRING(' ENABLED') %IF MODS(J)_F4 # 0 ! ENABLED? -> OUT TYPE(24): ! SPM REG Z == MMODS(J)_STORE NUMBER(Z(V_TAGS_BITS),4); ! BITS CONTAINS INDEX -> OUT OUT: NEWLINE %ROUTINE CS(%INTEGER FLAG) ! THIS WRITES OUT THE VALUE OF FLAGS %SHORTROUTINE %IF FLAG = 0 %THEN PRINTSTRING(' CLEAR') %C %ELSE PRINTSTRING(' SET ') %END %END %ROUTINE MYREAD(%INTEGER BUFNO, %INTEGERNAME N) ! THIS ROUTINE TAKES INPUT FROM THE INPUT BUFFER ! ALLOCATED TO THE INPUTTING MODULE AND READS INTEGER VALUES ! FROM IT %SHORTROUTINE %RECORDNAME BB(IOBUFFM) %INTEGERFNSPEC NEXT SYM INDEV <- NAME(WORD_NAME)_TEXT; ! NAME FOR PROMPT BB == BUFFER(BUFNO) %CYCLE RP = 0; LP = 0 %EXIT %IF CONSTANT FOUND(NEXT SYM) # 0 ! READ CONSTANT, 0 IF ERROR BB_SYMS = 0; ! SCRAP ALL INPUT SO FAR FAULT(0); ! QUERY %REPEAT N = REC(1); ! GET VALUE THAT WAS READ IN BB_SYMS = BB_SYMS+1 ! ADJUST BUFFER POINTERS BB_PT = BB_PT-1 %INTEGERFN NEXT SYM %RESULT = SYMBOL(BUFNO) %END %END %ROUTINE PSTRING(%INTEGER BUFNO, %STRINGNAME S) ! THIS ROUTINE OUTPUTS A STRING TO THE OUTPUT BUFFER ! ADDRESSES BY BUFNO %SHORTROUTINE %INTEGER J, L L = LENGTH(S); %RETURN %IF L = 0 %CYCLE J = 1,1,L PRINT(BUFNO,CHARNO(S,J));! OUTPUT CHARACTER TO BUFFER %REPEAT %END %ROUTINE SEND ! THIS ROUTINE OUTPUTS TO A BUFFERTHE VALUE OF THE ! VARIABLE 'RESULT', WHICH HOLDS THE VALUE COMPUTED DURING ! BUS OPERATIONS %SHORTROUTINE %STRING (8) TEXT NEWLINE TEXT <- NAME(WORD_NAME)_TEXT PRINTSTRING(TEXT.'=') SPACES(9-LENGTH(TEXT)) NUMBER(RESULT,1) NEWLINE %END %ROUTINE FLAG OP(%INTEGER TYPE) ! TYPE : 0 - %SAVE %OVF ! 3 - %SET ! 4 - %CLEAR ! 5 - %COMPLEMENT %SHORTROUTINE %SHORTINTEGERNAME MOD %IF TYPE = 0 %AND MGPA = 0 %START SAVED OVF = (!RESULT!>>16)&1 BUS1_OVF = SAVED OVF EN = SETBREAK(0) %FINISHELSESTART MOD == MODS(CRRNT)_F1 %IF TYPE = 3 %THEN MOD = 1 %IF TYPE = 4 %THEN MOD = 0 %IF TYPE = 5 %THEN MOD = MOD! ! 1 %FINISH %END %INTEGERFN GET TREG(%INTEGER TABLE ADDR, VALUE) ! THIS FUNCTION PERFORMS THE OUTPUT TRANSFORMATION REQUIRED ! BY TREGS AND BREGS (SEE PDP-16 HANDBOOK) %SHORTROUTINE %RECORDNAME LIST(TREG LIST FM) %SHORTINTEGER SHORT %INTEGER B, N, J %IF TABLE ADDR > 0 %START; ! NOT DEFAULT LIST == TABLES(TABLE ADDR) N = 0; ! CLEAR RESULT VARIABLE %CYCLE J = 0,1,15; ! PERFORM BIT SWOPPING B = (VALUE>>J)&1; ! BIT FROM SOURCE N = N! (B< 0 %START ! DISPLAY BUS CONTENTS %CYCLE J = 1,1,NNAMES ! ANY NAMES %EXIT %IF TESTINT(0,'ENOUGH') # 0 SHOW(NAME(J)) %IF PERMIT(NAME(J)_TAGS_TYPE) # 0 ! ROUND FOR EVERY NAME ! WRITE OUT VALUE AND NAME %REPEAT %FINISH %END %ROUTINE MONITOR(%INTEGER M, %STRING (127) ETXT) ! THIS ROUTINE GIVES A TRACE BACK OF THE PATH ! TAKEN TO REACH THE CUURENT POINT , THE ONLY THING ! TRACED IS ROUTINE ENTRY %SHORTROUTINE %CONSTSTRING (25) %ARRAY MONTEXT(0 : 8) = %C '','ADDRESS ERROR IN ','REFERENCE TO UNUSED NAME ', 'OUTPUT USED AS INPUT ON ','SPURIOUS BUFFER FOR ', 'INPUT USED AS OUTPUT ON ','SPURIOUS DESTINATION ', 'RETURN ERROR IN ROUTINE ','LABEL ' %INTEGER I, J, K %RECORDNAME RT(RTFM) PRINTSTRING(' ** MONITOR ENTERED FROM SAM ** ') PRINTSTRING(' '.MONTEXT(M).ETXT.' ') J = LAST RT K = STATEMENT; ! BACK TO FAILING STATEMENT %WHILE J # 0 %CYCLE; ! ROUND EVERY ROUTINE CALLED RT == RETAD(J) I = RT_RA; %EXIT %IF I < 2 ! RETURN ERROR PRINTSTRING('ENTERED FROM '.NAME(RT_NAME)_TEXT.' LINE') NUMBER(K,1) NEWLINE K = I J = RT_LAST RT; ! GET NEXT ROUTINE IN CHAIN %REPEAT PRINTSTRING('MAIN PROGRAM LINE'); NUMBER(K,1) NEWLINES(2) PDUMP %END %INTEGERFN FIELD(%INTEGER VALUE, KEY) ! THIS FUNCTION PERFORMS FIELD EXTRACTIONS FOR TREGS AND BREGS ! SEE PDP16 HANDBOOK AND ARTHUR DOCUMENTATION FOR VALID FIELDS %SHORTROUTINE %RESULT = VALUE %UNLESS 4 <= KEY <= 8 %SWITCH KV(4 : 8) -> KV(KEY) KV(4): ! <0:3> %RESULT = VALUE&X'F' KV(5): ! <0:7> %RESULT = VALUE&X'FF' KV(6): ! <0:11> %RESULT = VALUE&X'FFF' KV(7): ! <0:15> %RESULT = VALUE KV(8): ! <8:15> %RESULT = VALUE>>8&X'FF' %END %ROUTINE EVOKE ARITH OP(%INTEGER OP) ! THIS PERFORMS THE ARITHMETIC OPERATIONS FOR EVOKE ! INSTRUCTIONS %SHORTROUTINE %RECORDNAME MOD(MODFM) %INTEGER A %SWITCH EVOKEOP(0 : 50) %INTEGERFN SHIFTIN (%INTEGER I) %RECORDNAME KWORD(CODEFM) %INTEGER U %IF I = 0 %THEN U = V_TAGS_USE %ELSE %C U = V_TAGS_DEFN %RESULT = U!!1 %IF 0<=U<=1; ! %HIGH OR %LOW KWORD == WORD STORE WORD = WORD WORD == STORE WORD ! COPY OVER AS MUCH INFORMATION AS POSSIBLE WORD_NAME = U>>24 WORD_MODULE = U>>16&255 WORD_ADDR = U&X'FFFF' U = EXTRACT; ! FOR FLAGS ! EXTRACT USES WORD NOT KWORD WORD == KWORD; ! RESET WORD FOR DEPOSIT IN %RESULT = U %END MOD == MODS(CRRNT) -> EVOKEOP(OP&15) %IF OP < 29 A = V_TAGS_WHERE -> EVOKEOP(OP) EVOKEOP(1): ! LOAD A REG ONTO BUS RESULT = MOD_A -> EOP EVOKEOP(2): ! LOAD B REG ONTO BUS RESULT = MOD_B -> EOP EVOKEOP(3): ! NOT RESULT = \MOD_A -> EOP EVOKEOP(4): ! NOT B RESULT = \MOD_B -> EOP EVOKEOP(5):! *2 AND OR IN RSI RESULT = (MOD_A<<1)! SHIFTIN(0) -> EOP EVOKEOP(6): ! A+1 RESULT = MOD_A+1 -> EOP EVOKEOP(7): ! A-1 RESULT = MOD_A-1 -> EOP EVOKEOP(8): ! A+B RESULT = MOD_A+MOD_B -> EOP EVOKEOP(9): ! A-B RESULT = MOD_A-MOD_B -> EOP EVOKEOP(10): ! A&B RESULT = MOD_A&MOD_B -> EOP EVOKEOP(11): ! A XOR B RESULT = MOD_A! ! MOD_B -> EOP EVOKEOP(12): ! A OR B RESULT = MOD_A! MOD_B EOP: RESULT = (RESULT>>1)!(SHIFTIN(2)<<15) %IF OP > 16 -> END EVOKEOP(13): ! SET TO ZERO RESULT = 0 -> END EVOKEOP(36): ! SI A = A&X'00FF' %IF SINTMODE=0 %START INDEV <- NAME(WORD_NAME)_TEXT; ! SET UP NAME FOR PROMPT RESULT = SYMBOL(A) %FINISH %ELSE MY READ(A,RESULT) ! READ A SYMBOL -> END EVOKEOP(33): EVOKEOP(34): EVOKEOP(50): ! GPI,ININT,GPI_IN MYREAD(A&X'00FF',RESULT); ! READ A VALUE MOD_A <- RESULT; ! STORE VALUE IN INPUT SIDE -> END EVOKEOP(29): ! C GEN RESULT = CGEN OUT (WORD) -> END EVOKEOP(30): EVOKEOP(31): ! TREG OR BREG RESULT = GET TREG(A,MOD_A) ! TRANSFORM OUTPUT RESULT = FIELD(RESULT,WORD_ADDR);! EXTRACT FIELD -> END EVOKEOP(48): ! SPM REG DUM1 == MMODS(CRRNT)_STORE RESULT = DUM1(WORD_ADDR); ! INDEX IN ADDR -> END EVOKEOP(35): EVOKEOP(37): RESULT = BUS1_BUSREG; ! LOAD BUS REG -> END0 END: SETBUS END0: EVOKEOP(27): ! MEMORY EVOKEOP(0): %END %ROUTINE SET BUS BUS1 = 0 BUS1_BUSREG <- RESULT BUS1_DZ = 1 %IF BUS1_BUSREG = 0 BUS1_DP = 1 %IF BUS1_BUSREG > 0 BUS1_DN = 1 %IF BUS1_BUSREG < 0 BUS1_OVF = SAVED OVF EN = SET BREAK(0) %END %ROUTINE DEPOSIT IN(%INTEGER INDEX) ! THIS ROUTINE STORES THE VALUE COMPUTED (HELD IN 'RESULT') ! INTO THE LOCATION REQUIRED. ! THIS ROUTINE FUNCTIONS FOR SINGLE EVOKE OPERATIONS ONLY ! THAT IS OPS OF THE FORM A<-A+B ! THAT IS SOURCE AND DESTINATION IN SAME MODULE %SHORTROUTINE %SWITCH EVKDEST(0 : 10) %RECORDNAME MOD(MODFM) %INTEGER ADDR -> EVKDEST(INDEX) EVKDEST(0): %IF WORD_MODULE = 12 %START;! SI MOD == MODS(CRRNT) %IF J = 35 %THEN MOD_F4 = 1 %ELSE %START ! ENABLE MOD_F4 = 0; ! REMOVE ENABLE MOD_A = RESULT; ! STORE VALUE %FINISH %FINISH %RETURN EVKDEST(1): ! STORE IN 'A' REG MODS(CRRNT)_A <- RESULT %RETURN EVKDEST(2): ! STORE IN 'B' REG MODS(CRRNT)_B <- RESULT %RETURN EVKDEST(9): ! MEMORY CONTENTS TO BUS ADDR = MMODS(CRRNT)_MEMADDR DUM1 == MMODS(CRRNT)_STORE RESULT <- DUM1(ADDR) SET BUS %RETURN EVKDEST(10): ! ERROR TO REACH HERE MONITOR(6,'10') EVKDEST(3): EVKDEST(4): EVKDEST(5): EVKDEST(6): EVKDEST(7): EVKDEST(8): %END %ROUTINE STORE(%INTEGER OP) ! THIS ROUTINE PERFORMS STORE FOR CONTINUATION EVOKE STORES %SHORTROUTINE %INTEGER ADR %SHORTINTEGERNAME MM %SWITCH EVOKEDEST(0 : 35) RESULT = BUS1_BUSREG -> EVOKE DEST(OP) EVOKEDEST(20): ! SINT PRINT(V_TAGS_WHERE>>8,RESULT); ! OUTPUT VALUE -> B2; ! STORE RESULT EVOKEDEST(32): ! SPM REG STORE ADR = WORD_ADDR -> MM2 EVOKEDEST(17): EVOKEDEST(35): ! GPINT, GPINT _OUT SEND; ! TRANSMIT VALUE -> B2 EVOKEDEST(11): ! MEMORY ADDRESS REG MMODS(CRRNT)_MEMADDR <- RESULT %RETURN EVOKEDEST(19): ! OUTINT SEND EVOKEDEST(14): EVOKEDEST(15): EVOKEDEST(7): EVOKEDEST(1): ! STORE IN 'A' TYPE REG MODS(CRRNT)_A <- RESULT %RETURN B2: EVOKEDEST(2): ! STORE IN 'B' TYPE REG MODS(CRRNT)_B <- RESULT %RETURN EVOKEDEST(3): ! ERROR TO REACH HERE EVOKEDEST(4): EVOKEDEST(6): EVOKEDEST(10): MONITOR(6,CHAR(INDEX)) %RETURN EVOKEDEST(5): ! <0:7> MM == MODS(CRRNT)_A MM <- MM&X'FF00'! RESULT&X'00FF' %RETURN EVOKEDEST(8): ! BYTE OPERATION MM == MODS(CRRNT)_A MM <- MM&X'00FF'! (RESULT&X'00FF')<<8 %RETURN EVOKEDEST(9): ! STORE RESULT IN CONTENTS OF MEMORY ADDRESSED BY ! MEMADDR ADR = MMODS(CRRNT)_MEMADDR TEST ADDRESS(MMODS(CRRNT)_LIMIT,ADR,V_TEXT) ! CHECK ADDRESS MM2: DUM1 == MMODS(CRRNT)_STORE DUM1(ADR) <- RESULT %END %ROUTINE SIMULATE ! THIS ROUTINE SIMULATES THE MODIFIED CODE FROM THE ATHUR FILE %INTEGER PC; ! PC NOT NEEDED TO BE RETAINED BETWEEN WORDS %OWNINTEGER SELECT %SHORTINTEGERNAME PTR; ! GENERAL PURPOSE PTR %SWITCH INSTR(0 : 15) ROUND: PC = WORD_PC(INDEX) %IF PC < 0 %START; ! NEW STATEMENT RD: STATEMENT = -PC PC = STATPTRY(STATEMENT) -> RD %IF PC < 0 STATEMENT = STATEMENT+1 %WHILE PC = STATPTRY(STATEMENT+1) EN = BREAKHERE %IF EN # 0 %START BRK: LSBR = STATEMENT FORCE OUTPUT PRINTSTRING('BREAKPOINT LINE'); ! OUTPUT MESSAGE NUMBER(STATEMENT,1); ! PRINT LINE NUMBER IN RADIX NEWLINE %RETURN %FINISH %IF TRACE # 0 %START ! WRITE LINE NUMBER IF TRACE ON SELECTOUTPUT(77); ! SELECT TRACE OUTPUT NUMBER(STATEMENT,1); ! PRINT LINE NUMBER IN RADIX SELECTOUTPUT(0) %FINISH %FINISH WORD == CODE(PC) ! SET NOW SO IN CASE OF BREAK NOTHING LOST AND WORD SET PROPERLY %IF 0 < WORD_NAME <= NNAMES %START V == NAME(WORD_NAME) CRRNT = V_TAGS_USED %FINISH -> INSTR(WORD_CODE) INSTR(0): ! NOP BUS1 = 0 BUS1_DZ = 1 -> ROUND INSTR(1): ! EVOKE J = WORD_OPRN EVOKEARITHOP(J) %IF WORD_MODULE = 24 %START %IF J = 13 %START DUM1 == MMODS(CRRNT)_STORE DUM1(WORD_ADDR) = 0 %FINISH -> TEST CONTS %FINISH DEPOSIT IN(WORD_ADDR) -> TEST CONTS INSTR(2): ! CONTINUE EVOKE STORE(WORD_OPRN) TEST CONTS: EN = SET BREAK(WORD_NAME) !SIGNAL CONDITIONAL CHANGE -> ROUND INSTR(3): ! WAIT UNTIL-WHILE CONDITION %IF CONTROL&2 = 0 %START ! PRINT MESSAGE IF ENABLED PRINTSTRING('WAITING ') PRINTSTRING(WHUN(WORD_OPRN).V_TEXT.EXTENSION(WORD_ %C MODULE)) NEWLINE %FINISH FMAP(WORD_ADDR) = WORD_OPRN ! SETFLAG APPROPRIATELY -> INSTR(0); ! GET NOP EXECUTED INSTR(4): ! IF-UNLESS CONDITION INDEX = (EXTRACT+WORD_OPRN)&1; ! TRUE = 0 OR 2,FALSE = 1 ! SKIP IF COND SATISFIED INDEX ONLY CHANGED HERE -> ROUND INSTR(5): ! ROUTINE CALL RT == RETAD(CRRNT) J = STATEMENT J = J+1 %UNTIL STATPTRY(J) # PC RT_RA = J RT_LASTRT = LASTRT RT_NAME = WORD_NAME LAST RT = CRRNT -> ROUND INSTR(6): ! ROUTINE RETURN RT == RETAD(CRRNT) %IF RT_RA = 0 %START; ! NO RETURN ADDRESS MONITOR(7,V_TEXT) -> STOP %FINISH PC = -RT_RA WORD_PC(INDEX) = PC RT_RA = 0; ! CLEAR RA LAST RT = RT_LASTRT; ! RESET LAST ROUTINE NAME -> RD; ! LOOP STRAIGHT IN INSTR(9): ! 8-WAY BRANCH PTR == TABLES(V_TAGS_WHERE)_W(SELECT);! GET BRANCH ADDRESS %IF PTR = 0 %START MONITOR(8,V_TEXT.'('.TOSTRING('0'+SELECT).')NOT DEFINED') -> STOP %FINISH PC = -PTR WORD_PC(INDEX) = PC -> RD INSTR(10): ! TESTLINE FOR 8-WAY BRANCH %IF WORD_OPRN = 0 %THEN FLG = EXTRACT %C %ELSE FLG = WORD_OPRN-1 ! GET TEST LINE VALUE %HIGH,%LOW OR FLAG FLG = 1 %IF FLG # 0; ! ADJUST FLAG VALUE SELECT = (SELECT<<1!FLG)&7; ! BUILD UP ADDRESS -> ROUND INSTR(11): ! BREAKPOINT PTR == WORD_ADDR PTR = PTR-1 %UNLESS PTR = 0 -> ROUND %UNLESS WORD_MODULE = 0 = PTR %C %AND STATEMENT # LSBR EN = 0 %IF WORD_OPRN = 1 %START %IF BCOUNT = 0 %THEN -> ROUND %ELSE -> BRK %FINISH FORCE OUTPUT PRINTSTRING('BREAK POINT '.V_TEXT.' ') ! PRINT MESSAGE %RETURN INSTR(14): ! FLAG OPERATION FLAGOP(WORD_OPRN); ! DO FLAG -> ROUND INSTR(7): INSTR(12): INSTR(13): INSTR(15): ! ALL NOT USED IN MODIFIED CODE PRINTSTRING('ILLEGAL OPERATION ') %MONITORSTOP; ! CATASTROPHIC FAULT STOP: INSTR(8): ! STOP STPFLAG = 1; ! SET FLAG TO PREVENT %CONTINUE PRINTSTRING(' STOPPED AT LINE') NUMBER(STATEMENT,1) NEWLINE %END %ROUTINE RECOVER %SWITCH CT(0:4) -> CT(EN) CT(2): WORD_ADDR = N; ->END CT(1): SINGLE STEPS COUNT = N CT(0): CT(3): %IF CONDBR # 0 %START CT(4): %CYCLE NNAMES = 0,1,NNAMES C == CONPT(NNAMES) C_SET = 0 %AND C_COUNT = N %IF C_SET # 0 %REPEAT CONDBR = 0 %FINISH END: EN = 0 %END N = BUFFERS DUMMY BUF = 0 %WHILE BLIST # 0 %CYCLE; ! GO ROUND BUFFER CHAIN NP == NAME(BLIST); L = NP_TAGS_WHERE;! GET NEXT BUFFER NAME NP_TAGS_WHERE = 0 J = 0 J = 1 %UNLESS 10 <= NP_TAGS_TYPE <= 11 ! NEED 2 BUFFERS FOR SINT GPINT %CYCLE K = 0,1,J; ! ROUND NO. OF BUFFERS NEEDED TIMES DUMMY BUF_OWNER = BLIST; ! SET UP OWNER NAME %IF J = 0 %THEN DUMMY BUF_TYPE = NP_TAGS_TYPE&1 %C %ELSE DUMMY BUF_TYPE = K ! SET UP TYPE (IN=0,OUT=1) NP_TAGS_WHERE = NP_TAGS_WHERE! %C (BUFFERS<<(DUMMY BUF_TYPE<<3)) ! PACK DUMMY BUFFER ADDRESSES DUMMY BUF_SYMS = 80 %IF DUMMY BUF_TYPE = 1; ! INITIALIZE OUTPUT BUFFER(BUFFERS) = DUMMY BUF BUFFERS = BUFFERS-1; ! DECR NO. OF BUFFERS %REPEAT BLIST = L; ! NEXT IN CHAIN %REPEAT %IF BUFFERS > 1 %START; ! ERROR PRINTSTRING(' BUFFER ALLOCATION FAILS ') %MONITORSTOP %FINISH BUFFERS = N-BUFFERS; ! RESTORE NUMBER OF BUFFERS STPFLAG = 1; ! SET FLAG TO PREVENT %CONTINUE TRACE = 0; ! TRACE ON LAST = -2 INDEX = 0 TIME = 0 %IF MODUSEAGE(1) > 1 %THEN MGPA = 1 %ELSE MGPA = 0 ! SIMULATE MULTI GPAS - NO OVERFLOW 1: PHRASE(-1): %IF TIME = 1 %START WRITE(INT((CPUTIME-TM)*1000),6) TM = CPUTIME WRITE(INT((TM-START TIME)*1000),6) NEWLINE %FINISH RESULT = 0 RECONSTRUCT(0); ! GET NEXT COMMAND LP = 1; ! SET UP VARIABLES FOR PARSE SM = 0 RP = 0 REC(1) = -1 NAME FAULT = 0; NAME FLAG = 0 FAULT(0) %AND -> 1 %UNLESS PARSE(0) = 1; ! NAME OR SYNTAX FAULT K = 0 REC(0) = RP -> 1 %IF RP = 0 %IF CONTROL&1 # 0 %START; ! PRINT ANALYSIS RECORD IF ENABLED %CYCLE J = 1,1,RP WRITE(REC(J),5) K = K+1 K = 0 %AND NEWLINE %IF K >= 12 %REPEAT NEWLINE %FINISH RP = 1 PP = REC(1) -> PHRASE(PP) PHRASE(1): ! %CONTINUE (REPEAT COUNT') FAULT(0) %AND -> 1 %IF STPFLAG = 1 ! CANNOT CONTINUE AFTER A STOP N = REC(RP+1) RECOVER; ! CHECK CONDITIONALS SIMULATE; ! CONTINUE SIMULATING -> 1 PHRASE(2): ! (LOCATION) <- (PLUS') ! (CONSTANT) RP = RP+1 %IF REC(RP) = 0 %THEN LOCATION(DV) %ELSE DV = DUMMYNAME CURRENT ==DV_TEXT FAULT(4) %AND ->1 %IF DEST(DV_TAGS_TYPE) = 0 RP = RP+1; N = REC(RP+1); ! GET CONSTANT N = -N %IF REC(RP) # 0; ! NEGATIVE? FAULTS = 0 KWORD == STORE WORD KWORD_MODULE = DV_TAGS_TYPE SHRT <- N N = SHRT SMAP(DV) <- N; ! STORE VALUE IN LOCATION ADDRESSED RESULT = N; SET BUS -> 1 PHRASE(3): ! %GO ! FIRST CLEAR ROUTINE RETURN LISTS AND MODULES LAST RT = 0; ! SET BASIC LEVEL %CYCLE J = 1,1,RC RETAD(J) = 0 %REPEAT %CYCLE L = 1,1,NMT MODS(L) = 0 %REPEAT %CYCLE J = 0,1,NNAMES CONPT(J) = 0 %REPEAT DUMMY BUF = 0 %CYCLE J = 1,1,BUFFERS BUF == BUFFER(J) DUMMY BUF_OWNER = BUF_OWNER DUMMY BUF_TYPE = BUF_TYPE BUF = DUMMY BUF; ! SAVE ONLY WHAT IS NEEDED %REPEAT LSBR = 0 CONDBR = 0 EN = 0 STPFLAG = 0 CCOUNT = 0 WORD == CODE(0) MODIFY CODE %IF GOFLAG = 0 SIMULATE -> 1 PHRASE(4): ! %TRACE (ON-OFF) RP = RP+1 %IF REC(RP) = 0 %THEN TRACE = 0 %AND CLOSESTREAM(77) %C %ELSE %START ! %TRACE %OFF ! %TRACE %ON CLOSESTREAM(77) %IF TRACE # 0 RP = RP+1; TRACE = REC(RP) TRACE = 1 %IF TRACE = 0; ! IF NO DESTINATION MAKE IT .TT %IF TRACE = 3 %THEN OUT(3) = NAME(REC(RP+1))_TEXT ! SET UP FILE NAME LAST = -2; ! INIT TRACE DEFINE('ST77,'.OUT(TRACE)); ! DEFINE TRACE STREAM %FINISH -> 1 PHRASE(5): ! (FLAG OPERATION) [NAMELIST] RP = RP+1 J = REC(RP) RP = RP+1 N = REC(RP) %CYCLE N = 1,1,N RP = RP+1 CRRNT = NAME(REC(RP))_TAGS_USED; ! GET ADDRESS OF FLAG FLAGOP(J); ! PERFORM OPERATION %REPEAT -> 1 PHRASE(6): ! %MAP (LOCATION) (RLOCLIST') ! (WHERE') -> 1 PHRASE(7): ! ? (COND) (RCONDLIST') FAULT(0) %AND -> 1 %IF STPFLAG = 1 ! TESTS SET UP BEFORE %GO ARE MEANINGLESS %UNTIL REC(RP) = 0 %CYCLE; ! ROUND TILL END OF COND LIST RP = RP+1 %IF REC(RP) # 0 %THEN DV = DUMMY NAME %C %ELSE LOCATION(DV) ! EITHER SET UP TAGS FOR BUS OR GET LOCATION INFO MI = DV_TAGS_TYPE %IF Q(MI) = 0 %START; ! ERROR. LOCATION NOT CONDABLE PRINTSTRING(DV_TEXT.' NOT VALID ') C == DUM COND; ! CAN NOT BE USED NOW C_W == NMT; ! POINT C_W TO ANYWHERE TO PREVENT ADDRESS ERRORS %FINISH %ELSE %START C == CONPT(DV_TAGS_MASTER); !GET MASTER ONLY CCOUNT = CCOUNT+1 %IF C_FIRED = 0 !NOT SET THEN INCREMENT COUNT C = 0 C_FIRED = 1; ! SHOW SET UP AS COND C_DESC = DV KWORD == STORE WORD; KWORD_MODULE = MI ! SET UP PSEUDO INSTRUCTION FOR MAPPING ROUTINE C_W == SMAP(DV); ! SET UP POINTER TO TRAPPED LOCATION %FINISH RP = RP+1 C_FLAG = 1 %C %IF (MI = 2 %AND DV_TAGS_BITS # 0) %OR NK = 2 ! TRAPPED VARIABLE IS A NON-MODULE FLAG I.E. BIT EXTRACTS, ETC. C_COND = REC(RP); ! ENTER CONDITION TYPE INTO COND RECORD %IF REC(RP) = 0 %THEN C_TEST = C_W %ELSE %START ! IF TEST IS NOT ON VARIABLE CHANGE (I.E. NO CONDITION IS ! SPECIFIED ) STORE TEST VALUE IN C_TEST RP = RP+1 C_TEST = REC(RP); ! STORE TEST VALUE %FINISH RP = RP+1 %REPEAT ! UNTIL END OF LIST -> 1 PHRASE(8): ! %TREG [NAME] (PIN DEFINITION) -> 1 PHRASE(9): ! # (LOCATION) (RLOCLIST') %UNTIL REC(RP) = 0 %CYCLE RP = RP+1 %IF REC(RP) = 0 %THEN LOCATION(DV) %C %ELSE DV = DUMMY NAME ! GET LOCATION TAGS OR ELSE GENERATE BUS TAGS SHOW(DV); ! DISPLAY NAME AND VALUE RP = RP+1 %REPEAT -> 1 PHRASE(10): ! %DEFINE (EQITEM) (RDEFINE') -> 1 PHRASE(11): ! %DUMP (WHERE') RP = RP+1 REC(RP) = 1 %IF REC(RP) = 0; ! .TT IF NO DEST GIVEN %IF REC(RP) = 3 %THEN OUT(3) = NAME(REC(RP+1))_TEXT ! GET FILE NAME DEFINE('ST76,'.OUT(REC(RP))); ! DEFINE DUMP STREAM SELECTOUTPUT(76) PDUMP; ! DISPLAY CONTENTS SELECTOUTPUT(0); ! SELECT CONSOLE AGAIN CLOSESTREAM(76) -> 1 PHRASE(12): ! %IGNORE [OLD NAME LIST] ! THIS FUNCTION CAUSES A FLAG TO BE SET(_IGNORE) IN THE ! DATA ELEMENT ASSOCIATED WITH THE BREAKPOINTS NAMED WHICH ! CAUSES THEM TO BE IGNORED WHEN ENCOUNTERED IN THE INSTRUCTION ! FLOW,THAT IS THEY WILL NOT CAUSE A BREAKPOINT TO BE GENERATED. RP = RP+1 MODIFY CODE %IF GOFLAG = 0 %IF REC(RP) = 0 %START; ! IGNORE ALL %CYCLE J = 1,1,NNAMES DV = NAME(J) BREAKPOINT = 1 %IF DV_TAGS_TYPE = 17 %REPEAT -> 1 %FINISH ! LIST OF NAMES TO FOLLOW %CYCLE J = 1,1,REC(RP); ! REC(RP) HAS LENGTH OF LIST RP = RP+1 DV = NAME(REC(RP)) %IF DV_TAGS_TYPE # 17 %START; ! NAME NOT A BREAKPOINT NAME CURRENT == DV_TEXT FAULT(5); ! NOT A BREAKPOINT (NAME) %FINISH %ELSE BREAKPOINT = 1; ! SET FLAG %REPEAT -> 1 PHRASE(13): ! %REPLACE [OLDNAME LIST] ! THIS FUNCTION REINSTATES A PROGRAMMED BREAKPOINT THAT HAS ! BEEN 'IGNORED' , THAT IS IT WILL NOW CAUSE THE ! SIMULATOR TO GO DOWN IN A BREAK. ! THIS IS SIGNALED BY SETTING _IGNORE TO 0 FAULT(0) %AND ->1 %IF GOFLAG = 0 RP = RP+1 %IF REC(RP) = 0 %START; ! REPLACE ALL %CYCLE J = 1,1,NNAMES DV = NAME(J) BREAKPOINT = 0 %IF DV_TAGS_TYPE = 17 %REPEAT -> 1 %FINISH %CYCLE J = 1,1,REC(RP) RP = RP+1 DV = NAME(REC(RP)) %IF DV_TAGS_TYPE # 17 %START; ! NOT A BREAKPOINT NAME CURRENT == DV_TEXT FAULT(5) %FINISH %ELSE BREAKPOINT = 0; ! CLEAR FLAG %REPEAT -> 1 PHRASE(14): ! %ENDOFSIM PRINTSTRING('#CLOSE ') %RETURN; ! TERMINATE SIMULATOR RUN PHRASE(15): ! %CANCEL ! THIS ALLOWS ONE TO DELETE SELECTED CONDITIONAL BREALPOINTS ! BY GIVING THE NAME ON WHICH THE TRAP WAS SET ! (ALL TRAPS FOR THAT LOCATION WILL BE REMOVED) ! IF NO LOCATION IS GIVEN ALL TRAPS WILL BE REMOVED FAULT(0) %AND -> 1 %IF CCOUNT = 0; ! NO CONDITIONAL BREAKPOINTS RP = RP+1 %IF REC(RP) = 0 %START; ! REMOVE ALL BREAKPOINTS %CYCLE T = 1,1,NNAMES CONPT(T) = 0 %REPEAT CCOUNT = 0 ->1 %FINISH %UNTIL REC(RP) = 0 %CYCLE; ! ROUND UNTIL END OF LIST RP = RP+1 %IF REC(RP) = 0 %THEN LOCATION(DV) %C %ELSE DV = DUMMY NAME ! GET TAGS FOR LOCATION OR GENERATE BUS TAGS C == CONPT(DV_TAGS_MASTER) %IF C_FIRED = 1 %THEN CCOUNT = CCOUNT-1 %ELSE FAULT(0) C = 0; ! POINTER TO CURRENT BREAK INFO RP = RP+1 %REPEAT ! UNTIL END OF LIST -> 1 PHRASE(16): ! %BREAK RP = RP+1; SINGLE SHOT = 1 %AND -> 1 %IF REC(RP) = 0 ! SET SINGLE SHOT MODE IF NO LINE NUMBER LIST MODIFY CODE %IF GOFLAG = 0 %UNTIL REC(RP) = 0 %CYCLE RP = RP+1; N = REC(RP) FAULT(0) %AND -> 1 %IF N > TOTSTATS J = NPC+N KWORD == CODE(J) %IF KWORD_MODULE = 0 %AND KWORD_CODE = 11 %C %THEN FAULT(7) %ELSE %START %IF KWORD_MODULE = 0 %START KWORD <- 0 KWORD_CODE = 11 KWORD_OPRN = 1 STP == STATPTRY(N) KWORD_PC(0) = STP KWORD_PC(1) = STP T = N-1 %WHILE T > 1 %AND STP = STATPTRY(T) %CYCLE ! ALL THAT PASS THROUGH STATPTRY(T) = J T = T-1 %IF T # 1 %REPEAT STP = J %FINISH %ELSE KWORD_MODULE = 0 BCOUNT = BCOUNT+1 %FINISH RP = RP+1 %REPEAT SINGLE SHOT = 0; ! DISABLE SS -> 1 PHRASE(17): ! %FREE %IF BCOUNT = 0 %START %IF SINGLE SHOT # 0 %THEN SINGLE SHOT = 0 %C %ELSE FAULT(0) ! CLEAR SS ,OR ESLE GIVE FAULT -> 1 %FINISH SINGLE SHOT = 0 %IF REC(RP+1) = 0 %START J = 1 %CYCLE N = 1,1,BCOUNT KWORD == CODE(J+NPC) %AND J = J+1 %C %UNTIL KWORD_CODE = 11 KWORD_MODULE = 1 STATPTRY(J) = KWORD_PC(0) %REPEAT BCOUNT = 0 -> 1 %FINISH ! REMOVE ALL STATEMENT BREAKS FAULT(0) %AND ->1 %IF GOFLAG = 0 ! CANT %FREE BEFORE CODE SET UP %UNTIL REC(RP) = 0 %CYCLE RP = RP+1 N = REC(RP) %IF N <= TOT STATS %START J = NPC+N KWORD == CODE(J) -> FLT %IF KWORD_CODE # 11 KWORD_MODULE = 1 STATPTRY(N) = KWORD_PC(0) BCOUNT = BCOUNT-1 %FINISH %ELSE %START FLT: FAULT(0); ! FAULT IF NOT GENUINE %FINISH RP = RP+1 %REPEAT -> 1 PHRASE(18): ! CONTROL ! %CONTROL 1 ENABLES PRINTING OF ANALYSIS RECORDS ! %CONTROL 2 ENABLES INHIBIT OF MESSAGES ! %CONTROL 4 (%TRAPS) PRINTS OUT BREAKPOINT ! %CONTROL 5(%TIME) ENABLES PRINTING OF ELAPSED TIME ! %CONTROL 7(%NAMES) PRINTS OUT TAGS FOR NAMES RP = RP+1; N <- REC(RP) SINT MODE = N&1 %AND -> 1 %IF N&16 # 0 BDISP %AND -> 1 %IF N = 4 %IF N = 5 %START %IF TIME = 1 %THEN TIME = 0 %ELSESTART TM = CPUTIME TIME = 1 %FINISH -> 1 %FINISH DISPLAY %AND -> 1 %IF N = 7 %IF N = 8 %START %MONITOR -> 1 %FINISH SDISPLAY %AND -> 1 %IF N = 15; ! DISPLAY NAME TAGS FOR SYSTEM DECODE(N>>8) %AND -> 1 %IF N > 256 %AND N>>8 <= NNPC CONTROL <- N -> 1 PHRASE(21): ! %CLEAR %BUS BUS1 = 0; BUS1_DZ = 1; -> 1; ! ZERO BUS AND SET DZ PHRASE(23): ! %RADIX %UNLESS 0 < REC(RP+1) <= 36 %THEN FAULT(0) %C %ELSE RADIX = REC(RP+1) ! SET RADIX IF VALID -> 1 PHRASE(24): ! -> (OLD NAME) RP = RP+1; TEMP NAME == NAME(REC(RP)) FAULT(6) %AND -> 1 %IF TEMP NAME_TAGS_TYPE # 14 ! NOT A LABEL WORD == STOREWORD WORD_PC(INDEX) = TEMP NAME_TAGS_WHERE PRINTSTRING('CONTINUING FROM '.TEMP NAME_TEXT) NEWLINE -> PHRASE(1) PHRASE(25): ! %DECODE (WHERE') RP = RP+1 REC(RP) = 1 %IF REC(RP) = 0; ! .TT IF NO DEST GIVEN OUT(3) = NAME(REC(RP+1))_TEXT %IF REC(RP) = 3 ! GET FILE NAME DEFINE('ST75,'.OUT(REC(RP))); ! DEFINE DECODE STREAM SELECTOUTPUT(75) MODIFY CODE %IF GOFLAG = 0 DUMP CODE SELECTOUTPUT(0) -> 1 PHRASE(26): ! %INPUT (WHERE') RP = RP+1 FAULT(0) %AND -> 1 %IF REC(RP) = 2; ! NO INPUT FROM .LP? REC(RP) = REC(RP)!1; ! .TT IF NO DEST GIVEN OUT(3) = NAME(REC(RP+1))_TEXT.'+.TT' %IF REC(RP) = 3 ! GET FILE NAME SELECTINPUT(0) CLOSESTREAM(74) DEFINE('ST74,'.OUT(REC(RP))); ! DEFINE INPUT STREAM SELECTINPUT(74) -> 1 %END; ! OF COMPILE BLOCK ! CLEAR OUT MEMORY SPACE, ROUTINE SPACE AND BREAKPOINT SPACE NNPC = PC %CYCLE PC = 1,1,MQ STR(PC) = 0 %REPEAT %CYCLE PC = 1,1,TOTSTATS STATPTRY(PC) = 0 %REPEAT %CYCLE PC = 0,1,NNPC CODE(PC) = 0 %REPEAT ! CLEAR SYSTEM VARIABLES SINGLE SHOT = 0 SAVED OVF = 0 CCOUNT = 0; ! COND BREAK COUNT BCOUNT = 0; ! STAT BREAK COUNT STPFLAG = 1; ! SET STOP FLAG NK = 1 N = NNAMES %WHILE N # 0 %CYCLE; ! ROUND FOR ALL NAMES V1 == NAME(N)_TAGS %IF V1_USED # 0 %START; ! USED NAME %IF 0 # V1_MASTER # N %START; ! EQUIVALENCED NAME - NOT BUS V2 == NAME(V1_MASTER)_TAGS V1_USED = V2_USED %IF MODTY(V2_TYPE) # 0 ! IF NAME REFERS TO A MODULE REG THEN POINT IT AT ITS MASTERS ! STORAGE SPACE %FINISH %ELSE %START PC = MODTY(V1_TYPE) %IF PC # 0 %START; ! MODULE TYPE %IF PC = 1 %START; ! NOT MEMORY TYPE MODS(V1_USED) = 0; ! CLEAR LOCATION %FINISH %ELSE %START MMODS(V1_USED)_MEMADDR = 0; ! SET MEMADDR REG TO 0 %IF V1_SIZE # 0 %THEN PC = V1_SIZE %C %ELSE %START %IF V1_TYPE = 4 %THEN PC = 16 %ELSE PC = 1024 %FINISH; ! FIND AMOUNT OF SPACE NEEDED FOR MEMORY MMODS(V1_USED)_STORE == ARRAY(ADDR(STR(NK)) %C ,MEMODAFM) ! MAP ONTO NEXT SPACE IN 'STORE' MMODS(V1_USED)_LIMIT = PC; ! STORE MAX SIZE NK = NK+PC; ! MOVE FREE STORE POINTER %FINISH %FINISH %FINISH %FINISH N = N-1 %REPEAT BUS1 = 0; ! CLEAR BUS BUS1_DZ = 1; ! SET DZ COMPILE BLOCK; ! RUN DESTROY('SS#WORK'); ! TIDY UP ! *SS#WORK MUST NOT BE USED AS AN ARTHUR OBJECT FILE %END %END; ! OF SAM %ENDOFFILE