Vinace documentationIntroductionVinace 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 VinaceQuick startIf 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.KeyboardHere are the keys on the original Apple //e keyboard :
Apple //e keyboard keysGroupKeysLettersA 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.JoystickThere 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.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 drivesDisk 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 VinaceGeneral principlesBefore 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 :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 designI 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 :Core layerThe 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 layerThe 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 layerGUI layer is in charge of representing the hardware layer to the user.ProcessorThe 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 writingClock cycling requestSignalsIn 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.MemoryA 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 proxiesMemory 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 busesMemory 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 memoryHere is the schema of a 64K Apple //e memory.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 busThis 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 busReference : 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 BusApple //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 BusEach 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 cardsThe 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 filesROM 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.zipLocation : ftp://ftp.apple.asimov.net/pub/apple_II/emulators/rom_images/apple_iie_rom.zipContains only one file : APPLE2E.ROM
APPLE2E.ROM file mapFromToDescription0x00000x01ffEmpty0x02000x02ffUnknown, 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.zipLocation : ftp://ftp.apple.asimov.net/pub/apple_II/emulators/rom_images/apple_ii_rom.zipSame as apple_iie_rom.zip.apple_ii+_rom.zipLocation : ftp://ftp.apple.asimov.net/pub/apple_II/emulators/rom_images/apple_ii+_rom.zipContains only one file : APPLE2.ROM
APPLE2.ROM file mapFromToDescription0x00000x05ffEmpty0x06000x06ff16 Sector Disk II controller card ROM0x07000x0fffEmpty0x10000x15ffEmpty0x16000x16ff16 Sector Disk II controller card ROM0x20000x4fffMain $D000-$FFFF ROM
Input OutputI/O Unit on ][+
Apple ][+ I/O Unit addressesAddrNameAccessDescriptionUnitC000KBDRLast 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 7I/O Unit on //eApple //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 addressesAddrNameAccessDescriptionUnitC000KBDRLast 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 7I/O UnitsI/O Units are interfaces between Apple memory and the peripherals. In the
emulator, it is an interface between core layer and hardware layer.Unit classI/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.KeyboardCompatibility: 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.Methodsvoid 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.AddressesAddressNameAccessEffect0x00KBDRBits 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.TapeCompatibility: All models.Unfortunately this unit is not yet implemented.SpeakerCompatibility: 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.SwitchesSwitchOffOnSPKRSpeaker at low levelSpeaker at high levelAddressesAddressNameAccessEffect0x30SPKRRWToggle SPKR switchGameCompatibility: 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.SwitchesSwitchOffOnAN0Annunciator 0 level is lowAnnunciator 0 level is highAN1Annunciator 1 level is lowAnnunciator 1 level is highAN2Annunciator 2 level is lowAnnunciator 2 level is highAN3Annunciator 3 level is lowAnnunciator 3 level is highPB0Push button 0 is releasedPush button 0 is pressedPB1Push button 1 is releasedPush button 1 is pressedPB2Push button 2 is releasedPush button 2 is pressedPADDL0Paddle 0 capacitor is emptyPaddle 0 capacitor is loadedPADDL1Paddle 1 capacitor is emptyPaddle 1 capacitor is loadedPADDL2Paddle 2 capacitor is emptyPaddle 2 capacitor is loadedPADDL3Paddle 3 capacitor is emptyPaddle 3 capacitor is loadedPTRIGPaddle capacitors are dischargingPaddle capacitors are loadingAddressesAddressNameAccessEffect0x58CLRAN0WRTurn AN0 switch off0x59SETAN0WRTurn AN0 switch on0x5ACLRAN1WRTurn AN1 switch off0x5BSETAN1WRTurn AN1 switch on0x5CCLRAN2WRTurn AN2 switch off0x5DSETAN2WRTurn AN2 switch on0x5ECLRAN3WRTurn AN3 switch off0x5FSETAN3WRTurn AN3 switch on0x61PB0R7Read PB0 switch state0x62PB1R7Read PB1 switch state0x63PB2R7Read PB2 switch state0x64PADDL0R7Read PADDL0 switch state0x65PADDL1R7Read PADDL1 switch state0x66PADDL2R7Read PADDL2 switch state0x67PADDL3R7Read PADDL3 switch state0x70PTRIGRTrigger 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 ModeCompatibility: 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.SwitchesSwitchOffOnTEXTGraphic ModeText modeMIXEDFull screen modeSplit screen modePAGE2Page 1 displayedPage 2 displayedHIRESLow resolution High resolutionAddressesAddressNameAccessEffect0x50TXTCLRRWTurn TEXT switch off0x51TXTSETRWTurn TEXT switch on0x52MIXCLRRWTurn MIXED switch off0x53MIXSETRWTurn MIXED switch on0x54TXTPAGE1RWTurn PAGE2 switch off0x55TXTPAGE2RWTurn PAGE2 switch on0x56LORESRWTurn HIRES switch off0x57HIRESRWTurn HIRES switch onAnd, on //e and later, some read addresses were added :AddressNameAccessEffect0x1ARDTEXTR7Read TEXT switch state0x1BRDMIXEDR7Read MIXED switch state0x1CRDPAGE2R7Read PAGE2 switch state0x1DRDHIRESR7Read HIRES switch stateSlotsCompatibility: 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.Methodsvoid 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).AddressesAddressNameAccessEffect0x90-0x9FRWForwarded to addresses 0x00-0x0F of card in slot 10xA0-0xAFRWForwarded to addresses 0x00-0x0F of card in slot 20xB0-0xBFRWForwarded to addresses 0x00-0x0F of card in slot 30xC0-0xCFRWForwarded to addresses 0x00-0x0F of card in slot 40xD0-0xDFRWForwarded to addresses 0x00-0x0F of card in slot 50xE0-0xEFRWForwarded to addresses 0x00-0x0F of card in slot 60xF0-0xFFRWForwarded to addresses 0x00-0x0F of card in slot 7Language CardCompatibility: 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.SwitchesSwitchOffOnLCBNK2RAM bank 2 is used in $D000-$DFFFRam bank 1 is used in $D000-$DFFFLCRAMROM is read in $D000-$FFFFRAM is read in $D000-$DFFFLCWRITENo write operation in $D000-$FFFFRAM is writable in $D000-$FFFF (even if not visible)AddressesAddressNameAccessEffect0x11RDLCBNK2R7Read LCBNK2 switch state0x12RDLCRAMR7Read LCRAM switch state0x81RTurn LCBNK2 on, LCRAM on, LCWRITE off0x81RRTurn LCBNK2 on, LCRAM off, LCWRITE on0x82RTurn LCBNK2 on, LCRAM off, LCWRITE off0x83RRTurn LCBNK2 on, LCRAM on, LCWRITE on0x84-0x87Same as 0x80-0x830x88RTurn LCBNK2 off, LCRAM on, LCWRITE off0x89RRTurn LCBNK2 off, LCRAM off, LCWRITE on0x8ARTurn LCBNK2 off, LCRAM off, LCWRITE off0x8BRRTurn LCBNK2 off, LCRAM on, LCWRITE on0x8C-0x8FSame as 0x88-0x8BAux MemoryCompatibility: //e and later.Unfortunately this unit is not yet implemented.Text ModeCompatibility: //e and later.This unit takes care of 40/80 columns display switching and charset
switching.SwitchesSwitchOffOn80VID40 columns display80 columns displayALTCHARPrimary charset usedAlternative charset usedAddressesAddressNameAccessEffect0x0CCLR80VIDWTurn 80VID switch off0x0DSET80VIDWTurn 80VID switch on0x0ECLRALTCHARWTurn ALTCHAR switch off0x0FSETALTCHARWTurn ALTCHAR switch on0x1ERDALTCHARR7Read ALTCHAR switch state0x1FRD80VIDR7Read 80VID switch stateI/O RomCompatibility : //e, IIgsSome 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.SwitchesSwitchOffOnCXROMPeripheral ROM at $C100-$CFFFInternal ROM at $C100-$CFFFC3ROMROM selected by CXROM at $C300-$C3FFInternal ROM at $C300-$C3FFAddressesAddressNameAccessEffect0x06SETSLOTCXROMWTurn CXROM switch off0x07SETINTCXROMWTurn CXROM switch on0x0ASETINTC3ROMWTurn C3ROM switch off0x0BSETSLOTC3ROMWTurn C3ROM switch on0x15RDCXROMR7Read CXROM switch state0x17RDC3ROMR7Read C3ROM switch stateNot yet implementedHere is a list of features to be implemented:Tape input and output128K memory (AuxMemory)Vertical blanking signalReading floppy in ProDOS order format (.po) and in nibbles format (.nib)Floppy disk writingSome other features could also be implemented but they are less important :A 'paste' capable keyboardSounds for disk drivesReferencesOn the webAsimovAsimov 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_IIJon Relay's Apple II Info ArchivesJon 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.shtmlBooksThese 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 ManualThis 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.pdfApple II Reference Manual January 1978This 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.pdfUnderstanding the Apple III 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.pdfExisting emulatorsYAE - Yet Another Apple EmulatorBefore 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.gzAppleblossom - Portable Open-Source Apple IIe EmulatorWhen 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