Newsgroups: comp.sys.apple2.programmer Path: blue.weeg.uiowa.edu!news.uiowa.edu!uunet!haven.umd.edu!ames!waikato!comp.vuw.ac.nz!actrix.gen.nz!dempson From: dempson@actrix.gen.nz (David Empson) Subject: Re: [Q:] Can I use PEEK to find out what Apple I am using? Message-ID: Organization: Actrix Information Exchange References: <36q1f3$anj@panix2.panix.com> Date: Fri, 7 Oct 1994 08:59:02 GMT Lines: 262 In article <36q1f3$anj@panix2.panix.com>, Mark Mentovai wrote: > Common sense tells me that from Applesoft, I should be able to PEEK a few > memory locations and find out: 1) what type of Apple I am using; Yes, to a certain degree. You cannot officially identify a IIgs unless you poke in a small machine language routine which calls a routine in the ROM. Clones cannot reliably be identified - they will usually appear as a standard type of Apple II. I can see that there is another reply on this thread which may have useful information, but I haven't seen it, so I don't know what it says. The best source for this information is Apple II Miscellaneous Technical Note #7 (Apple II Family Identification). It documents the official ROM locations that can be PEEKed to identify the machine. Here is the table from that technote. All the numbers are in hex, but I've added decimal versions of the addresses, for use from BASIC. Machine $FBB3 $FB1E $FBC0 $FBDD $FBBE $FBBF 64435 64286 64448 64477 64446 64447 ------------------------------------------------------------------- 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 IIe Option Card $06 $E0 $02 $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 (special) Here is a list of decimal values for each of the hexadecimal numbers given in the table. $00 0 $02 2 $03 3 $04 4 $05 5 $06 6 $2F 47 $38 56 $60 96 $8A 138 $AD 173 $C1 193 $E0 224 $EA 234 $FF 255 You should first check $FBB3 (64435). This can be used to distinguish between an Apple ][, Apple ][+ (or Apple ///), and Apple IIe or later machines. To distinguish between a ][+ and Apple /// in emualtion mode, check location $FB1E (64286). To distinguish between an original Apple IIe, enhanced Apple IIe (or IIe emulation card for the Macintosh) and Apple IIc, check location $FBC0 (64448). To distinguish between an enhanced IIe and a IIe emulation card, check location $FBDD (64477). Any value other than 2 is an enhanced IIe. Location $FBBE (64446) contains the release number of the ROM for the IIe emulation card. Future versions of the emulated ROM should have values higher than 0 in this location. Location $FBBF (64447) contains the release number of the ROM for the IIc. Identifying a IIgs is not officially supported by performing ROM peeks. If you use the above peeks, the IIgs will appear to be an enhanced IIe. To identify a IIgs (including the ROM version) requires a small assembly language program. You could poke this in at location $300 (768), for example. 0300- A9 00 LDA #$00 0302- 85 00 STA $00 0304- 85 01 STA $01 0306- 38 SEC 0307- 20 1F FE JSR $FE1F 030A- B0 04 BCS $0310 030C- 84 01 STY $01 030E- E6 00 INC $00 0311- 60 RTS This routine will set location 0 to 0 if the machine is not a IIgs, or 1 if it is a IIgs. If so, location 1 contains the ROM version of the IIgs (0, 1 or 3). From BASIC, use code like this to poke in and call the routine. 5000 REM IDENTIFY A IIGS 5010 I = 768 5020 READ J: IF J < 0 THEN GOTO 5040 5030 POKE I,J: I = I + 1: GOTO 5020 5040 CALL 768 5050 GS = PEEK(0): REM 1 IF IIgs 5060 GV = PEEK(1): REM IIgs ROM VERSION 5070 RETURN 5080 DATA 169,0,133,0,133,1,56,32,31,254,176,4,132,1,230,0,96,-1 There is another way of identifying some machine types under ProDOS. There is a byte stored on the ProDOS global page called the "machine ID byte" ($BF98), which includes several flag bits indicating the type of machine, presence of an 80-column card and clock, and amount of memory. Accessing this from BASIC is a little messy because you have to break out the bit fields. Note: this will only work if your program is running under ProDOS. Here is a routine to break out the fields of the machine ID byte. 4000 REM BREAK UP THE PRODOS MACHINE ID BYTE 4010 ID = PEEK(49048) 4020 M1 = INT(ID / 64): REM MACHINE TYPE, PART 1 4030 ID = ID - MT * 64 4040 MEM = INT(ID / 16): REM MEMORY SIZE 4050 ID = ID - MEM * 16 4060 M2 = INT(ID / 8): REM MACHINE TYPE, PART 2 4070 ID = ID - INT(ID / 4) * 4 4080 C80 = INT(ID / 2): REM 80-COLUMN CARD 4090 CLK = ID - C80 * 2: REM CLOCK 4100 MT = M2 * 4 + M1: REM COMBINED MACHINE TYPE 4110 RETURN After calling this routine, the variables are set as follows: MEM = 1 (48k), 2 (64k) or 3 (128k) C80 = 1 (80-column card) or 0 (no 80-column card) CLK = 1 (clock) or 0 (no clock) MT = 0 (][), 1 (][+), 2 (IIe), 3 (/// emulation), 6 (IIc) Again, you cannot identify a IIgs. You need to make ROM peeks to distinguish between an original IIe, enhanced IIe, or IIe emulation card. You also need a ROM peek to determine the IIc ROM version. The memory test only knows about the IIe/IIc auxiliary 64k bank (on the extended 80-column card). It doesn't know about additional banks in a RAMWorks-style card, slot-based RAM cards such as the Apple II Memory Expansion Card or RamFactor, or IIgs memory. The 80-column card bit will only be set for IIe-compatible 80-column cards (i.e. IIe, IIc and IIgs). It may be clear in a IIe or IIgs if slot 3 is being used for another card, or if no auxiliary memory is present. Again, note that this code will only work if ProDOS is active. You can test for ProDOS by doing a PEEK of location 48896 ($BF00). If the returned value is 76 ($4C), then ProDOS is almost certainly present. (There is a small chance that some DOS 3.3 clone may have a JMP instruction at this location, but I'm not aware of any). > 2) the microprocessor installed This cannot be identified with a PEEK. You can make a few assumptions: - A ][, ][+ or /// in emulation mode may have a 6502, 65C02 or 65802. - A IIe (original or enhanced) may have a 6502, 65C02 or 65802. An original IIe will usually (but not always) have a 6502. An enhanced IIe will usually (but not always) have a 65C02. - A IIc may have a 65C02 or 65802. - A IIgs will have a 65816. To conclusively identify the processor requires another assembly language routine, as follows (taken from "Programming the 65816, et al, by Eyes & Lichty). 0320- A2 00 LDX #$00 0322- F8 SED 0323- A9 99 LDA #$99 0325- 18 CLC 0326- 69 01 ADC #$01 0328- 30 07 BMI $0331 032A- E8 INX 032B- 18 CLC 032C- FB XCE 032D- 90 02 BCC $0331 032F- FB XCE 0330- E8 INX 0331- D8 CLD 0332- 86 00 STX $00 0334- 60 RTS After calling this routine, location 0 contains a 0 for a 6502, 1 for a 65C02, or 2 for a 65802/65816. This routine relies on a "bug" in the 6502's decimal mode: it doesn't set the negative flag correctly after a decimal ADC operation. The 65C02 and 65802 are distinguished by checking if the "exchange carry and emulation mode" instruction works. On a 65C02, this acts as a NOP, so carry will still be clear. On a 65802 or 65816, it swaps the carry flag with the emulation mode flag, which should be a 1 (if not, the 65802/816 is in native mode, which shouldn't happen if this routine is called from BASIC or from an existing 8-bit assembly language program). You cannot easily distinguish between a 65802 and 65816, but there isn't much point anyway - the 65816 can only be used in a IIgs (and possibly some IIe memory expansion cards?), while the 65802 can only be used in 8-bit machines. There is a potential problem with the above routine: it will fail if you have a Rockwell 65C02 in the computer. Rockwell added a lot of extra bit-manipulation instructions to their version of the 65C02. These instructions are not compatible with a 65802 or 65816. One of the affected opcodes is $FB, which is XCE on the 65802/65816, but is BBS3 (branch if bit 3 is set) for the Rockwell 65C02. Apple never supplied Rockwell 65C02s, but someone may have installed one in their own machine. If you want to deal with this small chance, E-Mail me and I'll come up with a routine that can identify this processor safely. Here is a BASIC subroutine to implement the above routine. 6000 REM IDENTIFY THE PROCESSOR 6010 I = 800 6020 READ J: IF J < 0 THEN GOTO 6040 6030 POKE I,J: I = I + 1: GOTO 6020 6040 CALL 800 6050 CPU = PEEK(0): REM PROCESSOR (0 = 6502, 1 = 65C02, 2 = 65802/816) 6060 RETURN 6070 DATA 162,0,248,169,153,24,105,1,48,7,232,24,251,144,2,251,232,216 6080 DATA 134,0,96,-1 > 3) how much RAM is available. This is less easy. If ProDOS is present, you can use the Machine ID Byte code above to find out whether the auxiliary 64k memory is present in a IIe. If your program might be running in DOS 3.3 on a ][ or ][+, it may have to identify less than 48k RAM. This is difficult to do in a non-destructive fashion from a BASIC program. It is much safer to do this with a carefully written machine code program running at a known location. There is one possible shortcut here: it is quite easy to locate DOS 3.3, which is usually at the top of the main RAM (but might not be, e.g. if a non-master disk initialized on a machine with a small amount of RAM is booted on a machine with more RAM). This also has complications if DOS has been relocated into the language card. If you don't mind assuming that you have 48k of main RAM, then all that is left on a ][ or ][+ is identifying whether a language card is installed. This requires a machine language routine again. On a IIe, you may need to test for the presence of the auxiliary 64k bank (and/or the 1k RAM provided by the 80-column text card). Again, this requires a machine language routine. Can you be more specific about exactly what you want to test for? Are you interested in identifying other types of memory, e.g. auxiliary slot multi-bank RAM cards, standard slot RAM cards, and IIgs memory? All of these are complicated. Here endeth the lesson. :-) -- David Empson dempson@actrix.gen.nz Snail mail: P.O. Box 27-103, Wellington, New Zealand