-
Notifications
You must be signed in to change notification settings - Fork 0
RIOT
The RIOT (RAM-I/O-Timer; called "PIA" in the Stella Programmer's Guide) has no direct analog in most other consoles Rusty2600's sibling emulators cover — it's a standard MOS 6532, entirely independent of the TIA. It supplies the three things the VCS needs outside the TIA: the console's only RAM, its two I/O ports, and an interval timer.
Audio is NOT here. The Atari 2600's two sound channels live entirely in the TIA (see TIA); the 6532 has no sound hardware of any kind. This is worth stating plainly since a reader coming from another console's architecture might otherwise assume a chip named "I/O and Timer" also carries sound — it doesn't, on this console.
128 bytes, at 80ドル..=$FF. There is no separate work RAM on the 2600 — this is it, and the CPU stack overlaps this same region (the 6502 0100ドル stack page maps into the RIOT RAM mirror). Rusty2600's Bus therefore has no wram field at all; the RIOT's own RAM array is the entire story. Power-on RAM contents are randomized from the same seeded PRNG that seeds CPU register state (see Architecture-Decision-Records ADR 0004/0006), never the OS RNG.
| Port | Address | DDR | Contents |
|---|---|---|---|
SWCHA |
280ドル |
SWACNT (281ドル) |
Port A: the two joystick directionals (and paddle/keypad multiplexing) |
SWCHB |
282ドル |
SWBCNT (283ドル) |
Port B: console switches — Reset, Select, Color/B&W, the two difficulty switches |
Idle inputs read high (pulled up): ports power on to 0xFF.
Writing the count to one of four prescaler-selecting addresses starts the timer decrementing at that rate:
| Write addr | Name | Prescale | Tick period (NTSC) |
|---|---|---|---|
| 294ドル | TIM1T |
1 CPU cycle | 838 ns |
| 295ドル | TIM8T |
8 cycles | 6.7 μs |
| 296ドル | TIM64T |
64 cycles | 53.6 μs |
| 297ドル | T1024T |
1024 cycles | 858.2 μs (power-on default) |
Read the current value at INTIM (284ドル) and the underflow status at INSTAT (285,ドル undocumented). After hitting zero, the timer holds 0 for one prescale interval, then wraps to $FF and decrements once per CPU cycle — the classic "fast rollover" real hardware exhibits. Because the 6507 has no interrupt lines, the timer cannot fire an IRQ; software must poll INTIM, and this is the 2600's only substitute for a frame interrupt.
Once the timer underflows, real 6532 silicon decrements at the forced 1-CPU-cycle rate until the next time a program reads INTIM — at which point the divider reverts to the originally-selected prescale. Rusty2600 originally modeled this as two separate flags (one for the INSTAT-visible interrupt latch, one for the actual decrement-rate gate) rather than the single flag real silicon uses for both, which meant a program's timer, once underflowed even once, stayed in fast mode forever. This was found via a real differential-testing session against Gopher2600 and Stella on Pitfall II's boot-time RIOT-timer wait loop, and fixed to match the confirmed real-hardware behavior exactly. See Testing-Strategy for more on how this kind of bug gets found.
The RIOT advances on the CPU cycle (every third TIA color clock); the interval timer is further prescaled by 1/8/64/1024. See Lockstep-Scheduler for the full divisor table.