c64-debug-mcp 1.0.6 → 1.0.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 +98 -3
- package/dist/http.cjs +266 -14
- package/dist/http.js +266 -14
- package/dist/stdio.cjs +266 -14
- package/dist/stdio.js +266 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,101 @@ Debug Commodore 64 programs through conversation - AI-powered control of the VIC
|
|
|
14
14
|
- 📸 **Display Capture**: Capture screen state and text content
|
|
15
15
|
- ⌨️ **Input Control**: Send keyboard and joystick input
|
|
16
16
|
- 📝 **Program Loading**: Load PRG files and manage execution
|
|
17
|
+
- 🔢 **Flexible Formats**: Use C64 notation ($D000, $FF, %11111111) or standard formats (0xD000, 255, 0b11111111)
|
|
18
|
+
|
|
19
|
+
## Address Formats
|
|
20
|
+
|
|
21
|
+
The MCP server accepts C64 addresses in multiple formats for natural interaction:
|
|
22
|
+
|
|
23
|
+
- **C64 style**: `$D000` (dollar sign prefix - classic 6502 assembler notation)
|
|
24
|
+
- **C style**: `0xD000` (0x prefix - standard programming hex notation)
|
|
25
|
+
- **Decimal**: `53248` (traditional decimal format)
|
|
26
|
+
|
|
27
|
+
**Note**: Bare hex without prefix (e.g., `D000`) is NOT supported to avoid ambiguity with 4-digit decimals.
|
|
28
|
+
|
|
29
|
+
### Range Support
|
|
30
|
+
|
|
31
|
+
Tools that read memory or set breakpoints support both **address+length** and **start+end** formats:
|
|
32
|
+
|
|
33
|
+
**Address + Length format** (original):
|
|
34
|
+
```javascript
|
|
35
|
+
memory_read(address="$D000", length=256) // Read 256 bytes starting at $D000
|
|
36
|
+
breakpoint_set(kind="exec", address="$1000", length=1) // Breakpoint at $1000
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Start + End format** (more intuitive for ranges):
|
|
40
|
+
```javascript
|
|
41
|
+
memory_read(start="$D000", end="$D0FF") // Read from $D000 to $D0FF inclusive
|
|
42
|
+
memory_read(start=198, end=199) // Read addresses 198-199 (2 bytes)
|
|
43
|
+
breakpoint_set(kind="exec", start="$1000", end="$1000") // Breakpoint at $1000
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Both formats work with all address representations (decimal, $, 0x).
|
|
47
|
+
|
|
48
|
+
**Common C64 Addresses**:
|
|
49
|
+
- `$D000` - SID chip registers (sound)
|
|
50
|
+
- `$D020` - Border color register
|
|
51
|
+
- `$D021` - Background color register
|
|
52
|
+
- `$0400` - Default screen memory
|
|
53
|
+
- `$0800` - Common program start
|
|
54
|
+
- `$C000` - BASIC ROM start
|
|
55
|
+
|
|
56
|
+
## Address Ranges
|
|
57
|
+
|
|
58
|
+
For operations that work with memory ranges (like `memory_read` and `breakpoint_set`), you can specify ranges in two ways:
|
|
59
|
+
|
|
60
|
+
**Option 1: Address + Length**
|
|
61
|
+
```javascript
|
|
62
|
+
memory_read(address="$0400", length=256) // Read 256 bytes from $0400
|
|
63
|
+
breakpoint_set(kind="exec", address="$1000", length=16) // Break on $1000-$100F
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Option 2: Start + End (inclusive)**
|
|
67
|
+
```javascript
|
|
68
|
+
memory_read(start="$0400", end="$04FF") // Read from $0400 to $04FF (256 bytes)
|
|
69
|
+
breakpoint_set(kind="exec", start="$1000", end="$100F") // Break on $1000-$100F
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Both formats work identically and support all address formats (decimal, hex).
|
|
73
|
+
|
|
74
|
+
## Byte Value Formats
|
|
75
|
+
|
|
76
|
+
The MCP server accepts byte values (0-255) in multiple formats for natural C64-style input:
|
|
77
|
+
|
|
78
|
+
- **C64 hex**: `$FF` (dollar sign prefix - classic 6502 notation)
|
|
79
|
+
- **C hex**: `0xFF` (0x prefix - standard programming notation)
|
|
80
|
+
- **C64 binary**: `%11111111` (percent prefix - classic 6502 bit notation)
|
|
81
|
+
- **C binary**: `0b11111111` (0b prefix - standard programming notation)
|
|
82
|
+
- **Decimal**: `255` (traditional decimal format)
|
|
83
|
+
|
|
84
|
+
**Note**: Bare hex/binary without prefix (e.g., `FF`, `11111111`) is NOT supported to avoid ambiguity.
|
|
85
|
+
|
|
86
|
+
**Mixed formats in arrays**:
|
|
87
|
+
```json
|
|
88
|
+
[255, "$FF", "0xFF", "%11111111", "0b11111111"]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Common C64 Byte Values**:
|
|
92
|
+
- `$00`-`$0F` - Color values (0-15)
|
|
93
|
+
- `$20` - PETSCII space character
|
|
94
|
+
- `$41` - PETSCII 'A' character
|
|
95
|
+
- `%00011011` - VIC-II D011 control register (text mode, 25 rows, screen on)
|
|
96
|
+
- `%11111111` - All bits set (enable all sprites, etc.)
|
|
97
|
+
|
|
98
|
+
**Use Cases**:
|
|
99
|
+
```javascript
|
|
100
|
+
// Set border to light blue
|
|
101
|
+
memory_write(address="$D020", data=["$0E"])
|
|
102
|
+
|
|
103
|
+
// Enable all 8 sprites
|
|
104
|
+
memory_write(address="$D015", data=["%11111111"])
|
|
105
|
+
|
|
106
|
+
// Write " AB" to screen (PETSCII)
|
|
107
|
+
memory_write(address="$0400", data=["$20", "$41", "$42"])
|
|
108
|
+
|
|
109
|
+
// Set VIC-II control register with bit pattern
|
|
110
|
+
memory_write(address="$D011", data=["%00011011"])
|
|
111
|
+
```
|
|
17
112
|
|
|
18
113
|
## Requirements
|
|
19
114
|
|
|
@@ -24,7 +119,7 @@ Debug Commodore 64 programs through conversation - AI-powered control of the VIC
|
|
|
24
119
|
## Installation
|
|
25
120
|
|
|
26
121
|
```bash
|
|
27
|
-
claude mcp add
|
|
122
|
+
claude mcp add c64-dev-tools -- npx -y c64-debug-mcp@latest
|
|
28
123
|
```
|
|
29
124
|
|
|
30
125
|
Or add manually to your MCP client config:
|
|
@@ -32,9 +127,9 @@ Or add manually to your MCP client config:
|
|
|
32
127
|
```json
|
|
33
128
|
{
|
|
34
129
|
"mcpServers": {
|
|
35
|
-
"
|
|
130
|
+
"c64-dev-tools": {
|
|
36
131
|
"command": "npx",
|
|
37
|
-
"args": ["-y", "c64-debug-mcp"]
|
|
132
|
+
"args": ["-y", "c64-debug-mcp@latest"]
|
|
38
133
|
}
|
|
39
134
|
}
|
|
40
135
|
}
|
package/dist/http.cjs
CHANGED
|
@@ -152,9 +152,211 @@ var import_zod3 = require("zod");
|
|
|
152
152
|
// src/schemas.ts
|
|
153
153
|
var import_zod2 = require("zod");
|
|
154
154
|
var warningSchema = warningItemSchema;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
function parseAddress16(input) {
|
|
156
|
+
if (input === void 0) {
|
|
157
|
+
throw new import_zod2.z.ZodError([
|
|
158
|
+
{
|
|
159
|
+
code: "custom",
|
|
160
|
+
message: "Address is required",
|
|
161
|
+
path: []
|
|
162
|
+
}
|
|
163
|
+
]);
|
|
164
|
+
}
|
|
165
|
+
if (typeof input === "number") {
|
|
166
|
+
if (!Number.isInteger(input) || input < 0 || input > 65535) {
|
|
167
|
+
throw new import_zod2.z.ZodError([
|
|
168
|
+
{
|
|
169
|
+
code: "custom",
|
|
170
|
+
message: `Address must be an integer between 0 and 65535 (0xFFFF), got ${input}`,
|
|
171
|
+
path: []
|
|
172
|
+
}
|
|
173
|
+
]);
|
|
174
|
+
}
|
|
175
|
+
return input;
|
|
176
|
+
}
|
|
177
|
+
if (typeof input !== "string") {
|
|
178
|
+
throw new import_zod2.z.ZodError([
|
|
179
|
+
{
|
|
180
|
+
code: "custom",
|
|
181
|
+
message: `Address must be a number or string, got ${typeof input}`,
|
|
182
|
+
path: []
|
|
183
|
+
}
|
|
184
|
+
]);
|
|
185
|
+
}
|
|
186
|
+
const trimmed = input.trim();
|
|
187
|
+
let hexString;
|
|
188
|
+
let format;
|
|
189
|
+
if (trimmed.startsWith("$")) {
|
|
190
|
+
hexString = trimmed.slice(1);
|
|
191
|
+
format = "C64 hex ($)";
|
|
192
|
+
} else if (trimmed.toLowerCase().startsWith("0x")) {
|
|
193
|
+
hexString = trimmed.slice(2);
|
|
194
|
+
format = "C hex (0x)";
|
|
195
|
+
} else {
|
|
196
|
+
throw new import_zod2.z.ZodError([
|
|
197
|
+
{
|
|
198
|
+
code: "custom",
|
|
199
|
+
message: `Invalid address format: "${input}". Expected formats: decimal number (53248), hex with $ ($D000), or hex with 0x (0xD000). Bare hex not supported to avoid ambiguity.`,
|
|
200
|
+
path: []
|
|
201
|
+
}
|
|
202
|
+
]);
|
|
203
|
+
}
|
|
204
|
+
if (!/^[0-9A-Fa-f]{1,4}$/.test(hexString)) {
|
|
205
|
+
throw new import_zod2.z.ZodError([
|
|
206
|
+
{
|
|
207
|
+
code: "custom",
|
|
208
|
+
message: `Invalid ${format} address: "${input}". Hex portion must be 1-4 hex digits (0-9, A-F)`,
|
|
209
|
+
path: []
|
|
210
|
+
}
|
|
211
|
+
]);
|
|
212
|
+
}
|
|
213
|
+
const parsed = parseInt(hexString, 16);
|
|
214
|
+
if (isNaN(parsed) || parsed < 0 || parsed > 65535) {
|
|
215
|
+
throw new import_zod2.z.ZodError([
|
|
216
|
+
{
|
|
217
|
+
code: "custom",
|
|
218
|
+
message: `Address out of range: "${input}" (${parsed}). Must be 0x0000-0xFFFF (0-65535)`,
|
|
219
|
+
path: []
|
|
220
|
+
}
|
|
221
|
+
]);
|
|
222
|
+
}
|
|
223
|
+
return parsed;
|
|
224
|
+
}
|
|
225
|
+
var address16Schema = import_zod2.z.preprocess(parseAddress16, import_zod2.z.number().int().min(0).max(65535)).describe("16-bit C64 address: decimal (53248) or hex string with prefix ($D000, 0xD000)");
|
|
226
|
+
function parseByte(input) {
|
|
227
|
+
if (input === void 0) {
|
|
228
|
+
throw new import_zod2.z.ZodError([
|
|
229
|
+
{
|
|
230
|
+
code: "custom",
|
|
231
|
+
message: "Byte value is required",
|
|
232
|
+
path: []
|
|
233
|
+
}
|
|
234
|
+
]);
|
|
235
|
+
}
|
|
236
|
+
if (typeof input === "number") {
|
|
237
|
+
if (!Number.isInteger(input) || input < 0 || input > 255) {
|
|
238
|
+
throw new import_zod2.z.ZodError([
|
|
239
|
+
{
|
|
240
|
+
code: "custom",
|
|
241
|
+
message: `Byte value must be an integer between 0 and 255 (0xFF), got ${input}`,
|
|
242
|
+
path: []
|
|
243
|
+
}
|
|
244
|
+
]);
|
|
245
|
+
}
|
|
246
|
+
return input;
|
|
247
|
+
}
|
|
248
|
+
if (typeof input !== "string") {
|
|
249
|
+
throw new import_zod2.z.ZodError([
|
|
250
|
+
{
|
|
251
|
+
code: "custom",
|
|
252
|
+
message: `Byte value must be a number or string, got ${typeof input}`,
|
|
253
|
+
path: []
|
|
254
|
+
}
|
|
255
|
+
]);
|
|
256
|
+
}
|
|
257
|
+
const trimmed = input.trim();
|
|
258
|
+
if (trimmed.startsWith("$")) {
|
|
259
|
+
const hexString = trimmed.slice(1);
|
|
260
|
+
if (!/^[0-9A-Fa-f]{1,2}$/.test(hexString)) {
|
|
261
|
+
throw new import_zod2.z.ZodError([
|
|
262
|
+
{
|
|
263
|
+
code: "custom",
|
|
264
|
+
message: `Invalid C64 hex ($) byte value: "${input}". Hex portion must be 1-2 hex digits (0-9, A-F)`,
|
|
265
|
+
path: []
|
|
266
|
+
}
|
|
267
|
+
]);
|
|
268
|
+
}
|
|
269
|
+
const parsed = parseInt(hexString, 16);
|
|
270
|
+
if (isNaN(parsed) || parsed < 0 || parsed > 255) {
|
|
271
|
+
throw new import_zod2.z.ZodError([
|
|
272
|
+
{
|
|
273
|
+
code: "custom",
|
|
274
|
+
message: `Byte value out of range: "${input}" (${parsed}). Must be 0x00-0xFF (0-255)`,
|
|
275
|
+
path: []
|
|
276
|
+
}
|
|
277
|
+
]);
|
|
278
|
+
}
|
|
279
|
+
return parsed;
|
|
280
|
+
}
|
|
281
|
+
if (trimmed.toLowerCase().startsWith("0x")) {
|
|
282
|
+
const hexString = trimmed.slice(2);
|
|
283
|
+
if (!/^[0-9A-Fa-f]{1,2}$/.test(hexString)) {
|
|
284
|
+
throw new import_zod2.z.ZodError([
|
|
285
|
+
{
|
|
286
|
+
code: "custom",
|
|
287
|
+
message: `Invalid C hex (0x) byte value: "${input}". Hex portion must be 1-2 hex digits (0-9, A-F)`,
|
|
288
|
+
path: []
|
|
289
|
+
}
|
|
290
|
+
]);
|
|
291
|
+
}
|
|
292
|
+
const parsed = parseInt(hexString, 16);
|
|
293
|
+
if (isNaN(parsed) || parsed < 0 || parsed > 255) {
|
|
294
|
+
throw new import_zod2.z.ZodError([
|
|
295
|
+
{
|
|
296
|
+
code: "custom",
|
|
297
|
+
message: `Byte value out of range: "${input}" (${parsed}). Must be 0x00-0xFF (0-255)`,
|
|
298
|
+
path: []
|
|
299
|
+
}
|
|
300
|
+
]);
|
|
301
|
+
}
|
|
302
|
+
return parsed;
|
|
303
|
+
}
|
|
304
|
+
if (trimmed.startsWith("%")) {
|
|
305
|
+
const binString = trimmed.slice(1);
|
|
306
|
+
if (!/^[01]{1,8}$/.test(binString)) {
|
|
307
|
+
throw new import_zod2.z.ZodError([
|
|
308
|
+
{
|
|
309
|
+
code: "custom",
|
|
310
|
+
message: `Invalid C64 binary (%) byte value: "${input}". Binary portion must be 1-8 binary digits (0-1)`,
|
|
311
|
+
path: []
|
|
312
|
+
}
|
|
313
|
+
]);
|
|
314
|
+
}
|
|
315
|
+
const parsed = parseInt(binString, 2);
|
|
316
|
+
if (isNaN(parsed) || parsed < 0 || parsed > 255) {
|
|
317
|
+
throw new import_zod2.z.ZodError([
|
|
318
|
+
{
|
|
319
|
+
code: "custom",
|
|
320
|
+
message: `Byte value out of range: "${input}" (${parsed}). Must be 0b00000000-0b11111111 (0-255)`,
|
|
321
|
+
path: []
|
|
322
|
+
}
|
|
323
|
+
]);
|
|
324
|
+
}
|
|
325
|
+
return parsed;
|
|
326
|
+
}
|
|
327
|
+
if (trimmed.toLowerCase().startsWith("0b")) {
|
|
328
|
+
const binString = trimmed.slice(2);
|
|
329
|
+
if (!/^[01]{1,8}$/.test(binString)) {
|
|
330
|
+
throw new import_zod2.z.ZodError([
|
|
331
|
+
{
|
|
332
|
+
code: "custom",
|
|
333
|
+
message: `Invalid C binary (0b) byte value: "${input}". Binary portion must be 1-8 binary digits (0-1)`,
|
|
334
|
+
path: []
|
|
335
|
+
}
|
|
336
|
+
]);
|
|
337
|
+
}
|
|
338
|
+
const parsed = parseInt(binString, 2);
|
|
339
|
+
if (isNaN(parsed) || parsed < 0 || parsed > 255) {
|
|
340
|
+
throw new import_zod2.z.ZodError([
|
|
341
|
+
{
|
|
342
|
+
code: "custom",
|
|
343
|
+
message: `Byte value out of range: "${input}" (${parsed}). Must be 0b00000000-0b11111111 (0-255)`,
|
|
344
|
+
path: []
|
|
345
|
+
}
|
|
346
|
+
]);
|
|
347
|
+
}
|
|
348
|
+
return parsed;
|
|
349
|
+
}
|
|
350
|
+
throw new import_zod2.z.ZodError([
|
|
351
|
+
{
|
|
352
|
+
code: "custom",
|
|
353
|
+
message: `Invalid byte format: "${input}". Expected formats: decimal (255), hex with prefix ($FF, 0xFF), or binary with prefix (%11111111, 0b11111111). Bare hex/binary not supported to avoid ambiguity.`,
|
|
354
|
+
path: []
|
|
355
|
+
}
|
|
356
|
+
]);
|
|
357
|
+
}
|
|
358
|
+
var byteValueSchema = import_zod2.z.preprocess(parseByte, import_zod2.z.number().int().min(0).max(255)).describe("8-bit byte value: decimal (255), hex with prefix ($FF, 0xFF), or binary with prefix (%11111111, 0b11111111)");
|
|
359
|
+
var byteArraySchema = import_zod2.z.array(byteValueSchema).describe('Array of byte values in mixed formats: [255, "$FF", "%11111111", 42]');
|
|
158
360
|
var c64RegisterValueSchema = import_zod2.z.object(
|
|
159
361
|
Object.fromEntries(
|
|
160
362
|
C64_REGISTER_DEFINITIONS.map((register) => [
|
|
@@ -2437,9 +2639,21 @@ var ViceSession = class {
|
|
|
2437
2639
|
async #withAutoResumeForInput(commandName, operation) {
|
|
2438
2640
|
await this.#ensureReady();
|
|
2439
2641
|
this.#syncMonitorRuntimeState();
|
|
2642
|
+
if (this.#executionState === "unknown") {
|
|
2643
|
+
throw new ViceMcpError(
|
|
2644
|
+
"emulator_state_unknown",
|
|
2645
|
+
`${commandName} requires a known execution state (running or stopped)`,
|
|
2646
|
+
"session_state",
|
|
2647
|
+
false,
|
|
2648
|
+
{
|
|
2649
|
+
executionState: this.#executionState,
|
|
2650
|
+
lastStopReason: this.#lastStopReason
|
|
2651
|
+
}
|
|
2652
|
+
);
|
|
2653
|
+
}
|
|
2440
2654
|
const wasRunning = this.#executionState === "running";
|
|
2441
2655
|
const wasPaused = this.#explicitPauseActive;
|
|
2442
|
-
if (
|
|
2656
|
+
if (this.#executionState === "stopped") {
|
|
2443
2657
|
this.#writeProcessLogLine(`[${commandName}] auto-resuming for input operation`);
|
|
2444
2658
|
await this.#client.continueExecution();
|
|
2445
2659
|
await this.waitForState("running", 5e3, INPUT_RUNNING_STABLE_MS);
|
|
@@ -3440,10 +3654,27 @@ var setRegistersTool = createViceTool({
|
|
|
3440
3654
|
});
|
|
3441
3655
|
var readMemoryTool = createViceTool({
|
|
3442
3656
|
id: "memory_read",
|
|
3443
|
-
description: "Reads a memory chunk
|
|
3444
|
-
inputSchema: import_zod4.z.
|
|
3445
|
-
|
|
3446
|
-
|
|
3657
|
+
description: "Reads a memory chunk. Use either (address, length) or (start, end) format. Addresses can be decimal (53248) or hex string with prefix ($D000, 0xD000). Returns byte values as decimal numbers.",
|
|
3658
|
+
inputSchema: import_zod4.z.union([
|
|
3659
|
+
import_zod4.z.object({
|
|
3660
|
+
address: address16Schema.describe("Start address: decimal (53248) or hex string with prefix ($D000, 0xD000)"),
|
|
3661
|
+
length: import_zod4.z.number().int().positive().max(65535).describe("Number of bytes to read")
|
|
3662
|
+
}),
|
|
3663
|
+
import_zod4.z.object({
|
|
3664
|
+
start: address16Schema.describe("Start address (inclusive): decimal (53248) or hex string with prefix ($D000, 0xD000)"),
|
|
3665
|
+
end: address16Schema.describe("End address (inclusive): decimal (53248) or hex string with prefix ($D000, 0xD000)")
|
|
3666
|
+
})
|
|
3667
|
+
]).transform((input) => {
|
|
3668
|
+
if ("start" in input && "end" in input) {
|
|
3669
|
+
if (input.end < input.start) {
|
|
3670
|
+
throw new Error("End address must be greater than or equal to start address");
|
|
3671
|
+
}
|
|
3672
|
+
return {
|
|
3673
|
+
address: input.start,
|
|
3674
|
+
length: input.end - input.start + 1
|
|
3675
|
+
};
|
|
3676
|
+
}
|
|
3677
|
+
return input;
|
|
3447
3678
|
}).refine((input) => input.address + input.length <= 65536, {
|
|
3448
3679
|
message: "address + length must stay within the 64K address space",
|
|
3449
3680
|
path: ["length"]
|
|
@@ -3464,10 +3695,10 @@ var readMemoryTool = createViceTool({
|
|
|
3464
3695
|
});
|
|
3465
3696
|
var writeMemoryTool = createViceTool({
|
|
3466
3697
|
id: "memory_write",
|
|
3467
|
-
description:
|
|
3698
|
+
description: "Writes raw byte values into C64 memory. Address and byte values support decimal, hex ($FF, 0xFF), and binary (%11111111, 0b11111111) formats. Requires emulator to be stopped.",
|
|
3468
3699
|
inputSchema: import_zod4.z.object({
|
|
3469
|
-
address: address16Schema.describe("Start address
|
|
3470
|
-
data: byteArraySchema.min(1).describe("
|
|
3700
|
+
address: address16Schema.describe("Start address: decimal (53248) or hex string with prefix ($D000, 0xD000)"),
|
|
3701
|
+
data: byteArraySchema.min(1).describe("Bytes to write: decimal (255), hex ($FF, 0xFF), or binary (%11111111, 0b11111111). Mixed formats allowed.")
|
|
3471
3702
|
}).refine((input) => input.address + input.data.length - 1 <= 65535, {
|
|
3472
3703
|
message: "address + data.length must stay within the 16-bit address space",
|
|
3473
3704
|
path: ["data"]
|
|
@@ -3523,15 +3754,36 @@ var listBreakpointsTool = createViceTool({
|
|
|
3523
3754
|
});
|
|
3524
3755
|
var breakpointSetTool = createViceTool({
|
|
3525
3756
|
id: "breakpoint_set",
|
|
3526
|
-
description: "Creates an execution breakpoint or read/write watchpoint.",
|
|
3757
|
+
description: "Creates an execution breakpoint or read/write watchpoint. Use either (address, length) or (start, end) format. Addresses can be decimal (53248) or hex string with prefix ($D000, 0xD000).",
|
|
3527
3758
|
inputSchema: import_zod4.z.object({
|
|
3528
3759
|
kind: breakpointKindSchema,
|
|
3529
|
-
address: address16Schema.describe("Start address of the breakpoint range"),
|
|
3530
|
-
length: import_zod4.z.number().int().positive().default(1).describe("Size of the breakpoint range in bytes"),
|
|
3531
3760
|
condition: import_zod4.z.string().optional(),
|
|
3532
3761
|
label: import_zod4.z.string().optional(),
|
|
3533
3762
|
temporary: import_zod4.z.boolean().default(false),
|
|
3534
3763
|
enabled: import_zod4.z.boolean().default(true)
|
|
3764
|
+
}).and(
|
|
3765
|
+
import_zod4.z.union([
|
|
3766
|
+
import_zod4.z.object({
|
|
3767
|
+
address: address16Schema.describe("Start address: decimal (53248) or hex string with prefix ($D000, 0xD000)"),
|
|
3768
|
+
length: import_zod4.z.number().int().positive().default(1).describe("Size of the breakpoint range in bytes")
|
|
3769
|
+
}),
|
|
3770
|
+
import_zod4.z.object({
|
|
3771
|
+
start: address16Schema.describe("Start address (inclusive): decimal (53248) or hex string with prefix ($D000, 0xD000)"),
|
|
3772
|
+
end: address16Schema.describe("End address (inclusive): decimal (53248) or hex string with prefix ($D000, 0xD000)")
|
|
3773
|
+
})
|
|
3774
|
+
])
|
|
3775
|
+
).transform((input) => {
|
|
3776
|
+
if ("start" in input && "end" in input) {
|
|
3777
|
+
if (input.end < input.start) {
|
|
3778
|
+
throw new Error("End address must be greater than or equal to start address");
|
|
3779
|
+
}
|
|
3780
|
+
return {
|
|
3781
|
+
...input,
|
|
3782
|
+
address: input.start,
|
|
3783
|
+
length: input.end - input.start + 1
|
|
3784
|
+
};
|
|
3785
|
+
}
|
|
3786
|
+
return input;
|
|
3535
3787
|
}),
|
|
3536
3788
|
dataSchema: import_zod4.z.object({
|
|
3537
3789
|
breakpoint: breakpointSchema,
|