[comp.binaries.apple2] tn.iigs.071

mjohnson@APPLE.COM (Mark B. Johnson) (12/02/89)

This message  was originally  submitted by  mjohnson@APPLE.COM to  the APPLE2-L
list  at BROWNVM.  If  you simply  forward  it back  to the  list,  it will  be
distributed with the paragraph you are now reading being automatically removed.
If you  edit the  contributions you  receive into  a digest,  you will  need to
remove this  paragraph before mailing the  result to the list.  Finally, if you
need more information from the author of this message, you should be able to do
so by simply replying to this note.

----------------- Message requiring your approval (145 lines) -----------------
Apple II
Technical Notes
_____________________________________________________________________________
                                                  Developer Technical Support


Apple IIGS
#71:    CDA Tips and Techniques

Written by:    Dave Lyons                                       November 1989

This Technical Note presents tips and techniques for writing Classic Desk
Accessories.
_____________________________________________________________________________


Reading the Keyboard

For a CDA that runs only under GS/OS, the Console Driver is the best choice
for reading from the keyboard.  Other CDAs have two cases to deal with:  the
Event Manager may or may not be started.  The Text Tools can read the keyboard
in either case, but you should avoid using the Text Tools whenever possible
(see Apple IIGS Technical Note #69, The Ins and Outs of Slot Arbitration).

You can call EMStatus to determine whether the Event Manager is started.  When
it is, you can read keypresses by calling GetNextEvent.  When the Event
Manager is not started, you can read keys directly from the keyboard hardware
by waiting for bit 7 of location $E0C000 to turn on.  When it does, the lower
seven bits represent the key pressed.  Once you've detected a keypress, you
need to write to location $E0C010 to remove the keypress from the buffer.

Alternatively, you can use IntSource (in the Miscellaneous Tools) to
temporarily disable keyboard interrupts and then read the keyboard hardware
directly.  Be sure to reactivate keyboard interrupts if, and only if, they
were previously enabled.


Just One Page of Stack Space

CDAs normally have only a single page of stack space available to them (256
bytes at $00/01xx).  Your CDA may or may not be able to allocate additional
stack space from bank 0 during execution.  The following code (written for the
MPW IIGS cross-assembler) shows a safe way to try to allocate more stack space
and to switch between stacks when the space is available.

If ProDOS 8 is active, your CDA will not be able to allocate additional space
(and there is no completely safe way to "borrow" bank 0 space from the ProDOS
8 application).


HowMuchStack gequ $1000             ;try for 4K of stack space

start      phd
           phb
           phk
           plb

           pla                      ;Space for result
           pha
           PushLong #HowMuchStack
           pha
           _MMStartUp
           pla
           ora    #$0f00            ;OR in an arbitrary auxiliary ID
           pha
           PushWord #$C001          ;fixed, locked, use specified bank
           PushLong #0              ;(specify bank 0)
           _NewHandle
           tsc
           sta    theOldStack
           bcs    NoStackSpace      ;still set from _NewHandle
           tcd
           lda    [1]
           tcd
;          clc                      ;carry is already clear
           adc    #HowMuchStack-1
NoStackSpace pha
           ldx    #$fe
keepStack  lda    >$000100,x
           sta    stackImage,x
           dex
           dex
           bpl    keepStack
           pla
           tcs
           jsl    RealCDAentry      ;carry is clear if large stack available
           php
           php
           pla
           sta    pRegister
           sei
           ldx    #$fe

restoreStack lda  stackImage,x
           sta    >$000100,x
           dex
           dex
           bpl    restoreStack
           lda    theOldStack
           tcs
           lda    pRegister
           pha
           plp
           plp

           lda    1,s
           ora    3,s
           beq    noDispose
           _DisposeHandle
           bra    Exit
noDispose  pla
           pla


Exit       plb
           pld
           rtl

pRegister  ds     2
theOldStack ds    2
stackImage ds.b   256

When this routine calls RealCDAentry, the carry flag is set if no extra stack
space is available.  If the carry is clear, the additional stack space was
available and the direct-page register points to the bottom of that space.

RealCDAentry bcs  smallStack        ;if c set, only 1 page of stack is
                                    ;available
                                    ; put something interesting here
           rtl

smallStack _SysBeep
           rtl

Note that interrupts are disabled while the page-one stack is being restored;
they are re-enabled (if they were originally enabled) only after the stack
pointer is safely back in page one.


Further Reference
_____________________________________________________________________________
    o    Apple IIGS Toolbox Reference, Volume 1
    o    GS/OS Reference
    o    Apple IIGS Hardware Reference
    o    Apple IIGS Technical Note #69, The Ins and Outs of Slot Arbitration