Flashing the C-One Flash ROM

by Jens Schönfeld. Any suggestions to - thanks!



The C-One reconfigurable computer's flash rom was initially not meant to be programmed from "inside" the computer. The following documentation only applies to boards that have either been reworked, or shipped after August 16th, 2003.

With this rework, the flash rom appears in the CPU's memory map through a bottleneck. This bottleneck is designed to be as fast as possible. Given the fact that all the logic had to fit in the existing 32-macrocell CPLD, it's all we can do. The estimated time for flashing a 128K flash rom is below 1 minute. The rework even gives the possibility to access a 512K flash rom in the socket of the reworked mainboard.

Access to the rom is done by first storing the address in the address register, and then accessing the byte you chose at one of the four byte registers.

The Address register is 17 bits wide. It allows access to 128K of flash rom space. If a 512K flash rom is located in the socket, the two additional bits that are necessary are given by the number of the byte register that is being used to access the chip: Each of the four registers selects one of the four 128K blocks of a 512K flash rom. If a 128K flash chip is used, the four byte registers are identical.

Setting the address register

All commands that modify the address register are given by accessing a specific address in the I/O space of the drive CPU. It does not matter if the access is a read or a write access. The data is ignored: if you do a read access, the data that's read has no meaning, and if the access is a write, the data has no effect. However, the address space for the address register is shared with a possible real-time clock module on one of the clockports of the machine. Therefore, read accesses from the registers are recommended in order not to overwrite the RTC time.

The Address register can only be set. The current state of the register cannot be read! If you need to know where the address register currently points, you have to keep a shadow register in your code. The following addresses only apply to the drive CPU. The flash rom can also be accessed through this bottleneck from the main CPU, but this will be in a different address space. Documentation for this will follow later.

To clear the address register, read from $3f60.

To shift the current address one bit left, read from $3f66. By shifting left, the MSB is shifted "out" (into nirvana), and a 0 is shifted into the LSB. This operation can also be seen as a multiplication by 2.

To increment the counter by 1, read from $3f68. Increment can be used to set the LSB after shifting left, or to count the full register up (the full carry is implemented!).

The above commands can be used as often as necessary to get to the desired address. During the proess of setting the address, no access is done to the flash rom itself.

After setting the address, the data of the flash rom can be accessed by reading from or writing to the following addresses:

  $3f6c (0x0xxxx)
  $3f6d (0x2xxxx)
  $3f6e (0x4xxxx)
  $3f6f (0x6xxxx)

The addresses in brackets only apply to 512K flash roms (type 29F040). If a 128K type is used (29F010 or similar), all register addresses go to 0x02aaa of the chip. Accessing the rom chip through these four registers does not alter the address in the address register. You can write to the register, and immediately read back the value (verify-access) as often as necessary.

The drive CPU can also access other parts of the computer through it's I/O ports. This might be interesting for future use, like reacting to a CBM cartridge in the cartridge slot. Although only the first 16 bytes of the cartridge can be "seen", it's enough to make a recommendation to the user to use a C64 compatible core if the CBM80 string is detected:

  $3f00   ROML (cartridge)
  $3f10   I/O2 (cartridge)
  $3f20   Clockport1 (spare chip-select, for example Silversurfer or RR-Net)
  $3f30   SID1 (not enough registers, SID cannot be used!)
  $3f40   ROMH (cartridge)
  $3f50   I/O1 (cartridge)
  $3f60   Clockport2 (RTC select, real-time clock and flash rom address)
  $3f70   SID2 (not enough registers, SID cannot be used!)

AMD notes

From my experience from the Retro Replay and Kickflash, I know that AMD flash roms do not always behave as described in the datasheets. The different versions of the flash roms are not easily to identify, usually not by software. The big problems began on the Retro Replay when we started to use 29F010B flash roms. They would program properly, but would not erase. We worked out a lot, even contacted AMD for assistance and did literally everything what they suggested: Tested for spikes on the select/oe/write lines, made scope shots and sent them to the AMD engineers, and even got hold of an internal AMD document that describes a few changes from 29F010 to 29F010B. But still, the "multiple sector erase" command did not work!

Count 0's findings, as well as my findings prove that AMD f*cked up on that command with the die-shrink that they obviously made moving towards the B version of the chip. They might have done the same on the 29F040 (blank, A or B suffix), and this is a warning to you programmers: if one command of the flash chip works (such as chip identify and sector protection status read), all other commands should work as well. If multiple sector erase does not work, try erasing single sectors. That's what we did on the Retro Replay, and it'll save you a lot of time, and only cost a few seconds on the user end.