%CONSTSHORTINTEGERARRAY SMAIN(1: 141) = %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, 115, 116, 120, 0, 122, 125, 0, 128, 131, 0, 135, 137, 0, 139, 141, 0, 143, 147, 0, 149, 154, 0, 156, 0, 159, 164, 0, 166, 169, 0, 171, 174, 177, 180, 183, 186, 0, 189, 194, 0, 196, 198, 0, 200, 202, 0, 204, 207, 210, 0, 213, 215, 0, 217, 221, 222, 225, 226, 230, 0, 232, 238, 242, 0, 245, 249, 253, 260, 0, 262, 0, 265, 268, 0, 270, 273, 276, 279, 0, 282, 286, 289, 292, 295, 298, 0, 300, 305, 0, 307, 310, 313, 0, 316, 322, 0, 324, 0, 330, 335, 0, 337, 340, 343, 346, 349, 352, 355, 0, 358, 360, 363, 0 %CONSTSHORTINTEGERARRAY SSUB(2: 365) = %C 4098,-32768, 0, 1, 8193, 4164, 0, 10, 8193, 4164, 0, 12, 8195, 0, 15, 8196, 4131, 0, 21, 8198, 4184, 4161, 4167, 0, 25, 8199, 4146, 4148, 0, 27, 8201, 4128, 4161, 0, 29, 8203, 4167, 0, 34, 8204, 4134, 0, 41, 8205, 4134, 0, 49, 8206, 0, 58, 8207, 4125, 0, 65, 8208, 4140, 0, 71, 8209, 4137, 4143, 0, 8194, 4128, 4174, 4233, 12288, 0, 8197, 4213, 20481, 4217, 0, 76, 8200, 16385, 4177, 0, 81, 8202, 4220, 4222, 0, 88, 8210, 12288, 0, 96, 8210, 8192, 0, 101, 8210, 8198, 0, 107, 8210, 8199, 0, 113, 8210, 8196, 0, 119, 125, 8213, 0, 129, 8215, 12288, 0, 135, 8216, 16385, 0, 8193, 4128, 4161, 0, 8192, 0, 8192, 4184, 0, 8193, 138, 0, 142, 8192, 0, 146, 8193, 4167, 0, 20481, 0, 8192, 0, 12288, 0, 8192, 0, 8193, 12288, 4143, 0, 8192, 0, 149, 8193, 12288, 4143, 0, 8192, 0, 4128, 4151, 0, 149, 8193, 4146, 4148, 0, 8192, 0, 4154, 12288, 0, 8192, 0, 151, 8193, 0, 27, 8194, 0, 153, 8195, 0, 156, 8196, 0, 159, 8197, 0, 161, 8198, 0, 149, 8193, 4128, 4161, 0, 8192, 0, 12288, 0, 8192, 0, 4170, 0, 8192, 0, 163, 8193, 0, 167, 8194, 0, 8195, 16384, 0, 171, 0, 151, 0, 174, 12288, 4179, 176, 0, 149, 12288, 4179, 0, 10, 8193, 12288, 0, 8192, 0, 178, 8192, 16385, 4181, 180, 0, 8193, 16385, 4188, 0, 8194, 4203, 0, 182, 8193, 4225, 0, 27, 8194, 12288, 0, 159, 8195, 12288, 10, 12288, 161, 0, 8192, 0, 16385, 4195, 0, 182, 4225, 0, 8192, 0, 184, 8201, 0, 188, 8202, 0, 191, 8203, 0, 194, 8204, 0, 8192, 4193, 4210, 0, 197, 8202, 0, 202, 8203, 0, 211, 8204, 0, 220, 8201, 0, 4198, 0, 159, 8193, 12288, 161, 0, 8192, 0, 229, 8195, 0, 119, 8196, 0, 233, 8197, 0, 244, 8193, 4213, 20480, 4217, 0, 8192, 0, 16384, 151, 16385, 4188, 4210, 0, 149, 8193, 4220, 4222, 0, 8192, 0, 248, 8210, 0, 250, 8211, 0, 252, 8213, 0, 255, 8214, 0, 258, 8218, 0, 261, 8219, 0, 265, 8223, 0, 272, 0, 274, 8193, 0, 8192, 0 %CONSTBYTEINTEGERARRAY SLITERAL(1: 275) = %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, 5, 99, 108, 101, 97, 114, 3, 98, 117, 115, 5, 114, 97, 100, 105, 120, 2, 45, 62, 3, 66, 85, 83, 3, 111, 102, 102, 2, 111, 110, 1, 44, 1, 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 %CONSTSTRING (31) VERSION = ' SAM : VERSION 3.8' ! ! EXTERNAL SPECS ! %EXTERNALROUTINESPEC PROMPT(%STRING (15) S) %EXTERNALROUTINESPEC DEFINE(%STRING (63) X) %EXTERNALINTEGERFNSPEC TESTINT(%INTEGER C, %STRING (15) X) %EXTERNALROUTINESPEC MOVE(%INTEGER LENGTH, FROM, TO) %SYSTEMROUTINESPEC FDP(%INTEGER X, %STRING (17) S, %C %INTEGER A, N, %INTEGERNAME F) ! ! RECORDFORMATS ! %RECORDFORMAT HEADERFM( %C %INTEGER IDEN, USEAGE, NNAMES, NAMES, TEXT, CODE, %C CONSTANTS, 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) %RECORDFORMAT CODEFM(%BYTEINTEGER CODE, NAME, OPRN, MODULE, %C %SHORTINTEGER ADDR, STAT) %RECORDFORMAT TAGFM(%INTEGER MASTER, %SHORTINTEGER TYPE, %C %BYTEINTEGER USED, BITS, %INTEGER USE, DEFN, SIZE, WHERE) %RECORDFORMAT NAMEFM(%STRINGNAME TEXT,%RECORD TAGS(TAGFM)) %RECORDFORMAT BRKFM(%INTEGER COUNT, IGNORE) %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) %RECORDFORMAT CONDFM(%SHORTINTEGERNAME W, %C %SHORTINTEGER TEST,COUNT, %BYTEINTEGER COND, FLAG, FIRED%C ,%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 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 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(3 : 4) = %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 = 10 %OWNSTRING (63) OBJECT FILE = 'SS#ARTH' ! ! SAM STARTS HERE ! %EXTERNALROUTINE SAM(%STRING (63) FILES) ! %INTEGER NNAMES, N, FLAG, TEXTPT, NAMEFAULT, NAME FLAG, BUFFERS, %C BLIST %INTEGER RC, BC, LP, RP, J, SM, PP, CONS, FAULTS, CONNECT %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)(CODEFM) %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(CODEFM) %RECORDARRAYNAME TABLES(TABFM) %RECORDARRAYNAME EXTERNALS(EXTERNFM) %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 : 6) %PRINTTEXT '? ' -> FT(NUMBER) FT(0): -> OUT %IF NAMEFLAG # SM; ! SYNTAX FAULT OR COMMAND ERROR %PRINTTEXT ' NAME '; ! NAME FAULT SM = NAMEFAULT PRINTSTRING(SOURCE) SPACES(SM+10) %PRINTTEXT '!' -> OUT FT(1): %PRINTTEXT 'ILLEGAL SUBNAME'; -> OUT FT(2): %PRINTTEXT 'ILLEGAL INDEX'; -> OUT FT(3): %PRINTTEXT 'ILLEGAL EXTRACTION'; -> OUT FT(4): %PRINTTEXT 'INVALID ADDRESS'; -> OUT FT(5): %PRINTTEXT 'NOT A BREAKPOINT'; -> BODY FT(6): %PRINTTEXT 'NOT AN ADDRESS'; -> BODY BODY: %PRINTTEXT ' ' PRINTSTRING(CURRENT) OUT: NEWLINE FAULTS = FAULTS+1 %END ! ! !*********************************************************************** ! ! THE FOLLOWING ROUTINES ARE DEALT WITH IN PDP16S,THE SOURCE TEXT ! FOR ARTHUR. ! ! %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 %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 %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 ! !*********************************************************************** ! ! !******** START OF SIMULATION ******* ! OBJECT FILE = FILES %UNLESS FILES = '' CONNECT = 0 FDP(7, OBJECTFILE, 0, ADDR(CONNECT), FLAG);! CONNECT FOR READING %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+16); ! 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 %INTEGER WORK AD WORK AD = 0; ! TO ANY CONVENIENT SPACE FDP(4, WORKFILE, 3, ADDR(WORK AD), FLAG); ! CREATE WORK FILE %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+16) FDP(2, OBJECT FILE, 0, 0, WORKAD); ! DISCONNECT FILE %END SOURCE == STRING(ADDR(LINE(0))); ! MAP 'SOURCE' ONTO ARRAY 'LINE' NNAMES = HEADER_NNAMES; ! GET NU,BER OF NAMES DECLARED NAME == ARRAY(HEADER_NAMES+ADDR(HEADER), NAFM) ! NAME TAGS %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+ADDR(HEADER), MUFM) ! MODULE USEAGE TEXT == ARRAY(HEADER_TEXT+ADDR(HEADER), TXT1) ! NAME TEXTS EXTERNALS == ARRAY(HEADER_EXTERNS+ADDR(HEADER), EXTARFM) ! EXTERNAL EVENTS TABLES == ARRAY(HEADER_TABS+ADDR(HEADER), TBAFM) ! 8-WAY BRANCHES & REGFORMATS OBJECT == ARRAY(HEADER_CODE+ADDR(HEADER), CFM) ! OBJECT CODE CONSTANTS == ARRAY(HEADER_CONSTANTS+ADDR(HEADER), 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 -> 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; ! STROE 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 %BEGIN %INTEGER NK, PC, LSBR, L %SHORTINTEGER BCOUNT, CCOUNT %BYTEINTEGER STBR, STPFLAG, SINGLE SHOT %RECORD DUMMY BREAK (BRKFM) %RECORD BUS1(BUSFM) %SHORTINTEGERARRAY STR(1 : MQ) %RECORDNAME WORD, KWORD(CODEFM) %RECORDNAME CURBREAK(BRKFM) %RECORDARRAY BSTATS(1 : 48)(BRKFM); ! STATEMENT BREAKS %RECORDARRAY BREAKPOINT(1 : BC)(BRKFM); ! PROGRAM BREAKS %RECORDARRAY CONPT(1 : 48)(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 %INTEGER I TEXT <- V_TEXT; ! TRUNCATE NAME PRINTSTRING(TEXT) I = LENGTH(TEXT) %IF V_TAGS_TYPE = 25 %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 PRINTSTRING(EXTENSION(V_TAGS_TYPE)) I = I+LENGTH(EXTENSION(V_TAGS_TYPE)) %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 %THEN %PRINTTEXT 'NO CONDITIONAL BREAKS ' %C %ELSE %START %CYCLE I = 1, 1, CCOUNT C == CONPT(I) PRINTNAME(C_DESC); ! PRINT NAME TRAP IS ON %IF C_COND = 0 %THEN %PRINTTEXT 'ON VALUE CHANGE' %C %ELSE %START ! VALUE CHANGE OR CONSTANT COMPARISON ? PRINTSTRING(OP(C_COND));! PRINT COMPARITOR WRITE(C_TEST, 1) %FINISH %PRINTTEXT ' HELD FOR' %AND WRITE(C_COUNT, 1) %C %IF C_COUNT # 0 ! PRINT OUT HOLD COUNT IF ANY NEWLINE %REPEAT %FINISH %END %ROUTINE BDISP ! THIS ROUTINE DISPLAYS THE STATUS OF BREAKPOINTS ! IN RESPONSE TO %TRAPS OR %CONTROL 4 %SHORTROUTINE %INTEGER J NEWLINE %IF SINGLE SHOT # 0 %THEN %PRINTTEXT 'SINGLE SHOT MODE ' %C %ELSE %START %IF BCOUNT = 0 %C %THEN %PRINTTEXT 'NO STATEMENT BREAKS ' %ELSE %START %CYCLE J = 1, 1, BCOUNT %PRINTTEXT 'LINE' WRITE(BSTATS(J)_IGNORE, 1); ! WRITE LINE NUMBER %IF BSTATS(J)_COUNT # 0 %START; ! WRITE HOLD COUNT IF ANY %PRINTTEXT ' HELD FOR' WRITE(BSTATS(J)_COUNT, 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 %SWITCH FQ(0 : 3) RP = RP+1; -> FQ(REC(RP)) FQ(1): !'_' RP = RP+1; N = REC(RP) %IF (N < 20 %AND V_TAGS_TYPE # 1) %OR (23 > N > 20 %C %AND V_TAGS_TYPE # 12) %OR (N > 25 %C %AND V_TAGS_TYPE # 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 V_TAGS_TYPE = N; ! INSERT TYPE %RETURN FQ(2): ! '#' RP = RP+1; N = REC(RP) FAULT(2) %UNLESS V_TAGS_TYPE = 4 %AND 0 <= N <= 15 ! ILLEGAL INDEX, IF NOT SPM OR INDEX <0OR >15 V_TAGS_BITS = N; ! INSERT INDEX VALUE V_TAGS_TYPE = 24; ! SPM REG TYPE %RETURN FQ(3): ! N = REC(RP+1); M = REC(RP+2) RP = RP+2 N = 5 %UNLESS 6 <= V_TAGS_TYPE <= 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) %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>>(15-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 CONDITIONAL BREAK %SHORTROUTINE %OWNRECORD SINGLE STEPS(BRKFM) %INTEGER J, R %RECORDNAME C(CONDFM) %SWITCH CND(0 : 6) %RESULT = 0 %IF LSBR = WORD_STAT;! THIS STATEMENT ALREADY CHECKED %IF SINGLE SHOT # 0 %START; ! SINGLE SHOT ENABLED CURBREAK == SINGLE STEPS; ! SET UP BREAK POINTER %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 %IF CCOUNT # 0 %START; ! ANY CONDITIONALS? R = 0; ! CLEAR FLAG %CYCLE J = 1, 1, CCOUNT C == CONPT(J) C_COUNT = C_COUNT-1 %AND -> CONT %IF C_COUNT # 0 ! DECR REPEAT COUNT IF ANY -> CND(C_COND) CND(0): ! HAS VARIABLE CHANGED? C_W = SET FLAG(MODS(C_DESC_TAGS_USED), C_DESC) %C %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(C_DESC); ! WRITE OUT VARIABLE NAME %PRINTTEXT 'HAS CHANGED VALUE TO ' %IF C_DESC_TAGS_TYPE = 2 %C %OR (C_DESC_TAGS_TYPE = 25 %C %AND C_DESC_TAGS_DEFN # 0) %START ! SET OR CLEAR FOR A FLAG OR BUS FLAG %IF C_W # 0 %THEN %PRINTTEXT 'SET' %C %ELSE %PRINTTEXT 'CLEAR' %FINISH %ELSE NUMBER(C_W, 1); ! ELSE WRITE OUT VALUE TO CURRENT BASE NEWLINE -> INC 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(C_DESC); ! WRITE OUT VARIABLE NAME PRINTSTRING(OP(C_COND)); ! CONDITION SATISFIED NUMBER(C_TEST, 1); ! WRITE VALUE TEST WAS AGAINST NEWLINE INC: R = 1; ! INDICATE TRAP HAS OCCURED C_FIRED = 1; ! FLAG CONDTION THAT CAME TRUE CONT: %REPEAT %RESULT = 2 %IF R = 1; ! CONDITIONAL BREAK %RESULT = 0 %IF BCOUNT = 0 %OR SINGLE SHOT # 0 %FINISH LSBR = 0 %RESULT = 0 %IF BCOUNT = 0 %OR SINGLE SHOT # 0 ! NO STATEMENT BREAKS %CYCLE J = 1, 1, BCOUNT %IF BSTATS(J)_IGNORE = WORD_STAT %START;! BREAK SET ON THIS LINE CURBREAK == BSTATS(J) %IF CURBREAK_COUNT <= 0 %THEN %RESULT = 1 ! NO HOLD COUNT! BREAK CURBREAK_COUNT = CURBREAK_COUNT-1; ! DECR REPEAT COUNT %RESULT = 0; ! ! NO BREAK %FINISH %REPEAT %RESULT = 0 %END %ROUTINE COMPILE BLOCK %RECORDNAME TEMP NAME(NAMEFM) %ROUTINESPEC MONITOR %OWNBYTEINTEGER SINT MODE = 0 %OWNSTRING (14) INDEV = 'INPUT' %OWNSTRING (16) %ARRAY OUT(1 : 3) = %C '.TT','.LP','' %INTEGER T, N, J, MI, TL, FLG, SELECT %INTEGER K, LAST, RESULT, CRRNT, LAST RT %BYTEINTEGER FLAGDV2, EN, TRACE %RECORD STORE WORD(CODEFM) %RECORD DV(NAMEFM) %RECORDNAME NP(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) %SWITCH PHRASE(-1 : 24) ! ! %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 %RESULT == SET FLAG(MODS(NAME(WORD_NAME)_TAGS_USED), NAME( %C WORD_NAME)) 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 %ELSE %START ! BUS WANTED DV == NAME(WORD_NAME) 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>>(15-WORD_ADDR&X'FF')&1;! PICK OFF BIT %FINISH %ELSE %START %IF 5 <= MODE <= 6 %START; ! SWITCHES !************************ ! ! NOT YET IMPLEMENTED ! !************************** MONITOR %FINISH %ELSE %RESULT = FMAP(MODE);! OTHERWISE USE FMAP %FINISH %END %ROUTINE TEST ADDRESS(%INTEGER LIMIT, %INTEGERNAME ADDR, %C %STRINGNAME NAME) ! THIS ROUTINE CHECKS FOR INVALID ADDRESSING OF %MEMORY %ROM %SHORTROUTINE %UNLESS 0 <= ADDR <= LIMIT %START; ! CHECK ADDRESS ADDR = 0 PRINTSTRING('* ADDRESS ERROR IN '.NAME.' ') MONITOR; ! 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 : 40) J = V_TAGS_USED -> TYPE(WORD_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 PRINTSTRING('REFERENCE TO UNUSED NAME '.V_TEXT) MONITOR; ! PRINT TRACE BACK %RESULT == DUMP %END !THIS CONVERTS SYMBOLS AND VALYES 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) %INTEGER ADDR, J, K %SHORTINTEGERARRAYNAME Z %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? %STRING(7) FIDDLE %SWITCH TYPE(0 : 36) J = V_TAGS_USED; K = V_TAGS_TYPE %RETURN %IF (J = 0 %AND K # 25) %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 %IF V_TAGS_DEFN # 0 ! BUS FLAG WANTED NUMBER(BUS1_BUSREG, 4) NEWLINE %PRINTTEXT ' OVF:'; CS(BUS1_OVF) %PRINTTEXT ' DZ:'; CS(BUS1_DZ) %PRINTTEXT ' DN:'; CS(BUS1_DN) %PRINTTEXT ' 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) NUMBER(MODS(J)_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(MODS(J)_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 %IF V_TAGS_WHERE < 0 %THEN ADDR = \V_TAGS_WHERE %C %ELSE ADDR = MMODS(J)_MEMADDR ! DIRECT ADDRESS? Z == MMODS(J)_STORE NUMBER(ADDR, 4); ! WRITE OUT ADDRESS %IF 0 <= ADDR <= MMODS(J)_LIMIT %START; ! CHECK ADDRESS %PRINTTEXT ' ['; NUMBER(Z(ADDR), 0); %PRINTTEXT ' ]' ! WRITE OUT CONTENTS %FINISH %ELSE %PRINTTEXT ' 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 %PRINTTEXT 'IN:'; NUMBER(MODS(J)_A, 4); ! CONTENTS STORED %PRINTTEXT ' OUT:' NUMBER(GET TREG(V_TAGS_WHERE, MODS(J)_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 PRINTSTRING(''''.CHAR(MODS(J)_A).''' : '''.CHAR(MODS(J)_B). %C ''' KF:') CS(MODS(J)_F1); ! KF %PRINTTEXT ' PF:'; CS(MODS(J)_F2); !PF %PRINTTEXT ' OVR:'; CS(MODS(J)_F3); ! OVR %PRINTTEXT ' 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 %PRINTTEXT ' CLEAR' %C %ELSE %PRINTTEXT ' 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 %INTEGERFNSPEC NEXT SYM INDEV <- NAME(WORD_NAME)_TEXT; ! NAME FOR PROMPT %CYCLE RP = 0; LP = 0 %EXIT %IF CONSTANT FOUND(NEXT SYM) # 0; ! READ CONSTANT, 0 IF ERROR BUFFER(BUFNO)_SYMS = 0; ! SCRAP ALL INPUT SO FAR FAULT(0); ! QUERY %REPEAT N = REC(1); ! GET VALUE THAT WAS READ IN BUFFER(BUFNO)_SYMS = BUFFER(BUFNO)_SYMS+1; ! ADJUST BUFFER POINTERS BUFFER(BUFNO)_PT = BUFFER(BUFNO)_PT-1 %RETURN %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 %INTEGER BUF, N, RES %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 : 3 - %SET ! 4 - %CLEAR ! 5 - %COMPLEMENT ! %SHORTROUTINE %IF TYPE = 3 %THEN MODS(CRRNT)_F1 = 1 %IF TYPE = 4 %THEN MODS(CRRNT)_F1 = 0 %IF TYPE = 5 %THEN MODS(CRRNT)_F1 = MODS(CRRNT)_F1!!1 %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>>(15-J)&1; ! BIT FROM SOURCE N = N!(B<<(15-LIST_BIT(J))) %REPEAT %FINISHELSE N=VALUE SHORT=N;! TO SET THE SIGN CORRECTLY DUMMY:! TO FORCE A LOAD(I.E. FORGET SHORT) %RESULT = SHORT %END %INTEGERFN SYMBOL(%INTEGER BUFNO) ! THIS FUNCTION RETURNS THE VALUE OF THE NEXT CHARACTER ! IN THE ADDRESSED INPUT BUFFER, IF IT IS EMPTY THE USER IS ! PROMPTED FOR MORE INPUT %SHORTROUTINE %RECORDNAME BB(IOBUFFM) %BYTEINTEGER S %IF BUFNO = 0 %START; ! NOT A BUFFER PRINTSTRING('SPURIOUS BUFFER FOR '.V_TEXT) %RESULT = NL %FINISH BB == BUFFER(BUFNO) %IF BB_TYPE # 0 %START; ! TYPE ERROR PRINTSTRING('OUTPUT USED AS INPUT ON '.V_TEXT) MONITOR %RESULT = NL %FINISH %IF BB_SYMS <= 0 %START; ! BUFFER EMPTY PROMPT(INDEV.':'); ! PROMPT WITH NAME %UNTIL S = NL %CYCLE; ! READ IN INPUT LINE READSYMBOL(S) BB_SYMS = BB_SYMS+1; ! INCR BUFFER POINTER BB_TEXT(BB_SYMS) = S; ! STORE CHAR %REPEAT PROMPT(' :'); ! RESET SYSTEM PROMPT BB_PT = 0; ! POINT OT FIRST CHAR %FINISH BB_SYMS = BB_SYMS-1; BB_PT = BB_PT+1;! ADJUST POINTERS %RESULT = BB_TEXT(BB_PT); ! EXTRACT CHAR %END %ROUTINE PRINT(%INTEGER BUFNO, SYM) ! THIS ROUTINE OUTPUTS TO THE ADDRESSED BUFFER, IF IT FILLS !THE CONTENTS ARE WRITTEN ONTO THE CONSOLE TO EMPTY !THE BUFFER %SHORTROUTINE %RECORDNAME BB(IOBUFFM) %STRING (8) VNAME %INTEGER J %IF BUFNO <= 0 %START; ! ERROR PRINTSTRING('SPURIOUS BUFFER FOR '.V_TEXT) MONITOR %RETURN %FINISH BB == BUFFER(BUFNO) %IF BB_TYPE # 1 %START; ! TYPE ERROR PRINTSTRING('INPUT USED AS OUTPUT ON '.V_TEXT) MONITOR %RETURN %FINISH %IF SYM = NL %OR BB_SYMS <= 0 %START; ! CLEAR BUFFER VNAME <- NAME(BB_OWNER)_TEXT; ! TRUNCATE NAME PRINTSTRING(VNAME.':'); ! IDENTIFY BUFFER K = BB_PT %IF K > 0 %START %CYCLE J = 1, 1, K; ! OUTPUT BUFFER CONTENTS PRINTCH(BB_TEXT(J)) %REPEAT %FINISH NEWLINE BB_PT = 0; BB_SYMS = 64; ! ADJUST POINTERS %RETURN %IF SYM = NL %FINISH BB_SYMS = BB_SYMS-1; BB_PT = BB_PT+1 BB_TEXT(BB_PT) = SYM; ! INSERT CHARACTER %END %ROUTINE FORCE OUTPUT ! THIS ROUTINE EMPTIES ALL BUFFERS WHEN THE PROGRAM IS ! HALTED %SHORTROUTINE %INTEGER J %RETURN %IF BUFFERS = 0; ! NO BUFFERS %CYCLE J = 1, 1, BUFFERS; ! ROUND ALL BUFFERS PRINT(J, NL) %IF BUFFER(J)_TYPE = 1 %AND BUFFER(J)_PT # 0 ! OUTPUT ONLY %REPEAT %END %ROUTINE MONITOR ! THIS ROUTINE GIVES A TRACE BACK OF THE PATH ! TAKEN TO REACH THE CUURENT POINT , THE ONLY THING ! TRACED IS ROUTINE ENTRY %SHORTROUTINE %INTEGER J, K %RECORDNAME CODE(CODEFM) %RECORDNAME RT(RTFM) %PRINTTEXT ' ** MONITOR ** ' J = LAST RT K = PC-1; ! BACK TO FAILING STATEMENT %WHILE J # 0 %CYCLE; ! ROUND EVERY ROUTINE CALLED RT == RETAD(J); %EXIT %IF RT_RA < 2; ! RETURN ERROR CODE == OBJECT(RT_RA-1) %PRINTTEXT 'LINE'; WRITE(OBJECT(K)_STAT, 1) %PRINTTEXT ' OF ' PRINTSTRING(NAME(CODE_NAME)_TEXT) NEWLINE K = RT_RA-1 J = RT_LAST RT; ! GET NEXT ROUTINE IN CHAIN %REPEAT %PRINTTEXT 'MAIN PROGRAM LINE'; WRITE(OBJECT(K)_STAT, 1) NEWLINE %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 %INTEGERFN EVOKE ARITH OP(%INTEGER OP) ! THIS PERFORMS THE ARITHMETIC OPERATIONS FOR EVOKE ! INSTRUCTIONS %SHORTROUTINE %SWITCH EVOKEOP(1 : 50) %INTEGER RESULT,A ! -> EVOKEOP(OP) ! EVOKEOP(1): ! LOAD A REG ONTO BUS %RESULT = MODS(CRRNT)_A EVOKEOP(2): ! LOAD B REG ONTO BUS %RESULT = MODS(CRRNT)_B EVOKEOP(3): ! NOT %RESULT = \MODS(CRRNT)_A EVOKEOP(4): ! NOT B %RESULT = \MODS(CRRNT)_B EVOKEOP(5):!*2 AND OR IN RSI %RESULT = MODS(CRRNT)_A<<1!MODS(CRRNT)_F2 EVOKEOP(6): ! A+1 %RESULT = MODS(CRRNT)_A+1 EVOKEOP(7): ! A-1 %RESULT = MODS(CRRNT)_A-1 EVOKEOP(8): ! A+B %RESULT = MODS(CRRNT)_A+MODS(CRRNT)_B EVOKEOP(9): ! A-B %RESULT = MODS(CRRNT)_A-MODS(CRRNT)_B EVOKEOP(10): ! A&B %RESULT = MODS(CRRNT)_A&MODS(CRRNT)_B EVOKEOP(11): ! A XOR B %RESULT = MODS(CRRNT)_A!!MODS(CRRNT)_B EVOKEOP(12): ! A OR B %RESULT = MODS(CRRNT)_A!MODS(CRRNT)_B EVOKEOP(13): ! SET TO ZERO %RESULT = 0 EVOKEOP(36): ! LOAD %IF WORD_MODULE = 12 %START; ! SI INDEV <- NAME(WORD_NAME)_TEXT;! SET UP NAME FOR PROMPT %RESULT = SYMBOL(NAME(WORD_NAME)_TAGS_WHERE&X'00FF') %C %IF SINT MODE = 0 MY READ(NAME(WORD_NAME)_TAGS_WHERE&X'00FF',A) %RESULT=A ! READ A SYMBOL %FINISH %IF 9 <= WORD_MODULE <= 10 %OR WORD_MODULE = 26 %START ! GPI,ININT,GPI_IN MYREAD(V_TAGS_WHERE&X'00FF', RESULT); ! READ A VALUE MODS(CRRNT)_A <- RESULT; ! STORE VALUE IN INPUT SIDE %RESULT = RESULT %FINISH %IF WORD_MODULE = 5 %START; ! C GEN %RESULT = CONSTANTS(WORD_NAME) %FINISH %IF WORD_MODULE = 7 %OR WORD_MODULE = 6 %START ! TREG OR BREG RESULT = GET TREG(V_TAGS_WHERE, MODS(CRRNT)_A) ! TRANSFORM OUTPUT %RESULT = FIELD(RESULT, WORD_ADDR);! EXTRACT FIELD %FINISH %IF WORD_MODULE = 24 %START; ! SPM REG DUM1 == MMODS(CRRNT)_STORE %RESULT = DUM1(WORD_ADDR); ! INDEX IN ADDR %FINISH EVOKEOP(35): EVOKEOP(37): %RESULT = BUS1_BUSREG; !LOAD BUS REG %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=1 %UNLESS -32768 <= RESULT <= 32767 %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) %INTEGER ADDR -> EVKDEST(INDEX) EVKDEST(1): ! STORE IN 'A' REG MODS(CRRNT)_A <- RESULT %RETURN EVKDEST(2): ! STORE IN 'B' REG MODS(CRRNT)_B <- RESULT %RETURN EVKDEST(3): ! STORE IN BUS REG BUS1_BUSREG <- 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 %PRINTTEXT ' SPURIOUS DESTINATION' NUMBER(INDEX, 1); NEWLINE MONITOR 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 : 10) -> EVOKE DEST(OP) EVOKEDEST(0): ! VARIOUS DESTINATIONS %IF WORD_MODULE = 9 %OR WORD_MODULE = 11 %C %OR WORD_MODULE = 27 %START ! GPINT, OUTINT , GPINT _OUT SEND; ! TRANSMIT VALUE %IF WORD_MODULE = 11 %THEN MODS(CRRNT)_A <- RESULT %C %ELSE MODS(CRRNT)_B <- RESULT ! PUT VALUE IN 'A' IF OUTINT, ELSE PUT IT IN 'B' %RETURN %FINISH %IF WORD_MODULE = 3 %START; ! MEMORY ADDRESS REG MMODS(CRRNT)_MEMADDR <- RESULT %RETURN %FINISH %IF 6 <= WORD_MODULE <= 7 %START;! TREG BREG MODS(CRRNT)_A <- RESULT %FINISH %RETURN EVOKEDEST(1): ! STORE IN 'A' TYPE REG MODS(CRRNT)_A <- RESULT %RETURN EVOKEDEST(2): ! STORE IN 'B' TYPE REG MODS(CRRNT)_B <- RESULT %RETURN EVOKEDEST(3): ! ERROR TO REACH HERE EVOKEDEST(10): %PRINTTEXT ' SPURIOUS DESTINATION ' NUMBER(OP, 1) MONITOR %RETURN EVOKEDEST(4): ! <0:3> MM == MODS(CRRNT)_A MM <- MM&X'FFF0'!RESULT&X'000F' %RETURN EVOKEDEST(5): ! <0:7> MM == MODS(CRRNT)_A MM <- MM&X'FF00'!RESULT&X'00FF' %RETURN EVOKEDEST(6): ! <8:15> MM == MODS(CRRNT)_A MM <- MM&X'F000'!RESULT&X'0FFF' %RETURN EVOKEDEST(7): ! 'A' TYPE REG MODS(CRRNT)_A <- RESULT %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 DUM1 == MMODS(CRRNT)_STORE DUM1(ADR) <- RESULT %END %ROUTINE SIMULATE(%INTEGER MODE) ! THIS ROUTINE SIMULATES THE OBJECT CODE IN THE ARTHUR FILE %INTEGER STATEMENT,INDEX %SWITCH INSTR(0 : 15) %IF MODE = 0 %START; ! %GO OR %CONTINUE? ROUND: WORD == OBJECT(PC); PC = PC+1; ! POINT TO CURRENT INSTR AND INCR PCOUNT STATEMENT = WORD_STAT; ! GET STATEMENT NUMBER %IF STATEMENT#LAST%START ->BRK%IF TESTINT(0,'WAIT')#0;! USER HAS INTERUPTED %IF TRACE # 0 %START ! WRITE LINE NUMBER IF TRACE ON AND NEW STATEMENT SELECTOUTPUT(77); ! SELECT TRACE OUTPUT NUMBER(STATEMENT, 1); ! PRINT LINE NUMBER SELECTOUTPUT(0); ! RESELECT CONSOLE %FINISH EN = BREAKHERE; ! SAVE BREAK TYPE %IF EN # 0 %START; ! BREAKPOINT REACHED LSBR = STATEMENT; ! SAVE STATEMENT NUMBER BRK: STBR = 1; ! SET FLAG FORCE OUTPUT; ! CLEAR BUFFERS %PRINTTEXT 'BREAKPOINT LINE';! OUTPUT MESSAGE WRITE(STATEMENT, 1) NEWLINE %RETURN %FINISH %FINISH %FINISH %ELSE WORD == OBJECT(PC-1); ! RESTORE IT LAST=STATEMENT;! SAVE STATEMENT NUMBER %IF 0 < WORD_NAME <= NNAMES %START; ! POINT TO NAME IF VALID V == NAME(WORD_NAME); CRRNT = V_TAGS_USED %FINISH -> INSTR(WORD_CODE) INSTR(0): ! NOP -> ROUND INSTR(1): ! EVOKE J = WORD_OPRN; ! GET OPERATION %IF 17 <= J <= 28 %THEN J = J&15 %AND FLAGDV2 = 1 %C %ELSE FLAGDV2 = 0 ! /2 SPECIFIED, SET FLAG AND ADJUST OPERATION CODE RESULT = EVOKE ARITH OP(J); ! PERFORM OP %IF FLAGDV2 = 1 %THEN RESULT = RESULT>>1!MODS(CRRNT)_F1<<15 ! PERFORM /2 IF WANTED, AND OR IN LSI SET BUS %IF WORD_MODULE = 24 %AND J = 13 %START; ! SET SPM REG TO 0 DUM1 == MMODS(CRRNT)_STORE DUM1(WORD_ADDR) = 0 -> ROUND %FINISH %IF WORD_ADDR = 0 %START %IF WORD_MODULE = 12 %START; ! SI %IF J = 35 %START; ! ENABLE MODS(CRRNT)_F4 = 1; -> ROUND %FINISH MODS(CRRNT)_F4 = 0; ! REMOVE ENABLE MODS(CRRNT)_A = RESULT; ! STORE VALUE %FINISH -> ROUND %FINISH DEPOSIT IN(WORD_ADDR) %IF WORD_MODULE # 24 ! PERFORM STORE UNLESS SPM -> ROUND INSTR(2): ! BUS -> ROUND INSTR(3): ! CONDITION %IF 3 <= WORD_OPRN <= 4 %START; ! WAITUNTIL CONDITION %IF CONTROL&2 = 0 %START; ! PRINT MESSAGE IF NOT INHIBITED %PRINTTEXT ' WAITING ' PRINTSTRING(WHUN(WORD_OPRN).V_TEXT.EXTENSION(WORD_ %C MODULE)) NEWLINE %FINISH FMAP(WORD_ADDR>>8&X'FF') = WORD_OPRN-3; ! SET FLAG TO APPROPRIATE VALUE PC = PC+1; ! SKIP JUMP -> ROUND %FINISH ! IF-UNLESS CONDITION J = EXTRACT; ! GET FLAG VALUE PC = PC+1 %IF J = WORD_OPRN-1; ! SKIP IF COND SATISFIED -> ROUND INSTR(4): !MERGE -> ROUND INSTR(5): ! ROUTINE CALL DV = NAME(WORD_NAME); ! ROUTINE NAME TAGS J = DV_TAGS_USED RT == RETAD(J); ! POINT AT ROUTINE'S DATA AREA RT_RA = PC; ! SAVE RETURN ADDRESS RT_LAST RT = LAST RT ! SAVE NAME OF CURRENT ROUTINE(IF ANY) FOR TRACE BACK LAST RT = J; ! MAKE THIS THE CURRENT ROUTINE PC = WORD_ADDR; ! ADJUST PCOUNT -> ROUND INSTR(6): ! ROUTINE RETURN DV = NAME(WORD_ADDR) J = DV_TAGS_USED RT == RETAD(J) %IF RT_RA = 0 %START; ! NO RETURN ADDRESS!!!!!!!! %PRINTTEXT ' RETURN ERROR IN ROUTINE ' MONITOR -> STOP %FINISH PC = RT_RA; RT_RA = 0; ! RETURN PC AND CLEAR RET ADDR LAST RT = RT_LAST RT; ! RESET LAST ROUTINE NAME -> ROUND INSTR(7): ! JUMP PC = WORD_ADDR; ! ADJUST PCOUNT -> ROUND INSTR(9): ! 8 WAY BRANCH TL = 0; ! CLEAR 8-WAY BRANCH CONTROL VARIABLES SELECT = 0 KWORD == WORD; ! POINT TO THIS INSTRUCTION -> ROUND INSTR(10): ! TEST LINE FOR 8 WAY BRANCH %IF WORD_NAME = 0 = WORD_MODULE %C %THEN FLG = WORD_ADDR>>8-1 %ELSE FLG = EXTRACT ! GET TEST LINE VALUE !%HIGH,%LOW OR FLAG FLG = 1 %IF FLG # 0; ! ADJUST FLAG VALUE SELECT = SELECT<<1!FLG; ! BUILD UP ADDRESS %IF TL = 2 %START; ! ALL TEST LINES EXTRACTED DV = NAME(KWORD_NAME); ! GET BRANCH TAGS INDEX=TABLES(DV_TAGS_WHERE)_W(SELECT); !GET BRANCH ADDRESS %IF INDEX = 0 %START; ! LABEL NOT SET!!!!! PRINTSTRING(' LABEL '.DV_TEXT.'(') PRINTSYMBOL('0'+SELECT) %PRINTTEXT ') NOT DEFINED ' MONITOR -> STOP %FINISH PC=INDEX %FINISH TL = TL+1 -> ROUND INSTR(11): ! BREAKPOINT CURBREAK == BREAKPOINT(CRRNT); ! SAVE WHICH BREAKPOINT CURBREAK_COUNT = CURBREAK_COUNT-1 %UNLESS CURBREAK_COUNT = 0 ! DECR COUNT IF ANY -> ROUND %IF CURBREAK_IGNORE # 0 %OR CURBREAK_COUNT # 0 ! NO EFFECT IF IGNORED OR HELD FORCE OUTPUT; ! CLEAR BUFFERS PRINTSTRING('BREAKPOINT '.V_TEXT.' ');! PRINT MESSAGE PC=PC+1;! TO SKIP BREAKPOINT INSTRUCTION %RETURN INSTR(15): ! EXTRA EVOKE FOR WOMBLE INSTR(12): ! CONTINUATION FOR EVOKE %IF WORD_MODULE = 12 %START; ! SINT MODS(CRRNT)_B = RESULT; ! STORE RESULT PRINT(V_TAGS_WHERE>>8, RESULT); ! OUTPUT VALUE -> ROUND %FINISH %IF WORD_MODULE = 24 %START; ! SPM REG STORE DUM1 == MMODS(CRRNT)_STORE DUM1(WORD_ADDR) <- RESULT -> ROUND %FINISH STORE(WORD_ADDR); ! OTHERWISE DO STORE INSTR(13): ! CONTINUATION MERGE -> ROUND INSTR(14): ! FLAG OPERATION FLAG OP(WORD_OPRN); ! DO FLAG OPERATION -> ROUND STOP: INSTR(8): ! STOP STPFLAG = 1; ! SET FLAG TO PREVENT %CONTINUE %PRINTTEXT ' STOPPED AT LINE' WRITE(WORD_STAT, 1); ! LINE NUMBER NEWLINE %END ! N = BUFFERS %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 BUF == BUFFER(BUFFERS) BUF = 0; ! CLEAR NEXT FREE BUFFER BUF_OWNER = BLIST; ! SET UP OWNER NAME %IF J = 0 %THEN BUF_TYPE = NP_TAGS_TYPE&1 %C %ELSE BUF_TYPE = K ! SET UP TYPE (IN=0,OUT=1) NP_TAGS_WHERE = NP_TAGS_WHERE!(BUFFERS<<(BUF_TYPE<<3)) ! PACK BUFFER ADDRESSES BUF_SYMS = 80 %IF BUF_TYPE = 1; ! INITIALIZE OUTPUT BUFFERS = BUFFERS-1; ! DECR NO. OF BUFFERS %REPEAT BLIST = L; ! NEXT IN CHAIN %REPEAT %IF BUFFERS > 1 %START; ! ERROR %PRINTTEXT ' BUFFER ALLOCATION FAILS ' %MONITORSTOP %FINISH BUFFERS = N-BUFFERS; ! RESTORE NUMBER OF BUFFERS STPFLAG = 1; ! SET FLAG TO PREVENT %CONTINUE TRACE = 0; ! TRACE OFF LAST = -2 1: PHRASE(-1): 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 RP = RP+1 %IF EN # 0 %START %IF EN = 1 %THEN CURBREAK_COUNT = REC(RP) %ELSE %START ! FOR STAT OR PROG BREAK USE CURBREAK , FOR COND SEARCH LIST %IF CCOUNT # 0 %START; ! ALL BREAKPOINTS MAY HAVE BEEN CANCELED! %CYCLE J = 1, 1, CCOUNT C == CONPT(J) C_FIRED = 0 %AND C_COUNT = REC(RP) %IF C_FIRED = 1 ! COND BREAK THAT HAS CAUSED THE HALT (MAY BE MORE THAN ONE) %REPEAT %FINISH %FINISH %FINISH STBR = 0; ! CLEAR FLAG SIMULATE(1); ! CONTINUE SIMULATING -> 1 PHRASE(2): ! (LOCATION) <- (PLUS') !(CONSTANT) RP=RP+1 %IF REC(RP) = 0 %THEN LOCATION(DV) %ELSE DV=DUMMYNAME RP = RP+1; N = REC(RP+1); ! GET CONSTANT N = -N %IF REC(RP) # 0; ! NEGATIVE? FAULTS = 0 WORD == STORE WORD; ! FAKE INSTR FOR SMAP WORD_MODULE = DV_TAGS_TYPE 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 ! LSBR = 0; STBR = 0 STPFLAG = 0 PC = HEADER_STARTAD; ! GET START ADDRESS SIMULATE(0); ! SIMULATE -> 1 ! PHRASE(4): !%TRACE (ON-OFF) RP = RP+1 %IF REC(RP) = 0 %THEN TRACE = 0 %ELSE %START ! %TRACE %OFF !%TRACE %ON 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') %UNTIL REC(RP) = 0 %CYCLE; ! ROUND TILL END OF COND LIST CCOUNT = CCOUNT+1; ! INCREMENT COND TRAP COUNT C == CONPT(CCOUNT); C = 0 ! SET UP POINTER TO NEXT COND RECORD AND ZERO IT RP = RP+1 %IF REC(RP) # 0 %THEN DV = DUMMY NAME %ELSE LOCATION(DV) ! EITHER SET UP TAGS FOR BUS OR GET LOCATION INFO MI = DV_TAGS_TYPE C_DESC = DV; ! PUT TAGS IN COND RECORD %IF Q(MI) = 0 %START; ! ERROR. LOCATION NOT CONDABLE PRINTSTRING(C_DESC_TEXT) %PRINTTEXT ' NOT VALID ' C_W == NMT; ! POINT C_W TO ANYWHERE TO PREVENT ADDRESS ERRORS CCOUNT = CCOUNT-1; !DECREMENT COND COUNT %FINISH %ELSE %START WORD == OBJECT(0); WORD_MODULE = MI ! SET UP PSEUDO INSTRUCTION FOR MAPPING ROUTINE C_W == SMAP(C_DESC); ! SET UP POINTER TO TRAPPED LOCATION %FINISH RP = RP+1 C_FLAG = 1 %C %IF (DV_TAGS_TYPE = 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) %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) SHOW(DUMMY NAME); ! DISPLAY THE BUS CONTENTS %IF NNAMES > 0 %START; ! ANY NAMES? %CYCLE J = 1, 1, NNAMES; ! ROUND FOR EVERY NAME SHOW(NAME(J)); ! WRITE OUT VALUE AND NAME %REPEAT %FINISH SELECTOUTPUT(0); ! SELECT CONSOLE AGAIN -> 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 %IF REC(RP) = 0 %START; ! IGNORE ALL %CYCLE J = 1, 1, BC; ! ROUND ALL BREAKPOINTS BREAKPOINT(J)_IGNORE = 1; ! SET FLAG %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(DV_TAGS_USED)_IGNORE = 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 ! RP = RP+1 %IF REC(RP) = 0 %START; ! REPLACE ALL %CYCLE J = 1, 1, BC; ! ROUND ALL BREAKPOINTS BREAKPOINT(J) = 0; ! CLEAR FLAG %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(DV_TAGS_USED) = 0 ! CLEAR FLAG %REPEAT -> 1 PHRASE(14): ! %ENDOFSIM %PRINTTEXT '#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 CCOUNT = 0 %AND -> 1 %IF REC(RP) = 0; ! REMOVE ALL BREAKPOINTS %UNTIL REC(RP) = 0 %CYCLE; ! ROUND UNTIL END OF LIST RP = RP+1 %IF REC(RP) = 0 %THEN LOCATION(DV) %ELSE DV = DUMMY NAME ! GET TAGS FOR LOCATION OR GENERATE BUS TAGS %CYCLE J = 1, 1, CCOUNT; !ROUND FOR NUMBER OF BREAKS C == CONPT(J); ! POINTER TO CURRENT BREAK INFO C_FIRED = 2 %C %IF C_DESC_TEXT = DV_TEXT %AND C_DESC_TAGS_ %C TYPE = DV_TAGS_TYPE ! SET FIRED TO 2 IF LOCATION MATCHES TRAPPED LOCATION %REPEAT RP = RP+1 %REPEAT; ! UNTIL END OF LIST T = 0; ! NO BREAKS AS YET REMOVED %CYCLE J = 1, 1, CCOUNT; ! ROUND FOR NUMBER OF TRAPS C == CONPT(J); ! POINT TO CURRENT BUGLAB: %IF C_FIRED = 2 %THEN T = T+1 %ELSE CONPT(J-T) = C ! IF BREAK IS TO BE REMOVED(FIRED=2) THEN INCREMENT T !ELSE COPY THIS RECORD 'T' RECORDS DOWN ARRAY TO COMPACT STORAGE %REPEAT CCOUNT = CCOUNT-T; ! ADJUST NUMBER OF BREAKS -> 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 %UNTIL REC(RP) = 0 %CYCLE RP = RP+1; N = REC(RP) BCOUNT = BCOUNT+1; ! INCR BREAK COUNT BSTATS(BCOUNT)_COUNT = 0; ! CLEAR HOLD COUNT BSTATS(BCOUNT)_IGNORE = N; ! STORE LINE NUMBER 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 %ELSE FAULT(0) ! CLEAR SS ,OR ESLE GIVE FAULT -> 1 %FINISH SINGLE SHOT = 0 BCOUNT = 0 %AND -> 1 %IF REC(RP+1) = 0 !REMOVE ALL STATEMENT BREAKS %UNTIL REC(RP) = 0 %CYCLE RP = RP+1 %CYCLE J = 1, 1, BCOUNT; ! COMPARE WITH ALL BREAKS BSTATS(J)_IGNORE = -1 %IF BSTATS(J)_IGNORE = REC(RP) ! SET SIGNAL THAT THIS BREAK FREED %REPEAT RP = RP+1 %REPEAT T = 0 CURBREAK==DUMMY BREAK%IF CURBREAK_IGNORE=-1 %CYCLE J = 1, 1, BCOUNT; ! COMPACT ARRAY BUGLAB2: %IF BSTATS(J)_IGNORE = -1 %THEN T = T+1 %C %ELSE BSTATS(J-T) = BSTATS(J) ! INCR FREED COUNT OR MOVE VALUE DOWN %REPEAT BCOUNT = BCOUNT-T; ! ADJUST BREAK COUNT -> 1 PHRASE(18): ! CONTROL ! %CONTROL 1 ENABLES PRINTING OF ANALYSIS RECORDS ! %CONTROL 2 ENABLES INHIBIT OF MESSAGES !%CONTROL 4 (%TRAPS) PRINTS OUT BREAKPOINT !%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 DISPLAY %AND -> 1 %IF N = 7 SDISPLAY%AND ->1 %IF N=15;! DISPLAY NAME TAGS FOR SYSTEM CONTROL <- N -> 1 PHRASE(21): ! %CLEAR %BUS BUS1 = 0; BUS1_DZ = 1; -> 1; ! ZERO BUS AND SET DZ PHRASE(23): ! %RADIX %IF REC(RP+1) <= 0 %THEN FAULT(0) %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 PC = TEMP NAME_TAGS_WHERE+1 PRINTSTRING('CONTINUING FROM '.TEMP NAME_TEXT) NEWLINE ->PHRASE(1) %END; ! OF COMPILE BLOCK ! CLEAR OUT MEMORY SPACE, ROUTINE SPACE AND BREAKPOINT SPACE %CYCLE PC = 1, 1, MQ STR(PC) = 0 %REPEAT %CYCLE PC = 1, 1, RC RETAD(PC) = 0 %REPEAT %CYCLE PC = 1, 1, BC BREAKPOINT(PC) = 0 %REPEAT ! CLEAR SYSTEM VARIABLES STBR = 0; SINGLE SHOT = 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 V1_MASTER # N %START; ! EQUIVALENCED NAME 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 %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 DUMMY BREAK =0;! CLEAR DUMMY BREAKPOINT CURBREAK == DUMMY BREAK;! TO PREVENT ERRORS COMPILE BLOCK; ! RUN %END %END; ! OF SAM %ENDOFFILE