[comp.sys.apple] Apple // Technotes question

mjohnson@Apple.COM (Mark B. Johnson) (02/28/89)

In article <440@studsys.mu.edu> jetzer@studsys.UUCP (jetzer) writes:
>Does anyone know the status of the rest of the Apple // Technotes?  I have
>downloaded all of the ones at Brownvm, but there are several missing, namely:
>
>    tn.gsos.001
>    tn.misc.002
>    tn.pasc.001, 002, 003, 005, 006, 007, 008, 009, 010, 011, 013
>    tn.pdos.004, 005, 009, 010
>
All of the Notes have been sent out and we are currently checking with the
different sites to make sure they have a complete set.  The only things
which have not yet been sent are the IIe graphics.

Of the files listed, Pascal Notes 1-3,5-11, and 13 do NOT exist.


Mark B. Johnson                                            AppleLink: mjohnson
Developer Technical Support                         domain: mjohnson@Apple.com
Apple Computer, Inc.         UUCP:  {amdahl,decwrl,sun,unisoft}!apple!mjohnson

"You gave your life to become the person you are right now.  Was it worth it?"
                                                         - Richard Bach, _One_

delaneyg@wnre.aecl.CDN (02/28/89)

>Organization: Marquette University - Milwaukee, Wisconsin

Does anyone know the status of the rest of the Apple // Technotes?  I have
downloaded all of the ones at Brownvm, but there are several missing, namely:

    tn.gsos.001
    tn.misc.002
    tn.pasc.001, 002, 003, 005, 006, 007, 008, 009, 010, 011, 013
    tn.pdos.004, 005, 009, 010

Are these still "in the process" of being sent out?  (Although it has been
a while since I received any technotes in the mail...)

-- 
Mike Jetzer
"Hack first, ask questions later."

==================
Mike  I have a full set here.  First there are gaps in the pascal notes if you
read the introduction you will see what is supposed to be their.  What can you handle in the way of compressed files can you handle shrinkit and binscii.

Grant Delaney

asd@mentor.cc.purdue.edu (Kareth) (02/28/89)

In article <26446@apple.Apple.COM> mjohnson@Apple.COM (Mark B. Johnson) writes:
>All of the Notes have been sent out and we are currently checking with the
>different sites to make sure they have a complete set.  The only things
>which have not yet been sent are the IIe graphics.
>
>Of the files listed, Pascal Notes 1-3,5-11, and 13 do NOT exist.
>
>Mark B. Johnson                                            AppleLink: mjohnson
>Developer Technical Support                         domain: mjohnson@Apple.com
>Apple Computer, Inc.         UUCP:  {amdahl,decwrl,sun,unisoft}!apple!mjohnson

That's odd, I have Pascal.010 sitting over in a directory right now, downloaded
off 35.1.1.43 (Todd's site).  Ya fibbing us?  Or maybe my copy got pulled outa
mini hole in space during an ftp transfer.  Never know...:-)


And if 1-3,5-9,11,13 don't exist, then why aren't the notes numbered with
1-6?  Seems kinda silly to number em as if there existed some other technotes.

kareth.

delaneyg@wnre.aecl.CDN (02/28/89)

Here is what you are missing note PASC 1,2,3,5,6,7,8,9,11,13 do not exist


==================

Apple II
Technical Notes
_____________________________________________________________________________
                                                  Developer Technical Support


Apple IIGS
#1:    How to Install Custom BRK and /NMI Handlers

Revised by:    Jim Mensch & Jim Merritt                         November 1988
Written by:    Jim Merritt                                       October 1986

This Technical Note discusses a method to install a custom debugger or 
debugging stub within the Apple IIGS system.
_____________________________________________________________________________


Introduction

This Technical Note discusses a particular method that you may use to install 
a custom debugger or debugging stub within the Apple IIGS system.  The 
strategy and techniques described here should be of special interest to those 
who wish to operate the Apple IIGS as a slave to a debugger that resides on 
another machine.

Typically, an interrupt handler should pass control to a debugger or debugging 
stub whenever the processor executes a BRK instruction, or when an interface 
card triggers a non-maskable interrupt (/NMI).  To simplify the design of the 
debugger, the Apple IIGS Monitor should be responsible for the following:

o    saving all machine state information in locations that the 
     debugger can access
o    setting the machine to a known state
o    passing control to an arbitrary debugger
o    restoring the remembered machine state upon regaining control from 
     the debugger
o    resurrecting the interrupted process

The Monitor is designed to provide all of the services above for the BRK 
instruction, but only the third for /NMI interrupts.  In addition, Apple II 
family systems are generally intolerant of /NMI interrupts.  In this Technical 
Note we concentrate on the means by which you can install your own custom BRK 
handler, although we also briefly examine /NMI considerations.


Dealing With BRK

A BRK interrupt handler may reside at any address in memory.  The Monitor 
passes control to your code by executing a JSL instruction; consequently, your 
routine must terminate with an RTL instruction.  To install your BRK handler, 
simply load it into memory, call the Miscellaneous Tool Set GetVector routine 
to fetch the address of the current BRK handler, put that address in a safe 
place, then supply the address of your handler to the Miscellaneous Tool Set 
SetVector routine.  To deactivate your handler, restore the previous handler 
address using SetVector as follows:

;
;  NOTE: All Listings are in APW assembler format.
;

INSTMYBRK    anop                  ;Example code to install user's BREAK handle
r.
             PushLong #0           ;Space for function call result.
             PushWord #$1C         ;We want BREAK vector address.
             _GetVector            ;Make the call using standard macro.

;  The stack now holds address of the current break handler.
             PLA                   ;Get and save low word of address...
             STA    SBRKADR
             PLA                   ; ...and now high word.
             STA    SBRKADR+2
             PushWord #$1C         ;We want to change BREAK vector address.
             PushLong #MYHANDLR    ;Address of user's BRK handler.
             _SetVector            ;Make the call using standard macro.

;  Custom handler is in place, now go off and do whatever we like...

DEACMYBRK    anop                  ;Example code to deactivate the BRK handler.
             PushWord #$1C         ;We want to change BREAK vector address.
             PushLong SBRKADR      ;The previous BRK handler address.
             _SetVector            ;Make the call using standard macro.

Upon entry to your code, the machine will be in eight-bit native mode.  
Specifically, the m and x bits will be set (forcing eight-bit accumulator, 
memory access, and index registers), the processor will be running at the 
normal (1 MHz) speed, all memory shadowing will be enabled, and both the 
direct page and data bank registers will be reset to zero.  The same 
conditions must hold when your BRK handler returns control to the Monitor.  
While your code is active, however, it is free to affect the machine state in 
arbitrary ways, including (but not limited to) widening the registers, 
increasing the clock rate, and disabling shadowing.  Before returning control 
to the Monitor, your break handler must also clear the processor's carry flag, 
as an indication that the BRK was indeed serviced by an external handler.  
(Note:  The default BREAKVECTOR points to a "no-op" handler that simply sets 
the carry flag to indicate that there is no external handler available, and it 
then executes an RTL.)

When a BRK occurs, the processor saves the machine's state in the BRK.VAR 
area, and you may obtain this address with the Miscellaneous Tool Set GetAddr 
routine as follows:

             PushLong #0           ; space for result
             PushWord #9           ; we want BRK.VAR address
            _GetAddr               ; make the call using standard macro

; The stack now holds the address of the BRK.VAR area, expressed as a long 
word (four bytes).


Coping With /NMI

Handling /NMI interrupts is, by far, a trickier proposition than fielding BRK 
instructions.  For example, the user-definable /NMI jump-vector, /NMI 
($0003FB), only has room in its three-byte JMP-absolute instruction for a two-
byte address.  Because of this size limitation, at least the "front end" of 
any /NMI handler must reside in bank $00.  In addition, the Monitor does not 
"condition" the system in any way before transferring control through the /NMI 
hook, so the system could be in native mode, emulation mode, or any hybrid 
mode (with any screen condition) upon entry to your handler.  (Note:  Although 
the 65816 processor provides for separate /NMI vector addresses in native and 
emulation modes, the Apple IIGS implementation of these two vectors pass 
control to the same user hook at $0003FB.)  The processor only saves minimal 
machine state information when an /NMI occurs; if the handler needs to 
preserve more than the program counter and status register (which are saved 
automatically), then it must do so explicitly.  Because the 65816 assumes any 
program running in emulation mode has its program bank register in bank zero, 
it will not save the program bank register for any program running in 
emulation mode outside of bank zero.  Code which runs in this manner will 
always crash if it makes any attempt to return from the interrupt.  Finally, 
/NMI interrupts can create havoc with disk access and other aspects of the 
system; consequently, the only way you can safely use /NMI interrupts is as a 
one-way "escape hatch" to emergency debugging code.

Here are some ground rules for /NMI interrupt handlers.

o    On entry, store any interesting registers or machine state in RAM 
     space owned by the handler.
o    Determine whether the processor is in emulation mode or native 
     mode.
o    Take appropriate action, depending upon the processor mode.
o    Under no circumstances try to return from the interrupt!  Restart 
     the system instead.

To install an /NMI handler, load it into some free RAM in bank $00, put the 
two-byte address currently at location /NMI+1 in a safe place, then replace it 
with the address of your handler.  To deactivate your handler (assuming 
nothing has yet invoked it), simply restore the previous handler address to 
/NMI+1.


Apple II
Technical Notes
_____________________________________________________________________________
                                                  Developer Technical Support


Apple II Miscellaneous
#2:    Apple II Family Identification Routines 2.1

Revised by:    Matt Deatherage & Keith Rollin                   November 1988
Revised by:    Pete McDonald                                     January 1986

This Technical Note presents a new version of the Apple II Family 
Identification Routine, a sample piece of code which shows how to identify 
various Apple II computers and their memory configurations.
_____________________________________________________________________________


Why Identification Routines?

Although we present the Apple II family identification bytes in Apple II 
Miscellaneous Technical Note #7, many people would prefer a routine they can 
simply plug into their own program and call.  In addition, this routine serves 
as a small piece of sample code, and there is no reason for you to reinvent 
the wheel.

Most of the interesting part of the routine consists of identifying the memory 
configuration of the machine.  On an Apple IIe, the routine moves code into 
the zero page to test for the presence of auxiliary memory.  (A IIe with a 
non-extended 80-column card is a configuration still found in many schools 
throughout the country.)

The actual identification is done by a table-lookup method.


What the Routine Returns

This version (2.1) of the identification routine returns several things:

o    A machine byte, containing one of seven values:
     $00 = Unknown machine
     $01 = Apple ][
     $02 = Apple ][+
     $03 = Apple /// in emulation mode
     $04 = Apple IIe
     $05 = Apple IIc

     In addition, if the high bit of the byte is set, the machine is a 
     IIGS or equivalent.  For all current Apple IIGS computers, the 
     value returned in machine is $84 (high bit set to signify Apple 
     IIGS and $04 because it matches the ID bytes of an enhanced Apple 
     IIe).
o    A ROMlevel byte, indicating the revision of the firmware in the 
     machine.  For example, there are currently five revisions of the 
     IIc, two of the IIe (unenhanced and enhanced), and two versions of 
     the IIGS ROM (there will always be some owners who have not yet 
     upgraded).  These versions are identified starting at $01 for the 
     earliest.  Therefore, the current IIc will return ROMlevel = $04, 
     the current IIGS will return ROMlevel = $02, etc.  The routine 
     will also return correct values for future versions of the IIGS, 
     as a convention has been established for future ROM versions of 
     that machine.
o    A memory byte, containing the amount of memory in the machine.  
     This byte only has four values--0 (undefined), 48, 64, and 128.  
     Extra memory in an Apple IIGS, or extra memory in an Apple IIe or 
     IIc Memory Expansion card, is not included.  Programs must take 
     special considerations to use that memory (if available), beyond 
     those considerations required to use the normal 128K of today's 
     IIe and IIc.
o    If running on an Apple IIGS, three word-length fields are also 
     returned.  These are the contents of the registers as returned by 
     the ID routine in the IIGS ROM, and they indicate several things 
     about the machine.  See Apple II Miscellaneous Technical Note #7 
     for more details.

In addition to these features, most of the addressing done in the routine is 
by label.  If you wish things to be stored in different places, simply 
changing the labels will often do it.


Limitations and Improvements

As sample code, you might have already guessed that this is not the most 
compact, efficient way of identifying these machines.  Some improvements you 
might incorporate if using these routines include:

o    If you are running under ProDOS, you can remove the section that 
     determines how much memory is in the machine (starting at exit, 
     line 127), since the MACHID byte (at $BF98) in ProDOS already 
     contains this information for you.  This change would cut the 
     routine down to less than one page of memory.
o    If you know the ROM is switched in when you call the routine, you 
     can remove the sections which save and restore the language card 
     state.  Be careful in doing so, however, because the memory-
     determination routines switch out the ROM to see if a language 
     card exists.
o    If you need to know if a IIe is a 64K machine with a non-extended 
     80-column card, you may put your own identifying routines in after 
     line 284.  NoAux is only reached if there is an 80-column card but 
     only 64K of memory.


How It Works

The identification routine does the following things:

o    Disables interrupts
o    Saves four bytes from the language card areas so they may be restored 
     later
o    Identifies all machines by a table look-up procedure
o    Calls 16-bit ID routine to distinguish IIGS from other machines of any 
     kind, and returns values in appropriate locations if IIGS ID routine 
     returns any useful information in the registers
o    Identifies memory configuration:
     o    If Apple /// emulation, there is 48K
     o    If Apple ][ or ][+, tests for presence of language card and returns 
          64K if present, otherwise, returns 48K
     o    If Apple IIc or IIGS, returns 128K
     o    If Apple IIe, tries to identify auxiliary memory
          o    If reading auxiliary memory, it must be there
          o    If reading alternate zero page, auxiliary memory is present
          o    If none of this is conclusive:
               o    Exchanges a section of the zero page with a section of code
 
                    that switches memory banks.  The code executes in the zero
                    page and does not get switched out when we attempt to
                    switch in the auxiliary RAM.
               o    Jumps to relocated code on page zero:
                    o    Switches in auxiliary memory for reading and writing
                    o    Stores a value at $800 and sees if the same value
                         appears at $C00.  If so, no auxiliary memory is
                         present (the non-extended 80-column card has sparse
                         memory mapping which causes $800 and $C00 to be the
                         same location).
                    o    Changes value at $C00 and sees if the value at $800
                         changes as well.  If so, no auxiliary memory.  If not,
                         then there is 128K available
                    o    Switches main memory back in for reading and writing
               o    Puts the zero page back like we found it
          o    Returns memory configuration found (either 64K or 128K)
o    Restores language card and ROM state from four saved bytes
o    Restores interrupt status
o    Returns to caller

SOURCE   FILE #01 =>ID2.1
 
0000:                1           lst   on
----- NEXT OBJECT FILE NAME IS ID2.1.OBJ                     
2000:        2000    2           org   $2000
2000:                3 ********************************************
2000:                4 *                                          *
2000:                5 *  Apple II Family Identification Program  *
2000:                6 *                                          *
2000:                7 *               Version 2.1                *
2000:                8 *                                          *
2000:                9 *              September, 1988             *
2000:               10 *                                          *
2000:               11 *  Includes support for revisions to IIc   *
2000:               12 *  firmware, and IIgs identification too   *
2000:               13 *                                          *
2000:               14 ********************************************
2000:               15 *
2000:               16 *
2000:               17 *  First, some global equates for the routine:
2000:               18 *
2000:        0001   19 IIplain   equ   $01           ;Apple II
2000:        0002   20 IIplus    equ   $02           ;Apple II+
2000:        0003   21 IIIem     equ   $03           ;Apple /// in emulation mo
de
2000:        0004   22 IIe       equ   $04           ;Apple IIe
2000:        0005   23 IIc       equ   $05           ;Apple IIc
2000:               24 *
2000:        0001   25 safe      equ   $0001         ;start of code relocated t
o zp
2000:        0006   26 location  equ   $06           ;zero page location to use
2000:               27 *
2000:        00FB   28 xce       equ   $FB           ;65816 XCE instruction
2000:               29 *
2000:        00AA   30 test1     equ   $AA           ;test byte #1
2000:        0055   31 test2     equ   $55           ;lsr of test1
2000:        0088   32 test3     equ   $88           ;test byte #3
2000:        00EE   33 test4     equ   $EE           ;test byte #4
2000:               34 *
2000:        0400   35 begpage1  equ   $400          ;beginning of text page 1
2000:        0800   36 begpage2  equ   $800          ;beginning of text page 2
2000:        0C00   37 begsprse  equ   $C00          ;byte after text page 2
2000:               38 *
2000:        C000   39 clr80col  equ   $C000         ;disable 80-column store
2000:        C001   40 set80col  equ   $C001         ;enable 80-column store
2000:        C002   41 rdmainram equ   $C002         ;read main ram
2000:        C003   42 rdcardram equ   $C003         ;read aux ram
2000:        C004   43 wrmainram equ   $C004         ;write main ram
2000:        C005   44 wrcardram equ   $C005         ;write aux ram
2000:        C013   45 rdramrd   equ   $C013         ;are we reading aux ram?
2000:        C016   46 rdaltzp   equ   $C016         ;are we reading aux zero p
age?
2000:        C018   47 rd80col   equ   $C018         ;are we using 80-columns?
2000:        C01A   48 rdtext    equ   $C01A         ;read if text is displayed
2000:        C01C   49 rdpage2   equ   $C01C         ;read if page 2 is display
ed
2000:        C050   50 txtclr    equ   $C050         ;switch in graphics
2000:        C051   51 txtset    equ   $C051         ;switch in text
2000:        C054   52 txtpage1  equ   $C054         ;switch in page 1
2000:        C055   53 txtpage2  equ   $C055         ;switch in page 2
2000:        C080   54 ramin     equ   $C080         ;read LC bank 2, write pro
tected
2000:        C081   55 romin     equ   $C081         ;read ROM, 2 reads write e
nable LC
2000:        C08B   56 lcbank1   equ   $C08B         ;LC bank 1 enable 
2000:               57 *
2000:        E000   58 lc1       equ   $E000         ;bytes to save for LC
2000:        D000   59 lc2       equ   $D000         ;save/restore routine
2000:        D400   60 lc3       equ   $D400
2000:        D800   61 lc4       equ   $D800
2000:               62 *
2000:        FE1F   63 idroutine equ   $FE1F         ;IIgs id routine
2000:               64 *
2000:               65 *  Start by saving the state of the language card banks 
and
2000:               66 *  by switching in main ROM.
2000:               67 *
2000:08             68 strt      php                 ;save the processor state
2001:78             69           sei                 ;before disabling interrup
ts
2002:AD 00 E0       70           lda   lc1           ;save four bytes from
2005:8D F1 21       71           sta   save          ;ROM/RAM area for later
2008:AD 00 D0       72           lda   lc2           ;restoring of RAM/ROM
200B:8D F2 21       73           sta   save+1        ;to original condition
200E:AD 00 D4       74           lda   lc3
2011:8D F3 21       75           sta   save+2
2014:AD 00 D8       76           lda   lc4
2017:8D F4 21       77           sta   save+3
201A:AD 81 C0       78           lda   $C081         ;read ROM
201D:AD 81 C0       79           lda   $C081
2020:A9 00          80           lda   #0            ;start by assuming unknown
 machine
2022:8D E8 21       81           sta   machine
2025:8D E9 21       82           sta   romlevel
2028:               83 *
2028:A5 06          84 IdStart   lda   location      ;save zero page locations
202A:8D F5 21       85           sta   save+4        ;for later restoration
202D:A5 07          86           lda   location+1
202F:8D F6 21       87           sta   save+5
2032:A9 FB          88           lda   #$FB          ;all ID bytes are in page 
$FB
2034:85 07          89           sta   location+1    ;save in zero page as high
 byte
2036:A2 00          90           ldx   #0            ;init pointer to start of 
ID table
2038:BD F7 21       91 loop      lda   IDTable,x     ;get the machine we are te
sting for
203B:8D E8 21       92           sta   machine       ;and save it
203E:BD F8 21       93           lda   IDTable+1,x   ;get the ROM level we are 
testing for
2041:8D E9 21       94           sta   romlevel      ;and save it
2044:0D E8 21       95           ora   machine       ;are both zero?
2047:F0 1C   2065   96           beq   matched       ;yes - at end of list - le
ave
2049:               97 *
2049:E8             98 loop2     inx                 ;bump index to loc/byte pa
ir to test
204A:E8             99           inx
204B:BD F7 21      100           lda   IDTable,x     ;get the byte that should 
be in ROM
204E:F0 15   2065  101           beq   matched       ;if zero, we're at end of 
list
2050:85 06         102           sta   location      ;save in zero page
2052:              103 *
2052:A0 00         104           ldy   #0            ;init index for indirect a
ddressing
2054:BD F8 21      105           lda   IDTable+1,x   ;get the byte that should 
be in ROM
2057:D1 06         106           cmp   (Location),y  ;is it there?
2059:F0 EE   2049  107           beq   loop2         ;yes, so keep on looping
205B:              108 *
205B:E8            109 loop3     inx                 ;we didn't match.Scoot to 
the end of the
205C:E8            110           inx                 ;line in the ID table so w
e can start
205D:BD F7 21      111           lda   IDTable,x     ;checking for another mach
ine
2060:D0 F9   205B  112           bne   loop3
2062:E8            113           inx                  ;point to start of next l
ine
2063:D0 D3   2038  114           bne   loop          ;should always be taken
2065:              115 *
2065:        2065  116 matched   equ   * 
2065:              117 *
2065:              118 *  Here we check the 16-bit ID routine at $FE1F.  If it
2065:              119 *  returns with carry clear, we call it again in 16-bit
2065:              120 *  mode to provide more information on the machine.
2065:              121 *
2065:38            122 idIIgs    sec                 ;set the carry bit
2066:20 1F FE      123           jsr   idroutine     ;Apple IIgs ID Routine
2069:90 03   206E  124           bcc   idIIgs2       ;it's a IIgs or equivalent
206B:4C A2 20      125           jmp   exit          ;nope, go check memory
206E:AD E8 21      126 idIIgs2   lda   machine       ;get the value for machine
2071:09 80         127           ora   #$80          ;and set the high bit
2073:8D E8 21      128           sta   machine       ;put it back
2076:18            129           clc                 ;get ready to switch into 
native mode
2077:FB            130           dfb   xce           ;this is a 65816 XCE instr
uction
2078:08            131           php                 ;save the processor status
2079:C2 30         132           dfb   $C2,$30       ;REP 30, sets 16-bit regis
ters
207B:20 1F FE      133           jsr   $FE1f         ;call the ID routine again
207E:8D EB 21      134           sta   IIgsA         ;16-bit store!
2081:8E ED 21      135           stx   IIgsX         ;16-bit store!
2084:8C EF 21      136           sty   IIgsY         ;16-bit store!
2087:28            137           plp                 ;restores 8-bit registers
2088:FB            138           dfb   xce           ;switches back to whatever
 it was before
2089:              139 *
2089:AC EF 21      140           ldy   IIgsY         ;get the ROM vers number (
starts at 0)
208C:C0 02         141           cpy   #$02          ;is it ROM 01 or 00?
208E:B0 01   2091  142           bcs   idIIgs3       ;if not, don't increment
2090:C8            143           iny                 ;bump it up for romlevel
2091:8C E9 21      144 idIIgs3   sty   romlevel      ;and put it there
2094:C0 01         145           cpy   #$01          ;is it the first ROM?
2096:D0 0A   20A2  146           bne   IIgsOut       ;no, go on with things
2098:AD F0 21      147           lda   IIgsY+1       ;check the other byte too
209B:D0 05   20A2  148           bne   IIgsOut       ;nope, it's a IIgs success
or
209D:A9 7F         149           lda   #$7F          ;fix faulty ROM 00 on the 
IIgs
209F:8D EB 21      150           sta   IIgsA
20A2:        20A2  151 IIgsOut   equ   *
20A2:              152 *
20A2:              153 ******************************************
20A2:              154 * This part of the code checks for the   *
20A2:              155 * memory configuration of the machine.   *
20A2:              156 * If it's a IIgs, we've already stored   *
20A2:              157 * the total memory from above.  If it's  *
20A2:              158 * a IIc, we know it's 128K; if it's a    *
20A2:              159 * ][+, we know it's at least 48K and     *
20A2:              160 * maybe 64K.  We won't check for less    *
20A2:              161 * than 48K, since that's a really rare   *
20A2:              162 * circumstance.                          *
20A2:              163 ******************************************
20A2:              164 *
20A2:AD E8 21      165 exit      lda   machine       ;get the machine kind
20A5:30 14   20BB  166           bmi   exit128       ;it's a 16-bit machine (ha
s 128K)
20A7:C9 05         167           cmp   #IIc          ;is it a IIc?
20A9:F0 10   20BB  168           beq   exit128       ;yup, it's got 128K
20AB:C9 04         169           cmp   #IIe          ;is it a IIe?
20AD:D0 03   20B2  170           bne   contexit      ;yes, go muck with aux mem
ory
20AF:4C 4E 21      171           jmp   muckaux
20B2:C9 03         172 contexit  cmp   #IIIem        ;is it a /// in emulation?
20B4:D0 6E   2124  173           bne   exitII        ;nope, it's a ][ or ][+
20B6:A9 30         174           lda   #48           ;/// emulation has 48K
20B8:4C BD 20      175           jmp   exita
20BB:A9 80         176 exit128   lda   #128          ;128K 
20BD:8D EA 21      177 exita     sta   memory
20C0:AD 00 E0      178 exit1     lda   lc1           ;time to restore the LC
20C3:CD F1 21      179           cmp   save          ;if all 4 bytes are the sa
me
20C6:D0 18   20E0  180           bne   exit2         ;then LC was never on so
20C8:AD 00 D0      181           lda   lc2           ;do nothing
20CB:CD F2 21      182           cmp   save+1
20CE:D0 10   20E0  183           bne   exit2
20D0:AD 00 D4      184           lda   lc3
20D3:CD F3 21      185           cmp   save+2
20D6:D0 08   20E0  186           bne   exit2
20D8:AD 00 D8      187           lda   lc4
20DB:CD F4 21      188           cmp   save+3
20DE:F0 38   2118  189           beq   exit6
20E0:AD 88 C0      190 exit2     lda   $C088         ;no match! so turn first L
C
20E3:AD 00 E0      191           lda   lc1           ;bank on and check
20E6:CD F1 21      192           cmp   save
20E9:F0 06   20F1  193           beq   exit3
20EB:AD 80 C0      194           lda   $C080
20EE:4C 18 21      195           jmp   exit6
20F1:AD 00 D0      196 exit3     lda   lc2
20F4:CD F2 21      197           cmp   save+1        ;if all locations check
20F7:F0 06   20FF  198           beq   exit4         ;then do more more else
20F9:AD 80 C0      199           lda   $C080         ;turn on bank 2
20FC:4C 18 21      200           jmp   exit6
20FF:AD 00 D4      201 exit4     lda   lc3           ;check second byte in bank
 1
2102:CD F3 21      202           cmp   save+2
2105:F0 06   210D  203           beq   exit5
2107:AD 80 C0      204           lda   $C080         ;select bank 2
210A:4C 18 21      205           jmp   exit6
210D:AD 00 D8      206 exit5     lda   lc4           ;check third byte in bank 
1
2110:CD F4 21      207           cmp   save+3
2113:F0 03   2118  208           beq   exit6
2115:AD 80 C0      209           lda   $C080         ;select bank 2
2118:28            210 exit6     plp                 ;restore interrupt status
2119:AD F5 21      211           lda   save+4        ;put zero page back
211C:85 06         212           sta   location
211E:AD F6 21      213           lda   save+5        ;like we found it
2121:85 07         214           sta   location+1
2123:60            215           rts                 ;and go home.
2124:              216 *
2124:AD 8B C0      217 exitII    lda   lcbank1       ;force in language card
2127:AD 8B C0      218           lda   lcbank1       ;bank 1
212A:AE 00 D0      219           ldx   lc2           ;save the byte there
212D:A9 AA         220           lda   #test1        ;use this as a test byte
212F:8D 00 D0      221           sta   lc2
2132:4D 00 D0      222           eor   lc2           ;if the same, should retur
n zero
2135:D0 12   2149  223           bne   noLC
2137:4E 00 D0      224           lsr   lc2           ;check twice just to be su
re
213A:A9 55         225           lda   #test2        ;this is the shifted value
213C:4D 00 D0      226           eor   lc2           ;here's the second check
213F:D0 08   2149  227           bne   noLC
2141:8E 00 D0      228           stx   lc2           ;put it back!
2144:A9 40         229           lda   #64           ;there's 64K here
2146:4C BD 20      230           jmp   exita
2149:A9 30         231 noLC      lda   #48           ;no restore - no LC!
214B:4C BD 20      232           jmp   exita         ;and get out of here
214E:              233 *
214E:AE 1A C0      234 muckaux   ldx   rdtext        ;remember graphics in X
2151:AD 1C C0      235           lda   rdpage2       ;remember current video di
splay
2154:0A            236           asl   A             ;in the carry bit 
2155:A9 88         237           lda   #test3        ;another test character
2157:2C 18 C0      238           bit   rd80col       ;remember video mode in N
215A:8D 01 C0      239           sta   set80col      ;enable 80-column store
215D:08            240           php                 ;save N and C flags
215E:8D 55 C0      241           sta   txtpage2      ;set page two
2161:8D 51 C0      242           sta   txtset        ;set text
2164:AC 00 04      243           ldy   begpage1      ;save first character
2167:8D 00 04      244           sta   begpage1      ;and replace it with test 
character
216A:AD 00 04      245           lda   begpage1      ;get it back
216D:8C 00 04      246           sty   begpage1      ;and put back what was the
re
2170:28            247           plp
2171:B0 08   217B  248           bcs   muck2         ;stay in page 2
2173:8D 54 C0      249           sta   txtpage1      ;restore page 1
2176:30 03   217B  250 muck1     bmi   muck2         ;stay in 80-columns
2178:8D 00 C0      251           sta   $c000         ;turn off 80-columns
217B:A8            252 muck2     tay                 ;save returned character
217C:8A            253           txa                 ;get graphics/text setting
217D:30 03   2182  254           bmi   muck3
217F:8D 50 C0      255           sta   txtclr        ;turn graphics back on
2182:C0 88         256 muck3     cpy   #test3        ;finally compare it
2184:D0 2F   21B5  257           bne   nocard        ;no 80-column card!
2186:AD 13 C0      258           lda   rdramrd       ;is aux memory being read?
2189:30 2F   21BA  259           bmi   muck128       ;yup, there's 128K!
218B:AD 16 C0      260           lda   rdaltzp       ;is aux zero page used?
218E:30 2A   21BA  261           bmi   muck128       ;yup!
2190:A0 2A         262           ldy   #done-start
2192:BE BC 21      263 move      ldx   start-1,y     ;swap section of zero page
2195:B9 00 00      264           lda   safe-1,y      ;code needings safe locati
on during
2198:96 00         265           stx   safe-1,y      ;reading of aux mem
219A:99 BC 21      266           sta   start-1,Y
219D:88            267           dey
219E:D0 F2   2192  268           bne   move
21A0:4C 01 00      269           jmp   safe          ;jump to safe ground
21A3:08            270 back      php                 ;save status
21A4:A0 2A         271           ldy   #done-start   ;move zero page back
21A6:B9 BC 21      272 move2     lda   start-1,y
21A9:99 00 00      273           sta   safe-1,y
21AC:88            274           dey
21AD:D0 F7   21A6  275           bne   move2
21AF:68            276           pla
21B0:B0 03   21B5  277           bcs   noaux
21B2:4C BA 21      278 isaux     jmp   muck128       ;there is 128K
21B5:              279 *
21B5:              280 *  You can put your own routine at "noaux" if you wish t
o
21B5:              281 *  distinguish between 64K without an 80-column card and
21B5:              282 *  64K with an 80-column card.
21B5:              283 *
21B5:        21B5  284 noaux     equ   *
21B5:A9 40         285 nocard    lda   #64           ;only 64K
21B7:4C BD 20      286           jmp   exita
21BA:4C BB 20      287 muck128   jmp   exit128       ;there's 128K
21BD:              288 *
21BD:              289 *  This is the routine run in the safe area not affected
21BD:              290 *  by bank-switching the main and aux RAM.
21BD:              291 *
21BD:A9 EE         292 start     lda   #test4        ;yet another test byte
21BF:8D 05 C0      293           sta   wrcardram     ;write to aux while on mai
n zero page
21C2:8D 03 C0      294           sta   rdcardram     ;read aux ram as well
21C5:8D 00 08      295           sta   begpage2      ;check for sparse memory m
apping
21C8:AD 00 0C      296           lda   begsprse      ;if sparse, these will be 
the same 
21CB:C9 EE         297           cmp   #test4        ;value since they're 1K ap
art
21CD:D0 0E   21DD  298           bne   auxmem        ;yup, there's 128K!
21CF:0E 00 0C      299           asl   begsprse      ;may have been lucky so we
'll
21D2:AD 00 08      300           lda   begpage2      ;change the value and see 
what happens
21D5:CD 00 0C      301           cmp   begsprse
21D8:D0 03   21DD  302           bne   auxmem
21DA:38            303           sec                 ;oops, no auxiliary memory
21DB:B0 01   21DE  304           bcs   goback
21DD:18            305 auxmem    clc
21DE:8D 04 C0      306 goback    sta   wrmainram     ;write main RAM
21E1:8D 02 C0      307           sta   rdmainram     ;read main RAM
21E4:4C A3 21      308           jmp   back          ;continue with program in 
main mem
21E7:EA            309 done      nop                 ;end of relocated program 
marker
21E8:              310 *
21E8:              311 *
21E8:              312 *  The storage locations for the returned machine ID:
21E8:              313 *
21E8:00            314 machine   dfb   $00           ;the type of Apple II
21E9:00            315 romlevel  dfb   $00           ;which revision of the mac
hine
21EA:00            316 memory    dfb   $00           ;how much memory (up to 12
8K)
21EB:00 00         317 IIgsA     dw    $0000         ;16-bit field
21ED:00 00         318 IIgsX     dw    $0000         ;16-bit field
21EF:00 00         319 IIgsY     dw    $0000         ;16-bit field
21F1:00 00 00 00   320 save      dfb   0,0,0,0,0,0   ;six bytes for saved data
21F7:01 01 B3 38   321 IDTable   dfb   1,1,$B3,$38,$00 ;Apple ][
21FC:02 01 B3 EA   322           dfb   2,1,$B3,$EA,$1E,$AD,$00 ;Apple ][+
2203:03 01 B3 EA   323           dfb   3,1,$B3,$EA,$1E,$8A,$00 ;Apple /// (emul
ation)
220A:04 01 B3 06   324           dfb   4,1,$B3,$06,$C0,$EA,$00 ;Apple IIe (orig
inal)
2211:04 02 B3 06   325           dfb   4,2,$B3,$06,$C0,$E0,$00 ;Apple IIe (enha
nced)
2218:05 01 B3 06   326           dfb   5,1,$B3,$06,$C0,$00,$BF,$FF,$00 ;Apple I
Ic (original)
2221:05 02 B3 06   327           dfb   5,2,$B3,$06,$C0,$00,$BF,$00,$00 ;Apple I
Ic (3.5 ROM)
222A:05 03 B3 06   328           dfb   5,3,$B3,$06,$C0,$00,$BF,$03,$00 ;Apple I
Ic (Mem. Exp)
2233:05 04 B3 06   329           dfb   5,4,$B3,$06,$C0,$00,$BF,$04,$00 ;Apple I
Ic (Rev. Mem. 
Exp.)
223C:05 05 B3 06   330           dfb   5,5,$B3,$06,$C0,$00,$BF,$05,$00 ;Apple I
Ic Plus
2245:00 00         331           dfb   0,0           ;end of table

 21DD AUXMEM         21A3 BACK           0400 BEGPAGE1       0800 BEGPAGE2     
 
 0C00 BEGSPRSE      ?C000 CLR80COL       20B2 CONTEXIT       21E7 DONE         
 
 20E0 EXIT2          20A2 EXIT           20BB EXIT128       ?20C0 EXIT1        
 
 20F1 EXIT3          20FF EXIT4          210D EXIT5          2118 EXIT6        
 
 20BD EXITA          2124 EXITII         21DE GOBACK        ?2065 IDIIGS       
 
 206E IDIIGS2        2091 IDIIGS3        FE1F IDROUTINE     ?2028 IDSTART      
 
 21F7 IDTABLE          05 IIC              04 IIE            21EB IIGSA        
 
 20A2 IIGSOUT        21ED IIGSX          21EF IIGSY            03 IIIEM        
 
?  01 IIPLAIN       ?  02 IIPLUS        ?21B2 ISAUX          E000 LC1          
 
 D000 LC2            D400 LC3            D800 LC4            C08B LCBANK1      
 
   06 LOCATION       2038 LOOP           2049 LOOP2          205B LOOP3        
 
 21E8 MACHINE        2065 MATCHED        21EA MEMORY         21A6 MOVE2        
 
 2192 MOVE           21BA MUCK128       ?2176 MUCK1          217B MUCK2        
 
 2182 MUCK3          214E MUCKAUX        21B5 NOAUX          21B5 NOCARD       
 
 2149 NOLC          ?C080 RAMIN          C018 RD80COL        C016 RDALTZP      
 
 C003 RDCARDRAM      C002 RDMAINRAM      C01C RDPAGE2        C013 RDRAMRD      
 
 C01A RDTEXT        ?C081 ROMIN          21E9 ROMLEVEL         01 SAFE         
 
 21F1 SAVE           C001 SET80COL       21BD START         ?2000 STRT         
 
   AA TEST1            55 TEST2            88 TEST3            EE TEST4        
 
 C050 TXTCLR         C054 TXTPAGE1       C055 TXTPAGE2       C051 TXTSET       
 
 C005 WRCARDRAM      C004 WRMAINRAM        FB XCE           
** SUCCESSFUL ASSEMBLY := NO ERRORS
** ASSEMBLER CREATED ON 15-JAN-84 21:28 
** TOTAL LINES ASSEMBLED   331 
** FREE SPACE PAGE COUNT   81 


Further Reference
o    Apple II Miscellaneous Technical Note #7, Apple II Family Identification


Apple II
Technical Notes
_____________________________________________________________________________
                                                  Developer Technical Support


Pascal
#10:    Configuration and Use of the Apple II Pascal Run-Time Systems

Revised by:    Cheryl Ewy                                       November 1988
Revised by:    Cheryl Ewy                                           June 1985

This Technical Note describes the Apple II Pascal Run-Time Systems which 
permit the "turnkey" execution of application software which has been 
developed using Apple Pascal.
_____________________________________________________________________________


System Overview

The Run-Time Systems support only the execution of an application package.  
Unlike the Pascal Development System, the Run-Time Systems do not contain the 
Assembler, Compiler, Editor, Filer or Linker, nor even an error reporting 
mechanism at the system level.  System operations such as transferring files, 
compacting disks (Krunching), and the reporting of and recovery from errors, 
are all left to the application program.  It is the software developer's 
responsibility to design and implement friendly, entirely self-contained 
packages for use with the Run-Time Systems.  The safest assumption to make 
when developing such packages is that the user is not only unfamiliar with the 
facilities of the Pascal Development System, but may also be ignorant of 
computer operation and use in general. 

The three run-time systems currently available are :

o    The 48K Run-Time System  V1.2    (standard and stripped)
o    The 64K Run-Time System  V1.3    (standard only)
o    The 128K Run-Time System V1.3    (standard only)

The name of each Run-Time System indicates the minimum amount of RAM necessary 
for proper operation.  Any additional RAM available will not be used by the 
Run-Time Systems.

The 48K Run-Time System has not been updated to version 1.3, as have the 64K 
and 128K Run-Time Systems.  Thus, the changes and improvements made to Pascal 
for version 1.3 are not available in the 48K Run-Time System.  Specifically, 
the 48K Run-Time System can only use Disk II drives and can only boot from 
slot 6.  See the Apple II Pascal 1.3 Manual for more information on the 
differences between versions 1.2 and 1.3 of Apple II Pascal.

There are two configurations of the 48K Run-Time System available, one of 
which provides more free memory for the application package's programs and 
data than does the other.  Except as noted later, the standard configuration 
of the Run-Time System supports all features of the Pascal Development System 
that are relevant to turnkey execution of application software.  The stripped 
configuration lacks set operations and floating-point arithmetic.


Contents of the Apple II Pascal Run-Time System Disks

The following files are contained on the Apple II Pascal 1.2 48K Run-Time 
System disk (RT48:):

o    RTSTND.APPLE       48K Run-time standard P-machine.
o    RTSTRP.APPLE       48K Run-time stripped P-machine.
o    SYSTEM.PASCAL      48K Run-time operating system.
o    RTBSTND.BOOT       Contains the boot code for RTSTND.APPLE.
o    RTBSTRP.BOOT       Contains the boot code for RTSTRP.APPLE.
o    RTBOOTLOAD.CODE    Utility program to load 48K Run-time boot 
                        code onto blocks 0 and 1 of Vendor Product 
                        disk. 

The following files are described below:

o    SYSTEM.LIBRARY
o    SYSTEM.ATTACH 
o    RTSETMODE.CODE
o    II40.MISCINFO 
o    II80.MISCINFO 
o    IIE40.MISCINFO 
o    SYSTEM.MISCINFO
o    SYSTEM.CHARSET

The following files are contained on the Apple II Pascal 1.3 64K Run-Time 
System disk (RT64:):

o    SYSTEM.APPLE       64K Run-time standard P-machine.
o    SYSTEM.PASCAL      64K Run-time operating system.

The following files are described below:

o    SYSTEM.LIBRARY
o    SYSTEM.ATTACH
o    RTSETMODE.CODE
o    II40.MISCINFO
o    II80.MISCINFO
o    SYSTEM.MISCINFO
o    SYSTEM.CHARSET

The following files are contained on the Apple II Pascal 1.3 128K Run-Time 
System disk (RT128:):

o    SYSTEM.APPLE       128K Run-time standard P-machine.
o    SYSTEM.PASCAL      128K Run-time operating system.

The following files are described below, and are identical to the 64K Run-Time 
System files:

o    SYSTEM.LIBRARY
o    SYSTEM.ATTACH
o    RTSETMODE.CODE
o    SYSTEM.MISCINFO
o    SYSTEM.CHARSET

The Development Systems referred to in the following file descriptions are the 
Apple II Pascal 1.3 Development System when discussing files on the 64K and 
the 128K Run-Time System disks and the Apple II Pascal 1.2 Development System 
when discussing files on the 48K Run-Time System disk.

SYSTEM.LIBRARY    contains the run-time versions of the same Intrinsic 
                  Units supplied with the Development System.  These 
                  Units are for use only with the Run-Time System and 
                  will not execute properly in the Development 
                  environment.  Conversely, only the Units in this 
                  library, not those on the Development System disks, 
                  should be used when executing programs in the Run-time 
                  environment.  Note  that the developer is free to add 
                  his own Intrinsic Units to SYSTEM.LIBRARY.
SYSTEM.ATTACH     is a run-time version of the dynamic driver-attachment 
                  program described in Apple II Pascal Device and 
                  Interrupt Support Tools.  This version may only be 
                  used with the Run-Time Systems.
RTSETMODE.CODE    is a utility program that permits the vendor to arm or 
                  disarm any or all of four system options:  Filehandler 
                  Overlay, Single Drive System, Ignore External 
                  Terminal, and Get/Put and Filehandler Overlay.
MISCINFO          files are identical to those supplied on the 
                  Development System disks and are supplied here only 
                  for the sake of redundancy.
SYSTEM.CHARSET    is identical to the file supplied with the Development  
                  System; it is included here only for the sake of 
                  redundancy.  This file is needed on the Vendor Product 
                  Disk only if TURTLEGRAPHICS is used.

Of the files supplied on the Run-Time System disks, the final Vendor Product 
Disk should contain only the Run-time P-machine (SYSTEM.APPLE, RTSTND.APPLE, 
or RTSTRP.APPLE), SYSTEM.PASCAL, SYSTEM.LIBRARY, the appropriate MISCINFO file 
renamed to SYSTEM.MISCINFO, and, optionally, SYSTEM.CHARSET.  SYSTEM.ATTACH, 
with its attendant data files should be included on the Vendor Product Disk if 
special device drivers must be bound into the  system for use by the 
Application Package.  All other files on the Run-Time System disks are used in 
creating and configuring the Vendor Product  Disk.


Operation

Apple II
Technical Notes
_____________________________________________________________________________
                                                  Developer Technical Support


ProDOS 8
#4:    I/O Redirection in DOS and ProDOS

Revised by:    Matt Deatherage                                  November 1988
Revised by:    Pete McDonald                                    November 1985

This Technical Note discusses I/O redirection differences between DOS 3.3 and 
ProDOS.
_____________________________________________________________________________

Under DOS 3.3, all that is necessary to change the I/O hooks is installing 
your I/O routine addresses in the character-out vector ($36-$37) and the key-
in vector ($38-$39) and notifying DOS (JSR $3EA) to take your addresses and 
swap in its intercept routine addresses.

Under ProDOS, there is no instruction installed at $3EA, so what do you do?

You simply leave the ProDOS BASIC command interpreter's intercept addresses 
installed at $36-$39 and install your I/O addresses in the global page at 
$BE30-$BE33.  The locations $BE30-$BE31 should contain the output address 
(normally $FDF0, the Monitor COUT1 routine), while $BE32-$BE33 should contain 
the input address (normally $FD1B, the Monitor KEYIN routine).

By keeping these vectors in a global page, a special routine for  moving the 
vectors is no longer needed, thus, no $3EA instruction.  You install the 
addresses at their destination yourself.

If you intend to switch between devices (i.e., the screen and the printer), 
you should save the hooks you find in $BE30-$BE33 and restore them when you 
are done.  Blindly replacing the values in the global page could easily leave 
you no way to restore input or output to the previous device when you are 
done.



Apple II
Technical Notes
_____________________________________________________________________________
                                                  Developer Technical Support


ProDOS 8
#5:    ProDOS Block Device Formatting

Revised by:    Matt Deatherage                                  November 1988
Revised by:    Pete McDonald                                     October 1985

This Technical Note formerly described the ProDOS FORMATTER routine.
_____________________________________________________________________________

The ProDOS 8 Update Manual now contains the information about the ProDOS 
FORMATTER routine which this Note formerly described.  This routine is 
available from Apple Software Licensing at Apple Computer, Inc., 20525 Mariani 
Avenue, M/S 38-I, Cupertino, CA, 95014 or (408) 974-4667.

Note:    This routine does not work properly with network volumes on 
either entry point.  You cannot format a network volume with 
ProDOS 8, nor can you make low-level device calls to it (as 
FORMATTER does in ENTRY2 to determine the characteristics of a 
volume).  As a general rule, it is better to use GET_FILE_INFO to 
determine the size of the volume since ProDOS MLI calls work with 
network volumes.


Further Reference
o    ProDOS 8 Update Manual


Apple II
Technical Notes
_____________________________________________________________________________
                                                  Developer Technical Support


ProDOS 8
#9:    Buffer Management Using BASIC.SYSTEM

Revised by:    Matt Deatherage                                  November 1988
Revised by:    Pete McDonald                                     October 1985

This Technical Note discusses methods for allocating buffers which will not be 
arbitrarily deallocated in BASIC.SYSTEM.
_____________________________________________________________________________

Section A.2.1 of the ProDOS 8 Technical Reference Manual describes in detail 
how an application may obtain a buffer from BASIC.SYSTEM for its own use.  The 
buffer will be respected by BASIC.SYSTEM, so if you choose to put a program or 
other executable code in there, it will be safe.

However, BASIC.SYSTEM does not provide a way to selectively deallocate the 
buffers it has allocated.  Although it is quite easy to allocate space by 
calling GETBUFR ($BEF5) and also quite easy to deallocate by calling FREEBUFR 
($BEF8), it is not so easy to use FREEBUFR to deallocate a particular buffer.

In fact, FREEBUFR always deallocates all buffers allocated by GETBUFR.  This 
is fine for transient applications, but a method is needed to protect a static 
code buffer from being deallocated by FREEBUFR for a static application.

Location RSHIMEM ($BEFB) contains the high byte of the highest available 
memory location for buffers, normally $96.  FREEBUFR uses it to determine the 
beginning page of the highest (or first) buffer.  By lowering the value of 
RSHIMEM immediately after the first call to GETBUFR, and before any call to 
FREEBUFR, we can fool FREEBUFR into not reclaiming all the space.  So although 
it is not possible to selectively deallocate buffers, it is still possible to 
reserve space that FREEBUFR will not reclaim.

Physically, we place the code buffer between BASIC.SYSTEM and its buffers, in 
the space from $99FF down.

After creating the protected static code buffer, we can call GETBUFR and 
FREEBUFR to maintain temporary buffers as needed by our protected module.  
FREEBUFR will not reclaim the protected buffer until after RSHIMEM is restored 
to its original value.

The following is a skeleton example which allocates a two-page buffer for a 
static code module, protects it from FREEBUFR, then deprotects it and restores 
it to its original state.

START    LDA #$02            ;get 2 pages
         JSR GETBUFR 
         LDA RSHIMEM         ;get current RSHIMEM
         SEC                 ;ready for sub
         SBC #$02            ;minus 2 pages
         STA RSHIMEM         ;save new val to fool FREEBUFR
         JSR FREEBUFR        ;CALL FREEBUFR to deallocate.

At this point, the value of RSHIMEM is the page number of the beginning of our 
protected buffer.  The static code may now use GETBUFR and FREEBUFR for 
transient file buffers without fear of freeing its own space from RSHIMEM to 
$99FF.

To release the protected space, simply restore RSHIMEM to its original value 
and perform a JSR FREEBUFR.

END      LDA RSHIMEM         ;get current val
         CLC                 ;ready for ADD
         ADC #2              ;give back 2 pages
         STA RSHIMEM         ;tell FREEBUFR about it
         JSR FREEBUFR        ;DO FREEBUFR
         RTS 

You can reserve any number of pages using this method, as long as the amount 
you reserve is within available memory limits. 


Further Reference
o    ProDOS 8 Technical Reference Manual


Apple II
Technical Notes
_____________________________________________________________________________
                                                  Developer Technical Support


ProDOS 8
#10:    Installing Clock Driver Routines

Revised by:    Matt Deatherage                                  November 1988
Revised by:    Pete McDonald                                    November 1985

This Technical Note formerly described how to install a clock driver routine 
other than the default.
_____________________________________________________________________________

Section 6.1.1 of the ProDOS 8 Technical Reference Manual documents how to 
install a clock driver other than the default ThunderClock(TM) driver or the 
Apple IIGS clock driver into ProDOS 8, which this Note formerly covered.


Further Reference
o    ProDOS 8 Technical Reference Manual
o    ProDOS 8 Technical Note #1, The GETLN Buffer and a ProDOS Clock Card