.TITLE DDTMU ;MAIN PROGRAM FOR DDT22 INTERTASK DEBUGGER .IDENT /820819/ ;GLENN EVERHART ;NOTE THAT IT MUST BE LINKED WITH A VERSION OF DDT22 THAT WAS ;ASSEMBLED WITH MU$DBG DEFINED AND $VMEM DEFINED AT LEAST WITH I/O ;PAGE ACCESS. UNDER RSX11M (M+?) ALSO IT IS DESIRABLE TO DEFINE ;R$XMDB TO ALLOW QUICK MAPPING TO A TASK. NOTE THAT DDT AND THE ;TASK MUST NOT MOVE IN MEMORY DURING DEBUGGING; THIS MAY MEAN A QUIESCENT ;SYSTEM BUT SHOULD MEAN AT ANY RATE THAT THE SHUFFLER IS REMOVED ;TEMPORARILY AND THAT NO CHECKPOINT SPACE IS ALLOCATED IF SOMEONE ;ELSE IS TO BE ON. THIS WILL PREVENT TASK MOTION. ; ; NOTE: IF R$XMDB IS DEFINED, CALLS DMG11M (IN DDT) TO REMAP THE TASK ;AT EVERY MSG FROM THE TASK. ; ; CONTEXT SAVED FOR DDT FOR EACH TASK BEING DEBUGGED: ; BREAKPOINT ADDRESSES, PROCEED COUNTS, AND WORDS TO OPEN ; MEMORY WATCHPOINT CONTROLS AND DATA ; SINGLE STEP FLAG ; ALSO ALL REGS R0-R5, SP, PC, AC0-AC5, FPSTAT, U.PSW AND U.DSW ; ARE AVAILABLE PER TASK, BUT NOT INTERNALLY SAVED HERE. THESE ; ARE SAVED PER TASK IN THE TASK. D.SVR7 IS ALSO KLUDGED TO BE SAVED ; IN THE TASK CONTEXT IN CASE OF $X. .IIF DF,MEM$BK, .GLOBL MEMADR .IIF DF,MEM$BK,NMEM.B=8. ;LOCAL DEG FOR .BLKW DIRECTIVES ;NOTE THAT NMEM.B MUST BE SAME AS DDT22 DEFINITION!!!!!!!!!!!! .MCALL EXIT$S,ASTX$S .MCALL SRDA$S,SDAT$,DIR$,RCVD$S,RSUM$S .MCALL RSUM$ ;N.B. -- SUSPEND/RESUME USED FOR TSK SYNCHRONIZATION. DONE FOR ;SYSTEM COMPATIBILITY (M,M+,IAS,RSX11D). ;INTERNAL GLOBALS: .GLOBL DDTMU,TSKSAV,TSKRSU ;EXTERNAL GLOBALS: .GLOBL D.S ;SINGLE STEP MODE FLAG (BYTE) .GLOBL D.TRAV ;TRAP .GLOBL D.EMTV ;EMT .GLOBL D.SEGV ;SEG TRP .GLOBL D.IOTV ;IOT .GLOBL D.NXMT ;NXM .GLOBL D.ILGT ;ILL INST .GLOBL D.BRK ;BPT .IF DF,$XOK .GLOBL D.SVR4,D.PARS,D.PARO,D.XGO,D.UR7,D.TMP .ENDC .MCALL WSIG$S,ENAR$S,DSAR$S,RCVD$S,SDAT$S .GLOBL U.R0,U.PC ;DDT REGISTER DEFS ; ; GETMP - MAP TASK'S APR IN. ASSUMES RCVBUF & RCVBUF+2 ARE TSK NAME. ; .MACRO PUSH,LIST .IRP X, MOV X,-(SP) .ENDR .ENDM .MACRO POP,LIST .IRP X, MOV (SP)+,X .ENDR .ENDM .IF DF,R$XMDB .GLOBL GETMP GETMP: PUSH MOV RCVBUF,R0 ;1ST HALF OF TSK NAME MOV RCVBUF+2,R1 ;2ND HALF TSKNAM JSR PC,DBG11M ;NOW TSKAPR ARRAY HAS TASK APR'S. MOVE TO VKPAR0 AREA IN DDT .GLOBL TSKAPR,VKPAR0 MOV #TSKAPR,R0 MOV #VKPAR0,R1 MOV #8.,R2 1$: MOV (R0)+,(R1)+ DEC R2 BGT 1$ ;COPY APR IMAGES. ;DON'T ALTER PARMAP. USER HAS TO TURN THAT ON. POP RTS PC .IFF .GLOBL GETMP GETMP: RTS PC ;DUMMY ENTRY IF R$XMDB NOT DEFINED (11M OR 11D DEBUG) ; USE THIS IF USING "PURE" SEND-RCV FOR I/D SPACE VERSIONS OF DDT22M. .ENDC .IF DF,$$SDT TKID: .WORD 0 ;0 OR ADDR OF BRK TBL INFO (PAST TASK NAME CELL) N.BRK=8. NTSK=16. ;MAX TASKS ABLE TO BE DEBUGGED AT A TIME ;STORAGE FORMAT: ;2 WORDS TASK NAME ;8 WORDS BREAKPOINTS ;9 WORDS PROCEED OUNTS ;8 WORDS USER INSTS ;9 WORDS LOCS TO OPEN AT BRK ;1 WORD D.S FLAG STORAGE ;IF MEMORY WATCHPOINTS DEFINED, ALSO ; 8 WORDS MEM ADDRESSES ; 1 WORD CONTROL ; 8 WORDS OLD VALUES AT ADDRESSES ; PER TASK ENTRY. MBPINC=0 BINCW=0 BINC=0 .IIF DF,MEM$BK,MBPINC=1+<2*NMEM.B> BTBLSZ=<2*<4+<4*N.BRK>>> ;LENGTH OF ONE ENTRY .IF DF,CND$BK ;IF CONDITIONAL BREAKS BINCW=2*N.BRK+2 ;EXTRA NO. WORDS FOR CONDITIONAL STUFF BINC=2*BINCW BTBLSZ=BTBLSZ+BINC .ENDC BTBL: .BLKW >> .WORD 0 ;FENCE .ENDC LSTNM: .WORD 0,0 ;LAST TASK NAME TYPED... ; TNAMTY - TYPE NEW TASK IF (AND ONLY IF) IT DIFFERS FROM LAST ONE ; (USED TO ANNOUNCE NEW TASK AT TERMINAL PROVIDED THIS BREAK IS FROM ; A DIFFERENT TASK THAN THE LAST.) TNAMTY: PUSH ;TYPE TASK NAME BEING PROCESSED AND SET UP BREAKPOINT TABLES. .GLOBL D.BKTB,D.CT,D.UIN,D.OPEN .IF DF,$$SDT ;SYS DEBUGGER ;STORE OLD INFO IF ANY WAS THERE IN DDT. TST TKID ;ANY OLD TASK THERE? BEQ 57$ ;IF NOT, NO NEED TO SAVE OLD DATA ;SAVE OLD BRK INFO MOV TKID,R1 ;GET TSK INFO LOC MOV #D.BKTB,R2 ;START OF DDT INFO ;TKID POINTS AT BRK TBL AREA, NOT TSK NAME CLR TKID ;LEAVE ZERO MOV #/2,R3 ;NO. WORDS TO COPY OUT 58$: MOV (R2)+,(R1)+ ;STORE DDT BRK INFO HERE SOB R3,58$ ;(CHANGE IF BRK TBL CHANGES IN DDT!!! MOVB D.S,(R1) ;STORE D.S FLAG TST (R1)+ ;BUMP BY IT .IF DF,MEM$BK MOV #MEMADR,R2 ;COPY OUT MEM BRK CONTROLS TOO MOV #MBPINC,R3 ;THIS MANY WORDS 157$: MOV (R2)+,(R1)+ ;COPY HERE FROM DDT SOB R3,157$ .ENDC 57$: ;LOCATE THIS TASK'S ENTRY IN THE TABLE (OR A NEW ONE...) MOV #BTBL,R1 ;SEEK NEW TBL ENTRY TO FILL IN (OR REUSE) MOV #NTSK,R2 ;MAX ENTRIES AVAIL. ;TRY TO FIND THIS TASK'S NAME FIRST. THEN, IF A NEW ENTRY, SEEK NULL ENTRIES ;IN OUR BREAKPOINT DATA TABLE. 66$: CMP RCVBUF,@R1 ;ALSO USE IF SAME TSK NAME BNE 60$ ;IF NOT TRY NEXT CMP RCVBUF+2,2(R1) ;TEST 2ND HALF TSK NAME BEQ 59$ ;OK, GOT IT 60$: ADD #2+>,R1 ;POINT AT NEXT ENTRY DEC R2 ;BE SURE NOT DONE BGT 66$ ;IF NOT DONE, TEST NEXT SLOT CMP R0,#16 ;THIS AN INIT CALL? BNE 56$ ;IF NOT DONE NOW MOV #BTBL,R1 MOV #NTSK,R2 ;INIT LOOP TO SEEK NULL CELLS TO USE 67$: TST @R1 ;THIS CELL EMPTY? BEQ 59$ ;IF SO SAY WE GOT IT. ADD #2+>,R1 SOB R2,67$ ;ELSE KEEP LOOKING. FALL THRU IF NONE THERE BR 56$ ;IF NONE AVAIL JUST SKIP IT... 59$: MOV RCVBUF,(R1)+ ;SAVE TASK NAME IN ENTRY NOW MOV RCVBUF+2,(R1)+ ;AND POINTER ENTRY USED MOV R1,TKID ;LEAVE CURRENT ENTRY POINTER THERE 56$: .ENDC .IF NDF,$$SDT CMP R0,#16 ;SPECIAL TASK STARTUP CODE? BNE 1$ ;IF NOT, SKIP OVER THIS MOV RCVBUF+6,JOBSA ;IF SO SET UP DEFAULT START ADDRESS .ENDC ;CLEAR BREAKPOINT TABLES, ETC., AT TASK STARTUP N.BRK=8. ;NUMBER DDT BREAKPOINTS MOV #N.BRK,R1 MOV #D.BKTB,R2 ;CLR BRK TBL 2$: CLR (R2)+ SOB R1,2$ ;DO ALL 8 MOV #N.BRK+1,R1 ;CLR PROCEED COUNTS MOV #D.CT,R2 3$: CLR (R2)+ SOB R1,3$ MOV #N.BRK,R1 ;CLR USER STORED INSTS MOV #D.UIN,R2 4$: CLR (R2)+ SOB R1,4$ MOV #,R1 ;CLR LOCS TO OPEN AT BREAKS MOV #D.OPEN,R2 5$: CLR (R2)+ SOB R1,5$ CLRB D.S ;CLEAR SINGLE STEP FLAG .IF DF,MEM$BK MOV #MEMADR,R2 MOV #MBPINC,R1 105$: CLR (R2)+ SOB R1,105$ ;CLR OUT MEM WATCHPOINTS .ENDC 1$: .IF DF,$$SDT ;SYS DEBUGGER ;LOCATE TABLE FOR DDT BREAKPOINT INFO AND RESTORE OR SET UP CMP R0,#16 ;START UP? BNE 6$ ;IF NOT, NO INIT OF TBL MOV TKID,R1 ;CLEAR OUR TABLE OF BREAKS BEQ 6$ ;SKIP IF NO SLOT WAS THERE MOV #1+MBPINC+</2>,R2 ;NO WORDS TO ZERO 7$: CLR (R1)+ ;CLEAR OUR TABLE OF DATA SOB R2,7$ 6$: ;NOW FILL IN OUR BREAKPOINT INFO INTO DDT BEFORE BREAK BEGINS ; NOTE THAT BREAKPOINTS AND WATCHPOINTS (AND ASSOCIATED COUNTS AND ; CONTROLS) ARE KEPT SEPARATE PER TASK. THE SYMBOL TABLE IS GLOBAL ; ACROSS ALL, THOUGH. MOV TKID,R1 ;GET ADDRESS TO USE BEQ 8$ ;SKIP IF NONE MOV #D.BKTB,R2 ;GET WHERE TO BASH IN DDT MOV #/2,R3 ;NO WORDS TO BASH 9$: MOV (R1)+,(R2)+ SOB R3,9$ ;BASH DDT BREAKPOINT INFO MOVB (R1),D.S ;SET UP SINGLE STEP FLAG TST (R1)+ ;AND PASS IT .IF DF,MEM$BK MOV #MEMADR,R2 ;WHERE TO BASH MEM WATCHPOINTS MOV #MBPINC,R3 ;NUMBER TO BASH 109$: MOV (R1)+,(R2)+ ;PUT IN OUR MEM BRKS INTO DDT SOB R3,109$ ;DO ALL WORDS .ENDC 8$: .ENDC ;TYPE OUT TASK NAME IF DIFFERENT FROM LAST-TYPED NAME ONLY CMP LSTNM,RCVBUF ;TASK NAME SAME AS ALREADY TYPED? BNE 75$ ;NO, TYPE IT CMP LSTNM+2,RCVBUF+2 ;2ND HALF SAME TOO? BEQ 76$ ;YES, SKIP TYPE-OUT 75$: MOV RCVBUF,LSTNM ;SAVE TASK NAME WE'LL TYPE MOV RCVBUF+2,LSTNM+2 .GLOBL D.CRLF JSR PC,D.CRLF MOV #TNMASC,R1 ;WHERE TO STASH ASCII MOV RCVBUF,R0 ;TASK NAME MOV PARMAP,-(SP) ;SAVE MAP USED CLR PARMAP .IF DF,U$ID.!MPV2. .GLOBL UV$SPF MOV UV$SPF,-(SP) MOV #-1,UV$SPF .ENDC JSR PC,D.CHAR ;CONVERT TO ASCII MOV RCVBUF+2,R0 ;TASK NAME LOW ORDER MOV #TNMASC+3,R1 ;WHERE TO GO JSR PC,D.CHAR .GLOBL D.CHAR,D.STYP MOV #TNMASC,R4 ;POINT TO START OF STRING MOV #TNMEND,R3 ;AND ITS END JSR PC,D.STYP .IIF DF,MPV2.!U$ID., MOV (SP)+,UV$SPF MOV (SP)+,PARMAP ;NOW RESTORE MAPPING 76$: ;REF LABEL POP RTS PC TNMASC: .BLKW 3 .BYTE 40,40 ;SPACES AFTER TASK NAME TNMEND=. TNMSZ=.-TNMASC .BYTE 40,40 ;FENCES ; ; ;RCVBUF+30 IS WHERE WE GET DATA BACK ON REPLY FROM TASK IN SEND/RECEIVE ; MODE. RCVBUF: .BLKW 15. ;BUFFER FOR RECEIVED DATA SNDBUF: SDAT$ ,SNDDAT .GLOBL SNDDAT,RCVBUF SNDDAT: .BLKW 13. SNDTNM=SNDBUF+S.DATN ;TASK NAME ADDRESS TO SEND [BACK] TO. .GLOBL DOFLG DOFLG: .WORD 0 ;THIS WORD INCREMENTED WHEN FIRST $G GIVEN TO ;DDT22M. IT DETERMINES THAT THE $G IS TO BE SENT ;TO THE TARGET TASK RATHER THAN TO DDT. UNTIL THEN, ;DDT COMMANDS OPERATE WITHIN THE DDT TASK. .GLOBL D.UPC ;USER PC FOR DDT TO ALLOW TO OBSERVE D.UPC: .WORD 0 ;...AS DATA AREA... ;MAIN LINE. ; FLOW: ; ALLOW AST'S AND SET UP A MESSAGE INPUT AST TO MTMSG ;TO PROCESS ALL AST'S FROM TSK MESSAGES RECEIVED. (THIS ASSUMES ;THAT DDT IS STARTED PRIOR TO STARTING THE TASK. WE WILL ASSUME ;THAT OUR TASK NAME IS DDT22M (M FOR MULTITASK, NOT FOR RSX11M) ;SO THAT A TASK MAY SEND DATA TO OUR DEBUGGER BY TASK NAME. ; SAVE TSK START ADDRESS IN JOBSA AND TSK NAME HERE FOR USE WITH ;MESSAGES. ; EXECUTE A BPT TO GET BACK TO DDT COMMAND LEVEL. ; ** NOTE THAT TSKRSU MUST REPLACE D.UR7 WITH THE CORRECT DEFAULT ;LOOP ADDRESS ONCE IT IS DONE TO GET DDT TO CONTINUE ITS OWN ;TASK IN THE DDT IDLE LOOP. ; FALL INTO THE DDT IDLE LOOP WHICH ENABLES AST'S AND WAITS ;FOR SIGNIFICANT EVENTS. DDTMU: ;FIRST AWAIT A MESSAGE FROM THE USER TASK THAT HE STARTED. ;DDT IDLE LOOP - NORMALLY DDT IS HERE ONCE ITS TASK IS STARTED ; AND THE OTHER TASK IS INITIALIZED. SRDA$S #GOAST ;INITIAL AST ENTRY AT GOAST ENAR$S D.MU0: WSIG$S BR D.MU0 ;WAIT TILL WE GET INITIAL MSG D.MU1: MOV #1,DOFLG ENAR$S SRDA$S #MUAST ;SET AST ENTRY AT MUAST ON RCV DATA. ;NOTE THE BPT WILL RESET THE PC BUT JOBSA SHOULD BE OK ANYWAY. NOP ;(IN CASE WE NEED PATCHING ONLINE) BPT ;ENTER DDT COMMAND MODE AGAIN NOP ;(IN CASE WE NEED PATCHING ONLINE) DDTIDL: DSAR$S ;DISABLE FURTHER ASTS WHILE WE TRY TO READ RCVD$S ,#RCVBUF ;GET DATA IN BCS DDTID2 ;IF NOTHING, JUST IDLE TSTB @#$DSW ;ERROR ON DATA IN? BMI DDTID2 ;IF SO, JUST LOOP, AWAIT AST. MOV RCVBUF,SNDTNM ;AND SAVE TSK NAME MOV RCVBUF+2,SNDTNM+2 CMP RCVBUF+4,#16 ;STARTUP CODE? BNE 54$ ;IF NO STARTUP DONT SET ADDR MOV RCVBUF+6,JOBSA ;SAVE START ADDRESS IN DDT MOV JOBSA,D.UPC ;SAVE IN D.PC TOO... 54$: MOV RCVBUF+14,D.USTA ;SAVE PSW OF TASK TOO. .IIF DF,R$XMDB, JSR PC, GETMP ;SET UP DDT MAP JSR PC,FILPTR ;FILL IN TSK ADDRESSES (JUST PRECAUTION) ; SRDA$S #MUAST MOV R0,-(SP) ;NEED A REGISTER MOV RCVBUF+4,R0 ;GET MSG TYPE CODE BIT #^C16,R0 BEQ 1$ CMP #1,R0 ;CODE=1 IS EXIT COMMAND TO DDT .MCALL EXIT$S BNE 22$ ;IF NOT EXIT, GO ON EXIT$S 22$: .IF DF,$XOK ;CHECK FOR 20 = $X COMPLETION CODE CMP #20,R0 ;$X COMPLETION INPUT? BNE 25$ MOV RCVBUF+30,D.SVR7 ;RESTORE "OLD PC" MOV D.SVR7,D.UPC ;SAVE IT ALSO WHERE DDT CAN OBSERVE AS ;U.PC BR 1$ 25$: .ENDC MOV (SP)+,R0 ;IGNORE ILLEGAL CODES BR DDTIDL ;AND LOOK FOR ANY MORE MESSAGES TO US 1$: JSR PC,TNAMTY ; INIT TASK'S BREAKPOINT TABLES MOV R0,-(SP) MOV 2(SP),R0 ;RESTORE R0 MOV (SP)+,(SP) ;MOVE UP ADDR .IF DF,MPV2. BIC #^C377,(SP) ;LEAVE OFFSET ALONE. HI CODE BYTE IS I/D STUFF .ENDC ;NOTE HERE WE DUPLICATE SOME AST TYPE PROCESSING WITH ASTS OFF ;THIS GENERATES A FAKED TRAP INTO A DDT ROUTINE. THE CALL TO ;TSKRSU SHOULD SET DDT ADDRESS TO DDTIDL AT THE PROCEED TO ALLOW A ;NEW CHECK AND POSSIBLE TURN ON OF ASTS AT DDTID2. ADD #CODMAP,(SP) MOV @(SP)+,-(SP) ;GET WHERE TO GO MOV (SP),-(SP) ;COPY "WHERE TO GO" DOWN MOV (SP),-(SP) ;COPY "WHERE TO GO" DOWN MOV RCVBUF+14,4(SP) ;PS FROM OTHER TASK MOV RCVBUF+6,2(SP) ;PC FROM OTHER TASK RTS PC ;"RETURN" TO DDT TRAP ROUTINE DDTID2: ENAR$S ;ALLOW MESSAGE IN AST'S TO OCCUR. WSIG$S BR DDTID2 ;AST ENTRIES... START PROCESSING GOAST: TST DOFLG ;IS DDT ALREADY SET UP TO START? BNE MUAST ;IF SO HANDLE AS NEW AST. RCVD$S ,#RCVBUF ;GET DATA READ IN FROM ANY TASK BCS LSTAST TSTB @#$DSW BMI LSTAST ;IGNORE ERROR ASTS MOV RCVBUF,SNDTNM ;AND SAVE TSK NAME MOV RCVBUF+2,SNDTNM+2 .IIF DF,R$XMDB, JSR PC, GETMP ;SET UP DDT MAP .MCALL DSAR$S DSAR$S ; ;FORMAT OF MESSAGES: ;+4 WORD CODE OF MSG TYPE. IGNORED FIRST TIME. ; AFTER, 0=BPT, 2=ODD ADDR,4=ILL INST,6=EMT,10=TRAP, ; 12=IOT,14=SEG ERR ; 16=SPECIAL START CODE FOR NEW TSK START, 1=DDT EXIT CMD ; 20=SPECIAL CODE FOR $X COMPLETION ON LAST RUN THROUGH ;+6 WORD PC AT TRAP (START ADDRESS ON 1ST MSG) ;+10 WORD POINTER TO SAVED R0-R5,SP,PC,PSW ;+12 WORD POINTER TO FPU SAVE AREA (STAT, AC0-AC5) ;+14 WORD PSW AT TRAP ; ;FORMAT OF MESSAGES SENT BACK: ; WORD PC TO START WITH ; WORD PSW TO START WITH ; OTHERS ARE USED IN CASE OF $X... SEE BELOW. MOV RCVBUF+6,JOBSA ;SAVE START ADDRESS IN DDT MOV RCVBUF+6,D.UR7 ;ALSO SAVE AS USER PC MOV D.UR7,D.UPC MOV #D.MU1,2(SP) ;SET TO GO TO D.MU1 ON EXIT ;THIS ALLOWS THE PROCESSING TO FALL INTO THE BPT. JSR PC,FILPTR ;FILL DDT ADDR POINTERS TO REGS .IF NDF,X$INM MOV #16,R0 ;SAY INITIAL CALL JSR PC,TNAMTY ;TYPE TSK NAME .ENDC LSTAST: ENAR$S ;ALLOW AST PROCESSING NEXT .IIF NDF,..XID$, MOV #DDTIDL,2(SP) ;SET TO LOOP AT DDTIDL ASTX$S ; ;MUAST - NORMAL MSG-IN AST MUAST: RCVD$S ,#RCVBUF ;GET DATA IN FROM ANY TASK BCS LSTAST ;IF WE FAIL, JUST EXIT TSTB @#$DSW ;ALSO TEST $DSW BMI LSTAST ;AND IF IT SAYS WE HAD AN ERROR, FORGET AST. MOV RCVBUF,SNDTNM ;AND SAVE TSK NAME MOV RCVBUF+2,SNDTNM+2 CMP RCVBUF+4,#16 ;STARTUP CODE? BNE 54$ ;IF NO STARTUP DONT SET ADDR MOV RCVBUF+6,JOBSA ;SAVE START ADDRESS IN DDT MOV JOBSA,D.UPC ;AND AS D.PC ALSO ... 54$: MOV RCVBUF+14,D.USTA ;SAVE PSW OF TASK TOO. DSAR$S ;PREVENT ANY AST RECOGNITION .IIF DF,R$XMDB, JSR PC, GETMP ;SET UP DDT MAP JSR PC,FILPTR ;FILL IN TSK ADDRESSES (JUST PRECAUTION) ; SRDA$S #MUAST MOV R0,-(SP) ;NEED A REGISTER MOV RCVBUF+4,R0 ;GET MSG TYPE CODE BIT #^C16,R0 BEQ 1$ CMP #1,R0 ;CODE=1 IS EXIT COMMAND TO DDT .MCALL EXIT$S BNE 22$ ;IF NOT EXIT, GO ON EXIT$S 22$: .IF DF,$XOK ;CHECK FOR 20 = $X COMPLETION CODE CMP #20,R0 ;$X COMPLETION INPUT? BNE 25$ MOV RCVBUF+30,D.SVR7 ;RESTORE "OLD PC" MOV D.SVR7,D.UPC BR 1$ 25$: .ENDC MOV (SP)+,R0 ;IGNORE ILLEGAL CODES .IIF DF,..XID$, MOV #DDTIDL,2(SP) ;SET TO LOOP AT DDTIDL ENAR$S ;PERMIT MORE AST'S ASTX$S 1$: JSR PC,TNAMTY ; INIT TASK'S BREAKPOINT TABLES MOV R0,-(SP) MOV 2(SP),R0 ;RESTORE R0 MOV (SP)+,(SP) ;MOVE UP ADDR .IIF DF,MPV2., BIC #^C377,(SP) ;LEAVE CODE AS A BYTE ONLY ADD #CODMAP,(SP) MOV @(SP)+,-(SP) ;GET WHERE TO GO JMP ASTSET ;GO FAKE TRAP ENTRY NOW. CODMAP: .WORD D.BRK,D.NXMT,D.ILGT,D.EMTV+2 .WORD D.TRAV+2,D.IOTV,D.SEGV+4 .WORD D.BRK .IIF DF,$XOK, .WORD D.TMP ;NOTE ABOVE THAT D.EMTV AND D.TRAV ARE OFFSET BY 2 TO PASS ;THE TST (SP)+ INSTRUCTION TO REMOVE RSX CRUFT ON STACK FOR ;EMT OR TRAP. ;LIKEWISE D.SEGV IS OFFSET PAST THE ADD #X,SP INST. ; ;FILPTR - FILL DDT REG ADDR SYMBOLS WITH CORECT TSK VALUES. FILPTR: MOV R0,-(SP) MOV RCVBUF+10,R0 ;GET POINTER TO SAVED AREA MOV #2,-(SP) MOV R0,U.R0 ADD @SP,R0 MOV R0,U.R1 ;FILL IN ADDRESSES ADD @SP,R0 MOV R0,U.R2 ADD @SP,R0 MOV R0,U.R3 ADD @SP,R0 MOV R0,U.R4 ADD @SP,R0 MOV R0,U.R5 ADD @SP,R0 MOV R0,U.SP ADD @SP,R0 MOV R0,U.PC ;PC SAVED IN TARGET SPACE ;NOTE THAT PC IN TARGET SPACE WILL BE INCORRECT IF USING SEND/RECEIVE. ;HOWEVER D.PC IN DDT SPACE SHOULD BE OK. .IF DF,X$DSW ADD (SP)+,R0 MOV R0,U.PS .IFF ADD @SP,R0 MOV R0,U.PS ADD (SP)+,R0 MOV R0,U.DSW ;SAVE $DSW ADDRESS AT BREAK .ENDC MOV RCVBUF+12,R0 .IF DF,$D$FPU MOV R0,FPSTT MOV #10,-(SP) ADD #2,R0 MOV R0,FPAC ADD @SP,R0 MOV R0,FPAC+6 ADD @SP,R0 MOV R0,FPAC+6+6 ;AC2 ADD @SP,R0 MOV R0,FPAC+6+6+6 ;AC3 ADD @SP,R0 MOV R0,FPAC+24. ;AC4 ADD (SP)+,R0 MOV R0,FPAC+30. ;AC5 .ENDC MOV (SP)+,R0 RTS PC ; ;TSKSAV - PERFORM SPECIAL INITS NEEDED ONCE INTO BPT SERVICE. ; ; (NONE AT PRESENT) TSKSAV: CLC ;SAY ALL IS WELL RTS PC ;TSKRSU - RESUME THE TASK BY SENDING IT A CONTINUE MSG WITH SOME PS INFO ; TO USE. TSKRSU: TST DOFLG ;GOTTEN INIT'ED YET? BNE 1$ ;YES, LET US SEND MSG RTS PC ;NO, RETURN 1$: ;ASSUMES WE HAVE D.USTA AND D.UR7 AS WHERE TO GO. ALSO ASSUMES TASK NAME ;IS SET UP. MOV D.UR7,SNDDAT ;TELL WHERE TO START MOV D.USTA,SNDDAT+2 ;AND WITH WHAT PSW .IF DF,MPV2. MOVB UV$SPF,SNDDAT+26 ;FILL IN HIGH BYTE HOWEVER BPL 3$ ;AS FLAG TO DDTKNL THAT THIS IS I SPACE CLRB SNDDAT+26 ;CLAMP POSITIVE 3$: .ENDC .IF DF,$XOK ;CHECK FOR $X CASE WHERE D.XGO IS THE START ADDRESS SPECIFIED. ;IF SO, RELOCATE THE INSTRUCTION AND FILL IN SNDDAT+6 ON WITH THE ;INSTRUCTION. ;SNDDAT+4 WILL BE NONZERO IF IT'S A $X, OTHERWISE 0. ; TO MINIMIZE WORK FOR THE DDTKNL PROCESSOR, SNDDAT+4 WILL BE THE ; CODE (20) TO RETURN TO FLAG THE $X IS DONE. OTHERWISE IT'LL ; BE A ZERO TO FLAG NORMAL BPT OPERATION. ; D.SVR7 WILL BE SENT ACROSS IN SNDDAT+6 TO ENSURE IT WILL ; RETURN ON THE NEXT TYPE 20 RESPONSE. CLR SNDDAT+4 ;ASSUME NORMAL CASE CMP D.UR7,#D.XGO ;THIS A $X CASE? BNE 30$ ;IF NOT, OK AS IS .IF DF,MPV2. BISB #2,SNDDAT+26 ;FLAG SENDING OVER INSTRUCTION .ENDC MOV D.SVR7,SNDDAT+6 ;SAVE OLD TASK PC MOV D.SVR4,SNDDAT+10 ;FILL IN INSTRUCTION MOV D.PARS,SNDDAT+12 MOV D.PARS+2,SNDDAT+14 ;AS IN DDT MOV #BPT,SNDDAT+16 ;AND FINAL BPT IN CASE IT FINISHES MOV #20,SNDDAT+4 ;FLAG SPECIAL RETURN LOCATION ;COMPUTE ADDRESS IN DDTKNL OF RECEIVE BUFFER LOCATION. ;KNOW U.R0 HOLDA ADDRESS OF REGS AND 13 WORDS PRIOR GET SNDDAT. MOV R0,-(SP) ;(IT'S EASIER IN A REGISTER) MOV U.R0,R0 ;ADDRESS OF USER TASK'S REGS AREA SUB #22,R0 ;WHERE SNDDAT+10 WINDS UP NOW IN R0 MOV R0,SNDDAT ;SAVE NEW ADDRESS TO START WITH SUB #D.SVR4,R0 ;DIFFERENCE FROM OLD LOCATION NOW TST D.PARO ;RELOCATE 1ST WORD? BEQ 31$ ;IF NOT, OK NOW ADD R0,SNDDAT+10 ;ELSE ADJUST FOR NEW LOC'N 31$: TST D.PARO+2 ;RELOC 2ND WORD? BEQ 32$ ADD R0,SNDDAT+12 32$: MOV (SP)+,R0 30$: .ENDC MOV #DDTIDL,D.UR7 ;THEN FIX UP TO IDLE HERE BIC #360,D.USTA ;AND BE SURE NO T BIT IS SET. USDT:; DSAR$S ;BE SURE NO AST RECOGNIZE TILL BACK IN IDLE DIR$ #SNDBUF ;EMIT THE DATA TO THE TARGET TASK .IF NDF,I$AS31 ;NOT IAS V3.1 10$: RSUM$S #SNDTNM ;RESUME THE TASK THEN. .IFF .MCALL RSUS$S 10$: RSUS$S #SNDTNM ;IAS V3.1, RESUME THE TARGET TASK .ENDC CMPB @#$DSW,#IE.ITS ;IS TASK NOT SUSPENDED? BNE 2$ ;IF NOT THAT PROBLEM JUST GO ;IF TASK NOT SUSPENDED, COULD BE THAT DDT GOT CONTROL TOO FAST. WSIG$S ;WAIT A SIG EVENT TIME TO GIVE OTHER GUY CONTROL BR 10$ ;THEN TRY AGAIN. 2$: ;REF LABEL RTS PC ; ; ASTSET ; ; ENTER A PSEUDO INTERRUPT FROM AN RSX AST ENTRY. ; ** NOTE: SPECIAL VERSION FOR M/TSK DDT GETS PS/PC PAIR FROM MESSAGE BUFF. ;CALL (FROM INSIDE AN AST): ; MOV #,-(SP) ;FAKE JSR RETURN ; JMP ASTSET ; ; RETURNS FROM THE AST (ISSUES THE ASTX$S) AND RETURNS TO THE ;INTERRUPT HANDLER AFTER THE AST. THE INTERRUPT HANDLER WILL APPEAR TO ;HAVE JUST RECEIVED THE HARDWARE INTERRUPT. THE ASSUMPTION (VALID IN ;RSX11M V3.1) IS THAT THE AST STACK IS: ; E.F. WORD #1 ; E.F. WORD #2 ; E.F. WORD #3 ; E.F. WORD #4 ; AST PSW ; AST PC OF TASK ; SP: OLD $DSW ;(N.B. - THIS STATE IS VALID IN RSX11M+ V01, RSX11M V3.2, AND IAS V03 ALSO.) ; ;WE MOVE THE AST-RELATED STUFF DOWN THE STACK, COPY THE AST PS,PC PAIR TO ;THE TOP, AND CAUSE THE AST TO RETURN TO THE INTERRUPT HANDLER WITH ;THE TASK STACK THEN CONTAINING THE ORIGINAL AST PS,PC PAIR. .MCALL ASTX$S .GLOBL ASTSET ASTSET: ;FIRST BE SURE WE HAVE AN EVEN, NONZERO ADDRESS TO GO TO. TST (SP) ;RETURN ADDR ZERO? BNE 1$ ;NO, LOOKS OK. 2$: TST (SP)+ BR 100$ ;SOMETHING WRONG. JUST EXIT THE AST. 1$: BIT #1,(SP) ;IS ADDRESS EVEN BNE 2$ ;NO, EXIT AST. MOV 2(SP),-(SP) ;COPY NEW $DSW INTO PLACE MOV 6(SP),4(SP) ;MOVE THE OLD PC DOWN MOV 10(SP),6(SP) ;MOVE DOWN OLD PS MOV 12(SP),10(SP) ;...OLD STATUS 4... MOV 14(SP),12(SP) ;...3... MOV 16(SP),14(SP) ;...2... MOV 20(SP),16(SP) ;...AND 1 ... ;NOW WE HAVE FREED THE TOP WORD OF THE STACK AND MOVED THE AST STACK ;DOWN 1 WORD. FILL IT IN AND MOVE DOWN THE OTHER WORD. MOV RCVBUF+14,20(SP) ;FILL IN OTHER TASK PS ; MOV 6(SP),20(SP) ;PUT AST PS INTO PLACE MOV 6(SP),RSV ;SAVE TEMP LOC MOV 10(SP),6(SP) ;MOVE DOWN STATUS 4 MOV 12(SP),10(SP) ;...3... MOV 14(SP),12(SP) ;...2... MOV 16(SP),14(SP) ;...AND 1, TO MOVE ALL THESE DOWN. ;NOW 16(SP) MAY BE FILLED IN WITH THE AST PC ;NOTE WE WANT THE TRAP HANDLERS TO SEE THE PC IN THE OTHER TASK SO FILL ;THAP PC HERE INSTEAD OF THE NORMAL ONE. MOV RCVBUF+6,16(SP) ;GET TASK PC FROM MSG BUFFER ; MOV 4(SP),16(SP) ;FILL IN THE AST PC FOR INT. HANDLER. MOV RSV,4(SP) ;AND LET THE OLD PS APPLY TO THE INT HANDLER 100$: ASTX$S ;NOW OFF TO THE INTERRUPT HANDLER. RSV: .WORD 0 ;TEMP .IF DF,SPC$MP ;ALLOW MAPPING VIA DEBUG KERNEL IF NO VIRTUAL MAP IS TO BE USED. ;WORKS BY EXECUTING INSTRUCTIONS IN THE TARGET'S CONTEXT TO MOV ;OR MOVB TO OR FROM THE LOCATIONS DESIRED... ;EXPECT CALLING R3=ADDRESS, R0=D.BW FLAG, AND EITHER SEND DATA ;BACK IN R0 OR GET IT FROM R4. CGDAT: MOV U.R0,R1 ;ADDRESS OF TASK'S R0 SAVE AREA SUB #22,R1 ;POINT TO SNDDAT+10 IN TSK CONTEXT MOV R1,SNDDAT ;USE AS NEW PC MOV #20,SNDDAT+2 ;ALSO BE SURE T BIT IN NEW PSW .IIF DF,MPV2., MOVB UV$SPF,SNDDAT+26 ;SEND I/D INFO OVER IN PSW .IIF DF,MPV2., BISB #2,SNDDAT+26 ;FLAG INSTRUCTION SENT SUB #2,R1 ;NOW USE WORD BEFORE AS RETURN DATA LOC MOV #BPT,SNDDAT+16 ;BE SURE WE GET BPT AFTER INST. MOV #13737,SNDDAT+10 ;FILL IN "MOV @(PC)+,@(PC)+" INST BIT #1,R0 ;SEE IF IT SHOULD BE MOVB BEQ 2$ ;IF NOT LEAVE AS IS MOV #113737,SNDDAT+10 ; IF NOT FILL IN A MOVB BR 3$ 2$: BIC #1,R3 ;IF MOV, ENSURE EVEN ADDRESS 3$: RTS PC .GLOBL U.GDAT,U.PDAT ;U.GDAT - READ A BYTE/WORD INTO R0 FROM TARGET SPACE TASK. REPLY MSG ;GETS VALUE. NEEDS NO SPECIAL PROCESSING TO READ REGISTERS. U.GDAT: JSR PC,CGDAT ;"GET DATA INTO R0" SUB. SET UP PRELIMS MOV R3,SNDDAT+12 ;FILL IN ADDRESS MOV R1,SNDDAT+14 ;AND WHERE TO STASH IT .IIF DF,MPV2., BISB #4,SNDDAT+26 ;FLAG GETTING DATA JSR PC,USDT ;SEND A MESSAGE TO DDTKNL U1$: WSIG$S ;;;AWAIT A REPLY BY ORIGINAL;;; RCVD$S #SNDTNM,#RCVBUF ;GET BACK REPLY IF ONE EXISTS TSTB @#$DSW ;SEE IF WE GOT IS.SUC AND HAVE REPLY NOW BGT 2$ ;IF SO ALL'S WELL WSIG$S ;IF NOT WAIT SOME BR U1$ ;AND LISTEN AGAIN 2$: MOV RCVBUF+30,R0 ;GET DATA TO R0 THAT OUR MOV/MOVB STORED RTS PC ;U.PDAT - STORE VALUE IN R4 INTO TARGET TASK SPACE. ; NEEDS SPECIAL TREATMENT FOR REGISTERS IF MPV2. NOT DEFINED. U.PDAT: JSR PC,CGDAT ;SET UP TO STORE DATA IN R4 INTO TSK .IIF DF,MPV2., BISB #10,SNDDAT+26 ;FLAG SETTING DATA MOV R3,SNDDAT+14 ;SAVE WHERE TO STASH MOV R1,SNDDAT+12 ;WHERE TO GET DATA TO SAVE MOV R4,SNDDAT+6 ;AND PUT DATA TO SAVE INTO MSG TOO .IF NDF,XR$EG$ .IF NDF,MPV2. CMP R3,U.R0 ;IS THIS A MOV/MOVB TO A REGISTER? BLO DM.NOT ;NO CMP R3,U.PC ;CHECK R0-R7 AND SET UP ACCORDINGLY BHI DM.NOT ;IF HI NOT A REGISTER ;MODIFYING A REGISTER. CHANGE THE INSTRUCTION TO A MOV/MOVB TO REGISTER SUB U.R0,R3 ;MAKE UP REGISTER NUMBER ASR R3 ;0-7 BIC #^C7,R3 ;GUARANTEE LEGAL BIC #77,SNDDAT+10 ;MAKE IT "MOV[B] @#,Rn" BIS R3,SNDDAT+10 ;NOW WILL APPEAR RIGHT MOV #BPT,SNDDAT+14 ;ALSO ADD BPT AFTER IT TO GET BACK CONTROL. DM.NOT: .ENDC .ENDC JSR PC,USDT ;SEND THE COMMAND BR U1$ ;THEN GET REPLY AND RETURN. .ENDC .END DDTMU