.TITLE TSKCOM .IDENT "V1.9" .NLIST BEX,CND ; ; Author: D. Mischler 20-OCT-87 ; ; This module implements the communications with DBGAID. ; ; V1.1 D. Mischler 05-JAN-88 Major redesign. ; V1.2 D. Mischler 17-JAN-88 Correct address window limit checking. ; V1.3 D. Mischler 01-FEB-88 Maintain multiple WDBs & region attachments. ; V1.4 D. Mischler 16-JUL-88 Fix bug in mapping context processing. ; V1.5 D. Mischler 17-NOV-88 Minor optimizations, fix MCR DEBUG. ; V1.6 D. Mischler 22-NOV-88 Use fast mapping when possible (if X$FMAP). ; V1.7 D. Mischler 27-NOV-88 Improve fast mapping determination. ; V1.8 D. Mischler 30-NOV-88 Do not change length when fast mapping. ; V1.9 D. Mischler 03-DEC-88 Minor speed improvements in T$MAP. ; .MCALL CRAW$,DIR$,DTRG$,GIN$,MAP$S,RREF$,SDAT$S,WDBBK$,WDBDF$,WSIG$S WDBDF$ ; ; WDB structure offset definitions. ; .ASECT .=0 W.XWDB: .BLKB W.NLGH ; Window definition block (must be at offset zero). W.XBAS: .BLKW 1 ; Virtual base address mapped through window. W.XLNK: .BLKW 1 ; Link to next WDB. W.XMAX: .BLKW 1 ; Maximum target address mapped through this window. W.XRGN: .BLKW 1 ; Target task region ID. W.XTAR: .BLKW 1 ; Target task WDB address. W.XLEN: ; Length of WDB structure. .PAGE .PSECT DATA,D,RW ; ; Data definitions. ; CRTADW: CRAW$ PROWDB ; Create address window DPB. CURWDB::.WORD 0 ; Currently mapped WDB. DETACH: DTRG$ RDB ; Detach region DPB. FNDTSK: GIN$ GI.TSK,TSKBUF,3,0,0 ; Find task DPB. TSKNAM == .-4 ; Target task name. MAPCTX: .WORD 0 ; Mapping context buffer address. .IF DF X$FMAP MAPWDB::.WORD 0 ; Last WDB mapped with MAP$ directive. .ENDC ; DF X$FMAP PROWDB: WDBBK$ 7,128.,,,,,RCVBUF RCVBUF: .BLKW 10. ; Receive message buffer. RSPBUF = RCVBUF+4 ; Response packet address. RCVREF: RREF$ PROWDB ; Receive by reference DPB. RDB: .WORD 0,0,0,0,0,0,0,0 ; Dummy RDB for DTRG$. TSKBUF: .BLKW 2 ; Returned task name. TSK.TS: .BLKW 1 ; Returned 1st task status word. WDBFRE: .WORD 0 ; Free WDB structure list. WDBLST::.WORD 0 ; List of active WDBs. ; ; Task mapping tables. ; ASPTBL::.WORD UDSTBL,UISTBL,SISTBL ; Address space table. UDSTBL: .BLKW 8. ; User data space WDB addresses. UISTBL: .BLKW 8. ; User instruction space WDB addresses. SISTBL: .BLKW 8. ; Supervisor I space WDB addresses. TMTLEN = .-UDSTBL .PAGE .PSECT CODE,I,RO ; ; Cause the target task to exit. ; T$EXIT::TST TSKCTX ; Is there a target task? BEQ 10$ ; No, just exit. MOV #CT.XIT,-(SP) ; Build a command packet. MOV SP,R0 ; Point to it. CALL T$SEND ; Send exit command. TST (SP)+ ; Clean up stack. 10$: RETURN ; ; Subroutine to cause the target task to proceed with execution. ; T$PRO:: MOV #UDSTBL,R0 ; Point to first mapping table. MOV #TMTLEN/4,R1 ; Get length of all mapping tables. 10$: CLR (R0)+ ; Zero all mapping tables. CLR (R0)+ SOB R1,10$ ; Detach from all target task regions. 20$: MOV WDBLST,R0 ; Get an active WDB address, zero? BEQ 30$ ; Yes, send proceed command packet. MOV W.XLNK(R0),WDBLST ; Unlink WDB structure. MOV W.NRID(R0),RDB+R.GID ; Set up region ID. DIR$ #DETACH ; Detach from region. MOV WDBFRE,(R0) ; Link free WDBs to current one. MOV R0,WDBFRE ; Make it free as well. BR 20$ ; Send proceed command. 30$: MOV #CT.PRO,-(SP) ; Build a command packet. MOV SP,R0 ; Point to it. CALL T$SEND ; Send it. TST (SP)+ ; Clean up stack. CLR MAPCTX ; Indicate mapping context buffer is needed. .IF DF X$FMAP CLR MAPWDB ; No window is currently mapped. .ENDC ; DF X$FMAP ; Change all register symbol values to offsets. MOV REGSYM,R0 ; Point to first register symbol block, OK? BEQ RCVMSG ; No, no register symbols are defined. 40$: SUB TSKCTX,S.VALU(R0) ; Convert value to an offset. MOV (R0),R0 ; Point to next register symbol, OK? BNE 40$ ; Yes, turn its value into an offset. BR RCVMSG ; Wait for a response and return. .PAGE ; ; Subroutine to initiate communications with the target task. ; T$STRT:: DIR$ #FNDTSK,T$DEAD ; Get task status, terminate if error. MOV TSKBUF,TSKNAM ; Copy complete task name. MOV TSKBUF+2,TSKNAM+2 MOV #E.AWMF,R1 ; Point to possible error message. DIR$ #CRTADW,T$ABRT ; Create an address window. RCVMSG: CALLR T$RECV ; Wait for a message and return. ; ; Handle an undecodeable DBGAID packet. ; On entry: R0 points to packet. ; T$IPKT:: MOV R0,-(SP) ; Save packet address. MOV #TRMBUF,R0 ; Point to terminal buffer. MOV $DBG$T,R1 ; Get first task name word. CALL C$R50 ; Convert it to ASCII. MOV $DBG$T+2,R1 ; Get second task name word. CALL C$R50 ; Convert it to ASCII. CLRB (R0) ; Terminate task name. MOV #TRMBUF,R0 ; Point to debugger task name. MOV #E.DAFU,R1 ; Point to error message. CALL ERROR ; Display it. MOV (SP)+,R0 ; Recover packet address. BPT ; Trap to internal DBGAID. RETURN .PAGE .ENABL LSB ; ; Subroutine to map a specified address in the target task. ; On entry: R0 contains desired address space. ; R5 contains desired target address. ; On exit: R1 contains debugger virtual address, carry set if error. ; R0 is destroyed by this routine. ; T$MAP:: MOV R5,R1 ; Copy target task address. BIC #^C<160000>,R1 ; Mask to APR number. SWAB R1 ; Put APR number in low byte. .IF LE USEASH-4 ASH #-4,R1 ; Shift it to make a word index. .IFF ASR R1 ; Shift it to make a word index. ASR R1 ASR R1 ASR R1 .ENDC ADD ASPTBL(R0),R1 ; Point to appropriate WDB address. MOV (R1),R0 ; Is there a WDB for specified address? BEQ 60$ ; No, exit with failure. CMP R0,CURWDB ; Is desired WDB currently mapped? BEQ CMAPNG ; Yes, see if it must be re-mapped. ; Desired WDB is not currently mapped. Request if necessary and map it. CALL FNDWDB ; Find the appropriate WDB, OK? BCC CMAPNG ; Yes, go map it. MOV R0,-(SP) ; Push WDB address for command packet. MOV #CT.SWR,-(SP) ; Push command type. MOV SP,R0 ; Point to command packet. CALL T$SEND ; Send window request to target task. CMP (SP)+,(SP)+ ; Remove command packet from stack. CALL T$RECV ; Receive the response. CMP #RT.WIN,R.TYP(R0) ; Is packet type correct? BEQ 20$ ; Yes, continue. CALL T$IPKT ; Handle unexpected packet type. 20$: MOV CURWDB,R0 ; Point to the WDB. MOV R0,(R1) ; Point APR table entry to debugger WDB. ; See if the window is mapped correctly. R0 points to the WDB. CMAPNG: CMP R5,W.XMAX(R0) ; Is requested address mappable? BHI 60$ ; No, exit with failure. MOV R5,R1 ; Copy target task address. SUB W.XBAS(R0),R1 ; Produce window address offset in bytes. ROR R1 ; Pick up carry (indicates borrow). .IF LE USEASH-5 ASH #-5,R1 ; Convert offset to 64-byte blocks. .IFF ASR R1 ; Convert offset to 64-byte blocks. ASR R1 ASR R1 ASR R1 ASR R1 .ENDC CMP R1,W.NLEN(R0) ; Is desired address mapped by the window? BLO 50$ ; Yes, calculate debugger virtual address. .PAGE ; ; Re-map the window to overlap the desired location. ; ADD R1,W.NOFF(R0) ; Adjust region offset. .IF LE USEASH-6 ASH #6,R1 ; Produce window offset in bytes. .IFF ASL R1 ; Produce window offset in bytes. ASL R1 ASL R1 ASL R1 ASL R1 ASL R1 .ENDC ADD R1,W.XBAS(R0) ; Adjust window base address. .IF DF X$FMAP MOV MAPWDB,R1 ; Get address of last window mapped, OK? BEQ 40$ ; No, forget it. CMP R0,R1 ; Same as current window? BEQ 30$ ; Yes, use fast mapping. CMP W.XRGN(R0),W.XRGN(R1) ; Do windows map same target region? BNE 40$ ; No, start over with MAP$. MOV W.NSTS(R0),-(SP) ; Get desired access rights. BIC W.NSTS(R1),(SP) ; Mask out legal access. BIT #WS.WRT!WS.RED,(SP)+ ; Is desired access enabled? BNE 40$ ; No, use MAP$ directive. ; ; Perform fast mapping. R0 points to WDB. ; 30$: MOV R3,-(SP) ; Save R3, MOV R2,-(SP) ; and R2. MOV R0,-(SP) ; Save WDB address. MOV W.NOFF(R0),R1 ; Get window offset. MOV #000170,R0 ; Get window ID (user data space APR 7). IOT ; Issue fast mapping call. ROL R0 ; Set carry if failure. MOV (SP)+,R0 ; Recover WDB address. MOV (SP)+,R2 ; Recover saved registers. MOV (SP)+,R3 ; Is everything OK? BCC 50$ ; Yes, re-enter common code. ; ; Can't use fast mapping or fast mapping failed. ; .IFTF ; DF X$FMAP 40$: CLR W.NLEN(R0) ; Map as much of the region as possible. MAP$S R0 ; Attempt to map the desired area, OK? BCS 60$ ; No, exit with failure. .IFT ; DF X$FMAP MOV R0,MAPWDB ; Remember which window was MAP$ed. .ENDC ; DF X$FMAP ; Window is mapped correctly. Calculate debugger virtual address. 50$: MOV R5,R1 ; Copy virtual address again. SUB W.XBAS(R0),R1 ; Get offset from window base address. ADD W.NBAS(R0),R1 ; Add debugger virtual base of window. CLC ; Indicate success. RETURN ; Desired address cannot be mapped. 60$: SEC ; Indicate failure. RETURN .DSABL LSB .PAGE ; ; Subroutine to send a message to a task. ; On entry: R0 points to command packet. ; T$SEND:: SDAT$S #TSKNAM,R0 ; Send transmission buffer, OK? BCS T$DEAD ; No, complain. RETURN T$DEAD: MOV #E.NACT,R1 ; Point to error message. T$ABRT: CALL ERROR ; Display it. JMP ABORT ; Terminate. ; ; Subroutine to receive a message from a task. ; On exit: R0 points to response packet. ; T$RECV:: JSR R5,.SAVR1 ; Save everything but R0. CALL SETWDB ; Set up WDB for message reception. 10$: WSIG$S ; Wait for a significant event. DIR$ #RCVREF ; Receive a message, OK? BCC 20$ ; Yes, set up for exit. DIR$ #FNDTSK ; Get task status, OK? BCS T$DEAD ; No, terminate. TST TSK.TS ; Is the target task executing? BPL 10$ ; Yes, give it another try. BR T$DEAD ; Abort with error message. ; A message has been received: check sender and packet type. 20$: MOV #RCVBUF,R0 ; Point to sender task name. CMP (R0)+,TSKNAM ; Is first task name word OK? BNE 10$ ; No, try again. CMP (R0)+,TSKNAM+2 ; How about the second task name word? BNE 10$ ; Nope, keep trying. CMP #RT.DEB,(R0) ; Is the packet an MCR DEBUG command? BNE 30$ ; No, take the packet and run. MOV #-1,MCRDEB ; Flag MCR DEBUG packet received. MOV CURWDB,R0 ; Point to window definition block. MOV W.NRID(R0),RDB+R.GID ; Set up region ID. DIR$ #DETACH ; Detach from region. BR 10$ ; Try again. ; Process incoming address window. 30$: MOV CURWDB,R1 ; Get current WDB address. MOV R.WDB(R0),W.XTAR(R1) ; Remember target task WDB address. MOV R.VDAT(R0),W.XRGN(R1) ; Get target task region ID. MOVB R.APR(R0),R2 ; Get base APR in target task. SWAB R2 ; Put it in the high byte. .IF LE USEASH-5 ASH #5,R2 ; It belongs in the top 3 bits. .IFF ASL R2 ; It belongs in the top 3 bits. ASL R2 ASL R2 ASL R2 ASL R2 .ENDC MOV R2,W.XBAS(R1) ; Save window base address. MOV W.NLEN(R1),R3 ; Fetch WDB mapping length word. CLR W.NLEN(R1) ; Indicate window is not currently mapped. .IF LE USEASH-6 ASH #6,R3 ; Make mapping length into address offset. .IFF ASL R3 ; Make mapping length into address offset. ASL R3 ASL R3 ASL R3 ASL R3 ASL R3 .ENDC ADD R2,R3 ; Produce maximum virtual address + 1. DEC R3 ; Reduce it to get maximum virtual address. MOV R3,W.XMAX(R1) ; Save it. TST MAPCTX ; Is mapping context needed? BNE 100$ ; No, just exit. .PAGE ; ; Process mapping context buffer. The current window must be correct. ; CLR W.XRGN(R1) ; Context window always maps task region. TSTB R.ASPC(R0) ; Is data space in use? BEQ 35$ ; Yes, maintain I/D space distinction. MOV #UISTBL,ASPTBL ; Force user D references to user I space. 35$: MOV R.TCTX(R0),TSKCTX ; Save virtual address of task context. MOV R.MCTX(R0),R5 ; Get virtual address of map context buffer. MOV R5,MAPCTX ; Save for posterity. MOV R1,R0 ; Copy WDB address. CALL CMAPNG ; Point to start of mapping context buffer. ; Process window definition blocks in target task context buffer. 40$: MOV W.NSTS(R1),R2 ; Get window status. BIT #WS.MAP,R2 ; Is this window mapped? BEQ 80$ ; No, look at the next one. MOV #UISTBL,R3 ; Assume window is in user instruction space. BIT #WS.UDS,R2 ; Is window actually in user data space? BNE 50$ ; Yes, set APR table pointer accordingly. BIT #WS.SIS,R2 ; Is window actually in super I space? BEQ 60$ ; No, it really is in user instruction space. MOV #SISTBL,R3 ; Point to super mode APR mapping table. BR 60$ ; Here if address window maps user data space. 50$: MOV #UDSTBL,R3 ; Point to user data space APR mapping table. 60$: MOVB W.NAPR(R1),R2 ; Get starting APR number. ADD R2,R3 ; Point to the appropriate WDB pointer. ADD R2,R3 MOV W.NLEN(R1),R4 ; Get number of 64-byte blocks mapped. 70$: MOV R1,(R3) ; Save WDB pointer for this APR. SUB W.NBAS(R0),(R3) ; Subtract debugger window base address. ADD W.XBAS(R0),(R3) ; Add target task window base address. BIS #1,(R3)+ ; Make result odd to flag target task address. INC R2 ; Bump APR number. CMP R2,#7 ; Is another APR possible? BHI 80$ ; No, don't screw up. SUB #128.,R4 ; Does this WDB use the next APR also? BHI 70$ ; Yes, set it up as well. 80$: ADD #W.NLGH,R1 ; Point to next WDB. TST (R1) ; End of mapping context buffer? BPL 40$ ; No, process this WDB. MOV #RSPBUF,R0 ; Point to response packet. ; Convert register symbol offsets back into values. MOV REGSYM,R1 ; Point to first register symbol block, OK? BEQ 100$ ; No, no register symbols are defined. 90$: ADD TSKCTX,S.VALU(R1) ; Convert offset to a value. MOV (R1),R1 ; Point to next register symbol, OK? BNE 90$ ; Yes, turn its value into an offset. 100$: RETURN .PAGE ; ; Subroutine to set up a WDB for message reception. ; SETWDB: MOV WDBFRE,R0 ; Get a WDB from free list, OK? BNE 10$ ; Yes, unlink it from the list. MOV #W.XLEN,R0 ; Get length of WDB structure. CALL U$RQCB ; Allocate a WDB structure, OK? BCC 20$ ; Yes, re-enter common code. MOV #E.AWMF,R1 ; Point to error message. CALLR T$ABRT ; Display error and exit. ; WDB has been gotten from free list. 10$: MOV (R0),WDBFRE ; Save address of next free WDB. 20$: MOV R0,RCVREF+R.REBA; Save WDB address in RREF$ DPB. MOV R0,CURWDB ; Make it the current WDB too. MOV WDBLST,W.XLNK(R0) ; Link next WDB to current one. MOV R0,WDBLST ; Head list with current WDB. MOV #PROWDB,R1 ; Point to prototype WDB. MOV #8.,R2 ; Get WDB length in words. 30$: MOV (R1)+,(R0)+ ; Copy prototype WDB over new one. SOB R2,30$ RETURN ; ; Subroutine to find the appropriate WDB if it has been sent. ; On entry: R0 contains WDB from APR table. ; R1 points to APR table entry. ; FNDWDB: MOV R2,-(SP) ; Save R2. BIT #1,R0 ; Is WDB address in target task? BEQ 40$ ; No, just make it current. DEC R0 ; Correct target task WDB address. MOV WDBLST,R2 ; Get address of first active WDB, zero? BEQ 20$ ; Yes, WDB must be requested. 10$: CMP R0,W.XTAR(R2) ; Is this WDB correct? BEQ 30$ ; Yes, update APR table. MOV W.XLNK(R2),R2 ; Get address of next active WDB, zero? BNE 10$ ; No, keep looking. 20$: SEC ; Indicate window must be requested. BR 45$ ; Pop R2 and exit. ; Found correct debugger WDB. 30$: MOV R2,R0 ; Copy WDB address to expected location. MOV R0,(R1) ; Update APR table WDB address. 40$: MOV R0,CURWDB ; Make selected window current. CLR W.NLEN(R0) ; Force remapping. 45$: MOV (SP)+,R2 ; Recover saved R2. RETURN .END