GLă C˛˙C˛˙˝ TN.MISC.001Z“ Apple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #1: 80-Column Screen Dump Revised by: Pete McDonald November 1988 Written by: Greg Seitz December 1984 This Technical Note presents an example assembly language program which dumps the contents of the 80-column text screen to whatever is connected to COUT. _____________________________________________________________________________ 0000: 1 * 0000: 2 * 80-column screen dump 0000: 3 * 0000: 4 * By 0000: 5 * Greg Seitz 0000: 6 * 12-Jul-84 0000: 7 * 0000: 8 * This program will allow you to dump the contents 0000: 9 * of your 80-column text screen to whatever device is 0000: 10 * connected through COUT. If it is still connected to 0000: 11 * the screen, you will obviously be printing back 0000: 12 * what you were reading. 0000: 13 * 0000: FBC1 14 BASCALC EQU $FBC1 ;convert A reg to line ;addr on scrn 0000: FDED 15 COUT EQU $FDED ;A register out as ASCII 0000: C001 16 SET80COL EQU $C001 ;enable page 1/2 switches ;to control aux 0000: C055 17 TXTPAGE2 EQU $C055 ;page 2 or Aux depending 0000: C054 18 TXTPAGE1 EQU $C054 ;page 1 or main depending 0000: 0028 19 BASL EQU $28 ;BASCALC puts base addr. ;here 0000: 0029 20 BASH EQU $29 ;and high byte here. 0000: 21 * 1000: 1000 22 ORG $1000 ;or anywhere 1000: 1000 23 SCREENDMP EQU * 1000:A2 00 24 LDX #0 ;START AT LINE 0 1002: 25 * 1002:8A 26 SCRNLP TXA ;CALL BASCALC 1003:20 C1 FB 27 JSR BASCALC ;FOR ADDRESS OF LINE X 1006:A0 00 28 LDY #00 ;DO 80 CHARS STARTING FROM ;CHARACTER 0 1008: 29 * 1008: 1008 30 SCRNLP2 EQU * 1008:8D 01 C0 31 STA SET80COL ;SET UP FOR MAIN/AUX ;SWITCHING 100B:8D 55 C0 32 STA TXTPAGE2 ;START ON AUX 100E:98 33 TYA ;GET CURRENT INDEX FOR ;DIVIDE BY 2 100F:48 34 PHA ;SAVE ACTUAL COLUMN NUM ;WE'RE ON 1010:4A 35 LSR ;COLUMN/2=ODD OR EVEN ;BRANCH IF EVEN 1011:90 03 1016 36 BCC SCRNDMP1 ;TAKEN IF EVEN SINCE STATE ;IS PROPER 1013:8D 54 C0 37 STA TXTPAGE1 ;ELSE IF ODD TURN ON MAIN MEM 1016: 38 * 1016: 1016 39 SCRNDMP1 EQU * 1016:A8 40 TAY ;USE COLUMN/2 INDEX NOW 1017:B1 28 41 LDA (BASL),Y ;GRAB THE CHARACTER 1019:8D 54 C0 42 STA TXTPAGE1 ;SEL MAIN SO IT SEES RIGHT ;SCREEN HOLES 101C:20 ED FD 43 JSR COUT ;PRINT THE CHARACTER 101F:68 44 PLA ;RECOVER COLUMN NUM 1020:A8 45 TAY ;INTO Y FOR NEXT TRIP 1021:C8 46 INY ;NEXT COLUMN NUM 1022:C0 50 47 CPY #80 ;ANY MORE? 1024:90 E2 1008 48 BCC SCRNLP2 ;TAKEN IF YES 1026:A9 8D 49 LDA #$8D ;ELSE CARRIAGE RETURN 1028:20 ED FD 50 JSR COUT ;OUT 102B:A9 8A 51 LDA #$8A ;LINE FEED 102D:20 ED FD 52 JSR COUT ;OUT 1030:E8 53 INX ;NEXT LINE 1031:E0 18 54 CPX #24 ;ANYMORE? 1033:90 CD 1002 55 BCC SCRNLP ;TAKEN IF YES 1035:60 56 RTS FBC1 BASCALC ? 29 BASH 28 BASL FDED COUT C054 TXTPAGE1 C055 TXTPAGE2 ?1000 SCREENDMP 1016 SCRNDMP1 1008 SCRNLP2 1002 SCRNLP C001 SET80COL ** SUCCESSFUL ASSEMBLY := NO ERRORS ** ASSEMBLER CREATED ON 15-JAN-84 21:28 ** TOTAL LINES ASSEMBLED 56 ** FREE SPACE PAGE COUNT 84 GLă=)˛*˛+ w TN.MISC.002Z 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 mode 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 to 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 page? 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 displayed 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 protected 2000: C081 55 romin equ $C081 ;read ROM, 2 reads write enable 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 interrupts 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 testing 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 - leave 2049: 97 * 2049:E8 98 loop2 inx ;bump index to loc/byte pair 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 addressing 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 we can start 205D:BD F7 21 111 lda IDTable,x ;checking for another machine 2060:D0 F9 205B 112 bne loop3 2062:E8 113 inx ;point to start of next line 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 instruction 2078:08 131 php ;save the processor status 2079:C2 30 132 dfb $C2,$30 ;REP 30, sets 16-bit registers 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 successor 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 (has 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 memory 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 same 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 LC 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 return zero 2135:D0 12 2149 223 bne noLC 2137:4E 00 D0 224 lsr lc2 ;check twice just to be sure 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 display 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 there 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 location 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 to 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 main 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 mapping 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 apart 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 machine 21EA:00 316 memory dfb $00 ;how much memory (up to 128K) 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 /// (emulation) 220A:04 01 B3 06 324 dfb 4,1,$B3,$06,$C0,$EA,$00 ;Apple IIe (original) 2211:04 02 B3 06 325 dfb 4,2,$B3,$06,$C0,$E0,$00 ;Apple IIe (enhanced) 2218:05 01 B3 06 326 dfb 5,1,$B3,$06,$C0,$00,$BF,$FF,$00 ;Apple IIc (original) 2221:05 02 B3 06 327 dfb 5,2,$B3,$06,$C0,$00,$BF,$00,$00 ;Apple IIc (3.5 ROM) 222A:05 03 B3 06 328 dfb 5,3,$B3,$06,$C0,$00,$BF,$03,$00 ;Apple IIc (Mem. Exp) 2233:05 04 B3 06 329 dfb 5,4,$B3,$06,$C0,$00,$BF,$04,$00 ;Apple IIc (Rev. Mem. Exp.) 223C:05 05 B3 06 330 dfb 5,5,$B3,$06,$C0,$00,$BF,$05,$00 ;Apple IIc 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 GLă)˛*˛+  TN.MISC.003Z Apple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #3: Super Serial Card Firmware Bug Revised by: Matt Deatherage November 1988 Written by: Cameron Birse November 1985 This Technical Note documents two bugs in the Super Serial Card firmware. _____________________________________________________________________________ The Super Serial Card (SSC) firmware does not access location $CFFF to clear the $C800 space before jumping into its bank-switched ROM in that area. By omitting this access, the Super Serial Card can cause a slot data bus conflict when a ROM of equal or greater strength on another card "owns" the $C800 space when the Super Serial Card wants to use it. For example, the UniDisk 3.5 controller card uses the same 74LS245 octal bus driver as the Super Serial Card. If you are using the UniDisk 3.5 card and switch to the Super Serial Card firmware, there will be a bus conflict . The SSC is trying to switch in its own $C800 space while the UniDisk 3.5 card is trying to keep the $C800 space, since no one cleared it by accessing $CFFF. Since both have the same capability to drive the bus, neither wins the battle. An easy solution to this problem is to reference $CFFF before calling any of the Pascal entry points on the Super Serial Card. For example: NEWSLOT STA $CFFF ;reset the slot ROM space LDA Char ;Char = character to output LDX #$Cn ;n = slot number LDY #$n0 STX MSLOT ;MSLOT = $7F8, always set it up JSR PWRITE ;now call the Pascal routine of your choice This bug is in the Pascal entry points; the BASIC entry point does not have this problem as there is a STA $CFFF instruction at $Cn1B. This example code stores the slot number (in the form $Cn) in MSLOT, a screen hole used to tell the system which peripheral card had control when an interrupt occurred. The Super Serial Card firmware does set up MSLOT, but does not do so until long after it has enabled its $C800 space. If an IRQ comes through the system between the call to the card and when the card stores MSLOT, the system will crash. Both bugs can be avoided by using the sample code to call entry points on the Super Serial Card. Further Reference o Apple IIe Technical Reference Manual GLă)˛*˛+ ˆ TN.MISC.004ZApple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #4: AppleWorks Keys Revised by: Matt Deatherage November 1988 Written by: J.D. Eisenberg June 1985 This Technical Note formerly described information concerning AppleWorks(TM), which is now published by CLARIS. _____________________________________________________________________________ This Note formerly discussed sections of AppleWorks 1.2 and 1.3 code which checked for keypresses to allow other applications to tap into certain routines. For information on AppleWorks, contact CLARIS at: CLARIS 440 Clyde Avenue Mountain View, CA 94043 Technical Information Telephone: (415) 962-0371 AppleLink: Claris.Tech Non-Technical Information Telephone: (415) 962-8946 AppleLink: Claris.CR In addition to the support available from CLARIS, Bob Lissner, the author of AppleWorks, maintains a bulletin board for AppleWorks-related information. You can obtain technical information and file formats from this system as well as submit your comments in writing. You can reach this system at (702) 831- 1722. GLă)˛*˛+ O TN.MISC.005ZApple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #5: AppleWorks File Formats Revised by: Matt Deatherage November 1988 This Technical Note formerly documented the file formats for AppleWorks(TM), which is now published by CLARIS. _____________________________________________________________________________ This Note formerly documented the file formats available in AppleWorks and /// E-Z Pieces (AppleWorks for the Apple ///). This information is now documented in three File Type Notes: AppleWorks Data Base $19 AppleWorks Spreadsheet $1A AppleWorks Word processor $1B For additional information on AppleWorks, contact CLARIS at: CLARIS 440 Clyde Avenue Mountain View, CA 94043 Technical Information Telephone: (415) 962-0371 AppleLink: Claris.Tech Non-Technical Information Telephone: (415) 962-8946 AppleLink: Claris.CR In addition to the support available from CLARIS, Bob Lissner, the author of AppleWorks, maintains a bulletin board for AppleWorks-related information. You can obtain technical information and file formats from this system as well as submit your comments in writing. You can reach this system at (702) 831- 1722. Further Reference o Apple II File Type Note $19 o Apple II File Type Note $1A o Apple II File Type Note $1B GLă)˛*˛+  TN.MISC.006ZApple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #6: IWM Port Description Revised by: Glenn A. Baxter November 1988 Written by: Cameron Birse February 1986 This Technical Note documents the IWM port pin assignments on various machines. _____________________________________________________________________________ Apple IIGS Disk Port Pin Assignments Signal Name Disk Port Pins (DB-19) Phase 0 11 Phase 1 12 Phase 2 13 Phase 3 14 /WReq 15 Dr1 17 Rd 18 Wr 19 Wrt Prot 10 Dr2 9 HeadSel 16 Gnd 1,2,3 3.5Disk 4 -12v 5 +5v 6 +12v 7,8 Apple IIe UniDisk 3.5 Controller Disk Port Pin Assignments Signal Name Disk Port Pins (DB-19) Phase 0 11 Phase 1 12 Phase 2 13 Phase 3 14 /WrtReqII 15 /HstEnbl 17 Rd 18 Wr 19 Wrt Prot 10 No Connection 9,16 Gnd 1,2,3,4 -12v 5 +5v 6 +12v 7,8 Apple IIc Disk Port Pin Assignments Signal Name Disk Port Pins (DB-19) Phase 0 11 Phase 1 12 Phase 2 13 Phase 3 14 /WrtReq 15 /Enbl 2 17 Rd 18 Wr 19 Wrt Prot 10 No Connection 16 Gnd 1,2,3,4 -12v 5 +5v 6 +12v 7,8 External Interrupt 9 Note: On the Apple IIc Plus, the disk port pins are driven by a custom ASIC instead of by the IWM chip. Macintosh Disk Port Pin Assignments Signal Name Disk Port Pins (DB-19) Phase 0 11 Phase 1 12 Phase 2 13 Phase 3 14 /WrtReq 15 /Enbl 2 17 Rd 18 Wr 19 PWM 10 HdSel 16 GND 1,2,3,4 -12v 5 +5v 6 +12v 7,8 GLă )˛*˛+ Ă TN.MISC.007ZApple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #7: Apple II Family Identification Revised by: Matt Deatherage November 1988 Written by: Cameron Birse December 1986 This Technical Note describes the ROM identification bytes in the Apple II family. _____________________________________________________________________________ To identify which computer of the Apple II family is executing your program, you must check the following identification bytes. These bytes are in the main bank of main ROM (shadowed on the Apple IIGS), and you should make sure that this bank is switched in before making decisions based on the contents of these locations. Machine $FBB3 $FB1E $FBC0 $FBBF Apple ][ $38 [$60] [$2F] Apple ][+ $EA $AD [$EA] [$EA] Apple /// (emulation) $EA $8A Apple IIe $06 $EA [$C1] Apple IIe (enhanced) $06 $E0 [$00] Apple IIc $06 $00 $FF Apple IIc (3.5 ROM) $06 $00 $00 Apple IIc (Org. Mem. Exp.) $06 $00 $03 Apple IIc (Rev. Mem. Exp.) $06 $00 $04 Apple IIc Plus $06 $00 $05 Apple IIGS (See below) Note: Values listed in square brackets in the table are provided for your reference only. You do not need to check them to conclusively identify an Apple II. The ID bytes for an Apple IIGS are not listed in the table since they match those of an enhanced Apple IIe. Future 16-bit Apple II products may match different Apple II identification bytes for compatibility reasons, so to identify a machine as a IIGS or other 16-bit Apple II, you must make the following ROM call: SEC ;Set carry bit (flag) JSR $FE1F ;Call to the monitor BCS OLDMACHINE ;If carry is still set, then old machine BCC NEWMACHINE ;If carry is clear, then new machine In all the current, standard Apple II ROMs, $FE1F contains an RTS. In the Apple IIGS, there is a routine that returns compatibility information in the A, X, and Y registers: Bit Accumulator X Register Y Register Bit 15 Reserved Reserved Machine ID Number (0 = Apple IIGS) Bit 14 Reserved Reserved Machine ID Number Bit 13 Reserved Reserved Machine ID Number Bit 12 Reserved Reserved Machine ID Number Bit 11 Reserved Reserved Machine ID Number Bit 10 Reserved Reserved Machine ID Number Bit 9 Reserved Reserved Machine ID Number Bit 8 Reserved Reserved Machine ID Number Bit 7 Reserved Reserved ROM version number Bit 6 1 if system has memory expansion slot Reserved ROM version number Bit 5 1 if system has IWM port Reserved ROM version number Bit 4 1 if system has a built-in clock Reserved ROM version number Bit 3 1 if system has desktop bus Reserved ROM version number Bit 2 1 if system has SCC built-in Reserved ROM version number Bit 1 1 if system has external slots Reserved ROM version number Bit 0 1 if system has internal ports Reserved ROM version number Note: In emulation or eight-bit mode, only the lower eight bits are returned. This ROM call is enough to determine if a machine is an Apple IIGS or equivalent. Note: The original Apple IIGS ROM returns a faulty value in the accumulator. The value returned is $xx1F and should be $xx7F. If you see a $0000 in the Y register (i.e., Apple IIGS, ROM version $00), you should assume that the accumulator value is $xx7F. The current Apple IIGS ROM (ROM version $01) sets all the registers correctly before returning from this call. Further Reference o Miscellaneous Technical Note #2, Apple II Family Identification Routines 2.1 GLă )˛*˛+ f TN.MISC.008ZApple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #8: Pascal 1.1 Firmware Protocol ID Bytes Revised by: Matt Deatherage November 1988 Written by: Cameron Birse December 1986 This Technical Note documents the Pascal 1.1 Firmware Protocol ID bytes for Apple II peripheral cards and ports. _____________________________________________________________________________ Background Apple II Pascal 1.1 introduced a firmware protocol called, not surprisingly, the Pascal 1.1 Firmware Protocol. A card following this protocol could be identified by the following ID bytes, where n is the slot in which the card resides: Address Value Definition $Cn05 $38 ID byte (from Pascal 1.0) $Cn07 $18 ID byte (from Pascal 1.0) $Cn0B $01 Generic signature of cards with Pascal 1.1 Protocol $Cn0C $ci Device signature byte $Cn0C was interpreted as two nibbles. The high-order nibble, c, was defined as the device signature. This signature was a pre-defined value determining what kind of device was connected (i.e., printer, modem, joystick, clock, etc.). The low-order nibble, i, was defined as a unique identifier, so you could tell one printer from another, for example. Developer Technical Support no longer maintains a list of assignments for the i nibble in this protocol. Since, by definition, the Pascal 1.1 Protocol only has room for 16 uniquely identified devices of each signature, it is easy to see that the Apple II family has outgrown the definition. Following is a table which lists the values of the Pascal 1.1 Firmware Protocol ID bytes for some Apple products which follow the protocol. Previous versions of this Note listed ID bytes for products which did not follow the protocol. Do not attempt to identify devices which do not follow the protocol by checking these ID bytes. This method will not work and should be avoided. For example, trying to conclusively identify a 3.5" disk drive, SCSI hard drive, memory expansion card, or other SmartPort device using these ID bytes could be disastrous. For any SmartPort device, you should look for the ProDOS Block Device ID bytes ($Cn01 = $20, $Cn03 = $00, $Cn05 = $03), then look for the additional SmartPort ID byte ($Cn07 = $00). Once you have identified SmartPort, you should make a SmartPort STATUS call to determine the nature and types of connected devices. By this definition, ProDOS block devices and SmartPort devices cannot follow the Pascal 1.1 Firmware Protocol. Pascal 1.1 Devices $Cn05 $Cn07 $Cn0B $Cn0C Apple II Peripheral Cards Super Serial Card (or port) $38 $18 $01 $31 Apple 80 Column Card $38 $18 $01 $88 Apple II Mouse Card $38 $18 $01 $20 Apple IIc Ports 1st version $FBBF = $FF Slot 1 (Serial Port) $38 $18 $01 $31 Slot 2 (Serial Port) $38 $18 $01 $31 Slot 3 (80 Columns) $38 $18 $01 $88 Slot 4 (Mouse) $38 $18 $01 $20 2nd version $FBBF = $00 Slot 1 (Serial Port) $38 $18 $01 $31 Slot 2 (Serial Port) $38 $18 $01 $31 Slot 3 (80 Columns) $38 $18 $01 $88 Slot 4 (Mouse) $38 $18 $01 $20 Slot 7 (AppleTalk) $38 $18 $01 $31 3rd version $FBBF = $03, 4th version $FBBF = $04, and 5th version $FBBF = $05 Slot 1 (Serial Port) $38 $18 $01 $31 Slot 2 (Serial Port) $38 $18 $01 $31 Slot 3 (80 Columns) $38 $18 $01 $88 Slot 7 (Mouse) $38 $18 $01 $20 Apple IIGS Ports (ROM 1.0 and 2.0) Slot 1 (Serial Port) $38 $18 $01 $31 Slot 2 (Serial Port) $38 $18 $01 $31 Slot 3 (80 Columns) $38 $18 $01 $88 Slot 4 (Mouse Port) $38 $18 $01 $20 Slot 7 (AppleTalk) $38 $18 $01 $31 ProDOS and SmartPort Devices $Cn01 $Cn03 $Cn05 $Cn07 Generic ProDOS Block Device $20 $00 $03 $xx SmartPort Device $20 $00 $03 $00 GLă)˛*˛+ / TN.MISC.009ZApple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #9: AppleSoft Real Variable Storage Revised by: Pete McDonald November 1988 Written by: Cameron Birse December 1986 This Technical Note discusses real variable storage in AppleSoft BASIC. _____________________________________________________________________________ In AppleSoft BASIC, real variables (non-array) are stored sequentially starting at the address pointed to by locations $69 and $6A. The first two bytes are the name of the variable, the third is the exponent, and the fourth through seventh are the mantissa. Exponent The top bit of this byte is the sign of the exponent. This sign bit is the opposite of normal sign bits, since zero is negative and one is positive. The remainder of the byte minus one is the value of the exponent (i.e., 84 is a positive exponent of 3). Mantissa The mantissa is a binary fraction with the first bit being the sign bit (normal this time with zero being positive and one negative), and the remaining bits are fractional values starting with .5, .25, .125, etc. The equation which follows is: 2^(Exponent-1) * 1.Mantissa Examples A = 3 (real variable equal to 3) The seven bytes look like: 41 00 Variable name = A 82 Exponent = 1 40 00 00 00 Mantissa = .5 which works out as: 2^1 * 1.5 = 3 B = 5 (real variable equal to 5) The seven bytes look like: 42 00 Variable name = B 83 Exponent = 2 20 00 00 00 Mantissa = .25 which works out as: 2^2 * 1.25 = 5 Further Reference o AppleSoft BASIC Programmer's Reference Manual GLă )˛*˛+ Ÿ TN.MISC.010ZApple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #10: 80-Column GetChar Routine Revised by: Pete McDonald November 1988 Written by: Cameron Birse December 1986 This Technical Note presents an 80-column GetChar routine. _____________________________________________________________________________ The following is an example of how to display a string on the 80-column screen, reposition the cursor at the beginning of the string, and use the right arrow to get characters which are already there or accept new characters in their place. The routine is a simple BASIC program which displays the string and repositions the cursor before getting incoming characters. If the character input is a right arrow, the program calls the assembly language routine to get the character from screen memory at the current cursor location. 10 PRINT CHR$ (4);"bload getchar.0": REM first install assembly routine 20 B$ = "hello" 30 PRINT CHR$ (4);"pr#3" 40 PRINT B$;:B$ = "" 50 A = PEEK (1403): REM get horiz location 60 A = A - 5: REM move cursor to beginning of string 70 POKE 1403,A 80 GET A$: REM get a character 90 IF A$ = CHR$ (21) THEN GOSUB 130: REM if char is forward arrow, handle with assembly routine (GETCHAR) 100 IF A$ = CHR$ (27) THEN 170: REM if esc key then we're done 110 PRINT A$;:B$ = B$ + A$ 120 GOTO 80 130 CALL 768: REM GETCHAR 140 A = PEEK (6) 150 A$ = CHR$ (A) 160 RETURN 170 PRINT : PRINT : PRINT B$: REM and we're done An assembled listing of the assembly language GetChar routine follows on the next page. SOURCE FILE #01 =>GETCHAR ----- NEXT OBJECT FILE NAME IS GETCHAR.0 0300: 0300 1 ORG $300 0300: C01F 2 RD80VID EQU $C01F ;80 COLUMN STATE 0300: C054 3 TXTPAGE1 EQU $C054 ;TURN OFF PAGE 2 (READ) 0300: C055 4 TXTPAGE2 EQU $C055 ;TURN ON PAGE 2 (READ) 0300: C000 5 CLR80COL EQU $C000 ;TURN OFF 80 STORE (WRITE) 0300: C001 6 SET80COL EQU $C001 ;TURN ON 80 STORE (WRITE) 0300: 0028 7 BASL EQU $28 ;BASE ADDRESS OF SCREEN LOCATION 0300: 0029 8 BASH EQU $29 0300: 057B 9 OURCH EQU $57B ;80 COLUMNS HORIZ. POSITION 0300: 05FB 10 OURCV equ $5fb ;80 col vertical pos 0300: 0006 11 char equ 6 ;place to hand character back to basic 0300: 12 * 0300: 13 ************************************************************* 0300: 14 * GETCHAR - This routine gets an ascii character from the * 0300: 15 * 80 column display memory of the Apple IIe. It assumes * 0300: 16 * that main memory is switched in and that the base addrs * 0300: 17 * of the line has already been calculated and resides * 0300: 18 * in BASL and BASH. It is meant to be called from BASIC * 0300: 19 * as follows: * 0300: 20 * CALL 768 * 0300: 21 * A = PEEK (6) * 0300: 22 * A$ = CHR$(A) * 0300: 23 * As you can see, the character is returned in location * 0300: 24 * $6 in zero page. This routine is offered as an example. * 0300: 25 * No guaranties are made regarding its fitness for any * 0300: 26 * purpose. By Cameron Birse 6/10/86 * 0300: 27 ************************************************************* 0300: 28 * 0300: 0300 29 getchr equ * ;get the char at the current cursor loc. 0300:A9 01 30 lda #$01 ;mask for horiz test 0302:2C 7B 05 31 bit OURCH ;are we in main or aux mem? 0305:D0 17 031E 32 bne main ;if bit 0 of OURCH is set, then main mem 0307: 0307 33 aux equ * 0307:AD 7B 05 34 lda OURCH ;get horiz pos. 030A:18 35 clc ;clear the carry for divide 030B:6A 36 ror a ;divide by two 030C:A8 37 tay ;put the result in y 030D:8D 01 C0 38 sta SET80COL ;turn on 80 store 0310:AD 55 C0 39 lda TXTPAGE2 ;flip to aux text page 0313:B1 28 40 lda (basl),y ;get the character 0315:85 06 41 sta char 0317:AE 54 C0 42 ldx TXTPAGE1 ;turn off aux text page 031A:8D 00 C0 43 sta CLR80COL ;turn off 80 store 031D:60 44 rts 031E: 031E 45 main equ * 031E:AD 7B 05 46 lda OURCH ;get horiz pos. 0321:18 47 clc ;clear the carry for divide 0322:6A 48 ror a ;divide by two 0323:A8 49 tay ;put the result in y 0324:B1 28 50 lda (basl),y ;get the character 0326:85 06 51 sta char 0328:60 52 rts Further Reference o Apple IIGS Firmware Reference o Apple IIe Technical Reference Manual o Apple IIc Technical Reference Manual GLă)˛*˛+ Ł TN.MISC.011ZApple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #11: Examining the $C800 Space from AppleSoft Revised by: Pete McDonald November 1988 Written by: John Bennett August 1987 This Technical Note discusses examining the $C800 space from AppleSoft BASIC with PEEK statements. _____________________________________________________________________________ Both the 6502 and 65816 microprocessors perform a false read during absolute indexed instructions. When AppleSoft interprets a PEEK statement, it performs an absolute-indexed LDA instruction with a base address such that a false read from $CFxx is performed. Some peripheral cards have been designed to deallocate their $C800 ROM space any time a $CF value is placed on the high- order address lines of the address bus. Therefore, if you use the AppleSoft PEEK statement to examine an address in the $C800 space of such a peripheral card, the $C800 space will be turned off when the statement is interpreted, and the value returned by the statement will not reflect the actual value in the $C800 ROM. The 65C02, on the other hand, has been designed so that a false read is not performed for an absolute-indexed LDA instruction. As a result, if the PEEK statement is used to examine the $C800 space of the same peripheral card on an enhanced Apple IIe (or any other Apple II with a 65C02 installed), the $C800 space will not be deallocated, and the value returned by the statement will accurately reflect the value in the $C800 ROM. If it is absolutely necessary to examine the $C800 space from an AppleSoft BASIC program, it is safer to use a assembly language routine to examine the addresses and pass the results to the BASIC application. GLă)˛*˛+  TN.MISC.012ZApple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #12: The Apple II Firmware WAIT Routine Revised by: Matt Deatherage November 1988 Written by: Matt Deatherage May 1988 This Technical Note expands on the already documented descriptions of the Apple II firmware WAIT routine, which guaranteed a minimum, not an exact, specified delay. _____________________________________________________________________________ As described in the Apple IIe Technical Reference Manual and the Apple IIc Technical Reference Manual, the WAIT routine located in ROM at $FCA8 waits for a certain amount of time before returning to the calling program. The delay is listed in the IIe manual as being 1/2(26+27A+5A^2), where A is the value in the accumulator when WAIT is called. The value returned by this expression is the number of clock cycles taken by the routine, not the amount of time that passes while it waits. To obtain the elapsed time in microseconds, you must multiply the result by the scaling factor 14 / 14.318181. Different formulas have appeared in different firmware listings published by Apple in the past, but the above formula is in all current publications, and has been verified as correct by Developer Technical Support. If there were nothing in the system except a 65C02 (or 65816) microprocessor, this formula would be completely accurate. However, this is not the case in an Apple II, as there are interrupts, changing system speeds, fast and slow RAM, and numerous other additions to the system that can cause extra overhead when a routine is executed. For these reasons, the WAIT routine should be used only as a minimum delay. It should not be expected to wait for exactly the time specified by the WAIT formula. The Apple IIGS Firmware Reference correctly notes this fact, as well as including the scaling factor (14 / 14.318181) to return the minimum delay in microseconds without further calculation. Further Reference o Apple IIGS Firmware Reference o Apple IIe Technical Reference Manual o Apple IIc Technical Reference Manual