@xn-intenton-z2a/agentic-lib 7.1.65 → 7.1.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xn-intenton-z2a/agentic-lib",
3
- "version": "7.1.65",
3
+ "version": "7.1.66",
4
4
  "description": "Agentic-lib Agentic Coding Systems SDK powering automated GitHub workflows.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -1,110 +1,164 @@
1
1
  # Mission
2
2
 
3
- A JavaScript Commodore 64 emulator capable of running the classic game "The Lords of Midnight" (1984, Mike Singleton).
3
+ A JavaScript Commodore 64 emulator that runs in the browser, capable of playing the classic game "The Lords of Midnight" (1984, Mike Singleton).
4
+
5
+ ## Browser Presentation
6
+
7
+ The emulator runs entirely in the browser as a single-page application:
8
+
9
+ - **Canvas rendering** — VIC-II output drawn to an HTML `<canvas>` element at native 320x200, scaled with CSS `image-rendering: pixelated`.
10
+ - **Web Audio API** — SID output fed to an `AudioWorklet` (or `ScriptProcessorNode` fallback) for real-time sound.
11
+ - **Keyboard input** — browser `keydown`/`keyup` events mapped to the C64 keyboard matrix.
12
+ - **ROM loading** — user provides KERNAL, BASIC, and character ROM files via file input or drag-and-drop. ROMs are NOT bundled (they are copyrighted).
13
+ - **PRG loading** — user loads `.prg` game files via file input or drag-and-drop.
14
+ - **Responsive layout** — centred emulator screen with C64-style colour scheme, status bar showing cycle count and FPS.
15
+
16
+ Website files under `public/`:
17
+
18
+ | File | Purpose |
19
+ |------|---------|
20
+ | `public/index.html` | Main page — canvas, file inputs, controls |
21
+ | `public/style.css` | C64-themed styling (dark blue background, light blue text) |
22
+ | `public/emulator.js` | Browser entry point — imports core lib, wires up canvas/audio/input |
4
23
 
5
24
  ## Architecture
6
25
 
7
- The emulator is structured as layered components, each independently testable:
26
+ The core emulator is structured as independently testable modules under `src/lib/`:
27
+
28
+ | File | Module | Purpose |
29
+ |------|--------|---------|
30
+ | `src/lib/main.js` | Entry point | Re-exports all public API functions from submodules |
31
+ | `src/lib/cpu.js` | MOS 6510 CPU | 6502 variant with I/O port at $00/$01 |
32
+ | `src/lib/opcodes.js` | Opcode table | Data-driven array of 256 entries (mnemonic, addressing mode, cycles, handler) |
33
+ | `src/lib/memory.js` | Memory subsystem | 64KB RAM, ROM banking, I/O area routing |
34
+ | `src/lib/vic.js` | VIC-II video | Text/bitmap modes, sprites, raster interrupts, framebuffer |
35
+ | `src/lib/sid.js` | SID sound | 3-voice synthesiser, ADSR envelopes, PCM output |
36
+ | `src/lib/cia.js` | CIA timers | Timer interrupts, keyboard matrix scanning, joystick |
37
+ | `src/lib/input.js` | Input mapping | Browser key event codes to C64 8x8 keyboard matrix |
38
+ | `src/lib/loader.js` | PRG loader | Parse `.prg` header and load data into memory |
39
+ | `src/lib/c64.js` | Machine | Wires all subsystems together, provides `createC64()` and `runFrame()` |
40
+
41
+ This multi-file structure allows the agent to iterate on each subsystem independently without hitting context limits. Each module has a corresponding test file under `tests/`.
8
42
 
9
- 1. **MOS 6510 CPU** — the core processor (6502 variant with I/O port at $00/$01)
10
- 2. **Memory subsystem** — 64KB RAM, ROM banking (BASIC, KERNAL, character ROM), I/O area ($D000–$DFFF)
11
- 3. **VIC-II video** — text mode (40x25), bitmap mode, sprites, raster interrupt timing
12
- 4. **SID sound** — 3-voice synthesiser with ADSR envelopes (basic waveform generation)
13
- 5. **CIA timers** — two CIA chips for keyboard scanning, timer interrupts, and joystick input
14
- 6. **Input** — keyboard matrix and joystick mapped to browser events
15
- 7. **PRG/TAP loader** — load `.prg` files (and optionally `.tap` tape images) into memory
43
+ ## Research Phase
16
44
 
17
- ## Core Functions
45
+ During web-search and document-gathering workflow phases, the agent should look up:
18
46
 
19
- Export all from `src/lib/main.js`:
47
+ - **6502/6510 opcode reference** — complete instruction set with addressing modes, cycle counts, and flag effects. Key resource: "6502 Instruction Set" tables listing all 151 official opcode variants.
48
+ - **VIC-II register map** — all registers at $D000–$D03F, their bit layouts, and behaviour (C64 Programmer's Reference Guide).
49
+ - **SID register map** — registers at $D400–$D41C, waveform generation, ADSR timing.
50
+ - **CIA register map** — CIA1 ($DC00–$DC0F) and CIA2 ($DD00–$DD0F), keyboard matrix wiring, timer modes.
51
+ - **C64 keyboard matrix** — the 8x8 matrix mapping (which row/column pair for each physical key).
52
+ - **C64 colour palette** — the 16 VIC-II colours as RGB values.
53
+ - **Lords of Midnight technical details** — memory layout, which C64 features the game uses, loading address.
54
+ - **Existing open-source C64 emulators in JavaScript** — study approaches (e.g. virtual6502, SAE, c64js) for implementation patterns and known pitfalls.
20
55
 
21
- - `createC64(opts?)` — create an emulator instance with default ROMs and 64KB RAM. Returns an object with `cpu`, `memory`, `vic`, `sid`, `cia1`, `cia2` subsystems.
22
- - `loadPRG(c64, data)` — load a `.prg` file (Uint8Array) into memory at the address specified in its two-byte header.
23
- - `step(c64)` — execute one CPU instruction, advance cycle count, and update timers. Returns the new state.
24
- - `runFrame(c64)` — execute instructions for one video frame (~19656 cycles PAL). Trigger raster interrupts at the appropriate scanlines. Returns the framebuffer.
25
- - `getFramebuffer(c64)` — return the current screen as a Uint8Array RGBA pixel buffer (320x200 or 384x272 with borders).
56
+ The opcode table in particular should be assembled from reference data during the research phase and stored as `src/lib/opcodes.js` — a data-driven 256-entry array rather than hand-coded instruction by instruction. This avoids the agent losing track of which opcodes are implemented and reduces the chance of transcription errors.
57
+
58
+ ## Core API
59
+
60
+ Export from `src/lib/main.js` (re-exporting from submodules):
61
+
62
+ - `createC64(opts?)` — create an emulator instance with 64KB RAM and subsystem objects (`cpu`, `memory`, `vic`, `sid`, `cia1`, `cia2`).
63
+ - `loadROMs(c64, { kernal, basic, chargen })` — load ROM images (Uint8Arrays). Must be called before running.
64
+ - `loadPRG(c64, data)` — load a `.prg` file (Uint8Array) into memory at the address from its two-byte header.
65
+ - `step(c64)` — execute one CPU instruction, advance cycle count, update timers. Returns the updated state.
66
+ - `runFrame(c64)` — execute one PAL video frame (~19656 cycles). Fire raster interrupts. Returns the RGBA framebuffer.
67
+ - `getFramebuffer(c64)` — return the current screen as a Uint8Array RGBA pixel buffer (320x200).
26
68
  - `pressKey(c64, key)` / `releaseKey(c64, key)` — simulate keyboard input via CIA1 keyboard matrix.
27
69
  - `joystickInput(c64, port, directions)` — set joystick state (up/down/left/right/fire) on port 1 or 2.
28
- - `reset(c64)` — perform a hardware reset (set CPU to reset vector, clear state).
70
+ - `reset(c64)` — hardware reset (CPU to reset vector, clear subsystem state).
29
71
 
30
- ## CPU Requirements
72
+ ## CPU (src/lib/cpu.js, src/lib/opcodes.js)
31
73
 
32
74
  - All official 6502 opcodes (56 instructions, 151 opcode variants) with correct cycle counts.
33
- - Decimal mode (BCD arithmetic) support.
75
+ - Decimal mode (BCD arithmetic).
34
76
  - IRQ and NMI interrupt handling with correct stack behaviour.
35
- - The 6510 I/O port at $00/$01 for ROM/RAM bank switching.
36
- - Undocumented/illegal opcodes are NOT required (may be implemented as NOP).
77
+ - 6510 I/O port at $00/$01 for ROM/RAM bank switching.
78
+ - Undocumented/illegal opcodes: implement as NOP (not required for Lords of Midnight).
79
+ - The opcode table (`opcodes.js`) is a data-driven array of 256 entries to keep the code manageable and verifiable against reference data gathered during the research phase.
37
80
 
38
- ## Memory Map
81
+ ## Memory (src/lib/memory.js)
39
82
 
40
83
  - $0000–$00FF: Zero page
41
84
  - $0100–$01FF: Stack
42
85
  - $0200–$9FFF: Free RAM (programs load here)
43
86
  - $A000–$BFFF: BASIC ROM (banked, RAM underneath)
44
87
  - $C000–$CFFF: Free RAM
45
- - $D000–$D3FF: VIC-II registers
46
- - $D400–$D7FF: SID registers
88
+ - $D000–$D3FF: VIC-II registers (routed to VIC-II module)
89
+ - $D400–$D7FF: SID registers (routed to SID module)
47
90
  - $D800–$DBFF: Colour RAM (nibbles)
48
- - $DC00–$DCFF: CIA1 (keyboard, joystick, timer)
49
- - $DD00–$DDFF: CIA2 (serial, timer, VIC bank)
91
+ - $DC00–$DCFF: CIA1 registers (routed to CIA module)
92
+ - $DD00–$DDFF: CIA2 registers (routed to CIA module)
50
93
  - $E000–$FFFF: KERNAL ROM (banked, RAM underneath)
51
94
 
52
- ## Video (VIC-II)
95
+ ## Video VIC-II (src/lib/vic.js)
53
96
 
54
- - Standard text mode (mode 0) — 40x25 characters, 16 colours, character ROM.
97
+ - Standard text mode (40x25 characters, 16 colours, character ROM).
55
98
  - Multicolour text mode.
56
99
  - Standard bitmap mode (320x200) and multicolour bitmap mode (160x200).
57
100
  - Hardware sprites (8 sprites, 24x21 pixels, multicolour optional).
58
101
  - Raster interrupt — trigger IRQ at a programmable scanline.
59
- - Border colour and background colour registers.
60
- - Correct raster timing is essential — Lords of Midnight uses raster effects.
102
+ - Border and background colour registers.
103
+ - Correct raster timing — Lords of Midnight uses raster effects.
61
104
 
62
- ## Sound (SID — basic)
105
+ ## Sound SID (src/lib/sid.js)
63
106
 
64
- - 3 oscillator voices with waveform selection (triangle, sawtooth, pulse, noise).
107
+ - 3 oscillator voices: triangle, sawtooth, pulse, noise waveforms.
65
108
  - ADSR envelope per voice.
66
109
  - Frequency and pulse-width registers.
67
- - Audio output as PCM sample buffer suitable for Web Audio API playback.
110
+ - Audio output as PCM sample buffer (44100 Hz, mono) for Web Audio API.
68
111
  - Full filter emulation is NOT required (passthrough acceptable).
69
112
 
70
- ## Input
113
+ ## Input (src/lib/input.js, src/lib/cia.js)
71
114
 
72
- - CIA1 keyboard matrix scan — map browser `KeyboardEvent` codes to the C64 8x8 keyboard matrix.
73
- - Joystick via CIA1 ($DC01 port 1) and CIA1 ($DC00 port 2) — Lords of Midnight uses keyboard, but joystick support enables other games.
115
+ - CIA1 keyboard matrix — map browser `KeyboardEvent.code` values to the C64 8x8 keyboard matrix.
116
+ - Joystick via CIA1 port registers — Lords of Midnight uses keyboard, but joystick support enables other games.
74
117
 
75
118
  ## Lords of Midnight Compatibility
76
119
 
77
- The target game exercises these specific features:
120
+ The target game exercises:
78
121
  - Custom character sets (redefined at $3000 or similar)
79
122
  - Full keyboard input (directional + action keys)
80
123
  - Raster interrupts for split-screen effects
81
124
  - IRQ-driven game loop timing via CIA timer
82
125
  - PRG loading at the correct start address
83
126
 
127
+ ## Test Strategy
128
+
129
+ Testing a full emulator requires care to avoid the verification gap (passing unit tests but failing on real software):
130
+
131
+ - **CPU tests**: verify each addressing mode and instruction against known-good results. Use the research-phase opcode reference to generate expected values. Test interrupt handling (IRQ vector jump, flag push, RTI return).
132
+ - **Memory tests**: test bank switching ($01 register), I/O area routing, ROM overlay behaviour.
133
+ - **VIC-II tests**: set known register states, render one frame, verify specific pixels in the framebuffer.
134
+ - **Input tests**: simulate key press sequences, verify CIA1 port reads return correct matrix values.
135
+ - **Stub ROMs**: tests use minimal ROMs — just enough to set the reset vector ($FFFC/$FFFD) and RTI from the IRQ vector. The agent should create these as hex-encoded Uint8Arrays in the test fixtures.
136
+ - **Integration test**: a small test PRG (hex-encoded in the test file) that writes "HELLO" to screen RAM ($0400) and halts. Run it, verify the framebuffer contains the correct character glyphs.
137
+ - **Smoke test for the browser UI**: verify `public/index.html` loads without errors and the canvas element is present (can use a headless browser or DOM parser).
138
+
84
139
  ## Requirements
85
140
 
86
- - No external dependencies for the core emulator (Web Audio API and Canvas API are browser-provided).
87
- - KERNAL and BASIC ROMs must NOT be bundled (they are copyrighted). Provide a `loadROMs(c64, { kernal, basic, chargen })` function. Tests should use minimal stub ROMs.
88
- - Comprehensive unit tests for each subsystem:
89
- - CPU: test each addressing mode and instruction, verify cycle counts, test interrupt handling.
90
- - Memory: test bank switching, I/O area mapping.
91
- - VIC-II: test mode switching, framebuffer output for known register states.
92
- - Input: test keyboard matrix encoding/decoding.
93
- - Integration test: load a small test PRG that writes to screen memory and verify framebuffer output.
94
- - README with architecture overview, usage example, and instructions for obtaining legal ROM dumps.
141
+ - No external runtime dependencies pure JavaScript using only browser-provided APIs (Canvas, Web Audio, File API).
142
+ - ROMs must NOT be bundled. The `loadROMs()` function and browser drag-and-drop accept user-supplied ROM files.
143
+ - Multi-file structure as specified in the Architecture section.
144
+ - The `public/` website is self-contained and can be served with any static file server.
145
+ - README with architecture overview, browser usage instructions, and guidance on obtaining legal ROM dumps.
95
146
 
96
147
  ## Acceptance Criteria
97
148
 
98
149
  - [ ] CPU executes all 151 official opcodes with correct results and cycle counts
99
150
  - [ ] CPU handles IRQ and NMI interrupts correctly (push PC+flags, jump to vector)
100
151
  - [ ] Memory bank switching works ($01 register controls ROM/RAM visibility)
101
- - [ ] VIC-II text mode renders 40x25 character display to framebuffer
152
+ - [ ] VIC-II text mode renders 40x25 character display to RGBA framebuffer
102
153
  - [ ] VIC-II raster interrupt fires at the programmed scanline
103
154
  - [ ] SID produces audible waveform output for at least triangle and pulse waves
104
155
  - [ ] CIA1 keyboard matrix correctly maps key presses to the scanned row/column
105
156
  - [ ] `loadPRG()` places data at the correct address from the PRG header
106
- - [ ] `runFrame()` executes approximately the right number of cycles per frame (PAL timing)
157
+ - [ ] `runFrame()` executes the correct number of cycles per PAL frame (~19656)
107
158
  - [ ] A test PRG that writes "HELLO" to screen RAM ($0400) produces correct framebuffer output
108
159
  - [ ] `reset()` returns the emulator to a known initial state
160
+ - [ ] Browser UI renders emulator output to canvas at 50 FPS (PAL rate)
161
+ - [ ] Browser UI plays SID audio via Web Audio API
162
+ - [ ] Browser UI accepts ROM and PRG files via drag-and-drop or file input
109
163
  - [ ] All unit tests pass
110
- - [ ] README documents architecture and ROM loading
164
+ - [ ] README documents architecture, browser usage, and how to obtain legal ROM dumps
@@ -16,7 +16,7 @@
16
16
  "author": "",
17
17
  "license": "MIT",
18
18
  "dependencies": {
19
- "@xn-intenton-z2a/agentic-lib": "^7.1.65"
19
+ "@xn-intenton-z2a/agentic-lib": "^7.1.66"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@vitest/coverage-v8": "^4.0.18",