|PRG ROM capacity||512K|
|PRG ROM window||32K|
|PRG RAM capacity||None|
|Nametable mirroring||4 fixed|
Cheapocabra or GTROM is a self-flashable cartridge board intended for homebrew releases with its own unique mapper assigned to iNES Mapper 111. The board and mapper were designed by Membler Industries which also manufactures the cartridges.
The Cheapocabra board and mapper were developed in 2015 by Memblers to meet the needs of the lower end of the homebrew cartridge market. This includes games that would have historically used an NROM board as well as other simpler boards which provide some kind of bank switching but lacked more advanced features like IRQs. The underlying philosophy is that stocking larger numbers of a single board design allows for lower costs by economies of scale when compared to stocking smaller individual quantities of a suite of lower end boards all with similar capabilities. This is especially true when it is considered that using smaller flash chips and removing mapper logic does not significantly reduce the cost of manufacturing a board.
The name Cheapocabra is a play on Chupacabra, a creature from American folklore, where the similar sounding first syllable is replaced with the word "cheap" to indicate the intended low cost of the hardware. The GTROM moniker, meaning "Goat ROM," is derived directly from this as Chupacabra translates literally as "goat-sucker" and the Chupacabras of legend are known for attacking goats and other livestock.
A single, write-only, 8-bit register controls everything on the board. Since the register combines multiple controls into a single byte it is not possible to update the bit fields for one function without writing the value for all of them. If a program needs to update a particular field without affecting the others then its best to always keep a copy of the register value in RAM. The RAM value can be read and surgically manipulated as needed and then just copied to the register after each update or a group of updates is made.
The register is mapped to the CPU addresses $5000-$5FFF and $7000-$7FFF and writing a byte to any of these addresses all have the same result. Programs most commonly use $5000 for writing to the register but any of the others work equally well.
7 bit 0 ---- ---- GRNC PPPP |||| |||| |||| ++++- Select 32 KB PRG ROM bank for CPU $8000-$FFFF |||+------ Select 8 KB CHR RAM bank for PPU $0000-$1FFF ||+------- Select 8 KB nametable for PPU $2000-$3EFF |+-------- Red LED - 0=On; 1=Off +--------- Green LED - 0=On; 1=Off
There are two LEDs on the board; one red and one green. They can be independently turned on and off using the register at any time. The LEDs are potentially useful as a simple means of communicating debug information or some kind of indicator for the player. Another approach is to turn the light off during processing and on during idle resulting in the brightness of the light being a rough indicator of available CPU time.
PRG ROM (CPU $8000-$FFFF)
512 KB of flash memory is mapped to a 32 KB window located at $8000-$FFFF in CPU address space providing the PRG ROM for the cartridge. The full 512 KB is divided into sixteen 32 KB pages which can be selected by writing the index number of the desired page to the lower nybble of the control register located at $5000. No portion of the bank is fixed and no portion of the pages overlap and so switching pages results in all the addresses in the bank being redirected to another unique location on the flash chip.
The lack of a fixed bank may make development more difficult since care must be taken to ensure that the next instruction of the program to execute after the register update will be located at the next address in the page that is being switched in. If the new page contains something else at that address then the program will likely crash since the CPU will still proceed to execute it anyway. Possible ways to address this are to execute from RAM while bank switching or to duplicate sections of code across two or more banks. A common approach is to create a faux 16 KB fixed bank at $C000-$FFFF by duplicating the same 16 KB of data in the upper half of all 16 individual pages but this effectively reduces the size of the ROM to 272 KB (16 KB * 16 pages + 16 KB fixed). The same approach could also be used to create fixed banks of other sizes and at other locations within the window.
Like UNROM 512, GTROM uses a SST39SF040 flash chip as the PRG ROM storage device. Both of these mappers lack PRG RAM for game saves but the configuration of both boards make it possible to erase and rewrite sections of the chip using NES software thus allowing games to store saved games and other variable information on the "ROM" chip. The saved data actually becomes part of the ROM image since its just stored alongside the rest of the program and game data on the flash chip.
Rewriting is accomplished by writing specific sequences of bytes to specific addresses on the chip to unlock and perform a particular action such as erasing a sector or writing a byte value. The particular sequences are documented on the data sheet for the chip. The addresses given on the data sheet are in addresses on the chip and thus 5555h corresponds to CPU $D555 and 2AAAh corresponds to CPU $AAAA regardless of the PRG page selected.
NES programs must execute from RAM while erasing and writing to the chip since the CPU fetching instructions from it would interfere with the command sequence. Writing data to a sector is accomplished by first erasing the sector and then writing each byte in turn which requires writing the appropriate command sequence to the chip each time. This would be similar to the example code for UNROM except that the bank switches and addresses would need to be adjusted to match GTROM's requirements.
CHR RAM (PPU $0000-$1FFF)
Both pattern tables, $0000-$1FFF in PPU address space, are wired to 16 KB of CHR RAM split into two swapable 8 KB pages. The page is selected by setting or clearing bit 4 of the control register. Both pattern tables can be independently populated by first selecting the desired page and then filling the memory through the serial interface using the normal procedure. Once both pages in the bank are populated they can be instantly swaped between the two different sets of patterns by updating the control register like any other paged bank.
All of the normal advantages of CHR RAM over CHR ROM apply to this board such as being able to dynamical update tiles between frames for animations and other effects. Since the RAM bank is paged it also has the same kind of "flip book" capabilities often associated with CHR ROM.
VRAM (PPU $2000-$3EFF)
GTROM maps the nametable addresses, $2000-$3EFF in PPU address space, directly to nearly 16 KB of on-board RAM split into two swappable pages (each just shy of 8 KB). This provides unique memory in both pages for all 4 nametables. This means the mapper always uses 4-screen mirroring which eliminates the need for a soldered jumper or a physical or software switch to control the mirroring because none of the nametables are mirrored in this configuration. This also means that games can scroll freely in either or both directions simultaneously because there is always a full two screens worth of tiles for both directions.
Use bit 5 of the control register to select the specific page. As with the CHR RAM, either page can be selected and then the data can be read into the page through the serial interface like normal. Once both pages are populated they can be instantly flipped back and forth by updating the control register.
The nametable RAM on the board covers the full nametable address range extending all the way to $3EFF. Each of the four screens only use one kilobyte and so table four ends at $2FFF. Normally, $3000-$3EFF is just a mirror of $2000-$2EFF and is not usually useful since the last 256 bytes of the nametable 4 mirror are cut-off because palette RAM is mapped to $3F00-$3FFF (this is also the reason the bank window is slightly less than 8 KB).
On this board these addresses are not mirrored and instead are wired to real, independent addresses on the RAM chip. Since these PPU addresses aren't actually used by the system this creates some additional RAM space that can be used for general purposes. Both pages in this bank contain their own copy of this bonus RAM so the total is almost 8 KB split evenly across the two pages.
Since this is mapped to PPU addresses and not to CPU addresses the only way to read or write it is through the PPUADDR and PPUDATA registers. This complicates the use of the memory since the serial interface is slower and programming it adds complexity when compared to working with RAM wired directly to the CPU. Additionally, as with all PPU memory, the bonus RAM generally cannot be accessed while the PPU is rendering (since the PPU is actively using the bus) which may limit the usefulness of the added RAM.
Emulator support for this mapper is currently spotty. Most were designed before GTROM and have been slow to add support but this may be a chicken-or-the-egg problem with the current lack of many freely distributed ROM images that use the mapper. Some of the implementations that are available are incomplete since they commonly lack support for the bonus RAM or self-flashing capabilities. The LED lights on the board are universally unsupported at this time.
The 2.2.3 release of FCEUX does not support GTROM, though the current interim build does.
However, a custom build of FCEUX with support for the mapper is available for download from Memblers' homepage. This implementation doesn't support the "bonus RAM" at PPU $3000-$3EFF because the architecture of the emulator makes implementing this infeasible. The source code is also available on GitHub.
Memblers shared the schematic: https://forums.nesdev.com/viewtopic.php?p=226364#p226364
The functions evaluated by the logic include:
- CHRRAMA14 = N if (PPUA13==1) otherwise C
- PRGROM/OE = NOT(R/W)
- Latch on falling edge of M2, if /ROMSEL, A14, and A12 all high.
Note that reads from the latch will write the value of open bus to the latch, which includes dummy reads from indexed addressing.
- Membler Industries in 2015 - forum post describing the board.