home *** CD-ROM | disk | FTP | other *** search
- \\ CDBG96.SEQ A debugger for 80c196 by Mike Mayo
- Adapted from CODEBUG.SEQ, a CODE debugger for F-PC by Tom Zimmer
- ─────────────────────────────────────────────────────────────────────────────
- $Header: F:/tcom/debugger/logs/cdbg.sev 1.6 23 Apr 1991 11:00:24 MikeM $
- ─────────────────────────────────────────────────────────────────────────────
-
- This file contains a simple debugger for Intel 80c196 to allow debugging
- a Forth program compiled by TCOM96.
-
- It uses the COM port of a PC to communicate with the serial port
- of the 80c196.
- Code in the target supports several commands,
- e.g. fetch, store, call-subroutine.
- It also has code to handle breakpoint traps.
-
- Limited operations are supported while in the debugger,
- read the screen while debugging and press F1 for some help.
-
- ─────────────────────────────────────────────────────────────────────────────
- $Log: F:/tcom/debugger/logs/cdbg.sev $
- \
- \ Rev 1.6 23 Apr 1991 11:00:24 MikeM
- \ Improved
- ─────────────────────────────────────────────────────────────────────────────
- {
-
- anew cdbgwords
-
- target \ set target byte fetch for disassembler
-
- }
- ─────────────────────────────────────────────────────────────────────────────
- Words to allow setting the debugging registers
- ─────────────────────────────────────────────────────────────────────────────
- {
-
- : reg! ( a1 | <name> -- ) \ defining word to make register
- \ assignment words
- create , does> @ ! ;
-
- : reg@ ( a1 | <name> -- ) \ defining word to make register
- \ fetch words
- create , does> @ @ ;
-
-
- fload break96 \ target-specific breakpoint definitions
-
- }
- ─────────────────────────────────────────────────────────────────────────────
- Some handy debugging utilities
- ─────────────────────────────────────────────────────────────────────────────
- {
-
- : dbeeol ( -- ) \ fill the screen with spaces to the end of the box
- #out @ rboxcol
- < if rboxcol 1- sp>col
- else cols 1- sp>col
- then
- ;
-
- : .dbheader ( -- ) \ draw outline of debugging screen
- >norm
- 0 dbtop rboxcol 1- rows box&fill
- at? 1+ dplace 2!
- ." \1 Addr Instruction Data Code "
- rboxcol dbtop cols 1- rows box&fill
- at? 2+ rplace 2!
- at? 1- at
- ." \3 80c196 State \0"
- ;
-
- : .code ( a1 n1 -- ) \ show a string of code numbers that are in the target
- 0max bounds
- ?do i dt@ H.4 loop ;
-
- : Forth-command ( -- ) \ Provide for one forth command line
- savescr
- savecursor cursor-on
- 0 rows 3 - 2>r
- 2r@ at \ place it at the bottom of the debug window
- rboxcol sp>col cr
- rboxcol sp>col cr
- rboxcol sp>col
- 2r> at
- ." \1 Ready for a \`Forth\` command " cr
- ." ok" cr
- query interpret \ get and execute a Forth command line
- cr ." \2 Press a key "
- key drop
- restcursor
- restscr ;
-
- }
- ─────────────────────────────────────────────────────────────────────────────
- Display current instruction followed by data stack
- ─────────────────────────────────────────────────────────────────────────────
- {
-
- 0 value ipprev \ used for holding the address of the prior instruction
-
- : show-inst ( -- ) \ disassemble and show one instruction
- save> base hex
- at? dbeeol at \ blank the line
- cp @ dup>r \ get instruction address
- space h.4 inst \ disassemble instruction
- 44 #line @ at \ jump to code column
- r> cp @ over - 2 min .code \ show code
- restore> base
- >norm ;
-
- : .inst ( -- ) \ display the next instruction to single-step
- trapadr-@ cp !
- next-break if >rev else >ATTRIB3 then
- show-inst
- cp @ !> nextinline
- ;
-
- : .ninst ( n -- ) \ display the nth instruction after the next to single-step
- 1+ next-break
- = if >attrib3
- cp @ !> nextinline \ set up for "run to" option
- then
- show-inst ;
-
- : .pinst ( -- ) \ display the last executed instruction
- ipprev 0=
- if dbeeol
- else ipprev cp ! show-inst
- then
- ;
- }
- ─────────────────────────────────────────────────────────────────────────────
- Break point registers and control words.
- Allow setting, removing, and displaying the current break point.
- ─────────────────────────────────────────────────────────────────────────────
- {
- #trapbytes 2+ value #breakbytes
- create breakregs #breakbytes #breakregs * allot
- breakregs #breakbytes #breakregs * erase
- 0 value breakreg \ breakpoint selector, 0 <= breakreg < #breakregs
-
- : breakaddr ( -- a ) \ return pointer to the target address of
- \ the breakpoint selected by breakreg.
- breakreg
- 0max #breakregs 1- min
- #breakbytes *
- breakregs + ;
-
- : breaksave ( -- a ) \ return pointer to the target image of
- \ the breakpoint selected by breakreg.
- breakaddr 2+ ;
-
- : ?breakset ( n -- f ) \ return true flag f if breakpoint n is set.
- \ In addition it selects breakpoint n for
- \ subsequent use of breakaddr and breaksave
- !> breakreg
- breakaddr @ 0<> ;
-
- : unbreak ( n -- ) \ remove break point n
- ?breakset \ if break register is set
- if \ restore words at break point
- breakaddr @ breaksave tunbreak
- breakaddr off \ make address = 0, to indicate
- \ breakpoint no longer set
- then ;
-
- : unbreak-all ( -- ) \ remove all break points
- #breakregs 0 do i unbreak loop ;
-
- : setbreak ( break-address n -- ) \ set breakpoint n
- unbreak \ clear breakpoint
- breakaddr ! \ save target-address of breakpoint
- breaksave breakaddr @ tsetbreak \ save instructions at breakpoint
- ; \ and set trap
-
- : .breaks ( -- ) \ display the current break points
- cr
- 0
- #breakregs
- 0 do breakaddr @
- ?dup if ." Break point " i .
- ." set at " h. ." h"
- 1+ cr
- then
- loop
- 0= if ." No break point set" then
- ;
-
- }
- ─────────────────────────────────────────────────────────────────────────────
- Set a trap after the next instruction, return from the prior trap,
- then receive the next trap
- ─────────────────────────────────────────────────────────────────────────────
- {
- 0 value waiting-at-break \ flag to show the target is waiting in a breakpoint
-
- : receive-trap ( -- ) \ wait till it hits the next breakpoint
- \ at which time it sends a 't' followed by the SP
- \ and we copy the machine image from its stack.
-
- begin key? if key $1b = if Forth-command then then
- com-cnt 0<> if getbyte 't' =
- else false
- then
- until \ wait for the trap call to happen
-
- getword \ get the trap stack address
- read-break-stack \ now read in all the stacked items
- unbreak-all \ restore memory at the break location(s)
- on> waiting-at-break \ flag the target is waiting in a breakpoint
- ;
-
- : gofromtrap ( -- ) \ Make the target return from a trap
- \ First put (modified) values back into target
- restore-break-stack
- untrap \ excute from previous breakpoint
- off> waiting-at-break \ flag the target is no longer waiting
- ;
-
- : exec>trap ( -- ) \ make the target return from a trap,
- \ and wait for the next trap.
- gofromtrap \ excute from previous breakpoint
- receive-trap \ wait till it hits the next breakpoint
- \ and get all the data
- ;
-
- : one-step ( -- ) \ execute the next instruction
- TRAPADR-@ !> ipprev \ present instruction will be the previous
- next-break
- 0= if
- branch-type
- case
- 0 of nextinline 0 setbreak endof
- 1 of nextonbranch 0 setbreak endof
- 2 of nextinline 0 setbreak
- nextonbranch 1 setbreak endof
- 3 of nextonbranch 0 setbreak endof
- drop endcase
- else
- nextinline 0 setbreak
- then
- off> next-break
- exec>trap
- ;
-
- : one-step/skip ( -- ) \ execute to the next instruction in line
- \ i.e. do not nest into CALLs
- TRAPADR-@ !> ipprev \ present instruction will be the previous
- next-break
- 0= if
- branch-type
- case
- 0 of nextinline 0 setbreak endof
- 1 of nextonbranch 0 setbreak endof
- 2 of nextinline 0 setbreak
- nextonbranch 1 setbreak endof
- 3 of nextinline 0 setbreak endof
- drop endcase
- else
- nextinline 0 setbreak
- then
- off> next-break
- exec>trap
- ;
-
- }
- ─────────────────────────────────────────────────────────────────────────────
- Show the current registers,
- and a series of instructions as they will be executed.
- ─────────────────────────────────────────────────────────────────────────────
- {
- defer abrowse \ to enter the browser with a specific address
- 0 value browse-addr
-
- : show_debug ( -- )
- .regs
- dplace 2@ at
- .pinst dcr .inst dcr \ show past and present instructions
- at? 2>r
- 1 dbtop at
- next-break
- if ." \3 Press \4 Space \3 to run to highlighted instruction "
- else
- branch-type 3
- = if
- ." \4 Space \3 next in line \0────"
- ." \4 Enter \3 enter subroutine "
- else
- ." \3 Press \4 Space "
- ." \3 to execute highlighted instruction "
- then
- then
- 2r> at
- rows dbtop - 5 -
- 0 do i .ninst dcr loop
- next-break
- if nextinline !> browse-addr
- else trapadr-@ !> browse-addr
- then
- abrowse \ show source listing
- ;
-
- : set_register ( -- )
- savescr
- savecursor cursor-on
- 0 rows 1- 2dup at cols 1- sp>col at
- ." \1 { In the form e.g. $23 =W0 } command: "
- query interpret \ user may modify a register
- restcursor
- restscr
- .regs \ redisplay the registers
- ;
-
- : up_dbline ( -- ) \ move the breakpoint up one instruction
- next-break 1- 0max !> next-break
- next-break 1 = if off> next-break then \ skip 1
- show_debug
- ;
-
- : down_dbline ( -- ) \ move the breakpoint down one instruction
- next-break 0= if incr> next-break then \ skip 1
- incr> next-break
- show_debug
- ;
- }
- ─────────────────────────────────────────────────────────────────────────────
- Additional MINI help for the debugger.
- ─────────────────────────────────────────────────────────────────────────────
- {
- : debug_help ( -- )
- \ savecursor cursor-off savescr
- 0 5 59 19 box&fill
- bcr ." Debugger commands:" bcr
- bcr ." \1 SPACE \0 = Go to highlighted instruction"
- bcr ." \1 F \0 = Forth command line"
- bcr ." \1 R \0 = Set a Register ( Forth command line )"
- bcr ." \1 Enter \0 = Nest into a CALL"
- \ bcr ." \1 F2 \0 = Switch to full-screen browse"
- bcr ." \1 Esc \0 = Pull-down menus"
- bcr
- bcr ." \1 Press ESC to continue, or SPACE for more help "
- key $1B
- <> if
- 0 5 59 19 box&fill
- bcr ." After \1 R \0 = Set a Register ( FORTH command line )"
- bcr ." Using \`<number> =W0\` will set W0 to <number>."
- bcr ." Examples of registers that can be set...."
- bcr ." =W0 =W2 =TTOS =TTOS2 =flags"
- bcr ." Or use T! TC! tedit etc. to change target memory."
- bcr bcr ." \S10\1 Press ANY key to continue " key drop
- then
- \ restscr restcursor
- ;
-
-
- : DB-endfunc \ ( To be done when leaving the debugger )
- \ Maybe let the target run if it is waiting at a breakpoint
- waiting-at-break
- if \ if the target is waiting in a breakpoint
- 10 dbtop rows + 2/ 60 over 2+ box&fill
- ." \2 Do you wish to let the TMS320 run? \3 (Y/N) "
- begin
- key upc
- case
- 'Y' of true true endof
- 'N' of false true endof
- beep drop false
- endcase
- until
- if gofromtrap then \ run from the breakpoint
- then
- ;
- }
- ─────────────────────────────────────────────────────────────────────────────
- The main trace loop.
- It single-steps through instructions
- ─────────────────────────────────────────────────────────────────────────────
- {
-
- : dsteps ( -- ) \ This is the debugger.
- \ It is to be used after setting a breakpoint
- \ and causing it to be executed in the target.
- dbtop !> browselines
- 0 ?breakset if
- 0 dbtop rboxcol rows 1- box&fill
- ." \2 Waiting for target-trap " bcr
- ." \1 Press \3 ESC \1 for options \0 "
- receive-trap
- then
- .dbheader
- show_debug
- on> showingdebug
- ;
-
-