TI-99/4A GROM: Cartridge Addressing and GPL Execution
Trace TI-99/4A GROM address counters and ports, distinguish GPL code from the CPU-ROM interpreter, and identify read-only GROM versus writable RAM/GRAM hardware.
The TI-99/4A is a home computer with a cartridge slot, but its cartridge software is not always a conventional ROM image visible as a flat CPU address range. Texas Instruments’ Graphics Read Only Memory (GROM) devices expose their contents through a small memory-mapped interface and an internal address counter. That design let the console’s software and cartridges use a shared GROM access interface while keeping the processor’s address space, video memory, and GROM contents as distinct resources.
The distinction matters when reading a cartridge, writing an emulator, or diagnosing software that starts in one language environment and calls routines stored elsewhere. This article focuses on the GROM access path and its relationship to the console’s Graphics Programming Language (GPL) interpreter. It does not treat every TI cartridge as GROM-only: modules can use other ROM or RAM hardware, and their exact contents are product-specific.
GROM is accessed through ports, not as ordinary CPU RAM
The TI-99/4A technical data manual places GROM access in the CPU’s memory map. The data path uses separate read and write regions, with the GROM interface also exposing address access. Software first selects a GROM address, then transfers bytes through the data port; reads advance the device’s address counter. This is different from a processor directly fetching an instruction byte from a conventional ROM location, even though the contents are part of the program’s logical address space.
The interface’s port selection is important. In the documented memory map, >9800 is the GROM read-data port and >9C00 is the write-data port; corresponding address operations are decoded in those regions. These are I/O-facing CPU addresses, not the physical address of an individual GROM chip’s storage cell. The write-data cycle does not make a stock console GROM writable: TI’s service manual says that the TMC0430 does not accept a data transfer on this operation. Treat >9C00 as a path for hardware that actually implements writable RAM/GRAM or a compatible read/write GROM, not as a way to alter the read-only TMC0430. A cartridge or expansion device may add writable memory, so verify its own decode before relying on writes. Do not report >9800 as “the first byte of cartridge ROM”; it is the CPU’s route to the GROM interface.
A read routine therefore has state beyond a CPU pointer. It must set the GROM address using the address port in the required byte sequence, then consume the stream in order from the data port. If it seeks to a new location, it must program the device’s address counter again. A host-side emulator that models the port as a static byte array but omits the counter, read/write decode, or device selection can return plausible data for simple sequential reads and still fail on address setup or cartridge boundaries.
The console’s three built-in GROM devices and cartridge GROMs occupy different portions of the system’s GROM space. TI’s system-software design specification contains a GROM memory map and separate sections for console GROM usage, the GPL interpreter, and GROM BASIC execution. That specification is for the earlier TI-99/4, not a claim that every /4A revision is byte-for-byte identical. Use it as design context and cross-check hardware details against the /4A service and technical manuals before implementing or diagnosing a particular console.
The GPL interpreter is part of the system’s software path
TI’s “Graphic Programming Language” was a compact interpreted language used by the system software and some application code. The roles are distinct: the console’s CPU ROM contains the GPL interpreter, while GROM contains GPL programs and system software for that interpreter to run. The TMS9900 executes native interpreter code from ROM, and that interpreter fetches GPL program bytes through the GROM interface; the interpreter itself is not stored in GROM. A cartridge with GROM-resident software can therefore participate in a path that is not simply “CPU jumps to the cartridge start address and executes native instructions.” The host processor, GROM hardware, console routines, and ROM-resident GPL interpreter each have a role.
This layered design also explains why the word “graphics” should not be read as meaning that GROM is the video display processor’s memory. The VDP has its own memory and access interface. GPL code may direct graphics operations, but GROM is a program/data store reached through the CPU’s GROM interface. A memory dump of VDP RAM is not a dump of the GROM contents, and a GROM address is not a VDP address.
Nor should GROM replace “cartridge ROM” as a blanket term. TI’s original system documents distinguish ROM usage, GROM usage, CPU RAM, and VDP RAM. Cartridge designs can combine these resources or use a different address decode. Before deciding where a title’s code or assets reside, identify the actual module type and inspect its documented memory map or hardware. The GROM model describes a particular path, not the entirety of the TI-99/4A cartridge ecosystem.
Address counters change how tools should read a cartridge
A preservation or diagnostic tool should record the exact access sequence rather than pretending that every read is a random-access memory read. Start from a known reset or initialization state, program the requested GROM address through the device’s address registers, and log each data-port read with the resulting logical counter. Verify whether the target’s device-selection logic routes the request to console or cartridge GROM. Keep raw port transactions alongside decoded addresses so a mismatch can be separated into address setup, device select, or returned-data problems.
For hardware work, the TI-99/4A schematic and technical data identify the GROM devices and their control/data signals. A cartridge or replacement board may add its own selection logic, so the console’s built-in mapping does not prove that every module responds identically. Do not hot-swap a module or drive the bus from a test fixture unless the specific hardware documentation and electrical setup permit it; the old interface was not designed around a generic modern memory probe.
For emulator work, model the state that the real interface exposes: address writes, sequential data reads, device selection, and any timing or ready behavior that is supported by the implementation target. Keep GROM access separate from the VDP’s data/address ports and from cartridge ROM banking. A memory-map abstraction should document which layer owns each address and which side effects occur on a read. Use tests that perform sequential reads, set a new address mid-stream, cross the end of an installed device’s region, and switch between console and cartridge content. Compare against a known console or a hardware-validated reference rather than inferring correctness from one boot screen.
These tests should also preserve version boundaries. The 1980 TI-99/4 software specification is valuable for the original design and GPL execution path; the 1983 TI-99/4A technical and service manuals are the better references for the later machine’s hardware. A later flash cartridge can emulate or extend GROM behavior but is not evidence that an original cartridge had the same capacity, timing, or bank-selection circuit.
What GROM explains - and what it does not
GROM is a useful example of a cartridge system whose software-visible organization is mediated by a dedicated sequential-memory interface. Its address counter, separate CPU-facing ports, and interpreter relationship help explain how a compact console could locate and execute high-level software without placing every byte in directly addressed processor RAM. But it does not, by itself, explain the TI-99/4A’s graphics performance, BASIC speed, every cartridge’s contents, or every compatibility issue. Those require separate study of the TMS9900, VDP, sound device, GPL implementation, and cartridge-specific circuits.
When investigating a title, keep those components separate in notes and code. Identify whether a byte came from GROM, cartridge ROM/RAM, CPU memory, or VDP memory; record the access path and counter state; and cite the manual matching the machine revision. That small discipline prevents a GROM port from being mistaken for a flat ROM window and gives emulator tests a much clearer target.
Related:
- Cartridge Mappers and Bank Switching: How Consoles Addressed Games Larger Than Memory
- MAME Address Maps: Decoding Arcade Buses, Banks, Mirrors, and Handlers
Sources: