Technical Details

Ultimem supports additional memory as 8 kilobyte “banks” that can independently mapped into the following areas of the Commodore VIC-20 memory map:

  • RAM1/2/3
  • BLK1
  • BLK2
  • BLK3
  • BLK5
  • IO2/IO3

The Ultimem configuration registers are located at the top of the IO3 address space ($9ff0) and comprise 16 registers with the following definitions:

  1. CONTROL ($9ff0)
    • bit0: LED (1 = on)
    • bit1: switch0 (read only, 0 = pressed)
      • (switch 0 is the middle switch on Ultimem, and the rightmost top mounted switch on VIC-MIDI as viewed while installed in the VIC-20)
    • bit2: switch1 (read only, 0 = pressed)
      • (switch 1 is the left-most switch on Ultimem and VIC-MIDI, as viewed while installed in a VIC-20)
    • bit6: soft reset (1 = reset VIC, but keep register values)
    • bit7: hide registers (1 = hide registers)
  2. MEM_CONFIG1 ($9ff1)
    • bit0/1: RAM1/2/3 config
      • 00: no ram or rom
      • 01: RAM (R/O)
      • 10: FLASH ROM
      • 11: RAM (R/W)
    • bit 2/3: IO2 config
    • bit 4/5: IO3 config
  3. MEM_CONFIG2 ($9ff2)
    • bit0/1: BLK1 config
    • bit 2/3: BLK2 config
    • bit 4/5: BLK3 config
    • bit 6/7: BLK5 config
  4. ID ($9ff3)
    • bit0-3: Cartridge Type
      • $1: ULTIMEM
      • $2: VIC-MIDI
    • bit 4-7: Cartridge Manufacturer
      • $1: RETRO Innovations
    • Default Value: 1
    • Bank is stored in low byte/high byte order
  5. IO_BANK ($9ff6/7)
    • Default Value: 2
  6. BLK1_BANK ($9ff8/9)
    • Default Value: 3
  7. BLK2_BANK ($9ffa/b)
    • Default Value 4:
  8. BLK3_BANK($9ffc/d)
    • Default Value: 4
  9. BLK5_BANK($9ffe/f)
    • Default Value: 0


  • RAM1,2,3 can only be enabled/disabled/configured as 1 group of locations.  If you want RAM at RAM1, you’ll get it at RAM2 and 3 as well
  • IO2/3 can be independently enabled/disabled, but must map to the same area of memory.  If you have RAM at IO2 and IO3, they will both map to the same RAM bank in UltiMem
  • Memory is mapped on 8kB boundaries at all times. Thus, if memory is mapped to RAM1,2,3 or IO2,IO3, the first memory location stored in UltiMem memory will be at the 8kB based offset of the VIC-20 memory location.  For example.  If IO2 ($9800) is mapped to a RAM bank, a write to $9800 will be stored at offset $1800 in the RAM bank.   Normally, this is of no interest, unless you move the RAM bank.  If you store data in a bank of data mapped to $9800 and then map it to BLK1 ($2000), the data will be read from $3800 ($2000 base address + $1800).  You can use this to your advantage by mapping RAM1,2,3 and IO2/3 to the same bank of RAM or FLASH, as none of them overlap within the 8kB address space ($0400), ($0800), ($0c00), ($1800), ($1c00)
  • If RAM or FLASH is placed under the Ultimem registers, the registers will override the RAM or ROM values at those locations, unless the registers are hidden using bit 7 of the CONTROL register.
  • The LED and switches are for user usage.
  • On boot, BLK5 is set to FLASH bank 0.  All other banks are disabled
  • On boot and reset, holding down switch0 will disable BLK5 FLASH visibility
  • On reset, bank registers are set to the following values (RAM = 1, IO = 2, BLK1 = 3, BLK2= 4, BLK3 = 5, BLK5 = 0).  This is done to ensure that BLK5 will point to the first bank of memory, and that if someone enabled all banks, the banks will not collide.
  • After hiding the registers, one can re-enable them by reading $9f55,$9faa, and then $9f01. Thus, to check for Ultimem capability, one should read from the 3 locations, and then read the ID register.
  • Do not assume RAM size.  Perform a RAM test.
  • Do not assume FLASH ROM size.  FLASH ROM ICs can be queried for size and capabilities.


Project Files

Frequently Asked Questions

Usage Examples

  • To enable all memory, store 63 in MEM_CONFIG1 and 255 and MEM_CONFIG2 and then store 64 into CONTROL.  This will reset the machine with all RAM enabled