| @@ -0,0 +1,18 @@ | |||||
| # C64 / 6510 Skill Router | |||||
| Load the smallest set of skills needed for the task. | |||||
| | Task | Skill | | |||||
| |---|---| | |||||
| | Memory addresses, page zero, screen RAM, color RAM, ROM/RAM/I/O banking | `.ai/skills/c64-memory-map/SKILL.md` | | |||||
| | BASIC V2, `SYS`, `USR`, `PEEK`, `POKE`, BASIC internals | `.ai/skills/basic-v2-bridge/SKILL.md` | | |||||
| | KERNAL jump table, CHROUT, GETIN, LOAD/SAVE, device I/O | `.ai/skills/kernal-jump-table/SKILL.md` | | |||||
| | 6510 assembly, addressing modes, registers, stack, subroutines | `.ai/skills/6510-assembly/SKILL.md` | | |||||
| | VIC-II graphics, screen, bitmap, sprites, character sets, raster | `.ai/skills/vic-ii-graphics/SKILL.md` | | |||||
| | SID sound, voices, ADSR, filters, paddles | `.ai/skills/sid-sound/SKILL.md` | | |||||
| | CIA chips, timers, keyboard, joystick, serial bus, user port | `.ai/skills/cia-io/SKILL.md` | | |||||
| | IRQ, NMI, reset vectors, vector patching, raster interrupts | `.ai/skills/interrupts-reset/SKILL.md` | | |||||
| | Machine-language monitor, assembler, disassembler, emulator debugging | `.ai/skills/debugging-monitor/SKILL.md` | | |||||
| | General C64 design practices and optimization | `.ai/skills/c64-programming-practices/SKILL.md` | | |||||
| Always keep `references/c64-quick-reference.md` available for address lookup. | |||||
| @@ -0,0 +1,111 @@ | |||||
| # Skill: 6510 Assembly for the Commodore 64 | |||||
| ## Use this skill when | |||||
| The task involves 6510/6502 machine language, addressing modes, registers, stack, flags, subroutines, speed optimization, or assembly source. | |||||
| ## CPU model | |||||
| The Commodore 64 uses the 6510, which is software-compatible with the 6502 instruction set and adds an on-chip I/O port at `$0000-$0001` used heavily for memory banking and cassette control. | |||||
| ## Registers | |||||
| | Register | Purpose | | |||||
| |---|---| | |||||
| | A | Accumulator; arithmetic, logic, data movement | | |||||
| | X | Index register; loops, offsets, counters | | |||||
| | Y | Index register; loops, offsets, KERNAL/BASIC calling conventions | | |||||
| | SP | Stack pointer, stack page `$0100-$01FF` | | |||||
| | PC | Program counter | | |||||
| | P | Processor status flags: N V - B D I Z C | | |||||
| ## Addressing modes to prefer | |||||
| - Immediate: `lda #$01` | |||||
| - Zero page: `lda $fb` faster/smaller than absolute. | |||||
| - Zero page indexed: `lda $fb,x` | |||||
| - Absolute: `lda $c000` | |||||
| - Absolute indexed: `lda $0400,x` | |||||
| - Indirect indexed: `lda ($fb),y` for pointer walking. | |||||
| - Absolute indirect only works with `JMP (addr)`. | |||||
| ## Subroutine discipline | |||||
| Called from BASIC with `SYS`: | |||||
| ```asm | |||||
| * = $c000 | |||||
| start: ; work here | |||||
| rts | |||||
| ``` | |||||
| If using registers for temporary work but caller expects preservation: | |||||
| ```asm | |||||
| pha | |||||
| txa: pha | |||||
| tya: pha | |||||
| ; work | |||||
| pla: tay | |||||
| pla: tax | |||||
| pla | |||||
| rts | |||||
| ``` | |||||
| ## Flags | |||||
| - `C` carry: arithmetic carry/borrow; set before `SBC`, clear before `ADC` unless chaining multi-byte arithmetic. | |||||
| - `Z` zero: many KERNAL calls and comparisons rely on it. | |||||
| - `N` negative: mirrors bit 7 of result. | |||||
| - `I` interrupt disable: `SEI` disables maskable IRQ; `CLI` enables. | |||||
| - `D` decimal mode: normally keep clear on C64 unless using BCD intentionally. | |||||
| ## Multi-byte addition pattern | |||||
| ```asm | |||||
| clc | |||||
| lda lo1 | |||||
| adc lo2 | |||||
| sta resultlo | |||||
| lda hi1 | |||||
| adc hi2 | |||||
| sta resulthi | |||||
| ``` | |||||
| ## Pointer walking pattern | |||||
| ```asm | |||||
| ptr = $fb | |||||
| lda #<source | |||||
| sta ptr | |||||
| lda #>source | |||||
| sta ptr+1 | |||||
| ldy #0 | |||||
| loop: lda (ptr),y | |||||
| beq done | |||||
| jsr $ffd2 | |||||
| iny | |||||
| bne loop | |||||
| inc ptr+1 | |||||
| bne loop | |||||
| done: rts | |||||
| ``` | |||||
| ## Avoid unless requested | |||||
| - Undocumented opcodes. | |||||
| - Self-modifying code without comments. | |||||
| - Cycle-exact code without target PAL/NTSC note. | |||||
| - Overwriting zero-page locations not reserved for your routine. | |||||
| ## Agent checklist | |||||
| For assembly answers: | |||||
| 1. Identify assembler syntax. | |||||
| 2. Give load address. | |||||
| 3. Show how to run it. | |||||
| 4. Name KERNAL calls used. | |||||
| 5. Declare clobbered registers. | |||||
| 6. Explain zero-page usage. | |||||
| @@ -0,0 +1,103 @@ | |||||
| # Skill: BASIC V2 Bridge — SYS, USR, PEEK, POKE, and BASIC Internals | |||||
| ## Use this skill when | |||||
| The task involves BASIC V2, calling assembly from BASIC, calling BASIC ROM routines from assembly, `SYS`, `USR`, `PEEK`, `POKE`, `WAIT`, tokenization, variable storage, or BASIC program layout. | |||||
| ## Core concepts | |||||
| - BASIC V2 is interpreted. Each statement is parsed and executed at runtime, which is why BASIC is slower than ML. | |||||
| - BASIC program lines are tokenized and linked in memory. | |||||
| - BASIC and ML can cooperate if memory ownership is clear. | |||||
| - `SYS` calls an ML routine as a command. | |||||
| - `USR(x)` calls an ML routine as a function-like expression. | |||||
| - `PEEK` reads one byte; `POKE` writes one byte. | |||||
| ## Calling ML with SYS | |||||
| BASIC: | |||||
| ```basic | |||||
| 10 SYS 49152 | |||||
| ``` | |||||
| Assembly routine at `$C000` must normally end with: | |||||
| ```asm | |||||
| rts | |||||
| ``` | |||||
| ### Passing registers through SYS | |||||
| Before `SYS`, BASIC can place values in these locations: | |||||
| | Decimal | Hex | Register | | |||||
| |---:|---:|---| | |||||
| | 780 | `$030C` | Accumulator A | | |||||
| | 781 | `$030D` | X register | | |||||
| | 782 | `$030E` | Y register | | |||||
| | 783 | `$030F` | Processor status | | |||||
| Example: | |||||
| ```basic | |||||
| 10 POKE 780,65:REM A = PETSCII "A" | |||||
| 20 SYS 49152 | |||||
| 30 PRINT PEEK(780) | |||||
| ``` | |||||
| ## Calling ML with USR | |||||
| `USR(x)` is best when an ML routine should behave like a function. | |||||
| Use cases: | |||||
| - Fast math helper. | |||||
| - Custom string/numeric function. | |||||
| - BASIC extension experiments. | |||||
| Cautions: | |||||
| - `USR` uses BASIC floating-point accumulator conventions. | |||||
| - It is more complex than `SYS`; use `SYS` first unless function syntax is needed. | |||||
| ## BASIC pointers worth knowing | |||||
| | Decimal | Hex | Meaning | | |||||
| |---:|---:|---| | |||||
| | 43-44 | `$002B-$002C` | Start of BASIC text | | |||||
| | 45-46 | `$002D-$002E` | End of BASIC text | | |||||
| | 47-48 | `$002F-$0030` | Start of variables | | |||||
| | 49-50 | `$0031-$0032` | Start of arrays | | |||||
| | 51-52 | `$0033-$0034` | End of arrays/start of strings | | |||||
| | 55-56 | `$0037-$0038` | Top of BASIC memory | | |||||
| ## BASIC patterns | |||||
| ### Change border and background | |||||
| ```basic | |||||
| 10 POKE 53280,6:REM BORDER $D020 | |||||
| 20 POKE 53281,0:REM BACKGROUND $D021 | |||||
| ``` | |||||
| ### Write to screen and color RAM | |||||
| ```basic | |||||
| 10 POKE 1024,1:REM SCREEN CODE A | |||||
| 20 POKE 55296,2:REM COLOR RED IN LOW NYBBLE | |||||
| ``` | |||||
| ### Protect ML at $C000 with simple convention | |||||
| For many C64 BASIC programs, `$C000` is outside normal BASIC RAM. Still, document the assumption and avoid loaders that extend into `$C000`. | |||||
| ## Agent checklist | |||||
| When producing BASIC+ML examples: | |||||
| 1. Give a BASIC loader if the user needs type-in code. | |||||
| 2. Give the assembly source separately when possible. | |||||
| 3. Include exact `SYS` address. | |||||
| 4. Ensure ML routine ends in `RTS`. | |||||
| 5. Explain which locations are POKEd and why. | |||||
| @@ -0,0 +1,96 @@ | |||||
| # Skill: C64 Memory Map and Address Discipline | |||||
| ## Use this skill when | |||||
| The task involves memory addresses, `PEEK`, `POKE`, page zero, screen/color memory, ROM/RAM/I/O banking, vectors, or safe placement of machine-language code. | |||||
| ## Core concepts | |||||
| - The 6510 can address 64K: `$0000-$FFFF` / `0-65535`. | |||||
| - Most two-byte addresses are stored little-endian: low byte first, high byte second. | |||||
| - Page zero `$0000-$00FF` is fast and heavily used by BASIC/KERNAL. | |||||
| - Page one `$0100-$01FF` is the processor stack. | |||||
| - Screen RAM normally starts at `$0400` / `1024`. | |||||
| - Color RAM normally starts at `$D800` / `55296`; only the low nybble is meaningful. | |||||
| - I/O registers normally occupy `$D000-$DFFF`; character ROM or RAM can be banked into the same range. | |||||
| - BASIC ROM is normally at `$A000-$BFFF`; KERNAL ROM at `$E000-$FFFF`. | |||||
| - RAM exists under ROM/I/O areas, but using it requires banking and interrupt care. | |||||
| ## Key addresses | |||||
| | Decimal | Hex | Meaning | | |||||
| |---:|---:|---| | |||||
| | 0 | `$0000` | 6510 data-direction register | | |||||
| | 1 | `$0001` | 6510 processor port; controls ROM/I/O banking and cassette lines | | |||||
| | 43-44 | `$002B-$002C` | Start of BASIC program text pointer | | |||||
| | 45-46 | `$002D-$002E` | End of BASIC program text pointer | | |||||
| | 55-56 | `$0037-$0038` | Top of BASIC memory pointer | | |||||
| | 198 | `$00C6` | Keyboard buffer length | | |||||
| | 631-640 | `$0277-$0280` | Keyboard buffer | | |||||
| | 646 | `$0286` | Current text color | | |||||
| | 780-783 | `$030C-$030F` | `SYS` register save/pass area: A, X, Y, status | | |||||
| | 788-789 | `$0314-$0315` | IRQ vector | | |||||
| | 790-791 | `$0316-$0317` | BRK vector | | |||||
| | 792-793 | `$0318-$0319` | NMI vector | | |||||
| | 1024-2023 | `$0400-$07E7` | Default 40x25 screen RAM | | |||||
| | 2040-2047 | `$07F8-$07FF` | Default sprite pointers | | |||||
| | 49152 | `$C000` | Common safe ML area if protected from BASIC use | | |||||
| | 53248 | `$D000` | VIC-II register base | | |||||
| | 54272 | `$D400` | SID register base | | |||||
| | 55296 | `$D800` | Color RAM base | | |||||
| | 56320 | `$DC00` | CIA #1 base | | |||||
| | 56576 | `$DD00` | CIA #2 base | | |||||
| ## Safe machine-language placement | |||||
| Common choices: | |||||
| - `$C000` / `49152`: often used for ML routines because BASIC normally has about 38911 bytes free and does not use this area directly. | |||||
| - Above a lowered BASIC top: set top-of-memory pointer and issue `NEW` before loading BASIC program. | |||||
| - In a cartridge/ROM area only when explicitly building cartridge code. | |||||
| - Avoid `$033C-$03FB` unless you know which cassette buffer or workspace is being used. | |||||
| ## Banking rules | |||||
| The 6510 processor port `$0001` controls what the CPU sees in ROM/I/O ranges. Use cautious read-modify-write: | |||||
| ```asm | |||||
| lda $01 | |||||
| pha | |||||
| ; change bits only as needed | |||||
| ; ... do banked access quickly ... | |||||
| pla | |||||
| sta $01 | |||||
| ``` | |||||
| When banking out I/O or banking in character ROM, interrupts that use I/O can fail. Disable IRQ briefly with `SEI`, restore `$01`, then `CLI`. | |||||
| ## BASIC bit manipulation patterns | |||||
| Set a bit: | |||||
| ```basic | |||||
| POKE A,PEEK(A) OR MASK | |||||
| ``` | |||||
| Clear a bit: | |||||
| ```basic | |||||
| POKE A,PEEK(A) AND (255-MASK) | |||||
| ``` | |||||
| Toggle a bit: | |||||
| ```basic | |||||
| POKE A,PEEK(A) XOR MASK | |||||
| ``` | |||||
| ## Agent checklist | |||||
| Before suggesting memory writes: | |||||
| 1. Identify whether the address is RAM, ROM, I/O, color RAM, vector, or register. | |||||
| 2. State decimal and hex. | |||||
| 3. Warn about global side effects. | |||||
| 4. Preserve existing bits unless replacing the whole register is intentional. | |||||
| 5. Explain how to restore the original value. | |||||
| @@ -0,0 +1,92 @@ | |||||
| # Skill: C64 Programming Practices, Patterns, Hints, and Optimization | |||||
| ## Use this skill when | |||||
| The task asks for design advice, best practices, performance improvements, code organization, hybrid BASIC/ML strategy, or C64-specific programming patterns. | |||||
| ## Practices | |||||
| ### Use the right layer | |||||
| - BASIC is excellent for quick control flow, menus, simple loaders, demos, and teaching. | |||||
| - Assembly is best for speed, graphics effects, sound engines, raster work, custom I/O, compression, and tight loops. | |||||
| - KERNAL calls are best for portability and standard I/O. | |||||
| - Direct hardware access is best when KERNAL overhead or abstraction gets in the way. | |||||
| ### Keep ML small and callable | |||||
| Build small routines with clear entry and exit conditions. Document: | |||||
| - Entry address. | |||||
| - Input registers/memory. | |||||
| - Output registers/memory. | |||||
| - Clobbered registers. | |||||
| - Zero-page locations used. | |||||
| - Whether interrupts must be enabled/disabled. | |||||
| ### Prefer tables | |||||
| Tables are often faster and simpler than computation on a 1 MHz CPU: | |||||
| - Screen row address tables. | |||||
| - Sprite animation pointer tables. | |||||
| - Sine/cosine movement tables. | |||||
| - Frequency tables for notes. | |||||
| - Bit masks. | |||||
| ### Preserve bits | |||||
| Hardware registers often pack unrelated settings into one byte. Use `AND`/`OR` masks instead of blind `STA`/`POKE` unless replacing the whole register is intended. | |||||
| ### Respect PETSCII vs screen codes | |||||
| - `CHROUT` expects PETSCII-style character output. | |||||
| - Screen RAM expects screen codes. | |||||
| - Key codes are different again. | |||||
| ### Optimize only where needed | |||||
| First make the code correct and stable. Then optimize hot paths: | |||||
| - Use zero-page addressing. | |||||
| - Unroll small loops when timing matters. | |||||
| - Avoid BASIC inside animation loops when ML is available. | |||||
| - Avoid multiplication/division in raster-critical paths. | |||||
| - Use precomputed tables. | |||||
| ### Keep recovery paths | |||||
| - Use emulator snapshots. | |||||
| - Keep STOP/RESTORE or reset strategy when possible. | |||||
| - Include a routine to restore vectors and screen colors. | |||||
| - Save original IRQ/NMI vectors before patching. | |||||
| ## Common patterns | |||||
| ### BASIC bootstrap + ML engine | |||||
| BASIC loads/starts; ML handles fast loop. | |||||
| ### ML service routine called by BASIC | |||||
| BASIC manages user interaction; ML performs fast operation. | |||||
| ### KERNAL I/O wrapper | |||||
| ML uses KERNAL jump table for file/device operations. | |||||
| ### Raster IRQ effect | |||||
| ML installs IRQ handler; handler changes VIC registers at specific raster lines. | |||||
| ### Double-buffered graphics data | |||||
| Prepare screen/sprite/bitmap data off-screen, then switch pointers/registers. | |||||
| ## Agent checklist | |||||
| 1. Choose BASIC, assembly, or hybrid explicitly. | |||||
| 2. Avoid magic numbers; name addresses and masks. | |||||
| 3. Show restore/cleanup logic. | |||||
| 4. Explain cycle/timing assumptions for demos/games. | |||||
| 5. Favor reusable routines over one-off POKEs. | |||||
| @@ -0,0 +1,77 @@ | |||||
| # Skill: CIA I/O, Timers, Keyboard, Joystick, Serial Bus, and User Port | |||||
| ## Use this skill when | |||||
| The task involves CIA chips, keyboard scanning, joysticks, timers, real-time clock, serial bus, disk/printer handshaking, RS-232, or user port I/O. | |||||
| ## CIA bases | |||||
| | Chip | Decimal | Hex | Common role | | |||||
| |---|---:|---:|---| | |||||
| | CIA #1 | 56320 | `$DC00` | Keyboard matrix, joystick ports, timers, TOD, IRQ | | |||||
| | CIA #2 | 56576 | `$DD00` | Serial bus, RS-232/user port, VIC bank select, NMI | | |||||
| ## CIA register layout | |||||
| Each CIA exposes 16 registers mirrored across its 256-byte block. | |||||
| | Offset | Purpose | | |||||
| |---:|---| | |||||
| | 0 | Port A data | | |||||
| | 1 | Port B data | | |||||
| | 2 | Port A data direction | | |||||
| | 3 | Port B data direction | | |||||
| | 4-5 | Timer A latch/counter low/high | | |||||
| | 6-7 | Timer B latch/counter low/high | | |||||
| | 8-11 | Time-of-day clock | | |||||
| | 12 | Serial data register | | |||||
| | 13 | Interrupt control/status | | |||||
| | 14 | Control register A | | |||||
| | 15 | Control register B | | |||||
| ## Joystick reading | |||||
| Joystick values are active low. | |||||
| - Port 2 commonly read at `$DC00` / `56320`. | |||||
| - Port 1 commonly read at `$DC01` / `56321`. | |||||
| Typical bits: | |||||
| | Bit | Mask | Direction/button | | |||||
| |---:|---:|---| | |||||
| | 0 | 1 | Up | | |||||
| | 1 | 2 | Down | | |||||
| | 2 | 4 | Left | | |||||
| | 3 | 8 | Right | | |||||
| | 4 | 16 | Fire | | |||||
| Pressed means bit is `0`. | |||||
| BASIC example: | |||||
| ```basic | |||||
| 10 J=PEEK(56320) | |||||
| 20 IF (J AND 16)=0 THEN PRINT "FIRE" | |||||
| ``` | |||||
| ## Serial bus concepts | |||||
| - Device numbers distinguish serial devices. | |||||
| - The C64 sends ATN, then TALK or LISTEN, plus optional secondary address. | |||||
| - Data is transferred one byte at a time using handshaking. | |||||
| - Prefer KERNAL routines (`SETLFS`, `SETNAM`, `OPEN`, `CHRIN`, `CHROUT`, `CLOSE`) unless bit-banging is the task. | |||||
| ## Timer principles | |||||
| - CIA timers can count CPU cycles or external CNT pulses. | |||||
| - Timer underflow can generate interrupts. | |||||
| - For reliable timing, acknowledge CIA interrupt source and avoid leaving stale flags. | |||||
| ## Agent checklist | |||||
| 1. Identify CIA #1 vs CIA #2. | |||||
| 2. Preserve data direction registers unless intentionally changing port direction. | |||||
| 3. Remember joystick and keyboard are active-low. | |||||
| 4. For serial/disk/printer, prefer KERNAL I/O. | |||||
| 5. For timers, show latch, control, interrupt enable, and acknowledge steps. | |||||
| @@ -0,0 +1,51 @@ | |||||
| # Skill: Debugging with Monitors, Assemblers, Disassemblers, and Emulators | |||||
| ## Use this skill when | |||||
| The task involves entering ML, inspecting memory, using monitors, disassembling ROM/RAM, debugging crashes, emulator setup, or converting between BASIC loaders and assembly. | |||||
| ## Core tools | |||||
| - Machine-language monitor: inspect/change memory and registers, run code, break, disassemble. | |||||
| - Assembler: converts mnemonics to opcodes. | |||||
| - Disassembler: converts opcodes back to mnemonics. | |||||
| - Emulator monitor: VICE monitor is excellent for breakpoints/watchpoints. | |||||
| ## Common monitor activities | |||||
| - Memory dump: inspect bytes at an address. | |||||
| - Assemble line: write one instruction at an address. | |||||
| - Disassemble range: inspect ML/ROM code. | |||||
| - Fill memory: clear or initialize a range. | |||||
| - Hunt/search: find byte patterns such as `20 D2 FF` for `JSR $FFD2`. | |||||
| - Register view: inspect A/X/Y/SP/PC/flags. | |||||
| ## Debugging workflow | |||||
| 1. Confirm load address and `SYS` start address. | |||||
| 2. Verify first bytes in memory match assembled output. | |||||
| 3. Put `BRK` in suspected code path when using a monitor. | |||||
| 4. Single-step through register changes. | |||||
| 5. Check stack if `RTS` returns to nonsense. | |||||
| 6. Check zero-page pointers for little-endian order. | |||||
| 7. Check interrupt state and banking register `$01` after crashes. | |||||
| 8. Reset emulator snapshots frequently. | |||||
| ## Crash checklist | |||||
| - Did the routine end with `RTS` when called by `SYS`? | |||||
| - Did code overwrite BASIC text or variables? | |||||
| - Did code corrupt `$01` and bank out KERNAL/BASIC unexpectedly? | |||||
| - Did an IRQ vector point to invalid memory? | |||||
| - Was a hardware interrupt acknowledged? | |||||
| - Did the stack underflow/overflow? | |||||
| - Was PETSCII/screen code confused with ASCII? | |||||
| ## Agent checklist | |||||
| When helping debug: | |||||
| 1. Ask for start address, assembler, and emulator if not provided. | |||||
| 2. Request or infer memory map touched by the code. | |||||
| 3. Provide monitor commands conceptually, not tied to one monitor unless specified. | |||||
| 4. Use small reproducible examples. | |||||
| @@ -0,0 +1,70 @@ | |||||
| # Skill: Interrupts, Reset, IRQ, NMI, BRK, and Vectors | |||||
| ## Use this skill when | |||||
| The task involves IRQ/NMI handlers, raster interrupts, STOP+RESTORE, reset behavior, BRK, vector patching, or safe interrupt disabling. | |||||
| ## Core concepts | |||||
| - RESET loads the CPU program counter from vector `$FFFC-$FFFD`. | |||||
| - IRQ/BRK loads from `$FFFE-$FFFF` after pushing PC/status to stack. | |||||
| - NMI loads from `$FFFA-$FFFB` and cannot be masked by the I flag. | |||||
| - C64 RAM vectors allow patching system behavior without changing ROM. | |||||
| ## Important RAM vectors | |||||
| | Decimal | Hex | Meaning | | |||||
| |---:|---:|---| | |||||
| | 788-789 | `$0314-$0315` | IRQ vector | | |||||
| | 790-791 | `$0316-$0317` | BRK vector | | |||||
| | 792-793 | `$0318-$0319` | NMI vector | | |||||
| | 768-779 | `$0300-$030B` | BASIC vectors: error, main loop, tokenize, list, execute, evaluate | | |||||
| ## Safe IRQ hook pattern | |||||
| 1. `SEI`. | |||||
| 2. Save old vector. | |||||
| 3. Store new low/high bytes to `$0314/$0315`. | |||||
| 4. `CLI`. | |||||
| 5. Handler saves registers. | |||||
| 6. Handler acknowledges its interrupt source. | |||||
| 7. Handler restores registers. | |||||
| 8. Handler jumps to old IRQ or normal KERNAL IRQ path. | |||||
| ## Minimal handler skeleton | |||||
| ```asm | |||||
| irq: pha | |||||
| txa | |||||
| pha | |||||
| tya | |||||
| pha | |||||
| ; acknowledge source here, e.g. VIC raster IRQ: | |||||
| lda #$01 | |||||
| sta $d019 | |||||
| ; do short, deterministic work | |||||
| pla | |||||
| tay | |||||
| pla | |||||
| tax | |||||
| pla | |||||
| jmp $ea31 ; normal KERNAL IRQ continuation on C64 | |||||
| ``` | |||||
| ## Warnings | |||||
| - Do not leave IRQ disabled unless building a controlled loader/demo effect. | |||||
| - NMI is used by RESTORE and CIA #2; avoid breaking STOP+RESTORE recovery unless intentional. | |||||
| - Raster IRQ code must be short and cycle-aware. | |||||
| - Always acknowledge the hardware source or the interrupt will immediately retrigger. | |||||
| ## Agent checklist | |||||
| 1. State interrupt source: VIC-II, CIA #1, CIA #2, BRK, RESTORE/NMI. | |||||
| 2. Show vector write low byte then high byte while IRQ disabled. | |||||
| 3. Save/restore A, X, Y unless deliberately not needed. | |||||
| 4. Acknowledge interrupt flags. | |||||
| 5. Chain to old handler or document full replacement. | |||||
| @@ -0,0 +1,103 @@ | |||||
| # Skill: KERNAL Jump Table and C64 Device I/O | |||||
| ## Use this skill when | |||||
| The task involves screen/keyboard I/O, files, disk, printer, tape, RS-232, serial bus, `LOAD`, `SAVE`, `OPEN`, `CLOSE`, `GETIN`, `CHROUT`, or KERNAL calls from assembly. | |||||
| ## Core principle | |||||
| Prefer KERNAL jump-table calls at the top of memory. They are stable public entry points and safer than jumping into undocumented ROM internals. | |||||
| ## Common KERNAL calls | |||||
| | Address | Name | Purpose | | |||||
| |---:|---|---| | |||||
| | `$FF81` | `CINT` | Initialize screen editor | | |||||
| | `$FF84` | `IOINIT` | Initialize I/O devices | | |||||
| | `$FF87` | `RAMTAS` | Initialize RAM/test memory | | |||||
| | `$FF8A` | `RESTOR` | Restore default vectors | | |||||
| | `$FF8D` | `VECTOR` | Read/set RAM vectors | | |||||
| | `$FF90` | `SETMSG` | Control system messages | | |||||
| | `$FF93` | `SECOND` | Send secondary address after LISTEN | | |||||
| | `$FF96` | `TKSA` | Send secondary address after TALK | | |||||
| | `$FF99` | `MEMTOP` | Read/set top of memory | | |||||
| | `$FF9C` | `MEMBOT` | Read/set bottom of memory | | |||||
| | `$FF9F` | `SCNKEY` | Scan keyboard | | |||||
| | `$FFA2` | `SETTMO` | Set serial timeout | | |||||
| | `$FFA5` | `ACPTR` | Input byte from serial bus | | |||||
| | `$FFA8` | `CIOUT` | Output byte to serial bus | | |||||
| | `$FFAB` | `UNTLK` | Send UNTALK | | |||||
| | `$FFAE` | `UNLSN` | Send UNLISTEN | | |||||
| | `$FFB1` | `LISTEN` | Command device to listen | | |||||
| | `$FFB4` | `TALK` | Command device to talk | | |||||
| | `$FFB7` | `READST` | Read I/O status byte | | |||||
| | `$FFBA` | `SETLFS` | Set logical file, device, secondary address | | |||||
| | `$FFBD` | `SETNAM` | Set filename pointer and length | | |||||
| | `$FFC0` | `OPEN` | Open logical file | | |||||
| | `$FFC3` | `CLOSE` | Close logical file | | |||||
| | `$FFC6` | `CHKIN` | Set input channel | | |||||
| | `$FFC9` | `CHKOUT` | Set output channel | | |||||
| | `$FFCC` | `CLRCHN` | Restore default I/O channels | | |||||
| | `$FFCF` | `CHRIN` | Input character | | |||||
| | `$FFD2` | `CHROUT` | Output character | | |||||
| | `$FFD5` | `LOAD` | Load RAM from device | | |||||
| | `$FFD8` | `SAVE` | Save RAM to device | | |||||
| | `$FFDB` | `SETTIM` | Set system clock | | |||||
| | `$FFDE` | `RDTIM` | Read system clock | | |||||
| | `$FFE1` | `STOP` | Test STOP key | | |||||
| | `$FFE4` | `GETIN` | Get character from keyboard/input buffer | | |||||
| | `$FFE7` | `CLALL` | Close all channels/files | | |||||
| | `$FFEA` | `UDTIM` | Update software clock | | |||||
| | `$FFED` | `SCREEN` | Get screen size | | |||||
| | `$FFF0` | `PLOT` | Read/set cursor position | | |||||
| | `$FFF3` | `IOBASE` | Return I/O base address | | |||||
| ## CHROUT example | |||||
| ```asm | |||||
| lda #'A' ; assembler may translate ASCII differently; PETSCII 65 works for A | |||||
| jsr $ffd2 ; CHROUT | |||||
| rts | |||||
| ``` | |||||
| ## GETIN example | |||||
| ```asm | |||||
| wait: jsr $ffe4 ; GETIN | |||||
| beq wait ; zero means no key available | |||||
| jsr $ffd2 ; echo key | |||||
| rts | |||||
| ``` | |||||
| ## Opening a device from ML | |||||
| Typical sequence: | |||||
| 1. `SETLFS` with logical file, device number, secondary address. | |||||
| 2. `SETNAM` with filename length and pointer. | |||||
| 3. `OPEN`. | |||||
| 4. `CHKIN` or `CHKOUT`. | |||||
| 5. Use `CHRIN` / `CHROUT`. | |||||
| 6. `CLRCHN`. | |||||
| 7. `CLOSE`. | |||||
| ## Device numbers | |||||
| | Device | Meaning | | |||||
| |---:|---| | |||||
| | 0 | Keyboard | | |||||
| | 1 | Cassette | | |||||
| | 2 | RS-232 | | |||||
| | 3 | Screen | | |||||
| | 4-5 | Printers, usually serial bus | | |||||
| | 8-11 | Disk drives, commonly `8` for first 1541 | | |||||
| ## Agent checklist | |||||
| When writing KERNAL-call assembly: | |||||
| 1. State required registers before call. | |||||
| 2. State affected registers/status after call if important. | |||||
| 3. Use jump table names in comments. | |||||
| 4. Restore channels with `CLRCHN` after redirected I/O. | |||||
| 5. Close files that were opened. | |||||
| @@ -0,0 +1,77 @@ | |||||
| # Skill: SID 6581 Sound Programming | |||||
| ## Use this skill when | |||||
| The task involves music, sound effects, SID registers, waveforms, ADSR envelopes, filters, volume, or paddles. | |||||
| ## SID base | |||||
| SID base: `$D400` / `54272`. | |||||
| Each of the three voices uses 7 registers: | |||||
| | Voice | Base decimal | Base hex | | |||||
| |---|---:|---:| | |||||
| | Voice 1 | 54272 | `$D400` | | |||||
| | Voice 2 | 54279 | `$D407` | | |||||
| | Voice 3 | 54286 | `$D40E` | | |||||
| Per voice: | |||||
| | Offset | Purpose | | |||||
| |---:|---| | |||||
| | +0 | Frequency low | | |||||
| | +1 | Frequency high | | |||||
| | +2 | Pulse width low | | |||||
| | +3 | Pulse width high nybble | | |||||
| | +4 | Control: gate, sync, ring, test, waveform | | |||||
| | +5 | Attack/decay | | |||||
| | +6 | Sustain/release | | |||||
| Global/filter registers: | |||||
| | Decimal | Hex | Purpose | | |||||
| |---:|---:|---| | |||||
| | 54293 | `$D415` | Filter cutoff low bits | | |||||
| | 54294 | `$D416` | Filter cutoff high bits | | |||||
| | 54295 | `$D417` | Resonance/filter voice routing | | |||||
| | 54296 | `$D418` | Filter mode and master volume | | |||||
| | 54297 | `$D419` | Paddle X / ADC 1 | | |||||
| | 54298 | `$D41A` | Paddle Y / ADC 2 | | |||||
| | 54299 | `$D41B` | Voice 3 oscillator output | | |||||
| | 54300 | `$D41C` | Voice 3 envelope output | | |||||
| ## Waveform bits in control register | |||||
| | Bit/mask | Meaning | | |||||
| |---:|---| | |||||
| | `$01` | Gate | | |||||
| | `$02` | Sync | | |||||
| | `$04` | Ring modulation | | |||||
| | `$08` | Test | | |||||
| | `$10` | Triangle | | |||||
| | `$20` | Sawtooth | | |||||
| | `$40` | Pulse | | |||||
| | `$80` | Noise | | |||||
| ## Simple BASIC tone | |||||
| ```basic | |||||
| 10 S=54272 | |||||
| 20 POKE S+24,15:REM VOLUME | |||||
| 30 POKE S+5,9*16+0:REM ATTACK/DECAY | |||||
| 40 POKE S+6,15*16+8:REM SUSTAIN/RELEASE | |||||
| 50 POKE S,37:POKE S+1,17:REM FREQUENCY | |||||
| 60 POKE S+4,17:REM TRIANGLE + GATE | |||||
| 70 FOR T=1 TO 500:NEXT | |||||
| 80 POKE S+4,16:REM GATE OFF | |||||
| ``` | |||||
| ## Agent checklist | |||||
| 1. Initialize volume at `$D418`. | |||||
| 2. Set frequency before opening gate. | |||||
| 3. Set ADSR before gate-on. | |||||
| 4. Clear gate for release. | |||||
| 5. Avoid leaving `TEST` bit set accidentally. | |||||
| 6. Mention SID 6581 vs 8580 sound differences when relevant. | |||||
| @@ -0,0 +1,84 @@ | |||||
| # Skill: VIC-II Graphics, Screen, Characters, Sprites, and Raster | |||||
| ## Use this skill when | |||||
| The task involves screen memory, colors, sprites, character sets, bitmap graphics, raster interrupts, scrolling, border/background, or VIC-II banking. | |||||
| ## Core registers | |||||
| VIC-II base: `$D000` / `53248`. | |||||
| | Decimal | Hex | Purpose | | |||||
| |---:|---:|---| | |||||
| | 53248-53263 | `$D000-$D00F` | Sprite X/Y coordinates | | |||||
| | 53264 | `$D010` | High bits for sprite X positions | | |||||
| | 53265 | `$D011` | Control register 1; vertical scroll, screen on, bitmap, raster bit 8 | | |||||
| | 53266 | `$D012` | Raster line low byte | | |||||
| | 53267 | `$D013` | Light pen X | | |||||
| | 53268 | `$D014` | Light pen Y | | |||||
| | 53269 | `$D015` | Sprite enable bits | | |||||
| | 53270 | `$D016` | Control register 2; horizontal scroll, multicolor | | |||||
| | 53271 | `$D017` | Sprite Y expansion | | |||||
| | 53272 | `$D018` | Memory control: screen and character/bitmap pointers | | |||||
| | 53273 | `$D019` | Interrupt flags | | |||||
| | 53274 | `$D01A` | Interrupt enable | | |||||
| | 53275 | `$D01B` | Sprite/background priority | | |||||
| | 53276 | `$D01C` | Sprite multicolor enable | | |||||
| | 53277 | `$D01D` | Sprite X expansion | | |||||
| | 53278 | `$D01E` | Sprite-sprite collision | | |||||
| | 53279 | `$D01F` | Sprite-background collision | | |||||
| | 53280 | `$D020` | Border color | | |||||
| | 53281 | `$D021` | Background color 0 | | |||||
| | 53282-53284 | `$D022-$D024` | Extra background/multicolor registers | | |||||
| | 53285-53286 | `$D025-$D026` | Sprite multicolor registers | | |||||
| | 53287-53294 | `$D027-$D02E` | Sprite individual colors | | |||||
| ## Screen basics | |||||
| Default screen RAM: `$0400` / `1024`. | |||||
| Default color RAM: `$D800` / `55296`. | |||||
| Screen is 40 columns x 25 rows = 1000 character cells. | |||||
| Cell address: | |||||
| ```text | |||||
| screen = 1024 + row * 40 + column | |||||
| color = 55296 + row * 40 + column | |||||
| ``` | |||||
| ## Sprite basics | |||||
| - Each sprite is 24 x 21 pixels. | |||||
| - Each sprite pattern uses 64 bytes. | |||||
| - Default sprite pointers are `$07F8-$07FF` / `2040-2047`. | |||||
| - Pointer value = sprite data address / 64, within the active VIC bank. | |||||
| - Enable sprites with `$D015` bits. | |||||
| Example enable sprite 0 in BASIC: | |||||
| ```basic | |||||
| POKE 53269,PEEK(53269) OR 1 | |||||
| ``` | |||||
| ## VIC-II bank rule | |||||
| The VIC-II sees one 16K bank at a time. CIA #2 port A controls the video bank. All active screen RAM, character data, bitmap data, and sprite data must be visible inside the selected VIC bank. | |||||
| ## Character ROM copy warning | |||||
| To copy character ROM from CPU-visible `$D000-$DFFF`, you must bank character ROM in and I/O out. Since I/O disappears during that window, disable interrupts briefly and restore banking immediately. | |||||
| ## Raster interrupt principles | |||||
| - Set raster line in `$D012`; bit 8 is in `$D011`. | |||||
| - Enable raster IRQ in `$D01A` bit 0. | |||||
| - Acknowledge VIC interrupt by writing the relevant bit back to `$D019`. | |||||
| - Chain or jump to the normal KERNAL IRQ handler unless replacing the system IRQ completely. | |||||
| ## Agent checklist | |||||
| 1. Give addresses in decimal and hex. | |||||
| 2. Preserve unrelated VIC register bits. | |||||
| 3. Note PAL/NTSC timing differences for raster work. | |||||
| 4. Keep sprite data inside active VIC bank. | |||||
| 5. For character/bitmap changes, explain `$D018` layout. | |||||
| @@ -0,0 +1,133 @@ | |||||
| # AGENTS.md — Commodore 64 / 6510 Expert Agent | |||||
| ## Purpose | |||||
| Act as a panel of 150 expert Commodore 64 developers, 6510 assembly programmers, BASIC V2 power users, emulator/debugging specialists, and retro-computing systems programmers. | |||||
| Your job is to help create, debug, document, optimize, and explain Commodore 64 programs using: | |||||
| - Commodore BASIC V2 | |||||
| - 6510/6502-family assembly language | |||||
| - KERNAL jump-table calls | |||||
| - BASIC ROM routines when appropriate | |||||
| - Direct memory access through `PEEK`, `POKE`, `SYS`, and `USR` | |||||
| - VIC-II, SID, CIA #1, CIA #2, color RAM, screen RAM, joystick, keyboard, serial bus, tape, disk, and interrupt techniques | |||||
| ## Startup Instructions | |||||
| Before working on any C64 task: | |||||
| 1. Read this file. | |||||
| 2. Read the skill router: | |||||
| ```text | |||||
| ./.ai/SKILLS.md | |||||
| ``` | |||||
| 3. Load only the skill files relevant to the requested work. | |||||
| 4. Use `references/c64-quick-reference.md` when addresses, KERNAL vectors, or hardware registers are needed. | |||||
| 5. Prefer stable KERNAL jump-table calls over hard-coded internal ROM addresses unless the task specifically requires ROM internals. | |||||
| 6. Clearly state whether code is intended for: | |||||
| - BASIC V2 | |||||
| - 6510 assembly | |||||
| - monitor-entry hex | |||||
| - cc65/ca65 | |||||
| - ACME/TMPx/KickAssembler-style assembly | |||||
| - emulator-specific use | |||||
| ## Core Operating Principles | |||||
| ### 1. Preserve the machine | |||||
| The C64 is small, powerful, and easy to crash. When generating code: | |||||
| - Do not overwrite BASIC text, variables, stack, screen memory, color RAM, or KERNAL/BASIC vectors accidentally. | |||||
| - Protect machine-language regions from BASIC by lowering the top of BASIC memory or placing code in a safe RAM area such as `$C000` when appropriate. | |||||
| - End BASIC-called machine-language routines with `RTS` unless intentionally transferring control elsewhere. | |||||
| - Save and restore registers when a caller expects them preserved. | |||||
| - Disable interrupts only as long as necessary. | |||||
| - Restore memory banking after switching ROMs/I/O/character ROM in or out. | |||||
| ### 2. Prefer official entry points | |||||
| When calling operating-system routines, prefer the KERNAL jump table at `$FF81-$FFF3`. These addresses are intended as stable entry points across compatible Commodore systems. | |||||
| Use internal BASIC or KERNAL routines only when: | |||||
| - A documented jump-table routine cannot do the job. | |||||
| - The program is explicitly C64 ROM-version-specific. | |||||
| - The routine is wrapped in comments explaining entry conditions, clobbered registers, and risks. | |||||
| ### 3. Think in bytes, pages, and banks | |||||
| C64 work is address work. Always consider: | |||||
| - Decimal and hexadecimal address forms. | |||||
| - Low-byte/high-byte order for vectors. | |||||
| - Page zero efficiency and scarcity. | |||||
| - Page 1 stack use. | |||||
| - BASIC RAM boundaries. | |||||
| - I/O/ROM/RAM banking controlled by processor port `$0001`. | |||||
| - VIC-II 16K video banks selected through CIA #2 at `$DD00`. | |||||
| ### 4. BASIC and assembly should cooperate | |||||
| For mixed BASIC + ML programs: | |||||
| - Use BASIC loaders for short demos and bootstrapping. | |||||
| - Use `SYS address` for command-style routines. | |||||
| - Use `USR(x)` when the machine-language routine behaves like a function. | |||||
| - Use locations `780-783` / `$030C-$030F` for BASIC `SYS` register passing when appropriate. | |||||
| - Do not let BASIC garbage collection or variable storage overwrite machine-code bytes. | |||||
| ### 5. Make examples runnable | |||||
| When producing code, include: | |||||
| - Load/start address. | |||||
| - How to run it from BASIC or a monitor. | |||||
| - Required assembler syntax assumptions. | |||||
| - What memory is touched. | |||||
| - Expected output. | |||||
| - Reset/recovery advice if it crashes. | |||||
| ## Skill Routing | |||||
| Use `.ai/SKILLS.md` to choose the correct skill. | |||||
| Common routes: | |||||
| - Memory address, `PEEK`, `POKE`, banking → `c64-memory-map` | |||||
| - `SYS`, `USR`, BASIC internals → `basic-v2-bridge` | |||||
| - KERNAL calls, device I/O, files → `kernal-jump-table` | |||||
| - Assembly language, registers, addressing modes → `6510-assembly` | |||||
| - Sprites, screen, raster, bitmap, character sets → `vic-ii-graphics` | |||||
| - Sound/music → `sid-sound` | |||||
| - Keyboard, joystick, timers, serial bus, user port → `cia-io` | |||||
| - IRQ/NMI/raster interrupts → `interrupts-reset` | |||||
| - Debugging, monitors, emulators → `debugging-monitor` | |||||
| - Style, structure, optimization → `c64-programming-practices` | |||||
| ## Response Rules for Agents | |||||
| When answering C64 questions: | |||||
| - Give decimal and hex addresses together when useful: `53280 / $D020`. | |||||
| - Identify whether an address is RAM, ROM, I/O, color RAM, vector, or register. | |||||
| - For bit registers, show bit masks and safe `AND`/`OR` patterns. | |||||
| - For KERNAL calls, list entry registers and return behavior. | |||||
| - For assembly, mention clobbered registers. | |||||
| - For BASIC, keep lines short enough to type when possible. | |||||
| - Avoid undocumented opcodes unless explicitly requested. | |||||
| - Warn before code that changes interrupt vectors, memory banking, disk state, or hardware registers globally. | |||||
| ## Definition of Done | |||||
| A C64 answer is complete when it includes: | |||||
| - Correct target environment. | |||||
| - Safe memory placement. | |||||
| - Clear run instructions. | |||||
| - Address/register explanation. | |||||
| - Practical testing/debugging steps. | |||||
| - Notes for emulator and real hardware differences when relevant. | |||||
| @@ -0,0 +1,22 @@ | |||||
| # Commodore 64 / 6510 AI Agent Pack | |||||
| This pack turns the uploaded Commodore 64 reference texts into a practical AI-coding-agent workspace. It is designed for agents helping with C64 BASIC V2, 6510 assembly, KERNAL jump-table calls, memory-map work, VIC-II graphics, SID sound, CIA I/O, interrupts, and debugging. | |||||
| ## Layout | |||||
| ```text | |||||
| AGENTS.md Root agent operating instructions | |||||
| .ai/SKILLS.md Skill router and index | |||||
| .ai/skills/*/SKILL.md Focused C64 skills loaded on demand | |||||
| references/c64-quick-reference.md Memory, KERNAL, BASIC, and hardware tables | |||||
| examples/basic/* BASIC examples | |||||
| examples/assembly/* 6510 assembly examples | |||||
| templates/c64-task-brief.md Prompt template for future C64 tasks | |||||
| tools/address-cheatsheet.json Machine-readable address table | |||||
| ``` | |||||
| ## How to use | |||||
| Place this folder in the root of a Commodore 64 project. An AI coding agent should read `AGENTS.md` first, then follow `.ai/SKILLS.md` to load only the skill files relevant to the task. | |||||
| The material is summarized and transformed into working rules, not a copy of the source books. Verify timing-sensitive raster, IRQ, banking, and device behavior on an emulator or real C64. | |||||
| @@ -0,0 +1,17 @@ | |||||
| ; chrout-hello.asm | |||||
| ; Generic 6510 assembly. Load at $C000 and run with SYS 49152. | |||||
| ; Uses KERNAL CHROUT at $FFD2. Clobbers A/Y. | |||||
| * = $c000 | |||||
| start: ldy #$00 | |||||
| loop: lda message,y | |||||
| beq done | |||||
| jsr $ffd2 ; KERNAL CHROUT | |||||
| iny | |||||
| bne loop | |||||
| done: rts | |||||
| message: | |||||
| .byte 147 ; clear screen PETSCII | |||||
| .byte "HELLO FROM $C000",13,0 | |||||
| @@ -0,0 +1,10 @@ | |||||
| ; getin-echo.asm | |||||
| ; Load at $C000 and run with SYS 49152. | |||||
| ; Waits for a key using KERNAL GETIN, then echoes using CHROUT. | |||||
| * = $c000 | |||||
| wait: jsr $ffe4 ; GETIN | |||||
| beq wait ; no key yet | |||||
| jsr $ffd2 ; CHROUT | |||||
| rts | |||||
| @@ -0,0 +1,46 @@ | |||||
| ; irq-hook-skeleton.asm | |||||
| ; C64 IRQ hook skeleton. Educational template only. | |||||
| ; Installs handler at $C100 and changes border color briefly. | |||||
| ; Assemble/load with install at $C000. Run SYS 49152. | |||||
| * = $c000 | |||||
| oldirq: .word 0 | |||||
| install: | |||||
| sei | |||||
| lda $0314 | |||||
| sta oldirq | |||||
| lda $0315 | |||||
| sta oldirq+1 | |||||
| lda #<irq | |||||
| sta $0314 | |||||
| lda #>irq | |||||
| sta $0315 | |||||
| cli | |||||
| rts | |||||
| restore: | |||||
| sei | |||||
| lda oldirq | |||||
| sta $0314 | |||||
| lda oldirq+1 | |||||
| sta $0315 | |||||
| cli | |||||
| rts | |||||
| * = $c100 | |||||
| irq: | |||||
| pha | |||||
| txa | |||||
| pha | |||||
| tya | |||||
| pha | |||||
| inc $d020 ; visible heartbeat; keep handler short | |||||
| pla | |||||
| tay | |||||
| pla | |||||
| tax | |||||
| pla | |||||
| jmp (oldirq) ; chain to original IRQ handler | |||||
| @@ -0,0 +1,10 @@ | |||||
| ; safe-vic-bit-set.asm | |||||
| ; Demonstrates read-modify-write for VIC-II registers. | |||||
| ; Enables sprite 0 without changing other sprite-enable bits. | |||||
| * = $c000 | |||||
| start: lda $d015 ; VIC-II sprite enable | |||||
| ora #$01 ; set bit 0 | |||||
| sta $d015 | |||||
| rts | |||||
| @@ -0,0 +1,7 @@ | |||||
| 10 REM SCREEN AND COLOR RAM DEMO | |||||
| 20 S=1024:C=55296 | |||||
| 30 POKE 53280,6:POKE 53281,0 | |||||
| 40 FOR I=0 TO 39 | |||||
| 50 POKE S+I,1+I-INT(I/26)*26 | |||||
| 60 POKE C+I,I AND 15 | |||||
| 70 NEXT | |||||
| @@ -0,0 +1,7 @@ | |||||
| 10 REM SYS REGISTER PASS EXAMPLE | |||||
| 20 REM A/X/Y VALUES GO THROUGH 780/781/782 | |||||
| 30 POKE 780,65:REM PETSCII A | |||||
| 40 POKE 781,66:REM PETSCII B | |||||
| 50 POKE 782,67:REM PETSCII C | |||||
| 60 SYS 49152 | |||||
| 70 PRINT:PRINT "RETURNED A,X,Y=";PEEK(780);PEEK(781);PEEK(782) | |||||
| @@ -0,0 +1,124 @@ | |||||
| # Commodore 64 Quick Reference | |||||
| ## Memory map overview | |||||
| | Range | Meaning | | |||||
| |---:|---| | |||||
| | `$0000-$00FF` | Page zero: BASIC/KERNAL workspace, pointers, fast addressing | | |||||
| | `$0100-$01FF` | Processor stack | | |||||
| | `$0200-$03FF` | System workspace, buffers, vectors | | |||||
| | `$0400-$07E7` | Default screen RAM | | |||||
| | `$07F8-$07FF` | Default sprite pointers | | |||||
| | `$0801` | Default BASIC program start | | |||||
| | `$A000-$BFFF` | BASIC ROM, RAM underneath | | |||||
| | `$C000-$CFFF` | Free RAM often used for ML routines | | |||||
| | `$D000-$DFFF` | I/O, color RAM, character ROM, or RAM depending on banking | | |||||
| | `$E000-$FFFF` | KERNAL ROM, RAM underneath | | |||||
| ## Common addresses | |||||
| | Dec | Hex | Name | | |||||
| |---:|---:|---| | |||||
| | 1 | `$0001` | 6510 memory banking port | | |||||
| | 43 | `$002B` | BASIC start pointer low | | |||||
| | 44 | `$002C` | BASIC start pointer high | | |||||
| | 55 | `$0037` | BASIC top pointer low | | |||||
| | 56 | `$0038` | BASIC top pointer high | | |||||
| | 198 | `$00C6` | Keyboard buffer count | | |||||
| | 646 | `$0286` | Current text color | | |||||
| | 780 | `$030C` | SYS A register save/pass | | |||||
| | 781 | `$030D` | SYS X register save/pass | | |||||
| | 782 | `$030E` | SYS Y register save/pass | | |||||
| | 783 | `$030F` | SYS status save/pass | | |||||
| | 788 | `$0314` | IRQ vector low | | |||||
| | 789 | `$0315` | IRQ vector high | | |||||
| | 792 | `$0318` | NMI vector low | | |||||
| | 793 | `$0319` | NMI vector high | | |||||
| | 1024 | `$0400` | Screen RAM | | |||||
| | 2040 | `$07F8` | Sprite pointer 0 | | |||||
| | 49152 | `$C000` | Common ML start | | |||||
| | 53248 | `$D000` | VIC-II base | | |||||
| | 53280 | `$D020` | Border color | | |||||
| | 53281 | `$D021` | Background color | | |||||
| | 54272 | `$D400` | SID base | | |||||
| | 55296 | `$D800` | Color RAM | | |||||
| | 56320 | `$DC00` | CIA #1 base | | |||||
| | 56576 | `$DD00` | CIA #2 base | | |||||
| ## KERNAL jump table | |||||
| | Hex | Routine | Purpose | | |||||
| |---:|---|---| | |||||
| | `$FF81` | CINT | Initialize screen editor | | |||||
| | `$FF84` | IOINIT | Initialize I/O | | |||||
| | `$FF87` | RAMTAS | RAM test/init | | |||||
| | `$FF8A` | RESTOR | Restore vectors | | |||||
| | `$FF8D` | VECTOR | Read/set vectors | | |||||
| | `$FF90` | SETMSG | Set system message flag | | |||||
| | `$FF93` | SECOND | Send secondary address after LISTEN | | |||||
| | `$FF96` | TKSA | Send secondary address after TALK | | |||||
| | `$FF99` | MEMTOP | Read/set top of memory | | |||||
| | `$FF9C` | MEMBOT | Read/set bottom of memory | | |||||
| | `$FF9F` | SCNKEY | Scan keyboard | | |||||
| | `$FFA2` | SETTMO | Set timeout | | |||||
| | `$FFA5` | ACPTR | Read serial byte | | |||||
| | `$FFA8` | CIOUT | Write serial byte | | |||||
| | `$FFAB` | UNTLK | Untalk | | |||||
| | `$FFAE` | UNLSN | Unlisten | | |||||
| | `$FFB1` | LISTEN | Listen | | |||||
| | `$FFB4` | TALK | Talk | | |||||
| | `$FFB7` | READST | Read status | | |||||
| | `$FFBA` | SETLFS | Set logical file/device/secondary address | | |||||
| | `$FFBD` | SETNAM | Set filename | | |||||
| | `$FFC0` | OPEN | Open file | | |||||
| | `$FFC3` | CLOSE | Close file | | |||||
| | `$FFC6` | CHKIN | Set input channel | | |||||
| | `$FFC9` | CHKOUT | Set output channel | | |||||
| | `$FFCC` | CLRCHN | Restore default I/O | | |||||
| | `$FFCF` | CHRIN | Input character | | |||||
| | `$FFD2` | CHROUT | Output character | | |||||
| | `$FFD5` | LOAD | Load from device | | |||||
| | `$FFD8` | SAVE | Save to device | | |||||
| | `$FFDB` | SETTIM | Set clock | | |||||
| | `$FFDE` | RDTIM | Read clock | | |||||
| | `$FFE1` | STOP | Check STOP key | | |||||
| | `$FFE4` | GETIN | Get input character | | |||||
| | `$FFE7` | CLALL | Close all files | | |||||
| | `$FFEA` | UDTIM | Update clock | | |||||
| | `$FFED` | SCREEN | Get screen dimensions | | |||||
| | `$FFF0` | PLOT | Read/set cursor position | | |||||
| | `$FFF3` | IOBASE | Return I/O base | | |||||
| ## Color codes | |||||
| | Code | Color | | |||||
| |---:|---| | |||||
| | 0 | Black | | |||||
| | 1 | White | | |||||
| | 2 | Red | | |||||
| | 3 | Cyan | | |||||
| | 4 | Purple | | |||||
| | 5 | Green | | |||||
| | 6 | Blue | | |||||
| | 7 | Yellow | | |||||
| | 8 | Orange | | |||||
| | 9 | Brown | | |||||
| | 10 | Light red | | |||||
| | 11 | Dark gray | | |||||
| | 12 | Gray | | |||||
| | 13 | Light green | | |||||
| | 14 | Light blue | | |||||
| | 15 | Light gray | | |||||
| ## BASIC snippets | |||||
| ```basic | |||||
| REM BORDER AND BACKGROUND | |||||
| POKE 53280,6:POKE 53281,0 | |||||
| REM PUT "A" AT UPPER LEFT AND COLOR IT RED | |||||
| POKE 1024,1:POKE 55296,2 | |||||
| REM CALL MACHINE LANGUAGE AT $C000 | |||||
| SYS 49152 | |||||
| ``` | |||||
| @@ -0,0 +1,38 @@ | |||||
| # C64 Task Brief Template | |||||
| ## Goal | |||||
| Describe the desired program, bug fix, or explanation. | |||||
| ## Target | |||||
| - Machine: C64 / VIC-20 / both | |||||
| - Language: BASIC V2 / 6510 assembly / hybrid | |||||
| - Assembler/emulator: VICE / ACME / ca65 / KickAssembler / monitor / other | |||||
| - Load address: | |||||
| - Run command: | |||||
| ## Constraints | |||||
| - Must preserve BASIC? yes/no | |||||
| - Safe ML area: | |||||
| - Uses interrupts? yes/no | |||||
| - Uses disk/tape/printer/serial? yes/no | |||||
| - PAL/NTSC timing matters? yes/no | |||||
| ## Hardware areas touched | |||||
| - VIC-II: | |||||
| - SID: | |||||
| - CIA #1: | |||||
| - CIA #2: | |||||
| - KERNAL calls: | |||||
| - BASIC vectors/pointers: | |||||
| ## Expected result | |||||
| What should the user see/hear/control? | |||||
| ## Testing | |||||
| How should it be tested in emulator or real hardware? | |||||
| @@ -0,0 +1,74 @@ | |||||
| { | |||||
| "screen_ram": { | |||||
| "dec": 1024, | |||||
| "hex": "$0400" | |||||
| }, | |||||
| "color_ram": { | |||||
| "dec": 55296, | |||||
| "hex": "$D800" | |||||
| }, | |||||
| "vic_ii_base": { | |||||
| "dec": 53248, | |||||
| "hex": "$D000" | |||||
| }, | |||||
| "sid_base": { | |||||
| "dec": 54272, | |||||
| "hex": "$D400" | |||||
| }, | |||||
| "cia1_base": { | |||||
| "dec": 56320, | |||||
| "hex": "$DC00" | |||||
| }, | |||||
| "cia2_base": { | |||||
| "dec": 56576, | |||||
| "hex": "$DD00" | |||||
| }, | |||||
| "border_color": { | |||||
| "dec": 53280, | |||||
| "hex": "$D020" | |||||
| }, | |||||
| "background_color": { | |||||
| "dec": 53281, | |||||
| "hex": "$D021" | |||||
| }, | |||||
| "sys_a": { | |||||
| "dec": 780, | |||||
| "hex": "$030C" | |||||
| }, | |||||
| "sys_x": { | |||||
| "dec": 781, | |||||
| "hex": "$030D" | |||||
| }, | |||||
| "sys_y": { | |||||
| "dec": 782, | |||||
| "hex": "$030E" | |||||
| }, | |||||
| "sys_status": { | |||||
| "dec": 783, | |||||
| "hex": "$030F" | |||||
| }, | |||||
| "irq_vector": { | |||||
| "dec": 788, | |||||
| "hex": "$0314" | |||||
| }, | |||||
| "nmi_vector": { | |||||
| "dec": 792, | |||||
| "hex": "$0318" | |||||
| }, | |||||
| "ml_common_start": { | |||||
| "dec": 49152, | |||||
| "hex": "$C000" | |||||
| }, | |||||
| "kernal": { | |||||
| "CHROUT": "$FFD2", | |||||
| "GETIN": "$FFE4", | |||||
| "CHRIN": "$FFCF", | |||||
| "SETLFS": "$FFBA", | |||||
| "SETNAM": "$FFBD", | |||||
| "OPEN": "$FFC0", | |||||
| "CLOSE": "$FFC3", | |||||
| "LOAD": "$FFD5", | |||||
| "SAVE": "$FFD8", | |||||
| "CLRCHN": "$FFCC" | |||||
| } | |||||
| } | |||||
Powered by TurnKey Linux.