Skip to content

Commit d4a5870

Browse files
committed
opcodes jmp ldx stx
1 parent d2218f5 commit d4a5870

File tree

5 files changed

+266
-50
lines changed

5 files changed

+266
-50
lines changed

NES/APU.js

+2
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33

44
}
55

6+
APU.prototype.tick = function() {}
7+
68
module.exports = APU;
79
})();

NES/CPU.js

+247-49
Original file line numberDiff line numberDiff line change
@@ -6,73 +6,271 @@
66
this.nes = nes;
77
}
88

9-
CPU.prototype.powerUp = function() {
109

11-
// ============= registers =============
10+
function pad(width, string, padding) {
11+
return (width <= string.length) ? string : pad(width, padding + string, padding)
12+
}
13+
14+
CPU.prototype = {
15+
powerUp: function () {
16+
// ============= registers =============
17+
// Accumulator
18+
this.reg_a = 0;
19+
20+
// Indexes
21+
this.reg_x = 0;
22+
this.reg_y = 0;
23+
24+
// Program Counter
25+
this.reg_pc = 0xc000;
26+
27+
// Stack Pointer
28+
this.reg_s = 0xFD;
29+
30+
//Status Register
31+
// 7 bit 0
32+
// ---- ----
33+
// NVss DIZC
34+
this.reg_p = 0x34;
35+
36+
// http://wiki.nesdev.com/w/index.php/CPU_status_flag_behavior
37+
this.flag_c = false;
38+
this.flag_z = false;
39+
this.flag_i = true;
40+
this.flag_d = false;
41+
this.flag_v = false;
42+
this.flag_n = false;
43+
44+
this.memory = new Memory(this.nes.cartridge);
45+
// todo: noise channel LFSR = $0000 The first time the LFSR is clocked from the all-0s state, it will shift in a 1.
46+
47+
this.cycles = 0;
48+
},
49+
50+
_exec: function (opcode) {
51+
const regPc = this.reg_pc.toString(16);
52+
const log = regPc.toString(16) + '\t' + opcode.toString(16) + '\t';
53+
const log2 = '\t' + `A: ${this.reg_a} X:${this.reg_x} Y:${this.reg_y} P:${this.reg_p} SP:${this.reg_s.toString(16)} CYC:${this.cycles}`;
54+
switch (opcode) {
55+
case 0x4c:
56+
this._abs();
57+
this._jmp();
58+
this.cycles += 3 * 3;
59+
break;
60+
case 0xA2:
61+
this._imm();
62+
this._ldx();
63+
this.cycles += 2 * 3;
64+
break;
65+
case 0x86:
66+
this._zp();
67+
this._stx();
68+
this.cycles += 3 * 3;
69+
break;
70+
default:
71+
}
72+
console.log(log + pad(4, this.address.toString(16), ' ') + log2);
73+
},
74+
75+
// ============= op codes =============
76+
_adc: function () {
77+
},
78+
_and: function () {
79+
},
80+
_asl: function () {
81+
},
82+
_bcc: function () {
83+
},
84+
_bcs: function () {
85+
},
86+
_beq: function () {
87+
},
88+
_bit: function () {
89+
},
90+
_bmi: function () {
91+
},
92+
_bne: function () {
93+
},
94+
_bpl: function () {
95+
},
96+
_bvc: function () {
97+
},
98+
_bvs: function () {
99+
},
100+
_clc: function () {
101+
},
102+
_cld: function () {
103+
},
104+
_clv: function () {
105+
},
106+
_cmp: function () {
107+
},
108+
_cpx: function () {
109+
},
110+
_cpy: function () {
111+
},
112+
_dcp: function () {
113+
},
114+
_dec: function () {
115+
},
116+
_dex: function () {
117+
},
118+
_dey: function () {
119+
},
120+
_eor: function () {
121+
},
122+
_inc: function () {
123+
},
124+
_inx: function () {
125+
},
126+
_iny: function () {
127+
},
128+
_isb: function () {
129+
},
130+
_jmp: function () {
131+
this.reg_pc = this.address;
132+
},
133+
_jsr: function () {
134+
},
135+
_lax: function () {
136+
},
137+
_lda: function () {
138+
},
139+
_ldx: function () {
140+
this.reg_x = this.memory.read(this.address);
141+
},
142+
_ldy: function () {
143+
},
144+
_lsr: function () {
145+
},
146+
_nop: function () {
147+
},
148+
_ora: function () {
149+
},
150+
_pha: function () {
151+
},
152+
_php: function () {
153+
},
154+
_pla: function () {
155+
},
156+
_plp: function () {
157+
},
158+
_rla: function () {
159+
},
160+
_rol: function () {
161+
},
162+
_ror: function () {
163+
},
164+
_rra: function () {
165+
},
166+
_rti: function () {
167+
},
168+
_rts: function () {
169+
},
170+
_sax: function () {
171+
},
172+
_sbc: function () {
173+
},
174+
_sec: function () {
175+
},
176+
_sed: function () {
177+
},
178+
_sei: function () {
179+
},
180+
_slo: function () {
181+
},
182+
_sre: function () {
183+
},
184+
_sta: function () {
185+
},
186+
_stx: function () {
187+
this.memory.write(this.reg_x);
188+
},
189+
_sty: function () {
190+
},
191+
_tax: function () {
192+
},
193+
_tay: function () {
194+
},
195+
_tsx: function () {
196+
},
197+
_txa: function () {
198+
},
199+
_txs: function () {
200+
},
201+
_tya: function () {
202+
},
203+
204+
// ============= addressing modes =============
12205
// Accumulator
13-
this.REG_A = 0;
206+
_a: function () {
14207

15-
// Indexes
16-
this.REG_X = 0;
17-
this.REG_Y = 0;
208+
},
18209

19-
// Program Counter
20-
this.REG_PC = null;
210+
// absolute
211+
_abs: function () {
212+
const high = this.memory.read(this.reg_pc + 2) << 8,
213+
low = this.memory.read(this.reg_pc + 1);
21214

22-
// Stack Pointer
23-
this.REG_S = 0xFD;
215+
this.address = high | low;
216+
this.reg_pc += 3;
217+
},
24218

25-
//Status Register
26-
// 7 bit 0
27-
// ---- ----
28-
// NVss DIZC
29-
this.REG_P = 0x34;
219+
// absolute, X-indexed
220+
_abx: function () {
221+
},
30222

31-
// http://wiki.nesdev.com/w/index.php/CPU_status_flag_behavior
32-
this.FLAG_C = false;
33-
this.FLAG_Z = false;
34-
this.FLAG_I = true;
35-
this.FLAG_D = false;
36-
this.FLAG_V = false;
37-
this.FLAG_N = false;
223+
// absolute, Y-indexed
224+
_aby: function () {
225+
},
38226

39-
this.memory = new Memory(this.nes.cartridge);
40-
// todo: noise channel LFSR = $0000 The first time the LFSR is clocked from the all-0s state, it will shift in a 1.
227+
// immediate
228+
_imm: function () {
229+
this.address = this.memory.read(this.reg_pc + 1);
230+
this.reg_pc += 2;
231+
},
41232

42-
console.log(this.memory.read(0xc000).toString(16))
43-
console.log(this.memory.read(0x8000).toString(16))
233+
// implied
234+
_impl: function () {
235+
},
44236

45-
this.cycles = 0;
46-
};
237+
// indirect
238+
_ind: function () {
239+
},
47240

48-
CPU.prototype._exec = function (opcode) {
49-
console.log(opcode)
50-
};
241+
// X-indexed, indirect
242+
_izx: function () {
243+
},
51244

245+
// indirect, Y-indexed
246+
_izy: function () {
52247

53-
CPU.prototype._a = function() {};
54-
CPU.prototype._abs = function() {};
55-
CPU.prototype._abx = function() {};
56-
CPU.prototype._aby = function() {};
57-
CPU.prototype._imm = function() {};
58-
CPU.prototype._impl = function() {};
59-
CPU.prototype._ind = function() {};
60-
CPU.prototype._izx = function() {};
61-
CPU.prototype._izy = function() {};
62-
CPU.prototype._rel = function() {};
63-
CPU.prototype._zp = function() {};
64-
CPU.prototype._zpx = function() {};
65-
CPU.prototype._zpy = function() {};
248+
},
66249

250+
// relative
251+
_rel: function () {
252+
},
67253

68-
CPU.prototype.run = function () {
69-
};
254+
// zeropage
255+
_zp: function () {
256+
this.address = this.memory.read(this.reg_pc + 1);
257+
this.reg_pc += 2;
258+
},
70259

71-
CPU.prototype.jmp = function () {
260+
// zeropage, X-indexed
261+
_zpx: function () {
262+
},
72263

73-
};
264+
// zeropage, Y-indexed
265+
_zpy: function () {
266+
},
267+
268+
tick: function () {
269+
this._exec(this.memory.read(this.reg_pc))
270+
},
74271

75-
CPU.prototype.reset = function () {
272+
reset: function () {
273+
}
76274
};
77275

78276
module.exports = CPU;

NES/NES.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
const fs = require('fs');
33

44
const CPU = require('./CPU');
5+
const PPU = require('./PPU');
6+
const APU = require('./APU');
57
const CARTRIDGE = require('./CARTRIDGE');
68

79
function NES() {
@@ -12,8 +14,20 @@
1214
fs.readFile(cartridge, (err, data) => {
1315
this.cartridge = new CARTRIDGE(data);
1416
this.cpu = new CPU(this);
17+
this.ppu = new PPU();
18+
this.apu = new APU();
1519
this.cpu.powerUp();
16-
this.cpu.run();
20+
21+
let i = 0;
22+
while (i++ < 16) {
23+
this.cpu.tick();
24+
25+
this.ppu.tick();
26+
this.ppu.tick();
27+
this.ppu.tick();
28+
29+
this.apu.tick();
30+
}
1731
});
1832
};
1933

NES/PPU.JS

+2
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33

44
}
55

6+
PPU.prototype.tick = function() {}
7+
68
module.exports = PPU;
79
})();

rom/1942.nes

40 KB
Binary file not shown.

0 commit comments

Comments
 (0)