;       SCCSID = @(#)debbcmd.asm        6.2 91/06/01
PAGE    ,132
NAME    DEBBCMD
TITLE   DEBBCMD.ASM - Debug Breakpoint, Vector, Default command handler
.286p

;***    DEBBCMD.ASM
;
;       Contains the routines to handle the breakpoints, etc.
;
;       SCCSID = @(#)debbcmd.asm        6.2 91/06/01
;

.xlist
        include debseg.inc
        include debmac.inc
        include debequ.inc
        include debinit.inc
        include debdesc.inc
        include debsym.inc
.list

DataSegmentStart

Extern DebData,         WORD
Extern DefType,         WORD
Extern sbrtab,          BYTE
Extern pTXT,            WORD
Extern pTXTstart,       WORD
Extern RegSA,           WORD
Extern DefaultCmd,      BYTE

Static TempAddr,        STRUC,  AddrS, <>

ChgDefCommands  label   byte
        CmdTable_s <"L", codeOFFSET ChgDefList>
        CmdTable_s <"S", codeOFFSET ChgDefSet>
        CmdTable_s <0,   codeOFFSET perr>

DataSegmentEnd

CodeSegmentStart

Extern perr,            NEAR
Extern perror,          NEAR
Extern CmdBreak,        NEAR
Extern command,         NEAR

;***    ChangeDefCmd
;
;       Change the default command executed when the debugger is
;       entered thru a trace, ptrace or breakpoint which there is
;       no breakpoint command.
;
;       ENTRY:  NONE
;
;       EXIT:   NONE
;
;       USES:   ALL
;

DefProc ChangeDefCmd, NEAR, PUBLIC
        Pcall   GetChrI                         ; Get char & advance
        jz      short cdc1

;       Do the list or set of the default command

        mov     si,dataOFFSET ChgDefCommands
        Pcall   ExecSubr
        jmp     short cdc2

;       The Z command by itself executes the current default command

cdc1:   mov     si,dataOFFSET DefaultCmd
        Pcall   DoCommand
cdc2:
EndProc

;***    ChgDefList (ZL)
;
;       Print out the current default command.
;
;       ENTRY:  NONE
;
;       EXIT:   NONE
;
;       USES:   ALL
;

DefProc ChgDefList, NEAR, LOCAL
        Pcall   GetEOL
        mov     al,'"'                          ; display starting quote
        Pcall   put_ch                          ;

        cmp     DefaultCmd,0                    ; if nothing in buffer
        je      cdl1

        mov     dx,dataOFFSET DefaultCmd        ; (DX) = default command ptr
        Pcall   rprbuf

cdl1:   mov     al,'"'
        Pcall   put_ch
        Pcall   crlf
EndProc

;***    ChgDefSet (ZS)
;
;       Set the default command line.
;
;       ENTRY:  NONE
;
;       EXIT:   NONE
;
;       USES:   ALL
;

DefProc ChgDefSet, NEAR, LOCAL
        Pcall   ScanP
        jz      cds1
        mov     di,dataOFFSET DefaultCmd
        Pcall   ParseCommandLine
        jnc     cds2
        mov     di,dataOFFSET DefaultCmd        ; if error, reset to "R" cmd
        mov     ax,"R"
        stosw
cds1:   jmp     BadCommandLine

cds2:
EndProc

;***    ExecuteIfTrue
;
;       This command will execute the command following the expression
;       if the expression is true (not zero). J <expr> 'cmd' ;
;

DefProc ExecuteIfTrue, NEAR, PUBLIC

LocVar  TempCmdBuf, <CMDLINELEN>
LocVar  TmpExpr, <size ExprS>

BeginProc
        Pcall   ScanP                   ; skip leading commas and spaces
        lea     si,TmpExpr
        Pcall   EvalExpr

        lea     di,TempCmdBuf
        Pcall   ParseCommandLine        ; parse off command
        jc      BadCommandLine          ; if bad command line

        lea     si,TmpExpr
        Pcall   GetExprS                ; (BX:AX,DX) = expression value
        Pcall   IsTrue
        jnc     eit2                    ; if false, don't execute command

        lea     si,TempCmdBuf           ; execute command
        Pcall   DoCommand

eit1:   Pcall   GetChrI
        jnz     eit1                    ; go back to command prompt
        or      al,al
        jz      eit2
        inc     pTXT
        jmp     short eit1

Entry   BadCommandLine

        putstr  "Bad command line"
        jmp     CmdBreak
eit2:
EndProc

;***    ParseCommandLine
;
;       Parses off a command line or string from input buffer.
;
;       Pcall   ParseCommandLine
;
;       ENTRY:  (DI) = address of buffer to put command
;
;       EXIT:   Carry clear if no error
;               Carry set if error
;
;       USES:   AX, CL, SI, DI, Flags
;

DefProc ParseCommandLine, NEAR, LOCAL
        push    di                              ; save buffer pointer for later
        call    ParseString                     ; call ParseString
        pop     si
        jc      short pcl1
        Pcall   StrUpr                          ; force string upper case
        clc
pcl1:
EndProc

;***    ParseString
;
;       Parses off a string from input buffer.
;
;       Pcall   ParseString
;
;       ENTRY:  (DI) = address of buffer to put command
;
;       EXIT:   (DI) = pointer end of buffer, to EOS byte
;               Carry clear if no error
;               Carry set if error
;
;       USES:   AX, CL, SI, DI, Flags
;

DefProc ParseString, NEAR, PUBLIC
        xor     cl,cl
        Pcall   ScanP                           ; (AL) = next character
        mov     si,pTXT                         ; (SI) = ptr to command line
        jz      pst6

        Pcall   CheckString                     ; check for begining quote
        je      short pst1

        mov     al,";"                          ; EOS becomes the end of cmd
        dec     si

pst1:   inc     si                              ; skip quote
        mov     ah,al                           ; save quote or EOS

pst2:   lodsb                                   ; fetch character
        or      al,al
        jz      pst5                            ; exit on EOL
        cmp     al,ah
        jne     pst3                            ; exit on EOS
        cmp     al,";"
        je      pst5                            ; exit if EOS is ";"
        cmp     al,[si]
        jne     pst6                            ; check if two quotes in a row
        inc     si

pst3:   cmp     cl,CMDLINELEN
        jae     pst4                            ; error if command to long
        stosb
        inc     cl
        jmp     pst2

pst4:   stc
        jmp     short pst7

pst5:   dec     si                              ; don't eat ";"

pst6:   mov     pTXT,si                         ; fix up text pointer
        xor     al,al
        stosb                                   ; put NULL at end of cmd line
        clc
pst7:   dec     di
EndProc

;***    CheckString
;
;       Check if a starting string character " or '.
;
;       Pcall   CheckString
;
;       ENTRY:  AL = character
;
;       EXIT:   If zero clear, not a string character
;               If zero set, the character is a " or '.
;
;       USES:   FLAGS
;

DefProc CheckString, NEAR, PUBLIC
        cmp     al,"'"
        je      short cst1
        cmp     al,'"'
cst1:
EndProc

CodeSegmentEnd
        end
