TITLE DEBSP *** DEBUG-SUPPORT *** TWOSEG ;ENTRY POINTS ENTRY INDEB. ENTRY EXDEB. entry ddtdb. entry magic,isDisk,debnam ;EXTERNAL REFERENCES EXTERN END,DEBUG,.JBFF,chntb.,oldpc.,getpg.,norcht search monsym,pasunv ;REGISTER DEFINITION AC0=0 AC1=1 REGIN=1 ;INITILISATION OF REGISTERSTACK REG= REGIN+1 REG1=REGIN+1+1 REG2=REGIN+1+2 REG3=REGIN+1+3 REG4=REGIN+1+4 REG5=REGIN+1+5 REG6=REGIN+1+6 JBFFLW=14 NEWREG=15 BUFFER=15 BASIS=16 TOPP=17 ;CONSTANTS debpgs=2 ;number of pages for pasddt locals debsiz=2000 ;number of words " ;ADDRESSES: .JBREL= 44 .JBDDT= 74 .JBOPC=130 ;START OF DEBUG-SUPPORT'S CODE ;***************************** LOC .JBDDT ;UPDATE .JBDDT XWD 0,DDTDB. RELOC 0 ;This program had better be first!!! ;The following is ENTRY2 in DEBUG. It used to be at 140 - 144. rgstrs: block 1 pushj topp,exdeb. link: block 2 status: block 3 orig16: block 1 pushj topp,chk16. ;The following will be STRING, STRINGTYPE and STRINGINDEX in ;DEBUG. They used to be generated using a NEW. str: block 35 ;"heap" storage for DEBUG strptr: block 4 stridx: block 5 ttysno==7 ;number of parameters to save ttysav: block ttysno+1 ;saved state of tty ttybuf: block ^D50 ;temporary tty buffer for debugger filttb==filst1 ;current tty buffer filbct==filst2 ;tty byte count filbpt==filst3 ;tty byte pointer RELOC 400000 .lnkend 1,link ;*** INITDEBUG: TEST ON 'NONSHARABLE', CORE-EXPANSION, DEBUG*** indeb.: hrrzm basis ,rgstrs+3 ;save bottom of stack movei ac1 ,debpgs ;number of pages for locals pushj topp ,getpg. ;get pages hrrzm ac1 ,rgstrs ;start of core block is our new start PUSHJ TOPP ,SAVERG ;SAVE REGISTERS move ac1 ,[xwd 1,debint] ;set up ^D intercept movem ac1 ,chntb.+^D35 ;as channel 35 movei 1 ,400000 ;turn on the channel movei 2 ,1B35 aic move 1 ,[xwd .ticcd,^D35] ;and associate with ^D ati move 1 ,(topp) ;1 _ ret addr move 1 ,(1) ;1 _ jrst start hrrzm 1 ,STATUS ;LH='INIT', RH=PROG.BEGIN PUSHJ TOPP ,DEBUG. POPJ TOPP , EXDEB.: PUSHJ TOPP ,SAVERG ;SAVE REGISTERS HRLI AC1 ,1 ;STATUS='STOP' HRR AC1 ,0(TOPP) ;RH=RETURNADDR SUBI AC1 ,1 ;RH=STOPADDR MOVEM AC1 ,STATUS PUSHJ TOPP ,DEBUG. ;CALL DEBUG POPJ TOPP , jrst indeb. ;another magic entry point - must be ddtdb.-2 ERRDB.: JRST 0 ,ERRDB1 ;THIS ENTRY MUST BE BEFORE DDTDB. DDTDB.: PUSHJ TOPP ,SAVERG ;SAVE REGISTERS HRLI AC1 ,2 ;STATUS='DDT' HRR AC1 ,.JBOPC ;RETURNADDR MOVEM AC1 ,STATUS PUSHJ TOPP ,DEBUG. ;CALL DEBUG skipe .jbopc ;if there is someplace to go jrstf @.jbopc ;return hrroi ac1,[asciz /No saved PC /] esout haltf jrst .-1 debint: pushj topp ,saverg ;save acs hrli ac1 ,2 ;status='DDT' hrr ac1 ,oldpc. ;stop address movem ac1 ,status pushj topp ,debug. ;call pasddt debrk ;return to program ERRDB1: ;RETURNADDR IN AC0 EXPECTED HRLI AC0 ,3 ;STATUS='RUNTIME ERROR' MOVEM AC0 ,STATUS PUSHJ TOPP ,SAVERG ;SAVE REGISTERS PUSHJ TOPP ,DEBUG. ;CALL DEBUG POPJ TOPP ,0 ;EXIT SAVERG: MOVEM AC0 ,@RGSTRS ;SAVE USER-REGISTERS MOVE AC0 ,AC1 HRRZ AC1 ,RGSTRS MOVEM AC0 ,1(AC1) HRRI AC0 ,2(AC1) HRLI AC0 ,2 BLT AC0 ,17(AC1) POPJ TOPP ,0 DEBUG.: move ac1,[xwd -ttysno-1,ttysav] push ac1,fileol+tty## ;save the state of tty i/o push ac1,filcmp+tty## push ac1,filttb+tty## push ac1,filbct+tty## push ac1,filbpt+tty## push ac1,filcht+tty## push ac1,filcmp+ttyout## setzm filcmp+tty## ;reinit tty movei ac1,1 movem ac1,fileol+tty## movei ac1,ttybuf movem ac1,filttb+tty## setzm filbct+tty## move ac1,[xwd ac1,norcht] movem ac1,filcht+tty## setzm filcmp+ttyout## ;likewise ttyoutput MOVE AC1 ,RGSTRS ;GET DEBUG-REGISTERS MOVEI NEWREG ,DEBSIZE-1(AC1) MOVEI BASIS ,20(AC1) MOVEI TOPP ,1(BASIS) hrl topp,topp ;[2] movei reg,rgstrs movei reg1,str movei reg2,strptr movei reg3,stridx PUSHJ TOPP ,DEBUG ;DEBUG move ac1,[xwd -1,ttysav+ttysno] ;restore tty state pop ac1,filcmp+ttyout## pop ac1,filcht+tty## pop ac1,filbpt+tty## pop ac1,filbct+tty## pop ac1,filttb+tty## pop ac1,filcmp+tty## pop ac1,fileol+tty## HRLZ 17 ,RGSTRS ;RESTORE USER-REGISTERS BLT 17 ,17 POPJ TOPP , ;*** SHARABLE: TRUE, IF HIGH-SEGMENT IS SHARABLE . ; SEE DECSYSTEM10 ASSEMBLY LANG.-HANDBOOK: MONITOR CALLS 3.3.4 ;The following routine is called by idtree when it finds a ;pushj p,0(1). It restores the basis of the routine, backs ;up before the pushj, and simulates the code that set ac 1. ;This is the only way I can think of to get the address of ;the routine that was called. magic: move reg1,basis ;reg1 _ debugger basis hll basis,-1(reg) ;basis of caller hlr basis,basis ;in both halves move reg,(reg) ;address of pushj subi reg,2 ;first candidate for start instr move reg2,reg ;save - also is last instr to xct ldb 1,[point 9,(reg),17] ;ac and index fields caie 1,56 ;this is what we want as first inst soja reg,.-2 xct (reg) ;found instruction addi reg,1 ;next camg reg,reg2 ;if not beyond last to do jrst .-3 ;then do it. movem 1,1(topp) ;they got result in 1 move basis,reg1 ;restore debugger basis popj topp, ;b - FCB. Note that the open may have failed. isdisk: setzm 1(topp) ;assume the worst skipe fileof(reg) ;if open failed popj topp, ;forget it hrrz 1,filjfn(reg) ;else see what we have dvchr ldb 1,[point 9,2,17] ;type code caie 1,15 ;nul: or dsk: is OK cain 1,0 aos 1(topp) ;code = 0; disk - return true popj topp, debnam: popj topp, ;used only on Tops-10 ;This is a routine used as an LUUO handler when we want to break ;after exiting the current procedure. It uses 16(basis) as an ;indication of the procedure depth. chk16.: caml 16,orig16 ;are we at same or higher level? popj topp, ;yes, nothing to do jrst exdeb. ;no - do a break ;***PLATZ FUER LITERALS *** LIT END