rp2040js 0.19.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/clock/clock.d.ts +6 -8
- package/dist/cjs/clock/mock-clock.d.ts +2 -15
- package/dist/cjs/clock/mock-clock.js +4 -46
- package/dist/cjs/clock/simulation-clock.d.ts +26 -0
- package/dist/cjs/clock/simulation-clock.js +97 -0
- package/dist/cjs/cortex-m0-core.d.ts +1 -1
- package/dist/cjs/cortex-m0-core.js +39 -37
- package/dist/cjs/gdb/gdb-connection.d.ts +1 -1
- package/dist/cjs/gdb/gdb-connection.js +2 -2
- package/dist/cjs/gdb/gdb-server.d.ts +3 -3
- package/dist/cjs/gdb/gdb-server.js +12 -11
- package/dist/cjs/gdb/gdb-target.d.ts +7 -0
- package/dist/cjs/gdb/gdb-target.js +2 -0
- package/dist/cjs/gdb/gdb-tcp-server.d.ts +2 -2
- package/dist/cjs/gdb/gdb-tcp-server.js +2 -2
- package/dist/cjs/index.d.ts +5 -4
- package/dist/cjs/index.js +7 -5
- package/dist/cjs/peripherals/adc.d.ts +7 -2
- package/dist/cjs/peripherals/adc.js +12 -8
- package/dist/cjs/peripherals/dma.d.ts +1 -1
- package/dist/cjs/peripherals/dma.js +6 -15
- package/dist/cjs/peripherals/rtc.d.ts +1 -1
- package/dist/cjs/peripherals/rtc.js +3 -3
- package/dist/cjs/peripherals/timer.js +12 -17
- package/dist/cjs/peripherals/usb.d.ts +4 -0
- package/dist/cjs/peripherals/usb.js +56 -50
- package/dist/cjs/rp2040.d.ts +1 -5
- package/dist/cjs/rp2040.js +12 -31
- package/dist/cjs/simulator.d.ts +13 -0
- package/dist/cjs/simulator.js +45 -0
- package/dist/cjs/utils/timer32.d.ts +3 -3
- package/dist/cjs/utils/timer32.js +14 -16
- package/dist/esm/clock/clock.d.ts +6 -8
- package/dist/esm/clock/mock-clock.d.ts +2 -15
- package/dist/esm/clock/mock-clock.js +3 -44
- package/dist/esm/clock/simulation-clock.d.ts +26 -0
- package/dist/esm/clock/simulation-clock.js +92 -0
- package/dist/esm/cortex-m0-core.d.ts +1 -1
- package/dist/esm/cortex-m0-core.js +39 -37
- package/dist/esm/gdb/gdb-connection.d.ts +1 -1
- package/dist/esm/gdb/gdb-connection.js +2 -2
- package/dist/esm/gdb/gdb-server.d.ts +3 -3
- package/dist/esm/gdb/gdb-server.js +12 -11
- package/dist/esm/gdb/gdb-target.d.ts +7 -0
- package/dist/esm/gdb/gdb-target.js +1 -0
- package/dist/esm/gdb/gdb-tcp-server.d.ts +2 -2
- package/dist/esm/gdb/gdb-tcp-server.js +2 -2
- package/dist/esm/index.d.ts +5 -4
- package/dist/esm/index.js +2 -1
- package/dist/esm/peripherals/adc.d.ts +7 -2
- package/dist/esm/peripherals/adc.js +12 -8
- package/dist/esm/peripherals/dma.d.ts +1 -1
- package/dist/esm/peripherals/dma.js +6 -15
- package/dist/esm/peripherals/rtc.d.ts +1 -1
- package/dist/esm/peripherals/rtc.js +3 -3
- package/dist/esm/peripherals/timer.js +12 -17
- package/dist/esm/peripherals/usb.d.ts +4 -0
- package/dist/esm/peripherals/usb.js +56 -50
- package/dist/esm/rp2040.d.ts +1 -5
- package/dist/esm/rp2040.js +11 -30
- package/dist/esm/simulator.d.ts +13 -0
- package/dist/esm/simulator.js +41 -0
- package/dist/esm/utils/timer32.d.ts +3 -3
- package/dist/esm/utils/timer32.js +14 -16
- package/package.json +7 -7
- package/dist/cjs/clock/realtime-clock.d.ts +0 -23
- package/dist/cjs/clock/realtime-clock.js +0 -73
- package/dist/esm/clock/realtime-clock.d.ts +0 -23
- package/dist/esm/clock/realtime-clock.js +0 -68
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export type AlarmCallback = () => void;
|
|
2
|
+
export interface IAlarm {
|
|
3
|
+
schedule(deltaNanos: number): void;
|
|
4
|
+
cancel(): void;
|
|
4
5
|
}
|
|
5
6
|
export interface IClock {
|
|
6
|
-
readonly
|
|
7
|
-
|
|
8
|
-
resume(): void;
|
|
9
|
-
createTimer(deltaMicros: number, callback: () => void): IClockTimer;
|
|
10
|
-
deleteTimer(timer: IClockTimer): void;
|
|
7
|
+
readonly nanos: number;
|
|
8
|
+
createAlarm(callback: AlarmCallback): IAlarm;
|
|
11
9
|
}
|
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare class
|
|
3
|
-
readonly micros: number;
|
|
4
|
-
readonly callback: () => void;
|
|
5
|
-
constructor(micros: number, callback: () => void);
|
|
6
|
-
pause(): void;
|
|
7
|
-
resume(): void;
|
|
8
|
-
}
|
|
9
|
-
export declare class MockClock implements IClock {
|
|
10
|
-
micros: number;
|
|
11
|
-
readonly timers: MockClockTimer[];
|
|
12
|
-
pause(): void;
|
|
13
|
-
resume(): void;
|
|
1
|
+
import { SimulationClock } from './simulation-clock.js';
|
|
2
|
+
export declare class MockClock extends SimulationClock {
|
|
14
3
|
advance(deltaMicros: number): void;
|
|
15
|
-
createTimer(deltaMicros: number, callback: () => void): MockClockTimer;
|
|
16
|
-
deleteTimer(timer: IClockTimer): void;
|
|
17
4
|
}
|
|
@@ -1,52 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MockClock =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
this.micros = micros;
|
|
7
|
-
this.callback = callback;
|
|
8
|
-
}
|
|
9
|
-
pause() {
|
|
10
|
-
/* intentionally empty */
|
|
11
|
-
}
|
|
12
|
-
resume() {
|
|
13
|
-
/* intentionally empty */
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
exports.MockClockTimer = MockClockTimer;
|
|
17
|
-
class MockClock {
|
|
18
|
-
constructor() {
|
|
19
|
-
this.micros = 0;
|
|
20
|
-
this.timers = [];
|
|
21
|
-
}
|
|
22
|
-
pause() {
|
|
23
|
-
/* intentionally empty */
|
|
24
|
-
}
|
|
25
|
-
resume() {
|
|
26
|
-
/* intentionally empty */
|
|
27
|
-
}
|
|
3
|
+
exports.MockClock = void 0;
|
|
4
|
+
const simulation_clock_js_1 = require("./simulation-clock.js");
|
|
5
|
+
class MockClock extends simulation_clock_js_1.SimulationClock {
|
|
28
6
|
advance(deltaMicros) {
|
|
29
|
-
|
|
30
|
-
const targetTime = this.micros + Math.max(deltaMicros, 0.01);
|
|
31
|
-
while (timers[0] && timers[0].micros <= targetTime) {
|
|
32
|
-
const timer = timers.shift();
|
|
33
|
-
if (timer) {
|
|
34
|
-
this.micros = timer.micros;
|
|
35
|
-
timer.callback();
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
createTimer(deltaMicros, callback) {
|
|
40
|
-
const timer = new MockClockTimer(this.micros + deltaMicros, callback);
|
|
41
|
-
this.timers.push(timer);
|
|
42
|
-
this.timers.sort((a, b) => a.micros - b.micros);
|
|
43
|
-
return timer;
|
|
44
|
-
}
|
|
45
|
-
deleteTimer(timer) {
|
|
46
|
-
const timerIndex = this.timers.indexOf(timer);
|
|
47
|
-
if (timerIndex >= 0) {
|
|
48
|
-
this.timers.splice(timerIndex, 1);
|
|
49
|
-
}
|
|
7
|
+
this.tick(this.nanos + deltaMicros * 1000);
|
|
50
8
|
}
|
|
51
9
|
}
|
|
52
10
|
exports.MockClock = MockClock;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AlarmCallback, IAlarm, IClock } from './clock.js';
|
|
2
|
+
type ClockEventCallback = () => void;
|
|
3
|
+
export declare class ClockAlarm implements IAlarm {
|
|
4
|
+
private readonly clock;
|
|
5
|
+
readonly callback: AlarmCallback;
|
|
6
|
+
next: ClockAlarm | null;
|
|
7
|
+
nanos: number;
|
|
8
|
+
scheduled: boolean;
|
|
9
|
+
constructor(clock: SimulationClock, callback: AlarmCallback);
|
|
10
|
+
schedule(deltaNanos: number): void;
|
|
11
|
+
cancel(): void;
|
|
12
|
+
}
|
|
13
|
+
export declare class SimulationClock implements IClock {
|
|
14
|
+
readonly frequency: number;
|
|
15
|
+
private nextAlarm;
|
|
16
|
+
private nanosCounter;
|
|
17
|
+
constructor(frequency?: number);
|
|
18
|
+
get nanos(): number;
|
|
19
|
+
get micros(): number;
|
|
20
|
+
createAlarm(callback: ClockEventCallback): ClockAlarm;
|
|
21
|
+
linkAlarm(nanos: number, alarm: ClockAlarm): ClockAlarm;
|
|
22
|
+
unlinkAlarm(alarm: ClockAlarm): boolean;
|
|
23
|
+
tick(deltaNanos: number): void;
|
|
24
|
+
get nanosToNextAlarm(): number;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SimulationClock = exports.ClockAlarm = void 0;
|
|
4
|
+
class ClockAlarm {
|
|
5
|
+
constructor(clock, callback) {
|
|
6
|
+
this.clock = clock;
|
|
7
|
+
this.callback = callback;
|
|
8
|
+
this.next = null;
|
|
9
|
+
this.nanos = 0;
|
|
10
|
+
this.scheduled = false;
|
|
11
|
+
}
|
|
12
|
+
schedule(deltaNanos) {
|
|
13
|
+
if (this.scheduled) {
|
|
14
|
+
this.cancel();
|
|
15
|
+
}
|
|
16
|
+
this.clock.linkAlarm(deltaNanos, this);
|
|
17
|
+
}
|
|
18
|
+
cancel() {
|
|
19
|
+
this.clock.unlinkAlarm(this);
|
|
20
|
+
this.scheduled = false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.ClockAlarm = ClockAlarm;
|
|
24
|
+
class SimulationClock {
|
|
25
|
+
constructor(frequency = 125e6) {
|
|
26
|
+
this.frequency = frequency;
|
|
27
|
+
this.nextAlarm = null;
|
|
28
|
+
this.nanosCounter = 0;
|
|
29
|
+
}
|
|
30
|
+
get nanos() {
|
|
31
|
+
return this.nanosCounter;
|
|
32
|
+
}
|
|
33
|
+
get micros() {
|
|
34
|
+
return this.nanos / 1000;
|
|
35
|
+
}
|
|
36
|
+
createAlarm(callback) {
|
|
37
|
+
return new ClockAlarm(this, callback);
|
|
38
|
+
}
|
|
39
|
+
linkAlarm(nanos, alarm) {
|
|
40
|
+
alarm.nanos = this.nanos + nanos;
|
|
41
|
+
let alarmListItem = this.nextAlarm;
|
|
42
|
+
let lastItem = null;
|
|
43
|
+
while (alarmListItem && alarmListItem.nanos < alarm.nanos) {
|
|
44
|
+
lastItem = alarmListItem;
|
|
45
|
+
alarmListItem = alarmListItem.next;
|
|
46
|
+
}
|
|
47
|
+
if (lastItem) {
|
|
48
|
+
lastItem.next = alarm;
|
|
49
|
+
alarm.next = alarmListItem;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this.nextAlarm = alarm;
|
|
53
|
+
alarm.next = alarmListItem;
|
|
54
|
+
}
|
|
55
|
+
alarm.scheduled = true;
|
|
56
|
+
return alarm;
|
|
57
|
+
}
|
|
58
|
+
unlinkAlarm(alarm) {
|
|
59
|
+
let alarmListItem = this.nextAlarm;
|
|
60
|
+
if (!alarmListItem) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
let lastItem = null;
|
|
64
|
+
while (alarmListItem) {
|
|
65
|
+
if (alarmListItem === alarm) {
|
|
66
|
+
if (lastItem) {
|
|
67
|
+
lastItem.next = alarmListItem.next;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
this.nextAlarm = alarmListItem.next;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
lastItem = alarmListItem;
|
|
75
|
+
alarmListItem = alarmListItem.next;
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
tick(deltaNanos) {
|
|
80
|
+
const targetNanos = this.nanosCounter + deltaNanos;
|
|
81
|
+
let alarm = this.nextAlarm;
|
|
82
|
+
while (alarm && alarm.nanos <= targetNanos) {
|
|
83
|
+
this.nextAlarm = alarm.next;
|
|
84
|
+
this.nanosCounter = alarm.nanos;
|
|
85
|
+
alarm.callback();
|
|
86
|
+
alarm = this.nextAlarm;
|
|
87
|
+
}
|
|
88
|
+
this.nanosCounter = targetNanos;
|
|
89
|
+
}
|
|
90
|
+
get nanosToNextAlarm() {
|
|
91
|
+
if (this.nextAlarm) {
|
|
92
|
+
return this.nextAlarm.nanos - this.nanos;
|
|
93
|
+
}
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.SimulationClock = SimulationClock;
|
|
@@ -529,7 +529,7 @@ class CortexM0Core {
|
|
|
529
529
|
const wideInstruction = opcode >> 12 === 0b1111 || opcode >> 11 === 0b11101;
|
|
530
530
|
const opcode2 = wideInstruction ? this.readUint16(opcodePC + 2) : 0;
|
|
531
531
|
this.PC += 2;
|
|
532
|
-
|
|
532
|
+
let deltaCycles = 1;
|
|
533
533
|
// ADCS
|
|
534
534
|
if (opcode >> 6 === 0b0100000101) {
|
|
535
535
|
const Rm = (opcode >> 3) & 0x7;
|
|
@@ -579,7 +579,7 @@ class CortexM0Core {
|
|
|
579
579
|
}
|
|
580
580
|
else if (Rdn === pcRegister) {
|
|
581
581
|
this.registers[Rdn] = result & ~0x1;
|
|
582
|
-
|
|
582
|
+
deltaCycles++;
|
|
583
583
|
}
|
|
584
584
|
else if (Rdn === spRegister) {
|
|
585
585
|
this.registers[Rdn] = result & ~0x3;
|
|
@@ -634,7 +634,7 @@ class CortexM0Core {
|
|
|
634
634
|
}
|
|
635
635
|
if (this.checkCondition(cond)) {
|
|
636
636
|
this.PC += imm8 + 2;
|
|
637
|
-
|
|
637
|
+
deltaCycles++;
|
|
638
638
|
}
|
|
639
639
|
}
|
|
640
640
|
// B
|
|
@@ -644,7 +644,7 @@ class CortexM0Core {
|
|
|
644
644
|
imm11 = (imm11 & 0x7ff) - 0x800;
|
|
645
645
|
}
|
|
646
646
|
this.PC += imm11 + 2;
|
|
647
|
-
|
|
647
|
+
deltaCycles++;
|
|
648
648
|
}
|
|
649
649
|
// BICS
|
|
650
650
|
else if (opcode >> 6 === 0b0100001110) {
|
|
@@ -672,7 +672,7 @@ class CortexM0Core {
|
|
|
672
672
|
const imm32 = ((S ? 0b11111111 : 0) << 24) | ((I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1));
|
|
673
673
|
this.LR = (this.PC + 2) | 0x1;
|
|
674
674
|
this.PC += 2 + imm32;
|
|
675
|
-
|
|
675
|
+
deltaCycles += 2;
|
|
676
676
|
this.blTaken(this, false);
|
|
677
677
|
}
|
|
678
678
|
// BLX
|
|
@@ -680,14 +680,14 @@ class CortexM0Core {
|
|
|
680
680
|
const Rm = (opcode >> 3) & 0xf;
|
|
681
681
|
this.LR = this.PC | 0x1;
|
|
682
682
|
this.PC = this.registers[Rm] & ~1;
|
|
683
|
-
|
|
683
|
+
deltaCycles++;
|
|
684
684
|
this.blTaken(this, true);
|
|
685
685
|
}
|
|
686
686
|
// BX
|
|
687
687
|
else if (opcode >> 7 === 0b010001110 && (opcode & 0x7) === 0) {
|
|
688
688
|
const Rm = (opcode >> 3) & 0xf;
|
|
689
689
|
this.BXWritePC(this.registers[Rm]);
|
|
690
|
-
|
|
690
|
+
deltaCycles++;
|
|
691
691
|
}
|
|
692
692
|
// CMN (register)
|
|
693
693
|
else if (opcode >> 6 === 0b0100001011) {
|
|
@@ -725,12 +725,12 @@ class CortexM0Core {
|
|
|
725
725
|
// DMB SY
|
|
726
726
|
else if (opcode === 0xf3bf && (opcode2 & 0xfff0) === 0x8f50) {
|
|
727
727
|
this.PC += 2;
|
|
728
|
-
|
|
728
|
+
deltaCycles += 2;
|
|
729
729
|
}
|
|
730
730
|
// DSB SY
|
|
731
731
|
else if (opcode === 0xf3bf && (opcode2 & 0xfff0) === 0x8f40) {
|
|
732
732
|
this.PC += 2;
|
|
733
|
-
|
|
733
|
+
deltaCycles += 2;
|
|
734
734
|
}
|
|
735
735
|
// EORS
|
|
736
736
|
else if (opcode >> 6 === 0b0100000001) {
|
|
@@ -744,7 +744,7 @@ class CortexM0Core {
|
|
|
744
744
|
// ISB SY
|
|
745
745
|
else if (opcode === 0xf3bf && (opcode2 & 0xfff0) === 0x8f60) {
|
|
746
746
|
this.PC += 2;
|
|
747
|
-
|
|
747
|
+
deltaCycles += 2;
|
|
748
748
|
}
|
|
749
749
|
// LDMIA
|
|
750
750
|
else if (opcode >> 11 === 0b11001) {
|
|
@@ -755,7 +755,7 @@ class CortexM0Core {
|
|
|
755
755
|
if (registers & (1 << i)) {
|
|
756
756
|
this.registers[i] = this.readUint32(address);
|
|
757
757
|
address += 4;
|
|
758
|
-
|
|
758
|
+
deltaCycles++;
|
|
759
759
|
}
|
|
760
760
|
}
|
|
761
761
|
// Write back
|
|
@@ -769,7 +769,7 @@ class CortexM0Core {
|
|
|
769
769
|
const Rn = (opcode >> 3) & 0x7;
|
|
770
770
|
const Rt = opcode & 0x7;
|
|
771
771
|
const addr = this.registers[Rn] + imm5;
|
|
772
|
-
|
|
772
|
+
deltaCycles += this.cyclesIO(addr);
|
|
773
773
|
this.registers[Rt] = this.readUint32(addr);
|
|
774
774
|
}
|
|
775
775
|
// LDR (sp + immediate)
|
|
@@ -777,7 +777,7 @@ class CortexM0Core {
|
|
|
777
777
|
const Rt = (opcode >> 8) & 0x7;
|
|
778
778
|
const imm8 = opcode & 0xff;
|
|
779
779
|
const addr = this.SP + (imm8 << 2);
|
|
780
|
-
|
|
780
|
+
deltaCycles += this.cyclesIO(addr);
|
|
781
781
|
this.registers[Rt] = this.readUint32(addr);
|
|
782
782
|
}
|
|
783
783
|
// LDR (literal)
|
|
@@ -786,7 +786,7 @@ class CortexM0Core {
|
|
|
786
786
|
const Rt = (opcode >> 8) & 7;
|
|
787
787
|
const nextPC = this.PC + 2;
|
|
788
788
|
const addr = (nextPC & 0xfffffffc) + imm8;
|
|
789
|
-
|
|
789
|
+
deltaCycles += this.cyclesIO(addr);
|
|
790
790
|
this.registers[Rt] = this.readUint32(addr);
|
|
791
791
|
}
|
|
792
792
|
// LDR (register)
|
|
@@ -795,7 +795,7 @@ class CortexM0Core {
|
|
|
795
795
|
const Rn = (opcode >> 3) & 0x7;
|
|
796
796
|
const Rt = opcode & 0x7;
|
|
797
797
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
798
|
-
|
|
798
|
+
deltaCycles += this.cyclesIO(addr);
|
|
799
799
|
this.registers[Rt] = this.readUint32(addr);
|
|
800
800
|
}
|
|
801
801
|
// LDRB (immediate)
|
|
@@ -804,7 +804,7 @@ class CortexM0Core {
|
|
|
804
804
|
const Rn = (opcode >> 3) & 0x7;
|
|
805
805
|
const Rt = opcode & 0x7;
|
|
806
806
|
const addr = this.registers[Rn] + imm5;
|
|
807
|
-
|
|
807
|
+
deltaCycles += this.cyclesIO(addr);
|
|
808
808
|
this.registers[Rt] = this.readUint8(addr);
|
|
809
809
|
}
|
|
810
810
|
// LDRB (register)
|
|
@@ -813,7 +813,7 @@ class CortexM0Core {
|
|
|
813
813
|
const Rn = (opcode >> 3) & 0x7;
|
|
814
814
|
const Rt = opcode & 0x7;
|
|
815
815
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
816
|
-
|
|
816
|
+
deltaCycles += this.cyclesIO(addr);
|
|
817
817
|
this.registers[Rt] = this.readUint8(addr);
|
|
818
818
|
}
|
|
819
819
|
// LDRH (immediate)
|
|
@@ -822,7 +822,7 @@ class CortexM0Core {
|
|
|
822
822
|
const Rn = (opcode >> 3) & 0x7;
|
|
823
823
|
const Rt = opcode & 0x7;
|
|
824
824
|
const addr = this.registers[Rn] + (imm5 << 1);
|
|
825
|
-
|
|
825
|
+
deltaCycles += this.cyclesIO(addr);
|
|
826
826
|
this.registers[Rt] = this.readUint16(addr);
|
|
827
827
|
}
|
|
828
828
|
// LDRH (register)
|
|
@@ -831,7 +831,7 @@ class CortexM0Core {
|
|
|
831
831
|
const Rn = (opcode >> 3) & 0x7;
|
|
832
832
|
const Rt = opcode & 0x7;
|
|
833
833
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
834
|
-
|
|
834
|
+
deltaCycles += this.cyclesIO(addr);
|
|
835
835
|
this.registers[Rt] = this.readUint16(addr);
|
|
836
836
|
}
|
|
837
837
|
// LDRSB
|
|
@@ -840,7 +840,7 @@ class CortexM0Core {
|
|
|
840
840
|
const Rn = (opcode >> 3) & 0x7;
|
|
841
841
|
const Rt = opcode & 0x7;
|
|
842
842
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
843
|
-
|
|
843
|
+
deltaCycles += this.cyclesIO(addr);
|
|
844
844
|
this.registers[Rt] = signExtend8(this.readUint8(addr));
|
|
845
845
|
}
|
|
846
846
|
// LDRSH
|
|
@@ -849,7 +849,7 @@ class CortexM0Core {
|
|
|
849
849
|
const Rn = (opcode >> 3) & 0x7;
|
|
850
850
|
const Rt = opcode & 0x7;
|
|
851
851
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
852
|
-
|
|
852
|
+
deltaCycles += this.cyclesIO(addr);
|
|
853
853
|
this.registers[Rt] = signExtend16(this.readUint16(addr));
|
|
854
854
|
}
|
|
855
855
|
// LSLS (immediate)
|
|
@@ -906,7 +906,7 @@ class CortexM0Core {
|
|
|
906
906
|
const Rd = ((opcode >> 4) & 0x8) | (opcode & 0x7);
|
|
907
907
|
let value = Rm === pcRegister ? this.PC + 2 : this.registers[Rm];
|
|
908
908
|
if (Rd === pcRegister) {
|
|
909
|
-
|
|
909
|
+
deltaCycles++;
|
|
910
910
|
value &= ~1;
|
|
911
911
|
}
|
|
912
912
|
else if (Rd === spRegister) {
|
|
@@ -928,7 +928,7 @@ class CortexM0Core {
|
|
|
928
928
|
const Rd = (opcode2 >> 8) & 0xf;
|
|
929
929
|
this.registers[Rd] = this.readSpecialRegister(SYSm);
|
|
930
930
|
this.PC += 2;
|
|
931
|
-
|
|
931
|
+
deltaCycles += 2;
|
|
932
932
|
}
|
|
933
933
|
// MSR
|
|
934
934
|
else if (opcode >> 4 === 0b111100111000 && opcode2 >> 8 == 0b10001000) {
|
|
@@ -936,7 +936,7 @@ class CortexM0Core {
|
|
|
936
936
|
const Rn = opcode & 0xf;
|
|
937
937
|
this.writeSpecialRegister(SYSm, this.registers[Rn]);
|
|
938
938
|
this.PC += 2;
|
|
939
|
-
|
|
939
|
+
deltaCycles += 2;
|
|
940
940
|
}
|
|
941
941
|
// MULS
|
|
942
942
|
else if (opcode >> 6 === 0b0100001101) {
|
|
@@ -973,13 +973,13 @@ class CortexM0Core {
|
|
|
973
973
|
if (opcode & (1 << i)) {
|
|
974
974
|
this.registers[i] = this.readUint32(address);
|
|
975
975
|
address += 4;
|
|
976
|
-
|
|
976
|
+
deltaCycles++;
|
|
977
977
|
}
|
|
978
978
|
}
|
|
979
979
|
if (P) {
|
|
980
980
|
this.SP = address + 4;
|
|
981
981
|
this.BXWritePC(this.readUint32(address));
|
|
982
|
-
|
|
982
|
+
deltaCycles += 2;
|
|
983
983
|
}
|
|
984
984
|
else {
|
|
985
985
|
this.SP = address;
|
|
@@ -997,7 +997,7 @@ class CortexM0Core {
|
|
|
997
997
|
for (let i = 0; i <= 7; i++) {
|
|
998
998
|
if (opcode & (1 << i)) {
|
|
999
999
|
this.writeUint32(address, this.registers[i]);
|
|
1000
|
-
|
|
1000
|
+
deltaCycles++;
|
|
1001
1001
|
address += 4;
|
|
1002
1002
|
}
|
|
1003
1003
|
}
|
|
@@ -1076,7 +1076,7 @@ class CortexM0Core {
|
|
|
1076
1076
|
if (registers & (1 << i)) {
|
|
1077
1077
|
this.writeUint32(address, this.registers[i]);
|
|
1078
1078
|
address += 4;
|
|
1079
|
-
|
|
1079
|
+
deltaCycles++;
|
|
1080
1080
|
}
|
|
1081
1081
|
}
|
|
1082
1082
|
// Write back
|
|
@@ -1090,7 +1090,7 @@ class CortexM0Core {
|
|
|
1090
1090
|
const Rn = (opcode >> 3) & 0x7;
|
|
1091
1091
|
const Rt = opcode & 0x7;
|
|
1092
1092
|
const address = this.registers[Rn] + imm5;
|
|
1093
|
-
|
|
1093
|
+
deltaCycles += this.cyclesIO(address, true);
|
|
1094
1094
|
this.writeUint32(address, this.registers[Rt]);
|
|
1095
1095
|
}
|
|
1096
1096
|
// STR (sp + immediate)
|
|
@@ -1098,7 +1098,7 @@ class CortexM0Core {
|
|
|
1098
1098
|
const Rt = (opcode >> 8) & 0x7;
|
|
1099
1099
|
const imm8 = opcode & 0xff;
|
|
1100
1100
|
const address = this.SP + (imm8 << 2);
|
|
1101
|
-
|
|
1101
|
+
deltaCycles += this.cyclesIO(address, true);
|
|
1102
1102
|
this.writeUint32(address, this.registers[Rt]);
|
|
1103
1103
|
}
|
|
1104
1104
|
// STR (register)
|
|
@@ -1107,7 +1107,7 @@ class CortexM0Core {
|
|
|
1107
1107
|
const Rn = (opcode >> 3) & 0x7;
|
|
1108
1108
|
const Rt = opcode & 0x7;
|
|
1109
1109
|
const address = this.registers[Rm] + this.registers[Rn];
|
|
1110
|
-
|
|
1110
|
+
deltaCycles += this.cyclesIO(address, true);
|
|
1111
1111
|
this.writeUint32(address, this.registers[Rt]);
|
|
1112
1112
|
}
|
|
1113
1113
|
// STRB (immediate)
|
|
@@ -1116,7 +1116,7 @@ class CortexM0Core {
|
|
|
1116
1116
|
const Rn = (opcode >> 3) & 0x7;
|
|
1117
1117
|
const Rt = opcode & 0x7;
|
|
1118
1118
|
const address = this.registers[Rn] + imm5;
|
|
1119
|
-
|
|
1119
|
+
deltaCycles += this.cyclesIO(address, true);
|
|
1120
1120
|
this.writeUint8(address, this.registers[Rt]);
|
|
1121
1121
|
}
|
|
1122
1122
|
// STRB (register)
|
|
@@ -1125,7 +1125,7 @@ class CortexM0Core {
|
|
|
1125
1125
|
const Rn = (opcode >> 3) & 0x7;
|
|
1126
1126
|
const Rt = opcode & 0x7;
|
|
1127
1127
|
const address = this.registers[Rm] + this.registers[Rn];
|
|
1128
|
-
|
|
1128
|
+
deltaCycles += this.cyclesIO(address, true);
|
|
1129
1129
|
this.writeUint8(address, this.registers[Rt]);
|
|
1130
1130
|
}
|
|
1131
1131
|
// STRH (immediate)
|
|
@@ -1134,7 +1134,7 @@ class CortexM0Core {
|
|
|
1134
1134
|
const Rn = (opcode >> 3) & 0x7;
|
|
1135
1135
|
const Rt = opcode & 0x7;
|
|
1136
1136
|
const address = this.registers[Rn] + imm5;
|
|
1137
|
-
|
|
1137
|
+
deltaCycles += this.cyclesIO(address, true);
|
|
1138
1138
|
this.writeUint16(address, this.registers[Rt]);
|
|
1139
1139
|
}
|
|
1140
1140
|
// STRH (register)
|
|
@@ -1143,7 +1143,7 @@ class CortexM0Core {
|
|
|
1143
1143
|
const Rn = (opcode >> 3) & 0x7;
|
|
1144
1144
|
const Rt = opcode & 0x7;
|
|
1145
1145
|
const address = this.registers[Rm] + this.registers[Rn];
|
|
1146
|
-
|
|
1146
|
+
deltaCycles += this.cyclesIO(address, true);
|
|
1147
1147
|
this.writeUint16(address, this.registers[Rt]);
|
|
1148
1148
|
}
|
|
1149
1149
|
// SUB (SP minus immediate)
|
|
@@ -1224,7 +1224,7 @@ class CortexM0Core {
|
|
|
1224
1224
|
}
|
|
1225
1225
|
// WFE
|
|
1226
1226
|
else if (opcode === 0b1011111100100000) {
|
|
1227
|
-
|
|
1227
|
+
deltaCycles++;
|
|
1228
1228
|
if (this.eventRegistered) {
|
|
1229
1229
|
this.eventRegistered = false;
|
|
1230
1230
|
}
|
|
@@ -1234,7 +1234,7 @@ class CortexM0Core {
|
|
|
1234
1234
|
}
|
|
1235
1235
|
// WFI
|
|
1236
1236
|
else if (opcode === 0b1011111100110000) {
|
|
1237
|
-
|
|
1237
|
+
deltaCycles++;
|
|
1238
1238
|
this.waiting = true;
|
|
1239
1239
|
}
|
|
1240
1240
|
// YIELD
|
|
@@ -1246,6 +1246,8 @@ class CortexM0Core {
|
|
|
1246
1246
|
this.logger.warn(LOG_NAME, `Warning: Instruction at ${opcodePC.toString(16)} is not implemented yet!`);
|
|
1247
1247
|
this.logger.warn(LOG_NAME, `Opcode: 0x${opcode.toString(16)} (0x${opcode2.toString(16)})`);
|
|
1248
1248
|
}
|
|
1249
|
+
this.cycles += deltaCycles;
|
|
1250
|
+
return deltaCycles;
|
|
1249
1251
|
}
|
|
1250
1252
|
}
|
|
1251
1253
|
exports.CortexM0Core = CortexM0Core;
|
|
@@ -3,7 +3,7 @@ export type GDBResponseHandler = (value: string) => void;
|
|
|
3
3
|
export declare class GDBConnection {
|
|
4
4
|
private server;
|
|
5
5
|
private onResponse;
|
|
6
|
-
readonly
|
|
6
|
+
readonly target: import("./gdb-target.js").IGDBTarget;
|
|
7
7
|
private buf;
|
|
8
8
|
constructor(server: GDBServer, onResponse: GDBResponseHandler);
|
|
9
9
|
feedData(data: string): void;
|
|
@@ -7,7 +7,7 @@ class GDBConnection {
|
|
|
7
7
|
constructor(server, onResponse) {
|
|
8
8
|
this.server = server;
|
|
9
9
|
this.onResponse = onResponse;
|
|
10
|
-
this.
|
|
10
|
+
this.target = this.server.target;
|
|
11
11
|
this.buf = '';
|
|
12
12
|
server.addConnection(this);
|
|
13
13
|
onResponse('+');
|
|
@@ -16,7 +16,7 @@ class GDBConnection {
|
|
|
16
16
|
const { onResponse } = this;
|
|
17
17
|
if (data.charCodeAt(0) === 3) {
|
|
18
18
|
this.server.info('BREAK');
|
|
19
|
-
this.
|
|
19
|
+
this.target.stop();
|
|
20
20
|
onResponse((0, gdb_utils_js_1.gdbMessage)(gdb_server_js_1.STOP_REPLY_SIGINT));
|
|
21
21
|
data = data.slice(1);
|
|
22
22
|
}
|
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Copyright (C) 2021, Uri Shaked
|
|
5
5
|
*/
|
|
6
|
-
import { RP2040 } from '../rp2040.js';
|
|
7
6
|
import { Logger } from '../utils/logging.js';
|
|
8
7
|
import { GDBConnection } from './gdb-connection.js';
|
|
8
|
+
import { IGDBTarget } from './gdb-target.js';
|
|
9
9
|
export declare const STOP_REPLY_SIGINT = "S02";
|
|
10
10
|
export declare const STOP_REPLY_TRAP = "S05";
|
|
11
11
|
export declare class GDBServer {
|
|
12
|
-
readonly
|
|
12
|
+
readonly target: IGDBTarget;
|
|
13
13
|
logger: Logger;
|
|
14
14
|
private readonly connections;
|
|
15
|
-
constructor(
|
|
15
|
+
constructor(target: IGDBTarget);
|
|
16
16
|
processGDBMessage(cmd: string): string | undefined;
|
|
17
17
|
addConnection(connection: GDBConnection): void;
|
|
18
18
|
removeConnection(connection: GDBConnection): void;
|
|
@@ -66,13 +66,13 @@ const targetXML = `<?xml version="1.0"?>
|
|
|
66
66
|
</target>`;
|
|
67
67
|
const LOG_NAME = 'GDBServer';
|
|
68
68
|
class GDBServer {
|
|
69
|
-
constructor(
|
|
70
|
-
this.
|
|
69
|
+
constructor(target) {
|
|
70
|
+
this.target = target;
|
|
71
71
|
this.logger = new logging_js_1.ConsoleLogger(logging_js_1.LogLevel.Warn, true);
|
|
72
72
|
this.connections = new Set();
|
|
73
73
|
}
|
|
74
74
|
processGDBMessage(cmd) {
|
|
75
|
-
const { rp2040 } = this;
|
|
75
|
+
const { rp2040 } = this.target;
|
|
76
76
|
const { core } = rp2040;
|
|
77
77
|
if (cmd === 'Hg0') {
|
|
78
78
|
return (0, gdb_utils_js_1.gdbMessage)('OK');
|
|
@@ -113,8 +113,8 @@ class GDBServer {
|
|
|
113
113
|
return (0, gdb_utils_js_1.gdbMessage)('vCont;c;C;s;S');
|
|
114
114
|
}
|
|
115
115
|
if (cmd.startsWith('vCont;c')) {
|
|
116
|
-
if (!
|
|
117
|
-
|
|
116
|
+
if (!this.target.executing) {
|
|
117
|
+
this.target.execute();
|
|
118
118
|
}
|
|
119
119
|
return;
|
|
120
120
|
}
|
|
@@ -129,8 +129,8 @@ class GDBServer {
|
|
|
129
129
|
}
|
|
130
130
|
break;
|
|
131
131
|
case 'c':
|
|
132
|
-
if (!
|
|
133
|
-
|
|
132
|
+
if (!this.target.executing) {
|
|
133
|
+
this.target.execute();
|
|
134
134
|
}
|
|
135
135
|
return (0, gdb_utils_js_1.gdbMessage)('OK');
|
|
136
136
|
case 'g': {
|
|
@@ -169,7 +169,7 @@ class GDBServer {
|
|
|
169
169
|
}
|
|
170
170
|
case 'P': {
|
|
171
171
|
// Write register
|
|
172
|
-
const params = cmd.
|
|
172
|
+
const params = cmd.substring(1).split('=');
|
|
173
173
|
const registerIndex = parseInt(params[0], 16);
|
|
174
174
|
const registerValue = params[1].trim();
|
|
175
175
|
const registerBytes = registerIndex > 0x12 ? 1 : 4;
|
|
@@ -235,10 +235,11 @@ class GDBServer {
|
|
|
235
235
|
return (0, gdb_utils_js_1.gdbMessage)('');
|
|
236
236
|
}
|
|
237
237
|
addConnection(connection) {
|
|
238
|
+
const { rp2040 } = this.target;
|
|
238
239
|
this.connections.add(connection);
|
|
239
|
-
|
|
240
|
-
this.
|
|
241
|
-
|
|
240
|
+
rp2040.onBreak = () => {
|
|
241
|
+
this.target.stop();
|
|
242
|
+
rp2040.core.PC -= rp2040.core.breakRewind;
|
|
242
243
|
for (const connection of this.connections) {
|
|
243
244
|
connection.onBreakpoint();
|
|
244
245
|
}
|