@tmustier/pi-nes 0.2.18 → 0.2.20
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/extensions/nes/native/nes-core/index.d.ts +28 -0
- package/extensions/nes/native/nes-core/index.node +0 -0
- package/extensions/nes/native/nes-core/native.d.ts +25 -0
- package/extensions/nes/native/nes-core/src/lib.rs +57 -0
- package/extensions/nes/native/nes-core/vendor/nes_rust/src/cpu.rs +36 -1
- package/extensions/nes/native/nes-core/vendor/nes_rust/src/lib.rs +14 -1
- package/extensions/nes/native/nes-core/vendor/nes_rust/src/mapper.rs +33 -0
- package/extensions/nes/native/nes-core/vendor/nes_rust/src/rom.rs +5 -1
- package/extensions/nes/nes-component.ts +31 -10
- package/extensions/nes/nes-core.ts +33 -0
- package/extensions/nes/renderer.ts +2 -2
- package/package.json +1 -1
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
export function nativeVersion(): string;
|
|
2
2
|
|
|
3
|
+
export interface CpuDebugState {
|
|
4
|
+
pc: number;
|
|
5
|
+
a: number;
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
sp: number;
|
|
9
|
+
p: number;
|
|
10
|
+
lastPc: number;
|
|
11
|
+
lastOpcode: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface MapperDebugState {
|
|
15
|
+
mapperNum: number;
|
|
16
|
+
control: number;
|
|
17
|
+
prg: number;
|
|
18
|
+
chr0: number;
|
|
19
|
+
chr1: number;
|
|
20
|
+
prgMode: number;
|
|
21
|
+
chrMode: number;
|
|
22
|
+
outerPrg: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface NesDebugState {
|
|
26
|
+
cpu: CpuDebugState;
|
|
27
|
+
mapper: MapperDebugState;
|
|
28
|
+
}
|
|
29
|
+
|
|
3
30
|
export class NativeNes {
|
|
4
31
|
constructor();
|
|
5
32
|
setRom(data: Uint8Array): void;
|
|
@@ -14,6 +41,7 @@ export class NativeNes {
|
|
|
14
41
|
setSram(data: Uint8Array): void;
|
|
15
42
|
isSramDirty(): boolean;
|
|
16
43
|
markSramSaved(): void;
|
|
44
|
+
getDebugState(): NesDebugState;
|
|
17
45
|
getFramebuffer(): Uint8Array;
|
|
18
46
|
}
|
|
19
47
|
|
|
Binary file
|
|
@@ -4,6 +4,30 @@
|
|
|
4
4
|
/* auto-generated by NAPI-RS */
|
|
5
5
|
|
|
6
6
|
export declare function nativeVersion(): string
|
|
7
|
+
export interface CpuDebugState {
|
|
8
|
+
pc: number
|
|
9
|
+
a: number
|
|
10
|
+
x: number
|
|
11
|
+
y: number
|
|
12
|
+
sp: number
|
|
13
|
+
p: number
|
|
14
|
+
lastPc: number
|
|
15
|
+
lastOpcode: number
|
|
16
|
+
}
|
|
17
|
+
export interface MapperDebugState {
|
|
18
|
+
mapperNum: number
|
|
19
|
+
control: number
|
|
20
|
+
prg: number
|
|
21
|
+
chr0: number
|
|
22
|
+
chr1: number
|
|
23
|
+
prgMode: number
|
|
24
|
+
chrMode: number
|
|
25
|
+
outerPrg: number
|
|
26
|
+
}
|
|
27
|
+
export interface NesDebugState {
|
|
28
|
+
cpu: CpuDebugState
|
|
29
|
+
mapper: MapperDebugState
|
|
30
|
+
}
|
|
7
31
|
export declare class NativeNes {
|
|
8
32
|
constructor()
|
|
9
33
|
setRom(data: Uint8Array): void
|
|
@@ -18,5 +42,6 @@ export declare class NativeNes {
|
|
|
18
42
|
setSram(data: Uint8Array): void
|
|
19
43
|
isSramDirty(): boolean
|
|
20
44
|
markSramSaved(): void
|
|
45
|
+
getDebugState(): NesDebugState
|
|
21
46
|
getFramebuffer(): Uint8Array
|
|
22
47
|
}
|
|
@@ -48,6 +48,36 @@ impl Display for NativeDisplay {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
#[napi(object)]
|
|
52
|
+
pub struct CpuDebugState {
|
|
53
|
+
pub pc: u16,
|
|
54
|
+
pub a: u8,
|
|
55
|
+
pub x: u8,
|
|
56
|
+
pub y: u8,
|
|
57
|
+
pub sp: u8,
|
|
58
|
+
pub p: u8,
|
|
59
|
+
pub last_pc: u16,
|
|
60
|
+
pub last_opcode: u8,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
#[napi(object)]
|
|
64
|
+
pub struct MapperDebugState {
|
|
65
|
+
pub mapper_num: u8,
|
|
66
|
+
pub control: u8,
|
|
67
|
+
pub prg: u8,
|
|
68
|
+
pub chr0: u8,
|
|
69
|
+
pub chr1: u8,
|
|
70
|
+
pub prg_mode: u8,
|
|
71
|
+
pub chr_mode: u8,
|
|
72
|
+
pub outer_prg: u8,
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
#[napi(object)]
|
|
76
|
+
pub struct NesDebugState {
|
|
77
|
+
pub cpu: CpuDebugState,
|
|
78
|
+
pub mapper: MapperDebugState,
|
|
79
|
+
}
|
|
80
|
+
|
|
51
81
|
#[napi]
|
|
52
82
|
pub struct NativeNes {
|
|
53
83
|
nes: Nes,
|
|
@@ -133,6 +163,33 @@ impl NativeNes {
|
|
|
133
163
|
self.nes.mark_sram_saved();
|
|
134
164
|
}
|
|
135
165
|
|
|
166
|
+
#[napi]
|
|
167
|
+
pub fn get_debug_state(&self) -> NesDebugState {
|
|
168
|
+
let state = self.nes.debug_state();
|
|
169
|
+
NesDebugState {
|
|
170
|
+
cpu: CpuDebugState {
|
|
171
|
+
pc: state.cpu.pc,
|
|
172
|
+
a: state.cpu.a,
|
|
173
|
+
x: state.cpu.x,
|
|
174
|
+
y: state.cpu.y,
|
|
175
|
+
sp: state.cpu.sp,
|
|
176
|
+
p: state.cpu.p,
|
|
177
|
+
last_pc: state.cpu.last_pc,
|
|
178
|
+
last_opcode: state.cpu.last_opcode,
|
|
179
|
+
},
|
|
180
|
+
mapper: MapperDebugState {
|
|
181
|
+
mapper_num: state.mapper.mapper_num,
|
|
182
|
+
control: state.mapper.control,
|
|
183
|
+
prg: state.mapper.prg,
|
|
184
|
+
chr0: state.mapper.chr0,
|
|
185
|
+
chr1: state.mapper.chr1,
|
|
186
|
+
prg_mode: state.mapper.prg_mode,
|
|
187
|
+
chr_mode: state.mapper.chr_mode,
|
|
188
|
+
outer_prg: state.mapper.outer_prg,
|
|
189
|
+
},
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
136
193
|
#[napi]
|
|
137
194
|
pub fn get_framebuffer(&mut self) -> Uint8Array {
|
|
138
195
|
let ptr = self.framebuffer.as_mut_ptr();
|
|
@@ -14,6 +14,17 @@ const SRAM_START: usize = 0x6000;
|
|
|
14
14
|
const SRAM_END: usize = 0x8000;
|
|
15
15
|
const SRAM_SIZE: usize = SRAM_END - SRAM_START;
|
|
16
16
|
|
|
17
|
+
pub struct CpuDebugState {
|
|
18
|
+
pub pc: u16,
|
|
19
|
+
pub a: u8,
|
|
20
|
+
pub x: u8,
|
|
21
|
+
pub y: u8,
|
|
22
|
+
pub sp: u8,
|
|
23
|
+
pub p: u8,
|
|
24
|
+
pub last_pc: u16,
|
|
25
|
+
pub last_opcode: u8,
|
|
26
|
+
}
|
|
27
|
+
|
|
17
28
|
fn to_joypad_button(button: button::Button) -> joypad::Button {
|
|
18
29
|
match button {
|
|
19
30
|
button::Button::Joypad1A |
|
|
@@ -46,6 +57,8 @@ pub struct Cpu {
|
|
|
46
57
|
x: Register<u8>,
|
|
47
58
|
y: Register<u8>,
|
|
48
59
|
p: CpuStatusRegister,
|
|
60
|
+
last_pc: u16,
|
|
61
|
+
last_opcode: u8,
|
|
49
62
|
|
|
50
63
|
// CPU inside RAM
|
|
51
64
|
ram: Memory,
|
|
@@ -1106,6 +1119,8 @@ impl Cpu {
|
|
|
1106
1119
|
x: Register::<u8>::new(),
|
|
1107
1120
|
y: Register::<u8>::new(),
|
|
1108
1121
|
p: CpuStatusRegister::new(),
|
|
1122
|
+
last_pc: 0,
|
|
1123
|
+
last_opcode: 0,
|
|
1109
1124
|
ram: Memory::new(vec![0; 64 * 1024]), // 64KB
|
|
1110
1125
|
sram_dirty: false,
|
|
1111
1126
|
stall_cycles: 0,
|
|
@@ -1159,6 +1174,23 @@ impl Cpu {
|
|
|
1159
1174
|
self.p.set_i();
|
|
1160
1175
|
}
|
|
1161
1176
|
|
|
1177
|
+
pub fn debug_state(&self) -> CpuDebugState {
|
|
1178
|
+
CpuDebugState {
|
|
1179
|
+
pc: self.pc.load(),
|
|
1180
|
+
a: self.a.load(),
|
|
1181
|
+
x: self.x.load(),
|
|
1182
|
+
y: self.y.load(),
|
|
1183
|
+
sp: self.sp.load(),
|
|
1184
|
+
p: self.p.load(),
|
|
1185
|
+
last_pc: self.last_pc,
|
|
1186
|
+
last_opcode: self.last_opcode,
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
pub fn mapper_debug_state(&self) -> crate::mapper::MapperDebugState {
|
|
1191
|
+
self.rom.mapper_debug_state()
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1162
1194
|
pub fn get_ppu(&self) -> &Ppu {
|
|
1163
1195
|
&self.ppu
|
|
1164
1196
|
}
|
|
@@ -1301,7 +1333,10 @@ impl Cpu {
|
|
|
1301
1333
|
}
|
|
1302
1334
|
|
|
1303
1335
|
fn fetch(&mut self) -> u8 {
|
|
1304
|
-
let
|
|
1336
|
+
let pc = self.pc.load();
|
|
1337
|
+
let opc = self.load(pc);
|
|
1338
|
+
self.last_pc = pc;
|
|
1339
|
+
self.last_opcode = opc;
|
|
1305
1340
|
self.pc.increment();
|
|
1306
1341
|
opc
|
|
1307
1342
|
}
|
|
@@ -14,7 +14,8 @@ pub mod default_input;
|
|
|
14
14
|
pub mod default_audio;
|
|
15
15
|
pub mod default_display;
|
|
16
16
|
|
|
17
|
-
use cpu::Cpu;
|
|
17
|
+
use cpu::{Cpu, CpuDebugState};
|
|
18
|
+
use mapper::MapperDebugState;
|
|
18
19
|
use rom::Rom;
|
|
19
20
|
use button::Button;
|
|
20
21
|
use input::Input;
|
|
@@ -62,6 +63,11 @@ pub struct Nes {
|
|
|
62
63
|
cpu: Cpu
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
pub struct NesDebugState {
|
|
67
|
+
pub cpu: CpuDebugState,
|
|
68
|
+
pub mapper: MapperDebugState,
|
|
69
|
+
}
|
|
70
|
+
|
|
65
71
|
impl Nes {
|
|
66
72
|
/// Creates a new `Nes`.
|
|
67
73
|
/// You need to pass [`input::Input`](./input/trait.Input.html),
|
|
@@ -165,4 +171,11 @@ impl Nes {
|
|
|
165
171
|
pub fn mark_sram_saved(&mut self) {
|
|
166
172
|
self.cpu.mark_sram_saved();
|
|
167
173
|
}
|
|
174
|
+
|
|
175
|
+
pub fn debug_state(&self) -> NesDebugState {
|
|
176
|
+
NesDebugState {
|
|
177
|
+
cpu: self.cpu.debug_state(),
|
|
178
|
+
mapper: self.cpu.mapper_debug_state(),
|
|
179
|
+
}
|
|
180
|
+
}
|
|
168
181
|
}
|
|
@@ -3,6 +3,18 @@ use rom::Mirrorings;
|
|
|
3
3
|
use rom::RomHeader;
|
|
4
4
|
use register::Register;
|
|
5
5
|
|
|
6
|
+
#[derive(Clone, Copy, Default)]
|
|
7
|
+
pub struct MapperDebugState {
|
|
8
|
+
pub mapper_num: u8,
|
|
9
|
+
pub control: u8,
|
|
10
|
+
pub prg: u8,
|
|
11
|
+
pub chr0: u8,
|
|
12
|
+
pub chr1: u8,
|
|
13
|
+
pub prg_mode: u8,
|
|
14
|
+
pub chr_mode: u8,
|
|
15
|
+
pub outer_prg: u8,
|
|
16
|
+
}
|
|
17
|
+
|
|
6
18
|
impl MapperFactory {
|
|
7
19
|
pub fn create(header: &RomHeader) -> Box<dyn Mapper> {
|
|
8
20
|
match header.mapper_num() {
|
|
@@ -32,6 +44,10 @@ pub trait Mapper {
|
|
|
32
44
|
|
|
33
45
|
// @TODO: MMC3Mapper specific. Should this method be here?
|
|
34
46
|
fn drive_irq_counter(&mut self) -> bool;
|
|
47
|
+
|
|
48
|
+
fn debug_state(&self) -> MapperDebugState {
|
|
49
|
+
MapperDebugState::default()
|
|
50
|
+
}
|
|
35
51
|
}
|
|
36
52
|
|
|
37
53
|
pub struct NRomMapper {
|
|
@@ -196,6 +212,23 @@ impl Mapper for MMC1Mapper {
|
|
|
196
212
|
}
|
|
197
213
|
}
|
|
198
214
|
|
|
215
|
+
fn debug_state(&self) -> MapperDebugState {
|
|
216
|
+
MapperDebugState {
|
|
217
|
+
mapper_num: 1,
|
|
218
|
+
control: self.control_register.load(),
|
|
219
|
+
prg: self.prg_bank_register.load(),
|
|
220
|
+
chr0: self.chr_bank0_register.load(),
|
|
221
|
+
chr1: self.chr_bank1_register.load(),
|
|
222
|
+
prg_mode: self.control_register.load_bits(2, 2),
|
|
223
|
+
chr_mode: self.control_register.load_bit(4),
|
|
224
|
+
outer_prg: if self.program_bank_num > 16 {
|
|
225
|
+
(self.chr_bank0_register.load() >> 4) & 1
|
|
226
|
+
} else {
|
|
227
|
+
0
|
|
228
|
+
},
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
199
232
|
fn has_mirroring_type(&self) -> bool {
|
|
200
233
|
true
|
|
201
234
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
use memory::Memory;
|
|
2
|
-
use mapper::{Mapper, MapperFactory};
|
|
2
|
+
use mapper::{Mapper, MapperFactory, MapperDebugState};
|
|
3
3
|
|
|
4
4
|
pub struct Rom {
|
|
5
5
|
header: RomHeader,
|
|
@@ -132,6 +132,10 @@ impl Rom {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
pub fn mapper_debug_state(&self) -> MapperDebugState {
|
|
136
|
+
self.mapper.debug_state()
|
|
137
|
+
}
|
|
138
|
+
|
|
135
139
|
// @TODO: MMC3Mapper specific. Should this method be here?
|
|
136
140
|
pub fn irq_interrupted(&mut self) -> bool {
|
|
137
141
|
self.mapper.drive_irq_counter()
|
|
@@ -148,8 +148,8 @@ export class NesOverlayComponent implements Component {
|
|
|
148
148
|
|
|
149
149
|
const footer = " NES | Ctrl+Q=Detach | Q=Quit | WASD/Arrows=Move | Z/X=A/B | Enter/Space=Start | Tab=Select";
|
|
150
150
|
const frameBuffer = this.core.getFrameBuffer();
|
|
151
|
-
const
|
|
152
|
-
const footerRows = this.debug ?
|
|
151
|
+
const debugLines = this.debug ? this.buildDebugLines() : [];
|
|
152
|
+
const footerRows = this.debug ? 1 + debugLines.length : 1;
|
|
153
153
|
if (this.rendererMode === "image") {
|
|
154
154
|
const lines = this.imageRenderer.render(
|
|
155
155
|
frameBuffer,
|
|
@@ -159,8 +159,8 @@ export class NesOverlayComponent implements Component {
|
|
|
159
159
|
this.pixelScale,
|
|
160
160
|
!this.windowed,
|
|
161
161
|
);
|
|
162
|
-
|
|
163
|
-
lines.push(truncateToWidth(
|
|
162
|
+
for (const line of debugLines) {
|
|
163
|
+
lines.push(truncateToWidth(line, width));
|
|
164
164
|
}
|
|
165
165
|
lines.push(truncateToWidth(`\x1b[2m${footer}\x1b[0m`, width));
|
|
166
166
|
return lines;
|
|
@@ -176,8 +176,8 @@ export class NesOverlayComponent implements Component {
|
|
|
176
176
|
|
|
177
177
|
const rawLines = renderHalfBlock(frameBuffer, targetCols, targetRows, scaleX, scaleY);
|
|
178
178
|
const lines = rawLines.map((line) => truncateToWidth(`${padPrefix}${line}`, width));
|
|
179
|
-
|
|
180
|
-
lines.push(truncateToWidth(`${padPrefix}${
|
|
179
|
+
for (const line of debugLines) {
|
|
180
|
+
lines.push(truncateToWidth(`${padPrefix}${line}`, width));
|
|
181
181
|
}
|
|
182
182
|
lines.push(truncateToWidth(`\x1b[2m${padPrefix}${footer}\x1b[0m`, width));
|
|
183
183
|
return lines;
|
|
@@ -201,19 +201,40 @@ export class NesOverlayComponent implements Component {
|
|
|
201
201
|
this.imageCleared = true;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
private
|
|
204
|
+
private buildDebugLines(): string[] {
|
|
205
205
|
const stats = this.statsProvider?.();
|
|
206
206
|
if (!stats) {
|
|
207
|
-
return
|
|
207
|
+
return [];
|
|
208
208
|
}
|
|
209
209
|
const label = this.debugLabel ? ` core=${this.debugLabel}` : "";
|
|
210
210
|
const mem = stats.memory;
|
|
211
|
-
const
|
|
211
|
+
const lines: string[] = [];
|
|
212
|
+
const statsLine = `DEBUG${label} fps=${stats.tickFps.toFixed(1)} render=${stats.renderFps.toFixed(1)} `
|
|
212
213
|
+ `frames/tick=${stats.avgFramesPerTick.toFixed(2)} dropped=${stats.droppedFrames} `
|
|
213
214
|
+ `catch=${stats.lastCatchUpFrames}/${stats.maxCatchUpFrames} `
|
|
214
215
|
+ `eld=${stats.eventLoopDelayMs.toFixed(2)}ms `
|
|
215
216
|
+ `mem=${mem.heapUsedMb.toFixed(1)}/${mem.rssMb.toFixed(1)}MB ext=${mem.externalMb.toFixed(1)}MB ab=${mem.arrayBuffersMb.toFixed(1)}MB`;
|
|
216
|
-
|
|
217
|
+
lines.push(`\x1b[33m${statsLine}\x1b[0m`);
|
|
218
|
+
|
|
219
|
+
const debugState = this.core.getDebugState();
|
|
220
|
+
if (debugState) {
|
|
221
|
+
const cpu = debugState.cpu;
|
|
222
|
+
const mapper = debugState.mapper;
|
|
223
|
+
const cpuLine = `CPU pc=${this.formatHex(cpu.pc, 4)} op=${this.formatHex(cpu.lastOpcode, 2)} `
|
|
224
|
+
+ `a=${this.formatHex(cpu.a, 2)} x=${this.formatHex(cpu.x, 2)} y=${this.formatHex(cpu.y, 2)} `
|
|
225
|
+
+ `sp=${this.formatHex(cpu.sp, 2)} p=${this.formatHex(cpu.p, 2)} `
|
|
226
|
+
+ `last=${this.formatHex(cpu.lastPc, 4)}`;
|
|
227
|
+
const mapperLine = `MMC1 ctrl=${this.formatHex(mapper.control, 2)} prg=${this.formatHex(mapper.prg, 2)} `
|
|
228
|
+
+ `chr0=${this.formatHex(mapper.chr0, 2)} chr1=${this.formatHex(mapper.chr1, 2)} `
|
|
229
|
+
+ `prgMode=${mapper.prgMode} chrMode=${mapper.chrMode} outer=${mapper.outerPrg}`;
|
|
230
|
+
lines.push(`\x1b[36m${cpuLine}\x1b[0m`);
|
|
231
|
+
lines.push(`\x1b[36m${mapperLine}\x1b[0m`);
|
|
232
|
+
}
|
|
233
|
+
return lines;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private formatHex(value: number, width: number): string {
|
|
237
|
+
return value.toString(16).padStart(width, "0");
|
|
217
238
|
}
|
|
218
239
|
|
|
219
240
|
private tapButton(button: "start" | "select"): void {
|
|
@@ -8,6 +8,33 @@ export interface FrameBuffer {
|
|
|
8
8
|
data: Uint8Array;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
export interface NesCpuDebugState {
|
|
12
|
+
pc: number;
|
|
13
|
+
a: number;
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
sp: number;
|
|
17
|
+
p: number;
|
|
18
|
+
lastPc: number;
|
|
19
|
+
lastOpcode: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface NesMapperDebugState {
|
|
23
|
+
mapperNum: number;
|
|
24
|
+
control: number;
|
|
25
|
+
prg: number;
|
|
26
|
+
chr0: number;
|
|
27
|
+
chr1: number;
|
|
28
|
+
prgMode: number;
|
|
29
|
+
chrMode: number;
|
|
30
|
+
outerPrg: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface NesDebugState {
|
|
34
|
+
cpu: NesCpuDebugState;
|
|
35
|
+
mapper: NesMapperDebugState;
|
|
36
|
+
}
|
|
37
|
+
|
|
11
38
|
export interface NesCore {
|
|
12
39
|
loadRom(rom: Uint8Array): void;
|
|
13
40
|
tick(): void;
|
|
@@ -18,6 +45,7 @@ export interface NesCore {
|
|
|
18
45
|
isSramDirty(): boolean;
|
|
19
46
|
markSramSaved(): void;
|
|
20
47
|
getAudioWarning(): string | null;
|
|
48
|
+
getDebugState(): NesDebugState | null;
|
|
21
49
|
reset(): void;
|
|
22
50
|
dispose(): void;
|
|
23
51
|
}
|
|
@@ -39,6 +67,7 @@ interface NativeNesInstance {
|
|
|
39
67
|
setSram(data: Uint8Array): void;
|
|
40
68
|
isSramDirty(): boolean;
|
|
41
69
|
markSramSaved(): void;
|
|
70
|
+
getDebugState(): NesDebugState;
|
|
42
71
|
getFramebuffer(): Uint8Array;
|
|
43
72
|
}
|
|
44
73
|
|
|
@@ -148,6 +177,10 @@ class NativeNesCore implements NesCore {
|
|
|
148
177
|
return this.audioWarning;
|
|
149
178
|
}
|
|
150
179
|
|
|
180
|
+
getDebugState(): NesDebugState | null {
|
|
181
|
+
return this.nes.getDebugState();
|
|
182
|
+
}
|
|
183
|
+
|
|
151
184
|
reset(): void {
|
|
152
185
|
this.nes.reset();
|
|
153
186
|
}
|
|
@@ -145,7 +145,7 @@ export class NesImageRenderer {
|
|
|
145
145
|
columns,
|
|
146
146
|
rows,
|
|
147
147
|
imageId: this.imageId,
|
|
148
|
-
zIndex:
|
|
148
|
+
zIndex: 0,
|
|
149
149
|
});
|
|
150
150
|
|
|
151
151
|
const lines: string[] = [];
|
|
@@ -186,7 +186,7 @@ export class NesImageRenderer {
|
|
|
186
186
|
columns,
|
|
187
187
|
rows,
|
|
188
188
|
imageId: this.imageId,
|
|
189
|
-
zIndex:
|
|
189
|
+
zIndex: 0,
|
|
190
190
|
}),
|
|
191
191
|
columns,
|
|
192
192
|
rows,
|