







                             GSBug is Your Friend

                           (a quick intro to GSBug)
                               by:  Tim Swihart



So, you just got GSBug installed for the first time and don't have a clue how
to use it.  Sure, you could call APDA (1-800-282-2732) and order the complete
package (part #A0037LL/A, price $30), but you're not sure if GSBug will really
help you find those nasty bugs in the Apple IIGS software you're developing.
Well, from the next paragraph until the end of this file, I'll present a quick
introduction to some of the reasons why GSBug is a "MUST HAVE" tool for all
IIGS developers.  It doesn't matter what language you program in, or which
environment you use, GSBug is the key to tracking down and exterminating those
nasty bugs that make your software look shabby.


Installation:

Before we can really get into it, you need to install GSBug and the
GSBug.Templates file and reboot your IIGS.  If you only have one computer,
then print this file and continue reading from the printout.  GSBug is an INIT
with the file name "GSBug.INIT" - install it by copying this file into your
boot disk's SYSTEM/SYSTEM.SETUP folder.  Copy the "GSBug.Templates" file into
the same folder.


Care & Feeding of GSBug:

Now that everything is installed, reboot your computer.  No need to launch any
particular application just yet, I have to explain the various parts of
GSBug's screen and I want to cover a few basic GSBug commands before we go bug
hunting.  I'll assume you're running the Finder right now, but it really
doesn't matter a whole lot what application is running, as long as it is a
16-bit application (i.e.:  a true IIGS desktop application).

You can pop into GSBug at any time (assuming interrupts aren't disabled) by
pressing OPEN APPLE-OPTION-CONTROL-ESC  (if you're having troubles remembering
all of those keys at once, just think of it as the same keys that you use to
get to the built-in control panel plus the OPTION key).  You'll be presented
with a rather busy-looking 80-column text screen.  (there's a screen dump
right below this paragraph - I told you it was busy-looking screen)










------ cut here to start the screen dump ------

KEY BRK  DebugD  K/PC   B   D    S    A    X    Y    M   Q   L  P  nvmxdizc e d
00  o d   9500  FD/688D FD 2500 1FE0 0000 4D95 0044  0C  BE  1  03 00000011 0 0

1FF2:60  00/0000:  BE '>'  00/0000-00-00
1FF1:43  00/0000:  BE '>'  00/0000-00-00
1FF0:FE  00/0000:  BE '>'  00/0000-00-00
1FEF:01  00/0000:  BE '>'  00/0000-00-00
1FEE:37  00/0000:  BE '>'  00/0000-00-00
1FED:0C  00/0000:  BE '>'  00/0000-00-00
1FEC:00  00/0000:  BE '>'  00/0000-00-00
1FEB:4D  00/0000:  BE '>'  00/0000-00-00
1FEA:7A  00/0000:  BE '>'  00/0000-00-00
1FE9:C0  00/0000:  BE '>'
1FE8:00  00/0000:  BE '>'  E1/0000.000F-T
1FE7:2C  00/0000:  BE '>'  00/0000.0000-?
1FE6:00  00/0000:  BE '>'  00/0000.0000-?
1FE5:E0  00/0000:  BE '>'  00/0000.0000-?
1FE4:6A  00/0000:  BE '>'  00/0000.0000-?
1FE3:B4  00/0000:  BE '>'  00/0000.0000-?
1FE2:62  00/0000:  BE '>'  00/0000.0000-?
1FE1:DA  00/0000:  BE '>'  00/0000.0000-?
1FE0:FD  00/0000:  BE '>'  00/0000.0000-?

:GSBug V1.5b9 w/Glue Support -(C)1986-90 Apple Computer,Inc.

------ cut here to end the screen dump ------


Top Two Lines:

The first two lines of the screen show the contents of various registers.  The
top line of the screen starts off with "KEY  BRK  DebugD" - those are headings
for the items in the second line of the screen.  The meanings of those headings
(and the items under them) are:

Heading     Meaning
-------     -------------------------------------------
KEY         Modifiers used to separate debugger keys from application keys
BRK         (beyond the scope of this quick intro - see the manual)

DebugD      Debugger's direct page (1K in size) - in bank $00
K/PC        K=program bank, PC=program counter 

B           app's data bank
D           current direct page in bank zero 

S           current stack pointer
A           accumulator's value

X           X register's value
Y           Y register's value

M           machine state register's value
Q           quagmire register's value

L           Language card bank
P           processor-status register's value

nvmxdizc    bits that make up "P" (n=negative, c=carry, etc)
e           emulation mode flag
d           disassembly mode flag (0=recognize SEP & REP during "L"isting)


If you want more information on a specific register's meaning then look it up
in the IIGS Hardware reference manual, the GSBug manual, or any good book that
covers the IIGS's internal hardware.  Any of these register's values can be
changed - we'll show how to do that in a few paragraphs or so...


The Left-Hand Side:

The next major area of the screen is the 4-digit column of numbers running
down the far left side.  There is a colon on each line after the fourth
digit, and then there is a column (two digits wide) of numbers.  All of these
numbers are in hex and this area is the stack.  The four digit column, the
colons, and the two digit column are collectively known as the "stack
subdisplay area" - remember that, there's a test at the end of this file.
The column on the left of the colon is the address of the stack and the
column on the right (the two digit column) are the values on the stack.
The bottom-most four digit stack address is the "top" of the stack (i.e.:
if your app pushes anything on the stack, that's the address it would wind
up at).  As you step through your application (we'll show how in a minute,
patience...) the stack will scroll upwards as things are pushed onto it and
downwards as things are pulled off of it.


The Not-So-Left-Hand Side:

The next major area should be a column of "00/0000:  BE '>'" known as the
"RAM subdisplay area".  This area is used to display any 19 memory locations
that you want to keep an eye on.  The value at each of those locations is
shown in hex (that's what the "10" means - location 00/0000 contains hex "BE"
when I wrote this) and in ASCII (the ASCII version is between the single quote
marks, i.e.:  the "'>").  It is possible to have this subdisplay show a
two-byte or a three-byte value instead of the one-byte value.  You lose the
ASCII display if you opt for the 2 or 3 byte values.

After I finish explaining the rest of the screen, I'll come back and describe
how to change these 19 "windows on memory" to look at what you want to monitor.


The Center Part:

The next major area of the screen is the 9 lines of "00/0000-00-00", better
known as the "Breakpoint subdisplay" (they're on the top half of the screen).
GSBug lets you set up to 17 breakpoints in your program (not counting BRK
instructions you imbed in your program yourself).  Curious about how you set
17 break points when there are only 9 lines in this section?  Did I mention
that APDA stocks the manual (which has full details)? <grin>  Seriously, you
can "extend" the breakpoint subdisplay by shrinking the section under it
(which we haven't described yet).  For the purposes of this quick intro, I'm
not going to show how to do this (you need some kind of reason to get the
manual).  I'll just describe this area and later show how to set up to 9 break
points.

The "00/0000" part of the breakpoint subdisplay is obviously an address - in
fact, it's the address you want to break on.  The next part "-00-" is the
trigger value.  GSBug is smart enough to count how many times an address has
been executed and break on a certain number (i.e.:  put a "03" here and GSBug
will break the third time that address is executed).  The last part of this
area is the running count - this is how GSBug lets you know how many times
that area has been executed (rather than leave you wondering, it tells you and
you can be ready for the break).  You set the address and trigger portions and
GSBug sets the count portion.


The Bottom Part of the Center Part:

The bottom half of the center of the screen is known as the "Memory
Protection Subdisplay" and looks starts off with "E1/0000.000F-T".  This
area can be expanded (or shrunk) by trading lines of this area for lines of
the one above it (the "Breakpoint subdisplay").  If you want to know how to
do this, read the manual from APDA, it's big (roughly 150 pages) and I'm not
retyping all of it here!  <grin>

The "E1/0000.000F" is the address range starting at E1/0000 and ending at
E1/000F.  The "T" at the end means that this range of memory is protected from
code tracing.  If you're tracing through your code and it jumps (JSR's, JSL,
whatever) into this range of memory, then the code in this range will NOT be
traced - it will be executed at full speed instead.

There are two other options for code protection ("W" and "H").  They are beyond
the scope of this quick tutorial (c'mon, I'm only trying to cover the basics
here).


Where You Type Commands:

The bottom line on the screen is the command line subdisplay (catchy name,
eh?).  When you first enter GSBug, this line will contain the copyright
message and version number for GSBug (unless you've used the DebugStr or
SetMileStone "tool" calls to change this string).  As soon as you press a
key, the copyright message vanishes and your keypress shows up next to the
blinking cursor.  This is where you'll type various commands to make GSBug
help you get the kinks out of your software.


What's the Big Blank Spot For?:

The big blank area towards the far right of the screen is officially known as
the "disassembly subdisplay" (it's one of the big reasons you're using GSBug -
even if you don't know it yet).  As you single-step through your software,
trace through it, or just list areas of memory this area will show you the
disassembled version of your program.  One of the really slick things about
this area is that it's smart enough to know about the names of GS/OS calls and
Toolbox calls - so you see things like "_CheckUpdate" instead of "JSL E10000".
That makes if VERY easy to line up pieces of your source with the disassembly
if you're working in a high-level language.  It also makes it a LOT easier to
see what you're doing!

GSBug also knows about the alternate Toolbox entry point (E10004) and will
display those as tool calls also.  The leading underscore ("_") lets you know
that GSBug is substituting the tool's name for you.  If the tool call is being
made through "glue", then the underscore is preceded by an asterisk ("*").

If you've ever used the built in "monitor" (I'm not talking about your RGB
monitor, I'm talking about the disassembler that's been built into Apple II's
for a LONGGGGGGG time now), then you'll be able to quickly figure out that the
left-most part of the disassembly subdisplay is the address, the inside column
are the hex byte making up the code about to be disassembled, and the
right-most part is the disassembled version of your software.


Your First GSBug Command:

OK, you now know what all of the various areas of this rather busy-looking
screen are for, so let's get down to business!  The first thing to do is press
the "L" key (upper or lower case work the same these days) and then press
RETURN.  This will fill the disassembly subdisplay with 19 lines of
disassembled code (which 19 lines were disassembled really don't matter yet).
Study it until you can tell at a glance which parts are the address, which
parts are the hex bytes, and which parts are the disassembled code.

Type "L" and press RETURN again - you get the next 19 lines of memory (see,
told you it was a lot like the built-in monitor).

Now, let's do something a tad more useful...  Press the "S" key and RETURN
(you just told GSBug to start single-stepping through your application).  Be
careful what keys you press while in the single step mode - lots of
weird-looking things can happen (they're all normal, but if you don't expect
them you can get confused).  For now, ONLY press the keys this tutorial tells
you to.  If you can't wait and just HAVE to bang on all of the various keys,
then go ahead - reboot once you've totally confused yourself, pop back into
GSBug and catch up with the rest of the folks reading this.

To tell GSBug to execute the highlighted instruction, press the SPACE BAR one
time.  Heck, press it several times so that you get a bunch of lines of
disassembled code on the screen.  Notice that the code scrolls up and the
"highlighted" area stays in the same place?  Notice it's kind of close to the
bottom of the screen?  Later I'll tell you how to move it up higher.

Press the ESC key.  That takes you out of single-step and returns you to the
command line.  Press "S" and RETURN again to restart single stepping.  Notice
that the lines ABOVE the highlighted area have been erased?  Remember that -
if you halt single-stepping and need some piece of info above the highlighted
area, then write it down because it'll be wiped out when you restart
single-stepping (or when you do any of a bunch of different things).  If you
have your printer connected to slot 1, then you can print GSBug's screen using
the "P" command (press "P" and RETURN - be sure you're NOT single-stepping
when you do this, "P" only prints from the command line).


Lock a Tractor Beam onto Them Sulu!:

Want an easy way to have the computer step through source for you without
having to bang again and again on the SPACE BAR?  Start single-stepping
("S" and RETURN), then press RETURN again.  VRRRROOOOMMMMMM!  Can't read all
the stuff flying by?  No sweat, press SPACE BAR and you'll be back to
single-stepping.  Pressing the RETURN key a second time kicked GSBug into
"Trace" mode.

Trace actually has two speeds, the default is fast (we like to test
developers' speed reading skills).  To kick TRACE into low gear, press the
left arrow key.  If you're in single-step mode, then you won't see the speed
change (after all, it affects TRACE, not SINGLE-STEP), but fear not brave
developer, the speed change has been made.  Press RETURN again (to be sure
you're in TRACE mode) and press the left arrow key (if you didn't a few lines
ago) to kick TRACE into low gear.  Want to get back into high gear?  Press the
right arrow key (sneaky, eh?).


RED ALERT!:

Do _NOT_ press the down arrow key while TRACING or single-stepping (unless
you know what you're doing).  The down arrow key tells GSBug to SKIP the
highlighted instruction!  This is a great way to step over BRK instructions,
but it's not a real smart thing to do at random while TRACING through an
application (randomly skipping an instruction generally results in a crash).


Move That Line Up:

If you want to raise the highlighted line within the disassembly subdisplay,
then press ESC (to get back to the command line) and type "SET"  (don't type
the quotes, ok?) and press RETURN.  The up and down arrows now control the
vertical position of the highlighted bar within the disassembly subdisplay.
Position the bar where you want  it and press ESC.  That position will be
remembered until the next time you move it or until you reboot (then it goes
back to the default position).  The manual for GSBug tells you how to save
this new position to a configuration file (it also tells you that pressing the
left and right arrow will move the stack subdisplay up and down, and that
pressing a number less than eight will change the slot used to print the
screen).


Reaching the Breaking Point:

Alright, time for some fancy stuff!  The next couple of sections will assume
you were running the IIGS Finder when you popped into GSBug (other apps will
work just fine, but why be difficult?).  GSBug will let you break on any tool
call (or calls) that you specify, so let's set a few tool breaks and learn how
to use this feature.

From GSBug's command line (press ESC if you're still stepping or tracing),
type "settbrk _sysbeep" and press RETURN.  If GSBug beeps at you instead of
accepting this line, then you didn't type it right (there are two t's in
"settbrk" and don't type the quotes).  Type "settbrk #090E" and press RETURN.
You just added two tool calls to GSBug's list of tools to break on.  The first
one was added by naming the tool to break on ("_sysbeep") and the second one
was added by specifying the tool's number ("#090E").  This lets you set tool
breaks regardless of whether you know the tool's name or number.

Type "showbrks" and press RETURN to see the complete list of tool breaks that
GSBug has been told about.  Notice that the left hand side of the screen now
implies that you can set breaks on GS/OS calls?  That's because you can!
GS/OS breaks have to be set by number (not by name).

All we've done so far is make a list of tools for GSBug to break on.  We
haven't actually told GSBug to break on them, that requires a separate
command.  Type "tbrkin" to tell GSBug to break on all of the tool calls in
its list.  Now, when either a call to SysBeep or a call to NewWindow
(tool $090E is NewWindow) is made, we'll be dropped back into GSBug.


Oh Yeah?  Prove It!:

Make sure you're at GSBug's command line (press ESC if you aren't).  Type "R"
and RETURN.  This resumes full execution of your application.  To test the
tool breaks we just set, we need to force the Finder (or whatever app you
stubborn folks decided to use instead of the Finder) to make a call to
NewWindow and/or to SysBeep.  Double click on a disk icon, get info on a file,
open a folder, open a desk accessory, etc to get the Finder to open a new
window.  Notice that you land in GSBug?

Press "S" and RETURN to enter single-stepping.  Notice that the highlighted
instruction is "NewWindow".  Ah, the tool break works.  Now, press SPACE BAR
to execute the NewWindow call, press ESC to stop single-stepping, and type "R"
and RETURN to resume running the Finder.  (if we didn't bother to single step
across the NewWindow call, we would just fall right back into the debugger
since we have a break point set on that call).


Take it Out, Wise Guy!;

Tired of falling into GSBug everything a new window is opened?  There are
several ways to remove tool breaks.  The easiest way is to type "tbrkout" to
stop breaking on the listed tool calls without trashing the list.  Typing
"tbrkin" makes GSBug start breaking on them again.

To clear the list of tool breaks, either type "clrtbrk _sysbeep" (to remove
the sysbeep break we put in earlier) and repeat that for "_newwindow" or wipe
the all out with "clralltbrks".  I'll let you decide...


Cheap Trick #1:

Being able to break into the debugger based on a tool call is VERY handy!  But
what if you want to see the stack being set up BEFORE your code gets all the
way down to the tool call itself?  After all, if you're not putting enough
parameters on the stack (or too many), then breaking on the tool call itself
is too late to watch the stack being built.  There's an easy solution for
this - stick a SysBeep call in your source ABOVE the tool call you really
want to break on and set a tool break on SysBeep.  This will let you
single-step through the stack setup for the call you're really interested in.
OK, so it's a cheap trick, but it's darned effective...


I Don't Like My Registers:

Remember earlier I mentioned that you can change the values of the various
registers from within GSBug?  This lets you change values that are about to be
pushed on the stack and do all kinds of neat things.  You're sharp, so I won't
bore you with all the things this lets you do, I'll just cut right to the
description of HOW to do it...

To change the accumulator's value, type "a=value" on the command line.
Replace "value" with the hex value you want  to stuff into the accumulator.
Type "x=value" to set the x register, "y=value" to set the y register, etc.
You can't type "a=x" to set the accumulator to the value in the x register,
but since you can see the x register's value, this isn't that big of a loss.


Cheap Trick #2:

If you accidently SKIP an instruction that you didn't mean to (and you haven't
executed any more since then), you can "unskip" it by exiting single-step
mode, then type "pc=value" where "value" is the address (all three bytes just
to be safe) that the skipped instruction is at.  Press RETURN and then resume
single-stepping (notice that you're back at the skipped instruction now).


Cheap Trick #3:

Fudging the program counter (pc=value) will let you push extra info on the
stack in cases where you didn't push enough for a call.  Be careful with
this - you may need to set the accumulator before re-executing an
already-executed PHA and you could totally trash the stack if you're not
paying attention.  One place this is handy is to compensate for passing a
WORD instead of a LONG (easy to do with C when you're dealing with resource
ID's).  If you don't understand this trick, don't use it!

A minor modification on this stunt is (obviously) to pull extra bytes OFF of
the stack in cases where you left something on there that shouldn't have been
left on.  Once you spot problems like too much or too little data on the
stack,  FIX YOUR SOURCE CODE AND RECOMPILE IT!!!!  You don't really want to
have to find this bug a second time do you?


Cheap Trick #4:

GSBug is a lot like the monitor in certain respects.  That means many of the
commands you're used to from the monitor will work under GSBug.  Setting
values in memory under GSBug is done just like it is under the monitor
(i.e.:  address : value1 value2 value3 value4 ...).   addressT and RETURN
starts tracing at the memory location specified by "address".  addressS and
RETURN starts single-stepping at the memory location specified by "address".
addressL and RETURN lists 19 lines of disassemby starting at the memory
location specific by "address".  You can even use the built-in mini assembler
if you want (type "asm" and RETURN).


Peering Into Memory:

The 19 "windows on memory" can be used by typing "mem" and RETURN on the
command line.  This puts the cursor on the far right of the first line in the
RAM subdisplay area.  Type the address you want to watch and press RETURN.
That will move you to the next line (so you can set the address for the second
memory location).  If you want to see two bytes starting at that address,
press "P".  To see three bytes, press "L".  "Z" toggles between direct-page
and absolute addressing, ":" toggles between direct, 2-byte indirect, and
3-byte indirect addressing.  Press "?" for more info.

This provides a nice way to look at variables in memory, dereference
pointers/handles, etc.  When the contents of any "peered into" location
changes, the corresponding line on GSBug's screen will change also.


Cheap Trick #5:

(this one's actually not cheap, it's pretty danged useful!)  While
single-stepping or tracing, you can see other "screens" by pressing various
keys (this accounts for the weird effects I alluded to earlier).  Press "S" to
see the SHR screen (i.e.:  your desktop application's desktop), "D" to see the
double hi-res screen, "T" to see the text screen, "8" to see 80-column
display, "4" to see 40-column display, "H" to see the Hi-Res screen, "L" for
the Lo-Res screen, and ESC to exit single-stepping.  This lets you see your
application's screen instead of GSBug's screen (makes it a LOT easier to
debug your apps when you can see their screens...).


Study For The Test:

I told you earlier that there would be a test at the end of this tutorial, so
now's your chance to kick back and study a bit.  So far, we've covered what
the various parts of GSBug's screen mean, how to disassemble pieces of memory
(using "L"), how to single-step and trace (at different speeds) through your
application, how to set, use, and clear breakpoints, how to display various
screens, and how to set up the RAM subdisplay area.


Don't Touch That Dial!:

The material covered so far gives you a decent foundation to draw upon as you
hunt bugs in your own software.  We've only lightly touched on what GSBug can
really do (I'm not typing all 150 or so pages of the manual into this
"introduction" to GSBug).  GSBug offers a lot of power and capabilities that
should be learned by all developers.

Before I wrap up this tutorial I want to cover the use of templates and
describe some of the new features in GSBug v.1.5b9 that aren't described in
the APDA documentation (because we just added the features and haven't
replaced APDA's master manual yet).


Templates By Jim:

GSBug provides an easy way for you to view portions of memory through
templates.  This allows you to "see" the data structures in memory just
like they appear in the documentation (i.e.: see them divided into the
various fields).  The GSBug.Templates file that you were supposed to
have placed in the SYSTEM/SYSTEM.SETUP folder of your boot disk contains
a complete set of templates for our latest interface files.  One of the
Apple II Developer Technical Support Engineers put these templates together
(and came up with a pretty neat way to build in a "help system" - so tell
Jim "thanks" next time a template bails you out of a jam).

GSBug does NOT automatically load those templates (boy, that would sure eat
memory - having the template auto-loaded!).  You have to tell GSBug to load
them (and you can unload them later).  To load these templates, just type
"loadtemp */system/system.setup/gsbug.templates" and press RETURN.  Keep
trying until you get it right - it does work (watch out for typos, etc).

To view a piece of memory with a template simply determine the starting
address of the template.  The starting address can be found in a number of
ways - you can dereference a pointer that you just pushed on the stack, etc.
Then, type an underscore, the type of structure you want used, a blank space,
and the starting address (don't forget the bank).  (i.e.:  if you know you
have a graf port starting at location 06/15E4, then type:  "_grafport 06/15E4"
and press RETURN.

To use the built-in template help system that Jim came up with (thanks Jim!),
just type: "_template 0" and press return.  This will give you a list of all
the categories of help you can get more info on (such as ADB, FONTS, etc).
The categories are grouped by toolbox manager.  To get details on a particular
toolbox manager's tool calls, type "_toolmgrname 0" and press RETURN
(replace "_toolmgrname" with the name of any tool manager - lead with an
underscore or it won't work).  (i.e.: "_quickdraw 0" for details on QuickDraw
data structures)  For more details, read the separate documentation file on
using the templates.

If you want to create your own custom templates, then read the GSBug manual
(pages 86-88) or decipher the templates in the GSBug.Templates file.  To
unload the templates (and free up the memory they're eating), type "killtemp"
and press RETURN from GSBug's command line.


The New Stuff:

As if all of this weren't reason enough to use GSBug, the man behind this
jewel recently added a couple more reasons (he calls them features).  The two
most important ones (in my opinion) are "SetMileStone" and "DebugStr".  Both
of these are fake tool calls that the debugger sees, intercepts, and acts on.  

SetMileStone simply changes the copyright message to be a string of your
choice.  If you're having a problem figuring out where your code was last at
before it jumped off into the weeds, then sprinkle SetMileStone calls into
your source code (with different strings on each of course).  Then, when your
app chokes and dies, you'll be presented with the text from the last
SetMileStone that was executed.


Cheap (and short) Trick #6:

If you get really fancy, you can build the strings on the fly and imbed the
values of key variables into them to further simplify locating the bug.


Calling all Debuggers:

Several "tool calls" have been added to GSBug.  These are called just like a
regular tool call, except they're intercepted (and acted on) by the debugger.
Do _NOT_ leave calls to these debugger tools in your software when you ship it
to customers!  Why?  Because making these calls on a system that doesn't have
GSBug installed makes a real mess...

The new calls are SetMileStone, DebugStr, DebugVersion, and DebugStatus.
SetMileStone simply changes the debugger's string and lets your app keep
running.  DebugStr works like SetMileStone (i.e.: changes the copyright string
to something with info about your application) except it dumps you immediately
into GSBug.  DebugVersion and DebugStatus act just like normal version and
status calls for regular tool sets - they simply allow you to verify what
version of the debugger is running before you try to make any debugger tool
calls.

The tool numbers and parameter lists for these calls are:

Name            Tool #  Parameter (returns)
--------------  ------  ---------------------------------------------------
DebugStatus     $06FF   (non-zero = true, ToolLocator error it not loaded)
DebugStr        $09FF   pointer to Pascal-style string
DebugVersion    $04FF   ($159F for v.1.5B9)
SetMileStone    $0AFF   pointer to Pascal-style string


Want More Info?

Contact APDA and order the full package (you have a newer version of GSBug
with this file, but APDA has the full manual).  You could also try to
persuade me to add more detail to this file in the future (it's long enough
for the first release).  Order it by calling APDA (1- 800-282-2732) and
asking for part #A0037LL/A (the price is $30).
