.TITLE DDTKNL .IDENT /801122/;GCE .IF EQ,1 This program is a tiny kernel for use with DDT22 and DDTMU in RSX or IAS systems. It allows a task to communicate with DDT running in another task using the DDT facility of mapping to other physical machine addresses. This is rather strange, but works in the following way: 1. The user links DDT22 and DDTMU together, assembling DDT22 with MU$DBG defined (and DDTMU that way too) and with at least $VMEM defined and with DDT having access to the I/O page at least via a device common. He then types $G to start the program in DDTMU. At this point, that main program is awaiting a message from the task linked with this program, DDTKNL, giving the start address of this program. 2. The user then fixes the program to be debugged, or otherwise ensures that it CANNOT MOVE in physical memory during the debug. This normally means the shuffler must not be able to move it as well as not checkpointing it and will often require a quiescent system. Now the user runs his program, which has been linked with DDTKNL as a Debug Aid. DDTKNL gains initial control with R0=the task start address. It declares a SVDB$ debug trap to control selected vectors (which must include BPT) and sends a message to the DDT task which MUST BE NAMED DDT22M. It then suspends itself and awaits being resumed by DDT. 3. At this point, DDT gets the message, sets up pointers to the task's addresses and start addresses, and does a BPT there to get back to DDT command mode. Now the user issues commands to get DDT to map to the other task. This involves the UL'tasknam' command under RSX11M (and maybe M+) or setting virtual APRs PAR0 thru PAR7 to point at the task for IAS. The UM command turns on using those APRs. Now DDT is addressing the task target. The user now types commands to enter breakpoints or single stepping. Finally he types a G command to get DDT to go. (To try to avoid problems where the task being debugged moves, DDTMU may be assbreakpoint. This is a bandaid and will not work in IAS, but should reduce the liklihood of errors in the debugging since the task may then legally move between breakpoints and still be debugged correctly. If it moves while the user is typing DDT commands before proceeding, the debugging will still work wrongly even so. Caution is needed for use of the tool. 4. DDT now saves the instructions in any breakpoint locations in the task being addressed and inserts BPTs (as normal), then sends a message to the task of a PC/PS pair to use for start and then resumes the task. DDT itself then goes into an idle loop awaiting receive-data ASTs from the task. 5. The task reads the message from DDT, then restores registers it has saved at any BPT from dedicated core slots, then issues a fake RTT to execute the next instruction (and possibly trap again). It goes on in this way. DDT addresses the register save area directly so the registers, f.p. accumulators, etc., are stored purely locally in dedicated cells. Thus the 13 word intertask messages convey ample information to let DDT debug them. 6. At the next BPT, the task sends a message to DDT giving the PC, PS, and some other info on the trap type, which DDT decodes and gets back to command mode with via the BPT entry. The task suspends itself as before until DDT sends a reply with a new PC/PS pair to use in resumption. This proceeds until debug is complete. This is done to allow this program, which is small compared to DDT or even ODT, to be linked with programs of nearly 32K and allow them to be symbolically debugged. Present implementation requires 133 words (decimal) if no floating point support exists or 199 if it does in DDTKNL. Glenn C. Everhart .ENDC ;D.BGNA: .WORD 0 ;D.TNM: .WORD 0,0 .MCALL SVDB$S,SPND$S,RCVD$S,SDAT$ REGS: .WORD 0,0,0,0,0,0,0,0 ;R0-R5, SP, PC .WORD 0 ;PSW SNDBUF: SDAT$ DDT22M,SNDDAT SNDDAT: .WORD 0 ;CODE .WORD 0 ;PC .WORD REGS ;REG SAVE AREA .IIF NDF,$D$FPU, FPSTAT=0 .WORD FPSTAT ;FP REG AREA .WORD 0 ;PSW .BLKW 9. ;REST RCVBUF: .BLKW 15. ;RCV DATA AREA .MCALL RCVD$ RCVX: RCVD$ ,RCVBUF ;RCV DATA D.BP: CLR -(SP) BR D.DSPA D.OD: MOV #2,-(SP) BR D.DSPA D.ILL: MOV #4,-(SP) BR D.DSPA ;TRAP CATCHERS ;IF EMT OR TRAP IS TO BE INTERCEPTED, CHANGE DDT22 HANDLERS TO NOT ;POP OFF THE EXTRA STACK ENTRIES OR THE LOGIC HERE WILL WORK WRONG. ;THE FORTRAN OTS (AND MANY OTHERS) USE EMT OR TRAP TO COMMUNICATE ;SO IN GENERAL CATCHING THOSE INSTRUCTIONS IS NOT A GOOD IDEA. ;D.EMT: MOV #6,(SP) ; BR D.DSPA D.EMT=0 ;D.TRP: MOV #10,(SP) ;NOTE KLUDGE DUE TO RSX STACK MUCKUP ; BR D.DSPA D.TRP=0 ;D.IOT: MOV #12,-(SP) ; BR D.DSPA D.IOT=0 D.SEG: MOV #14,-(SP) BR D.DSPA ;COMMENT OUT UNCAUGHT TRAPS DBTBL: .WORD D.OD,D.SEG,D.BP,D.IOT,D.ILL,D.EMT,D.TRP DDTKNL:: ; MOV R0,D.BGNA ;SAVE TSK START ADDR ; MOV R1,D.TNM ; MOV R2,D.TNM+2 ;SAVE TSK NAME TOO. MOV R0,SNDDAT+2 ;SEND START PC (USED BY DDT22M) .IIF DF,$$DBG,MOV R0,SNDDAT+12 ;EXTRA COPY OF START PC SVDB$S #DBTBL,#7 .MCALL DIR$ CMP -(SP),-(SP) ;SET STACK AS IF A "TRAP" WAS SEEN MOV SP,REGS+14 ;SAVE SP DIR$ #SNDBUF ;EMIT THE DATA SPND$S ;SUSPEND OURSELVES BR D.RESM D.DSPA: MOV R0,REGS MOV #REGS+2,R0 MOV R1,(R0)+ MOV R2,(R0)+ MOV R3,(R0)+ MOV R4,(R0)+ ;SAVE REGS, SP, PC, PSW MOV R5,(R0)+ MOV (SP)+,SNDDAT ;SAVE CODE IN MSG MOV SP,(R0)+ MOV (SP),(R0)+ MOV (SP),SNDDAT+2 ;SAVE PC VALUE MOV 2(SP),(R0) ;SAVE PSW MOV (R0),SNDDAT+14 ;BOTH PLACES .IIF DF,$D$FPU, JSR PC,FSAV ;SAVE F.P. REGS DIR$ #SNDBUF ;TELL DDT ABOUT OUR TRAP SPND$S ;SUSPEND OURSELVES. ;ON RESUMPTION FROM DDT READ ITS CMD D.RESM: DIR$ #RCVX ;GET DATA FROM DDT ; RCVD$S ,#RCVBUF ;BUFFER GETS PC, PS TO USE .IIF DF,$D$FPU, JSR PC,FRST ;RESTORE FPU REGS IF THERE MOV #REGS+2,R0 ;GET BACK REGS MOV (R0)+,R1 MOV (R0)+,R2 MOV (R0)+,R3 MOV (R0)+,R4 MOV (R0)+,R5 MOV (R0)+,SP MOV REGS,R0 ;RESTORES REGS & STACK CMP (SP)+,(SP)+ ;POP OLD PS/PC PAIR FROM SST MOV RCVBUF+4+2,-(SP) ;PUSH PSW TO USE MOV RCVBUF+4,-(SP) ;PUSH PC TO USE RTT ;EXIT THIS TRAP .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 ;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 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 .END DDTKNL