TITLE DEBSP *** DEBUG-SUPPORT *** TWOSEG ;edit history - starts with edit 2 ;2 - check mon.tp so we don't check for write-prot hiseg on tops-20 ;ENTRY POINTS ENTRY INDEB. ENTRY EXDEB. entry ddtdb. entry magic,isdisk,debnam ;EXTERNAL REFERENCES EXTERN END,DEBUG,.JBFF,MON.TP,IN.DDT,parse,norcht search pasunv,uuosym ;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 MAXEOF=10 DEBSIZE=1024 ;1K ;ADDRESSES: .JBREL= 44 .JBDDT= 74 .JBOPC=130 .GTSGN=14 ;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 RELOC 400000 .lnkend 1,link ;*** INITDEBUG: TEST ON 'NONSHARABLE', CORE-EXPANSION, DEBUG*** indeb.: hrrzm basis ,rgstrs+3 ;save bottom of stack PUSHJ TOPP ,SHRCOD ;CALL SHARABLE" JUMPE AC1 ,.+3 ;NOT SHR OUTSTR[ ASCIZ /$ PROGRAMS WITH DEBUGSWITCH ON ( D+ ) MUST NOT BE SHARABLE! $ TRY AGAIN WITH "SAVE ..." INSTEAD OF "SSAVE ..."/ ] JRST END HRRZ AC1 ,.JBFF ;[1] GET HIGHEST LOC MOVEM AC1 ,RGSTRS ;OLD CORE-END BECOMES BEGIN OF DEBUG AREA ADDI AC1 ,DEBSIZE hrrm ac1 ,.jbff ;[1] new last location camg ac1 ,.jbrel ;only do CORE if not enough jrst ,indb1 CORE AC1 , ;GET CORE FOR DEBUGGING HALT ;ERROR RETURN indb1: aos .jbff ;[1] .jbff is one beyond end PUSHJ TOPP ,SAVERG ;SAVE REGISTERS 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 JRST 0 ,@.JBOPC ;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 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 ,RGSTRS ;GET DEBUG-REGISTERS MOVEI NEWREG ,DEBSIZE(AC1) MOVEI BASIS ,20(AC1) MOVEI TOPP ,1(BASIS) movei reg,rgstrs movei reg1,str movei reg2,strptr movei reg3,stridx push p,filcht+tty## ;save old tty mode move ac0,[xwd ac1,norcht] ;and set so see eol movem ac0,filcht+tty## push p,(p) setom in.ddt PUSHJ TOPP ,DEBUG ;DEBUG setzm in.ddt pop p,(p) pop p,filcht+tty## ;retore user's tty mode 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 shrcod: move ac1,mon.tp ;[2] if not tops-10, can always change cain ac1,1 ;[2] jrst shr10 ;[2] is tops-10, test with gettab setz ac1, ;[2] not tops-10, say not sharable popj topp, ;[2] shr10: HRROI AC1 ,.GTSGN ;SEE IF HGH SEGM. IS SH. GETTAB AC1 , ; LOOK AT .GTSGN TABLE HALT ;ERROR RETURN LSH AC1 ,777736 ;SHIFT BIT 1 TO RIGHTMOST PLACE ANDI AC1 ,1 ;CLEAR THE OTHER BITS POPJ TOPP , ;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, ;isdisk - return true if disk or nul: ; reg - FCB isdisk: setzm 1(topp) ;assume the worst skipe fileof(reg) ;if open failed popj topp, ;forget it ldb 1,[point 4,filchn(reg),12] ;get chan no. devchr 1, tlne 1,(dv.dsk) aos 1(topp) ;code = 0; disk - return true popj topp, ;debname sets up the file name fields. It can get its data from ;either of two sources: ; a binary copy of the fields used by the original source file, ; compiled into the .REL file ; an ascii string given by the user in response to the error ; handler. ;It distinguishes these cases by the fact that the data block starts ;with a zero word in the first case, but not the second. ; b - fcb ; c - address of data block ; d - length of data block, when used as a character string ;Note that these arguments are the same as used by PARSE, the normal ;file-name parser used by PASIO, so we can just call it. debnam: move t,filtst(b) ;see if needs init caie t,314157 pushj p,initb.## skipe (c) ;if first word is non-zero jrst parse ;parse it as string add c,[xwd ^D10,^D10] ;else restore magic words pop c,filppn+5(b) pop c,filppn+4(b) pop c,filppn+3(b) pop c,filppn+2(b) pop c,filppn+1(b) pop c,filppn(b) pop c,filpro(b) pop c,filext(b) pop c,filnam(b) pop c,fildev(b) popj p, ;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