mirror of
https://github.com/whscullin/apple1js.git
synced 2024-12-13 05:29:06 +00:00
Use submodule for cpu6502
This commit is contained in:
parent
6e49066162
commit
b5dd61b88e
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "submodules/cpu6502"]
|
||||
path = submodules/cpu6502
|
||||
url = https://github.com/whscullin/cpu6502
|
@ -9,6 +9,8 @@ Things are still a little rough around the edges right now, hopefully I will hav
|
||||
First
|
||||
|
||||
```sh
|
||||
git submodule init
|
||||
git submodule update
|
||||
npm install
|
||||
```
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
import MicroModal from 'micromodal';
|
||||
|
||||
import Apple1IO from './apple1io';
|
||||
import CPU6502 from './cpu6502';
|
||||
import { CPU6502, word, byte } from '@whscullin/cpu6502';
|
||||
import Prefs from './prefs';
|
||||
import RAM from './ram';
|
||||
import { TextPage } from './canvas1';
|
||||
@ -25,7 +25,6 @@ import Krusader from './roms/krusader';
|
||||
import ACI from './cards/aci';
|
||||
|
||||
import { mapKeyEvent, KeyBoard } from './ui/keyboard';
|
||||
import { address, byte } from './types';
|
||||
|
||||
// eslint-disable-next-line prefer-const
|
||||
let DEBUG = false;
|
||||
@ -197,7 +196,7 @@ export function setTurboTape(val: boolean) {
|
||||
turbotape = val;
|
||||
}
|
||||
|
||||
function run(pc?: address) {
|
||||
function run(pc?: word) {
|
||||
if (runTimer) {
|
||||
clearInterval(runTimer);
|
||||
}
|
||||
@ -364,7 +363,7 @@ export function doLoadText() {
|
||||
lines.forEach(function (line) {
|
||||
const parts = line.split(': ');
|
||||
if (parts.length === 2) {
|
||||
let addr: address = 0;
|
||||
let addr: word = 0;
|
||||
if (parts[0].length > 0) {
|
||||
addr = parseInt(parts[0], 16);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
import { TextPage } from './canvas1';
|
||||
import type { byte } from './types';
|
||||
import type { byte } from '@whscullin/cpu6502';
|
||||
|
||||
const LOC = {
|
||||
KBD: 0x10,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { memory } from './types';
|
||||
import { memory } from '@whscullin/cpu6502';
|
||||
|
||||
const B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
import { charset } from './roms/apple1char';
|
||||
import type { byte } from './types';
|
||||
import type { byte } from '@whscullin/cpu6502';
|
||||
|
||||
/*
|
||||
0: A9 9 AA 20 EF FF E8 8A 4C 2 0
|
||||
|
@ -1,28 +1,40 @@
|
||||
import CPU6502 from '../cpu6502';
|
||||
import { CPU6502, byte } from '@whscullin/cpu6502';
|
||||
import { debug } from '../util';
|
||||
import { byte } from '../types';
|
||||
|
||||
// prettier-ignore
|
||||
const rom = [
|
||||
0xa9, 0xaa, 0x20, 0xef, 0xff, 0xa9, 0x8d, 0x20, 0xef, 0xff, 0xa0, 0xff, 0xc8,
|
||||
0xad, 0x11, 0xd0, 0x10, 0xfb, 0xad, 0x10, 0xd0, 0x99, 0x00, 0x02, 0x20, 0xef,
|
||||
0xff, 0xc9, 0x9b, 0xf0, 0xe1, 0xc9, 0x8d, 0xd0, 0xe9, 0xa2, 0xff, 0xa9, 0x00,
|
||||
0x85, 0x24, 0x85, 0x25, 0x85, 0x26, 0x85, 0x27, 0xe8, 0xbd, 0x00, 0x02, 0xc9,
|
||||
0xd2, 0xf0, 0x56, 0xc9, 0xd7, 0xf0, 0x35, 0xc9, 0xae, 0xf0, 0x27, 0xc9, 0x8d,
|
||||
0xf0, 0x20, 0xc9, 0xa0, 0xf0, 0xe8, 0x49, 0xb0, 0xc9, 0x0a, 0x90, 0x06, 0x69,
|
||||
0x88, 0xc9, 0xfa, 0x90, 0xad, 0x0a, 0x0a, 0x0a, 0x0a, 0xa0, 0x04, 0x0a, 0x26,
|
||||
0x24, 0x26, 0x25, 0x88, 0xd0, 0xf8, 0xf0, 0xcc, 0x4c, 0x1a, 0xff, 0xa5, 0x24,
|
||||
0x85, 0x26, 0xa5, 0x25, 0x85, 0x27, 0xb0, 0xbf, 0xa9, 0x40, 0x20, 0xcc, 0xc1,
|
||||
0x88, 0xa2, 0x00, 0xa1, 0x26, 0xa2, 0x10, 0x0a, 0x20, 0xdb, 0xc1, 0xd0, 0xfa,
|
||||
0x20, 0xf1, 0xc1, 0xa0, 0x1e, 0x90, 0xec, 0xa6, 0x28, 0xb0, 0x98, 0x20, 0xbc,
|
||||
0xc1, 0xa9, 0x16, 0x20, 0xcc, 0xc1, 0x20, 0xbc, 0xc1, 0xa0, 0x1f, 0x20, 0xbf,
|
||||
0xc1, 0xb0, 0xf9, 0x20, 0xbf, 0xc1, 0xa0, 0x3a, 0xa2, 0x08, 0x48, 0x20, 0xbc,
|
||||
0xc1, 0x68, 0x2a, 0xa0, 0x39, 0xca, 0xd0, 0xf5, 0x81, 0x26, 0x20, 0xf1, 0xc1,
|
||||
0xa0, 0x35, 0x90, 0xea, 0xb0, 0xcd, 0x20, 0xbf, 0xc1, 0x88, 0xad, 0x81, 0xc0,
|
||||
0xc5, 0x29, 0xf0, 0xf8, 0x85, 0x29, 0xc0, 0x80, 0x60, 0x86, 0x28, 0xa0, 0x42,
|
||||
0x20, 0xe0, 0xc1, 0xd0, 0xf9, 0x69, 0xfe, 0xb0, 0xf5, 0xa0, 0x1e, 0x20, 0xe0,
|
||||
0xc1, 0xa0, 0x2c, 0x88, 0xd0, 0xfd, 0x90, 0x05, 0xa0, 0x2f, 0x88, 0xd0, 0xfd,
|
||||
0xbc, 0x00, 0xc0, 0xa0, 0x29, 0xca, 0x60, 0xa5, 0x26, 0xc5, 0x24, 0xa5, 0x27,
|
||||
0xe5, 0x25, 0xe6, 0x26, 0xd0, 0x02, 0xe6, 0x27, 0x60,
|
||||
0xA9,0xAA,0x20,0xEF,0xFF,0xA9,0x8D,0x20,
|
||||
0xEF,0xFF,0xA0,0xFF,0xC8,0xAD,0x11,0xD0,
|
||||
0x10,0xFB,0xAD,0x10,0xD0,0x99,0x00,0x02,
|
||||
0x20,0xEF,0xFF,0xC9,0x9B,0xF0,0xE1,0xC9,
|
||||
0x8D,0xD0,0xE9,0xA2,0xFF,0xA9,0x00,0x85,
|
||||
0x24,0x85,0x25,0x85,0x26,0x85,0x27,0xE8,
|
||||
0xBD,0x00,0x02,0xC9,0xD2,0xF0,0x56,0xC9,
|
||||
0xD7,0xF0,0x35,0xC9,0xAE,0xF0,0x27,0xC9,
|
||||
0x8D,0xF0,0x20,0xC9,0xA0,0xF0,0xE8,0x49,
|
||||
0xB0,0xC9,0x0A,0x90,0x06,0x69,0x88,0xC9,
|
||||
0xFA,0x90,0xAD,0x0A,0x0A,0x0A,0x0A,0xA0,
|
||||
0x04,0x0A,0x26,0x24,0x26,0x25,0x88,0xD0,
|
||||
0xF8,0xF0,0xCC,0x4C,0x1A,0xFF,0xA5,0x24,
|
||||
0x85,0x26,0xA5,0x25,0x85,0x27,0xB0,0xBF,
|
||||
0xA9,0x40,0x20,0xCC,0xC1,0x88,0xA2,0x00,
|
||||
0xA1,0x26,0xA2,0x10,0x0A,0x20,0xDB,0xC1,
|
||||
0xD0,0xFA,0x20,0xF1,0xC1,0xA0,0x1E,0x90,
|
||||
0xEC,0xA6,0x28,0xB0,0x98,0x20,0xBC,0xC1,
|
||||
0xA9,0x16,0x20,0xCC,0xC1,0x20,0xBC,0xC1,
|
||||
0xA0,0x1F,0x20,0xBF,0xC1,0xB0,0xF9,0x20,
|
||||
0xBF,0xC1,0xA0,0x3A,0xA2,0x08,0x48,0x20,
|
||||
0xBC,0xC1,0x68,0x2A,0xA0,0x39,0xCA,0xD0,
|
||||
0xF5,0x81,0x26,0x20,0xF1,0xC1,0xA0,0x35,
|
||||
0x90,0xEA,0xB0,0xCD,0x20,0xBF,0xC1,0x88,
|
||||
0xAD,0x81,0xC0,0xC5,0x29,0xF0,0xF8,0x85,
|
||||
0x29,0xC0,0x80,0x60,0x86,0x28,0xA0,0x42,
|
||||
0x20,0xE0,0xC1,0xD0,0xF9,0x69,0xFE,0xB0,
|
||||
0xF5,0xA0,0x1E,0x20,0xE0,0xC1,0xA0,0x2C,
|
||||
0x88,0xD0,0xFD,0x90,0x05,0xA0,0x2F,0x88,
|
||||
0xD0,0xFD,0xBC,0x00,0xC0,0xA0,0x29,0xCA,
|
||||
0x60,0xA5,0x26,0xC5,0x24,0xA5,0x27,0xE5,
|
||||
0x25,0xE6,0x26,0xD0,0x02,0xE6,0x27,0x60
|
||||
] as const;
|
||||
|
||||
export interface ACICallback {
|
||||
|
3265
js/cpu6502.ts
3265
js/cpu6502.ts
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,7 @@
|
||||
|
||||
import { base64_decode, base64_encode } from './base64';
|
||||
import { allocMemPages } from './util';
|
||||
import type { byte } from './types';
|
||||
import type { byte, memory } from '@whscullin/cpu6502';
|
||||
|
||||
export interface RAMState {
|
||||
start: byte;
|
||||
@ -20,7 +20,7 @@ export interface RAMState {
|
||||
}
|
||||
|
||||
export default class RAM {
|
||||
mem: Uint8Array | byte[];
|
||||
mem: memory;
|
||||
|
||||
constructor(
|
||||
private start_page: byte,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { byte } from 'js/types';
|
||||
import { byte } from '@whscullin/cpu6502';
|
||||
|
||||
export default class Basic {
|
||||
ram = [
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { byte } from 'js/types';
|
||||
import { byte } from '@whscullin/cpu6502';
|
||||
|
||||
export default class Bios {
|
||||
rom = [
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { byte } from 'js/types';
|
||||
import { byte } from '@whscullin/cpu6502';
|
||||
|
||||
export default class EnhancedBasic {
|
||||
rom = [
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { byte } from 'js/types';
|
||||
import { byte } from '@whscullin/cpu6502';
|
||||
|
||||
export default class Krusader {
|
||||
rom = [
|
||||
|
@ -9,9 +9,9 @@
|
||||
* implied warranty.
|
||||
*/
|
||||
|
||||
import type { address } from './types';
|
||||
import type { word } from '@whscullin/cpu6502';
|
||||
|
||||
export const SYMBOLS: Record<address, string> = {
|
||||
export const SYMBOLS: Record<word, string> = {
|
||||
0xd010: 'KBD',
|
||||
0xd011: 'KBDCR',
|
||||
0xd012: 'DSP',
|
||||
|
43
js/types.ts
43
js/types.ts
@ -1,43 +0,0 @@
|
||||
/* Copyright 2023 Will Scullin <scullin@scullinsteel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation. No representations are made about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without express or
|
||||
* implied warranty.
|
||||
*/
|
||||
|
||||
export type byte = number;
|
||||
|
||||
export type word = number;
|
||||
|
||||
export type address = word;
|
||||
|
||||
export type memory = Uint8Array | byte[];
|
||||
|
||||
export interface Memory {
|
||||
/** Read a byte. */
|
||||
read(page: byte, offset: byte): byte;
|
||||
/** Write a byte. */
|
||||
write(page: byte, offset: byte, value: byte): void;
|
||||
}
|
||||
|
||||
/** A mapped region of memory. */
|
||||
export interface MemoryPages extends Memory {
|
||||
/** Start page. */
|
||||
start(): byte;
|
||||
/** End page, inclusive. */
|
||||
end(): byte;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the members of a constant array as a type. Used as:
|
||||
*
|
||||
* @example
|
||||
* const SOME_VALUES = ['a', 'b', 1, 2] as const;
|
||||
* type SomeValues = MemberOf<typeof SOME_VALUES>; // 'a' | 'b' | 1 | 2
|
||||
*/
|
||||
export type MemberOf<T extends ReadonlyArray<unknown>> =
|
||||
T extends ReadonlyArray<infer E> ? E : never;
|
@ -9,11 +9,10 @@
|
||||
* implied warranty.
|
||||
*/
|
||||
|
||||
import CPU6502 from 'js/cpu6502';
|
||||
import { CPU6502, byte } from '@whscullin/cpu6502';
|
||||
import { debug, toHex } from '../util';
|
||||
import Apple1IO from 'js/apple1io';
|
||||
import { TextPage } from 'js/canvas1';
|
||||
import { byte } from 'js/types';
|
||||
|
||||
// keycode: [plain, cntl, shift]
|
||||
|
||||
|
@ -9,12 +9,12 @@
|
||||
* implied warranty.
|
||||
*/
|
||||
|
||||
import { byte, word } from './types';
|
||||
import { byte, word } from '@whscullin/cpu6502';
|
||||
|
||||
const hex_digits = '0123456789ABCDEF';
|
||||
const bin_digits = '01';
|
||||
|
||||
export function allocMem(size: word) {
|
||||
export function allocMem(size: word): Uint8Array | byte[] {
|
||||
let result;
|
||||
if (window.Uint8Array) {
|
||||
result = new Uint8Array(size);
|
||||
|
1253
package-lock.json
generated
1253
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -47,6 +47,7 @@
|
||||
"webpack-dev-server": "^4.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@whscullin/cpu6502": "file:submodules/cpu6502",
|
||||
"micromodal": "^0.4.9"
|
||||
}
|
||||
}
|
||||
|
1
submodules/cpu6502
Submodule
1
submodules/cpu6502
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 208e761911a0088a5bafbdbc2c82de8110a92992
|
@ -1,48 +0,0 @@
|
||||
import CPU6502, { FLAVOR_ROCKWELL_65C02 } from '../js/cpu6502';
|
||||
// From https://github.com/Klaus2m5/6502_65C02_functional_tests
|
||||
import Test6502 from './roms/6502test';
|
||||
import Test65C02 from './roms/65C02test';
|
||||
|
||||
import { toHex } from '../js/util';
|
||||
|
||||
describe('CPU', function () {
|
||||
let cpu: CPU6502;
|
||||
let lastPC = 0;
|
||||
let done = false;
|
||||
|
||||
function traceCB() {
|
||||
const pc = cpu.getPC();
|
||||
done = lastPC === pc;
|
||||
lastPC = pc;
|
||||
}
|
||||
|
||||
describe('6502', function () {
|
||||
it('completes the test ROM', function () {
|
||||
cpu = new CPU6502();
|
||||
const test = new Test6502();
|
||||
cpu.addPageHandler(test);
|
||||
cpu.setPC(0x400);
|
||||
|
||||
do {
|
||||
cpu.stepCyclesDebug(1000, traceCB);
|
||||
} while (!done);
|
||||
|
||||
expect(toHex(lastPC)).toEqual(toHex(0x3469));
|
||||
});
|
||||
});
|
||||
|
||||
describe('65C02', function () {
|
||||
it('completes the test ROM', function () {
|
||||
cpu = new CPU6502({ flavor: FLAVOR_ROCKWELL_65C02 });
|
||||
const test = new Test65C02();
|
||||
cpu.addPageHandler(test);
|
||||
cpu.setPC(0x400);
|
||||
|
||||
do {
|
||||
cpu.stepCyclesDebug(1000, traceCB);
|
||||
} while (!done);
|
||||
|
||||
expect(toHex(lastPC)).toEqual(toHex(0x24f1));
|
||||
});
|
||||
});
|
||||
});
|
3254
test/cpu6502.spec.ts
3254
test/cpu6502.spec.ts
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,29 +0,0 @@
|
||||
// From https://github.com/Klaus2m5/6502_65C02_functional_tests
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { MemoryPages, byte } from '../../js/types';
|
||||
|
||||
export default class Test6502 implements MemoryPages {
|
||||
private data: Buffer;
|
||||
|
||||
constructor() {
|
||||
this.data = fs.readFileSync(path.join(__dirname, '6502_functional_test.bin'));
|
||||
}
|
||||
|
||||
start = () => {
|
||||
return 0x00;
|
||||
};
|
||||
|
||||
end = () => {
|
||||
return 0xff;
|
||||
};
|
||||
|
||||
read = (page: byte, off: byte) => {
|
||||
return this.data[page << 8 | off];
|
||||
};
|
||||
|
||||
write = (page: byte, off: byte, val: byte) => {
|
||||
this.data[page << 8 | off] = val;
|
||||
};
|
||||
}
|
Binary file not shown.
@ -1,29 +0,0 @@
|
||||
// From https://github.com/Klaus2m5/6502_65C02_functional_tests
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { MemoryPages, byte } from '../../js/types';
|
||||
|
||||
export default class Test65C02 implements MemoryPages {
|
||||
private data: Buffer;
|
||||
|
||||
constructor() {
|
||||
this.data = fs.readFileSync(path.join(__dirname, '65C02_extended_opcodes_test.bin'));
|
||||
}
|
||||
|
||||
start = () => {
|
||||
return 0x00;
|
||||
};
|
||||
|
||||
end = () => {
|
||||
return 0xff;
|
||||
};
|
||||
|
||||
read = (page: byte, off: byte) => {
|
||||
return this.data[page << 8 | off];
|
||||
};
|
||||
|
||||
write = (page: byte, off: byte, val: byte) => {
|
||||
this.data[page << 8 | off] = val;
|
||||
};
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import { byte } from "../../js/types";
|
||||
|
||||
export const assertByte = (b: byte) => {
|
||||
expect(b <= 0xff).toEqual(true);
|
||||
expect(b >= 0x00).toEqual(true);
|
||||
};
|
@ -1,56 +0,0 @@
|
||||
import { MemoryPages, byte } from "../../js/types";
|
||||
import { assertByte } from "./asserts";
|
||||
|
||||
export class Program implements MemoryPages {
|
||||
private data: Buffer;
|
||||
|
||||
constructor(private page: byte, code: byte[]) {
|
||||
this.data = Buffer.from(code);
|
||||
}
|
||||
|
||||
start() {
|
||||
return this.page;
|
||||
}
|
||||
|
||||
end() {
|
||||
return this.page;
|
||||
}
|
||||
|
||||
read(page: byte, off: byte) {
|
||||
assertByte(page);
|
||||
assertByte(off);
|
||||
return this.data[off];
|
||||
}
|
||||
|
||||
write(_page: byte, _off: byte, _val: byte) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
export const bios = new Program(
|
||||
0xff,
|
||||
[
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x45, 0x4c, 0x4c,
|
||||
0x4f, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x04, 0x00, 0xff,
|
||||
]
|
||||
);
|
@ -1,34 +0,0 @@
|
||||
import { flags, CpuState } from "js/cpu6502";
|
||||
import { byte } from "js/types";
|
||||
import { toHex } from "js/util";
|
||||
|
||||
export const dumpStatusRegister = (sr: byte) =>
|
||||
[
|
||||
sr & flags.N ? "N" : "-",
|
||||
sr & flags.V ? "V" : "-",
|
||||
sr & flags.X ? "X" : "-",
|
||||
sr & flags.B ? "B" : "-",
|
||||
sr & flags.D ? "D" : "-",
|
||||
sr & flags.I ? "I" : "-",
|
||||
sr & flags.Z ? "Z" : "-",
|
||||
sr & flags.C ? "C" : "-",
|
||||
].join("");
|
||||
|
||||
const detail = !!process.env.JEST_DETAIL;
|
||||
|
||||
export function toReadableState(state: CpuState) {
|
||||
if (detail) {
|
||||
const { pc, sp, a, x, y, s } = state;
|
||||
|
||||
return {
|
||||
pc: toHex(pc, 4),
|
||||
sp: toHex(sp),
|
||||
a: toHex(a),
|
||||
x: toHex(x),
|
||||
y: toHex(y),
|
||||
s: dumpStatusRegister(s),
|
||||
};
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
import { MemoryPages, byte, word } from "js/types";
|
||||
import { assertByte } from "./asserts";
|
||||
|
||||
export type Log = [address: word, value: byte, types: "read" | "write"];
|
||||
export class TestMemory implements MemoryPages {
|
||||
private data: Buffer;
|
||||
private logging: boolean = false;
|
||||
private log: Log[] = [];
|
||||
|
||||
constructor(private size: number) {
|
||||
this.data = Buffer.alloc(size << 8);
|
||||
}
|
||||
|
||||
start() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
end() {
|
||||
return this.size - 1;
|
||||
}
|
||||
|
||||
read(page: byte, off: byte) {
|
||||
assertByte(page);
|
||||
assertByte(off);
|
||||
|
||||
const val = this.data[(page << 8) | off];
|
||||
if (this.logging) {
|
||||
this.log.push([(page << 8) | off, val, "read"]);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
write(page: byte, off: byte, val: byte) {
|
||||
assertByte(page);
|
||||
assertByte(off);
|
||||
assertByte(val);
|
||||
|
||||
if (this.logging) {
|
||||
this.log.push([(page << 8) | off, val, "write"]);
|
||||
}
|
||||
this.data[(page << 8) | off] = val;
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.log = [];
|
||||
}
|
||||
|
||||
logStart() {
|
||||
this.log = [];
|
||||
this.logging = true;
|
||||
}
|
||||
|
||||
logStop() {
|
||||
this.logging = false;
|
||||
}
|
||||
|
||||
getLog() {
|
||||
return this.log;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user