rp2040js 0.17.7 → 0.17.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,20 +6,21 @@ Raspberry Pi Pico Emulator for the [Wokwi Simulation Platform](https://wokwi.com
6
6
 
7
7
  If you are just looking to play around with the Raspberry Pi Pico Simulator, check out the Wokwi Simulator:
8
8
 
9
- * [Raspberry Pi Pico Traffic Light](https://wokwi.com/arduino/projects/297322571959894536)
10
- * [LCD1602 Hello World](https://wokwi.com/arduino/projects/297323005822894602)
11
- * [MicroPython Blink](https://wokwi.com/arduino/projects/300504213470839309)
12
- * [MicroPython 7-Segment Counter](https://wokwi.com/arduino/projects/300210834979684872)
9
+ - [Raspberry Pi Pico Traffic Light](https://wokwi.com/arduino/projects/297322571959894536)
10
+ - [LCD1602 Hello World](https://wokwi.com/arduino/projects/297323005822894602)
11
+ - [MicroPython Blink](https://wokwi.com/arduino/projects/300504213470839309)
12
+ - [MicroPython 7-Segment Counter](https://wokwi.com/arduino/projects/300210834979684872)
13
13
 
14
14
  For more information, take a look at the [wokwi-pi-pico docs](https://docs.wokwi.com/parts/wokwi-pi-pico) and the [Pi Pico MicroPython Guide](https://docs.wokwi.com/guides/micropython).
15
15
 
16
16
  If you want to develop your own application using the Raspberry Pi Pico simulator, the following examples may be helpful:
17
17
 
18
- * [Blink LEDs with RP2040js, from scratch](https://stackblitz.com/edit/rp2040js-blink?file=index.ts) - Press "Run" and patiently wait for the code to compile ;-)
18
+ - [Blink LEDs with RP2040js, from scratch](https://stackblitz.com/edit/rp2040js-blink?file=index.ts) - Press "Run" and patiently wait for the code to compile ;-)
19
19
 
20
20
  ## Run the demo project
21
21
 
22
22
  ### Native code
23
+
23
24
  You'd need to get `hello_uart.hex` by building it from the [pico-examples repo](https://github.com/raspberrypi/pico-examples/tree/master/uart/hello_uart), then copy it to the rp2040js root directory and run:
24
25
 
25
26
  ```
@@ -28,6 +29,7 @@ npm start
28
29
  ```
29
30
 
30
31
  ### MicroPython code
32
+
31
33
  To run the MicroPython demo, first download [rp2-pico-20210902-v1.17.uf2](https://micropython.org/resources/firmware/rp2-pico-20210902-v1.17.uf2), place it in the rp2040js root directory, then run:
32
34
 
33
35
  ```
@@ -35,14 +37,27 @@ npm install
35
37
  npm run start:micropython
36
38
  ```
37
39
 
38
- and enjoy the MicroPython REPL! Quit the REPL with Ctrl+X.
40
+ and enjoy the MicroPython REPL! Quit the REPL with Ctrl+X. A different UF2 image can be loaded by supplying the `--image` option:
41
+
42
+ ```
43
+ npm run start:micropython -- --image=my_image.uf2
44
+ ```
39
45
 
40
- You can replace rp2-pico-20210902-v1.17.uf2 with any recent MicroPython or CircuitPython release built for the RP2040.
46
+ A GDB server on port 3333 can be enabled by specifying the `--gdb` flag:
47
+
48
+ ```
49
+ npm run start:micropython -- --gdb
50
+ ```
51
+
52
+ For using the MicroPython demo code in tests, the `--expect-text` can come handy: it will look for the given text in the serial output and exit with code 0 if found, or 1 if not found. You can find an example in [the MicroPython CI test](./github/workflows/ci-micropython.yml).
53
+
54
+ #### Filesystem support
41
55
 
42
56
  With MicroPython – and probably also CircuitPython – you can use the filesystem on the Pico. This becomes useful as more than one script file is used in your code. Just put a [LittleFS](https://github.com/littlefs-project/littlefs) formatted filesystem image called `littlefs.img` into the rp2040js root directory, and your `main.py` will be automatically started from there.
43
57
 
44
58
  A simple way to create a suitable LittleFS image containing your script files is outlined in [create_littlefs_image.py](https://github.com/tomods/GrinderController/blob/358ad3e0f795d8cc0bdf4f21bb35f806871d433f/tools/create_littlefs_image.py).
45
59
  So, using [littlefs-python](https://pypi.org/project/littlefs-python/), you can do the following:
60
+
46
61
  ```python
47
62
  from littlefs import LittleFS
48
63
  files = ['your.py', 'files.py', 'here.py', 'main.py']
@@ -66,4 +81,4 @@ Currently, the filesystem is not writeable, as the SSI peripheral required for f
66
81
 
67
82
  ## License
68
83
 
69
- Released under the MIT licence. Copyright (c) 2021, Uri Shaked.
84
+ Released under the MIT licence. Copyright (c) 2021-2023, Uri Shaked.
@@ -79,7 +79,7 @@ export declare class CortexM0Core {
79
79
  BXWritePC(address: number): void;
80
80
  private substractUpdateFlags;
81
81
  private addUpdateFlags;
82
- slowIO(addr: number): boolean;
82
+ cyclesIO(addr: number, write?: boolean): 3 | 0 | 1 | 4;
83
83
  executeInstruction(): void;
84
84
  }
85
85
  export {};
@@ -502,9 +502,15 @@ class CortexM0Core {
502
502
  this.V = (result | 0) === signedSum ? false : true;
503
503
  return result & 0xffffffff;
504
504
  }
505
- slowIO(addr) {
505
+ cyclesIO(addr, write = false) {
506
506
  addr = addr >>> 0;
507
- return addr < rp2040_1.SIO_START_ADDRESS || addr > rp2040_1.SIO_START_ADDRESS + 0x10000000;
507
+ if (addr >= rp2040_1.SIO_START_ADDRESS && addr < rp2040_1.SIO_START_ADDRESS + 0x10000000) {
508
+ return 0;
509
+ }
510
+ if (addr >= rp2040_1.APB_START_ADDRESS && addr < rp2040_1.APB_START_ADDRESS + 0x10000000) {
511
+ return write ? 4 : 3;
512
+ }
513
+ return 1;
508
514
  }
509
515
  executeInstruction() {
510
516
  if (this.interruptsUpdated) {
@@ -759,6 +765,7 @@ class CortexM0Core {
759
765
  const Rn = (opcode >> 3) & 0x7;
760
766
  const Rt = opcode & 0x7;
761
767
  const addr = this.registers[Rn] + imm5;
768
+ this.cycles += this.cyclesIO(addr);
762
769
  this.registers[Rt] = this.readUint32(addr);
763
770
  }
764
771
  // LDR (sp + immediate)
@@ -766,6 +773,7 @@ class CortexM0Core {
766
773
  const Rt = (opcode >> 8) & 0x7;
767
774
  const imm8 = opcode & 0xff;
768
775
  const addr = this.SP + (imm8 << 2);
776
+ this.cycles += this.cyclesIO(addr);
769
777
  this.registers[Rt] = this.readUint32(addr);
770
778
  }
771
779
  // LDR (literal)
@@ -774,6 +782,7 @@ class CortexM0Core {
774
782
  const Rt = (opcode >> 8) & 7;
775
783
  const nextPC = this.PC + 2;
776
784
  const addr = (nextPC & 0xfffffffc) + imm8;
785
+ this.cycles += this.cyclesIO(addr);
777
786
  this.registers[Rt] = this.readUint32(addr);
778
787
  }
779
788
  // LDR (register)
@@ -782,9 +791,7 @@ class CortexM0Core {
782
791
  const Rn = (opcode >> 3) & 0x7;
783
792
  const Rt = opcode & 0x7;
784
793
  const addr = this.registers[Rm] + this.registers[Rn];
785
- if (this.slowIO(addr)) {
786
- this.cycles++;
787
- }
794
+ this.cycles += this.cyclesIO(addr);
788
795
  this.registers[Rt] = this.readUint32(addr);
789
796
  }
790
797
  // LDRB (immediate)
@@ -793,9 +800,7 @@ class CortexM0Core {
793
800
  const Rn = (opcode >> 3) & 0x7;
794
801
  const Rt = opcode & 0x7;
795
802
  const addr = this.registers[Rn] + imm5;
796
- if (this.slowIO(addr)) {
797
- this.cycles++;
798
- }
803
+ this.cycles += this.cyclesIO(addr);
799
804
  this.registers[Rt] = this.readUint8(addr);
800
805
  }
801
806
  // LDRB (register)
@@ -804,9 +809,7 @@ class CortexM0Core {
804
809
  const Rn = (opcode >> 3) & 0x7;
805
810
  const Rt = opcode & 0x7;
806
811
  const addr = this.registers[Rm] + this.registers[Rn];
807
- if (this.slowIO(addr)) {
808
- this.cycles++;
809
- }
812
+ this.cycles += this.cyclesIO(addr);
810
813
  this.registers[Rt] = this.readUint8(addr);
811
814
  }
812
815
  // LDRH (immediate)
@@ -815,9 +818,7 @@ class CortexM0Core {
815
818
  const Rn = (opcode >> 3) & 0x7;
816
819
  const Rt = opcode & 0x7;
817
820
  const addr = this.registers[Rn] + (imm5 << 1);
818
- if (this.slowIO(addr)) {
819
- this.cycles++;
820
- }
821
+ this.cycles += this.cyclesIO(addr);
821
822
  this.registers[Rt] = this.readUint16(addr);
822
823
  }
823
824
  // LDRH (register)
@@ -826,9 +827,7 @@ class CortexM0Core {
826
827
  const Rn = (opcode >> 3) & 0x7;
827
828
  const Rt = opcode & 0x7;
828
829
  const addr = this.registers[Rm] + this.registers[Rn];
829
- if (this.slowIO(addr)) {
830
- this.cycles++;
831
- }
830
+ this.cycles += this.cyclesIO(addr);
832
831
  this.registers[Rt] = this.readUint16(addr);
833
832
  }
834
833
  // LDRSB
@@ -837,9 +836,7 @@ class CortexM0Core {
837
836
  const Rn = (opcode >> 3) & 0x7;
838
837
  const Rt = opcode & 0x7;
839
838
  const addr = this.registers[Rm] + this.registers[Rn];
840
- if (this.slowIO(addr)) {
841
- this.cycles++;
842
- }
839
+ this.cycles += this.cyclesIO(addr);
843
840
  this.registers[Rt] = signExtend8(this.readUint8(addr));
844
841
  }
845
842
  // LDRSH
@@ -848,9 +845,7 @@ class CortexM0Core {
848
845
  const Rn = (opcode >> 3) & 0x7;
849
846
  const Rt = opcode & 0x7;
850
847
  const addr = this.registers[Rm] + this.registers[Rn];
851
- if (this.slowIO(addr)) {
852
- this.cycles++;
853
- }
848
+ this.cycles += this.cyclesIO(addr);
854
849
  this.registers[Rt] = signExtend16(this.readUint16(addr));
855
850
  }
856
851
  // LSLS (immediate)
@@ -1091,9 +1086,7 @@ class CortexM0Core {
1091
1086
  const Rn = (opcode >> 3) & 0x7;
1092
1087
  const Rt = opcode & 0x7;
1093
1088
  const address = this.registers[Rn] + imm5;
1094
- if (this.slowIO(address)) {
1095
- this.cycles++;
1096
- }
1089
+ this.cycles += this.cyclesIO(address, true);
1097
1090
  this.writeUint32(address, this.registers[Rt]);
1098
1091
  }
1099
1092
  // STR (sp + immediate)
@@ -1101,9 +1094,7 @@ class CortexM0Core {
1101
1094
  const Rt = (opcode >> 8) & 0x7;
1102
1095
  const imm8 = opcode & 0xff;
1103
1096
  const address = this.SP + (imm8 << 2);
1104
- if (this.slowIO(address)) {
1105
- this.cycles++;
1106
- }
1097
+ this.cycles += this.cyclesIO(address, true);
1107
1098
  this.writeUint32(address, this.registers[Rt]);
1108
1099
  }
1109
1100
  // STR (register)
@@ -1112,9 +1103,7 @@ class CortexM0Core {
1112
1103
  const Rn = (opcode >> 3) & 0x7;
1113
1104
  const Rt = opcode & 0x7;
1114
1105
  const address = this.registers[Rm] + this.registers[Rn];
1115
- if (this.slowIO(address)) {
1116
- this.cycles++;
1117
- }
1106
+ this.cycles += this.cyclesIO(address, true);
1118
1107
  this.writeUint32(address, this.registers[Rt]);
1119
1108
  }
1120
1109
  // STRB (immediate)
@@ -1123,9 +1112,7 @@ class CortexM0Core {
1123
1112
  const Rn = (opcode >> 3) & 0x7;
1124
1113
  const Rt = opcode & 0x7;
1125
1114
  const address = this.registers[Rn] + imm5;
1126
- if (this.slowIO(address)) {
1127
- this.cycles++;
1128
- }
1115
+ this.cycles += this.cyclesIO(address, true);
1129
1116
  this.writeUint8(address, this.registers[Rt]);
1130
1117
  }
1131
1118
  // STRB (register)
@@ -1134,9 +1121,7 @@ class CortexM0Core {
1134
1121
  const Rn = (opcode >> 3) & 0x7;
1135
1122
  const Rt = opcode & 0x7;
1136
1123
  const address = this.registers[Rm] + this.registers[Rn];
1137
- if (this.slowIO(address)) {
1138
- this.cycles++;
1139
- }
1124
+ this.cycles += this.cyclesIO(address, true);
1140
1125
  this.writeUint8(address, this.registers[Rt]);
1141
1126
  }
1142
1127
  // STRH (immediate)
@@ -1145,9 +1130,7 @@ class CortexM0Core {
1145
1130
  const Rn = (opcode >> 3) & 0x7;
1146
1131
  const Rt = opcode & 0x7;
1147
1132
  const address = this.registers[Rn] + imm5;
1148
- if (this.slowIO(address)) {
1149
- this.cycles++;
1150
- }
1133
+ this.cycles += this.cyclesIO(address, true);
1151
1134
  this.writeUint16(address, this.registers[Rt]);
1152
1135
  }
1153
1136
  // STRH (register)
@@ -1156,9 +1139,7 @@ class CortexM0Core {
1156
1139
  const Rn = (opcode >> 3) & 0x7;
1157
1140
  const Rt = opcode & 0x7;
1158
1141
  const address = this.registers[Rm] + this.registers[Rn];
1159
- if (this.slowIO(address)) {
1160
- this.cycles++;
1161
- }
1142
+ this.cycles += this.cyclesIO(address, true);
1162
1143
  this.writeUint16(address, this.registers[Rt]);
1163
1144
  }
1164
1145
  // SUB (SP minus immediate)
@@ -89,8 +89,8 @@ class Interpolator {
89
89
  const overf0 = Boolean((input0 >>> ctrl0.shift) & ~msbmask0);
90
90
  const overf1 = Boolean((input1 >>> ctrl1.shift) & ~msbmask1);
91
91
  const overf = overf0 || overf1;
92
- const sextmask0 = (uresult0 & (1 << ctrl0.maskMSB)) ? (-1 << ctrl0.maskMSB) : 0;
93
- const sextmask1 = (uresult1 & (1 << ctrl1.maskMSB)) ? (-1 << ctrl1.maskMSB) : 0;
92
+ const sextmask0 = uresult0 & (1 << ctrl0.maskMSB) ? -1 << ctrl0.maskMSB : 0;
93
+ const sextmask1 = uresult1 & (1 << ctrl1.maskMSB) ? -1 << ctrl1.maskMSB : 0;
94
94
  const sresult0 = uresult0 | sextmask0;
95
95
  const sresult1 = uresult1 | sextmask1;
96
96
  const result0 = ctrl0.signed ? sresult0 : uresult0;
@@ -98,8 +98,16 @@ class Interpolator {
98
98
  const addresult0 = this.base0 + (ctrl0.addRaw ? input0 : result0);
99
99
  const addresult1 = this.base1 + (ctrl1.addRaw ? input1 : result1);
100
100
  const addresult2 = this.base2 + result0 + (do_blend ? 0 : result1);
101
- const uclamp0 = bit_1.u32(result0) < bit_1.u32(this.base0) ? this.base0 : (bit_1.u32(result0) > bit_1.u32(this.base1) ? this.base1 : result0);
102
- const sclamp0 = bit_1.s32(result0) < bit_1.s32(this.base0) ? this.base0 : (bit_1.s32(result0) > bit_1.s32(this.base1) ? this.base1 : result0);
101
+ const uclamp0 = bit_1.u32(result0) < bit_1.u32(this.base0)
102
+ ? this.base0
103
+ : bit_1.u32(result0) > bit_1.u32(this.base1)
104
+ ? this.base1
105
+ : result0;
106
+ const sclamp0 = bit_1.s32(result0) < bit_1.s32(this.base0)
107
+ ? this.base0
108
+ : bit_1.s32(result0) > bit_1.s32(this.base1)
109
+ ? this.base1
110
+ : result0;
103
111
  const clamp0 = ctrl0.signed ? sclamp0 : uclamp0;
104
112
  const alpha1 = result1 & 0xff;
105
113
  const ublend1 = bit_1.u32(this.base0) + (Math.floor((alpha1 * (bit_1.u32(this.base1) - bit_1.u32(this.base0))) / 256) | 0);
@@ -205,7 +205,7 @@ class RPUSBController extends peripheral_1.BasePeripheral {
205
205
  (_b = this.onEndpointWrite) === null || _b === void 0 ? void 0 : _b.call(this, endpoint, buffer);
206
206
  }
207
207
  }
208
- if (doubleBuffer && ((value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_AVAILABLE)) {
208
+ if (doubleBuffer && (value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_AVAILABLE) {
209
209
  const bufferLength = (value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_LEN_MASK;
210
210
  const bufferOffset = this.getEndpointBufferOffset(endpoint, bufferOut) + USB_BUF1_OFFSET;
211
211
  this.debug(`Start USB transfer, endPoint=${endpoint}, direction=${bufferOut ? 'out' : 'in'} buffer=${bufferOffset.toString(16)} length=${bufferLength}`);
@@ -15,6 +15,7 @@ import { RPSIO } from './sio';
15
15
  import { Logger } from './utils/logging';
16
16
  export declare const FLASH_START_ADDRESS = 268435456;
17
17
  export declare const RAM_START_ADDRESS = 536870912;
18
+ export declare const APB_START_ADDRESS = 1073741824;
18
19
  export declare const DPRAM_START_ADDRESS = 1343225856;
19
20
  export declare const SIO_START_ADDRESS = 3489660928;
20
21
  export declare class RP2040 {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RP2040 = exports.SIO_START_ADDRESS = exports.DPRAM_START_ADDRESS = exports.RAM_START_ADDRESS = exports.FLASH_START_ADDRESS = void 0;
3
+ exports.RP2040 = exports.SIO_START_ADDRESS = exports.DPRAM_START_ADDRESS = exports.APB_START_ADDRESS = exports.RAM_START_ADDRESS = exports.FLASH_START_ADDRESS = void 0;
4
4
  const realtime_clock_1 = require("./clock/realtime-clock");
5
5
  const cortex_m0_core_1 = require("./cortex-m0-core");
6
6
  const gpio_pin_1 = require("./gpio-pin");
@@ -29,6 +29,7 @@ const logging_1 = require("./utils/logging");
29
29
  const tbman_1 = require("./peripherals/tbman");
30
30
  exports.FLASH_START_ADDRESS = 0x10000000;
31
31
  exports.RAM_START_ADDRESS = 0x20000000;
32
+ exports.APB_START_ADDRESS = 0x40000000;
32
33
  exports.DPRAM_START_ADDRESS = 0x50100000;
33
34
  exports.SIO_START_ADDRESS = 0xd0000000;
34
35
  const LOG_NAME = 'RP2040';
@@ -79,7 +79,7 @@ export declare class CortexM0Core {
79
79
  BXWritePC(address: number): void;
80
80
  private substractUpdateFlags;
81
81
  private addUpdateFlags;
82
- slowIO(addr: number): boolean;
82
+ cyclesIO(addr: number, write?: boolean): 3 | 0 | 1 | 4;
83
83
  executeInstruction(): void;
84
84
  }
85
85
  export {};
@@ -1,5 +1,5 @@
1
1
  import { MAX_HARDWARE_IRQ } from './irq';
2
- import { SIO_START_ADDRESS } from './rp2040';
2
+ import { APB_START_ADDRESS, SIO_START_ADDRESS } from './rp2040';
3
3
  /* eslint-disable @typescript-eslint/no-unused-vars */
4
4
  const EXC_RESET = 1;
5
5
  const EXC_NMI = 2;
@@ -499,9 +499,15 @@ export class CortexM0Core {
499
499
  this.V = (result | 0) === signedSum ? false : true;
500
500
  return result & 0xffffffff;
501
501
  }
502
- slowIO(addr) {
502
+ cyclesIO(addr, write = false) {
503
503
  addr = addr >>> 0;
504
- return addr < SIO_START_ADDRESS || addr > SIO_START_ADDRESS + 0x10000000;
504
+ if (addr >= SIO_START_ADDRESS && addr < SIO_START_ADDRESS + 0x10000000) {
505
+ return 0;
506
+ }
507
+ if (addr >= APB_START_ADDRESS && addr < APB_START_ADDRESS + 0x10000000) {
508
+ return write ? 4 : 3;
509
+ }
510
+ return 1;
505
511
  }
506
512
  executeInstruction() {
507
513
  if (this.interruptsUpdated) {
@@ -756,6 +762,7 @@ export class CortexM0Core {
756
762
  const Rn = (opcode >> 3) & 0x7;
757
763
  const Rt = opcode & 0x7;
758
764
  const addr = this.registers[Rn] + imm5;
765
+ this.cycles += this.cyclesIO(addr);
759
766
  this.registers[Rt] = this.readUint32(addr);
760
767
  }
761
768
  // LDR (sp + immediate)
@@ -763,6 +770,7 @@ export class CortexM0Core {
763
770
  const Rt = (opcode >> 8) & 0x7;
764
771
  const imm8 = opcode & 0xff;
765
772
  const addr = this.SP + (imm8 << 2);
773
+ this.cycles += this.cyclesIO(addr);
766
774
  this.registers[Rt] = this.readUint32(addr);
767
775
  }
768
776
  // LDR (literal)
@@ -771,6 +779,7 @@ export class CortexM0Core {
771
779
  const Rt = (opcode >> 8) & 7;
772
780
  const nextPC = this.PC + 2;
773
781
  const addr = (nextPC & 0xfffffffc) + imm8;
782
+ this.cycles += this.cyclesIO(addr);
774
783
  this.registers[Rt] = this.readUint32(addr);
775
784
  }
776
785
  // LDR (register)
@@ -779,9 +788,7 @@ export class CortexM0Core {
779
788
  const Rn = (opcode >> 3) & 0x7;
780
789
  const Rt = opcode & 0x7;
781
790
  const addr = this.registers[Rm] + this.registers[Rn];
782
- if (this.slowIO(addr)) {
783
- this.cycles++;
784
- }
791
+ this.cycles += this.cyclesIO(addr);
785
792
  this.registers[Rt] = this.readUint32(addr);
786
793
  }
787
794
  // LDRB (immediate)
@@ -790,9 +797,7 @@ export class CortexM0Core {
790
797
  const Rn = (opcode >> 3) & 0x7;
791
798
  const Rt = opcode & 0x7;
792
799
  const addr = this.registers[Rn] + imm5;
793
- if (this.slowIO(addr)) {
794
- this.cycles++;
795
- }
800
+ this.cycles += this.cyclesIO(addr);
796
801
  this.registers[Rt] = this.readUint8(addr);
797
802
  }
798
803
  // LDRB (register)
@@ -801,9 +806,7 @@ export class CortexM0Core {
801
806
  const Rn = (opcode >> 3) & 0x7;
802
807
  const Rt = opcode & 0x7;
803
808
  const addr = this.registers[Rm] + this.registers[Rn];
804
- if (this.slowIO(addr)) {
805
- this.cycles++;
806
- }
809
+ this.cycles += this.cyclesIO(addr);
807
810
  this.registers[Rt] = this.readUint8(addr);
808
811
  }
809
812
  // LDRH (immediate)
@@ -812,9 +815,7 @@ export class CortexM0Core {
812
815
  const Rn = (opcode >> 3) & 0x7;
813
816
  const Rt = opcode & 0x7;
814
817
  const addr = this.registers[Rn] + (imm5 << 1);
815
- if (this.slowIO(addr)) {
816
- this.cycles++;
817
- }
818
+ this.cycles += this.cyclesIO(addr);
818
819
  this.registers[Rt] = this.readUint16(addr);
819
820
  }
820
821
  // LDRH (register)
@@ -823,9 +824,7 @@ export class CortexM0Core {
823
824
  const Rn = (opcode >> 3) & 0x7;
824
825
  const Rt = opcode & 0x7;
825
826
  const addr = this.registers[Rm] + this.registers[Rn];
826
- if (this.slowIO(addr)) {
827
- this.cycles++;
828
- }
827
+ this.cycles += this.cyclesIO(addr);
829
828
  this.registers[Rt] = this.readUint16(addr);
830
829
  }
831
830
  // LDRSB
@@ -834,9 +833,7 @@ export class CortexM0Core {
834
833
  const Rn = (opcode >> 3) & 0x7;
835
834
  const Rt = opcode & 0x7;
836
835
  const addr = this.registers[Rm] + this.registers[Rn];
837
- if (this.slowIO(addr)) {
838
- this.cycles++;
839
- }
836
+ this.cycles += this.cyclesIO(addr);
840
837
  this.registers[Rt] = signExtend8(this.readUint8(addr));
841
838
  }
842
839
  // LDRSH
@@ -845,9 +842,7 @@ export class CortexM0Core {
845
842
  const Rn = (opcode >> 3) & 0x7;
846
843
  const Rt = opcode & 0x7;
847
844
  const addr = this.registers[Rm] + this.registers[Rn];
848
- if (this.slowIO(addr)) {
849
- this.cycles++;
850
- }
845
+ this.cycles += this.cyclesIO(addr);
851
846
  this.registers[Rt] = signExtend16(this.readUint16(addr));
852
847
  }
853
848
  // LSLS (immediate)
@@ -1088,9 +1083,7 @@ export class CortexM0Core {
1088
1083
  const Rn = (opcode >> 3) & 0x7;
1089
1084
  const Rt = opcode & 0x7;
1090
1085
  const address = this.registers[Rn] + imm5;
1091
- if (this.slowIO(address)) {
1092
- this.cycles++;
1093
- }
1086
+ this.cycles += this.cyclesIO(address, true);
1094
1087
  this.writeUint32(address, this.registers[Rt]);
1095
1088
  }
1096
1089
  // STR (sp + immediate)
@@ -1098,9 +1091,7 @@ export class CortexM0Core {
1098
1091
  const Rt = (opcode >> 8) & 0x7;
1099
1092
  const imm8 = opcode & 0xff;
1100
1093
  const address = this.SP + (imm8 << 2);
1101
- if (this.slowIO(address)) {
1102
- this.cycles++;
1103
- }
1094
+ this.cycles += this.cyclesIO(address, true);
1104
1095
  this.writeUint32(address, this.registers[Rt]);
1105
1096
  }
1106
1097
  // STR (register)
@@ -1109,9 +1100,7 @@ export class CortexM0Core {
1109
1100
  const Rn = (opcode >> 3) & 0x7;
1110
1101
  const Rt = opcode & 0x7;
1111
1102
  const address = this.registers[Rm] + this.registers[Rn];
1112
- if (this.slowIO(address)) {
1113
- this.cycles++;
1114
- }
1103
+ this.cycles += this.cyclesIO(address, true);
1115
1104
  this.writeUint32(address, this.registers[Rt]);
1116
1105
  }
1117
1106
  // STRB (immediate)
@@ -1120,9 +1109,7 @@ export class CortexM0Core {
1120
1109
  const Rn = (opcode >> 3) & 0x7;
1121
1110
  const Rt = opcode & 0x7;
1122
1111
  const address = this.registers[Rn] + imm5;
1123
- if (this.slowIO(address)) {
1124
- this.cycles++;
1125
- }
1112
+ this.cycles += this.cyclesIO(address, true);
1126
1113
  this.writeUint8(address, this.registers[Rt]);
1127
1114
  }
1128
1115
  // STRB (register)
@@ -1131,9 +1118,7 @@ export class CortexM0Core {
1131
1118
  const Rn = (opcode >> 3) & 0x7;
1132
1119
  const Rt = opcode & 0x7;
1133
1120
  const address = this.registers[Rm] + this.registers[Rn];
1134
- if (this.slowIO(address)) {
1135
- this.cycles++;
1136
- }
1121
+ this.cycles += this.cyclesIO(address, true);
1137
1122
  this.writeUint8(address, this.registers[Rt]);
1138
1123
  }
1139
1124
  // STRH (immediate)
@@ -1142,9 +1127,7 @@ export class CortexM0Core {
1142
1127
  const Rn = (opcode >> 3) & 0x7;
1143
1128
  const Rt = opcode & 0x7;
1144
1129
  const address = this.registers[Rn] + imm5;
1145
- if (this.slowIO(address)) {
1146
- this.cycles++;
1147
- }
1130
+ this.cycles += this.cyclesIO(address, true);
1148
1131
  this.writeUint16(address, this.registers[Rt]);
1149
1132
  }
1150
1133
  // STRH (register)
@@ -1153,9 +1136,7 @@ export class CortexM0Core {
1153
1136
  const Rn = (opcode >> 3) & 0x7;
1154
1137
  const Rt = opcode & 0x7;
1155
1138
  const address = this.registers[Rm] + this.registers[Rn];
1156
- if (this.slowIO(address)) {
1157
- this.cycles++;
1158
- }
1139
+ this.cycles += this.cyclesIO(address, true);
1159
1140
  this.writeUint16(address, this.registers[Rt]);
1160
1141
  }
1161
1142
  // SUB (SP minus immediate)
@@ -85,8 +85,8 @@ export class Interpolator {
85
85
  const overf0 = Boolean((input0 >>> ctrl0.shift) & ~msbmask0);
86
86
  const overf1 = Boolean((input1 >>> ctrl1.shift) & ~msbmask1);
87
87
  const overf = overf0 || overf1;
88
- const sextmask0 = (uresult0 & (1 << ctrl0.maskMSB)) ? (-1 << ctrl0.maskMSB) : 0;
89
- const sextmask1 = (uresult1 & (1 << ctrl1.maskMSB)) ? (-1 << ctrl1.maskMSB) : 0;
88
+ const sextmask0 = uresult0 & (1 << ctrl0.maskMSB) ? -1 << ctrl0.maskMSB : 0;
89
+ const sextmask1 = uresult1 & (1 << ctrl1.maskMSB) ? -1 << ctrl1.maskMSB : 0;
90
90
  const sresult0 = uresult0 | sextmask0;
91
91
  const sresult1 = uresult1 | sextmask1;
92
92
  const result0 = ctrl0.signed ? sresult0 : uresult0;
@@ -94,8 +94,16 @@ export class Interpolator {
94
94
  const addresult0 = this.base0 + (ctrl0.addRaw ? input0 : result0);
95
95
  const addresult1 = this.base1 + (ctrl1.addRaw ? input1 : result1);
96
96
  const addresult2 = this.base2 + result0 + (do_blend ? 0 : result1);
97
- const uclamp0 = u32(result0) < u32(this.base0) ? this.base0 : (u32(result0) > u32(this.base1) ? this.base1 : result0);
98
- const sclamp0 = s32(result0) < s32(this.base0) ? this.base0 : (s32(result0) > s32(this.base1) ? this.base1 : result0);
97
+ const uclamp0 = u32(result0) < u32(this.base0)
98
+ ? this.base0
99
+ : u32(result0) > u32(this.base1)
100
+ ? this.base1
101
+ : result0;
102
+ const sclamp0 = s32(result0) < s32(this.base0)
103
+ ? this.base0
104
+ : s32(result0) > s32(this.base1)
105
+ ? this.base1
106
+ : result0;
99
107
  const clamp0 = ctrl0.signed ? sclamp0 : uclamp0;
100
108
  const alpha1 = result1 & 0xff;
101
109
  const ublend1 = u32(this.base0) + (Math.floor((alpha1 * (u32(this.base1) - u32(this.base0))) / 256) | 0);
@@ -202,7 +202,7 @@ export class RPUSBController extends BasePeripheral {
202
202
  (_b = this.onEndpointWrite) === null || _b === void 0 ? void 0 : _b.call(this, endpoint, buffer);
203
203
  }
204
204
  }
205
- if (doubleBuffer && ((value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_AVAILABLE)) {
205
+ if (doubleBuffer && (value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_AVAILABLE) {
206
206
  const bufferLength = (value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_LEN_MASK;
207
207
  const bufferOffset = this.getEndpointBufferOffset(endpoint, bufferOut) + USB_BUF1_OFFSET;
208
208
  this.debug(`Start USB transfer, endPoint=${endpoint}, direction=${bufferOut ? 'out' : 'in'} buffer=${bufferOffset.toString(16)} length=${bufferLength}`);
@@ -15,6 +15,7 @@ import { RPSIO } from './sio';
15
15
  import { Logger } from './utils/logging';
16
16
  export declare const FLASH_START_ADDRESS = 268435456;
17
17
  export declare const RAM_START_ADDRESS = 536870912;
18
+ export declare const APB_START_ADDRESS = 1073741824;
18
19
  export declare const DPRAM_START_ADDRESS = 1343225856;
19
20
  export declare const SIO_START_ADDRESS = 3489660928;
20
21
  export declare class RP2040 {
@@ -26,6 +26,7 @@ import { ConsoleLogger, LogLevel } from './utils/logging';
26
26
  import { RPTBMAN } from './peripherals/tbman';
27
27
  export const FLASH_START_ADDRESS = 0x10000000;
28
28
  export const RAM_START_ADDRESS = 0x20000000;
29
+ export const APB_START_ADDRESS = 0x40000000;
29
30
  export const DPRAM_START_ADDRESS = 0x50100000;
30
31
  export const SIO_START_ADDRESS = 0xd0000000;
31
32
  const LOG_NAME = 'RP2040';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rp2040js",
3
- "version": "0.17.7",
3
+ "version": "0.17.8",
4
4
  "description": "Raspberry Pi Pico (RP2040) Emulator",
5
5
  "repository": "https://github.com/wokwi/rp2040js",
6
6
  "keywords": [
@@ -30,6 +30,7 @@
30
30
  "build": "rimraf dist && tsc && tsc -p tsconfig.esm.json && node build-scripts/dist-package-json",
31
31
  "prepublish": "npm run build",
32
32
  "prepare": "husky install",
33
+ "format:check": "prettier --check **/*.{ts,js} !**/dist/** !**/node_modules/**",
33
34
  "lint": "eslint . --ext .ts",
34
35
  "start": "ts-node demo/emulator-run.ts",
35
36
  "start:micropython": "ts-node demo/micropython-run.ts",
@@ -38,13 +39,15 @@
38
39
  },
39
40
  "devDependencies": {
40
41
  "@types/jest": "^27.4.1",
42
+ "@types/minimist": "^1.2.2",
41
43
  "@types/node": "^14.14.22",
42
44
  "@typescript-eslint/eslint-plugin": "^4.22.1",
43
45
  "@typescript-eslint/parser": "^4.22.1",
44
46
  "eslint": "^7.26.0",
45
- "husky": "^6.0.0",
47
+ "husky": "^8.0.0",
46
48
  "jest": "^27.5.1",
47
49
  "lint-staged": "^11.0.0",
50
+ "minimist": "^1.2.7",
48
51
  "prettier": "^2.2.1",
49
52
  "rimraf": "^3.0.2",
50
53
  "ts-jest": "^27.1.3",