# Atari 2600 Emulator ## About This App A developer-tools emulator for running classic Atari 2600 ROMs with cycle-accurate VSYNC/VBLANK timing diagnostics ## Specification # Atari 2600 Emulator with Strict VSYNC/VBLANK Timing Create a visually stunning, retro-themed Atari 2600 emulator web app that faithfully emulates the 6507 CPU (a cut-down 6502) and the TIA (Television Interface Adapter) chip entirely in JavaScript. Users can upload ROM files of any file extension, and the emulator will attempt to run them as Atari 2600 cartridges. This is a **HTML5 Canvas App** — the TIA output will be rendered to a canvas element simulating the classic NTSC TV output, and the entire experience should feel like powering on a vintage console. **Key Modification: Strict VSYNC/VBLANK Timing Engine** This version implements a precise, cycle-accurate NTSC frame timing model. The emulator enforces and tracks the exact VSYNC and VBLANK protocol that real Atari 2600 hardware requires: - **VSYNC Phase**: VSYNC must be turned ON (bit 1 of VSYNC register written), held for at least 3 scanlines (2+ complete lines), then turned OFF. The emulator tracks exactly how many scanlines VSYNC is held active and flags deviations. - **VBLANK Phase**: After VSYNC ends, VBLANK must be turned ON (bit 1 of VBLANK register written) and held for exactly 37 scanlines of vertical blank period before being turned OFF to begin the visible frame. - **Visible Frame**: Exactly 192 scanlines of visible picture. - **Overscan**: 30 scanlines of overscan (VBLANK turned back on) before the next VSYNC. - **Total Frame**: 262 scanlines per NTSC frame (3 VSYNC + 37 VBLANK + 192 visible + 30 overscan). The emulator includes a **Timing Diagnostics Panel** that shows the current frame's timing breakdown in real-time, highlights timing violations, and helps developers debug ROMs with incorrect timing. The emulator will tolerate minor timing deviations (as real hardware does) but will visually flag them for educational purposes. ## UI Elements ### Overall Layout & Theme - Dark background (#1a1a2e or similar deep CRT-monitor black) with scanline overlay effects - Retro woodgrain panel aesthetic inspired by the original Atari 2600 "heavy sixer" console design - A warm color palette: woodgrain browns, black plastic, chrome/silver accents, and the classic Atari red-orange - Pixel-perfect fonts — use a retro bitmap-style font (e.g., "Press Start 2P" from Google Fonts) - CRT screen curvature effect on the game display canvas using CSS border-radius and subtle box-shadow glow ### Header Area - "ATARI 2600" logo rendered in the classic Atari futura-style font with rainbow stripe decoration - Subtitle: "JavaScript TIA & 6507 Emulator — Cycle-Accurate VSYNC/VBLANK Timing" in smaller retro text - A subtle animated scanline effect across the header ### Console Display Area (Center Stage) - A large HTML5 Canvas element (160×192 native resolution, scaled up to ~640×480 or responsive) representing the TV screen - The canvas should be wrapped in a "TV frame" — a rounded rectangle with a dark bezel, CRT glass reflection overlay (subtle CSS gradient), and phosphor glow effect - Scanline overlay (semi-transparent horizontal lines) rendered via CSS or a second overlay canvas - When no ROM is loaded, display a "Insert Cartridge" message with the classic Atari "fuji" logo animated with a gentle color cycling effect - Color palette: Implement the full NTSC TIA 128-color palette accurately - **Frame Timing Indicator**: A small LED-style indicator in the corner of the TV bezel that glows green when frame timing is correct (262 lines, proper VSYNC/VBLANK), yellow for minor deviations (±2 lines), and red for major timing violations. This gives instant visual feedback on ROM timing correctness. ### ROM Upload Panel - A prominent "INSERT CARTRIDGE" button styled like a physical cartridge slot — a wide rectangular button with woodgrain texture and a dark slot opening - Drag-and-drop zone surrounding the button with dashed retro border - Accept ANY file extension (no filtering) — the app will attempt to interpret any file as a raw Atari 2600 ROM - Display the loaded ROM filename, file size, and detected mapper type (if applicable: 2K, 4K, F8, F6, etc.) - Show a "cartridge inserted" animation when a file is loaded (cartridge sliding down into slot) ### Controls Panel - **Virtual Joystick**: An on-screen D-pad (up/down/left/right) and fire button, styled like the classic Atari CX40 joystick — black stick with orange fire button - **Console Switches**: Toggle switches for RESET, SELECT, Color/BW, and Difficulty A/B (Left/Right) — styled as physical silver toggle switches - **Keyboard Mapping Display**: Show the keyboard controls mapping (Arrow keys = joystick, Space/Z = fire, R = reset, S = select, etc.) - Controls should work on both desktop (keyboard) and mobile (touch) ### Emulator Controls Bar - Play/Pause button with retro styling - Reset button (sends console reset signal) - Speed controls: 1x, 2x, turbo - Volume slider for TIA audio output (the TIA generates two channels of sound — implement basic square wave / noise audio via Web Audio API) - FPS counter and cycle counter display in a small green-on-black "LED" style readout - Fullscreen toggle button - **Strict Timing Mode Toggle**: A switch labeled "STRICT TIMING" that when enabled, forces the emulator to enforce exact NTSC timing (262 scanlines per frame) and will display warnings when ROMs deviate. When disabled, the emulator is more tolerant (like some real hardware variations). ### VSYNC/VBLANK Timing Diagnostics Panel (New — Collapsible) This is a **new dedicated panel** that provides real-time visibility into the frame timing protocol: - **Frame Timing Diagram**: A visual horizontal bar chart showing the current frame's breakdown: - VSYNC lines (expected: 3, shown in red/orange) - VBLANK lines (expected: 37, shown in blue) - Visible lines (expected: 192, shown in green) - Overscan lines (expected: 30, shown in purple) - Total line count with expected vs actual - **Timing State Machine Display**: Show the current state of the VSYNC/VBLANK state machine: - States: `VSYNC_ON`, `VSYNC_OFF → VBLANK_ON`, `VBLANK_ACTIVE`, `VBLANK_OFF → VISIBLE`, `VISIBLE`, `OVERSCAN`, `WAITING_VSYNC` - Highlight the current state with a glowing indicator - Show the scanline counter within each phase - **Timing Event Log**: A scrolling log (last ~20 events) showing timing events with scanline numbers: - "Line 0: VSYNC ON (write $02 to VSYNC)" - "Line 3: VSYNC OFF (write $00 to VSYNC)" - "Line 3: VBLANK ON (write $02 to VBLANK)" - "Line 40: VBLANK OFF (write $00 to VBLANK) — visible frame begins" - "Line 232: VBLANK ON (write $02 to VBLANK) — overscan begins" - Timing violations shown in red with explanations: "⚠ VSYNC held for only 1 line (expected 3+)" - **Per-Frame Statistics**: - VSYNC duration (in scanlines): actual vs expected (3) - VBLANK duration (in scanlines): actual vs expected (37) - Visible frame duration: actual vs expected (192) - Overscan duration: actual vs expected (30) - Total scanlines this frame: actual vs expected (262) - CPU cycles per frame: actual vs expected (~76 × 228 / 3 ≈ 5,776 per scanline, ~17,556 total... display actual) - Frame deviation counter: how many frames have had timing errors - **Timing Violation Warnings**: Large, clear warning banners when: - VSYNC is too short (< 2 complete lines) - VSYNC is never triggered (frame without VSYNC) - VBLANK period is too short or too long - Total scanlines significantly deviate from 262 - WSYNC is never called (potential racing the beam issues) - Styled in amber-on-black terminal aesthetic, distinct from the CPU debug panel ### Debug Panel (Collapsible/Toggle) - **CPU State**: Display all 6507 registers (A, X, Y, SP, PC, Status flags N/V/B/D/I/Z/C) in real-time, hex format, green-on-black terminal style - **TIA Registers**: Show key TIA register values (COLUBK, COLUPF, COLUP0, COLUP1, GRP0, GRP1, PF0-PF2, etc.) - **Enhanced**: Also prominently display VSYNC ($00) and VBLANK ($01) register values with their bit fields decoded (bit 1 = sync/blank enable, bit 6 of VBLANK = latched input, bit 7 of VBLANK = ground paddle ports) - **Memory Viewer**: A hex dump view of the 128 bytes of RIOT RAM ($80-$FF) - **Disassembly View**: Show the current instruction and a few surrounding instructions with addresses and opcodes - **Enhanced**: Highlight writes to VSYNC ($00) and VBLANK ($01) addresses in a distinct color (amber/yellow) so developers can immediately spot timing-related code - **Step/Break Controls**: Step one instruction, step one frame, step one scanline (new), run to breakpoint - **New**: "Step to next VSYNC" button — runs until the next VSYNC write is detected - **New**: "Step to next VBLANK OFF" button — runs until VBLANK is turned off (start of visible frame) - **Scanline Breakpoint**: Set a breakpoint on a specific scanline number — the emulator pauses when that scanline is reached - Monospaced font, dark terminal aesthetic with green or amber text ### Sidebar Info Panel - Display cartridge info: filename, size, detected bank switching scheme - Brief description of the 6507 CPU: "MOS 6507 — 1.19 MHz, 8-bit, 13-bit address bus (8KB addressable)" - Brief description of the TIA: "Television Interface Adapter — 160×192 resolution, 128 colors, 2 players, 2 missiles, 1 ball, playfield" - **New — NTSC Timing Reference Card**: - "NTSC Frame Structure (262 scanlines total):" - "├─ VSYNC: 3 scanlines (lines 0-2)" - "├─ VBLANK: 37 scanlines (lines 3-39)" - "├─ Visible: 192 scanlines (lines 40-231)" - "└─ Overscan: 30 scanlines (lines 232-261)" - "Each scanline: 228 color clocks (76 CPU cycles)" - "Frame rate: 59.94 Hz (262 × 228 ÷ 3 = ~19,912 cycles/frame)" - "WSYNC halts CPU until horizontal blank" - This serves as a quick reference for developers and learners - Link to Atari 2600 programming resources ### Footer - "Powered by JavaScript — No actual hardware harmed in this emulation 🕹️" - Remix on Berrry - Small disclaimer: "This is an educational emulator. Please use legally obtained ROM files." ## Styling Preferences - **CRT Effect**: Scanlines, slight screen curvature (via CSS), phosphor glow (box-shadow), and optional RGB sub-pixel rendering - **Woodgrain Texture**: CSS gradient or subtle background image for the console body panels - **Animations**: Smooth cartridge insertion animation, power-on screen fade-in, color cycling on idle screen - **Responsive**: Scale the canvas and controls for mobile — stack vertically, make touch controls prominent - **Audio Feedback**: Satisfying "click" sound on button presses, cartridge insertion sound effect - **Timing Panel Styling**: The VSYNC/VBLANK diagnostics panel should use an amber-on-black color scheme (distinct from the green CPU debug panel) to visually separate timing concerns from general CPU debugging. Timing violations should pulse/flash briefly in red when they occur. ## Core Emulation Functionality ### 6507 CPU (Complete Implementation) - Implement ALL legal 6502/6507 opcodes (56 instructions, ~151 opcode variants) - Accurate cycle counting per instruction (important for TIA timing) - Support all addressing modes: Immediate, Zero Page, Zero Page X/Y, Absolute, Absolute X/Y, Indirect X/Y, Implied, Relative, Accumulator - 13-bit address bus (mirrors the full 6502 but only exposes A0-A12) - Proper BCD mode for ADC/SBC (though rarely used in games) ### TIA Chip (Television Interface Adapter) — Enhanced with Strict Timing - Implement the full NTSC color palette (128 colors, 16 hues × 8 luminances) - Render: Background (COLUBK), Playfield (PF0/PF1/PF2), Player 0 & 1 sprites (GRP0/GRP1), Missiles (ENAM0/ENAM1), Ball (ENABL) - Proper sprite positioning via RESP0/RESP1, HMP0/HMP1, HMOVE - Playfield reflection/duplication modes - Collision detection registers (CXM0P, CXM1P, CXP0FB, etc.) - WSYNC (halt CPU until end of scanline), VSYNC, VBLANK timing - Implement basic TIA audio: Two channels with frequency dividers, volume, and noise/tone control registers (AUDC0/1, AUDF0/1, AUDV0/1) via Web Audio API **Strict VSYNC/VBLANK Timing Implementation (Core Modification):** - **VSYNC Register ($00) Handling**: - When bit 1 is set (STA VSYNC with value $02), the TIA enters VSYNC state - The emulator records the scanline number where VSYNC was activated - VSYNC must remain active for at least 3 complete scanlines (the TV needs this to detect vertical sync) - When bit 1 is cleared (STA VSYNC with value $00), the TIA exits VSYNC state - The emulator calculates and records the VSYNC duration in scanlines - If VSYNC duration < 2 complete lines, flag a timing violation: "VSYNC too short" - If VSYNC duration > 5 lines, flag a timing warning: "VSYNC unusually long" - If no VSYNC occurs within 300 scanlines, flag: "Missing VSYNC — frame may not sync" - **VBLANK Register ($01) Handling**: - When bit 1 is set (STA VBLANK with value $02), the TIA enters vertical blank — the display outputs black regardless of other TIA register contents - The emulator records when VBLANK is turned on and off - After VSYNC ends, VBLANK should be active for 37 scanlines (lines 3-39) - When bit 1 is cleared (STA VBLANK with value $00), the visible frame begins - The emulator records the actual VBLANK duration and compares to expected 37 lines - Deviation tracking: if VBLANK is only 30 lines, the visible frame starts 7 lines early; if 45 lines, 8 lines of visible frame are lost - Also handle VBLANK ## About Berrry Berrry transforms your social media content into interactive web applications. Share a Twitter/X post or Reddit comment, and our AI creates a custom web app hosted at your own subdomain. **Visit**: https://berrry.app Transform your social media ideas into real web applications today.