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 Delaneyasd@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