rp2040js 0.17.17 → 0.18.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 (182) hide show
  1. package/dist/cjs/clock/clock.d.ts +11 -11
  2. package/dist/cjs/clock/clock.js +2 -2
  3. package/dist/cjs/clock/mock-clock.d.ts +17 -17
  4. package/dist/cjs/clock/mock-clock.js +52 -52
  5. package/dist/cjs/clock/realtime-clock.d.ts +23 -23
  6. package/dist/cjs/clock/realtime-clock.js +73 -73
  7. package/dist/cjs/cortex-m0-core.d.ts +87 -87
  8. package/dist/cjs/cortex-m0-core.js +1251 -1251
  9. package/dist/cjs/gdb/gdb-connection.d.ts +11 -11
  10. package/dist/cjs/gdb/gdb-connection.js +57 -57
  11. package/dist/cjs/gdb/gdb-server.d.ts +23 -23
  12. package/dist/cjs/gdb/gdb-server.js +232 -232
  13. package/dist/cjs/gdb/gdb-tcp-server.d.ts +10 -10
  14. package/dist/cjs/gdb/gdb-tcp-server.js +34 -34
  15. package/dist/cjs/gdb/gdb-utils.d.ts +9 -9
  16. package/dist/cjs/gdb/gdb-utils.js +48 -48
  17. package/dist/cjs/gpio-pin.d.ts +56 -56
  18. package/dist/cjs/gpio-pin.js +216 -216
  19. package/dist/cjs/index.d.ts +11 -11
  20. package/dist/cjs/index.js +36 -36
  21. package/dist/cjs/interpolator.d.ts +36 -36
  22. package/dist/cjs/interpolator.js +150 -150
  23. package/dist/cjs/irq.d.ts +29 -29
  24. package/dist/cjs/irq.js +33 -33
  25. package/dist/cjs/peripherals/adc.d.ts +52 -52
  26. package/dist/cjs/peripherals/adc.js +261 -261
  27. package/dist/cjs/peripherals/busctrl.d.ts +10 -10
  28. package/dist/cjs/peripherals/busctrl.js +84 -84
  29. package/dist/cjs/peripherals/clocks.d.ts +9 -9
  30. package/dist/cjs/peripherals/clocks.js +42 -42
  31. package/dist/cjs/peripherals/dma.d.ts +109 -109
  32. package/dist/cjs/peripherals/dma.js +520 -520
  33. package/dist/cjs/peripherals/i2c.d.ts +54 -54
  34. package/dist/cjs/peripherals/i2c.js +458 -458
  35. package/dist/cjs/peripherals/io.d.ts +11 -11
  36. package/dist/cjs/peripherals/io.js +100 -100
  37. package/dist/cjs/peripherals/pads.d.ts +13 -13
  38. package/dist/cjs/peripherals/pads.js +58 -58
  39. package/dist/cjs/peripherals/peripheral.d.ts +22 -22
  40. package/dist/cjs/peripherals/peripheral.js +61 -61
  41. package/dist/cjs/peripherals/pio.d.ts +120 -120
  42. package/dist/cjs/peripherals/pio.js +1086 -1086
  43. package/dist/cjs/peripherals/ppb.d.ts +25 -25
  44. package/dist/cjs/peripherals/ppb.js +229 -229
  45. package/dist/cjs/peripherals/pwm.d.ts +65 -65
  46. package/dist/cjs/peripherals/pwm.js +372 -372
  47. package/dist/cjs/peripherals/reset.d.ts +8 -8
  48. package/dist/cjs/peripherals/reset.js +40 -40
  49. package/dist/cjs/peripherals/rtc.d.ts +10 -10
  50. package/dist/cjs/peripherals/rtc.js +74 -74
  51. package/dist/cjs/peripherals/spi.d.ts +38 -38
  52. package/dist/cjs/peripherals/spi.js +240 -240
  53. package/dist/cjs/peripherals/ssi.d.ts +6 -6
  54. package/dist/cjs/peripherals/ssi.js +43 -43
  55. package/dist/cjs/peripherals/syscfg.d.ts +5 -5
  56. package/dist/cjs/peripherals/syscfg.js +26 -26
  57. package/dist/cjs/peripherals/sysinfo.d.ts +4 -4
  58. package/dist/cjs/peripherals/sysinfo.js +22 -22
  59. package/dist/cjs/peripherals/tbman.d.ts +4 -4
  60. package/dist/cjs/peripherals/tbman.js +17 -17
  61. package/dist/cjs/peripherals/timer.d.ts +18 -18
  62. package/dist/cjs/peripherals/timer.js +156 -156
  63. package/dist/cjs/peripherals/uart.d.ts +31 -31
  64. package/dist/cjs/peripherals/uart.js +132 -132
  65. package/dist/cjs/peripherals/usb.d.ts +29 -29
  66. package/dist/cjs/peripherals/usb.js +309 -309
  67. package/dist/cjs/rp2040.d.ts +71 -71
  68. package/dist/cjs/rp2040.js +361 -361
  69. package/dist/cjs/sio.d.ts +21 -21
  70. package/dist/cjs/sio.js +425 -425
  71. package/dist/cjs/usb/cdc.d.ts +20 -20
  72. package/dist/cjs/usb/cdc.js +126 -126
  73. package/dist/cjs/usb/interfaces.d.ts +47 -47
  74. package/dist/cjs/usb/interfaces.js +46 -46
  75. package/dist/cjs/usb/setup.d.ts +5 -5
  76. package/dist/cjs/usb/setup.js +53 -53
  77. package/dist/cjs/utils/assembler.d.ts +79 -79
  78. package/dist/cjs/utils/assembler.js +328 -328
  79. package/dist/cjs/utils/bit.d.ts +3 -3
  80. package/dist/cjs/utils/bit.js +15 -15
  81. package/dist/cjs/utils/fifo.d.ts +15 -15
  82. package/dist/cjs/utils/fifo.js +56 -56
  83. package/dist/cjs/utils/logging.d.ts +23 -23
  84. package/dist/cjs/utils/logging.js +48 -48
  85. package/dist/cjs/utils/pio-assembler.d.ts +45 -45
  86. package/dist/cjs/utils/pio-assembler.js +87 -87
  87. package/dist/cjs/utils/time.d.ts +2 -2
  88. package/dist/cjs/utils/time.js +32 -32
  89. package/dist/cjs/utils/timer32.d.ts +57 -57
  90. package/dist/cjs/utils/timer32.js +208 -208
  91. package/dist/esm/clock/clock.d.ts +11 -11
  92. package/dist/esm/clock/clock.js +1 -1
  93. package/dist/esm/clock/mock-clock.d.ts +17 -17
  94. package/dist/esm/clock/mock-clock.js +47 -47
  95. package/dist/esm/clock/realtime-clock.d.ts +23 -23
  96. package/dist/esm/clock/realtime-clock.js +68 -68
  97. package/dist/esm/cortex-m0-core.d.ts +87 -87
  98. package/dist/esm/cortex-m0-core.js +1247 -1247
  99. package/dist/esm/gdb/gdb-connection.d.ts +11 -11
  100. package/dist/esm/gdb/gdb-connection.js +53 -53
  101. package/dist/esm/gdb/gdb-server.d.ts +23 -23
  102. package/dist/esm/gdb/gdb-server.js +228 -228
  103. package/dist/esm/gdb/gdb-tcp-server.d.ts +10 -10
  104. package/dist/esm/gdb/gdb-tcp-server.js +30 -30
  105. package/dist/esm/gdb/gdb-utils.d.ts +9 -9
  106. package/dist/esm/gdb/gdb-utils.js +36 -36
  107. package/dist/esm/gpio-pin.d.ts +56 -56
  108. package/dist/esm/gpio-pin.js +212 -212
  109. package/dist/esm/index.d.ts +11 -11
  110. package/dist/esm/index.js +11 -11
  111. package/dist/esm/interpolator.d.ts +36 -36
  112. package/dist/esm/interpolator.js +145 -145
  113. package/dist/esm/irq.d.ts +29 -29
  114. package/dist/esm/irq.js +30 -30
  115. package/dist/esm/peripherals/adc.d.ts +52 -52
  116. package/dist/esm/peripherals/adc.js +257 -257
  117. package/dist/esm/peripherals/busctrl.d.ts +10 -10
  118. package/dist/esm/peripherals/busctrl.js +80 -80
  119. package/dist/esm/peripherals/clocks.d.ts +9 -9
  120. package/dist/esm/peripherals/clocks.js +38 -38
  121. package/dist/esm/peripherals/dma.d.ts +109 -109
  122. package/dist/esm/peripherals/dma.js +515 -515
  123. package/dist/esm/peripherals/i2c.d.ts +54 -54
  124. package/dist/esm/peripherals/i2c.js +454 -454
  125. package/dist/esm/peripherals/io.d.ts +11 -11
  126. package/dist/esm/peripherals/io.js +96 -96
  127. package/dist/esm/peripherals/pads.d.ts +13 -13
  128. package/dist/esm/peripherals/pads.js +54 -54
  129. package/dist/esm/peripherals/peripheral.d.ts +22 -22
  130. package/dist/esm/peripherals/peripheral.js +55 -55
  131. package/dist/esm/peripherals/pio.d.ts +120 -120
  132. package/dist/esm/peripherals/pio.js +1081 -1081
  133. package/dist/esm/peripherals/ppb.d.ts +25 -25
  134. package/dist/esm/peripherals/ppb.js +225 -225
  135. package/dist/esm/peripherals/pwm.d.ts +65 -65
  136. package/dist/esm/peripherals/pwm.js +368 -368
  137. package/dist/esm/peripherals/reset.d.ts +8 -8
  138. package/dist/esm/peripherals/reset.js +36 -36
  139. package/dist/esm/peripherals/rtc.d.ts +10 -10
  140. package/dist/esm/peripherals/rtc.js +70 -70
  141. package/dist/esm/peripherals/spi.d.ts +38 -38
  142. package/dist/esm/peripherals/spi.js +236 -236
  143. package/dist/esm/peripherals/ssi.d.ts +6 -6
  144. package/dist/esm/peripherals/ssi.js +39 -39
  145. package/dist/esm/peripherals/syscfg.d.ts +5 -5
  146. package/dist/esm/peripherals/syscfg.js +22 -22
  147. package/dist/esm/peripherals/sysinfo.d.ts +4 -4
  148. package/dist/esm/peripherals/sysinfo.js +18 -18
  149. package/dist/esm/peripherals/tbman.d.ts +4 -4
  150. package/dist/esm/peripherals/tbman.js +13 -13
  151. package/dist/esm/peripherals/timer.d.ts +18 -18
  152. package/dist/esm/peripherals/timer.js +152 -152
  153. package/dist/esm/peripherals/uart.d.ts +31 -31
  154. package/dist/esm/peripherals/uart.js +128 -128
  155. package/dist/esm/peripherals/usb.d.ts +29 -29
  156. package/dist/esm/peripherals/usb.js +305 -305
  157. package/dist/esm/rp2040.d.ts +71 -71
  158. package/dist/esm/rp2040.js +357 -357
  159. package/dist/esm/sio.d.ts +21 -21
  160. package/dist/esm/sio.js +421 -421
  161. package/dist/esm/usb/cdc.d.ts +20 -20
  162. package/dist/esm/usb/cdc.js +121 -121
  163. package/dist/esm/usb/interfaces.d.ts +47 -47
  164. package/dist/esm/usb/interfaces.js +43 -43
  165. package/dist/esm/usb/setup.d.ts +5 -5
  166. package/dist/esm/usb/setup.js +46 -46
  167. package/dist/esm/utils/assembler.d.ts +79 -79
  168. package/dist/esm/utils/assembler.js +245 -245
  169. package/dist/esm/utils/bit.d.ts +3 -3
  170. package/dist/esm/utils/bit.js +9 -9
  171. package/dist/esm/utils/fifo.d.ts +15 -15
  172. package/dist/esm/utils/fifo.js +52 -52
  173. package/dist/esm/utils/logging.d.ts +23 -23
  174. package/dist/esm/utils/logging.js +44 -44
  175. package/dist/esm/utils/pio-assembler.d.ts +45 -45
  176. package/dist/esm/utils/pio-assembler.js +75 -75
  177. package/dist/esm/utils/time.d.ts +2 -2
  178. package/dist/esm/utils/time.js +27 -27
  179. package/dist/esm/utils/timer32.d.ts +57 -57
  180. package/dist/esm/utils/timer32.js +203 -203
  181. package/package.json +33 -22
  182. package/dist/esm/package.json +0 -1
@@ -1,1251 +1,1251 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CortexM0Core = exports.SYSM_CONTROL = exports.SYSM_PRIMASK = exports.SYSM_PSP = exports.SYSM_MSP = void 0;
4
- const irq_1 = require("./irq");
5
- const rp2040_1 = require("./rp2040");
6
- /* eslint-disable @typescript-eslint/no-unused-vars */
7
- const EXC_RESET = 1;
8
- const EXC_NMI = 2;
9
- const EXC_HARDFAULT = 3;
10
- const EXC_SVCALL = 11;
11
- const EXC_PENDSV = 14;
12
- const EXC_SYSTICK = 15;
13
- const SYSM_APSR = 0;
14
- const SYSM_IAPSR = 1;
15
- const SYSM_EAPSR = 2;
16
- const SYSM_XPSR = 3;
17
- const SYSM_IPSR = 5;
18
- const SYSM_EPSR = 6;
19
- const SYSM_IEPSR = 7;
20
- exports.SYSM_MSP = 8;
21
- exports.SYSM_PSP = 9;
22
- exports.SYSM_PRIMASK = 16;
23
- exports.SYSM_CONTROL = 20;
24
- /* eslint-enable @typescript-eslint/no-unused-vars */
25
- // Lowest possible exception priority
26
- const LOWEST_PRIORITY = 4;
27
- var ExecutionMode;
28
- (function (ExecutionMode) {
29
- ExecutionMode[ExecutionMode["Mode_Thread"] = 0] = "Mode_Thread";
30
- ExecutionMode[ExecutionMode["Mode_Handler"] = 1] = "Mode_Handler";
31
- })(ExecutionMode || (ExecutionMode = {}));
32
- function signExtend8(value) {
33
- return (value << 24) >> 24;
34
- }
35
- function signExtend16(value) {
36
- return (value << 16) >> 16;
37
- }
38
- const spRegister = 13;
39
- const pcRegister = 15;
40
- var StackPointerBank;
41
- (function (StackPointerBank) {
42
- StackPointerBank[StackPointerBank["SPmain"] = 0] = "SPmain";
43
- StackPointerBank[StackPointerBank["SPprocess"] = 1] = "SPprocess";
44
- })(StackPointerBank || (StackPointerBank = {}));
45
- const LOG_NAME = 'CortexM0Core';
46
- class CortexM0Core {
47
- constructor(rp2040) {
48
- this.rp2040 = rp2040;
49
- this.registers = new Uint32Array(16);
50
- this.bankedSP = 0;
51
- this.cycles = 0;
52
- this.eventRegistered = false;
53
- this.waiting = false;
54
- // APSR fields
55
- this.N = false;
56
- this.C = false;
57
- this.Z = false;
58
- this.V = false;
59
- // How many bytes to rewind the last break instruction
60
- this.breakRewind = 0;
61
- // PRIMASK fields
62
- this.PM = false;
63
- // CONTROL fields
64
- this.SPSEL = StackPointerBank.SPmain;
65
- this.nPRIV = false;
66
- this.currentMode = ExecutionMode.Mode_Thread;
67
- this.IPSR = 0;
68
- this.interruptNMIMask = 0;
69
- this.pendingInterrupts = 0;
70
- this.enabledInterrupts = 0;
71
- this.interruptPriorities = [0xffffffff, 0x0, 0x0, 0x0];
72
- this.pendingNMI = false;
73
- this.pendingPendSV = false;
74
- this.pendingSVCall = false;
75
- this.pendingSystick = false;
76
- this.interruptsUpdated = false;
77
- this.VTOR = 0;
78
- this.SHPR2 = 0;
79
- this.SHPR3 = 0;
80
- /** Hook to listen for function calls - branch-link (BL/BLX) instructions */
81
- this.blTaken = (core, blx) => {
82
- void core; // surpress unused variable warnings
83
- void blx;
84
- };
85
- this.SP = 0xfffffffc;
86
- this.bankedSP = 0xfffffffc;
87
- }
88
- get logger() {
89
- return this.rp2040.logger;
90
- }
91
- reset() {
92
- this.SP = this.rp2040.readUint32(this.VTOR);
93
- this.PC = this.rp2040.readUint32(this.VTOR + 4) & 0xfffffffe;
94
- this.cycles = 0;
95
- }
96
- get SP() {
97
- return this.registers[13];
98
- }
99
- set SP(value) {
100
- this.registers[13] = value & ~0x3;
101
- }
102
- get LR() {
103
- return this.registers[14];
104
- }
105
- set LR(value) {
106
- this.registers[14] = value;
107
- }
108
- get PC() {
109
- return this.registers[15];
110
- }
111
- set PC(value) {
112
- this.registers[15] = value;
113
- }
114
- get APSR() {
115
- return ((this.N ? 0x80000000 : 0) |
116
- (this.Z ? 0x40000000 : 0) |
117
- (this.C ? 0x20000000 : 0) |
118
- (this.V ? 0x10000000 : 0));
119
- }
120
- set APSR(value) {
121
- this.N = !!(value & 0x80000000);
122
- this.Z = !!(value & 0x40000000);
123
- this.C = !!(value & 0x20000000);
124
- this.V = !!(value & 0x10000000);
125
- }
126
- get xPSR() {
127
- return this.APSR | this.IPSR | (1 << 24);
128
- }
129
- set xPSR(value) {
130
- this.APSR = value;
131
- this.IPSR = value & 0x3f;
132
- }
133
- checkCondition(cond) {
134
- // Evaluate base condition.
135
- let result = false;
136
- switch (cond >> 1) {
137
- case 0b000:
138
- result = this.Z;
139
- break;
140
- case 0b001:
141
- result = this.C;
142
- break;
143
- case 0b010:
144
- result = this.N;
145
- break;
146
- case 0b011:
147
- result = this.V;
148
- break;
149
- case 0b100:
150
- result = this.C && !this.Z;
151
- break;
152
- case 0b101:
153
- result = this.N === this.V;
154
- break;
155
- case 0b110:
156
- result = this.N === this.V && !this.Z;
157
- break;
158
- case 0b111:
159
- result = true;
160
- break;
161
- }
162
- return cond & 0b1 && cond != 0b1111 ? !result : result;
163
- }
164
- readUint32(address) {
165
- return this.rp2040.readUint32(address);
166
- }
167
- readUint16(address) {
168
- return this.rp2040.readUint16(address);
169
- }
170
- readUint8(address) {
171
- return this.rp2040.readUint8(address);
172
- }
173
- writeUint32(address, value) {
174
- this.rp2040.writeUint32(address, value);
175
- }
176
- writeUint16(address, value) {
177
- this.rp2040.writeUint16(address, value);
178
- }
179
- writeUint8(address, value) {
180
- this.rp2040.writeUint8(address, value);
181
- }
182
- switchStack(stack) {
183
- if (this.SPSEL !== stack) {
184
- const temp = this.SP;
185
- this.SP = this.bankedSP;
186
- this.bankedSP = temp;
187
- this.SPSEL = stack;
188
- }
189
- }
190
- get SPprocess() {
191
- return this.SPSEL === StackPointerBank.SPprocess ? this.SP : this.bankedSP;
192
- }
193
- set SPprocess(value) {
194
- if (this.SPSEL === StackPointerBank.SPprocess) {
195
- this.SP = value;
196
- }
197
- else {
198
- this.bankedSP = value >>> 0;
199
- }
200
- }
201
- get SPmain() {
202
- return this.SPSEL === StackPointerBank.SPmain ? this.SP : this.bankedSP;
203
- }
204
- set SPmain(value) {
205
- if (this.SPSEL === StackPointerBank.SPmain) {
206
- this.SP = value;
207
- }
208
- else {
209
- this.bankedSP = value >>> 0;
210
- }
211
- }
212
- exceptionEntry(exceptionNumber) {
213
- // PushStack:
214
- let framePtr = 0;
215
- let framePtrAlign = 0;
216
- if (this.SPSEL && this.currentMode === ExecutionMode.Mode_Thread) {
217
- framePtrAlign = this.SPprocess & 0b100 ? 1 : 0;
218
- this.SPprocess = (this.SPprocess - 0x20) & ~0b100;
219
- framePtr = this.SPprocess;
220
- }
221
- else {
222
- framePtrAlign = this.SPmain & 0b100 ? 1 : 0;
223
- this.SPmain = (this.SPmain - 0x20) & ~0b100;
224
- framePtr = this.SPmain;
225
- }
226
- /* only the stack locations, not the store order, are architected */
227
- this.writeUint32(framePtr, this.registers[0]);
228
- this.writeUint32(framePtr + 0x4, this.registers[1]);
229
- this.writeUint32(framePtr + 0x8, this.registers[2]);
230
- this.writeUint32(framePtr + 0xc, this.registers[3]);
231
- this.writeUint32(framePtr + 0x10, this.registers[12]);
232
- this.writeUint32(framePtr + 0x14, this.LR);
233
- this.writeUint32(framePtr + 0x18, this.PC & ~1); // ReturnAddress(ExceptionType);
234
- this.writeUint32(framePtr + 0x1c, (this.xPSR & ~(1 << 9)) | (framePtrAlign << 9));
235
- if (this.currentMode == ExecutionMode.Mode_Handler) {
236
- this.LR = 0xfffffff1;
237
- }
238
- else {
239
- if (!this.SPSEL) {
240
- this.LR = 0xfffffff9;
241
- }
242
- else {
243
- this.LR = 0xfffffffd;
244
- }
245
- }
246
- // ExceptionTaken:
247
- this.currentMode = ExecutionMode.Mode_Handler; // Enter Handler Mode, now Privileged
248
- this.IPSR = exceptionNumber;
249
- this.switchStack(StackPointerBank.SPmain);
250
- this.eventRegistered = true;
251
- const vectorTable = this.VTOR;
252
- this.PC = this.readUint32(vectorTable + 4 * exceptionNumber);
253
- }
254
- exceptionReturn(excReturn) {
255
- let framePtr = this.SPmain;
256
- switch (excReturn & 0xf) {
257
- case 0b0001: // Return to Handler
258
- this.currentMode = ExecutionMode.Mode_Handler;
259
- this.switchStack(StackPointerBank.SPmain);
260
- break;
261
- case 0b1001: // Return to Thread using Main stack
262
- this.currentMode = ExecutionMode.Mode_Thread;
263
- this.switchStack(StackPointerBank.SPmain);
264
- break;
265
- case 0b1101: // Return to Thread using Process stack
266
- framePtr = this.SPprocess;
267
- this.currentMode = ExecutionMode.Mode_Thread;
268
- this.switchStack(StackPointerBank.SPprocess);
269
- break;
270
- // Assigning CurrentMode to Mode_Thread causes a drop in privilege
271
- // if CONTROL.nPRIV is set to 1
272
- }
273
- // PopStack:
274
- this.registers[0] = this.readUint32(framePtr); // Stack accesses are performed as Unprivileged accesses if
275
- this.registers[1] = this.readUint32(framePtr + 0x4); // CONTROL<0>=='1' && EXC_RETURN<3>=='1' Privileged otherwise
276
- this.registers[2] = this.readUint32(framePtr + 0x8);
277
- this.registers[3] = this.readUint32(framePtr + 0xc);
278
- this.registers[12] = this.readUint32(framePtr + 0x10);
279
- this.LR = this.readUint32(framePtr + 0x14);
280
- this.PC = this.readUint32(framePtr + 0x18);
281
- const psr = this.readUint32(framePtr + 0x1c);
282
- const framePtrAlign = psr & (1 << 9) ? 0b100 : 0;
283
- switch (excReturn & 0xf) {
284
- case 0b0001: // Returning to Handler mode
285
- this.SPmain = (this.SPmain + 0x20) | framePtrAlign;
286
- break;
287
- case 0b1001: // Returning to Thread mode using Main stack
288
- this.SPmain = (this.SPmain + 0x20) | framePtrAlign;
289
- break;
290
- case 0b1101: // Returning to Thread mode using Process stack
291
- this.SPprocess = (this.SPprocess + 0x20) | framePtrAlign;
292
- break;
293
- }
294
- this.APSR = psr & 0xf0000000;
295
- const forceThread = this.currentMode == ExecutionMode.Mode_Thread && this.nPRIV;
296
- this.IPSR = forceThread ? 0 : psr & 0x3f;
297
- this.interruptsUpdated = true;
298
- // Thumb bit should always be one! EPSR<24> = psr<24>; // Load valid EPSR bits from memory
299
- this.eventRegistered = true;
300
- // if CurrentMode == Mode_Thread && SCR.SLEEPONEXIT == '1' then
301
- // SleepOnExit(); // IMPLEMENTATION DEFINED
302
- }
303
- get pendSVPriority() {
304
- return (this.SHPR3 >> 22) & 0x3;
305
- }
306
- get svCallPriority() {
307
- return this.SHPR2 >>> 30;
308
- }
309
- get systickPriority() {
310
- return this.SHPR3 >>> 30;
311
- }
312
- exceptionPriority(n) {
313
- switch (n) {
314
- case EXC_RESET:
315
- return -3;
316
- case EXC_NMI:
317
- return -2;
318
- case EXC_HARDFAULT:
319
- return -1;
320
- case EXC_SVCALL:
321
- return this.svCallPriority;
322
- case EXC_PENDSV:
323
- return this.pendSVPriority;
324
- case EXC_SYSTICK:
325
- return this.systickPriority;
326
- default: {
327
- if (n < 16) {
328
- return LOWEST_PRIORITY;
329
- }
330
- const intNum = n - 16;
331
- for (let priority = 0; priority < 4; priority++) {
332
- if (this.interruptPriorities[priority] & (1 << intNum)) {
333
- return priority;
334
- }
335
- }
336
- return LOWEST_PRIORITY;
337
- }
338
- }
339
- }
340
- get vectPending() {
341
- if (this.pendingNMI) {
342
- return EXC_NMI;
343
- }
344
- const { svCallPriority, systickPriority, pendSVPriority, pendingInterrupts } = this;
345
- for (let priority = 0; priority < LOWEST_PRIORITY; priority++) {
346
- const levelInterrupts = pendingInterrupts & this.interruptPriorities[priority];
347
- if (this.pendingSVCall && priority === svCallPriority) {
348
- return EXC_SVCALL;
349
- }
350
- if (this.pendingPendSV && priority === pendSVPriority) {
351
- return EXC_PENDSV;
352
- }
353
- if (this.pendingSystick && priority === systickPriority) {
354
- return EXC_SYSTICK;
355
- }
356
- if (levelInterrupts) {
357
- for (let interruptNumber = 0; interruptNumber < 32; interruptNumber++) {
358
- if (levelInterrupts & (1 << interruptNumber)) {
359
- return 16 + interruptNumber;
360
- }
361
- }
362
- }
363
- }
364
- return 0;
365
- }
366
- setInterrupt(irq, value) {
367
- const irqBit = 1 << irq;
368
- if (value && !(this.pendingInterrupts & irqBit)) {
369
- this.pendingInterrupts |= irqBit;
370
- this.interruptsUpdated = true;
371
- if (this.waiting && this.checkForInterrupts()) {
372
- this.waiting = false;
373
- }
374
- }
375
- else if (!value) {
376
- this.pendingInterrupts &= ~irqBit;
377
- }
378
- }
379
- checkForInterrupts() {
380
- /* If we're waiting for an interrupt (i.e. WFI/WFE), the ARM says:
381
- > If PRIMASK.PM is set to 1, an asynchronous exception that has a higher group priority than any
382
- > active exception results in a WFI instruction exit. If the group priority of the exception is less than or
383
- > equal to the execution group priority, the exception is ignored.
384
- */
385
- const currentPriority = this.waiting
386
- ? this.PM
387
- ? this.exceptionPriority(this.IPSR)
388
- : LOWEST_PRIORITY
389
- : Math.min(this.exceptionPriority(this.IPSR), this.PM ? 0 : LOWEST_PRIORITY);
390
- const interruptSet = this.pendingInterrupts & this.enabledInterrupts;
391
- const { svCallPriority, systickPriority, pendSVPriority } = this;
392
- if (this.pendingNMI) {
393
- this.pendingNMI = false;
394
- this.exceptionEntry(EXC_NMI);
395
- return true;
396
- }
397
- for (let priority = 0; priority < currentPriority; priority++) {
398
- const levelInterrupts = interruptSet & this.interruptPriorities[priority];
399
- if (this.pendingSVCall && priority === svCallPriority) {
400
- this.pendingSVCall = false;
401
- this.exceptionEntry(EXC_SVCALL);
402
- return true;
403
- }
404
- if (this.pendingPendSV && priority === pendSVPriority) {
405
- this.pendingPendSV = false;
406
- this.exceptionEntry(EXC_PENDSV);
407
- return true;
408
- }
409
- if (this.pendingSystick && priority === systickPriority) {
410
- this.pendingSystick = false;
411
- this.exceptionEntry(EXC_SYSTICK);
412
- return true;
413
- }
414
- if (levelInterrupts) {
415
- for (let interruptNumber = 0; interruptNumber < 32; interruptNumber++) {
416
- if (levelInterrupts & (1 << interruptNumber)) {
417
- if (interruptNumber > irq_1.MAX_HARDWARE_IRQ) {
418
- this.pendingInterrupts &= ~(1 << interruptNumber);
419
- }
420
- this.exceptionEntry(16 + interruptNumber);
421
- return true;
422
- }
423
- }
424
- }
425
- }
426
- this.interruptsUpdated = false;
427
- return false;
428
- }
429
- readSpecialRegister(sysm) {
430
- switch (sysm) {
431
- case SYSM_APSR:
432
- return this.APSR;
433
- case SYSM_XPSR:
434
- return this.xPSR;
435
- case SYSM_IPSR:
436
- return this.IPSR;
437
- case exports.SYSM_PRIMASK:
438
- return this.PM ? 1 : 0;
439
- case exports.SYSM_MSP:
440
- return this.SPmain;
441
- case exports.SYSM_PSP:
442
- return this.SPprocess;
443
- case exports.SYSM_CONTROL:
444
- return (this.SPSEL === StackPointerBank.SPprocess ? 2 : 0) | (this.nPRIV ? 1 : 0);
445
- default:
446
- this.logger.warn(LOG_NAME, `MRS with unimplemented SYSm value: ${sysm}`);
447
- return 0;
448
- }
449
- }
450
- writeSpecialRegister(sysm, value) {
451
- switch (sysm) {
452
- case SYSM_APSR:
453
- this.APSR = value;
454
- break;
455
- case SYSM_XPSR:
456
- this.xPSR = value;
457
- break;
458
- case SYSM_IPSR:
459
- this.IPSR = value;
460
- break;
461
- case exports.SYSM_PRIMASK:
462
- this.PM = !!(value & 1);
463
- this.interruptsUpdated = true;
464
- break;
465
- case exports.SYSM_MSP:
466
- this.SPmain = value;
467
- break;
468
- case exports.SYSM_PSP:
469
- this.SPprocess = value;
470
- break;
471
- case exports.SYSM_CONTROL:
472
- this.nPRIV = !!(value & 1);
473
- if (this.currentMode === ExecutionMode.Mode_Thread) {
474
- this.switchStack(value & 2 ? StackPointerBank.SPprocess : StackPointerBank.SPmain);
475
- }
476
- break;
477
- default:
478
- this.logger.warn(LOG_NAME, `MRS with unimplemented SYSm value: ${sysm}`);
479
- return 0;
480
- }
481
- }
482
- BXWritePC(address) {
483
- if (this.currentMode == ExecutionMode.Mode_Handler && address >>> 28 == 0b1111) {
484
- this.exceptionReturn(address & 0x0fffffff);
485
- }
486
- else {
487
- this.PC = address & ~1;
488
- }
489
- }
490
- substractUpdateFlags(minuend, subtrahend) {
491
- const result = minuend - subtrahend;
492
- this.N = !!(result & 0x80000000);
493
- this.Z = (result & 0xffffffff) === 0;
494
- this.C = minuend >= subtrahend;
495
- this.V =
496
- (!!(result & 0x80000000) && !(minuend & 0x80000000) && !!(subtrahend & 0x80000000)) ||
497
- (!(result & 0x80000000) && !!(minuend & 0x80000000) && !(subtrahend & 0x80000000));
498
- return result;
499
- }
500
- addUpdateFlags(addend1, addend2) {
501
- const unsignedSum = (addend1 + addend2) >>> 0;
502
- const signedSum = (addend1 | 0) + (addend2 | 0);
503
- const result = addend1 + addend2;
504
- this.N = !!(result & 0x80000000);
505
- this.Z = (result & 0xffffffff) === 0;
506
- this.C = result === unsignedSum ? false : true;
507
- this.V = (result | 0) === signedSum ? false : true;
508
- return result & 0xffffffff;
509
- }
510
- cyclesIO(addr, write = false) {
511
- addr = addr >>> 0;
512
- if (addr >= rp2040_1.SIO_START_ADDRESS && addr < rp2040_1.SIO_START_ADDRESS + 0x10000000) {
513
- return 0;
514
- }
515
- if (addr >= rp2040_1.APB_START_ADDRESS && addr < rp2040_1.APB_START_ADDRESS + 0x10000000) {
516
- return write ? 4 : 3;
517
- }
518
- return 1;
519
- }
520
- executeInstruction() {
521
- if (this.interruptsUpdated) {
522
- if (this.checkForInterrupts()) {
523
- this.waiting = false;
524
- }
525
- }
526
- // ARM Thumb instruction encoding - 16 bits / 2 bytes
527
- const opcodePC = this.PC & ~1; //ensure no LSB set PC are executed
528
- const opcode = this.readUint16(opcodePC);
529
- const wideInstruction = opcode >> 12 === 0b1111 || opcode >> 11 === 0b11101;
530
- const opcode2 = wideInstruction ? this.readUint16(opcodePC + 2) : 0;
531
- this.PC += 2;
532
- this.cycles++;
533
- // ADCS
534
- if (opcode >> 6 === 0b0100000101) {
535
- const Rm = (opcode >> 3) & 0x7;
536
- const Rdn = opcode & 0x7;
537
- this.registers[Rdn] = this.addUpdateFlags(this.registers[Rm], this.registers[Rdn] + (this.C ? 1 : 0));
538
- }
539
- // ADD (register = SP plus immediate)
540
- else if (opcode >> 11 === 0b10101) {
541
- const imm8 = opcode & 0xff;
542
- const Rd = (opcode >> 8) & 0x7;
543
- this.registers[Rd] = this.SP + (imm8 << 2);
544
- }
545
- // ADD (SP plus immediate)
546
- else if (opcode >> 7 === 0b101100000) {
547
- const imm32 = (opcode & 0x7f) << 2;
548
- this.SP += imm32;
549
- }
550
- // ADDS (Encoding T1)
551
- else if (opcode >> 9 === 0b0001110) {
552
- const imm3 = (opcode >> 6) & 0x7;
553
- const Rn = (opcode >> 3) & 0x7;
554
- const Rd = opcode & 0x7;
555
- this.registers[Rd] = this.addUpdateFlags(this.registers[Rn], imm3);
556
- }
557
- // ADDS (Encoding T2)
558
- else if (opcode >> 11 === 0b00110) {
559
- const imm8 = opcode & 0xff;
560
- const Rdn = (opcode >> 8) & 0x7;
561
- this.registers[Rdn] = this.addUpdateFlags(this.registers[Rdn], imm8);
562
- }
563
- // ADDS (register)
564
- else if (opcode >> 9 === 0b0001100) {
565
- const Rm = (opcode >> 6) & 0x7;
566
- const Rn = (opcode >> 3) & 0x7;
567
- const Rd = opcode & 0x7;
568
- this.registers[Rd] = this.addUpdateFlags(this.registers[Rn], this.registers[Rm]);
569
- }
570
- // ADD (register)
571
- else if (opcode >> 8 === 0b01000100) {
572
- const Rm = (opcode >> 3) & 0xf;
573
- const Rdn = ((opcode & 0x80) >> 4) | (opcode & 0x7);
574
- const leftValue = Rdn === pcRegister ? this.PC + 2 : this.registers[Rdn];
575
- const rightValue = this.registers[Rm];
576
- const result = leftValue + rightValue;
577
- if (Rdn !== spRegister && Rdn !== pcRegister) {
578
- this.registers[Rdn] = result;
579
- }
580
- else if (Rdn === pcRegister) {
581
- this.registers[Rdn] = result & ~0x1;
582
- this.cycles++;
583
- }
584
- else if (Rdn === spRegister) {
585
- this.registers[Rdn] = result & ~0x3;
586
- }
587
- }
588
- // ADR
589
- else if (opcode >> 11 === 0b10100) {
590
- const imm8 = opcode & 0xff;
591
- const Rd = (opcode >> 8) & 0x7;
592
- this.registers[Rd] = (opcodePC & 0xfffffffc) + 4 + (imm8 << 2);
593
- }
594
- // ANDS (Encoding T2)
595
- else if (opcode >> 6 === 0b0100000000) {
596
- const Rm = (opcode >> 3) & 0x7;
597
- const Rdn = opcode & 0x7;
598
- const result = this.registers[Rdn] & this.registers[Rm];
599
- this.registers[Rdn] = result;
600
- this.N = !!(result & 0x80000000);
601
- this.Z = (result & 0xffffffff) === 0;
602
- }
603
- // ASRS (immediate)
604
- else if (opcode >> 11 === 0b00010) {
605
- const imm5 = (opcode >> 6) & 0x1f;
606
- const Rm = (opcode >> 3) & 0x7;
607
- const Rd = opcode & 0x7;
608
- const input = this.registers[Rm];
609
- const shiftN = imm5 ? imm5 : 32;
610
- const result = shiftN < 32 ? input >> shiftN : (input & 0x80000000) >> 31;
611
- this.registers[Rd] = result;
612
- this.N = !!(result & 0x80000000);
613
- this.Z = (result & 0xffffffff) === 0;
614
- this.C = input & (1 << (shiftN - 1)) ? true : false;
615
- }
616
- // ASRS (register)
617
- else if (opcode >> 6 === 0b0100000100) {
618
- const Rm = (opcode >> 3) & 0x7;
619
- const Rdn = opcode & 0x7;
620
- const input = this.registers[Rdn];
621
- const shiftN = (this.registers[Rm] & 0xff) < 32 ? this.registers[Rm] & 0xff : 32;
622
- const result = shiftN < 32 ? input >> shiftN : (input & 0x80000000) >> 31;
623
- this.registers[Rdn] = result;
624
- this.N = !!(result & 0x80000000);
625
- this.Z = (result & 0xffffffff) === 0;
626
- this.C = input & (1 << (shiftN - 1)) ? true : false;
627
- }
628
- // B (with cond)
629
- else if (opcode >> 12 === 0b1101 && ((opcode >> 9) & 0x7) !== 0b111) {
630
- let imm8 = (opcode & 0xff) << 1;
631
- const cond = (opcode >> 8) & 0xf;
632
- if (imm8 & (1 << 8)) {
633
- imm8 = (imm8 & 0x1ff) - 0x200;
634
- }
635
- if (this.checkCondition(cond)) {
636
- this.PC += imm8 + 2;
637
- this.cycles++;
638
- }
639
- }
640
- // B
641
- else if (opcode >> 11 === 0b11100) {
642
- let imm11 = (opcode & 0x7ff) << 1;
643
- if (imm11 & (1 << 11)) {
644
- imm11 = (imm11 & 0x7ff) - 0x800;
645
- }
646
- this.PC += imm11 + 2;
647
- this.cycles++;
648
- }
649
- // BICS
650
- else if (opcode >> 6 === 0b0100001110) {
651
- const Rm = (opcode >> 3) & 0x7;
652
- const Rdn = opcode & 0x7;
653
- const result = (this.registers[Rdn] &= ~this.registers[Rm]);
654
- this.N = !!(result & 0x80000000);
655
- this.Z = result === 0;
656
- }
657
- // BKPT
658
- else if (opcode >> 8 === 0b10111110) {
659
- const imm8 = opcode & 0xff;
660
- this.breakRewind = 2;
661
- this.rp2040.onBreak(imm8);
662
- }
663
- // BL
664
- else if (opcode >> 11 === 0b11110 && opcode2 >> 14 === 0b11 && ((opcode2 >> 12) & 0x1) == 1) {
665
- const imm11 = opcode2 & 0x7ff;
666
- const J2 = (opcode2 >> 11) & 0x1;
667
- const J1 = (opcode2 >> 13) & 0x1;
668
- const imm10 = opcode & 0x3ff;
669
- const S = (opcode >> 10) & 0x1;
670
- const I1 = 1 - (S ^ J1);
671
- const I2 = 1 - (S ^ J2);
672
- const imm32 = ((S ? 0b11111111 : 0) << 24) | ((I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1));
673
- this.LR = (this.PC + 2) | 0x1;
674
- this.PC += 2 + imm32;
675
- this.cycles += 2;
676
- this.blTaken(this, false);
677
- }
678
- // BLX
679
- else if (opcode >> 7 === 0b010001111 && (opcode & 0x7) === 0) {
680
- const Rm = (opcode >> 3) & 0xf;
681
- this.LR = this.PC | 0x1;
682
- this.PC = this.registers[Rm] & ~1;
683
- this.cycles++;
684
- this.blTaken(this, true);
685
- }
686
- // BX
687
- else if (opcode >> 7 === 0b010001110 && (opcode & 0x7) === 0) {
688
- const Rm = (opcode >> 3) & 0xf;
689
- this.BXWritePC(this.registers[Rm]);
690
- this.cycles++;
691
- }
692
- // CMN (register)
693
- else if (opcode >> 6 === 0b0100001011) {
694
- const Rm = (opcode >> 3) & 0x7;
695
- const Rn = opcode & 0x7;
696
- this.addUpdateFlags(this.registers[Rn], this.registers[Rm]);
697
- }
698
- // CMP immediate
699
- else if (opcode >> 11 === 0b00101) {
700
- const Rn = (opcode >> 8) & 0x7;
701
- const imm8 = opcode & 0xff;
702
- this.substractUpdateFlags(this.registers[Rn], imm8);
703
- }
704
- // CMP (register)
705
- else if (opcode >> 6 === 0b0100001010) {
706
- const Rm = (opcode >> 3) & 0x7;
707
- const Rn = opcode & 0x7;
708
- this.substractUpdateFlags(this.registers[Rn], this.registers[Rm]);
709
- }
710
- // CMP (register) encoding T2
711
- else if (opcode >> 8 === 0b01000101) {
712
- const Rm = (opcode >> 3) & 0xf;
713
- const Rn = ((opcode >> 4) & 0x8) | (opcode & 0x7);
714
- this.substractUpdateFlags(this.registers[Rn], this.registers[Rm]);
715
- }
716
- // CPSID i
717
- else if (opcode === 0xb672) {
718
- this.PM = true;
719
- }
720
- // CPSIE i
721
- else if (opcode === 0xb662) {
722
- this.PM = false;
723
- this.interruptsUpdated = true;
724
- }
725
- // DMB SY
726
- else if (opcode === 0xf3bf && (opcode2 & 0xfff0) === 0x8f50) {
727
- this.PC += 2;
728
- this.cycles += 2;
729
- }
730
- // DSB SY
731
- else if (opcode === 0xf3bf && (opcode2 & 0xfff0) === 0x8f40) {
732
- this.PC += 2;
733
- this.cycles += 2;
734
- }
735
- // EORS
736
- else if (opcode >> 6 === 0b0100000001) {
737
- const Rm = (opcode >> 3) & 0x7;
738
- const Rdn = opcode & 0x7;
739
- const result = this.registers[Rm] ^ this.registers[Rdn];
740
- this.registers[Rdn] = result;
741
- this.N = !!(result & 0x80000000);
742
- this.Z = result === 0;
743
- }
744
- // ISB SY
745
- else if (opcode === 0xf3bf && (opcode2 & 0xfff0) === 0x8f60) {
746
- this.PC += 2;
747
- this.cycles += 2;
748
- }
749
- // LDMIA
750
- else if (opcode >> 11 === 0b11001) {
751
- const Rn = (opcode >> 8) & 0x7;
752
- const registers = opcode & 0xff;
753
- let address = this.registers[Rn];
754
- for (let i = 0; i < 8; i++) {
755
- if (registers & (1 << i)) {
756
- this.registers[i] = this.readUint32(address);
757
- address += 4;
758
- this.cycles++;
759
- }
760
- }
761
- // Write back
762
- if (!(registers & (1 << Rn))) {
763
- this.registers[Rn] = address;
764
- }
765
- }
766
- // LDR (immediate)
767
- else if (opcode >> 11 === 0b01101) {
768
- const imm5 = ((opcode >> 6) & 0x1f) << 2;
769
- const Rn = (opcode >> 3) & 0x7;
770
- const Rt = opcode & 0x7;
771
- const addr = this.registers[Rn] + imm5;
772
- this.cycles += this.cyclesIO(addr);
773
- this.registers[Rt] = this.readUint32(addr);
774
- }
775
- // LDR (sp + immediate)
776
- else if (opcode >> 11 === 0b10011) {
777
- const Rt = (opcode >> 8) & 0x7;
778
- const imm8 = opcode & 0xff;
779
- const addr = this.SP + (imm8 << 2);
780
- this.cycles += this.cyclesIO(addr);
781
- this.registers[Rt] = this.readUint32(addr);
782
- }
783
- // LDR (literal)
784
- else if (opcode >> 11 === 0b01001) {
785
- const imm8 = (opcode & 0xff) << 2;
786
- const Rt = (opcode >> 8) & 7;
787
- const nextPC = this.PC + 2;
788
- const addr = (nextPC & 0xfffffffc) + imm8;
789
- this.cycles += this.cyclesIO(addr);
790
- this.registers[Rt] = this.readUint32(addr);
791
- }
792
- // LDR (register)
793
- else if (opcode >> 9 === 0b0101100) {
794
- const Rm = (opcode >> 6) & 0x7;
795
- const Rn = (opcode >> 3) & 0x7;
796
- const Rt = opcode & 0x7;
797
- const addr = this.registers[Rm] + this.registers[Rn];
798
- this.cycles += this.cyclesIO(addr);
799
- this.registers[Rt] = this.readUint32(addr);
800
- }
801
- // LDRB (immediate)
802
- else if (opcode >> 11 === 0b01111) {
803
- const imm5 = (opcode >> 6) & 0x1f;
804
- const Rn = (opcode >> 3) & 0x7;
805
- const Rt = opcode & 0x7;
806
- const addr = this.registers[Rn] + imm5;
807
- this.cycles += this.cyclesIO(addr);
808
- this.registers[Rt] = this.readUint8(addr);
809
- }
810
- // LDRB (register)
811
- else if (opcode >> 9 === 0b0101110) {
812
- const Rm = (opcode >> 6) & 0x7;
813
- const Rn = (opcode >> 3) & 0x7;
814
- const Rt = opcode & 0x7;
815
- const addr = this.registers[Rm] + this.registers[Rn];
816
- this.cycles += this.cyclesIO(addr);
817
- this.registers[Rt] = this.readUint8(addr);
818
- }
819
- // LDRH (immediate)
820
- else if (opcode >> 11 === 0b10001) {
821
- const imm5 = (opcode >> 6) & 0x1f;
822
- const Rn = (opcode >> 3) & 0x7;
823
- const Rt = opcode & 0x7;
824
- const addr = this.registers[Rn] + (imm5 << 1);
825
- this.cycles += this.cyclesIO(addr);
826
- this.registers[Rt] = this.readUint16(addr);
827
- }
828
- // LDRH (register)
829
- else if (opcode >> 9 === 0b0101101) {
830
- const Rm = (opcode >> 6) & 0x7;
831
- const Rn = (opcode >> 3) & 0x7;
832
- const Rt = opcode & 0x7;
833
- const addr = this.registers[Rm] + this.registers[Rn];
834
- this.cycles += this.cyclesIO(addr);
835
- this.registers[Rt] = this.readUint16(addr);
836
- }
837
- // LDRSB
838
- else if (opcode >> 9 === 0b0101011) {
839
- const Rm = (opcode >> 6) & 0x7;
840
- const Rn = (opcode >> 3) & 0x7;
841
- const Rt = opcode & 0x7;
842
- const addr = this.registers[Rm] + this.registers[Rn];
843
- this.cycles += this.cyclesIO(addr);
844
- this.registers[Rt] = signExtend8(this.readUint8(addr));
845
- }
846
- // LDRSH
847
- else if (opcode >> 9 === 0b0101111) {
848
- const Rm = (opcode >> 6) & 0x7;
849
- const Rn = (opcode >> 3) & 0x7;
850
- const Rt = opcode & 0x7;
851
- const addr = this.registers[Rm] + this.registers[Rn];
852
- this.cycles += this.cyclesIO(addr);
853
- this.registers[Rt] = signExtend16(this.readUint16(addr));
854
- }
855
- // LSLS (immediate)
856
- else if (opcode >> 11 === 0b00000) {
857
- const imm5 = (opcode >> 6) & 0x1f;
858
- const Rm = (opcode >> 3) & 0x7;
859
- const Rd = opcode & 0x7;
860
- const input = this.registers[Rm];
861
- const result = input << imm5;
862
- this.registers[Rd] = result;
863
- this.N = !!(result & 0x80000000);
864
- this.Z = result === 0;
865
- this.C = imm5 ? !!(input & (1 << (32 - imm5))) : this.C;
866
- }
867
- // LSLS (register)
868
- else if (opcode >> 6 === 0b0100000010) {
869
- const Rm = (opcode >> 3) & 0x7;
870
- const Rdn = opcode & 0x7;
871
- const input = this.registers[Rdn];
872
- const shiftCount = this.registers[Rm] & 0xff;
873
- const result = shiftCount >= 32 ? 0 : input << shiftCount;
874
- this.registers[Rdn] = result;
875
- this.N = !!(result & 0x80000000);
876
- this.Z = result === 0;
877
- this.C = shiftCount ? !!(input & (1 << (32 - shiftCount))) : this.C;
878
- }
879
- // LSRS (immediate)
880
- else if (opcode >> 11 === 0b00001) {
881
- const imm5 = (opcode >> 6) & 0x1f;
882
- const Rm = (opcode >> 3) & 0x7;
883
- const Rd = opcode & 0x7;
884
- const input = this.registers[Rm];
885
- const result = imm5 ? input >>> imm5 : 0;
886
- this.registers[Rd] = result;
887
- this.N = !!(result & 0x80000000);
888
- this.Z = result === 0;
889
- this.C = !!((input >>> (imm5 ? imm5 - 1 : 31)) & 0x1);
890
- }
891
- // LSRS (register)
892
- else if (opcode >> 6 === 0b0100000011) {
893
- const Rm = (opcode >> 3) & 0x7;
894
- const Rdn = opcode & 0x7;
895
- const shiftAmount = this.registers[Rm] & 0xff;
896
- const input = this.registers[Rdn];
897
- const result = shiftAmount < 32 ? input >>> shiftAmount : 0;
898
- this.registers[Rdn] = result;
899
- this.N = !!(result & 0x80000000);
900
- this.Z = result === 0;
901
- this.C = shiftAmount <= 32 ? !!((input >>> (shiftAmount - 1)) & 0x1) : false;
902
- }
903
- // MOV
904
- else if (opcode >> 8 === 0b01000110) {
905
- const Rm = (opcode >> 3) & 0xf;
906
- const Rd = ((opcode >> 4) & 0x8) | (opcode & 0x7);
907
- let value = Rm === pcRegister ? this.PC + 2 : this.registers[Rm];
908
- if (Rd === pcRegister) {
909
- this.cycles++;
910
- value &= ~1;
911
- }
912
- else if (Rd === spRegister) {
913
- value &= ~3;
914
- }
915
- this.registers[Rd] = value;
916
- }
917
- // MOVS
918
- else if (opcode >> 11 === 0b00100) {
919
- const value = opcode & 0xff;
920
- const Rd = (opcode >> 8) & 7;
921
- this.registers[Rd] = value;
922
- this.N = !!(value & 0x80000000);
923
- this.Z = value === 0;
924
- }
925
- // MRS
926
- else if (opcode === 0b1111001111101111 && opcode2 >> 12 == 0b1000) {
927
- const SYSm = opcode2 & 0xff;
928
- const Rd = (opcode2 >> 8) & 0xf;
929
- this.registers[Rd] = this.readSpecialRegister(SYSm);
930
- this.PC += 2;
931
- this.cycles += 2;
932
- }
933
- // MSR
934
- else if (opcode >> 4 === 0b111100111000 && opcode2 >> 8 == 0b10001000) {
935
- const SYSm = opcode2 & 0xff;
936
- const Rn = opcode & 0xf;
937
- this.writeSpecialRegister(SYSm, this.registers[Rn]);
938
- this.PC += 2;
939
- this.cycles += 2;
940
- }
941
- // MULS
942
- else if (opcode >> 6 === 0b0100001101) {
943
- const Rn = (opcode >> 3) & 0x7;
944
- const Rdm = opcode & 0x7;
945
- const result = Math.imul(this.registers[Rn], this.registers[Rdm]);
946
- this.registers[Rdm] = result;
947
- this.N = !!(result & 0x80000000);
948
- this.Z = (result & 0xffffffff) === 0;
949
- }
950
- // MVNS
951
- else if (opcode >> 6 === 0b0100001111) {
952
- const Rm = (opcode >> 3) & 7;
953
- const Rd = opcode & 7;
954
- const result = ~this.registers[Rm];
955
- this.registers[Rd] = result;
956
- this.N = !!(result & 0x80000000);
957
- this.Z = result === 0;
958
- }
959
- // ORRS (Encoding T2)
960
- else if (opcode >> 6 === 0b0100001100) {
961
- const Rm = (opcode >> 3) & 0x7;
962
- const Rdn = opcode & 0x7;
963
- const result = this.registers[Rdn] | this.registers[Rm];
964
- this.registers[Rdn] = result;
965
- this.N = !!(result & 0x80000000);
966
- this.Z = (result & 0xffffffff) === 0;
967
- }
968
- // POP
969
- else if (opcode >> 9 === 0b1011110) {
970
- const P = (opcode >> 8) & 1;
971
- let address = this.SP;
972
- for (let i = 0; i <= 7; i++) {
973
- if (opcode & (1 << i)) {
974
- this.registers[i] = this.readUint32(address);
975
- address += 4;
976
- this.cycles++;
977
- }
978
- }
979
- if (P) {
980
- this.SP = address + 4;
981
- this.BXWritePC(this.readUint32(address));
982
- this.cycles += 2;
983
- }
984
- else {
985
- this.SP = address;
986
- }
987
- }
988
- // PUSH
989
- else if (opcode >> 9 === 0b1011010) {
990
- let bitCount = 0;
991
- for (let i = 0; i <= 8; i++) {
992
- if (opcode & (1 << i)) {
993
- bitCount++;
994
- }
995
- }
996
- let address = this.SP - 4 * bitCount;
997
- for (let i = 0; i <= 7; i++) {
998
- if (opcode & (1 << i)) {
999
- this.writeUint32(address, this.registers[i]);
1000
- this.cycles++;
1001
- address += 4;
1002
- }
1003
- }
1004
- if (opcode & (1 << 8)) {
1005
- this.writeUint32(address, this.registers[14]);
1006
- }
1007
- this.SP -= 4 * bitCount;
1008
- }
1009
- // REV
1010
- else if (opcode >> 6 === 0b1011101000) {
1011
- const Rm = (opcode >> 3) & 0x7;
1012
- const Rd = opcode & 0x7;
1013
- const input = this.registers[Rm];
1014
- this.registers[Rd] =
1015
- ((input & 0xff) << 24) |
1016
- (((input >> 8) & 0xff) << 16) |
1017
- (((input >> 16) & 0xff) << 8) |
1018
- ((input >> 24) & 0xff);
1019
- }
1020
- // REV16
1021
- else if (opcode >> 6 === 0b1011101001) {
1022
- const Rm = (opcode >> 3) & 0x7;
1023
- const Rd = opcode & 0x7;
1024
- const input = this.registers[Rm];
1025
- this.registers[Rd] =
1026
- (((input >> 16) & 0xff) << 24) |
1027
- (((input >> 24) & 0xff) << 16) |
1028
- ((input & 0xff) << 8) |
1029
- ((input >> 8) & 0xff);
1030
- }
1031
- // REVSH
1032
- else if (opcode >> 6 === 0b1011101011) {
1033
- const Rm = (opcode >> 3) & 0x7;
1034
- const Rd = opcode & 0x7;
1035
- const input = this.registers[Rm];
1036
- this.registers[Rd] = signExtend16(((input & 0xff) << 8) | ((input >> 8) & 0xff));
1037
- }
1038
- // ROR
1039
- else if (opcode >> 6 === 0b0100000111) {
1040
- const Rm = (opcode >> 3) & 0x7;
1041
- const Rdn = opcode & 0x7;
1042
- const input = this.registers[Rdn];
1043
- const shift = (this.registers[Rm] & 0xff) % 32;
1044
- const result = (input >>> shift) | (input << (32 - shift));
1045
- this.registers[Rdn] = result;
1046
- this.N = !!(result & 0x80000000);
1047
- this.Z = result === 0;
1048
- this.C = !!(result & 0x80000000);
1049
- }
1050
- // NEGS / RSBS
1051
- else if (opcode >> 6 === 0b0100001001) {
1052
- const Rn = (opcode >> 3) & 0x7;
1053
- const Rd = opcode & 0x7;
1054
- this.registers[Rd] = this.substractUpdateFlags(0, this.registers[Rn]);
1055
- }
1056
- // NOP
1057
- else if (opcode === 0b1011111100000000) {
1058
- // Do nothing!
1059
- }
1060
- // SBCS (Encoding T1)
1061
- else if (opcode >> 6 === 0b0100000110) {
1062
- const Rm = (opcode >> 3) & 0x7;
1063
- const Rdn = opcode & 0x7;
1064
- this.registers[Rdn] = this.substractUpdateFlags(this.registers[Rdn], this.registers[Rm] + (1 - (this.C ? 1 : 0)));
1065
- }
1066
- // SEV
1067
- else if (opcode === 0b1011111101000000) {
1068
- this.logger.info(LOG_NAME, 'SEV');
1069
- }
1070
- // STMIA
1071
- else if (opcode >> 11 === 0b11000) {
1072
- const Rn = (opcode >> 8) & 0x7;
1073
- const registers = opcode & 0xff;
1074
- let address = this.registers[Rn];
1075
- for (let i = 0; i < 8; i++) {
1076
- if (registers & (1 << i)) {
1077
- this.writeUint32(address, this.registers[i]);
1078
- address += 4;
1079
- this.cycles++;
1080
- }
1081
- }
1082
- // Write back
1083
- if (!(registers & (1 << Rn))) {
1084
- this.registers[Rn] = address;
1085
- }
1086
- }
1087
- // STR (immediate)
1088
- else if (opcode >> 11 === 0b01100) {
1089
- const imm5 = ((opcode >> 6) & 0x1f) << 2;
1090
- const Rn = (opcode >> 3) & 0x7;
1091
- const Rt = opcode & 0x7;
1092
- const address = this.registers[Rn] + imm5;
1093
- this.cycles += this.cyclesIO(address, true);
1094
- this.writeUint32(address, this.registers[Rt]);
1095
- }
1096
- // STR (sp + immediate)
1097
- else if (opcode >> 11 === 0b10010) {
1098
- const Rt = (opcode >> 8) & 0x7;
1099
- const imm8 = opcode & 0xff;
1100
- const address = this.SP + (imm8 << 2);
1101
- this.cycles += this.cyclesIO(address, true);
1102
- this.writeUint32(address, this.registers[Rt]);
1103
- }
1104
- // STR (register)
1105
- else if (opcode >> 9 === 0b0101000) {
1106
- const Rm = (opcode >> 6) & 0x7;
1107
- const Rn = (opcode >> 3) & 0x7;
1108
- const Rt = opcode & 0x7;
1109
- const address = this.registers[Rm] + this.registers[Rn];
1110
- this.cycles += this.cyclesIO(address, true);
1111
- this.writeUint32(address, this.registers[Rt]);
1112
- }
1113
- // STRB (immediate)
1114
- else if (opcode >> 11 === 0b01110) {
1115
- const imm5 = (opcode >> 6) & 0x1f;
1116
- const Rn = (opcode >> 3) & 0x7;
1117
- const Rt = opcode & 0x7;
1118
- const address = this.registers[Rn] + imm5;
1119
- this.cycles += this.cyclesIO(address, true);
1120
- this.writeUint8(address, this.registers[Rt]);
1121
- }
1122
- // STRB (register)
1123
- else if (opcode >> 9 === 0b0101010) {
1124
- const Rm = (opcode >> 6) & 0x7;
1125
- const Rn = (opcode >> 3) & 0x7;
1126
- const Rt = opcode & 0x7;
1127
- const address = this.registers[Rm] + this.registers[Rn];
1128
- this.cycles += this.cyclesIO(address, true);
1129
- this.writeUint8(address, this.registers[Rt]);
1130
- }
1131
- // STRH (immediate)
1132
- else if (opcode >> 11 === 0b10000) {
1133
- const imm5 = ((opcode >> 6) & 0x1f) << 1;
1134
- const Rn = (opcode >> 3) & 0x7;
1135
- const Rt = opcode & 0x7;
1136
- const address = this.registers[Rn] + imm5;
1137
- this.cycles += this.cyclesIO(address, true);
1138
- this.writeUint16(address, this.registers[Rt]);
1139
- }
1140
- // STRH (register)
1141
- else if (opcode >> 9 === 0b0101001) {
1142
- const Rm = (opcode >> 6) & 0x7;
1143
- const Rn = (opcode >> 3) & 0x7;
1144
- const Rt = opcode & 0x7;
1145
- const address = this.registers[Rm] + this.registers[Rn];
1146
- this.cycles += this.cyclesIO(address, true);
1147
- this.writeUint16(address, this.registers[Rt]);
1148
- }
1149
- // SUB (SP minus immediate)
1150
- else if (opcode >> 7 === 0b101100001) {
1151
- const imm32 = (opcode & 0x7f) << 2;
1152
- this.SP -= imm32;
1153
- }
1154
- // SUBS (Encoding T1)
1155
- else if (opcode >> 9 === 0b0001111) {
1156
- const imm3 = (opcode >> 6) & 0x7;
1157
- const Rn = (opcode >> 3) & 0x7;
1158
- const Rd = opcode & 0x7;
1159
- this.registers[Rd] = this.substractUpdateFlags(this.registers[Rn], imm3);
1160
- }
1161
- // SUBS (Encoding T2)
1162
- else if (opcode >> 11 === 0b00111) {
1163
- const imm8 = opcode & 0xff;
1164
- const Rdn = (opcode >> 8) & 0x7;
1165
- this.registers[Rdn] = this.substractUpdateFlags(this.registers[Rdn], imm8);
1166
- }
1167
- // SUBS (register)
1168
- else if (opcode >> 9 === 0b0001101) {
1169
- const Rm = (opcode >> 6) & 0x7;
1170
- const Rn = (opcode >> 3) & 0x7;
1171
- const Rd = opcode & 0x7;
1172
- this.registers[Rd] = this.substractUpdateFlags(this.registers[Rn], this.registers[Rm]);
1173
- }
1174
- // SVC
1175
- else if (opcode >> 8 === 0b11011111) {
1176
- this.pendingSVCall = true;
1177
- this.interruptsUpdated = true;
1178
- }
1179
- // SXTB
1180
- else if (opcode >> 6 === 0b1011001001) {
1181
- const Rm = (opcode >> 3) & 0x7;
1182
- const Rd = opcode & 0x7;
1183
- this.registers[Rd] = signExtend8(this.registers[Rm]);
1184
- }
1185
- // SXTH
1186
- else if (opcode >> 6 === 0b1011001000) {
1187
- const Rm = (opcode >> 3) & 0x7;
1188
- const Rd = opcode & 0x7;
1189
- this.registers[Rd] = signExtend16(this.registers[Rm]);
1190
- }
1191
- // TST
1192
- else if (opcode >> 6 == 0b0100001000) {
1193
- const Rm = (opcode >> 3) & 0x7;
1194
- const Rn = opcode & 0x7;
1195
- const result = this.registers[Rn] & this.registers[Rm];
1196
- this.N = !!(result & 0x80000000);
1197
- this.Z = result === 0;
1198
- }
1199
- // UDF
1200
- else if (opcode >> 8 == 0b11011110) {
1201
- const imm8 = opcode & 0xff;
1202
- this.breakRewind = 2;
1203
- this.rp2040.onBreak(imm8);
1204
- }
1205
- // UDF (Encoding T2)
1206
- else if (opcode >> 4 === 0b111101111111 && opcode2 >> 12 === 0b1010) {
1207
- const imm4 = opcode & 0xf;
1208
- const imm12 = opcode2 & 0xfff;
1209
- this.breakRewind = 4;
1210
- this.rp2040.onBreak((imm4 << 12) | imm12);
1211
- this.PC += 2;
1212
- }
1213
- // UXTB
1214
- else if (opcode >> 6 == 0b1011001011) {
1215
- const Rm = (opcode >> 3) & 0x7;
1216
- const Rd = opcode & 0x7;
1217
- this.registers[Rd] = this.registers[Rm] & 0xff;
1218
- }
1219
- // UXTH
1220
- else if (opcode >> 6 == 0b1011001010) {
1221
- const Rm = (opcode >> 3) & 0x7;
1222
- const Rd = opcode & 0x7;
1223
- this.registers[Rd] = this.registers[Rm] & 0xffff;
1224
- }
1225
- // WFE
1226
- else if (opcode === 0b1011111100100000) {
1227
- this.cycles++;
1228
- if (this.eventRegistered) {
1229
- this.eventRegistered = false;
1230
- }
1231
- else {
1232
- this.waiting = true;
1233
- }
1234
- }
1235
- // WFI
1236
- else if (opcode === 0b1011111100110000) {
1237
- this.cycles++;
1238
- this.waiting = true;
1239
- }
1240
- // YIELD
1241
- else if (opcode === 0b1011111100010000) {
1242
- // do nothing for now. Wait for event!
1243
- this.logger.info(LOG_NAME, 'Yield');
1244
- }
1245
- else {
1246
- this.logger.warn(LOG_NAME, `Warning: Instruction at ${opcodePC.toString(16)} is not implemented yet!`);
1247
- this.logger.warn(LOG_NAME, `Opcode: 0x${opcode.toString(16)} (0x${opcode2.toString(16)})`);
1248
- }
1249
- }
1250
- }
1251
- exports.CortexM0Core = CortexM0Core;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CortexM0Core = exports.SYSM_CONTROL = exports.SYSM_PRIMASK = exports.SYSM_PSP = exports.SYSM_MSP = void 0;
4
+ const irq_js_1 = require("./irq.js");
5
+ const rp2040_js_1 = require("./rp2040.js");
6
+ /* eslint-disable @typescript-eslint/no-unused-vars */
7
+ const EXC_RESET = 1;
8
+ const EXC_NMI = 2;
9
+ const EXC_HARDFAULT = 3;
10
+ const EXC_SVCALL = 11;
11
+ const EXC_PENDSV = 14;
12
+ const EXC_SYSTICK = 15;
13
+ const SYSM_APSR = 0;
14
+ const SYSM_IAPSR = 1;
15
+ const SYSM_EAPSR = 2;
16
+ const SYSM_XPSR = 3;
17
+ const SYSM_IPSR = 5;
18
+ const SYSM_EPSR = 6;
19
+ const SYSM_IEPSR = 7;
20
+ exports.SYSM_MSP = 8;
21
+ exports.SYSM_PSP = 9;
22
+ exports.SYSM_PRIMASK = 16;
23
+ exports.SYSM_CONTROL = 20;
24
+ /* eslint-enable @typescript-eslint/no-unused-vars */
25
+ // Lowest possible exception priority
26
+ const LOWEST_PRIORITY = 4;
27
+ var ExecutionMode;
28
+ (function (ExecutionMode) {
29
+ ExecutionMode[ExecutionMode["Mode_Thread"] = 0] = "Mode_Thread";
30
+ ExecutionMode[ExecutionMode["Mode_Handler"] = 1] = "Mode_Handler";
31
+ })(ExecutionMode || (ExecutionMode = {}));
32
+ function signExtend8(value) {
33
+ return (value << 24) >> 24;
34
+ }
35
+ function signExtend16(value) {
36
+ return (value << 16) >> 16;
37
+ }
38
+ const spRegister = 13;
39
+ const pcRegister = 15;
40
+ var StackPointerBank;
41
+ (function (StackPointerBank) {
42
+ StackPointerBank[StackPointerBank["SPmain"] = 0] = "SPmain";
43
+ StackPointerBank[StackPointerBank["SPprocess"] = 1] = "SPprocess";
44
+ })(StackPointerBank || (StackPointerBank = {}));
45
+ const LOG_NAME = 'CortexM0Core';
46
+ class CortexM0Core {
47
+ constructor(rp2040) {
48
+ this.rp2040 = rp2040;
49
+ this.registers = new Uint32Array(16);
50
+ this.bankedSP = 0;
51
+ this.cycles = 0;
52
+ this.eventRegistered = false;
53
+ this.waiting = false;
54
+ // APSR fields
55
+ this.N = false;
56
+ this.C = false;
57
+ this.Z = false;
58
+ this.V = false;
59
+ // How many bytes to rewind the last break instruction
60
+ this.breakRewind = 0;
61
+ // PRIMASK fields
62
+ this.PM = false;
63
+ // CONTROL fields
64
+ this.SPSEL = StackPointerBank.SPmain;
65
+ this.nPRIV = false;
66
+ this.currentMode = ExecutionMode.Mode_Thread;
67
+ this.IPSR = 0;
68
+ this.interruptNMIMask = 0;
69
+ this.pendingInterrupts = 0;
70
+ this.enabledInterrupts = 0;
71
+ this.interruptPriorities = [0xffffffff, 0x0, 0x0, 0x0];
72
+ this.pendingNMI = false;
73
+ this.pendingPendSV = false;
74
+ this.pendingSVCall = false;
75
+ this.pendingSystick = false;
76
+ this.interruptsUpdated = false;
77
+ this.VTOR = 0;
78
+ this.SHPR2 = 0;
79
+ this.SHPR3 = 0;
80
+ /** Hook to listen for function calls - branch-link (BL/BLX) instructions */
81
+ this.blTaken = (core, blx) => {
82
+ void core; // surpress unused variable warnings
83
+ void blx;
84
+ };
85
+ this.SP = 0xfffffffc;
86
+ this.bankedSP = 0xfffffffc;
87
+ }
88
+ get logger() {
89
+ return this.rp2040.logger;
90
+ }
91
+ reset() {
92
+ this.SP = this.rp2040.readUint32(this.VTOR);
93
+ this.PC = this.rp2040.readUint32(this.VTOR + 4) & 0xfffffffe;
94
+ this.cycles = 0;
95
+ }
96
+ get SP() {
97
+ return this.registers[13];
98
+ }
99
+ set SP(value) {
100
+ this.registers[13] = value & ~0x3;
101
+ }
102
+ get LR() {
103
+ return this.registers[14];
104
+ }
105
+ set LR(value) {
106
+ this.registers[14] = value;
107
+ }
108
+ get PC() {
109
+ return this.registers[15];
110
+ }
111
+ set PC(value) {
112
+ this.registers[15] = value;
113
+ }
114
+ get APSR() {
115
+ return ((this.N ? 0x80000000 : 0) |
116
+ (this.Z ? 0x40000000 : 0) |
117
+ (this.C ? 0x20000000 : 0) |
118
+ (this.V ? 0x10000000 : 0));
119
+ }
120
+ set APSR(value) {
121
+ this.N = !!(value & 0x80000000);
122
+ this.Z = !!(value & 0x40000000);
123
+ this.C = !!(value & 0x20000000);
124
+ this.V = !!(value & 0x10000000);
125
+ }
126
+ get xPSR() {
127
+ return this.APSR | this.IPSR | (1 << 24);
128
+ }
129
+ set xPSR(value) {
130
+ this.APSR = value;
131
+ this.IPSR = value & 0x3f;
132
+ }
133
+ checkCondition(cond) {
134
+ // Evaluate base condition.
135
+ let result = false;
136
+ switch (cond >> 1) {
137
+ case 0b000:
138
+ result = this.Z;
139
+ break;
140
+ case 0b001:
141
+ result = this.C;
142
+ break;
143
+ case 0b010:
144
+ result = this.N;
145
+ break;
146
+ case 0b011:
147
+ result = this.V;
148
+ break;
149
+ case 0b100:
150
+ result = this.C && !this.Z;
151
+ break;
152
+ case 0b101:
153
+ result = this.N === this.V;
154
+ break;
155
+ case 0b110:
156
+ result = this.N === this.V && !this.Z;
157
+ break;
158
+ case 0b111:
159
+ result = true;
160
+ break;
161
+ }
162
+ return cond & 0b1 && cond != 0b1111 ? !result : result;
163
+ }
164
+ readUint32(address) {
165
+ return this.rp2040.readUint32(address);
166
+ }
167
+ readUint16(address) {
168
+ return this.rp2040.readUint16(address);
169
+ }
170
+ readUint8(address) {
171
+ return this.rp2040.readUint8(address);
172
+ }
173
+ writeUint32(address, value) {
174
+ this.rp2040.writeUint32(address, value);
175
+ }
176
+ writeUint16(address, value) {
177
+ this.rp2040.writeUint16(address, value);
178
+ }
179
+ writeUint8(address, value) {
180
+ this.rp2040.writeUint8(address, value);
181
+ }
182
+ switchStack(stack) {
183
+ if (this.SPSEL !== stack) {
184
+ const temp = this.SP;
185
+ this.SP = this.bankedSP;
186
+ this.bankedSP = temp;
187
+ this.SPSEL = stack;
188
+ }
189
+ }
190
+ get SPprocess() {
191
+ return this.SPSEL === StackPointerBank.SPprocess ? this.SP : this.bankedSP;
192
+ }
193
+ set SPprocess(value) {
194
+ if (this.SPSEL === StackPointerBank.SPprocess) {
195
+ this.SP = value;
196
+ }
197
+ else {
198
+ this.bankedSP = value >>> 0;
199
+ }
200
+ }
201
+ get SPmain() {
202
+ return this.SPSEL === StackPointerBank.SPmain ? this.SP : this.bankedSP;
203
+ }
204
+ set SPmain(value) {
205
+ if (this.SPSEL === StackPointerBank.SPmain) {
206
+ this.SP = value;
207
+ }
208
+ else {
209
+ this.bankedSP = value >>> 0;
210
+ }
211
+ }
212
+ exceptionEntry(exceptionNumber) {
213
+ // PushStack:
214
+ let framePtr = 0;
215
+ let framePtrAlign = 0;
216
+ if (this.SPSEL && this.currentMode === ExecutionMode.Mode_Thread) {
217
+ framePtrAlign = this.SPprocess & 0b100 ? 1 : 0;
218
+ this.SPprocess = (this.SPprocess - 0x20) & ~0b100;
219
+ framePtr = this.SPprocess;
220
+ }
221
+ else {
222
+ framePtrAlign = this.SPmain & 0b100 ? 1 : 0;
223
+ this.SPmain = (this.SPmain - 0x20) & ~0b100;
224
+ framePtr = this.SPmain;
225
+ }
226
+ /* only the stack locations, not the store order, are architected */
227
+ this.writeUint32(framePtr, this.registers[0]);
228
+ this.writeUint32(framePtr + 0x4, this.registers[1]);
229
+ this.writeUint32(framePtr + 0x8, this.registers[2]);
230
+ this.writeUint32(framePtr + 0xc, this.registers[3]);
231
+ this.writeUint32(framePtr + 0x10, this.registers[12]);
232
+ this.writeUint32(framePtr + 0x14, this.LR);
233
+ this.writeUint32(framePtr + 0x18, this.PC & ~1); // ReturnAddress(ExceptionType);
234
+ this.writeUint32(framePtr + 0x1c, (this.xPSR & ~(1 << 9)) | (framePtrAlign << 9));
235
+ if (this.currentMode == ExecutionMode.Mode_Handler) {
236
+ this.LR = 0xfffffff1;
237
+ }
238
+ else {
239
+ if (!this.SPSEL) {
240
+ this.LR = 0xfffffff9;
241
+ }
242
+ else {
243
+ this.LR = 0xfffffffd;
244
+ }
245
+ }
246
+ // ExceptionTaken:
247
+ this.currentMode = ExecutionMode.Mode_Handler; // Enter Handler Mode, now Privileged
248
+ this.IPSR = exceptionNumber;
249
+ this.switchStack(StackPointerBank.SPmain);
250
+ this.eventRegistered = true;
251
+ const vectorTable = this.VTOR;
252
+ this.PC = this.readUint32(vectorTable + 4 * exceptionNumber);
253
+ }
254
+ exceptionReturn(excReturn) {
255
+ let framePtr = this.SPmain;
256
+ switch (excReturn & 0xf) {
257
+ case 0b0001: // Return to Handler
258
+ this.currentMode = ExecutionMode.Mode_Handler;
259
+ this.switchStack(StackPointerBank.SPmain);
260
+ break;
261
+ case 0b1001: // Return to Thread using Main stack
262
+ this.currentMode = ExecutionMode.Mode_Thread;
263
+ this.switchStack(StackPointerBank.SPmain);
264
+ break;
265
+ case 0b1101: // Return to Thread using Process stack
266
+ framePtr = this.SPprocess;
267
+ this.currentMode = ExecutionMode.Mode_Thread;
268
+ this.switchStack(StackPointerBank.SPprocess);
269
+ break;
270
+ // Assigning CurrentMode to Mode_Thread causes a drop in privilege
271
+ // if CONTROL.nPRIV is set to 1
272
+ }
273
+ // PopStack:
274
+ this.registers[0] = this.readUint32(framePtr); // Stack accesses are performed as Unprivileged accesses if
275
+ this.registers[1] = this.readUint32(framePtr + 0x4); // CONTROL<0>=='1' && EXC_RETURN<3>=='1' Privileged otherwise
276
+ this.registers[2] = this.readUint32(framePtr + 0x8);
277
+ this.registers[3] = this.readUint32(framePtr + 0xc);
278
+ this.registers[12] = this.readUint32(framePtr + 0x10);
279
+ this.LR = this.readUint32(framePtr + 0x14);
280
+ this.PC = this.readUint32(framePtr + 0x18);
281
+ const psr = this.readUint32(framePtr + 0x1c);
282
+ const framePtrAlign = psr & (1 << 9) ? 0b100 : 0;
283
+ switch (excReturn & 0xf) {
284
+ case 0b0001: // Returning to Handler mode
285
+ this.SPmain = (this.SPmain + 0x20) | framePtrAlign;
286
+ break;
287
+ case 0b1001: // Returning to Thread mode using Main stack
288
+ this.SPmain = (this.SPmain + 0x20) | framePtrAlign;
289
+ break;
290
+ case 0b1101: // Returning to Thread mode using Process stack
291
+ this.SPprocess = (this.SPprocess + 0x20) | framePtrAlign;
292
+ break;
293
+ }
294
+ this.APSR = psr & 0xf0000000;
295
+ const forceThread = this.currentMode == ExecutionMode.Mode_Thread && this.nPRIV;
296
+ this.IPSR = forceThread ? 0 : psr & 0x3f;
297
+ this.interruptsUpdated = true;
298
+ // Thumb bit should always be one! EPSR<24> = psr<24>; // Load valid EPSR bits from memory
299
+ this.eventRegistered = true;
300
+ // if CurrentMode == Mode_Thread && SCR.SLEEPONEXIT == '1' then
301
+ // SleepOnExit(); // IMPLEMENTATION DEFINED
302
+ }
303
+ get pendSVPriority() {
304
+ return (this.SHPR3 >> 22) & 0x3;
305
+ }
306
+ get svCallPriority() {
307
+ return this.SHPR2 >>> 30;
308
+ }
309
+ get systickPriority() {
310
+ return this.SHPR3 >>> 30;
311
+ }
312
+ exceptionPriority(n) {
313
+ switch (n) {
314
+ case EXC_RESET:
315
+ return -3;
316
+ case EXC_NMI:
317
+ return -2;
318
+ case EXC_HARDFAULT:
319
+ return -1;
320
+ case EXC_SVCALL:
321
+ return this.svCallPriority;
322
+ case EXC_PENDSV:
323
+ return this.pendSVPriority;
324
+ case EXC_SYSTICK:
325
+ return this.systickPriority;
326
+ default: {
327
+ if (n < 16) {
328
+ return LOWEST_PRIORITY;
329
+ }
330
+ const intNum = n - 16;
331
+ for (let priority = 0; priority < 4; priority++) {
332
+ if (this.interruptPriorities[priority] & (1 << intNum)) {
333
+ return priority;
334
+ }
335
+ }
336
+ return LOWEST_PRIORITY;
337
+ }
338
+ }
339
+ }
340
+ get vectPending() {
341
+ if (this.pendingNMI) {
342
+ return EXC_NMI;
343
+ }
344
+ const { svCallPriority, systickPriority, pendSVPriority, pendingInterrupts } = this;
345
+ for (let priority = 0; priority < LOWEST_PRIORITY; priority++) {
346
+ const levelInterrupts = pendingInterrupts & this.interruptPriorities[priority];
347
+ if (this.pendingSVCall && priority === svCallPriority) {
348
+ return EXC_SVCALL;
349
+ }
350
+ if (this.pendingPendSV && priority === pendSVPriority) {
351
+ return EXC_PENDSV;
352
+ }
353
+ if (this.pendingSystick && priority === systickPriority) {
354
+ return EXC_SYSTICK;
355
+ }
356
+ if (levelInterrupts) {
357
+ for (let interruptNumber = 0; interruptNumber < 32; interruptNumber++) {
358
+ if (levelInterrupts & (1 << interruptNumber)) {
359
+ return 16 + interruptNumber;
360
+ }
361
+ }
362
+ }
363
+ }
364
+ return 0;
365
+ }
366
+ setInterrupt(irq, value) {
367
+ const irqBit = 1 << irq;
368
+ if (value && !(this.pendingInterrupts & irqBit)) {
369
+ this.pendingInterrupts |= irqBit;
370
+ this.interruptsUpdated = true;
371
+ if (this.waiting && this.checkForInterrupts()) {
372
+ this.waiting = false;
373
+ }
374
+ }
375
+ else if (!value) {
376
+ this.pendingInterrupts &= ~irqBit;
377
+ }
378
+ }
379
+ checkForInterrupts() {
380
+ /* If we're waiting for an interrupt (i.e. WFI/WFE), the ARM says:
381
+ > If PRIMASK.PM is set to 1, an asynchronous exception that has a higher group priority than any
382
+ > active exception results in a WFI instruction exit. If the group priority of the exception is less than or
383
+ > equal to the execution group priority, the exception is ignored.
384
+ */
385
+ const currentPriority = this.waiting
386
+ ? this.PM
387
+ ? this.exceptionPriority(this.IPSR)
388
+ : LOWEST_PRIORITY
389
+ : Math.min(this.exceptionPriority(this.IPSR), this.PM ? 0 : LOWEST_PRIORITY);
390
+ const interruptSet = this.pendingInterrupts & this.enabledInterrupts;
391
+ const { svCallPriority, systickPriority, pendSVPriority } = this;
392
+ if (this.pendingNMI) {
393
+ this.pendingNMI = false;
394
+ this.exceptionEntry(EXC_NMI);
395
+ return true;
396
+ }
397
+ for (let priority = 0; priority < currentPriority; priority++) {
398
+ const levelInterrupts = interruptSet & this.interruptPriorities[priority];
399
+ if (this.pendingSVCall && priority === svCallPriority) {
400
+ this.pendingSVCall = false;
401
+ this.exceptionEntry(EXC_SVCALL);
402
+ return true;
403
+ }
404
+ if (this.pendingPendSV && priority === pendSVPriority) {
405
+ this.pendingPendSV = false;
406
+ this.exceptionEntry(EXC_PENDSV);
407
+ return true;
408
+ }
409
+ if (this.pendingSystick && priority === systickPriority) {
410
+ this.pendingSystick = false;
411
+ this.exceptionEntry(EXC_SYSTICK);
412
+ return true;
413
+ }
414
+ if (levelInterrupts) {
415
+ for (let interruptNumber = 0; interruptNumber < 32; interruptNumber++) {
416
+ if (levelInterrupts & (1 << interruptNumber)) {
417
+ if (interruptNumber > irq_js_1.MAX_HARDWARE_IRQ) {
418
+ this.pendingInterrupts &= ~(1 << interruptNumber);
419
+ }
420
+ this.exceptionEntry(16 + interruptNumber);
421
+ return true;
422
+ }
423
+ }
424
+ }
425
+ }
426
+ this.interruptsUpdated = false;
427
+ return false;
428
+ }
429
+ readSpecialRegister(sysm) {
430
+ switch (sysm) {
431
+ case SYSM_APSR:
432
+ return this.APSR;
433
+ case SYSM_XPSR:
434
+ return this.xPSR;
435
+ case SYSM_IPSR:
436
+ return this.IPSR;
437
+ case exports.SYSM_PRIMASK:
438
+ return this.PM ? 1 : 0;
439
+ case exports.SYSM_MSP:
440
+ return this.SPmain;
441
+ case exports.SYSM_PSP:
442
+ return this.SPprocess;
443
+ case exports.SYSM_CONTROL:
444
+ return (this.SPSEL === StackPointerBank.SPprocess ? 2 : 0) | (this.nPRIV ? 1 : 0);
445
+ default:
446
+ this.logger.warn(LOG_NAME, `MRS with unimplemented SYSm value: ${sysm}`);
447
+ return 0;
448
+ }
449
+ }
450
+ writeSpecialRegister(sysm, value) {
451
+ switch (sysm) {
452
+ case SYSM_APSR:
453
+ this.APSR = value;
454
+ break;
455
+ case SYSM_XPSR:
456
+ this.xPSR = value;
457
+ break;
458
+ case SYSM_IPSR:
459
+ this.IPSR = value;
460
+ break;
461
+ case exports.SYSM_PRIMASK:
462
+ this.PM = !!(value & 1);
463
+ this.interruptsUpdated = true;
464
+ break;
465
+ case exports.SYSM_MSP:
466
+ this.SPmain = value;
467
+ break;
468
+ case exports.SYSM_PSP:
469
+ this.SPprocess = value;
470
+ break;
471
+ case exports.SYSM_CONTROL:
472
+ this.nPRIV = !!(value & 1);
473
+ if (this.currentMode === ExecutionMode.Mode_Thread) {
474
+ this.switchStack(value & 2 ? StackPointerBank.SPprocess : StackPointerBank.SPmain);
475
+ }
476
+ break;
477
+ default:
478
+ this.logger.warn(LOG_NAME, `MRS with unimplemented SYSm value: ${sysm}`);
479
+ return 0;
480
+ }
481
+ }
482
+ BXWritePC(address) {
483
+ if (this.currentMode == ExecutionMode.Mode_Handler && address >>> 28 == 0b1111) {
484
+ this.exceptionReturn(address & 0x0fffffff);
485
+ }
486
+ else {
487
+ this.PC = address & ~1;
488
+ }
489
+ }
490
+ substractUpdateFlags(minuend, subtrahend) {
491
+ const result = minuend - subtrahend;
492
+ this.N = !!(result & 0x80000000);
493
+ this.Z = (result & 0xffffffff) === 0;
494
+ this.C = minuend >= subtrahend;
495
+ this.V =
496
+ (!!(result & 0x80000000) && !(minuend & 0x80000000) && !!(subtrahend & 0x80000000)) ||
497
+ (!(result & 0x80000000) && !!(minuend & 0x80000000) && !(subtrahend & 0x80000000));
498
+ return result;
499
+ }
500
+ addUpdateFlags(addend1, addend2) {
501
+ const unsignedSum = (addend1 + addend2) >>> 0;
502
+ const signedSum = (addend1 | 0) + (addend2 | 0);
503
+ const result = addend1 + addend2;
504
+ this.N = !!(result & 0x80000000);
505
+ this.Z = (result & 0xffffffff) === 0;
506
+ this.C = result === unsignedSum ? false : true;
507
+ this.V = (result | 0) === signedSum ? false : true;
508
+ return result & 0xffffffff;
509
+ }
510
+ cyclesIO(addr, write = false) {
511
+ addr = addr >>> 0;
512
+ if (addr >= rp2040_js_1.SIO_START_ADDRESS && addr < rp2040_js_1.SIO_START_ADDRESS + 0x10000000) {
513
+ return 0;
514
+ }
515
+ if (addr >= rp2040_js_1.APB_START_ADDRESS && addr < rp2040_js_1.APB_START_ADDRESS + 0x10000000) {
516
+ return write ? 4 : 3;
517
+ }
518
+ return 1;
519
+ }
520
+ executeInstruction() {
521
+ if (this.interruptsUpdated) {
522
+ if (this.checkForInterrupts()) {
523
+ this.waiting = false;
524
+ }
525
+ }
526
+ // ARM Thumb instruction encoding - 16 bits / 2 bytes
527
+ const opcodePC = this.PC & ~1; //ensure no LSB set PC are executed
528
+ const opcode = this.readUint16(opcodePC);
529
+ const wideInstruction = opcode >> 12 === 0b1111 || opcode >> 11 === 0b11101;
530
+ const opcode2 = wideInstruction ? this.readUint16(opcodePC + 2) : 0;
531
+ this.PC += 2;
532
+ this.cycles++;
533
+ // ADCS
534
+ if (opcode >> 6 === 0b0100000101) {
535
+ const Rm = (opcode >> 3) & 0x7;
536
+ const Rdn = opcode & 0x7;
537
+ this.registers[Rdn] = this.addUpdateFlags(this.registers[Rm], this.registers[Rdn] + (this.C ? 1 : 0));
538
+ }
539
+ // ADD (register = SP plus immediate)
540
+ else if (opcode >> 11 === 0b10101) {
541
+ const imm8 = opcode & 0xff;
542
+ const Rd = (opcode >> 8) & 0x7;
543
+ this.registers[Rd] = this.SP + (imm8 << 2);
544
+ }
545
+ // ADD (SP plus immediate)
546
+ else if (opcode >> 7 === 0b101100000) {
547
+ const imm32 = (opcode & 0x7f) << 2;
548
+ this.SP += imm32;
549
+ }
550
+ // ADDS (Encoding T1)
551
+ else if (opcode >> 9 === 0b0001110) {
552
+ const imm3 = (opcode >> 6) & 0x7;
553
+ const Rn = (opcode >> 3) & 0x7;
554
+ const Rd = opcode & 0x7;
555
+ this.registers[Rd] = this.addUpdateFlags(this.registers[Rn], imm3);
556
+ }
557
+ // ADDS (Encoding T2)
558
+ else if (opcode >> 11 === 0b00110) {
559
+ const imm8 = opcode & 0xff;
560
+ const Rdn = (opcode >> 8) & 0x7;
561
+ this.registers[Rdn] = this.addUpdateFlags(this.registers[Rdn], imm8);
562
+ }
563
+ // ADDS (register)
564
+ else if (opcode >> 9 === 0b0001100) {
565
+ const Rm = (opcode >> 6) & 0x7;
566
+ const Rn = (opcode >> 3) & 0x7;
567
+ const Rd = opcode & 0x7;
568
+ this.registers[Rd] = this.addUpdateFlags(this.registers[Rn], this.registers[Rm]);
569
+ }
570
+ // ADD (register)
571
+ else if (opcode >> 8 === 0b01000100) {
572
+ const Rm = (opcode >> 3) & 0xf;
573
+ const Rdn = ((opcode & 0x80) >> 4) | (opcode & 0x7);
574
+ const leftValue = Rdn === pcRegister ? this.PC + 2 : this.registers[Rdn];
575
+ const rightValue = this.registers[Rm];
576
+ const result = leftValue + rightValue;
577
+ if (Rdn !== spRegister && Rdn !== pcRegister) {
578
+ this.registers[Rdn] = result;
579
+ }
580
+ else if (Rdn === pcRegister) {
581
+ this.registers[Rdn] = result & ~0x1;
582
+ this.cycles++;
583
+ }
584
+ else if (Rdn === spRegister) {
585
+ this.registers[Rdn] = result & ~0x3;
586
+ }
587
+ }
588
+ // ADR
589
+ else if (opcode >> 11 === 0b10100) {
590
+ const imm8 = opcode & 0xff;
591
+ const Rd = (opcode >> 8) & 0x7;
592
+ this.registers[Rd] = (opcodePC & 0xfffffffc) + 4 + (imm8 << 2);
593
+ }
594
+ // ANDS (Encoding T2)
595
+ else if (opcode >> 6 === 0b0100000000) {
596
+ const Rm = (opcode >> 3) & 0x7;
597
+ const Rdn = opcode & 0x7;
598
+ const result = this.registers[Rdn] & this.registers[Rm];
599
+ this.registers[Rdn] = result;
600
+ this.N = !!(result & 0x80000000);
601
+ this.Z = (result & 0xffffffff) === 0;
602
+ }
603
+ // ASRS (immediate)
604
+ else if (opcode >> 11 === 0b00010) {
605
+ const imm5 = (opcode >> 6) & 0x1f;
606
+ const Rm = (opcode >> 3) & 0x7;
607
+ const Rd = opcode & 0x7;
608
+ const input = this.registers[Rm];
609
+ const shiftN = imm5 ? imm5 : 32;
610
+ const result = shiftN < 32 ? input >> shiftN : (input & 0x80000000) >> 31;
611
+ this.registers[Rd] = result;
612
+ this.N = !!(result & 0x80000000);
613
+ this.Z = (result & 0xffffffff) === 0;
614
+ this.C = input & (1 << (shiftN - 1)) ? true : false;
615
+ }
616
+ // ASRS (register)
617
+ else if (opcode >> 6 === 0b0100000100) {
618
+ const Rm = (opcode >> 3) & 0x7;
619
+ const Rdn = opcode & 0x7;
620
+ const input = this.registers[Rdn];
621
+ const shiftN = (this.registers[Rm] & 0xff) < 32 ? this.registers[Rm] & 0xff : 32;
622
+ const result = shiftN < 32 ? input >> shiftN : (input & 0x80000000) >> 31;
623
+ this.registers[Rdn] = result;
624
+ this.N = !!(result & 0x80000000);
625
+ this.Z = (result & 0xffffffff) === 0;
626
+ this.C = input & (1 << (shiftN - 1)) ? true : false;
627
+ }
628
+ // B (with cond)
629
+ else if (opcode >> 12 === 0b1101 && ((opcode >> 9) & 0x7) !== 0b111) {
630
+ let imm8 = (opcode & 0xff) << 1;
631
+ const cond = (opcode >> 8) & 0xf;
632
+ if (imm8 & (1 << 8)) {
633
+ imm8 = (imm8 & 0x1ff) - 0x200;
634
+ }
635
+ if (this.checkCondition(cond)) {
636
+ this.PC += imm8 + 2;
637
+ this.cycles++;
638
+ }
639
+ }
640
+ // B
641
+ else if (opcode >> 11 === 0b11100) {
642
+ let imm11 = (opcode & 0x7ff) << 1;
643
+ if (imm11 & (1 << 11)) {
644
+ imm11 = (imm11 & 0x7ff) - 0x800;
645
+ }
646
+ this.PC += imm11 + 2;
647
+ this.cycles++;
648
+ }
649
+ // BICS
650
+ else if (opcode >> 6 === 0b0100001110) {
651
+ const Rm = (opcode >> 3) & 0x7;
652
+ const Rdn = opcode & 0x7;
653
+ const result = (this.registers[Rdn] &= ~this.registers[Rm]);
654
+ this.N = !!(result & 0x80000000);
655
+ this.Z = result === 0;
656
+ }
657
+ // BKPT
658
+ else if (opcode >> 8 === 0b10111110) {
659
+ const imm8 = opcode & 0xff;
660
+ this.breakRewind = 2;
661
+ this.rp2040.onBreak(imm8);
662
+ }
663
+ // BL
664
+ else if (opcode >> 11 === 0b11110 && opcode2 >> 14 === 0b11 && ((opcode2 >> 12) & 0x1) == 1) {
665
+ const imm11 = opcode2 & 0x7ff;
666
+ const J2 = (opcode2 >> 11) & 0x1;
667
+ const J1 = (opcode2 >> 13) & 0x1;
668
+ const imm10 = opcode & 0x3ff;
669
+ const S = (opcode >> 10) & 0x1;
670
+ const I1 = 1 - (S ^ J1);
671
+ const I2 = 1 - (S ^ J2);
672
+ const imm32 = ((S ? 0b11111111 : 0) << 24) | ((I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1));
673
+ this.LR = (this.PC + 2) | 0x1;
674
+ this.PC += 2 + imm32;
675
+ this.cycles += 2;
676
+ this.blTaken(this, false);
677
+ }
678
+ // BLX
679
+ else if (opcode >> 7 === 0b010001111 && (opcode & 0x7) === 0) {
680
+ const Rm = (opcode >> 3) & 0xf;
681
+ this.LR = this.PC | 0x1;
682
+ this.PC = this.registers[Rm] & ~1;
683
+ this.cycles++;
684
+ this.blTaken(this, true);
685
+ }
686
+ // BX
687
+ else if (opcode >> 7 === 0b010001110 && (opcode & 0x7) === 0) {
688
+ const Rm = (opcode >> 3) & 0xf;
689
+ this.BXWritePC(this.registers[Rm]);
690
+ this.cycles++;
691
+ }
692
+ // CMN (register)
693
+ else if (opcode >> 6 === 0b0100001011) {
694
+ const Rm = (opcode >> 3) & 0x7;
695
+ const Rn = opcode & 0x7;
696
+ this.addUpdateFlags(this.registers[Rn], this.registers[Rm]);
697
+ }
698
+ // CMP immediate
699
+ else if (opcode >> 11 === 0b00101) {
700
+ const Rn = (opcode >> 8) & 0x7;
701
+ const imm8 = opcode & 0xff;
702
+ this.substractUpdateFlags(this.registers[Rn], imm8);
703
+ }
704
+ // CMP (register)
705
+ else if (opcode >> 6 === 0b0100001010) {
706
+ const Rm = (opcode >> 3) & 0x7;
707
+ const Rn = opcode & 0x7;
708
+ this.substractUpdateFlags(this.registers[Rn], this.registers[Rm]);
709
+ }
710
+ // CMP (register) encoding T2
711
+ else if (opcode >> 8 === 0b01000101) {
712
+ const Rm = (opcode >> 3) & 0xf;
713
+ const Rn = ((opcode >> 4) & 0x8) | (opcode & 0x7);
714
+ this.substractUpdateFlags(this.registers[Rn], this.registers[Rm]);
715
+ }
716
+ // CPSID i
717
+ else if (opcode === 0xb672) {
718
+ this.PM = true;
719
+ }
720
+ // CPSIE i
721
+ else if (opcode === 0xb662) {
722
+ this.PM = false;
723
+ this.interruptsUpdated = true;
724
+ }
725
+ // DMB SY
726
+ else if (opcode === 0xf3bf && (opcode2 & 0xfff0) === 0x8f50) {
727
+ this.PC += 2;
728
+ this.cycles += 2;
729
+ }
730
+ // DSB SY
731
+ else if (opcode === 0xf3bf && (opcode2 & 0xfff0) === 0x8f40) {
732
+ this.PC += 2;
733
+ this.cycles += 2;
734
+ }
735
+ // EORS
736
+ else if (opcode >> 6 === 0b0100000001) {
737
+ const Rm = (opcode >> 3) & 0x7;
738
+ const Rdn = opcode & 0x7;
739
+ const result = this.registers[Rm] ^ this.registers[Rdn];
740
+ this.registers[Rdn] = result;
741
+ this.N = !!(result & 0x80000000);
742
+ this.Z = result === 0;
743
+ }
744
+ // ISB SY
745
+ else if (opcode === 0xf3bf && (opcode2 & 0xfff0) === 0x8f60) {
746
+ this.PC += 2;
747
+ this.cycles += 2;
748
+ }
749
+ // LDMIA
750
+ else if (opcode >> 11 === 0b11001) {
751
+ const Rn = (opcode >> 8) & 0x7;
752
+ const registers = opcode & 0xff;
753
+ let address = this.registers[Rn];
754
+ for (let i = 0; i < 8; i++) {
755
+ if (registers & (1 << i)) {
756
+ this.registers[i] = this.readUint32(address);
757
+ address += 4;
758
+ this.cycles++;
759
+ }
760
+ }
761
+ // Write back
762
+ if (!(registers & (1 << Rn))) {
763
+ this.registers[Rn] = address;
764
+ }
765
+ }
766
+ // LDR (immediate)
767
+ else if (opcode >> 11 === 0b01101) {
768
+ const imm5 = ((opcode >> 6) & 0x1f) << 2;
769
+ const Rn = (opcode >> 3) & 0x7;
770
+ const Rt = opcode & 0x7;
771
+ const addr = this.registers[Rn] + imm5;
772
+ this.cycles += this.cyclesIO(addr);
773
+ this.registers[Rt] = this.readUint32(addr);
774
+ }
775
+ // LDR (sp + immediate)
776
+ else if (opcode >> 11 === 0b10011) {
777
+ const Rt = (opcode >> 8) & 0x7;
778
+ const imm8 = opcode & 0xff;
779
+ const addr = this.SP + (imm8 << 2);
780
+ this.cycles += this.cyclesIO(addr);
781
+ this.registers[Rt] = this.readUint32(addr);
782
+ }
783
+ // LDR (literal)
784
+ else if (opcode >> 11 === 0b01001) {
785
+ const imm8 = (opcode & 0xff) << 2;
786
+ const Rt = (opcode >> 8) & 7;
787
+ const nextPC = this.PC + 2;
788
+ const addr = (nextPC & 0xfffffffc) + imm8;
789
+ this.cycles += this.cyclesIO(addr);
790
+ this.registers[Rt] = this.readUint32(addr);
791
+ }
792
+ // LDR (register)
793
+ else if (opcode >> 9 === 0b0101100) {
794
+ const Rm = (opcode >> 6) & 0x7;
795
+ const Rn = (opcode >> 3) & 0x7;
796
+ const Rt = opcode & 0x7;
797
+ const addr = this.registers[Rm] + this.registers[Rn];
798
+ this.cycles += this.cyclesIO(addr);
799
+ this.registers[Rt] = this.readUint32(addr);
800
+ }
801
+ // LDRB (immediate)
802
+ else if (opcode >> 11 === 0b01111) {
803
+ const imm5 = (opcode >> 6) & 0x1f;
804
+ const Rn = (opcode >> 3) & 0x7;
805
+ const Rt = opcode & 0x7;
806
+ const addr = this.registers[Rn] + imm5;
807
+ this.cycles += this.cyclesIO(addr);
808
+ this.registers[Rt] = this.readUint8(addr);
809
+ }
810
+ // LDRB (register)
811
+ else if (opcode >> 9 === 0b0101110) {
812
+ const Rm = (opcode >> 6) & 0x7;
813
+ const Rn = (opcode >> 3) & 0x7;
814
+ const Rt = opcode & 0x7;
815
+ const addr = this.registers[Rm] + this.registers[Rn];
816
+ this.cycles += this.cyclesIO(addr);
817
+ this.registers[Rt] = this.readUint8(addr);
818
+ }
819
+ // LDRH (immediate)
820
+ else if (opcode >> 11 === 0b10001) {
821
+ const imm5 = (opcode >> 6) & 0x1f;
822
+ const Rn = (opcode >> 3) & 0x7;
823
+ const Rt = opcode & 0x7;
824
+ const addr = this.registers[Rn] + (imm5 << 1);
825
+ this.cycles += this.cyclesIO(addr);
826
+ this.registers[Rt] = this.readUint16(addr);
827
+ }
828
+ // LDRH (register)
829
+ else if (opcode >> 9 === 0b0101101) {
830
+ const Rm = (opcode >> 6) & 0x7;
831
+ const Rn = (opcode >> 3) & 0x7;
832
+ const Rt = opcode & 0x7;
833
+ const addr = this.registers[Rm] + this.registers[Rn];
834
+ this.cycles += this.cyclesIO(addr);
835
+ this.registers[Rt] = this.readUint16(addr);
836
+ }
837
+ // LDRSB
838
+ else if (opcode >> 9 === 0b0101011) {
839
+ const Rm = (opcode >> 6) & 0x7;
840
+ const Rn = (opcode >> 3) & 0x7;
841
+ const Rt = opcode & 0x7;
842
+ const addr = this.registers[Rm] + this.registers[Rn];
843
+ this.cycles += this.cyclesIO(addr);
844
+ this.registers[Rt] = signExtend8(this.readUint8(addr));
845
+ }
846
+ // LDRSH
847
+ else if (opcode >> 9 === 0b0101111) {
848
+ const Rm = (opcode >> 6) & 0x7;
849
+ const Rn = (opcode >> 3) & 0x7;
850
+ const Rt = opcode & 0x7;
851
+ const addr = this.registers[Rm] + this.registers[Rn];
852
+ this.cycles += this.cyclesIO(addr);
853
+ this.registers[Rt] = signExtend16(this.readUint16(addr));
854
+ }
855
+ // LSLS (immediate)
856
+ else if (opcode >> 11 === 0b00000) {
857
+ const imm5 = (opcode >> 6) & 0x1f;
858
+ const Rm = (opcode >> 3) & 0x7;
859
+ const Rd = opcode & 0x7;
860
+ const input = this.registers[Rm];
861
+ const result = input << imm5;
862
+ this.registers[Rd] = result;
863
+ this.N = !!(result & 0x80000000);
864
+ this.Z = result === 0;
865
+ this.C = imm5 ? !!(input & (1 << (32 - imm5))) : this.C;
866
+ }
867
+ // LSLS (register)
868
+ else if (opcode >> 6 === 0b0100000010) {
869
+ const Rm = (opcode >> 3) & 0x7;
870
+ const Rdn = opcode & 0x7;
871
+ const input = this.registers[Rdn];
872
+ const shiftCount = this.registers[Rm] & 0xff;
873
+ const result = shiftCount >= 32 ? 0 : input << shiftCount;
874
+ this.registers[Rdn] = result;
875
+ this.N = !!(result & 0x80000000);
876
+ this.Z = result === 0;
877
+ this.C = shiftCount ? !!(input & (1 << (32 - shiftCount))) : this.C;
878
+ }
879
+ // LSRS (immediate)
880
+ else if (opcode >> 11 === 0b00001) {
881
+ const imm5 = (opcode >> 6) & 0x1f;
882
+ const Rm = (opcode >> 3) & 0x7;
883
+ const Rd = opcode & 0x7;
884
+ const input = this.registers[Rm];
885
+ const result = imm5 ? input >>> imm5 : 0;
886
+ this.registers[Rd] = result;
887
+ this.N = !!(result & 0x80000000);
888
+ this.Z = result === 0;
889
+ this.C = !!((input >>> (imm5 ? imm5 - 1 : 31)) & 0x1);
890
+ }
891
+ // LSRS (register)
892
+ else if (opcode >> 6 === 0b0100000011) {
893
+ const Rm = (opcode >> 3) & 0x7;
894
+ const Rdn = opcode & 0x7;
895
+ const shiftAmount = this.registers[Rm] & 0xff;
896
+ const input = this.registers[Rdn];
897
+ const result = shiftAmount < 32 ? input >>> shiftAmount : 0;
898
+ this.registers[Rdn] = result;
899
+ this.N = !!(result & 0x80000000);
900
+ this.Z = result === 0;
901
+ this.C = shiftAmount <= 32 ? !!((input >>> (shiftAmount - 1)) & 0x1) : false;
902
+ }
903
+ // MOV
904
+ else if (opcode >> 8 === 0b01000110) {
905
+ const Rm = (opcode >> 3) & 0xf;
906
+ const Rd = ((opcode >> 4) & 0x8) | (opcode & 0x7);
907
+ let value = Rm === pcRegister ? this.PC + 2 : this.registers[Rm];
908
+ if (Rd === pcRegister) {
909
+ this.cycles++;
910
+ value &= ~1;
911
+ }
912
+ else if (Rd === spRegister) {
913
+ value &= ~3;
914
+ }
915
+ this.registers[Rd] = value;
916
+ }
917
+ // MOVS
918
+ else if (opcode >> 11 === 0b00100) {
919
+ const value = opcode & 0xff;
920
+ const Rd = (opcode >> 8) & 7;
921
+ this.registers[Rd] = value;
922
+ this.N = !!(value & 0x80000000);
923
+ this.Z = value === 0;
924
+ }
925
+ // MRS
926
+ else if (opcode === 0b1111001111101111 && opcode2 >> 12 == 0b1000) {
927
+ const SYSm = opcode2 & 0xff;
928
+ const Rd = (opcode2 >> 8) & 0xf;
929
+ this.registers[Rd] = this.readSpecialRegister(SYSm);
930
+ this.PC += 2;
931
+ this.cycles += 2;
932
+ }
933
+ // MSR
934
+ else if (opcode >> 4 === 0b111100111000 && opcode2 >> 8 == 0b10001000) {
935
+ const SYSm = opcode2 & 0xff;
936
+ const Rn = opcode & 0xf;
937
+ this.writeSpecialRegister(SYSm, this.registers[Rn]);
938
+ this.PC += 2;
939
+ this.cycles += 2;
940
+ }
941
+ // MULS
942
+ else if (opcode >> 6 === 0b0100001101) {
943
+ const Rn = (opcode >> 3) & 0x7;
944
+ const Rdm = opcode & 0x7;
945
+ const result = Math.imul(this.registers[Rn], this.registers[Rdm]);
946
+ this.registers[Rdm] = result;
947
+ this.N = !!(result & 0x80000000);
948
+ this.Z = (result & 0xffffffff) === 0;
949
+ }
950
+ // MVNS
951
+ else if (opcode >> 6 === 0b0100001111) {
952
+ const Rm = (opcode >> 3) & 7;
953
+ const Rd = opcode & 7;
954
+ const result = ~this.registers[Rm];
955
+ this.registers[Rd] = result;
956
+ this.N = !!(result & 0x80000000);
957
+ this.Z = result === 0;
958
+ }
959
+ // ORRS (Encoding T2)
960
+ else if (opcode >> 6 === 0b0100001100) {
961
+ const Rm = (opcode >> 3) & 0x7;
962
+ const Rdn = opcode & 0x7;
963
+ const result = this.registers[Rdn] | this.registers[Rm];
964
+ this.registers[Rdn] = result;
965
+ this.N = !!(result & 0x80000000);
966
+ this.Z = (result & 0xffffffff) === 0;
967
+ }
968
+ // POP
969
+ else if (opcode >> 9 === 0b1011110) {
970
+ const P = (opcode >> 8) & 1;
971
+ let address = this.SP;
972
+ for (let i = 0; i <= 7; i++) {
973
+ if (opcode & (1 << i)) {
974
+ this.registers[i] = this.readUint32(address);
975
+ address += 4;
976
+ this.cycles++;
977
+ }
978
+ }
979
+ if (P) {
980
+ this.SP = address + 4;
981
+ this.BXWritePC(this.readUint32(address));
982
+ this.cycles += 2;
983
+ }
984
+ else {
985
+ this.SP = address;
986
+ }
987
+ }
988
+ // PUSH
989
+ else if (opcode >> 9 === 0b1011010) {
990
+ let bitCount = 0;
991
+ for (let i = 0; i <= 8; i++) {
992
+ if (opcode & (1 << i)) {
993
+ bitCount++;
994
+ }
995
+ }
996
+ let address = this.SP - 4 * bitCount;
997
+ for (let i = 0; i <= 7; i++) {
998
+ if (opcode & (1 << i)) {
999
+ this.writeUint32(address, this.registers[i]);
1000
+ this.cycles++;
1001
+ address += 4;
1002
+ }
1003
+ }
1004
+ if (opcode & (1 << 8)) {
1005
+ this.writeUint32(address, this.registers[14]);
1006
+ }
1007
+ this.SP -= 4 * bitCount;
1008
+ }
1009
+ // REV
1010
+ else if (opcode >> 6 === 0b1011101000) {
1011
+ const Rm = (opcode >> 3) & 0x7;
1012
+ const Rd = opcode & 0x7;
1013
+ const input = this.registers[Rm];
1014
+ this.registers[Rd] =
1015
+ ((input & 0xff) << 24) |
1016
+ (((input >> 8) & 0xff) << 16) |
1017
+ (((input >> 16) & 0xff) << 8) |
1018
+ ((input >> 24) & 0xff);
1019
+ }
1020
+ // REV16
1021
+ else if (opcode >> 6 === 0b1011101001) {
1022
+ const Rm = (opcode >> 3) & 0x7;
1023
+ const Rd = opcode & 0x7;
1024
+ const input = this.registers[Rm];
1025
+ this.registers[Rd] =
1026
+ (((input >> 16) & 0xff) << 24) |
1027
+ (((input >> 24) & 0xff) << 16) |
1028
+ ((input & 0xff) << 8) |
1029
+ ((input >> 8) & 0xff);
1030
+ }
1031
+ // REVSH
1032
+ else if (opcode >> 6 === 0b1011101011) {
1033
+ const Rm = (opcode >> 3) & 0x7;
1034
+ const Rd = opcode & 0x7;
1035
+ const input = this.registers[Rm];
1036
+ this.registers[Rd] = signExtend16(((input & 0xff) << 8) | ((input >> 8) & 0xff));
1037
+ }
1038
+ // ROR
1039
+ else if (opcode >> 6 === 0b0100000111) {
1040
+ const Rm = (opcode >> 3) & 0x7;
1041
+ const Rdn = opcode & 0x7;
1042
+ const input = this.registers[Rdn];
1043
+ const shift = (this.registers[Rm] & 0xff) % 32;
1044
+ const result = (input >>> shift) | (input << (32 - shift));
1045
+ this.registers[Rdn] = result;
1046
+ this.N = !!(result & 0x80000000);
1047
+ this.Z = result === 0;
1048
+ this.C = !!(result & 0x80000000);
1049
+ }
1050
+ // NEGS / RSBS
1051
+ else if (opcode >> 6 === 0b0100001001) {
1052
+ const Rn = (opcode >> 3) & 0x7;
1053
+ const Rd = opcode & 0x7;
1054
+ this.registers[Rd] = this.substractUpdateFlags(0, this.registers[Rn]);
1055
+ }
1056
+ // NOP
1057
+ else if (opcode === 0b1011111100000000) {
1058
+ // Do nothing!
1059
+ }
1060
+ // SBCS (Encoding T1)
1061
+ else if (opcode >> 6 === 0b0100000110) {
1062
+ const Rm = (opcode >> 3) & 0x7;
1063
+ const Rdn = opcode & 0x7;
1064
+ this.registers[Rdn] = this.substractUpdateFlags(this.registers[Rdn], this.registers[Rm] + (1 - (this.C ? 1 : 0)));
1065
+ }
1066
+ // SEV
1067
+ else if (opcode === 0b1011111101000000) {
1068
+ this.logger.info(LOG_NAME, 'SEV');
1069
+ }
1070
+ // STMIA
1071
+ else if (opcode >> 11 === 0b11000) {
1072
+ const Rn = (opcode >> 8) & 0x7;
1073
+ const registers = opcode & 0xff;
1074
+ let address = this.registers[Rn];
1075
+ for (let i = 0; i < 8; i++) {
1076
+ if (registers & (1 << i)) {
1077
+ this.writeUint32(address, this.registers[i]);
1078
+ address += 4;
1079
+ this.cycles++;
1080
+ }
1081
+ }
1082
+ // Write back
1083
+ if (!(registers & (1 << Rn))) {
1084
+ this.registers[Rn] = address;
1085
+ }
1086
+ }
1087
+ // STR (immediate)
1088
+ else if (opcode >> 11 === 0b01100) {
1089
+ const imm5 = ((opcode >> 6) & 0x1f) << 2;
1090
+ const Rn = (opcode >> 3) & 0x7;
1091
+ const Rt = opcode & 0x7;
1092
+ const address = this.registers[Rn] + imm5;
1093
+ this.cycles += this.cyclesIO(address, true);
1094
+ this.writeUint32(address, this.registers[Rt]);
1095
+ }
1096
+ // STR (sp + immediate)
1097
+ else if (opcode >> 11 === 0b10010) {
1098
+ const Rt = (opcode >> 8) & 0x7;
1099
+ const imm8 = opcode & 0xff;
1100
+ const address = this.SP + (imm8 << 2);
1101
+ this.cycles += this.cyclesIO(address, true);
1102
+ this.writeUint32(address, this.registers[Rt]);
1103
+ }
1104
+ // STR (register)
1105
+ else if (opcode >> 9 === 0b0101000) {
1106
+ const Rm = (opcode >> 6) & 0x7;
1107
+ const Rn = (opcode >> 3) & 0x7;
1108
+ const Rt = opcode & 0x7;
1109
+ const address = this.registers[Rm] + this.registers[Rn];
1110
+ this.cycles += this.cyclesIO(address, true);
1111
+ this.writeUint32(address, this.registers[Rt]);
1112
+ }
1113
+ // STRB (immediate)
1114
+ else if (opcode >> 11 === 0b01110) {
1115
+ const imm5 = (opcode >> 6) & 0x1f;
1116
+ const Rn = (opcode >> 3) & 0x7;
1117
+ const Rt = opcode & 0x7;
1118
+ const address = this.registers[Rn] + imm5;
1119
+ this.cycles += this.cyclesIO(address, true);
1120
+ this.writeUint8(address, this.registers[Rt]);
1121
+ }
1122
+ // STRB (register)
1123
+ else if (opcode >> 9 === 0b0101010) {
1124
+ const Rm = (opcode >> 6) & 0x7;
1125
+ const Rn = (opcode >> 3) & 0x7;
1126
+ const Rt = opcode & 0x7;
1127
+ const address = this.registers[Rm] + this.registers[Rn];
1128
+ this.cycles += this.cyclesIO(address, true);
1129
+ this.writeUint8(address, this.registers[Rt]);
1130
+ }
1131
+ // STRH (immediate)
1132
+ else if (opcode >> 11 === 0b10000) {
1133
+ const imm5 = ((opcode >> 6) & 0x1f) << 1;
1134
+ const Rn = (opcode >> 3) & 0x7;
1135
+ const Rt = opcode & 0x7;
1136
+ const address = this.registers[Rn] + imm5;
1137
+ this.cycles += this.cyclesIO(address, true);
1138
+ this.writeUint16(address, this.registers[Rt]);
1139
+ }
1140
+ // STRH (register)
1141
+ else if (opcode >> 9 === 0b0101001) {
1142
+ const Rm = (opcode >> 6) & 0x7;
1143
+ const Rn = (opcode >> 3) & 0x7;
1144
+ const Rt = opcode & 0x7;
1145
+ const address = this.registers[Rm] + this.registers[Rn];
1146
+ this.cycles += this.cyclesIO(address, true);
1147
+ this.writeUint16(address, this.registers[Rt]);
1148
+ }
1149
+ // SUB (SP minus immediate)
1150
+ else if (opcode >> 7 === 0b101100001) {
1151
+ const imm32 = (opcode & 0x7f) << 2;
1152
+ this.SP -= imm32;
1153
+ }
1154
+ // SUBS (Encoding T1)
1155
+ else if (opcode >> 9 === 0b0001111) {
1156
+ const imm3 = (opcode >> 6) & 0x7;
1157
+ const Rn = (opcode >> 3) & 0x7;
1158
+ const Rd = opcode & 0x7;
1159
+ this.registers[Rd] = this.substractUpdateFlags(this.registers[Rn], imm3);
1160
+ }
1161
+ // SUBS (Encoding T2)
1162
+ else if (opcode >> 11 === 0b00111) {
1163
+ const imm8 = opcode & 0xff;
1164
+ const Rdn = (opcode >> 8) & 0x7;
1165
+ this.registers[Rdn] = this.substractUpdateFlags(this.registers[Rdn], imm8);
1166
+ }
1167
+ // SUBS (register)
1168
+ else if (opcode >> 9 === 0b0001101) {
1169
+ const Rm = (opcode >> 6) & 0x7;
1170
+ const Rn = (opcode >> 3) & 0x7;
1171
+ const Rd = opcode & 0x7;
1172
+ this.registers[Rd] = this.substractUpdateFlags(this.registers[Rn], this.registers[Rm]);
1173
+ }
1174
+ // SVC
1175
+ else if (opcode >> 8 === 0b11011111) {
1176
+ this.pendingSVCall = true;
1177
+ this.interruptsUpdated = true;
1178
+ }
1179
+ // SXTB
1180
+ else if (opcode >> 6 === 0b1011001001) {
1181
+ const Rm = (opcode >> 3) & 0x7;
1182
+ const Rd = opcode & 0x7;
1183
+ this.registers[Rd] = signExtend8(this.registers[Rm]);
1184
+ }
1185
+ // SXTH
1186
+ else if (opcode >> 6 === 0b1011001000) {
1187
+ const Rm = (opcode >> 3) & 0x7;
1188
+ const Rd = opcode & 0x7;
1189
+ this.registers[Rd] = signExtend16(this.registers[Rm]);
1190
+ }
1191
+ // TST
1192
+ else if (opcode >> 6 == 0b0100001000) {
1193
+ const Rm = (opcode >> 3) & 0x7;
1194
+ const Rn = opcode & 0x7;
1195
+ const result = this.registers[Rn] & this.registers[Rm];
1196
+ this.N = !!(result & 0x80000000);
1197
+ this.Z = result === 0;
1198
+ }
1199
+ // UDF
1200
+ else if (opcode >> 8 == 0b11011110) {
1201
+ const imm8 = opcode & 0xff;
1202
+ this.breakRewind = 2;
1203
+ this.rp2040.onBreak(imm8);
1204
+ }
1205
+ // UDF (Encoding T2)
1206
+ else if (opcode >> 4 === 0b111101111111 && opcode2 >> 12 === 0b1010) {
1207
+ const imm4 = opcode & 0xf;
1208
+ const imm12 = opcode2 & 0xfff;
1209
+ this.breakRewind = 4;
1210
+ this.rp2040.onBreak((imm4 << 12) | imm12);
1211
+ this.PC += 2;
1212
+ }
1213
+ // UXTB
1214
+ else if (opcode >> 6 == 0b1011001011) {
1215
+ const Rm = (opcode >> 3) & 0x7;
1216
+ const Rd = opcode & 0x7;
1217
+ this.registers[Rd] = this.registers[Rm] & 0xff;
1218
+ }
1219
+ // UXTH
1220
+ else if (opcode >> 6 == 0b1011001010) {
1221
+ const Rm = (opcode >> 3) & 0x7;
1222
+ const Rd = opcode & 0x7;
1223
+ this.registers[Rd] = this.registers[Rm] & 0xffff;
1224
+ }
1225
+ // WFE
1226
+ else if (opcode === 0b1011111100100000) {
1227
+ this.cycles++;
1228
+ if (this.eventRegistered) {
1229
+ this.eventRegistered = false;
1230
+ }
1231
+ else {
1232
+ this.waiting = true;
1233
+ }
1234
+ }
1235
+ // WFI
1236
+ else if (opcode === 0b1011111100110000) {
1237
+ this.cycles++;
1238
+ this.waiting = true;
1239
+ }
1240
+ // YIELD
1241
+ else if (opcode === 0b1011111100010000) {
1242
+ // do nothing for now. Wait for event!
1243
+ this.logger.info(LOG_NAME, 'Yield');
1244
+ }
1245
+ else {
1246
+ this.logger.warn(LOG_NAME, `Warning: Instruction at ${opcodePC.toString(16)} is not implemented yet!`);
1247
+ this.logger.warn(LOG_NAME, `Opcode: 0x${opcode.toString(16)} (0x${opcode2.toString(16)})`);
1248
+ }
1249
+ }
1250
+ }
1251
+ exports.CortexM0Core = CortexM0Core;