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