ac6502 1.0.0

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.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +261 -0
  3. package/dist/components/CPU.js +1170 -0
  4. package/dist/components/CPU.js.map +1 -0
  5. package/dist/components/Cart.js +23 -0
  6. package/dist/components/Cart.js.map +1 -0
  7. package/dist/components/IO/Empty.js +19 -0
  8. package/dist/components/IO/Empty.js.map +1 -0
  9. package/dist/components/IO/GPIOAttachments/GPIOAttachment.js +71 -0
  10. package/dist/components/IO/GPIOAttachments/GPIOAttachment.js.map +1 -0
  11. package/dist/components/IO/GPIOAttachments/GPIOJoystickAttachment.js +90 -0
  12. package/dist/components/IO/GPIOAttachments/GPIOJoystickAttachment.js.map +1 -0
  13. package/dist/components/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.js +489 -0
  14. package/dist/components/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.js.map +1 -0
  15. package/dist/components/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.js +274 -0
  16. package/dist/components/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.js.map +1 -0
  17. package/dist/components/IO/GPIOCard.js +597 -0
  18. package/dist/components/IO/GPIOCard.js.map +1 -0
  19. package/dist/components/IO/InputBoard.js +19 -0
  20. package/dist/components/IO/InputBoard.js.map +1 -0
  21. package/dist/components/IO/LCDCard.js +19 -0
  22. package/dist/components/IO/LCDCard.js.map +1 -0
  23. package/dist/components/IO/RAMCard.js +63 -0
  24. package/dist/components/IO/RAMCard.js.map +1 -0
  25. package/dist/components/IO/RTCCard.js +483 -0
  26. package/dist/components/IO/RTCCard.js.map +1 -0
  27. package/dist/components/IO/SerialCard.js +282 -0
  28. package/dist/components/IO/SerialCard.js.map +1 -0
  29. package/dist/components/IO/SoundCard.js +620 -0
  30. package/dist/components/IO/SoundCard.js.map +1 -0
  31. package/dist/components/IO/StorageCard.js +428 -0
  32. package/dist/components/IO/StorageCard.js.map +1 -0
  33. package/dist/components/IO/VGACard.js +9 -0
  34. package/dist/components/IO/VGACard.js.map +1 -0
  35. package/dist/components/IO/VideoCard.js +623 -0
  36. package/dist/components/IO/VideoCard.js.map +1 -0
  37. package/dist/components/IO.js +3 -0
  38. package/dist/components/IO.js.map +1 -0
  39. package/dist/components/Machine.js +310 -0
  40. package/dist/components/Machine.js.map +1 -0
  41. package/dist/components/RAM.js +24 -0
  42. package/dist/components/RAM.js.map +1 -0
  43. package/dist/components/ROM.js +23 -0
  44. package/dist/components/ROM.js.map +1 -0
  45. package/dist/index.js +441 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/tests/CPU.test.js +1626 -0
  48. package/dist/tests/CPU.test.js.map +1 -0
  49. package/dist/tests/Cart.test.js +119 -0
  50. package/dist/tests/Cart.test.js.map +1 -0
  51. package/dist/tests/IO/GPIOAttachments/GPIOAttachment.test.js +339 -0
  52. package/dist/tests/IO/GPIOAttachments/GPIOAttachment.test.js.map +1 -0
  53. package/dist/tests/IO/GPIOAttachments/GPIOJoystickAttachment.test.js +126 -0
  54. package/dist/tests/IO/GPIOAttachments/GPIOJoystickAttachment.test.js.map +1 -0
  55. package/dist/tests/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.test.js +779 -0
  56. package/dist/tests/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.test.js.map +1 -0
  57. package/dist/tests/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.test.js +355 -0
  58. package/dist/tests/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.test.js.map +1 -0
  59. package/dist/tests/IO/GPIOCard.test.js +503 -0
  60. package/dist/tests/IO/GPIOCard.test.js.map +1 -0
  61. package/dist/tests/IO/RAMCard.test.js +229 -0
  62. package/dist/tests/IO/RAMCard.test.js.map +1 -0
  63. package/dist/tests/IO/RTCCard.test.js +177 -0
  64. package/dist/tests/IO/RTCCard.test.js.map +1 -0
  65. package/dist/tests/IO/SerialCard.test.js +423 -0
  66. package/dist/tests/IO/SerialCard.test.js.map +1 -0
  67. package/dist/tests/IO/SoundCard.test.js +528 -0
  68. package/dist/tests/IO/SoundCard.test.js.map +1 -0
  69. package/dist/tests/IO/StorageCard.test.js +647 -0
  70. package/dist/tests/IO/StorageCard.test.js.map +1 -0
  71. package/dist/tests/IO/VideoCard.test.js +549 -0
  72. package/dist/tests/IO/VideoCard.test.js.map +1 -0
  73. package/dist/tests/Machine.test.js +383 -0
  74. package/dist/tests/Machine.test.js.map +1 -0
  75. package/dist/tests/RAM.test.js +160 -0
  76. package/dist/tests/RAM.test.js.map +1 -0
  77. package/dist/tests/ROM.test.js +123 -0
  78. package/dist/tests/ROM.test.js.map +1 -0
  79. package/jest.config.cjs +9 -0
  80. package/package.json +43 -0
  81. package/src/components/CPU.ts +1371 -0
  82. package/src/components/Cart.ts +20 -0
  83. package/src/components/IO/GPIOAttachments/GPIOAttachment.ts +189 -0
  84. package/src/components/IO/GPIOAttachments/GPIOJoystickAttachment.ts +99 -0
  85. package/src/components/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.ts +465 -0
  86. package/src/components/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.ts +287 -0
  87. package/src/components/IO/GPIOCard.ts +677 -0
  88. package/src/components/IO/RAMCard.ts +68 -0
  89. package/src/components/IO/RTCCard.ts +518 -0
  90. package/src/components/IO/SerialCard.ts +335 -0
  91. package/src/components/IO/SoundCard.ts +711 -0
  92. package/src/components/IO/StorageCard.ts +473 -0
  93. package/src/components/IO/VideoCard.ts +730 -0
  94. package/src/components/IO.ts +11 -0
  95. package/src/components/Machine.ts +364 -0
  96. package/src/components/RAM.ts +23 -0
  97. package/src/components/ROM.ts +19 -0
  98. package/src/index.ts +474 -0
  99. package/src/tests/CPU.test.ts +2045 -0
  100. package/src/tests/Cart.test.ts +149 -0
  101. package/src/tests/IO/GPIOAttachments/GPIOAttachment.test.ts +413 -0
  102. package/src/tests/IO/GPIOAttachments/GPIOJoystickAttachment.test.ts +147 -0
  103. package/src/tests/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.test.ts +961 -0
  104. package/src/tests/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.test.ts +449 -0
  105. package/src/tests/IO/GPIOCard.test.ts +644 -0
  106. package/src/tests/IO/RAMCard.test.ts +284 -0
  107. package/src/tests/IO/RTCCard.test.ts +222 -0
  108. package/src/tests/IO/SerialCard.test.ts +530 -0
  109. package/src/tests/IO/SoundCard.test.ts +659 -0
  110. package/src/tests/IO/StorageCard.test.ts +787 -0
  111. package/src/tests/IO/VideoCard.test.ts +668 -0
  112. package/src/tests/Machine.test.ts +437 -0
  113. package/src/tests/RAM.test.ts +196 -0
  114. package/src/tests/ROM.test.ts +154 -0
  115. package/tsconfig.json +12 -0
@@ -0,0 +1,1170 @@
1
+ "use strict";
2
+ // 65c02 CPU
3
+ // Adapted from: https://github.com/OneLoneCoder/olcNES
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.CPU = void 0;
6
+ class CPU {
7
+ constructor(read, write) {
8
+ this.fetched = 0x00; // Working input value to the ALU
9
+ this.temp = 0x0000; // A convenience var used everywhere
10
+ this.addrAbs = 0x0000; // All used memory addresses end up here
11
+ this.addrRel = 0x0000; // Represents abs address following a branch
12
+ this.opcode = 0x00; // The instruction byte
13
+ this.cyclesRem = 0; // Counts how many cycles the current instruction has remaining
14
+ this.cycles = 0; // Counts the total number of cycles executed
15
+ this.a = 0x00;
16
+ this.x = 0x00;
17
+ this.y = 0x00;
18
+ this.pc = 0x0000;
19
+ this.sp = 0xFD;
20
+ this.st = 0x00 | CPU.U;
21
+ //
22
+ // Instruction Table
23
+ //
24
+ this.instructionTable = [
25
+ { name: 'BRK', cycles: 7, opcode: this.BRK.bind(this), addrMode: this.IMM.bind(this) },
26
+ { name: 'ORA', cycles: 6, opcode: this.ORA.bind(this), addrMode: this.IZX.bind(this) },
27
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
28
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
29
+ { name: 'TSB', cycles: 5, opcode: this.TSB.bind(this), addrMode: this.ZP0.bind(this) },
30
+ { name: 'ORA', cycles: 3, opcode: this.ORA.bind(this), addrMode: this.ZP0.bind(this) },
31
+ { name: 'ASL', cycles: 5, opcode: this.ASL.bind(this), addrMode: this.ZP0.bind(this) },
32
+ { name: 'RMB0', cycles: 5, opcode: this.RMB0.bind(this), addrMode: this.ZP0.bind(this) },
33
+ { name: 'PHP', cycles: 3, opcode: this.PHP.bind(this), addrMode: this.IMP.bind(this) },
34
+ { name: 'ORA', cycles: 2, opcode: this.ORA.bind(this), addrMode: this.IMM.bind(this) },
35
+ { name: 'ASL', cycles: 2, opcode: this.ASL.bind(this), addrMode: this.IMP.bind(this) },
36
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
37
+ { name: 'TSB', cycles: 6, opcode: this.TSB.bind(this), addrMode: this.ABS.bind(this) },
38
+ { name: 'ORA', cycles: 4, opcode: this.ORA.bind(this), addrMode: this.ABS.bind(this) },
39
+ { name: 'ASL', cycles: 6, opcode: this.ASL.bind(this), addrMode: this.ABS.bind(this) },
40
+ { name: 'BBR0', cycles: 5, opcode: this.BBR0.bind(this), addrMode: this.ZPR.bind(this) },
41
+ { name: 'BPL', cycles: 2, opcode: this.BPL.bind(this), addrMode: this.REL.bind(this) },
42
+ { name: 'ORA', cycles: 5, opcode: this.ORA.bind(this), addrMode: this.IZY.bind(this) },
43
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
44
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
45
+ { name: 'TRB', cycles: 5, opcode: this.TRB.bind(this), addrMode: this.ZP0.bind(this) },
46
+ { name: 'ORA', cycles: 4, opcode: this.ORA.bind(this), addrMode: this.ZPX.bind(this) },
47
+ { name: 'ASL', cycles: 6, opcode: this.ASL.bind(this), addrMode: this.ZPX.bind(this) },
48
+ { name: 'RMB1', cycles: 5, opcode: this.RMB1.bind(this), addrMode: this.ZP0.bind(this) },
49
+ { name: 'CLC', cycles: 2, opcode: this.CLC.bind(this), addrMode: this.IMP.bind(this) },
50
+ { name: 'ORA', cycles: 4, opcode: this.ORA.bind(this), addrMode: this.ABY.bind(this) },
51
+ { name: '???', cycles: 2, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
52
+ { name: '???', cycles: 7, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
53
+ { name: 'TRB', cycles: 6, opcode: this.TRB.bind(this), addrMode: this.ABS.bind(this) },
54
+ { name: 'ORA', cycles: 4, opcode: this.ORA.bind(this), addrMode: this.ABX.bind(this) },
55
+ { name: 'ASL', cycles: 7, opcode: this.ASL.bind(this), addrMode: this.ABX.bind(this) },
56
+ { name: 'BBR1', cycles: 5, opcode: this.BBR1.bind(this), addrMode: this.ZPR.bind(this) },
57
+ { name: 'JSR', cycles: 6, opcode: this.JSR.bind(this), addrMode: this.ABS.bind(this) },
58
+ { name: 'AND', cycles: 6, opcode: this.AND.bind(this), addrMode: this.IZX.bind(this) },
59
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
60
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
61
+ { name: 'BIT', cycles: 3, opcode: this.BIT.bind(this), addrMode: this.ZP0.bind(this) },
62
+ { name: 'AND', cycles: 3, opcode: this.AND.bind(this), addrMode: this.ZP0.bind(this) },
63
+ { name: 'ROL', cycles: 5, opcode: this.ROL.bind(this), addrMode: this.ZP0.bind(this) },
64
+ { name: 'RMB2', cycles: 5, opcode: this.RMB2.bind(this), addrMode: this.ZP0.bind(this) },
65
+ { name: 'PLP', cycles: 4, opcode: this.PLP.bind(this), addrMode: this.IMP.bind(this) },
66
+ { name: 'AND', cycles: 2, opcode: this.AND.bind(this), addrMode: this.IMM.bind(this) },
67
+ { name: 'ROL', cycles: 2, opcode: this.ROL.bind(this), addrMode: this.IMP.bind(this) },
68
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
69
+ { name: 'BIT', cycles: 4, opcode: this.BIT.bind(this), addrMode: this.ABS.bind(this) },
70
+ { name: 'AND', cycles: 4, opcode: this.AND.bind(this), addrMode: this.ABS.bind(this) },
71
+ { name: 'ROL', cycles: 6, opcode: this.ROL.bind(this), addrMode: this.ABS.bind(this) },
72
+ { name: 'BBR2', cycles: 5, opcode: this.BBR2.bind(this), addrMode: this.ZPR.bind(this) },
73
+ { name: 'BMI', cycles: 2, opcode: this.BMI.bind(this), addrMode: this.REL.bind(this) },
74
+ { name: 'AND', cycles: 5, opcode: this.AND.bind(this), addrMode: this.IZY.bind(this) },
75
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
76
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
77
+ { name: '???', cycles: 4, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
78
+ { name: 'AND', cycles: 4, opcode: this.AND.bind(this), addrMode: this.ZPX.bind(this) },
79
+ { name: 'ROL', cycles: 6, opcode: this.ROL.bind(this), addrMode: this.ZPX.bind(this) },
80
+ { name: 'RMB3', cycles: 5, opcode: this.RMB3.bind(this), addrMode: this.ZP0.bind(this) },
81
+ { name: 'SEC', cycles: 2, opcode: this.SEC.bind(this), addrMode: this.IMP.bind(this) },
82
+ { name: 'AND', cycles: 4, opcode: this.AND.bind(this), addrMode: this.ABY.bind(this) },
83
+ { name: '???', cycles: 2, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
84
+ { name: '???', cycles: 7, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
85
+ { name: '???', cycles: 4, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
86
+ { name: 'AND', cycles: 4, opcode: this.AND.bind(this), addrMode: this.ABX.bind(this) },
87
+ { name: 'ROL', cycles: 7, opcode: this.ROL.bind(this), addrMode: this.ABX.bind(this) },
88
+ { name: 'BBR3', cycles: 5, opcode: this.BBR3.bind(this), addrMode: this.ZPR.bind(this) },
89
+ { name: 'RTI', cycles: 6, opcode: this.RTI.bind(this), addrMode: this.IMP.bind(this) },
90
+ { name: 'EOR', cycles: 6, opcode: this.EOR.bind(this), addrMode: this.IZX.bind(this) },
91
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
92
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
93
+ { name: '???', cycles: 3, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
94
+ { name: 'EOR', cycles: 3, opcode: this.EOR.bind(this), addrMode: this.ZP0.bind(this) },
95
+ { name: 'LSR', cycles: 5, opcode: this.LSR.bind(this), addrMode: this.ZP0.bind(this) },
96
+ { name: 'RMB4', cycles: 5, opcode: this.RMB4.bind(this), addrMode: this.ZP0.bind(this) },
97
+ { name: 'PHA', cycles: 3, opcode: this.PHA.bind(this), addrMode: this.IMP.bind(this) },
98
+ { name: 'EOR', cycles: 2, opcode: this.EOR.bind(this), addrMode: this.IMM.bind(this) },
99
+ { name: 'LSR', cycles: 2, opcode: this.LSR.bind(this), addrMode: this.IMP.bind(this) },
100
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
101
+ { name: 'JMP', cycles: 3, opcode: this.JMP.bind(this), addrMode: this.ABS.bind(this) },
102
+ { name: 'EOR', cycles: 4, opcode: this.EOR.bind(this), addrMode: this.ABS.bind(this) },
103
+ { name: 'LSR', cycles: 6, opcode: this.LSR.bind(this), addrMode: this.ABS.bind(this) },
104
+ { name: 'BBR4', cycles: 5, opcode: this.BBR4.bind(this), addrMode: this.ZPR.bind(this) },
105
+ { name: 'BVC', cycles: 2, opcode: this.BVC.bind(this), addrMode: this.REL.bind(this) },
106
+ { name: 'EOR', cycles: 5, opcode: this.EOR.bind(this), addrMode: this.IZY.bind(this) },
107
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
108
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
109
+ { name: '???', cycles: 4, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
110
+ { name: 'EOR', cycles: 4, opcode: this.EOR.bind(this), addrMode: this.ZPX.bind(this) },
111
+ { name: 'LSR', cycles: 6, opcode: this.LSR.bind(this), addrMode: this.ZPX.bind(this) },
112
+ { name: 'RMB5', cycles: 5, opcode: this.RMB5.bind(this), addrMode: this.ZP0.bind(this) },
113
+ { name: 'CLI', cycles: 2, opcode: this.CLI.bind(this), addrMode: this.IMP.bind(this) },
114
+ { name: 'EOR', cycles: 4, opcode: this.EOR.bind(this), addrMode: this.ABY.bind(this) },
115
+ { name: 'PHY', cycles: 3, opcode: this.PHY.bind(this), addrMode: this.IMP.bind(this) },
116
+ { name: '???', cycles: 7, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
117
+ { name: '???', cycles: 4, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
118
+ { name: 'EOR', cycles: 4, opcode: this.EOR.bind(this), addrMode: this.ABX.bind(this) },
119
+ { name: 'LSR', cycles: 7, opcode: this.LSR.bind(this), addrMode: this.ABX.bind(this) },
120
+ { name: 'BBR5', cycles: 5, opcode: this.BBR5.bind(this), addrMode: this.ZPR.bind(this) },
121
+ { name: 'RTS', cycles: 6, opcode: this.RTS.bind(this), addrMode: this.IMP.bind(this) },
122
+ { name: 'ADC', cycles: 6, opcode: this.ADC.bind(this), addrMode: this.IZX.bind(this) },
123
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
124
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
125
+ { name: 'STZ', cycles: 3, opcode: this.STZ.bind(this), addrMode: this.ZP0.bind(this) },
126
+ { name: 'ADC', cycles: 3, opcode: this.ADC.bind(this), addrMode: this.ZP0.bind(this) },
127
+ { name: 'ROR', cycles: 5, opcode: this.ROR.bind(this), addrMode: this.ZP0.bind(this) },
128
+ { name: 'RMB6', cycles: 5, opcode: this.RMB6.bind(this), addrMode: this.ZP0.bind(this) },
129
+ { name: 'PLA', cycles: 4, opcode: this.PLA.bind(this), addrMode: this.IMP.bind(this) },
130
+ { name: 'ADC', cycles: 2, opcode: this.ADC.bind(this), addrMode: this.IMM.bind(this) },
131
+ { name: 'ROR', cycles: 2, opcode: this.ROR.bind(this), addrMode: this.IMP.bind(this) },
132
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
133
+ { name: 'JMP', cycles: 5, opcode: this.JMP.bind(this), addrMode: this.IND.bind(this) },
134
+ { name: 'ADC', cycles: 4, opcode: this.ADC.bind(this), addrMode: this.ABS.bind(this) },
135
+ { name: 'ROR', cycles: 6, opcode: this.ROR.bind(this), addrMode: this.ABS.bind(this) },
136
+ { name: 'BBR6', cycles: 5, opcode: this.BBR6.bind(this), addrMode: this.ZPR.bind(this) },
137
+ { name: 'BVS', cycles: 2, opcode: this.BVS.bind(this), addrMode: this.REL.bind(this) },
138
+ { name: 'ADC', cycles: 5, opcode: this.ADC.bind(this), addrMode: this.IZY.bind(this) },
139
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
140
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
141
+ { name: 'STZ', cycles: 4, opcode: this.STZ.bind(this), addrMode: this.ZPX.bind(this) },
142
+ { name: 'ADC', cycles: 4, opcode: this.ADC.bind(this), addrMode: this.ZPX.bind(this) },
143
+ { name: 'ROR', cycles: 6, opcode: this.ROR.bind(this), addrMode: this.ZPX.bind(this) },
144
+ { name: 'RMB7', cycles: 5, opcode: this.RMB7.bind(this), addrMode: this.ZP0.bind(this) },
145
+ { name: 'SEI', cycles: 2, opcode: this.SEI.bind(this), addrMode: this.IMP.bind(this) },
146
+ { name: 'ADC', cycles: 4, opcode: this.ADC.bind(this), addrMode: this.ABY.bind(this) },
147
+ { name: 'PLY', cycles: 4, opcode: this.PLY.bind(this), addrMode: this.IMP.bind(this) },
148
+ { name: '???', cycles: 7, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
149
+ { name: 'JMP', cycles: 6, opcode: this.JMP.bind(this), addrMode: this.IAX.bind(this) },
150
+ { name: 'ADC', cycles: 4, opcode: this.ADC.bind(this), addrMode: this.ABX.bind(this) },
151
+ { name: 'ROR', cycles: 7, opcode: this.ROR.bind(this), addrMode: this.ABX.bind(this) },
152
+ { name: 'BBR7', cycles: 5, opcode: this.BBR7.bind(this), addrMode: this.ZPR.bind(this) },
153
+ { name: 'BRA', cycles: 3, opcode: this.BRA.bind(this), addrMode: this.REL.bind(this) },
154
+ { name: 'STA', cycles: 6, opcode: this.STA.bind(this), addrMode: this.IZX.bind(this) },
155
+ { name: '???', cycles: 2, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
156
+ { name: '???', cycles: 6, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
157
+ { name: 'STY', cycles: 3, opcode: this.STY.bind(this), addrMode: this.ZP0.bind(this) },
158
+ { name: 'STA', cycles: 3, opcode: this.STA.bind(this), addrMode: this.ZP0.bind(this) },
159
+ { name: 'STX', cycles: 3, opcode: this.STX.bind(this), addrMode: this.ZP0.bind(this) },
160
+ { name: 'SMB0', cycles: 5, opcode: this.SMB0.bind(this), addrMode: this.ZP0.bind(this) },
161
+ { name: 'DEY', cycles: 2, opcode: this.DEY.bind(this), addrMode: this.IMP.bind(this) },
162
+ { name: 'BIT', cycles: 2, opcode: this.BIT.bind(this), addrMode: this.IMM.bind(this) },
163
+ { name: 'TXA', cycles: 2, opcode: this.TXA.bind(this), addrMode: this.IMP.bind(this) },
164
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
165
+ { name: 'STY', cycles: 4, opcode: this.STY.bind(this), addrMode: this.ABS.bind(this) },
166
+ { name: 'STA', cycles: 4, opcode: this.STA.bind(this), addrMode: this.ABS.bind(this) },
167
+ { name: 'STX', cycles: 4, opcode: this.STX.bind(this), addrMode: this.ABS.bind(this) },
168
+ { name: 'BBS0', cycles: 5, opcode: this.BBS0.bind(this), addrMode: this.ZPR.bind(this) },
169
+ { name: 'BCC', cycles: 2, opcode: this.BCC.bind(this), addrMode: this.REL.bind(this) },
170
+ { name: 'STA', cycles: 6, opcode: this.STA.bind(this), addrMode: this.IZY.bind(this) },
171
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
172
+ { name: '???', cycles: 6, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
173
+ { name: 'STY', cycles: 4, opcode: this.STY.bind(this), addrMode: this.ZPX.bind(this) },
174
+ { name: 'STA', cycles: 4, opcode: this.STA.bind(this), addrMode: this.ZPX.bind(this) },
175
+ { name: 'STX', cycles: 4, opcode: this.STX.bind(this), addrMode: this.ZPY.bind(this) },
176
+ { name: 'SMB1', cycles: 5, opcode: this.SMB1.bind(this), addrMode: this.ZP0.bind(this) },
177
+ { name: 'TYA', cycles: 2, opcode: this.TYA.bind(this), addrMode: this.IMP.bind(this) },
178
+ { name: 'STA', cycles: 5, opcode: this.STA.bind(this), addrMode: this.ABY.bind(this) },
179
+ { name: 'TXS', cycles: 2, opcode: this.TXS.bind(this), addrMode: this.IMP.bind(this) },
180
+ { name: '???', cycles: 5, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
181
+ { name: 'STZ', cycles: 4, opcode: this.STZ.bind(this), addrMode: this.ABS.bind(this) },
182
+ { name: 'STA', cycles: 5, opcode: this.STA.bind(this), addrMode: this.ABX.bind(this) },
183
+ { name: 'STZ', cycles: 5, opcode: this.STZ.bind(this), addrMode: this.ABX.bind(this) },
184
+ { name: 'BBS1', cycles: 5, opcode: this.BBS1.bind(this), addrMode: this.ZPR.bind(this) },
185
+ { name: 'LDY', cycles: 2, opcode: this.LDY.bind(this), addrMode: this.IMM.bind(this) },
186
+ { name: 'LDA', cycles: 6, opcode: this.LDA.bind(this), addrMode: this.IZX.bind(this) },
187
+ { name: 'LDX', cycles: 2, opcode: this.LDX.bind(this), addrMode: this.IMM.bind(this) },
188
+ { name: '???', cycles: 6, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
189
+ { name: 'LDY', cycles: 3, opcode: this.LDY.bind(this), addrMode: this.ZP0.bind(this) },
190
+ { name: 'LDA', cycles: 3, opcode: this.LDA.bind(this), addrMode: this.ZP0.bind(this) },
191
+ { name: 'LDX', cycles: 3, opcode: this.LDX.bind(this), addrMode: this.ZP0.bind(this) },
192
+ { name: 'SMB2', cycles: 5, opcode: this.SMB2.bind(this), addrMode: this.ZP0.bind(this) },
193
+ { name: 'TAY', cycles: 2, opcode: this.TAY.bind(this), addrMode: this.IMP.bind(this) },
194
+ { name: 'LDA', cycles: 2, opcode: this.LDA.bind(this), addrMode: this.IMM.bind(this) },
195
+ { name: 'TAX', cycles: 2, opcode: this.TAX.bind(this), addrMode: this.IMP.bind(this) },
196
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
197
+ { name: 'LDY', cycles: 4, opcode: this.LDY.bind(this), addrMode: this.ABS.bind(this) },
198
+ { name: 'LDA', cycles: 4, opcode: this.LDA.bind(this), addrMode: this.ABS.bind(this) },
199
+ { name: 'LDX', cycles: 4, opcode: this.LDX.bind(this), addrMode: this.ABS.bind(this) },
200
+ { name: 'BBS2', cycles: 5, opcode: this.BBS2.bind(this), addrMode: this.ZPR.bind(this) },
201
+ { name: 'BCS', cycles: 2, opcode: this.BCS.bind(this), addrMode: this.REL.bind(this) },
202
+ { name: 'LDA', cycles: 5, opcode: this.LDA.bind(this), addrMode: this.IZY.bind(this) },
203
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
204
+ { name: '???', cycles: 5, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
205
+ { name: 'LDY', cycles: 4, opcode: this.LDY.bind(this), addrMode: this.ZPX.bind(this) },
206
+ { name: 'LDA', cycles: 4, opcode: this.LDA.bind(this), addrMode: this.ZPX.bind(this) },
207
+ { name: 'LDX', cycles: 4, opcode: this.LDX.bind(this), addrMode: this.ZPY.bind(this) },
208
+ { name: 'SMB3', cycles: 5, opcode: this.SMB3.bind(this), addrMode: this.ZP0.bind(this) },
209
+ { name: 'CLV', cycles: 2, opcode: this.CLV.bind(this), addrMode: this.IMP.bind(this) },
210
+ { name: 'LDA', cycles: 4, opcode: this.LDA.bind(this), addrMode: this.ABY.bind(this) },
211
+ { name: 'TSX', cycles: 2, opcode: this.TSX.bind(this), addrMode: this.IMP.bind(this) },
212
+ { name: '???', cycles: 4, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
213
+ { name: 'LDY', cycles: 4, opcode: this.LDY.bind(this), addrMode: this.ABX.bind(this) },
214
+ { name: 'LDA', cycles: 4, opcode: this.LDA.bind(this), addrMode: this.ABX.bind(this) },
215
+ { name: 'LDX', cycles: 4, opcode: this.LDX.bind(this), addrMode: this.ABY.bind(this) },
216
+ { name: 'BBS3', cycles: 5, opcode: this.BBS3.bind(this), addrMode: this.ZPR.bind(this) },
217
+ { name: 'CPY', cycles: 2, opcode: this.CPY.bind(this), addrMode: this.IMM.bind(this) },
218
+ { name: 'CMP', cycles: 6, opcode: this.CMP.bind(this), addrMode: this.IZX.bind(this) },
219
+ { name: '???', cycles: 2, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
220
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
221
+ { name: 'CPY', cycles: 3, opcode: this.CPY.bind(this), addrMode: this.ZP0.bind(this) },
222
+ { name: 'CMP', cycles: 3, opcode: this.CMP.bind(this), addrMode: this.ZP0.bind(this) },
223
+ { name: 'DEC', cycles: 5, opcode: this.DEC.bind(this), addrMode: this.ZP0.bind(this) },
224
+ { name: 'SMB4', cycles: 5, opcode: this.SMB4.bind(this), addrMode: this.ZP0.bind(this) },
225
+ { name: 'INY', cycles: 2, opcode: this.INY.bind(this), addrMode: this.IMP.bind(this) },
226
+ { name: 'CMP', cycles: 2, opcode: this.CMP.bind(this), addrMode: this.IMM.bind(this) },
227
+ { name: 'DEX', cycles: 2, opcode: this.DEX.bind(this), addrMode: this.IMP.bind(this) },
228
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
229
+ { name: 'CPY', cycles: 4, opcode: this.CPY.bind(this), addrMode: this.ABS.bind(this) },
230
+ { name: 'CMP', cycles: 4, opcode: this.CMP.bind(this), addrMode: this.ABS.bind(this) },
231
+ { name: 'DEC', cycles: 6, opcode: this.DEC.bind(this), addrMode: this.ABS.bind(this) },
232
+ { name: 'BBS4', cycles: 5, opcode: this.BBS4.bind(this), addrMode: this.ZPR.bind(this) },
233
+ { name: 'BNE', cycles: 2, opcode: this.BNE.bind(this), addrMode: this.REL.bind(this) },
234
+ { name: 'CMP', cycles: 5, opcode: this.CMP.bind(this), addrMode: this.IZY.bind(this) },
235
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
236
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
237
+ { name: '???', cycles: 4, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
238
+ { name: 'CMP', cycles: 4, opcode: this.CMP.bind(this), addrMode: this.ZPX.bind(this) },
239
+ { name: 'DEC', cycles: 6, opcode: this.DEC.bind(this), addrMode: this.ZPX.bind(this) },
240
+ { name: 'SMB5', cycles: 5, opcode: this.SMB5.bind(this), addrMode: this.ZP0.bind(this) },
241
+ { name: 'CLD', cycles: 2, opcode: this.CLD.bind(this), addrMode: this.IMP.bind(this) },
242
+ { name: 'CMP', cycles: 4, opcode: this.CMP.bind(this), addrMode: this.ABY.bind(this) },
243
+ { name: 'PHX', cycles: 3, opcode: this.PHX.bind(this), addrMode: this.IMP.bind(this) },
244
+ { name: 'STP', cycles: 3, opcode: this.STP.bind(this), addrMode: this.IMP.bind(this) },
245
+ { name: '???', cycles: 4, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
246
+ { name: 'CMP', cycles: 4, opcode: this.CMP.bind(this), addrMode: this.ABX.bind(this) },
247
+ { name: 'DEC', cycles: 7, opcode: this.DEC.bind(this), addrMode: this.ABX.bind(this) },
248
+ { name: '???', cycles: 7, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
249
+ { name: 'CPX', cycles: 2, opcode: this.CPX.bind(this), addrMode: this.IMM.bind(this) },
250
+ { name: 'SBC', cycles: 6, opcode: this.SBC.bind(this), addrMode: this.IZX.bind(this) },
251
+ { name: '???', cycles: 2, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
252
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
253
+ { name: 'CPX', cycles: 3, opcode: this.CPX.bind(this), addrMode: this.ZP0.bind(this) },
254
+ { name: 'SBC', cycles: 3, opcode: this.SBC.bind(this), addrMode: this.ZP0.bind(this) },
255
+ { name: 'INC', cycles: 5, opcode: this.INC.bind(this), addrMode: this.ZP0.bind(this) },
256
+ { name: 'SMB6', cycles: 5, opcode: this.SMB6.bind(this), addrMode: this.ZP0.bind(this) },
257
+ { name: 'INX', cycles: 2, opcode: this.INX.bind(this), addrMode: this.IMP.bind(this) },
258
+ { name: 'SBC', cycles: 2, opcode: this.SBC.bind(this), addrMode: this.IMM.bind(this) },
259
+ { name: 'NOP', cycles: 2, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
260
+ { name: 'WAI', cycles: 3, opcode: this.WAI.bind(this), addrMode: this.IMP.bind(this) },
261
+ { name: 'CPX', cycles: 4, opcode: this.CPX.bind(this), addrMode: this.ABS.bind(this) },
262
+ { name: 'SBC', cycles: 4, opcode: this.SBC.bind(this), addrMode: this.ABS.bind(this) },
263
+ { name: 'INC', cycles: 6, opcode: this.INC.bind(this), addrMode: this.ABS.bind(this) },
264
+ { name: 'BBS5', cycles: 5, opcode: this.BBS5.bind(this), addrMode: this.ZPR.bind(this) },
265
+ { name: 'BEQ', cycles: 2, opcode: this.BEQ.bind(this), addrMode: this.REL.bind(this) },
266
+ { name: 'SBC', cycles: 5, opcode: this.SBC.bind(this), addrMode: this.IZY.bind(this) },
267
+ { name: '???', cycles: 2, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
268
+ { name: '???', cycles: 8, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
269
+ { name: '???', cycles: 4, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
270
+ { name: 'SBC', cycles: 4, opcode: this.SBC.bind(this), addrMode: this.ZPX.bind(this) },
271
+ { name: 'INC', cycles: 6, opcode: this.INC.bind(this), addrMode: this.ZPX.bind(this) },
272
+ { name: 'SMB7', cycles: 5, opcode: this.SMB7.bind(this), addrMode: this.ZP0.bind(this) },
273
+ { name: 'SED', cycles: 2, opcode: this.SED.bind(this), addrMode: this.IMP.bind(this) },
274
+ { name: 'SBC', cycles: 4, opcode: this.SBC.bind(this), addrMode: this.ABY.bind(this) },
275
+ { name: 'PLX', cycles: 4, opcode: this.PLX.bind(this), addrMode: this.IMP.bind(this) },
276
+ { name: '???', cycles: 7, opcode: this.XXX.bind(this), addrMode: this.IMP.bind(this) },
277
+ { name: '???', cycles: 4, opcode: this.NOP.bind(this), addrMode: this.IMP.bind(this) },
278
+ { name: 'SBC', cycles: 4, opcode: this.SBC.bind(this), addrMode: this.ABX.bind(this) },
279
+ { name: 'INC', cycles: 7, opcode: this.INC.bind(this), addrMode: this.ABX.bind(this) },
280
+ { name: 'BBS7', cycles: 5, opcode: this.BBS7.bind(this), addrMode: this.ZPR.bind(this) }
281
+ ];
282
+ this.read = read;
283
+ this.write = write;
284
+ }
285
+ //
286
+ // Interface
287
+ //
288
+ reset() {
289
+ // Read the PC location from the Reset vector
290
+ const resetVector = 0xFFFC;
291
+ const lo = this.read(resetVector + 0);
292
+ const hi = this.read(resetVector + 1);
293
+ this.pc = (hi << 8) | lo;
294
+ // Clear the registers
295
+ this.a = 0x00;
296
+ this.x = 0x00;
297
+ this.y = 0x00;
298
+ this.sp = 0xFD;
299
+ this.st = 0x00 | CPU.U;
300
+ // Clear our helper variables
301
+ this.addrRel = 0x0000;
302
+ this.addrAbs = 0x0000;
303
+ this.fetched = 0x00;
304
+ // Reset takes 7 clock cycles
305
+ this.cyclesRem = 7;
306
+ this.cycles += 7;
307
+ }
308
+ irq() {
309
+ // Are interrupts enabled?
310
+ if (this.getFlag(CPU.I) == 0) {
311
+ // Push the program counter onto the stack
312
+ this.write(0x0100 + this.sp, (this.pc >> 8) & 0x00FF);
313
+ this.decSP();
314
+ this.write(0x0100 + this.sp, this.pc & 0x00FF);
315
+ this.decSP();
316
+ // Push the status register onto the stack
317
+ this.setFlag(CPU.B, false);
318
+ this.setFlag(CPU.I, true);
319
+ this.write(0x0100 + this.sp, this.st);
320
+ this.decSP();
321
+ // Read new PC location from IRQ vector
322
+ const irqVector = 0xFFFE;
323
+ const lo = this.read(irqVector + 0);
324
+ const hi = this.read(irqVector + 1);
325
+ this.pc = (hi << 8) | lo;
326
+ // IRQ takes 7 clock cycles
327
+ this.cyclesRem = 7;
328
+ this.cycles += 7;
329
+ }
330
+ }
331
+ nmi() {
332
+ // Push the program counter onto the stack
333
+ this.write(0x0100 + this.sp, (this.pc >> 8) & 0x00FF);
334
+ this.decSP();
335
+ this.write(0x0100 + this.sp, this.pc & 0x00FF);
336
+ this.decSP();
337
+ // Push the status register onto the stack
338
+ this.setFlag(CPU.B, false);
339
+ this.setFlag(CPU.I, true);
340
+ this.write(0x0100 + this.sp, this.st);
341
+ this.decSP();
342
+ // Read new PC location from NMI vector
343
+ const nmiVector = 0xFFFA;
344
+ const lo = this.read(nmiVector + 0);
345
+ const hi = this.read(nmiVector + 1);
346
+ this.pc = (hi << 8) | lo;
347
+ // NMI takes 7 clock cycles
348
+ this.cyclesRem = 7;
349
+ this.cycles += 7;
350
+ }
351
+ tick() {
352
+ if (this.cyclesRem == 0) {
353
+ // Perform one clock cycle
354
+ this.opcode = this.read(this.pc);
355
+ this.setFlag(CPU.U, true);
356
+ this.incPC();
357
+ const instruction = this.instructionTable[this.opcode];
358
+ this.cyclesRem = instruction.cycles;
359
+ this.cycles += instruction.cycles;
360
+ const addCycleAddrMode = instruction.addrMode();
361
+ const addCycleOpcode = instruction.opcode();
362
+ // addrMode() and opcode() return 1 or 0 if additional clock cycles are required
363
+ this.cyclesRem += addCycleAddrMode & addCycleOpcode;
364
+ this.cycles += addCycleAddrMode & addCycleOpcode;
365
+ }
366
+ this.cyclesRem--;
367
+ }
368
+ step() {
369
+ // Finish current instruction
370
+ if (this.cyclesRem > 0) {
371
+ do {
372
+ this.tick();
373
+ } while (this.cyclesRem > 0);
374
+ }
375
+ const startCycles = this.cycles;
376
+ // Execute one instruction
377
+ do {
378
+ this.tick();
379
+ } while (this.cyclesRem > 0);
380
+ return this.cycles - startCycles;
381
+ }
382
+ //
383
+ // Helpers
384
+ //
385
+ fetch() {
386
+ // For IMP addressing mode (opcode 0x0A, 0x2A, 0x4A, 0x6A), fetched is already set to this.a
387
+ // Don't fetch from memory for those instructions
388
+ const accumulatorOpcodes = [0x0A, 0x2A, 0x4A, 0x6A];
389
+ if (!accumulatorOpcodes.includes(this.opcode)) {
390
+ this.fetched = this.read(this.addrAbs);
391
+ }
392
+ }
393
+ getFlag(flag) {
394
+ return (this.st & flag) > 0 ? 1 : 0;
395
+ }
396
+ setFlag(flag, value) {
397
+ if (value) {
398
+ this.st |= flag;
399
+ }
400
+ else {
401
+ this.st &= ~flag;
402
+ }
403
+ }
404
+ incPC() {
405
+ if (this.pc == 0xFFFF) {
406
+ this.pc = 0x0000;
407
+ }
408
+ else {
409
+ this.pc++;
410
+ }
411
+ }
412
+ decPC() {
413
+ if (this.pc > 0x0000) {
414
+ this.pc--;
415
+ }
416
+ else {
417
+ this.pc = 0xFFFF;
418
+ }
419
+ }
420
+ incSP() {
421
+ if (this.sp == 0xFF) {
422
+ this.sp = 0x00;
423
+ }
424
+ else {
425
+ this.sp++;
426
+ }
427
+ }
428
+ decSP() {
429
+ if (this.sp > 0x00) {
430
+ this.sp--;
431
+ }
432
+ else {
433
+ this.sp = 0xFF;
434
+ }
435
+ }
436
+ //
437
+ // Addressing Modes
438
+ //
439
+ IMP() {
440
+ this.fetched = this.a;
441
+ return 0;
442
+ }
443
+ IMM() {
444
+ this.addrAbs = this.pc;
445
+ this.incPC();
446
+ return 0;
447
+ }
448
+ ZP0() {
449
+ this.addrAbs = this.read(this.pc);
450
+ this.incPC();
451
+ this.addrAbs &= 0x00FF;
452
+ return 0;
453
+ }
454
+ ZPX() {
455
+ this.addrAbs = this.read(this.pc) + this.x;
456
+ this.incPC();
457
+ this.addrAbs &= 0x00FF;
458
+ return 0;
459
+ }
460
+ ZPY() {
461
+ this.addrAbs = this.read(this.pc) + this.y;
462
+ this.incPC();
463
+ this.addrAbs &= 0x00FF;
464
+ return 0;
465
+ }
466
+ REL() {
467
+ this.addrRel = this.read(this.pc);
468
+ this.incPC();
469
+ if ((this.addrRel & 0x80) != 0) {
470
+ this.addrRel |= 0xFFFFFF00;
471
+ }
472
+ return 0;
473
+ }
474
+ ABS() {
475
+ const lo = this.read(this.pc);
476
+ this.incPC();
477
+ const hi = this.read(this.pc);
478
+ this.incPC();
479
+ this.addrAbs = (hi << 8) | lo;
480
+ return 0;
481
+ }
482
+ ABX() {
483
+ const lo = this.read(this.pc);
484
+ this.incPC();
485
+ const hi = this.read(this.pc);
486
+ this.incPC();
487
+ this.addrAbs = (hi << 8) | lo;
488
+ this.addrAbs += this.x;
489
+ if ((this.addrAbs & 0xFF00) != (hi << 8)) {
490
+ return 1;
491
+ }
492
+ else {
493
+ return 0;
494
+ }
495
+ }
496
+ ABY() {
497
+ const lo = this.read(this.pc);
498
+ this.incPC();
499
+ const hi = this.read(this.pc);
500
+ this.incPC();
501
+ this.addrAbs = (hi << 8) | lo;
502
+ this.addrAbs += this.y;
503
+ if ((this.addrAbs & 0xFF00) != (hi << 8)) {
504
+ return 1;
505
+ }
506
+ else {
507
+ return 0;
508
+ }
509
+ }
510
+ IND() {
511
+ const ptrLo = this.read(this.pc);
512
+ this.incPC();
513
+ const ptrHi = this.read(this.pc);
514
+ this.incPC();
515
+ const ptr = (ptrHi << 8) | ptrLo;
516
+ // 65C02 fixed the page boundary bug from the original 6502
517
+ this.addrAbs = (this.read(ptr + 1) << 8) | this.read(ptr);
518
+ return 0;
519
+ }
520
+ IZX() {
521
+ const t = this.read(this.pc);
522
+ this.incPC();
523
+ const lo = this.read((t + this.x) & 0x00FF);
524
+ const hi = this.read((t + this.x + 1) & 0x00FF);
525
+ this.addrAbs = (hi << 8) | lo;
526
+ return 0;
527
+ }
528
+ IZY() {
529
+ const t = this.read(this.pc);
530
+ this.incPC();
531
+ const lo = this.read((t) & 0x00FF);
532
+ const hi = this.read((t + 1) & 0x00FF);
533
+ this.addrAbs = (hi << 8) | lo;
534
+ this.addrAbs += this.y;
535
+ if ((this.addrAbs & 0xFF00) != (hi << 8)) {
536
+ return 1;
537
+ }
538
+ else {
539
+ return 0;
540
+ }
541
+ }
542
+ // IAX - Indexed Absolute Indirect - (a,x)
543
+ // Used by JMP (addr,X) on 65C02
544
+ IAX() {
545
+ const lo = this.read(this.pc);
546
+ this.incPC();
547
+ const hi = this.read(this.pc);
548
+ this.incPC();
549
+ const ptr = ((hi << 8) | lo) + this.x;
550
+ const addrLo = this.read(ptr);
551
+ const addrHi = this.read(ptr + 1);
552
+ this.addrAbs = (addrHi << 8) | addrLo;
553
+ return 0;
554
+ }
555
+ // ZPR - Zero Page + Relative
556
+ // Used by BBR/BBS instructions on WDC 65C02
557
+ ZPR() {
558
+ // First byte is zero page address
559
+ this.addrAbs = this.read(this.pc) & 0x00FF;
560
+ this.incPC();
561
+ // Second byte is relative offset for branch
562
+ const relAddr = this.read(this.pc);
563
+ this.incPC();
564
+ if (relAddr & 0x80) {
565
+ this.addrRel = relAddr | 0xFF00;
566
+ }
567
+ else {
568
+ this.addrRel = relAddr;
569
+ }
570
+ return 0;
571
+ }
572
+ //
573
+ // Opcodes
574
+ //
575
+ ADC() {
576
+ this.fetch();
577
+ this.temp = this.a + this.fetched + this.getFlag(CPU.C);
578
+ this.setFlag(CPU.C, (this.temp & 0xFF00) != 0);
579
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0);
580
+ this.setFlag(CPU.V, ((this.temp ^ this.a) & (this.temp ^ this.fetched) & 0x0080) != 0);
581
+ this.setFlag(CPU.N, (this.temp & 0x0080) != 0);
582
+ this.a = this.temp & 0x00FF;
583
+ return 1;
584
+ }
585
+ AND() {
586
+ this.fetch();
587
+ this.a &= this.fetched;
588
+ this.setFlag(CPU.Z, this.a == 0x00);
589
+ this.setFlag(CPU.N, (this.a & 0x80) != 0);
590
+ return 1;
591
+ }
592
+ ASL() {
593
+ this.fetch();
594
+ this.temp = this.fetched << 1;
595
+ this.setFlag(CPU.C, (this.temp & 0xFF00) > 0);
596
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0x00);
597
+ this.setFlag(CPU.N, (this.temp & 0x80) != 0);
598
+ // Opcode 0x0A is ASL A (accumulator mode)
599
+ if (this.opcode === 0x0A) {
600
+ this.a = this.temp & 0x00FF;
601
+ }
602
+ else {
603
+ this.write(this.addrAbs, this.temp & 0x00FF);
604
+ }
605
+ return 0;
606
+ }
607
+ BCC() {
608
+ if (this.getFlag(CPU.C) == 0) {
609
+ this.cycles++;
610
+ this.addrAbs = this.pc + this.addrRel;
611
+ if ((this.addrAbs & 0xFF00) != (this.pc & 0xFF00)) {
612
+ this.cycles++;
613
+ }
614
+ this.pc = this.addrAbs;
615
+ }
616
+ return 0;
617
+ }
618
+ BCS() {
619
+ if (this.getFlag(CPU.C) == 1) {
620
+ this.cycles++;
621
+ this.addrAbs = this.pc + this.addrRel;
622
+ if ((this.addrAbs & 0xFF00) != (this.pc & 0xFF00)) {
623
+ this.cycles++;
624
+ }
625
+ this.pc = this.addrAbs;
626
+ }
627
+ return 0;
628
+ }
629
+ BEQ() {
630
+ if (this.getFlag(CPU.Z) == 1) {
631
+ this.cycles++;
632
+ this.addrAbs = this.pc + this.addrRel;
633
+ if ((this.addrAbs & 0xFF00) != (this.pc & 0xFF00)) {
634
+ this.cycles++;
635
+ }
636
+ this.pc = this.addrAbs;
637
+ }
638
+ return 0;
639
+ }
640
+ BIT() {
641
+ this.fetch();
642
+ this.temp = this.a & this.fetched;
643
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0x00);
644
+ this.setFlag(CPU.N, (this.fetched & (1 << 7)) != 0);
645
+ this.setFlag(CPU.V, (this.fetched & (1 << 6)) != 0);
646
+ return 0;
647
+ }
648
+ BMI() {
649
+ if (this.getFlag(CPU.N) == 1) {
650
+ this.cycles++;
651
+ this.addrAbs = this.pc + this.addrRel;
652
+ if ((this.addrAbs & 0xFF00) != (this.pc & 0xFF00)) {
653
+ this.cycles++;
654
+ }
655
+ this.pc = this.addrAbs;
656
+ }
657
+ return 0;
658
+ }
659
+ BNE() {
660
+ if (this.getFlag(CPU.Z) == 0) {
661
+ this.cycles++;
662
+ this.addrAbs = this.pc + this.addrRel;
663
+ if ((this.addrAbs & 0xFF00) != (this.pc & 0xFF00)) {
664
+ this.cycles++;
665
+ }
666
+ this.pc = this.addrAbs;
667
+ }
668
+ return 0;
669
+ }
670
+ BPL() {
671
+ if (this.getFlag(CPU.N) == 0) {
672
+ this.cycles++;
673
+ this.addrAbs = this.pc + this.addrRel;
674
+ if ((this.addrAbs & 0xFF00) != (this.pc & 0xFF00)) {
675
+ this.cycles++;
676
+ }
677
+ this.pc = this.addrAbs;
678
+ }
679
+ return 0;
680
+ }
681
+ BRK() {
682
+ this.incPC();
683
+ this.setFlag(CPU.I, true);
684
+ this.write(0x0100 + this.sp, (this.pc >> 8) & 0x00FF);
685
+ this.decSP();
686
+ this.write(0x0100 + this.sp, this.pc & 0x00FF);
687
+ this.decSP();
688
+ this.setFlag(CPU.B, true);
689
+ this.write(0x0100 + this.sp, this.st);
690
+ this.decSP();
691
+ this.setFlag(CPU.B, false);
692
+ this.pc = this.read(0xFFFE) | this.read(0xFFFF) << 8;
693
+ return 0;
694
+ }
695
+ BVC() {
696
+ if (this.getFlag(CPU.V) == 0) {
697
+ this.cycles++;
698
+ this.addrAbs = this.pc + this.addrRel;
699
+ if ((this.addrAbs & 0xFF00) != (this.pc & 0xFF00)) {
700
+ this.cycles++;
701
+ }
702
+ this.pc = this.addrAbs;
703
+ }
704
+ return 0;
705
+ }
706
+ BVS() {
707
+ if (this.getFlag(CPU.V) == 1) {
708
+ this.cycles++;
709
+ this.addrAbs = this.pc + this.addrRel;
710
+ if ((this.addrAbs & 0xFF00) != (this.pc & 0xFF00)) {
711
+ this.cycles++;
712
+ }
713
+ this.pc = this.addrAbs;
714
+ }
715
+ return 0;
716
+ }
717
+ CLC() {
718
+ this.setFlag(CPU.C, false);
719
+ return 0;
720
+ }
721
+ CLD() {
722
+ this.setFlag(CPU.D, false);
723
+ return 0;
724
+ }
725
+ CLI() {
726
+ this.setFlag(CPU.I, false);
727
+ return 0;
728
+ }
729
+ CLV() {
730
+ this.setFlag(CPU.V, false);
731
+ return 0;
732
+ }
733
+ CMP() {
734
+ this.fetch();
735
+ this.temp = this.a - this.fetched;
736
+ this.setFlag(CPU.C, this.a >= this.fetched);
737
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0x0000);
738
+ this.setFlag(CPU.N, (this.temp & 0x0080) != 0);
739
+ return 1;
740
+ }
741
+ CPX() {
742
+ this.fetch();
743
+ this.temp = this.x - this.fetched;
744
+ this.setFlag(CPU.C, this.x >= this.fetched);
745
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0x0000);
746
+ this.setFlag(CPU.N, (this.temp & 0x0080) != 0);
747
+ return 0;
748
+ }
749
+ CPY() {
750
+ this.fetch();
751
+ this.temp = this.y - this.fetched;
752
+ this.setFlag(CPU.C, this.y >= this.fetched);
753
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0x0000);
754
+ this.setFlag(CPU.N, (this.temp & 0x0080) != 0);
755
+ return 0;
756
+ }
757
+ DEC() {
758
+ this.fetch();
759
+ this.temp = this.fetched - 0x01;
760
+ this.write(this.addrAbs, this.temp & 0x00FF);
761
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0x0000);
762
+ this.setFlag(CPU.N, (this.temp & 0x0080) != 0);
763
+ return 0;
764
+ }
765
+ DEX() {
766
+ this.x = (this.x - 1) & 0xFF;
767
+ this.setFlag(CPU.Z, this.x == 0x00);
768
+ this.setFlag(CPU.N, (this.x & 0x80) != 0);
769
+ return 0;
770
+ }
771
+ DEY() {
772
+ this.y = (this.y - 1) & 0xFF;
773
+ this.setFlag(CPU.Z, this.y == 0x00);
774
+ this.setFlag(CPU.N, (this.y & 0x80) != 0);
775
+ return 0;
776
+ }
777
+ EOR() {
778
+ this.fetch();
779
+ this.a ^= this.fetched;
780
+ this.setFlag(CPU.Z, this.a == 0x00);
781
+ this.setFlag(CPU.N, (this.a & 0x80) != 0);
782
+ return 1;
783
+ }
784
+ INC() {
785
+ this.fetch();
786
+ this.temp = this.fetched + 1;
787
+ this.write(this.addrAbs, this.temp & 0x00FF);
788
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0x0000);
789
+ this.setFlag(CPU.N, (this.temp & 0x0080) != 0);
790
+ return 0;
791
+ }
792
+ INX() {
793
+ this.x = (this.x + 1) & 0xFF;
794
+ this.setFlag(CPU.Z, this.x == 0x00);
795
+ this.setFlag(CPU.N, (this.x & 0x80) != 0);
796
+ return 0;
797
+ }
798
+ INY() {
799
+ this.y = (this.y + 1) & 0xFF;
800
+ this.setFlag(CPU.Z, this.y == 0x00);
801
+ this.setFlag(CPU.N, (this.y & 0x80) != 0);
802
+ return 0;
803
+ }
804
+ JMP() {
805
+ this.pc = this.addrAbs;
806
+ return 0;
807
+ }
808
+ JSR() {
809
+ this.decPC();
810
+ this.write(0x0100 + this.sp, (this.pc >> 8) & 0x00FF);
811
+ this.decSP();
812
+ this.write(0x0100 + this.sp, this.pc & 0x00FF);
813
+ this.decSP();
814
+ this.pc = this.addrAbs;
815
+ return 0;
816
+ }
817
+ LDA() {
818
+ this.fetch();
819
+ this.a = this.fetched;
820
+ this.setFlag(CPU.Z, this.a == 0x00);
821
+ this.setFlag(CPU.N, (this.a & 0x80) != 0);
822
+ return 1;
823
+ }
824
+ LDX() {
825
+ this.fetch();
826
+ this.x = this.fetched;
827
+ this.setFlag(CPU.Z, this.x == 0x00);
828
+ this.setFlag(CPU.N, (this.x & 0x80) != 0);
829
+ return 1;
830
+ }
831
+ LDY() {
832
+ this.fetch();
833
+ this.y = this.fetched;
834
+ this.setFlag(CPU.Z, this.y == 0x00);
835
+ this.setFlag(CPU.N, (this.y & 0x80) != 0);
836
+ return 1;
837
+ }
838
+ LSR() {
839
+ this.fetch();
840
+ this.setFlag(CPU.C, (this.fetched & 0x0001) != 0);
841
+ this.temp = this.fetched >> 1;
842
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0x0000);
843
+ this.setFlag(CPU.N, (this.temp & 0x0080) != 0);
844
+ // Opcode 0x4A is LSR A (accumulator mode)
845
+ if (this.opcode === 0x4A) {
846
+ this.a = this.temp & 0x00FF;
847
+ }
848
+ else {
849
+ this.write(this.addrAbs, this.temp & 0x00FF);
850
+ }
851
+ return 0;
852
+ }
853
+ NOP() {
854
+ switch (this.opcode) {
855
+ case 0x1C:
856
+ case 0x3C:
857
+ case 0x5C:
858
+ case 0x7C:
859
+ case 0xDC:
860
+ case 0xFC:
861
+ return 1;
862
+ }
863
+ return 0;
864
+ }
865
+ ORA() {
866
+ this.fetch();
867
+ this.a |= this.fetched;
868
+ this.setFlag(CPU.Z, this.a == 0x00);
869
+ this.setFlag(CPU.N, (this.a & 0x80) != 0);
870
+ return 1;
871
+ }
872
+ PHA() {
873
+ this.write(0x0100 + this.sp, this.a);
874
+ this.decSP();
875
+ return 0;
876
+ }
877
+ PHP() {
878
+ this.write(0x0100 + this.sp, this.st | CPU.B | CPU.U);
879
+ this.setFlag(CPU.B, false);
880
+ this.setFlag(CPU.U, false);
881
+ this.decSP();
882
+ return 0;
883
+ }
884
+ PLA() {
885
+ this.incSP();
886
+ this.a = this.read(0x0100 + this.sp);
887
+ this.setFlag(CPU.Z, this.a == 0x00);
888
+ this.setFlag(CPU.N, (this.a & 0x80) != 0);
889
+ return 0;
890
+ }
891
+ PLP() {
892
+ this.incSP();
893
+ this.st = this.read(0x0100 + this.sp);
894
+ this.setFlag(CPU.U, true);
895
+ return 0;
896
+ }
897
+ ROL() {
898
+ this.fetch();
899
+ this.temp = (this.fetched << 1) | this.getFlag(CPU.C);
900
+ this.setFlag(CPU.C, (this.temp & 0xFF00) != 0);
901
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0x00);
902
+ this.setFlag(CPU.N, (this.temp & 0x0080) != 0);
903
+ // Opcode 0x2A is ROL A (accumulator mode)
904
+ if (this.opcode === 0x2A) {
905
+ this.a = this.temp & 0x00FF;
906
+ }
907
+ else {
908
+ this.write(this.addrAbs, this.temp & 0x00FF);
909
+ }
910
+ return 0;
911
+ }
912
+ ROR() {
913
+ this.fetch();
914
+ this.temp = (this.getFlag(CPU.C) << 7) | (this.fetched >> 1);
915
+ this.setFlag(CPU.C, (this.fetched & 0x01) != 0);
916
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0x00);
917
+ this.setFlag(CPU.N, (this.temp & 0x0080) != 0);
918
+ // Opcode 0x6A is ROR A (accumulator mode)
919
+ if (this.opcode === 0x6A) {
920
+ this.a = this.temp & 0x00FF;
921
+ }
922
+ else {
923
+ this.write(this.addrAbs, this.temp & 0x00FF);
924
+ }
925
+ return 0;
926
+ }
927
+ RTI() {
928
+ this.incSP();
929
+ this.st = this.read(0x0100 + this.sp);
930
+ this.st &= ~CPU.B;
931
+ this.st &= ~CPU.U;
932
+ this.incSP();
933
+ this.pc = this.read(0x0100 + this.sp);
934
+ this.incSP();
935
+ this.pc |= this.read(0x0100 + this.sp) << 8;
936
+ return 0;
937
+ }
938
+ RTS() {
939
+ this.incSP();
940
+ this.pc = this.read(0x0100 + this.sp);
941
+ this.incSP();
942
+ this.pc |= this.read(0x0100 + this.sp) << 8;
943
+ this.incPC();
944
+ return 0;
945
+ }
946
+ SBC() {
947
+ this.fetch();
948
+ const value = this.fetched ^ 0x00FF;
949
+ this.temp = this.a + value + this.getFlag(CPU.C);
950
+ this.setFlag(CPU.C, (this.temp & 0xFF00) != 0);
951
+ this.setFlag(CPU.Z, (this.temp & 0x00FF) == 0);
952
+ this.setFlag(CPU.V, ((this.temp ^ this.a) & (this.temp ^ value) & 0x0080) != 0);
953
+ this.setFlag(CPU.N, (this.temp & 0x0080) != 0);
954
+ this.a = this.temp & 0x00FF;
955
+ return 1;
956
+ }
957
+ SEC() {
958
+ this.setFlag(CPU.C, true);
959
+ return 0;
960
+ }
961
+ SED() {
962
+ this.setFlag(CPU.D, true);
963
+ return 0;
964
+ }
965
+ SEI() {
966
+ this.setFlag(CPU.I, true);
967
+ return 0;
968
+ }
969
+ STA() {
970
+ this.write(this.addrAbs, this.a);
971
+ return 0;
972
+ }
973
+ STX() {
974
+ this.write(this.addrAbs, this.x);
975
+ return 0;
976
+ }
977
+ STY() {
978
+ this.write(this.addrAbs, this.y);
979
+ return 0;
980
+ }
981
+ TAX() {
982
+ this.x = this.a;
983
+ this.setFlag(CPU.Z, this.x == 0x00);
984
+ this.setFlag(CPU.N, (this.x & 0x80) != 0);
985
+ return 0;
986
+ }
987
+ TAY() {
988
+ this.y = this.a;
989
+ this.setFlag(CPU.Z, this.y == 0x00);
990
+ this.setFlag(CPU.N, (this.y & 0x80) != 0);
991
+ return 0;
992
+ }
993
+ TSX() {
994
+ this.x = this.sp;
995
+ this.setFlag(CPU.Z, this.x == 0x00);
996
+ this.setFlag(CPU.N, (this.x & 0x80) != 0);
997
+ return 0;
998
+ }
999
+ TXA() {
1000
+ this.a = this.x;
1001
+ this.setFlag(CPU.Z, this.a == 0x00);
1002
+ this.setFlag(CPU.N, (this.a & 0x80) != 0);
1003
+ return 0;
1004
+ }
1005
+ TXS() {
1006
+ this.sp = this.x;
1007
+ return 0;
1008
+ }
1009
+ TYA() {
1010
+ this.a = this.y;
1011
+ this.setFlag(CPU.Z, this.a == 0x00);
1012
+ this.setFlag(CPU.N, (this.a & 0x80) != 0);
1013
+ return 0;
1014
+ }
1015
+ //
1016
+ // 65C02 Instructions
1017
+ //
1018
+ BRA() {
1019
+ // Branch Always
1020
+ this.cyclesRem++;
1021
+ this.pc = (this.pc + this.addrRel) & 0xFFFF;
1022
+ if ((this.pc & 0xFF00) != ((this.pc - this.addrRel) & 0xFF00)) {
1023
+ this.cyclesRem++;
1024
+ }
1025
+ return 0;
1026
+ }
1027
+ PHX() {
1028
+ // Push X Register
1029
+ this.write(0x0100 + this.sp, this.x);
1030
+ this.decSP();
1031
+ return 0;
1032
+ }
1033
+ PHY() {
1034
+ // Push Y Register
1035
+ this.write(0x0100 + this.sp, this.y);
1036
+ this.decSP();
1037
+ return 0;
1038
+ }
1039
+ PLX() {
1040
+ // Pull X Register
1041
+ this.incSP();
1042
+ this.x = this.read(0x0100 + this.sp);
1043
+ this.setFlag(CPU.Z, this.x == 0x00);
1044
+ this.setFlag(CPU.N, (this.x & 0x80) != 0);
1045
+ return 0;
1046
+ }
1047
+ PLY() {
1048
+ // Pull Y Register
1049
+ this.incSP();
1050
+ this.y = this.read(0x0100 + this.sp);
1051
+ this.setFlag(CPU.Z, this.y == 0x00);
1052
+ this.setFlag(CPU.N, (this.y & 0x80) != 0);
1053
+ return 0;
1054
+ }
1055
+ STZ() {
1056
+ // Store Zero
1057
+ this.write(this.addrAbs, 0x00);
1058
+ return 0;
1059
+ }
1060
+ TRB() {
1061
+ // Test and Reset Bits
1062
+ this.fetch();
1063
+ this.setFlag(CPU.Z, (this.a & this.fetched) == 0x00);
1064
+ this.write(this.addrAbs, this.fetched & ~this.a);
1065
+ return 0;
1066
+ }
1067
+ TSB() {
1068
+ // Test and Set Bits
1069
+ this.fetch();
1070
+ this.setFlag(CPU.Z, (this.a & this.fetched) == 0x00);
1071
+ this.write(this.addrAbs, this.fetched | this.a);
1072
+ return 0;
1073
+ }
1074
+ //
1075
+ // WDC 65C02 Instructions
1076
+ //
1077
+ STP() {
1078
+ // Stop the processor
1079
+ // Implementation: halt execution by preventing PC increment
1080
+ // The processor would need to be reset to continue
1081
+ this.cyclesRem = 0xFF; // Set a large cycle count to effectively halt
1082
+ return 0;
1083
+ }
1084
+ WAI() {
1085
+ // Wait for Interrupt
1086
+ // Implementation: stall until an interrupt occurs
1087
+ // For simplicity, we'll just add cycles
1088
+ this.cyclesRem = 0xFF; // Wait state
1089
+ return 0;
1090
+ }
1091
+ BBR(bit) {
1092
+ // Branch on Bit Reset
1093
+ this.fetch();
1094
+ if ((this.fetched & (1 << bit)) == 0) {
1095
+ this.cyclesRem++;
1096
+ this.pc = (this.pc + this.addrRel) & 0xFFFF;
1097
+ if ((this.pc & 0xFF00) != ((this.pc - this.addrRel) & 0xFF00)) {
1098
+ this.cyclesRem++;
1099
+ }
1100
+ }
1101
+ return 0;
1102
+ }
1103
+ BBR0() { return this.BBR(0); }
1104
+ BBR1() { return this.BBR(1); }
1105
+ BBR2() { return this.BBR(2); }
1106
+ BBR3() { return this.BBR(3); }
1107
+ BBR4() { return this.BBR(4); }
1108
+ BBR5() { return this.BBR(5); }
1109
+ BBR6() { return this.BBR(6); }
1110
+ BBR7() { return this.BBR(7); }
1111
+ BBS(bit) {
1112
+ // Branch on Bit Set
1113
+ this.fetch();
1114
+ if ((this.fetched & (1 << bit)) != 0) {
1115
+ this.cyclesRem++;
1116
+ this.pc = (this.pc + this.addrRel) & 0xFFFF;
1117
+ if ((this.pc & 0xFF00) != ((this.pc - this.addrRel) & 0xFF00)) {
1118
+ this.cyclesRem++;
1119
+ }
1120
+ }
1121
+ return 0;
1122
+ }
1123
+ BBS0() { return this.BBS(0); }
1124
+ BBS1() { return this.BBS(1); }
1125
+ BBS2() { return this.BBS(2); }
1126
+ BBS3() { return this.BBS(3); }
1127
+ BBS4() { return this.BBS(4); }
1128
+ BBS5() { return this.BBS(5); }
1129
+ BBS6() { return this.BBS(6); }
1130
+ BBS7() { return this.BBS(7); }
1131
+ RMB(bit) {
1132
+ // Reset Memory Bit
1133
+ this.fetch();
1134
+ this.write(this.addrAbs, this.fetched & ~(1 << bit));
1135
+ return 0;
1136
+ }
1137
+ RMB0() { return this.RMB(0); }
1138
+ RMB1() { return this.RMB(1); }
1139
+ RMB2() { return this.RMB(2); }
1140
+ RMB3() { return this.RMB(3); }
1141
+ RMB4() { return this.RMB(4); }
1142
+ RMB5() { return this.RMB(5); }
1143
+ RMB6() { return this.RMB(6); }
1144
+ RMB7() { return this.RMB(7); }
1145
+ SMB(bit) {
1146
+ // Set Memory Bit
1147
+ this.fetch();
1148
+ this.write(this.addrAbs, this.fetched | (1 << bit));
1149
+ return 0;
1150
+ }
1151
+ SMB0() { return this.SMB(0); }
1152
+ SMB1() { return this.SMB(1); }
1153
+ SMB2() { return this.SMB(2); }
1154
+ SMB3() { return this.SMB(3); }
1155
+ SMB4() { return this.SMB(4); }
1156
+ SMB5() { return this.SMB(5); }
1157
+ SMB6() { return this.SMB(6); }
1158
+ SMB7() { return this.SMB(7); }
1159
+ XXX() { return 0; }
1160
+ }
1161
+ exports.CPU = CPU;
1162
+ CPU.C = 0b00000001;
1163
+ CPU.Z = 0b00000010;
1164
+ CPU.I = 0b00000100;
1165
+ CPU.D = 0b00001000;
1166
+ CPU.B = 0b00010000;
1167
+ CPU.U = 0b00100000;
1168
+ CPU.V = 0b01000000;
1169
+ CPU.N = 0b10000000;
1170
+ //# sourceMappingURL=CPU.js.map