Skip to content

Commit f15c2e7

Browse files
authored
merge Dev (#6)
* added opcodes & tests for LDA: 0xA5, 0xB5, 0xAD * update README.md for opcodes * iml opcodes: 0xBD, 0xB9, 0xA1, 0xB1 all iml from LDA
1 parent 7f7b834 commit f15c2e7

File tree

4 files changed

+518
-53
lines changed

4 files changed

+518
-53
lines changed

js/README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
### Opcodes progress by Instructions:
2+
3+
<details>
4+
<summary><b>Opcodes for <span style="color: orange">LDA - Load Accumulator with Memory</span></b></summary>
5+
6+
| Dec | Opcode | Instruction | Addressing Mode | Cycles | Implemented |
7+
|:---:|:------:|:----------------:|:---------------:|:------:|:-----------:|
8+
| 169 | 0xA9 | LDA #immediate | Immediate | 2 | ✅️ |
9+
| 165 | 0xA5 | LDA zeropage | Zeropage | 3 | ✅️ |
10+
| 181 | 0xB5 | LDA zeropage,X | Zeropage,X | 4 | ✅️ |
11+
| 173 | 0xAD | LDA absolute | Absolute | 4 ||
12+
| 189 | 0xBD | LDA absolute,X | Absolute,X | 4 (+1) ||
13+
| 185 | 0xB9 | LDA absolute,Y | Absolute,Y | 4 (+1) ||
14+
| 161 | 0xA1 | LDA (indirect,X) | Indirect,X | 6 ||
15+
| 177 | 0xB1 | LDA (indirect),Y | Indirect,Y | 5 (+1) ||
16+
17+
</details>
18+
19+
<details open>
20+
<summary><b>Opcodes for <span style="color: orange">LDX - Load Index Register X From Memory</span></b></summary>
21+
22+
| Decimal | Opcode | Instruction | Addressing Mode | Cycles | Implemented |
23+
|:-------:|:------:|:--------------:|:---------------:|:------:|:-----------:|
24+
| 169 | 0xA2 | LDX #immediate | Immediate | 2 ||
25+
| 181 | 0xA6 | LDX zeropage | Zeropage | 3 | |
26+
| 197 | 0xB6 | LDX zeropage,Y | Zeropage,Y | 4 | |
27+
| 173 | 0xAE | LDX absolute | Absolute | 4 | |
28+
| 189 | 0xBE | LDX absolute,Y | Absolute,Y | 4 (+1) | |
29+
30+
</details>
31+
32+
33+
34+
### Opcodes (23/151)
35+
36+
| Dec | Opcode | Instruction | Status |
37+
|:---:|:------:|:--------------:|:------:|
38+
| 0 | 0x00 | BRK ||
39+
| 9 | 0x09 | ORA #immediate ||
40+
| 29 | 0x29 | AND #immediate ||
41+
| 41 | 0x49 | EOR #immediate ||
42+
| 84 | 0x84 | STY zeropage ||
43+
| 85 | 0x85 | STA zeropage ||
44+
| 86 | 0x86 | STX zeropage ||
45+
| 88 | 0x88 | DEY ||
46+
| 90 | 0x90 | BCC ||
47+
| 98 | 0x98 | TYA ||
48+
| 105 | 0x69 | ADC #immediate ||
49+
| 138 | 0x8A | TXA ||
50+
| 160 | 0xA0 | LDY #immediate ||
51+
| 162 | 0xA2 | LDX #immediate ||
52+
| 168 | 0xA8 | TAY ||
53+
| 170 | 0xAA | TAX ||
54+
| 200 | 0xC8 | INY ||
55+
| 202 | 0xCA | DEX ||
56+
| 232 | 0xE8 | INX ||
57+
| 233 | 0xE9 | SBC #immediate ||
58+
| 234 | 0xEA | NOP ||

js/opcodes.js

Lines changed: 108 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,21 @@ const OPCODES = {
303303
cpu.zeroFlag = cpu.Y;
304304
}
305305
},
306-
0xA1: "",
306+
0xA1: {
307+
name: "LDA (indirect,X)", // Load Accumulator with Memory (Indirect Indexed Addressing with X)
308+
t: 6, // Cycles required
309+
code: 0xA1,
310+
run: (cpu) => {
311+
const baseAddress = (cpu.fetch() + cpu.X) & 0xFF; // 0x00-0xFF (zeropage)
312+
const lowByte = cpu.memory.readByte(baseAddress);
313+
const highByte = cpu.memory.readByte((baseAddress + 1) & 0xFF); // wrap around in zeropage
314+
const address = (highByte << 8) | lowByte; // 16-bit address
315+
316+
cpu.ACC = cpu.memory.readByte(address);
317+
cpu.negativeFlag = cpu.ACC;
318+
cpu.zeroFlag = cpu.ACC;
319+
},
320+
},
307321
0xA2: {
308322
name: "LDX #immediate", // Load Index X with Memory
309323
t: 2,
@@ -316,7 +330,17 @@ const OPCODES = {
316330
},
317331
0xA3: "", // lax("(d,x)") // illegal
318332
0xA4: "",
319-
0xA5: "",
333+
0xA5: {
334+
name: "LDA zeropage", // Load Accumulator with Memory from Zeropage
335+
t: 3,
336+
code: 0xA5,
337+
run: (cpu) => {
338+
const address = cpu.fetch();
339+
cpu.ACC = cpu.memory.readByte(address);
340+
cpu.negativeFlag = cpu.ACC;
341+
cpu.zeroFlag = cpu.ACC;
342+
}
343+
},
320344
0xA6: "",
321345
0xA7: "", // illegal
322346
0xA8: {
@@ -351,23 +375,100 @@ const OPCODES = {
351375
},
352376
0xAB: "", // lax("#i") // illegal
353377
0xAC: "",
354-
0xAD: "",
378+
0xAD: {
379+
name: "LDA absolute", // Load Accumulator Absolute
380+
t: 4,
381+
code: 0xAD,
382+
run: (cpu) => {
383+
const lowByte = cpu.fetch();
384+
const highByte = cpu.fetch();
385+
const address = (highByte << 8) | lowByte;
386+
cpu.ACC = cpu.memory.readByte(address);
387+
cpu.negativeFlag = cpu.ACC;
388+
cpu.zeroFlag = cpu.ACC;
389+
}
390+
},
355391
0xAE: "",
356392
0xAF: "", // lax("a") // illegal
357393
0xB0: "", // bcs("*+d")
358-
0xB1: "", // lda("(d),y")
394+
0xB1: {
395+
name: "LDA (indirect),Y", // Load Accumulator with Memory (Indirect) and Indexed Addressing with Y
396+
t: 5, // 5 (+1)
397+
code: 0xB1,
398+
run: (cpu) => {
399+
const baseAddress = cpu.fetch();
400+
const lowByte = cpu.memory.readByte(baseAddress);
401+
const highByte = cpu.memory.readByte((baseAddress + 1) & 0xFF); // wrap around in zeropage
402+
const address = (highByte << 8) | lowByte + cpu.Y; // 16-bit address
403+
404+
// Check if the address crosses a page boundary
405+
if ((address & 0xFF00) !== ((highByte << 8) & 0xFF00)) {
406+
cpu.cycles += 1; // Add an extra cycle if a page boundary is crossed
407+
}
408+
409+
410+
cpu.ACC = cpu.memory.readByte(address);
411+
cpu.negativeFlag = cpu.ACC;
412+
cpu.zeroFlag = cpu.ACC;
413+
},
414+
},
359415
0xB2: "", // stp_implied() // illegal
360416
0xB3: "", // lax("(d),y") // illegal
361417
0xB4: "",
362-
0xB5: "",
418+
0xB5: {
419+
name: "LDA zeropage,X", // Load Accumulator with X-Indexed Zero Page
420+
t: 4,
421+
code: 0xB5,
422+
run: (cpu) => {
423+
const baseAddress = cpu.fetch();
424+
const address = (baseAddress + cpu.X) & 0xFF;
425+
cpu.ACC = cpu.memory.readByte(address);
426+
cpu.negativeFlag = cpu.ACC;
427+
cpu.zeroFlag = cpu.ACC;
428+
}
429+
},
363430
0xB6: "",
364431
0xB7: "", // lax("d,y") // illegal
365432
0xB8: "", // clv_implied()
366-
0xB9: "", // lda("a,y")
433+
0xB9: {
434+
name: "LDA absolute,Y", // Load Accumulator with Memory (Absolute Addressing with Y offset)
435+
t: 4, // 4 (+1)
436+
code: 0xB9,
437+
run: (cpu) => {
438+
const lowByte = cpu.fetch();
439+
const highByte = cpu.fetch();
440+
const address = ((highByte << 8) | lowByte) + cpu.Y; // Combine bytes and add Y register value
441+
// Check if address crosses a page boundary
442+
if ((address & 0xFF00) !== ((highByte << 8) & 0xFF00)) {
443+
cpu.cycles += 1; // Add an extra cycle if a page boundary is crossed
444+
}
445+
446+
cpu.ACC = cpu.memory.readByte(address);
447+
cpu.negativeFlag = cpu.ACC;
448+
cpu.zeroFlag = cpu.ACC;
449+
}
450+
},
367451
0xBA: "", // tsx_implied()
368452
0xBB: "", // las("a,y") // illegal
369453
0xBC: "", // ldy("a,x")
370-
0xBD: "", // lda("a,x")
454+
0xBD: {
455+
name: "LDA absolute,X", // Load Accumulator with Memory (Absolute Addressing with X offset)
456+
t: 4, // 4 (+1)
457+
code: 0xBD,
458+
run: (cpu) => {
459+
const lowByte = cpu.fetch();
460+
const highByte = cpu.fetch();
461+
const address = ((highByte << 8) | lowByte) + cpu.X; // Combine bytes and add X register value
462+
// Check if address crosses a page boundary
463+
if ((address & 0xFF00) !== ((highByte << 8) & 0xFF00)) {
464+
cpu.cycles += 1; // Add an extra cycle if a page boundary is crossed
465+
}
466+
467+
cpu.ACC = cpu.memory.readByte(address);
468+
cpu.negativeFlag = cpu.ACC;
469+
cpu.zeroFlag = cpu.ACC;
470+
}
471+
},
371472
0xBE: "", // ldx("a,y")
372473
0xBF: "", // lax("a,y") // illegal
373474
0xC0: "", // cpy("#i")

js/opcodes.md

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)