.TITLE DDT -- DYNAMIC DEBUGGING AID .ENABL LC ;ALLOW LOWER-CASE INPUT WITHOUT CONVERSION TO UPPER R$$11M=0 ; RSX11M VERSION RKB002 R$$EIS=0 ; ALLOW HARDWARE MUL AND DIV DDTFIS=0 ; INCLUDE FIS INSTRUCTIONS (FADD,FSUB,FMUL,FDIV) DDTFPP=0 ; PRINT FPP INSTRUCTIONS OCTAL FORMAT DDTRNG=0 ; DEFAULT ###:SYMBOL TO MAX RANGE DDTSOR=0 ; INCLUDE SOROC CURSOR UP-ARROW DDTCHG=0 ; INCLUDE 'M' COMMAND--BREAK ON CHANGE LOCATION DDTINS=0 ; PRINT INSTRUCTION AT PC ON BREAKPOINT DDTDFS=0 ; AT START-UP, DEFINE THE EXTERNAL SYMBOL 'PROG' DDTPLS=0 ; PARSE ' +40 ' AS ' #PROG+40 ' ....ETC. M$$MGE=0 ; DETECT SEGMENT FAULT ERRORS ; T$$BUG=0 ; SPECIAL CASE FOR .IF DF R$$11M .IDENT /M01.3/ .IFF .IDENT /D01.3/ .ENDC ; DDT ; 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. CONDITIONAL ON T$$BUG: IS TYPED AS "DBUG NNNNNNN" ; WHERE "NNNNNNN" IS THE OCTAL VALUE OF THE WORD FOLLOWING THE TRAP. ; ; 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. (** RETRACTED IF DDTRNG IS DEFINED---SEE NOTE 5. BELOW **) ; 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.***** RETRACTED BY 12. BELOW ******* ; 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. ; TO GET BACK TO OCTAL MODE, YOU MUST FIRST OPEN A LOCATION WITH ; THE / COMMAND. ; ; 24. FIXED BUG ON USING SYMBOLS STARTING WITH . OR $ IN ? COMMAND. ; ; 25. FIXED BUG ON NEGATIVE INDEX IN ? COMMAND [EG: INC -2(R1)] ; Modified April, 1979 by Daniel Steinberg @ SRI International ; 333 Ravenswood Loc K1023 ; Menlo Park, Ca 94025 ; (415) 326-6200 ext.5539 ; ; 1. Changed conditional for hardware MUL, SOB, and DIV from R$$11M to ; R$$EIS. Other uses of R$$11M are intact. ; ; 2. Added the ability to use the symbol . to represent the program ; counter in instruction coding (ie. BR .+4 ). The location O.CAD ; is used for the value of . and the symbol parsing was slightly ; changed. ; ; 3. Conditionally (on DDTFIS) will encode/decode FIS instructions, at ; the cost of about 34 words. Also, for 12 more words (conditional ; on DDTFPP), will print FPP instructions as FPP: ###### where ; ###### is the octal code....the operand is not decoded, though, ; so the next word may come out wrong. ; ; 4. Added the length of the external symbol table to the range of ; symbol DDT. ; ; 5. Changed symbol definition (conditional on DDTRNG) so that the ; syntax: ###:symbol will have a the maximum range (rather than ; the minimum. I found this useful for defining only the top symbols ; of PSECTs in a MACRO-11 program; then, all the offsets are the ; same as in my assembly listing. ; ; 6. Rubouts are trapped as errors by the input subroutine (as in ODT) ; instead of being caught in several places by various callers. ; However, the rubout code is conditional via R$$11M, since rubouts ; never get to the program via QIO with 11M. An 11M user can simulate ; a rubout with a CTRL-A, or some other nonsense control char. ; ; 7. Internal register designations must be followed by some sort of ; location opening or closing command [ie. /\"'%&^_@><= ] ; to avoid confusion and IL breaks ; ; 8. Changed _ prompt to ~ just for fun. ; ; 9. Added octal 013 as a synonym for ^ to allow SOROC cursor keypad ; up-arrow to work (conditional on DDTSOR). ; ; 10. Made the ? command illegal if no location is open (just like all ; other location modifying commands. ; 11. (conditional on DDTCHG) Added the M command (M for Modified ; location) to give the 'break on change' capability. The syntax is ; #M (where # is 0-7) and the effect is to single step thru the user ; program until the location specified by the autoprint register $#P ; has been modified. (Error if #$P contains 0) When that happens, ; a #M: break will occur and the modified location will be auto- ; printed. An alternate syntax is: M ; in which case locations specified by $0P thru $7P will be watched. ; The M command requires about 72 extra words, and is well worth ; it if you ever need to know why and where some "pure" code is being ; altered or where your stack is overflowing, etc.... ; ** NOTE: When a break due to a changed location occurs, the PC of the ; instruction that changed the location is printed! This is NOT the ; PC of the next instruction to be executed (as is normally printed). ; ; 12. To implement the M command without adding much code, the ; function of $8P has been modified to be the default auto-print ; location only if there is no location to print for the particular ; breakpoint (it's a default rather than an override). ; ; 13. (Conditional on DDTDFS) At start-up, define the external symbol ; PROG with the value of the task SP (this will often correspond to ; location 0 in .PSECT of a macro program). PROG has an ; upper limit of DDT-1 so that it will effectively cover all of the ; the user task space. This symbol is most useful when debugging ; single source-file macro programs since the offsets to PROG will ; be the same as the .PSECT addresses in the .LST file. ; To eliminate PROG, simply redefine it (e.g. 0;0:PROG ). ; ; 14. (Conditional on DDTPLS) Parse the expression +.... as ; #PROG+.... -- this has the effect of using the symbol PROG as ; an ODT type relocation register (i.e. the ODT command 0,50/ ; causes 50 to be added to the contents of relocation reg 0... ; the DDT command +50/ would cause 50 to be added to the value ; of the symbol PROG and the resulting address opened. The value ; of PROG remains unchanged throughout. ; ; 15. (Conditional on DDTINS) Print the decoded instruction after the ; PC on breakpoint entry. Except for #M: breaks, this will be ; the instruction about to be executed. On #M: breaks, this will ; be the instruction that changed the monitored location. ; ; 16. Fixed bug when DDT ends up exactly on a 32-word boundary (extra ; word allocated to external symbol table avoids Memory Management ; Violations.) ; ; 17. Fixed bug in decoding of SWAB instructions. ; 18. Implemented the IO,EM,TR,FP traps (they were commented out before) ; with the following modifications: ; a) when one of these traps occur, the location printed is ; the address of the offending instruction, NOT the next ; instruction to be executed. ; b) when a MM trap occurs, the PC is updated to point back ; at the offending instruction ; c) the same is true for IL traps ; ; These changes enable you to see the instruction that failed, rather ; the next instruction after....ideally, the same would happen with ; OD traps, but i don't know of a sure-fire way of locating the PC ; of the offending instruction (with MM, it's on the stack). ; ; 19. Fixed G command to accept either LG or L;G syntax.... ; this allows a command like: #PROG;G ; *** Note that before this change, the syntax L G could have been ; used (e.g. #PROG G )....personally, i prefer L;G ; ; 20. Fixed instruction decoding dispatch table so that unused op-codes ; aren't translated into garbage. ; ; 21. Removed all references to GCML (Get Command Line) code. If the ; user program doesn't reference it either, then this saves some ; space and prevents all the I/O function codes and FDB offsets from ; being defined globally....that way there aren't a mess of junk ; symbols in the .STB file to confuse address printout and slow the ; .STB searches. ; *** Note that this saves approximately 330. words of code in DDT ; (both in buffer space and $$FSR1 space)....If the user program ; doesn't call GCML either, then the total savings is about ; 1370. words!! *** ; ; 22. In conjuction with 21., defined the global function codes locally ; with the FSCBT$ and FILIO$ macros. ; ; 23. Made all page sizes 55 lines or less to optimize MACRO listings. ; ; 24. Fixed bug in decoding of BPL instructions. ; ; 25. Fixed bug in NOCRC definition. ; ; 26. Added $W register ($DSW)...like in ODT...it has the saved user ; Directive Status Word, since DDT's directives change the task DSW. ; === 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, led 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 ; ; Seven 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 (specifically, the second arg, if present, ; is the high address limit of the range of the symbol). ; ; Examples: ; ; 1000:JUNK (define symbol JUNK) ; ; 2774;3000:DATA (define symbol DATA with length 3000-2774) ; ; # 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. CAUTION: If ; you forget to type # and start typing a symbol, DDT ; will try to execute each character as a command (very ; dangerous if there's a G , P , etc. in the string). ; ; & 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. ; e. If the absolute value of the current word is less ; than SMALL , the word will be printed in octal ; format, regardless of symbol definitions. ; ; ; ? 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. ; **** Note that an implicit FINIT$ is performed the first time ; any file is opened, if FINIT$ has not already been ; explicitly done....This means that opening an .STB file ; before running a program will perform FINIT$....If the ; program then does an explicit FINIT$, the FDBs will be ; reset....so watch out **** ; M Monitor locations for value change. Locations to monitor are ; or set in $#P registers (0-7 only) and the M command is issued. ; #M DDT single steps thru the program, watching for changes in the ; values of any of these locations, breaking to prompt mode when ; a change has occurred. The command #M monitors only a single ; location ( 3M , for example, watches the location specified in ; the register $3P ). See the implementation notes (a few pages ; above) and DDT.TXT for more info. ; ; ; ; 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-11 DDT may be included by something like: ; ; TKB JUNK,JUNK,JUNK=JUNK,...,[1,1]DDT/DA ; ; or if DDT is called ODT and lives in LB0:[1,1]: ; ; TKB JUNK/DA,JUNK,JUNK=JUNK.... ; ; THE IAS EQUIVALENT IS: ; ; LINK /SYMBOLS/MAP/DE:[1,1]DDT JUNK,... ; 6. 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. ; ; The user should also note that if I/O function codes, ; FDB offsets, error codes, masks, etc. are not defined locally ; in each module of the program, the the .STB file will be filled ; with possibly hundreds of nonsense global symbols which almost ; certainly screw up any attempts to print meaningful symbolic ; offsets.....buyer beware! ; 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 or a space. DDT will reject ; an instruction which violates it's 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 ;USED IN LOCATING "JMP"'S AS OPPOSED TO "BR"'S .MACRO JUMP A JMP A .ENDM ;This macro is commented out since the current MACRO assembler knows ;about the CALL instruction....put it back in if you have trouble. ;.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 .IF NDF,R$$EIS ;IF NO HARDWARE SOB .MACRO SOB A,B DEC A BNE B .ENDM .ENDC .SBTTL JIM'S BELOVED MACROS ZENTER=0 ;*** ENTER: .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 ;*** END OF ENTER ;*** XEXIT: .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 ;*** END OF XEXIT ;*** XRTRN: .MACRO XRTRN,N,T,OP OP RTZ'T'N RTRNZ'T=1 .ENDM XRTRN ;*** END OF XRTRN .SBTTL .MCALLS AND REGISTER DEFINITIONS .MCALL DSAR$S,ENAR$S,GTSK$S .MCALL FILIO$,FCSBT$,CSI$,CSI$1,CSI$2 .MCALL FSRSZ$,FDBDF$,FDRC$A,FDOP$A,NMBLK$ .MCALL OPEN$R,CLOSE$,ALUN$S,GET$ FILIO$ ;DEFINE I/O FUNCTIONS LOCALLY FCSBT$ ;DEFINE FCS OFFSETS LOCALLY FSRSZ$ 1 .PSECT $$$DDT ;THESE LINES ARE REDUNDANT WITH THE CURRENT MACRO ASSEMBLER ;R0 = %0 ; REGISTER ;R1 = %1 ; NAMING ;R2 = %2 ; CONVENTIONS ;R3 = %3 ;R4 = %4 ;R5 = %5 ;SP = %6 ;PC = %7 .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 = 176 ;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 ;THE CURRENT MACRO ASSEMBLER KNOWS ABOUT BPT ;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.DSW: 0 ;DIRECTIVE STATUS $W 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 + V.IOTX ;3-IOT + V.ILLI ;4-RESERVED OR ILLEGAL INSTRUCTION + 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 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.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 .IF DF,DDTCHG ;IF M COMMAND O.OLDP: .WORD 0 ;OLD PC, USED DURING M COMMAND .ENDC ;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 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 'W ;O.DSW DIRECTIVE 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) NOXX=. .ASCII #\/'"%&# NORC=.-NOXX ; NUMBER OF OPEN-REG COMMANDS ;CLOSE REGISTER COMMANDS .BYTE 015,012 .IF DF,DDTSOR ;IF SPECIAL CURSOR KEYPAD .BYTE 013 .ENDC .BYTE '^,'_,'@,'>,'< ;SPECIAL FORMS .BYTE '= NOCRC=.-NOXX ;END OF COMMANDS THAT CAN FOLLOW A $ COMMAND .BYTE '$,'C,'Q,'. ;OPERATORS (ORDER OF -+* IS CRITCAL) .BYTE ';,'-,'+,'* ;COMMANDS .ASCII /BEFGLNP/ .IF DF,DDTCHG ;IF BREAK ON CHANGE (M COMMAND) .ASCII /M/ .ENDC .ASCII /SVWX/ .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 .IF DF,DDTSOR ;IF SPECIAL KEYPAD + CLUPAR ; CLOSE, OPEN PREVIOUS .ENDC + 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 + EQUALS ;= PRINT LEFT SIDE IN CURRENT MODE + O.REGT ;$ INTERNAL REGISTER REFERENCE + 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 .IF DF,DDTCHG ;IF M COMMAND + M.CHAN ;M MODIFIED LOCATION BREAK .ENDC + 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)+ .IF DF,DDTDFS ;DEFINE SYMBOL 'PROG' MOV O.USP,EXTT ;SET 'PROG' ABOVE USER STACK .ENDC ;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$: JSR R5,LOOKUP ;LOOK FOR COMMAND CHAR + COMTAB BCS O.ERR0 ;COULDN'T FIND IT CMP R1,#NOCRC*2 ;IS IT A LOC OPEN/CLOSE COMMAND? BGE O.ERR0 ; NOPE...DISALLOW IT JUMP O.CL02 ;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 "Q-C-." 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 ;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 O.CL02: 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 + .IF DF,DDTPLS ;OFFSET TO PROG IF NO LEFT-HAND SIDE .IF NDF,DDTDFS .ERROR ;PROG MUST BE DEFINED .IFF TST R2 ;ANY LEFT HAND SIDE EXPRESSION? BNE O.CO00 ;YES...FINISH UP INC R2 ;NO...SET VALUE OF PROG HERE MOV EXTT,O.EXP ;(I KNOW WHERE IT LIVES) .ENDC .ENDC 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 .IF DF,DDTRNG ;IF DEFINED, SET MAX LIMIT MOV #-1,R5 ; 177777 AS SECOND ARG .IFF ;IF UNDEFINED, SET MIN LIMIT INC R5 ; + 1, AS SECOND ARG .ENDC 15$: CALL ADDSYM BCS SYMERR JUMP 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: TST O.OPN ;CURRENT LOC OPEN? BEQ SYMERR ;NO...SKIP IT MOV O.CAD,R1 ; CURRENT ADDRESS BIT #1,R1 BNE SYMERR ; ODD GUYS LOSE CALL ENIN ; GET INSTRUCTION BCS SYMERR 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 ; L;G START PROGRAM AT LOCATION L ; G START PROGRAM AT CURRENT PC O.GOTO: TST R2 ;SEE IF SPECIFIC ADDRESS BNE 5$ ;YES....IN R4 TST R3 ;WAS THERE ONE BEFORE A SEMI-COLON? BEQ 10$ ;NO...START AT CURRENT PC MOV R5,R4 ;YES...PUT IT IN R4 5$: 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 .IF DF,DDTCHG ;BREAK ON CHANGE CAPABILITY .SBTTL "M" PROCESSOR - MODIFIED LOCATION BREAKPOINT ;SYNTAX: NM SINGLE STEP TIL LOCATION AT $NP CHANGES ; M SINGLE STEP TIL ANY LOCATION AT $0P - $7P CHANGES M.CHAN: CLRB O.S ;USE AS A FLAG FOR NOW TST R2 ;ARGUMENT? BNE 2$ ;YUP MOV #8.,R4 ;NO...SET FOR ALL $#P REGS 2$: CMP R4,#8. ;ARG WITHIN RANGE? BHI M.ERR ;NO BEQ 6$ ;IF NO # SPECIFIED, DON'T CHECK VALIDITY MOV R4,R2 ;SET TO CHECK THIS $#P REG ASL R2 TST O.BPTP(R2) ;$#P NON-ZERO? BEQ M.ERR ;NO...ERROR 6$: MOV #16.,R2 ;SAVE ALL VALID $#P REGS INC R4 ; 0-8 -> 1-9 7$: SUB #2,R2 BLT M.PRCD ;BR WHEN DONE TST O.BPTP(R2) ;VALID LOCATION? BEQ 7$ ;NO...SKIP IT MOV @O.BPTP(R2),O.UIN(R2) ;IT HAD BETTER BE A VALID LOC MOVB R4,O.S ;SET FLAG FOR S.I. MODE...ALSO ARG TO M CMD BR 7$ ;LOOP FOR THE REST M.PRCD: MOV O.UPC,O.OLDP ;SAVE PC OF THE INSTRUCTION ABOUT TO EXECUTE TSTB O.S ;ANY LOCS SAVED? BNE O.C990 ;YES...GO GO GO M.ERR: ERROR ;OH WELL...(S)HE CAN TRY AGAIN .ENDC .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 ;AFTER SO MANY MODIFICATIONS, THIS CODE HAS BECOME INCREDIBLY CONTORTED.... ; THE IMPORTANT FLAG IS O.S WHICH TELLS WHICH DDT COMMAND EXECUTED LAST: ; O.S = 0 IF THE LAST COMMAND WAS G OR P ; O.S = 16 (O.BKP+2) IF THE LAST COMMAND WAS S ; O.S = 1-9 IF THE LAST COMMAND WAS M (CONDITIONAL ON DDTCHG) ; O.P WAS SET AT THE INTERRUPT ENTRIES (A FEW PAGES DOWN) TO INDICATE WHAT ; KIND OF TRAP OCCURRED AND WHETHER A PROCEED IS POSSIBLE: ; O.P < 0 => NO PROCEED....MM IL OD ; O.P = 0 => PROCEED OK....BPT or T-BIT ENTRY ; O.P > 0 => PROCEED OK....IO EM TR FP 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 ? BEQ 11$ ;YES....GO CHECK IT OUT BLT 30$ ;NO.....MM IL OD....PRINT INFO SUB #2,R5 ;NO.....IO EM TR FP...PRINT LOC OF BAD INSTR. BR 30$ ;BUT DON'T EXECUTE IT AGAIN 11$: MOVB #O.BKP+2,O.P ;8TH BREAKPOINT IS SINGLE STEP MOVB O.S,R4 ;SEE IF SINGLE STEPPING BEQ 13$ ;NO...RESTART WAS FROM G OR P COMMAND ;FALL THRU IF WE WERE SINGLE STEPPING ;FALL THRU TO HERE IF SINGLE-STEPPING.....IF DDTCHG (M COMMAND), THEN ;THE LAST DDT COMMAND WAS S OR M ........IF NO DDTCHG, IT WAS S .IF DF,DDTCHG ;IF INCLUDING THE M COMMAND .IFF ;IF NOT, THE RESTART MUST HAVE BEEN AN S COMMAND BR 22$ ;SINGLE-STEPPING...#8 BREAK .IFT ;IF THE M COMMAND IS INCLUDED: CMPB R4,#O.BKP+2 ;RESTART WAS S COMMAND? BEQ 22$ ; YES...#8 BREAK DEC R4 ;NO...RESTART WAS M COMMAND! ASL R4 ; M - CONVERT BACK TO OFFSET (REVERSE PARSE) CMP R4,#16. ;CHECK ALL LOCS $0P - $7P ? BNE 115$ ;NO...JUST TRY ONE 111$: SUB #2,R4 ;YES...DON'T TRY $8P, THOUGH BLT M.PRCD ;NONE OF THEM CHANGED....DO ANOTHER S.I. JSR PC,275$ ;SEE IF THIS LOC IS MODIFIED BEQ 111$ ; NOPE BR 150$ ;GOT IT!!! 115$: JSR PC,275$ ;CHECK JUST ONE LOCATION BEQ M.PRCD ;IT'S THE SAME...GO S.I. 150$: MOV R4,R3 ;SAVE THE BREAKPOINT OFFSET FOR AUTO-PRINT ASR R4 ;AND MAKE A PREFIX ADD #"0M,R4 MOV O.OLDP,R5 ;RESTORE THE PC SAVED BEFORE EXECUTING S.I. BR 26$ ;AND GO ON...PRINT PC OF PREVIOUS INSTRUCTION ;THIS SUBROUTINE IS EMBEDDED IN THE CODE CONDITIONAL ON DDTCHG ; IT LOOKS AT A BREAK-ON-CHANGE LOCATION TO SEE IF IT WAS MODIFIED ; (SINCE WE'RE SINGLE-STEPPING, ONLY ONE LOCATION OUT OF SEVERAL COULD ; HAVE BEEN MODIFIED, SO THE FIRST ONE FOUND IS IT) 275$: TST O.BPTP(R4) ;IS THERE A LOC HERE TO CHECK? BEQ 300$ ;NO...MAKE IT LOOK LIKE THERE WAS NO CHANGE CMP @O.BPTP(R4),O.UIN(R4) ;YES...DID IT CHANGE? 300$: RTS PC ;LET THE CALLER DECIDE .ENDC ;HERE, THE STARTUP COMMAND WAS EITHER G OR P, SO THE SST THAT ENTERED DDT ; WAS EITHER A USER BPT IN THE CODE, A BPT FROM A $#B BREAKPOINT, OR ; AN MCR BREAK (NOT LIKELY)....SINCE THE BREAKPOINTS HAVE BEEN RESTORED, ; THE INSTRUCTION JUST EXECUTED WILL NOT LOOK LIKE A BPT UNLESS IT WAS IN ; THE USER CODE TO BEGIN WITH....THE FOLLOWING CHECK COUNTS ON THIS: 13$: CMP -(R5),O.TRTC ;BACK-UP R5 AND SEE IF USER BPT CMD BEQ 30$ ;YES...LEAVE PC BUT PRINT PC-2 ;AT THIS POINT IT MAY BE DUE TO MCR OR BREAKPOINT ($0B-$7B) ;IF THE ADDRESS IS IN THE BREAKPOINT TABLE ($#B), IT WAS A BREAKPOINT 14$: 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 .IF DF,DDTINS ;PRINT THE DECODED INSTRUCTION, TOO MOV #"! ,R0 ;TELL USER WHAT'S GOING DOWN JSR PC,O.FTYP MOV R5,R0 ;SET PC IN R0 JSR PC,DCDI ;AND PRINT THE DECODED INSTRUCTION LIVING THERE .ENDC MOV O.BPTP(R3),R0 ; TRY AUTO PRINT ADDR FOR THIS BKPT # BNE 35$ ; EXISTS MOV O.BPTP+20,R0 ; ELSE TRY DEFAULT AUTO PRINT ADDR (AT $8P) 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 V.NIXP: MOVB #-1,O.P ;NO PROCEED V.INT1: MOV $DSW,O.DSW ;SET $W...EVEN THOUGH IT WON'T GET RESTORED V.INT0: JMP V.INTR ;COMMON INTERRUPT .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 SSTSTK+2,(SP) ;POINT BACK TO OFFENDING INSTRUCTION MOV #"MP,ENPRFX ;ENTRY PREFIX .ENDC ;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 ;PDP 11/40 FLOAT POINT - V7 - "FP" - 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.INT0 ;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 SUB #2,(SP) ;POINT BACK TO ILLEGAL INSTRUCTION BR V.NIXP ;NO GO V.FPPE: MOV #"FP,ENPRFX ;"FP:" FOR 11/40 FIS FLOATING POINT BR V.ALOP ;ALLOW PROCEED ;NON RSX EMT - V5 - "EM" - PROCEED ;TRAP - V6 - "TR" - PROCEED ; SP+ 6,4,2 HONEST DATA, PS, PC ; 0 LO BYTE X 2 INTO $0E V.NEMT: MOV #"EM,ENPRFX ;"EM:" FOR EMTEE BR V.V700 V.TRAP: MOV #"TR,ENPRFX ;"TR:" FOR TRAPPED V.V700: MOV (SP)+,SSTSTK+0 ;SET UP $0E V.ALOP: MOVB #O.BKP+2,O.P ;ALLOW PROCEED BR V.INT1 ;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$$EIS .IFT MUL #50,R3 ;SHIFT IT OVER BY 50 .IFF 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 .SBTTL "O" PROCESSOR -- OPEN .STB FILE ; OPEN INPUT FILE OPNIPT: MOV #PRMPTS,R1 ;WRITE A PROMPT FOR .STB FILENAME 5$: MOVB (R1)+,R0 BEQ 6$ ;ASCIZ STYLE JSR PC,O.FTYP ;TYPE CHAR BR 5$ 6$: MOV #BUF,R4 ;SET ADDRESS OF INPUT BUFFER MOV R4,R5 7$: JSR PC,O.GET ;GET A CHAR CMPB R0,#'$ ;DOLLAR IS ILLEGAL CHAR...ALSO ESC, ETC. BEQ 8$ ;SO USE IT AS A TERMINATOR CMPB R0,#15 ;CARRAIGE RETURN? BNE 9$ ;NOPE...TAKE IT AT FACE VALUE 8$: CLR R0 ;SET END OF LINE 9$: MOVB R0,(R5)+ ;PUT CHAR IN STRING BEQ 15$ ;DONE CMP R5,#BUF+80. ;FULL BUFFER SOON? BLO 7$ ;NO...GET NEXT CHAR CLRB (R5)+ ;YES...SET END OF STRING 15$: DEC R5 ;BACK UP ONE SUB R4,R5 ;GET LENGTH MOV R5,CSI+C.CMLD ;SET LENGTH MOV R4,CSI+C.CMLD+2 ;AND START ADDRESS 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 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: .ASCIZ / .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 .IF NDF,R$$11M ;IF NOT 11M, CHECK FOR RUBOUTS CMPB R0,#177 ;RUBOUT? BNE 15$ ;NO...RETURN ERROR ;YES...ABORT THE WHOLE COMMAND .ENDC 15$: 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$$EIS .IFT 10$: CLR R0 ;RHJ IN R0 R1 DIV (R2)+,R0 ;R0 HAS QUO(CHAR) R1 HAS REMAINDER .IFF 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 .IF DF,DDTFIS ;INCLUDE FIS DECODING? OPFIS: OP FADD,RD ;FIS INSTRUCTIONS OP FSUB,RD OP FMUL,RD OP FDIV,RD .ENDC 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.: .IF DF,DDTFPP ;IF FPP CODE RECOGNITION OPFPP: .ASCII /FPP:/ .EVEN .ENDC DCDITB: .WORD 077000,DCDISO ; SOB .IF DF,DDTFIS ;INCLUDE FIS? .WORD 075040,DCDIN1 ;UNUSED**** .WORD 075000,DCDFIS ; FIS .IFF ;NO FIS .WORD 075000,DCDIN1 ;UNUSED**** .ENDC .WORD 070000,DCDIRD ; REGISTER-SOURCE .WORD 060000,DCDIAD ; ADD/SUBRACT .WORD 010000,DCDISD ; S-D .WORD 007000,DCDIN1 ;UNUSED**** .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 000210,DCDIN1 ;UNUSED**** .WORD 000200,DCDIRT ; RTS .WORD 000100,DCDIJM ; JUMP .WORD 7,DCDIN1 ;UNUSED**** .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 OPTYRD=2 ; REGISTER DESTINATION (FIS ONLY) OPTYBR=4 ; BRANCH OPTYD=6 ; DESTINATION ONLY OPTYFN=8. ; FUNNY (I.E. NONE OF THE ABOVE) OPTYSD=10. ; SOURCE-DESTINATION OPTYRS=12. ; REGISTER SOURCE ; 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 .IF NDF,R$$EIS ;IF NO HARDWARE MUL/DIV MUL42: MOV R0,-(SP) ;REPLACE MUL R4,R2 WITH SUBROUTINE MOV R1,-(SP) ;SAVE R0,R1 MOV R4,R0 MOV R2,R1 ;SET UP CALLING ARGS JSR PC,$MUL ;MUL R1,R0 MOV R1,R3 ;RETURN VALUE MOV R0,R2 MOV (SP)+,R1 ;RESTORE REGS MOV (SP)+,R0 TST R2 ;SET CONDITION CODES RTS PC .ENDC ; 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 .IF DF,DDTFPP ;IF FPP INSTRUCTION RECOGNITION CMP R2,#170000 ;FPP CODE? BHIS DCDFPP ;YUP .ENDC CMP R2,#100377 ; BPL INSTRUCTION? BLOS 6$ ; MAYBE.... BIC #100000,R2 ; DITCH SIGN BIT ON INSTRUCTION 6$: MOV R2,INST.M ; SAVE INST MAGNITUDE BMI DCDBPL ;MUST HAVE BEEN BPL 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 DCDBPL: BIC #100000,R2 ;CLEAR SIGN BIT AND ENTER BRANCH DECODING DCDIBR: SHIFT -8.,R2 .IF DF,R$$EIS ;IF HARDWARE MUL/DIV MUL R4,R2 .IFF ;NO EIS JSR PC,MUL42 ;MUL R4,R2 .ENDC 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 .IF DF,DDTFPP ;IF WE'RE ALLOWING FPP DCDFPP: MOV #OPFPP-2,R3 ;FUDGE THE ADDRESS OF THE 'FPP:' STRING CALL DCIMV ;AND PUT IT IN THE OUTPUT STREAM MOVB #' ,(R1)+ ;PUT IN A SPACE FOR CLARITY BR DCDIN1 ;GO WRITE THE OCTAL CONTENTS AND LET THE USER ;FEND FOR HER(HIM)SELF...ESPECIALLY WHERE THE ;ADDRESS MODES (AND NEXT WORD) ARE CONCERNED. .ENDC ; 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$: DCDIN1: 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 .IF DF,R$$EIS ;IF HARDWARE MUL/DIV MUL R4,R2 .IFF ;NO EIS JSR PC,MUL42 ;MUL R4,R2 .ENDC 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 .IF DF,DDTFIS ; FIS DECODING DCDFIS: SHIFT -3,R2 ;FIS INSTRUCTION SUB #7500,R2 .IF DF,R$$EIS ;IF HARDWARE MUL/DIV MUL R4,R2 .IFF ;NO EIS JSR PC,MUL42 ;MUL R4,R2 .ENDC ADD #OPFIS,R3 CALL DCPOP ;PRINT INSTRUCTION MOVB DREG,R3 ;ONE DEST REG CALL DCPRRG BR DCDIFI ;AND DONE .ENDC 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 .IF DF,R$$EIS ;IF HARDWARE MUL/DIV MUL R4,R2 .IFF ;NO EIS JSR PC,MUL42 ;MUL R4,R2 .ENDC 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 JMP DCDIB0 DCDISD: SHIFT -12.,R2 ; SOURCE-DESTINATION: RJ OP CODE .IF DF,R$$EIS ;IF HARDWARE MUL/DIV MUL R4,R2 .IFF ;NO EIS JSR PC,MUL42 ;MUL R4,R2 .ENDC 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 DCDIDQ ; PRINT INSTRUCTION AND DESTINATION 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$: .IF DF,R$$EIS ;IF HARDWARE DIV CLR R2 DIV (R4)+,R2 ; GET CHARACTER .IFF ;IF NO HARDWARE MOV R0,-(SP) ;PUSH R0,R1 MOV R1,-(SP) MOV R3,R0 MOV (R4)+,R1 ;SET UP FOR $DIV JSR PC,$DIV ;R0,R1 <- R0/R1 MOV R1,R3 MOV R0,R2 ;TRANSFER RESULT MOV (SP)+,R1 ;RESTORE REGS MOV (SP)+,R0 TST R2 ;SET CONDITION CODES APPROPRIATELY .ENDC 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 .IF DF,DDTFIS ;IF FIS ; FIS INSTRUCTIONS ENRD: CALL ENGREG ; GET REG RETURN S,BCS BR ENFN80 ;AND STICK IT IN .ENDC ; 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),(R3) .IF DF,DDTFIS ;IF FIS... CMP R2,#OPFIS ;FIS? BLO 26$ ;NOPE CMP R2,#OPSOB ;FIS? BHIS 26$ ;NO BIC #7,(R3)+ ; CLEAN UP OP-CODE MOV (R2),R2 BIC #177770,R2 ;CLEAN UP TYPE BR 28$ ;AND GO ON .ENDC 26$: BIC #17,(R3)+ ; CLEAN UP OP-CODE (NON-FIS) MOV (R2),R2 BIC #177760,R2 ;CLEAN UP NON-FIS INSTRUCTION TYPE 28$: CALL @30$-2(R2) ; BUILD NEW GUY RETURN S,BCS MOV R3,R1 ; COMPUTE NEW INSTRUCTION LENGTH SUB #ENINST,R1 RETURN C 30$: .IF DF,DDTFIS ;IF FIS ENCODING .WORD ENRD ; REG DEST (FIS) .IFF ;IF NOT, LEAVE SPACE .WORD 0 .ENDC .WORD ENBR ; BRANCH .WORD ENGD ; DESTINATION ONLY .WORD ENFN ; FUNNY TYPE (HA HA) .WORD ENSD ; SOURCE - DESTINATION .WORD ENRS ; REGISTER - SOURCE ; 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$: CMP R0,#O.CAD ;KLUGE---WAS THIS A . ? RETURN S,BEQ ;YUP...N.G. 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 CMP R1,#^R. ; JUST A DOT? BEQ 20$ ; YES...SUBSTITUTE O.CAD 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$ 20$: MOV #O.CAD,R0 ;SET ADDRESS OF CURRENTLY OPEN LOC CLC 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 ... BEQ 25$ 22$: CMPB SYMSPC,#'$ ; ... DOLLARS,... BEQ 25$ CMPB SYMSPC,#'A RETURN S,BLT ; AND LETTERS, BUT NOT NUMBERS 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$: .IF DF,R$$EIS ;IF HARDWARE MUL MUL #50,R1 .IFF ;NO HARDWARE ASL R1 ; MULTIPLY BY 10 ASL R1 ASL R1 MOV R1,-(SP) ; AND SAVE IT ASL R1 ; MULTIPLY BY 40 ASL R1 ADD (SP)+,R1 ;(NET EFFECT...*50) .ENDC 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 .SBTTL SYMBOL TABLE JUNK ; OUR ONLY SYMBOL (INPUT) SYMSPC: .BLKB 8. SYMR50: .BLKW 1 ; RAD-50 EQUIVALENT SYMR51: .BLKW 1 REGS: .ASCII /R0R1R2R3R4R5SPPC/ EXSYMS: .WORD 0 ; STORE ADDRESS OF EXTERNAL TABLE ENDODT=. ; LAST LOCATION USED SIZODT=ENDODT-ORGODT ; SIZE OF DDT .PSECT $$$SYM ; THIS SEEMS A GOOD PLACE ; 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 DDTHDR=070707 ; EXTERNAL SYMBOL HEADER EXTSYM: .WORD DDTHDR .WORD ORGODT,ENDODT+EXTSIZ .RAD50 /DDT / .IF DF,DDTDFS ;DEFINE 'PROG' .WORD DDTHDR EXTT: .WORD 0,ORGODT-1 ;LIMIT IS BOTTOM OF DDT .RAD50 /PROG/ .ENDC 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 .WORD 0 ;FLAG END OF SYMBOL TABLE EXTEND=. EXTSIZ=EXTEND-EXTSYM .END O.ODT