; *** NORMALLY MODIFIED ASSEMBLY CONDITIONALS. CONFIGURE FOR ; *** YOUR SYSTEM'S NEEDS. .IIF NDF,MAXBK, MAXBK=177777 ;HIGHEST CORE BLOCK (64 BYTES) IN MACHINE ; SHOULD BE DEFINED TO PROTECT AGAINST ILL MEM REFERENCES. ; **** END OF NORMALLY-MODIFIED SECTION ***** TCBREG=20 ;SOME MSX-11/BSX-11 DEFINITIONS (USED IN SOME VIRTUAL ; ;MAPPING COMMANDS SPECIFICALLY FOR BSX/MSX) TCBDSP=12 TCBISP=10 ;INITIAL SP IN BSX0 .TITLE DDT11 .IDENT /850429/ ;Glenn C. Everhart ;12/4/81 ADD .PSECTS FOR RO AND RW SECTIONS OF CODE ;1/4/82 ADD MVTS$ CALLS IF MPV2. DEFINED ;4/16/82 ADD EQUIVALENCE OF ";" WITH "ESC" ; AND MAGIC BACKUP-AN-INSTRUCTION SUB ; AND SUPERDUPER Q REGISTER COMMAND LOGIC .PSECT ..DDT.,RW,I ;IMPURE CODE .PSECT ..DDTP,RO,I ;CODE .PSECT ..DDTD,RW,D ;DATA ; .PSECT ..DDT.,RW,I ;12/29/81 ADD CODE FOR HANDLING SOME USER MODE I/D SPACE DEBUGGING .ENABL LC .IIF DF,MV3.2,MMV3.2=0 ;DEFINE K$ID IF KNL I/D SPACE USED (RSX11M+) .IF DF,MPV2. .IF DF,..MVTS ; DEFINITION OF MVTS$S MACRO ;USE FOR TEST ASSEMBLIES UNTIL REAL DEF'N COMES OUT WITH 11M+ V2 .IF NDF,..MVRL MV.TUI=0 ;MOVE TO USER I MV.TUD=1 ;MOVE TO USER D FROM VALUE ARG MV.TSI=2 ;MOVE TO SUPER I FROM VALUE ARG MV.TSD=3 ;MOVE TO SUPER D MV.FUI=4 ;MOVE FROM USER I SPACE TO BUF (SAME OFSET AS 3RD ARG) MV.FUD=5 ;MOVE FROM USER D SPACE MV.FSI=6 ;MOVE FROM SUPER I MV.FSD=7 ;MOVE FROM SUPER D SPACE ;DUMMY MACRO FOR TESTING, ASSUMES NO I/D SPACE AND ONLY MV.TUI AND MV.FUI .MACRO MVTS$S ACTION,ADDR,VAL,?A,?B CMP ACTION,#MV.TUI BNE A MOV VAL,@ADDR BR B A: CMP ACTION,#MV.FUI BNE B MOV @ADDR,@VAL B: .ENDM .IFF .MCALL MVTS$S,MVTS$ .IF EQ,1 .MACRO MVTS$S ACTION,ADDR,VAL .IF B,VAL CLR -(SP) .IFF MOV VAL,-(SP) ;VALUE TO PUT IN OR BUF TO GET DATA .ENDC MOV ADDR,-(SP) ;WHERE IN "SOME" SPACE TO ACCESS MOV ACTION,-(SP) ;SYMBOLIC ACTION MOV (PC)+,-(SP) .BYTE 203.,4 ;DIRECTIVE CODE EMT 377 ;CALL RSX ;DEFINITIONS OF CODES - NOT CORRECT UNLESS BY ACCIDENT MV.TUI=0 ;MOVE TO USER I MV.TUD=1 ;MOVE TO USER D FROM VALUE ARG MV.TSI=2 ;MOVE TO SUPER I FROM VALUE ARG MV.TSD=3 ;MOVE TO SUPER D MV.FUI=4 ;MOVE FROM USER I SPACE TO BUF (SAME OFSET AS 3RD ARG) MV.FUD=5 ;MOVE FROM USER D SPACE MV.FSI=6 ;MOVE FROM SUPER I MV.FSD=7 ;MOVE FROM SUPER D SPACE .ENDM .ENDC ;EQ,1 .ENDC .ENDC .MCALL MVTS$S ; MVTS$S ACTION, ADDR, VAL/BUF ; WHERE ACTION MV.TUI OR MV.FUI MOVE TO/FROM USER I SPACE ; (MV.TUD OR MV.FUD ACCESS USER D SPACE) ; ADDR IS WHERE TO MODIFY ; VAL OR BUF IS DATA TO PUT INTO USER I/D SPACE (VAL) OR PLACE ; TO HOLD DATA (BUF) .PSECT ..DDTD MPI.DT: .WORD 0 ;DATA CELL FOR MVTS$ VAL/BUF AREA .ENDC .IF DF,MU$DBG .GLOBL D.S ;SINGLE STEP MODE FLAG (BYTE) .IIF DF,MEM$BK, .GLOBL MEMADR,NMEM.B ;BLK OF 1+2*NMEM.B WDS .IIF NDF,X$DSW, .GLOBL U.DSW ;DSW FROM DDTKNL IF X$DSW NOT DEFINED .GLOBL D.STYP,PARMAP,D.CHAR,D.CRLF .GLOBL D.TRAV ;TRAP .GLOBL D.EMTV ;EMT .GLOBL D.SEGV ;SEG TRP .IF DF,U$ID.!MPV2. .GLOBL UV$SPF ;AUX I/D MAPPING FLAG USED WITH PARMAP .ENDC .GLOBL D.IOTV ;IOT .GLOBL D.NXMT ;NXM .GLOBL D.ILGT ;ILL INST .GLOBL D.BRK ;BPT .GLOBL DDT,FPSTT,FPAC,JOBSA,D.UR7,D.UR6,D.UR0,D.USTA $VMEM=0 ;MUST BE DEFINED FOR MULTITASK DEBUG! .ENDC ; ;DULMOD DEFINED ALLOWS DDT TO RUN IN ONE MODE (E.G. KNL) AND PGM IN ANOTHER ;D.MCRO DEEFINED TURNS ON MACROS ;DEFINE D.INLU AND D.OUTU FOR TERMINAL INPUT,OUTPUT LUNS ;TO GET THIS BEAST TO RUN. .IF DF,R$XMDB!R$XDDB $VMEM=0 ;FORCE $VMEM DEFINED FOR RSX11M INTERTASK DEBUGGING .IF NDF,R$XDDB .MCALL TCBDF$,HDRDF$,PCBDF$ TCBDF$ HDRDF$ PCBDF$ .ENDC .ENDC .IF DF,$$RSX .IIF NDF,D.INLU, D.INLU=5 .IIF NDF,D.OUTU, D.OUTU=5 .ENDC .IF NDF,$$RSX .IF NDF,$$DOS .IF NDF,$$RT11 DULMOD=0 ;DUAL MODE USE, STANDALONE .ENDC .ENDC .ENDC D.KSR=0 .IIF NDF,$D$FPU, .PRINT ;IGNORE A FEW ERRS IN F.P. INSTRUCTION DECODER ASSEMBLY .IIF DF,$D$FPU,$FOP$=0 .IF EQ,1 ;THIS VERSION OF DDT PERMITS .PSECT .SYMS. TO CONTAIN ADDITIONAL SYMBOLS ;TO ADD TO DDT. A DDT SYMBOL IS OF THE FORM .RAD50 /SYMNAM/ ;2 WORD RAD50 NAME .WORD SYMADR ;1 WORD SYMBOL ADDRESS THE SYMBOLS MUST BE TERMINATED BY 3 ZERO WORDS, I.E., .WORD 0,0,0 ;SYMBOL TABLE TERMINATOR BUT MAY BE ADDED BY A SEPARATELY ASSEMBLED MODULE WITH .PSECT DECLARED AS .PSECT .SYMS.,RW,CON WITH SYMBOLS IN IT. TO ENABLE THE ADDITIONAL SYMBOLS, FILL IN THE 2 WORDS AT "SYMEND" WITH -1'S WITH DDT. DDT CONDITIONS D.KSR DEFINE ALWAYS; SETS TTY MODE I/O TTYASR DEFINE FOR DIRECT DDT CONTROL OF NON-CONSOLE TTY $$RT11 DEFINE FOR RT11 DDT (ONLY PROVIDES "BYE" SYMBOL) $$DOS DEFINE FOR DOS-11 DDT $$RSX DEFINE FOR ALL RSX DDT'S (11-M OR 11-D). $RSXM DEFINE IF RSX11M ON MACHINE WITHOUT RTT $RSXMM DEFINE IF RSX11M ON MACHINE WITH RTT L$$SI DEFINE FOR USE WITH LSI-11 MSX11D=0 ;DEFINE FOR OMITTING DEBUG TRACE OF TRAP INSTRUCTIONS (WILL NOT CAUSE DDT TO GAIN CONTROL ON ANY "TRAP" INSTRUCTIONS. USEFUL FOR DEBUG OF FORTRAN PROGRAMS WHERE ERROR PRINTOUTS ARE DUE TO TRAPS.) R$XMDB=0 ;ALLOW RSX11M DEBUG OF ANY TASK VIA VIRTUAL MAP R$XDDB=0 ;ALLOW IAS/RSX11D DEBUG OF ANY TASK BY NAME TCBREG=20 ;SOME MSX-11/BSX-11 DEFINITIONS (USED IN SOME VIRTUAL ; ;MAPPING COMMANDS SPECIFICALLY FOR BSX/MSX) TCBDSP=12 TCBISP=10 ;INITIAL SP IN BSX0 XTCOM DEFINE WHERE DDT IS TO OPERATE DIRECTLY ON TTY HARDWARE. (OTHERWISE USES LUNS 5 AND 6, EVENT FLAGS 22 AND 23.) $VMEM USE PSEUDO MAP FOR MEMORY MAPPED DDT. ALL ADDRESSES AND INSTRUCTIONS ARE IN A PSEUDO MAP WITH APR'S CONTROLLED BY WORDS "PAR0" THROUGH "PAR7", WHICH ARE INITIALIZED TO VALUES OF DDT STARTUP. NOTE THAT THESE ARE NOT USED UNTIL A COMMAND ($UM, $UU, $UK) IS GIVEN AND THEY MAY BE STOPPED VIA THE $UV COMMAND FROM AFFECTING ACTUAL MAPPING USED. SINCE APR'S ARE ALTERED WHEN SWAPPING OR SHUFFLING OCCURS, IT IS BEST NOT TO USE THIS MODE UNLESS DEBUGGING CODE NOT MOVING IN MEMORY. DULMOD ALLOWS DDT TO RUN IN KERNEL MODE WITH USER MODE PROGRAMS IF DEFINED. (NOT FOR RSX VERSIONS). D.MCRO IF DEFINED, ENABLES MACROS TO WORK IN DDT (ENTER MACROS WITH UF CONSTRUCT; USE VIA UC CONSTRUCT.) F$DPX DEFINED CAUSES RSX DDT TO USE READ WITHOUT ECHO AND TO THEREFORE ECHO ALL CHARACTERS ITSELF. THIS IS THE PREFERRED MODE FOR RSX. DB$L DEFINED, INCLUDES 32 BIT INTEGER DISPLAY / EXAMINE COMMAND ADDR$1Jnumber TO INSERT NUMBER, ADDR$J TO DISPLAY ADDR AND ADDR+2 AS A NUMBER IN FORM (LO=ADDR,HIGH=ADDR+2) AS THE FORTRAN CONVENTION SAYS. SM$FIL DEFINED ALLOWS DDT TO USE THE $UO AND $UQ COMMANDS TO OPEN AND CLOSE AN .STB FILE TO GET SYMBOLS FROM THE SYMBOL TABLE. NOTE THAT THESE ARE NOT COMPLETELY EQUIVALENT TO REAL INTERNAL SYMBOLS BUT ARE FAIRLY CLOSE. WHEN $UO IS SEEN, DDT PROMPTS FOR A FILENAME AND WILL READ IT WHENEVER IT CANNOT DEFINE A SYMBOL. THE $UQ COMMAND CLOSES THIS FILE AGAIN. ALSO, NOTE THAT IF THE FILE DOES NOT EXIST OR IF $1UO US ENTERED, DDT WILL CLOSE THE FILE AND POSSIBLY TYPE ? TO INDICATE A POSSIBLE ERROR. I$$SD DEFINED, CAUSES DDT22 TO PROCESS ISD DECLARATIONS IN DECUS FORMAT. This is the usual object format for PDP11, but since ISD blocks are undefined, the following treatment is assumed: 1. A GSD block appears with a module name entry and some optional ISD blocks. 2. The ISD definitions for that module are in the same format as GSD definitions within the GSD block (name and value in the same place) but with the ISD code instead. 3. The module name appears before any of the ISD definitions so that it may be used to discard records. The named variable MODULE in the DDT space, which is initialized to ".MAIN.", will contain the RAD50 module name to seek. If the MDLCTL variable is zero, ISD symbols will be ignored. If it is +, they will be included for the module named only, and if it is - (to 16 bits), they will be included for any module. The object module so handled will have to have relocated addresses as its input, so it is necessary for the .STB file to be made up using some form of alternate "linker" to be supplied. Because this is not yet available, the code will normally not be included at present. CD$FIL CODE FILE ... ALLOWS DDT TO BE USED TO ALTER A CODE FILE WHICH IS ON CD.LUN. CD.BAS IS BASE ADDRESS OF FILE (I.E., VIRTUAL BLOCK 1, BYTE 0 = START ADDRESS - CD.BAS BYTES). THIS ALLOWS PATCHING OF MEMORY IMAGES REGARDLESS OF SIZE OF TASK HEADERS. CD.BLK IS A BLOCK NUMBER TO BE USED AS THE START BLOCK NUMBER ONCE ADDRESSES ARE STRIPPED TO MULTIPLES OF 512 BYTES. THE ACTION IS THE LOW 9 BITS ARE TREATED AS A BYTE OFFSET, THE HIGH 7 AS A BLOCK NUMBER, AND CD.BLK IS ADDED. IT WILL INITIALLY BE 1 WHEN A FILE IS OPENED BUT MAY BE WHATEVER IS DESIRED. NOTE THAT THE ADDRESS IS FOUND FROM THE ADDRESS INTO GETCAD OR PUTCAD BY SUBTRACTING THE VALUE IN CD.BAS (16 BITS) FROM IT, THEN CONVERTING TO THE BLK # / OFFSET FORM. IF CD.CTL IS 0, NORMAL CORE LOOKUPS ARE DONE. IF IT IS +, VIRTUAL READ/WRITES ARE DONE TO AN OPEN FILE (OPENED VIA THE $L COMMAND WHICH PROMPTS FOR THE FILE TO EXAMINE/ALTER), AND IF CD.CTL IS NEGATIVE IO.RLB OR IO.WLB IS DONE TO ALLOW ABSOLUTE DISK PATCHING FROM DDT. THIS CONDITIONAL WILL REQUIRE THE SM$FIL LOGIC TO BE PRESENT, AND $VMEM DEFINED. X$OVL DEFINED INCUDES SYMBOL "OVRBRK" WHICH MAY BE SET IN DDT. IF SET, AND IF PC AT A BREAK IS SAME AS OVRBRK, ONLY CODE AT THAT BREAKPOINT WILL BE SAVED/RESTORED, NOT OTHER BREAKS. NOTE PC WILL BE OFFSET BY 2 SO COMPARISON IS (PC-2) TO OVRBRK. THIS IS DONE TO ALLOW A BREAK AT OVERLAY LOAD RETURN SO THAT THE NEW OVERLAY SEGMENT MAY BE LOADED AND NOT TRASHED BY DDT REMOVING BREAKS IN OLD OVERLAY AND "REPLACING" INCORRECT INSTRUCTIONS. CND$BK DEFINED WILL ALLOW LOCATIONS D.BMSK(BP#) AND D.BTST(BP#) TO PERMIT CONDITIONAL BREAKPOINTS. IF D.BMSK(BREAKPOINT #) IS NONZERO, THE WORD TO OPEN WITH THE BREAKPOINT WILL BE AND'ED WITH D.BMSK(BP #) AND THE RESULT COMPARED WITH D.BTST(BP#). IF THE TWO ARE DIFFERENT THE BREAKPOINT WILL BE IGNORED. NOTE THAT IF D.BMSK(BP #) IS 0, THESE TESTS WILL BE OMITTED. SPC$MP DEFINED WILL, IF MU$DBG DEFINED, DO ALL INTERTASK DATA GETS/PUTS VIA A PURE SEND/RECEIVE LOGIC RATHER THAN MAPPING. NORMALLY ONE DEFINES X$MPP THEN TO REMOVE ALL I/O PAGE REFS. SLOWER THAN THE NORMAL MODE, BUT INSENSITIVE TO SWAPPING, SHUFFLING, ETC. LOCATION SR.CTL, INITED TO VALUE OF SPC$MP, CONTROLS THIS. IF NONZERO, USES SEND/RCV, ELSE USES MAPPING. D.INLU AND D.OUTU ARE LUNS FOR RSX TERMINAL I/O. THEY MAY BE THE SAME IF DESIRED, BUT THIS WILL MESS UP SEARCH OPERATIONS IN RSX11D/IAS VERSIONS WITHOUT XTCOM. RSX11M V3.1 AND EARLIER TT HANDLER MESSES SEARCHES ANYHOW. AN -11M CONDITIONAL (MV3.2) ALLOWS THIS CODE TO LOOK MORE LIKE -11D BUT RSX11D-ONLY CALLS HAVE BEEN REPLACED BY COMPATIBLE ONES SO THE RSX11D VERSION MAY BE USED WITH RSX11M V3.2 AND LATER. NOTE THAT THE SYMBOLS MV3.2 AND MMV3.2 SHOULD BOTH BE DEFINED FOR RSX11M V3.2 WITH FULL DUPLEX HANDLER TO ENABLE FULL DUPLEX DDT OPERATION (INCLUDING STOPPING AUTO-PROCEED ON TYPING OF A CHARACTER). $DDBSX ALLOWS USE OF MAP PRESETS FOR BSX STANDALONE SYSTEM $VPAT ALLOWS DDT TO PATCH A FILE ON A PATCH LUN (SEE THE CODE) D.PLUN (EV IS D.PEV, BOTH GLOBAL). IT ASSUMES IT PATCHES A SYSTEM IMAGE ON A CONTIGUOUS FILE STARTING AT A BASE BLOCK AND CONVERTS ADDRESSES TO BLOCKS+OFFSETS TO DO SO. DDT HAS NO OPEN CODE HOWEVER, SO THIS MUST BE TO A FOREIGN-MOUNTED (OR UNMOUNTED IN RSX11M) DEVICE. $FORM$ ALLOWS FORMATION INTERRUPT VECTOR (IN STANDALONE VERSIONS) TO ACT LIKE A PSEUDO SINGLE-INSTRUCTION BREAKPOINT AND JUMPS TO D.BRK AFTER SETTING SINGLE INSTRUCTION MODE ON. D.FFPN IS INTERRUPT VECTOR LOCATION; DDT DOES NOT INITIALIZE IT. $D$FPU DEFINED, CAUSES DDT TO HAVE ROUTINES SAVE OR RESTORE 11/45 FORM FLOATING POINT HARDWARE REGS. LOCATION FPSTAT WILL THEN CONTAIN THE F.P.U. STATUS, AND LOCATIONS AC0 THRUOUGH AC5 WILL CONTAIN THE FLOATING POINT REGISTERS. ...NOTE THIS CAN CAUSE TROUBLE IF THE TASK IS NOT BUILT WITH THE /FP SWITCH, SO THE WORD FPCTL IS DEFINED AND INITIALLY 0. IF IT IS NONZERO, FLOATING POINT SAVE/RESTORE IS ENABLED; OTHERWISE NOT. IT SHOULD BE SET AT PROGRAM STARTUP IF DESIRED. IT WILL BE INITIALIZED TO THE VALUE OF $D$FPU SO IF YOU WISH TO DEFAULT TO F.P. SAVE/RESTORE ON MERELY INCLUDE $D$FPU=1 IN YOUR ASSEMBLY. OTHERWISE INCLUDE $D$FPU=0. $FOP$ DEFINE TO ALLOW FLOATING OPCODES TO BE UNDERSTOOD IN A VERY ABBREVIATED WAY. DEFAULTS ON IF $D$FPU IS DEFINED. MEM$TR DEFINED, CREATES MT.BUF ARRAY (TOP MT.TOP, POINTED TO BY MT.PTR) WHICH SAVES PCs AT BREAKPOINT TRAPS CIRCULARLY FOR MT.NUM TRAPS. HANDY IN CONJUNCTION WITH SINGLE STEP MODES TO FIND OUT WHERE YOU GOT TO A CRAZY PLACE FROM WITHOUT HAVING TO EXAMINE THE PC BY TYPING IT OUT DURING MANUAL SINGLE STEP. .ENDC .IIF DF,CD$FIL, SM$FIL=0 .IIF DF,CD$FIL, $VMEM=0 .IIF DF,I$$SD, SM$FIL=0 ;IF WE MUST TREAT ISD'S, MUST DO STB'S .IIF DF,$FORM$, .GLOBL D.FFPN D.KSR=0;ASR33 DEFAULT NOW .IIF DF,$D$FPU,$FOP$=0 .IF DF,$$DOS .PRINT ;DDT-11 FOR DOS-11 SYSTEM .ENDC .IF DF,$$RSX .IF DF,$VMEM .IF NDF,Q$UIET .PRINT ;DDT-11 ASSEMBLED FOR VIRTUAL APR MAPPING .PRINT ; (MUST RUN ON A CPU WITH MAPPING ON) .IIF DF,R$XMDB, .PRINT ;DDT ALLOWS RSX11M INTERTASK EXAM/MODS .ENDC .ENDC MMM11=0 .IIF DF,$RSXM,MMM11=MMM11+1 .IIF DF,$RSXMM,MMM11=MMM11+2 .IF EQ,MMM11 .IIF DF,R$XMDB, .ERROR ;RSX11M TASK DEBUG BAD FOR RSX11D/IAS! .IF NDF,Q$UIET .PRINT ;DDT-11 FOR RSX-11D ON 11/45 CPU .ENDC .ENDC .IF EQ, .IF NDF,Q$UIET .PRINT ;DDT-11 FOR RSX11M ON 11/05 OR 11/20 CPU .IIF DF,$VMEM, .ERROR ;MAPPING DDT ILLEGAL IN UNMAPPED RSX11M .IIF DF, R$XMDB, .ERROR ;RSX11M DEBUG ASSUMES MAPPED! .ENDC .ENDC .IF GT, .IF NDF,$D$FPU .IF NDF,Q$UIET .PRINT ;DDT-11 FOR MAPPED RSX11M (11/40 CPU ASSUMED) .ENDC .IFF .IF NDF,Q$UIET .PRINT ;DDT-11 FOR MAPPED RSX11M WITH FP (11/70 CPU ASSUMED) .ENDC .ENDC .ENDC .IF DF,XTCOM .IF NDF,Q$UIET .PRINT ;HARDWARE CONTROLLED DIRECTLY BY DDT .ENDC .IFF .IF NDF,SM$FIL .IF NDF,Q$UIET .PRINT ;CONSOLE I/O VIA LUNS 5 AND 6, EVENT FLAGS 22. , 23. .PRINT D.INLU ;INPUT LUN DISPLAYED .PRINT D.OUTU ;OUTPUT LUN DISPLAYED .ENDC .IFF .IF NDF,Q$UIET .PRINT ;I/O VIA .ODTL1 AND .ODTL2 .PRINT ;MAP FILE OPEN AVAILABLE .IIF DF,CD$FIL, .PRINT ;CODE FILE EXAMINE/MODIFY AVAILABLE .ENDC .ENDC .ENDC .ENDC .IF DF,$D$FPU .IF NDF,Q$UIET .PRINT ;DDT USES 11/45 FPU HARDWARE SAVE/RESTORE IF FPCTL IS NON-0 .PRINT $D$FPU ;VALUE OF FPCTL INITIALLY DISPLAYED .PRINT ;ADDR$UINUMBER ADDR$UJNUMBER AND ADDR$UX SUPPORTED (INSERT XAMINE .PRINT ;F.P. NUMBERS .ENDC .ENDC .IF NDF,Q$UIET .IIF DF,SM$FIL, .PRINT ;DDT ALLOWS SYM. TBL FILES TO BE READ VIA $UO .IIF DF,MEM$BK, .PRINT ;MEMORY WATCHPOINT LOGIC INCLUDED. .IIF DF, F$DPX, .PRINT ;TERMINAL I/O WITH DDT ECHO OF ALL CHARS. .IIF DF,CND$BK, .PRINT ;CONDITIONAL BREAKS INCLUDED. .ENDC UPAR0=177640 UPDR0=177600 ;USER PAR,PDR KPAR0=172340 ;KERNEL PAR 0 ; THIS IS DDT: DYNAMIC DEBUGGING TECHNIQUE FOR A PDP-11. ; IT RESEMBLES DDT FOR A PDP-10 IN AS MANY WAYS AS POSSIBLE ; AND FALLS SHORT ONLY SLIGHTLY DUE TO THE VARIETY OF PDP-11 ; CONFIGURATIONS AVAILABLE. IT WAS MODIFIED DRASTICALLY ; FROM DEC'S ODT (JUST TRY TO FIND ANY ODT CODE!) ; ; AUTHOR: STEVEN M. RUBIN (SR12@CMU) ;MODIFIED 10/1975 BY G. C. EVERHART, MIT. ; ; ; THIS VERSION MAY BE CONDITIONED FOR USE WITH DOS-11 BY DEFINING ; "$$DOS" AT ASSEMBLY TIME OR FOR RSX11-D BY DEFINING "$$RSX". ; THE DOS VERSION IS NOT VERY DIFFERENT FROM THE USUAL DDT. ; THE RSX VERSION IS INTENDED TO REPLACE ODT HOWEVER, AND IT ; HAS TO USE THE FOLLOWING KLUDGES TO WORK AT ALL: ; 1. IT GAINS CONTROL BY SETTING A TABLE OF TRAPS AND LETTING ; RSX PASS TASK TRAPS TO IT AS ODT DOES. ; 2. IT DOES A SIMPLE QIO$ TO TI: TO DO ITS CONSOLE I/O ; (IMPLEMENTED AS A 1-FOR-1 REPLACEMENT OF THE LOW-LEVEL ; INTERNAL CALL TO GRAB CHARACTERS OFF THE CONSOLE), AND ; HANDLES CONSOLE OUTPUT IN LIKE FASHION. THE INTERNAL ; ASSUMPTION IS THAT LUN 6 IS RESERVED FOR TI:, THOUGH THIS ; WILL BE MODIFIABLE FROM SOURCES WHERE DESIRED. IT IS ; INTERNALLY EXPECTED THIS IS DONE AT TKB TIME. ; (IO.RVB AND IO.WVB WILL BE USED FOR I/O IN CASE SOME IDIOT ; HAS LUN 6 ASSIGNED TO A DISK!) ; 3. APPROPRIATE RSX CALLS WILL BE MADE TO FIND OUT TASK STARTING ; ADDRESS SO A SIMPLE G WILL START THE TASK. ; EXIT WILL BE DONE VIA ANOTHER G COMMAND VIZ: ; DDTXITG ; WHICH WILL SIMPLY EXECUTE AN EXIT$S AND SCRAM. (THE DOS ; VERSION CAN EXIT VIA "$$DOSG"). .GLOBL DDT,JOBSA,D.SYMT ; THE NEXT THREE DEFINES DESCRIBE THE MAIN OUTPUT DEVICE THAT ; DDT WILL USE. ONLY 1 MAY BE DEFINED AND THE REST MUST BE ; COMMENTED OUT. ;D.GDP = 1 ; TTY IS GRAPHICS DISPLAY PROCESSOR ;D.KSR = 1 ; TTY IS KSR-33 ;D.GT40 = 1 ; TTY IS DEC GT40 .MCALL DSAR$S,ENAR$S D.OKTTY=-1 .IF DF,D.GDP D.OKTTY=D.OKTTY+1 .TITLE D.GDP .IF NDF,Q$UIET .PRINT ; *****DDT for a GDP***** .ENDC D.RDB = 165202 ; READER DATA BUFFER D.RCSR = 165200 ; READER STATUS REGISTER D.PRIO = 0 ; RUN AT PRIORITY ZERO .ENDC .IF DF,D.GT40 D.OKTTY=D.OKTTY+1 .TITLE D.GT40 .IF NDF,Q$UIET .PRINT ; *****DDT for a GT40***** .ENDC D.RCSR = 177560 ; READER STATUS REGISTER D.RDB = 177562 ; READER DATA BUFFER D.PRIO = 200 ; RUN AT PRIORITY FOUR .ENDC .IF DF,D.KSR D.OKTTY=D.OKTTY+1 .IF DF,$$RSX!$$DOS!$$RT11!MSX11D .TITLE DDT11 .IFF .TITLE D.KSR .ENDC .IF NDF,TTYASR ;IF NOT NONSTD TTY DEVICE .IF NDF,Q$UIET .PRINT ; *****DDT for a TTY***** .ENDC D.RCSR = 177560 ; READER STATUS REGISTER D.RDB = 177562 ; READER DATA BUFFER D.TCSR = 177564 ; PRINTER STATUS REGISTER D.TDB = 177566 ; PRINTER DATA BUFFER .IF NDF,$$RSX ;DOS OR S/A VERSIONS D.PRIO = 340 ; RUN AT PRIORITY SEVEN .IFF ;$$RSX D.PRIO = 0 ;RUN AT PRIO 0 IN RSX11D .ENDC ;$$RSX .IFF ;TTYASR D.RCSR=175410 ;RDR STATUS. DEFINE FOR YOUR TERMINAL. D.RDB=D.RCSR+2 D.TCSR=D.RDB+2 D.TDB=D.TCSR+2 D.PRIO=340;PRI7 DEFAULT .IF NDF,Q$UIET .PRINT ;****DDT FOR A NONSTANDARD TERMINAL****(TTY-LIKE!)** .ENDC .ENDC .ENDC .IIF NE,D.OKTTY,.ERROR ; INVALID OUTPUT DEVICE FOR DDT D.BKP = 8. ; NUMBER OF BREAKPOINTS D.SYML = 10. ; MAX NUMBER CHARS IN A SYMBOL R0 = %0 R1 = %1 R2 = %2 R3 = %3 R4 = %4 R5 = %5 SP = %6 PC = %7 PS = 177776 ; PROCESSOR STATUS D.CNUM=71. .IF NE,0 DDT/11 - Dynamic Debugging Technique on the PDP-11 Each command in DDT/11 is identical to the PDP-10 version whenever possible. In some cases, DDT/10 commands have been omitted in the interest of saving core and making good sense. The following is a list of the DDT/11 commands: n/ Open word n. Type contents in current mode / Open word pointed to by last typed value n Modify currently open word to be n. Close word. n Modify, close, open next word n^ Modify, close, open previous word n Modify, close, open word pointed to by last typed address n\ Modify, close, examine word n \ Examine word pointed to by last typed value n? Type word n in RAD50 format (forces even address) Also displays address in octal, decimal, hex, octal bytes, and ASCII. @ Types out location absolutely addressed by the open location (the same convention as , and the same as the DEC ODT convention for @ sign. $S Change current mode to instruction type out ("Symbolic") $A Addresses will be typed as absolute numbers ("Absolute") $R Addresses will be typed relative to symbols ("Relative") $C Change current mode to numeric type out ("Constant") $nR Change current radix for $C to n (n read in decimal) $T Change current mode to ASCII text output ("Text") $5T Change current mode to Radix-50 text output $nO Change current mode to n bit byte typeout $H Change to halfword (byte) mode (reset by $5T and $S) Note that the initial modes are $S and $8R. These can be temporarily changed by the above commands and will return to the permanent setting by a carriage return. The settings can be permanently changed by using two altmodes before the mode setting command ($$T sets permanent ASCII mode) n[ Open location n, type as a numeric n] Open location n, type as instruction n! Open location n, do not type value ; Retype currently open word = Retype currently open word as number n= Type value of n as a number _ Retype currently open word as instruction $_ Retype currently open word symbolically i$X Execute instruction i (cannot execute branches or jumps) Note the instruction executes in the context of the target task if multi-task DDT is in use. n$G Start executing program at location n. Default is to start executing at address in JOBSA (start of program) v$nB Set breakpoint n at address v (n from 1 to 8 or can be omitted) a,v$nB Same as above but open address a at breakpoint If two altmodes are used, automatic proceding is enabled. The breakpoint will cause the message to be typed and the program resumed. If you type a character, the automatic proceding will stop. If a is less than 8 (the # of breakpoints defined), then Q register number a will be executed at the break instead of displaying anything. The Y command alters the Q regs (Q was in use...). 0$nB Remove breakpoint n $B Remove all breakpoints $P Procede from breakpoint n$P Procede from breakpoint n times (without halting) If two altmodes are used, the breakpoint will be proceded from automatically n$UW Set offset limit to n (used when typing addresses) $1UT Turn on single stepping (break at each instruction) a$1UT Turn on single stepping and open location a at each break If two altmodes are used, the single stepping will be done automatically $UT Turn off single stepping a: Make current location have symbolic name a v Define macro number n. The characters between the &'s make up the body of the macro. A & is entered into the text by typing two &'s. 0$nY Delete contents of macro number n. $nY Execute the contents of macro n. Legal range is 0<=n<=8. n$M Set mask for searches (below) to n ls$W Search core from l to u for word s. ls$E Search core from l to u for effective address s. ls$N Search core from l to u for word not equal to s. addr$J Display 32 bit number in current radix. Number assumed stored as (low order, high order) as in FORTRAN. addr$nJnumber. Insert number (delimited by any nondigit outside the range of the current radix (so hex input will work)) at addr. If n is 2 the number is treated as 16 bits only, otherwise as 32 bits. This allows entry of hex radix. Soft restart at address 1004 (Graphics DDT only) $UG Turn on user display when in DDT (Graphics DDT only) addr$UInumber Insert 32-bit floating-point number at addr addr$UJnumber Insert 64-bit floating point number at addr addr$UX EXamine floating point number at addr. Assumed to have precision in D.PRCN (2 or 4 for 32 or 64 bits) which is left over from last $UI or $UJ or set from console. Note that floating AC's are saved/restored only if FPCTL is set nonzero. If so, FPSTAT is FPU status and AC0-AC% are floating AC's. $UO Prompt for name of symbol table file. If a file is specified and exists, set to use it to resolve symbols. If file spec is null or does not exist, close existing symbol table file. $1UO will close any open symbol table file too but will erase DDT's internal "cache" of symbols. $UQ leaves that cache intact. $UQ Close symbol table file if any is open. $L Close any open core image file and reset PARMAP (effective $UV) so subsequent memory examines will be from DDT virtual space. $1L Prompt for core image file to use and treat subsequent virtual ($UM mode) memory accesses as relative to the base of the file. If the /AB switch is used, addresses will be taken relative to device. Base address is stored in CD.BAS and start block number (added to block number/offset calculated from (address-CD.BAS) to obtain device or file virtual block number) is in CD.BLK in the order (low order 16 bits, High order 16 bits). These two commands are present only if CD$FIL is defined at assembly time and use CD.LUN which defaults the same as D.OUTU. The definition of CD$FIL forces $UO and $UQ mapping to work and requires $VMEM to be defined also, thus forcing taskbuilds with I/O page commons at least. If the /RO switch is used, file (or device) is opened read only (this is simulated in the case of the device). Note that the file or device must be on SY: as presently implemented. $UM Turn on use of virtual map. Variables PAR0 through PAR7 will be used as APR's for all number entry or displays in any format. $UR Turn virtual mapping back off. Mapping of APR's will be as it was when DDT was started. (*** NOT recommended; use $UV.) $UU Turn on virtual mapping and copy current User APR's into maps used by DDT. All addressing will be done via those virtual APR's. $UK Turn on virtual mapping and copy current Kernel APR's into maps used by DDT. All mapping will be done via these APR's. Note that if Kernel I and D space exists, $UK gets kernel D APRs and 1$UK gets I space kernel APRs. $UV Use standard DDT virtual mapping (no pseudo maps). This differs from the other commands in that no APR's are used; the others use the APR's that DDT is intialized with, which may be inadequate if the task is checkpointed and moved. DDT initializes in this mode and can, in it, access whatever a normal DDT can access (and conversely). $1UV will set up examination of user mode I space registers; $UV gives D space registers. This option is conditioned on U$ID. at assembly and REQUIRES I/O page mapping. ntext Fill in text of macro (up to 80 char) with any characters. Text is always read from console and the command terminates, filling in a legal end sentinel, after buffer full or recognition of the second delimiter character, which may be any ASCII character not in the text string. These macros are enabled by the D.MCRO assembly conditional defined. The conditional DULMOD allows a DDT that can run in one space and debug programs in the other (another...). NOTE DDT mapping does not affect program execution; only displays are affected. Modifications to memory will use the current APR's, but breakpoints will not be put into arbitrary memory locations. The $UM, $UR, $UU and $UK commands only exist where the assembly conditional $VMEM was defined and DDT is linked to a common in the I/O page at APR 7. $ULTSKNAM Read a task name (6 characters maximum) from the console (or macro) and locate its header and mapping information inside RSX11M. Then compute the APR mappings for that task and move them into the locations used by DDT for its pseudo mapping. This option requires that R$XMDB be defined and that DDT be assembled with $VMEM defined and with the appropriate RSX macros (normally [1,1]EXEMC) available for header, TCB, and window block offset definitions. Also, the task using such a version of DDT must have access to the I/O page via APR 7. This option only makes sense on fixed tasks or in systems without checkpointing, but may be useful in those systems for examining or modifying other tasks. addr$J Display contents of (addr, addr+2) as a 32 bit integer in current radix. addr$1Jnumber Insert number at addr and addr+2 as a 32 bit integer. number is delimited by any character not legal in the current radix. The 32 bit integers are assumed stored as (low order, high order) in memory (addr=l.o., addr+2=h.o.). addr$2Jnumber Insert number (in current radix) at addr as a 16 bit number. This is provided in addition to the usual DDT methods since the DDT parser cannot handle bases higher than 10. Thus, this command gives a means to enter, as well as display, numbers in higher bases, such as hex. Note that numbers can be as any combination of the following: . " "$ The operators + (addition), - (subtraction), * (multiplication), and ' (division) are evaluated from left to right unless parenthesis are included. The space is treated like a plus except after instructions when it is merely a separator. All input is accepted in lower or upper case and is folded (except for text.) If you are not in DDT, you can re-enter with a Meta-BREAK on a graphics or a restart at DDT (location typed out initially). In addition to program symbols, the following are also defined for you: R0-R5 are the user registers. R1/ would open register 1. SP is the user's stack pointer PC is the user's program counter $I is the user status $2I is the status of DDT $M is the mask for searches $Q is the value at the current address $V is the value at the current address with the bytes switched $nB is the address of breakpoint n JOBSA is the starting address of your program. AC0-AC5 are the FPU registers where $D$FPU was defined at assembly (Note however that instructions still print the symbols R0 through R5 instead of AC0-AC5.) FPAC0-FPAC5 are equivalent to AC0-AC5 FPSTAT is the FPU status register FPCTL controls FP save/restore. If 0, no save/restore of floating registers occurs. if nonzero, all FPU status is saved across calls. Initially the value of $D$FPU at assembly. FPFMT 2 bytes for number decimals and width fo FP print field D.PRCN is the precision of FP print conversions. It may be 2 or 4 for single precision or double precision outputs. RSXEXT IS RSX-11-M or -D EXIT$S call $$DOS is DOS-11 EXIT call DDTODD is DDT odd addr SST table entry (RSX DDT only) DDTIOT is DDT IOT table entry DDTTRP is TRAP entry DDTRES is RESERVED INST entry DDTEMT is non-RSX EMT entry D.FILV is number filled in by $Z command (initially 0) (TASK NAME) is start address of task BYE is equivalent to RSXEXT in RSX DDT DDTBGN is the start address of DDT itself In multi-task DDT, U.PSW and U.DSW are the target task's PSW and $DSW respectively. Then D.R0 thru D.PC are the DDT registers. MEMCTL is the control for memory breakpoints. MEMADR and MBPVAL are addresses and last seen values for watchpoints which are used if MEMCTL is nonzero. Note D.CT should be -1 and DDT should be in single step mode to use memory watchpoints. The $UZ command establishes those conditions. SR.CTL if 0 allows normal DDT mapping to arbitrary memory areas, and if 1 allows send/receive data directives to be used for communication with a target task (if MU$DBG defined only!) OVRBRK If present, may contain 0 or the address of a special breakpoint. If nonzero, then if a breakpoint occurs from the address in OVRBRK, only the data from OVRBRK will be restored with the original instruction. It is expected that a break at $ALBP2 will be used here (the autoload completion point) so breakpoints may be redefined after an overlay load. D.BMSK and D.BTST Used to support conditional breakpoints, in the following sense: if the D.BMSK array word corresponding to breakpoint number is nonzero, it is ANDed with the word opened at the breakpoint and if the result is different from the corresponding word in the D.BTST array (both are word arrays generally 9 words long), the breakpoint will be ignored. MT.BUF (ending at MT.TOP) is a buffer of PCs which records, circularly, the last "n" (usually 32) PCs at breakpoints or tracepoints. The MT.PTR word points to the last used. This array, used with a breakpoint and with a large proceed count on single stepping, can allow one to find where one gets to an illegal spot from. Some instruction mnemonics in DDT are nonstandard to reduce the size of the instruction database. The following are the nonstandard mnemonics and their standard counterparts: Nonstd Standard HLT HALT WAT WAIT RST RESET MK MARK FA FADD FS FSUB FM FMUL FD FDIV GD MFPD PD MTPD CC CFCC F SETF I SETI D SETD L SETL LS LDFPS SS STFPS S STST C CLRF T TSTF AB ABSF NG NEGF ML MULF MD MODF AD ADDF LD LDF SB SUBF CM CMPF ST STF DV DIVF SX STEXP SI STCFI SD STCFD LX LDEXP LI LDCFI LF LDCDF This completes the list of nonstandard DDT instruction mnemonics. PAR0 Is the current virtual memory APR 0. (PDR is always 4K R/W) PAR1 is the current virtual APR 1 PAR2 is current APR 2 PAR3 is current APR 3 PAR4 is current APR 4 (all these are in virtual ($UM) space PAR5 is current APR 5 PAR6 is current APR 6 PAR7 is current APR 7 (must be I/O page for this to work) Up to 160. user symbols (as presently defined) may be entered. . represents the current location. Thus .$1B puts breakpoint 1 at the currently opened location. When your program is executing, the following unexpected traps may occur. NXM! is caused when your program requests a non-existant memory or does a word operation on an odd address. ILG! is caused by an illegal instruction. BPT! is caused by an entry to DDT that is unexpected (i.e. executing the BPT instruction or setting the T-bit). Also TRP! means a TRAP, EMT! means an EMT was seen, and a few others indicate the type of trap. To include DDT with your task, just include on the input side of the taskbuild. thus, whn your normal TKB would be TKB MYFILE,MYFILE=MYFILE make it look like this: TKB MYFILE,MYFILE=MYFILE,[1,1]DDT/DA DDT will gain control at startup. To start your program, type G where you type the ESC key, not the 5 characters "". To exit prematurely, type BYEG (again the ESC key). Note that DDT does not prompt with anything! Also some terminals (like VT52, VT100) may not echo all escapes as $ because the terminal interprets the escape as part of an escape sequence. Even so, DDT will handle the command correctly. .ENDC .IIF NDF,MAXBK,MAXBK=20000 ;256K MAX CORE DEFAULT .PSECT ..DDT.,RW,I .PSECT ..DDTP,RO,I ;CODE ; MAIN LOOP OF DDT .IF DF,$$RT11 .GLOBL O.ODT O.ODT: .ENDC DDT: BR D.DDT3 ; HARD ENTRY ADDRESS TO DDT .IF NDF,$$RSX ; ;SAVE STATUS ONLY IF NOT MAPPED. .IF NDF,L$$SI MOV @#PS,D.USTA ; GET USER'S STATUS .IFF MFPS D.USTA .ENDC .ENDC MOV (SP)+,D.UR7 ; SOFT ENTRY ASSUMES STACK HAS RETURN ADDRESS JSR PC,D.SAVE ; SAVE REGISTERS BR D.DDT2 ; FINISH INITIALIZATION D.DDT3: .IF DF,$$RT11 MOV @#40,JOBSA ;SET UP PROGRAM START IN RT11 .ENDC .IF DF,$VMEM ;FOR VIRTUAL DDT ONLY... .IF NDF,X$MPP DD.SVV: MOV R1,-(SP) ;SAVE A REG MOV #UPAR0,R1 ;SET UP TO SAVE INITIAL MAP MOV R2,-(SP) ; MOV #VKPAR0,R2 ;ADDR OF SAVE AREAS FOR PARS MOV R3,-(SP) MOV #10,R3 ;NUMBER OF PARS 1$: MOV (R1),(R2) ;SAVE APR LISTS WITH INITIAL MAP MOV (R1)+,(R2)+ ;TWICE. BOTH MAPPINGS INITIALLY ALIKE. SOB R3,1$ ;DO ALL MOV (SP)+,R3 MOV (SP)+,R2 ;RESTORE REGS MOV (SP)+,R1 .ENDC .ENDC .IF NDF,$$RSX .IF NDF,L$$SI MOV @#PS,D.USTA ; SAVE USER'S STATUS .IFF MFPS D.USTA .ENDC .ENDC .IF DF,$$RSX ;RSX GET START ADDRESS JUNK MOV R0,JOBSA ;TKB STASHES START ADDR IN ENTRY R0 MOV R0,NMH+2 MOV R2,NMH MOV R1,NAMLO ;R1 HAS 1ST HALF OF TASK NAME MOV R2,NAMHI ;...AND R2 2ND HALF BNE 2$ MOV #-1,NAMLO ;IF ZERO FILL IN A NONZERO MOV #-1,NAMHI ;TO AVOID TRUNCATING SYM TBL 2$: .IF NDF,XTCOM .MCALL QIOW$S,ALUN$S ;ASSIGN LUNS .IF NDF,SM$FIL ALUN$S #D.INLU,#"TI,#0 ALUN$S #D.OUTU,#"TI,#0 ;TI: GETS BOTH ITS LUNS .IFF .MCALL FINIT$ FINIT$ ;SET UP FSR SPACE AT STARTUP .ENDC ;ATTACH TERMINAL TO PREVENT MCR NONSENSE IN -11M... .IF NDF,R.N.D. ;R.N.D ALLOWS TO RUN DETACHEC. .IIF DF,DOAT..,AT$$$=0 .IIF NDF,MU$DBG,AT$$$=0 .IF DF,AT$$$ .IF NDF,SM$FIL QIOW$S #IO.ATT,#D.INLU,#26.,,#III.II .IFF QIOW$S #IO.ATT,.ODTL1,#26.,,#III.II .ENDC BR III.IJ .PSECT ..DDTD III.II: .WORD 0,0;I/O STAT .PSECT ..DDTP,RO,I ;CODE III.IJ: .ENDC .ENDC .ENDC MOV #000,D.USTA ;SET USER STATUS, PRI 0 .ENDC .IF DF,MEM$TR MOV #MT.BUF,MT.PTR ;INITIALIZE POINTER .ENDC ;END SPECIAL RSX INITIALIZATION .IF DF,$$DOS ;DOS VERSION ONLY MOV @#40,-(SP) ;GET SVT ADD #22,@SP ;POINT TO PGM START ADDR MOV @(SP)+,JOBSA ;SAVE IN JOBSA .ENDC .IF NDF,$$RSX ;FOR RSX, WE USE SST VECTORS, NOT THIS MOV #D.NOSP,@#4 ; SET FOR INVALID STACK INTERRUPT MOV #340,@#6 ; SET HIGH STATUS MOV #D.ILGT,@#10 ; SET FOR ILLEGAL INSTRUCTIONS MOV #340,@#12 ; SET HIGH STATUS .ENDC .IF DF,$$RSX .MCALL SVDB$S,QIO$S,WTSE$S ;I/O TO TI: AND SST DEFINING SVDB$S #DDTODD,#11 ;SET UP SST'S .ENDC D.FIX0: MOV SP,D.XXX ; SAVE HIS STACK MOV #D.STK,SP ; USE OURS TEMPORARILY TST @D.XXX ; DOES HIS STACK EXIST? MOV D.XXX,SP ; GIVE HIM BACK HIS STACK D.FIX: .IIF NDF,$$RSX, MOV #D.NXMT,@#4 ; RESTORE FOR EXTERNAL NXMS MOV JOBSA,D.UR7 ; ASSUME HE CAME FROM STARTING ADDRESS JSR PC,D.SAVE ; SAVE REGISTERS .IF DF,D.GDP MOV #DDT+2,R0 ; ADDRESS OF RESTART FOR MONITOR TRAP 133 ; DDTCAL .ENDC CLRB D.NOTY ; ALLOW TYPEOUT MOV #D.GRET,R4 ; TELL YOU ARE HERE MOV #D.GRND,R3 ; END OF MESSAGE JSR PC,D.STYP ; TYPE MESSAGE .IF NDF,D.GDP .IF NDF,$$RSX MOV #DDT,R0 ; ADDRESS OF RESTART JSR PC,D.TYPN ; TYPE RESTART ADDRESS .ENDC .ENDC D.DDT2: JSR PC,D.CRLF ; TYPE CARRIAGE RETURN-LINE FEED CLR D.SD.T ; NOT IN SINGLE STEP OR TRACE MOVB #-1,D.P ; DISALLOW PROCEDE .IF NDF,X$QRG BR D.DCD0 ; GET INTO MAIN LOOP .IFF D.DDT4: JSR PC,D.DCD BR D.DDT4 ; EXECUTE COMMAND AND LOOP .ENDC D.ERSG: ADD #6,SP ;PASS SST SR0 TO SR2 DATA D.ERR: .IF DF,ER$SV ; FOR DEBUGGING DDT... MOV (SP),D.ERPC ;SAVE PC AND REGS MOV R0,D.ERR0 MOV #D.ERR0+2,R0 MOV R1,(R0)+ MOV R2,(R0)+ MOV R3,(R0)+ MOV R4,(R0)+ MOV R5,(R0)+ MOV SP,(R0) .ENDC MOV #' ,R0 ; TYPE A SPACE .IIF DF,D.MCRO, CLR D.CHSW ;USE CONSOLE INPUT IF ERROR. JSR PC,D.TYPE MOV #'?,R0 ; ? TO BE TYPED D.ERRO: JSR PC,D.TYPE ; TYPE CHARACTER D.DCD: .IF DF,X$QRR CMPB D.CPOS,#D.CNUM ; NO TAB IF AT BEGINNING OF LINE BEQ D.DCD0 .ENDC JSR PC,D.TTAB ; TYPE TAB D.DCD0: CLR D.COMA ; NO , PARAMETER. RETURN FROM HCTSAR> CLRB D.FWAF ; NO < PARAMETER .IF NDF,$$RSX .IF NDF,L$$SI MOV D.DSTA,@#PS ; SET DDT STATUS .IFF MTPS D.DSTA .ENDC .ENDC MOV #NOP,D.PARS ; FILL $X AREA WITH NOPS MOV #NOP,D.PARS+2 ; IN CASE OF SHORT INSTRUCTIONS CLR D.PARO ; NO OFFSET CLR D.PARO+2 ; NO OFFSET D.DCD2: CLR D.SVR2 ; RETURN FROM ,< CLR D.SVR4 ; D.SVR4 IS A SAVE REGISTER FOR R4 CLR D.OFST ; TALLY CLR R2 ; NUMBER TYPED FLAG D.DCD3: CLRB D.ALTF ; RETURN FROM B"MVQI D.DCD1: CLRB D.LEVL ; RETURN FROM $ CLRB D.INPA ; NOT IN INSTRUCTION TYPE-IN MOV D.CAD,D.CADC ; KEEP A CURRENT COPY FOR INST TYPE-IN MOV #D.STK,SP ; RESET STACK POINTER JSR PC,D.EXPR ; GET EXPRESSION (R2,R4,R1) TST R2 ; NEED OPERANDS FOR INSTRUCTION? BPL D.DCD4 ; BRANCH IF NOT JSR PC,D.GETI ; GET OPERANDS D.DCD4: TST R2 ; ANY VALUE TYPED? BEQ D.DCD5 ; BRANCH IF NOT MOV R4,D.LASV ; STORE LAST TYPED VALUE MOV R4,D.LASW ; STORE LAST TYPED WORD TOO D.DCD5: ASL R1 ; MULTIPLY BY TWO JSR PC,@D.LGDR(R1) ; GO TO PROPER ROUTINE .IF NDF,X$QRG BR D.DCD ; GET NEXT COMMAND .IFF CMP #D.STK,SP ;ZERO STACK? BEQ D.DDT4 ;YES, SETUP STD CALL LOOP RTS PC .ENDC D.NOSP: MOV #D.STK,SP ; SET OWN STACK PERMANENTLY FOR USER BR D.FIX ; RETURN ; ROUTINE TO GET A PRIMARY INTO R1 (COMMAND DECODER) D.PRIM: ; PRIMARY READING SUBROUTINE CLR R4 ; R4 CONTAINS THE CONVERTED OCTAL CLR D.DECN ; CLEAR DECIMAL NUMBER CLRB D.USED ; CLEAR USE-DECIMAL NUMBER INDICATOR JSR PC,D.CLSM ; CLEAR SYMBOL D.PRI1: JSR PC,D.GET ; GET A CHAR, RETURN IN R0 CMP #'0,R0 ; COMPARE WITH ASCII 0 BHI D.PRI3 ; CHECK LEGALITY IF NON-NUMERIC CMP #'9,R0 ; COMPARE WITH ASCII 9 BLO D.PRI3 ; CHECK LEGALITY IF NOT OCTAL CMP D.POS,#D.SYM ; IN THE MIDDLE OF A SYMBOL? BNE D.PRI6 ; YES, PUT DIGIT IN SYMBOL SUB #'0,R0 ; CONVERT TO BCD ASL R4 ; MAKE ROOM ASL R4 ; IN ASL R4 ; R4 ADD R0,R4 ; PACK THREE BITS IN R4 MOV D.DECN,R1 ; GET DECIMAL NUMBER ASL R1 ; MULTIPLY BY 2 ADD R1,R0 ; ADD 2X ASL R1 ; MULTIPLY BY 4 ASL R1 ; MULTIPLY BY 8 ADD R0,R1 ; ADD IN NEW DIGIT MOV R1,D.DECN ; STORE IN DECIMAL NUMBER INC R2 ; R2 HAS NUMERIC FLAG BR D.PRI1 ; AND TRY AGAIN D.PRI2: MOV #'U,R0 ; UNDEFINED MESSAGE .IIF DF,D.MCRO, CLR D.CHSW ;USE CONSOLE INPUT IF ERROR. BR D.ERRO ; ERROR OUTPUT D.PRI3: CMPB R0,#'. ; DOT FOUND? BEQ D.PRI7 ; BRANCH IF SO CLR R1 ; BASE OF CHARACTER TABLE D.PRI4: CMPB D.LGCH(R1),R0 ; MATCH? BEQ D.PRI5 ; YES INC R1 ; NEXT CHARACTER CMP R1,#D.CLGT ; ANY MORE? BLT D.PRI4 ; LOOP IF SO D.PRI6: TST R4 ; NUMBER ALREADY? BEQ 1$ JMP D.ERR ; ERROR TO START SYMBOL 1$: JSR PC,D.PTSM ; PUT SYMBOL IN D.SYM BR D.PRI1 ; DECODE MORE CHARACTERS D.PRI7: TST R4 ; NUMBER BEING TYPED? BEQ D.PRI6 ; BRANCH IF NOT INCB D.USED ; IT IS, MAKE IT DECIMAL BR D.PRI1 ; CONTINUE SCANNING D.PRI5: TSTB D.ALTF ; ALTMODE FOUND? BNE D.PRI8 ; YES, DO IT CMP R1,#D.LETR ; IS IT A LETTER? BGE D.PRI6 ; YES D.PRI8: CMPB #' ,D.SYM ; ANY SYMBOL? BEQ D.PRIB ; NO, RETURN CMP #". ,D.SYM ; IS SYMBOL A DOT? BNE D.PRI9 ; BRANCH IF NOT MOV D.DOT,R4 ; USE VALUE OF D.DOT INC R2 ; NOTE THAT IT IS A NUMBER BR D.PRIB ; DO THE REST D.PRI9: MOV #D.SYM,R0 ; ADDRESS OF SYMBOL JSR PC,D.GTAD ; GET ADDRESS CMP R1,#D.COLO ; COLON? BEQ D.PRIC ; RETURN IF SO TST R0 ; CHECK SYMBOL ADDRESS BEQ D.PRID ; BRANCH IF NOT AN ADDRESS MOV (R0),R4 ; GET SYMBOL VALUE D.PRIA: INC R2 ; MARK R2 AS A NUMBER D.PRIB: TSTB D.USED ; USE DECIMAL NUMBER? BEQ D.PRIC ; BRANCH IF NOT MOV D.DECN,R4 ; USE DECIMAL NUMBER D.PRIC: RTS PC ; RETURN D.PRID: MOV #D.COUS,R0 ; ADDRESS OF OFFSET TABLE D.PRIE: CMP R0,#D.ECNT ; END OF LIST? BHIS D.PRI2 ; YES, LOSE MOV #D.SYM,R5 ; SCAN THE SYMBOL MOV (R0)+,R3 ; GET OFFSET OF CHARACTERS BIC #177400,R3 ; TURN OFF EXTRA CRUFT CMPB R3,(R0) ; NULL STRING? BEQ D.PRIE ; YES, IGNORE IT D.PRIF: CMPB D.STRS(R3),(R5)+; IS IT A CHARACTER MATCH? BNE D.PRIE ; BRANCH IF NOT INC R3 ; NEXT CHARACTER CMPB R3,(R0) ; END OF STRING? BNE D.PRIF ; BRANCH IF NOT MOV D.TOPS-D.COUS-2(R0),R4 ;GET THE INSTRUCTION-1 MOVB -1(R0),R3 ; GET LEGALITY BYTE CMPB R3,#10 ; IS IT A CONDITION CODE SET/CLEAR? BEQ D.PRIK ; MAY BE INC R4 ; FIX INSTRUCTION D.PRIG: CMPB #' ,(R5) ; BLANK AT END OF SYMBOL? BNE D.PRII ; NO, HOW ABOUT "B"? BIC #177774,R3 ; STRIP TO MACHINE TYPE CMPB R3,D.MACH ; VALID ON THIS MACHINE? BGT D.PRI2 ; UNDEFINED SYMBOL D.PRIH: MOVB -(R0),R3 ; RE-FETCH LEGALITY BYTE CMP R1,#D.SPAC ; IS INSTRUCTION TERMINATED WITH SPACE? BNE D.PRIA ; DON'T GET OPERANDS IF NOT MOV #-2,R2 ; MARK INSTRUCTION BR D.PRIA ; ALL DONE D.PRII: CMPB #'B,(R5)+ ; BYTE INSTRUCTION MUST TERMINATE WITH "B" BNE D.PRIE ; NOT AN INSTRUCTION TSTB R3 ; TEST LEGALITY BYTE BPL D.PRIE ; NO ADD #100000,R4 ; ADD IN BYTE OFFSET BCC D.PRIG ; AND CONTINUE, UNLESS THAT WAS A SECOND "B" BR D.PRIE ; IN WHICH CASE WE LOSE D.PRIJ: BITB (SP),R4 ; BIT ALREADY ON? BNE D.PRIN ; YES, LOSE BISB (SP),R4 ; SET IT CMPB (SP)+,(R5)+ ; BUMP SP BY 2, R5 BY 1 CMPB #' ,(R5) ; SPACE YET? BEQ D.PRIH ; YES, ALL DONE. D.PRIK: MOVB #10,-(SP) ; SET UP MAGIC BIT MOV #D.NZVC+4,R3 ; CHARACTER POINTER D.PRIL: CMPB (R5),-(R3) ; MATCH? BEQ D.PRIJ ; BRANCH IF SO ASRB (SP) ; MOVE BIT BNE D.PRIL ; AND LOOP D.PRIN: TSTB (SP)+ BR D.PRIE ; ELSE NOT THE RIGHT INSTRUCTION .IIF DF,SM$FIL,SM$FL=0 ; ROUTINES TO HANDLE THE SYMBOL TABLE D.GTAD: .IF DF,U$ID.!MPV2. MOV UV$SPF,-(SP) MOV #140000,UV$SPF .ENDC MOV R0,-(SP) ; SAVE CHARACTER ADDRESS .IIF DF,$VMEM, MOV PARMAP,-(SP) ;NO VIRTUAL MAP HERE .IIF DF,$VMEM, CLR PARMAP JSR PC,D.RD50 ; CONVERT FIRST 3 TO RAD50 MOV R0,D.RAD1 ; SAVE VALUE .IIF DF,$VMEM,MOV (SP)+,PARMAP MOV (SP)+,R0 ; GET CHARACTER ADDRESS ADD #3,R0 ; POINT TO LAST 3 CHARACTERS .IIF DF,$VMEM, MOV PARMAP,-(SP) ;NO VIRTUAL MAP HERE .IIF DF,$VMEM, CLR PARMAP JSR PC,D.RD50 ; CONVERT TO RAD50 .IIF DF,$VMEM,MOV (SP)+,PARMAP .IF DF,U$ID.!MPV2. MOV (SP)+,UV$SPF .ENDC MOV R0,D.RAD2 ; STORE IT AWAY D.GTAC: MOV #D.SYMA-2,R0 ; ADDRESS OF SYMBOL TABLE .IF DF,SM$FL MOV D.RAD1,SYMR50 MOV D.RAD2,SYMR51 ; COPY RAD50 FOR .STB FILE LOOKUP .ENDC D.GTA2: TST (R0)+ ; BUMP R0 BY 2 CMP (R0)+,(R0) ; BUMP R0 BY 2 MORE, CHECK IF END OF TABLE BNE D.GTA6 TST (R0) ; WERE BOTH SYMBOL HALVES 0? BNE D.GTA6 ; NO, KEEP LOOKING .IF DF,SM$FL .IF DF,$VMEM MOV PARMAP,-(SP) CLR PARMAP ; BE SURE NO MAPPING NONSENSE NOW... .ENDC .IF DF,U$ID.!MPV2. MOV UV$SPF,-(SP) MOV #140000,UV$SPF .ENDC CMP D.RAD1,#-1 BEQ 1$ ; NO LOOKUP FOR NEW SYMBOL CELLS TST D.RAD1 BEQ 1$ TST STBFDB BEQ 1$ ; IF ANY STB FILE EXISTS... JSR PC,SYMLOC ; LOOK IN .STB FILE IF OPEN BCS 1$ ; IF CARRY RETURNS WE DIDN'T SEE IT .IIF DF,U$ID.!MPV2., MOV (SP)+,UV$SPF .IIF DF,$VMEM, MOV (SP)+,PARMAP ; SYMLOC RETURNS ADDRESS OF VALUE. HOWEVER, RETURN ADDRESS IN DDT TABLE HERE. MOV @R0,-(SP) ; SAVE ADDRESS ON STACK A MOMENT MOV .SYMPT,R0 ; GET SYMBOL POINTER MOV D.RAD1,(R0)+ ; CACHE NEW SYMBOL MOV D.RAD2,(R0)+ MOV (SP),(R0)+ ; SAVE ADDRESS TOO MOV R0,(SP) ; SAVE SYMBOL TBL ADDRESS SUB #2,(SP) ; ADJUSTED CMP R0,#.SYMND ; PAST END OF CACHE AREA BLO 4$ ; IF NOT SKIP MOV #.SYMBG,R0 ; ELSE LOOK AT START ;X$CACH REMOVES CACHE OF SYMBOLS FROM .STB FILE. NORMALLY NOT EVER ;DEFINED. .IF NDF,X$CACH 4$: MOV R0,.SYMPT ; UPDATE POINTER .IFF 4$: .ENDC MOV (SP)+,R0 ; RETURN SYM TBL POINTER RTS PC ; ELSE R0 RETURNS ADDRESS. 1$: .IIF DF,U$ID.!MPV2., MOV (SP)+,UV$SPF .IIF DF,$VMEM, MOV (SP)+,PARMAP .ENDC CLR R0 ; NOT FOUND...MARK RETURN REGISTER RTS PC ; RETURN D.GTA6: CMP D.RAD2,(R0)+ ; DO SECOND THREE CHARACTERS MATCH? BNE D.GTA2 ; NO, GO TO NEXT SYMBOL CMP -4(R0),D.RAD1 ; YES, HOW ABOUT THE FIRST THREE? BNE D.GTA2 ; NO, GO TO NEXT SYMBOL RTS PC ; RETURN .IF NDF,SM$FL D.GTSM: CLR -(SP) ; SPACE FOR TEMPORARIES .IFF D.GTSM: JSR PC,D.GTSN ; GET SYMBOL OUT OF LOCAL SYM TBL IF THERE TST R1 ; GOT A SYMBOL? BNE 100$ ; IF SO USE THAT ONE... .IF DF,$VMEM MOV PARMAP,-(SP) ; ELSE LOOK LOCALLY FOR .STB FILE STUFF CLR PARMAP ; (NO MAPPING STUFF FOR HERE...) .ENDC .IF DF,U$ID.!MPV2. MOV UV$SPF,-(SP) MOV #140000,UV$SPF .ENDC MOV R3,-(SP) MOV R0,-(SP) MOV R0,R3 ; LOOK UP SYMBOL IN .STB FILE IF THERE TST STBFDB BEQ 101$ ;ENSURE AN FDB THERE OR SKIP IT .IF DF,S..MS. CMP R3,#377 ; IS VALUE FOR SYMBOL VERY SMALL? BLOS 101$ ;IF SO DON'T TRY A LOOKUP .ENDC JSR PC,HUNTSM ; DIG IT OUT BCS 101$ ; IF CS NO FILE MOV (SP)+,R0 MOV (SP)+,R3 TST .STBSM ;GOT A SYMBOL? BEQ 104$ ; NO, NO COPY ;KEEP A CACHE OF SYMBOLS OUT OF THE .STB FILE IN MEMORY TO SPEED ;UP LOOKUPS. CACHE LENGTH IS CONSTANT AND A NEW SYMBOL WILL ;OVERWRITE THE OLDEST LAST-USED ONE. SYMBOLS ALWAYS LOOK ALLOCATED ;TO THE NORMAL SYMBOL ROUTINES BUT AT ADDRESS 0 TILL USED. ; UNFORTUNATELY, THEY MAY BE KILLED, BUT THAT'LL BE JUST TOO ;BAD... CMP .STBSM,#-1 ; IS IT THE "NULL" SYMBOL? BEQ 104$ ; IF SO ALSO IGNORE... MOV R0,-(SP) MOV .SYMPT,R0 ; GET CURRENT SYMBOL START BEQ 143$ ;(AVOID ERRORS) MOV .STBSM,(R0)+ ;SAVE SYMBOL IN CACHE MOV .STBSM+2,(R0)+ MOV .STBSM+4,(R0)+ CMP R0,#.SYMND ;AT END OF STB CACHE AREA? BLO 102$ ;NO, BRANCH MOV #.SYMBG,R0 ;YES, RESET TO START 102$: MOV R0,.SYMPT ;SET TO FILL IN NEXT MOV (SP)+,R0 JSR PC,D.GTSN ; THEN LOOK AGAIN. PRINT IF OK. BR 104$ 101$: MOV (SP)+,R0 MOV (SP)+,R3 BR 104$ 143$: MOV (SP)+,R0 ;ERROR PATH... SHOULDN'T EVER BE USED 104$: .IIF DF, U$ID.!MPV2., MOV (SP)+,UV$SPF ;RESTORE I/D FLAGGING .IIF DF, $VMEM, MOV (SP)+,PARMAP ; RESTORE EXPECTED MAPPING 100$: RTS PC D.GTSN: CLR -(SP) ; SPACE FOR TEMPORARIES .ENDC MOV D.FENC,R2 ; FIND CLOSEST SYMBOL <= R0 MOV D.RFNL,R1 ; WHICH IS ALSO >= R0-D.RFNL D.GTS1: CMP (R2)+,(R2)+ ; SKIP OVER THE NAME BEQ D.GTS3 D.GTS2: MOV R0,R3 ; SET A TEMPORARY SUB (R2)+,R3 ; OBTAIN DIFERENCE BLO D.GTS1 ; IF SYMBOL HIGHER THAN R0, NO GO SUB R1,R3 ; ARE WE CLOSER THAN BEFORE? BHI D.GTS1 ; NO, FURTHER MOV R2,(SP) ; SAVE POINTER TO SYMBOL ADD R3,R1 ; SAVE DIFFERENCE BR D.GTS1 ; AND LOOK FOR ONE CLOSER D.GTS3: TST -2(R2) ; AT END OF TABLE? BNE D.GTS2 ; NO, KEEP GOING MOV (SP)+,R1 ; GET SYMBOL PTR BEQ D.GTS4 ; BRANCH IF NOT FOUND. CMP -(R1),#400 ; IGNORE SMALL SYMBOLS BLO D.GTS4 SUB (R1),R0 ; RECOMPUTE DIFFERENCE .IF DF,U$ID.!MPV2. MOV UV$SPF,-(SP) MOV #140000,UV$SPF .ENDC MOV R0,-(SP) ; SAVE DIFFERENCE MOV -(R1),-(SP) ; GET LAST THREE CHARACTERS MOV -(R1),R0 ; GET FIRST THREE MOV #D.SYM,R1 ; ADDRESS TO PUT CHARACTERS .IIF DF,$VMEM, MOV PARMAP,-(SP) ;NO VIRTUAL MAP HERE .IIF DF,$VMEM, CLR PARMAP JSR PC,D.CHAR ; CONVERT TO ASCII .IIF DF,$VMEM,MOV (SP)+,PARMAP MOV (SP)+,R0 ; GET FIRST RAD50 WORD .IIF DF,$VMEM, MOV PARMAP,-(SP) ;NO VIRTUAL MAP HERE .IIF DF,$VMEM, CLR PARMAP JSR PC,D.CHAR ; CONVERT TO ASCII .IIF DF,$VMEM,MOV (SP)+,PARMAP MOV (SP)+,R0 ; RESTORE DIFFERENCE .IIF DF,U$ID.!MPV2., MOV (SP)+,UV$SPF MOV #D.SYM,R1 ; POINT TO CHARACTERS RTS PC ; RETURN D.GTS4: CLR R1 ; NOT FOUND...MARK IT SO RTS PC ; RETURN ; ROUTINE TO GET AN EXPRESSION (VALUE IN R4, FLAG IN R2, TERMINATOR IN R1) D.CEXP: INCB D.INPA ; NOT IN INSTRUCTION CLR D.OFST ; START OUT FRESH D.EXPR: MOV #D.ADD,D.OPER ; INITIAL FUNCTION D.EXP7: JSR PC,D.PRIM ; GET PRIMARY EXPRESSION TST R2 ; INSTRUCTION? BMI D.EXP1 ; EXIT IF SO CMP R1,#D.OPAR ; OPEN PARENTHESIS OR OPERATOR? BLT D.EXP1 ; BRANCH IF NEITHER BEQ D.EXP2 ; BRANCH IF OPEN PARENTHESIS CMP R1,#D.CPAR ; CLOSE PARENTHESIS OR OPERATOR? BLT D.EXP3 ; BRANCH IF OPERATOR BEQ D.EXP4 ; BRANCH IF CLOSE PARENTHESIS D.EXP1: TSTB D.LEVL ; TERMINATOR FOUND...AT UPPER LEVEL? BEQ D.EXP5 ; BRANCH IF SO BR D.ERRD ; ERROR D.EXP2: TSTB D.INPA ; IN AN INSTRUCTION TYPE-IN? BNE D.EXP5 ; BRANCH IF SO (INSTRUCTION FORMAT) INCB D.LEVL ; GO DOWN TO NEXT PARENTHESIS LEVEL MOV D.OFST,-(SP) ; SAVE TALLY MOV D.OPER,-(SP) ; SAVE OPERATION CLR D.OFST ; CLEAR TALLY JSR PC,D.EXPR ; RECURSION! MOV (SP)+,D.OPER ; RESTORE OPERATION MOV (SP)+,D.OFST ; RESTORE TALLY JSR PC,@D.OPER ; COMBINE THEM BR D.EXPR ; LOOP D.EXP4: DECB D.LEVL ; UP TO HIGHER PARENTHESIS LEVEL BMI D.ERRD ; ERROR IF NONE HIGHER D.EXP5: JSR PC,@D.OPER ; DO OPERATION MOV D.OFST,R4 ; GET TALLY AS RETURN PARAMETER RTS PC ; RETURN (POSSIBLY TO SELF) D.EXP3: JSR PC,@D.OPER ; DO OPERATION ASL R1 ; AND GET MOV D.LGDR(R1),D.OPER ; THE NEXT BR D.EXP7 ; LOOP ; ROUTINE TO HANDLE PARAMETERS FOR INSTRUCTION TYPE-IN D.GETI: ASR R3 ; PARAMETER CODE BIC #177741,R3 ; MASK OUT OTHER BITS MOV R4,-(SP) ; SAVE OPERATION MASK JSR PC,@D.PARG(R3) ; GET PARAMETERS BIS (SP)+,R4 ; PUT OPERATION MASK INTO OPERANDS MOV #1,R2 ; MARK A GOOD NUMBER RTS PC ; RETURN D.GR: JSR PC,D.PRIM ; GET PRIMARY D.REDR: SUB U.R0,R4 ; GET REGISTER ADDRESS ASR R4 ; MAKE INTEGER FROM ADDRESS BIT #177770,R4 ; ANY HIGH BITS ON? BNE D.ERRD ; ERROR IF NOT A REGISTER D.NONE: RTS PC ; RETURN D.GGET: MOV R0,-(SP) ; SAVE WHAT MUST BE READ D.GGE2: JSR PC,D.GET ; GET LETTER CMP R0,(SP) ; EQUAL? BEQ D.GGE1 ; YES, RETURN D.ERRD: JMP D.ERR ; ERROR D.GGE1: TST (SP)+ ; FIX STACK RTS PC ; RETURN D.PSAV: MOV (SP),-(SP) ; PUSH RETURN ADDRESS DOWN SWAB R4 ; MOVE ASR R4 ; TO ASR R4 ; HIGH POSITION MOV R4,2(SP) ; PUT PARAMETERS IN CMP R1,#D.COMM ; COMMA IN-BETWEEN? BNE D.ERRD ; ERROR IF NOT RTS PC ; RETURN D.DISP: JSR PC,D.CEXP ; GET EXPRESSION SUB D.DOT,R4 ; COMPUTE OFFSET ASR R4 ; SHIFT DEC R4 ; POINTS TO PROPER WORD BIC #177400,R4 ; CLEAR HIGH BITS RTS PC ; RETURN D.GRNN: JSR PC,D.GR ; GET REGISTER JSR PC,D.PSAV ; SAVE PARAMETERS JSR PC,D.DISP ; GET ADDRESS NEG R4 ;;;GCE;;; NEGATE FOR SOB! BIC #177700,R4 ; REDUCE TO 6-BITS D.GGE3: BIS (SP)+,R4 ; ADD IN REGISTER RTS PC ; RETURN D.GSD: JSR PC,D.GDD ; GET 6-BIT OPERAND D.GGE4: JSR PC,D.PSAV ; SAVE PARAMETER JSR PC,D.GDD ; GET OTHER PARAMETER BR D.GGE3 ; DO THE REST D.GR2: JSR PC,D.GR ;GET REG BIC #4,R4 ;MASK REG TO R0-R3 RANGE (SHOULD BE F0-F3) BR D.GGE4 D.GRSS: JSR PC,D.GR ; GET REGISTER BR D.GGE4 ; DO THE REST D.GRS2: JSR PC,D.GDD ;GET 6 BIT OPERAND MOV R4,-(SP) ;SAVE IT JSR PC,D.GR ;GET REGISTER BIC #4,R4 ;MASK TO RANGE 0-3 SWAB R4 ASR R4 ASR R4 BR D.GGE3 D.GDDR: JSR PC,D.GDD ; GET 6-BIT-OPERAND MOV R4,-(SP) ; SAVE OPERAND JSR PC,D.GR ; GET REGISTER SWAB R4 ; SHIFT ASR R4 ; INTO ASR R4 ; HIGH PLACE BR D.GGE3 ; DO THE REST D.NEXP: MOV D.CADC,R0 ; GET CAD COPY TST (R0)+ ; BUMP TO NEXT MOV R0,D.CADC ; RESTORE NEW VALUE TST (R0)+ ; INCREMENT AGAIN RTS PC ; RETURN D.GDD: CLR R2 ; NO PARAMETERS YET JSR PC,D.CEXP ; GET EXPRESSION CMP R1,#D.OPAR ; OPEN PARENTHESIS? BEQ D.G02 ; BRANCH IF SO CMP R1,#D.HASH ; HASH MARK? BEQ D.G05 ; BRANCH IF SO BLO D.G03 ; BRANCH IF AT-SIGN ;NOTE THAT U.R0 AND U.PC ARE USED SINCE M/T DDT MAY CHANGE THEM... ;THEY ARE HOWEVER SYMBOLS R0-SP,PC ... CMP R4,U.R0 ; REGISTER? BLO D.NOTR ; BRANCH IF NOT CMP R4,U.PC ; REGISTER? BHI D.NOTR ; BRANCH IF NOT SUB U.R0,R4 ; NORMALIZE ASR R4 RTS PC ; RETURN D.NOTR: JSR PC,D.NEXP ; POINT TO NEXT PARAMETER MOV R0,-(SP) ; SAVE RELOCATION SUB D.CAD,R0 ; GET PARAMETER OFFSET MOV (SP)+,D.PARO-4(R0) ; PUT IN OFFSET MOV R4,D.PARS-4(R0) ; PUT VALUE IN MOV #67,R4 ; RELATIVE PC ADDRESSING RTS PC ; DONE D.G05: JSR PC,D.CEXP ; GET EXPRESSION D.G014: JSR PC,D.NEXP ; NEXT PARAMETER SUB D.CAD,R0 ; GET PARAMETER OFFSET CLR D.PARO-4(R0) ; NO RELOCATION MOV R4,D.PARS-4(R0) ; PUT VALUE IN MOV #27,R4 ; IMMEDIATE ADDRESSING RTS PC ; RETURN D.G02: TST R2 ; "(" FOUND, ANY OFFSET? BNE D.G013 ; BRANCH IF SO (INDEX ADDRESSING) CMP D.OPER,#D.SUBT ; "-(R)" ? BNE D.G016 ; BRANCH IF NOT JSR PC,D.GR ; GET REGISTER ADD #40,R4 ; ADD IN AUTO-DECR OFFSET BR D.G09 ; SKIP TO COMMAND AND RETURN D.G016: JSR PC,D.GR ; GET REGISTER..."(R)" OR "(R)+" JSR PC,D.G09 ; SKIP TO NEXT PARAMETER CMP R1,#D.ADDS ; PLUS SIGN? BNE D.G012 ; BRANCH IF NOT ADD #20,R4 ; ADD IN AUTO-INCR OFFSET BR D.G09 ; SKIP TO COMMAND AND RETURN D.G013: JSR PC,D.G014 ; PUT PARAMETER IN JSR PC,D.GR ; GET REGISTER ADD #60,R4 ; ADD IN INDEX OFFSET BR D.G09 ; SKIP TO COMMAND AND RETURN D.G03: CLR R2 ; "@" FOUND, MARK NO NUMBER FOUND YET JSR PC,D.CEXP ; AN "@" WAS FOUND, LOOK TO NEXT CMP R1,#D.HASH ; "@#" MEANS ABSOLUTE ADDRESSING BEQ D.G06 ; BRANCH IF SO CMP R1,#D.OPAR ; COULD BE "@(" OR "@X(" BEQ D.G07 ; BRANCH IF EITHER CMP R4,U.R0 ; IS IT @R? BLO D.G08 ; BRANCH IF NOT CMP R4,U.PC ; TEST UPPER RANGE BHI D.G08 ; BRANCH IF NOT JSR PC,D.REDR ; REDUCE TO REGISTER NUMBER D.G012: ADD #10,R4 ; ADD IN REG-DEFERRED OFFSET RTS PC ; THATS ALL...RETURN D.G08: JSR PC,D.NOTR ; PERFORM NORMAL RELOCATION MOV #77,R4 ; MARK RELATIVE DEFERRED ADDRESSING RTS PC ; RETURN D.G07: TST R2 ; ANY NUMBER THERE? BEQ D.G010 ; BRANCH IF "@(" JSR PC,D.G014 ; GET OFFSET INTO PARAMETER JSR PC,D.GR ; NOW GET REGISTER ADD #70,R4 ; ADD IN INDEX DEFERRED OFFSET D.G09: MOV R4,-(SP) ; SAVE VALUE JSR PC,D.PRIM ; SKIP TO NEXT COMMAND MOV (SP)+,R4 ; RESTORE VALUE RTS PC ; RETURN D.G010: CMP D.OPER,#D.SUBT ; "@-(" ? BNE D.G015 ; BRANCH IF NOT JSR PC,D.GR ; GET REGISTER ADD #50,R4 ; ADD IN AUTO-DECR DEFERRED OFFSET BR D.G09 ; SKIP TO COMMAND AND RETURN D.G015: JSR PC,D.GR ; GET REGISTER MOV #'+,R0 ; FORM IS "@(R)+" JSR PC,D.GGET ; GET THE PLUS ADD #30,R4 ; ADD IN AUTO-INCR DEFERRED OFFSET BR D.G09 ; SKIP TO COMMAND AND RETURN D.G06: JSR PC,D.G05 ; GET ABSOLUTE ADDRESS MOV #37,R4 ; MARK ABSOLUTE MODE RTS PC ; DONE D.GNUM: JMP D.PRIM ; GET NUMBER AND RETURN ; SYMBOL MANIPULATION SUBROUTINES D.PTSM: MOV D.POS,R1 ; GET POSITION ADDRESS CMP R1,#D.SYM+D.SYML; NO MORE ROOM? BHIS D.PTS1 ; EXIT IF SO MOVB R0,(R1)+ ; PUT CHARACTER IN MOV R1,D.POS ; RESTORE POINTER D.PTS1: RTS PC ; RETURN D.CLSM: MOV #D.SYM+D.SYML,R0 D.CLS3: MOVB #' ,-(R0) CMP R0,#D.SYM BHI D.CLS3 MOV R0,D.POS RTS PC ; RETURN ; ADDITION, SUBTRACTION, MULTIPLICATION, DIVISION FOR DECODER D.ADD: ADD R4,D.OFST ; ADD OPERANDS RTS PC ; RETURN D.SUBT: SUB R4,D.OFST ; SUBTRACT OPERANDS RTS PC ; RETURN D.MULT: CLR R0 ; MULTIPLY THEM MOV #16.,-(SP) ; LOOPER D.MUL1: ASR R4 ; GET BOTTOM BIT BCC D.MUL2 ; SKIP IF OFF ADD D.OFST,R0 ; ADD IN OPERAND D.MUL2: ASL D.OFST ; SHIFT OPERAND DEC (SP) ; MORE TO LOOP? BGT D.MUL1 ; LOOP IF SO MOV R0,D.OFST ; RESULT IN D.OFST TST (SP)+ ; FIX STACK RTS PC ; RETURN D.DIV: MOV R1,-(SP) ; SAVE R1 MOV D.OFST,R0 ; GET OPERAND MOV R4,R2 ; GET OTHER OPERAND JSR PC,D.DIVD ; DIVIDE THEM MOV R0,D.OFST ; GET RESULT MOV (SP)+,R1 ; RESTORE R1 RTS PC ; RETURN .IF DF,D.MCRO D.UE: MOV #1,D.ECSW ;UE TURN ON MACRO ECHO MODE RTS PC D.UN: CLR D.ECSW ;UN TURN OFF MACRO ECHO MODE RTS PC ; UC PROCESSING -- TURN ON CORE PSEUDO INPUT D.UDAT: MOV #1,D.CHSW ;SET CORE INPUT MODE MOV #<33*400+33>,D.KBFE-2 ;PUT IN ALTMODES AT BUF END MOV #-1,D.KBFE ;AND GUARANTEE A FENCE RTS PC ; US PROCESSING -- TURN OFF CORE INPUT MODE (USE STANDARD INPUT) D.UKOT: CLR D.CHSW RTS PC .ENDC .IF DF,$VMEM ;VIRTUAL DDT ONLY... ; UV USE VIRTUAL MAP UNALTERED O.VVIR: CLR PARMAP .IIF DF, U$ID.!MPV2., MOV UV$SPF,UV$SPS .IIF DF, U$ID.!MPV2., MOV R2,UV$SPF ;SAVE FLAG OF WHICH SPACE TO SEE. RTS PC ;FORGET MAPPING ; .IF DF,$DDBSX ;IF BSX HOOK FOR READING TCB STATES... ; ; UP SET UP PROGRAM STATUS FROM TCB ENTRY IN BSX ; ( ADDR$UP WHERE ADDR = BSX TCB ADDRESS) ; ; UP SET UP REGS AND VIRTUAL APR'S FROM AN AREA OF MEMORY ; POINTED TO BY ADDRESS IN ADDR$UP. NOTE THAT ALL PARS ARE ; SET UP AS ARE REGS 0-7 IN SAVE AREA. THE SAVE AREA FORMAT ;EXPECTED IS APR0 THROUGH APR7 FIRST, THEN R5 THROUGH R0. THE SP ;IS EXPECTED AT ADDRESS TCBDSP AND THE SAVE AREA AT TCBREG RELATIVE ;TO THE GIVEN ADDRESS. ; O.PVIR: JSR R5,S.RSAV SUB #40,SP ;GET A SAVE AREA ON THE STACK MOV SP,R5 ;R5 INDEXES IT (ALLOWS US TO UPDATE ;LOCAL "APR" INFO ALL AT ONCE) MOV D.BW,-(SP) ;SAVE BYTE/WORD MODE MOV D.CAD,-(SP) ;SAVE "CURRENT ADDR" MOV #2,D.BW ;SET FOR FULLWORDS MOV D.FWA,R3 ;GET ADDRESS BIC #1,R3 ;EVENIZE JUST IN CASE. MOV R3,D.CAD ;GET USER PS,PC ADD #34,D.CAD ;TCB OFFSET OF TASK PC JSR PC,GETCAD ;GET IT (IF ANY) MOV R0,D.UR7 ;THE FILL IT IN ADD #2,D.CAD ;POINT AT USER STATUS IN TASK JSR PC,GETCAD ;LOAD IT MOV R0,D.USTA ;FILL IN MOV R3,D.CAD ;GET USER SP ADD #TCBDSP,D.CAD ;FROM TCB OF DYNAM. JSR PC,GETCAD ;LOAD TO R0 MOV R0,D.UR6 ;SAVE BNE 1$ ;IF NONZERO ALL IS WELL ADD #,D.CAD ;ELSE GET START SP JSR PC,GETCAD ;LOAD MOV R0,D.UR6 ;TO DDT SP 1$: ADD #TCBREG,R3 ;NOW POINTER THE SAVE AREA ;HERE HAVE SAVED R0-R5, THEN APR0-7 IN ORDER SO COPY HERE MOV #6,R2 ;COUNT REGS MOV #D.UR0,R1 ;DDT COPIES HERE 2$: MOV R3,D.CAD ;POINT AT SAVE AREA ADD #2,R3 ;BUMP FOR NEXT JSR PC,GETCAD ;LOAD THE VALUE MOV R0,(R1)+ ;SAVE IN DDT AREA DEC R2 BGT 2$ ;DO ALL REGS MOV #10,R2 ;COUNT APR'S MOV R5,R1 ;WHERE TO SAVE FOR NOW... 3$: MOV R3,D.CAD ;GET EM ADD #2,R3 JSR PC,GETCAD ;GET AN APR MOV R0,(R1)+ ;PUT IN OUR SAVE AREA DEC R2 BGT 3$ ;DO ALL APR'S ;AT THIS POINT ALL APR VALUES MAY BE LOCALLY MOVED TO DDT ;AREA STARTING AT VKPAR0, IGNORING PSEUDO MAP THE WHILE. MOV #10,R2 MOV #VKPAR0,R1 ;POINT AT DDT PSEUDO MAP 4$: MOV (R5)+,(R1)+ ;COPY AN APR DEC R2 ; BGT 4$ ;DO ALL 8. MOV (SP)+,D.CAD MOV (SP)+,D.BW ;RESTORE ADD #40,SP ;REMOVE SAVE AREA JSR R5,S.RRES RTS PC .ENDC ; UB SET BASE ; SYNTAX IS PAR> BLO 4$ ;CLEAR ALL RTS PC ;BACK AGAIN 1$: CMP D.FWA,# ;CHECK LEGAL MEM BRK # BHI 2$ ;ILLEGALS ARE WAY TO TURN OFF MEM BRK MOV D.FWA,R3 ;GET BRK # ASL R3 MOV #1,MEMCTL ;SET MEM BREAKS ON MOVB #1,D.S ;SINGLE STEP MOV D.SVR4,MEMADR(R3) ;SAVE ADDRESS TO EXAMINE MOV #-1,D.CT ;SET INFINITE PROCEED COUNT RTS PC .ENDC ; PROCESS : - DEFINE SYMBOL D.COLN: CMPB D.SYM,#' ; NULL SYMBOL? BEQ D.ERRB ; ERROR IF SO MOV D.DOT,R4 ; ASSUME DOT ADDRESS TSTB D.FWAF ; REAL VALUE GIVEN? BEQ D.COL1 ; BRANCH IF NOT MOV D.FWA,R4 ; GET REAL VALUE D.COL1: TST R0 ; IN SYMBOL TABLE? BNE D.COL2 ; BRANCH IF SO MOV D.RAD1,-(SP) ; SAVE RAD50 OF NAME MOV D.RAD2,-(SP) ; BOTH HALVES MOV #-1,D.RAD1 ; ASSUME NULL RAD50 LABEL MOV #-1,D.RAD2 ; IN BOTH HALVES JSR PC,D.GTAC ; LOOK IT UP TST R0 ; FOUND? BEQ D.ERRB ; ERROR IF NOT MOV (SP)+,-(R0) ; FILL LABEL IN MOV (SP)+,-(R0) ; BY SETTING BOTH WORDS CMP (R0)+,(R0)+ ; NOW FIX POSITION D.COL2: MOV R4,(R0) ; AND SET VALUE MOV R0,D.LASC ; SET LAST COLONED WORD MOV D.FENC,R1 ; GET FENCE CMP R0,R1 ; BEHIND FENCE? BHI D.COL5 ; DONE IF NOT JSR PC,D.SWAP ; SWAP SYMBOLS MOV R1,D.FENC ; STORE IN FENCE D.COL5: RTS PC ; RETURN D.ERRB: JMP D.ERR ; ERROR ; PROCESS D - DELETE LAST COLONED SYMBOL D.DELE: MOV D.LASC,R0 ; GET LAST COLONED SYMBOL BEQ D.ERRB ; ERROR IF NONE CLR D.LASC ; LAST TIME TO COLON IT BR D.KIL3 ; NOW KILL IT ; PROCESS K - KILL SYMBOL D.KILL: JSR PC,D.GTAC ; GET ADDRESS OF SYMBOL TST R0 ; ANY SYMBOL? BEQ D.ERRB ; ERROR IF NOT CMPB D.ALTF,#1 ; HOW MANY ALTMODES? BGT D.KIL1 ; BRANCH IF 2 D.KIL3: MOV D.FENC,R1 ; GET FENCE CMP R0,R1 ; SYMBOL BEHIND FENCE? BLO D.KIL4 ; BRANCH IF ALREADY KILLED ADD #6,R1 ; PUSH UP FENCE MOV R1,D.FENC ; AND STORE IT JMP D.SWAP ; SWAP SYMBOLS AND RETURN D.KIL1: CLR (R0) ; CLEAR ADDRESS MOV #-1,-(R0) ; PUT IN NULL SYMBOL MOV #-1,-(R0) ; IN BOTH WORDS D.KIL4: RTS PC ; RETURN ; PROCESS ALTMODE D.ALTM: TSTB D.ALTF ; ALREADY AN ALTMODE TYPED? BNE D.ALT1 ; BRANCH IF SO MOV R2,D.SVR2 ; AN ALTMODE HAS BEEN RECEIVED MOV R4,D.SVR4 ; NUMERIC FLAG TO D.SVR2, CONTENTS TO D.SVR4 D.ALT1: CLR R2 ; NO ARGS TYPED YET CLR D.OFST ; CLEAR OFFSET INCB D.ALTF ; COUNT NUMBER OF ALTMODES JMP D.DCD1 ; RETURN ; PROCESS / - OPEN WORD D.WRD: MOV D.CURM,D.OMOD ; TEMP COPY OF ROUTINE ADDRESS D.WRD1: TST R2 ; NUMBER THERE? BNE D.WRD3 ; BRANCH IF SO D.WRD4: MOV D.LASV,D.CAD ; SET LAST ADDRESS BR D.SEMI ; DO IT D.WRD3: MOV R4,D.DOT ; SET DOT D.WRD5: MOV D.DOT,D.CAD ; SET CURRENT ADDRESS ; PROCESS ; - RETYPE WORD D.SEMI: JMP @D.OMOD ; TYPE WORD AND RETURN ; PROCESS - OPEN INDIRECT D.ORAB: JSR PC,D.CLSE ; CLOSE WORD MOV D.LASV,D.DOT ; INDIRECT REFERENCE BR D.OP2 ; OPEN IT AND RETURN ; PROCESS ! - OPEN WORD SILENTLY D.EXCL: MOV #D.RTS,D.OMOD ; NULL ROUTINE FOR TYPING BR D.WRD1 ; OPEN WORD ; PROCESS \ - OPEN LAST REFERENCED WORD D.BKSL: TST R2 ; ANY PARAMETER? BEQ D.WRD4 ; BRANCH IF NOT JSR PC,D.CLSE ; CLOSE WORD BR D.WRD4 ; OPEN INDIRECT ; PROCESS - OPEN NEXT WORD D.OP1: JSR PC,D.CLSE ; CLOSE WORD ADD D.BW,D.DOT ; ADD IN BYTE/WORD INCREMENT ADD D.LFIN,D.DOT ; ADD IN LINE-FEED INCREMENT D.OP2: .$$..=0 .IF DF,$$RSX .IF GT,MMM11 .$$..=1 .ENDC .IIF DF,XTCOM,.$$..=0 .ENDC ;$$RSX .IF EQ,.$$.. JSR PC,D.CRLF ; TYPE CRLF .IFF MOV R0,-(SP) MOV #15,R0 ;EMIT C.R. ONLY MOVB #D.CNUM,D.CPOS ;RESET CHAR POINTER JSR PC,D.TYP3 MOV (SP)+,R0 .ENDC D.OP3: MOV D.DOT,R0 ; GET WORD JSR PC,D.RFND ; TYPE ADDRESS MOV #'/,R0 ; SLASH JSR PC,D.TYPE ; TYPE IT BR D.WRD5 ; TYPE CONTENTS ; PROCESS [ - OPEN WORD AS NUMERIC D.OPBR: MOV #D.CADV,D.OMOD ; NUMBER ROUTINE BR D.WRD1 ; DO ROUTINE ; PROCESS ] - OPEN WORD AS INSTRUCTION D.CLBR: MOV #D.INST,D.OMOD ; INSTRUCTION ROUTINE BR D.WRD1 ; DO IT ; ; SUBROUTINE TO BACK UP D.DOT BY ONE INSTRUCTION ; D.MAGIC: MOVB D.NOTY,-(SP) ; SAVE TYPE-OUT FLAG MOVB SP,D.NOTY ; PREVENT TYPE OUT CLR -(SP) ; MAKE ROOM ON STACK MOV D.DOT,R5 ; GET CURRENT LOCATION SUB #6,R5 ; BACK UP BY 1 INSTRUCTION 1$: MOV R5,(SP) ; RECORD CURRENT LOCATION JSR PC,D.DC49 ; CONVERT INSTRUCTION TO SYMBOLIC CMP R5,D.DOT ; DID IT REACH US? BHIS 2$ ; YES, WE ARE DONE MOV (SP),R5 ; GET BACK LOCATION ADD #2,R5 ; BUMP TO NEXT INSTRUCTION BR 1$ ; AND TRY AGAIN 2$: MOV (SP)+,D.DOT ; POP BACKED UP LOCATION MOVB (SP)+,D.NOTY ; ENABLE TYPE OUT RTS PC ; AND RETURN .IF NDF,X$QRG .SBTTL Q - DEFINE / EXECUTE MACRO ; ; THE FORMAT FOR USING Q-REGISTERS (MACROS) IS: ; ; ;NQ - EXECUTE MACRO N ; 0;NQ - DELETE MACRO N ; 1;NQ&.........& - DEFINE MACRO N. THE &'S ARE NECESSARY ; SINCE THEY DELIMIT THE TEXT OF THE MACRO. DOUBLE &'S ; ARE PASSED AS SINGLE &'S TO THE MACRO. ; D.Q: CMP R4,#D.BKP ; Q-REG OUT OF BOUNDS? BHIS 2$ ; YES ASL R4 ; CONVERT FOR WORD TABLES TST D.SVR2 ; ARGUMENT SPECIFIED? BNE 3$ ; NO, SO DEFINE/DELETE MACRO MOV D.QSPT,R0 ; GET STACK POINTER CMP R0,#D.QSTP ; CHECK FOR STACK OVERFLOW BHIS 2$ ; OOPS! MOV D.INLN,(R0)+ ; STACK CURRENT INPUT LENGTH MOV D.INPT,(R0)+ ; AND POINTER MOV R0,D.QSPT ; RESET STACK POINTER MOV D.QLEN(R4),D.INLN ; SET NEW INPUT LENGTH MOV D.QPTR(R4),D.INPT ; AND NEW INPUT POINTER 1$: RTS PC ; RETURN 2$: JMP D.ERR ; OOPS!!! 3$: TST D.SVR4 ; ZERO ARGUMENT? BNE 10$ ; NO, SO DEFINE NEW MACRO ; ; DELETE MACRO POINTED TO BY R4 ; 4$: MOV D.QLEN(R4),R0 ; GET CURRENT LENGTH BEQ 9$ ; NOTHING TO DELETE MOV D.QPTR(R4),R1 ; POINT TO TEXT MOV R1,R2 ; COPY POINTER ADD R0,R2 ; POINT PAST TEXT MOV D.QFREE,R0 ; POINT TO FREE SPACE SUB R2,R0 ; CALCULATE LENGTH OF BLOCK TO MOVE BEQ 6$ ; DEALLOCATING AT END OF STORAGE 5$: MOVB (R2)+,(R1)+ ; SLIDE BLOCK UP DEC R0 ; OVER QREG BEING DEALLOCATED BGT 5$ ; TO LEAVE LARGE HOLE AT END 6$: MOV R1,D.QFREE ; SAVE NEW POINTER TO FREE AREA MOV D.QPTR(R4),R1 ; GET OLD POINTER MOV #D.QPTR,R2 ; POINT TO START OF LIST MOV D.QLEN(R4),R3 ; GET LENGTH OF MOVEMENT MOV #D.BKP,R0 ; NUMBER OF TABLE ENTRIES 7$: CMP R1,(R2)+ ; WAS THIS GUY MOVED? BHIS 8$ ; ONPE SUB R3,-2(R2) ; CORRECT HIS POINTER 8$: DEC R0 ; BECAUSE WE JUST BGT 7$ ; MOVED HIM CLR D.QLEN(R4) ; CLEAR LENGTH TO MARK AS GONE 9$: RTS PC ; AND EXIT ; ; DEFINE NEW MACRO ; 10$: JSR PC,4$ ; DELETE OLD COPY OF MACRO JSR PC,D.GET ; GRAB A CHARACTER CMPB #'&,R0 ; &? BNE 2$ ; NO, SYNTAX ERROR THEN MOV D.QFREE,D.QPTR(R4) ; POINT TO WHERE TEXT WILL GO 11$: JSR PC,D.GET ; GET A CHAR CMPB #'&,R0 ; END? BEQ 13$ ; YES? 12$: MOV D.QFREE,R1 ; POINT TO FREE CORE MOVB R0,(R1)+ ; STORE CHAR CMP R1,#D.QTOP ; OUT OF ROOM? BHIS 2$ ; YES MOV R1,D.QFREE ; RESTORE POINTER INC D.QLEN(R4) ; INCREMENT LENGTH BR 11$ ; AND LOOP 13$: JSR PC,D.GET ; GRAB A CHAR CMPB #'&,R0 ; QUOTED & ? BEQ 12$ ; YES, SO PASS & RTS PC ; ELSE WE ARE DONE .ENDC .IF NDF,X$QRG .PSECT ..DDTD ; ; MACRO DATA STORAGE ; D.QSPT: .WORD 1$ ; INPUT POINTER STACK 1$: .BLKW 2*10 ; 10 MACRO NESTING LEVELS D.QSTP: .BLKW 1 ; TOP OF INPUT STACK D.INLN: .WORD 0 ; INPUT LENGTH D.INPT: .WORD 0 ; INPUT POINTER D.QLEN: .REPT D.BKP ; MACRO LENGTHS .WORD 0 .ENDR D.QPTR: .BLKW D.BKP ; MACRO POINTERS D.QFREE: .WORD 1$ ; POINTER TO FREE STORAGE 1$: .BLKB 200 ; 200 CHARACTERS OF MACRO STORAGE D.QTOP: .BLKB 2 ; TOP OF STORAGE .EVEN .PSECT ..DDTP .ENDC ; PROCESS ^ - OPEN PREVIOUS WORD D.BACK: JSR PC,D.CLSE ; CLOSE WORD .IF NDF,X.MGIC CMP #D.INST,D.OMOD ;IN INSTRUCTION MODE? BNE 1$ ;IF NE NO, JUST BACK UP AND DISPLAY JSR PC,D.MAGIC ; IF YES, BCK UP A FULL INSTRUCTION BR 2$ ;THEN PROCEED WITH DISPLAY 1$: .ENDC SUB D.BW,D.DOT ; SUBTRACT BYTE/WORD INCREMENT 2$: JMP D.OP2 ; OPEN WORD ; PROCESS _ - TYPE WORD SYMBOLICALLY D.ORPC: MOV D.LASW,R0 ; GET LAST TYPED WORD CLR D.LFIN ; NO LINE-FEED INCREMENT TSTB D.ALTF ; IS IT AN $_ ? BEQ D.ORP1 ; BRANCH IF NOT JMP D.RFND ; TYPE SYMBOLICALLY AND RETURN D.ORP1: JMP D.INST ; TYPE INSTRUCTION AND RETURN ; PROCESS = - TYPE WORD AS NUMBER D.EQAL: MOV D.LASW,R0 ; GET LAST TYPED WORD CLR D.LFIN ; NO LINE-FEED INCREMENT JMP D.TYPN ; TYPE AS A NUMBER ; PROCESS , - COMMA PARAMETER D.DCOM: TST R2 ; ANY PARAMETER? BEQ D.FWA1 ; BRANCH IF NOT MOV R4,D.COMA ; PUT IN PARAMETER AREA BR D.FWA1 ; RETURN ; PROCESS < - STORE FIRST WORD ADDRESS FOR SEARCH D.FWAS: MOV R4,D.FWA ; SET FIRST WORD INCB D.FWAF ; MARK FIRST WORD FOUND D.FWA1: JMP D.DCD2 ; RETURN ; PROCESS Z - ZERO CORE D.ZERO: MOV D.FWA,R0 ; FIRST WORD D.ZER1: CMP R0,D.SVR4 ; AT LAST WORD? BHI D.ONE1 ; DONE IF SO ; MOV D.FILV,(R0)+ ;FILL WORD WITH PATTERN MOV R0,-(SP) ; SAVE CELLS AND USE PUTCAD ADD #2,(SP) ; ALSO "AUTOINC" R0 MOV D.BW,-(SP) MOV R4,-(SP) MOV D.CAD,-(SP) MOV #2,D.BW ; FILL IN WORDS MOV R0,D.CAD MOV D.FILV,R4 ; FILL D.FILV VALUE IN THE AREA... JSR PC,PUTCAD MOV (SP)+,D.CAD MOV (SP)+,R4 MOV (SP)+,D.BW MOV (SP)+,R0 ; RESTORE ALL CELLS NEEDED FOR PUTCAD BR D.ZER1 ; LOOP ; PROCESS U - SECOND SET OF INSTRUCTIONS D.SNGL: CLR R5 ; OFFSET JSR PC,D.GET ; GET CHARACTER D.SNG2: CMPB D.UTAB(R5),R0 ; MATCH? BNE D.SNG1 ; NO ASL R5 ; MULTIPLY BY 2 JMP @D.UADD(R5) ; DO THIS ROUTINE D.SNG1: INC R5 ; NEXT CHARACTER CMP R5,#D.ENUT ; END OF LIST? BLT D.SNG2 ; LOOP IF NOT D.ERRE: JMP D.ERR ; RETURN ; .IF DF,D.UUY ;PROCESS Y - THIRD SET OF INSTRUCTIONS ($UYl where l = command letter) ; D.UY: CLR R5 JSR PC,D.GET ; GET A LETTER 1$: CMPB D.UYTB(R5),R0 ; SEE IF IT'S A VALID COMMAND BEQ 2$ ; IF EQ YES, WE GOT IT INC R5 ; ELSE KEEP ON TRUCKIN... CMP R5,#D.EUYT ; IF WE GOT IT, GO GO GO BGE D.ERRE ; IF WE PASS ALL, MUST BE AN ERROR BR 1$ ; ELSE LOOK AGAIN 2$: ASL R5 ; ENWORD THE COUNTER JMP @D.UYAD(R5) ; GO SERVICE THE COMMAND .ENDC ; PROCESS UT - SET SINGLE INSTRUCTION D.ONES: MOVB R4,D.S ; SET INDICATOR .IIF DF,$FORM$, BNE 1$ .IIF DF,$FORM$, CLR D.FFPC ;CLEAR HDWR INT FLG ON $UT .IIF DF,$FORM$ 1$: ;SKIP MOD ON SGL STEP SET CLR D.CT ; SET FOR AUTOMATIC PROCEDE CMPB D.ALTF,#1 ; TWO ALTMODES? BGT D.ONE2 ; FINISH UP IF SO INC D.CT ; SET NORMAL PROCEDE D.ONE2: MOV D.SVR4,D.OPEN ; SET ADDRESS TO OPEN AT BREAK D.ONE1: RTS PC ; RETURN ; PROCESS UW - SET RFND LIMIT D.WULF: MOV D.SVR4,D.RFNL ; SET LIMIT RTS PC ; RETURN ; PROCESS UG - RETURN USER DISPLAY .IF DF,D.GDP .PSECT ..DDT. D.GRAP: TRAP 144 MOV #104544,D.SAV9 ; UG! SELF MODIFYING-CODE RTS PC .PSECT ..DDTP,RO,I ;CODE .ENDC ;GENERALIZED-MAPPING READ/WRITE ROUTINES ;USED TO IMPLEMENT PSEUDO-22 BIT MAPPING. ; REQUIRE THAT $VMEM BE DEFINED AND THAT I/O COMMON IN APR7 BE THERE... ;GET CONTENTS OF ADDRESS IN THE MODE JSR PC,GETCAD ;NEEDS-- ;D.BW THE MODE 1=BYTE, 2=WORD ;D.CAD THE ADDRESS ;O.DEVI THE DEVICE CODE ;RETURNS-- ;R0 HAS THE DATA YOU ASKED FOR GETCAD: MOV R3,-(SP) ;SAVE R3 ACROSS THE CALL MOV D.BW,R0 ; LOAD D.BW HERE FOR UNIFORMITY MOV D.CAD,R3 ; GET CORE ADDRESS .IF DF,$VMEM ;IF I/O PAGE COMMON... TST PARMAP ;USING PSEUDO MAP OF ANY KIND? BEQ GC001 ;NO, USE REAL ONE MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) ;SAVE REGS WE NEED .IF DF,CD$FIL TST CD.CTL ;LOOKING AT FILE? BEQ 170$ ;NO, EXAMINE MEMORY JSR PC,CD.GET JMP GC002 ;YES, GET FILE DATA INTO R0 170$: .ENDC .IF DF,MU$DBG .IF DF,SPC$MP TST SR.CTL ;DOING SND/RCV HERE? BEQ 174$ ;NO, NORMAL JSR PC,U.GDAT ;YES, DO JMP GC002 ;AND RETURN 174$: .ENDC .ENDC ; .IIF DF,X$MPP, JMP GC002 .IF NDF,X$MPP MOV #4,R2 ;DEFAULT IS USE PAR 2 FOR MAP .WORD 20727 ;HAND ASSEMBLE THE FOLLOWING "CMP PC,#24000" .WORD 24000 ;TO AVOID A Z ERROR ; CMP PC,#24000 ;BUT SEE IF WE ARE IN PAR 0 BLOS 1$ ;IF SO USE DEFAULT CLR R2 ;OTHERWISE MAP THROUGH PAR 0 1$: MOV R2,R5 ;SAVE PAR OFFSET FOR LATER MOV R3,R4 ;GET COPY OF DATA .IF NDF,MU$DBG ;(ONLY TEST PAR 7 IF IN DDT TASK WHERE IT MUST ;BE MAPPED ALWAYS...) CMP R3,#157776 ;SEE IF IN PAR 7 (IF NOT, GUARANTEE NO ERR) BHI X2$ ;IF IN PAR 7 JUST LET IT THROUGH .IFF .IF DF,R$XMDB!R$XDDB .IF NDF,Q$UIET .IIF NDF,MP$ONE, .PRINT ;MAPPING ONLY AT EVERY BREAK TO TASK .IIF DF,MP$ONE, .PRINT ;MAPPING DONE TO TASK EVERY MAPPED ACCESS. .ENDC .IF DF,MP$ONE .GLOBL GETMP,DOFLG ; SUB IN DDTMU TO MAP TO CURRENT TASK ;ALLOW MAP TO TASK AT EVERY ACCESS TO PREVENT ANY WINDOWS WHERE TASK ;GETS MOVED BETWEEN BREAK AND TIME DDT LOOKS AT IT. TST DOFLG ;HAVE WE STARTED YET? BEQ 400$ ;IF NO, DON'T MAP A TASK TST M$$CTL ;ALSO IS INTERNAL FLAG SET? BEQ 400$ ;IF 0, SKIP TASK MAP JSR PC,GETMP ; SET APRS TO MAP TO CURRENT TASK 400$: .ENDC .ENDC ;ONLY WINDOW OCCURS HERE, UNTIL WE GO TO PRI7. MUST NOT GOOF AROUND ;WITH RSX AT PRI7 THOUGH...TOO LIKELY TO CRASH THE SYSTEM. .ENDC ASH #-12.,R4 ;GENERATE PAR OFFSET BIC #^C16,R4 ;AND ISOLATE OFFSET BITS ADD PARMAP,R4 ;R4 NOW POINTS TO PAR CONTENTS DESIRED BIC #160000,R3 ;R3 NOW GETS PAR OFFSET .IF NDF,L$$SI MOV @#PS,-(SP) ;SAVE PSW BIS #30340,@#PS ;SET PREV USER MODE, PRIO 7 .IFF MFPS -(SP) MOV (SP),-(SP) ;COPY PS IMAGE DOWN BIS #30340,(SP) ;SET PREV USER BITS MTPS (SP)+ ;AND FILL PSW FROM RESULT .ENDC MOV UPAR0(R2),-(SP) ;SAVE OLD PAR BEING USED FOR MAPPING MOV UPDR0(R2),-(SP) ;SAVE OLD PDR ALSO IOPAG=177600 ;22 BIT I/O PAGE APR CONTENT .IIF DF,$ADR18,IOPAG=7600 ;18 BIT ADDRESSING I/O PAGE VALUE MOV @R4,UPAR0(R2) ;FILL IN PAR AS WE WANT IT NOW CMP UPAR0(R2),#IOPAG ;IN I/O PAGE? BHIS 73$ ;I/O PAGE IS OK .IF LT,MAXBK-2000 .PRINT MAXBK ;** WARNING ** MAX SIZE BLOCK TOO SMALL, SETTING HIGH MAXBK=20000 .ENDC CMP UPAR0(R2),#MAXBK ;NOT I/O PAGE... LEGAL CORE? BLO 73$ ;YES, BRANCK ; MOV #MAXBK-200,UPAR0(R2) ;ILLEGAL...MAP TO TOP OF PHY S MEM BR 74$ ;SKIP THE ACCESS 73$: MOV #77406,UPDR0(R2) ;SET 4K R/W PDR ALSO MOV R3,R5 ;GET OFFSET BIC #1,R3 MMR3=172516 .IF NDF,U$ID. TST R2 ;ARE WE USING PAR 0 FOR MAP? BEQ 2$ ;IF SO ALL IS OK NOW BIS #40000,R3 ;ELSE SET PAR 2 BITS IN 2$: MFPI (R3) ;GRAB THE DATA (WHOLE WORD) MOV (SP)+,R3 ;STORE IN R3 A MOMENT .IFF ;BE SURE I AND D SPACE OFF WHILE DOING CRITICAL DATA BASHING TST R2 ;USING PAR0? BEQ 2$ BIS #40000,R3 ;NO, SET PAR2 BITS IN 2$: MOV R0,-(SP) ;SAVE A REG FOR MMR3 VALUE MOV @#MMR3,R0 ;GET MMR3 (INTS OFF HERE) BIC #1,@#MMR3 ;TURN OFF USER I/D SPACE ;SINCE WE ARE ASSUMING USER MODE OPERATION, CAN USE MOV HERE, NOT MFPI. ;BY ENSURING I/D SPACE IS OFF, WE WILL GET THE DESIRED ADDRESS. MOV (R3),R3 ;GET OUR DATA WORD IN I SPACE MOV R0,@#MMR3 ;RESTORE MMR3 (USER MODE I/D SPACE) MOV (SP)+,R0 ;AND GET BACK R0 OFF CORRECT STACK .ENDC 74$: MOV (SP)+,UPDR0(R2) ;RESTORE OUR PDR MOV (SP)+,UPAR0(R2) ;AND OUR PAR .IF NDF,L$$SI MOV (SP)+,@#PS ;RESTORE PSW .IFF MTPS (SP)+ .ENDC ASR R0 ;WANT WORD OR BYTE? BCC 3$ ;WORD SO BRANCH BIT #1,R5 ;WAS THE ADDRESS ODD? BEQ 4$ ;IF NOT LOW BYTE OK NOW SWAB R3 ;ELSE SWAP BYTES 4$: MOVB R3,R0 ;GET THE DATA BIC #177400,R0 ;ZERO SIGN EXTENSION! BR GC002 ;THEN BUG OUT 3$: MOV R3,R0 ;GET FULL WORD .ENDC ;X$MPP GC002: MOV (SP)+,R5 MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 ;RESTORE REGS MOV (SP)+,R3 ;RESTORE R3 TO CALL STATE RTS PC ;BYPASS REST OF CODE X2$: MOV (SP)+,R5 MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 .ENDC GC001: .IF DF,U$ID.!MPV2. TST UV$SPF ;NORMAL TYPE "VIRTUAL" MAP? BLE 9$ ;IF MI YES AND IF EQ USE DATA SPACE TOO .IF DF,U$ID. ;EXAMINE IN I SPACE REGISTERS. ;DO SO BY CLEARING MEM. MGT. I/D ENABLE TO DEFAULT TO I SPACE. MOV @#PS,-(SP) ;SAVE OLD PSW BIS #140340,@#PS ;;;ENSURE PRI7 OPERATION MOV R1,-(SP) ;;;SAVE A REGISTER TOO MOV @#MMR3,R1 ;;;SAVE MMR3 THERE ;CAN'T USE STACK SINCE I/D SWITCH CLOBBERS ACCESS TO IT BIC #1,@#MMR3 ;;;ENSURE NO I/D SPACE ENABLE ASR R0 ;;;TEST BYTE FLAG BCC 8$ MOVB (R3),R0 ;;;GET BYTE BR 7$ 8$: MOV (R3),R0 ;;;GET WORD 7$: MOV R1,@#MMR3 ;;;REACCESS I/D SPACE IF ANY MOV (SP)+,R1 ;;;RESTORE R1 MOV (SP)+,@#PS ;RESTORE PRIO ETC. BR GETC99 .IFF ;USE MVTS$ DIRECTIVE TO ACCESS USER D SPACE MOV R0,-(SP) MOV R3,R0 BIC #1,R0 ;GET WORD ADDRESS MVTS$S #MV.FUI,R0,#MPI.DT ;ACCESS WORD IN I SPACE MOV (SP)+,R0 BIC #^C1,R3 ;REMOVE ALL BUT BYTE FLAG IN ADDR BIS #MPI.DT,R3 ;AND POINT R3 AT DATA FOUND. .ENDC 9$: .ENDC 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: MOV (SP)+,R3 ;RESTORE R3 TO CALL STATE RTS PC ;STACK ACCESS ;PUT R4 INTO ADDRESS IN THE MODE JSR PC,PUTCAD ;NEEDS-- ;R4 THE DATA ;D.BW THE MODE FLAG, IF 0 THEN NO LOCATION OPEN PUTCAD: MOV D.BW,R0 ;PICK UP MODE AN CC'S MOV R3,-(SP) ; SAVE CALLER'S R3 MOV D.CAD,R3 ; GET CORE ADDRESS .IF DF,$VMEM ;IF I/O PAGE COMMON... TST PARMAP ;SEE IF ANY VIRT. MAPS BEQ PC001 ;NO, SKIP MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) ;SAVE REGS WE NEED .IF DF,CD$FIL TST CD.CTL ;LOOKING AT FILE? BEQ 170$ ;NO, EXAMINE MEMORY JSR PC,CD.PUT JMP PC002 ;YES, PUT DATA IN BUFFER INTO FILE. 170$: .ENDC .IF DF,MU$DBG .IF DF,SPC$MP TST SR.CTL ;DOING SND/RCV HERE? BEQ 174$ ;NO, NORMAL JSR PC,U.PDAT ;YES, DO JMP PC002 ;AND RETURN 174$: .ENDC .ENDC ; .IIF DF,X$MPP, JMP PC002 .IF NDF,X$MPP MOV #4,R2 ;DEFAULT IS USE PAR 2 FOR MAP .WORD 20727 ;HAND ASSEMBLE THE FOLLOWING "CMP PC,#24000" .WORD 24000 ;TO AVOID A Z ERROR ; CMP PC,#24000 ;BUT SEE IF WE ARE IN PAR 0 BLOS 1$ ;IF SO USE DEFAULT CLR R2 ;OTHERWISE MAP THROUGH PAR 0 1$: MOV R4,R5 ;SAVE PAR OFFSET FOR LATER MOV R3,R4 ;GET COPY OF DATA .IF NDF,MU$DBG ;OMIT PAR7 TEST IF INTERTSK DBG CMP R3,#157776 ;SEE IF IN PAR 7 (IF NOT, GUARANTEE NO ERR) BHI YX2$ ;IF IN PAR 7 JUST LET IT THROUGH .IFF .IF DF,MP$ONE ;ALLOW MAP TO TASK AT EVERY ACCESS TO PREVENT ANY WINDOWS WHERE TASK ;GETS MOVED BETWEEN BREAK AND TIME DDT LOOKS AT IT. ; *** NOTE: REQUIRES NO MAPPED ACCESS UNTIL THERE'S A TASK TO USE. .IF DF,R$XMDB!R$XDDB TST DOFLG ;STARTED? BEQ 401$ ;IF NO, SKIP TST M$$CTL BEQ 401$ ;ALSO SKIP IF INTERNAL CONTROL SAYS TO JSR PC,GETMP ; SET APRS TO MAP TO CURRENT TASK 401$: .ENDC ; *** DO NOT USE IN IAS! .ENDC .ENDC ASH #-12.,R4 ;GENERATE PAR OFFSET BIC #^C16,R4 ;AND ISOLATE OFFSET BITS ADD PARMAP,R4 ;R4 NOW POINTS TO PAR CONTENTS DESIRED BIC #160000,R3 ;R3 NOW GETS PAR OFFSET .IF NDF,L$$SI MOV @#PS,-(SP) ;SAVE PSW BIS #30340,@#PS ;SET PREV USER MODE, PRIO 7 .IFF MFPS -(SP) MOV (SP),-(SP) ;COPY PS IMAGE DOWN BIS #30340,(SP) ;SET PREV USER BITS MTPS (SP)+ ;AND FILL PSW FROM RESULT .ENDC MOV UPAR0(R2),-(SP) ;SAVE OLD PAR BEING USED FOR MAPPING MOV UPDR0(R2),-(SP) ;SAVE OLD PDR ALSO MOV @R4,UPAR0(R2) ;FILL IN PAR AS WE WANT IT NOW CMP UPAR0(R2),#IOPAG ;IN I/O PAGE? BHIS 73$ ;I/O PAGE IS OK CMP UPAR0(R2),#MAXBK ;NOT I/O PAGE... LEGAL CORE? BLO 73$ ;YES, BRANCK ; MOV #MAXBK-200,UPAR0(R2) ;ILLEGAL...MAP TO TOP OF PHY S MEM BR 74$ ;SKIP THE ACCESS 73$: MOV #77406,UPDR0(R2) ;SET 4K R/W PDR ALSO MOV R3,R4 ;GET OFFSET BIC #1,R3 TST R2 ;ARE WE USING PAR 0 FOR MAP? BEQ 2$ ;IF SO ALL IS OK NOW BIS #40000,R3 ;ELSE SET PAR 2 BITS IN 2$: .IF NDF,U$ID. MFPI (R3) ;GRAB THE DATA (WHOLE WORD) .IFF CLR -(SP) ;SAVE A STACK CELL MOV R1,-(SP) MOV R2,-(SP) MOV @#MMR3,R1 ;SAVE I/D MODE BIC #1,@#MMR3 ;CLEAR USER MODE I/D ENABLES MOV (R3),R2 ;GRAB OUR OLD DATA MOV R1,@#MMR3 ;RESTORE I/D SPACE TO ACCESS STACK AGAIN MOV R2,4(SP) ;SAVE VALUE ON NEXT TOP OF STACK MOV (SP)+,R2 MOV (SP)+,R1 ;RESTORE REGISTERS ;NOW (SP) IS WORD WE WANTED. .ENDC BIT #1,R0 ;BYTE ADDRESSING IN EFFECT? BEQ 5$ ;NO, BASH WORD BIT #1,R4 ;YES, IS IT THE ODD BYTE? BEQ 6$ ;NO, THE EVEN ONE -- BRANCH MOVB R5,1(SP) ;YES, BASH ODD BYTE OF DATA BR 7$ ;THEN DO IT 6$: MOVB R5,(SP) ;BASH EVEN BYTE ONLY BR 7$ ;THEN DO IT 5$: MOV R5,(SP) ;BASH WORD 7$: .IF NDF,U$ID. MTPI (R3) ;PUT BACK MODIFIED DATA WHERE WE GOT IT FROM. .IFF MOV R1,-(SP) MOV R2,-(SP) MOV 4(SP),R2 ;GET DATA VALUE IN R2 MOV @#MMR3,R1 ;SAVE I/D ENABLE STATE BIC #1,@#MMR3 ;TURN IT OFF IN USER MODE MOV R2,(R3) ;REPLACE THE WORD WE WANT TO REPLACE MOV R1,@#MMR3 ;REESTABLISH STACK AND I/D ADDRESSING MOV (SP)+,R2 MOV (SP)+,R1 ;RESTORE REGS WE USED TST (SP)+ ;CLEAN UP EXTRA STACK CELL .ENDC 74$: MOV (SP)+,UPDR0(R2) ;RESTORE OUR PDR MOV (SP)+,UPAR0(R2) ;AND OUR PAR .IF NDF,L$$SI MOV (SP)+,@#PS ;RESTORE PSW .IFF MTPS (SP)+ .ENDC .ENDC ;X$MPP PC002: MOV (SP)+,R5 MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 ;RESTORE REGS MOV (SP)+,R3 ;RESTORE R3 TO CALL STATE RTS PC ;BYPASS REST OF CODE YX2$: MOV (SP)+,R5 MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 .ENDC PC001: .IF DF,U$ID.!MPV2. .IIF DF, X$MPP .PRINT ;WARNING - I/O PAGE ACCESS REQUIRED FOR I/D MAPPING TST UV$SPF ;NORMAL TYPE "VIRTUAL" MAP? BLE 9$ ;IF MI YES AND IF EQ USE DATA SPACE TOO .IF DF,U$ID. ;EXAMINE IN I SPACE REGISTERS. ;DO SO BY CLEARING MEM. MGT. I/D ENABLE TO DEFAULT TO I SPACE. MOV @#PS,-(SP) ;SAVE OLD PSW BIS #140340,@#PS ;;;ENSURE PRI7 OPERATION MOV R1,-(SP) ;;;SAVE A REGISTER TOO MOV @#MMR3,R1 ;;;SAVE MMR3 THERE ;CAN'T USE STACK SINCE I/D SWITCH CLOBBERS ACCESS TO IT BIC #1,@#MMR3 ;;;ENSURE NO I/D SPACE ENABLE BIT #177776,R0 ;;;TEST MODE BNE 8$ ;;;WORD IF NE MOVB R4,(R3) ;;;PUT BYTE BR 7$ 8$: MOV R4,(R3) ;;;PUT WORD 7$: MOV R1,@#MMR3 ;;;REACCESS I/D SPACE IF ANY MOV (SP)+,R1 ;;;RESTORE R1 MOV (SP)+,@#PS ;RESTORE PRIO ETC. BR X12$ .IFF ;USE MVTS$ TO PUT DATA INTO USER D SPACE MOV R0,-(SP) ;NEED A REG ;FOR BYTE OPS WE NEED TO READ OLD WORD, THEN MASK IN NEW ONE MOV R3,R0 ;GET WORD ADDRESS BIC #1,R0 ;EVENIZE MVTS$S #MV.FUI,R0,#MPI.DT ;GET OLD DATA MOV R3,R0 ;GET BYTE BIT NOW BIC #^C1,R0 BIS #MPI.DT,R0 ;POINT AT BUFFER WE HAD BIT #1,R0 ;CHECK BYTE MODE BEQ 7$ ;IF EQ IT'S WORD MODE MOVB R4,@R0 ;ELSE FILL IN BYTE BR 8$ 7$: MOV R4,@R0 ;FILL IN WORD 8$: MOV R3,R0 ;ACCESS ADDRESS AGAIN BIC #1,R0 ;CORRECT FOR MVTS$ TAKING VALUE ON MOVE TO ;CORRECTION IS MPI.DT, NOT #MPI.DT MVTS$S #MV.TUI,R0,MPI.DT ;PUT DATA INTO USER I SPACE MOV (SP)+,R0 BR X12$ ;THEN SKIP OUT .ENDC 9$: .ENDC 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$: X12$: MOV (SP)+,R3 ;RESTORE R3 TO CALL STATE RTS PC ; PROCESS E, N AND W - SEARCHES D.EFF: MOV #1,R1 ; SET EFFECTIVE SEARCH BR D.WDS ; DO SEARCH D.NSCH: MOV #-1,R1 ; SET NON-SEARCH BR D.WDS ; DO SEARCH D.WSCH: CLR R1 ; SET WORD SEARCH D.WDS: TST D.SVR2 ; NUMBER TO SEARCH FOR? ; BEQ D.ERRE ; ERROR IF NOT BNE 1$ JMP D.ERR 1$: MOV D.FWA,R2 ; SET ORIGIN D.WDS2: .IF NDF,D.KSR TSTB @#D.RCSR ; CHARACTER TYPED? BMI D.WDS6 ; BRANCH IF SO .ENDC .IF DF,D.KSR JSR PC,D.POLL ; CHECK FOR TYPED CHARACTER .IF DF,$$RSX .IF NDF,XTCOM ;ALLOW AN ALTMODE TO BE ENTERED WITHOUT PREJUDICE... CMP D.INPU,D.OUTP BEQ 11$ CMPB @D.INPU,#33 ;WAS THE CHARACTER AN ESCAPE BNE 10$ ;IF NOT, HANDLE AS TERMINATION .IF DF,GRB$CH ;(NORMALLY NOT DEFINED...) JSR R5,S.RSAV JSR PC,D.GET ;GET CHAR AND IGNORE JSR R5,S.RRES .ENDC 11$: .ENDC .ENDC CMP D.INPU,D.OUTP ; ANY CHARACTERS IN BUFFER? BNE D.WDS6 10$: .ENDC CMP R2,D.LWA ; IS THE SEARCH ALL DONE? BHI D.WDS6 ; YES MOV D.SVR4,R5 ; GET NUMBER TO SEARCH FOR MOV D.MASK,R4 ; GET MASK COM R4 ; COMPLEMENT IT MOV D.BW,-(SP) ; SAVE OLD BYTE FLAG MOV #2,D.BW ;SET WORD MODE MOV R2,D.CAD ;SAVE CURRENT ADDRESS JSR PC,GETCAD ;LOAD CURRENT ADDR TO R0 IN ANY SPACE MOV (SP)+,D.BW ;RESTORE BYTE/WORD FLAG TO OF YORE ; MOV (R2),R0 ; GET OBJECT ; MOV R2,D.CAD ; THIS IS CURRENT ADDRESS BIC R4,R0 ; TURN OFF BITS NOT BEING SEARCHED FOR BIC R4,R5 ; TURN OFF BITS NOT BEING SEARCHED FOR MOV R1,-(SP) ; STORE AND TEST BMI D.WDS5 ; BRANCH IF NON-SEARCH BGT D.WDS7 ; BRANCH IF EFFECTIVE SEARCH CMP R0,R5 ; EQUALITY? D.WDS3: BNE D.WDS4 ; RE-LOOP IF NO MATCH D.WDS1: JSR PC,D.CRLF ; TYPE CRLF MOV D.CAD,R0 ; GET READY TO TYPE JSR PC,D.RFND ; RELOCATE D.SLST: MOV #'/,R0 ; SLASH TO R0 JSR PC,D.TYPE ; TYPE IT JSR PC,@D.CURM ; TYPE CONTENTS D.WDS4: MOV (SP)+,R1 ; RESTORE R1 MOV D.CAD,R2 ; RESTORE R2 TST (R2)+ ; INCREMENT TO NEXT CELL AND BR D.WDS2 ; RETURN D.WDS7: MOV #1,D.BOTH ; MARK NOTHING FOUND AND DON'T TYPE INSTRUCTION JSR PC,D.INST ; "TYPE" THE INSTRUCTION DEC D.BOTH ; ALLOW TYPEOUT AND TEST FOUND INDICATOR D.WDS9: BEQ D.WDS4 ; BRANCH IF NOT FOUND BR D.WDS1 ; BRANCH IF FOUND D.WDS5: CMP R0,R5 ; EQUALITY? BR D.WDS9 ; BRANCH TO DECIDE D.WDS6: RTS PC ; RETURN ;PROCESS ? - RAD50 TYPEOUT D.RDT1: .IF DF,X$QRG MOV #D.RADC,D.OMOD ;SET RAD50 MODE BIC #1,D.CAD ;FORCE EVEN ADDRESS!! JMP D.WRD1 ;GO TYPE OUT IN RAD50 .IFF ;DISPLAY DATA IN ALL APPLICABLE MODES MOV #D.RDT2,D.OMOD ;SET UP ? MODE FOR DEFAULT DISPLAY TST R2 ; SEE IF ANY ADDRESS GIVEN BNE 2$ ; IF YES, USE IT MOV D.LASV,D.CAD ;ELSE USE LAST BR 3$ 2$: MOV R4,D.DOT MOV R4,D.CAD ; 3$: D.RDT2: JSR PC,D.CADV ;DISPLAY NUMERIC NOW JSR PC,D.TTAB ;THEN A TAB MOV #10.,D.DVTB ;THEN SET DECIMAL JSR PC,D.CADV ;DISPLAY THUSLY MOV #16.,D.DVTB ;THEN HEX JSR PC,D.TTAB JSR PC,D.CADV MOV #8.,D.DVTB ;RESET DEFAULT OCTAL NOW JSR PC,D.TTAB JSR PC,D.ASCI ;TYPE AS ASCII JSR PC,D.TTAB MOV #8.,D.SIZE ;SET 8 BIT BYTES JSR PC,D.PART ;SHOW AS 2 BYTES JSR PC,D.TTAB JSR PC,D.RADC ;FINALLY DISPLAY AS RAD50 RTS PC .ENDC ; PROCESS H - HALF WORD TYPEOUT D.INHA: MOV #1,D.BW ; SET HALF WORD MODE ; PROCESS C - SET NUMERIC TYPEOUT D.INNM: MOV #D.CADV,D.CURM ; SET NUMERIC MODE D.INN3: MOV D.CURM,D.OMOD ; SET LF AND ^ TYPEOUT MODE D.INN2: CMPB D.ALTF,#2 ; TWO ALTMODES TYPED? BLT D.CRE1 ; RETURN IF NOT MOV #D.CURM,R0 ; ADDRESS OF TEMPORARY TABLE MOV #D.PERM,R1 ; ADDRESS OF PERMANENT TABLE D.SWAM: MOV #4,R2 ; SWAP MODES: WORD COUNTER IN R2 D.SWA2: MOV (R0)+,(R1)+ ; MOVE A WORD DEC R2 ; DECREMENT COUNTER BGT D.SWA2 ; LOOP TILL DONE RTS PC ; RETURN ; PROCESS T - TEXT TYPEOUT D.INTX: MOV #D.ASCI,D.CURM ; DEFAULT TO ASCII CMP R4,#5 ; RAD50? BNE D.INN3 ; RETURN IF NOT MOV #D.RADC,D.CURM ; RAD50 BR D.INM1 ; RETURN ; PROCESS O - BYTE TYPEOUT D.BYTE: MOV #D.PART,D.CURM ; IN BYTE TYPEOUT MODE MOV D.DECN,D.SIZE ; SET BYTE SIZE BR D.INM1 ; RETURN ; PROCESS S - INSTRUCTION TYPEOUT D.INMD: MOV #D.INST,D.CURM ; IN INSTRUCTION MODE D.INM1: MOV #2,D.BW ; MUST BE FULLWORD MODE BR D.INN3 ; RETURN ; PROCESS A - ABSOLUTE ADDRESS TYPEOUT D.ABS: MOV #1,D.IFMT ; SET ABSOLUTE ADDRESSING BR D.INN2 ; RETURN ; PROCESS R - SET RADIX D.INRD: TST R2 ; RADIX SPECIFIED? BEQ D.INR1 ; BRANCH IF NOT CMP D.DECN,#2 ; MUST BE GREATER THAN 1 BLT D.ERRC ; BRANCH IF NOT MOV D.DECN,D.DVTB ; ALWAYS DECIMAL RADIX BR D.INN2 ; RETURN D.INR1: CLR D.IFMT ; TURN ON RELATIVE ADDRESSING BR D.INN2 ; RETURN ; PROCESS - CLOSE WORD AND RESET PERMANENT MODES D.CRET: JSR PC,D.CLSE ; CLOSE LOCATION MOV #D.PERM,R0 ; ADDRESS OF PERMANENT TABLE MOV #D.CURM,R1 ; ADDRESS OF TEMPORARY TABLE JSR PC,D.SWAM ; SWAP MODES MOV D.CURM,D.OMOD ; SET LF AND ^ TYPEOUT MODE D.CRE1: JMP D.DCD0 ; RETURN ; PROCESS > - STORE LAST WORD ADDRESS FOR SEARCH D.LWAS: MOV R4,D.LWA ; SET LAST WORD TST R2 ; ANY WORD THERE? BNE D.CRE1 ; BRANCH IF NOT MOV #DDT-2,D.LWA ; SET HIGH LAST WORD BR D.CRE1 ; RETURN ; PROCESS B - SET AND REMOVE BREAKPOINTS D.BKPT: TST D.SVR2 ; DID HE GIVE A FIRST ARG? BEQ D.BKP9 ASL R4 ; MULTIPLY NUMBER BY TWO MOV D.SVR4,R5 ; GET FIRST NUMBER BEQ D.BKP4 ; REMOVE BREAK IF FIRST ARG 0 .IIF NDF,MU$DBG, TST (R5) ; VALID ADDRESS? NXM IF NOT TST R4 ; SPECIFIC CELL REQUESTED? BNE D.BKP1 ; JUMP IF SO MOV #2,R4 D.BKP3: MOV D.BKTB-2(R4),R0 ; IS THIS CELL FREE? BEQ D.BKP2 ; JUMP IF YES CMP R0,R5 ; IS BREAK ALREADY SET FOR THIS ADDRESS? BEQ D.BKP2 ; BRANCH IF YES TST (R4)+ ; INCREMENT BY TWO CMP R4,#D.BKP*2 ; ARE WE AT THE END OF OUR ROPE? BLOS D.BKP3 ; NO, KEEP LOOKING D.BKP1: CMP R4,#D.BKP*2 ; REQUESTED NUMBER TOO LARGE? BHI D.ERRC ; ERROR IF TOO LARGE D.BKP2: MOV R5,D.BKTB-2(R4) ; SET BREAKPOINT .IF DF,$BSXMU!MU$DBG ;SPECIAL M/U BSX TYPE DEBUG OR PURE AREA DBG ; READ BREAKPOINT INSTRUCTION NOW AND DO NOT READ AT STARTUP ; OF PROGRAM (ALLOWS SAME ROUTINE TO BE HANDLED BY MULTIPLE ; COPIES OF DDT) MOV R0,-(SP) ;USE GETCAD TO LOAD INSTRUCTION MOV D.BW,-(SP) MOV D.CAD,-(SP) MOV #2,D.BW ;GET A USER INST. WORD MOV R5,D.CAD ;AT R5 ADDR JSR PC,GETCAD ;GO GET IT MOV R0,D.UIN-2(R4) ;SAVE INSTRUCTION MOV (SP)+,D.CAD ;RESTORE SAVED CONTEXT MOV (SP)+,D.BW MOV (SP)+,R0 .ENDC MOV D.COMA,D.OPEN(R4) ; SET WORD TO OPEN AT BREAKPOINT CLR D.CT(R4) ; SET CONTINUE COUNT CMPB D.ALTF,#1 ; TWO ALTMODES? BGT D.BKP8 ; BRANCH IF NOT INC D.CT(R4) ; DO NOT SET AUTOMATIC PROCEDE D.BKP8: RTS PC ; RETURN D.BKP4: TST R2 ; IF NO NUMBER WAS TYPED... BEQ D.BKP6 ; GO REMOVE ALL CMP R4,#D.BKP*2 ; WAS THE TYPED NUMBER VALID? BHI D.ERRC ; JUMP IF NOT CLR D.BKTB-2(R4) ; CLEAR BREAKPOINT RTS PC ; RETURN D.BKP5: ASL R4 D.BKP6: MOV #D.BKTB+,R4 D.BKP7: CLR -(R4) CMP R4,#D.BKTB BHI D.BKP7 RTS PC ; RETURN D.BKP9: TST R2 BEQ D.BKP5 DEC R4 CMP R4,#D.BKP ; WAS THE TYPED NUMBER VALID? BHIS D.ERRC ; JUMP IF NOT ADD #D.BKTB-2+1,R4 BR D.MAS2 D.ERRC: JMP D.ERR ; INTERMEDIATE HELP ; PROCESS M - TYPE AND SET MASK D.MAST: MOV #D.MASK,-(SP) ; GET MASK TST D.SVR2 ; NUMBER THERE? BNE D.MAS3 ; BRANCH IF SO D.MAS1: MOV (SP)+,R4 ; ADDRESS TO OPEN D.MAS2: JSR PC,@D.OPER ; COMBINE VALUE WITH CURRENT EXPRESSION INC R2 ; MARK A TYPED NUMBER JMP D.DCD3 ; CONTINUE SCANNING D.MAS3: MOV D.SVR4,@(SP)+ ; SET MASK RTS PC ; RETURN ; PROCESS V - GET CONTENTS OF D.DOT SWABBED D.ALTV: MOV R0,-(SP) ;SAVE OLD R0 MOV D.BW,-(SP) MOV D.CAD,-(SP) ;SAVE CONTEXT FOR GETCAD MOV D.DOT,D.CAD ;COPY CURRENT ADDR MOV #2,D.BW ;WORD MODE JSR PC,GETCAD ;LOAD D.CAD CONTENT IN ANY SPACE MOV R0,R4 ;COPY DATA TO R4 MOV (SP)+,D.CAD MOV (SP)+,D.BW MOV (SP)+,R0 ;RESTORE JUNK ; MOV @D.DOT,R4 ; CONTENTS OF WORD SWAB R4 ; SWAB IT BR D.MAS2 ; RETURN ; PROCESS Q - GET CONTENTS OF D.DOT D.ALTQ: MOV R0,-(SP) ;SAVE OLD R0 MOV D.BW,-(SP) MOV D.CAD,-(SP) ;SAVE CONTEXT FOR GETCAD MOV D.DOT,D.CAD ;COPY CURRENT ADDR MOV #2,D.BW ;WORD MODE JSR PC,GETCAD ;LOAD D.CAD CONTENT IN ANY SPACE MOV R0,R4 ;COPY DATA TO R4 MOV (SP)+,D.CAD MOV (SP)+,D.BW MOV (SP)+,R0 ;RESTORE JUNK ; MOV @D.DOT,R4 ; CONTENTS OF WORD BR D.MAS2 ; RETURN ; PROCESS I - GET ADDRESS OF USER STATUS D.ALTI: MOV #D.USTA,R4 ; ADDRESS OF STATUS BR D.MAS2 ; RETURN ; PROCESS " - GET TEXT D.TEXT: JSR PC,D.GET ; GET NEXT CHARACTER CLR R2 ; RAD50/ASCII INDICATOR CMP R0,#33 ; ALTMODE? BNE D.TEX1 ; BRANCH IF NOT INC R2 ; SET INDICATOR JSR PC,D.GET ; GET NEXT CHARACTER D.TEX1: MOV R1,R5 ; DELIMETER (EXACT CHARACTER) D.TEX2: JSR PC,D.GET ; GET CHARACTER CMP R1,R5 ; DELEMETER? BEQ D.TEX3 ; BRANCH IF SO MOV R1,R0 ; PUT IN ARGUMENT PLACE JSR PC,D.PTSM ; PUT IN SYMBOL BR D.TEX2 ; LOOP D.TEX3: TST R2 ; ASCII? BNE D.TEX4 ; BRANCH IF NOT MOV D.SYM,R4 ; GET ASCII CHARACTERS BR D.MAS2 ; RETURN D.TEX4: MOV #D.SYM,R0 ; ADDRESS OF FIRST THREE CHARACTERS .IF DF,$VMEM MOV PARMAP,-(SP) CLR PARMAP .ENDC .IF DF,U$ID.!MPV2. MOV UV$SPF,-(SP) MOV #140000,UV$SPF .ENDC JSR PC,D.RD50 ; CONVERT TO RAD50 .IIF DF,U$ID.!MPV2., MOV (SP)+,UV$SPF .IIF DF,$VMEM, MOV (SP)+,PARMAP MOV R0,R4 ; NOW CURRENT VALUE BR D.MAS2 ; RETURN ; PROCESS - SOFT RESTART .IF DF,D.GDP D.SOFT: MOV #1004,R5 ; ADDRESS OF SOFT RESTART BR D.GO3 ; GO THERE .ENDC ; ; PROCESS ADDR ; ;D.PBUF NOW HAS CONTENTS OF BLOCK WITH DATA DESIRED. ; PATCH IT NOW. BIT #1,D.BW ;BYTE PATCH? BNE 4$ ;YES, PATCH BYTES MOV D.SVR4,D.PBUF(R0) ;NO, BASH DATA AS WORDS BR 5$ 4$: MOVB R4,D.PBUF(R0) ;YES, BASH BYTES 5$: QIOW$S #IO.WVB,#D.PLUN,#D.PEV,,#D.IOSP,,<#D.PBUF,#512.,,R3,R2> ; WRITE BUFFER BACK OUT JSR R5,S.RRES MOV (SP)+,D.BW ;RESTORE BYTE/WORD MODE RTS PC ;BACK TO CALLER .PSECT ..DDTD D.BASE:: .WORD 1,0 D.PBUF: .BLKW 256. D.IOSP: .WORD 0,0 ;I/O STATUS BLK FOR QIO$ .PSECT ..DDTP,RO,I ;CODE .ENDC .ENDC ; PROCESS UF - FILL MACRO WITH TEXT ; .IF DF,D.MCRO D.UF: MOV R5,-(SP) MOV R4,-(SP) MOV R0,-(SP) CLR D.CHSW ;ALWAYS FILL MACRO FROM CONSOLE ; SYNTAX IS UFTEXT ; WHERE DELIM IS ANY CHARACTER AND TEXT IS UP TO 80 ; BYTES LONG. JSR PC,D.GET ;READ A CHARACTER AS DELIM. MOV R0,R4 ;SAVE IN R4 MOV #D.KBBF,R5 ;POINT AT BUFFER TO FILL 1$: JSR PC,D.GET ;LOAD A CHARACTER CMP R5,#D.KBBF+82. ;PAST LEGAL END? BHI 3$ ;YES, SKIP IT CMP R0,R4 ;TERMINATOR CHARACTER? BEQ 3$ ;YES, DONE MOVB R0,(R5)+ ;LOOKS OK TO FILL IN THIS ONE BR 1$ ;GET ANOTHER. 3$: MOVB #-1,@R5 ;STASH TERMINATOR FOR MACRO MOV (SP)+,R0 MOV (SP)+,R4 MOV (SP)+,R5 ;RESTORE REGS RTS PC ;BACK TO WHEREVER... .ENDC .IF DF,R$XMDB!R$XDDB .GLOBL TSKAPR,VKPAR0 ; PROCESS $UL - LOOK UP RSX11M TASK AND MAP TO IT D.UUL: ; SYNTAX IS ULTASKNAME ; JSR R5,S.RSAV MOV PARMAP,-(SP) CLR PARMAP ;SET NO VIRTUAL MAPPING HERE .IF DF,U$ID.!MPV2. MOV UV$SPF,-(SP) MOV #140000,UV$SPF .ENDC ; ; HERE READ IN THE TASK NAME WITH DELIMITERS... ;NOTE WE ONLY WILL BASH MAP IF HDRADR IS SET NONZERO ON RETURN ;FROM DBG11M ; JSR PC,D.GET ;READ DELIMITER MOV R0,R4 ;SAVE IN R4 ; 20040 = ASCII SPACE,SPACE MOV #20040,D.TNAM MOV #20040,D.TNAM+2 ;CLEAR BUFFER OF OLD JUNK MOV #20040,D.TNAM+4 MOV #D.TNAM,R5 ;TEXT IN D.TNAM BUFFER 1$: JSR PC,D.GET ;GET A BYTE CMP R5,#D.TNAM+5 ;PAST LEGAL END? BHI 3$ ;YES, BUG OUT CMP R0,R4 ;TERMINATOR? BEQ 3$ ;YES, DONE MOVB R0,(R5)+ ;NO,SAVE CHARACTER BR 1$ ;AND GET ANOTHER 3$: ;NOW CONVERT TO RAD50 MOV #D.TNAM,R0 ;POINT AT 1ST 3 CHARS JSR PC,D.RD50 ;GET RAD50 MOV R0,D.RTNM ;SAVE 1ST 3 CHARS MOV #D.TNAM+3,R0 JSR PC,D.RD50 MOV R0,R1 ;SET TSK NAME MOV R1,D.RTNM+2 ;SAVE RAD50 NAME FOR DEBUGGING MOV D.RTNM,R0 ;INTO R0,R1 JSR PC,DBG11M ;CALL RSX LOOKUP PROGRAM TST HDRADR ;DID IT FIND A HEADER IN CORE? BNE 7$ ;IF YES, ALL WELL JMP D.ERR ;ELSE TELL USER WE LOST! 7$: MOV #10,R0 MOV #TSKAPR,R1 MOV #VKPAR0,R2 ;SET UP TO COPY APR INFO 10$: MOV (R1)+,(R2)+ DEC R0 BGT 10$ ;COPY ALL 8 .IIF DF,U$ID.!MPV2., MOV (SP)+,UV$SPF MOV (SP)+,PARMAP ;STAY MAPPED IF WE WERE BEFORE... JSR R5,S.RRES .IF DF,MU$DBG .IF DF,R$XMDB!R$XDDB ;SET UP AUTOMATIC MAP TO THE TASK IF ENABLED. MOV #1,M$$CTL ;AND SET AUTO MAP .ENDC .ENDC RTS PC .PSECT ..DDTD D.TNAM: .BLKW 4 ;TASK NAME STORAGE (ASCII) D.RTNM: .BLKW 2 ;RAD50 NAME SAVE .PSECT ..DDTP,RO,I ;CODE .ENDC ; S.RSAV: MOV R4,-(SP) ;JSR R5,S.RSAV SAVES REGS MOV R3,-(SP) MOV R2,-(SP) MOV R1,-(SP) MOV R0,-(SP) MOV R5,-(SP) ;STASH RETURN TO STACK MOV 14(SP),R5 ;PUT CALLING R5 IN R5 ON RETURN RTS PC ;RETURN TO RIGHT PLACE S.RRES: TST (SP)+ ;JSR R5,S.RRES. JUNK CALLING R5 MOV (SP)+,R0 MOV (SP)+,R1 MOV (SP)+,R2 MOV (SP)+,R3 MOV (SP)+,R4 RTS R5 ;RETURN POPS BACK R5 .IF DF,DB$L ;HANDLE ADDR$J AND ADDR$NJNUMBER COMMANDS. .PSECT ..DDTD JDAT: .WORD 0 ;SCRATCH FOR L.O. WORD ON EXAMINE .PSECT ..DDTP,RO,I ;CODE JXAM: JSR R5,S.RSAV ;SAVE REGISTERS MOV D.BW,-(SP) ;NEED BYTE/WORD FLG AND MOV D.CAD,-(SP) ;D.CAD TOO MOV #2,D.BW ;SET TO WORDS TST D.SVR2 ;WAS AN ADDRESS GIVEN? BEQ 1$ ;IF NONE, USE CURRENT MOV D.SVR4,D.CAD ;ELSE USE GIVEN ONE 1$: BIC #1,D.CAD ;BUT IN ANY CASE IT MUST BE EVEN MOV R4,JDAT ;SAVE ARG FOR LATER TESTS TST R2 ;WAS THIS AN INSERT? BNE JINSRT ;IF SO GO TO IT JSR PC,GETCAD ;GET 1ST (LOW ORDER) WORD MOV R0,JDAT ;SAVE ADD #2,D.CAD JSR PC,GETCAD ;GET NEXT WORD MOV R0,R1 ;MAKE IT H.O. MOV JDAT,R0 ;RETRIEVE L.O. JSR PC,D.TY32 ;GO TYPE IN CURRENT RADIX JBACK: MOV (SP)+,D.CAD ;NOW PUT ALL THE STUFF BACK MOV (SP)+,D.BW JSR R5,S.RRES ;GET REGS TOO RTS PC ;DONE DISPLAY. ;INSERT 32 BIT INTEGER FROM CONSOLE JINSRT: ;FIRST GET DIGITS. CLR R4 CLR R5 ;USE (R4,R5) AS ACCUMULATOR MOV D.DVTB,R3 ;RADIX IN R3 ;READ UNTIL NONDIGIT SEEN. CLR R2 ;R2=1 IF NEGATIVE. JSR PC,D.GET ;GET R0=CHAR CMPB R0,#'- ;MINUS? BNE 1$ ;IF NOT LEAVE R2=0 INC R2 BR 6$ 1$: CMPB R0,#'0 ;TOO LOW? BLO 2$ ;YES,EXIT CMPB R0,#'9 ;BIGGER THAN 9? BLOS 3$ ;NO, OK SUB #<'A-'9-1>,R0 ;YES, ADJUST 3$: SUB #'0,R0 ;MAKE CORRECT NUMBER BINARY CMP R0,R3 ;BIGGER THAN BASE? BHIS 2$ ;IF SO DONE MOV R3,R1 DEC R1 ;ADD TIMES BLE 2$ ;BASE 1 IS ILLEGAL MOV R4,-(SP) MOV R5,-(SP) ;MULTIPLY VIA ADD 4$: ADD 2(SP),R4 ADC R5 ADD (SP),R5 ;DO AN ADD OF OLD VALUE TO ITSELF DEC R1 BGT 4$ ; TIMES CMP (SP)+,(SP)+ ;ADJUST STACK NOW ADD R0,R4 ;ADD NEW PART TO L.O. NOW ADC R5 ;MAKE IT 32 BITS WIDE NOW. 6$: JSR PC,D.GET BR 1$ ;DONE POINT. SAVE R4,R5 AT D.CAD, D.CAD+2 2$: TST R2 ;NEED TO NEGATE IT? BEQ 5$ ;NO, LEAVE ALONE COM R4 COM R5 ADD #1,R4 ;YES, NEGATE ADC R5 5$: MOV R5,-(SP) ;NEED R5 NEXT TIME. R4 OK NOW. JSR PC,PUTCAD ;STASH FIRST (L.O.) PART ADD #2,D.CAD MOV (SP)+,R4 ;NOW GET 2ND PART CMP #2,JDAT ;WAS THIS A 16 BIT STASH? BEQ 7$ ;YES, OMIT 2ND HALF JSR PC,PUTCAD ;POKE 2ND PART BACK NOW ;DONE. 7$: JMP JBACK ;DIVIDE 32BIT (R0,R1) BY R3 ;REMAINDER IN R2 ON RETURN ;BASHES ALL REGS D.D32: CLR R2 ;ASSUME NO REMAINDER MOV #32.,-(SP) ;WORD SIZE D.D31: ASL R0 ROL R1 ;SHIFT UP ROL R2 CMP R3,R2 ;DIVISOR BIGGER? BHI D.D332 ;IF SO NO MORE QUOTIENT BITS NOW SUB R3,R2 ;ELSE ADJUST REMAINDER INC R0 ;AND TURN ON QUOTIENT BIT D.D332: DEC @SP ;COUNT SHIFTS BGT D.D31 TST (SP)+ ;POP OLD SHIFT COUNT RTS PC D.TY32: MOV D.DVTB,R3 ;GET RADIX CMP R3,#10. ;DECIMAL IS SIGNED. BEQ D.T324 ;SO DO IT D.T325: JSR PC,D.D32 ;DIVIDE BY RADIX ADD #'0,R2 ;ADD ASCII ZONES MOV R2,-(SP) ;THEN SAVE DIGIT DURING RECURSION CMP R2,#'9 ;MORE THAN 9? BLE 1$ ;IF DIGIT ALL WELL ADD #<'A-'9-1>,(SP) ;ELSE MAKE LETTERS FOLLOW, NOT FUNNY CHARS 1$: TST R0 ;32 BITS ALL 0 NOW? BNE D.T326 ;IF NOT DO IT AGAIN TST R1 ;IF SO IS H.O. 0? BEQ D.T327 ;IF 0, UN-RECURSE D.T326: JSR PC,D.T325 ;RECURSE FOR HIGHER DIGIT NEXT D.T327: MOV (SP)+,R0 ;GET LEFT DIGIT JMP D.TYPE ;AND TYPE IT D.T324: MOV #'.,-(SP) ;TRAILING PERIOD IF DECIMAL MOV R1,R2 ;GET H.O. THAT HAS SIGN BPL D.T326 ;IF POSITIVE ALL OK NOW MOV R0,R2 ;ELSE SAVE R0 MOV #'-,R0 ;TYPE "-" JSR PC,D.TYPE MOV R2,R0 ;GET L.O. AGAIN COM R1 COM R0 ;COMPLEMENT ADD #1,R0 ;AND ADD 1 AS 2S COMPL NEGATE ADC R1 ;TO 32 BITS BR D.T326 ;NOW PRINT POSITIVE NUMBER. .ENDC ; .IF DF,$D$FPU ;DDT FLOATING POINT SUPPORT ONLY! ; ;DDT FLOATING POINT SUPPORT ENTRY POINTS .PSECT ..DDTD D.PRCN: .WORD 0 D.FPAC: .WORD 0,0,0,0 ;F.P. AC STORAGE AREA .PSECT ..DDTP,RO,I ;CODE ;D.UINS AND D.UJNS ; addr$UInumber ; or addr$UJnumber ; type out the F.P. number at addr (or current if ;no addr is entered) as a 2 or 4 word floating point number. D.UINS: MOV #2,D.PRCN ;2 WORD F.P. INSPECT BR U.INCM ;GO TO COMMON INSPECT D.UJNS: MOV #4,D.PRCN ;4 WORD F.P. INSPECT U.INCM: MOV D.BW,-(SP) MOV R0,-(SP) MOV D.CAD,-(SP) MOV #2,D.BW ;FORCE WORD OPERATIONS LDFPS #40200 ;NOW SET UP LONG FPU STAT CLRF D.FPAC ;ZERO THE FLAC AREA ;SET UP D.CAD FOR LATER WHEN WE FILL IN THE USER'S AREA MOV D.DOT,D.CAD TST D.SVR2 ;ANY ADDRESS GIVEN? BEQ 2$ ;IF NO, SKIP MOV D.SVR4,D.CAD ;IF YES, HANDLE IT 2$: BIC #1,D.CAD ;NOW GET THE NUMBER FROM THE USER. JSR PC,FLIN ;GET THE F.P. NUMBER ;AC0 NOW HAS THE NUMBER. STF AC0,D.FPAC ;NOW WE HAVE THE NUMBER IN MEMORY MOV R3,-(SP) MOV R2,-(SP) MOV #D.FPAC,R3 ;GET NUMBERS TO SHOVE MOV D.PRCN,R2 ;AND NO. WORDS TO USE 3$: MOV (R3)+,R4 ;PUTCAD DATA GOES INTO R4 JSR PC,PUTCAD ;SAVE AT D.CAD ADD #2,D.CAD ;BUMP ADDRESS DEC R2 ;COUNT DOWN PRCN TO USE BGT 3$ ;TILL DONE ALL WORDS TO INSERT MOV (SP)+,R2 MOV (SP)+,R3 MOV (SP)+,D.CAD MOV (SP)+,R0 MOV (SP)+,D.BW RTS PC ; ;D.UXAM ;Examines F.P. number in precision of D.PRCN (either 2 or 4 words) ;and shows it on terminal. form of command is ; addr$UX D.UXAM: CMP #4,D.PRCN ;DOUBLE PRECISION? BEQ 1$ ;IF SO OK MOV #2,D.PRCN ;OTHERWISE MUST BE 2 1$: MOV R4,-(SP) MOV D.BW,-(SP) MOV R0,-(SP) MOV D.CAD,-(SP) MOV #2,D.BW ;FORCE WORD OPERATIONS MOV D.DOT,D.CAD TST D.SVR2 ;ANY ARGUMENT GIVEN? BEQ 2$ ;IF NOT, SKIP LOAD AND LEAVE D.CAD THERE MOV D.SVR4,D.CAD ;IF SO, SET UP D.CAD HERE 2$: MOV R3,-(SP) BIC #1,D.CAD MOV R2,-(SP) MOV D.PRCN,R2 ;COUNTER OF WORDS TO LOAD MOV #D.FPAC,R3 ;WHERE TO SAVE THIS STUFF LDFPS #40200 ;SET LONG FP MODE CLRF D.FPAC ;ZERO THE SAVE AREA 3$: JSR PC,GETCAD ;GET A WORD FROM SOMEWHERE MOV R0,(R3)+ ;DUMP TO OUR SCRATCH AREA ADD #2,D.CAD ;BUMP CURRENT ADDR POINTER DEC R2 ;THEN LOOP OVER WORDS NEEDED BGT 3$ ;NOW HAVE ALL THE NUMBER IN D.FPAC, SO LOAD TO AC0 & TYPE LDF D.FPAC,AC0 ;AC0 GETS NUMBER JSR PC,FLOUT ;THEN PRINT IT MOV (SP)+,R2 MOV (SP)+,R3 MOV (SP)+,D.CAD MOV (SP)+,R0 MOV (SP)+,D.BW MOV (SP)+,R4 RTS PC ; ;F.P. UTILITY ROUTINES ; EOUT TYPE AN E FORMAT NUMBER ; FLOUT TYPE A FLOATING POINT NUMBER ; FLIN READ A FLOATING POINT NUMBER AC0=%0 AC1=%1 AC2=%2 AC3=%3 ;READ ROUTINE: ENTER WITH STRING ADDRESS IN R0, MAXIMUM NUMBER ;OF BYTES IN R1. CALL WITH JSR PC,READ. .PSECT ..DDTD ; SAV0: 0 SAV1: 0 SAV2: 0 FLAG: 0 EFLG: 0 SIGN: 0 BUFLOC: 0 .=.+30. .WORD 0,0,0,0 BUF2: 0 .=.+30. .WORD 0,0,0,0 DEC: 12 ;10(10) .PSECT ..DDTP,RO,I ;CODE ;FLOATING POINT INPUT ROUTINE ;ENTER WITH JSR PC,FLIN ;RESULT IS RETURNED IN AC0 FLIN: MOV R0,-(SP) ;SAVE REGISTERS MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) MOV R5,-(SP) ;**********!!!!!! ;GET STRING INTO BUFLOC. ;USE DDT TEXT ROUTINES TO LOAD IT. MOV #BUFLOC,R5 ;PUT NUMBER IN HERE. 1$: JSR PC,D.GET ;GET NEXT CHAR CMPB R0,#40 ;SPACE OR HIGHER? BLT 2$ ;LESS THAN SPACE IS TERMINATOR BEQ 1$ ;IGNORE SPACES HOWEVER MOVB R0,(R5)+ ;FILL IN OUTPUT BUFFER CMP R5,#BUFLOC+29. ;PAST END OF BUFF? BLO 1$ ;IF NOT, GET MORE NUMBERS. 2$: CLRB @R5 ;IF DONE, NULL THE STRING END ;**********!!!!!! CLR R3 ;EXPONENT COUNTER F5: CLR SWITCH ;CLEAR SWITCH (SET BY E OR.) CLR SWE ;SET BY E IN INPUT STRING CLR EXPSGN ;EXPONENT SIGN CLRF AC0 ;CLEAR AC0 STF AC1,-(SP) ;SAVE FL ACCUMULATORS STF AC2,-(SP) LDF #ONE,AC2 ;SET AC2 TO 1 MOV #BUFLOC,R0 ;STRING LOCATION F1: MOVB (R0)+,R1 ;GET CHARACTER BEQ FINB ;QUIT IF ZERO (END OF STRING) CMPB #105,R1 ;LOOK FOR AN E BEQ EE CMPB #56,R1 ;LOOK FOR A DECIMAL POINT BEQ DP CMPB #55,R1 ;LOOK FOR A MINUS BEQ MINA CMPB #53,R1 ;LOOK FOR A PLUS BEQ F1 ;IGNORE IT BIC #177760,R1 ;CLEAR UNWANTED BITS TST SWITCH BNE SVAL ;BRANCH IF SWITCH IS SET LDCIF R1,AC1 ;MUST BE A NUMBER, PUT IN AC1 MULF #TEN,AC0 ;MULTIPLY AC0 BY 10 ADDF AC1,AC0 ;AND ADD C(AC1) BR F1 ;CONTINUE FINB: DIVF AC2,AC0 ;SCALE VALUE TST SWE ;IS E SWITCH SET? BNE EXP ;SET EXPONENT IF SET F4: TST SIGN ;CHECK SIGN OF NUMBER BEQ F3 NEGF AC0 F3: LDF (SP)+,AC2 ;RESTORE REGISTERS LDF (SP)+,AC1 MOV (SP)+,R5 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 RTS PC ;AND EXIT DP: INC SWITCH ;SET SWITCH NE 0 BR F1 EE: INC SWITCH INC SWE ;INCREMENT E SWITCH BR F1 MINA: TST SWE ;IS E SWITCH SET? BNE F2 ;GO TO F2 IF IT IS BR ERRF ;ERROR MESSAGE IF NOT F2: INC EXPSGN ;INDICATE SIGN TO BE NEGATIVE BR F1 SVAL: TST SWE ;CHECK SWITCHES BNE SE ;BRANCH IF E SWITCH IS SET LDCIF R1,AC1 ;HANDLE NUMBER NORMALLY MULF #TEN,AC2 ;BUT KEEP TRACK OF FRACTION IN AC2 MULF #TEN,AC0 ADDF AC1,AC0 BR F1 SE: MUL DEC,R3 ;GET POWER OF 10 ADD R1,R3 BR F1 EXP: TST R3 ;SEE IF EXPONENT IS ZERO BEQ F4 ;SKIP NEXT PART IF IT IS TST EXPSGN ;CHECK SIGN OF E PART BEQ F6 FF1: DIVF #TEN,AC0 ;DIVIDE BY TEN SOB R3,FF1 BR F4 F6: MULF #TEN,AC0 ;MULTIPLY BY TEN SOB R3,F6 BR F4 ERRF:; MOV #MES2,R0 ;ERROR MESAGE ;*************!!!!!!!!!! JMP D.ERR ;GO TYPE ? TO TELL USER OF ERROR ; JSR PC,TYPE ;*************!!!!!!!!!! ; BR F5 TEN= 41040 TWO= 40400 ONE= 40200 .PSECT ..DDTD SWITCH: 0 SWE: 0 EXPSGN: 0 .PSECT ..DDTP,RO,I ;CODE ;FLOATING OUTPUT ROUTINE, SINGLE PRECISION ;ENTER WITH NUMBER IN AC0, FORMAT IN R0 (FIELD/DEC.PT) ;SET R1 = 0 FOR NORMAL TTY OUTPUT, SET R1 = BUFFER ADDRESS ;IF NO TYPED OUTPUT IS WANTED ;USE JSR PC,FLOUT FLOUT: MOV R0,-(SP) ;SAVE REGISTERS MOV R1,-(SP) MOV #BUFLOC,SAV1 ;USE BUFLOC AS PRINT BUFFER ; MOV R1,SAV1 MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) STF AC0,-(SP) STF AC1,-(SP) MOV (PC)+,R0 ;FIELD/DECIMAL POINT IS FIXED FPFMT: .BYTE 10.,20. ;F20.10 FOR LOTS OF PRECISION. MOVB R0,R1 ;NUMBER OF DECIMAL PLACES SWAB R0 MOVB R0,R4 MOVB R0,R3 MOVB R0,R2 ;FIELD SIZE SUB R1,R4 SUB R1,R2 BLE ERRG ;BRANCH IF DP>FS-1 CLR SIGN DEC R4 ;NUMBER OF PLACES BEFORE DP LDF #ONE,AC1 ;PUT ONE IN AC1 TSTF AC0 CFCC BPL G4 ABSF AC0 INC SIGN G4: TST R1 ;SET TO ROUND NUMBER BEQ G4C ;DONT DIVIDE IF DP = 0 DIVF #TEN,AC1 ;DIVIDE BY TEN TO GET LEAST SIG DIGIT SOB R1,G4 G4C: DIVF #TWO,AC1 ;HALF OF LEAST SIGNIFICANT DIGIT ADDF AC1,AC0 ;DONE LDF #ONE,AC1 ;PUT ONE IN AC1 TST R2 ;IF DP =0, DONT DIVIDE BEQ G4B G4A: MULF #TEN,AC1 ;GET MULTIPLIER FOR DECIMAL PLACES SOB R2,G4A MOVB R3,R2 DIVF AC1,AC0 ;DIVIDE TO CONVERT TO FRACTION STEXP AC0,R0 ;GET EXPONENT BGT ERRG ;ERROR IF GREATER THAN ZERO G4B: MODF #TEN,AC0 ;GET FIRST INTEGER STCFI AC1,R0 ;CONVERT TO FIXED POINT BNE ERRG ;ERROR IF FIRST INTEGER IS NOT ZERO MOV #BUF2,R1 ;SET UP BUFFER LOCATION G1: MODF #TEN,AC0 ;GET NEXT INTEGER STCFI AC1,R0 ;CONVERT TO FIXED POINT ADD #60,R0 ;AND CONVERT TO ASCII MOVB R0,(R1)+ ;STORE IT SOB R2,G1 ;CHECK FOR END OF FIELD ; TST SAV1 ;WHAT OUTPUT IS WANTED? ; BEQ GA1 ;GO TO GA1 FOR TTY OUTPUT ; MOV SAV1,R2 ;SET NEW BUFFER IF NOT WANTED ; BR GA2 ;AND SKIP NEXT INSTRUCTION GA1: MOV #BUFLOC,R2 ;TTY OUTPUT BUFFER GA2: MOV #BUF2,R1 ;PRESENT CHARACTER BUFFER CLR EXPSGN ;FIRST CHARACTER FLAG G2: CMPB #60,(R1) ;IS CHARACTER ZERO? BNE GO MOVB #40,(R2)+ ;YES,PUT IN SPACE INC R1 DEC R3 DEC R4 BEQ DECPT ;PUT IN DECIMAL POINT? BR G2 ;NO, TRY NEXT CHARACTER GO: INC EXPSGN ;SET FIRST CHARACTER FLAG TST SIGN ;IS NUMBER NEGATIVE? BEQ GO1 CMP #BUFLOC,R2 ;YES, IS THERE ROOM FOR SIGN? BEQ ERRG ;NO, ERROR DEC R2 ;YES, DECREMENT R2 MOVB #55,(R2)+ ;PUT IN - SIGN CLR SIGN GO1: MOVB (R1)+,(R2)+ ;TRANSFER CHARACTER DEC R4 BEQ DECPT ;DECIMAL POINT? G8: SOB R3,GO DEC R2 CLRB (R2) ;INDICATE END OF LIST ;*****!!!!! ALWAYS JUST FILL IN STRING.WOULD ELSE TYPE OUT HERE. 1$: MOV #BUFLOC,R4 ;TYPE THE BUFFER OUT MOV R2,R3 ;FROM R4 TO R3 DEC R3 ;(EXCEPT FORGET THE NULL) CMP R4,R3 ;BE SURE END PAST START BHIS G3 ;OR NO TYPE. JSR PC,D.STYP ;TO OUTPUT DEVICE (TTY) BR G3 DECPT: TST EXPSGN ;FIRST CHARACTER FOUND? BNE DA1 DEC R2 ;NO TST SIGN ;IS NUMBER NEGATIVE? BEQ DA2 ;BRANCH TO DA2 IF POSITIVE DEC R2 MOVB #55,(R2)+ ;PUT IN NEG SIGN IF IT IS CLR SIGN DA2: MOVB #60,(R2)+ ;PUT IN LEADING ZERO INC R3 INC EXPSGN ;SHOW THAT FIRST CHARACTER IS HERE DA1: MOVB #56,(R2)+ BR G8 G3: LDF (SP)+,AC1 LDF (SP)+,AC0 MOV (SP)+,R4 ;RESTORE REGISTERS MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 ; MOV SAV1,R1 MOV (SP)+,R0 RTS PC ;AND EXIT ERRG: LDF (SP)+,AC1 ;RESTORE ACCUMULATOR LDF (SP)+,AC0 MOV (SP)+,R4 ;AND USE E FORMAT MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 ; MOV SAV1,R1 MOV (SP)+,R0 JSR PC,EOUT ;CALL E FORMAT ROUTINE RTS PC ;AND EXIT ;SUBROUTINE FOR E FORMAT TELETYPE OUTPUT ;ENTER WITH NUMBER IN AC0, FORMAT IN R0 (FIELD/DEC.PT) ;USE JSR PC,EOUT ;THE ROUTINE OPERATES IN THE PRECISION OF THE CALLING ;PROGRAM. THE PRECISION IS NOT RESET BY THE ROUTINE. ; EOUT: MOV R0,-(SP) ;SAVE REGISTERS MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) STF AC1,-(SP) ;SAVE ACCUMULATOR MOV FPFMT,R0 ;GET FLOATING FORMAT MOVB R0,R1 ;DECIMAL POINT LOCATER SWAB R0 ;SWAP BYTES BIC #177400,R0 ;GET FIELD SIZE MOV R0,-(SP) ;SAVE IT ADD #7,R1 ;EFFECTIVE SIZE SUB R1,R0 ;SPACES BLE E1A ;GREATER THAN ZERO? ;**********!!!!!!!!!!!! MOVB #40,R0 ;OUTPUT A SINGLE SPACE JSR PC,D.TYPE ;AND THAT'S ALL... ; JSR PC,SPACE ;YES,OUTPUT THEM ;**********!!!!!!!!!!!! TST (SP)+ ;INCREMENT STACK POINTER MOV R1,R0 BR E1B E1A: MOV (SP)+,R0 ;NO SPACES-CHECK IF THERE IS ENOUGH ROOM CMP #10,R0 ;SHOULD BE AT LEAST 10 BLE E1C MOV #10,R0 ;SET IT TO 10 IF SMALLER E1C: MOV R0,R1 E1B: CLR R4 ;R4 CONTAINS EXPONENT CLR SIGN ;SIGN FLAG TSTF AC0 ;IS NUMBER ZERO OR NEGATIVE? CFCC BEQ E2 ;BRANCH IF ZERO BPL E3 ABSF AC0 ;NEGATIVE, TAKE ABS VALUE INC SIGN ;AND SET SIGN E3: STEXP AC0,R2 ;GET EXPONENT BGT E1 ;GREATER THAN ZERO? E3A: CMP #-3,R2 ;NO, LESS THAN -3? BLE E2 MULF #TEN,AC0 ;YES,MULTIPLY BY 10 DEC R4 ;AND DECREMENT COUNTER STEXP AC0,R2 ;GET EXPONENT BR E3A ;TRY AGAIN E1: DIVF #TEN,AC0 ;TOO LARGE, DIVIDE BY TEN INC R4 ;AND INCREMENT COUNTER STEXP AC0,R2 ;GET EXPONENT BGT E1 ;IF STILL GREATER, DIVIDE AGAIN E2: MOV #BUF2,R2 ;NOW CONVERT NUMBER SUB #7,R0 ;NUMERICAL FIELD SIZE LDF #ONE,AC1 ;ROUND NUMBER MOV R0,R1 EX: DIVF #TEN,AC1 SOB R0,EX DIVF #TWO,AC1 ;HALF OF LEAST SIG DIGIT ADDF AC1,AC0 ;ROUNDED TST SIGN ;IS NUMBER NEGATIVE? BEQ E5 MOVB #55,(R2)+ ;YES, SET SIGN BR E6 E5: MOVB #40,(R2)+ ;NN, START WITH SPACE E6: MOVB #60,(R2)+ ;"0" MOVB #56,(R2)+ ;"." E7: MODF #TEN,AC0 ;GET INTEGER STCFI AC1,R0 ;CONVERT TO FIXED POINT ADD #60,R0 ;AND CONVERT TO ASCII MOVB R0,(R2)+ ;STORE IT SOB R1,E7 ;DONE? MOVB #105,(R2)+ ;ALL DONE, PUT IN EXPONENT TST R4 ;SIGN BPL E10 MOVB #55,(R2)+ ;"+" NEG R4 BR E11 E10: MOVB #53,(R2)+ ;"+" E11: TST R4 ;IS EXPONENT ZERO? BNE E12 MOVB #60,(R2)+ ;YES MOVB #60,(R2)+ BR E20 E12: CMP R4,DEC ;IS IT <10? BLT E14 MOV R4,R1 ;YES, PUT NUMBER IN R1 CLR R0 DIV DEC,R0 ;DIVIDE BY 10 ADD #60,R0 ;CONVERT TO ASCII MOVB R0,(R2)+ ADD #60,R1 MOVB R1,(R2)+ BR E20 E14: MOVB #60,(R2)+ ADD #60,R4 MOVB R4,(R2)+ E20: CLRB (R2) MOV #BUF2,R0 ;**********!!!!!!!!!!!! MOV R0,R4 ;START OF BUFFER MOV R2,R3 ;END OF BUFFER DEC R3 ;EXTRACT NULL CMP R4,R3 ;BE SURE END BEFORE BEGINNING BHIS 1$ ;IF NOT NO OUTPUT JSR PC,D.STYP 1$: ; JSR PC,TYPE ;**********!!!!!!!!!!!! LDF (SP)+,AC1 ;RESTORE ACCUMULATOR MOV (SP)+,R4 ;RESTORE REGISTERS MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 RTS PC .PSECT ..DDTD V1: .FLT4 0.0 .PSECT ..DDTP,RO,I ;CODE .ENDC ; PROCESS G - GO D.GO: MOV D.SVR4,R5 ; GET STARTING ADDRESS TST D.SVR2 ; STARTING ADDRESS SPECIFIED? BNE DD.GO3 ; IF NOT, USE USER SA MOV JOBSA,R5 ; GET STARTING ADDRESS DD.GO3: .IF DF,MU$DBG CMP R5,#RSXEXT ;ALWAYS ALLOW EXIT BNE D.GO3 JMP RSXEXT ;JUST GO THEE, FORGET RESTORE... .ENDC D.GO3: .IIF NDF,MU$DBG, TST (R5) ; VALID ADDRESS? NXM IF NOT JSR PC,D.CRLF D.GO5: TST D.SD.T ; SHOULD THE T-BIT BE ON? BEQ D.GO2 ; BRANCH IF NO D.GO4: BIS #20,D.USTA ; SET T-BIT D.GO2: MOV R5,D.UR7 .IF DF,RTTTST ;TEST FOR RTI OR RTT INSTRUCTIONS WE ARE GOING TO EXECUTE AND ;IF WE ARE EXECUTING THEM, SET T BIT ON TASK STACK TOO... CLR RTRFG ;FLAG NOT RTI/RTT ..TMP=0 .IIF DF,MU$DBG,..TMP=1 .IIF DF,DULMOD,..TMP=1 .IF EQ,..TMP ; .IF NDF,MU$DBG!DULMOD CMP @D.UR7,#2 ;RTI? BNE 1$ INC RTRFG ;YES,FLAG 1$: CMP @D.UR7,#6 ;RTT? BNE 2$ INC RTRFG ;YES, FLAG 2$: .IFF .PRINT ;RTI/RTT TEST AND BREAK NOT SUPPORTED IN THIS VERSION .ENDC .ENDC JSR PC,D.REST ; RESTORE REGISTERS .IF DF,RTTTST TST RTRFG BEQ 1$ ;SET T BIT ON USER STACK ..TMP=0 .IIF DF,MU$DBG,..TMP=1 .IIF DF,DULMOD,..TMP=1 .IF EQ,..TMP ; .IF NDF,MU$DBG!DULMOD BIS #20,2(SP) ;SET T BIT ON STACK IF RTI/RTT .ENDC 1$: .ENDC MOV D.USTA,-(SP) ; AND STATUS MOV D.UR7,-(SP) ; AND PC JMP D.GO1 .PSECT ..DDT. ;IMPURE CODE ;D.GO1 MODIFIED BY STARTUP! BUT MUST LEAVE AS INST. D.GO1: .IF NDF,L$$SI .IF NDF,$$RSXMM!$D$FPU .IF DF,$RSXMM RTT ;MAPPED RSX11M ASSUMES RTT WILL EXIST .IFF RTI ; THIS IS "RTT" IF 11/40...($RSXMM UNDEFINED) .ENDC .IFF RTT ;$D$FPU OR $$RSXM DEFINED .ENDC .IFF RTT ;LSI-11 ALWAYS HAS RTT .ENDC .PSECT ..DDTD .IIF DF,RTTTST, RTRFG: .WORD 0 ;FLAG WE SAW RTI .PSECT ..DDTP,RO,I ;CODE ; PROCESS P - PROCEED D.PROC: TST R2 ; CHECK FOR ILLEGAL COUNT BNE D.ERRA ; JUMP IF ILLEGAL MOV D.UR7,R5 ; GET PC .IF NDF,MU$DBG TST (R5) ; VALID ADDRESS? NXM IF NOT .ENDC MOVB D.P,R0 ; DID WE ENTER VIA A BREAK? BLT D.PRO3 ; NO, RETURN TO CALLER MOV D.SVR4,R4 ; GET COUNT TST D.SVR2 ; WAS COUNT SPECIFIED? BNE D.PRO1 ; NO .IF DF,MEM$BK TST MEMCTL ; WERE MEMORY BREAKS ENABLED? BEQ 1$ ; IF NOT, NORMAL OPERATION TST R0 ; THIS A BREAKPOINT (OR SINGLE STEP?) BNE 1$ ; DO USUAL FOR BREAKS. MOV #-1,R4 ; IF SO, DEFAULT IS INFINITE PROCEED BR D.PRO6 ; AND DISREGARD 1 OR 2 ALTS 1$: .ENDC MOV #1,R4 ; SET COUNT OF 1 D.PRO1: CMPB D.ALTF,#1 ; AUTOMATIC PROCEDE? BLE D.PRO6 ; BRANCH IF NOT NEG R4 ; SET TO AUTOMATIC D.PRO6: MOV R4,D.CT(R0) ; PUT AWAY COUNT D.PRO7: JSR PC,D.CRLF ; CARRIAGE RETURN LINE FEED D.PRO2: INCB D.T ; SET SPECIAL BIT TO 1 MOV R5,D.TPC ; SAVE PC FOR 11/40 KLUDGE BR D.GO5 D.PRO3: TST D.SVR2 ; COUNT SPECIFIED? BEQ D.GO3 ; NO, OK, RETURN TO CALLER OF DDT D.ERRA: JMP D.ERR ; ELSE ERROR D.PRO4: TSTB D.MACH ; 11/40,45? BEQ D.PRO5 ; NO, DON'T NEED TO KLUDGE CMP R5,D.TPC ; DID WE NOT EXECUTE THE BROKEN INSTRUCTION? BEQ D.GO4 ; YES, TRY IT AGAIN D.PRO5: CLRB D.T ; WE CAN CONTINUE NORMALLY TSTB D.S ; UNLESS WE ARE SINGLE STEPPING BEQ D.GO5 BR D.BRK2 ; IN WHICH CASE WE BREAK IMMEDIATELY ; PROCESS X - EXECUTE INSTRUCTION D.EXEC: TST D.SVR2 ; ANY INSTRUCTION? BEQ D.ERRA ; ERROR IF NOT .IF NDF,$$RSX MOV #D.SVR4,R5 ; INSTRUCTION STARTING ADDRESS .IFF MOV DDTODD,D.SVOD ;SAVE OLD ODD ADDRESS TRAP (MOD HERE A SEC) MOV #D.XGO,R5 ;FOR RSX, SPECIAL JUNK TO GET PSW .IF DF,MU$DBG .GLOBL D.PARO,D.XGO ;LET DDTMU RECOGNIZE $X SEQUENCE & ;SEND INSTRUCTION IN RCV PACKET MSG ;NOTE -- DDTMU MAY RECOGNIZE TRANSFERS TO D.XGO AND SET UP ;INST. TO START AT. MAY THEN RELOCATE IF D.PARO OR D.PARO+2 ;ARE NONZERO. USE ADDRESS OF D.PARS TO CALC. AMOUNT. .GLOBL D.PARS,D.EXE2 ;GO TO D.EXE2 SOMEHOW IF INST. FINISHES. ;DON'T REALLY SEE HOW TO DO THIS WITHOUT SOME SUBSTANTIAL ;ENLARGEMENT OF DDTKNL. HOLD OFF MORE TILL THAT IS CLEAR. .GLOBL D.TMP ;PSEUDO TRAP SVC ENTRY .IF NDF,$XOK CLR PARMAP ;NO MAPPING TO OTHER TASK NOW .IIF DF,U$ID.!MPV2., MOV #140000,UV$SPF JMP D.ERR ;DON'T KNOW HOW TO SUPPORT THIS HERE... .ENDC .ENDC .ENDC TST D.PARO ; RELOCATE FIRST WORD? BEQ D.EXE1 ; BRANCH IF NOT SUB #D.PARS+2,D.PARS; RELOCATE FIRST WORD D.EXE1: TST D.PARO+2 ; RELOCATE SECOOND WORD? BEQ D.EXE3 ; BRANCH IF NOT SUB #D.PARS+4,D.PARS+2 ; RELOCATE SECOND WORD D.EXE3: MOV D.UR7,D.SVR7 ; SAVE PC BR D.GO5 ; EXECUTE INSTRUCTION D.EXE2: .IF NDF,$$RSX .IF NDF,L$$SI MOV @#PS,D.USTA ; GET PS .IFF MFPS D.USTA .ENDC .ENDC MOV D.SVR7,D.UR7 ; RESTORE CORRECT PC JSR PC,D.SAVE ; SAVE ALL REGISTERS JMP D.BRK8 ; RETURN ; ERROR TRAPS ; NOTE THAT ALL RSX STACK ADJUSTMENTS ARE FIRST SO AN OFFSET ; FROM THE GLOBAL TRAP ENTRY MAY BE USED FOR SIMPLE ; HARDWARE EMULATION LOGIC. D.TRAV: .IIF DF, $$RSX, TST (SP)+ ;FLUSH EXTRA RSX WORD MOV #D.TRA,D.ERF ; TRAP INSTRUCTION SERVICE BR D.BRK D.EMTV: .IIF DF, $$RSX, TST (SP)+ ;FLUSH EXTRA RSX WORD MOV #D.EMT,D.ERF ;EMT INSTRUCTION BR D.BRK D.SEGV: .IIF DF,$$RSX, ADD #6,SP MOV #D.SEG,D.ERF ;SEGMENT FAULT BR D.BRK D.IOTV: MOV #D.IOT,D.ERF ;IOT INSTRUCTION BR D.BRK D.NXMT: MOV #D.NM,D.ERF ; NXM TRAP SERVICE BR D.BRK ; HANDLE BREAKPOINT D.ILGT: MOV #D.IM,D.ERF ; ILLEGAL INSTRUCTION .IF DF,$FORM$ BR D.BRK ; FALL THROUGH $X D.FFPN: MOVB #1,D.S ; SET SINGLE MODE MOV #1,D.CT ;SET PROCEED COUNT TO 1 FOR THIS INT INC D.FFPC ; BUMP COUNT SAYING IN FORMATION INT. ; FALL THROUGH TO HANDLE BREAKPOINT AS IF SINGLE MODE... ; N.B. D.REST BETTER RESTORE USER INSTRUCTIONS! .ENDC ; BREAKPOINT HANDLER D.BRK: MOV (SP)+,D.UR7 ; SAVE PC AND STATUS BIC #20,(SP) ; TURN OFF T-BIT MOV (SP)+,D.USTA ; SAVE PS JSR PC,D.SAVE ; SAVE VARIOUS REGISTERS MOV D.UR7,R5 ; GET PC, IT POINTS TO THE INSTRUCTION TST D.ERF ; TEST ADDRESS OF ERROR MESSAGE BEQ 1$ JMP D.BRK7 ; BRANCH IF ERROR 1$: ; BNE D.BRK7 ; BRANCH IF ERROR TSTB D.T ; WERE WE PROCEEDING AFTER A BREAK? BGT D.PRO4 ; YES, FIX IT UP D.BRK2: MOV #D.BKP*2,R4 ; GET A COUNTER TSTB D.S ; DID WE ENTER VIA BPT? BNE D.BRK3 .IF NDF,MU$DBG TST -(R5) ; YES, BACK UP A WORD .IFF SUB #2,R5 ; BACK UP W/O MEM REF .ENDC D.BRK3: CMP R5,D.BKTB-2(R4) ; IS THIS THE BPT? BEQ D.BRK4 ; BRANCH IF YES SUB #2,R4 BHI D.BRK3 ; LOOP, UNLESS DONE TSTB D.S ; SINGLE STEP MODE? BNE D.BRK4 JMP D.BRK6 ; NO, WE SHOULDN'T HAVE BEEN CALLED. D.BRK4: MOV R5,D.UR7 ; UPDATE THE PC, IF WE DECREMENTED IT MOVB R4,D.P ; AND SET THE BREAKPOINT FLAG .IF DF,MEM$TR ;MEMORY ADDRESS TRACER MOV R5,@MT.PTR ;STORE THIS PC ADD #2,MT.PTR ;BUMP FOR NEXT TIME CMP MT.PTR,#MT.TOP ;PAST END? BLOS 432$ ;IF LOS NO, LEAVE ALONE MOV #MT.BUF,MT.PTR ;ELSE RESET TO START 432$: .ENDC .IF DF,PR$FIL ;PROFILER ;PROFILER CODE TST PRFCTL ;IS PROFILER ON? BEQ PF$ND ;NO, SKIP BY CODE ;PROFILE CODE BY TESTING PC WE CAME FROM AND MAKING A HISTOGRAM ;OF REFERENCES. ; PRFBAS = BASE ADDRESS (LOWEST ADDRESS) OF CODE BEING PROFILED ; PRFSHF = SHIFT COUNT OF PC (0 = NO SHIFT, 1=SHIFT RIGHT 1, ; 2=SHIFT RIGHT 2 AND SO ON) ; PRFHST = HISTOGRAM STORAGE INTERNALLY, OF SIZE IN BYTES OF PRFSIZ, ; TO STORE DATA. DISPLAY VIA NORMAL DDT DISPLAY ; COMMANDS. MOV R5,-(SP) CMP R5,PRFBAS ;ADDRESS BELOW BASE TO PROFILE? BLO 1$ MOV PRFSHF,-(SP) ;GET SHIFT COUNT (WRONG SIGN BUT WE WILL FIX) SUB PRFBAS,R5 ;ADJUST PC BY BASE NEG (SP) ;MAKE PROPER SHIFT COUNT ASH (SP)+,R5 ;SHIFT DOWN BY SHIFT COUNT (MAYBE TO 0 OR -1) BIC #1,R5 ;MAKE IT A WORD DISPLACEMENT CMP R5,#PRFSIZ ;IS IT TOO BIG? BHIS 1$ ;IF SO CANNOT INCREMENT ANYTHING. INC PRFHST(R5) ;ELSE OK TO COUNT THIS INSTRUCTION. 1$: MOV (SP)+,R5 PF$ND: .ENDC .IF DF,MEM$BK ;ALLOW MEMORY "MONITOR" OF AN ADDRESS AT MEMBPA. ;IF MEMCTL IS NONZERO TST MEMCTL BEQ 1$ ;IF MEM BREAK TURNED OFF, IGNORE MOV D.BW,-(SP) MOV D.CAD,-(SP) MOV R0,-(SP) MOV R1,-(SP) MOV #2,D.BW MOV R3,-(SP) ;COUNTER CLR R3 ;...OF MEMORY BREAKS .IIF NDF,NMEM.B, NMEM.B=8. 50$: ;LOOP START ADDRESS... MOV MEMBPA(R3),D.CAD ;GET ADDRESS FOR MEMORY CELL TO MONITOR BEQ 51$ ;ZERO MEANS NONE ASSIGNED JSR PC,GETCAD ;OBTAIN DATA IN USER SPACE CMP R0,MBPVAL(R3) ;SEE IF SAME AS LAST BREAKPOINT BEQ 3$ MOV #1,D.CT ;SET NO AUTO-PROCEED NOW ;(NOTE USER HAS SYMBOLIC ACCESS TO D.CT ALREADY ;IF D.CT = -1. THEN THIS SHOULD WORK OK TO DO INFINITE PROCEED TILL WE STOP ;IT HERE. .IF NDF,XMA.PR ;PRINT nM;ADDRESS: MESSAGE GIVING WHICH MEM BRK HIT AND ADDRESS. MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) ;NEED SOME REGS MOV R4,-(SP) MOV R3,-(SP) JSR PC,D.CRLF ;NO OVERPRINT MOV (SP)+,R3 MOV (SP),R4 MOV R3,R0 ;GET MEM BRK # ASR R0 ADD #'0,R0 ;MAKE ASCII JSR PC,D.TYPE ;TYPE NUMBER MOV #'M,R0 JSR PC,D.TYPE ;THEN M MOV #';,R0 JSR PC,D.TYPE ;THEN ";" MOV MEMBPA(R3),R0 ;THEN GET ADDRESS BIC #1,R0 ;(ENSURE EVEN) JSR PC,D.RFND ;PRINT SYMBOLICALY OR IN CURRENT MODE MOV #':,R0 JSR PC,D.TYPE ;DELIMIT WITH COLON MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 .ENDC 3$: MOV R0,MBPVAL(R3) ;SAVE VALUE FOR NEXT GO 51$: ADD #2,R3 ;NOW EXAMINE NEXT MEM CELL CMP R3,#<2*NMEM.B> ;ABOVE LAST? BLO 50$ ;IF NOT KOOK SOME MORE MOV (SP)+,R3 ;ELSE RESTORE R3 AND GO ON 2$: MOV (SP)+,R1 MOV (SP)+,R0 MOV (SP)+,D.CAD MOV (SP)+,D.BW 1$: .ENDC .IF DF,CND$BK ;Permit conditional breakpoints if D.BMSK nonzero and if D.BMSK ;ANDed with value at D.OPEN is different from D.BTST then ignore ;the breakpoint. TST D.BMSK(R4) ;ANY MASK THERE? BEQ 40$ ;NO, SKIP SPECIAL ACTION TST D.OPEN(R4) ;OPEN LOC SPECIFIED? BEQ 40$ ;IF NO, SKIP TEST MOV R0,-(SP) ;YES, MUST TEST MOV D.CAD,-(SP) ;AND SAVE THIS STUFF FOR REST OF DDT MOV D.BW,-(SP) MOV #2,D.BW ;SET WORD OPERATIONS MOV D.OPEN(R4),D.CAD ;SET CURRENT ADDRESS TO TEST BIC #1,D.CAD ;AFTER ENSURING IT'S EVEN JSR PC,GETCAD ;GET THE ADDRESS OUT OF WHEREVER WE'RE DEBUGGING MOV (SP)+,D.BW ;RESTORE POINTERS MOV (SP)+,D.CAD ;R0 HAS VALUE AT D.OPEN ADDRESS MOV D.BMSK(R4),-(SP) ;GET MASK COM (SP) ;COMPLEMENT IT BIC (SP)+,R0 ;AND MASK WITH VALUE CMP R0,D.BTST(R4) ;THEN SEE IF IT'S WHAT WE WANT BEQ 41$ ;IF SO, BRANCH MOV (SP)+,R0 ;IF NOT, GET BACK R0 BR D.BRKD ;AND JUNK THIS BREAKPOINT 41$: MOV (SP)+,R0 ;IF OK, RESTORE R0 AND DROP THRU TO 40$. 40$: .ENDC TST D.CT(R4) ; AUTOMATIC PROCEDE? BMI D.BRK9 ; BRANCH IF GETTING THERE BEQ D.BRKA ; BRANCH IF AUTOMATIC PROCEDE DEC D.CT(R4) ; TEST REPEAT COUNT BLE D.BRKC ; BRANCH IF NO REPEAT D.BRKD: JMP D.PRO2 ; PROCEDE D.BRKC: MOV #1,D.CT(R4) ; RESET COUNT TO 1 D.BRKA: ;NOTHING SPECIAL IS NEEDED FOR AUTO PROCEED ON SINGLE ;INST. MODE EXCEPT ACCESS TO D.CT FOR REPEAT COUNT NEG. MOV D.CT(R4),-(SP) ; SAVE COUNT ASR R4 ; FIX IT ADD #'0,R4 ; MAKE IT ASCII MOVB R4,D.BMES+1 ; PUT IN STRING JSR PC,D.CRLF ; PREVENT OVERPRINTING MOV #D.BMES,R4 ; REST OF MESSAGE MOV #D.BMES+6,R3 ; END OF MESSAGE JSR PC,D.STYP ; TYPE IT MOV R5,R0 ; GET ADDRESS OF BREAK MOV R5,-(SP) ; AND SAVE IN CASE OF AUTO REPEAT JSR PC,D.RFND ; RELOCATE MOVB D.P,R4 ; PROCEED ALLOWED? BMI D.BRK8 ; NO MOV D.OPEN(R4),R0 ; ANY WORD TO OPEN AT BREAKPOINT? BEQ D.BRKB ; BRANCH IF NOT .IF NDF,X$QRG ;PROVIDE ABILITY TO EXECUTE A Q REG IF NUMBER TO BE EXAMINED IS LOWER THAN ;THE NUMBER OF BREAKPOINTS. EXECUTES THAT Q REG AT THE BREAK INSTEAD OF ;DISPLAYING A NUMBER. (NEAT!) 21$: CMP #D.BKP,R0 ; EXECUTE Q REGISTER? BLO 22$ ; NOPE, DUMP LOCATION MOV R0,R4 ; COPY Q REG NUMBER CLR D.SVR2 ; MARK AS EXECUTION MOV D.QSPT,-(SP) ; SAVE STACK POINTER JSR PC,D.Q ; EXECUTE MACRO 26$: JSR PC,D.DCD ; EXECUTE COMMAND CMP D.QSPT,(SP) ; DONE WITH MACRO? BHI 26$ ; NOT YET TST (SP)+ ; KILL GARBAGE ON STACK BR D.BRKB ; AND FALL THROUGH ;JUST WHERE IT LOOKS FOR # TO DISPLAY AT BREAK. COMMAND DECODER ;ALLOWS Q REG TO EXECUTE AT BREAK. IF ADDRESS < 22$: .ENDC MOV R0,D.DOT ; PUT IN CURRENT WORD JSR PC,D.TTAB ; TYPE A TAB JSR PC,D.OP3 ; OPEN IT D.BRKB: MOV (SP)+,R5 ; RESTORE R5 TST (SP)+ ; AUTOMATIC PROCEDE? ;DEFINE .NAP. IF USING OLD LOGIC, NO AUTOPROCEED WITH DISPLAY ;DON'T DEFINE IF ALLOWING AUTOPROCEED WITH DISPLAY .IF DF,.NAP. BNE D.BRK8 ; RETURN IF NOT .IFF BGT D.BRK8 ; RETURN IF NOT .IIF DF,.RPT., BMI D.BRKD .ENDC XX.XXX=0 .IF DF,$$RSX .IF DF,XTCOM XX.XXX=1 ;OK TO TEST COMMON .ENDC .IFF ;NOT RSX XX.XXX=1 ;OK IF STAND ALONE .IFT .IF EQ,MMM11 ;IF RSX11D, WE CAN USE FULL DUPLEX XX.XXX=2 ;SPECIAL CROCK CODE FOR 11D MAPPED .ENDC .IF DF,MV3.2 ;11M V3.2 MAY HAVE FULL DUPLEX TERMINAL FOR KROCK XX.XXX=2 .ENDC .ENDC .IF EQ, TSTB @#D.RCSR ; CHARACTER TYPED? BMI D.BRK8 ; EXIT IF SO .ENDC .IF EQ, .MCALL RDAF$S MOV R5,-(SP) ;IF CAN GET AWAY WITH EF 23 READ... SUB #12,SP ;READ EV FLGS TO STACK MOV SP,R5 ;AVOID MORE Z ERRS RDAF$S R5 ;FLAGS TO STACK BIT #100,2(R5) ;EVENT FLAG 23. SET? BEQ 1$ ;IF SO, READIN OF KB OVER ADD #12,SP ;ELSE NOT SO GO ON MOV (SP)+,R5 ;RESTORE R5 THEN BR D.BRK8 ;HERE READ WAS OVER SO STOP 1$: ADD #12,SP ;HERE READ STILL PENDS SO GO ON MOV (SP)+,R5 ;AFTER STACK FIXUP .ENDC JMP D.PRO7 ; CONTINUE BREAKPOINT D.BRK9: TST R4 ; THIS THE SINGLE INST. BKPT? BNE 1$ ; NO, NORMAL TREATMENT CMP D.CT(R4),#-1 ;-1 MEANS INFINITE REPEATS BEQ D.BRKD ;SO JUST PROCEED & NEVER BREAK 1$: INC D.CT(R4) ; COUNT 'EM OFF .IF DF,.NAP. BMI D.BRKD ; PROCEDE IF STILL NEGATIVE BR D.BRKA ; DO THE BREAK .IFF BR D.BRKA ; PROCEED IF NEGATIVE AFTER TYPEOUT .ENDC D.BRK6: MOV #D.BE,D.ERF ; ERROR: UNEXPECTED BREAK D.BRK7: MOV D.UR7,R0 ; GET ADDRESS OF BREAK JSR PC,D.RFND ; RELOCATE MOV D.ERF,R3 ; GET CODE MOV R3,R4 ; OBTAIN END ADD #4,R3 ; BY ADDING 4 TO BEGIN JSR PC,D.STYP ; TYPE MESSAGE CLR D.ERF ; REMOVE TRACES OF THIS ENTRY MOVB #-1,D.P ; DISALLOW PROCEED CLRB D.T ; TURN OFF BIT D.BRK8: JMP D.DCD ; RETURN ; CONVERT 3 ASCII CHARACTERS AT (R0) TO RAD50 WORD IN R0 D.RD50: MOV R2,-(SP) ; SAVE R2 MOV R5,-(SP) ; SAVE R5 AS SCRATCH MOV R1,-(SP) ; SAVE R1 ALSO MOV #-3,-(SP) ; CHARACTER LOOPER CLR R2 ; NOW CLEAR IT D.RD51: CLR R1 ; OFFSET OF CHARACTERS MOV D.BW,-(SP) ;SAVE CONTENTS OF D.BW MOV R0,-(SP) ;AND ADDR MOV D.CAD,-(SP) ;AND CAD MOV R0,D.CAD ;SET TO LOCATE CONTENT OF R0 MOV #1,D.BW ;BYTE MODE JSR PC,GETCAD ;DO THE LOOKUP IN ANY SPACE MOV R0,R5 ;RESULT IN R0 MOV (SP)+,D.CAD MOV (SP)+,R0 MOV (SP)+,D.BW D.RD52: CMPB D.RDTB(R1),R5 ; CHARACTER MATCH? BEQ D.RD53 ; BRANCH IF SO INC R1 ; NEXT CHARACTER CMP R1,#D.ENTB ; AT END OF TABLE BLT D.RD52 ; BRANCH IF NOT D.ERRF: JMP D.ERR ; BAD CHARACTERS D.RD53: ASL R2 ; MULTIPLY BY 2 ASL R2 ; MULTIPLY BY 4 ASL R2 ; MULTIPLY BY 8 MOV R2,-(SP) ; STORE AWAY ASL R2 ; MULTIPLY BY 16 ASL R2 ; MULTIPLY BY 32 ADD (SP)+,R2 ; ADD 8X TO MAKE IT 40X ADD R1,R2 ; PUT IN NEW CHARACTER INC R0 ; POINT TO NEXT CHARACTER INC (SP) ; INCREMENT LOOPER BMI D.RD51 ; BRANCH IF MORE TST (SP)+ ; RESET STACK MOV R2,R0 ; RESULT IN R0 MOV (SP)+,R1 ; RESTORE R1 MOV (SP)+,R5 MOV (SP)+,R2 ; RESTORE R2 RTS PC ; RETURN ; CONVERT RAD50 WORD IN R0 TO THREE ASCII CHARACTERS AT (R1) D.CHAR: MOV R1,R3 ; INDEX HERE SINCE D.DIVD WILL USE R1 MOV #1600.,R2 ; OTHER OPERAND JSR PC,D.DIVD ; DIVIDE THEM MOV D.CAD,-(SP) MOV D.BW,-(SP) MOV R0,-(SP) MOV R4,-(SP) ;SAVE ARGS MOV #1,D.BW ;SET BYTE MODE MOV R3,D.CAD ;SET OUT ADDRESS MOVB D.RDTB(R0),R4 ;GET DATA INC R3 ;BUMP R3 JSR PC,PUTCAD ;STASH THE DATA BYTE MOV (SP)+,R4 ;RESTORE R4 MOV (SP)+,R0 ;AND R0 MOV (SP)+,D.BW MOV (SP)+,D.CAD ;THEN GLOBAL VRBLS. ; MOVB D.RDTB(R0),(R3)+; MOVE A CHARACTER IN MOV #40.,R2 ; OPERAND MOV R1,R0 ; GET NEW NUMERATOR JSR PC,D.DIVD ; DIVIDE THEM MOV D.CAD,-(SP) MOV D.BW,-(SP) MOV R0,-(SP) MOV R4,-(SP) ;SAVE ARGS MOV #1,D.BW ;SET BYTE MODE MOV R3,D.CAD ;SET OUT ADDRESS MOVB D.RDTB(R0),R4 ;GET DATA INC R3 ;BUMP R3 JSR PC,PUTCAD ;STASH THE DATA BYTE MOV (SP)+,R4 ;RESTORE R4 MOV (SP)+,R0 ;AND R0 MOV (SP)+,D.BW MOV (SP)+,D.CAD ;THEN GLOBAL VRBLS. ; MOVB D.RDTB(R0),(R3)+; MOVE ANOTHER CHARACTER IN MOV D.CAD,-(SP) MOV D.BW,-(SP) MOV R0,-(SP) MOV R4,-(SP) ;SAVE ARGS MOV #1,D.BW ;SET BYTE MODE MOV R3,D.CAD ;SET OUT ADDRESS MOVB D.RDTB(R1),R4 ;GET DATA INC R3 ;BUMP R3 JSR PC,PUTCAD ;STASH THE DATA BYTE MOV (SP)+,R4 ;RESTORE R4 MOV (SP)+,R0 ;AND R0 MOV (SP)+,D.BW MOV (SP)+,D.CAD ;THEN GLOBAL VRBLS. ; MOVB D.RDTB(R1),(R3)+; MOVE LAST CHARACTER IN MOV R3,R1 ; RESTORE FOR THE USER RTS PC ; RETURN ; SAVE THE WORLD .IF DF,$$RSX .PSECT ..DDTD D.ASTF: .WORD 0 ;AST DISABLED FLAG .PSECT ..DDTP,RO,I ;CODE .ENDC D.SAVE: MOV (SP)+,D.XXX ; PICK UP RETURN ADDRESS FROM STACK .IIF DF,$$RSX, MOV $DSW,DDTDSW ;SAVE DSW IF RSX VERSION .IIF DF,$$RSX, DSAR$S ;DISABLE AST RECOGNITION .IIF DF,$$RSX, MOV @#$DSW,D.ASTF .IF NDF,DULMOD ; DULMOD DEFINED ALLOWS DDT TO RUN IN ;KERNEL TO DEBUG USER MODE MOV SP,D.UR6 ; SAVE USER STACK ADDRESS .IFF MFPI SP ; GET SP FROM OLD SPACE MOV (SP)+,D.UR6 ; GET USER SP FOR EXAMINING .ENDC MOV #D.UR6,SP ; SET TO INTERNAL STACK MOV R5,-(SP) ; SAVE MOV R4,-(SP) ; REGISTERS MOV R3,-(SP) ; 0 MOV R2,-(SP) ; THRU MOV R1,-(SP) ; 5 MOV R0,-(SP) ; HERE .IIF DF,MU$DBG, JSR PC,TSKSAV ;SAVE OTHER TSK REG POINTERS ;NOTE THAT INPUT MSG PROCESSING SAVES ADDRESSES MOSTLY. THIS IS MAINLY ;FOR OTHER CLEANUPS. .IF DF,$D$FPU TST FPCTL ;ANY FPU SAVE/RESTORE ACTIVE? BEQ 2$ ;IF NOT, SKIP CALL TO SAVE AC'S JSR PC,FSAV ;IF SO, SAVE FP AC'S AND STATUS 2$: .ENDC .IF DF,D.GDP TRAP 72 ; USECLR D.SAV9: NOP ; MAY HAVE USERET TRAP 107 ; SCRUNB .ENDC .IF DF,$FORM$ TST D.FFPC ;SEE IF FORMATION INTERRUPT BNE 1$ ;IF SO ALWAYS SAVE BREAKPOINTS .ENDC TST D.SD.T ; TEST D.S AND D.T BNE D.SAV3 ; SKIP BREAKPOINTS IF SO 1$: CLR R4 ; REMOVE ALL BREAKPOINTS D.SAV1: MOV D.BKTB(R4),R5 ; GET ADDRESS OF BREAKPOINT BEQ D.SAV2 ; BRANCH IF NOT FILLED .IF DF,X$OVL MOV OVRBRK,-(SP) ;SEE IF THIS IS SPECIAL BPT ADD #2,(SP) ;BY PC COMPARE CMP D.UR7,(SP)+ ;OF OVRBRK+2 WITH PC ;IF THIS PC NOT SAME AS SPECIAL ONE, TREAT BREAK NORMALLY. BNE 1$ ;BR IF NOT TO DO SAVE TST OVRBRK ;(ZERO IS NOT FILED IN #) BEQ 1$ ;IF 0, NORMAL SAVE CMP R5,OVRBRK ;THIS BPT THE SPECIAL ONE? BNE D.SAV2 ;IF NOT, NO ACTION 1$: .ENDC .IF NDF,DULMOD ..TMP=0 .IIF DF,MU$DBG,..TMP=1 .IIF DF,U$ID.,..TMP=1 .IIF DF,MPV2.,..TMP=1 .IF EQ,..TMP ; .IF NDF,MPV2.!U$ID.!MU$DBG ;FOR NON INTERTASK DEBUGS ;SAVE IN OUR ADDRS MOV D.UIN(R4),(R5) ; RESTORE USER'S INSTRUCTION .IFF .IIF DF,U$ID.!MPV2., MOV UV$SPF,-(SP) .IIF DF,U$ID.!MPV2., MOV #1,UV$SPF ;SET I SPACE FLAG FOR USER SPACE MOV D.BW,-(SP) MOV D.CAD,-(SP) ;RESTORE INSTRUCTIONS TO OTHER TASK MOV R4,-(SP) MOV #2,D.BW ;SET WORD MODE MOV D.UIN(R4),R4 ;GET SAVED INSTRUCTION MOV R5,D.CAD ;ADDR IN OTHER SPACE JSR PC,PUTCAD ;STORE INSTRUCTION MOV (SP)+,R4 MOV (SP)+,D.CAD MOV (SP)+,D.BW ;RESTORE REST OF CONTEXT .IIF DF,U$ID.!MPV2., MOV (SP)+,UV$SPF ;RESTORE I/D SPACE FLAG .ENDC .IFF ;DUAL MODE DDT (IN KERNEL MODE NORMALLY) MOV D.UIN(R4),-(SP) ;RESTORE... MTPI (R5) ;...USER'S INSTRUCTION .ENDC D.SAV2: TST (R4)+ ; LOOP CMP R4,#D.BKP*2 ; AT END? BLT D.SAV1 ; RE-LOOP UNTIL DONE D.SAV3: MOV #340,R1 ; PS .IF NDF,$$RSX MOV #4,R0 ; START FILLING AT WORD 4 MOV (R0),-(SP) ; 4 MOV #D.SAV5,(R0)+ ; INTERNAL NXMS MOV (R0),-(SP) ; 6 MOV R1,(R0)+ ; SET VECTOR PS MOV (R0),-(SP) ; 10 MOV #D.SAV5,(R0)+ ; INTERRUPT FOR ILLEGAL INSTRUCTION MOV (R0),-(SP) ; 12 MOV R1,(R0)+ ; SET VECTOR PS MOV #D.BRK,(R0)+ ; BPT VECTOR MOV R1,(R0) ; SET VECTOR PS MOV @#D.RCSR,-(SP) ; SAVE KEYBOARD STATUS CLR @#D.RCSR ; TURN OFF ALL INTERRUPTS .IF DF,D.KSR MOV @#D.TCSR,-(SP) ; SAVE PRINTER STATUS CLR @#D.TCSR ; REMOVE ALL ENABLES .ENDC MOVB #2,D.MACH ; SET MACHINE TO 11/45 SXT R1 ; 11/40,45 INSTRUCTION CMPB D.MACH,#1 ; 11/15? BEQ D.SAV4 ; BRANCH IF NOT .IFTF ;CONDITION OUT FILLIN OF D.GO1 SINCE WE ASSEMBLE DESIRED CODE IN. .IF DF,UZ$DF .IF NDF,$RSXM MOV #RTT,D.GO1 ; USE RTT INSTRUCTION .ENDC .ENDC .IFT D.SAV4: TST @#177772 ; WORD ONLY EXISTS ON 11/45 MOV #D.ERR,@#4 ; RESET NXM ADDRESS MOV #D.ILGT,@#10 ; ILLEGAL INSTRUCTION .IFF ;$$RSX DEFINED .IF DF,XTCOM; IF EXTERNAL PAGE COMMON MOV @#D.RCSR,-(SP);SAVE KBD CSR7S CLR @#D.RCSR MOV @#D.TCSR,-(SP) .ENDC MOVB #2,D.MACH ;SET 11/45 STANDARD CPU TYPE. .IIF DF,$RSXM, MOVB #0,D.MACH ;SET 11/05 IF RSX11M UNMAPPED .IIF DF,$RSXMM, MOVB #1,D.MACH ;SET 11/40 IF MAPPED .IIF DF,$D$FPU, MOVB #2,D.MACH .ENDC .IF DF,$$RSX ;SET INTERNAL ERROR FORMS SVDB$S #D.TINS,#11 ;SET INTERNAL DEBUG TRAPS .ENDC JMP @D.XXX ;RETURN TO CALLER .IF DF,$$RSX D.TINS: .WORD D.ERR ;INTERNAL DDT TRAPS .WORD D.ERSG ;MEM SEG ERR IS TO POP EXTRA CELL .WORD D.ERR,D.ERR,D.ERR ;BPT,IOT, ILL .WORD D.EVVV,D.EVVV ;EMT,TRAP .WORD D.ERR D.EVVV: TST (SP)+ ;POP EXTRA STACK CELL JMP D.ERR DDTODD: .WORD D.NXMT ;ODD ADDRESS ERROR TRAPPER .WORD D.SEGV ;SEGMENT FAULT .WORD D.BRK ;BPT OR T-BIT SET DDTIOT: .WORD D.IOTV ;IOT INSTRUCTION DDTRES: .WORD D.ILGT ;ILLEGAL INSTRUCTION DDTEMT: .WORD D.EMTV ;NON-RSX EMT DDTTRP: .IF NDF,MSX11D .WORD D.TRAV ;TRAP INSTRUCTION .IFF .WORD 0 .ENDC DDTFPP: .WORD D.ILGT ;11/40 FPP FAULT .WORD D.SEGV ;MEMORY PARITY ERROR .WORD 0 ;SAFETY WORD ;END OF SST TABLE USED FOR RSX DDT SST VECTORING. .IF EQ,MMM11 .MCALL RDEF$S,CLEF$S,SETF$S ;READ/CLR/SET SINGLE EVENT FLAGS .IFF .MCALL CLEF$S,SETF$S .ENDC .ENDC ; JMP @D.XXX ; RETURN D.SAV5: DECB D.MACH ; IT FAILED, DIFFERENT MACHINE RTI ; RETURN .IF DF,$D$FPU ;F.P.U. SAVE/RESTORE ROUTINES ;LEAVE REGS ALONE IN ALL CASES. AC0=%0 AC1=%1 AC2=%2 AC3=%3 AC4=%4 AC5=%5 ;DEFINE FLOATING REGS .PSECT ..DDTD FPCTL: .WORD $D$FPU ;CONTROL. SAVE/RESTORE FP REGS IF NONZERO FPSTAT: .WORD 40000 ;FPU STATUS. SET INITIAL INTERRUPT DISABLE. FPAC0: .WORD 0,0,0,0 FPAC1: .WORD 0,0,0,0 FPAC2: .WORD 0,0,0,0 FPAC3: .WORD 0,0,0,0 FPAC4: .WORD 0,0,0,0 FPAC5: .WORD 0,0,0,0 ;FP AC STORAGE .PSECT ..DDTP,RO,I ;CODE FSAV: STFPS FPSTAT ;SAVE FP STATUS LDFPS #40200 ;SET DBL PREC SHORT INT NO INTS MOV R0,-(SP) ;PRESERVE R0 MOV #FPAC0,R0 ;SET UP SAVE STF AC0,(R0)+ STF AC1,(R0)+ STF AC2,(R0)+ STF AC3,(R0)+ ;SAVE EASY AC'S LDF AC4,AC0 ;GET AC4 TO AC0 STF AC0,(R0)+ LDF AC5,AC0 ;COPY AC5 TO AC0 STF AC0,(R0)+ LDF FPAC0,AC0 ;RESTORE AC0 TO OLD VALUE MOV (SP)+,R0 ;RESTORE R0 FROM CALL RTS PC ;THEN BACK ;RESTORE F.P. HARDWARE TO VALUE AT FSAV CALL FRST: LDFPS #40200 ;SET STATUS TO DBL PREC NO INTERRUPTS MOV R0,-(SP) ;NEED A GEN'L REG MOV #FPAC1,R0 LDF (R0)+,AC1 LDF (R0)+,AC2 LDF (R0)+,AC3 LDF (R0)+,AC0 ;GET AC4 DATA STF AC0,AC4 ;AND PUT THERE LDF (R0)+,AC0 ;GET AC5 DATA STF AC0,AC5 ;AND PUT THERE LDF FPAC0,AC0 ;RESTORE AC0 TO OLD VALUE LDFPS FPSTAT MOV (SP)+,R0 ;GET BACK CALL R0 RTS PC .ENDC ; RESTORE THE WORLD AS WE FOUND IT D.REST: MOV (SP)+,D.XXX ; GET RETURN ADDRESS FROM STACK TST D.SD.T ; TEST D.S AND D.T BNE D.RES3 ; SKIP BREAKPOINTS IF SO MOV #-2,R4 ; RESTORE ALL BREAKPOINTS D.RES1: MOV D.BKTB(R4),R5 ; GET ADDRESS OF BREAKPOINT BEQ D.RES2 ; BRANCH IF NO BREAKPOINT .IF DF,X$OVL ;CONDITION TWICE SINCE RESUME OUGHT TO BE OK AFTER BREAK. .IF NDF,XX$OVL MOV OVRBRK,-(SP) ;SEE IF PC=OVRBRK+2 ADD #2,(SP) CMP D.UR7,(SP)+ ;IF NOT = THEN NO SPECIAL ACTION BNE 1$ ;SO SKIP TO NORMAL TST OVRBRK ;OVRBRK=0 IS NOTHING TO DO ALSO BEQ 1$ CMP R5,OVRBRK ;IF SPECIAL ONLY DO OVRBRK BPT BNE D.RES2 ;ELSE SKIP RESTORE STUFF 1$: ;TARGET LABEL .ENDC .ENDC .IF NDF,DULMOD ..TMP=0 .IIF DF,MU$DBG,..TMP=1 .IIF DF,U$ID.!MPV2.,..TMP=1 .IF EQ,..TMP ; .IF NDF,MU$DBG!U$ID.!MPV2. MOV (R5),D.UIN(R4) ; SAVE CONTENTS OF USER LOCATION MOV #BPT,(R5) ; PUT BREAKPOINT THERE .IFF .IF DF,U$ID.!MPV2. MOV UV$SPF,-(SP) MOV #1,UV$SPF ;FLAG I SPACE .ENDC MOV D.BW,-(SP) ;SAVE DDT CONTEXT MOV D.CAD,-(SP) MOV R4,-(SP) MOV #2,D.BW ;SET WORD MODE MOV R5,D.CAD ;ADDR IN R5 JSR PC,GETCAD ;GET INSTRUCTION WORD MOV @SP,R4 ;RELOAD R4 ADDR MOV R0,D.UIN(R4) ;SAVE INSTRUCTION HERE FOR RESTORE LATER MOV #BPT,R4 ;READY TO INSERT THE BPT JSR PC,PUTCAD ;NOW PLACE BPT ON TASK INSTRUCTION MOV (SP)+,R4 MOV (SP)+,D.CAD MOV (SP)+,D.BW ;RESTORE CONTEXT .IIF DF,U$ID.!MPV2., MOV (SP)+,UV$SPF ;RESTORE I/D CONTEXT .ENDC .IFF .IF NDF,$BSXMU ;IF BKPT SET DIDNT SAVE INST DO HERE MFPI (R5) MOV (SP)+,D.UIN(R4) ;SAVE USER'S INSTRUCTION .ENDC ;DDT IN KERNEL MODE (DUAL MODE)... MOV #BPT,-(SP) ;SHOVE BPT THERE MTPI (R5) .ENDC D.RES2: SUB #2,R4 ; DECREMENT BGE D.RES1 ; RE-LOOP UNTIL DONE D.RES3: MOV #D.STK,SP ; SET STACK POINTER TO BASE .IF NDF,$$RSX .IIF DF,D.KSR,MOV (SP)+,@#D.TCSR; PUT TELETYPE STATUS BACK MOV (SP)+,@#D.RCSR ; PUT KEYBOARD STATUS BACK MOV #12,R0 ; RESTORE HIS VECTORS MOV (SP)+,(R0) ; 12 MOV (SP)+,-(R0) ; 10 MOV (SP)+,-(R0) ; 6 MOV (SP)+,-(R0) ; 4 .ENDC .IF DF,$$RSX .IF DF,XTCOM MOV (SP)+,@#D.TCSR MOV (SP)+,@#D.RCSR .ENDC .ENDC ; WE DO NOT ALTER SST TABLE FOR RSX, SO NO SAVE/RESTORE ;OF VECTORS IS NEEDED OR DESIRABLE. .IIF DF,D.GDP,TRAP 144 ; USERET .IF DF,$D$FPU TST FPCTL ;ARE WE TO RESTORE F.P. REGS ETC? BEQ 1$ ;IF NOT SKIP JSR PC,FRST ;IF SO RESTORE THE STUFF 1$: .ENDC MOV (SP)+,R0 ; RESTORE MOV (SP)+,R1 ; USER MOV (SP)+,R2 ; REGISTERS MOV (SP)+,R3 ; 0 MOV (SP)+,R4 ; THRU MOV (SP)+,R5 ; 5 .IF NDF,DULMOD MOV (SP),SP ; RESTORE USER STACK .IFF MOV (SP),-(SP) ; GET STACK MTPI SP ;AND SAVE IN USER STACK .ENDC .IF DF,$$RSX SVDB$S #DDTODD,#11 ; SET PROGRAM TYPE TRAP CATCHER TSTB D.ASTF ; ANY AST'S DISABLED? BMI 10$ ; IF NOT, LEAVE THEM ALONE ENAR$S ; IF SO, TURN THEM BACK ON 10$: .ENDC .IIF DF,$$RSX, MOV DDTDSW,@#$DSW ;RESTORE DSW IF IN RSX ;TSKRSU FORMATS AND SENDS AN INTERTASK MSG WITH PC,PS TO START WITH ;WHICH CAUSES THE REMOTE TASK'S "BPT KERNEL" TO CONTINUE THE TASK. ;IT THEN RETURNS TO ITS "MAIN PROGRAM" IN THIS TASK WHICH MUST BE ;CONSTRUCTED TO REENABLE ASTS AND FORCE THE ASTS TO IMITATE BPT ;ENTRIES ON RETURN. (SEE CODE IN MXSUBS WHICH DOES THIS). ; ; *** NOTE THIS ROUTINE MUST REPLACE D.UR7 WITH CORRECT MAIN ADDRESS ; PRIOR TO RETURN SO DDT TASK STAYS IN ITS IDLE LOOP WHILE THE TASK ; BEING DEBUGGED GOES WHERE IT SHOULD GO. .IIF DF,MU$DBG, JSR PC,TSKRSU ;RESUME THE TASK VIA MSG TO IT. JMP @D.XXX ; AND RETURN ; TYPE R0 IN ADDRESS FORM D.RFND: MOV R1,-(SP) ; SAVE R1 MOV R0,-(SP) ; SAVE ADDRESS FOR LATER CMP R0,D.SVR4 ; IS IT THE ADDRESS WE ARE LOOKING FOR? BNE D.RFN2 ; BRANCH IF NOT INCB D.FIND ; MARK IT FOUND D.RFN2: TST D.IFMT ; ABSOLUTE ADDRESSING? BNE D.RFN7 ; BRANCH IF SO JSR PC,D.GTSM ; GET SYMBOL (IF ANY) TST R1 ; ANY SYMBOL? BNE D.RFN8 ; BRANCH IF SO CMP 4(SP),#D.SLST ;COME FROM SEARCH ROUTINE? BNE D.RFN7 ;NO, DON'T DO ANYTHING UNUSUAL TST D.IFMT ;SEE IF NEGATIVE (PSEUDO-ASSEMBLY MODE) BMI D.RFN1 ;IF SO, FORGET THIS STUFF BR D.RFN7 D.RFN8: ;CONTINUE IF FOUND SYMBOL ; BEQ D.RFN7 ; BRANCH IF NOT MOV R0,-(SP) ; SAVE OFFSET VALUE MOV #6,-(SP) ; REPEAT COUNT D.RFN5: MOVB (R1)+,R0 ; GET CHARACTER CMPB R0,#40 ; IS IT A BLANK? BEQ D.RFN6 ; DONE IF SO JSR PC,D.TYPE ; TYPE IT DEC (SP) ; DECREMENT COUNT BGT D.RFN5 ; LOOP IF MORE D.RFN6: TST (SP)+ ; RESET STACK MOV (SP)+,R1 ; GET OFFSET BEQ D.RFN1 ; BRANCH IF NONE MOV #'+,R0 ; MAKE A PLUS JSR PC,D.TYPE ; TYPE IT MOV R1,R0 ; GET OFFSET D.RFN7: JSR PC,D.TYPN ; TYPE THE NUMBER D.RFN1: MOV (SP),D.LASW ; LAST TYPED WORD MOV (SP)+,D.LASV ; LAST TYPED ADDRESS MOV (SP)+,R1 ; RESTORE R1 RTS PC ; RETURN ; CLOSE WORD OR BYTE D.CLSE: TST R2 ; IF NO NUMBER WAS TYPED THERE IS BEQ D.CLS1 ; NOTHING TO CLOSE CMP D.CAD,#177776 ; ANY OPEN WORD? BEQ D.CLS1 ; BRANCH IF NOT CLR D.LFIN ; NO LINE FEED INCREMENT CMP #1,D.BW ; BYTE MODE? BEQ D.CLS2 ; JUMP IF BYTE MODE MOV D.CAD,R2 ; WORD ADDRESS MOV R0,-(SP) ;SAVE R0 AROUND CALL TO PUTCAD ADD #2,R2 ;"AUTOINCREMENT" R2 JSR PC,PUTCAD ;STASH DATA IN R4 AT D.CAD MOV (SP)+,R0 ;BACK WITH R0 ; MOV R4,(R2)+ ; STORE VALUE MOV R2,R4 ; PUT INTO R4 FOR COMPUTATION SUB D.CADC,R4 ; SUBTRACT COPY BGT D.CLS1 ; BRANCH IF NO MORE MOV #2,D.LFIN ; LINE FEED INCREMENT ; MOV D.PARS,(R2) ; MOVE ANOTHER WORD (2 OR 3 WORD INST) ; SUB D.PARO,(R2)+ ; RELOCATE WORD MOV R4,-(SP) MOV D.PARS,R4 ;MAKE DATA UP IN R4 SUB D.PARO,R4 MOV D.CAD,-(SP) ;SAVE D.CAD MOV R0,-(SP) ;ALSO R0 MOV R2,D.CAD ;SAVE ADDR JSR PC,PUTCAD ADD #2,R2 MOV (SP)+,R0 MOV (SP)+,D.CAD MOV (SP)+,R4 ;BACK WITH DATA TST R4 ; THIRD PARAMETER? BEQ D.CLS1 ; BRANCH IF NOT MOV #4,D.LFIN ; LINE FEED INCREMENT MOV R4,-(SP) MOV D.PARS+2,R4 ;MAKE DATA UP IN R4 SUB D.PARO+2,R4 MOV D.CAD,-(SP) ;SAVE D.CAD MOV R0,-(SP) ;ALSO R0 MOV R2,D.CAD ;SAVE ADDR JSR PC,PUTCAD MOV (SP)+,R0 MOV (SP)+,D.CAD MOV (SP)+,R4 ;BACK WITH DATA ; MOV D.PARS+2,(R2) ; PUT THIRD WORD IN ; SUB D.PARO+2,(R2) ; RELOCATE WORD BR D.CLS1 ; FINISH UP D.CLS2: MOV R0,-(SP) JSR PC,PUTCAD ;STORE BYTE IN R4 AT D.CAD MOV (SP)+,R0 ;RESTORE R0 ; MOVB R4,@D.CAD ; STORE BYTE D.CLS1: MOV #177776,D.CAD ; CLOSE WORD RTS PC ; RETURN ; SUBROUTINE TO TYPE @D.CAD IN NUMBER FORM D.CADV: CMP #1,D.BW ; BYTE MODE? BEQ D.CAD1 ; BRANCH IF SO JSR PC,GETCAD ; GET OPERAND. ; MOV @D.CAD,R0 ; GET OPERAND JSR PC,D.RFND ; TYPE NUMBER BR D.ASC2 ; RETURN D.CAD1: JSR PC,GETCAD ; GET OPERAND ; MOVB @D.CAD,R0 ; GET OPERAND BIC #177400,R0 ; CLEAR HIGH BITS JSR PC,D.TYPN ; TYPE IT BR D.ASC2 ; RETURN ; SUBROUTINE TO TYPE @D.CAD IN ASCII FORM D.ASCI: MOV D.CAD,R5 ; GET ADDRESS MOV D.BW,-(SP) MOV #1,D.BW JSR PC,GETCAD ;LOAD BYTE MOV (SP)+,D.BW INC R5 ; MOVB (R5)+,R0 ; GET FIRST CHARACTER BIC #177400,R0 ; CLEAR HIGH BITS MOV R0,D.LASV ; LAST TYPED DATA MOV R0,D.LASW ; LAST TYPED WORD TOO JSR PC,D.TYPE ; TYPE IT MOV D.BW,-(SP) MOV D.CAD,-(SP) MOV #1,D.BW MOV R5,D.CAD JSR PC,GETCAD MOV (SP)+,D.CAD MOV (SP)+,D.BW ;GET BYTE ; MOVB (R5),R0 ; GET NEXT CHARACTER ROR R5 ; EXAMINE LOW BIT BCC D.ASC2 ; BRANCH IF CLEAR JSR PC,D.TYPE ; TYPE IT D.ASC3: MOV D.BW,-(SP) ; SAVE BYTE/WORD FLAG MOV R0,-(SP) ;ALSO SAVE R0 MOV #2,D.BW ;SET TO LOAD WORD JSR PC,GETCAD ;LOAD TO R0 MOV R0,D.LASV MOV R0,D.LASW ;SAVE DATA MOV (SP)+,R0 MOV (SP)+,D.BW ;RESTORE OLD STUFF ; MOV @D.CAD,D.LASV ; LAST TYPED DATA ; MOV @D.CAD,D.LASW ; LAST TYPED WORD TOO D.ASC2: CLR D.LFIN ; TURN OFF LINE-FEED SKIPPING D.RTS: RTS PC ; RETURN ; SUBROUTINE TO TYPE @D.CAD IN MULTI-BYTE FORM D.PART: MOV D.BW,-(SP) ;SAVE BYTE/WORD MOV R0,-(SP) MOV #2,D.BW JSR PC,GETCAD ;GET CURRENTLY ADDRESSED WORD MOV R0,R5 ;INTO R5 MOV (SP)+,R0 MOV (SP)+,D.BW ;RESTORE D.BW ; MOV @D.CAD,R5 ; GET WORD MOV #16.,-(SP) ; BIT COUNT D.PAR5: MOV R5,R0 ; ACCUMULATOR FOR BYTE MOV #177777,R3 ; MASK FOR BYTE MOV D.SIZE,R2 ; BYTE SIZE D.PAR1: ASR R5 ; REMOVE ONE BIT ASL R3 ; ONE MORE BIT IN MASK DEC (SP) ; ONE LESS BIT IN WORD BLE D.PAR2 ; EXIT IF DONE DEC R2 ; ONE LESS BIT IN BYTE BGT D.PAR1 ; LOOP IF NOT DONE D.PAR2: BIC R3,R0 ; MASK WORD JSR PC,D.TYPN ; TYPE BYTE TST (SP) ; ALL DONE? BLE D.PAR4 ; BRANCH IF SO MOV #',,R0 ; COMMA JSR PC,D.TYPE ; TYPE IT BR D.PAR5 ; GET NEXT BYTE D.PAR4: TST (SP)+ ; FIX STACK BR D.ASC3 ; RETURN ; SUBROUTINE TO TYPE @D.CAD IN RAD50 FORM D.RADC: MOV D.BW,-(SP) MOV #2,D.BW JSR PC,GETCAD ;GET @D.CAD TO R0 IN ANY SPACE MOV (SP)+,D.BW ; MOV @D.CAD,R0 ; PUT VALUE IN R0 MOV #D.SYM,R1 ; ADDRESS FOR RESULT .IIF DF,$VMEM, MOV PARMAP,-(SP) ;NO VIRTUAL MAP HERE .IIF DF,$VMEM, CLR PARMAP .IF DF,U$ID.!MPV2. MOV UV$SPF,-(SP) MOV #140000,UV$SPF ;SET NO MAPPING SPECIAL STUFF .ENDC JSR PC,D.CHAR ; MAKE CHARACTERS OF IT .IIF DF,U$ID.!MPV2., MOV (SP)+,UV$SPF .IIF DF,$VMEM,MOV (SP)+,PARMAP MOV #D.SYM,R4 ; ADDRESS OF FIRST CHARACTER MOV #D.SYM+2,R3 ; ADDRESS OF LAST CHARACTER JSR PC,D.STYP ; TYPE THEM BR D.ASC3 ; DONE ; SUBROUTINE TO TYPE @D.CAD IN INSTRUCTION FORMAT D.INST: MOV D.CAD,R5 ; PUT CURRENT ADDRESS INTO DECODE JSR PC,D.TTAB ; TYPE TAB JSR PC,D.DC49 ; DECODE IT SUB D.CAD,R5 ; GET INSTRUCTION LENGTH TST -(R5) ; DECREMENT TO BE OFFSET OF INSTR CMP D.DOT,D.CAD ; ARE WE AT THE DOT? BNE D.INS2 ; DON'T SET INCREMENT IF NOT MOV R5,D.LFIN ; PUT IN LINE-FEED INCREMENT D.INS2: ASR R5 ; DIVIDE BY TWO BEQ D.INS4 ; BRANCH IF NOT ZERO ADD #'1,R5 ; ASCIIZE MOVB R5,D.WAMS+1 ; FILL IN NUMBER OF WORDS MOV #D.WAMS,R4 ; BEGIN WARNING MESSAGE MOV #D.WAMS+7,R3 ; END WARNING MESSAGE JSR PC,D.TTAB ; TYPE A TAB JSR PC,D.STYP ; TYPE IT D.INS4: MOV D.BW,-(SP) MOV R0,-(SP) MOV #2,D.BW JSR PC,GETCAD ;GET @D.CAD MOV R0,D.LASW MOV (SP)+,R0 MOV (SP)+,D.BW ; MOV @D.CAD,D.LASW ; LAST TYPED WORD RTS PC ; RETURN .PSECT ..DDTP,RO,I ;CODE ; GET A CHARACTER INTO R0 D.GET: .IF DF,D.MCRO ;IF CORE BUFFER MAY BE USED ALLOW THIS TST D.CHSW ;USING CORE BUFFER? BEQ 1$ ;NO, SKIP TO NORMAL CONSOLE IN MOV #-1,D.KBFE ;ENSURE WE TERMINATE THE READ SOMETIME MOVB @D.KBPT,R0 ;LOAD CHAR. FROM BUFFER INTO R0 INC D.KBPT TST R0 ;SEE WHAT WE GOT IF ANYTHING BMI 3$ ;IF AT END SKIP OUT BEQ D.GET ;IGNORE NULLS TST D.ECSW ;ECHOING THIS STUFF? BEQ 2$ ;NO, SKIP ECHO JSR PC,D.TYPE ;YES, ECHO IT 2$: RTS PC ;SCRAM IF HERE 3$: CLR D.CHSW ;NOT CORE IN NOW... MOV #D.KBBF,D.KBPT ;RESET IN POINTER 1$: ;NORMAL COMMANDS HERE .ENDC .IF NDF,X$QRG TST D.INPT ;GOT ANY MACRO INPUT SET UP NOW? BEQ 420$ ;IF EQ NO, SKIP IT MOVB @D.INPT,R0 ;GRAB A CHAR OTHERWISE INC D.INPT ;AND POINT TO NEXT FOR NEXT PASS DEC D.INLN ;COUNT DOWN NUMBER LEFT TO DO BMI 419$ ;IF NEGATIVE GET THEM FROM TERMINAL AFTER CLR RTS PC ;ELSE JUST RETURN HERE ;AHA! LAST CHAR WAS THE FINAL ONE WE HAD, SO TERMINATE THIS 419$: CLR D.INPT CLR D.INLN ;ZERO THESE FOR NEXT TIME 420$: .ENDC .IF NDF,D.KSR TSTB @#D.RCSR ; CHARACTER TYPED? BPL D.GET ; LOOP UNTIL FOUND MOVB @#D.RDB,R0 ; GET A CHARACTER .ENDC .IF DF,D.KSR JSR PC,D.POLL ; CHECK FOR CHARACTERS IN I/O BUFFER ; ;FOR RSX11 "NORMAL" I/O, ISSUE A WAIT HERE TO LET OTHER ;TASKS HAVE THE CPU UNTIL I/O DONE. .IF NDF,XTCOM .IF DF,$$RSX WTSE$S #23. ;USE E.F. #23. AS I/O SEMAPHORE FOR INPUT CMPB TIBUF,#'Z-100 ; CONTROL-Z SEEN? BEQ 19$ ; IF SO SCRAM CMPB TIOST,#IE.EOF ; CHECK INPUT FOR CTL-Z BNE 17$ ; IF NOT SKIP OUT 19$: JMP RSXEXT ; IF SO, LEAVE... 17$: .ENDC .ENDC CMP D.INPU,D.OUTP ; ANY CHARACTERS TYPED? BEQ D.GET ; LOOP IF BUFFER EMPTY MOVB @D.OUTP,R0 ; GET CHARACTER FROM BUFFER INC D.OUTP ; POINT TO NEXT CHARACTER CMP D.OUTP,#D.ENDB ; AT END OF BUFFER? BNE D.GET9 ; BRANCH IF NOT MOV #D.BUFR,D.OUTP ; WRAP-AROUND D.GET9: .ENDC .IIF DF,D.GDP,TRAP 64 ; KEYASC BIC #177600,R0 ; CLEAR META, CNTL AND SHIFT STUFF MOV R0,R1 ; EXACT (UNFOLDED COPY IN R1) BEQ D.GET ; IGNORE NULLS CMPB R0,#15 ; SEE IF A BNE D.GET2 ; BRANCH IF NOT MOV #12,R0 ; LINE FEED JSR PC,D.TYPE ; TYPE IT MOV #15,R0 ; RESET TO CR D.GET2: CMPB R0,#177 ; IS IT A BACKSPACE BEQ D.GET5 ; GUARANTEED TO GET A ? .IF NDF,F$DPX CMP R0,#12 ; IS IT A LINE FEED? BEQ D.GET1 ; IF SO, SAVE THE PAPER .ENDC CMPB R0,#33 ; IS IT AN ESCAPE? BEQ D.GET4 ; TYPE DOLLAR SIGN IF SO .IF NDF,XSEMI$ ;TREAT SEMICOLON THE SAME AS ESCAPE (FOR ODT COMPATIBILITY) CMPB R0,#73 ; 73 = SEMICOLON BNE 430$ ; IF NE LEAVE AS IS ; MOVB #33,R0 ; ELSE MAKE IT AN ESCAPE BR D.GET4 ; AND ECHO AS DOLLAR 430$: .ENDC .IF DF,D.KSR CMPB R0,#175 ; IS IT AN ALTMODE? BGE D.GET4 ; TYPE DOLLAR SIGN IF SO .ENDC .IF DF,$$RSX .IF DF,XTCOM!F$DPX JSR PC,D.TYPE .ENDC .ENDC .IF NDF,$$RSX JSR PC,D.TYPE ; ECHO CHARACTER .ENDC CMPB #'a,R0 ; FOLD TO UPPER CASE BGT D.GET1 ; BRANCH IF NOT A LETTER CMPB #'z,R0 ; IS IT IN ALPHABET? BLT D.GET1 ; BRANCH IF STILL NOT SUB #'a-'A,R0 ; FOLD DOWN D.GET1: RTS PC ; RETURN D.GET4: MOV #'$,R0 ; DOLLAR SIGN JSR PC,D.TYPE ; TYPE IT MOV #33,R0 ; RESTORE R0 RTS PC ; RETURN D.GET5: MOV #'X,R0 ; TYPE "XXX" JSR PC,D.TYPE ; TYPE FIRST JSR PC,D.TYPE ; TYPE SECOND JMP D.ERRO ; JUMP TO LAST .IF DF,D.KSR ; ; RSX11 DDT-- DO I/O BY QIO$S INTO SHORT BUFFER HERE.USE 2 WORDS ; AS FLAGS, 1 THAT I/O IS IN PROGRESS AND ANOTHER THAT SERVES ; AS TEMPORARY BUFFER. EVENTUALLY PUT THESE INTO SEPARATE PSECT FROM CODE. .IF NDF,XTCOM .IF DF,$$RSX .PSECT ..DDTD TOOST: .WORD 0,0 TIOST: .WORD 0,0 ;I/O STATUS BLOCK TIOFLG: .WORD 0 ;0==>NO I/O GOING, >0 ==>I/O UNDERWAY TIBUF: .WORD 0 ;I/O "BUFFER" FLGS: .WORD 0,0,0,0 ;EVENT FLAG SAVE AREA LFFG: .WORD 0 ;LINEFEED FLAG SET IF LF TYPED, CLEARED AFTER OTHER ;NONCONTROL CHARACTER TYPED EXCEPT CR. .PSECT ..DDTP,RO,I ;CODE .MCALL RDAF$S D.POLL: ;ENTRY FOR READING OR TRYING TO READ CHARS TST TIOFLG ;I/O BEGUN? BNE 1$ ;YES MOV #1,TIOFLG ;NO, BEGIN IT NOW CLR TIOST .IF NDF,R$EDT .IF NDF,F$DPX .IF NDF,SM$FIL QIO$S #IO.RAL,#D.INLU,#23.,,#TIOST,,<#TIBUF,#1,#0> .IFF QIO$S #IO.RAL,.ODTL1,#23.,,#TIOST,,<#TIBUF,#1,#0> .ENDC .IFF .IF NDF,SM$FIL QIO$S #IO.RAL!IO.RNE,#D.INLU,#23.,,#TIOST,,<#TIBUF,#1,#0> .IFF QIO$S #IO.RAL!IO.RNE,.ODTL1,#23.,,#TIOST,,<#TIBUF,#1,#0> .ENDC .ENDC .IFF .IF NDF,SM$FIL QIO$S #IO.RVB,#D.INLU,#23.,,#TIOST,,<#TIBUF,#1,#0> .IFF QIO$S #IO.RVB,.ODTL1,#23.,,#TIOST,,<#TIBUF,#1,#0> .ENDC .ENDC ;STARTS UP I/O ON LUN 6, EVENT FLG 23. 1$: ;NOW SEE IF I/O ALREADY DONE .IIF DF,$RSXM,RSX11M=0 .IIF DF,$RSXMM,RSX11M=0 .IF NDF,RSX11M ;RSX11D/IAS VERSION RDEF$S #23. ;SEE IF FLAG SET (READ EVENT FLAG) TSTB @#$DSW ;SEE IF 0 OR 2 ;IF 0, FLAG NOT SET--JUST EXIT. IF 2, GET DATA. BLE D.POL1 ;IF 0 (OR NEGATIVE) KEEP WAITING .IFF ;RSX11M VERSION .IF NDF,MMV3.2 WTSE$S #23. ;WAIT FOR EVENT FLAG .IFF RDAF$S #FLGS ;GET EVENT FLAGS BIT #100,FLGS+2 ;SEE IF E.F. 23 WAS SET BEQ D.POL1 ;IF NOT KEEP WAITING .ENDC .ENDC BICB #200,TIBUF ;SET 7 BIT ASCII ONLY MOVB TIBUF,@D.INPU ;SAVE DATA CLR TIOFLG ;SET NO MORE I/O GOING 2$: .ENDC .ENDC .IF DF,$$RSX .IF DF,XTCOM D.POLL: TSTB @#D.RCSR BPL D.POL1 MOVB @#D.RDB,@D.INPU .ENDC .ENDC .IF NDF,$$RSX D.POLL: TSTB @#D.RCSR ; ANY CHARACTER TYPED? BPL D.POL1 ; BRANCH IF NOT MOVB @#D.RDB,@D.INPU ; PUT CHARACTER IN BUFFER .ENDC .IF DF,$$DOS!$RT11 .IF NDF,TTYASR MOVB @D.INPU,-(SP) ;PREPARE... BIC #177600,@SP ;...ELABORATE PARITY CALCULATION CMPB (SP)+,#3 ;TEST FOR CTL-C BEQ D.POL2 ;GO TO DOS IF SO... .ENDC .ENDC .IF DF,$$RSX .IF NDF,$RSXMM!$RSXM .IF NDF,XTCOM!F$DPX ;IAS/RSX11D ONLY! CMPB TIBUF,#12 ; JUST SEE A LINEFEED ENTERED? BNE 11$ ; IF NOT, NORMAL INC LFFG ; IF SO FLAG NO MULTIPLE LINEFEEDS 11$: .ENDC .ENDC .ENDC INC D.INPU ; NEXT CMP D.INPU,#D.ENDB ; AT END OF BUFFER? BNE D.POL1 ; BRANCH IF NOT MOV #D.BUFR,D.INPU ; WRAP-AROUND D.POL1: RTS PC ; RETURN .IF DF,$$DOS!$RT11 .IF NDF,TTYASR D.POL2: MOV D.UR6,SP ;RESTORE USER STACK CLR -(SP) CLC ;INPUT INTERRUPT MOV #D.POL3,-(SP) ;SETUP LOOP WHILE DOS WORKS .IF NDF,L$$SI MOVB #200,@#-2 ;SPL 4 .IFF MTPS #200 .ENDC BIS #100,@#D.RCSR ;INPUT INTERRUPT ON MOV @#60,PC ;GO TO DOS SVC. ROUTINE D.POL3: BR D.POL3 .ENDC .ENDC .ENDC ; TYPE A TAB D.TTAB: .IIF NDF,D.KSR,MOV #11,R0 ; TAB .IF DF,D.KSR TSTB D.NOTY ; IN NON-TYPEOUT MODE? BNE D.TYP8 ; EXIT IF SO MOV #40,R0 ; SPACE JSR PC,D.TYPE ; TYPE IT BITB #7,D.CPOS ; ON A MULTIPLE OF 8? BNE D.TTAB ; LOOP ON SPACES IF NOT RTS PC ; RETURN .ENDC ; TYPE THE CHARACTER IN R0 D.TYPE: TSTB D.NOTY ; SHOULD WE TYPE? BNE D.TYP8 ; BRANCH IF NOT .IIF DF,D.GDP,TRAP 120 ; SCRRTN .IIF DF,D.GT40,EMT 0 .IF DF,D.KSR CMPB #33,R0 ; WAS THIS AN ESCAPE? (DON'T TYPE ESCAPES) BNE 17$ ;NO, NORMAL MOVB #'$,R0 ; ECHO AS DOLLAR SIGN JSR PC,D.TYP3 ;PRINT THE DOLLAR SIGN MOV #33,R0 ;REPLACE THE ESCAPE BR 18$ 17$: JSR PC,D.TYP3 ; TYPE CHARACTER 18$: CMPB R0,#15 ; CARRIAGE RETURN? BEQ D.TYP2 ; ZERO POSITION COUNTER IF SO BITB #140,R0 ; CONTROL CHARACTER? BEQ D.TYP1 ; RETURN IF SO CMPB R0,#12 ; LINE FEED? **** NEW/ GCE *** BEQ D.TYP2 ; YES, RESET CHAR. POSITION. **** NEW/ GCE *** DECB D.CPOS ; INCREMENT CHARACTER POSITION BPL D.TYP1 ; RETURN IF NOT MOV R0,-(SP) ; SAVE CHARACTER MOV #15,R0 ; YES, GENERATE CARRIAGE RETURN JSR PC,D.TYP3 ; TYPE IT ;;;; MOV #12,R0 ; AND A LINE FEED JSR PC,D.TYP3 ; TYPE IT ;;;; MOV (SP)+,R0 ; RESTORE CHARACTER D.TYP2: MOVB #D.CNUM,D.CPOS ; CLEAR CHARACTER POSITION D.TYP1: RTS PC ; RETURN .IF NDF,$$RSX D.TYP3: TSTB @#D.TCSR ; PRINTER READY FOR CHARACTER? BPL D.TYP3 ; LOOP IF NOT MOVB R0,@#D.TDB ; PUT OUT CHARACTER .IFF D.TYP3: .IF DF,XTCOM TSTB @#D.TCSR BPL D.TYP3 MOVB R0,@#D.TDB .ENDC .IF NDF,XTCOM ;ISSUE I/O VIA RSX HANDLER USING LUN 5, E.F. #22. MOVB R0,TIBUF+1 ;USE 2ND BYTE OF INPUT WORD AS BUFFER BICB #200,TIBUF+1 .IF NDF,F$DPX CMPB TIBUF+1,#12 ;LINEFEED? BEQ 22$ ;IF SO SET FLAG CMPB TIBUF+1,#15 ;C.R.? IGNORE FOR LFFG IF SO BEQ 23$ CLR LFFG ;SAY LAST WASN'T LF BR 23$ ;AND GO AHEAD 22$: TST LFFG ;WAS LAST A LF? BNE 25$ ;IF SO, DO NOT TYPE A 2ND IN A ROW INC LFFG ;IF NOT, BUMP COUNT AND DO IT 23$: ;DO NOT CLEAR LF FLAG .ENDC CLR TOOST CMPB TIBUF+1,#33 ;THIS AN ESCAPE? (NO TYPE THEN) BNE 14$ MOVB #'$,TIBUF+1 ;SPECIAL ECHO ESC AS DOLLAR SIGN .IF NDF,SM$FIL 14$: QIO$S #IO.WAL,#D.OUTU,#22.,,#TOOST,,<#TIBUF+1,#1,#0> .IFF 14$: QIO$S #IO.WAL,.ODTL1,#22.,,#TOOST,,<#TIBUF+1,#1,#0> .ENDC WTSE$S #22. ;JUST DO I/O AND WAIT ONCE PER CHAR 25$: ;REF LABEL .ENDC .ENDC .IF NDF,$$RSX ;DON'T NEED THIS WHERE RSX HAS TYPE-AHEAD JSR PC,D.POLL ; CHECK FOR TYPED-IN CHARACTERS .ENDC .ENDC D.TYP8: RTS PC ; RETURN ; TYPE CARRIAGE RETURN LINE FEED D.CRLF: MOV #D.CR+1,R3 ; LWA MOV #D.CR,R4 ; FWA ; TYPE A STRING STARTING AT R4 AND ENDING AT R3 D.STYP: CMP R3,R4 ; CHECK FOR COMPLETION BHIS 1$ JMP D.GET1 ; EXIT WHEN DONE 1$: MOVB (R4)+,R0 ; GET A CHARACTER JSR PC,D.TYPE ; TYPE ONE CHARACTER BR D.STYP ; LOOP UNTIL DONE ; SUBROUTINE TO TYPE R0 IN CURRENT RADIX D.TYPN: MOV R0,D.LASV ; MARK LAST NUMBER TYPED MOV R0,D.LASW ; LAST TYPED WORD TOO MOV D.DVTB,R2 ; GET RADIX CMP R2,#10. ; DECIMAL? BEQ D.TYP4 ; YES D.TYP5: JSR PC,D.DIVD ; DIVIDE IT. ADD #60,R1 ; CONVERT REMAINDER TO ASCII MOV R1,-(SP) ; AND SAVE IT. CMP R1,#71 ; ...FOR HEX, BE SURE NOT OUT OF RANGE BLE 1$ ;IF OK, BRANCH ADD #<'A-'9-1>,(SP) ;IF NOT, ADJUST SAVED NUMBER CHARACTER 1$: TST R0 ; DONE? BEQ D.TYP7 ; YES, TYPE THE DIGIT AND RETURN D.TYP6: JSR PC,D.TYP5 ; CALL OURSELF RECURSIVELY D.TYP7: MOV (SP)+,R0 ; RESTORE THE DIGIT JMP D.TYPE ; PRINT IT, AND RETURN D.TYP4: MOV #'.,-(SP) ; PUT A . AT THE END OF THE NUMBER MOV R0,R3 ; GET THE NUMBER BPL D.TYP6 ; AND TYPE IF POSITIVE MOV #'-,R0 ; ELSE PRINT A - JSR PC,D.TYPE MOV R3,R0 ; RESTORE NUMBER NEG R0 ; BUT TAKE ABSOLUTE VALUE BR D.TYP6 ; DIVISION ROUTINE - R1 (HIGH) AND R0 (LOW)/R2=R0 REMAINDER R1 D.DIVD: MOV #16.,-(SP) ; SHIFT COUNT CLR R1 ; ASSUME NO HIGH PART D.DIV1: ASL R0 ; DOUBLE PRECISON SHIFT ROL R1 CMP R2,R1 ; WILL DIVISOR GO IN? BHI D.DIV2 SUB R2,R1 INC R0 D.DIV2: DEC (SP) BGT D.DIV1 ; SOB? TST (SP)+ RTS PC ; TYPE WORD(S) AT R5 IN INSTRUCTION FORMAT D.DC49: MOV D.BW,-(SP) MOV D.CAD,-(SP) MOV #2,D.BW ;USE GETCAD TO FIND INSTRUCTION MOV R5,D.CAD ; JSR PC,GETCAD MOV (SP)+,D.CAD ADD #2,R5 MOV (SP)+,D.BW ; MOV (R5)+,R0 ; GET INSTRUCTION INTO R0 MOV #D.TOPS+2,R1 ; POINT TO ARRAY OF INSTRUCTION VALUES MOV R0,R4 ; SAVE INSTRUCTION CLR R3 ; DON'T TYPE A "B" BIC #100000,R0 ; START OUT LOOKING FOR INS. WITHOUT "B" D.LOOP: CMP R0,(R1)+ ; DOES INSTRUCTION FALL IN HERE? BHI D.LOOP ; NO, LOOP CMP R4,R0 ; DID WE GET REAL INSTRUCTION MATCH? BEQ D.FOUN ; YES MOV R4,R0 ; NO, BUT DO SO NEXT TIME TSTB D.LEGS-D.TOPS-4(R1) ; BYTE INSTRUCTION? BPL D.LOOP ; NO! DEC R3 ; PRINT A "B" D.FOUN: MOVB D.LEGS-D.TOPS-4(R1),R2 ; GET LEGAL CONSIDERATION BYTE BIC #177774,R2 ; CLEAR HIGH BITS CMPB R2,D.MACH ; MACHINE TYPE RIGHT? BGT D.N16 ; TYPE NUMBER IF BAD ADD #D.COUS-D.TOPS-4,R1 ; ADD IN ADDRESS OF STRING MOV (R1)+,R2 ; GET OFFSET OF CHARACTERS BIC #177400,R2 ; TURN OFF EXTRA CRUFT D.DC6: CMPB R2,(R1) ; AT END? BEQ D.DC3 ; BRANCH IF SO MOVB D.STRS(R2),R0 ; GET A CHARACTER JSR PC,D.TYPE ; TYPE IT INC R2 ; NEXT CHARACTER BR D.DC6 ; LOOP D.DC3: TST R3 ; BYTE INSTRUCTION? BEQ D.DONE ; BRANCH IF NOT MOV #'B,R0 ; BYTE INSTRUCTION: TYPE "B" JSR PC,D.TYPE ; TYPE IT D.DONE: MOVB -(R1),R3 ; RE-GET LEGALITY BYTE BIC #177703,R3 ; GET LEGAL CONSIDERATION CMP R3,#10 ; TYPE A SPACE AFTER OP-CODE? BLE D.NOBL ; BRANCH IF NOT MOV #' ,R0 ; SPACE JSR PC,D.TYPE ; TYPE IT D.NOBL: MOV R4,R0 ; GET INSTRUCTION BACK ASL R4 ; GET OPERAND THAT STARTS AT BIT 6 ASL R4 ; WITH TWO SHIFTS AND... SWAB R4 ; A SWAB ASR R3 JMP @D.PARM(R3) ; TYPE PARAMETERS D.DC7: MOV R0,R1 ; GET R1 FOR D.DC5 ADD #D.MOD7,R1 ; DISPLACEMENT OF OPENING CHARACTERS MOVB (R1),R2 ; GET OFFSET OF CHARACTERS CMPB D.FIRS(R2),#'? ; IS IT LEGAL? BEQ D.DC50 ; BRANCH IF NOT JSR PC,D.DC5 ; TYPE THEM ; CMP R0,#6 ; RELATIVE ADDRESSING? MOV R0,-(SP) ; SAVE R0 FOR REL ADDRESSING CHK MOV D.BW,-(SP) MOV D.CAD,-(SP) MOV #2,D.BW ;USE GETCAD TO FIND INSTRUCTION MOV R5,D.CAD ; JSR PC,GETCAD MOV (SP)+,D.CAD ADD #2,R5 MOV (SP)+,D.BW ; MOV (R5)+,R0 ; NOTE THAT THIS LEAVES CARRY ALONE CMP (SP)+,#6 ; RELATIVE ADDRESSING? BCS D.N16 ; BRANCH IF IMMEDIATE D.N17: ADD R5,R0 ; FUDGE FOR RELATIVE. D.N16: JMP D.RFND ; TYPE IN CURRENT ADDRESSING MODE D.SSDD: MOV R0,-(SP) ; SAVE SECOND PARAMETER MOV R4,R0 ; GET FIRST ONE JSR PC,D.DD ; TYPE IT BR D.SS ; DO THE REST D.CZVN: MOV #D.NZVC,R1 ; LOOP ON BITS OF CODE MOV R0,R2 ; SAVE OPERATION IN R2 JSR PC,(PC) ; DO WHAT FOLLOWS TWICE JSR PC,(PC) ; NO, I MEAN 4 TIMES MOVB (R1)+,R0 ; GET CHARACTER ROR R2 ; TEST A BIT BCC D.RTS2 ; BRANCH IF NOT ON JMP D.TYPE ; TYPE IT AND RETURN D.N3: BIC #177770,R0 ; MASK OUT ALL BUT LOW 3 BITS D.N6: BIC #177700,R0 ; MASK OUT ALL BUT LOW 6 BITS D.N8: BIC #177400,R0 ; MASK OUT ALL BUT LOW 8 BITS JMP D.TYPN ; TYPE THE NUMBER D.RN6: MOV R5,-(SP) MOV R0,-(SP) ; SAVE R0 MOV R4,R0 ; GET FIRST PARAMETER JSR PC,D.R ; TYPE AS REGISTER MOV #',,R0 ; INSERT COMMA BETWEEN PARAMETERS JSR PC,D.TYPE ; TYPE IT MOV (SP)+,R0 ; GET SECOND PARAMETER NEG R0 ;;;GCE;;; NEGATE FOR SOB BIS #177700,R0 ; TURN ON HIGH TWO BITS IN LOW BYTE MOV (SP)+,R5 D.X8: MOVB R0,R0 ; SIGN EXTEND ASL R0 ; MULTIPLY BY 2 BR D.N17 ; DO THE REST AND RETURN D.RDD2: MOV R0,-(SP) ;SAVE 2ND PARM. DO D.RDD WITH 2BIT REG FIELD MOV R4,R0 BIC #4,R0 BR D.RD3 D.RDD: MOV R0,-(SP) ; SAVE SECOND PARAMETER MOV R4,R0 ; GET FIRST ONE D.RD3: JSR PC,D.R ; TYPE AS A REGISTER D.SS: MOV #',,R0 ; PUT COMMA... JSR PC,D.TYPE ; ... INBETWEEN PARAMETERS MOV (SP)+,R0 ; GET SECOND PARAMETER D.DD: ; THIS ROUTINE TYPES A MODE/REGISTER OPERAND IN R0 MOV R0,R3 ; LOW 6 BITS OF R0 HAVE MODE/REG BIC #177770,R3 ; R3 HAS REGISTER ASR R0 ; GET MODE ASR R0 ; BY SHIFTING ASR R0 ; INTO LOW BITS BIC #177770,R0 ; R0 HAS MODE CMP R3,#7 ; PC ADDRESSING? BEQ D.DC7 ; BRANCH IF SO D.DC50: MOV R0,-(SP) ; MAKE THIS SAVED DATA MOV R0,R1 ; PUT IN R1 FOR D.DC5 ADD #D.OPCH,R1 ; ADD IN DISPLACEMENT OF SPECIAL CHARACTERS JSR PC,D.DC5 ; TYPE PRECEDING CHARACTERS MOV R3,-(SP) ; SAVE R3 CMP R0,#6 ; IS THERE AN INDEX? BLT D.DC8 ; BRANCH IF NOT MOV D.BW,-(SP) MOV D.CAD,-(SP) MOV #2,D.BW ;USE GETCAD TO FIND INSTRUCTION MOV R5,D.CAD ; JSR PC,GETCAD MOV (SP)+,D.CAD ADD #2,R5 MOV (SP)+,D.BW ; MOV (R5)+,R0 ; PUT ADDRESS IN R0 JSR PC,D.RFND ; TYPE ADDRESS AND OFFSET MOV #'(,R0 ; PUT "(" IN OUTPUT JSR PC,D.TYPE ; TYPE IT D.DC8: MOV (SP)+,R0 ; GET REGISTER JSR PC,D.R ; TYPE REGISTER NUMBER MOV (SP)+,R1 ; RESTORE MODE ADD #D.CLOS,R1 ; ADD IN CLOSING CHARACTERS D.DC5: ; THIS ROUTINE TYPES A STRING INDEXED BY R1 MOV R0,-(SP) ; SAVE R0 MOVB (R1)+,R2 ; GET OFFSET OF CHARACTERS D.DC62: MOVB D.FIRS(R2),R0 ; GET CHARACTER BEQ D.DC4 ; SKIP IF NULL CHARACTER JSR PC,D.TYPE ; TYPE IT D.DC4: INC R2 ; NEXT CHARACTER CMPB R2,(R1) ; AT END? BLO D.DC62 ; BRANCH IF NOT MOV (SP)+,R0 ; RETURN R0 D.RTS2: RTS PC ; RETURN D.RD2: MOV R4,-(SP) ;SAVE 1ST PARM JSR PC,D.DD ;TYPE 2ND MOV #',,R0 ;TYPE COMMA JSR PC,D.TYPE MOV (SP)+,R0 BIC #4,R0 ;MASK REG RANGE TO 0-3 BR D.R D.DDR: MOV R4,-(SP) ; SAVE FIRST PARAMETER JSR PC,D.DD ; TYPE SECOND PARAMETER MOV #',,R0 ; COMMA JSR PC,D.TYPE ; TYPE IT MOV (SP)+,R0 ; RESTORE REGISTER D.R: ; THIS ROUTINE TYPES A REGISTER BIC #177770,R0 ; CLEAR HIGH BITS CMP R0,#6 ; R5 OR LOWER? BLO D.DC9 ; BRANCH IF SO BHI D.DC19 ; BRANCH IF PC MOV #D.SP,R1 ; "SP" BR D.DC5 ; TYPE IT AND RETURN D.DC19: MOV #D.SP+1,R1 ; "PC" BR D.DC5 ; TYPE IT AND RETURN D.DC9: MOV R0,-(SP) ; SAVE R0 MOV #'R,R0 ; "R" JSR PC,D.TYPE ; TYPE IT MOV (SP)+,R0 ; RESTORE R0 ADD #60,R0 ; ASCIIZE IT JMP D.TYPE ; TYPE IT AND RETURN .IF DF,SM$FIL ;SYMBOL FILE ONLY... .PSECT ..DDT.,RW,I ;LOGIC TO PERMIT OPENING OF SYMBOL TABLE FILES ON $UO COMMAND AND ;READING SYMBOLS FROM THERE... A NULL FILE NAME CLOSES .STB FILE. .MCALL DSAR$S,ENAR$S,GTSK$S .MCALL GCMLB$,GCML$,CSI$,CSI$1,CSI$2 .MCALL FSRSZ$,FDBDF$,FDRC$A,FDOP$A,NMBLK$ .MCALL OPEN$R,CLOSE$,ALUN$S,GET$ .IF NDF,CD$FIL FSRSZ$ 2 .IFF FSRSZ$ 3 .ENDC ;USED IN LOCATING "JMP"'S AS OPPOSED TO "BR"'S .MACRO JUMP A JMP A .ENDM .MACRO CALL SUBR JSR PC,SUBR .ENDM ;USED TO CALL RSX-11 FOR HELP .MACRO RSX11 EMT 377 .ENDM ;CAUSE ERROR RESPONSE, INTERNAL CODE SAVER .MACRO ERROR JMP D.ERR .ENDM .MACRO SHIFT N,REG ASH #N,REG .ENDM ZENTER=0 .MACRO ENTER,ARGS RTRNZ=0 RTRNZS=0 RTRNZC=0 ZENTER=ZENTER+1 .NARG NARG .IF GT,NARG .IRP FOO, MOV FOO,-(SP) .ENDM .ENDC .MACRO RETURN,T,OP .NARG NARG .IIF EQ,NARG-2 XRTRN \ZENTER,T,OP .IIF NE,NARG-2 XRTRN \ZENTER,T,BR .ENDM RETURN .IF GT,NARG .MACRO EXIT XEXIT \ZENTER, .ENDM EXIT .ENDC .IF EQ,NARG .MACRO EXIT XEXIT \ZENTER .ENDM EXIT .ENDC .ENDM ENTER .MACRO XEXIT,N,ARGS .NARG NARG NARG=NARG-1 .IF GT, BR RTZ'N RTZC'N': CLC .ENDC .IF GT, BR RTZ'N RTZS'N': SEC .ENDC RTZ'N': $CT=0 .IRP FOO, $CT=$CT+1 .ENDM .REPT $CT $N=1 .IRP FOO, .IIF EQ,$N-$CT MOV (SP)+,FOO $N=$N+1 .ENDM $CT=$CT-1 .ENDM RTS PC .ENDM XEXIT .MACRO XRTRN,N,T,OP OP RTZ'T'N RTRNZ'T=1 .ENDM XRTRN ;LOGICAL UNIT BUCKETS TO USE FOR I/O .PSECT ..DDT.,RW,I .PSECT ..DDTD IOLUNS: ;LOGICAL UNIT SLOTS ; THESE NEXT TWO LOCATIONS ARE FILLED BY THE TASK BUILDER ; WHEN IT SEES THE /DA SWITCH IN THE OUTPUT SIDE OF THE COMMAND STRING .GLOBL .ODTL1,.ODTL2 .ODTL1: .WORD D.INLU ; LUN FOR TTY (DEFAULT TO D.INLU) .ODTL2: .WORD D.OUTU ; LUN FOR SYMBOLS FILE ODTEFN=22. .WORD ODTEFN ; EVENT FLAG FOR ODT INTEND =.-2 ;END OF INTERNAL REGISTERS AND TABLES GTSKBF: .BLKW 16. ; GET TASK PARAMETER BUFFER .PSECT ..DDT.,RW,I ;RSX-11 DIC DATA STUFF ; COMMAND LINE FOR SYMBOLS FILE GCMLB: GCMLB$ ,,BUF,,,80. CSI$ CSI: LNEBUF: .BLKB 200 ; FOR COMMAND LINE AND WORK ; SPACE ALSO. PLENTY FOR ALL STBFLE: FDBDF$ ; FILE DESCRIPTOR FOR SYMBOLS FILE FDRC$A ,LNEBUF,200 FDOP$A ,CSI+C.DSDS,NMBLK,FO.RD .PSECT ..DDT.,RW,I 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 .PSECT ..DDT.,RW,I NMBLK: NMBLK$ ,STB,,SY .PSECT ..DDT.,RW,I ; ;SERVICE $UQ CLOSE INPUT COMMAND .PSECT ..DDTP,RO,I ;CODE CLSERA: MOV R0,-(SP) MOV R1,-(SP) MOV #.SYMNM,R0 ;GET NO. SYMS TO CLR MOV #.SYMBG,R1 ;AND NO. SYMS TO CLR 1$: MOV #4,(R1)+ MOV #4,(R1)+ CLR (R1)+ ;"ZERO" OUT SYMBOL CACHE DEC R0 BGT 1$ ;DO ALL OF THEM MOV (SP)+,R1 MOV (SP)+,R0 CLSIPT: TST STBFDB ; ANY FDB OPEN BEQ 1$ ; IF NO JUST RETURN MOV STBFDB,R0 CLOSE$ 1$: JMP D.DCD ; GO GET MORE TO DO ; ;SERVICE $UO COMMAND (OPEN .STB FILE) ; OPEN INPUT FILE ; ALSO ALLOW $NNUO TO CLOSE FILE OPNIPT: TST R2 ;ANY PARAMETER? BNE CLSERA ; IF SO, CLOSE ONLY. MOV .ODTL1,GCMLB+42 ; USE TTY LUN GCML$ #GCMLB,#PRMPTS,#PRMPTL ; PROMPT FOR .STB FILE BCS 99$ ; HE GOOFED CLR CSI+C.CMLD ; CLEAR HI-BYTE, SINCE CSI IS OVERLAID BY LNEBUF MOVB GCMLB+G.CMLD,CSI+C.CMLD ;CMD LINE SIZE (HI-BYTE HAS TERM CHAR) MOV GCMLB+G.CMLD+2,CSI+C.CMLD+2 ; CSI$1 #CSI BCS 99$ ; ERROR DURING SYNTAX CHECK CSI$2 #CSI,OUTPUT ; GO FIND A F/S BCS 99$ ; RATS MOV STBFDB,R0 ; IS THERE A SYMBOLS FILE OPEN ? BEQ 10$ ; NO CLOSE$ ; YES, CLOSE IT CLR STBFDB ; REMEMBER ITS CLOSED 10$: MOV IOLUNS+2,R1 ; GET SYMBOL FILE LUN ALUN$S R1,#"SY ; ASSIGN LUN TO SY: OPEN$R #STBFLE,R1 ; TRY OPEN IT FOR READ BCS 99$ ; IT JUST ISN'T THERE OLD BEAN MOV R0,STBFDB ; REMEMBER THAT IT IS OPEN JMP D.DCD ; GET NEXT EXPRESSION... 99$: TST STBFDB ; SEE IF ANY IS OPEN BEQ 199$ ; IF NOT JUST SAY ERROR MOV STBFDB,R0 CLOSE$ ; ELSE CLOSE IT CLR STBFDB 199$: JMP D.ERR .PSECT ..DDT.,RW,I .PSECT ..DDTD PRMPTS: .ASCII / .STB FILE: / PRMPTL=.-PRMPTS .EVEN BUF: .BLKB 82. ; OUTPUT BUFFER -- GCML ALSO ;SYMBOL TABLE FILE OPERATIONS... ; OUR ONLY SYMBOL (INPUT) SYMSPC: .BLKB 8. SYMR50: .BLKW 1 ; RAD-50 EQUIVALENT SYMR51: .BLKW 1 ;CODE FOR HUNTING UP SYMBOL... ;USE WHERE ADDRESS IS KNOWN, NEED TO FIND CLOSEST SYMBOL. .PSECT ..DDTP,RO,I ;CODE HUNTSM: ;PRINT ADDRESS SUB HERE... ;NUMBER IN R3. THRU R1. ENTER 20$: CLR R2 ; BEST SYMBOL MOV R3,R4 ; BEST DISPLACEMENT 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 HAVEN'T 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 ; DID WE FIND ANY SYMBOL AT ALL? BNE 500$ ; IF SO GO AHEAD MOV (SP)+,R2 ; FIX UP THE STACK MOV (SP)+,R1 BR 43$ ; IF NONE, FORGET ABOUT IT... 500$: MOV (SP)+,R2 ; GET BACK PREVIOUS SYMBOL 510$: MOV (SP)+,R1 ; RECOVER POINTER TO TEXT LINE MOV CHR1,.STBSM ; SAVE SYMBOL FOR DDT INTERNALS MOV CHR1+2,.STBSM+2 ; ALL 6 CHARS OF IT MOV R0,.STBAD ; THEN SAVE THE SYMBOL'S ADDRESS. 55$: BR 520$ 43$: RETURN S ; RETURN ERROR BR 550$ 520$: RETURN C ; SAY ALL IS WELL. 550$: EXIT ;ACTUAL PRINTOUT MERELY CACHES BEST SYMBOL IN THE REAL ;DDT SYMBOL TABLE. A FIXED NUMBER OF SUCH SYMBOLS ARE KEPT ;AROUND ONCE LOOKED UP FOR ADDRESSES AS THE BEST MATCHES. THESE ;ARE OVERWRITTEN AS NEEDED BY NEW SYMBOLS. ;DUMMY SYMBOL FOR DDT PRINTOUT USE. .PSECT ..DDT.,RW,I .PSECT ..DDTD .STBSM: .WORD 0,0 ;RAD50 SYMBOL NAME USED .STBAD: .WORD 0 ;SYMBOL ADDRESS ; .PSECT ..DDTP,RO,I ;CODE ;SYMBOL TBL SEARCH UTILITY ROUTINES ; GET NEXT RECORD OF SYMBOL TABLE FILE .IF DF,I$$SD ; SAVE RECORD TYPE OF OBJECT RECORD SO WE CAN TELL BELOW WHETHER ;WE ARE IN A GSD BLOCKOR AN ISD BLOCK. IN AN ISD BLOCK, WE WILL ;CHECK MODULE NAMES IF MDLCTL IS NONZERO. IN A GSD BLOCK WE WILL ;CHECK MODULE NAMES ONLY IF MDLCTL IS NEGATIVE. GETRT.: .WORD 0 ; TEMP STORAGE FOR RECORD TYPE (ISD/GSD) .ENDC .PSECT ..DDTP,RO,I ;CODE ; GETREC: GET$ R0 ; GET A RECORD BCS 99$ ; ERROR IN FILE TSTB F.ERR(R0) ; CHECK F.ERR FOR ERROR TOO BMI 99$ ; IF NEGATIVE, WE FOUL UP, SCRAM. 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 .IF DF,I$$SD MOV R2,GETRT. ; STORE RECORD TYPE .ENDC 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 .IF NDF,$$ISD .IF NDF,I$$SD BR 500$ ; 5 ISD .IFF TST MDLCTL ; DOING ISD TYPE ACTIONS? BEQ 500$ ;NO, IGNORE THE ISD BR 100$ ;ELSE TREAT JUST AS A GSD RECORD. NOTE THAT ;INTERNAL STRUCTURE ASSUMED IDENTICAL WITH GSD. .ENDC .IFF BR 100$ ;MAY TREAT ISD'S AND GSD'S ALIKE... .ENDC 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 ... .IF DF,CL.ZIT MOV STBFDB,R0 ; CLOSE FILE FIRST.. BEQ 998$ CLOSE$ .IFTF 998$: .IFT CLR STBFDB ; ... DON'T USE FILE AGAIN .ENDC SEC ; GO HOME CRYING RTS PC ; GET NEXT SYMBOL FROM GSD ; GETGSD: MOV STBFDB,R0 ; IS THERE A FILE OPEN ? BEQ L.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 L.10$ ; NO .IF DF,I$$SD RECGT.: .ENDC CALL GETREC ; YES, GET NEXT RECORD BCS L1000$ ; OOPS L.10$: 10$: MOVB 5(R1),R2 ; GET GSD ENTRY TYPE BIT #177770,R2 ; CHECK VALIDITY OF RANGE BNE 998$ ; GOSH ! CAN'T BE A .STB FILE ASL R2 ; TURN INTO WORD OFFSET ADD R2,PC ; AND LEAP OFF THRO' TABLE .IF NDF,I$$SD BR GETGSD ; TYPE 0 - MODULE NAME .IFF BR GETNMK ;TYPE 0 - MODULE NAME. COMPARE WITH MDLNAM. .ENDC BR GETGSD ; 1 - CONTROL SECTION NAME .IF NDF,$$ISD .IF NDF,I$$SD BR GETGSD ; 2 - INTERNAL SYMBOL NAME .IFF BR GETGIS ; 2 - INTERNAL SYMBOL NAME .ENDC .IFF BR 400$ ; ACCEPT ISD'S AS GSD'S .ENDC 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 998$: .IF DF,CL.ZIT MOV STBFDB,R0 ; GET FDB CLOSE$ ; AND CLOSE IT CLR STBFDB ; DON'T USE FILE AGAIN. NOT AN STB. .ENDC 999$: L.999$: ;CLR STBFDB ; DON'T USE FILE AGAIN L1000$: SEC ; RTS PC ; QUIT .IF DF,I$$SD GETGIS: TST MDLCTL ; IF ISD STUFF TURNED ON BEQ GETGSD ; THEN... (AND ONLY THEN...) CLC ; ALLOW GSD ENTRIES TO BE SIMULATED BY ISD RTS PC ; ENTRIES. ; IF MDLCTL IS +, THEN FOR ISD BLOCKS ONLY CHECK MODULE NAME FOR BEING SAME ; AS DESIRED MODULE IN GLOBAL 'MDLNAM' WHICH IS ACCESSED AS "MODULE" ; SYMBOLICALLY WITHIN DDT. IF IT IS NEGATIVE HOWEVER, DO THE MODULE NAME ; CHECK EVEN WITHIN GSD RECORDS. FORCE A NEW READ IF THE MODULE NAME ; IS NOT THE ONE DESIRED. GETNMK: TST MDLCTL BEQ GETGSD ;IF NO SPECIAL ISD STUFF, IGNORE MODULE NAME BMI 1$ ;IF MDLCTL IS -, ONLY LOOK AT MDULE. CMP GETRT.,#5 ;INSIDE AN ISD BLOCK? IF NOT, JUST RETURN BNE GETGSD ;INSIDE ISD BLOCK, LOOK AT MODULE NAME 1$: CMP (R1),MDLNAM ;IF NAME MATCHES ALL IS WELL BNE RECGT. ;ELSE FORCE NEW RECORD IN (OR END) CMP 2(R1),MDLNAM+2 BNE RECGT. ;FORCE NEW RECORD IF NOT CORRECT MODULE TO LOOK AT BR GETGSD .ENDC ; SYMLOC -- LOCATE SYMBOL IN .STB FILE ; SYMBOL STORED IN RAD-50 IN SYMR50 & SYMR51 ;USE TO FIND SYMBOL FROM USER DEFINITION ; ; 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 .ENDC .PSECT ..DDT.,RW,I .IF DF,CD$FIL .PSECT ..DDT.,RW,I .PSECT ..DDTD CD.NEW: .WORD 0 ;NEW FLAG - 0 IF NO READ DONE YET CDFDB: .WORD 0 ;FDB ADDRESS OR 0 CDFLD: FDBDF$ ;AND THE FDB .MCALL FDBK$A FDBK$A CD.BUF,512.,,,CD.STT FDOP$A CD.LUN,CSI+C.DSDS,CNMBK,FO.MFY .MCALL FDOP$R CCMLB: GCMLB$ ,,BUF,D.INLU,,80. CNMBK: NMBLK$ ,SYS,,SY .PSECT ..DDT.,RW,I CD.STT: .WORD 0,0 ;I/O STATUS BLK .PSECT ..DDT.,RW,I .MCALL CSI$SW,CSI$ND CSISW: .WORD 0 ;SWITCHES ON CODE FILE SWTBL: CSI$SW AB,1,CSISW ;/AB SPECIFIES LOGICAL BLK CSI$SW RO,2,CSISW ;/RO OPENS FILE IN READ ONLY MODE CSI$ND .PSECT ..DDT.,RW,I CPRP: .ASCII <15><12>/ CODE FILE:/ CPRPL=.-CPRP .EVEN ; ; SERVICE $L COMMANDS. ; $L CLOSES ANY OPEN CODE FILE AND RESETS CD.CTL AND CDFDB ; $1L PROMPTS FOR FILE NAME AND OPENS LUN CD.LUN WITH THAT ; FILE. IT ALSO SETS CD.CTL TO 1. .IIF NDF,CD.LUN,CD.LUN=D.OUTU .PSECT ..DDTP,RO,I ;CODE CD.OPN: CLR CD.NEW ;FLAG NO BLK THERE NOW CLR CSISW ;NO /AB INITIALLY TST R2 ;ANY PARAMETERS? BEQ CD.CLS ;NO, CLOSE FILE CLR CD.CTL ;AND RESET CONTROL BELOW ;OPENING A CODE FILE NOW. TST CDFDB ;OLD FILE OPEN? BEQ 1$ ;NO MOV CDFDB,R0 CLOSE$ CLR CDFDB ;YES, CLOSE IT + MARK 1$: MOV .ODTL1,CCMLB+42 ;USE TTY LUN GCML$ #CCMLB,#CPRP,#CPRPL ;PROMPT FOR CODE FILE BCS 999$ ;ON ERROR GO COMPLAIN CLR CSI+C.CMLD ;CLR HI BYTE SINCE CSI OVERLAIN BY LNEBUF MOVB CCMLB+G.CMLD,CSI+C.CMLD MOV CCMLB+G.CMLD+2,CSI+C.CMLD+2 ;CMD LINE SIZE CSI$1 #CSI ;SYNTAX CHECK IT BCS 999$ ;OR LOSE CSI$2 #CSI,OUTPUT,SWTBL ;GET FILE (OR DEVICE) BCS 999$ MOV #CD.LUN,R1 ;GET OUR LUN ALUN$S R1,#"SY ;ASSIGN LUN TO SY0: MOV #CDFLD,R0 MOVB #FO.MFY,F.FACC(R0) ;DEFAULT R/W ACCESS BIT #2,CSISW ;/RO READ ONLY OPEN SPECIFIED? BEQ 96$ ;NO, R/W MOVB #FO.RD,F.FACC(R0) ;SET R/O 96$: BIT #1,CSISW ;/AB SPECIFIED? BNE 99$ ;IF SO NO OPEN .MCALL OPEN$ OPEN$ #CDFLD,,R1 ;TRY TO OPEN FOR MODIFY OR READ BCS 999$ ;IF FAIL, FORGET IT MOV #1,CD.CTL ;FLAG WE HAVE AN OPEN FILE TO ACCESS CLR CD.BLK+2 ;REMOVE BLOCK OFFSET MOV #3,CD.BLK ;AND PUT IN 3 (TO 32 BITS) TO START WITH BR 98$ 99$: MOV #-1,CD.CTL ;FLAG ABSOLUTE BLK PATCHES MOV #-777,CD.BLK ;ALSO GIVE BLOCK OFF IN SPACE MOV #-777,CD.BLK+2 ;TO AVOID BASHING BOOT BLOCK ;;;; NOTE THAT THESE BLK NOS CANNOT BECOME VALID BLKS IF FILES 11 DISK ;;;; SIZES ARE OBSERVED (24 BITS BLK #) AND ARE UNLIKELY TO EVER BE ;;;; VALID. ;;;N.B. ALLOW-ALL MODE WOULD PUT -2 IN CD.CTL. 98$: MOV R0,CDFDB ;ELSE RECALL IT'S OPEN JMP D.DCD ;GET NEXT THING TO DO 999$: TST CDFDB CLR CD.CTL ;SAY NO MORE FILE OPEN CLR PARMAP .IIF DF,U$ID.!MPV2., MOV #140000,UV$SPF BEQ 998$ MOV CDFDB,R0 CLOSE$ CLR CDFDB ;CLOSE + MARK FILE 998$: JMP D.ERR ;GO CRYING CD.CLS: CLR CD.CTL ;STOP ACCESSES TO FILE MOV R0,-(SP) MOV CDFDB,R0 ;ZAP OPEN FILE IF ANY BEQ 1$ CLOSE$ ;CLOSE IT 1$: CLR CDFDB MOV (SP)+,R0 JMP D.DCD ;GET MORE TO DO ;BLOCK READ/WRITE SECTION. USED FOR "MEMORY-LIKE" ;ACCESSES FROM FILE. NOTE THAT FDB IS OPEN ALREADY AND ;CD.BLK ALLOWS ACCESS TO IT. ;WE USE CD.BUF AS BUFFER (512. BYTES LONG) AND CALL .XQIO TO ;DO OUR I/O IF FILE IN USE, ELSE DO OUR OWN QIOW$S. ;USE CD.BKN TO GIVE CURRENT VIRTUAL BLK # (NOTE 16 BITS, ;CD.BLK IS 32 BITS LONG AND GIVES BASE BLOCK TO ADD...) ; NOTE FURTHER CD.NEW IS NONZERO IF A BLOCK IS PRESENT. ; ; CD.GET: INPUT IN R3 = ADDRESS TO GET ; R0=BYTE/WORD FLAG ; R5,R4,R3,R2 FREE. RETURN CONTENTS IN R0. ; -- > DON'T BOTHER WRITING OUT OLD BLK, SINCE CD.PUT WILL DO ; WRITES AUTOMATICALLY. JUST READ BLK IF NEED BE. CD.GET: JSR PC,CD.CLC ;GET OFFSET IN R2 AND BLK # IN C.BLL TST CD.NEW ;ANY DATA THERE YET? BEQ 93$ ;IF NOT, READ NOW CMP R5,CD.BKN ;R5 = VIRTUAL BLK #. HAVE IT NOW? BEQ CD.LOD ;IF EQ YES, GET DATA 93$: MOV R2,-(SP) MOV R1,-(SP) MOV R3,-(SP) MOV R5,CD.BKN ;SAVE CURRENT BLOCK IN CASE OF WRITE MOV #IO.RVB,R1 ;READ VIRTUAL FUNCTION TST CD.CTL ;IS THIS IO.RVB? BPL 1$ ;IF SO LEAVE IN R1 MOV #IO.RLB,R1 ;ELSE IT'S READ LOGICAL 1$: MOV CDFDB,R0 ;FDB WE NEED MOV #C.PL,R3 ;PARAMETER LIST MOV #5,R2 ;5 PARAMS TO USE JSR PC,.XQIO ;DO THE QIOW$ FOR US...GET FILE IN. MOV #1,CD.NEW ;FLAG BUFFER IS OCCUPIED NOW. MOV (SP)+,R3 MOV (SP)+,R1 MOV (SP)+,R2 ;SAVE OFFSET CD.LOD: CLR R0 ;SET 0 START ADD #CD.BUF,R2 ;POINT R2 AT DATA BISB 1(R2),R0 ;GET HI BYTE SWAB R0 BISB (R2),R0 ;NOW HAVE BYTE OR WORD BIT #1,D.BW ;BYTE ONLY? BEQ 1$ ;IF EQ NO BIC #177400,R0 ;IF NE YES, CLEAR H.O. BYTE 1$: RTS PC ; CD.PUT: INPUT IN R3= ADDRESS TO STORE DATA IN ; R4=DATA TO STORE ; R0=BYTE/WORD FLAG (ODD=BYTE) ; STORE DATA. USE WRITE DIRECT TO DISK ALWAYS. CD.PUT: BIT #2,CSISW ;READ/ONLY ACCESS (NEVER WRITE) BEQ 95$ ;IF EQ NO RTS PC ;IF NE, RO ACCESS SO DON'T WRITE 95$: ;IF EQ, DO WRITE IF OTHER STUFF OK JSR PC,CD.CLC ;GET THE ADDRESS WE NEED CMP CD.CTL,#-2 ;SPECIAL "ALLOW ALL" CODE? BEQ 22$ ;YES, SKIP SAFETY CHECKS. CMP CD.CTL,#2 ;(ALLOW FOR FILES TOO IF +2) BEQ 22$ TST CD.NEW ;ANYTHING THERE? BEQ 11$ ;IF NOT, NO WRITE CMP R5,CD.BKN ;DID WE READ THIS BLK BEFORE? BNE 11$ ;IF NOT, ALSO FORGET IT. 22$: ADD #CD.BUF,R2 ;POINT R2 AT DATA AREA MOVB R4,(R2)+ ;STORE DATA BIT #1,D.BW ;BYTE MODE? BNE 12$ ;IF NE YES, THAT'S IT SWAB R4 ;NO, WORD MODE. MOVB R4,(R2)+ ;SO SAVE WORD THIS TIME 12$: MOV R2,-(SP) MOV R1,-(SP) MOV R3,-(SP) MOV #IO.WVB,R1 ;WRITE VIRTUAL FUNCTION TST CD.CTL ;IS THIS IO.RVB? BPL 1$ ;IF SO LEAVE IN R1 MOV #IO.WLB,R1 ;ELSE IT'S WRITE LOGICAL 1$: MOV CDFDB,R0 ;FDB WE NEED MOV #C.PL,R3 ;PARAMETER LIST MOV #5,R2 ;5 PARAMS TO USE JSR PC,.XQIO ;DO THE QIOW$ FOR US...GET FILE IN. MOV (SP)+,R3 MOV (SP)+,R1 MOV (SP)+,R2 ;SAVE OFFSET 11$: RTS PC CD.CLC: MOV R3,R5 ;GET ADDRESS TO BLK # SUB CD.BAS,R5 ;FIRST SUBTRACT BASE MOV R5,R2 ;COPY FOR OFFSET OUT IN R2 ASH #-9.,R5 ;SHIFT OFF ALL BUT BLK # (LOW) BIC #^C177,R5 ;CLEAR OUT ALL BUT THE BLK # NEEDED. BIC #^C777,R2 MOV R5,C.BLL+2 ;SAVE LOCALLY THE L.O. BLK # CLR C.BLL ;(CLR H.O.) ADD CD.BLK,C.BLL+2 ;THEN ADD IN BASE. 1ST LOW ORDER ADC C.BLL ;THEN H.O. CARRY ADD CD.BLK+2,C.BLL ;NOW ADD H.O. RTS PC ;THEN DONE. .PSECT ..DDTD C.PL: .WORD CD.BUF,512.,0 C.BLL: .WORD 0,0 ;WHERE BLK # RETURNS (H.O./L.O.) .WORD 0 ;SAFETY .PSECT ..DDTP,RO,I ;CODE .ENDC .PSECT ..DDT.,RW,I .PSECT ..DDTP,RO,I ;CODE ; .IF DF,R$XMDB!R$XDDB ;RSX11M DEBUGGING OR RSX11D DEBUG ; .TITLE DBG11M .GLOBL DBG11M ;ROUTINE TO LOAD RSX11M DEBUGGING INFORMATION INTO DDT ; ; OPERATION: ; THIS ROUTINE IS PASSED THE RAD50 TASK NAME OF A TASK ;THAT IS ASSUMED TO BE SOMEWHERE IN MEMORY. THE TASK IN WHICH THIS ;ROUTINE RUNS IS ASSUMED TO HAVE ACCESS TO THE I/O PAGE ON THE PDP11 ;AND WILL HAVE TO BE LINKED WITH THE RSX11M SYMBOL TABLE TO WORK. ; IT WILL LOOK UP THE TASK ON THE SYSTEM TASK LIST AND RETURN ;THE HEADER ADDRESS AND WILL COMPUTE THE TASK'S APR VALUES USING THE ;WINDOWS IN KERNEL SPACE. THESE WILL BE RETURNED IN GLOBAL LOCATIONS ;HDRADR (FOR THE HEADER) AND TSKAPR (AN 8 WORD ARRAY, FOR APRS 0-7). ; ; ENTRY TASK NAME IS ASSUMED TO BE IN R0,R1 ; ALL REGISTERS ARE DESTROYED HEREIN... ; ; GLENN C. EVERHART ; VIII JUNE MDCCCCLXXVIIII ; ; .GLOBL HDRADR,TSKAPR .PSECT ..DDTD HDRADR: .WORD 0 ;TASK HEADER ADDRESS 9WHEN WE FIND IT TSKAPR: .WORD 0,0,0,0,0,0,0,0 ;TASL'S COMPUTED APRS .WORD 0,0 ;GUARDS... .IF DF,R$XDDB VIRTPR: .WORD 0,0,0,0,0 ;VIRTUAL APRS (USE 1ST ONLY, REST GUARDS) .ENDC .IF DF,MU$DBG M$$CTL: .WORD 1 ;CONTROL 0 IF NO MAP TO TASK, ELSE 1 .ENDC .GLOBL DBG11M ;CALL: ; SET 1ST 3 CHARS OF TASKNAME (RAD50) INTO R0 ; SET 2ND 3 CHARS OF TASKNAME (RAD50) INTO R1 ; JSR PC,DBG11M .PSECT ..DDTP,RO,I ;CODE ; DBG11M: ; ; MUST GO TO PRIO 7 DURING ALL THIS TO PREVENT ANY CONTEXT ;SWITCHES MOV @#PS,-(SP) ;SAVE PSW FIRST .IF DF,R$XDDB MOV #144340,@#PS ;SET PRI7, PREV KNL, REG SET 1 .IFF MOV #140340,@#PS ;SET PRI 7, PREVIOUS KERNEL MODE .ENDC ;NOW THE FUN PART TO FIND STUFF IN RSX. SET UP A MACRO TO ;MAKE IT A LITTLE EASIER TO READ .MACRO KMOV SRC,DST .IF NDF,K$ID ;IF NO KNL I/D SPACE USE MTPI MFPI SRC .IFF MFPD SRC ;IF KNL I/D SPACE USE MTPD/MFPD .ENDC MOV (SP)+,DST ;ALWAYS MOVE FROM KERNEL... .ENDM .IF NDF,R$XDDB KMOV $ACTHD,R2 ;GET ATL HEADER IN R2 ; CLR HDRADR ;HDRADR = 0 ON RETURN IF NO TASK 1$: TST R2 ;BE SURE NOT AT END OF ATL BEQ 2$ ;SKIP IF SO KMOV T.NAM+2(R2),R3 ;GET 2ND 3 CHARS OF TSK NAME CMP R3,R1 ;COMPARE WITH THE ONE WE WANT BNE 3$ ;IF NOT THERE GET NEXT KMOV T.NAM(R2),R3 ;IF 2ND 3 OK TRY 1ST CMP R3,R0 ;CHECK BNE 3$ ;IF NE THEN NOT OUR TASK BR 4$ ;AT THIS POINT WE HAVE OUR TSK SO PROCESS 3$: KMOV T.ACTL(R2),R2 ;GET NEXT LIST ELEMENT (OR 0) BR 1$ ;GO BACK, TRY AGAIN 4$: ;HERE HAVE FOUND THE DESIRED TASK ;NOTE THAT R2 NOW HOLDS THE TCB OF THE TASK WE WANT ; R0 AND R1 ARE NOW FREE ; (CONFOUNDED RSX11M LISTS ARE HARD TO TRACK DOWN... ; LOOKS LIKE TCB POINTS TO PCB POINTS TO TASK HEADER POINTS TO ; WINDOW BLOCKS WHICH ARE WHAT WE NOW NEED...) KMOV T.PCB(R2),R0 ;DE TCB CONNECTS TO DE PCB... KMOV P.HDR(R0),R1 ;..DE PCB CONNECTS TO DE HEADER.. MOV R1,HDRADR ;SAVE TASK HEADER ADDRESS FOR CALLER KMOV H.WND(R1),R3 ;GET WINDOW BLOCK ADDRESES KMOV (R3)+,R4 ;R4 = NUMBER OF WINDOWS NOW ;R3 NOW POINTS TO THE FIRST WINDOW BLOCK. ; TO FIND THE PAR NUMBERS WE WILL CHEAT AND USE THE ;PDR ADDRESS AND NUMBER OF PDR'S. SINCE THERE IS ONE PAR PER PDR ;AND THE PHYSICAL MEMORY START IS IN THE WINDOW BLOCK, WE HAVE ;ALL THAT WE NEED... 10$: KMOV W.BFPD(R3),R1 ;FIRST PDR ADDRESS MOVB R1,R2 ;(1ST PDR ADDR=BYTE) BIS #177600,R2 ;(GUARANTEE RANGE IS OK) SWAB R1 ;GET # OF PDRS (=> # APRS) BIC #177770,R1 ;ZAP HI BYTE OF JUNK BEQ 16$ ;SKIP PAST FILLIN IF NO APRS TO FILL SUB #177600,R2 ;SUBTRACT OFFSET TO USER I PDR 0 BLT 2$ ;NEGATIVE # HERE IS BAD NEWS BIC #177761,R2 ;FORCE R2 TO BE LEGAL ALWAYS KMOV W.BOFF(R3),R5 ;GET NUMBER FOR FIRST PAR 11$: KMOV W.BPCB(R3),R0 ;GET PCB ADDRESS OF WINDOW .IF NDF,K$ID ;KNL ONLY I SPACE (11M, IAS) MFPI P.REL(R0) ;GET BASE OF PRTTN .IFF MFPD P.REL(R0) ;GET BASE OF PRTTN (KNL I/D SPACE (M+)) .ENDC ADD (SP)+,R5 ;FORM APR CONTENT FOR WINDOW START 12$: MOV R5,TSKAPR(R2) ;FILL IN APR NUMBER TST (R2)+ ;PASS THAT APR NUMBER BIC #177761,R2 ;BE SURE R2 STAYS IN BOUNDS... ADD #200,R5 ;BUMP PHYS ADDR DEC R1 ;BE SURE NOT DONE ALL BGT 12$ ;IF DONE, SAY SO 16$: ADD #W.BLGH,R3 ;PASS THIS WINDOW BLOCK DEC R4 BGT 10$ ;DO ALL WINDOWS .IFF ;R$XDDB .MCALL HDRSY$ HDRSY$ ;DEFINE HEADER OFFSETS KMOV .ATLLH,R4 ;GET ATL HEADER ADDRESS CLR HDRADR ;SET NO HDR FOUND AT FIRST 1$: TST R4 ;GOT ANYTHING? BEQ 2$ ;NO, EXIT CMP R4,#.ATLLH ;BE SURE NO CIRCULAR LOOP EITHER BEQ 2$ ;IF THERE IS ONE, SCRAM. KMOV A.TD(R4),R5 ;GET STD ENTRY THEN KMOV S.TN(R5),R3 ;GET 1ST HALF TASK NAME CMP R3,R0 ;SAME AS OURS? BNE 3$ ;NO, TRY NEXT KMOV S.TN+2(R5),R3 ;GET 2ND HALF OF NAME CMP R3,R1 ;SEE IF IT'S OURS BNE 3$ ;IF NOT, GO AWAY. (NOTE NO TESTS FOR TI:) .IF NDF,I$AS31 ;IAS V3.0 AND EARLIER KMOV S.TZ(R5),R3 ;GET TASK SIZE FOR LATER .IFF KMOV A.TZ(R4),R3 ;GET TASK SIZE .ENDC KMOV A.HA(R4),R2 ;GET TASK HDR ADDRESS MOV R2,HDRADR ;SAY WE FOUND A HEADER NOW... ;NOW THE PARS WE WANT ARE IN THE TASK HEADER POINTED TO BY R2 AS PAR. ;SINCE WE HAVE GETCAD SET TO GRAB WHATEVER WE LIKE, USE IT TO GET ;PARS FROM H.PA0(R2) THRU H.PA7(R2)AND MOVE TO VKPAR0 THRU VKPAR7. MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) MOV PARMAP,-(SP) MOV D.BW,-(SP) MOV D.CAD,-(SP) ;SAVE CONTEXT MOV M$$CTL,-(SP) CLR M$$CTL ;SAY NO AUTO MAP TO TASK .IF DF,SPC$MP MOV SR.CTL,-(SP) ;BE SURE DOING REAL MAP HERE CLR SR.CTL ;BY DISABLING SEND/RCV USAGE, ENABLING MAPPING .ENDC MOV #2,D.BW ;SET WORD OPERATIONS MOV #VIRTPR,PARMAP ;SET UP TO USE VIRTPR FOR PAR0 MOV R2,VIRTPR ;SET UP HDR'S APR OFFSET MOV #H.PA0,D.CAD ;GET VIRTUAL ADDRESS USING IT MOV #TSKAPR,R3 ;WHERE TO SAVE DATA MOV #8.,R2 ;NUMBER OF LOOPS TO DO 10$: JSR PC,GETCAD ;GET PAR0 OFFSET MOV R0,(R3)+ ;SAVE ADD #2,D.CAD ;POINT AT NEXT APR SOB R2,10$ ;AND DO FOR ALL 8 APRS POSSIBLE. .IIF DF,SPC$MP, MOV (SP)+,SR.CTL ;RESTORE OLD SEND/RCV STATE MOV (SP)+,M$$CTL MOV (SP)+,D.CAD MOV (SP)+,D.BW MOV (SP)+,PARMAP ;RESTORE CONTEXT MOV (SP)+,R5 MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 BR 2$ 3$: KMOV (R4),R4 ;GET NEXT ATL ELEMENT BR 1$ .ENDC 2$: MOV (SP)+,@#PS ;RESTORE ORIGINAL PSW RTS PC .ENDC ;R$XMDB .PSECT ..DDT.,RW,I .PSECT ..DDTD ; INSTRUCTION DECODE/ENCODE TABLE .MACRO INSTRS ; THE FIVE PARAMETERS TO THE CODE OP-CODE DESCRIBE AN INSTRUCTION: ; THE FIRST PARAMETER IS THE LOWER LIMIT OF VALUES THAT WILL FALL ; INTO THAT OP-CODE (THE TABLE MUST BE SCANNED SEQUENTIALLY) ; THE SECOND PARAMETER IS THE OP-CODE TEXT ; THE THIRD PARAMETER TELLS THE MACHINE SUITABILITY ; 0 MEANS ANY MACHINE HAS THIS INSTRUCTION. 1 MEANS ; 11/40 AND UP ONLY, 2 MEANS 11/45 ONLY. ; THE FOURTH PARAMETER TELLS HOW TO DECODE THE PARAMETERS: ; 0 MEANS NO PARAMETERS ; 1 MEANS "NNNNNN" (16 BIT NUMBER) ; 2 MEANS DECODE CONDITION CODE BITS (NZVC) ; 3 MEANS "N" (3 BIT NUMBER) ; 4 MEANS "XXX" (8 BIT DISPLACEMENT) ; 5 MEANS "R,DD" ; 6 MEANS "NN" (6 BIT NUMBER) ; 7 MEANS "SS,DD" (OR "DD,SS") ; 10 MEANS "R" ; 11 MEANS "R,NN" (6 BIT DISPLACEMENT) ; 12 MEANS "NNN" (8 BIT NUMBER) ; 13 MEANS "DD" (OR "SS") ; 14 MEANS "SS,R" ; 15 MEANS "SS,R" WITH 2 BIT R FIELD (FPU INSTS) ; 16 MEANS "R,SS" WITH 2 BIT R FIELD (FPU INSTS) ; THE FIFTH PARAMETER IS 1 IF THIS INSTRUCTION IS LEGAL IN BYTE MODE .IF NDF,$FOP$ CODE 0,HALT,0,0,0 CODE 1,WAIT,0,0,0 .IFF CODE 0,HLT,0,0,0 CODE 1,WAT,0,0,0 .ENDC CODE 2,RTI,0,0,0 CODE 3,BPT,0,0,0 CODE 4,IOT,0,0,0 .IF DF,$FOP$ CODE 5,RST,0,0,0 .IFF CODE 5,RESET,0,0,0 .ENDC CODE 6,RTT,1,0,0 CODE 7,,0,1,0 CODE 100,JMP,0,13,0 CODE 200,RTS,0,10,0 CODE 210,,0,1,0 CODE 230,SPL,2,3,0 CODE 240,NOP,0,0,0 CODE 241,CL,0,2,0 CODE 257,CCC,0,0,0 CODE 260,,0,1,0 CODE 261,SE,0,2,0 CODE 277,SCC,0,0,0 CODE 300,SWAB,0,13,0 CODE 400,BR,0,4,0 CODE 1000,BNE,0,4,0 CODE 1400,BEQ,0,4,0 CODE 2000,BGE,0,4,0 CODE 2400,BLT,0,4,0 CODE 3000,BGT,0,4,0 CODE 3400,BLE,0,4,0 CODE 4000,JSR,0,5,0 CODE 5000,CLR,0,13,1 CODE 5100,COM,0,13,1 CODE 5200,INC,0,13,1 CODE 5300,DEC,0,13,1 CODE 5400,NEG,0,13,1 CODE 5500,ADC,0,13,1 CODE 5600,SBC,0,13,1 CODE 5700,TST,0,13,1 CODE 6000,ROR,0,13,1 CODE 6100,ROL,0,13,1 CODE 6200,ASR,0,13,1 CODE 6300,ASL,0,13,1 .IF DF,$FOP$ CODE 6400,MK,1,6,0 .IFF CODE 6400,MARK,1,6,0 .ENDC CODE 6500,MFPI,1,13,0 CODE 6600,MTPI,1,13,0 CODE 6700,SXT,1,13,0 CODE 7000,,0,1,0 CODE 10000,MOV,0,7,1 CODE 20000,CMP,0,7,1 CODE 30000,BIT,0,7,1 CODE 40000,BIC,0,7,1 CODE 50000,BIS,0,7,1 CODE 60000,ADD,0,7,0 CODE 70000,MUL,1,14,0 CODE 71000,DIV,1,14,0 CODE 72000,ASH,1,14,0 CODE 73000,ASHC,1,14,0 CODE 74000,XOR,1,5,0 .IF DF,$D$FPU CODE 75000,FA,1,10,0 CODE 75010,FS,1,10,0 CODE 75020,FM,1,10,0 CODE 75030,FD,1,10,0 .IFF CODE 75000,FADD,1,10,0 CODE 75010,FSUB,1,10,0 CODE 75020,FMUL,1,10,0 CODE 75030,FDIV,1,10,0 .ENDC CODE 75040,,0,1,0 CODE 77000,SOB,1,11,0 CODE 100000,BPL,0,4,0 CODE 100400,BMI,0,4,0 CODE 101000,BHI,0,4,0 CODE 101400,BLOS,0,4,0 CODE 102000,BVC,0,4,0 CODE 102400,BVS,0,4,0 CODE 103000,BCC,0,4,0 CODE 103000,BHIS,0,4,0 CODE 103400,BCS,0,4,0 CODE 103400,BLO,0,4,0 CODE 104000,EMT,0,12,0 CODE 104400,TRAP,0,12,0 CODE 105000,,0,1,0 ;GET PREV DATA OR PUT PREV DATA .IF DF,$FOP$ CODE 106500,GD,2,13,0 CODE 106600,PD,2,13,0 .IFF CODE 106500,MFPD,2,13,0 CODE 106600,MTPD,2,13,0 .ENDC CODE 106700,,0,1,0 CODE 160000,SUB,0,7,0 .IF NDF,$FOP$ CODE 170000,,0,1,0 .IFF .IF DF,L$GFP ;THESE DON'T FIT IN BYTE TBL. ;MUST MAKE WORD TBL TO MAKE THEM GO IN. USE SHORT VERSIONS BELOW. CODE 170000,CFCC,2,0,0 CODE 170001,SETF,2,0,0 CODE 170002,SETI,2,0,0 CODE 170003,,0,1,0 CODE 170011,SETD,2,0,0 CODE 170012,SETL,2,0,0 CODE 170013,,0,1,0 CODE 170100,LDFPS,2,13,0 CODE 170200,STFPS,2,13,0 CODE 170300,STST,2,13,0 CODE 170400,CLRF,2,13,0 CODE 170500,TSTF,2,13,0 CODE 170600,ABSF,2,13,0 CODE 170700,NEGF,2,13,0 CODE 171000,MULF,2,14,0 CODE 171400,MODF,2,15,0;;;; CODE 172000,ADDF,2,14,0 CODE 172400,LDF,2,15,0;;;; CODE 173000,SUBF,2,14,0 CODE 173400,CMPF,2,15,0;;;; CODE 174000,STF,2,16,0 CODE 174400,DIVF,2,15,0;;;; CODE 175000,STEXP,2,16,0 CODE 175400,STCFI,2,16,0;;;; CODE 176000,STCFD,2,16,0 CODE 176400,LDEXP,2,15,0;;;; CODE 177000,LDCIF,2,14,0 CODE 177400,LDCDF,2,15,0;;;; .IFF CODE 170000,CC,2,0,0 ;CFCC CODE 170001,F,2,0,0 ;SETF CODE 170002,I,2,0,0 ;SETI CODE 170003,,0,1,0 CODE 170011,D,2,0,0 ;SETD CODE 170012,L,2,0,0 ;SETL CODE 170013,,0,1,0 CODE 170100,LS,2,13,0;LDFPS CODE 170200,SS,2,13,0;STFPS CODE 170300,S,2,13,0 ;STST CODE 170400,C,2,13,0 ;CLRF CODE 170500,T,2,13,0 ;TSTF CODE 170600,AB,2,13,0;ABSF CODE 170700,NG,2,13,0;NEGF CODE 171000,ML,2,14,0;MULF CODE 171400,MD,2,15,0;MODF CODE 172000,AD,2,14,0;ADDF CODE 172400,LD,2,15,0;LDF CODE 173000,SB,2,14,0;SUBF CODE 173400,CM,2,15,0;CMPF CODE 174000,ST,2,16,0;STF CODE 174400,DV,2,15,0;DIVF CODE 175000,SX,2,16,0;STEXP CODE 175400,SI,2,16,0;STCFI CODE 176000,SD,2,16,0;STCFD CODE 176400,LX,2,15,0;LDEXP CODE 177000,LI,2,14,0;LDCFI CODE 177400,LF,2,15,0;LDCDF .ENDC .ENDC CODE 177777,,0,1,0 .ENDM ; .PSECT ..DDT.,RW,I ; WORD ALIGNED CONSTANTS D.UADD: D.WULF ; UW WULF COMMAND D.ONES ; UT SINGLE STEP MODE .IIF DF,D.GDP,D.GRAP ; UG RETURN USER DISPLAY .IF DF,$VMEM .WORD O.OVIR ;UM MAP VIRTUAL MAPPING .WORD O.KVIR ;UK MAP WITH KERNEL APR'S .WORD O.UVIR ;UU MAP WITH USER APR'S .WORD O.EVIR ;UR REMOVE VIRTUAL MAPPING .WORD O.VVIR ;UV REMOVE VIRTUAL USE ALTOGETHER .WORD O.BVIR ;UB SET VIRTUAL BASE ("PAR,ADDR$UB") .IF DF,$VPAT .WORD O.PATW ;addr - 3RD SET OF COMMANDS D.LGDR: ; COMMAND DISPATCH TABLE D.ORAB ; @ OPEN RELATED, ABSOLUTE--AS ODT D.ERR ; # ERROR D.ERR ; ( ERROR D.ADD ; + D.ADD ; D.MULT ; * MULTIPLICATION D.DIV ; ' DIVISION D.SUBT ; - SUBTS SIGN D.ERR ; ) ERROR D.TEXT ; " MAKE ASCII D.LWAS ; > D.FWAS ; < SET FIRST WORD OF SEARCH D.EQAL ; = D.ALTM ; $ ALTMODE D.COLN ; : DEFINES SYMBOL D.SEMI ; ; RE-TYPE WORD D.WRD ; / OPEN WORD D.BKSL ; \ STORE AND REFERENCE D.DCOM ; , COMMA PARAMETER D.CRET ; CLOSE D.OP1 ; MODIFY, CLOSE, OPEN NEXT D.ORPC ; _ TYPE WORD AS INSTRUCTION D.BACK ; ^ OPEN PREVIOUS .IIF DF,D.GDP,D.SOFT ; SOFT RESTART AT 1004 D.ORAB ; OPEN RELATED, ABSOLUTE D.OPBR ; [ OPEN WORD AS NUMERIC D.CLBR ; ] OPEN WORD AS INSTRUCTION D.RDT1 ; ? OPEN WORD IN RAD50 D.EXCL ; ! OPEN WORD SILENTLY D.ERR ; SECOND SPACE (ERROR) D.ABS ; A ABSOLUTE ADDRESSES D.BKPT ; B BREAKPOINTS D.INNM ; C IN NUMERICS D.DELE ; D KILL LAST SYMBOL D.EFF ; E SEARCH EFFECTIVE ADDRESS D.ERR ; F ERROR D.GO ; G GO TO ADDRESS K D.INHA ; H IN HALF WORDS D.ALTI ; I STATUS ADDRESS .IF NDF,DB$L D.ERR ; J ERROR .IFF .WORD JXAM ; J EXAMINE/INSERT 32 BIT INTEGER .ENDC D.KILL ; K SYMBOL TABLE DELETION .IF NDF,CD$FIL D.ERR ; L ERROR .IFF CD.OPN ; L LOOK UP CODE FILE OR CLOSE .ENDC D.MAST ; M SET MASK D.NSCH ; N NON-SEARCH D.BYTE ; O TYPEOUT IN BYTES D.PROC ; P PROCEED D.ALTQ ; Q CURRENT WORD D.INRD ; R SET RADIX D.INMD ; S IN INSTRUCTION MODE D.INTX ; T IN TEXT D.SNGL ; U SECOND SET OF ROUTINES D.ALTV ; V SWAB OF CURRENT WORD D.WSCH ; W SEARCH WORD D.EXEC ; X EXECUTE INSTRUCTION .IF DF,X$ORG D.ERR ; Y ERROR .IFF D.Q ; Q REG MANIPULATION .ENDC D.ZERO ; Z ZERO CORE D.PARM: D.RTS D.N16 D.CZVN D.N3 D.X8 D.RDD D.N6 D.SSDD D.R D.RN6 D.N8 D.DD D.DDR D.RD2 D.RDD2 D.PARG: D.NONE ; NO PARAMETERS D.NONE ; 16-BIT NUMBER NOT AN INSTRUCTION D.NONE ; CONDITION CODE ALREADY DECODED D.NONE ; 3 BIT OPERAND ADDED IN AUTOMATICALLY D.DISP ; GET 8-BIT DISPLACEMENT D.GRSS ; GET "R,SS" D.GNUM ; GET 6-BIT NUMBER (MARK OPERAND) D.GSD ; GET "SS,DD" D.GR ; GET "R" D.GRNN ; GET "R,NN" D.GNUM ; GET 8-BIT OPERAND D.GDD ; GET "DD" (OR "SS") D.GDDR ; GET "DD,R" D.GRS2 ; GET "R,SS", 2 BIT R FIELD D.GR2 .MACRO CODE TOP,STR,LEG,PARM,BYT .WORD TOP-1 .ENDM D.TOPS: INSTRS .WORD -1 .MACRO CODE TOP,STR,LEG,PARM,BYT .BYTE ++LEG .NCHR D.LEN,STR D.ADDR=D.ADDR+D.LEN .BYTE D.ADDR .ENDM D.ADDR=0 D.COUS: .BYTE D.ADDR D.LEGS: INSTRS D.ECNT=.-1 .MACRO CODE TOP,STR,LEG,PARM,BYT .ASCII "STR" .ENDM D.STRS: INSTRS .IF DF,D.UUY D.UYTB: .ASCII /A/ ;DUMMY LETTER TABLE FOR $UY COMMANDS D.EUYT=.-D.UYTB .EVEN D.UYAD: .WORD D.ERR ;ADDRESSES FOR D.UYTB LETTER COMMANDS. $UYA - ERROR .ENDC ; BYTE ALIGNED CONSTANTS D.FIRS: .ASCII <0> "((@(-(@-(" <0> "@" <0> "))+)+))))??#@#??" <0> "@SPPC" D.NZVC: .ASCII "CVZN" D.OPCH: .BYTE 0,1,2,3,5,7,12,13 D.CLOS: .BYTE 14,15,16,20,22,23,24,25 D.MOD7: .BYTE 26,27,30,31,33,34,35,36 D.SP: .BYTE 37,41,43 D.GRET: .ASCII <15><12>"DDT-11 V005 : " .IF NDF,$$RSX .IIF NDF,D.GDP,.ASCII "; MANUAL RESTART = " .ENDC .IIF DF, $$RSX, .ASCII / RSX/ .IIF DF, $VMEM, .ASCII "/22BIT" .IIF DF, $D$FPU, .ASCII "/FPU" .IIF DF, DULMOD, .ASCII "/KNL" .IIF DF, MU$DBG, .ASCII "/MTSK" .IIF DF, SM$FIL, .ASCII "/STB" .BYTE 40 D.GRND =.-1 .EVEN D.BE: .ASCII ";BPT!" D.NM: .ASCII ";NXM!" D.IM: .ASCII ";ILG!" D.TRA: .ASCII ";TRP!" D.EMT: .ASCII ";EMT!" D.SEG: .ASCII ";SEG!" D.IOT: .ASCII ";IOT!" .EVEN D.UTAB: .BYTE 'W ; W .BYTE 'T ; T .IIF DF,D.GDP,.BYTE 'G ; G .IIF DF,$VMEM, .ASCII /MKURVB/ ;VIRTUAL MAPPING COMMANDS .IF DF,$VMEM .IF DF,$VPAT .ASCII /PH/ ;PATCHING FUNCTIONS .ENDC .ASCII /D/ .IIF DF,$DDBSX, .ASCII /A/ .ENDC .IIF DF,D.MCRO, .ASCII /ENCSF/ .IIF DF,R$XMDB!R$XDDB, .ASCII /L/ .IIF DF,SM$FIL, .ASCII /OQ/ .IIF DF,MEM$BK, .ASCII /Z/ .IIF DF,$D$FPU, .ASCII /IJX/ ;FREE: Y .IIF DF,D.UUY, .ASCII /Y/ .BYTE 0 ;SAFETY BDY D.ENUT =.-D.UTAB D.LGCH: ; FIRST CHARACTERS MUST BE "@#(+ *'-)" .BYTE '@ ; @ D.HASH =.-D.LGCH .BYTE '# ; # D.OPAR =.-D.LGCH .BYTE '( ; ( D.ADDS =.-D.LGCH .BYTE '+ ; + D.SPAC =.-D.LGCH .BYTE ' ; .BYTE '* ; * .BYTE '' ; ' D.DASH =.-D.LGCH .BYTE '- ; - D.CPAR =.-D.LGCH .BYTE ') ; ) .BYTE '" ; " .BYTE '> ; > .BYTE '< ; < .BYTE '= ; = .BYTE 33 ; D.COLO =.-D.LGCH .BYTE ': ; : .BYTE '; ; ; .BYTE '/ ; / .BYTE '\ ; \ D.COMM =.-D.LGCH .BYTE ', ; , D.CR: .BYTE 15 ; .BYTE 12 ; .BYTE '_ ; _ .BYTE '^ ; ^ .IIF DF,D.GDP,.BYTE 3 ; .BYTE 11 ; .BYTE '[ ; [ .BYTE '] ; ] .BYTE '? ; ? .BYTE '! ; ! D.LETR =.-D.LGCH D.RDTB: .ASCII " ABCDEFGHIJKLMNOPQRSTUVWXYZ" D.CLGT =.-D.LGCH ; COMMAND TABLE END .ASCII "$.*0123456789" D.ENTB =.-D.RDTB ; .PSECT ..DDT.,RW,I ; BYTE ALIGNED VARIABLES .IF DF,D.KSR D.CPOS: .BYTE D.CNUM ; CHARACTER POSITION FOR TTY D.BUFR: .BLKB 25. ; 25 CHARACTER INPUT BUFFER D.ENDB: .ENDC D.USED: .BYTE 0 ; IF ZERO, USE OCTAL NUMBER D.MACH: .BYTE 1 ; 0=11/15 1=11/40 2=11/45 D.LEVL: .BYTE 0 ; PARENTHESIS LEVEL D.FWAF: .BYTE 0 ; MARKER OF < PARAMETER D.INPA: .BYTE 0 ; NON-ZERO IF IN AN INSTRUCTION TYPE-IN D.P: .BYTE -1 ; PROCEED FLAG = <1-8>*2 IF NORMAL BREAK ; 0 IF SINGLE STEP BREAK ; -1 IF NOT ENTERED BY BREAK D.ALTF: .BYTE 0 ; ALTMODE FOUND D.WAMS: .ASCII "; WORDS" ;NOTE FOLLOWING 2 BYTES MUST PRECEDE D.BMES IMMEDIATELY: .BYTE 15,12 ;CR, LF D.BMES: .ASCII "$ B >> " ; .PSECT ..DDT.,RW,I .PSECT ..DDTD ; WORD ALIGNED VARIABLES .EVEN .IF DF,MEM$BK ;ALLOW CHEAPIE MEMORY BREAKPOINT VIA SINGLE INSTRUCTION TRAP. ;NOTE THAT D.CT IS ACCESSABLE AND THE PROCEED COUNT THERE (FOR B.P. #0) ;MAY BE SET NEGATIVE TO ALLOW PROCEED. IF MEMCTL IS NONZERO, THEN, THE ;DATA AT MEMBPA WILL BE COMPARED TO MBPVAL AND WHEN NONZERO, THE ;PROCEEDS WILL BE DISABLED. THIS PROVIDES A SLOW BUT EFFECTIVE ;MEMORY-ALTERATION STOP. ; -- UP TO 8 OF THESE WILL BE ALLOWED AND THE $UZ COMMAND WILL SUPPORT THE ;OPTION MORE EASILY... .GLOBL MEMADR MEMADR: MEMBPA: .WORD 0 ;ADDRESS (IN USER SPACE) OF MEMORY CELL TO MONITOR .BLKW MEMCTL: .WORD 0 ;CONTROL. TURNS ON MEM BREAKPOINT IF NON-0 MBPVAL: .WORD 0 ;DATA VALUE AT MEMBPA AT LAST INST .BLKW .ENDC .IF DF,D.MCRO ;IF MACROS ARE ENABLED D.KBPT: .WORD D.KBBF ;CORE INPUT ADDRESS IM.G=0 .IF DF,MU$DBG .IIF DF,IM$$G,IM.G=1 .ENDC D.ECSW: .WORD 0 ;ECHO FLAG. 0=NO,1=YES D.CHSW: .WORD IM.G ;CORE IN SWITCH 0=KB, 1=CORE IN D.KBBF: .IF DF,MU$DBG .IF DF,IM$$G ;IF IM$$G IS DEFINED, PERFORM AN IMMEDIATE $G TO START DDT22M UP AT INIT. .BYTE 33,'G,-1,-1 ;$G, THEN DELIMITERS TO GET CONSOLE NEXT .EVEN .ENDC .ENDC .BLKW <66.-<2*IM.G>> ;CORE INPUT BUFFER. NEG. CODE TERMINATES. .BYTE 33,33 ;ESCAPES D.KBFE: .WORD -1,-1 ;FENCES .ENDC .IF DF,I$$SD MDLNAM: .RAD50 /.MAIN./ ;MODULE NAME FOR 1ST HALF OF ISD DECLARATIONS MDLCTL: .WORD 0 ;1 IF USING ISD TYPE NAMES, ELSE 0 .ENDC .IF DF,PR$FIL ;PROFILER DATA AREA PRFCTL: .WORD 0 ;0 = PROFILER OFF, 1=PROFILER ON PRFBAS: .WORD 0 ;BASE ADDRESS OF PROFILE PRFSHF: .WORD 0 ;+ SHIFT COUNT OF PROFILER. 0 = NO SHIFT ;1=SHIFT RIGHT 1, 2=SHIFT RIGHT 2, ETC. .IIF NDF,PF$SZZ,PF$SZZ=4096. PRFHST: .BLKW PF$SZZ ;HISTOGRAM OF ADDRESSES EXECUTED PRFSIZ=.-PRFHST .WORD 0 ;SAFETY .ENDC .IF DF,MEM$TR .IIF NDF,MT.NUM,MT.NUM=32. MT.BUF: .BLKW MT.NUM MT.TOP: .WORD 0 ;SAFETY .WORD 0 MT.PTR: .WORD MT.BUF ;POINTER TO SAVED PCs. .ENDC .IF DF,CD$FIL CD.BKN: .WORD 0 ;BLK # IN CD.BUF CD.BUF: .BLKW 256. ;BUFFER FOR CODE FILE CD.BAS: .WORD 0 ;BASE ADDRESS FOR CODEFILE CD.CTL: .WORD 0 ;CONTROL, 0=NO CODEFILE ; += CODEFILE A FILE ; -= CODEFILE A DEVICE CD.BLK: .WORD 1,0 ;LO,HI BLK # TO ADD TO GET TO CODE BLK .ENDC .IF DF,D.KSR D.INPU: D.BUFR ; INPUT BUFFER POINTER D.OUTP: D.BUFR ; OUTPUT BUFFER POINTER .ENDC .IIF DF,$FORM$, D.FFPC: .WORD 0 ;INT COUNTER FOR FORMATION PANEL .IIF DF, $FORM$, .GLOBL D.FFPC .IIF DF, $$RSX, DDTDSW: .WORD 0 ;DSW STORAGE FOR RSX DDT D.SYM: .BLKW /2 ; HOLDS SYMBOL TYPED D.SD.T: ; WORD ADDRESS OF D.S AND D.T D.S: .BYTE 0 ; SINGLE STEP FLAG D.T: .BYTE 0 ; T-BIT FLAG D.BOTH: ; WORD ADDRESS OF D.NOTY AND D.FIND D.NOTY: .BYTE 0 ; DON'T TYPE OUT IF EQUALS 1 D.FIND: .BYTE 0 ; ADDRESS FOUND (EFF SEARCH) IF EQUALS 1 D.TPC: 0 ; PC OF LAST BPT WE PROCEEDED D.LFIN: 0 ; LINE FEED INCREMENT ; THE NEXT 4 WORDS FORM THE TEMPORARY MODE TABLE AND MUST BE IN ORDER******** D.CURM: D.INST ; TYPEOUT MODE ADDRESS ***** D.DVTB: 8. ; CURRENT RADIX ***** D.BW: 2 ; BYTE-WORD INDICATOR (1=BYTE, 2=WORD) ***** D.IFMT: 0 ; (1=ABSOLUTE, 0=RELATIVE) ***** ; END OF CRITICAL ORDERING*************************************************** ; THE NEXT 4 WORDS FORM THE PERMANENT MODE TABLE AND MUST BE IN ORDER******** D.PERM: D.INST ; PERMANENT TYPEOUT MODE ***** D.PERN: 8. ; PERMANENT RADIX ***** D.PEBW: 2 ; PERMANENT BYTE-WORD INDICATOR ***** D.PEFM: 0 ; PERMANENT ADDRESS TYPEOUT INDICATOR ***** ; END OF CRITICAL ORDERING*************************************************** D.OMOD: D.INST ; MODE TO OPEN WORDS IN D.OPER: 0 ; OPERATION D.DECN: 0 ; DECIMAL NUMBER D.SVR2: 0 ; SAVE FOR R2 .PSECT ..DDT. .IF DF,$$RSX D.XGO: .IIF NDF,MU$DBG, MOV #D.TMP,DDTODD ;SET UP ODD ADDRESS TRAP .IIF DF,MU$DBG,.GLOBL D.SVR4,D.PARS,D.SVR7 .ENDC ; THE NEXT THREE LINES MUST BE IN THAT ORDER FOR $X INST.******************** D.SVR4: 0 ; SAVE FOR R4 ***** D.PARS: 0,0 ; PARAMETERS FOR INSTR. TYPE-IN ***** ;NOTE IF MU$DBG IS DEFINED WE NEVER REALLY EXECUTE THIS INSTRUCTION... .IIF DF,$$RSX,JMP @#3 ;CAUSE TRAP THRU ODD ADDR JMP D.EXE2 ; RETURN IN CASE INSTRUCTION FINISHES ***** ; END OF CRITICAL ORDERING*************************************************** .PSECT ..DDTD ; D.SVR7: 0 ; SAVE FOR PC DURING $X D.PARO: 0,0 ; RELOCATIOON FOR D.PARS D.OFST: 0 ; OFFSET FROM COMMA D.RFNL: 127. ; RFND OFFSET D.LASV: 0 ; LAST TYPED NUMBER D.LASW: 0 ; LAST TYPED WORD D.DOT: 0 ; CURRENT LOCATION D.CADC: 0 ; COPY OF D.CAD FOR TYPE-IN D.ERF: 0 ; ADDRESS OF ERROR MESSAGE D.CAD: 0 ; CURRENT ADDRESS D.XXX: 0 ; TEMPORARY STORAGE D.COMA: 0 ; ADDRESS BEFORE COMMA D.SIZE: 0 ; BYTE SIZE FOR "O" TYPEOUT D.RAD1: 0 ; FIRST WORD OF RAD50 SYMBOL D.RAD2: 0 ; SECOND WORD OF RAD50 SYMBOL D.LASC: 0 ; LAST COLONED WORD D.FILV: .WORD 0 ;FILLER VALUE FOR $Z COMMAND ; .IF DF,$$RSX D.SVOD: .WORD D.NXMT ;ADDR OF ODD ERR TRAP ;ARRIVE HERE AFTER IMMEDIATE INSTRUCTION EXECUTION VIA inst$X ; IN ORDER TO CAPTURE PSW CONTENTS. CANNOT RELY ON PSW IN OUR ;ADDRESS SPACE AT ALL TIMES FOR THIS SO MUST FAKE IT UP. ; ---> NOTE THAT IN DEBUGGING ANOTHER TASK WE REALLY DON'T ; ---> QUITE NEED THE PSW THE SAME WAY, BUT FAKE THINGS UP ; HERE ANYWAY AND IN DDTMU TO ALLOW $X TO WORK. CUTE FIX ; ALLOWS THE CODE TO WORK EVEN THOUGH WE ARE IN A DIFFERENT ; TASK CONTEXT. .PSECT ..DDTP,RO,I ;CODE D.TMP: .IF NDF,MU$DBG MOV D.SVOD,DDTODD ;RESTORE ODD ADDR TRAP TO USUAL .ENDC TST (SP)+ ;FLUSH OLD PC MOVB (SP),D.USTA ;SAVE USER PS (LO BYTE ONLY) TST (SP)+ ;POP OFF OLD STACK JMP D.EXE2 ;FINISH $X INSTRUCTION .ENDC .PSECT ..DDTD D.FENC: D.SYMA ; ADDRESS OF FENCE SYMBOL TABLE D.POS: D.SYM ; ADDRESS OF CHARACTER IN D.SYM D.FWA: 0 ; LOW LIMIT D.LWA: DDT-2 ; HIGH LIMIT D.MASK: 177777 ; MASK .IIF DF,MU$DBG, .GLOBL D.CT,D.BKTB,D.UIN,D.OPEN ; BREAKPOINT ADDRESSES D.BKTB: .REPT D.BKP 0 ; ADDRESS OF BREAKPOINTS .ENDR ; PROCEED COUNT D.CT: .BLKW D.BKP+1 ; EXTRA LOCATION FOR SINGLE STEP D.UIN: .BLKW D.BKP ; INSTRUCTION AT BREAKPOINT LOC'N ; LOCATION TO OPEN AT EACH BREAKPOINT D.OPEN: .BLKW D.BKP+1 ; EXTRA LOCATION FOR SINGLE STEP .IF DF,CND$BK .GLOBL D.BMSK,D.BTST D.BMSK: .BLKW D.BKP+1 ;EXTRA LOC FOR SINGLE STEP D.BTST: .BLKW D.BKP+1 ;EXTRA LOC FOR SINGLE STEP .ENDC ; .PSECT ..DDT.,RW,I ; THE DDT STACK, INCLUDING SOME VARIABLES AT ITS BASE (HIGH ADDRESSES) ; WHICH DESCRIBE THE USER'S PROGRAM STATE: ; THE FOLLOWING VARIABLES ARE CRITICALLY ORDERED FOR VARIOUS REASONS.******** .BLKW 100. .IIF DF,SM$FIL, .BLKW 140. .BLKW 40. ; ACTIVE STACK AREA ***** D.STK: ; BASE OF ACTIVE DDT STACK ***** .IF NDF,$$RSX ;IN RSX, NO SAVE/RESTORE EXTRA STUFF .IIF DF,D.KSR, 0 ; SAVE CELL - R C/SR ***** 0 ; SAVE CELL - T C/SR ***** 0,0,0,0 ; USER LOCATION 12,10,6,4 ***** .ENDC .IF DF,$$RSX .IF DF,XTCOM .WORD 0,0 .ENDC .ENDC D.UR0: 0 ; USER REGISTER 0 ***** D.UR1: 0 ; USER REGISTER 1 ***** D.UR2: 0 ; USER REGISTER 2 ***** D.UR3: 0 ; USER REGISTER 3 ***** D.UR4: 0 ; USER REGISTER 4 ***** D.UR5: 0 ; USER REGISTER 5 ***** D.UR6: 0 ; USER SP ***** D.UR7: 0 ; USER PC ***** JOBSA: DDT ; USER START ADDRESS ***** ; END OF CRITICALLY ORDERED VARIABLES**************************************** .IF DF,ER$SV D.ERPC: .WORD 0 D.ERR0: .BLKW 7 ;PC, REGS SAVED AT D.ERR CALLS ON INTERNAL ERROR .ENDC .IIF DF,X$OVL, OVRBRK: .WORD 0 ;OVERLAY BREAKPOINT .IF DF,MU$DBG .IF DF,SPC$MP SR.CTL: .WORD SPC$MP ;SEND/RCV CONTROL MODE .ENDC .ENDC .IF DF,$VMEM VKPAR0: .WORD 0 VKPAR1: .WORD 0 ;VIRTUAL PARS VKPAR2: .WORD 0 VKPAR3: .WORD 0 VKPAR4: .WORD 0 VKPAR5: .WORD 0 VKPAR6: .WORD 0 VKPAR7: .WORD 0 ORGPAR: .BLKW 8. PARMAP: .WORD 0 ;INITIALLY USE ORGPAR TABLE FOR MAPPING. .ENDC .IF DF,U$ID.!MPV2. ;FLAG FOR USER MODE I VS D SPACE ;0 IF D SPACE, NONZERO FOR I SPACE ; IF NEGATIVE, JUST ACCESSES NORMALLY ; WITH NO SPECIAL PROCESSING. IF POSITIVE OR 0, HOWEVER, CAUSES I OR D ; SPACE TO BE ACCESSED. $-1UV SETS NEGATIVE, $UV SETS D SPACE, $1UV SETS ; I SPACE. UV$SPF: .WORD 0 ;START IN D SPACE UV$SPS: .WORD 0 ;SAVE FOR UV$SPF AT $UV COMMAND .ENDC .IF DF,$$RSX .IF DF,SM$FIL .SYMPT: .WORD .SYMBG ;SYMBOL TABLE AREA RESERVED FOR NAMES ;FROM .STB FILE. THESE FILL IN CIRCULARLY ;OVER A RANGE AND ARE ALWAYS MARKED ;AS FULL FOR THE REST OF DDT. .SYMBG ;AND .SYMND DEFINE START, END OF LIST. .ENDC .PSECT ..DDTP,RO,I ;CODE .MCALL EXIT$S RSXEXT: .IF DF,SM$FIL .IF DF,CD$FIL TST CDFDB ;CODEFILE FDB OPEN BEQ 82$ ;IF EQ NO MOV CDFDB,R0 CLOSE$ 82$: .ENDC ;CLOSE SYMBOL TBL FILE HERE IF APPROPRIATE. TST STBFDB ;IS STB FILE OPEN? BEQ 1$ ;IF NOT DON'T CLOSE IT MOV STBFDB,R0 CLOSE$ ;IF SO, DO CLOSE IT 1$: .ENDC EXIT$S .PSECT ..DDTD .ENDC .IF DF,$$RT11 .MCALL .EXIT RTEXIT: .EXIT ;GO TO RT11 .ENDC .IIF DF,$$DOS,DOSEXT: EMT 60 ;EXIT TO DOS .PSECT ..DDTD D.USTA: 0 ; USER STATUS D.DSTA: D.PRIO ; DDT'S STATUS .PSECT .SYMS.,RW,CON ;ALLOW SYMBOL .PSECT TO BE EXTENDED BY USERS D.SYMA: .RAD50 /R0 / ; THIS SYMBOL TABLE MUST APPEAR .IIF DF,MU$DBG, .GLOBL U.R0,U.R1,U.R2,U.R3,U.R4,U.R5,U.SP,U.PC,U.PS ;NOTE THESE SYMBOL NAMES ARE USED TO REFER TO TASK R0-PC IN MULTITASK ;DEBUGGER. NAMES D.R0 ETC ARE USED FOR DDT'S REGISTERS. U.R0: D.UR0 ; AT THE END OF DDT SINCE IT IS .RAD50 /R1 / ; EXTENDED MAGICALLY BY THE LINKER U.R1: D.UR1 ; STARTING AT ADDRESS D.SYMT .RAD50 /R2 / U.R2: D.UR2 .RAD50 /R3 / U.R3: D.UR3 .RAD50 /R4 / U.R4: D.UR4 .RAD50 /R5 / U.R5: D.UR5 .RAD50 /SP / U.SP: D.UR6 .RAD50 /PC / U.PC: D.UR7 .RAD50 /U.PSW / U.PS: .WORD D.USTA .IF DF,MU$DBG .IF NDF,X$DSW .RAD50 /U.DSW / U.DSW: .WORD DDTDSW ;$DSW FROM OTHER TASK .ENDC .RAD50 /D.R0 / ; THIS SYMBOL TABLE MUST APPEAR D.UR0 ; AT THE END OF DDT SINCE IT IS .RAD50 /D.R1 / ; EXTENDED MAGICALLY BY THE LINKER D.UR1 ; STARTING AT ADDRESS D.SYMT .RAD50 /D.R2 / D.UR2 .RAD50 /D.R3 / D.UR3 .RAD50 /D.R4 / D.UR4 .RAD50 /D.R5 / D.UR5 .RAD50 /D.SP / D.UR6 .RAD50 /D.PC / D.UR7 .GLOBL D.UPC .RAD50 /U.PC / D.UPC .ENDC .RAD50 /D.CNT/ ;IF -, REPEAT -N TIMES. ;IF 0, AUTO REPEAT WITH TYPING ;IF +, REPEAT N TIMES ;IF +, RESETS REPEAT TO 1 WHEN BACK TO 0. IF - LETS ;COUNT GO TO 0 AND STAY THERE. .WORD D.CT ;1ST WORD IS FOR SINGLE STEP MODE BKPT .RAD50 /D.UIN/ ;USER INST. VALUES FOR REAL BKPTS .WORD D.UIN .RAD50 /D.IFMT/ D.IFMT ;DDT INSTRUCTION FORMAT. ;(NEGATIVE==> PSEUDO-ASSEMBLY MODE) .IF DF,SM$FIL ;HOLE FOR SYMBOL PICKED UP FROM .STB FILE. .SYMBG: .SYMNM=30. ;NUMBER OF SYMBOLS TO CACHE FROM .STB FILE .REPT .SYMNM .WORD 4,4,0 ;SYMBOLS FROM .STB FILE. .SYMPT ADDRESSES ;CURRENT ONE TO FILL IN NEXT. .ENDR .SYMND: .IF DF,I$$SD .RAD50 /MODULE/ .WORD MDLNAM ;MODULE NAME FOR ISD DECLARATIONS .RAD50 /MDLCTL/ .WORD MDLCTL ;CONTROL WORD TO SET 1 TO USE ISD TYPE NAMES .ENDC .ENDC .IF DF,$D$FPU .RAD50 /FPSTAT/ ;FPU STATUS .WORD FPSTAT .RAD50 /FPCTL/ .WORD FPCTL ;FP SAVE/REST CONTROL. 0=NO SAVE,1=SAVE/RSTORE .RAD50 /FPAC0/ ;FPU AC 0 .WORD FPAC0 .RAD50 /FPAC1/ .WORD FPAC1 .RAD50 /FPAC2/ .WORD FPAC2 .RAD50 /FPAC3/ .WORD FPAC3 .RAD50 /FPAC4/ .WORD FPAC4 .RAD50 /FPAC5/ .WORD FPAC5 ;MAKE ALIASES AC0 THRU AC5 FOR FPU REGS .IF DF,MU$DBG .IF DF,R$XMDB!R$XDDB .RAD50 /M$$CTL/ .WORD M$$CTL .ENDC .RAD50 /FP.STT/ ;GLOBAL POINTERS MODIFIED BY DDTMU MAIN PGM FOR MULTI-TASK DEBUGGER. FPSTT: .WORD FPSTAT .ENDC .RAD50 /AC0 / FPAC: .WORD FPAC0 .RAD50 /AC1 / .WORD FPAC1 .RAD50 /AC2 / .WORD FPAC2 .RAD50 /AC3 / .WORD FPAC3 .RAD50 /AC4 / .WORD FPAC4 .RAD50 /AC5 / .WORD FPAC5 .RAD50 /FPFMT/ .WORD FPFMT ;F.P. OUTPUT FORMAT .RAD50 /D.PRCN/ ;F.P. PRECISION .WORD D.PRCN .RAD50 /D.FPAC/ ;F.P. CORE AC .WORD D.FPAC .ENDC .IF DF,R$XMDB!R$XDDB .RAD50 /HDRADR/ .WORD HDRADR .RAD50 /TSKAPR/ .WORD TSKAPR .RAD50 /DBG11M/ .WORD DBG11M .ENDC .RAD50 /DDTGO/ .WORD DDT .RAD50 /JOBSA / JOBSA ;START ADDR OF JOB .IF DF,MEM$TR ;IF MEMORY TRACE ENABLED .RAD50 /MT.BUF/ .WORD MT.BUF ;DATA BUFFER .RAD50 /MT.PTR/ .WORD MT.PTR ;CURRENT LOC IN BUFFER. BUF USED ;CIRCULARLY. .RAD50 /MT.TOP/ .WORD MT.TOP ;TOP OF MEM TRACE BUFFER .ENDC .IF DF,$$DOS .RAD50 /$$DOS / ;GO HERE TO EXIT DOSEXT .RAD50 /BYE / .WORD DOSEXT .ENDC .IF DF,$$RT11 .RAD50 /BYE / .WORD RTEXIT .ENDC .IF DF,$$RSX .RAD50 /D.ASTF/ .WORD D.ASTF ;AST FLAG, CONTROLS AST REENABLE .RAD50 /RSXEXT/ .WORD RSXEXT .RAD50 /$DSW / .WORD DDTDSW ;SAVE $DSW HERE AT EACH D.SAVE CALL .RAD50 /DDTODD/ .WORD DDTODD .IFTF ;ALWAYS... .IF DF,ER$SV .RAD50 /D.ERPC/ .WORD D.ERPC .RAD50 /D.ERR0/ .WORD D.ERR0 .ENDC .RAD50 /D.FILV/ .WORD D.FILV .IF DF,$FORM$ .RAD50 /PNLINT/ .WORD D.FFPC .ENDC .IFT .RAD50 /DDTIOT/ .WORD DDTIOT .RAD50 /DDTRES/ .WORD DDTRES .RAD50 /DDTEMT/ .WORD DDTEMT .RAD50 /DDTTRP/ .WORD DDTTRP .RAD50 /DDTFPP/ .WORD DDTFPP .RAD50 /BGN/ NMH: .WORD 0,1 .RAD50 /BYE / .WORD RSXEXT .RAD50 /DDTBGN/ .WORD DDT .RAD50 /DDTRST/ .WORD DDT+2 NAMLO: .WORD 0 ;TASK NAME AS START ADDR NAMHI: .WORD 0 .WORD JOBSA .ENDC .MACRO SYMBL NAME,ADDR .RAD50 /NAME/ .WORD ADDR .ENDM .IF DF,MEM$BK ;NOTE D.CT MUST BE SET UP FOR CORRECT PROCEEDING IN SINGLESTEP ;MODE FOR MEM BRKPOINT TO WORK. SYMBL MEMBPA,MEMBPA ;MEM BRKPT MONITOR ADDRESS SYMBL MEMCTL,MEMCTL ;CONTROL (NON-0 TO ENABLE MEM BRKPT) SYMBL MBPVAL,MBPVAL ;VALUE AT ADDR MEMBPA .ENDC .IF DF,MU$DBG .GLOBL SNDDAT,RCVBUF SYMBL SNDDAT,SNDDAT SYMBL RCVBUF,RCVBUF .ENDC .IF DF,$VMEM SYMBL PAR0,VKPAR0 SYMBL PAR1,VKPAR1 SYMBL PAR2,VKPAR2 SYMBL PAR3,VKPAR3 SYMBL PAR4,VKPAR4 SYMBL PAR5,VKPAR5 SYMBL PAR6,VKPAR6 SYMBL PAR7,VKPAR7 .IF DF,D.MCRO SYMBL D.KBPT,D.KBPT ;CORE IN ADDR SYMBL D.ECSW,D.ECSW ;ECHO SWITCH SYMBL D.CHSW,D.CHSW ;CORE IN SWITCH SYMBL D.KBBF,D.KBBF ;CORE INPUT BUFFER .ENDC .IF DF,CD$FIL SYMBL CD.CTL,CD.CTL SYMBL CD.BUF,CD.BUF SYMBL CD.BAS,CD.BAS SYMBL CD.BLK,CD.BLK SYMBL CD.LO,CD.BLK SYMBL CD.HI,CD.BLK+2 .ENDC .IF DF,PR$FIL SYMBL PRFCTL,PRFCTL ;PROFILER CONTROL SYMBL PRFBAS,PRFBAS ;PROFILER BASE ADDRESS SYMBL PRFSHF,PRFSHF ;PROFILER SHIFT RIGHT COUNT (0,1,2,3,...) SYMBL PRFHST,PRFHST ;HISTO OF PROFILER DATA SYMBL PRFSIZ,PRFSIZ ;LENGTH IN BYTES OF PRFHST .ENDC .IF DF,$VPAT SYMBL PBASEL,D.BASE SYMBL PBASEH,D.BASE+2 .ENDC .ENDC .IF DF,MU$DBG .IF DF,SPC$MP SYMBL SR.CTL,SR.CTL .ENDC .ENDC .IF DF,MPV2.!U$ID. SYMBL UV$SPS,UV$SPS .ENDC .IF DF,X$OVL SYMBL OVRBRK,OVRBRK .ENDC .IF DF,CND$BK SYMBL D.BMSK,D.BMSK SYMBL D.BTST,D.BTST ;SYMBOLS TO SET UP CONDITIONAL BREAKPOINTS .ENDC .REPT 160. ;ALLOW 160. USER-DEFINED SYMBOLS .WORD -1,-1,0 .ENDR ;BY ADDING NULL SYMBOLS. .RAD50 /SYMEND/ ;ALLOW D.SYMT TO BE PATCHED SMBOLICALLY .WORD D.SYMT ;AND TERMINATED IN THE USER'S CODE .GLOBL D.SYMT ;GLOBALIZE TO ALLOW GBLPAT TO WORK ; GBLPAT=DDT22:D.SYMT:177777:177777 ; TO MAKE EXTENSION OF PSECT AUTOMATIC D.SYMT: .WORD 0,0,0 ; TABLE TERMINATED BY NULL SYMBOL NAME .IF NDF,Q$UIET .PRINT ;LENGTH OF DDT SYMBOL TABLE .ENDC ; .PSECT ..DDT.,RW,I .PSECT ..DDTP,RO,I ;CODE .IF NDF,Q$UIET ; .PRINT ;LENGTH OF DDT SEGMENT. .IIF DF, SM$FIL, .PRINT ;DDT CODE IN BLANK .PSECT EXCLUDED FROM ABOVE TOTAL .ENDC .END DDT ;DDT=START ADDR