engine-parity-check
Auto-activates when modifying CPU instructions or engine code. Ensures JS and WASM engines produce identical behavior.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Auto-activates when modifying CPU instructions or engine code. Ensures JS and WASM engines produce identical behavior.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
| name | engine-parity-check |
| description | Auto-activates when modifying CPU instructions or engine code. Ensures JS and WASM engines produce identical behavior. |
This skill activates when working on CPU instruction implementations to ensure both JS and WASM engines behave identically.
Both engines MUST produce identical:
When modifying code, list all affected opcodes:
Instruction: ADC (Add with Carry)
Opcodes: $69 (imm), $65 (zp), $75 (zpx), $6D (abs), $7D (abx), $79 (aby), $61 (izx), $71 (izy)
JavaScript (src/core/cpu6502/instructions.ts):
private ADC(value: number): void {
// Check implementation
}
Rust (wasm-cpu/src/instructions_bus_impl.rs — the bus-aware path that runs in-app;
instructions.rs is the non-bus reference):
fn adc(&mut self, value: u8) {
// Check implementation
}
For each instruction, test:
describe('ADC instruction parity', () => {
it('should match JS and WASM for immediate mode', async () => {
// Setup identical state
jsEngine.setRegister('A', 0x50);
wasmEngine.setRegister('A', 0x50);
// Execute same instruction
jsEngine.execute(0x69, 0x50); // ADC #$50
wasmEngine.execute(0x69, 0x50);
// Compare all state
expect(jsEngine.getState()).toEqual(wasmEngine.getState());
});
});
Always verify these scenarios:
| Test Case | Description |
|---|---|
| Zero result | Result is exactly 0x00 |
| Negative result | Result has bit 7 set |
| Carry out | Result > 0xFF |
| Overflow | Signed overflow occurred |
| Page crossing | Address crosses page boundary |
| Wrap-around | Address wraps from $FFFF to $0000 |
// WRONG: Different evaluation order
let n_flag = (result & 0x80) != 0;
let z_flag = result == 0;
// RIGHT: Match JS exactly
let z_flag = (result & 0xFF) == 0;
let n_flag = (result & 0x80) != 0;
// JS counts page boundary crossing
cycles += if page_crossed { 1 } else { 0 };
// WASM must match
self.cycles += if self.page_crossed() { 1 } else { 0 };
// Write order matters for memory-mapped I/O
// Both engines must write in same order
self.write(addr, low_byte);
self.write(addr + 1, high_byte);
Run this to verify parity for common operations (vitest uses -t to filter by test name):
yarn test -t parity
The dedicated suite is src/core/cpu-engines/__tests__/engine-parity.vitest.test.ts. Note it
skips when the WASM module can't be fetched under the vitest runner; the headless benchmark's
file:// fetch shim is the working pattern to make it load. Or use the /engine-test command.
| Component | JS Location | Rust Location (in-app = bus-aware) |
|---|---|---|
| CPU Core | src/core/cpu6502/core.ts | wasm-cpu/src/cpu.rs, system.rs |
| Instructions | src/core/cpu6502/instructions.ts | instructions_with_bus.rs + instructions_bus_impl.rs (ref: instructions.rs) |
| Opcodes | src/core/cpu6502/opcodes.ts | opcodes_with_bus.rs (ref: opcodes.rs) |
| Tests | src/core/__tests__/CPU6502-*.vitest.test.ts | wasm-cpu/tests/ |