This is a low-level programmer's description of the ACA500plus. This information is not required for everyday use of the product. For details about using the product, please refer to the main page (fixme: insert link)
|mem address||standard use||early overlay mode|
|$00.0000 to $03.ffff||Chipram||flashrom overlay.|
|$04.0000 to $07.ffff||Chipram|
|$08.0000 to $1f.ffff||Chipram|
|$20.0000 to $3f.ffff||2MByte mapped from host computer, available for Z2 expansions|
|$40.0000 to $9f.ffff||6 MBytes fastmem.|
|$a0.0000 to $a7.ffff||512K RAM covered by 512k MapROM area (see MapROM chapter)|
|$a8.0000 to $ad.ffff||896 KBytes fastmem.|
|$ae.0000 to $ae.ffff||64k for resident modules, write protected on register-lock|
|$af.0000 to $af.ffff||64k for software-defined autoconfig, write protected on register-lock|
|$b0.0000 to $b3.ffff||ACA500plus registers. See further down.|
|$b4.0000 to $b9.ffff||CIA chips|
|$ba.0000 to $bd.ffff||random access to lowest 256k of flash rom|
|$be.0000 to $bf.ffff||CIA chips|
|$c0.0000 to $c7.ffff||512k fastmem|
|$c8.0000 to $cf.ffff||512k mapped from host computer or trapdoor memory (see $c8mem register)|
|$d0.0000 to $d7.ffff||512k empty space (reserved)|
|$d8.0000 to $d8.3fff||ACA500plus local clockport|
|$d8.4000 to $d8.7fff||clockport on A1200 accelerator (for example ACA1221, ACA1233n)|
|$d8.8000 to $d8.bfff||unused; writing has no effect and reading returns garbage.|
|$d8.c000 to $d8.ffff||display module registers (see separate chapter - fixme: insert link)|
|$d9.0000 to $d9.ffff||secondary "fast" clockport on A1200 accelerator (for example RapidRoad port on ACA1221)|
|$da.0000 to $da.ffff||A600-compatible IDE controller|
|$db.0000 to $db.ffff||mapped from host computer; will most likely contain chip register mirror|
|$dc.0000 to $dc.ffff||RTC window: May be switched between trapdoor-RTC and external RTC with register(fixme!)|
|$dd.0000 to $dd.ffff||mapped from host computer; will most likely contain chip register mirror|
|$de.0000 to $de.ffff||A600-Gayle identification registers|
|$df.0000 to $df.ffff||Amiga chip registers|
|$e0.0000 to $e7.ffff||Kickstart mirror. Note that MapROM will also replace this area!||Physical Kickstart ROM, regardless of MapROM bit|
|$e8.0000 to $ed.ffff||Autoconfig area|
|$ee.0000 to $ef.ffff||Local I/O expansion port|
|$f0.0000 to $f0.ffff||64k RAM mapped read-only from $ae.0000|
|$f1.0000 to $f1.ffff||64k mapped from host computer|
|$f2.0000 to $f2.ffff||64k RAM mapped read-only from $ae.0000|
|$f3.0000 to $f7.ffff||320k mapped from host computer|
|$f8.0000 to $ff.ffff||If Maprom-bit=0, this area contains the physical Kickstart ROM of the A500 on read accesses. If Maprom-bit=1, read accesses will reach the fast Kickstart-copy. Write accesses are passed to the host system (i.e. will do nothing).||Lower 256k of flash rom, random access, 128k blocks swapped (see explanation below)|
Early overlay is switched on with every reset, except when De-Brick mode is externally selected. Early overlay is automatically switched off upon the first access to the flash rom at $ba.0000 to $bd.ffff area. Switching early overlay back on is not possible unless you reset the system (for example with the reset command or a keyboard reset).
If the "early overlay" column is empty, then the standard use of the address space is available.
During early overlay, 512k Kickstart ROM at $f8.0000 is replaced with two copies of the lower 256k of the flash rom. Note that the first and the second 128k block will be swapped in relation to the $00.0000 addresses, so $f8.0000 will show a mirror of $02.0000, and $fa.0000 will show a mirror of $00.0000. This gives the possibility to place different vectors to $00.0000 and $f8.0000. Also, the $e0.0000 area is not touched at all, so detecting the physical Kickstart ROM is still possible. Note that only accessing flash at $ba.000 will deactivate Early Overlay. Accesses to $f8.0000 and following will keep the hardware in early overlay mode.
ACA500plus register locations
Many of the ACA500plus registers are in the same place as with the predecessor ACA500. However, they may have a different meaning in certain details, so please make sure that you double-ceck your code for compatibility with the new hardware. It will most likely not be possible to port code without changes, although it has been attempted to make register changes as small as possible. ACA500plus registers only use the MSB of the even byte or word of each address.
|address||write function||read function|
|$b0.3000||Register lock||Card Detect #1|
|$b0.7000||-.-||Card Detect #2|
|$b0.f000||CF#2 power and floppy control||CF IRQ#2|
|$b1.3000||Set 7MHz||Hardware ID bit 3|
|$b1.7000||Set 14MHz||Hardware ID bit 2|
|$b1.b000||Set 21MHz||Hardware ID bit 1|
|$b1.f000||Set 42MHz||Hardware ID bit 0|
|$b2.3800||-.-||Clock speed bit#0|
|$b2.7800||-.-||Clock speed bit#1|
|$b2.f000||VBR move||VBR move|
|$b2.f800||-.-||SD-Ram init done|
|$b3.7000||ExtRTC select||ExtRTC select|
|$b3.b000||A1200 RTC select||A1200 RTC select|
|$b3.b800||CF#2 IRQ enable||CF#2 IRQ enable status|
|$b3.f800||-.-||A1200 accel present|
On power-up and with every reset, all registers will be unlocked. It is therefore recommended to lock registers whenever the menu is left and the user can launch his own software.
There are four write-registers for locking:
Note that Unlock registers 2 and 3 are shared with the c8mem and the CF2_power/Floppy control register. Only when locked, these two registers are changed to unlock control registers.
To lock all registers, write any value to $b0.3000 (Register lock). This will set lock state 3, inhibiting any write access to other registers. Only lock state 0 will allow altering register contents. To unlock, please follow this procedure:
- Write any value to Unlock register 1. This will set unlock state 2.
- Write any value to Unlock register 3. This will set unlock state 1.
- Write any value to Unlock register 2. This will set unlock state 0.
Card Detect #1 $b0.3000 (boot card)
The MSB of this register will be 1 if the Boot Card is present, and it will be 0 if the card has been removed.
Writing to this register will lock all registers and reset the early overlay and the FlashWrite bit to 0. After locking, write accesses to registers will have no effect. Reading the register contents will still return the current values.
Card Detect #2 $b0.7000 (Aux card)
The MSB of this register will be 1 if the Aux Card is present, and it will be 0 if the card has been removed.
Writing to this register does nothing at this point.
CF Interrupt #1 $b0.b000 (boot card)
Upon read, the MSB of this word will be 1 if the Boot card is currently requesting an IRQ, and it will be 0 if no IRQ has been requested from this card. Use this bit in conjunction with the Gayle IDE registers. Note that this bit will show the real status of the IRQ line, regardless of the state of the IRQ enable bit in the Gayle registers.
Writing to this register will set/reset the c8mem bit. This bit will be 0 after power-up and does not change it's state on reset. Please consult the memory config table at the end of this chapter about how this bit interacts with the ChipMap bit and with Cloaking mode.
Aux CF and floppy control $b0.f000
Upon read, the MSB of this word will be 1 if the Aux card is currently requesting an IRQ, and it will be 0 if no IRQ has been requested from this card. Use this bit in conjunction with the Gayle IDE registers. Note that this bit will show the real status of the IRQ line, regardless of the state of the IRQ enable bits in the Gayle registers and the power state of the Aux card slot. It may therefore contain false data when power is switched off for the Aux port.
Upon write, this is the only register that also uses other bits than the MSB (bit 7):
|bit 7||bit 6||bit 5||bit 4||bit 3||bit 2||bit 1||bit 0|
|Aux power||DF0: empty||Bootselect||Disable DF1:||Disable DF2:||Disable DF3:||unused||unused|
The MSB controls Aux Power: If you set this bit to 1, the Aux CF card slot will function normally, and IRQs from the Aux port are enabled (IRQ mask bit $b3.b800 is automatically set/reset with CF#2 power bit).
If you set the MSB to 0, power is cut off from the Aux CF card slot. At the same time, all data and address lines and even the reset line will be tristated, so the CF card won't get any power through these lines. At the same time, IRQs from this slot will be ignored, so a hot-plug process on this port cannot cause any glitch within the system. While power is switched off, any remaining energy in the Aux CF card will be discharged through a resistor. For power-cycling a card, you should leave power off for at least two seconds in order to give enough time to discharge the capacitors in the card.
Bit 6 on write is the "DF0: empty" bit. If you set this bit to 1, then the df0: drive will appear empty. This is helpful if the computer has a defective disk drive that adds an annoying wait to the boot-time of the computer. Other floppy drives are not affected; they can be used as normal. In addition to "appearing empty", STEP pulses are also inhibited to the drive, which results in "no clicking" at all, even if there is no "noclick" program installed or the drive is not capable of not clicking (like early NEC 1036 drives). This bit is 0 on power-up and does not change it's value on a reset.
Bit 5 on write is the "Bootselect" bit. If you set this bit to 1, then floppy drives DF0: and DF1: will be swapped, just like the bootselectors of the old days did. When swapped, the internal drive will NOT appear as DF1: automatically. Again, this is helpful if the internal drive of the computer is defective and shall be replaced by an external drive. However, the internal drive is available to the hardware as DF1:, and you may write software that enables/mounts the drive when the system has been launched.
Bit 4 on write is the "Disable DF1:" bit. If you set this bit to 1, then floppy drive DF1: will be de-selected by hardware, no matter what you write into the CIA register. Note that setting this bit together with the Bootsel bit does not make sense: It will disable your boot floppy. Setting the Bootsel bit will put DF0: in plce of DF1:, which will not be recognized by the computer as an external drive.
Bit 3 on write is the "Disable DF2:" bit. If you set this bit to 1, then floppy drive DF2: will be de-selected by hardware, no matter what you write into the CIA register.
Bit 2 on write is the "Disable DF3:" bit. If you set this bit to 1, then floppy drive DF3: will be de-selected by hardware, no matter what you write into the CIA register.
All floppy control bits can be set and reset at any time. Their effect is instant. However, you cannot read the values back, so you must keep their values in a shadow-register and check that before you make a change to the Aux card power bit. Since these three bits are located in a different chip, these bits MUST be in the same register. Sorry for the inconvenience.
ACA500plus version ID and clock control
|mem address||read function||write function|
|register $b1.3000||ID bit 3||7MHz sync clock select|
|register $b1.7000||ID bit 2||14MHz async clock select|
|register $b1.b000||ID bit 1||21/28MHz async clock select|
|register $b1.f000||ID bit 0||42MHz async clock select|
These four registers are read-only for identification; they form the ACA500plus revision nibble. Only the MSB of each word is used; the nibble must be "assembled" of the four MSBs of these words. For the development/prototype unit, the ID is set to 8. This is the next-higher number above the highest logic revision of the predecessor ACA500.
On write, these four addresses control clocking of the processor. Note that it does not matter what value you write; only the address where you write controls the new clock rate. 7MHz syncronous clock means that the ACA500plus gets it's clock from the host computer (which may be 7.14MHz on NTSC machines or 7.09MHz on PAL machines). Further, memory access to fastmem in location $c0.0000 is slowed down to "trapdoor memory speed". This means that although the memory is actually located in real fastmem of the ACA500plus, any access will only be completed at the time that a DMA slot is free on the host computer. This will make the computer much more compatible to games and other programs that require cycle-exact speed of an un-accelerated Amiga 500.
The three other clock control registers result in an asyncronous clock, meaning that the CPU frequency floats against the host computer's bus, and syncronization will be performed on every host computer access. The exact CPU frequencies can be read in the following table:
|clock setting||resulting clock speed|
|0||7.09 or 7.14 MHz|
|2||21.2814 MHz or 28.37516 MHz|
Note that for clock speed 3, the mentioned clock rate is not valid over the whole time. During a fastmem access, one out of four clocks is stretched by just under 12ns, resulting in a slightly slower average clock rate that comes out at an average of 42.0 MHz if measured over a long time. Although this sounds like a slowdown, it actually speeds up the access by half a clock cycle, because if the CPU would be running at full frequency all the time, it would have to insert a full cycle as a wait-state. With the clock-slowdown, the effective wait time is not a full cycle, but only half a cycle.
Clock setting 2 (21 or 28 MHz) is a special case, because the MemProbe bit will decide the resulting clock frequency: With MemProbe=0, the clock rate will be 21 MHz. With MemProbe=1, the clock frequency will be 28 MHz. Note that switching directly between these two frequencies with the MemProbe bit may not be glitch-free (to be tested in-depth!). Should an instability show upon switching directly between 21MHz and 28MHz, you will be able to fix this by switching to 14MHz, then altering the MemProbe bit, and then switching back to clock rate 2, which will then be the glitch-free clock chosen by the state of the MemProbe bit.
The computer will launch at 14MHz. The value of these bits does NOT change on a reset. You can write to these registers at any time without preparation. Their effect is instant. Note that most A1200 accelerators don't like any other frequency than 14MHz, so if you detect a CPU higher than the 68ec000, you should not alter the CPU frequency unless you know that the A1200 accelerator is compatible. If the A1200 accelerator is not compatible, the computer will crash with no possibility to recover it with a reset. Only a power-cycle will bring it back to life.
Maprom register $b2.3000
This read/write register is 0 on power-up and does not change it's value on a reset. When this register is 0, Kickstart ROM can be read normally at $f8.0000 and $e0.0000. In addition to this, RAM area starting at $a0.0000 will be covered by the 512k RAM block that is reserved for Maprom. If Maprom is not used, you can safely regard the 512k area starting at $a0.0000 as RAM, and use $40.0000 to $ad.ffff as a continuous RAM block.
When this register is set to 1, the 512k area at $f8.0000 will be replaced by the 512K Maprom area that was previously available in $a0.0000. Further, the space at $e0.0000 will also be replaced with a mirror of the $f8.0000 area in order to replicate the exact memory map that an A500 computer has. With Maprom=1, the 512k block in $a0.0000 will be replaced with another 512k RAM block, so the whole space from $40.0000 to $ad.ffff can be used as a continuous RAM block.
Writing to either Kickstart space ($f8.0000 or $e0.0000) has no effect, but will be passed to the host computer.
Note that setting the OVL bit in the CIA register will NOT map fastmem, but the physical ROM of the A500 to address $00.0000. However, the computer will never start from that ROM, because Flash of the ACA500plus always takes precedence over anything else with it's early overlay mode. The only exception to this is de-brick status, where the whole computer will run off the Kickstart ROM of the host computer.
ChipMap register $b2.7000
This read/write register is 0 after power-up and does not change it's value on a reset. If set to 1 while the c8mem bit is set to 0 at the same time, any access to the chipmem area $08.0000-$0f.ffff will be mapped to the physical address space $c0.0000-$c7.ffff of the A500 mainboard. This will effectively move the 512k trapdoor expansion to chipmem area, bearing a few incompatibility dangers. Therefore, you may only set this bit after making sure that the host computer fulfills the following points:
- a memory block of exactly 512k was found at start address $c0.0000 (local fastmem at this area must be switched off for probing!)
- Agnus type indicates ECS Agnus
- an amount of exactly 512k chipmem was found at start address $00.0000
You may NOT switch this option on if one or more of the following things are true:
- Agnus type indicates 512k-chipram OCS Agnus
- more than 512k chipmem was found at $00.0000
- more than 512k trapdoor mem was found at $c0.0000
- no trapdoor memory was found at $c0.0000
Note that - as opposed to the predecessor ACA500 - this bit can be normally set/reset when registers are fully unlocked. The old behaviour of only allowing a bit-set in lock state 1 has been removed, because there is no more need to hide the feature - it's been out there for long enough.
Please consult the memory config table at the end of this chapter about how this bit interacts with the ChipMap bit and with Cloaking mode.
FlashWrite register $b2.b000
This read/write register is 0 after every reset. In this state, reading from flash is possible in locations $ba.0000 and $00.0000 (the latter only when early overlay is switched on). While reading the flash rom is transparent and "true-random" with the possibility of code execution directly from flash, writing to flash requires more software interaction. This is due to the fact that the flash chip is an SPI serial flash which requires command sequences in order to execute read, write or erase functions. Only read functions are generated automatically by the hardware, but for any other operation, you need to execute slightly more complicated software. Note that you will need the datasheet of the flash chip (TODO: insert link to Winbond datasheet 25Q64).
In order to pass any command to the serial flash chip, the FlashWrite register must be set to 1. This will disable the transparent-read feature, so you should not run the code for fiddling with the flash chip from flash! When in FlashWrite mode, any command or data can be passed to the flash chip. However, this is not done through data that is written to the chip, but through the addresses that you access. For any byte that you want to pass to the chip, you write any value to an address between $bc.0000 and $bc.01fe. The actual byte that is sent to the chip is taken from address bits 8 down to 1. Address bit 0 will be ignored.
For any 16-bit word that you want to send to the chip, write any value to an address between $ba.0000 and $bb.fffe. The actual word that is sent to the chip will be taken from address bits 16 down to 1. Address bit 0 will be ignored.
Since the "select" signal to the chip is used as a marker for starting and ending a command, the hardware will help you controlling that signal as well. The chip will be automatically selected once you send the first byte or word to it. If you want to end a command, you need to write 0 to the FWrite bit. Remember to set it back to 1 if you want to do further accesses! This allows you to send any sequence to the chip, no matter how long, including sequential read of the whole 8MByte space.
Example: If you want to read the device code, Enable FlashWrite mode and write any value to address $bc.0120. This will select the chip and send the byte $90. Note that the select line remains active, and you can now read bytes from $bc.0000. The first three bytes are $ff, and then you can read the manufacturer code $ef and the device code $16 if you keep on reading the byte at $bc.0000. End the command by setting the FlashWrite bit back to 0. Reading 16-bit words is also possible if you read from $ba.0000, and longword-reads from $ba.0000 will also work as expected, although they won't be much faster than 16-bit word reads.
Caution: Using the FlashWrite register keeps the SPI flash chip selected, which reveals a hardware trick that has been used in order to reduce the amount of external signals: The clock signal of the chip is shared with the address-mapper for the ChipMap feature. Therefore, any mapping that is selected with ChipMap and/or c8mem will be inhibited while the FlashWrite bit is set. This means that during flashing or reading parts of the flash outside the first 256k, you may lose chipram at $08.0000 or mapped memory at $c8.0000. In addition to that, access to the 16-bit local expansion port will generate the wrong addresses while the FlashWrite register is set to 1, which may mean that reading a flash update from a USB stick or from network will have to be completed before any actual flashing takes place.
VBR move $b2.f000
This read/write bit is reset to 0 on every reset. It only has an effect if the 68EC000 processor is working. With an A1200 accelerator connected, this bit will have no effect. If set to 1, all IRQ vector fetches will be moved from Chipram into the beginning of fastmem at $40.0000. The effect of this bit is instant, so you should initialize all vectors prior to setting the bit. Moving the vectors to fastmem will improve performance, but also allows programs like WHDload to intercept a keyboard IRQ ("quit key support"). Further, the VBR-move state machine will *always* fetch the vector for an INT7 from fastmem, regardless of the state of this bit. This is done in preparation of freezer support.
|mem address||write function||short name|
|register $b3.7000||External RTC bit||ExtRTC|
|register $b3.b000||A1200-accel RTC bit||RTC1200|
These two bits control the location of a real-time clock chip. Both bits are 0 on a power-up and do not change their value on a reset. With the "External RTC" bit being 0 and the "A1200-accel RTC" also set to 0, any access to $dc.xxxx will go to the host computer, which will route the access to an RTC that is located on the trapdoor memory expansion, or - in case of an A500plus - the RTC on the main board. However, on an A1000 or on an A500 without trapdoor expansion, it may be desirable to add an external RTC. In this case, the "External RTC" bit must be set to 1. With the "A1200-accel RTC" bit set to 0, an RTC on the ACA500plus clock port can be used. If an A1200 accelerator is connected and it is equipped with an RTC, the "A1200-accel RTC" bit should be set to 1 as well, and the RTC of the accelerator will be used. This is even the case if the A1200 accelerator has been switched off.
By setting the A1200-accel RTC bit to 1, but leaving the External RTC bit 0, any access to $dc.xxxx will go nowhere. This will let you create a configuration without RTC, which can be useful for software testing or for protecting the RTC from unwanted changes.
|ExtRTC||RTC1200||Read access||write access|
|0||0||A500 trapdoor/main board||A500 trapdoor/main board|
|0||1||none/invalid data||dummy-write, no target|
|1||0||ACA500plus clock port, dummy-read from A1200 accelerator||ACA500plus clock port and A1200 accelerator|
|1||1||A1200 accelerator, dummy-read from ACA500plus clock port||ACA500plus clock port and A1200 accelerator|
The above table shows the four possible bit combinations and implications for multiple RTCs in the system. While it is perfectly OK to have an RTC on the trapdoor expansion and on a single external location, it is not recommended to have both external locations occupied with an RTC. This is due to the ACA500plus clock port and the A1200 accelerator port sharing RTC control lines. Only the data buses are separated on read accesses, but for write accesses, both locations are written to at the same time. No harm will be done if two external RTCs are installed, but it just makes no sense.
Start searching for an RTC by first checking the A1200 accelerator setting. This should be done regardless of the $b3.f800 register contents, because even if an ACA1233n or a Blizzard accelerator have been switched off, the RTC of these units is still available. If that RTC is not available, continue searching on the ACA500plus port. If both these locations have no RTC available, try the host computer setting.
MemoryProbe bit $b3.7800
During early overlay (that is: after a reset), this register can be used to probe if an A1200 accelerator is allowing access to a part of the 24-bit address space. It is assumed that every A1200 accelerator is allowing access to the lower 2MBytes of memory, because every A1200 has been shipped with 2MBytes of chipmem. Further, it is assumed that every A1200 accelerator allows access to 0xa0.0000 to 0xbf.ffff, because PCMCIA and CIA registers are located there. Both these 2MByte areas cannot be probed with this feature. Use of the MemoryProbe register is recommended for code execution in flash only in early overlay, or in RAM starting at $a0.0000. With MemProbe only working while Early Overlay is switched on, you should avoid accessing the 256k Flash area at $ba.0000. Since this area can't be probed anyway (see assumptions above), there should not be any need to access this space.
You should also double-check that the computer does NOT run at clock rate#2 (21/28MHz) because the changing states of the MemProbe bit during probing would also alter the clock frequency, which will surely confuse the A1200 accelerator. Since most A1200 accelerators will only work at 14MHz bus frequency anyway, it's safe to always switch to clock rate #1 for probing.
You can write any value to this register and read it back at any time. If you have written 0 previously and read a 1 in this register, then an access to the A500 memory space between 0x20.0000 - 0x9f.ffff or 0xc0.0000 – 0xff.ffff has been made since the last time you have written 0 to it. All interrupts and caches should be switched off during the probing procedure. You can only gain useful information from this register with direct successions of:
– reset MemoryProbe to 0
– dummy access to the area you want to probe (preferrably a read access)
– read MemoryProbe register
If you read 0, then the dummy access has been kept within the domain of the A1200 accelerator. If you read 1, then the access has been passed to the A1200 CPU slot, and you can assume that an access to this area will access the hardware of the ACA500plus. Use this feature to find out if you can use the 0xf0.0000-flash mirror, and the Z2 memory space. You will also be able to find out if memory in 0xc0.0000 is located on the ACA500plus or on the A1200 accelerator.
ARENA bit $b3.f000
ARENA is short for "Action Replay Enable". By writing 1 to the MSB of this location, the memory area from $40.0000 to $43.ffff will be write-protected. Any write access to this 256k space will be ignored. Further, any write access to chip registers in $df.fxxx will not just be written into the chip registers, but also to memory location $44.fxxx, where "xxx" is between $000 and $1ff. If the Action Replay emulation shall be used, please make sure that your memory pool does not start any lower than $45.0000. Also, be careful when using the VBRmove feature: All vectors will be fetched from $40.0000 and higher, so they will be in a write-protected area of ACA500plus memory.
overview of memory configurations
The following table shows how register bits and cloaking device control memory mapping. The top row shows the address that the CPU accesses, and the table cell contents show the address space that is actually reached on the mainboard. Address space is given as the upper byte of a 24-bit address, and a range is shown as "start address to end address +1". This table applies only when Early Overlay is off. Green indicates that the accessed address is located at the exact same place of the host computer. Yellow indicates that the accessed address is a mapped space of the host computer. Blue indicates that the accessed space is located on the ACA500plus.
|1||0||0||0||$08-$10||7Mbyte||512k||$c8-$d0||512k Chipram(*),512k trapdoor mem, 7M Fastmem|
|2||1||0||0||$c0-$c8||7Mbyte||512k||$c8-$d0||1M Chipram,512k trapdoor mem, 7M Fastmem|
|3||0||1||0||$08-$10||7Mbyte||512k||$c0-$c8||512k Chipram(*),1M trapdoor mem, 7M Fastmem|
|4||1||1||0||$c0-$c8||7Mbyte||$c8-$d0||$c8-$d0||1M Chipram,no trapdoor mem, 7M Fastmem|
|5||0||0||1||$08-$10||1Mbyte||512k||$c8-$d0||512k Chipram(*),512k trapdoor mem even without physical trapdoor exp, Space for Action Replay.|
|6||1||0||1||$c0-$c8||1Mbyte||512k||$c8-$d0||1M Chipram,512k trapdoor mem, Space for Action Replay.|
|7||0||1||1||$08-$10||1Mbyte||$c8-$d0||$c8-$d0||512k(*) Chipram-only config, Space for Action Replay.|
|8||1||1||1||$c0-$c8||1Mbyte||$c8-$d0||$c8-$d0||1M Chipram,no trapdoor mem, Space for Action Replay.|
(*): May be larger if host machine has more than 512k chipram. All configs with ChipMap=0 are compatible with any size of Chipram.
Mapping the $c8 space to $c0 is meant to create a copy of the chip registers in place of the trapdoor memory expansion, effectively switching off the expansion. This will only work if the trapdoor expansion is 512k, but not with any larger internal expansion, so a memory config that re-maps $c8 to $c0 may only be switched on if the trapdoor memory expansion is 512k or not installed at all.
Caution: When the FlashWrite bit has been set to 1, any re-mapped host computer memory area will not be re-mapped any more. With FlashWrite=1. the original host computer memory will apear at the accessed address. In "graphic terms", setting FlashWrite to 1 will turn all yellow table cells into green cells.
IDE/CF port details
|mem address||function||access speed|
|$da.0000-$da.01ff||Boot CF card command registers||260ns|
|$da.0200-$da.03ff||intentional gap - no access pulses to CF card are generated.|
|$da.0400-$da.05ff||Boot CF card command registers||260ns|
|$da.0600-$da.07ff||intentional gap - no access pulses to CF card are generated.|
|$da.0800-$da.09ff||Boot CF card 16-bit movem-area||260ns|
|$da.0a00-$da.0bff||intentional gap - no access pulses to CF card are generated.|
|$da.0c00-$da.0dff||Boot CF card 32-bit movem-area: See further down||70ns+45ns pause+70ns|
|$da.0e00-$da.0fff||intentional gap - no access pulses to CF card are generated.|
|$da.1000-$da.11ff||Aux CF card command registers||260ns|
|$da.1200-$da.13ff||intentional gap - no access pulses to CF card are generated.|
|$da.1400-$da.15ff||Aux CF card command registers||260ns|
|$da.1600-$da.17ff||intentional gap - no access pulses to CF card are generated.|
|$da.1800-$da.19ff||Aux CF card 16-bit movem-area||260ns|
|$da.1a00-$da.1bff||intentional gap - no access pulses to CF card are generated.|
|$da.1c00-$da.1dff||Aux CF card 32-bit movem-area: See further down||70ns+45ns pause+70ns|
|$da.1e00-$da.1fff||intentional gap - no access pulses to CF card are generated.|
|$da.2000-$da.21ff||Boot CF card command registers||100ns|
|$da.2200-$da.23ff||intentional gap - no access pulses to CF card are generated.|
|$da.2400-$da.25ff||Boot CF card command registers||80ns|
|$da.2600-$da.27ff||intentional gap - no access pulses to CF card are generated.|
|$da.2800-$da.29ff||Boot CF card movem-area: See further down||100ns|
|$da.2a00-$da.2bff||intentional gap - no access pulses to CF card are generated.|
|$da.2c00-$da.2dff||Boot CF card movem-area: See further down||80ns|
|$da.2e00-$da.2fff||intentional gap - no access pulses to CF card are generated.|
|$da.3000-$da.31ff||Aux CF card command registers||100ns|
|$da.3200-$da.33ff||intentional gap - no access pulses to CF card are generated.|
|$da.3400-$da.35ff||Aux CF card command registers||80ns|
|$da.3600-$da.37ff||intentional gap - no access pulses to CF card are generated.|
|$da.3800-$da.39ff||Aux CF card movem-area: See further down||100ns|
|$da.3a00-$da.3bff||intentional gap - no access pulses to CF card are generated.|
|$da.3c00-$da.3dff||Aux CF card movem-area: See further down||80ns|
|$da.3e00-$da.3fff||intentional gap - no access pulses to CF card are generated.|
The IDE controller of the ACA500plus is compatible with the Amiga 600/1200 IDE controller, but has a few changes that help in increasing performance and separating the two CF card slots.
Each CF card slot has it's own address space. This is achieved by using the "IDE-fix wiring" which puts the second IDE/CF port at the address where you'd normally expect the alternate status register. Since the original scsi.device has never used that register anyway, it has become an established standard to use this space for an additional port that has it's registers at $da.1000 and $da.3000. Both ports will issue the same IRQ level 2, which will be shown in the same Gayle status register. Separate IRQ status registers for each port are available in the ACA500plus registers described above.
Probably the largest difference to the original Gayle-IDE is that the address space does not contain "all mirrors", but gaps of 512 bytes appear on every upper half of one Kbyte. In terms of bit-wise addressing, gaps are created whenever address bit A9 is high. Since the standard scsi.device does not use any address beyond the first addresses, this should not cause any trouble. However, it makes using the movem.l command possible for a specialized driver.
Both CF port areas have a special area that only contains all-mirrors of the IDE data port register. This area is intentionally interrupted with addresses that will not generate any access pulses to the card in order to work around a bug that the 68(EC)000 CPU has: The processor will generate a dummy-access to the next address after the intentional addresses. If this dummy-access would also go to the IDE data port register, you'd lose data on read, or you'd generate gaps (and ultimately an overflow) on writes. You should therefore start your multiple-access at the end of the movem-area, so the dummy-access will end up in one of the gaps where it's safe to have such an access happening.
For use with A1200 accelerators, there is the 32-bit longword movem-area, which will do two consecutive PIO-mode 4 accesses to the data register of the CF card. This allows raw transfer rates of over 9MBytes/second in both directions. The CF card should be programmed to do PIO mode 4 or higher prior to using this fast transfer area. Wait states that the CF card is trying to insert will be ignored, so "fake" CF cards that only pretend to be this fast, will not work at this speed. If the 32-bit movem-area is accessed with any other word size or with the 68ec000 processor, it will generate "slow" accesses of 260ns.
This feature helps getting drivers into the Amiga OS without the need for ugly hacks. With some A1200 accelerators "covering" the $f0.0000 area, the old method that was used on the ACA500 had to be improved. The solution is to sacrifice 64k of memory (of which "plenty" is available) and prepare it with autoconfig data. Although any vendor ID and product ID can be used, you should use the iComp vendor ID 4626 ($1212) and product ID 65 ($41) for the autoconfig nibbles. These have already been added to the latest boards.library.
Since there is no config_in and config_out lines on the A1200 accelerator port, the ACA500plus implements a "sniffing circuit" that will generate these signals internally. For this circuit to work properly and maintain the config chain, the system must know ahead of time which address the 64k-sized board will be mapped to, and how many Autoconfig boards are located within the A1200 accelerator. A few examples:
ACA12xx accelerators use no autoconfig at all. The ACA500plus should be programmed to be the first autoconfig board.
ACA1233n accelerators use Z3 autoconfig for it's memory, which will end up outside the Z2 area. The ACA500plus should be programmed to be the second autoconfig board and to final address $e9.0000.
ACA1221 accelerators use Z2 autoconfig for a 64k-sized IO space, which will be mapped to $e9.0000. The ACA500plus should be programmed to be the second autoconfig board and to final address $ea.0000.
Blizzard 1230-IV accelerators use Z2 autoconfig for a 128k-sized IO space, which will be mapped to $ea.0000. The ACA500plus should be programmed to be the second autoconfig board and to final address $e9.0000.
associated registers and memory space
|mem address||write function||read function|
|area $af.0000-$af.ffff||64k that will be mapped to $e8, $e9 or $ea|
|register $b3.3000||advance/reset register for sniffing engine||state of config-counter bit 0|
|register $b3.3800||final location register|
|register $e8.0048||"configure" address within autoconfig nibbles|
Before the software-defined autoconfig feature can be used, the memory area in $af.0000 up to $af.ffff must be initialized with the autoconfig nibbles and ROM contents. For ideal space utilization, it is recommended to use a (virtual) 16-bit ROM. Loading from this ROM width is bug-free in all known Kickstart versions. Although it's pointless to use a virtual 8-bit ROM in this space, you may be tempted to do so anyway because you have known-good code already. Please be aware that Kickstart versions up to V1.3 have a bug when using 8-bit autoconfig ROMs, so this may not work in all configurations.
After initialization, you must determine where the final location of the autoconfig board will be - this should be possible by looking at the config nibbles in $e8.0000 right after a reset. There are two possible locations that the ACA500plus virtual Autoconfig card can reside at: $e9.0000 and $ea.0000. If you need the card to show up in $e9.0000, write $00 to register $b3.3800. If you need the board to be located in $ea.0000, write $80 to register $b3.3800.
Now launch the sniffing engine by writing $80 to register b3.3000. The sniffing engine is now in a state where it will wait for two autoconfig boards to be configured (two writes to $e8.0048) before it will show itself at $e8.0000. This is a very rare case; for most A1200 accelerators, you will need another write of $80 to register $b3.3000 to advance the sniffing engine to a state where it will only wait for a single autoconfig card to be processed before it will show itself at $e8.0000. To bypass the sniffing engine and place the ACA500plus "first in line", write $80 one more time to $b3.3000. This will immediately show the 64k RAM area in $e8.0000, and when the OS configures the board with a write to $e8.0048, the 64k area will be moved to $e9.0000 or $ea.0000, depending on what you have set before. Once the sniffing engine has reached this state, writing to the final location register will have no effect any more. If the 64k area is mapped to $e8, $e9 or $ea, it will always be read-only, so the two write accesses that configure the virtual board will have no effect on memory contents. The memory area at $af.0000 will always be write-protected when registers are fully locked.
Reading $b3.3000 will return the state of the LSB of the two-bit counter of the sniffing engine. This can be used as a feedback to know if a write access to $e8.0048 has been passed by an A1200 accelerator or not. Some accelerators will show the access on the bus, others won't, and watching this bit during an early scan of autoconfig boards will give you enough information about how to pre-set the counter for normal operation with any unpatched Kickstart ROM.
By writing 0 to the $b3.3000 register, you reset the sniffing engine to it's idle state where it ignores writes to $e8.0048, and you un-configure any previously-configured ACA500plus Autoconfig card. This should be done on every reset. The $af.0000 area will be write-protected when registers are fully locked. For completeness, it should be noted that the $af.0000 area should not be added to the freemem pool under normal conditions. There's a loophole, though: Any other lock state than "fully locked" of the registers will release write protection of this 64k chunk of memory. This could be used to create a "maximum free memory" configuration, or it could be used by other software as temporary space in case standard OS routines are not available.
Resident module RAM
The 64k RAM space from $ae.0000 to $ae.ffff will be mapped to $f0.xxxx and $f2.xxxx unconditionally. Both target 64k areas are equal. This can be used to add resident modules to a Kickstart, or to test diagnosis ROMs that use the magic $1111 value in $f0.0000. Note that Blizzard accelerators will shadow the $f0.xxxx area, so diagnosis ROMs can only be used in 68ec000 mode, or with an ACA12xx accelerator. The $f2.xxxx copy of that same 64k can be used for adding resident modules, such as a high-priority module that takes care of cleaning up software-defined autoconfig on a soft-reset.
Please note that the resident module RAM area will be write-protected as soon as the registers are locked. This means that you should not add this space to the normal freemem pool under normal conditions. The same loophole as for software-defined autoconfig RAM applies: Any other lock state than "fully locked" will enable writing to this space, which can be used to create a "maximum memory" config.
Early startup considerations
The ACA500plus starts with early overlay switched on, meaning that Flash contents are shown at address $00.0000 and higher. Before any other action can be performed, you need to make sure that all parts of the ACA500plus have powered up properly and passed their cold-start initialization:
- wait for the SD-Ram controller to finish initialization
- register $b2.f800 will show the state of initialization. When the mode register of the SD-Ram chip has been set, this bit will be 1. From this time, another two refresh cycles must be done before Fastmem can be accessed. The easiest way to accomplish this is to wait in an idle-loop for 32µs.
- init display-MCU
- the display MCU takes care of the 2-digit 7-segment display, the Red-Blue LED and the brightness of the two CF card activity LEDs. Any access to the MCU will give bus control to the MCU and halt the 68k processor until the MCU sends an ACK. By accessing any register, the CPU will automatically wait until the MCU has properly started up. If you read the register that contains the information "cold start or warm start", a returned value will automatically mean that the MCU has started.
- check if A1200 accelerator is present
- register $b3.f800 will show a 0 in bit 15 if an A1200 accelerator is present. If this is the case, probe for shadowed memory areas and store the results in a safe place, for example in the display-MCU or in a fastmem area that will not be added to the free memory pool.
- check trapdoor memory size
- While in early overlay mode, the first 256k of address space are overlaid with flash memory. At the same time, the second 256k-block of address space will be re-mapped to $cc.0000, which allows probing for memory in the second 512k-block of trapdoor memory. This information is required to determine if the ChipMap feature can be offered to the user or not. Since most ACA12xx accelerators will shadow 1MB of the trapdoor memory area, you should also probe for presence of a 512k trapdoor expansion in this step by setting the ChipMap bit. If you find RAM at $08.0000 with this register config, it's a $c0.0000 RAM expansion. If you find RAM at $04.0000 during early overlay, the host computer has a trapdoor memory expansion with a Gary-adapter, which makes use of the ChipMap feature impossible. Remember to switch off ChipMap after probing!
- end early overlay mode
- Jump to an address within the 256k-block starting at $ba.0000. Code execution can continue normally and does not have to do anything special to end early overlay mode. It's switched off automatically just by jumping to the address, giving normal access to chipram. Remember to switch off the OVL bit (CIA register) to gain access to chipram!
The ACA500plus shall not give the user any reason to disconnect the hardware from the computer. Removing and attaching the accelerator may cause wear on the connector and the Amiga, so the "cloaking" method has been introduced. To activate the cloaking device, you need to attempt to send the bate-command $01 (write status) to the flash chip (FlashWrite bit set). Note that sending the $01 command as part of a 16-bit word to the Flash chip will not activate the cloaking device. This command will not be sent to the flash chip, so no harm can be done (such as bringing the flash chip into a state where it can't be recovered). Instead, the cloaking device will be activated, resulting in the following changes:
- All registers will be locked
- the described unlocking method will not work. All registers will stay locked until the next reset.
- FWrite bit will be set to 0
- This is a safety measure, because you won't be able to access the FWrite bit after activating the cloaking device.
- Fastmem at $40.0000 will be reduced to 1MByte
- This memory may be used to activate Action Replay emulation and/or HRTmon.
- Software-defined autoconfig will be deactivated
- you may need to execute a reset command before activating cloaking in order to reset all autoconfig boards. This MUST happen before activating cloaking, because a "low" on the reset line will deactivate cloaking.
- All clock ports will be deactivated
- This includes the ACA500plus clock port, the "RapidRoad port" of the ACA1221(ec) and ACA1233n accelerators but keeps RTCs available.
- the IDE controller will be deactivated
- it is recommended to switch power off for CF card#2. Any access to Gayle-compatible registers will be routed to the host computer.
- the network/USB expansion port will be deactivated
- accesses to $ee.0000 and $ef.0000 will be routed to the host computer.
- Flash access will be switched off
- any access to flash areas will be routed to the host computer
- ACA500plus registers are not readable
- this includes all read-addresses for registers, but also Gayle-identification registers
- Gayle-IRQs are inhibited
- no Level-2 IRQs from any of the two ports, regardless of the IRQ enable state.
- Resident module RAM will be switched off
- Reading $f0.xxxx and $f2.xxxx areas will return the value that the host machine provides
The following features stay active during cloaking, so they can be used to create a config with a selected memory and clock compatibility. Make sure that all bits are set to the required value before activating the cloaking device:
- Usual restrictions apply - see ChipMap description. When ChipMap is activated, 512k Fastmem of the ACA500plus at $c0.0000 are mapped in, even with cloaking activated. This has been done to NOT have the same 512k chunk of memory twice in the computer. With ChipMap=c8mem=1, you can still deactivate the trapdoor memory expansion (chip registers from $c8.0000 will be mapped to $c0.0000).
- any 512k Kickstart Image can be used, which can be seen at $f8.0000 and $e0.0000.
- CF card #2 power
- make sure to turn power off before activating the cloaking device!
- RTC configuration
- all four RTC selections can be used: Trapdoor, Clockport, A1200 accelerator and no RTC.
- ARENA bit
- when set, clock port addresses at $d8.c000 remain available, allowing access to the MCU, which is required for Action Replay emulation. Note that clock speed changes are not possible with cloaking activated.
- VBRmove bit
- when set, IRQ vectors will be fetched from fastmem at $40.0000.
- higher-speed clock
- although it's most desirable to run the computer at syncronous 7MHz when cloaked, you may also choose a higher speed.
Effects of a reset
This chapter was introduced in order to have an overview about what happens on a reset. Since the reset instrucion of the M68k CPU is required a number of times during startup for scanning Autoconfig devices and bringing other components into a known state, it may be handy to have an overview about what happens in the ACA500plus hardware.
- During a reset, any INT7 that may come from DisMo is inhibited. That means, if DisMo is currently issuing an INT7, it will come back after the reset has been completed, probably causing hardly-predictable behaviour of the CPU (Todo: Find out how a pending NMI affects continued execution after reset command). It may therefore be wise to double check in the DisMo status register if an INT7 is pending and acknowledge it before executing the reset command.
- Affected registers
- The reset instruction will unlock all registers unconditionally
- VBRmove will be cleared
- The state machine that identifies an IRQ vector fetch will be reset
- FlashWrite register will be cleared, so random read access from flash is possible
- Early Overlay mode will be set
- Gayle identification will be reset
- Gayle-IDE IRQs will be masked (register $da.a000 cleared)
- Pending Gayle-IDE IRQ will be cleared
- Cloaking device will be deactivated
- Affected components
- any clock port device
- the network/USB module
- Boot CF card
- Aux CF card if power to the Aux card is switched on
- components not affected
- The SD-Ram state machine will continue to work and for example generate refresh cycles during a reset (also during a long keyboard reset).
- DisMo will not know about the reset - the signal isn't even wired to the small daughterboard.
- overclocked MC68ec000
Please keep in mind that the 68ec000 on the ACA500plus is overclocked - quite substantially, that is: The chip is 10MHz-rated, and behaves nicely up to 14MHz. Soft-reset becomes a problem starting at 21MHz. It is therefore recommended to write ACA500plus-specific soft-reset routines that clock down to 14MHz, then issue the reset command, and then go back to the desired frequency.
DisMo (Display/Button unit) registers
The small PCB on top of the ACA500plus serves as display, LED and button unit. It will be referred to as "DisMo", short for "display module". DisMo serves as debug output, MHz-display, freeze-button and even as a replacement for the de-brick jumper. It occupies a total of 32 registers starting at $d8.c001 with a register spacing of 512 bytes. The lowest register has no effect but locking write-accesses to other registers in order to gain highest possible compatibility with clockport drivers looking for hardware at base address $d8.c000. With the large register spacing, there's hope that most (if not all) clockport drivers that know about 4-way clockport splitters will only use the lowest mirror of clockport registers. By activating register lock, such drivers will automatically make sure that no unwanted changes to the display will happen. On power-up, registers are not locked.
All registers are nibble-wide, and they use the lower-significant nibble of a byte.
"Digit A" refers to the left 7-segment digit. "Digit B" refers to the right 7-segment digit. Segments are labelled with a 2-character positional code, for example: LL=lower left, UR=upper right, and more self-explanatory positions.
|address||reg #||write function||read function|
|$d8.c001||0||Lock write-registers||Lock write-registers|
|$d8.c201||1||Brightness register Digit A, Segment 1 (UL)||Blank display|
|$d8.c401||2||Brightness register Digit A, Segment 2 (UR)|
|$d8.c601||3||Brightness register Digit A, Segment 3 (MID)|
|$d8.c801||4||Brightness register Digit A, Segment 4 (TOP)|
|$d8.ca01||5||Brightness register Digit A, Segment 5 (BOT)|
|$d8.cc01||6||Brightness register Digit A, Segment 6 (LR)|
|$d8.ce01||7||Brightness register Digit A, Segment 7 (LL)|
|$d8.d001||8||Brightness register for decimal point (digit A)|
|$d8.d201||9||Brightness register Digit B, Segment 1 (UL)|
|$d8.d401||10||Brightness register Digit B, Segment 2 (UR)|
|$d8.d601||11||Brightness register Digit B, Segment 3 (MID)|
|$d8.d801||12||Brightness register Digit B, Segment 4 (TOP)|
|$d8.da01||13||Brightness register Digit B, Segment 5 (BOT)|
|$d8.dc01||14||Brightness register Digit B, Segment 6 (LR)|
|$d8.de01||15||Brightness register Digit B, Segment 7 (LL)|
|$d8.e001||16||Brightness register for red part of R-B LED||Execute Soft-INT7 command|
|$d8.e201||17||Brightness register for blue part of R-B LED|
|$d8.e401||18||Brightness register for CF card LEDs|
|$d8.e601||19||Brightness for use with hex-display|
|$d8.e801||20||Digit A hex value||Last button-push time high nibble|
|$d8.ea01||21||Digit B hex value||Last button-push time low nibble|
|$d8.ec01||22||Set user-defined character||De-Brick status in LSB: 1=armed|
|$d8.ee01||23||address pointer bits 0-3||address pointer bits 0-3|
|$d8.f001||24||address pointer bits 4-7||address pointer bits 4-7|
|$d8.f201||25||address pointer bits 8-11||address pointer bits 8-11|
|$d8.f401||26||address pointer bits 12-15||address pointer bits 12-15|
|$d8.f601||27||Data register EEPROM||Data register EEPROM|
|$d8.f801||28||Data register RAM 1 (128 bytes)||Data register RAM 1|
|$d8.fa01||29||Data register RAM 2 (256 bytes)||Data register RAM 2|
|$d8.fc01||30||Data register RAM 3 (32 bytes)||Data register RAM 3|
|$d8.fe01||31||command register (may use parameters from from RAM-3)||status|
Write a hex-value to the display by first choosing a brightness (write to $d8.e601, register#19) and then writing the two digits. Setting a brightness in register#19 is only required if you want to change it. Setting register#19 will only have effect on the next digit that you set. You can also control each segment individually by writing to it's brightness register. Using the hex-value registers will overwrite the contents in the individual brightness registers. A mix of using both is possible, for example by setting hex-value 8, and then turning it into a 6 by setting segment-2 to brightness 0.
Register #22 uses the same birhgtness setting from register#19, but chooses one out of eight user-defined 7-segment characters from RAM1 area. The MSB of this nibble selects if the character is set on Digit A (MSB=0) or Digit B (MSB=1). Note that each segment has it's own character-RAM space!
Reading the status register returns 4 bits of data in the lower nibble:
bit#0: MaskINT7 (1=masked)
bit#1: INT7 status (1=INT7 comes from DisMo, 0=no INT7 from DisMo)
bit#2: PowerUp (1 on a fresh power up, 0 after executing the Reset-powerup command)
bit#3: Soft-INT7 flag. Shows the cause of an active INT7: 0= cause was a button-press, 1=cause was a $f command or a register #19-read.
Writing to the command register will execute one of 16 commands immediately. The value you write into the command register is the command to be executed. During command execution, the 68k processor will be halted.
Command# $0: Reset PowerUp. After executing this command, the PowerUp bit in the status register will read 0. Use this bit to identify a power-up or a keyboard reset.
Command# $1: Mask INT7. Executing this command will disable INT7-IRQs from DisMo.
Command# $2: Allow INT7. Executing this command will allow INT7-IRQs from DisMo. If the button is pressed for more than two jiffies (where one jiffy is about 17ms), and INT7 will be issued to the host computer upon release of the button. However, if the button is pressed long enough for de-brick mode to be enabled, an INT7 will not be issued upon release of the button. If INT7 is not masked and an INT7 has been issued to the computer, it will remain active (and readable in the status register) until the $3 command has been executed.
Command# $3: Acknowledge INT7. Execute this command to release the INT7 request - this should be the second command in your IRQ service routine, right after finding out in the status register that DisMo is the cause for the INT7. This command is always available, register locking does not apply to this one.
Command# $4: Get version. This command writes version information to the beginning of RAM3 (Ascii string, 0-terminated).
Command# $5: Erase EEPROM sector. This command requires the string "I AM SURE" (case-sensitive) to be at address 0 of RAM3, otherwise the command will not be executed, and the string "NOT ERASED." is placed into RAM3. EEPROM Erase can only happen in 512-byte sectors. The address of the sector is taken from the address pointer, so please make sure to set the address pointer to one of the 1024 nibble-locations within the sector you want to erase - that is of course _after_ you have put the "I AM SURE" string into RAM3, using the same pointer. After the operation has been completed, the string "ERASED." is placed into RAM3.
Command# $6: Unlock DisMo registers. This command requires the string "OPEN SESAME" (case-sensitive) to be located at address 0 of RAM3, otherwise it will answer with "REFUSED" in that same RAM space. If the unlock code is found, RAM3 will show "DisMo unlocked." and EEPROM, RAM1 and RAM2 access will work as described. With register locking, write access to RAM1, RAM2 and EEPROM is inhibited, and EEPROM erasing will not be executed. All other actions are not affected by register locking.
Command# $7: Reset animation sequence pointer to 0. Execute this command after initializing RAM2 with your own animation sequence.
Command# $8: Load and start Animation preset. This command takes a parameter from RAM3, address 0. Allowed values are 0 to 3. All other bits will be masked. Animation #0 is the one that's displayed when the button is held long enough to get to de-brick mode. Animations #1 and #2 display a wheel, one turning left, the other turning right, which can be used for "please wait"-messages. Animation #3 is used during mass-production for testing all segments.
Command# $9: Stop animation. This will stop any animation and leave the display in it's current status. If you want it blanked, you need to call the "blank" command by reading from register #1.
Command# $d: Disarm De-Brick. This command will disarm de-brick, stop any running animation and blank the 7-segment displays. Use this command after a successful rescue-flash if you don't want to prompt the user to press the button.
Command# $e: Re-initialize DisMo. This will re-initialize the MCU on DisMo. Use with caution: This command will also set the "Power up" bit, so the next start will apear like a fresh power up if you don't execute the $0 command right after this one.
Command# $f; Issue INT7. Use this command to issue an INT7. Only works if INT7 is not masked. Use this command to launch Breakpoints in the old Action Replay software. A software-issued INT7 also needs acknowledge with the $3 command! This command may also be executed by reading from register#16. The returned value has no meaning and will likely contain whatever you've read from a DisMo register before. It is therefore recommended to not use the value you've read.
Accessing RAM and EEPROM
RAM and EEPROM of the DisMo MCU can be accessed through the nibble-based pointer (NBP), which can be directly written to through registers #23 to #26. The pointer is called "nibble-based", because it really points to nibbles, not to bytes. All four RAM and EEPROM access registers (#27 to #30) share the same pointer. Whenever one of the access registers is read or written, the pointer is automatically increased. It is therefore recommended to make sure that accessing RAM or EEPROM spaces is an atomic operation, so one access window won't alter the pointer that another routine may be using. Another alternative would be to store the current state of the NBP - the four registers are read/writable.
Writing to RAM is transparent. Although the MCU has both RAM and EEPROM byte-based, you can read and write nibbles without taking care of the other nibble which is located in the same byte. Note that nibble-based addressing is using big-endian-like addressing: Nibble#0 uses bits 7 down to 4, and nibble #1 uses bits 3 down to 0 of the actual memory cells inside the MCU. This knowledge is required to re-build bytes and strings that are part of commands.
Writing to EEPROM is not as transparent as writing to RAM, because writing the first (higher-order) nibble is not written to EEPROM immediately, but to a temporary buffer in RAM. Only when the second nibble of a byte has been written, the actual write to EEPROM is executed, and the byte is stored in non-volatile memory of the MCU. A byte in EEPROM must be $ff before it can be written to. Setting a byte to $ff can only be done with the sector erase command.
The EEPROM space of the MCU is used for storing user-defined profiles, menu-wide variables and support for factory-side flashing. Since the 5KByte space can only be erased in 512-byte blocks, these have been chosen as natural boundaries for each storage segment.
Byte 0 of EEPROM space serves as initial flash marker. If this byte contains any other value than 0, the ACA500plus will power-up with De-Brick mode set. You can always leave de-brick mode with a short press on the button and restart the computer with a keyboard reset. It is recommended to write $00 to this byte after any successful flashing, so the card will launch in menu-mode on power-up.
RAM1 contains the character generator for the "user-defined characters" write-register #22. There is a total of 16 characters starting at address 0. Each byte defines one character. The first 8 bytes are used for Digit A, and the next 8 bytes are used for Digit B. This means that you can define different characters for the left and for the right digit, giving slightly more flixibility. The lower seven out of eight bits are used, the MSB is unused. The following bit layout is used:
|bit 7||bit 6||bit 5||bit 4||bit 3||bit 2||bit 1||bit 0|
|unused||Segment 7 (LL)||Segment 6 (LR)||Segment 5 (BOT)||Segment 4 (TOP)||Segment 3 (MID)||Segment 2 (UR)||Segment 1 (UL)|
Example: The value %01101011=$6B in address 8 will display something that comes close to the upper-case letter "N" on the right digit upon writing $8 to register #22, which can be used in conjunction with a "0" in Digit A to display "ON".
In addition to that, RAM1 contains the brightness translation table. Internally, the MCU handles LED brightness with an 8-bit linear PWM value. However, the human eye is not linear at all, so in order to create a perception of 16 linear brightness values, the 16 bytes starting at address $10 in RAM1 are initialized at power-up with these values:
|RAM1 address||value (decimal)|
Alter this table for example if you want to reduce the overall brightness of the display. If you desire an especially low brightness, you may lose a few brightness steps because consecutive translation entries must be filled with the same value.
Note that only the 7-segment display and the R-B LED brightness is translated using this user-defined table. The CF activity brightness is always translated using the "full brightness" table in order not to lose the highest setting. This is due to the fact that pulse width modulation does not work nicely with quickly changing on/off settings that you have on the CF card activity LEDs.
Display animation sequences
DisMo supports a simple command sequence that allows showing simple animations on the green 7-segment displays (the R-B LED is not supported for animations). All animation code is located in RAM2, the 256-byte block. Each byte contains opcode and parameter. Opcodes are encoded according to the following table:
|bit 7||bit 6||bit 5||bit 4||bit 3||bit 2||bit 1||bit 0||meaning|
|0||0||a||a||a||a||a||a||Wait for (a) Jiffies (max 63 = about 1 second)|
|0||1||0||x||a||a||a||a||Load 4-bit value a into accumulator|
|0||1||1||x||a||a||a||a||Store Accumulator into segment brightness register (see further down)|
|1||0||a||a||a||a||a||a||Goto address %aaaa.aa00 in RAM2 memory|
|1||1||0||a||a||a||a||a||Write accumulator to RAM3 location a|
The Wait and Load opcodes should be self-explanatory. Waiting for 0 Jiffies makes no sense, but will be executed normally. For Store, the parameter refers to segment brightness in the same order as listed in the write-registers of Dismo with the only difference being that the Store command starts at 0 for Digit A, Segment 1 (=register number minus one).
If you use the Store command is used with parameter $F, you write to the Fade-out speed register. A fade-out speed of 0 means that there is no fading. Higher numbers mean the number of jiffies to skip until all 7-segment registers are reduced by 1. That means 1 is the highest speed and $F is the slowest speed. This can be used to create an afterglow-effect. Note that the Fading engine will run in parallel to your animation sequence, so if you choose a value of 2, it will only take 32 Jiffies until the whole display is completely dark. Your animation sequence should either set the desired segments over and over again (thus creating a flash-and-afterglow effect), or set the Fade-speed register to 0 after a certain amount of jiffies. Setting the Fade Speed register does NOT cause the sequence to wait; the next command is executed right away. If you want the animation sequence to wait, then only a wait command will do this.
The Goto command can be used to jump unconditionally within the animation sequence. Note that the lower two bits of the address cannot be set directly. Adjust your "code" with NOP commands in order to create a correct entry point for your animation. Caution: The command on the jump target will not be executed. You should therefore jump to a NOP location, or really be aware that the command you're jumping to will be skipped, and execution will be continued at the next byte.
Writing to RAM3 can be used to talk back to the host machine: If for example you write a characteristic value to the end of RAM3, you can syncronize your display with the automatic animation sequence.
The animation and fading engines are stopped on power-up. After writing your own animation sequence to RAM2, you launch the animation engine with the $7 command. The first command in memory is not executed.
Example: The following sequence uses the bottom segment of Digit B as a "blinking cursor":
- $e0, $4f, $6c, $0e : NOP, Load $f, Store $f in address $c, delay for 14 Jiffies
- $40, $6c, $0e : Load $0, Store $0 in address $c, delay for 14 Jiffies
- $80 : Jump to address 0
Changes for BigDismo
The 2018 production run of the ACA500plus is shipped with a slightly updated DisMo. The button is placed at a more convenient position, and the display is about twice as high as the original DisMo's display. Further, the R-B LED has been upgraded to an RGB LED. The green part of the LED is controlled with register $d8.e401 (register 18). CF brightness control is not available on the new DisMo; CF Activity LEDs are always full-brightness.
Another new feature is the possibility to issue a soft-INT7 from an animation sequence. Opcode $70 within an animation sequence will issue an INT7, then continue with the animation sequence. You can use this to either issue a recurring INT7, or as a one-shot timer if you place an endless loop after the $70 command.
BigDismo identifies with version 1.9 instead of 1.7 of the original DisMo.