MCALL   .MODULE
MODULE  DEBUG,RELEASE=X01,VERSION=01,COMMENT=<Enable debugging for job>

; Copyright (C) 1989 By Megan B Gentry. All Rights Reserved
;
; This software is provided for personal use only and may be used and
; copied only with the inclusion of the above copyright notice.
;
; The author assumes no responsibility for the use or reliability of
; this software.
      .SBTTL  Abstract and Edit History

;+
;
; DEBUG
;
;       The purpose of this program is to provide a tool for debugging
;       foreground or system jobs under RT11 using DBG-11.  The reason
;       this program is needed is that the breakpoint trap vector is
;       a context-switched location, and unless it has been specified
;       for a foreground or system job, it defaults to the system
;       BPTRAP routine and aborts a job.
;
;       This program duplicates the contents of the current physical
;       breakpoint trap vector in the appropriate locations in the
;       impure area of the specified job.
;
; X01 (000) 21-Jun-89   Initial coding
;       MBG
;
; X01 (001) 10-Oct-89   Corrections to code which finds location of
;       MBG             register save area, reported by George
;                       Stevens.
;
;-
      .SBTTL  Definitions

; Specify system library

       .LIBRARY "SRC:SYSTEM.MLB"

; System communcations area

       .MCALL  .SYCDF, .JSWDF

       .SYCDF
       .JSWDF                          ;Job status word

; RMON Fixed offsets

       .MCALL  .FIXDF, .CF1DF, .SGNDF

       .FIXDF
       .CF1DF                          ;Configuration word 1
       .SGNDF                          ;System generation features word

; Impure area offsets

       .MCALL  .IMPDF

       .IMPDF

; RT-11 Programmed requests we'll be using

       .MCALL  .GVAL,  .RCTRL, .GTLIN
       .MCALL  .PRINT, .GTJB,  .EXIT

; PDP-11 Vector area

       V.BPT   =: 14                   ;Breakpoint trap vector

; Characters

       LF      =: 12                   ;Line feed
       CR      =: 15                   ;Carriage return
      .SBTTL  Local Macro Definitions

; Error message reporting macro

       .MACRO  ERROR.  SEVER,TEXT,CR=YES
       ..MASK = 0
       ..FLAG = 0
       .IRPC XXX,<IWEFU>
        .IF EQ ..FLAG
         .IF IDN SEVER,XXX
               ..FLAG = 1
         .IFF
          .IIF EQ ..MASK ..MASK = 1
               ..MASK = ..MASK*2
         .ENDC
        .ENDC
       .ENDR
       .IF NE ..FLAG
        .SAVE
        .PSECT .TEXT.
        ... = .
               .NLIST  BEX
               .BYTE   ..MASK
               .ASCII  |'SEVER'TEXT|
        .IF IDN CR,YES
               .BYTE   0
        .IFF
               .BYTE   200
        .ENDC
               .LIST   BEX
        .RESTORE
               MOV     #...,R0
               CALL    ERRPRO
        .IFF
               .ERROR ;Invalid severity - ''sever''
        .ENDC
       .ENDM
      .SBTTL  PSECT Ordering

       .PSECT  .CODE.                  ;Pure code
       .PSECT  .TEXT.                  ;Pure/impure text
       .PSECT  .DATA.                  ;Impure data
      .SBTTL  Start of utility

       .PSECT  .CODE.

       .ENABL  LSB

DEBUG:  .GVAL   #AREA,#$CNFG1           ;Get system configuration word 1
       BIT     #FBMON$,R0              ;Running under SJ?
       BNE     10$                     ;Nope...
       ERROR.  F,<No other jobs in SJ>
       .EXIT

10$:    BIT     #KT11$,R0               ;Running under XM?
       BNE     15$                     ;Yep...
       ERROR.  F,<Breakpoint vector not context switched in FB>
       .EXIT

15$:    BIS     #TTLC$,@#$JSW           ;Enable lower case
       .RCTRL                          ; and make sure it takes effect
20$:    CALL    GETCOM                  ;Get a valid command
       CALL    PROCOM                  ; and go process it
       BR      20$                     ;Do until when?

       .DSABL  LSB
      .SBTTL  GETCOM  - Get a valid command from the user

;+
;
; GETCOM
;       Prompts the user for a command line of the form
;
;               job_name
;
;       where 'job_name' is the name of the job for which DBG
;       debugging is to be enabled.
;
; Implicit output:
;       JOBNAM  contains <NUL>-terminated ascii jobname string
;
;-

       .ENABL  LSB

GETCOM:
       MOV     #ARGBLK,R5              ;R5 -> GTLIN argument block
       CALL    GTLIN                   ;Get a line from chain area or tty
       MOV     #LINBUF,R1              ;R1 -> User's response
       TSTB    (R1)                    ;Was user response simply a <RETURN>?
       BNE     10$                     ;Nope...
       .PRINT  #M.ID                   ;Yes, respond with program info
       BR      GETCOM

10$:    MOV     #JOBNAM,R2              ;R2 -> Where to put job name
       MOV     #6,R3                   ;R3 = Maximum job name string length
20$:    MOVB    (R1)+,(R2)+             ;Nope, move a character
       BEQ     30$
       SOB     R3,20$                  ;Loop for valid job_name string length
       ERROR.  F,<Invalid command line>
       BR      GETCOM

30$:    RETURN

       .DSABL  LSB
      .SBTTL  PROCOM  - Process command

;+
;
; PROCOM
;       Processes the command, referencing the impure area of the specified
;       job and setting the breakpoint trap info.
;
; Note:
;       When we enter this routine, we have already verified that
;       we are running under XM, so no XM checking need be done.
;
;-

       .ENABL  LSB

PROCOM: .GTJB   #AREA,#JOBINF           ;Get info on this job
       MOV     JOBINF,R1               ;Save its number
       .GTJB   #AREA,#JOBINF,#JOBNAM   ;Locate the specified job
       BCC     20$                     ;Got it
       ERROR.  F,<No such job >,CR=NO
10$:    .PRINT  #JOBNAM
       BR      120$

20$:    CMP     JOBINF,R1               ;Same target as current job?
       BNE     30$                     ;Nope...
       ERROR.  F,<Invalid target job >,CR=NO
       BR      10$

30$:    MOV     #JOBINF,R0              ;R0 -> Job info area
       MOV     JB.IMP(R0),R1           ;R1 -> Impure area for job

; Begin code to determine location of two word BPT vector save area
; within the impure area of the specified job.

       .GVAL   #AREA,#$SYSGE           ;R0 = Sysgen features

       MOV     #I.BLOK+2,R2            ;R2 = I.JID (last fixed impure offset)

       BIT     #STASK$,R0              ;Monitor support system tasks?
       BEQ     40$                     ;Nope...
       ADD     #<14-10>,R2             ;Yes, account for larger I.JID
       ADD     #6,R2                   ; and we must account for I.LNAM
40$:    ADD     #10,R2                  ;Account for I.JID in all monitors

                                       ;R2 = I.NAME
       ADD     #<10+2+2>,R2            ;Account for I.NAME, I.SPLS,
                                       ; and I.TRAP in all monitors
       BIT     #FPU11$,R0              ;Do we have FPU support?
       BEQ     50$                     ;Nope...
       ADD     #2,R2                   ;Yes, then account for I.FPP
50$:
;;;     BIT     #MMGT$,R0               ;Running under XM?
;;;     BEQ     60$                     ;Nope...
       ADD     #2,R2                   ;Yes, then account for I.SPSV

60$:                                    ;R2 = I.SWAP
       ADD     #<4+2>,R2               ;Account for I.SWAP, I.SP,

; ** ACTION ** At this point, should code branch for FB?  Registers
;               saved in stack frame rather than in impure area.

       ADD     #<$USRLO-$LOWMA>,R2     ; and I.BITM for all monitors
       BIT     #MTTY$,R0               ;Do we have Multi-terminal support?
       BEQ     70$                     ;Nope...
       ADD     #<2+2>,R2               ;Yes, then account for I.CLUN
                                       ; and I.TTLC

70$:                                    ;R2 = I.IRNG
       ADD     #<2+2+2+2>,R2           ;Account for I.IRNG, I.IPUT,
                                       ; I.ICTR, and I.IGET
       MOV     R2,-(SP)                ;Build pointer to I.ITOP
       ADD     R1,@SP                  ; ...
       MOV     @(SP),@SP               ;Get pointer to I.OPUT
       ADD     #<2+2+2>,@SP            ;Build pointer to I.OTOP
       MOV     @(SP),@SP               ;Get pointer to I.QUE
       SUB     R1,@SP                  ;Determine offset for I.QUE
       MOV     (SP)+,R2                ; and replace running offset

                                       ;R2 = I.QUE
;;;     BIT     #MMGT$,R0               ;Running under XM?
;;;     BEQ     80$                     ;Nope...
       ADD     #<24-16>,R2             ;Yes, account for larger I.QUE in XM
80$:    ADD     #16,R2                  ;Account for I.QUE

                                       ;R2 = I.MSG
       ADD     #<4+6+2+2+2>,R2         ;Account for I.MSG, I.SERR, I.TERM,
                                       ; I.TRM2 and I.SCCA in all monitors
;;;     BIT     #MMGT$,R0               ;Running under XM?
;;;     BEQ     90$                     ;Nope...
       ADD     #2,R2                   ;Yes, account for I.SCCI

90$:                                    ;R2 = I.DEVL
       ADD     #2,R2                   ;R2 = I.SCOM
;;;     BIT     #MMGT$,R0               ;Running under XM?
;;;     BEQ     ***                     ;Nope...
       BIT     #FPU11$,R0              ;FPU support?
       BEQ     100$                    ;Nope...
       ADD     #2,R2                   ;Yes, account for I.FPSA
100$:   BIT     #MTTY$,R0               ;Running under multi-terminal?
       BEQ     110$                    ;Nope...
       ADD     #<40-36>,R2             ;Yes, account for larger I.SCOM
110$:   ADD     #36,R2                  ;Account for I.SCOM

                                       ;R2 = I.RSAV
       ADD     R1,R2                   ;R2 -> I.RSAV
       MOV     @#V.BPT+2,-12(R2)       ;Enable BPT's for target job
       MOV     @#V.BPT,-10(R2)         ; to go to same debugger as background
120$:   RETURN

       .DSABL  LSB
       .if eq 1
      .SBTTL  TCBPTR  - Returns TCB address

;+
;
; TCBPTR
;       Returns the address of the TCB associated with a terminal
;       in a multiterminal configuration.
;
; CALL:
;       R1 = Number of terminal TCB desired
;               (^RCTY for system console TCB)
;
; Return:
;       c-bit = 0
;         R1 -> TCB
;       c-bit = 1, invalid argument
;         R1 unchanged
;
;-

TCBPTR: MOV     R0,-(SP)                ;Save R0 for awhile
       .MTSTA  #AREA,#MTINFO           ;Get info on this multiterminal system
       CMP     R1,#<^RCTY>             ;Now, is request for TCB of CTY?
       BNE     10$                     ;Nope...
       MOV     MTINFO+2,R1             ;R1 = Offset from $RMON to TCB
       BR      40$

10$:    CMP     R1,MTINFO+4             ;If not CTY, is terminal number valid?
       BGT     50$                     ;Nope...
       MOV     R1,-(SP)                ;Save terminal number passed
       MOV     MTINFO,R1               ;R1 = Offset from $RMON to first TCB
20$:    DEC     (SP)                    ;Any more TCB's to account for?
       BLT     30$                     ;Nope, we're there...
       ADD     MTINFO+6,R1             ;Yes, add size of a TCB
       BR      20$

30$:    TST     (SP)+                   ;Discard counter
40$:    ADD     @#SYSPTR,R1             ;Add address of $RMON
       TST     (PC)+                   ;Good return, c-bit clear
50$:    SEC                             ;Error return, c-bit set
       MOV     (SP)+,R0                ;*C* Restore saved R0
       RETURN

       .endc ;eq 1
      .SBTTL  ERRPRO  - Centralized error processor

;+
;
; ERRPRO
;       Prints error messages in the form
;
;               ?Facility-Severity-Text
;
; CALL:
;       R0 -> Message definition
;               First byte is $USRRB mask
;               Second byte is severity character
;               Remaining bytes comprise message
;                       (end in <NULL> or <200> byte)
;
;-

ERRPRO: BISB    (R0)+,@#$USRRB          ;Set the User Error Byte
       MOVB    (R0)+,SEVER             ;Set message severity
       MOV     R0,-(SP)                ;Save pointer to text
       .PRINT  #FACILI                 ;'?Facility-Severity-
       .PRINT  (SP)+                   ; text'
       RETURN
      .SBTTL  Text messages

       .PSECT  .TEXT.
       .NLIST  BEX

M.FORC: .NLCSI  TYPE=I,PART=NAME
       .ASCII  />/<200>
M.ID:   .NLCSI  TYPE=Z,PART=ALL

       .LIST   BEX
       .EVEN
      .SBTTL  Impure data area

       .PSECT  .DATA.

FACILI: .NLCSI  TYPE=I,PART=PREFIX
SEVER:  .ASCII  /x-/<200>
       .EVEN

AREA:   .BLKW   3                       ;General purpose EMT area

ARGBLK: .WORD   3
       .WORD   LINBUF
       .WORD   M.FORC
       .WORD   STRING

STRING: .ASCIZ  /PLAIN/
JOBNAM: .BLKB   8.                      ;Six characters plus <NUL>

LINLEN: .BLKW                           ;Number of characters
LINBUF: .BLKB   134.                    ;User response buffer

JOBINF: .BLKW   12.

       JB.IMP = 10

       .END    DEBUG