c64bridge 0.5.1 → 0.6.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/README.md +17 -5
- package/data/assembly/assembly-spec.md +24 -0
- package/data/assembly/examples/video/hello_world.asm +39 -0
- package/data/basic/basic-pitfalls.md +236 -0
- package/data/basic/basic-spec.md +507 -198
- package/data/video/petscii-style-guide.md +105 -0
- package/data/video/sprite-charset-best-practices.md +292 -0
- package/dist/c64Client.js +1 -0
- package/dist/prompts/registry.js +10 -2
- package/dist/rag/knowledgeIndex.js +111 -24
- package/dist/rag/retriever.js +110 -4
- package/dist/tools/audio.js +26 -13
- package/dist/tools/developer.js +34 -0
- package/dist/tools/graphics.js +6 -5
- package/dist/tools/memory.js +1 -1
- package/dist/tools/pollValidator.js +256 -0
- package/dist/tools/programRunners.js +352 -12
- package/dist/tools/rag.js +1 -7
- package/doc/MCP_SETUP.md +7 -1
- package/doc/bun/baseline-metrics.md +16 -0
- package/doc/bun/migration-checklist.md +55 -0
- package/doc/bun/migration.md +83 -0
- package/doc/developer.md +72 -10
- package/doc/improve-knowledge/notes.md +29 -0
- package/doc/improve-knowledge/plan.md +28 -3
- package/doc/improve-knowledge/rollout.md +39 -5
- package/doc/meta-tools/README.md +101 -0
- package/doc/meta-tools/analysis.md +255 -0
- package/doc/{meta-tools.md → meta-tools/catalog.md} +2 -2
- package/doc/meta-tools/notes.md +174 -0
- package/doc/meta-tools/rollout.md +343 -0
- package/mcp.json +1 -1
- package/package.json +17 -10
- package/scripts/c64-cli.mjs +42 -7
- package/scripts/c64-tool.sh +7 -1
- package/scripts/check-node-compat.mjs +107 -0
- package/scripts/invoke-bun.mjs +58 -0
- package/scripts/rag-rebuild.mjs +11 -13
- package/scripts/run-mcp-check.sh +10 -2
- package/scripts/run-tests.mjs +3 -3
- package/scripts/run-tests.ts +187 -0
- package/scripts/start.mjs +3 -26
- package/scripts/update-readme.ts +17 -1
- package/scripts/verify-package.mjs +0 -1
- package/data/assembly/examples/effects/sinewave.asm +0 -5
- package/doc/meta-tools-rollout.md +0 -211
- package/scripts/register-ts-node.mjs +0 -6
- /package/data/assembly/examples/{graphics/sprite/mover.asm → video/sprite_mover.asm} +0 -0
package/README.md
CHANGED
|
@@ -332,10 +332,16 @@ Please note that all logs use `stderr` since `stdout` is reserved for the MCP pr
|
|
|
332
332
|
|
|
333
333
|
## Build & Test 🧪
|
|
334
334
|
|
|
335
|
-
- `
|
|
335
|
+
- `bun install` — install dependencies for development (fast path). Node users can continue to use `npm install`.
|
|
336
|
+
- `bun run build` — type-check the TypeScript sources, normalize the dist layout for packaging, and regenerate the MCP API tables in `README.md`.
|
|
336
337
|
- `npm test` — run the integration tests against an in-process mock that emulates the c64 REST API.
|
|
337
338
|
- `npm test -- --real` — exercise the same tests against a real c64 device. The runner reuses your MCP config (`~/.c64bridge.json` or `C64BRIDGE_CONFIG`) to determine the REST endpoint. You can also override explicitly with `--base-url=http://<host>`.
|
|
338
339
|
- `npm run check` — convenience command that runs both the type-check and the mock-backed test suite.
|
|
340
|
+
- `npm run coverage` — runs the Bun-powered test harness with coverage enabled and emits `coverage/lcov.info` (CI uploads to Codecov).
|
|
341
|
+
|
|
342
|
+
**Development Tooling**
|
|
343
|
+
|
|
344
|
+
This project uses [Bun](https://bun.sh/) for building and testing due to its high performance (significantly faster than npm/node for development workflows). The npm package remains fully compatible with Node.js 18+ and can be installed and run using standard npm commands. For release preparation, npm/node is still used to ensure everything works correctly on the target platform.
|
|
339
345
|
|
|
340
346
|
The test runner accepts the following options:
|
|
341
347
|
|
|
@@ -347,6 +353,8 @@ The test runner accepts the following options:
|
|
|
347
353
|
|
|
348
354
|
<!-- AUTO-GENERATED:MCP-DOCS-START -->
|
|
349
355
|
|
|
356
|
+
This MCP server exposes **74 tools**, **25 resources**, and **7 prompts** for controlling your Commodore 64.
|
|
357
|
+
|
|
350
358
|
### Tools
|
|
351
359
|
|
|
352
360
|
#### Programs
|
|
@@ -395,10 +403,10 @@ The test runner accepts the following options:
|
|
|
395
403
|
| `analyze_audio` | Automatically analyze SID playback when the user requests verification feedback. | `sid`, `audio`, `analysis` |
|
|
396
404
|
| `modplay_file` | Play a MOD tracker module stored on the Ultimate filesystem. | `sid`, `audio`, `playback` |
|
|
397
405
|
| `music_compile_and_play` | Compile a SIDWAVE composition to PRG or SID and optionally play it immediately. | `sid`, `audio`, `music`, `compiler` |
|
|
398
|
-
| `music_generate` | Generate a lightweight arpeggio and schedule playback on SID voice 1. | `sid`, `audio`, `music`, `generator` |
|
|
406
|
+
| `music_generate` | Generate a lightweight arpeggio and schedule playback on SID voice 1. | `sid`, `audio`, `music`, `generator`, `pal-ntsc` |
|
|
399
407
|
| `record_and_analyze_audio` | Record audio from the default input device and analyze SID playback characteristics. | `sid`, `audio`, `analysis` |
|
|
400
408
|
| `sid_note_off` | Release a SID voice by clearing its GATE bit. | `sid`, `audio`, `control`, `music` |
|
|
401
|
-
| `sid_note_on` | Trigger a SID voice with configurable waveform, pulse width, and ADSR envelope. See c64://specs/sid. | `sid`, `audio`, `control`, `music` |
|
|
409
|
+
| `sid_note_on` | Trigger a SID voice with configurable waveform, pulse width, and ADSR envelope. See c64://specs/sid. | `sid`, `audio`, `control`, `music`, `pal-ntsc` |
|
|
402
410
|
| `sid_reset` | Reset the SID chip either softly (silence) or with a full register scrub. | `sid`, `audio`, `control` |
|
|
403
411
|
| `sid_silence_all` | Silence all SID voices by clearing control and envelope registers. | `sid`, `audio`, `control` |
|
|
404
412
|
| `sid_volume` | Set the SID master volume register at $D418. See c64://specs/sid. | `sid`, `audio`, `control` |
|
|
@@ -458,8 +466,8 @@ The test runner accepts the following options:
|
|
|
458
466
|
|
|
459
467
|
| Name | Description | Tags |
|
|
460
468
|
| --- | --- | --- |
|
|
461
|
-
| `create_petscii_image` | Create PETSCII art from prompts or text, optionally run it on the C64, and return metadata. See c64://specs/basic and c64://specs/
|
|
462
|
-
| `generate_sprite_prg` | Generate and execute a PRG that displays a sprite from raw 63-byte data. See c64://specs/vic for registers. | `graphics`, `vic`, `sprite`, `assembly` |
|
|
469
|
+
| `create_petscii_image` | Create PETSCII art from prompts or text, optionally run it on the C64, and return metadata including PETSCII codes and glyphs. See c64://specs/basic, c64://specs/vic, and c64://specs/charset. | `graphics`, `vic`, `petscii`, `basic`, `pal-ntsc` |
|
|
470
|
+
| `generate_sprite_prg` | Generate and execute a PRG that displays a sprite from raw 63-byte data. See c64://specs/vic for registers. | `graphics`, `vic`, `sprite`, `assembly`, `pal-ntsc` |
|
|
463
471
|
| `render_petscii_screen` | Render PETSCII text to the screen with optional border/background colours. See c64://specs/basic. | `graphics`, `vic`, `basic`, `screen` |
|
|
464
472
|
|
|
465
473
|
#### Printer
|
|
@@ -561,12 +569,16 @@ The test runner accepts the following options:
|
|
|
561
569
|
| `c64://docs/index` | Explains how to approach each knowledge bundle and when to consult it. |
|
|
562
570
|
| `c64://context/bootstrap` | Step-by-step rules for safe automation, verification, and rollback on the C64. |
|
|
563
571
|
| `c64://specs/basic` | Token definitions, syntax rules, and device I/O guidance for BASIC v2. |
|
|
572
|
+
| `c64://docs/basic/pitfalls` | Quickref covering quotation handling, line length, tokenization, variable names, and other BASIC traps. |
|
|
564
573
|
| `c64://specs/assembly` | Official opcode matrix, addressing modes, and zero-page strategy for the 6510 CPU. |
|
|
565
574
|
| `c64://specs/sid` | Register map, waveform behaviour, and ADSR envelopes for expressive SID playback. |
|
|
566
575
|
| `c64://specs/sidwave` | Defines the SIDWAVE interchange format used by the SID composer workflow. |
|
|
567
576
|
| `c64://docs/sid/file-structure` | Explains PSID/RSID headers, metadata blocks, and compatibility notes for imported music. |
|
|
568
577
|
| `c64://docs/sid/best-practices` | Captures proven waveforms, ADSR presets, phrasing, and verification workflow for pleasant SID music. |
|
|
569
578
|
| `c64://specs/vic` | Covers raster timing, sprite control, colour RAM, and bitmap modes on the VIC-II. |
|
|
579
|
+
| `c64://specs/charset` | Character code table mapping PETSCII codes to screen codes, glyphs, and keyboard input. |
|
|
580
|
+
| `c64://docs/petscii-style` | Documents colour palette, readability presets, dithering patterns, and best practices for creating artistic and readable PETSCII displays. |
|
|
581
|
+
| `c64://docs/sprite-charset-workflows` | Documents sprite and charset workflows, memory layout, VIC-II configuration, common pitfalls, and proven techniques for hardware-accelerated graphics. |
|
|
570
582
|
| `c64://specs/memory-map` | Page-by-page breakdown of the 64 KB address space with hardware, ROM, and RAM regions. |
|
|
571
583
|
| `c64://specs/memory-low` | Documents zero-page variables, BASIC pointers, and KERNAL workspace addresses. |
|
|
572
584
|
| `c64://specs/memory-kernal` | Lists KERNAL ROM vectors and service routines for OS-level functionality. |
|
|
@@ -194,3 +194,27 @@ Modes (columns): `A # ZP ZPX ZPY ABS ABSX ABSY IND IZX IZY REL IMP`
|
|
|
194
194
|
- Data: `.byte expr[,…]`, `.word expr[,…]`
|
|
195
195
|
- Symbols: `name = expr` / `.equ name, expr`
|
|
196
196
|
- Alignment/fill (assembler‑specific): `.align n`, `.fill count, value`
|
|
197
|
+
|
|
198
|
+
## Tips and Tricks
|
|
199
|
+
|
|
200
|
+
### Basic Start Header
|
|
201
|
+
|
|
202
|
+
- PRG file = 2-byte little-endian load address + bytes
|
|
203
|
+
- Place a tokenized BASIC line at $0801, e.g. `10 SYS 4096` (token SYS = $9E) to jump to $1000
|
|
204
|
+
- Ensure load-address at PRG start matches where BASIC was placed (e.g. $01 $08)
|
|
205
|
+
- Machine code may live at $1000 or directly after BASIC; adjust SYS target accordingly
|
|
206
|
+
|
|
207
|
+
### Display Text on Screen
|
|
208
|
+
|
|
209
|
+
1) KERNAL CHROUT (portable)
|
|
210
|
+
- Put PETSCII byte in A; JSR $FFD2 to print at cursor. Handles charset mapping.
|
|
211
|
+
- Use for portability and when charset may vary.
|
|
212
|
+
2) Direct screen writes (fast)
|
|
213
|
+
- STA $0400,X writes VIC-II screen codes directly. Use when you control charset and need speed.
|
|
214
|
+
- Color via STA $D800,X (4-bit color index).
|
|
215
|
+
|
|
216
|
+
Screen-code conversion
|
|
217
|
+
|
|
218
|
+
- If input is ASCII uppercase 'A'..'Z', convert: screen = PETSCII - $40 (e.g. $41→$01). Implement in a small loop if needed.
|
|
219
|
+
|
|
220
|
+
This file is intentionally minimal: use `basicConverter` / `assemblyConverter` in `src/` for tokenization/PRG building and `data/video/character-set.csv` for exact screen-code mappings.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
; hello_world_prg.asm
|
|
2
|
+
; Single-file PRG layout:
|
|
3
|
+
; - Tokenized one-line BASIC at $0801: 10 SYS 4096
|
|
4
|
+
; - Machine code placed at $1000 which writes the message directly to screen RAM ($0400)
|
|
5
|
+
; (no KERNAL CHROUT or BASIC printing is used)
|
|
6
|
+
|
|
7
|
+
.org $0801
|
|
8
|
+
; next-line pointer (little-endian) -> $080C (start + line length)
|
|
9
|
+
.byte $0C, $08
|
|
10
|
+
; line number 10
|
|
11
|
+
.byte $0A, $00
|
|
12
|
+
; tokenized content: SYS (0x9E), space (0x20), '4','0','9','6' (ASCII/PETSCII digits)
|
|
13
|
+
.byte $9E, $20, $34, $30, $39, $36
|
|
14
|
+
; line terminator
|
|
15
|
+
.byte $00
|
|
16
|
+
; program end marker (two zero bytes)
|
|
17
|
+
.byte $00, $00
|
|
18
|
+
|
|
19
|
+
; -- machine code at $1000 ------------------------------------------------
|
|
20
|
+
.org $1000
|
|
21
|
+
start:
|
|
22
|
+
ldx #$00 ; X = 0
|
|
23
|
+
write_loop:
|
|
24
|
+
lda message, x ; load byte from message
|
|
25
|
+
beq done ; zero terminator -> finished
|
|
26
|
+
sta $0400, x ; write character to screen RAM (fast direct write)
|
|
27
|
+
inx
|
|
28
|
+
jmp write_loop
|
|
29
|
+
|
|
30
|
+
done:
|
|
31
|
+
rts
|
|
32
|
+
|
|
33
|
+
message:
|
|
34
|
+
; ASCII bytes for: HELLO, WORLD! (0-terminated)
|
|
35
|
+
; VIC-II screen codes for: HELLO, WORLD! (screen codes from data/video/character-set.csv)
|
|
36
|
+
; H E L L O , <space> W O R L D !
|
|
37
|
+
.byte $08, $05, $0C, $0C, $0F, $2C, $20, $17, $0F, $12, $0C, $04, $21, $00
|
|
38
|
+
|
|
39
|
+
; End of file
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# BASIC Pitfalls Quickref
|
|
2
|
+
|
|
3
|
+
Common mistakes and gotchas when writing Commodore BASIC v2 programs.
|
|
4
|
+
|
|
5
|
+
## Quotation Handling
|
|
6
|
+
|
|
7
|
+
**Problem:** Strings with unmatched quotes cause parsing errors.
|
|
8
|
+
|
|
9
|
+
```basic
|
|
10
|
+
10 PRINT "HELLO WORLD
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Solution:** Always close string literals with matching double quotes.
|
|
14
|
+
|
|
15
|
+
```basic
|
|
16
|
+
10 PRINT "HELLO WORLD"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Escaping quotes:** BASIC v2 has no escape sequence. Use `CHR$(34)` for embedded quotes.
|
|
20
|
+
|
|
21
|
+
```basic
|
|
22
|
+
10 PRINT "HE SAID " + CHR$(34) + "HELLO" + CHR$(34)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Line Length Limits
|
|
26
|
+
|
|
27
|
+
**Problem:** BASIC lines are limited to 80 characters (2 physical screen lines). Longer lines are truncated or cause errors.
|
|
28
|
+
|
|
29
|
+
**Solution:** Break long statements across multiple numbered lines.
|
|
30
|
+
|
|
31
|
+
```basic
|
|
32
|
+
10 A=1:B=2:C=3
|
|
33
|
+
20 D=A+B+C
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Multi-statement lines:** Use `:` to separate statements, but watch total character count.
|
|
37
|
+
|
|
38
|
+
## Line Numbers
|
|
39
|
+
|
|
40
|
+
**Problem:** Line numbers must be 0-63999. Reordering requires renumbering.
|
|
41
|
+
|
|
42
|
+
**Best practice:** Use increments of 10 (e.g., 10, 20, 30) to leave room for insertions.
|
|
43
|
+
|
|
44
|
+
```basic
|
|
45
|
+
10 REM MAIN LOOP
|
|
46
|
+
20 FOR I=1 TO 10
|
|
47
|
+
30 PRINT I
|
|
48
|
+
40 NEXT I
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Tokenization Issues
|
|
52
|
+
|
|
53
|
+
**Problem:** BASIC tokenizes keywords, which affects string matching and `DATA` statements.
|
|
54
|
+
|
|
55
|
+
**Impact on DATA:**
|
|
56
|
+
|
|
57
|
+
```basic
|
|
58
|
+
10 DATA PRINT,GOTO,END
|
|
59
|
+
20 READ A$,B$,C$
|
|
60
|
+
30 PRINT A$ :REM DISPLAYS "P" + token bytes, not "PRINT"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Solution:** Quote `DATA` strings that might contain keywords.
|
|
64
|
+
|
|
65
|
+
```basic
|
|
66
|
+
10 DATA "PRINT","GOTO","END"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Variable Names
|
|
70
|
+
|
|
71
|
+
**Problem:** Only the first two characters are significant. `SPEED` and `SPECIAL` both resolve to `SP`.
|
|
72
|
+
|
|
73
|
+
```basic
|
|
74
|
+
10 SPEED=10
|
|
75
|
+
20 SPECIAL=20
|
|
76
|
+
30 PRINT SPEED :REM PRINTS 20, NOT 10
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Solution:** Use unique first-two-character combinations.
|
|
80
|
+
|
|
81
|
+
```basic
|
|
82
|
+
10 SP=10
|
|
83
|
+
20 SZ=20
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Array Dimensions
|
|
87
|
+
|
|
88
|
+
**Problem:** Arrays default to dimension 10 (indices 0-10, 11 elements). Using `DIM A(10)` also creates 11 elements (0-10).
|
|
89
|
+
|
|
90
|
+
**Solution:** Explicitly dimension arrays to the exact size needed and remember the 0 index.
|
|
91
|
+
|
|
92
|
+
```basic
|
|
93
|
+
10 DIM A(9) :REM CREATES 10 ELEMENTS (0-9)
|
|
94
|
+
20 FOR I=0 TO 9
|
|
95
|
+
30 A(I)=I*2
|
|
96
|
+
40 NEXT I
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## String Concatenation
|
|
100
|
+
|
|
101
|
+
**Problem:** String concatenation without spaces can be ambiguous.
|
|
102
|
+
|
|
103
|
+
```basic
|
|
104
|
+
10 A$="HELLO"
|
|
105
|
+
20 B$="WORLD"
|
|
106
|
+
30 C$=A$+B$ :REM WORKS
|
|
107
|
+
40 D$=A$B$ :REM SYNTAX ERROR
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Solution:** Always use `+` for concatenation.
|
|
111
|
+
|
|
112
|
+
## Floating Point Precision
|
|
113
|
+
|
|
114
|
+
**Problem:** BASIC uses 5-byte floating point with limited precision (~9 digits). Rounding errors accumulate.
|
|
115
|
+
|
|
116
|
+
```basic
|
|
117
|
+
10 A=0.1+0.1+0.1
|
|
118
|
+
20 PRINT A=0.3 :REM MAY PRINT 0 (FALSE)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Solution:** Use integer arithmetic when exact values are required, or add small epsilon for comparisons.
|
|
122
|
+
|
|
123
|
+
```basic
|
|
124
|
+
10 A=1+1+1
|
|
125
|
+
20 B=A/10
|
|
126
|
+
30 IF ABS(B-0.3)<0.0001 THEN PRINT "CLOSE ENOUGH"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Device Numbers
|
|
130
|
+
|
|
131
|
+
**Problem:** Using wrong device numbers causes `FILE NOT FOUND` or hangs.
|
|
132
|
+
|
|
133
|
+
- Device 0: Keyboard
|
|
134
|
+
- Device 1: Cassette
|
|
135
|
+
- Device 3: Screen
|
|
136
|
+
- Device 4-7: Printers
|
|
137
|
+
- Device 8-11: Disk drives
|
|
138
|
+
|
|
139
|
+
**Solution:** Always verify device numbers before `OPEN` statements.
|
|
140
|
+
|
|
141
|
+
```basic
|
|
142
|
+
10 OPEN 1,8,15,"I0":REM OPEN COMMAND CHANNEL ON DRIVE 8
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Memory Conflicts
|
|
146
|
+
|
|
147
|
+
**Problem:** BASIC program area grows downward from `$0801`. String/array space grows upward from `$9FFF` (or lower if adjusted). They can collide.
|
|
148
|
+
|
|
149
|
+
**Symptoms:** `OUT OF MEMORY` errors or system crashes.
|
|
150
|
+
|
|
151
|
+
**Solution:** Monitor free memory with `FRE(0)` and keep programs compact.
|
|
152
|
+
|
|
153
|
+
```basic
|
|
154
|
+
10 PRINT FRE(0) :REM PRINT FREE BYTES
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## GOTO/GOSUB Loops
|
|
158
|
+
|
|
159
|
+
**Problem:** Excessive `GOSUB` without matching `RETURN` exhausts the stack (limited to ~50 nested calls).
|
|
160
|
+
|
|
161
|
+
**Solution:** Structure programs with main loops and balanced subroutine calls.
|
|
162
|
+
|
|
163
|
+
```basic
|
|
164
|
+
10 FOR I=1 TO 10
|
|
165
|
+
20 GOSUB 100
|
|
166
|
+
30 NEXT I
|
|
167
|
+
40 END
|
|
168
|
+
100 PRINT I
|
|
169
|
+
110 RETURN
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Timing and Speed
|
|
173
|
+
|
|
174
|
+
**Problem:** BASIC is interpreted and slow (~1000 statements/sec). Tight loops with many operations lag.
|
|
175
|
+
|
|
176
|
+
**Solution:** Optimize hot loops, minimize array access, and consider assembly for performance-critical code.
|
|
177
|
+
|
|
178
|
+
```basic
|
|
179
|
+
10 REM SLOW
|
|
180
|
+
20 FOR I=1 TO 1000
|
|
181
|
+
30 A=A+1:B=B+1:C=C+1
|
|
182
|
+
40 NEXT I
|
|
183
|
+
|
|
184
|
+
10 REM FASTER
|
|
185
|
+
20 FOR I=1 TO 1000
|
|
186
|
+
30 A=A+1
|
|
187
|
+
40 NEXT I:B=A:C=A
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Input Quirks
|
|
191
|
+
|
|
192
|
+
**Problem:** `INPUT` statements can be aborted with `STOP` or `RUN/STOP-RESTORE`, leaving variables unchanged or partially set.
|
|
193
|
+
|
|
194
|
+
**Solution:** Validate inputs and handle empty/invalid responses.
|
|
195
|
+
|
|
196
|
+
```basic
|
|
197
|
+
10 INPUT "ENTER NUMBER";A
|
|
198
|
+
20 IF A<1 OR A>100 THEN PRINT "INVALID":GOTO 10
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Screen Codes vs. PETSCII
|
|
202
|
+
|
|
203
|
+
**Problem:** `PRINT` uses PETSCII codes, but `POKE` to screen memory requires screen codes (different mappings).
|
|
204
|
+
|
|
205
|
+
**Solution:** Use conversion routines or lookup tables when directly writing to screen RAM ($0400-$07E7).
|
|
206
|
+
|
|
207
|
+
```basic
|
|
208
|
+
10 REM PRINT USES PETSCII
|
|
209
|
+
20 PRINT "A" :REM DISPLAYS 'A'
|
|
210
|
+
|
|
211
|
+
30 REM POKE TO SCREEN USES SCREEN CODES
|
|
212
|
+
40 POKE 1024,1 :REM DISPLAYS 'A' (SCREEN CODE 1)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## RESTORE Statement
|
|
216
|
+
|
|
217
|
+
**Problem:** `RESTORE` without line number resets `READ` pointer to the first `DATA` statement. If you need to re-read from a specific line, use `RESTORE linenum`.
|
|
218
|
+
|
|
219
|
+
```basic
|
|
220
|
+
10 DATA 1,2,3
|
|
221
|
+
20 DATA 4,5,6
|
|
222
|
+
30 READ A:READ B:READ C
|
|
223
|
+
40 RESTORE 20 :REM RESET TO LINE 20
|
|
224
|
+
50 READ D:READ E:READ F
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Summary
|
|
228
|
+
|
|
229
|
+
- **Always close quotes** and watch line lengths (80 chars).
|
|
230
|
+
- **Use unique variable prefixes** (first 2 chars matter).
|
|
231
|
+
- **Dimension arrays explicitly** and remember 0-indexing.
|
|
232
|
+
- **Quote DATA strings** to avoid tokenization issues.
|
|
233
|
+
- **Check device numbers** before OPEN.
|
|
234
|
+
- **Balance GOSUB/RETURN** to avoid stack overflow.
|
|
235
|
+
- **Validate INPUT** to handle user errors gracefully.
|
|
236
|
+
- **Convert between PETSCII and screen codes** when needed.
|