.TITLE DDT -- DYNAMIC DEBUGGING AID R$$11M=0 ; RSX11M VERSION RKB002 O$$DFL=0 ; FULL DDT M$$MGE=0 ; DETECT SEGMENT FAULT ERRORS T$$BUG=0 ; SPECIAL CASE FOR .PSECT $$$SYM ; MAKE SURE BEFORE DDT .PSECT $$$DDT .IF DF R$$11M .IDENT /M01/ .IFF .IDENT /D01/ .ENDC ;COPYRIGHT 1976, DIGITAL EQUIPMENT CORP., MAYNARD MASS. 01754 ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR ; RELIABILITY OF ITS SOFTWARE ON EQUIPMENT ; WHICH IS NOT SUPPLIED BY DEC. ; ; THIS SOFTWARE IS FOR INTERNAL USE ONLY. ; ; VERSION: 01 ; ;MIKE SMITH 03/24/73 ; MODIFIED BY : H. LEV ; ; DATE ; SEP-73 MODIFIED TO RUN ON RSX11D OR RSX11M ; NOV-73 ADDED EXTERNAL SYMBOLS .ODTL1 AND .ODTL2 ; WHICH ARE FILLED BY THE TASK BUILDER WITH THE ; LOGICAL UNIT NUMBERS FOR THE TTY AND LINE PRINTER ; ASSIGNED AUTOMATICALLY FOR ODT. ; MAR-74 REMOVED EIS INSTRUCTIONS ; APR-74 ADDED TEST FOR RTT AND RTI INSTRUCTIONS ; MAY-74 FIXED MINOR BUGS ; AUG-74 FIXED MINOR BUGS ; ; HJL004 10/25/75 ADD CONDITIONALS TO GENERATE SUBSET ; OF COMMANDS FOR SHORT ODT ; AUG-76 MODIFIED 'JDT' TO BECOME 'DDT' INCLUDING ; ABILITY TO INTERPRET TASK .STB FILE ; ; MODIFIED BY RICHARD K. BENNETT, LOCKHEED MISSILES & SPACE, PALO ALTO, CA ; JUN-78 MODS AND BUG FIXES AS FOLLOWS: ; ; 1. ELIMINATED EXTRA TYPEOUT ON THE COMMAND. (PREVIOUSLY, ; THE EXTRA PRODUCED THE EFFECT OF DOUBLE-SPACING.) ; ; 2. MADE INSTRUCTION-MODE TYPEOUT LEGAL FOR THE "L" COMMAND. ; NB: AT THE END OF SUCH A TYPEOUT "." IS LEFT EQUAL TO THE LOCATION ; LAST TYPED. ; ; 3. CHANGED THE HI LIMIT IN THE "L" COMMAND FROM THE LAST ADDRESS ; TO THE NEXT ADDRESS BEYOND. EG: 100;200 (FORMERLY: 100;177) ; ; 4. CHANGED THE ":" COMMAND FROM (FIRST;LENGTH) TO (FIRST;NEXT), ; WHERE "NEXT" MEANS NEXT LOCATION BEYOND. EG: 100;200:ABC ; (FORMERLY: 100:100:ABC). NB: THE SYMBOL TABLE ENTRY IS CHANGED ; ACCORDINGLY. ; ; 5. FIXED BUG, WHERE ERROR IN "?" COMMAND, WHICH WAS DETECTED ; AFTER THE TERMINATING , CAUSED AN OVERPRINT. ; ; 6. FIXED BUG, WHICH CAUSED SPURIOUS TYPEOUT AFTER AN "OD" ERROR. ; ; 7. REMOVED OPTION (O$$DFL) TO NOT BUILD THE FULL DDT. ; ; 8. : ; A. ELIMINATED THE "FEATURE" WHERE WAS CONVERTED TO "+". ; B. ALLOWED 'S BEFORE & AFTER COMMANDS AND ARGUMENTS, ETC. ; THIS PERMITS COMMANDS WHICH BEFORE WERE ILLEGAL, SUCH AS: ; ; _#TPM G ; _#ABC;#DEF L ; 9. FIXED BUG WHERE "TRAP" INSTRUCTION WAS TYPED AS "EMT". ; ; 10. SPECIAL CASE: IS TYPED AS "DBUG NNNNNNN" ; WHERE "NNNNNNN" IS THE OCTAL VALUE OF THE WORD FOLLOWING THE TRAP. ; NB: THIS SPECIAL CASE CAN BE ELIMINATED BY REMOVING T$$BUG FROM PAGE 1. ; ; 11. ADDED INSTRUCTION: HALT,WAIT,RTI,IOT,RESET,RTT. ; NB: RESET IS SPELLED "RSET" TO CONFORM TO 4-CHARACTER LIMIT. ; ; 12. SMALL INDEX OFFSETS AND LITERALS (#) ARE NOW TYPED AS SIGNED ; OCTAL INTEGERS, RATHER THAN AS IRRELEVANT SYMBOLS. ; NB: VALUE OF SMALL IS IN CELL "SMALL", A GLOBAL. ; ; 13. LITERAL (#) MASKS FOR BIC, BIT, & BIS INSTRUCTIONS ARE TYPED ; AS OCTAL NUMBERS, RATHER THAN AS MEANINGLESS LOCATION SYMBOLS. ; ; 14. WHEN A VALUE IS SEARCHED FOR ITS SYMBOLIC EQUIVALENT, THE ; FIRST SEARCH IS IN THE SYMBOL TABLE WITHIN DDT AND THE BEST MATCH ; IS FOUND (AS BEFORE). BUT NOW, IF THE VALUE IS WITHIN THE RANGE OF ; ANY SYMBOL, THEN THE BEST SYMBOL (PLUS OFFSET) IS USED, RATHER THAN ; TRYING TO FIND A CLOSER MATCH IN THE EXTERNAL SYMBOL TABLE. ; FOR EXAMBLE: "DDT" HAS AN ENTRY IN THE INTERNAL SYMBOL ; TABLE WITH A RANGE CORRESPONDING TO THE SIZE OF DDT. HOWEVER, ; IF THE USER OPENS AN EXTERNAL SYMBOL TABLE (STB FILE),THEN ; ".ODTL2" IS DEFINED WITHIN DDT, AND THIS SYMBOL WAS USED, WHICH ; CERTAINLY WAS NOT WANTED. ; ; 15. WHEN A SYMBOL IS DEFINED BY ":", THE 2ND ARG DEFAULTS TO THE ; 1ST ARG +1. ; ; 16. A SPACE MAY BE USED (INSTEAD OF THE PREVIOUSLY REQUIRED TAB) ; AFTER THE OPERATION MNEMONIC IN AN INSTRUCTION INPUT UNDER "?" CMD. ; ; 17. IF AN ADDRESS IS LESS THAN THE PROGRAM'S STACK LIMIT, THE ADDRESS ; IS TYPED AS OCTAL, RATHER THAN AS SOME DUMB SYMBOLIC. ; ; 18. THE PROMPT FOR "O" (STB FILE) IS GREATLY SHORTENED. ; ; 19. THE TERMINAL IS "ATTACHED" FOR THE "L" COMMAND IN THE "!" MODE. ; ; 20. AN ADDRESS IN OR BELOW THE STACK IS TYPED AS OCTAL. ; ; 21. AUTO-TYPE ON BREAKPOINT: "L;N;T B" WHERE: L = BREAKPOINT ; LOCATION; N = BREAKPOINT #; T = TYPEOUT LOCATION. ; "$NP" IS ADDR OF AUTO PRINT LOC FOR BKPT N. ; ; 22. IF "$8P" IS SET TO A LOC (BY USING "$7P" AND LF), THEN THAT ; LOC IS USED FOR AUTO PRINT FOR ALL BKPT'S. ; ; 23. CHANGED "=" TO TYPE OUT IN CURRENT MODE, RATHER THAN ALWAYS OCTAL. ; ; 24. FIXED BUG ON USING SYMBOLS STARTING WITH "." OR "$" IN "?" COMMAND. ; ; 25. FIXED BUG ON NEGATIVE INDEX IN "?" COMMAND [EG: INC -2(R1)] ; === DDT -- DYNAMIC DEBUGGING TOOL === ; ; ; ; ORIGINAL AUTHOR JIM STARKY ML5-5 E40 ; ; (JIM'S DEBUGGING TOOL) ; ; ; Edited: pete white ese, rg ; ; Include task symbol table ; ; ; 1. Goals and Ambitions of DDT ; ; ; DDT IS A HACKISH ATTEMPT TO MOVE ODT (Odious Debugging ; Tool) closer toward a more civilized DDT (Dastardly ; Debugging Technique) of the 10 ilk. three major additions ; have been made to RSX11D ODT. first, DDT KNOWS ENOUGH ABOUT ; PDP11 INSTRUCTIONS TO PRINT THEM IN A RECOGNIZEABLE FORMAT. ; THIS INCLUDES MOST OF THE USER INSTRUCTION SET (SANS ; FLOATING POINT), THE 11 ADDRESSING MODES, AND THE MACRO ; FORMAT FOR THE VARIOUS INSTRUCTION CLASSES. SECOND, A ; SYMBOLIC CAPABILITY HAS BEEN ADDED TO ODT. DDT ALLOWS A ; USER TO SPECIFY AND DEFINE SYMBOLS, THEIR VALUES, AND THEIR ; RANGES. IT CAN ALSO INTERPRET THE SYMBOL TABLE OUTPUT BY ; TASK BUILDER AND SO MAKE AVAILABLE ALL TASK GLOBAL SYMBOLS. ; THIS CAPABILITY, IN TURN, LEAD TO THE DEMISE OF STANDARD ODT ; relocation registers. finally, DDT WILL ACCEPT MACRO-FORMAT ; INSTRUCTION MODIFICATIONS, ADDRESS COMPUTATIONS BEING ; PERFORMED AUTOMATICALLY BY DDT. ; ; ; ; 2. NEW COMMANDS ; ; SIX NEW COMMANDS HAVE BEEN ADDED TO ODT. these are: ; ; ! Print an instruction as an instruction. DDT tries the ; print the currently opened location as a PDP-11 ; machine instruction. if the object is clearly (in the ; eyes of DDT) not an instruction, the object is printed ; as an address (see "&" command). The arguments of the ; instruction are printed as symbolic addresses if ; possible. ; ; : Define (or re-define) a symbol. A symbol is entered ; into DDT's symbol internal table with a value and an ; optional range. ; ; Examples: ; ; 1000:JUNK (define symbol JUNK) ; ; 2774;3000:DATA (define symbol data with LENGTH 3000) ; # accept the symbol following the # and uses its value. ; this construction should be legal at any point where ; ODT would normally accept an octal number. ; ; & print the current word as a symbol and offset, if ; possible. DDT searches its internal symbol table for ; the best symbol, and then the task symbol table, ; prints the symbol and computes and prints the offset ; from the symbol. its ideas concerning "best" are: ; ; a. The symbol must be less than the value ; b. the value must be within the range of the the ; symbol ; c. If more than one symbol are possible, the one with ; the least offset is chosen. ; d. A symbol will be chosen preferentially from the ; DDT in-core symbol table so enabling the most ; recent definition to be used. ; ; ; ? decode the macro-type instruction following the ? and ; insert the resultant machine instruction in the ; current open location. the instruction may be from ; one to three words long depending on the addressing ; modes. ; ; o causes DDT to prompt for the task symbol table file. ; since DDT normally has to search the entire symbol ; table file - quite a slow process - the file may be ; closed by specifying a null file in answer to the ; prompt. the file may be re-opened later, when needed, ; by re-specifying the file name. ; ; ; ; 3. old commands purged ; ; four old guys are gone. they are: ; ; r Set up relocation register ; k Print an object using a specified relocation ; register ; , Compute relocation ; o Compute offset ; gone also is the use of the line printer as used in ; dump type commands. this enables DDT to use the lun ; automatically assigned for the printer to be used for ; the symbols file. ; 4. size requirements ; ; DDT requires about two and a half k on top of run of ; the mill (sic) ODT. for the curious, the breakdown is: ; ; 500 bytes -- op-code table ; ; 500 bytes -- instruction decoding ; ; 800 bytes -- instruction encoding ; ; remainder -- symbol table management ; ; ; 5. linkage ; ; in RSX-11D DDT may be included by something like: ; ; tkb junk,junk,junk=junk,...,[1,1]DDT/DA ; ; THE IAS EQUIVALENT IS: ; ; LINK /SYMBOLS/MAP/DE:[1,1]DDT JUNK,... ; ; ; 5. STABILITY ; ; DDT IS SUBJECT TO CHANGE WITHOUT NOTICE. ; ; 7. AUTOMATIC SYMBOL DEFINITION ; ; DDT'S SYMBOL TABLE LIVES IN A PSECT NAMED $$$SYM. ; ASSUMING REASONABLE CARE IS TAKEN, ANY NUMBER OF SYMBOLS ; AND/OR UNUSED SYMBOL BLOCKS MAY BE CREATED. THE FORMAT OF A ; DDT SYMBOL IS: ; ; ; .WORD 070707 ; GLOBAL DDTHDR ; .WORD ; .WORD ; .RAD50 /NAME/ ; THE VALUE 'NAME' MUST CONFORM TO THE FOLLOWING ; ARBITRARY RULES: ; ; 1. IT MUST BE COMPOSED OF ONLY RAD-50 CHARACTERS ; 2. IT MUST NOT START WITH A NUMBER ; 3. IT MUST BE 6 CHARACTERS LONG, COUNTING ; TRAILING BLANKS. (2 WORDS OF RAD50). ; ; AT START-UP TIME, DDT MARCHES BACKWARDS FROM ITS OWN ; SYMBOLS IN THE PSECT $$$SYM SEARCHING FOR PLAUSIBLE SYMBOL ; BLOCKS. ANY SYMBOLS FOUND IN THIS SEARCH WILL UTILIZED BY ; DDT. ; ; THE USER SHOULD NOTE THAT MOST OF THE MORE USEFUL ; OFFSETS ARE INCLUDED IN THE TASK SYMBOL FILE. HOWEVER, THE ; FACILITY MAY PROVE USEFUL IN ORDER TO MAKE AVAILABLE TASK ; LOCAL SYMBOLS WHICH WOULD NOT BE FOUND IN THE SYMBOLS FILE. ; 8. INSTRUCTION FORMAT ; ; DDT IS ALMOST AS RICH AND GENEROUS IN INSTRUCTION ; FORMAT AS THE MACRO ASSEMBLER. THE FOLLOWING SYMBOLS IN THE ; PROPER CONTEXT HAVE MEANING TO DDT: ; ; @ - DEFERRED ADDRESSING MODE ; + - AUTO INCREMENT MODE [(R1)+] OR ADDITION ; - - AUTO DECREMENT MODE [-(R1)] OR SUBTRACTIONS ; # - LITERAL [ FOOBAR] (ADDRESSING MODE 27) ; ' - VALUE OF NEXT CHARACTER ; " - VALUE OF NEXT TWO CHARACTERS ; () - INDEXED [FOO(R1)] OR REGISTER DEFERRED [(R1)] ; ; ALL OPERANDS EXPECTED BY AN INSTRUCTION MUST BE ; ENTERED. "CLC" EXPECTS NO ARGUMENTS, "DEC" EXPECTS ONE, ; "ADD" EXPECTS TWO. DDT WILL INSIST ON AN ARGUMENT OR ; COMPLAIN. ALL OP-CODES OF INSTRUCTIONS EXPECTING ARGUMENTS ; MUST BE FOLLOWED BY A TAB. A SPACE WON'T DO. DDT WILL ; REJECT AN INSTRUCTION WHICH VIOLATES IT SPECIFICATION. THIS ; INCLUDES SUCH THINGS AS BRANCHES OUT OF RANGE, ILLEGAL ; REFERENCE TO ODD ADDRESSES, SOB'S IN THE FORWARD DIRECTION, ; ETC. ; ; DDT DOES NOT RECOGNIZE FLOATING, PRIVILEGED, OR ; UN-INTERESTING INSTRUCTIONS. IT DOES, HOWEVER, RECOGNIZE ; THE ALMOST NON-EXISTENT "NOP" (000240). ; ; ADDRESSES, WHERE APPROPRIATE, MAY CONSIST OF ; COMBINATIONS OF SYMBOLS, OCTAL NUMBERS, AND SELF DEFINING ; TERMS (SINGLE AND DOUBLE QUOTES). SYMBOLS DO NOT REQUIRE ; THE PREFACE REQUIRED IN LESS CIVILIZED PORTIONS OF DDT. ; EXPRESSIONS, HOWVER, MAY NOT BEGIN WITH THE SYMBOL "-" . ; THIS IS NECESSARY TO AVOID CONFUSING WITH AUTO-DECREMENT ; MODE. ANY 800 BYTE PARSER IS BOUND TO HAVE SOME GLITCHES. ; ; 9. REGISTER SYMBOLS ; ; DDT, TO REDUCE SPACE AND CONFUSION, PRETENDS THAT THE ; 11 REGISTERS BEHAVE LIKE THOSE ON THE 10, I.E., THAT ANY ; ADDRESS LESS THAN 8 DENOTES A REGISTER. IN MOST CASES, THE ; CONTEXT IS CLEAR AND THIS WILL CAUSE NO PROBLEMS. ON THE ; OTHER HAND, THE INSTRUCTION "MOV 2,4" WILL BE TREATED AS ; "MOV R2,R4" RATHER THAN THE PROPER FORM. THERE IS NO ; SOLUTION TO THIS PROBLEM COMPARABLE TO ITS MAGNITUDE; HENCE ; THIS BUG WILL REMAIN. IF DIRECT REFERRENCE TO LOCATIONS 0 - ; 7 ARE REQUIRED, ONE WILL HAVE TO PRETEND ONLY ODT is ; available. ; ; for the sake of convenience, the symbols ; r0,r1,r2,r3,r4,r5,sp, and pc are automatically part of the ; DDT SYMBOL TABLE. THIS IS FINE FOR INSTRUCTIONS BUT A ; HASSLE FOR OTHER THINGS. JUST REMEMBER THAT R3 OUT OF ; CONTEXT MEANS 3. ; 10. INSTRUCTION CHASING ; ; WHEN PRINTING INSTRUCTIONS VIA THE ! COMMAND, DDT ; KEEPS TRACK OF THE LAST TWO EFFECTIVE ADDRESSES COMPUTED. ; (DDT CONSIDERS PC RELATIVE, LITERAL, AND BRANCH TYPE ; OPERANDS AS EFFECTIVE ADDRESSES). THESE ADDRESSES MAY BE ; ACCESSED BY THE FOLLOWING COMMANDS: ; ; ; ^D OPEN THE LAST EFFECTIVE ADDRESS AND PRINT THE ; CONTENTS IN THE CURRENT MODE. ; ; ^I OPEN THE SECOND TO LAST EFFECTIVE ADDRESS AND ; PRINT THE CONTENTS IN THE CURRENT MODE .MCALL DSAR$S,ENAR$S,GTSK$S .MCALL GCMLB$,GCML$,CSI$,CSI$1,CSI$2 .MCALL FSRSZ$,FDBDF$,FDRC$A,FDOP$A,NMBLK$ .MCALL OPEN$R,CLOSE$,ALUN$S,GET$ FSRSZ$ 2 .PSECT $$$DDT R0 = %0 ; REGISTER R1 = %1 ; NAMING R2 = %2 ; CONVENTIONS R3 = %3 R4 = %4 R5 = %5 SP = %6 PC = %7 ; DEFINE BPT OPCODE ; BPT = 3 ; BREAK POINT TRAP CODE ;USED IN LOCATING "JMP"'S AS OPPOSED TO "BR"'S .MACRO JUMP A JMP A .ENDM .MACRO CALL SUBR JSR PC,SUBR .ENDM ;USED TO CALL RSX-11 FOR HELP .MACRO RSX11 EMT 377 .ENDM ;CAUSE ERROR RESPONSE, INTERNAL CODE SAVER .MACRO ERROR EMT 0;JMP O.ERR .ENDM ;CALL COMMAND DE-CODER, INTERNAL CODE SAVER .MACRO DECODE IOT;JMP O.DCD .ENDM .MACRO SHIFT N,REG ASH #N,REG .ENDM .SBTTL JIM'S BELOVED MACROS ZENTER=0 .MACRO ENTER,ARGS RTRNZ=0 RTRNZS=0 RTRNZC=0 ZENTER=ZENTER+1 .NARG NARG .IF GT,NARG .IRP FOO, MOV FOO,-(SP) .ENDM .ENDC .MACRO RETURN,T,OP .NARG NARG .IIF EQ,NARG-2 XRTRN \ZENTER,T,OP .IIF NE,NARG-2 XRTRN \ZENTER,T,BR .ENDM RETURN .IF GT,NARG .MACRO EXIT XEXIT \ZENTER, .ENDM EXIT .ENDC .IF EQ,NARG .MACRO EXIT XEXIT \ZENTER .ENDM EXIT .ENDC .ENDM ENTER .MACRO XEXIT,N,ARGS .NARG NARG NARG=NARG-1 .IF GT, BR RTZ'N RTZC'N': CLC .ENDC .IF GT, BR RTZ'N RTZS'N': SEC .ENDC RTZ'N': $CT=0 .IRP FOO, $CT=$CT+1 .ENDM .REPT $CT $N=1 .IRP FOO, .IIF EQ,$N-$CT MOV (SP)+,FOO $N=$N+1 .ENDM $CT=$CT-1 .ENDM RTS PC .ENDM XEXIT .MACRO XRTRN,N,T,OP OP RTZ'T'N RTRNZ'T=1 .ENDM XRTRN .SBTTL USER STATE AREA AND DATA CONTROL ;SOME ODT TYPE DEFINITIONS (THESE ARE NOT PARAMETERS). O.BKP =16 ;NUMBER OF BREAKPTS-1 X 2 O.TBT =20 ;T-BIT MASK, PROCESSOR STATUS PROMPT = 137 ;PROMPT CHARACTER "_" ; EVENT FLAG FOR ODT TO WAIT ON WHEN DOING I/O ODTEFN =28. ;SOMETHING TO WAIT AROUND FOR ; ; DEFINE BPT (BREAK POINT TRAP CODE AS VALID OPERAND) ; FOR RSX11M ASSEMBLER ; .IF DF R$$11M BPT = 3 ; BREAK POINT TRAP .ENDC ;SET UP THE REAL THING FINALLY ORGODT = . ;DEFINE RELOCATABLE ZERO STKSIZ=200 ; STACKSIZE ODTSTK = ORGODT+STKSIZ ;DEFINE BASE OF THE STACK .=ODTSTK ;IN THE BEGINNING ;THE ORDER OF THESE ITEMS IS INTENTIONAL, SEE REGISTER MAPPING SCHEME INTBEG =. ;STARTING ADDRESS OF INTERNAL REGISTERS O.UR0: 0 ;USER R0 $0 0 ; R1 $1 0 ; R2 $2 0 ; R3 $3 0 ; R4 $4 0 ; R5 $5 O.USP: 0 ;USER SP $6 O.UPC: 0 ;USER PC $7 O.UST: 0 ;USER PS $S O.ARG: 0 ;ARGUMENT REGISTER $A O.MSK: -1 ;MASK $M O.LOW: 0 ;LOW LIMIT $L O.HI: 0 ;HIGH LIMIT $H O.CNST: O.ODT ;CONSTANT REGISTER $C O.QUAN: 0 ;QUANTITY REGISTER $Q O.FORM: 0 ;FORMAT REGISTER $F ENFLAG: -1 ;ENTRY FLAG $X .SBTTL BREAKPOINT, RELOCATION AND SST VECTOR TABLES INTINX =. ;STARTING ADDRESS OF INTERNAL TABLES ;BREAKPOINT CONTROL LISTS, AND EXTRA SLOT FOR SINGLE STEP O.ADR1: ;ADDRESS OF THE BREAKPOINT ($0B-$7B) .WORD O.TRTC,O.TRTC,O.TRTC,O.TRTC,O.TRTC,O.TRTC,O.TRTC,O.TRTC,O.TRTC O.CT: ;PROCEED COUNT ($0G-$7G) .WORD 1,1,1,1,1,1,1,1,1 O.UIN: ;USER INSTRUCTION SAVE LOCATION ($0I-$7I) .WORD BPT,BPT,BPT,BPT,BPT,BPT,BPT,BPT,BPT ; BREAKPOINT AUTO PRINT LOCATIONS ($0P-$7P) O.BPTP: .WORD 0,0,0,0,0,0,0,0,0 ;USER'S SST VECTOR ADDRESSES (SEE "RESSST" ROUTINE FOR REAL COPY) SSTVEC: ;SST VECTORS FOR USER WHILE RUNNING ($0V-$7V) + V.ODDA ;0-ODD ADDRESS, OR HALT, VECTOR @4 .IF DF M$$MGE .IFT + V.SGMT ;1-SEGMENT FAULT .IFF + 0 ; NO SEGMENT FAULT POSSIBLE .ENDC SSTBPT: + V.BPTI ;2-T-BIT OR BPT + 0;V.IOTX ;3-IOT + V.ILLI ;4-RESERVED OR ILLEGAL INSTRUCTION + 0;V.NEMT ;5-NON RSX EMT + 0;V.TRAP ;6-TRAP + 0;V.FPPE ;7-PDP 11/40 FLOATING POINT ;USER'S STACK VALUES ON SST ENTRIES SSTSTK: ;TOP STACK ITEMS ON SST ERRORS UPON ENTRY ($0E-$2E) .WORD 0,0,0 ;LOGICAL UNIT BUCKETS TO USE FOR I/O IOLUNS: ;LOGICAL UNIT SLOTS ($0D-$2D) ; THESE NEXT TWO LOCATIONS ARE FILLED BY THE TASK BUILDER ; WHEN IT SEES THE /DA SWITCH IN THE OUTPUT SIDE OF THE COMMAND STRING ; .ODTL1::.WORD 0 ; LUN FOR TTY .ODTL2::.WORD 0 ; LUN FOR SYMBOLS FILE .WORD ODTEFN ; EVENT FLAG FOR ODT INTEND =.-2 ;END OF INTERNAL REGISTERS AND TABLES GTSKBF: .BLKW 16. ; GET TASK PARAMETER BUFFER .SBTTL INTERNAL DIRTY DATA AREA O.CRLF: .BYTE 015,012 ; O.EOL: .BYTE 015,012 ; CURRENT END-OF-LINE CHARS: INITIALLY O.BACK: .WORD 0 ; BACKED-UP CHAR ;WORDS AND ORDERED BYTES, ITEMS MUST BE KEPT FROM COMMAND TO COMMAND O.CAD: .WORD 0 ;ADDRESS OF CURRENTLY OPEN REGISTER O.DOT: .WORD 0 ;ADDRESS OF LAST EXPLICITLY OPENED CELL O.BW: .WORD 0 ;LAST OPEN MODE 1=BYTE, 2=WORD O.OPN: .WORD 0 ; LOCATION OPEN FLAG 0=NOT OPEN, NON-ZERO=OPEN O.DSW: .WORD 0 ; USER'S DSW SAVED AT BREAK POINT TIME O.LAST: .WORD 0 ; 0= LAST SST NOT A BREAK POINT, 1=LAST SST WAS A BREAKPOINT D.ARGS: .WORD 0 ;SEMI COLON PUSH WORD ENTRAN: .WORD 0 ;TRANSFER ADDRESS OF USER PROGRAM ;THE FOLLOWING ITEMS NEED NOT BE KEPT FROM COMMAND TO COMMAND ;THEIR ORDER IS INTENTIONAL SO KNOW THY MAKER! O.OP: .BYTE 0 ;CURRENT ARITHMETIC OPERATOR O.SMFD: .BYTE 0 ;SEMI-COLON COUNTER O.EXP: .WORD 0 ;EXPRESSION BUCKET ENPRFX = O.EXP ;ENTRY PREFIX TEMP STORE ;THE FOLLOWING ITEMS MUST BE KEPT FROM COMMAND TO COMMAND. O.T: .BYTE 0 ;T BIT IN USE FLAG O.P: .BYTE -1 ;PROCEED ALLOW FLAG O.S: .BYTE 0 ;SINGLE INSTRUCTION MODE, 0=NORMAL, >0=ENABLE O.FM: .BYTE 2 ;OUTPUT FORMAT MODE, BYTE, WORD, ANSII, RAD50 .EVEN O.OBW: .WORD 2 ;OPEN CELL TYPE, 1=BYTE, 2=WORD O.SEQ: .WORD 0 ; SEQUENCE INDICATIOR ; THE FOLLOWING WORD IS SET BY INITIALIZATION TO SELECT THE ; CORRECT FORM OF RETURN FROM INTERRUPT FOR THE HARDWARE ; THAT ODT IS RUNNING ON. ; RTT IS USED FOR 11/40, 11/45, AND 11/50 ; RTI IS USED FOR 11/10, AND 11/20 ; O.RTN: .WORD 0 ; THE ADDRESS OF THE CORRECT ; RETURN INSTRUCTION ;THE BELOW LOCATION IS USED IN BREAKPOINT PROCESSING AND IS DIRTY O.TRTC: BPT ;TRACE TRAP PROTOTYPE ZERO: .WORD 0 ; CONSTANT 0 .SBTTL RSX-11 DPB'S AND INTERFACE DIRTY DATA ;RSX-11 DIC DATA STUFF DPBQIO: .BYTE 01.,12. ;TYPE, WD CNT DPBIOF: .WORD 0 ;FUNC (TTYRD,TTYWRT) DPBLUN: .WORD 0 ;LUN (MUST BE TTY) DPBEFN: .BYTE 0,0 ;EVENT NUM, PRIORITY = USER'S .WORD IOSTAT ; I/O STATUS BLOCK ADDRESS .WORD 0 ; AST'S .WORD CHRBUF ;I/O BUFF ADDR .WORD 1 ;BYTE COUNT .WORD 0 ;CARRIAGE CONTROL CHARACTER IOSTAT: .BLKW 2 ; I/O STATUS BLOCK CHRBUF: .WORD 0 ;I/O BUFFER ; COMMAND LINE FOR SYMBOLS FILE GCMLB: GCMLB$ ,,BUF,,,80. CSI$ CSI: LNEBUF: .BLKB 200 ; FOR COMMAND LINE AND WORK ; SPACE ALSO. PLENTY FOR ALL STBFLE: FDBDF$ ; FILE DESCRIPTOR FOR SYMBOLS FILE FDRC$A ,LNEBUF,200 FDOP$A ,CSI+C.DSDS,NMBLK,FO.RD STBFDB: .WORD 0 ; 0 IF NO STB FILE, ELSE STB FDB ADDRESS GSDPNT: .WORD 0 ; POINTER TO CURRENT GSD ENTRY ENDREC: .WORD 0 ; END ADDRESS OF CURRENT RECORD CHR1: .WORD 0,0 ; RAD-50 SYMBOL EXTRACTED FROM .STB FILE NMBLK: NMBLK$ ,STB,,SY .SBTTL *** PURE CODE STARTS HERE *** ;COMMANDS AND Q I/O SYMBOLS IO.WLB =000400 ;WRITE LOGICAL BLOCK, VERY SHORT ONE .IF DF R$$11M .IFT IO.RLB =001000 ;READ LOGICAL .IFF IO.RLB =001030 ; READ LOGICAL, NO ECHO, PASS ALL .ENDC ;DPB'S FOR SETTING THE DE-BUGGING SST VECTORS DPSSTU: .BYTE 103.,03. ;SST IN USE WHILE USER RUNS .WORD SSTVEC .WORD 8. DPSSTO: .BYTE 103.,03. ;SST IN USE WHILE ODT RUNS .WORD SSTODT .WORD 8. ;ALL ODT TYPE ERRORS JUST GO TO "O.ERR" OR SOMEWHERE ELSE SSTODT: + O.ERR ;0-ODD ADDRESS + O.ERR ;1-SEGMENT FAULT + O.ERR ;2-BPT OR T-BIT ("MCR" CALL) + O.DCD ;3-IOT ("DECODE") + O.ERR ;4-RESERVED OR ILLEGAL INSTRUCTION + O.ERR ;5-NON RSX EMT ("ERROR") + O.ERR ;6-TRAP + O.ERR ;7-PDP 11/40 FLOATING POINT EXCEPTION .SBTTL INTERNAL REGISTER NAME AND CONTROL TABLES ;NON-INDEXED REGISTER NAMES NIXMAP: .ASCII /01234567/ ;USER REGISTER NAMES FOR MAPPING NIXREG: .BYTE 'S ;O.UST USER STATUS .BYTE 'A ;O.ARG ARGUMENT .BYTE 'M ;O.MSK MASK REGISTER .BYTE 'L ;O.LOW LOW SCAN LIMIT .BYTE 'H ;O.HI HIGH SCAN LIMIT .BYTE 'C ;O.CNST CONSTANT .BYTE 'Q ;O.QUAN QUANTITY .BYTE 'F ;O.FORM FORMAT CONTROL .BYTE 'X ;ENFLAG ENTRY FLAG FIX CONTINIOUS DE-BUG .BYTE 00 ;END OF THIS LIST ;INDEXED REGISTER NAMES INXREG: .BYTE 'B ;O.ADR1 BKPT ADDRESSES .BYTE 'G ;O.CT BKPT PROCEED COUNTS .BYTE 'I ;O.UIN BKPT USER INSTRUCTIONS .BYTE 'P ;O.BPTP BKPT AUTO PRINT LOCS .BYTE 'V ;SSTVEC USER'S SST TRAPPING VECTORS .BYTE 'E ;SSTSTK SST STACK CONTENTS .BYTE 'D ;IOLUNS LOGICAL UNITS FOR I/O .BYTE 00 ;END OF THIS LIST ;INDEXED REGISTER TABLE BASES .EVEN INXTBL: .WORD O.ADR1 ;BKPT ADDRESS TABLE .WORD O.CT ;BKPT PROCEED COUNTS .WORD O.UIN ;BKPT'D INSTRUCTION .WORD O.BPTP ;BKPT AUTO PRINT LOCS .WORD SSTVEC ;USER SST VECTOR TABLE .WORD SSTSTK ;ERROR SST STACK VALUES .WORD IOLUNS ;LOGICAL UNIT NUMBERS .WORD INTEND+2 ;END OF TABLE AREA FOR ADDRESS MAPPING ;CHARACTER CONVERSION LISTS. ALTTAB: .BYTE 033,175,176 ;ALTERNATE ALT-MODE FORMS .BYTE 000 ;END OF THIS LIST TOO .SBTTL COMMAND NAME AND DISPATCH TABLES COMTAB: ;ADDRESS OF THE CHARACTER TABLE ;OPEN REGISTER COMMANDS (ORDER AND POSITION CRITICAL) NORC=. .ASCII #\/'"%&# NORC=.-NORC ; NUMBER OF OPEN-REG COMMANDS ;CLOSE REGISTER COMMANDS .BYTE 015,012,'^,'_,'@,'>,'< ;SPECIAL FORMS .BYTE '$,'=,'C,'Q,'. ;OPERATORS (ORDER OF -+* IS CRITCAL) .BYTE ';,'-,'+,'* ;COMMANDS .ASCII /BEFGLNPSVWX/ .ASCII /!:#?O/ ; DDT STUFF .BYTE 'I-100 ; ^I (TAB) .BYTE 'D-100 ; ^D .BYTE 00 ; END OF LIST .EVEN ;THE DISPATCH TABLE, ORDERED ON ABOVE TABLE ;OPEN REGISTER COMMANDS COMDIS: + OCBYTE ;\ OPEN OCTAL BYTE + OCWORD ;/ OPEN OCTAL WORD + ANBYTE ;' OPEN ANSII BYTE + ANWORD ;" OPEN ANSII WORD + MODULO ;% OPEN RADIX 50 WORD + SYMPRT ;& PRINT SYMBOLICALLY ;CLOSE REGISTER COMMANDS + CLCRET ; CLOSE, NO SUCESSIVE OPEN + CLLNFD ; CLOSE, OPEN NEXT + CLUPAR ;^ CLOSE, OPEN PREVIOUS + CLBACK ;_ CLOSE, OPEN PC RELATIVE MODE + CLATSG ;@ CLOSE, OPEN INDIRECT + CLGRTH ;> CLOSE, OPEN PC OFFSET AS BRANCH + CLLSTH ;< CLOSE, OPEN OLD SEQUENCE ;SPECIAL FORMS + O.REGT ;$ INTERNAL REGISTER REFERENCE + EQUALS ;= PRINT LEFT SIDE IN CURRENT MODE + CHRCEE ;C CONSTANT REGISTER CONTENTS + CHRQUE ;Q QUANTITY REGISTER CONTENTS + CHRDOT ;. LAST OPENED LOCATION'S ADDRESS ;OPERATORS + O.SEMI ;; MULTIPLE ARGUMENT DELIMITER + O.MINS ;- SUBTRACTION + O.PLUS ;+ ADDITION + O.STAR ;* MULTIPLY BY 50 ;COMMANDS + O.SEBK ;B SET / CLEAR BREAKPOINTS + O.EFFA ;E EFFECTIVE ADDRESS SEARCH + O.FILL ;F MEMORY FILL + O.GOTO ;G GO TO USER'S DATA + O.LIST ;L LIST MEMORY ON CONSOLE + O.NOTW ;N NOT WORD SEARCH + O.PROC ;P PROCEED FROM BREAKPOINT + O.SNGL ;S SET / RESET SINGLE STEP MODE + O.SSTR ;V RESTORE ORIGINAL SST VECTORS + O.WSCH ;W MEMORY WORD SEARCH + O.EXIT ;X EXIT TASK TO RSX-11 + DCINST ;! PRINT INSTRUCTION + SYMADD ;: ADD SYMBOL TO TABLE + SYMGET ;# EAT A SYMBOL + INSGET ;? EAT AN INSTRUCTION + OPNIPT ;O OPEN INPUT FILE + O.SRC ;TAB OPEN LAST SOURCE ADDRESS + O.DST ;^D OPEN LAST DESTINATION ADDRESS .SBTTL MAIN ENTRY POINT TO ODT FOR RSX-11 ;START ODT FROM SCRATCH, CLEAN SLATE O.ODT: CLR O.UST ;SAVE STATUS AND RUN AT ENTRY STATUS CLR O.LAST ; SET LAST SST WAS NOT A BPT TST SP ;SEE IF THERE IS A STACK TO USE BNE 10$ ;YES SO USE IT MOV #ODTSTK,SP ;SET UP ODT'S FOR A WHILE 10$: TST ENFLAG ;SEE WHAT KIND OF ENTRY TO USE BMI 12$ ;IF MINUS FRESH LOAD, SET TRANSFER MOV ENTRAN,R0 ;ELSE USE OLD TRANSFER FORM FIRST 1 12$: MOV R0,ENTRAN ;REFRESH THE TRANSFER ADDRESS MOV R0,O.UPC ;SET UP USER'S TRANSFER ADDRESS JSR R0,O.SVR ;SAVE REGISTERS (MAINLY SP),SET SST'S TST ENFLAG ;CLEAR REGISTERS ON A FRESH LOAD BPL 18$ ;OTHER WISE USE THEM AS DIRTY MOV #O.UR0,R0 ;CLEAR OUT USER'S R0-R2 CLR (R0)+ ;TO SIMULATE REAL TASK START CLR (R0)+ CLR (R0)+ ;TYPE OUT AN ANNOUNCEMENT THAT WE ARE HERE 18$: TST ENFLAG ;AVOID TYPE OUT IN CONTINIOUS MOOD BGT 20$ ;MINUS IS CONTINIOUS MOOD MOV IOLUNS+0,DPBLUN ;RESET, FORCE DEFAULT LUN FOR I/O JSR PC,O.TEOL ;RESET CONSOLE MOV #"DD,R0 ;TYPE MY NAME JSR PC,O.TYPE ;TWO CHARACTERS MOV #"T:,R0 ;ALL OF IT JSR PC,O.TYPE TST ENFLAG ;SKIP NAME OUTPUT ON SECOND TIME BPL 20$ ;AS REGISTERS ARE GARBAGE GTSK$S #GTSKBF ; GET TASK PARAMETERS BCS 20$ ; ERROR MOV GTSKBF+G.TSTN,R0 ; GET TASK NAME JSR PC,TYRADX ; PRINT 1ST THREE CHARACTERS MOV GTSKBF+G.TSTN+2,R0 ; JSR PC,TYRADX ; PRINT LAST 3 CHARACTERS ;SEE WHAT TO DO ABOUT BREAKS AND START-UP ETC. ; ; SELECT CORRECT RETURN FROM INTERRUPT ; 20$: CLR O.RTN ; ZERO RETURN INSTRUCTION ADDRESS CLR -(SP) ; ZERO PS MOV #30$,-(SP) ; RETURN TO 30$ IF RTT EXISTS RTT ; TRY IT 30$: MOV #O.RTT,O.RTN ; GOT BACK, SO SET TO USE RTT O.ODT1: TST ENFLAG ;CHECK FOR FIRST TIME ENTRY BPL 25$ ;DO NOT CLEAR BREAKS AND RELOC CLR ENFLAG ;FIRST IS FIRST ONLY ONCE MOV #O.TRTC,R0 ;BREAKS MAY BE LEFT IF USER EXITS CLR R4 22$: JSR PC,SETBRK ;CLEAR BREAKPOINT TABLES BCC 22$ 25$: CLRB O.S ;NO SINGLE STEP MOVB #-1,O.P ;NO ALLOW PROCEED JSR PC,O.REM ;GET RID OF ANY BREAKPOINTS CALL SETSYM ; SET UP SYMBOL TABLE TST ENFLAG ;SEE HOW TO DO THIS BGT 30$ ;CONTINUOUS DECODE ;GO ASK FOR A COMMAND 30$: CLR R2 ;GO TO THE USER'S PROGRAM JMP O.GOTO ;AND SEE WHAT HAPPENS .SBTTL COMMAND PROCESSORS, SECTION ONE ( $ B R K A Q . ) .SBTTL "$," PROCESSOR - INTERNAL REGISTER MAPPER ;SYNTAX-- ;$L DELIVER INTERNAL ADDRESS OF L ;$NL DELIVER INTERNAL ADDRESS OF L+2N ;$N DELIVER INTERNAL ADDRESS OF USER REGISTER N ;SEE MAPPING TABLES, RANGE OF N IS 0-7 O.REGT: JSR PC,GETNUM ;GET AN OCTAL NUMBER JSR PC,O.RTST ;CHECK FOR ERROR BCS O.ERR0 ;MPY R4 X 2 TST R2 ;SEE IF ANYTHING TYPED BNE 10$ ;IF SO IS INDEXED OR USER REGISTER JSR R5,LOOKUP ;SEE IF NON-INDEXED + NIXREG BCS 12$ ;NON-INDEXED TURNS INTO A COMMAND MOV R1,R4 ;PLACE IN LIST IS INTERNAL ORDER ADD #O.UST,R4 ;GET ADDRESS IN R4, GOTTA READ CHAR BR 20$ 10$: JSR R5,LOOKUP ;SEE IF INDEXED + INXREG BCC 15$ ;WAS TRULY INDEXED 12$: CMP #7+7,R4 ;INTERNAL USER REGISTER RANGE CHECK BLO O.ERR0 ADD #O.UR0,R4 ;SET ACCESS TO R0-R7 OF THE USER BR 25$ ;AVOID READING OF COMMAND 15$: ADD INXTBL(R1),R4 ;COMPUTE ADDRESS TO INDEXED TABLE 20$: JSR PC,O.GET ;GET THE ASSUMED TERMINATOR 25$: INC R2 ;SHOW THEM THAT R4 GOT VALID DATA JUMP O.CLGL ;RE-USE CHARACTER, R2 IS NON-ZERO .SBTTL "B" PROCESSOR - SET AND REMOVE BREAKPOINTS ;SYNTAX-- ;B CLEAR ALL BREAKPOINTS ;NB CLEAR BKPT N ;A;B SET BKPT AT A, USE FIRST FREE BKPT ;A;NB SET BKPT N AT A ;DEPENDS MIGHTILY UPON LOCATION "O.TRTC" CONTAINING A TRAP INST. ;AND THAT A FREE BKPT CONTAINS THE ADDRESS "O.TRTC". O.SEBK: CLR R1 ; ASSUME NO AUTO PRINT LOCATION CMPB O.SMFD,#2 BNE 5$ ; NO AUTO PRINT SPECIFIED MOV R4,R1 ; PLACE WE'RE TO PRINT MOV R3,R2 ; BACK UP ARGUMENTS MOV R5,R4 MOV D.ARGS,R5 MOV #1,R3 ; I'M SURE SOMETING WAS TYPED 5$: ASL R4 ;MPY R4 X2, JUST IN CASE ALL IS GO MOV #O.TRTC,R0 ;SET MAGIC VALUE IN R0, JUST IN CASE TST R3 ;CHECK FOR THE REAL CASE BEQ O.REMB ;REMOVAL CASES, CLEAR THEM UP BIT #1,R5 ;LOOK AT ADDRESS BNE O.ERR ;THAT'S ODD ? TST R2 ;SEE IF I GET TO PICK IT OR NOT BNE 15$ ;OR NOT, DISAPPOINTMENT 10$: CMP R0,O.ADR1(R4) ;LOOK FOR LOCATION WITH FREE ADDRESS BEQ 15$ ;A HIT TST (R4)+ ;KEEP AT FOR A LONG WHILE BR 10$ ;LOOOOOOOOP 15$: MOV R1,O.BPTP(R4) ; AUTOPRINT LOCATION MOV R5,R0 ;R0 HAS ADDRESS OF BREAKPOINT BR O.RE02 ;GO TUCK IT IN ;REMOVE SOME BREAKPOINTS O.REMB: TST R2 ;SEE IF ONE OR ALL BEQ O.RALL ;ALL O.RE02: JSR PC,SETBRK ;SET THE ONE SET UP TO SET BCC O.DCD ;IT HAPPENED O.ERR0: ERROR ;SOME THING WENT WRONG ;REMOVE ALL BREAKPOINTS (N.B. CALLED BY THE INIT CODE) O.RALL: MOV #O.TRTC,R0 ;MAGIC IN R0 CLR R4 ;R4 IS ZERO 10$: JSR PC,SETBRK ;SET THEM TILL BCC 10$ ;THEY GET OUTTA DECODE ;HAND!!!! .SBTTL "A-Q-." PROCESSORS - SPECIAL VALUES ;MERELY SUBSTITUTE THE VALUE IN R4 WITH THE CONTENTS OF THE SPECIFIED ;REGISTER. CHRQUE: MOV O.QUAN,R4 ;LAST QUANTITY PRINTED BR CHR001 CHRCEE: MOV O.CNST,R4 ;CONSTANT REGISTER BR CHR001 CHRDOT: MOV O.CAD,R4 ;CURRENT LOCATION ;BR CHR001 CHR001: INC R2 ;ALLOW AS R4 IS REAL JSR PC,O.GET ;GET NEXT CHARACTER AND ASSUME BR O.CLGL ;IT IS A TERMINATOR .SBTTL COMMAND DE-CODER AND MAIN LOOP OF ODT ; ALL REGISTERS MAY BE USED (R0-R5), ;ERROR ENTRY, TYPE FLAG AND GO DO COMMAND O.ERR: MOV #ODTSTK,SP ;FORCE A NEW STACK MOV IOLUNS+0,DPBLUN ;FORCE THE CONSOLE TST O.RTN ; ARE WE LOOKING FOR CORRECT RTI? BNE 10$ ; NO MOV #O.RTI,O.RTN ; YES, NO RTT(CAUSED TRAP) SO SET RTI JMP O.ODT1 ; CONTINUE INITIALIZATION 10$: MOV #" ?,R0 ; ? TO BE TYPED JSR PC,O.TYPE ; OUTPUT ? ;DECODE FROM THE TOP, CLOSE ALL AND DO CR/LF/_ O.DCD: MOV #ODTSTK,SP ;SET THE STACK FOR SANITY MOV IOLUNS+0,DPBLUN ;FORCE THE CONSOLE JSR PC,O.TEOL ;TYPE END-OF-LINE CLR O.OPN ;SET NO LOCATION OPEN MOVB #PROMPT,R0 ;_ TO GO NEXT JSR PC,O.FTYP ;MAINTAIN OPENED LOCATION, RE-INIT INPUT O.NEWC: CLRB O.SMFD ;CLEAR SEMI-COLON FLAG/COUNT CLR R3 ;ZERO SECONDARY ARGUMENT FLAG CLR R5 ;AND ARGUMENT TST O.SEQ ; IN SEQUENCE? BEQ O.NEWE ; NO: CONTINUE JMP CLLF1 ; YES: GOTO LF HANDLER ;NEW SUB-EXPRESSION ENTRY O.NEWE: CLRB O.OP ;CLEAR OPERATOR FOUND CLR O.EXP ;SET ZERO IN EXPRESSION SO FAR LOCATION ;GET NUMBER AND THEN SCAN FOR COMMAND O.NEWN: JSR PC,GETNUM ;GET AN OCTAL NUMBER AND TERMINATOR ;NON-OCTAL CHAR TYPED WHAT ARE WE TO DO? O.CLGL: JSR R5,LOOKUP ;GO SEE IF IT IS REAL + COMTAB ;THIS DEFINES REAL BCS O.ERR ;EASY ENOUGH IF NOT REAL TST R2 ;IF NOTHING TYPE BOTHER NOT BEQ O.CL01 ;WITH THE EXPRESSION JSR PC,EXPCOM ;COMPUTE EXPRESSION O.CL01: JMP @COMDIS(R1) ;GO TO PROPER ROUTINE ;FOR THE BENEFIT ALL REGISTERS ARE AS FOLLOWS ;R0 LAST CHARACTER TYPED, THE COMMAND ITSELF! ;R1 TABLE INDEX TO COMMAND ADDRESSES, IT IS USED. ;R2,R4 FIRST ARGUMENT, IF R2<>0 THEN R4 IS DATA ;R3,R5 SECOND ARGUMENT, IF R3<>0 THEN R5 IS DATA .SBTTL EXPRESSION SETUP COMMANDS ( ; + - * , ) ;SEMI-COLON PROCESSOR O.SEMI: INCB O.SMFD ;COUNT SEMI-COLON CMPB #2,O.SMFD ;PUSH CONTENTS INTO MULTI BNE O.SEM1 ;SEMI COLON ARG LIST MOV R5,D.ARGS O.SEM1: MOV R2,R3 ;PUSH R2 AND R4 INTO MOV R4,R5 ;R3 AND R5 (FLAG AND CONTENTS) BR O.NEWE ;CONTINUE SCANNER ;ADDITION SETUP O.PLUS: CLRB O.OP ;OP IS 0 FOR + BR O.CO00 ;SUBTRACT SET UP O.MINS: MOVB #2,O.OP BR O.CO00 ;MULTIPLY BY 50 AND ADD O.STAR: MOVB #-2,O.OP ;OP IS -2 FOR * O.CO00: CLR R4 ;R4 IS RESET BR O.NEWN .SBTTL OPEN AND CLOSE PROCESSORS .SBTTL "\-/-'-"-%-:" PROCESSOR - OPEN AND TYPE CONTENT COMMANDS ;SYNTAX-- ;NC OPEN LOC N IN MODE C, SET MODE FOR NEXT ;C TYPE LAST OPENED LOC IN MODE C OCWORD: ;OCTAL WORD - R1=2 ANWORD: ;ANSII WORD - R1=6 MODULO: ;RADIX 50 WORD - R1=10 ;OPEN WORD MODE ENTRY, R1 CONTAINS FORMAT INDEX MOV #2,R0 ;SET BYTE FLAG TO WORD FLAG BR OPE004 ;GO TO IT ACE HOLE OCBYTE: ;OCTAL BYTE - R1=0 ANBYTE: ;ANSII BYTE - R1=4 OPE001: MOV #1,R0 ;SET WORD FLAG TO BYTE FLAG OPE004: TST R2 ;IF NO VALUE TYPED NO MODE SET BEQ 10$ MOV R0,O.BW ;SET MODE AND FORMAT FLAGS MOV R0,O.OBW ;SET THE LATER USE MODE MOVB R1,O.FM ;SET THE MODE FLAG FOR SOOTH MOV R4,O.CAD ;SET ADDRESS FOR EXPLICIT OPEN MOV R4,O.DOT ;RESET RETURN PTR. 10$: CMP #1,R0 ;CHECK ON BYTE MODE BEQ 15$ ;NOT BYTE MODE BIT #1,O.CAD ;SEE IF ADDRESS IS ODD BEQ 15$ ;ALL IS GOOD CLR R1 ;THEY GET BYTE MODE ONLY BR OPE001 15$: MOV R1,-(SP) ;SAVE FORMAT MAINLY JSR PC,GETCAD ;GET THE DATA MOV (SP)+,R1 ;GET FORMAT JSR PC,@TYFORM(R1) ;PRINT DATA IN PROPER FORMAT BR O.NEWC ;GO GETTA NEW COMMAND TO DO DCINST: CALL READYP ; GET READY FOR PRINT BCS SYMERR MOV R4,R0 MOV (R4),O.QUAN ; QUANTITY FOR RE-PRINTING CALL DCDI SUB R4,R0 ; COMPUTE LENGTH OF INSTR MOVB R0,O.BW ; AND STORE IT IN "BYTE" WORD BR O.NEWC SYMADD: CALL GETSYM ; GET A NEW SYMBOL BCS SYMERR ; WE TRIED.... TST R2 ; ANY ARGS? BEQ SYMERR ; NO 1ST ARG TST R3 ; 2 ARGS? BEQ 10$ ; NO MOV R5,R2 ; TWO ARGS, FLIP THEM MOV R4,R5 ; 2ND ARG = HI LIMIT MOV R2,R4 ; 1ST ARG = LO BR 15$ 10$: MOV R4,R5 ; USE FIRST ARG INC R5 ; + 1, AS SECOND ARG 15$: CALL ADDSYM BCS SYMERR BR O.DCD SYMPRT: CALL READYP BCS SYMERR MOVB #2,O.BW ; MORE OR LESS LENGTH MOV (R4),R0 CALL O.RORA BR O.NEWC SYMGET: CALL GETSYM ; GET A SYMBOL BCS SYMERR ; BUT DIDN'T MOV R0,-(SP) CALL FNDSYM ; SEARCH FOR IT IN CORE BCC 80$ ; GOT IT CALL SYMLOC ; DIDN'T, TRY .STB FILE 80$: MOV (R0),R4 ; GET IT'S VALUE MOV (SP)+,R0 BCS SYMERR ; QUIT IF NOT FOUND MOV #1,R2 ; ELSE PRETEND WE DID SOMETHING JMP O.CLGL SYMERR: CMP R0,#015 ; ? BNE 10$ ; NO MOV #012,R0 ; CHAR CALL O.FTYP ; TYPE IT 10$: ERROR READYP: TST R2 BEQ 10$ ; NOTHING TYPED MOV R4,O.CAD ; CURRENT ADDRESS MOV R4,O.DOT MOVB R1,O.FM 10$: MOV O.CAD,R4 BIT #1,R4 BNE 15$ ; ODD ADDRESS, BASTARD MOV SP,O.OPN ; OPEN SWITCH CLC BR 20$ 15$: SEC 20$: RTS PC ; GET NEW INSTRUCTION INSGET: MOV O.CAD,R1 ; CURRENT ADDRESS BIT #1,R1 BNE SYMERR ; ODD GUYS LOSE CALL ENIN ; GET INSTRUCTION BCS SYMERR CMP R0,#177 BEQ SYMERR ; RUBBED OUT MOV #ENINST,R2 MOV O.CAD,R3 MOV R1,O.BW ; SAVE LENGTH 10$: MOVB (R2)+,(R3)+ ; REPLACE INSTRUCTION SOB R1,10$ CLR R2 CLR R3 JMP O.CLGL .SBTTL "-->-<-^-_-@" PROCESSOR - CLOSE AND OPEN REGISTERS CLCRET: JSR PC,PUTCAD ; CARRIAGE RETURN DECODE CLLSTH: JSR PC,PUTCAD ;LESS THAN, BACK TO MAIN STREAM MOV O.DOT,O.CAD ;RESTORE PREVIOUS SEQUENCE BR O.OP2A ; ;LINE FEED, NEXT ONE DOWN CLLNFD: MOV #15,O.EOL ; SET EOL TO . HAS ALREADY BEEN ECHOED. CLLF1: JSR PC,PUTCAD ; PUT DATA IN CURRENT ADDR O.OP5: ADD O.BW,O.CAD ;GENERATE NEW ADDRESS TST O.SEQ ; IN SEQUENCE? BEQ O.OP2 ; NO CMP O.CAD,O.HI ; IN RANGE? BLO O.OP2 ; YES: CONTINUE CLR O.SEQ ; NO: CLEAR INDICATOR, MOV #IO.DET,DPBIOF ; DETATCH TTY MOV #DPBQIO,-(SP) RSX11 SUB O.BW,O.CAD ; BACKUP CURRENT ADDR, CLR O.OPN ; CLOSE CELL & JMP O.NEWE ; GO BACK TO MAIN LOOP O.OP2: MOV O.CAD,O.DOT ;INITIALIZE DOT O.OP2A: JSR PC,O.TEOL ;END-OF-LINE MOV O.CAD,R0 ;NUMBER TO TYPE JSR PC,O.RORA ; CHECK FORMAT MOVB O.FM,R0 ;SET FORMAT ASR R0 ;SPLIT R0 IN HALF MOVB COMTAB(R0),R0 ;SET SUFFIX CHARACTER JSR PC,O.FTYP ;PRINT IT MOV O.CAD,R4 ;SET UP THE DATA CLR R2 ; SET TO USE O.CAD ADDRESS CLRB O.OP ;THIS IS BECUZE CLR O.EXP JUMP O.CLGL ;R0 HAS TERMIN, R4- DATA, R2= FLAG CLUPAR: JSR PC,PUTCAD ;UP ARROW, NEXT ONE UP SUB O.BW,O.CAD ;GENERATE NEW ADDRESS BR O.OP2 ;GO DO THE REST ;BACK ARROW, PC RELATIVE COMPUTE CLBACK: JSR PC,O.TCLS ;TEST WORD MODE AND CLOSE ADD @R2,R2 ;COMPUTE INC R2 INC R2 ; NEW ADDRESS O.PCS: MOV R2,O.CAD ;UPDATE CAD BR O.OP2A ;GO FINISH UP ;AT SIGN, ABSOLUTE OR INDIRECT CHAIN CLATSG: JSR PC,O.TCLS ;TEST WORD MODE AND CLOSE MOV @R2,R2 ;GET ABSOLUTE ADDRESS BR O.PCS ;SOURCE, DESTINATION O.SRC: MOV SRCEA,O.CAD BR O.OP2 O.DST: MOV DSTEA,O.CAD BR O.OP2 CLGRTH: JSR PC,O.TCLS ;TEST AND CLOSE MOVB @R2,R1 ;COMPUTE NEW ADDRESS, EXTEND SIGN ASL R1 ;R2=2(@R2) INC R1 ; +2 INC R1 ADD R1,R2 ; +PC BR O.PCS ;HANDY DANDY TO DO SOME LEG WORK O.TCLS: JSR PC,PUTCAD ;CLOSE CURRENT CELL CMP #2,O.BW ;ONLY WORD MODE ALLOWED BNE O.ERR1 ;BRANCH IF ERROR MOV O.CAD,R2 ;CURRENT ADDRESS IN R2 RTS PC .SBTTL "=" PROCESSOR - PRINT LEFT SIDE EXPRESSION ON RIGHT SIDE EQUALS: MOV R4,R0 ;PROPER PRIOR PLANNING PREVENTS MOVB O.FM,R1 ;FORMAT CMP R1,#NORC*2 ;OPEN-REG COMMAND? BLO 10$ ;YES MOV #2,R1 ;NO: USE OCTAL WORD FORMAT 10$: JSR PC,@TYFORM(R1) ;TYPE IN CURRENT FORMAT JMP O.NEWC ;JUST ANOTHER ERROR CALL O.ERR1: ERROR .SBTTL "G" PROCESSOR - GO TO PROGRAM COMMAND ;SYNTAX-- ;LG START PROGRAM AT LOCATION L ;G START PROGRAM AT CURRENT PC O.GOTO: TST R2 ;SEE IF SPECIFIC ADDRESS BEQ 10$ ;NO MOV R4,O.UPC ;SET THE PC 10$: CLRB O.S ;NO SINGLE INSTRUCTIONS MOVB #O.BKP+3,O.P ;GOTTA BREAK TO PROCEED O.TBIT: CLRB O.T ;CLEAR T-BIT FLAGS BIS #O.TBT,O.UST ;BOTH TSTB O.S ;SEE IF WE NEED A T-BIT BIT BNE O.GRTT ;NO GO ON BIC #O.TBT,O.UST ;SET THE TEE BIT JSR PC,O.RSB ;RESTORE BREAKPOINTS O.GRTT: JSR R0,O.RSR ;RESTORE USER REGISTERS MOV O.UST,-(SP) ; AND STATUS MOV O.UPC,-(SP) ; AND PC TST O.LAST ; SST LAST A BPT? BEQ 20$ ; NO DEC O.LAST ; YES, ZERO FLAG MOV O.DSW,-(SP) ; SET USER'S DSW ON STACK IN CASE OF NESTING TST $DSW ; AST'S ALREADY DISABLED? BMI 10$ ; YES, DON'T REENABLE THEM ENAR$S ; NO, REENABLE ASTS 10$: MOV (SP)+,$DSW ; RESTORE USER'S DSW 20$: JMP @O.RTN ; RETURN TO USER O.RTT: RTT ; FOR 11/40, 11/45, AND 11/50 O.RTI: RTI ; FOR 11/10, AND 11/20 .SBTTL "S" PROCESSOR - SINGLE STEP PROCEED COMMAND ;SYNTAX-- ;NS EXECUTE N INSTRUCTIONS AND THEN STOP ;S EXECUTE ONE INSTRUCTION O.SNGL: MOVB #O.BKP+2,R0 ;FAKE THE BREAK MOVB R0,O.S ;SET THE FLAG FOR S.I. MODE BR O.PR01 ;FAKE A PROCEED IN S.I. MOOD .SBTTL "P" PROCESSOR - PROCEED FROM BREAKPOINT COMMAND ;SYNTAX-- ;NP PROCEED THRU THIS BREAKPOINT N TIMES ;P ASSUME N=1 O.PROC: CLRB O.S ;SET FAST MODE MOVB O.P,R0 ;GET NUMBER OF BREAK BMI O.ERR1 ;THERE WASN'T ONE SO FAR ? O.PR01: TST R2 ;SEE IF VALUE IN R4 VIA R2 BNE 10$ ;SEE IF AND WHAT SETTING FOR COUNT MOV #1,R4 ;INIT IT TO ONE FOR A START 10$: MOV R4,O.CT(R0) ;SET USER'S COUNT O.C990: CMPB O.P,#O.BKP ;SEE IF A REAL ONE OR A FAKE BGT O.TBIT ;BRANCH IF FAKE TSTB O.S ;SEE IF SINGLE INSTRUCTION MODE BNE O.TBIT ;IF SO EXIT NOW INCB O.T ;SET T-BIT FLAG BIS #O.TBT,O.UST ;SET T-BIT BR O.GRTT .SBTTL SST INTERRUPT ROUTINES, COMMON INTERRUPT SERVICE AND DISPATCHER V.INTR: MOV (SP)+,O.UPC ;SET THE USER PC VALUE MOV (SP)+,O.UST ;AND HIS ENTRY STATUS JSR R0,O.SVR ;SAVE REGISTERS 0-6 TSTB O.P ;SEE IF CONTROLLED BREAKPOINT BNE 10$ ;NOT DUE TO A PLANNED INTERRUPT TSTB O.T ;IS A BPT OR T-BIT, SEE IF A PROCEED BNE O.TBIT ;COMMAND IS BEING DONE, GO FINISH IT TSTB O.S ;NO REMOVAL OF BREAKS ON S.I. MODE BNE 12$ ;SKIP NEXT TWO WORDS 10$: JSR PC,O.REM ;REMOVE BREAKPOINTS 12$: MOV O.UPC,R5 ;GET A COPY OF THE PC AT INTERRUPT MOV #ZERO-O.BPTP,R3 ; TO PREVENT GARBAGE ON BP AUTOPRINT, IF NOT BP TSTB O.P ;BREAKPOINT OR T-BIT CHECK BNE 30$ ;DEFINITELY NOT A BREAKPOINT MOVB O.S,R4 ;SEE IF SINGLE STEPPING BNE 22$ ;AND PRETEND ;AT THIS POINT IT MAY BE DUE TO MCR, T-BIT, OR A BPT MOVB #O.BKP+2,O.P ;SET ALLOW TO THE 8'TH ONE CMP -(R5),O.TRTC ;BACK-UP R5 AND SEE WHAT'S UP BEQ 30$ ;IT WAS A NON-BREAK BPT MOV #O.BKP,R4 ;SET ADDRESS OF LEGIT BREAKS 15$: CMP R5,O.ADR1(R4) ;LOOK IT UP IN THE TABLE BEQ 20$ ;FOUND THE NASTY LITTLE BUGGER SUB #2,R4 ;KEEP AT IT BGE 15$ ;UNLESS NO MORE MOV #"MC,R4 ;NOT THERE, MUST BE MCR INDUCED TST (R5)+ ;RESET PC TO MAKE IT RIGHT BR 26$ ;LABOR 20$: MOV R5,O.UPC ;BACK-UP PC FOR BREAKPOINT 22$: MOVB R4,O.P ;BREAKPOINT IS A REAL ONE DEC O.CT(R4) ;CHECK OUT THE PROCEED COUNT BNE O.C990 ;LABOR ON A MIS-CONCEPTION INC O.CT(R4) ;RESET PROCEED COUNT MOV R4,R3 ; SAVE BREAKPOINT NUMBER ASR R4 ;OCTAL TO UN-BIASED ASCII ADD #"0B,R4 ;BIAS TO ASCII 26$: MOV R4,ENPRFX ;SET THE PREFIX UP ;COMMON TYPE ROUTINE FOR SST VECTORS USED UP 30$: JSR PC,O.TEOL ; END-OF-LINE MOV ENPRFX,R0 ;THE PREFIX JSR PC,O.TYPE MOV #':,R0 ;THE MIDDLE OF THE ENTRY CLUE JSR PC,O.FTYP MOV R5,R0 ;TYPE ADDRESS OF INTERRUPT JSR PC,O.RORA ;AND THE REST OF THE ENTRY MOV O.BPTP+20,R0 ; AUTO PRINT ADDR FOR ALL BKPT'S (AT $8P) BNE 35$ ; EXISTS MOV O.BPTP(R3),R0 ; NOW TRY AUTO PRINT ADDR FOR THIS BKPT # BEQ 40$ ; NONE SPECIFIED 35$: MOV R0,O.CAD ; FAKE SOMETHING JMP O.OP2A ; GO OFF AND PRINT 40$: DECODE .SBTTL SST INTERRUPT VECTOR ENTRY POINTS .IF DF M$$MGE ;SEGMENT FAULT - V1 - "MP" - NO PROCEED ; SP+ 12,10,6 REAL DATA, PS, PC ; 4,2,0 SR0,SR2,SR1 V.SGMT: MOV (SP)+,SSTSTK+4 ;SR1 TO $2E MOV (SP)+,SSTSTK+2 ;SR2 TO $1E MOV (SP)+,SSTSTK+0 ;SR0 TO $0E MOV #"MP,ENPRFX ;ENTRY PREFIX .ENDC V.NIXP: MOVB #-1,O.P ;NO PROCEED BR V.INTR ;COMMON INTERRUPT ;ODD ADDRESS - V0 - "OD" - NO PROCEED ;BPT OR T-BIT - V2 - "BE" - SPECIAL CASES ;IOT - V3 - "IO" - PROCEED ;RESERVED OR ILLEGAL - V4 - "IL" - NO PROCEED ; SP+ 4,2,0 LIVE DATA, PS, PC V.ODDA: MOV #"OD,ENPRFX ;"OD:" FOR ODD ONE BR V.NIXP ;NIX ON PROCEED V.BPTI: MOV $DSW,-(SP) ; SAVE USER'S DSW DSAR$S ; DISABLE AST'S MOV (SP)+,O.DSW ; SAVE USER'S DSW INC O.LAST ; SET LAST SST WAS A BPT ; DSW IS NOT THAT FROM DISABLE AST DIRECTIVE MOV #"BE,ENPRFX ;"BE:" FOR MAYBE A BAD ENTRY CLRB O.P ;ALLOW PROCEED DEAL BR V.INTR ;SPECIAL NUMBER FOR THIS ONE V.IOTX: MOV #"IO,ENPRFX ;"IO:" FOR IOTEE BR V.ALOP ;ALLOW PROCEED V.ILLI: MOV #"IL,ENPRFX ;"IL:" FOR ILL INSTRUCTION BR V.NIXP ;NO GO ;NON RSX EMT - V5 - "EM" - PROCEED ;TRAP - V6 - "TR" - PROCEED ;PDP 11/40 FLOAT POINT - V7 - "FP" - PROCEED ; SP+ 6,4,2 HONEST DATA, PS, PC ; 0 LO BYTE X 2 / FPP CONDITION CODES, INTO $0E V.NEMT: MOV #"EM,ENPRFX ;"EM:" FOR EMTEE BR V.V700 V.TRAP: MOV #"TR,ENPRFX ;"TR:" FOR TRAPPED BR V.V700 V.FPPE: MOV #"FP,ENPRFX ;"FP:" FOR FLOT POINT V.V700: MOV (SP)+,SSTSTK+0 ;SET UP $0E V.ALOP: MOVB #O.BKP+2,O.P ;ALLOW PROCEED JMP V.INTR ;PROCESS IT COMMONLY .SBTTL COMMAND PROCESSORS, SECTION THREE ( L V X W N E F ) .SBTTL "L" PROCESSOR - LIST MEMORY ON THE CONSOLE ;SYNTAX-- ; S;FL WHERE: ; S IS START ADDRESS, SETS $L IF THERE ; F IS STOP ADDRESS, SETS $H IF THERE O.LIST: TST R2 ;SET UPPER AND LOWER LIMITS BEQ 10$ ;IF SPECIFIED TO DO SO MOV R4,O.HI 10$: TST R3 ;DO THE LOW ONE BEQ 15$ MOV R5,O.LOW 15$: CMPB O.FM,#NORC*2 ; CK FORMAT FOR OPEN-REG COMMAND BLO 19$ ; YES CMP O.LOW,O.HI ; CHECK RANGE BHI 18$ ; NG MOV O.LOW,O.CAD ; INITIALIZE CURRENT ADDR TO LOW INC O.SEQ ; SET SEQUENCE INDICATOR MOV #IO.ATT,DPBIOF ; ATTATCH TTY MOV #DPBQIO,-(SP) RSX11 JMP O.OP2 ; GOTO LF HANDLER 18$: ERROR 19$: JSR PC,SARSET ;SET UP THE LIMITS TO START TST -(SP) ;MAKE A HOLE IN THE STACK 20$: CLR (SP) ;NEW LINE UP JSR PC,SNAGIT ;ACCESS DEVICE FOR DATA JSR PC,SPRINT ;PRINT ADDRESS AND FIRST ITEM 25$: JSR PC,SNAGIT ;GET MORE DATA JSR PC,DPRINT ;JUST PRINT THE DATA INC (SP) ;COUNT THE DATA CMP #7,(SP) ;CHECK THE COUNT BNE 25$ ;JUST LIKE THEY TOLD YOU AT THE BR 20$ ;FAMOUS PROGRAMMERS SCHOOL .SBTTL "V" PROCESSOR - RESTORE USER SST VECTORS ;SYNTAX-- ; V WHERE IT AIN'T GOT BUT ONE THING TO DO O.SSTR: JSR PC,RESSST ;REST DECODE ;COMMON RESTORE THEM ROUTINE RESSST: MOV #10,R0 ;TEN VECTORS MOV #20$,R1 ;CLEAN COPY MOV #SSTVEC,R2 ;DIRTY COPY 10$: MOV (R1)+,(R2)+ ;CLEAN TO DIRTY DEC R0 ; DONE? BNE 10$ ; NO, LOOP RTS PC ;COPY OF THE VECTORS TO RESTORE WITH 20$: + V.ODDA ;0-ODD ADDRESS .IF DF M$$MGE .IFT + V.SGMT ;1-SEGMENT FAULT .IFF + 0 ; NO SEGMENT TRAP POSSIBLE IN NON-MAPPED SYSTEM .ENDC + V.BPTI ;2-BPT OR T-BIT + V.IOTX ;3-IOT + V.ILLI ;4-RESERVED OR ILLEGAL INSTRUCTION + V.NEMT ;5-NON RSX-11 EMT + V.TRAP ;6-TRAP + V.FPPE ;7-PDP 11/40 FLOATING POINT EXCEPTION .SBTTL "X" PROCESSOR - EXIT THE WORKS TO RSX-11 ;SYNTAX-- ; X O.EXIT: CLOSE$ #STBFLE ; OSE SYMBOLS FILE JSR PC,O.TEOL ;SAY GOOD BYE IN OUR OWN WAY MOV (PC)+,-(SP) ;VERY SIMPLE, THIS ONE .BYTE 51.,01. ;DPB FOR EXIT TASK RSX11 ERROR .SBTTL "W" PROCESSOR - MASKED EQUAL WORD SEARCH ;SYNTAX-- ;M;AW SET $M TO M, SET $A TO A, DO SEARCH ;AW SET $A TO A, DO SEARCH ;W USE $L, $H, $M, $A TO SEARCH. PRINT HITS O.WSCH: JSR PC,SARGUS ;SET UP $A, $M AND R5 10$: JSR PC,SNAGIT ;R5 IS MEMORY INDEX, CHECK FOR IT BNE 10$ ;NOT EQUAL IS NOT THE OBJECTIVE JSR PC,SPRINT ;PRINT LOCATION AND VALUE BR 10$ ;MOVE ON .SBTTL "N" PROCESSOR - MASKED NOT EQUAL WORD SEARCH ;SYNTAX-- ;N COMMAND IS "N", FORMS AS ARE FOR "W" O.NOTW: JSR PC,SARGUS 10$: JSR PC,SNAGIT BEQ 10$ ;THE ONLY DIFFERENCE JSR PC,SPRINT BR 10$ .SBTTL "E" PROCESSOR - MASKED EFFECTIVE ADDRESS ;SYNTAX-- ;E COMMAND IS "E", FORMS ARE AS ABOVE IN "W" AND "N" O.EFFA: JSR PC,SARGUS ;SET IT ALL UP PLEASE 10$: JSR PC,SNAGIT ;GET THE DATA VIA R5 BEQ 15$ ;SAME ABSOLUTE ADDRESS FOUND MOV R5,R0 ;DO THE PC REL JSR PC,SRCHEF ;GO SEE IF MASKED SAME BEQ 15$ ;SAME PC RELATIVE ADDRESS MOVB R5,R0 ;DISPLACEMENT INTO R1, SIGN EXTEND ASL R0 ;CARRY IS CLEAR JSR PC,SRCHEF ;CHECK IT BNE 10$ ;SAME BRANCH DISPLACE IN FALL THRU 15$: JSR PC,SPRINT BR 10$ .SBTTL "F" COMMAND - FILL MEMORY WORDS ;AF SET ARG REGISTER, FILL WITH $A FROM $L TO $H O.FILL: CLR R3 ;NO MASK IS TO BE SET JSR PC,SARGUS ;SET UP ARG AND R5 10$: JSR PC,SNAGIT ;GET LOC IN R5 MOV SP,R2 ;PRETEND DATA IS HERE MOV O.ARG,R4 ;THIS IS WHY MOV O.OBW,O.BW ;OPEN THE ITEM JSR PC,PUTCAD ;PUT THE DATA BR 10$ ;GO TILL BROKEN .SBTTL UTILITIES - SAVE AND RESTORE USER DATA. ;SAVE REGISTERS R0-R6, SET ODT'S STACK UP JSR R0,O.SVR O.SVR: MOV (SP)+,O.UR0 ;PICK R0 FROM STACK AND SAVE MOV SP,O.USP ;SAVE USER STACK ADDRESS MOV #O.USP,SP ;SET TO INTERNAL STACK MOV R5,-(SP) ;SAVE MOV R4,-(SP) ; REGISTERS MOV R3,-(SP) ;5 MOV R2,-(SP) ; THRU MOV R1,-(SP) ; 1 CMP -(SP),-(SP) ;SET UP ODT'S STACK AND COVER R0 SAVE JSR R5,DOAEMT ;GO SET SST VECTOR FOR ODT + DPSSTO RTS R0 ;RESTORE REGISTERS R0-R6, SET USER'S SST JSR R0,O.RSR O.RSR: MOV #V.BPTI,SSTBPT ;USER CAN'T SET THAT ONE JSR R5,DOAEMT ;SET THE USER'S SST VECTORS + DPSSTU CMP (SP)+,(SP)+ ;POP THE EXTRA CELLS MOV (SP)+,R1 ;RESTORE MOV (SP)+,R2 ; REGISTERS MOV (SP)+,R3 ; 1 MOV (SP)+,R4 ; THRU MOV (SP)+,R5 ; 5 MOV O.USP,SP ;RESTORE USER STACK MOV O.UR0,-(SP) ;PUT R0 ON USER STACK RTS R0 ;PUT USER R0 IN REAL R0 ;RESTORE BREAKPOINTS 7-0 JSR PC,O.RSB O.RSB: MOV #O.BKP,R4 ;RESTORE ALL BREAKPOINTS 10$: MOV @O.ADR1(R4),O.UIN(R4) ;SAVE CONTENTS MOV O.TRTC,@O.ADR1(R4) ;REPLACE WITH TRAP SUB #2,R4 ;DE CRE MEN T LOOOOP COUNTER BGE 10$ ;RE-LOOP UNTIL DONE RTS PC ; THEN QUIT ;REMOVE BREAKPOINTS 0-7, OPPOSITE ORDER!! JSR PC,O.REM O.REM: CLR R4 ;REMOVE ALL START WITH 0 10$: MOV O.UIN(R4),@O.ADR1(R4) ;INSTR BACK TO PROGRAM TST (R4)+ ;BUMP BUMP CMP #O.BKP,R4 BHIS 10$ ;LOOP RTS PC ;THEN SPLIT .SBTTL UTILITIES - COMMAND SUPPORT ROUTINES ;TEST FOR VALID RELOCATION REGISTER IN R4 O.RTST: TST R4 BMI O.RTS9 ;LOW IS NO GOOD CMP R4,#O.BKP/2 ;GET A GOOD NUMBER FOR A REGISTER BHI O.RTS9 ;NOT TOO GOOD, QUESTION IT ASL R4 O.RTS8: CLC RTS PC O.RTS9: SEC RTS PC ;RESET BREAKPOINT VIA VALUE IN R4 AND R0 SETBRK: CMP #O.BKP,R4 ;SEE IF LEGAL REFERENCE BLO O.RTS9 ;NO GO SIGNAL ON SPLIT MOV R0,O.ADR1(R4) ;SET THE ADDRESS MOV (R0),O.UIN(R4) ;SET THE INSTRUCTION/ OR TRAP MOV #1,O.CT(R4) ;RESET PROCEED COUNT TO 1 TST (R4)+ ;A TOUCH BR O.RTS8 ;GOOD SPLIT ;SNAG MEMORY LOCATION AND CHECK FOR = JSR PC,SNAGIT ;NEEDS-- ;O.CAD POINTS TO MEMORY WORD (APPROXIMATELY THAT IS) ;R0,R5 CONTAINS REAL WORD UPON EXIT TO "SRCHEK" ;FALLS THRU TO "SRCHEK" FOR THE NITTY GRITTY SNAGIT: MOV O.OBW,R0 ; MODE WD ADD R0,O.CAD ; ADD INCREMENT AND NOW CMP O.CAD,O.HI ;SEE IF MORE TO DO BLO 10$ ;IF NOT DO NOT DECODE ;GO RESET STACK AND NO NEXT COMMAND 10$: JSR PC,GETCAD ;ACCESS METHOD MOV R0,R5 ;MAKE A COPY FOR LATER ;MASKED SEARCH CHECKER JSR PC,SRCHEK ;NEEDS-- ;R0 HAS OBJECT UNDER TEST ;SEES IF R0 UNDER MASK IS SAME AS ARGUMENT UNDER MASK ;RETURNS-- ;CODES SET FOR BEQ GOOD FOR SAME, R0=0 ; BNE GOOD FOR NOT SAME, R0<>0 SRCHEK: MOV R0,R2 ;MAKA COPY MOV O.ARG,R1 ;DE ARGUMENT TO COMPARE AGAINST BIC R1,R0 ; (NOT A) AND O = X BIC R2,R1 ; (NOT O) AND A = Y BIS R0,R1 ; X IOR Y = Z MOV O.MSK,R0 COM R0 BIC R0,R1 ;(NOT (NOT M)) AND Z = R1 RTS PC ;BACK TO NEXT ONE ;FINISH EFFECTIVE ADDRESS COMPUTE AND CHECK IT, R0 HAS THE ADDRESS SRCHEF: ADD #2,R0 ;TWO CAUSE THE PC GETS TWO TOO ADD O.CAD,R0 ;RELOCATION PLEASE BR SRCHEK ;DO THE LOGICAL COMPARE ;SET UP SEARCH ARGUMENTS JSR PC,SARGUS ;JUST SET UP LIMIT JSR PC,SARSET ;SETS UP-- ;O.ARG IF R4 IS VALID ;O.MSK IF R5 IS VALID ;O.CAD,O.OBW USED TO GET THE ADDRESS TO START OUT WITH SARGUS: TST R2 BEQ 10$ MOV R4,O.ARG ;SET THE SEARCH ARGUMENT 10$: TST R3 BEQ SARSET MOV R5,O.MSK SARSET: MOV O.LOW,O.CAD ;SET THE START OF START SUB O.OBW,O.CAD RTS PC ;SEARCH HIT PRINT JSR PC,SPRINT ;O.CAD POINTS TO THE LOC TO BE PRINTED ;R5 CONTAINS THE CONTENTS OF THE LOCATION TO BE PRINTED SPRINT: JSR PC,O.TEOL MOV O.CAD,R0 ;THE LOCATION JSR PC,O.RORA ;THE MODE MOVB O.FM,R0 ;PICK UP OLD CURENT MODE ASR R0 ;HALVES MOVB COMTAB(R0),R0 ;AH HA JSR PC,O.FTYP ;TYPE THE MODE DESIGNATOR ;DATA PRINT ROUTINE JSR PC,DPRINT ;PRINTS DATA IN R5 IN CURRENT MODE DPRINT: MOVB O.FM,R1 ;SET THE MODE MOV R5,R0 ;THIS IS THE POOR DATA MOV R5,-(SP) ;SAVE THE DATA JSR PC,@TYFORM(R1) ;DO THAT __ TO THE POOR DATA MOV (SP)+,R5 ;RESTORE THE DATA RTS PC ;RESTORE THE PC ;EXPRESSION COMPUTATION ROUTINE JSR PC,EXPCOM ;NEEDS-- ;O.OP THE OPERATION (-2=*, 0=+, *=2) ;O.EXP THE LEFT SIDE ;R4 THE RIGHT SIDE ;SETS UP-- ;O.OP BACK TO 0 FOR ADD ;O.EXP,R4 ALL SO FAR EXPCOM: TSTB O.OP ;SEE WHAT'S UP CHUCK BMI 20$ BEQ 10$ NEG R4 ;MINUS, OP=2 10$: ADD O.EXP,R4 ;PLUS, OP=0 15$: MOV R4,O.EXP ;COMMON OUT, SET EXP TO WHATEVER CLRB O.OP ;IS IN R4 TOO INC R2 ;SET R2 SO THAT R4 IS, OP=0 RTS PC 20$: MOV R3,-(SP) ;SAVE AN ODD AND END MOV O.EXP,R3 ;GET THE LEFT SIDE OF EXPRESSION .IF DF R$$11M .IFF MUL #50,R3 ;SHIFT IT OVER BY 50 .IFT ASL R3 ; MULTIPLY BY 10 ASL R3 ; ASL R3 ; ADD R3,R4 ; ADD IT ASL R3 ; MULTIPLY BY 40 ASL R3 ; WHICH IS LIKE MULTIPLYING BY 50 .ENDC ADD R3,R4 ;AND ADD IT TO THE RIGHT MOV (SP)+,R3 ;PUT R3 BACK, THANK YOU BR 15$ ;COMMON OUT ;BUILD AN OCTAL NUMBER JSR PC,GETNUM ;NEEDS AND RETURNS-- ;R0 NON-OCTAL TERMINATING CHARACTER ;R2 OCTAL CHARACTER COUNT ;R4 OCTAL NUMBER THAT I GOT, YOU GET GETNUM: CLR R2 ;NEW R2 AND R4 CLR R4 10$: CALL O.GET ;GET 1 CHARACTER CMPB #' ,R0 ; SPACE? BEQ 20$ ; YES CMPB #'0,R0 ;NON-OCTAL, LESS THAN "0" BHI 30$ CMPB #'7,R0 ;NON-OCTAL, LESS THAN "7" BLO 30$ BIC #177770,R0 ;MAKE INTO ACCEPTABLE RANGE SHIFT 3,R4 ADD R0,R4 ;PLANT LO PLACE INC R2 ;ACCOUNT FOR NEW ONE BR 10$ ;NEXT ONE OR OTHER 20$: TST R2 ; ANY DIGITS? BEQ 10$ ; NO: IGNORE SPACES 25$: CALL O.GET ; READ CHAR UNTIL NON-SPACE CMPB #' ,R0 ; SPACE? BEQ 25$ ; YES 30$: RTS PC ;SCAN A LIST OF CHARACTERS JSR R5,LOOKUP ;CALL-- ; R0 HAS THE CHARACTER ; JSR R5,LOOKUP ;THAT IS IT ; + LIST TO USE, 00 BYTE IS END OF LIST ;RETURNS AT CALL + 2 WITH-- ;R0 STILL HAS CHARACTER ;R1 HAS INDEX X2 OF FOUND CHARACTER IF C=0 ;C=1 CHARACTER WAS NOT FOUND LOOKUP: MOV (R5),R1 ;GET LIST START 10$: CMPB R0,(R1) ;IS THIS THE ONE BNE 20$ ;RIGHT IT WASN'T SUB (R5)+,R1 ;COMPUTE INDEX AND RETURN ASL R1 ;DO THIS FOR EVERBODY, C=0 BR 30$ 20$: TSTB (R1)+ ;CHECK FOR END OF LIST BNE 10$ ;IF NOT LOOK AT NEXT ITEM TST (R5)+ ;END, AVOID ILLEGAL INSTRUCTION SEC ;SECURITY EXCHANGE COMMISION 30$: RTS R5 ;SECURITY ELSEWHERE ;GET CONTENTS OF ADDRESS IN THE MODE JSR PC,GETCAD ;NEEDS-- ;R0 THE MODE 1=BYTE, 2=WORD ;O.CAD THE ADDRESS ;O.DEVI THE DEVICE CODE ;RETURNS-- ;R0 HAS THE DATA YOU ASKED FOR GETCAD: MOV O.CAD,R3 ; GET CORE ADDRESS MOV SP,O.OPN ; SET LOCATION OPEN ASR R0 ;PUSH BW FLAG INTO CARRY BIT BCC 10$ ;2 WON'T FIT SO IS WORD MOVB (R3),R0 ;ACCESS BYTE BR GETC99 10$: MOV (R3),R0 ;ACCESS WORD GETC99: RTS PC ;STACK ACCESS ;PUT R4 INTO ADDRESS IN THE MODE JSR PC,PUTCAD ;NEEDS-- ;R2 CONTENT FLAG, 0 FOR NONE, ELSE R4 IS GOLD ;R4 THE DATA ;O.BW THE MODE FLAG, IF 0 THEN NO LOCATION OPEN PUTCAD: TST R2 ;CHECK FOR TYPED VALUE BEQ 12$ ;NO DATA NO DODO MOV O.BW,R0 ;PICK UP MODE AN CC'S TST O.OPN ; IS A LOCATION OPEN AT PRESENT? BEQ 12$ ;NOT OPEN NOT STORED MOV O.CAD,R3 ; GET CORE ADDRESS BIT #177776,R0 ;CHECK MODE BNE 10$ ;WORD MODE MOVB R4,(R3) ;BYTE MODE BR 12$ ;BRANCH MODE 10$: MOV R4,(R3) ;WORD MODE 12$: RTS PC .SBTTL UTILITIES - TELETYPE I/O ROUTINES ;TYPE END-OF-LINE JSR PC,O.TEOL O.TEOL: MOV O.EOL,R0 ; USE CURRENT EOL CHARS MOV O.CRLF,O.EOL ; RESET END-OF-LINE WITH ;TYPE TWO CHARS IN R0 PLEASE JSR PC,O.TYPE O.TYPE: JSR PC,O.FTYP ;DO ONE SWAB R0 ;TYPE ONLY ONE CHARACTER IN R0 JSR PC,O.FTYP O.FTYP: MOV #IO.WLB,DPBIOF ;SET WRITE FUNCTION MOVB R0,CHRBUF ;PUT CHAR IN BUFF ;GENERAL QIO TO CONSOLE ROUTINE DOAQIO: MOV $DSW,-(SP) ; SAVE DSW MOV IOLUNS+4,-(SP) ;SET UP THE EVENT ON THE STACK MOV (SP),DPBEFN ;SET UP EVENT IN THE DPB MOV #DPBQIO,-(SP) ;POINT TO THE DPB RSX11 ;POINT TO THE EXEC MOV (PC)+,-(SP) ;PUSH A WAITFOR SINGLE EVENT .BYTE 41.,02. ;WAITFOR=41., SIZE=2. RSX11 ;GO WAIT MOV (SP)+,$DSW ; RESTORE DSW RTS PC ;GO BACK ; OPEN INPUT FILE OPNIPT: MOV IOLUNS+0,GCMLB+42 ; USE TTY LUN GCML$ #GCMLB,#PRMPTS,#PRMPTL ; PROMPT FOR .STB FILE BCS 99$ ; HE GOOFED CLR CSI+C.CMLD ; CLEAR HI-BYTE, SINCE CSI IS OVERLAID BY LNEBUF MOVB GCMLB+G.CMLD,CSI+C.CMLD ; CMD LINE SIZE (HI-BYTE HAS TERM CHAR) MOV GCMLB+G.CMLD+2,CSI+C.CMLD+2 ; CSI$1 #CSI BCS 99$ ; ERROR DURING SYNTAX CHECK CSI$2 #CSI,OUTPUT ; GO FIND A F/S BCS 99$ ; RATS MOV STBFDB,R0 ; IS THERE A SYMBOLS FILE OPEN ? BEQ 10$ ; NO CLOSE$ ; YES, CLOSE IT CLR STBFDB ; REMEMBER ITS CLOSED 10$: MOV IOLUNS+2,R1 ; GET SYMBOL FILE LUN ALUN$S R1,#"SY ; ASSIGN LUN TO SY: OPEN$R #STBFLE,R1 ; TRY OPEN IT FOR READ BCS 99$ ; IT JUST ISN'T THERE OLD BEAN MOV R0,STBFDB ; REMEMBER THAT IT IS OPEN DECODE 99$: JSR PC,O.TEOL ERROR PRMPTS: .ASCII / .STB FILE: / PRMPTL=.-PRMPTS .EVEN ;GENERAL CHAR INPUT ROUTINE O.GET: MOVB O.BACK,R0 ; BACKED-UP CHAR BNE 13$ ; EXISTS: EXIT WITH BACKED-UP CHAR MOV #IO.RLB,DPBIOF ;SET READ JSR PC,DOAQIO ;DO A QIO MOVB CHRBUF,R0 ;GET CHAR INPUT .IF DF R$$11M TST IOSTAT+2 ;IF NON-ZERO, GOT A CHARACTER BNE 5$ ; WE GOT ONE MOVB IOSTAT+1,R0 ; IF ZERO, GET CONTROL CHARACTER 5$: .ENDC JSR R5,LOOKUP ;CHECK IF ALTMODE + ALTTAB .IF DF R$$11M BCS 11$ .IFF BCS 10$ ; .ENDC MOVB #'$,R0 ;CHANGE TO $ IF SO 10$: JSR PC,O.FTYP ; AND ECHO 11$: CMPB R0,#141 ; LOWER CASE? BLT 13$ ; NO CMPB R0,#172 ; MAYBE BGT 13$ ; NO SUB #40,R0 ; YES, CONVERT TO UPPER CASE 13$: CLRB O.BACK ; CLEAR BACKED-UP CHAR RTS PC ;GENERAL EMT EXECUTER ROUTINE DOAEMT: MOV $DSW,-(SP) ; SAVE DIRECTIVE STATUS MOV (R5)+,-(SP) ;SET EXIT ADDRESS AND STACK RSX11 MOV (SP)+,$DSW ; RESET DIRECTIVE STATUS RTS R5 .SBTTL UTILITIES - PRETTY PRINTERS ;PRINT ADDRESS- RELOC, SYMBOLIC, OR ABSL JSR PC.O.RORA ;R0 ADDRESS TO BE PRINTED ;O.FORM CORE ADDRESS FORMAT (0-RELOC 1-ABSOL) ;REGISTER '$R ' OR '$DR ' ;CORE 'D,XXXXXX ' OR 'XXXXXX ' O.RORA: MOV R0,-(SP) ;CALLING VALUE ONA TOPPA STACK CMP #INTBEG,(SP) BHI 50$ ;BELOW FIRST NON-INDEXED CMP #INTEND,(SP) BLO 50$ ;ABOVE LAST NON-INDEXED MOV #'$,R0 ;ANNOUNCE INTENTIONS JSR PC,O.FTYP CMP #INTINX,(SP) BLOS 20$ ;GO TO DO INDEXED MOV (SP)+,R0 ;NON-INDEXED REGISTER ----- "$R " SUB #INTBEG,R0 ;CLEANED UP STACK, GET OFFSET ASR R0 ;BYTE THAT WORD, WORD THAT BYTE MOVB NIXMAP(R0),R0 ;MAGIC CHARACTER FROM TABLE 15$: BIS (PC)+,R0 .BYTE 000,' ;CHARACTER PLUSSA BLANK JMP O.TYPE ;NAME PLUS BLANK AND SPLIT 20$: CLR R1 ;SEE WHICH SET OF TABLES WE GOT 22$: CMP INXTBL+2(R1),(SP) ;LOOK ON AHEAD TO FIND BEHIND BHI 24$ ;R1 POINTS TO BASE OF SET TST (R1)+ ;THINK ABOUT THOSE DUMMY ENTRIES DUMMY BR 22$ 24$: MOV (SP)+,R0 ;INDEXED REGISTER ---- "$DR " SUB INXTBL(R1),R0 ;GET ADDRESS AND COMPUTE OFFSET IN WORDS ASR R0 ;AND FINALLY IN PLAIN TALK ADD #'0,R0 ;CONVERT TO ASCII JSR PC,O.FTYP ;TYPE OUT REGISTER NUMBER ASR R1 MOVB INXREG(R1),R0 ;PICK UP THE REAL CHARACTER BR 15$ ;GO PRINT REST OF IT 50$: MOV R0,O.QUAN MOV R3,R0 ; I WISHED MY REG CONVENTIONS MATCHED MOV (SP)+,R3 CALL DCPRA MOV R0,R3 RTS PC ;TYPE R0 AS BYTE OR WORD, TWO ENTRIES ; FOR A WORD JSR PC,O.CADW ; FOR A BITE JSR PC,O.CADB O.CADW: MOV R0,O.QUAN ;SET THE FAMOUS QUANTITY VALUE MOV #6,R3 ;# OF DIGITS MOV #-2,R4 ;# OF BITS FIRST-3 BR O.CA01 ;DO THE COMMON THING O.CADB: CLR O.QUAN ;SET FOR ALL OF QUAN A BYTE MOVB R0,O.QUAN ;SET THE QUANTITY THING AGAIN MOV #3,R3 ;THERE ARE THREE DIGITS MOV #-1,R4 ;AND ONLY TWO BITS SWAB R0 ;SWITCH ENDS O.CA01: MOV R0,-(SP) ;SAVE R0 10$: ADD #3,R4 ;COMPUTE THE NUMBER OF BITS TO DO CLR R0 15$: ROL (SP) ;GET A BIT ROL R0 ;STORE IT AWAY DEC R4 ;DECREMENT COUNTER BGT 15$ ;LOOP IF MORE BITS NEEDED ADD #'0,R0 ;CONVERT TO ASCII JSR PC,O.FTYP ;TYPE IT DEC R3 ;SEE IF MORE DIGITS TO DO BGT 10$ ;LOOP IF SO MOVB #' ,R0 ;SET UP FOR TRAILING SPACE TST (SP)+ ;GET RID OF JUNK O.FT01: JUMP O.FTYP ;TYPE CONTENTS OF WORD IN FORMAT JSR PC,@TYFORM(R1) ;R0 WORD OR BYTE TO BE TYPED, RHJ ;R1 CODE- ENTRY PT, FORMAT, CODE TYFORM: + O.CADB ;BYTE OCTAL - 0 + O.CADW ;WORD OCTAL - 2 + 30$ ;BYTE ANSII - 4 + 20$ ;WORD ANSII - 6 + 10$ ;RADIX 50 - 10 + 40$ ;SYMBOLIC - 12 10$: JSR PC,TYRADX ;R0 GETS THE RADIX 50 TREATMENT BR 35$ ;APPEND A BLANK TO 3 CHAR'S 20$: JSR PC,O.FTYP ;TYPE BYTE IN R0 SWAB R0 ;SWAP EM AND TYPE IT 30$: JSR PC,O.FTYP ;TYPE OF BYTE IN R0 35$: MOVB #' ,R0 ;SAVE SPACE BR O.FT01 ;ALSO SAVE SPACE 40$: JSR PC,O.RORA BR 35$ ;TYPE CONTENTS OF R0 IN RADIX 50 JSR PC,TYRADX TYRADX: MOV #3,R5 ;COUNT OF CHARACTERS MOV #RD50TB,R2 ;POINTER TO COEFFICENT TABLE MOV R0,R1 ;COPY OF RADIX 50 WORD .IF DF R$$11M .IFF 10$: CLR R0 ;RHJ IN R0 R1 DIV (R2)+,R0 ;R0 HAS QUO(CHAR) R1 HAS REMAINDER .IFT 10$: MOV R1,R0 ; GET DIVIDEND MOV (R2)+,R1 ; GET DIVISOR JSR PC,$DIV ; DIVIDE, R0=QUOTIENT, R1 =REMAINDER TST R0 ; IS QUOTIENT ZERO? (SP)? .ENDC ;RADIX 50 CHAR IN R0, COUNT TO ASCII BEQ 12$ ;"SP" = 040 CMPB R0,#33 ;RAD50-$ =33 BEQ 16$ ;"$" = 044 BGT 14$ ;"." OR "0-9" = 056 OR 060-071 ADD #40,R0 ;RAD50-A = 1, "A" = 101 12$: ADD #16,R0 ;40+16+11+11 = 100 + (A-Z) 14$: ADD #11,R0 ;16+11+11 = 40 + (SP) 16$: ADD #11,R0 ;11+11 = 22 + (.,0-9) JSR PC,O.FTYP ;TYPE CHARACTER IN R0 DEC R5 ;COUNT THE CHARACTERS BNE 10$ ; LOOP RTS PC ;COEFFICENT TABLE, RADIX 50 CONVERT RD50TB: .WORD +1600.,+40.,+1. ;40.^2, 40.^1, 40.^0 .SBTTL OP-CODE TABLE, DEFINITIONS .MACRO OP,INST,TYPE .WORD !OPTY'TYPE .ASCII /INST/ .EVEN .ENDM OP ILOP=0 ; ILLEGAL OP CODE OPADD: OP ADD,SD OPSUB: OP SUB,SD OPMOV: OP MOV,SD OP CMP,SD OP BIT,SD OP BIC,SD OP BIS,SD OPBR: .WORD
!OPTYBR .ASCII /BR/ .WORD 0 OP BNE,BR OP BEQ,BR OP BGE,BR OP BLT,BR OP BGT,BR OP BLE,BR OPBPL: OP BPL,BR OP BMI,BR OP BHI,BR OP BLOS,BR OP BHIS,BR OP BVS,BR OP BCC,BR OP BCS,BR OPCLR: OP CLR,D ; DESTINATION INSTRUCTIONS OP COM,D OP INC,D OP DEC,D OP NEG,D OP ADC,D OP SBC,D OP TST,D OP ROR,D OP ROL,D OP ASR,D OP ASL,D OPSXT: OP SXT,D OPMUL: OP MUL,RS ; REGISTER,SOURCE OP DIV,RS OP ASH,RS OP ASHC,RS OP XOR,RS OPSOB: OP SOB,FN ; FUNNY GUYS OPEMT: OP EMT,FN OPJSR: OP JSR,FN OPTRAP: OP TRAP,FN .IF DF T$$BUG OPDBUG: TRAP 0 .ASCII /DBUG/ ; DUMMY INSTRUCTION: "DBUG" .ENDC OPSWAB: OP SWAB,D OPRTS: OP RTS,FN OPJMP: OP JMP,D OPBPT: OP HALT OP WAIT OP RTI OP BPT OP IOT RESET .ASCII /RSET/ OP RTT OP CLC OP CLV OP CLN OP SEC OP SEV OP SEN OP SCC OP CCC OP NOP OPBPT.: DCDITB: .WORD 077000,DCDISO ; SOB .WORD 070000,DCDIRD ; REGISTER-SOURCE .WORD 060000,DCDIAD ; ADD/SUBRACT .WORD 010000,DCDISD ; S-D .WORD 006700,DCDIST ; SXT .WORD 005000,DCDID ; DESTINATION ONLY .WORD 004000,DCDIEJ ; EMT/JSR .WORD 000400,DCDIBR ; BRANCH FAMILY .WORD 000300,DCDISW ; SWAB .WORD 000240,DCDINO ; CONDITION CODE GUYS .WORD 000200,DCDIRT ; RTS .WORD 000100,DCDIJM ; JUMP .WORD 0,DCDINO SRCEA: .WORD 0 ; SOURCE EFFECTIVE ADDRESS DSTEA: .WORD 0 ; DESTINATION EFFECTIVE ADDRESS DREG: .BLKB 1 ; DESTINATION REGISTER DMODE: .BLKB 1 ; DESTINATION MODE SREG: .BLKB 1 ; SOURCE REGISTER SMODE: .BLKB 1 ; SOURCE MODE INST: .BLKW 1 ; CURRENT INSTRUCTION WD INST.M: .BLKW 1 ; MAGNITUDE SMALL:: .WORD 1000 ; SMALL VALUE FOR INSTR LITERAL & OFFSET CRITERION MDREG=0 ; REGISTER MODE MDINC=2 ; AUTO INCREMENT MDDEC=4 ; AUTO DECREMENT MDINDX=6 ; INDEX REG: .BLKB 1 MODE: .BLKB 1 BUF: .BLKB 82. ; OUTPUT BUFFER -- GCML ALSO OPLEN=6 ; OP-CODE TABLE ELEMENT LENGTH OPTY=0 ; FOR NULL TYPE OPTYND=0 ; NO OPERAND OPTYRS=2 ; REGISTER SOURCE OPTYBR=4 ; BRANCH OPTYD=6 ; DESTINATION ONLY OPTYFN=8. ; FUNNY (I.E. NONE OF THE ABOVE) OPTYSD=10. ; SOURCE-DESTINATION .SBTTL SYMBOL TABLE JUNK ; OUR ONLY SYMBOL (INPUT) SYMSPC: .BLKB 8. SYMR50: .BLKW 1 ; RAD-50 EQUIVALENT SYMR51: .BLKW 1 REGS: .ASCII /R0R1R2R3R4R5SPPC/ ; REGISTER DEFINITION (FOR THAT TIME) .MACRO DEFREG,VALUE,REG .WORD DDTHDR .WORD VALUE .WORD VALUE+1 .RAD50 /REG/ .WORD 0 .ENDM DEFREG ; AND FINALLY, A SYMBOL TABLE NUMSYM=16. ; NUMBER OF USER DEFINABLE SYMBOLS SYMLEN=8. EXTLEN=SYMLEN+2 ; EXTERNAL SYMBOL LENGTH EXSYMS: .WORD 0 ; START OF EXTERNAL TABLE DDTHDR=070707 ; EXTERNAL SYMBOL HEADER .PSECT $$$SYM ; THIS SEEMS A GOOD PLACE EXTSYM: .WORD DDTHDR .WORD ORGODT,ENDODT .RAD50 /DDT / DEFREG 0,R0 DEFREG 1,R1 DEFREG 2,R2 DEFREG 3,R3 DEFREG 4,R4 DEFREG 5,R5 DEFREG 6,SP DEFREG 7,PC .REPT NUMSYM ; GENERATE EMPTY SLOTS .WORD DDTHDR .WORD 0,0,0,0 .ENDM .PSECT $$$DDT ; ENCODE DEFINITIONS .EVEN ENINST: .BLKW 3 ; INSTRUCTION TO BE ENBYTE: .BLKB 1 ;SWITCH FOR BYTE INSTRUCTION .EVEN ; ADDRESSING MODES ENAMRD=0 ; REGISTER DIRECT ENAMAI=20 ; AUTO INCREMENT ENAMAD=40 ; AUTO DECREMENT ENAMIN=60 ; INDEX ENAMPR=67 ; PC RELATIVE ENAMDF=10 ; DEFERRED ENAMLT=27 ; LITERAL .SBTTL INSTRUCTION DECODING LOGIC ; DCDD/DCDS -- DECODE SOURSE/DESTINATION FIELDS DCDD: MOV DREG,REG BR DCDDS DCDS: MOV SREG,REG DCDDS: CALL DCRM RTS PC ; DCDI -- DECODE INSTRUCTION ; THRU R0 ; PC ; USE R1 ; OUTPUT POINTER ; USE R2 ; INSTRUCTION DECODING DCDI: ENTER MOV (R0)+,R1 ; GET INSTRUCTION MOV R1,R2 ; A COPY TO BUTCHER MOV R1,INST ; AND ONE TO SAVE MOV #DREG,R3 ; LOC OF DEST REG MOV #4,R4 05$: MOVB R1,(R3) ; CHOP UP REGISTER/MODE FIELDS BICB #370,(R3)+ SHIFT -3,R1 SOB R4,05$ MOV #BUF,R1 MOV #OPLEN,R4 ; NICE PLACE FOR CONSTANT BIC #100000,R2 ; DITCH SIGN BIT ON INSTRUCTION MOV R2,INST.M ; SAVE INST MAGNITUDE MOV #DCDITB-2,R3 ; A NICE TABLE 10$: TST (R3)+ CMP R2,(R3)+ BLT 10$ MOV (R3),R3 JMP (R3) ; OH, FOR A CONDITION JUMP ; BRANCH TYPE INSTRUCTION DCDIBR: SHIFT -8.,R2 MUL R4,R2 ADD #OPBR-OPLEN,R3 ; ISN'T THIS OBSCURE TST INST BGE 10$ ADD #OPBPL-OPBR+OPLEN,R3 10$: CALL DCPOP ; PRINT OP-CODE,TAB MOV INST,R3 SHIFT 8.,R3 SHIFT -7,R3 DCDIB0: ADD R0,R3 ; (JOINED BY SOB) CALL DCPEA BR DCDIFI ; FINISHED ; CHECK NO-OPERAND FAMILY OF INSTRUCTIONS DCDINO: MOV #OPBPT,R3 10$: CMP R3,#OPBPT. BHIS 30$ ; DIDN'T FIND IT CMP R2,(R3) BEQ 20$ ADD R4,R3 BR 10$ 20$: CALL DCIMV BR DCDIFI 30$: MOV INST,R3 DCDINX: CALL DCPN ; WE LOSE BR DCDIFI DCDIAD: MOV #OPADD,R3 ; ADD/SUB TST INST BGT 10$ MOV #OPSUB,R3 10$: CALL DCPOP BR DCDISX ; FINISH SOURCE-DEST DCDID: SHIFT -6,R2 ; DESTINATION TYPE INSTRUCTION SUB #50,R2 MUL R4,R2 ADD #OPCLR,R3 DCDIDQ: CALL DCPBI DCDIDY: CALL DCDD ; DECODE DESTINATION BR DCDIFI DCDIST: MOV #OPSXT,R3 ; SXT BR DCDIDQ DCDIFI: CALL DCPRPR ; FINISH: PRINT REST OF LINE RETURN DCDIEJ: MOV #OPJSR,R3 ; JSR, EMT, OR TRAP TST INST BGT 10$ ; WAS A JSR MOV #OPEMT,R3 BIT #400,INST BEQ 5$ ; WAS AN EMT MOV #OPTRAP,R3 ; WAS A TRAP .IF DF T$$BUG CMP INST,OPDBUG ; TRAP 0? BEQ DCTRP0 ; YES .ENDC 5$: CALL DCPOP MOVB INST,R3 ; GET OPERAND BIC #177400,R3 BR DCDINX ; PRINT IT NUMERICALLY 10$: CALL DCPOP ; PRINT OP-CODE MOVB SREG,R3 CALL DCPRRG ; PRINT REGISTER BR DCDISY DCDIRD: SHIFT -9.,R2 ; REGISTER DESTINATION INSTRUCTION SUB #70,R2 MUL R4,R2 ADD #OPMUL,R3 DCDIRX: CALL DCPOP CALL DCDD ; DECODE DESTINATION MOVB #',,(R1)+ MOVB SREG,R3 DCDIRY: CALL DCPRRG ; PRINT REGISTER BR DCDIFI DCDIRT: MOV #OPRTS,R3 ; RTS DCDIRU: CALL DCPOP ; (JOINED BY SPL) MOVB DREG,R3 BR DCDIRY DCDISO: MOV #OPSOB,R3 ; SOB CALL DCPOP MOVB SREG,R3 CALL DCPRRG ; PRINT REGISTER MOVB #',,(R1)+ MOV INST,R3 ASL R3 BIC #177600,R3 NEG R3 BR DCDIB0 DCDISD: SHIFT -12.,R2 ; SOURCE-DESTINATION: RJ OP CODE MUL R4,R2 ; TIMES ENTRY LENGTH ADD #OPMOV-OPLEN,R3 DCDISE: CALL DCPBI ; PRINT (POSSIBLE) BYTE INSTRUCTION DCDISX: CALL DCDS ; DECODE SOURCE DCDISY: MOVB #',,(R1)+ BR DCDIDY ; JOIN DESTINATION GUYS DCDISW: MOV #OPSWAB,R3 ; SWAB BR DCDISE DCDIJM: MOV #OPJMP,R3 ; JUMP (GOT MISSED ABOVE) CALL DCPOP BR DCDIDY ; FINISH AS DESTINATION .IF DF T$$BUG DCTRP0: MOV #OPDBUG,R3 ; TRAP 0: SPECIAL DEBUG CASE CALL DCPOP ; PRINT "DBUG" OP CODE MOV (R0)+,R3 ; LOAD DEBUG WD AND ADV LOC CTR CALL DCPN ; PRINT IT BR DCDIFI ; FINISH .ENDC EXIT ; DCIMV -- MOVE IN OP-CODE ; IN R3 ; POINTER INTO OP-TABLE ; THRU R1 ; DEVELOPING STRING DCIMV: ENTER ; TST (R3)+ MOVB (R3)+,(R1)+ MOVB (R3)+,(R1)+ MOVB (R3)+,(R1)+ ; ALL ARE AT LEAST THREE BYTES BEQ 10$ MOVB (R3)+,(R1)+ RETURN ,BNE 10$: DEC R1 EXIT ; DCCKMG -- CHECK MAGNITUDE > SMALL ; IN R3: VALUE ; OUT C: MAG > SMALL DCCKMG: CMP R3,SMALL BGT 10$ ; VAL > SMALL NEG R3 CMP R3,SMALL BGT 9$ ; -VAL > SMALL NEG R3 CLC BR 20$ 9$: NEG R3 10$: SEC ; MAG > SMALL 20$: RTS PC ; DCPA -- PRINT ADDRESS ; THRU R1 ; IN R3 ; NUMBER DCPA: ENTER CALL DCCKMG ; CHECK MAGNITUDE BCS 10$ ; LARGE MAG CALL DCPSN ; SMALL MAG: PRINT AS SIGNED OCTAL NUM RETURN 10$: CMP R3,20 ; COMPARE LOC WITH STK LIMIT BHIS 20$ ; BEYOND: PRINT SYMBOLICALLY CALL DCPN ; PRINT AS OCTAL NUM RETURN 20$: CLR R2 ; BEST SYMBOL MOV R3,R4 ; BEST DISPLACEMENT ; SEARCH EXTERNAL TABLE 30$: MOV EXSYMS,R0 35$: CMP (R0)+,#DDTHDR BNE 40$ ; NOT SYMBOL BLOCK TST 4(R0) BEQ 36$ ; SLOT IS EMPTY CMP R3,(R0) BLO 36$ ; TOO LOW CMP R3,2(R0) BHIS 36$ ; TOO HI MOV R3,R5 SUB (R0),R5 ; COMPUTE DISPLACEMENT CMP R5,R4 ; COMPARE W BEST DISPL BHI 36$ ; WORSE MOV R0,R2 ; NEW BEST SYMBOL MOV R5,R4 ; NEW BEST DISPL 36$: ADD #EXTLEN-2,R0 BR 35$ 40$: TST R2 ; ANY SYMBOL FOUND? BNE 44$ ; YES, USE IT MOV STBFDB,R0 ; NO, IS SYMBOLS FILE OPEN ? BEQ 43$ ; NO, USE WHATEVER WE CAN MOV R1,-(SP) ; SAVE SOME REGS JUST INCASE MOV R2,-(SP) ; POINTER TO CHAR STRING IN RAD50 MOV R3,-(SP) ; REQUIRED VALUE CLR R1 ; DO A SORT OF "REWIND" MOV #1,R2 ; CLR R3 ; CALL .POINT ; POINT FCS IN RIGHT DIRECTION MOV (SP)+,R3 ; GET BACK WANTED VALUE MOV #-11,GSDPNT ; FORCE READ OF NEW BLOCK CLR CHR1 ; REMEMBER WE AINT GOT A SYMBOL 400$: CALL GETGSD ; GET ME A GSD ENTRY BCS 499$ ; WHOOPS. WE LANDED IN MUD MOV 6(R1),R0 ; GET VALUE CMP R0,R3 ; HOWSZAT ? BHI 400$ ; TOO HIGH, GET NEXT MOV R3,R5 ; JUST RIGHT OR LOWER SUB R0,R5 CMP R5,R4 ; HOW DID WE FARE ? BHI 400$ ; TERRIBLY, GET NEXT MOV (R1),CHR1 ; REMEMBER NAME ( FIRST WORD ) MOV 2(R1),CHR1+2 ; ( SECOND WORD ) MOV R5,R4 ; REMEMBER NEW BEST DISPLACEMENT BNE 400$ ; AND TRY AGAIN 450$: 499$: ; ALL ROADS LEAD TO ROME TST CHR1 ; HAVE WE FOUND A BETTER SYMBOL ? BEQ 500$ ; NO RECOVER OTHER ONE MOV #CHR1-4,R2 ; POINT HIM AT MY SYMBOL TST (SP)+ ; DIDDLE STACK ACCORDINGLY BR 510$ 500$: MOV (SP)+,R2 ; GET BACK PREVIOUS SYMBOL 510$: MOV (SP)+,R1 ; RECOVER POINTER TO TEXT LINE 43$: TST R2 ; ANY SYMBOLS USEABLE ? BEQ 55$ ; NO, DO IT WITH NUMBERS 44$: MOV 4(R2),R0 ; FIRST THREE CHARACTERS CALL DCPRD5 ; CONVERT FROM RAD-50 MOV 6(R2),R0 ; SECOND THREE CHARACTERS CALL DCPRD5 45$: TST R4 ; ANY DISPLACEMENT ? RETURN ,BEQ ; NO, ALL DONE MOVB #'+,(R1)+ ; YES, APPEND "+" AND ... 55$: MOV R4,R3 CALL DCPN ; PRINT DISPLACEMENT EXIT ; DCPBI -- POSSIBLE BYTE INSTRUCTION, FUDGE OP-CODE DCPBI: ENTER CALL DCIMV ; MOVE IN OPCODE TST INST BGT 10$ MOVB #'B,(R1)+ ; HACK HACK HACK 10$: MOVB #' ,(R1)+ EXIT ; DCPEA -- PRINT EFFECTIVE ADDR ; IN R3 DCPEA: ENTER MOV DSTEA,SRCEA ; WE HAVE A NEW E.A. MOV R3,DSTEA CALL DCPA EXIT ; DCPOP -- PRINT SIMPLE OP-CODE, SPACE DCPOP: ENTER CALL DCIMV MOVB #' ,(R1)+ EXIT ; DCPSN -- PRINT SIGNED NUMBER (CF: DCPN) DCPSN: BIT #100000,R3 ; TEST SIGN BIT BEQ DCPN ; POSITIVE: PRINT NUMBER AS IS MOVB #'-,(R1)+ ; "-" NEG R3 ; NEGATE NUMBER & PRINT IT ; DCPN -- PRINT NUMBER ; IN R3 ; NUMBER ; THRU R1 ; POINTER DCPN: ENTER ; CLR R2 ASHC #14.,R2 ; LEFT ADJUST NUMBER MOV #6,R4 ; MAX DIGITS 10$: BIT #160000,R2 BNE 20$ ; FOUND SIGNIFICANT DIGIT ASHC #3,R2 ; SWING NEXT DIGIT INTO PLACE SOB R4,10$ MOVB #'0,(R1)+ ; WHOLE THING WAS ZERO RETURN 20$: MOV R2,R0 SHIFT -13.,R0 ; RIGHT ADJUST DIGIT BIC #177770,R0 ADD #'0,R0 MOVB R0,(R1)+ ASHC #3,R2 SOB R4,20$ EXIT ; DCPRD5 -- CONVERT THREE CHARACTERS FROM RAD-50 ; IN R0 ; RAD-50 WORD ; THRU R1 ; OUTPUT BYTE POINTER ; TRASHES R0,R3 DCPRD5: ENTER ; MOV R0,R3 MOV #RD50TB,R4 ; DIVISOR TABLE MOV #3,R0 ; NMBER OF CHARACTERS 10$: CLR R2 DIV (R4)+,R2 ; GET CHARACTER RETURN ,BEQ ; NULL=>SPACE CMPB R2,#33 ; THIS IS MAGIC BEQ 16$ ; $ [44] BGT 14$ ; . [56] OR 0-9 [60-71] ADD #56,R2 ; MUST BE LETTER 14$: ADD #11,R2 16$: ADD #11,R2 MOVB R2,(R1)+ SOB R0,10$ EXIT ; DCPRA -- PRINT ADDRESS SYMBOLICALLY DCPRA: ENTER MOV #BUF,R1 CALL DCPA CALL DCPRPR ; PRINT LINE EXIT ; DCPRPR -- PRINT GENERATED LINE ; IN R1 DCPRPR: ENTER MOVB #' ,(R1)+ MOV #BUF,R3 SUB R3,R1 10$: MOVB (R3)+,R0 CALL O.FTYP SOB R1,10$ EXIT ; DCPRXR -- PRINT INDEX REGISTER NOTATION ; IN R3 ; REGISTER NUMBER ; THRU R1 DCPRXR: ENTER MOVB #'(,(R1)+ CALL DCPRRG MOVB #'),(R1)+ EXIT ; DCPRRG -- PRINT REGISTER ; IN R3 ; REG # ; THRU R1 DCPRRG: ENTER ASL R3 ; REG-# TIMES 2 ADD #REGS,R3 ; LOCATE ASCII MOVB (R3)+,(R1)+ ; MOVE CHARS TO OUT BUFF MOVB (R3)+,(R1)+ EXIT ; DCRM -- DECODE REGISTER/MODE ; THRU R1 DCRM: ENTER ; MOVB MODE,R2 ; ADDRESSING MODE ROR R2 BCC 10$ ; NO INDIRECT BIT MOVB #'@,(R1)+ ; INDICATE INDIRECT 10$: ASL R2 ; WHAT A GREAT HACK MOVB REG,R3 CMP R3,#7 JMP .+4(R2) ; DISPATCH ON TYPE BR 20$ ; REGISTER BR 30$ ; AUTO INCREMENT BR 40$ ; AUTO DECRMENT BEQ 15$ ; INDEXED: ADDRESSED OFF PC MOV (R0)+,R3 ; GET BASE ADDRESS CALL DCPA ; PRINT ADDRESS MOVB REG,R3 BR 45$ ; FINISH LIKE AUTO DEC 15$: MOV (R0)+,R3 ; PC RELATIVE ADD R0,R3 ; RELOCATE 18$: CALL DCPEA ; PRINT AS EFFECTIVE ADDRESS RETURN 20$: CALL DCPRRG ; REGISTER TYPE: PRINT REGISTER RETURN 30$: BEQ 35$ ; AUTO INCREMENT: LITERAL TYPE (OFF PC) CALL DCPRXR ; PRINT INDEX REGISER MOVB #'+,(R1)+ RETURN 35$: MOVB #'#,(R1)+ MOV (R0)+,R3 ; GET VALUE OF LITERAL CMP INST.M,#030000 ; BIT INST BLO 18$ ; NOT BIT,BIC,BIS CMP INST.M,#060000 ; ADD INST BHIS 18$ ; NOT BIT, BIC, OR BIS CALL DCPN ; PRINT NUMBER RETURN 40$: MOVB #'-,(R1)+ ; AUTO DECREMENT 45$: CALL DCPRXR EXIT .SBTTL INSTRUCTION ENCODING SECTION ; ENBR -- BRANCH TYPE INSTRUCTIONS ; THRU ENBR: ENTER CALL ENGW ; GET ALIGNED ADDRESS RETURN S,BCS SUB R1,R4 ; MAKE PC RELATIVE ASR R4 ; MAKE WORD OFFSET CMP R4,#177 ; CHECK RANGE RETURN S,BGT CMP R4,#-177 RETURN S,BLT BIC #177400,R4 ; CLEAN UP OFFSET BIS R4,ENINST ; INSERT IN INSTRUCTION CLC EXIT ; ENDIG -- DO WE HAVE A DIGIT HANGING AROUND ; IN R0 ENDIG: ENTER CMPB R0,#'0 RETURN S,BLT CMPB R0,#'9 RETURN S,BGT CLC EXIT ; ENFN -- GENERATE FUNNY GUYS ; THRU ENFN: ENTER <;R2> MOV #ENFN10,R2 ; FUNNY INSTRUCTION TABLE 10$: CMP (R2)+,ENINST BEQ 15$ ; FOUND IT TST (R2)+ BR 10$ 15$: JMP (R2) ; DISPATCH ENFN10: .WORD BR ENFN20 .WORD BR ENFN30 .WORD BR ENFN40 .WORD BR ENFN50 .WORD BR ENFN40 ; RTS ENFN20: CALL ENGREG ; GET REGISTER RETURN S,BCS BR ENFN80 ; JSR ENFN30: CALL ENIR ; INSERT REGISTER RETURN S,BCS CALL ENGC ; GET COMMA RETURN S,BCS CALL ENGD ; GET DESTINATION RETURN ; EMT ENFN40: CALL ENGA RETURN S,BCS CMP R4,#377 RETURN S,BHI ; EXCEEDED SPECIFICATIONS BR ENFN80 ; SOB ENFN50: CALL ENIR ; GET A REGISTER RETURN S,BCS CALL ENGC ; GET COMMA RETURN S,BCS CALL ENGW ; GET ALIGNED WORD RETURN S,BCS SUB R1,R4 ; MAKE IT PC RELATIVE RETURN S,BGT ASR R4 ; MAKE IT WORD OFFSET NEG R4 ; AND POSITIVE CMP R4,#77 RETURN S,BGT ; OUT OF RANGE ; BR ENFN80 ; FINISH OFF MOST GUYS ENFN80: BIS R4,ENINST CLC EXIT ; ENGA -- GET AN ADDRESS EXPRESSION ; THRU R0 ; NEXT CHARACTER ; OUT R4 ; VALUE ENGA: ENTER CLR R1 ; INITIALIZE SUBTRACT FLAG CLR R4 ; INIT ACCUMULATED VALUE ENGA10: CMPB R0,#'+ BEQ 40$ ; ADD CMPB R0,#'- BEQ 30$ ; SUBRACT CMPB R0,#'' BEQ 50$ ; SINGLE QUOTE CMPB R0,#'" BEQ 60$ ; DOUBLE QUOTE CMPB R0,#'A BGE ENGA20 ; POSSIBLE SYMBOL CMPB R0,#'. BEQ ENGA20 ; POSSIBLE SYMBOL CMPB R0,#'$ BEQ ENGA20 ; POSSIBLE SYMBOL CALL ENDIG ; IS IT A DIGIT RETURN C,BCS ; NOPE, WE'RE ALL DONE CLR R2 ; GET AN OCTAL NUMBER 10$: CALL ENDIG BCS ENGA15 ; NOT A DIGIT SHIFT 3,R2 ; MAKE ROOM FOR COMING DIGIT SUB #'0,R0 ; BINARYIZE IT BIS R0,R2 CALL ENGCHR ; GET ANOTHER CHARACTER BR 10$ 30$: COM R1 ; MARK FOR SUBRACTION 40$: CALL ENGCHR BR ENGA10 ; SINGLE QUOTE 50$: CALL ENGCHR ; GET A CHARACTER MOV R0,R2 BR 65$ ; DOUBLE QUOTE 60$: CALL ENGCHR MOV R0,R2 ; SAVE FIRST CHAR CALL ENGCHR SHIFT 8.,R0 ; 11'S ARE A LITTLE FUNNY BIS R0,R2 65$: CALL ENGCHR BR ENGA15 ; GOT ANOTHER VALUE FOR ACCUMULATION ENGA15: TST R1 ; TEST SUBTRACT FLAG BLT 10$ ADD R2,R4 BR ENGA10 ; GET ANOTHER ELEMENT 10$: SUB R2,R4 CLR R1 ; CLEAR SUBTRACT FLAG BR ENGA10 ; GOT A SYMBOL, DO THING ABOUT IT ENGA20: CMPB R0,#'Z RETURN C,BGT ; ACTUALLY DIDN'T HAVE ONE CALL GETSXM RETURN S,BCS MOV R0,-(SP) ; SAVE "NEXT" CHARACTER CALL FNDSYM ; TRY IN CORE SEARCH BCC 50$ ; GOT THE LITTLE BUGGER CALL SYMLOC ; NEVER MIND, PERHAPS IT'S IN ; THE .STB FILE WOT ? 50$: MOV (R0),R2 ; GET VALUE OF SYMBOL ( IF ANY ) MOV (SP)+,R0 RETURN S,BCS ; WE FAILED BR ENGA15 EXIT ; ENGC -- GET COMMA (BARF ON NON-COMMA) ; THRU R0 ENGC: ENTER CMPB R0,#', RETURN S,BNE CALL ENGCHR CLC EXIT ; ENGCHR -- GET A CHARACTER (SANITARY VERSION) ; OUT R0 ENGCHR: ENTER CALL O.GET EXIT ; ENGD -- GET DESTINATION FIELD ; THRU ENGD: ENTER CALL ENGM ; GET MODE RETURN S,BCS BIS R2,ENINST CLC EXIT ; ENGM -- GET ADDRESSING MODE ; THRU R0 ; NEXT CHARACTER ; THRU R1 ; REAL ADDRESS FOR INSTRUCTION ; THRU R3 ; GENERATION LOCATION ADDRESS ; OUT R2 ; MODE ENGM: ENTER CLR R5 ; ASSUME NOT DEFERED CMPB R0,#'@ BNE 10$ ; GOOD ASSUMPTION DEC R5 ; MAKE AS DEFERRED CALL ENGCHR 10$: CMPB R0,#'# BEQ 20$ ; LITERAL CMPB R0,#'- BEQ 30$ ; AUTO DECREMENT (I HOPE) CMPB R0,#'( BEQ 40$ ; AUTO INC OR REG DEFERRED ; WE SEEM TO HAVE A PLAIN VANILLA SYMBOL 12$: CALL ENGA ; GET ITS VALUE RETURN S,BCS CMPB R0,#'( BEQ 18$ ; INDEX CMP R4,#7 BHI 15$ ; NOT REGISTER MOV R4,R2 BIS #ENAMRD,R2 ; SET REGISTER DEFERRED BR ENGM20 ; FINISH UP ; PC RELATIVE 15$: TST (R1)+ ; SIMULATE INSTRUCTION SUB R1,R4 ; COMPUTE OFFSET MOV R4,(R3)+ MOV #ENAMPR,R2 ; PC RELATIVE BR ENGM20 ; INDEX 18$: MOV R4,(R3)+ ; MOVE IN DISPLACEMENT TST (R1)+ CALL ENGR ; GET REGISTER EXPRESSION RETURN S,BCS BIS #ENAMIN,R2 ; SET INDEX MODE BR ENGM20 ; LITERAL 20$: CALL ENGCHR CALL ENGA ; GET VALUE RETURN S,BCS MOV R4,(R3)+ ; MOVE IN VALUE TST (R1)+ MOV #ENAMLT,R2 ; SET LITERAL MODE BR ENGM20 ; AUTO DECREMENT (THIS CAN SCREW UP) 30$: MOV R0,-(SP) ; SAVE CURRENT CHAR CALL ENGCHR ; GET NEXT CHAR CMPB R0,#'( ; IS IT AUTO DECREMENT MODE? BEQ 35$ ; YES: MOVB R0,O.BACK ; STORE NEW CHAR AS BACKUP MOV (SP)+,R0 ; RESTORE CURRENT CHAR BR 12$ ; GO TO EXPRESSION HANDLER 35$: CLR (SP)+ ; POP STK CALL ENGR ; GET REGISTER NOTATION RETURN S,BCS ; MUST HAVE SCREWED UP BIS #ENAMAD,R2 ; SET AUTO DEC BR ENGM20 ; AUTO INC OR REG. DEFERRED 40$: CALL ENGR ; GET REGISTER NOTATION RETURN S,BCS CMPB R0,#'+ BEQ 45$ ; NOT AUTO INC DEC R5 ; SET DEFERED BR ENGM20 45$: BIS #ENAMAI,R2 ; SET AUTO INCREMENT CALL ENGCHR ; BR ENGM20 ENGM20: TST R5 RETURN C,BGE ; NOT DEFERRED MODE BIS #ENAMDF,R2 CLC EXIT ; ENGR -- GET REGISTER NOTATION ; THRU R0 ; NEXT CHARACTER ; OUT R2 ; REGISTER ENGR: ENTER CMPB R0,#'( RETURN S,BNE CALL ENGCHR CALL ENGREG ; GET REGISTER RETURN S,BCS MOV R4,R2 ; GET VALUE SINCE ITS OK CMPB R0,#') RETURN S,BNE CALL ENGCHR CLC EXIT ; ENGREG -- GET SIMPLE REGISTER, NO PARENS ; THRU R0 ; OUT R2 ENGREG: ENTER CALL ENGA RETURN S,BCS CMP R4,#7 ; NOT IN REGISTER RANGE RETURN S,BHI CLC EXIT ; ENGS -- GET SOURCE FIELD ; THRU R1 ; REAL ADDRESS ; THRU R3 ; GENERATION ADDRESS ENGS: ENTER CALL ENGM ; GET MODE RETURN S,BCS SHIFT 6,R2 BIS R2,ENINST ; SET UP SOURCE FIELD IN OP-CODE CLC EXIT ; ENGW -- GET ALIGNED WORD ; OUT R4 ENGW: ENTER CALL ENGA ; GET AN ADDRESS RETURN S,BCS BIT #1,R4 RETURN S,BNE CLC EXIT ; ENIR -- INSERT REGISTER ; I'M GETTING RATHER TIRED OF DIDDLY-SHIT SUBROUTINES ; TRASHES R4, BUT WHAT THE HELL ENIR: ENTER CALL ENGREG RETURN S,BCS SHIFT 6,R4 BIS R4,ENINST CLC EXIT ; ENRS -- GENERATE REGISTER-SOURCE INSTRUCTION TYPE ; THRU ; THE USUAL ENRS: ENTER CALL ENGD ; GET DESTINATION ADDRESS RETURN S,BCS CALL ENGC ; EAT COMMA RETURN S,BCS CALL ENIR ; GET REGISTER RETURN S,BCS CLC EXIT ; ENSB -- BYTE INSTRUCTION FUDGE ENSB: ENTER TSTB ENBYTE RETURN ,BEQ BIS #100000,ENINST EXIT ; ENSD -- GENERATE SOURCE-DESTINATION INSTRUCTION ; THRU R0 ; NEXT CHARACTER ; THRU R1 ; REAL ADDRESS ; THRU R3 ; PRETEND ADDRESS ENSD: ENTER CALL ENSB ; SET BYTE BIT IF NECESSARY CALL ENGS ; SET SOURCE FIELD RETURN S,BCS CALL ENGC ; EAT COMMA RETURN S,BCS CALL ENGD ; GET DESTINATION EXIT ; ENSO -- SEARCH OP-CODE TABLE ; OUT R2 ; TABLE ENTRY ENSO: ENTER MOV #OPADD,R2 ; BEGINNING OF TABLE 10$: CMP R2,#OPBPT. ; NEXT LOC BEYOND TABLE RETURN S,BHIS ; RAN OUT OF TBLE TST (R2)+ CMP SYMSPC,(R2)+ BNE 15$ ; NOT THIS ONE CMP SYMSPC+2,(R2)+ BNE 10$ ; NOR THIS ONE EITHER SUB #6,R2 RETURN C 15$: TST (R2)+ BR 10$ EXIT ; ENIN -- ACCEPTION INSTRUCTION ; IN R1 ; ADDRESS OF NEW INSTRUCTION ; OUT R1 ; LENGTH OF NEW INSTRUCTION ; OUT R0 ; NEXT CHARACTER ENIN: ENTER CLRB ENBYTE ; ASSUME WORD INSTRUCTION CALL GETSYM ; GET AN OP-CODE (WITH LUCK) RETURN S,BCS CALL ENSO ; SEARCH FOR INSTRUCTION BCC 20$ ; GOT IT (NEAT!) MOV #SYMSPC,R2 ; FIND LAST CHARACTER 10$: TSTB (R2)+ BNE 10$ ; WE KNOW ONE IS THERE TSTB -(R2) ; BACK UP A LITTLE CMPB -(R2),#'B RETURN S,BNE ; OBVIOUSLY NOT BYTE INST CLRB (R2) ; PRETEND A LITTLE CALL ENSO ; GIVE GUY SECOND CHANCE RETURN S,BCS DECB ENBYTE ; INDICATE BYTE INSTRUCTION 20$: TST (R1)+ MOV #ENINST,R3 ; A PLACE TO BUILD NEW INSTRUCTION CMP R2,#OPBPT BHIS ENINNA ; NO ARGUMENT OP-CODE CMPB #' ,R0 ; TAB? BNE 25$ ; NO: THEN WE ALREADY HAVE NEXT CHAR CALL ENGCHR ; GET NEX CHAR 25$: MOV (R2),R2 ; GET OP-CODE MOV R2,(R3) BIC #17,(R3)+ ; CLEAN UP OP-CODE BIC #177760,R2 ; CLEAN UP INSTRUCTION TYPE CALL @30$-2(R2) ; BUILD NEW GUY RETURN S,BCS MOV R3,R1 ; COMPUTE NEW INSTRUCTION LENGTH SUB #ENINST,R1 RETURN C 30$: .WORD ENRS ; REGISTER - SOURCE .WORD ENBR ; BRANCH .WORD ENGD ; DESTINATION ONLY .WORD ENFN ; FUNNY TYPE (HA HA) .WORD ENSD ; SOURCE - DESTINATION ; NO ARG INSTRUCTION ENINNA: MOV (R2),(R3)+ MOV #2,R1 CLC EXIT .SBTTL SYMBOL HANDLING LOGIC ; ADDSYM -- ADD (OR UPDATE) SYMBOL ; IN R4 ; LOWER BOUND ; IN R5 ; UPPER BOUND ADDSYM: ENTER CALL FNDSYM BCC 20$ ; SYMBOL ALREADY EXISTS ; FIND EMPTY SLOT MOV EXSYMS,R0 10$: CMP (R0)+,#DDTHDR RETURN S,BNE ; COULDN'T FIND SLOT TST 4(R0) BEQ 20$ ; FOUND EMPTY SLOT ADD #EXTLEN-2,R0 BR 10$ 20$: MOV R4,(R0)+ MOV R5,(R0)+ MOV SYMR50,(R0)+ ; FIRST 3 CHARACTERS MOV SYMR51,(R0)+ ; SECOND 3 CHARACTERS CLC EXIT ; FNDSYM -- FIND SLOT IN TABLE ; OUT R0 ; ADDRESS OF TABLE ENTRY FNDSYM: ENTER MOV #SYMSPC,R0 ; ADDRESS OF SYMBOL CALL GRD50 ; CONVERT TO RAD-50 MOV R1,SYMR50 MOV R1,R2 CALL GRD50 ; SECOND HALF OF SYMBOL MOV R1,SYMR51 ; SEARCH EXTERNAL TABLE FIRST MOV EXSYMS,R0 ; START OF EXTERNAL TABLE 10$: CMP (R0)+,#DDTHDR RETURN S,BNE ; NOT IN EXTERNAL TABLE CMP 4(R0),R2 BNE 15$ CMP 6(R0),R1 RETURN C,BEQ ; FOUND SYMBOL 15$: ADD #EXTLEN-2,R0 ; NEXT ENTRY IN TABLE BR 10$ EXIT ; GETSYM -- READ A SYMBOL ; OUT R0 ; TERMINATING CHARACTER ; OUT SYMSPC ; ASCIZ SYMBOL WHEN DONE GETSYM: ENTER CALL ENGCHR CALL GETSXM ; UGHLY UGHLY UGHLY EXIT ; GETSXM - REAL GUY FOR GETSYM ; THRU R0 ; NEXT CHARACTER GETSXM: ENTER MOV #7,R2 MOV #SYMSPC,R3 CLRB (R3) 5$: CMPB #' ,R0 ; SPACE? BNE 10$ ; NO: CONTINUE CALL ENGCHR ; READ CHARS UNTIL NON-SPACE BR 5$ 10$: CMPB R0,#'. ; DOTS ARE O.K. BEQ 15$ CMPB R0,#'$ ; SO ARE DOLLARS BEQ 15$ CMPB R0,#'0 BLT 20$ ; BAD CHARACTER CMPB R0,#'9 BLE 15$ ; NICE NUMBER CMPB R0,#'A BLT 20$ ; NOT LETTER EITHER CMPB R0,#'Z BGT 20$ ; LIKEWISE 15$: MOVB R0,(R3)+ ; EAT CHARACTER CALL ENGCHR ; AND GET ANOTHER SOB R2,10$ RETURN S ; TOO MANY CHARACTERS 18$: CALL ENGCHR ; READ CHARS UNTIL NON-SPACE 20$: CMPB #' ,R0 ; SPACE? BEQ 18$ ; YES CMPB SYMSPC,#'. ; SYMBOLS CAN START WITH DOTS .... BNE 22$ CMP R2,#7-1 ; SINGLE DOT FOR A NAME ? BR 24$ ; IF SO: NG 22$: CMPB SYMSPC,#'$ ; ... DOLLARS,... BEQ 25$ CMPB SYMSPC,#'A RETURN S,BLT ; AND LETTERS, BUT NOT NUMBERS CMPB R0,#177 24$: RETURN S,BEQ ; RUBOUTS ARE VERY BAD 25$: CLRB (R3)+ SOB R2,20$ ; ZERO OUT REST OF SYMBOL CLC EXIT .SBTTL SYMBOL TABLE SEARCH UTILITIES ; GET NEXT RECORD OF SYMBOL TABLE FILE ; GETREC: GET$ R0 ; GET A RECORD BCS 99$ ; ERROR IN FILE MOV F.NRBD+2(R0),R1 ; GET START ADDRESS OF LINE MOV (R1),R2 ; GET RECORD TYPE ( IN FIRST BYTE ) BIT #177770,R2 ; IS RECORD TYPE IN RANGE 0-7 ? BNE 999$ ; NO, THEN NOT AN STB FILE ASL R2 ; CONVERT TO WORDS ADD R2,PC ; AND DISPATCH THROUGH TABLE FOLLOWING BR 999$ ; RECORD TYPE --------- FUNCTION BR 100$ ; 1 DECLARE GSD BR 200$ ; 2 END GSD BR 300$ ; 3 TEXT BR 400$ ; 4 RLD BR 500$ ; 5 ISD BR 600$ ; 6 END OF MODULE BR 700$ ; 7 NOT DEFINED FOR STB 100$: ; THESE ARE THE IMPORTANT ONES MOV R1,ENDREC ; START ADDRESS PLUS ... ADD F.NRBD(R0),ENDREC ; ... LENGTH GIVES END ADDRESS ADD #2,R1 ; SKIP OVER RECORD TYPE MOV R1,GSDPNT ; PREPARE POINTER CLC ; THERES A GOOD BOY RTS PC ; 200$: 300$: ; THESE ARE JUST IGNORED ... 400$: ; ... BY JUST GETTING THE NEXT ... 500$: ; ... RECORD ... BR GETREC ; .....THUS 600$: ; END OF MODULE 99$: ; SPURIOUS ERROR ( I HOPE ) SEC ; SMACK HAND AND RTS PC ; JUST QUIT 700$: ; OBVIOUSLY NOT A SYMBOL TABLE FILE ... 999$: ; ... SO ... CLR STBFDB ; ... DON'T USE FILE AGAIN SEC ; GO HOME CRYING RTS PC ; GET NEXT SYMBOL FROM GSD ; GETGSD: MOV STBFDB,R0 ; IS THERE A FILE OPEN ? BEQ 999$ ; WHOOPS ... NO SYMBOLS FOR YOU THEN ADD #10,GSDPNT ; GET NEXT GSD ENTRY MOV GSDPNT,R1 ; ADDRESS IN R1 CMP R1,ENDREC ; IS POINTER OUTSIDE RECORD ? BLO 10$ ; NO CALL GETREC ; YES, GET NEXT RECORD BCS 1000$ ; OOPS 10$: MOVB 5(R1),R2 ; GET GSD ENTRY TYPE BIT #177770,R2 ; CHECK VALIDITY OF RANGE BNE 999$ ; GOSH ! CAN'T BE A .STB FILE ASL R2 ; TURN INTO WORD OFFSET ADD R2,PC ; AND LEAP OFF THRO' TABLE BR GETGSD ; TYPE 0 - MODULE NAME BR GETGSD ; 1 - CONTROL SECTION NAME BR GETGSD ; 2 - INTERNAL SYMBOL NAME BR 999$ ; 3 - TRANSFER ADDRESS BR 400$ ; 4 - GLOBAL SYMBOL NAME BR GETGSD ; 5 - PROGRAM SECTION NAME BR GETGSD ; 6 - PROGRAM VERSION I-D BR 999$ ; 7 - NOTHING AT ALL REALLY 400$: CLC ; THIS IS THE GROOVY ENTRY WE WANT RTS PC ; ADDRESS OF ENTRY IN R1 999$: ;CLR STBFDB ; DON'T USE FILE AGAIN 1000$: SEC ; RTS PC ; QUIT .SBTTL SYMLOC -- LOCATE SYMBOL IN .STB FILE ; SYMBOL STORED IN RAD-50 IN SYMR50 & SYMR51 ; ; ADDRESS OF VALUE RETURNED IN R0 SYMLOC: ENTER MOV STBFDB,R0 ; .STB FILE AVAILABLE ? RETURN S,BEQ ; RETURN IF NO CLR R1 ; REWIND .STB FILE MOV #1,R2 ; CLR R3 ; CALL .POINT ; FCS DOES THE REST MOV #-11,GSDPNT ; FORCE READ OF FIRST BLOCK 10$: CALL GETGSD ; GET AN ENTRY RETURN S,BCS ; RETURN EMPTY HANDED CMP (R1),SYMR50 ; FIRST 3 CHARS MATCH ? BNE 10$ ; NOPE, GET NEXT ENTRY CMP 2(R1),SYMR51 ; SECOND 3 CHARS MATCH ? BNE 10$ ; NO, GET NEXT ENTRY MOV R1,R0 ; CALCULATE ADDRESS TO RETURN ADD #6,R0 ; TO CALLER RETURN C ; RETURN CHUFT TO BITS EXIT ; GRD50 -- CONVERT THREE CHARACTERS TO RAD-50 VALUE ; THRU R0 ; STRING POINTER ; OUT R1 ; RAD-50 EQUIV GRD50: ENTER CLR R1 MOV #3,R3 ; NUMBER OF CHARACTERS 10$: MOVB (R0)+,R2 BEQ 20$ ; NULL CMP #'$,R2 ; WAS IT A DOLLAR ? BNE 13$ ; NO MOV #33,R2 ; YES BR 20$ ; KEEP SCORE 13$: CMP #'.,R2 ; WAS IT A DOT THEN ? BNE 15$ ; NO MOV #34,R2 ; YES BR 20$ ; ADD IT IN TO TOTAL SO FAR 15$: SUB #'A-1,R2 ; ASSUME LETTER BGT 20$ ; GOOD GUESS ADD #'A-1-'0+36,R2 ; NUMBER 20$: MUL #50,R1 ADD R2,R1 SOB R3,10$ EXIT ; SETSYM -- FIND BEGINNING OF EXTERNAL SYMBOL TABLE SETSYM: ENTER MOV #EXTSYM,R0 ; SOMEPLACE IN TABLE 10$: MOV R0,EXSYMS SUB #EXTLEN,R0 CMP (R0),#DDTHDR BEQ 10$ ; FOUND ANOTHER SYMBOL EXIT ENDODT=. ; LAST LOCATION USED SIZODT=ENDODT-ORGODT ; SIZE OF DDT .END O.ODT