====== Apple ][ ======
The bulk of this page will focus on the Enhanced IIe, both because it was the most popular of the line and because it is the model we have.
===== Memory layout =====
Despite the [[.:6502]]'s 64K address space, an Apple II could have significantly more RAM and ROM than that. The IIe came standard with 64K built into the motherboard, which could be doubled with an extended 80-column text card. Other peripheral cards tended to contain their own onboard RAM/ROM. All of this extra memory is accessible through bank switching.
* \$0000--\$00FF: [[#zero page]]
* \$0100--\$01FF: stack, [[#Applesoft]] temporary storage
* \$0200--\$02FF: keyboard/diskette input buffer
* \$0300--\$03CF: user assembly programs
* \$03D0--\$03FF: subroutine vectors for DOS, Applesoft, and system monitor
* \$0400--\$07FF: text/low-res page 1
* \$0800--\$0BFF: text/low-res page 2; more commonly used for Applesoft program storage
* \$0C00--\$1FFF: free for use
* \$2000--\$3FFF: high-res page 1
* \$4000--\$5FFF: high-res page 2
* \$6000--\$BFFF: normally free for use; \$9600 and above is used by DOS
* \$C000--\$C0FF: [[#I/O]]
* \$C100--\$C1FF: slot 1 ROM
* \$C200--\$C2FF: slot 2 ROM
* \$C300--\$C3FF: slot 3 ROM
* \$C400--\$C4FF: slot 4 ROM
* \$C500--\$C5FF: slot 5 ROM
* \$C600--\$C6FF: slot 6 ROM
* \$C700--\$C7FF: slot 7 ROM
==== Zero page ====
==== I/O ====
Soft switches, status, and I/O addresses [(Little1985)]
^ Address ^ Direction ^ Symbolic name ^ Description ^
| \$C000 | W | ''80STOREOFF'' | Allow ''PAGE2'' to switch between video page 1 and page 2 |
| | R | ''KBD'' | Keyboard data (bits 0--6) |
| | R7 | ''KBD'' | 1 = keyboard stroke is on \\ 0 = keyboard stroke is off |
| \$C001 | W | ''80STOREON'' | Allow ''PAGE2'' to switch between main and aux video memory |
| \$C002 | W | ''RAMRDOFF'' | Read-enable main memory from \$0200--\$BFFF |
| \$C003 | W | ''RAMRDON'' | Read-enable aux memory from \$0200--\$BFFF |
| \$C004 | W | ''RAMWRTOFF'' | Write-enable main memory from \$0200--\$BFFF |
| \$C005 | w | ''RAMWRTON'' | Write-enable aux memory from \$0200--\$BFFF |
| \$C006 | W | ''INTCXROMOFF'' | Enable slot ROM from \$C100--\$CFFF |
| \$C007 | W | ''INTCXROMON'' | Enable main ROM from \$C100--\$CFFF |
| \$C008 | W | ''ALTZPOFF'' | Enable main memory from \$0000--\$01FF and make main BSR available |
| \$C009 | W | ''ALTZPON'' | Enable aux memory from \$0000--\$01FF and make aux BSR available |
| \$C00A | W | ''SLOTC3ROMOFF'' | Enable main ROM from \$C300--\$C3FF |
| \$C00B | W | ''SLOTC3ROMON'' | Enable slot ROM from \$C300--\$C3FF |
| \$C00C | W | ''80COLOFF'' | Turn off 80-column display |
| \$C00D | W | ''80COLON'' | Turn on 80-column display |
| \$C00E | W | ''ALTCHARSETOFF'' | Turn off alternate characters |
| \$C00F | W | ''ALTCHARSETON'' | Turn on alternate characters |
| \$C010 | R7 | ''AKD'' | 1 = a key is being pressed \\ 0 = all keys are released |
| | RW | ''KBDSTRB'' | Clear keyboard strobe |
| \$C011 | R7 | ''BSRBANK2'' | 1 = bank 2 of BSR is available \\ 0 = bank 1 of BSR is available |
| \$C012 | R7 | ''BSRREADRAM'' | 1 = BSR is active for read operations \\ 0 = \$D000--\$FFFF ROM is active for read operations |
| \$C013 | R7 | ''RAMRD'' | 0 = main \$0200--\$BFFF is active for read operations \\ 1 = aux \$0200--\$BFFF is active for read operations |
| \$C014 | R7 | ''RAMWRT'' | 0 = main \$0200--\$BFFF is active for write operations \\ 1 = aux \$0200--\$BFFF is active for write operations |
| \$C015 | R7 | ''INTCXROM'' | 1 = main \$C100--\$CFFF ROM is active \\ 0 = slot \$C100--\$C1FF ROM is active |
| \$C016 | R7 | ''ALTZP'' | 1 = aux zero page & stack are active; aux BSR is available \\ 0 = main zero page & stack is active; main BSR is available |
| \$C017 | R7 | ''SLOTC3ROM'' | 1 = slot \$C3 ROM is active \\ 0 = main \$C3 ROM is active |
| \$C018 | R7 | ''80STORE'' | 1 = ''PAGE2'' switches main/aux \\ 0 = ''PAGE2'' switches video pages |
| \$C019 | R7 | ''VERTBLANK'' | 1 = vertical retrace is on \\ 0 = vertical retrace is off |
| \$C01A | R7 | ''TEXT'' | 1 = a text mode is active \\ 0 = a graphics mode is active |
| \$C01B | R7 | ''MIXED'' | 1 = mixed graphics and text \\ 0 = full-screen graphics |
| \$C01C | R7 | ''PAGE2'' | 1 = video page 2 selected OR aux video page selected |
| \$C01D | R7 | ''HIRES'' | 1 = high-res graphics \\ 0 = low-res graphics |
| \$C01E | R7 | ''ALTCHARSET'' | 1 - alternate character set is on \\ 0 = primary character set is on |
| \$C01F | R7 | ''80COL'' | 1 = 80-column display is on \\ 0 = 40-column display is on |
| \$C020 | R | ''CASSOUT'' | Toggle the state of the cassette output port |
| \$C021 |
| \$C022 |
| \$C023 |
| \$C024 |
| \$C025 |
| \$C026 |
| \$C027 |
| \$C028 |
| \$C029 |
| \$C02A |
| \$C02B |
| \$C02C |
| \$C02D |
| \$C02E |
| \$C02F |
| \$C030 | R | ''SPEAKER'' | Toggle the state of the speaker |
| \$C031 |
| \$C032 |
| \$C033 |
| \$C034 |
| \$C035 |
| \$C036 |
| \$C037 |
| \$C038 |
| \$C039 |
| \$C03A |
| \$C03B |
| \$C03C |
| \$C03D |
| \$C03E |
| \$C03F |
| \$C040 | R | ''GCSTROBE'' | Generate a game I/O connector strobe signal |
| \$C041 |
| \$C042 |
| \$C043 |
| \$C044 |
| \$C045 |
| \$C046 |
| \$C047 |
| \$C048 |
| \$C049 |
| \$C04A |
| \$C04B |
| \$C04C |
| \$C04D |
| \$C04E |
| \$C04F |
| \$C050 | RW | ''TEXTOFF'' | Select graphics mode |
| \$C051 | RW | ''TEXTON'' | Select text mode |
| \$C052 | RW | ''MIXEDOFF'' | Use full screen for graphics |
| \$C053 | RW | ''MIXEDON'' | User graphics with four lines of text |
| \$C054 | RW | ''PAGE2OFF'' | Select page 1 display (or main video memory) |
| \$C055 | RW | ''PAGE2ON'' | Select page 2 display (or aux video memory) |
| \$C056 | RW | ''HIRESOFF'' | Select low-res graphics |
| \$C057 | RW | ''HIRESON'' | Select high-res graphics |
| \$C058 | RW | ''CLRAN0'' | Turn off annunciator 0 |
| \$C059 | RW | ''SETAN0'' | Turn on annunciator 0 |
| \$C05A | RW | ''CLRAN1'' | Turn off annunciator 1 |
| \$C05B | RW | ''SETAN1'' | Turn on annunciator 1 |
| \$C05C | RW | ''CLRAN2'' | Turn off annunciator 2 |
| \$C05D | RW | ''SETAN1'' | Turn on annunciator 2 |
| \$C05E | RW | ''CLRAN3'' | Turn off annunciator 3 |
| \$C05F | RW | ''SETAN1'' | Turn on annunciator 3 |
| \$C060 | R7 | ''CASSIN'' | 1 = cassette input is on |
| \$C061 | R7 | ''PB0'' | 1 = push button 0 is on |
| \$C062 | R7 | ''PB1'' | 1 = push button 1 is on |
| \$C063 | R7 | ''PB2'' | 1 = push button 2 is on |
| \$C064 | R7 | ''GC0'' | 0 = game controller 0 timed out |
| \$C065 | R7 | ''GC1'' | 0 = game controller 1 timed out |
| \$C066 | R7 | ''GC2'' | 0 = game controller 2 timed out |
| \$C067 | R7 | ''GC3'' | 0 = game controller 3 timed out |
| \$C068 | R | ''GCRESET'' | Reset the game controllers |
| \$C069 |
| \$C06A |
| \$C06B |
| \$C06C |
| \$C06D |
| \$C06E |
| \$C06F |
| \$C070 |
| \$C071 |
| \$C072 |
| \$C073 |
| \$C074 |
| \$C075 |
| \$C076 |
| \$C077 |
| \$C078 |
| \$C079 |
| \$C07A |
| \$C07B |
| \$C07C |
| \$C07D |
| \$C07E |
| \$C07F |
| \$C080 | R | ''READBSR2'' | Select bank 2, read BSR, write-protect BSR |
| \$C081 | RR | ''WRITEBSR2'' | Select bank 2, read ROM, write-enable BSR |
| \$C082 | R | ''OFFBSR2'' | Select bank 2, read ROM, write-protect BSR |
| \$C083 | RR | ''RDWRBSR2'' | Select bank 2, read BSR, write-enable BSR |
| \$C084 |
| \$C085 |
| \$C086 |
| \$C087 |
| \$C088 | R | ''READBSR1'' | Select bank 1, read BSR, write-protect BSR |
| \$C089 | RR | ''WRITEBSR1'' | Select bank 1, read ROM, write-enable BSR |
| \$C08A | R | ''OFFBSR1'' | Select bank 1, read ROM, write-protect BSR |
| \$C08B | RR | ''RDWRBSR1'' | Select bank 1, read BSR, write-enable BSR |
| \$C08C |
| \$C08D |
| \$C08E |
| \$C08F |
| \$C090--\$C09F | | | Reserved for use by slot 1 |
| \$C0A0--\$C0AF | | | Reserved for use by slot 2 |
| \$C0B0--\$C0BF | | | Reserved for use by slot 3 |
| \$C0C0--\$C0CF | | | Reserved for use by slot 4 |
| \$C0D0--\$C0DF | | | Reserved for use by slot 5 |
| \$C0E0--\$C0EF | | | Reserved for use by slot 6 |
| \$C0F0--\$C0FF | | | Reserved for use by slot 7 |
==== Video memory ====
==== Other locations ====
To determine the exact model and version, examine \$FBB3 and \$FBC0. If \$FBB3 contains \$06, the computer is a IIe or IIc. \$FBC0 can contain the following values: [(Little1985)]
* \$EA: IIe with original ROMs
* \$E0: IIe with enhanced ROMs
* \$00: IIc
===== Programming =====
==== Applesoft ====
==== Integer BASIC ====
==== System monitor ====
Monitor commands [(Little1985)]
===== Operating systems =====
==== DOS 3.3 ====
==== ProDOS 8 ====
==== CP/M ====
In order to run CP/M, a Z80 soft card is required. While we do not currently possess one, it should be possible to find one online --- or we may be able to assemble our own from scratch using available schematics [(msc80scschem)].
===== Peripheral cards =====
As with the rest of this page, we will focus on cards our machine has installed.
The Apple IIe has eight expansion slots (7 regular and 1 auxiliary). This alone is indicative of a completely different era of Apple's history, one in which the engineering team held more sway than the marketing team.
==== Apple extended 80-column card ====
==== Disk II interface ====
==== Super Serial ====
==== Applied Engineering RAMFactor ====
A RAM disk/memory expansion. ProDOS automatically registers it as a volume named ''/RAMs'' (where ''s'' is the slot number where the card is installed), and AppleWorks appears to relocate some of itself onto the card. Because the card uses volatile RAM, **anything saved to the card will be lost when the computer is switched off** unless external power is applied to the card. Applied Engineering sold a device to do just that, but we do not have one, nor do we particularly wish to.
The particular revision we have contains a total of 1 MB of RAM.
===== Sample code =====
==== Determining current execution page ====
This snippet is particularly useful for writing peripheral card ROM, where the code needs to function irrespective of its installed slot. It works by calling a "subroutine" consisting entirely of an ''RTS'' (\$FF58 is one of a handful of addresses that Apple guaranteed will contain an ''RTS'' instruction). Upon returning, ''$100+S'' contains the high byte of the return (calling) address.
If calling from a peripheral card, the slot number can be identified by ANDing the result with 0F.
; stores the high byte of the execution address in the A register
; clobbers: A, X
getpage:
JSR $FF58 ; push the return address to the stack
TSX ; use stack pointer as index to stack page
LDA $100,X ; get high byte of return address
RTS
==== Writing bytes as hexadecimal ====
We don't have to reinvent the wheel for this one --- the [[#system monitor]] includes a handy routine called ''PRBYTE'' (\$FDDA) for just this task, shown below [(a2eenhpg)]:
PRBYTE: PHA
LSR A
LSR A
LSR A
LSR A
JSR PRHEXZ ; =$FDE5
PLA
PRHEX: AND #$0F
PRHEXZ: ORA #$B0
CMP #$BA
BCC COUT ; =$FDED
ADC #$06
COUT: JMP (CSWL) ; =$0036, user output routine
To make use of it from Applesoft, load the following anywhere into memory:
JSR $DEBE ; CHKCOM - skips comma in Applesoft parsing
JSR $DFE3 ; GETPNT - get pointer to variable data, put it in $83...$84
LDY #$00
LDA ($83),Y ; get high byte from VARPNT
JSR $FDDA ; PRBYTE
INY
LDA ($83),Y ; get low byte from VARPNT
JMP $FDDA ; PRBYTE (will RTS for us)
Then it can be called from Applesoft like so (assuming the program was loaded at \$0300):
10 LET X% = 69
20 CALL 768,X%
==== Generate the Mandelbrot set ====
Useful as a benchmark. The computer must be in 80-column mode for it to display properly.
10 FOR Y=-12 TO 12
20 FOR X=-39 TO 39
30 CA=X*0.0458
40 CB=Y*.08333
50 A=CA
60 B=CB
70 FOR I = 0 TO 15
80 T=A*A-B*B+CA
90 B=2*A*B+CB
100 A=T
110 IF(A*A+B*B)>4 GOTO 200
120 NEXT I
130 PRINT " ";
140 GOTO 210
200 IF I>9 THEN I=I+7
205 PRINT CHR$(48+I);
210 NEXT X
220 PRINT
230 NEXT Y
===== Resources =====
* [[https://apple2online.com]]
* [[http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/|Apple II Documentation Project]]
* [[https://adtpro.com/index.html|ADTPro]]
===== Notes =====
[(Little1985>//[[https://apple2online.com/wp-content/uploads/Inside-the-Apple-IIe.pdf|Inside the Apple IIe]]// (1985))]
[(a2etechnotes>[[https://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Computers/Apple%20II/Apple%20IIe/Documentation/Apple%20IIe%20Technical%20Notes.pdf|Apple IIe Technical Notes]])]
[(a2etechrefmanual>[[https://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Computers/Apple%20II/Apple%20IIe/Manuals/Apple%20IIe%20Technical%20Reference%20Manual.pdf|Apple IIe Technical Reference Manual]])]
[(msc80scschem>https://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Interface%20Cards/Z80%20Cards/Microsoft%20SoftCard/Schematics/)]
[(a2eenhpg>[[https://ia804504.us.archive.org/19/items/about-your-enhanced-apple-iie-programmers-guide/About%20Your%20Enhanced%20Apple%20IIe%20Programmer%27s%20Guide.pdf|About Your Enhanced Apple IIe: Programmer's Guide]])]
[(Sather1985>[[https://ia800702.us.archive.org/18/items/Understanding_the_Apple_IIe/Understanding_the_Apple_IIe.pdf|Understanding the Apple IIe]] (1985))]
[(usingprodos>[[https://mirrors.apple2.org.za/ftp.apple.asimov.net/documentation/os/prodos/Using%20ProDOS%20-%20The%20Multilayered%20DOS.pdf|Using ProDOS]])]
[(allpinoutsa2>[[https://allpinouts.org/pinouts/connectors/buses/apple-ii-slot/]])]
~~REFNOTES~~