Vinace documentation Introduction Vinace is for VINtage Apple Computer Emulator. For now, it is an Apple //e 64Ko emulator. It should easily evolve to an any Apple ][ model emulator. This document contains two parts. The Using Vinace explains how to use Vinace and the Inside Vinace tells about how Vinace works. This document is still being written, it is not a definitive version. Many information may be missing. Using Vinace Quick start If you are in a hurry, here are the directions for using Vinace. To start Vinace, just launch vinace from inside its directory. To stop Apple from reading from disk drive, press Ctrl - Pause. To restart the Apple, press simultaneously Left Alt - Ctrl - Pause. To insert a disk, just drag the disk image file onto the disk drive. Keyboard Here are the keys on the original Apple //e keyboard : Apple //e keyboard keys GroupKeysLettersA to Z (uppercase, lowercase and control)Numbers0 to 9Symbols! @ # $ % ^ & * ( ) - _ + = { } [ ] : ; " ' ~ `| \ < > , . ? /Other keysEsc, Tab, Return, Del, Arrows (left, right, down and up)Special keyReset, Open apple, Closed apple
The virtual Apple keyboard is mapped to your computer keyboard. Letters (uppercase, lowercase and control), numbers, symbols and other keys are directly mapped to corresponding keys. The Open apple and Closed apple keys are mapped to left Alt and right Alt keys. The Ctrl - Reset keys combination is mapped to Ctrl - Pause keys (the Reset key alone had no effect on Apple keyboard). This mean that, if you want to restart the Apple //e, you have to press left Alt - Ctrl - Pause where, on the original keyboard, you were pressing Open apple - Ctrl - Reset.
Joystick There is a simple joystick emulation in Vinace, using the numeric keypad. Actually, the Apple joystick is able to detect 256 positions on each axis. The Vinace joystick is only able to emulate three positions on each axis (0, 128 and 255). This would fit to most of the games but should not be enough for those making an accurate use of joystick. The key "5" on the numeric keypad is the center position. Key "8" is for up, key "2" for down, key "4" for left and "6" for right. Diagonal keys (7, 9, 1 and 3)works also.
Numeric keypad joystick emulation The numeric keypad joystick emulation : how keys are binded to joystick positions.
There is no button emulation yet so left alt key should be used for button 0 and right alt key for button 1.
Disks and disk drives Disk drives in Vinace are easy to use. To open and close the drive, just click on the drive lid. To insert a disk in a drive, just drag the disk image file onto the disk drive. If successfully inserted, the disk name will appear on the drive and the drive will be automatically closed. Only .dsk files (DOS ordered disk images) are supported for now. Other formats (ProDOS ordered and nibbles disk images) will be supported later. Disk writing is not yet implemented. Disk images can be found on Asimov repository in the Images section : ftp://ftp.apple.asimov.net/pub/apple_II/images/
Inside Vinace General principles Before going deep into Vinace, here are some general principles as an introduction.
Why another emulator? Existing emulators have an old, not very convenient, graphical interface (no use of mouse, command line to change disks). Existing emulators are written in a performance purpose and not a comprehension or modular purpose. Existing emulators are monolithics, not close enough to the original design and so not easy to make evolve. I wanted to develop a not to difficult project to get back into C++.
What is a computer? Basically, a computer is a processor (CPU), some memory, and some peripherals. The processor is the core component of the computer. The CPU gets data from memory, computes it and put it back into memory. The processor can receive signals, like reset signal or interrupts signals. It also gets a periodic signal from a clock that tells it when to perform cycles (an instruction is "made" of several cycles). Except signals, the only communication between the processor and the rest of the world goes through the memory. As different types of memory are available (RAM, ROM or what so ever), a memory bus is in charge of interfacing the processor to these types of memory. Depending of the address given by the processor, the memory bus forwards request to the right memory. To drive peripherals, the processor uses the memory (once again, the only gate to the outside world). A specific type of memory, the I/O Unit is connected to the memory bus. The I/O Unit is not really memory as it does not store information. When an address is accessed in the IOU, it activates something in a peripheral or read some information from it. For example, accessing address 15 could activate a light or reading from address 17 could read a button status. That's basically the way processor interacts with peripherals. If we put that all together, we have a "simple" schema of what is a computer :
A simple computer A simple computer : a processor, a memory bus, some RAM, some ROM and an I/O Unit.
The orange box, containing CPU, memory and IOU but neither peripherals nor clock, represents what I called the "core". The core is the minimal component necessary for the computer to work. Peripherals only connect the computer to the world and, in particular, the user but they are not necessary for computing. I've put the clock outside because I consider the clock as an interface between the computer and the real time. We can change the clock frequency without affecting the computer behavior. We could even use a manual clock to study a computer step by step.
Three layers emulator design I wanted to have a modular emulator that is flexible and easy to develop new features on. I also wanted something that is very close to the reality. For example, I wanted to be able to develop new emulated peripheral later that I could "plug" in my emulator, just the way you plug peripherals to your machine. I decided to use a three layers design. Here are these three layers in one schema :
Three layers model Three layers model
Core layer The core layer contains all components, and only them, needed to have a working computer. That means that we could instantiate only a core layer and play with it. That's interesting for studying purpose but it results in a deaf and blind computer. The core layer can be seen as the computer seen from inside itself (inside this layer, programs are running as if they were in the real computer).
Hardware layer The hardware layer is a software representation of the emulated computer. This representation is independent from the graphical interface. For example, a video output is represented by a pixel matrix, a joystick button by a simple flag. This layer should contain representation of all the objects from the emulated world, like floppy disks or ROM cartriges. It should also contain all the logic of the emulator so the next layer is just in charge of the user interface.
GUI layer GUI layer is in charge of representing the hardware layer to the user.
Processor The processor is a device that can execute a sequence of instructions stored in memory. These instructions may require the use of registers (small amounts of internal memory). They may also require reading from and writing to memory. The periodicity of instruction execution is controlled by a clock telling to the processor when to perform a cycle. A cycle a part of an instruction : decoding the instruction, fetching data from memory, writing to memory and so on. The number of cycles for an instruction depends on its complexity. The processor can also react to some external signals like reset signal and interrupt request. These signals are usually emitted by peripherals. So, a processor has three interactions with outside world : Memory reading and writing Clock cycling request Signals In Vinace, processors are represented by classes deriving from CProcessor class. To create a new processor, a child class must be created and the following methods have to be implemented : Constructor: the CProcessor constructor takes two parameters : the memory to be linked to the processor and a number of signals. The child class constructor should call the CProcessor constructor with a given number of signals. This is the number of different possible signals. For example, for a processor having only a reset signal, this number is 1. reset(): this method is supposed to reset the processor state. It is called once when the processor is instantiated. It is the child class responsibility to connect any reset signal to this method. process_instruction(): this method is supposed to process the next instruction. It is called by cycle() once the cycles of the previous instruction have been finished. process_instruction() should increase the cycles member of the amount of cycles corresponding to the instruction. process_signals(): this method is supposed to process signals. It is called by cycle(). It should return false if a signal has been processed and true if there was no signal to process. In that case, cycle() calls then process_instruction. Memory A memory is a component capable of been read and written. In Vinace, the class that represents memory is CMemory. A CMemory object does not have to actually remind anything. For example, CDummyMemory, a child class of CMemory, is a memory that returns dummy values. It is used for filling areas that are not connected to any memory. RAM and ROM are represented by CMemory child classes CRamMemory and CRomMemory.
Memory proxies Memory proxies, represented by CMemoryProxy class, are proxies that allow to address a part of a CMemory object. Actually, they only translate the address according to the start address of the target.
Memory buses Memory buses are CMemory childs that dispatch the read and write requests to sub-memories according to requested address or flags from a CUnit. There is no common class for memory buses as they do not have anything in common, except that they are memories.
Apple //e memory Here is the schema of a 64K Apple //e memory.
Apple //e memory buses Apple //e memory buses
The CPU accesses only the main memory bus. IOU is the I/O Unit. There is one bank of 64K bytes RAM and several ROM banks : The language card ROM (LC ROM) contains monitor routines and basic (Applesoft on //e, Integer on ][+). It is visible in the $D000-$FFFF space. The internal ROM contains additional routines for the //e. The card ROMs are ROMs brought by expansion cards. Here is an explanation of each bus.
Main memory bus This bus is the visible part of the memory (from the processor point of view). This bus divides memory in four parts : $0000-$BFFF is connected to RAM. $C000-$C0FF is connected to the I/O Unit. $C100-$CFFF is connected to the I/O ROM bus (this can be connected to slots ROM or internal ROM). $D000-$FFFF is connected to the language card bus (usually, main ROM is visible here).
Language Card bus Reference : Apple IIe Technical Reference Manual pages 79 to 83 (PDF pp113-117) Language Card bus is in charge of the upper 12K memory. This space was originally dedicated to Basic and Monitor ROM in 48K Apple ][. On 64K Apples, a new possibility was to address RAM in this space. This feature is used to load alternative languages in memory (like ][+ Integer Basic on a //e). Read and Write can be switched independently. This allows to write into RAM while ROM is visible. It is quite convenient when setting up the RAM as many low level routines are in ROM (text display, keyboard input...). As there are 16K available RAM but only a 12K slot, the low 4K ($D000-$FFFF) can address two banks of RAM. The high 8K are always connected to the same RAM. This bus is driven by the Language Card Unit using LCRAM, LCWRITE and LCBNK2 soft switches. By default (LCRAM is off, LCWRITE off), the ROM is readable and write requests has no effect. Write requests are forwarded to RAM if LCWRITE is set. If it is not set, write requests have no effect (like for ROM). Read requests are forwarded to RAM if LCRAM is set and to ROM if it is not set. High 8K requests ($E000-$FFFF) are connected to highest 8K of RAM ($E000-$FFFF). Low 4K requests ($D000-$DFFF) are connected to RAM at $D000-$DFFF if LCBNK2 is set or to RAM at $C000-$CFFF if not.
I/O Rom Bus Apple //e and later models had more than 12k of ROM. To access the rest of the ROM, the space $C100-$CFFF, usually reserved for peripheral ROM could be used. A window in $C300-$C3FF, corresponding to the 80 column card, can be specifically selected. This bus is driven by I/O Rom unit using CXROM and C3ROM switches. If CXROM is on, I/O Rom bus forwards request to the Slot Rom bus (cards ROMs). If CXROM is off, internal ROM is visible. The C3ROM switch allows to see internal ROM in $C300-$C3FF space whatever the state of CXROM is. This is use to shadow 80 column extension card ROM and use internal routines instead.
Slot ROM Bus Each expansion card can have 256 bytes of basic ROM, plus a 4K ROM expansion. The basic ROM is visible at $Cn00-$CnFF, where n is the slot number. Whenever the basic ROM is accessed, the ROM expansion (if any) is selected and becomes visible at $C800-$CFFF. $CFFF is also a soft switch (called CLRROM) that clears the ROM selection. This is explained in the IIe Reference Manual page 132. Slot ROM Bus is in charge of forwarding read requests to the right card ROM. Like the Slots unit, it has to be informed of card inserting and removal.
Inserting and removing cards The insert_card method tells the Slot ROM bus that a card has been inserted : void CSlotRomBus::insert_card(int slot, CMemory *cardRom, CMemory *cardRomExt) slot is the slot number (1-7). cardRom is the basic ROM of the card and cardRomExt is its ROM expansion. The remove_card method tells the Slot ROM bus that a card has been removed : void CSlotRomBus::remove_card(int slot) slot is the slot number (1-7).
ROM files ROM image files are required for emulators but they are copyrighted and cannot be distributed freely. A good place to fetch ROM images is the emulators section of the Asimov repository. Vinace needs internal ROM but also Disk II ROM if a Disk II Controller is plugged in. Here is a description of ROM files used by Vinace.
apple_iie_rom.zip Location : ftp://ftp.apple.asimov.net/pub/apple_II/emulators/rom_images/apple_iie_rom.zip Contains only one file : APPLE2E.ROM APPLE2E.ROM file map FromToDescription0x00000x01ffEmpty0x02000x02ffUnknown, probably a slot 2 peripheral card rom0x03000x05ffEmpty0x06000x06ff16 Sector Disk II controller card ROM0x07000x0fffEmpty0x10000x3fffInteger basic ROM ?0x40000x40ffEmpty0x41000x4fffInternal $C100-$CFFF ROM0x50000x7fffMain $D000-$FFFF ROM
apple_ii_rom.zip Location : ftp://ftp.apple.asimov.net/pub/apple_II/emulators/rom_images/apple_ii_rom.zip Same as apple_iie_rom.zip.
apple_ii+_rom.zip Location : ftp://ftp.apple.asimov.net/pub/apple_II/emulators/rom_images/apple_ii+_rom.zip Contains only one file : APPLE2.ROM APPLE2.ROM file map FromToDescription0x00000x05ffEmpty0x06000x06ff16 Sector Disk II controller card ROM0x07000x0fffEmpty0x10000x15ffEmpty0x16000x16ff16 Sector Disk II controller card ROM0x20000x4fffMain $D000-$FFFF ROM
Input Output
I/O Unit on ][+ Apple ][+ I/O Unit addresses AddrNameAccessDescriptionUnitC000KBDRLast key pressedKeyboardC010KBDSTRBRWKeyboard StrobeKeyboardC020TAPEOUTR7Toggle Cassette Tape OutputC030SPKRRToggle SpeakerSpeakerC040STROBERGame I/O Strobe OutputGameC050TXTCLRWRDisplay GraphicsGraphicModeC051TXTSETWRDisplay TextGraphicModeC052MIXCLRWRDisplay Full ScreenGraphicModeC053MIXSETWRDisplay Split ScreenGraphicModeC054TXTPAGE1WRDisplay Page 1GraphicModeC055TXTPAGE2WRDisplay Page 2 GraphicModeC056LORESWRDisplay LoRes GraphicsGraphicModeC057HIRESWRDisplay HiRes GraphicsGraphicModeC058CLRAN0WRAnnunciator 0 OffGameC059SETAN0WRAnnunciator 0 OnGameC05ACLRAN1WRAnnunciator 1 OffGameC05BSETAN1WRAnnunciator 1 OnGameC05CCLRAN2WRAnnunciator 2 OffGameC05DSETAN2WRAnnunciator 2 OnGameC05ECLRAN3WRAnnunciator 3 OffGameC05FSETAN3WRAnnunciator 3 OnGameC060TAPEINR7Read Cassette InputC061PB0R7Switch Input 0GameC062PB1R7Switch Input 1GameC063PB2R7Switch Input 2GameC064PADDL0R7Analog Input 0GameC065PADDL1R7Analog Input 1GameC066PADDL2R7Analog Input 2GameC067PADDL3R7Analog Input 3GameC070PTRIGRAnalog Input ResetGameC080RRead RAM bank 2; no writeLanguageCardC081RRRead ROM; write RAM bank 2LanguageCardC082RRead ROM; no writeLanguageCardC083RRRead/write RAM bank 2LanguageCardC084-C087Same as C080-C083LanguageCardC088RRead RAM bank 1; no writeLanguageCardC089RRRead ROM; write RAM bank 1LanguageCardC08ARRead ROM; no writeLanguageCardC08BRRRead/write RAM bank 1LanguageCardC08C-C08FRSame as C088-C08BLanguageCardC090-C09FSlot 1 addressesSlotsC0A0-C0AFSlot 2 addressesSlotsC0B0-C0BFSlot 3 addressesSlotsC0C0-C0CFSlot 4 addressesSlotsC0D0-C0DFSlot 5 addressesSlotsC0E0-C0EFSlot 6 addressesSlotsC0F0-C0FFSlot 7 addressesSlots
R - Read to act or get information, W - Write to act, RR - Read twice to act, R7 - Read information from bit 7
I/O Unit on //e Apple //e I/O unit is based on the Apple ][+ unit except for the TXTPAGE1 and TXTPAGE2 addresses which are managed by the AuxMemory unit (which passes requests to the GraphicMode unit). Apple //e I/O unit has a few more soft switches and some more soft switches status. Apple //e I/O Unit addresses AddrNameAccessDescriptionUnitC000KBDRLast key pressedKeyboardC00080STOREOFFWUse $C002-$C005 for Aux MemoryAuxMemoryC00180STOREONWUse PAGE2 for Aux MemoryAuxMemoryC002RDMAINRAMWIf 80STORE Off: Read Main Mem $0200-$BFFFAuxMemoryC003RDCARDRAMWIf 80STORE Off: Read Aux Mem $0200-$BFFFAuxMemoryC004WRMAINRAMWIf 80STORE Off: Write Main Mem $0200-$BFFFAuxMemoryC005WRCARDRAMWIf 80STORE Off: Write Aux Mem $0200-$BFFFAuxMemoryC006SETSLOTCXROMWPeripheral ROM ($C100-$CFFF)IoRomC007SETINTCXROMWInternal ROM ($C100-$CFFF)IoRomC008SETSTDZPWMain Stack and Zero PageAuxMemoryC009SETALTZPWAux Stack and Zero PageAuxMemoryC00ASETINTC3ROMWROM in Slot 3IoRomC00BSETSLOTC3ROMWROM in Aux SlotIoRomC00CCLR80VIDW40 ColumnsTextModeC00DSET80VIDW80 ColumnsTextModeC00ECLRALTCHARWPrimary Character SetTextModeC00FSETALTCHARWAlternate Character SetTextModeC010KBDSTRBRWKeyboard StrobeKeyboardC011RDLCBNK2R7Status of $D000-DFFF RAM Bank 1 (0) or Bank 2 (1)LanguageCardC012RDLCRAMR7Status of $D000-$FFFF ROM (0) or RAM (1)LanguageCardC013RDRAMRDR7Status of Main/Aux RAM ReadingAuxMemoryC014RDRAMWRTR7Status of Main/Aux RAM WritingAuxMemoryC015RDCXROMR7Status of Periph (0) or Internal (1) ROM AccessIoRomC016RDALTZPR7Status of Main/Aux Stack and Zero PageAuxMemoryC017RDC3ROMR7Status of Slot 3 (0) or Aux Slot (1) ROMIoRomC018RD80STORER7Status of $C002-$C005/PAGE2 for Aux MemAuxMemoryC019RDVBLR7Vertical Blanking (1=drawing)C01ARDTEXTR7Status of Text (1) or Graphics (0)GraphicModeC01BRDMIXEDR7Status of Full Screen (0) or Mixed Graphics (1)GraphicModeC01CRDPAGE2R7Status of Page 1 (0) or Page 2 (1)GraphicModeC01DRDHIRESR7Status of LoRes (0) or HiRes (1)GraphicModeC01ERDALTCHARR7Status of Primary/Alternate Character SetTextModeC01FRD80VIDR7Status of 40/80 ColumnsTextModeC020TAPEOUTR7Toggle Cassette Tape OutputC030SPKRRToggle SpeakerSpeakerC040STROBERGame I/O Strobe OutputGameC050TXTCLRWRDisplay GraphicsGraphicModeC051TXTSETWRDisplay TextGraphicModeC052MIXCLRWRDisplay Full ScreenGraphicModeC053MIXSETWRDisplay Split ScreenGraphicModeC054TXTPAGE1WRDisplay Page 1GraphicModeC055TXTPAGE2WRIf 80STORE Off: Display Page 2, If 80STORE On: Read/Write Aux Display Mem AuxMemory, GraphicModeC056LORESWRDisplay LoRes GraphicsGraphicModeC057HIRESWRDisplay HiRes GraphicsGraphicModeC058CLRAN0WRAnnunciator 0 OffGameC059SETAN0WRAnnunciator 0 OnGameC05ACLRAN1WRAnnunciator 1 OffGameC05BSETAN1WRAnnunciator 1 OnGameC05CCLRAN2WRAnnunciator 2 OffGameC05DSETAN2WRAnnunciator 2 OnGameC05ECLRAN3WRAnnunciator 3 OffGameC05FSETAN3WRAnnunciator 3 OnGameC060TAPEINR7Read Cassette InputC061PB0R7Switch Input 0 / Open AppleGameC062PB1R7Switch Input 1 / Solid AppleGameC063PB2R7Switch Input 2 / Shift Key (on a few models)GameC064PADDL0R7Analog Input 0GameC065PADDL1R7Analog Input 1GameC066PADDL2R7Analog Input 2GameC067PADDL3R7Analog Input 3GameC070PTRIGRAnalog Input ResetGameC073BANKSELWMemory Bank Select for > 128KC07FRDDHIRESR7Status of Double HiResC080RRead RAM bank 2; no writeLanguageCardC081RRRead ROM; write RAM bank 2LanguageCardC082RRead ROM; no writeLanguageCardC083RRRead/write RAM bank 2LanguageCardC084-C087Same as C080-C083LanguageCardC088RRead RAM bank 1; no writeLanguageCardC089RRRead ROM; write RAM bank 1LanguageCardC08ARRead ROM; no writeLanguageCardC08BRRRead/write RAM bank 1LanguageCardC08C-C08FRSame as C088-C08BLanguageCardC090-C09FSlot 1 addressesSlotsC0A0-C0AFSlot 2 addressesSlotsC0B0-C0BFSlot 3 addressesSlotsC0C0-C0CFSlot 4 addressesSlotsC0D0-C0DFSlot 5 addressesSlotsC0E0-C0EFSlot 6 addressesSlotsC0F0-C0FFSlot 7 addressesSlots
R - Read to act or get information, W - Write to act, RR - Read twice to act, R7 - Read information from bit 7
I/O Units I/O Units are interfaces between Apple memory and the peripherals. In the emulator, it is an interface between core layer and hardware layer.
Unit class I/O Units are represented by child classes of the CUnit class. On the Apple memory side, only two methods are used : read and write. This is much like Memory, except that the addressing is on 8 bits rather than 16. On the peripheral side, there is no specification. Most units only consist of soft switches. To each switch corresponds a get_<switch> method and, if changeable, a set_<switch> method, where <switch> is the switch name in lowercase. Units have a reset method which is supposed to reset the unit. It is called both at the unit instantiation and when the user presses the reset button (this is in the hardware layer). All units are observable and should notify whenever any change occurs. Hardware layer objects should observe units to be informed of what's happening.
Keyboard Compatibility: All models. This unit is in charge of keyboard. On Apple II computer there was no keyboard buffer. This unit can only handle one key at once.
Methods void press_key(BYTE key); Tells the unit that key is being pressed. Note that if the previous key has not been read yet, it will be forgotten. The key code must be an Apple ASCII code. void release_key(); Tells the unit that the pressed key has been released. bool key_waiting(); Tells if there's a key waiting to be read by the Apple. This method could be very convenient for developing a buffered keyboard or a copy paste tool.
Addresses AddressNameAccessEffect 0x00KBDRBits 0-6 : Last key pressed or being pressed. Bit 7 : is set if a key has been pressed since last strobe. 0x10KBDSTROBERWStrobes the keyboard. Bits 0-6 : Last key pressed or being pressed. Bit 7 : is set if the key is being pressed.
Tape Compatibility: All models. Unfortunately this unit is not yet implemented.
Speaker Compatibility: All models. The Apple speaker is quite basic : it has only two levels. Speaker level is toggled by accessing to the SPKR soft switch. On the peripheral side, the current speaker level can be read.
Switches SwitchOffOn SPKRSpeaker at low levelSpeaker at high level
Addresses AddressNameAccessEffect 0x30SPKRRWToggle SPKR switch
Game Compatibility: All models (maybe except //c). Game unit has three different kinds of devices : Three push buttons, four annunciators and four analog inputs. Push buttons are connected to the joystick or paddles buttons. Button 0 is also connected to the open apple keyboard key and button 1 to the closed apple key. On a few //e models, the button 2 is connected to the shift key. Annunciators are outputs on the game plug, capable of outputting an two levels signal (they have not been used so much, maybe not at all). Analogs inputs are connected to the joystick X and Y axis (usually inputs 0 and 1) or to the paddles. These analog inputs worked by measuring the discharge time of a capacitor into variable resistance of paddle or joystick. The unit was only able to trigger the capacitor load and sense when it was discharged. The time is measured by a program in ROM. It is important to simulate this mechanism as some software implements their own measuring routine. The difficulty is that it is important to synchronize the simulator to the clock so the cycle count, seen from the inside, is correct.
Switches SwitchOffOn AN0Annunciator 0 level is lowAnnunciator 0 level is high AN1Annunciator 1 level is lowAnnunciator 1 level is high AN2Annunciator 2 level is lowAnnunciator 2 level is high AN3Annunciator 3 level is lowAnnunciator 3 level is high PB0Push button 0 is releasedPush button 0 is pressed PB1Push button 1 is releasedPush button 1 is pressed PB2Push button 2 is releasedPush button 2 is pressed PADDL0Paddle 0 capacitor is emptyPaddle 0 capacitor is loaded PADDL1Paddle 1 capacitor is emptyPaddle 1 capacitor is loaded PADDL2Paddle 2 capacitor is emptyPaddle 2 capacitor is loaded PADDL3Paddle 3 capacitor is emptyPaddle 3 capacitor is loaded PTRIGPaddle capacitors are dischargingPaddle capacitors are loading
Addresses AddressNameAccessEffect 0x58CLRAN0WRTurn AN0 switch off 0x59SETAN0WRTurn AN0 switch on 0x5ACLRAN1WRTurn AN1 switch off 0x5BSETAN1WRTurn AN1 switch on 0x5CCLRAN2WRTurn AN2 switch off 0x5DSETAN2WRTurn AN2 switch on 0x5ECLRAN3WRTurn AN3 switch off 0x5FSETAN3WRTurn AN3 switch on 0x61PB0R7Read PB0 switch state 0x62PB1R7Read PB1 switch state 0x63PB2R7Read PB2 switch state 0x64PADDL0R7Read PADDL0 switch state 0x65PADDL1R7Read PADDL1 switch state 0x66PADDL2R7Read PADDL2 switch state 0x67PADDL3R7Read PADDL3 switch state 0x70PTRIGRTrigger capacitor discharges* * : When the capacitor charge is triggered, the PTRIG switch goes true, observers are notified, then it goes back false (and observers are notified again). All that in the same clock cycle (actually during the same method call). This is the way the Game unit informs observers that they should begin discharge simulation.
Graphic Mode Compatibility: All models. Reference: Apple IIe Technical Reference Manual page 29 (PDF p63) This unit takes care of graphic and text modes switching, except the double hires mode which was implemented later. The Apple ][ has one text mode and two graphic modes (low resolution and high resolution). A mixed mode allows to split the screen having 4 lines of text at the bottom and the rest in graphic mode. Each mode has two pages corresponding to different memory spaces.
Switches SwitchOffOn TEXTGraphic ModeText mode MIXEDFull screen modeSplit screen mode PAGE2Page 1 displayedPage 2 displayed HIRESLow resolution High resolution
Addresses AddressNameAccessEffect 0x50TXTCLRRWTurn TEXT switch off 0x51TXTSETRWTurn TEXT switch on 0x52MIXCLRRWTurn MIXED switch off 0x53MIXSETRWTurn MIXED switch on 0x54TXTPAGE1RWTurn PAGE2 switch off 0x55TXTPAGE2RWTurn PAGE2 switch on 0x56LORESRWTurn HIRES switch off 0x57HIRESRWTurn HIRES switch on And, on //e and later, some read addresses were added : AddressNameAccessEffect 0x1ARDTEXTR7Read TEXT switch state 0x1BRDMIXEDR7Read MIXED switch state 0x1CRDPAGE2R7Read PAGE2 switch state 0x1DRDHIRESR7Read HIRES switch state
Slots Compatibility: All models. This units manages the expansion slots of the Apple. It just forwards read and write requests on the $C090-$C0FF memory space to the corresponding card's I/O unit. Like Slot ROM Bus, this unit has to be informed when a card is inserted or removed.
Methods void insert_card(int slot, CUnit *cardUnit); Tells the unit that a card has been inserted. slot is the slot number (1-7) and cardUnit is the I/O unit of the expansion card. void remove_card(int slot); Tells the unit that a card has been removed. slot is the slot number (1-7).
Addresses AddressNameAccessEffect 0x90-0x9FRWForwarded to addresses 0x00-0x0F of card in slot 1 0xA0-0xAFRWForwarded to addresses 0x00-0x0F of card in slot 2 0xB0-0xBFRWForwarded to addresses 0x00-0x0F of card in slot 3 0xC0-0xCFRWForwarded to addresses 0x00-0x0F of card in slot 4 0xD0-0xDFRWForwarded to addresses 0x00-0x0F of card in slot 5 0xE0-0xEFRWForwarded to addresses 0x00-0x0F of card in slot 6 0xF0-0xFFRWForwarded to addresses 0x00-0x0F of card in slot 7
Language Card Compatibility: All models (probably not ][). Reference : Apple IIe Technical Reference Manual pages 79 to 83 (PDF pp113-117) This unit drives the Language Card Bus using three switches : LCRAM, LCBNK2 and LCWRITE. Only LCRAM and LCBNK2 are visible from inside the Apple. LCWRITE is not an official name for this switch (I chose this one because I did not found any name in documentation). To change state of LCWRITE, two read requests must be done on the appropriate address. A fourth switch is used in Vinace to manage that double read and is called LCWCHG.
Switches SwitchOffOn LCBNK2RAM bank 2 is used in $D000-$DFFFRam bank 1 is used in $D000-$DFFF LCRAMROM is read in $D000-$FFFFRAM is read in $D000-$DFFF LCWRITENo write operation in $D000-$FFFFRAM is writable in $D000-$FFFF (even if not visible)
Addresses AddressNameAccessEffect 0x11RDLCBNK2R7Read LCBNK2 switch state 0x12RDLCRAMR7Read LCRAM switch state 0x81RTurn LCBNK2 on, LCRAM on, LCWRITE off 0x81RRTurn LCBNK2 on, LCRAM off, LCWRITE on 0x82RTurn LCBNK2 on, LCRAM off, LCWRITE off 0x83RRTurn LCBNK2 on, LCRAM on, LCWRITE on 0x84-0x87Same as 0x80-0x83 0x88RTurn LCBNK2 off, LCRAM on, LCWRITE off 0x89RRTurn LCBNK2 off, LCRAM off, LCWRITE on 0x8ARTurn LCBNK2 off, LCRAM off, LCWRITE off 0x8BRRTurn LCBNK2 off, LCRAM on, LCWRITE on 0x8C-0x8FSame as 0x88-0x8B
Aux Memory Compatibility: //e and later. Unfortunately this unit is not yet implemented.
Text Mode Compatibility: //e and later. This unit takes care of 40/80 columns display switching and charset switching.
Switches SwitchOffOn 80VID40 columns display80 columns display ALTCHARPrimary charset usedAlternative charset used
Addresses AddressNameAccessEffect 0x0CCLR80VIDWTurn 80VID switch off 0x0DSET80VIDWTurn 80VID switch on 0x0ECLRALTCHARWTurn ALTCHAR switch off 0x0FSETALTCHARWTurn ALTCHAR switch on 0x1ERDALTCHARR7Read ALTCHAR switch state 0x1FRD80VIDR7Read 80VID switch state
I/O Rom Compatibility : //e, IIgs Some Apple models had more than 12k of ROM. To access the rest of the ROM, the space $C100-$CFFF, usually reserved for peripheral ROM could be used. A window in $C300-$C3FF, corresponding to the 80 column card, can be specifically selected. This unit drives the I/O Rom bus that takes care of $C100-$CFFF ROM switching between slot ROM and internal ROM.
Switches SwitchOffOn CXROMPeripheral ROM at $C100-$CFFFInternal ROM at $C100-$CFFF C3ROMROM selected by CXROM at $C300-$C3FFInternal ROM at $C300-$C3FF
Addresses AddressNameAccessEffect 0x06SETSLOTCXROMWTurn CXROM switch off 0x07SETINTCXROMWTurn CXROM switch on 0x0ASETINTC3ROMWTurn C3ROM switch off 0x0BSETSLOTC3ROMWTurn C3ROM switch on 0x15RDCXROMR7Read CXROM switch state 0x17RDC3ROMR7Read C3ROM switch state
Not yet implemented Here is a list of features to be implemented: Tape input and output 128K memory (AuxMemory) Vertical blanking signal Reading floppy in ProDOS order format (.po) and in nibbles format (.nib) Floppy disk writing Some other features could also be implemented but they are less important : A 'paste' capable keyboard Sounds for disk drives References
On the web
Asimov Asimov repository is the place to go on internet to find apple stuff. There are disk images, original documentation, ROM images, emulators and so on. Asimov repository is here : ftp://ftp.apple.asimov.net/pub/apple_II
Jon Relay's Apple II Info Archives Jon Relay's Apple II Info Archives contains useful stuff that can also be found in reference manuals, except for the fabulous I/O Memory page that summarizes input/output of all Apple II models in one big table : http://www.kreativekorp.com/miscpages/a2info/iomemory.shtml
Books These are the most interesting books, they can all be found on Asimov repository. Reading these books, you can notice how much times have changed if you compare them to the information you can get, even as a developer, from hardware constructors. These books gives you an amazing amount of information : electronic schemas, ROM listings, specifications...
Apple IIe Technical Reference Manual This is the bible. Almost every thing is explained. I have the French version. The English original version can be found there : ftp://ftp.apple.asimov.net/pub/apple_II/documentation/Apple IIe Technical Reference Manual.pdf
Apple II Reference Manual January 1978 This is an older bible. It is also known as the red book. Fortunately I got one from ebay. A PDF version can be found there : ftp://ftp.apple.asimov.net/pub/apple_II/documentation/Apple_II_Redbook.pdf
Understanding the Apple II I read the chapter 8, about the Disk II Controller, as official Apple manual does not provide any information on it. I haven't read the rest of this book (I have no paper version) but it looks very interesting and goes deep in Apple II description. A PDF version can be found there : ftp://ftp.apple.asimov.net/pub/apple_II/documentation/understanding the apple ii.pdf
Existing emulators
YAE - Yet Another Apple Emulator Before I decided to write Vinace, I have been using YAE. It has a lot of limitations : no simple joystick emulation, no easy disk drive interface. I first tried to improve it but I quickly found out that writing a new emulator from scratch would not be harder. I studied a lot the source code from YAE while writing Vinace. I took the routines for nibble encoding and decoding, used in disk drives, from it. The files gcr.h and gcr.cpp are nearly the same that in YAE. It seems that the YAE website does not exists anymore (http://quark.netfront.net:6502/) but source code can still be found on Asimov Repository here : ftp://ftp.apple.asimov.net/pub/apple_II/emulators/yae/yae-0.1.tar.gz
Appleblossom - Portable Open-Source Apple IIe Emulator When I couldn't find answers neither in documentation nor in YAE source, I searched in Apple Blossom source code. I took charset code from Apple Blossom. It is now in the CCharset.cpp file. Source code of Apple Blossom is here : ftp://ftp.apple.asimov.net/pub/apple_II/emulators/appleblossom/appleblossom.zip