home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!dtix!darwin.sura.net!news.udel.edu!bach.udel.edu!lecates
- From: lecates@bach.udel.edu (Roy LeCates)
- Newsgroups: comp.sys.apple2
- Subject: Re: GS id
- Message-ID: <C07FLy.5Jz@news.udel.edu>
- Date: 2 Jan 93 02:15:34 GMT
- References: <JOHNP.93Jan1172507@silver.lcs.mit.edu>
- Sender: usenet@news.udel.edu
- Organization: University of Delaware
- Lines: 543
- Nntp-Posting-Host: bach.udel.edu
-
- In article <JOHNP.93Jan1172507@silver.lcs.mit.edu> johnp@silver.lcs.mit.edu (John Palaima) writes:
- >I am interested in telling WHAT machine a program is running on to activate app
- >ropriate title screens text coloring etc on the GS and //e and i need the addre
- >sses to poke.. I trie both $fbb3 and $fbc0 on my //e and my friends GS and THE\
- >Y MATCH.. i was told there are a total of 4 bytes i need to check..where are the other 2...
-
- That information is located in the Apple II Miscellaneous Tech Notes.
- Just for convenience, here it is!
-
- ------------------------------------------------------------
-
- Apple II
- Technical Notes
- _____________________________________________________________________________
- Developer Technical Support
-
-
- Apple II Miscellaneous
- #2: Apple II Family Identification Routines 2.2
-
- Revised by: Jim Luther May 1991
- 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.
-
- Changes since November 1988: Converted the identification routine from Apple
- II Assembler/Editor (EDASM) source code to Apple IIgs Programmer's Workshop
- (APW) Assembler source code. Added the Apple IIe Card for the Macintosh LC
- to the identification routine's lookup table and memory check routine. Made
- minor corrections to text.
- _____________________________________________________________________________
-
-
- 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.2) 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
- $06 = Apple IIe Card for the Macintosh LC
-
- 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 three versions of the IIgs ROM (there
- will always be some owners who have not yet upgraded from ROM 00 to ROM
- 01). These versions are identified starting at $01 for the earliest.
- Therefore, the current IIc will return ROMlevel = $05, the current IIgs
- will return ROMlevel = $03, 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
-
-
- keep ID2.2
-
- list on
-
- org $2000
-
- longa off
- longi off
-
- *********************************************
- * *
- * Apple II Family Identification Program *
- * *
- * Version 2.2 *
- * *
- * March, 1990 *
- * *
- * Includes support for the Apple IIe Card *
- * for the Macintosh LC. *
- * *
- *********************************************
-
-
- ; First, some global equates for the routine:
-
- PROGRAM start
-
- IIplain equ $01 ;Apple II
- IIplus equ $02 ;Apple II+
- IIIem equ $03 ;Apple /// in emulation mode
- IIe equ $04 ;Apple IIe
- IIc equ $05 ;Apple IIc
- IIeCard equ $06 ;Apple IIe Card for the Macintosh LC
-
- safe equ $0001 ;start of code relocated to zp
- location equ $06 ;zero page location to use
-
- test1 equ $AA ;test byte #1
- test2 equ $55 ;lsr of test1
- test3 equ $88 ;test byte #3
- test4 equ $EE ;test byte #4
-
- begpage1 equ $400 ;beginning of text page 1
- begpage2 equ $800 ;beginning of text page 2
- begsprse equ $C00 ;byte after text page 2
-
- clr80col equ $C000 ;disable 80-column store
- set80col equ $C001 ;enable 80-column store
- rdmainram equ $C002 ;read main ram
- rdcardram equ $C003 ;read aux ram
- wrmainram equ $C004 ;write main ram
- wrcardram equ $C005 ;write aux ram
- rdramrd equ $C013 ;are we reading aux ram?
- rdaltzp equ $C016 ;are we reading aux zero page?
- rd80col equ $C018 ;are we using 80-columns?
- rdtext equ $C01A ;read if text is displayed
- rdpage2 equ $C01C ;read if page 2 is displayed
- txtclr equ $C050 ;switch in graphics
- txtset equ $C051 ;switch in text
- txtpage1 equ $C054 ;switch in page 1
- txtpage2 equ $C055 ;switch in page 2
- ramin equ $C080 ;read LC bank 2, write protected
- romin equ $C081 ;read ROM, 2 reads write enable LC
- lcbank1 equ $C08B ;LC bank 1 enable
-
- lc1 equ $E000 ;bytes to save for LC
- lc2 equ $D000 ;save/restore routine
- lc3 equ $D400
- lc4 equ $D800
-
- idroutine equ $FE1F ;IIgs id routine
-
- ; Start by saving the state of the language card banks and
- ; by switching in main ROM.
-
- strt php ;save the processor state
- sei ;before disabling interrupts
- lda lc1 ;save four bytes from
- sta save ;ROM/RAM area for later
- lda lc2 ;restoring of RAM/ROM
- sta save+1 ;to original condition
- lda lc3
- sta save+2
- lda lc4
- sta save+3
- lda $C081 ;read ROM
- lda $C081
- lda #0 ;start by assuming unknown machine
- sta machine
- sta romlevel
-
- IdStart lda location ;save zero page locations
- sta save+4 ;for later restoration
- lda location+1
- sta save+5
- lda #$FB ;all ID bytes are in page $FB
- sta location+1 ;save in zero page as high byte
- ldx #0 ;init pointer to start of ID table
- loop lda IDTable,x ;get the machine we are testing for
- sta machine ;and save it
- lda IDTable+1,x ;get the ROM level we are testing for
- sta romlevel ;and save it
- ora machine ;are both zero?
- beq matched ;yes - at end of list - leave
-
- loop2 inx ;bump index to loc/byte pair to test
- inx
- lda IDTable,x ;get the byte that should be in ROM
- beq matched ;if zero, we're at end of list
- sta location ;save in zero page
-
- ldy #0 ;init index for indirect addressing
- lda IDTable+1,x ;get the byte that should be in ROM
- cmp (Location),y ;is it there?
- beq loop2 ;yes, so keep on looping
-
- loop3 inx ;we didn't match. Scoot to the end of the
- inx ;line in the ID table so we can start
- lda IDTable,x ;checking for another machine
- bne loop3
- inx ;point to start of next line
- bne loop ;should always be taken
-
- matched anop
-
- ; Here we check the 16-bit ID routine at idroutine ($FE1F). If it
- ; returns with carry clear, we call it again in 16-bit
- ; mode to provide more information on the machine.
-
- idIIgs sec ;set the carry bit
- jsr idroutine ;Apple IIgs ID Routine
- bcc idIIgs2 ;it's a IIgs or equivalent
- jmp IIgsOut ;nope, go check memory
- idIIgs2 lda machine ;get the value for machine
- ora #$80 ;and set the high bit
- sta machine ;put it back
- clc ;get ready to switch into native mode
- xce
- php ;save the processor status
- rep #$30 ;sets 16-bit registers
- longa on
- longi on
- jsr idroutine ;call the ID routine again
- sta IIgsA ;16-bit store!
- stx IIgsX ;16-bit store!
- sty IIgsY ;16-bit store!
- plp ;restores 8-bit registers
- xce ;switches back to whatever it was before
- longa off
- longi off
-
- ldy IIgsY ;get the ROM vers number (starts at 0)
- cpy #$02 ;is it ROM 01 or 00?
- bcs idIIgs3 ;if not, don't increment
- iny ;bump it up for romlevel
- idIIgs3 sty romlevel ;and put it there
- cpy #$01 ;is it the first ROM?
- bne IIgsOut ;no, go on with things
- lda IIgsY+1 ;check the other byte too
- bne IIgsOut ;nope, it's a IIgs successor
- lda #$7F ;fix faulty ROM 00 on the IIgs
- sta IIgsA
- IIgsOut anop
-
- ******************************************
- * This part of the code checks for the *
- * memory configuration of the machine. *
- * If it's a IIgs, we've already stored *
- * the total memory from above. If it's *
- * a IIc or a IIe Card, we know it's *
- * 128K; if it's a ][+, we know it's at *
- * least 48K and maybe 64K. We won't *
- * check for less than 48K, since that's *
- * a really rare circumstance. *
- ******************************************
-
- exit lda machine ;get the machine kind
- bmi exit128 ;it's a 16-bit machine (has 128K)
- cmp #IIc ;is it a IIc?
- beq exit128 ;yup, it's got 128K
- cmp #IIeCard ;is it a IIe Card?
- beq exit128 ;yes, it's got 128K
- cmp #IIe ;is it a IIe?
- bne contexit ;yes, go muck with aux memory
- jmp muckaux
- contexit cmp #IIIem ;is it a /// in emulation?
- bne exitII ;nope, it's a ][ or ][+
- lda #48 ;/// emulation has 48K
- jmp exita
- exit128 lda #128 ;128K
- exita sta memory
- exit1 lda lc1 ;time to restore the LC
- cmp save ;if all 4 bytes are the same
- bne exit2 ;then LC was never on so
- lda lc2 ;do nothing
- cmp save+1
- bne exit2
- lda lc3
- cmp save+2
- bne exit2
- lda lc4
- cmp save+3
- beq exit6
- exit2 lda $C088 ;no match! so turn first LC
- lda lc1 ;bank on and check
- cmp save
- beq exit3
- lda $C080
- jmp exit6
- exit3 lda lc2
- cmp save+1 ;if all locations check
- beq exit4 ;then do more more else
- lda $C080 ;turn on bank 2
- jmp exit6
- exit4 lda lc3 ;check second byte in bank 1
- cmp save+2
- beq exit5
- lda $C080 ;select bank 2
- jmp exit6
- exit5 lda lc4 ;check third byte in bank 1
- cmp save+3
- beq exit6
- lda $C080 ;select bank 2
- exit6 plp ;restore interrupt status
- lda save+4 ;put zero page back
- sta location
- lda save+5 ;like we found it
- sta location+1
- rts ;and go home.
-
- exitII lda lcbank1 ;force in language card
- lda lcbank1 ;bank 1
- ldx lc2 ;save the byte there
- lda #test1 ;use this as a test byte
- sta lc2
- eor lc2 ;if the same, should return zero
- bne noLC
- lsr lc2 ;check twice just to be sure
- lda #test2 ;this is the shifted value
- eor lc2 ;here's the second check
- bne noLC
- stx lc2 ;put it back!
- lda #64 ;there's 64K here
- jmp exita
- noLC lda #48 ;no restore - no LC!
- jmp exita ;and get out of here
-
- muckaux ldx rdtext ;remember graphics in X
- lda rdpage2 ;remember current video display
- asl A ;in the carry bit
- lda #test3 ;another test character
- bit rd80col ;remember video mode in N
- sta set80col ;enable 80-column store
- php ;save N and C flags
- sta txtpage2 ;set page two
- sta txtset ;set text
- ldy begpage1 ;save first character
- sta begpage1 ;and replace it with test character
- lda begpage1 ;get it back
- sty begpage1 ;and put back what was there
- plp
- bcs muck2 ;stay in page 2
- sta txtpage1 ;restore page 1
- muck1 bmi muck2 ;stay in 80-columns
- sta $c000 ;turn off 80-columns
- muck2 tay ;save returned character
- txa ;get graphics/text setting
- bmi muck3
- sta txtclr ;turn graphics back on
- muck3 cpy #test3 ;finally compare it
- bne nocard ;no 80-column card!
- lda rdramrd ;is aux memory being read?
- bmi muck128 ;yup, there's 128K!
- lda rdaltzp ;is aux zero page used?
- bmi muck128 ;yup!
- ldy #done-start
- move ldx start-1,y ;swap section of zero page
- lda |safe-1,y ;code needing safe location during
- stx safe-1,y ;reading of aux mem
- sta start-1,Y
- dey
- bne move
- jmp |safe ;jump to safe ground
- back php ;save status
- ldy #done-start ;move zero page back
- move2 lda start-1,y
- sta |safe-1,y
- dey
- bne move2
- pla
- bcs noaux
- isaux jmp muck128 ;there is 128K
-
- * You can put your own routine at "noaux" if you wish to
- * distinguish between 64K without an 80-column card and
- * 64K with an 80-column card.
-
- noaux anop
- nocard lda #64 ;only 64K
- jmp exita
- muck128 jmp exit128 ;there's 128K
-
- * This is the routine run in the safe area not affected
- * by bank-switching the main and aux RAM.
-
- start lda #test4 ;yet another test byte
- sta wrcardram ;write to aux while on main zero page
- sta rdcardram ;read aux ram as well
- sta begpage2 ;check for sparse memory mapping
- lda begsprse ;if sparse, these will be the same
- cmp #test4 ;value since they're 1K apart
- bne auxmem ;yup, there's 128K!
- asl begsprse ;may have been lucky so we'll
- lda begpage2 ;change the value and see what happens
- cmp begsprse
- bne auxmem
- sec ;oops, no auxiliary memory
- bcs goback
- auxmem clc
- goback sta wrmainram ;write main RAM
- sta rdmainram ;read main RAM
- jmp back ;continue with program in main mem
- done nop ;end of relocated program marker
-
-
- * The storage locations for the returned machine ID:
-
- machine ds 1 ;the type of Apple II
- romlevel ds 1 ;which revision of the machine
- memory ds 1 ;how much memory (up to 128K)
- IIgsA ds 2 ;16-bit field
- IIgsX ds 2 ;16-bit field
- IIgsY ds 2 ;16-bit field
- save ds 6 ;six bytes for saved data
-
- IDTable dc I1'1,1' ;Apple ][
- dc H'B3 38 00'
-
- dc I1'2,1' ;Apple ][+
- dc H'B3 EA 1E AD 00'
-
- dc I1'3,1' ;Apple /// (emulation)
- dc H'B3 EA 1E 8A 00'
-
- dc I1'4,1' ;Apple IIe (original)
- dc H'B3 06 C0 EA 00'
-
- ; Note: You must check for the Apple IIe Card BEFORE you
- ; check for the enhanced Apple IIe since the first
- ; two identification bytes are the same.
-
- dc I1'6,1' ;Apple IIe Card for the Macintosh LC (1st
- release)
- dc H'B3 06 C0 E0 DD 02 BE 00 00'
-
- dc I1'4,2' ;Apple IIe (enhanced)
- dc H'B3 06 C0 E0 00'
-
- dc I1'5,1' ;Apple IIc (original)
- dc H'B3 06 C0 00 BF FF 00'
-
- dc I1'5,2' ;Apple IIc (3.5 ROM)
- dc H'B3 06 C0 00 BF 00 00'
-
- dc I1'5,3' ;Apple IIc (Mem. Exp)
- dc H'B3 06 C0 00 BF 03 00'
-
- dc I1'5,4' ;Apple IIc (Rev. Mem. Exp.)
- dc H'B3 06 C0 00 BF 04 00'
-
- dc I1'5,5' ;Apple IIc Plus
- dc H'B3 06 C0 00 BF 05 00'
-
- dc I1'0,0' ;end of table
-
- end
-
-
- Further Reference
- _____________________________________________________________________________
- o Apple II Miscellaneous Technical Note #7, Apple II Family Identification
-
- --
- ------------------------------------------------------------------
- Roy M. LeCates EE Undergraduate lecates@bach.udel.edu
- University of Delaware Electrical Engineering and Computer Science
- ------------------------------------------------------------------
-