UNPKG

zx-generation

Version:

A high-fidelity ZX Spectrum emulator in JavaScript — fully generated by a large language model (LLM) to explore the boundaries of AI in systems programming.

304 lines (240 loc) 9.5 kB
# ZX Generation *ZX Generation* is a modern, JavaScript-powered emulator of the legendary **Sinclair ZX Spectrum** home computer. **100 % AI-crafted** the project was conceived, designed, and developed end-to-end by LLMs (Large Language Models). The codebase was generated, reviewed, and refined primarily with **Anthropic Claude (Claude Code)**. > *No human lines were typed:* every commit originates from model output; human input was limited to prompting, dependency wiring, CI/CD orchestration and few documentation details. ## Why this matters - **Transparency** Showcases the current state of autonomous software engineering. - **Benchmarking** Serves as a live case-study for AI-generated code quality, maintainability, and performance. ## Limitations & future work - Edge-case fuzzing for every ZX instruction is still pending. - Performance tuning (JIT, SIMD) is on the roadmap. - Expect rapid iteration as newer model checkpoints become available. --- ## Table of Contents - [ZX Generation](#zx-generation) - [Why this matters](#why-this-matters) - [Limitations \& future work](#limitations--future-work) - [Table of Contents](#table-of-contents) - [Features](#features) - [Screenshots](#screenshots) - [Quick Start](#quick-start) - [Basic usage](#basic-usage) - [Loading programs](#loading-programs) - [Examples](#examples) - [Browser Support](#browser-support) - [API Reference](#api-reference) - [src file structure](#src-file-structure) - [Development Guide](#development-guide) - [License](#license) --- ## Features - **Cycle-accurate Z80 CPU emulation** - **Full 48 K Spectrum support** - **Pixel-perfect video output** (256 × 192) with border and colour-clash effects - **Authentic audio** via the Web Audio API - **needs improvements** - **Tape loading** for `.TAP` and `.TZX` files and **snapshot** loading/saving for `.Z80` files - **On-screen touch keyboard** for mobile devices - **Turbo mode** to run the CPU faster than real-time - **Zero dependencies** pure ES 2023 JavaScript modules - **Responsive layout** for phones and tablets --- ## Screenshots <table> <tr> <td><img src="docs/screenshots/screenshot-1.png" alt="screenshot-1" width="300"/></td> <td><img src="docs/screenshots/screenshot-2.png" alt="screenshot-1" width="300"/></td> </tr> <tr> <td><img src="docs/screenshots/screenshot-3.png" alt="screenshot-1" width="300"/></td> <td><img src="docs/screenshots/screenshot-4.png" alt="screenshot-1" width="300"/></td> </tr> </table> --- ## Quick Start ### Basic usage ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ZX Spectrum</title> <style> body { display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background: #000; } </style> </head> <body> <canvas id="screen"></canvas> <script type="module"> import { ZXSpectrum } from 'https://cdn.jsdelivr.net/npm/zx-generation@latest/dist/zxgeneration.esm.js'; new ZXSpectrum('#screen'); </script> </body> </html> ``` ### Loading programs ```javascript // Load a TAP file const tap = await fetch('game.tap').then(r => r.arrayBuffer()); spectrum.loadTape(new Uint8Array(tap)); // Type the LOAD "" command spectrum.typeText('J""\n'); // Start tape playback spectrum.playTape(); ``` --- ## Examples | File | Description | | ------------------------- | ------------------------------------------------------ | | **examples/minimal.html** | Truly minimal emulator setup | | **examples/basic.html** | Full-featured interface with controls and tape loading | | **examples/retro.css** | ZX Spectrum themed styling for examples | --- ## Browser Support | Browser | Version | Status | | --------------- | ------- | ----------------- | | Chrome | 80 + | Fully supported | | Firefox | 75 + | Fully supported | | Safari | 13.1 + | Fully supported | | Edge (Chromium) | 80 + | Fully supported | | Chrome Android | 80 + | Fully supported | | Mobile Safari | 13.4 + | Fully supported | --- ## API Reference ```ts class ZXSpectrum { constructor(canvasOrSelector: string | HTMLCanvasElement, options?: Options); // ROM Management loadROM(data: Uint8Array): void; loadROMFromURL(url: string): Promise<void>; // Emulation Control start(): Promise<void>; stop(): void; reset(): void; setTurboMode(enabled: boolean): void; destroy(): void; // Tape Operations loadTape(data: ArrayBuffer | Uint8Array, filename?: string): void; loadTapeFromURL(url: string): Promise<void>; playTape(): void; pauseTape(): void; stopTape(): void; rewindTape(): void; getTapeStatus(): TapeStatus; // Keyboard Input keyDown(keyOrEvent: string | KeyboardEvent): void; keyUp(keyOrEvent: string | KeyboardEvent): void; keyPress(keyOrEvent: string | KeyboardEvent, duration?: number): Promise<void>; typeText(text: string, options?: TypeOptions): Promise<void>; setKeyMapping(pcKey: string, spectrumKey: string | KeyMapping): void; setKeyMappings(mappings: Record<string, string | KeyMapping>): void; clearCustomKeyMappings(): void; // Snapshots loadSnapshot(data: SnapshotData): void; loadZ80Snapshot(data: ArrayBuffer | Uint8Array): void; saveSnapshot(): SnapshotData; // Memory Access poke(address: number, value: number): void; peek(address: number): number; // Audio Control setVolume(volume: number): void; setMuted(muted: boolean): void; setAudioDebugMode(enabled: boolean): void; // Statistics getStats(): EmulatorStats; } interface Options { rom?: string | Uint8Array; // ROM data or URL (default: CDN URL) autoStart?: boolean; // Start automatically (default: true) sound?: boolean; // Enable sound (default: true) useAudioWorklet?: boolean; // Use AudioWorklet API (default: true) scale?: number | 'auto'; // Display scale (default: 'auto') handleKeyboard?: boolean; // Handle keyboard input (default: true) touchKeyboard?: boolean | 'auto'; // Touch keyboard support (default: 'auto') fps?: number; // Frames per second (default: 50) onReady?: (emulator: ZXSpectrum) => void; onError?: (error: Error) => void; } interface TypeOptions { keyDelay?: number; // Delay between keys in ms (default: 100) keyDuration?: number; // Key press duration in ms (default: 50) } interface TapeStatus { status: string; position: number; playing: boolean; paused: boolean; } interface SnapshotData { ram: Uint8Array; cpu: CPUState; ula: { borderColor: number }; } ``` --- ## src file structure ``` src/ ├── core/ # Z80 CPU core ├── cpu.js # Main CPU emulation ├── registers.js # CPU registers implementation └── flags.js # CPU flags handling ├── decoder/ # Instruction decoding └── instruction-decoder.js ├── instructions/ # Z80 instruction implementations ├── arithmetic.js # Arithmetic operations ├── bit.js # Bit manipulation ├── extended.js # Extended instruction set ├── indexed.js # IX/IY indexed instructions ├── jump.js # Jump and call instructions ├── load.js # Load and store operations ├── logical.js # Logical operations └── misc.js # Miscellaneous instructions ├── interfaces/ # Hardware interfaces ├── io-interface.js # I/O port interface └── memory-interface.js # Memory access interface ├── spectrum/ # ZX Spectrum hardware emulation ├── spectrum.js # Main emulator class ├── memory.js # Memory management ├── display.js # Video display rendering ├── ula.js # ULA chip emulation ├── sound.js # Basic sound generation ├── audio-worklet.js # Advanced audio using Web Audio ├── tape.js # Tape loading emulation ├── snapshot.js # Snapshot loading/saving └── touch-keyboard.js # Touch screen keyboard └── utils/ # Helper utilities ├── debugger.js # Debugging utilities └── helpers.js # General helper functions ``` --- ## Development Guide 1. **Clone the repository** ```bash git clone https://github.com/alvaromah/zx-generation cd zx-generation ``` 2. **Serve the files** ```bash # Python python -m http.server 8000 # Node.js npx serve . # PHP php -S localhost:8000 ``` 3. **Open the demo** Visit [http://localhost:8000/examples/basic.html](http://localhost:8000/examples/basic.html) in your browser. --- ## License MIT see the [LICENSE](LICENSE) file for details. > The original ZX Spectrum ROM (`rom/48k.rom`) is copyright **Sky UK Limited** (acquired from Amstrad plc). Distributed solely for use with emulators under Amstrad’s permission. See `rom/README.md` for the full copyright notice. --- Made with ❤️ + 🤖 for the ZX Spectrum community