 Apple IIgs Debugging Tips and Techniques
 compiled by David A. Lyons, Apple II Developer Technical Support
 July 18, 1990
 
 (July 23: corrected "InstallNDA is new for 5.0" to "RemoveNDA is new
 for 5.0, and be careful about removing DAs.  Otherwise this document
 is what I handed out as the A2-Central Developers Conference.)
 
 General Techniques
 
 In a Desktop-based program that normally displays the super-hires
 graphics screen, write debugging messages to the text screen at
 selected points in your program (using the Text Tools, for example).
 Then in the event loop, test the mouse position (it appears in the 
 "where" field of the event record after a GetNextEvent or TaskMaster 
 call).  If the mouse is in the upper left corner of the screen switch
 to the text screen using the QuickDraw II call GrafOff.  If the mouse
 is anywhere else, switch back to the graphics display with GrafOn. 
 (Reported by Ron Lichty; technique by Allan Bell, Australia)
 
 Check for errors on all toolbox calls that allocate memory.  Have a
 scheme for dealing with low-memory situations.  See Apple IIgs
 Technical Notes #51, 52, 56, and others, and read about the System 
 Software 5.0 Out Of Memory Queue handling introduced (Apple IIgs
 Toolbox Reference Volume 3).
 
 Make sure the Bank register is set right.  If you're writing code
 that all fits into a single 64K bank, you may want to always keep
 your data inside your code segment and use PHK PLB.  If your data
 is in a separate segment, this is bad (you may not discover it right
 away, because two segments can wind up in the same bank most of the 
 time, especially if they happen to be small).
 
 Use safety checks possible in your development environment.  For
 example, if you use macros to allocate direct-page locations, use
 assemble-time error messages to check the amount of direct-page space
 you're using.  If it exceeds 256 bytes, complain during assembly; 
 this will be a lot more fun than trying to figure out why your code
 mysteriously crashes.
 
 Watch out for uninitialized storage locations!  Random values may
 allow your code to work a lot of the time, so suspect this problem 
 especially if your code works right sometimes and fails other times.
 (Developer Technical Support provides "Pointer Check" routines for
 use with APW C.  See Sample Code volume 2.)
 
 
 
 Tips for using GSBug
 (Thanks to Tim Swihart for some of these GSBug tips.)
 
 Break into your application at a strategic toolbox call, such as 
 TaskMaster, by using the GSBug commands SetTBrk and TBrkIn.  When
 you hit r to resume your application, you will automatically drop
 into GSBug when you hit the selected call.  At that point you can 
 disassemble pieces of your code, start single-stepping it with s,
 or whatever.   You can usually even hit Apple-Ctrl-ESC to enter your
 favorite CDA (see below).
 
 Here's a way to trace your program's code for handling a particular
 menu item.  Set a tool break on TaskMaster.  Resume your code and let
 it break on the TaskMaster call.  Type s to display the super-hires 
 screen, and click and hold the mouse button on the menu bar.  Press 
 space to execute the TaskMaster call.  Select a menu item and release
 the mouse.  At this point, you are still in GSBug, and TaskMaster has
 just returned.  Press T to display the text screen, and press space 
 to step through your code.
 
 Debugging a Classic Desk Accessory is hard, because the stack is
 normally in $00/01xx when a CDA executes.  GSBug is not able to 
 trace code reliably while the stack pointer is in this range. 
 Here's something you can do instead, if you really need to trace 
 that CDA code:  break into the application at a convenient point 
 (like at a TaskMaster call), set D=0 and start Stepping from the
 CDA's entry point (one way to determine the entry point is with
 Nifty List--try c018.5000i to find the right block in memory, and 
 use ;c to display the name and entry points).
 
 Debugging a New Desk Accessory with GSBug was hard in the past,
 because the debugger could not receive any keystrokes while an NDA
 window was in front.  With GSBug 1.5, just push down the CapsLock 
 key, and all is well (the NDA does not receive any keystrokes while
 CapsLock is down and GSBug 1.5 is installed.)
 
 Type off in GSBug to see the top 23 lines of your code's "Real" text
 screen.  Type on to get the GSBug screen back. 
 
 If you get really fancy, you can build the strings (used in the
 SetMileStone and DebugStr calls) on the fly and imbed the values 
 of key variables into them to further simplify locating the bug.
 
 If your development languages supports imbedding names or other 
 info about your source into your object, use them.  This helps you
 find routines at debug-time.
 
 
 
 Nifty List Techniques
 
 Nifty List is a Classic Desk Accessory by Dave Lyons.  It's 
 Shareware, and you can download it from GEnie or America Online, 
 among other places.  If he ever happens to be right in the same room
 with you, be sure to ask him for a copy.
 
 Here are a few things I do when I'm debugging some code with Nifty
 List handy.
 
 Pop into Nifty List and type V to see if you've really started up 
 all the tools you think you have, and make sure the Work Area 
 Pointers are valid (most tools use their WAPs for the address you
 pass to the startup routine; the Control Manager is currently an 
 exception).  Most of the other tool sets have valid handles or 0 for
 their WAPs.  This is not guarnateed, but it's a useful sanity check
 while you're writing an application.  (A few tool sets share the same
 work areas.  Don't worry; it's normal for the Window Manager and
 Event Manager to share, and for QuickDraw II and QuickDraw II 
 Auxiliary to share, for example.)
 
 Use the new Nifty List 3.0 \addfree and \check commands in Big
 Brother module to detect accidental memory stomping.
 
 Use c018.1000i to locate the static code segments in your application
 ("Info on handles with owner $10xx and memory manager attributes 
 $C018").
 
 Use 0/0;w to dump info about your window, including the pointer to
 the Content Draw routine.  Make sure the content-draw routine does
 not assume that the Bank or D registers are set on entry!  If it 
 changes them, make sure it puts them back.
 
 If your window doesn't update right, check your content draw 
 routine--you must not assume you are the frontmost window, so using
 FrontWindow to see what window you're supposed to draw in is wrong.
 Use GetPort instead, because TaskMaster sets the QuickDraw port to
 your window before it calls your update routine.
 
 Explore the toolbox by making toolbox calls directly from the Nifty 
 List command line.
 
 
 When you Crash
 
 When you crash, look on the stack for return addresses to see how 
 you got there.  Sometimes things went so weird this is impractical,
 but it often helps.  Nifty List's ;s command looks for RTS and RTL
 addresses for you automatically.  (An "RTL address" is a sequence of
 3 bytes on the stack that is the address of the last byte of a JSL 
 instruction your program has executed, but which has not yet
 returned.)
 
 Check the Direct page register on a crash--by comparing against the 
 WAPs for tools, you can often determine which toolset was in control
 of the machine when it crashes (that doesn't mean it isn't your 
 fault, but it gives you a clue about where to look!). 
 
 
 
 Logic Analyzers
 
 Logic Analyzers are hardware that hooks up to your computer and
 watches what's going on.  They're pretty expensive, and you don't
 need one for most debugging problems.  For certain types of problems,
 though, they come in very handy.  For example, if you have found a
 particular byte of memory that gets changed for no reason, but your 
 best efforts to find out what piece of code is actually changing 
 that byte have failed, a logic analyzer can help.  (Debugging code
 that gets called during interrupts can be impossible to debug with
 GSBug.  If you can step through the code outside the interrupt 
 environment, great--if that's impossible, consider using a logic 
 analyzer.)
 
 The general idea is to tell that logic analyzer to "trigger" on a
 particular event (a read or write of a particular byte in memory)
 and then to record what happens after that (storing everything that 
 the processor does, or just selected operations).  This happens
 quickly, and then you can scroll through the resulting list to see
 exactly what happened in the next thousand or more clock cycles.
 
 Trick:  include accesses to known ROM locations to help you trigger
 the analyzer at particlar spots in your code (STA $FF0000, $FF0002,
 $FF0004, etc).
 
 
 Here is some specific information about HP logic analyzers used for
 debugging on the Apple II Family.  The HP 16500 provides more 
 sophisticated trap specification end specification of which
 instructions to store when a trap is in effect.  This provides for
 more trace mileage out of the 1024 instructions that can be traced 
 than is possible on the HP 1630G, also used at Apple. Also, the 
 16500 works just like the 1650A for a lot of things.
 
 You can call the HP Customer Information Center at 1-800-752-0900,
 extension779E.  Their catalog says that if they don't have an answer
 they'll put you in touch with someone who does.
 
 Also, the software for using these analyzers with the 65816 or 65C02
 is available direct from us at Apple along with instructions for 
 wiring the PODs accordingly. There are a couple of San Francisco 
 area companies who rent these machines (see below).
 
 If you prefer to rent or lease the models, HP should be able to put
 you in contact with a vendor in your area that could do this.
 Engineers at Apple using these systems are very happy with them and
 generally prefer the touch screen capability of the 16500 model.
 (Hey, this isn't an endorsement, it's just information!)
 
 Also, an in-circuit emulator for the IIe and IIgs is manfactured by
 the Western Design Center, Inc.  At the 1989 A2-Central Apple II
 Developer's conference Andrew Hall demonstrated this ICE system,
 called the Toolbox Design System, and stated that they would be open 
 to rentals of the system.  You can contact The Western Design Center
 at 2166 East Brown Rd., Mesa, AZ 85213,  (602) 962-4545.
 
 These HP Logic Analyzer units should be rentable through the 
 following companies:
 
    Continental Resources       McGrath RentCorp
    1575 McCandless Drive       2500 Grant Avenue
    Milpitas, CA  95035         San Lorenzo, CA  94580
    (408) 263-1775              (415) 276-2626
 
 (Thanks to Dan Strnad of DTS for this information on HP logic 
 analyzers)
