您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

6.6KB

C64 6502 Assembly Cheat Sheet


1. Memory Map

$0000–$00FF    Zero page (fast access, 2-byte instructions)
$0100–$01FF    Stack (grows downward from $01FF)
$0200–$1FFF    System/free area
$2000–$3FFF    User RAM (40 KB available)
$D000–$DFFF    I/O ports (VIC-II, SID, CIA1, CIA2)
$E000–$FFFF    Kernal ROM (can be banked out for more RAM)

2. Key VIC-II Registers

All addresses relative to $D000 (e.g., $D010 = $D000 + $10).

Sprite Coordinates

$D000–$D00F  Sprite X positions (16 bytes, 2 per sprite)
  $D000 = Sprite 0 X (low byte)
  $D010 = X high bits (bit 0 = Sprite 0 X bit 8, etc.)

$D001–$D00F  Sprite Y positions (16 bytes, 2 per sprite)
  $D001 = Sprite 0 Y
  $D003 = Sprite 1 Y
  ... (every other byte)

Sprite Control

$D015  Sprite enable ($00 = all off, $3F = all 6 on)
$D017  Sprite Y expand (1 = double height)
$D01D  Sprite X expand (1 = double width)
$D025  Sprite 0 color
$D026  Sprite 1 color
... (one byte per sprite)

$D027  Sprite 0 multicolor (0–3 for multicolor mode)
$D028  Sprite 1 multicolor
...
$D01C  Multicolor mode enable (bit = sprite index)

Screen Control

$D011  VIC control register 1
  Bit 7: Raster interrupt request
  Bit 6: Extended color text mode
  Bit 5: Bitmap mode
  Bit 4: Blank screen (1 = blank)
  Bits 3–0: Scroll Y

$D012  Raster line (read for current, write for interrupt trigger)

$D016  VIC control register 2 (scroll X, multicolor, etc.)

$D018  Memory control (screen addr, bitmap addr)
  Default: $14 (screen at $0400, bitmap at $2000)

Colors

$D020  Border color
$D021  Background color 0
$D022  Background color 1 (multicolor mode)
$D023  Background color 2 (multicolor mode)
$D024  Background color 3 (multicolor mode)

3. CIA (Complex Interface Adapter) — Input

CIA1 ($DC00–$DC0F)

$DC00  Data direction register A (keyboard columns)
$DC01  Keyboard matrix input register
       Bit 0 = Key Row
       Bit 1 = Key Row, etc.

$DC02  Data direction register B
$DC03  Joystick / paddle input

$DC04–$DC05  Timer A (low/high)
$DC06–$DC07  Timer B (low/high)
$DC0E  Control register A (timer, interrupt)
$DC0F  Interrupt enable register

Simple Joystick Read

LDA #$00            ; Set port B for input
STA $DC02
LDA $DC01           ; Read joystick (port 2) or keyboard
; Bit pattern: 7=up, 6=down, 5=left, 4=right, 3=fire

4. Common 6502 Instructions

Load/Store

LDA #$42        ; Load immediate
LDA $42         ; Load from zero page
LDA $4200       ; Load from absolute address
LDA $4200,X     ; Indexed
LDA ($42,X)     ; Indirect indexed
STA $42         ; Store

Arithmetic

ADC #$10        ; Add with carry
SBC #$10        ; Subtract with carry
INC $42         ; Increment memory
DEC $42         ; Decrement memory
INX, INY, DEX, DEY  ; Increment/decrement registers

Branching

BNE $4000       ; Branch if not equal (after CMP, etc.)
BEQ $4000       ; Branch if equal
BCS $4000       ; Branch if carry set
BCC $4000       ; Branch if carry clear
BPL $4000       ; Branch if plus (MSB = 0)
BMI $4000       ; Branch if minus (MSB = 1)
JMP $4000       ; Unconditional jump
JSR $4000       ; Jump to subroutine (push return address)
RTS             ; Return from subroutine

Comparisons

CMP #$10        ; Compare A with immediate (sets flags)
CMP $42         ; Compare A with memory
CPX #$10        ; Compare X
CPY #$10        ; Compare Y
; Flags: Z=zero (equal), C=carry (unsigned <), N=minus

Bit Operations

ASL             ; Arithmetic shift left (A or M)
LSR             ; Logical shift right
ROL             ; Rotate left
ROR             ; Rotate right
AND #$0F        ; Bitwise AND
ORA #$F0        ; Bitwise OR
EOR #$FF        ; Bitwise XOR
BIT $42         ; Test bits (sets N, V, Z)

Stack

PHA             ; Push A
PLA             ; Pull A
PHP             ; Push status
PLP             ; Pull status

5. Interrupt Handling

Setup IRQ Handler

; In initialization:
LDA #<IRQ_HANDLER    ; Low byte of handler address
STA $0314
LDA #>IRQ_HANDLER    ; High byte
STA $0315

CLI                  ; Clear interrupt disable flag

IRQ Handler Structure

IRQ_HANDLER:
  PHA                ; Save registers
  TXA
  PHA
  TYA
  PHA
  
  ; Check if it's our interrupt (raster or timer)
  LDA $D019          ; VIC interrupt status
  BIT #$01           ; Test raster interrupt
  BEQ NOT_VIC
  
  ; Handle VIC/raster interrupt
  ; (your game logic here)
  
  LDA #$01           ; Acknowledge interrupt
  STA $D019
  
NOT_VIC:
  PLA                ; Restore registers
  TAY
  PLA
  TAX
  PLA
  RTI

6. Sprite Data Format

C64 sprites are 24 pixels wide × 21 pixels high, stored as 63 bytes (3 bytes/line).

Location: Default at $3000–$3FFF (can be changed via $D018)

Format:

Bytes 0–2:    Line 0 (pixel data)
Bytes 3–5:    Line 1
...
Bytes 60–62:  Line 20

Each 3-byte line = 24 pixels (bit pattern).

Example: Simple square

$38 $38 $00  (11000000 11000000 00000000 = two vertical bars)
$38 $38 $00
...

7. Useful Zero-Page Patterns

; Temporary registers (safe to overwrite)
TEMP0   = $F0
TEMP1   = $F1
TEMP2   = $F2
TEMP3   = $F3

; Loop counters
LOOP_X  = $F4
LOOP_Y  = $F5
LOOP_C  = $F6

; Pointers (16-bit address)
PTR0    = $F8   ; PTR0_L = $F8, PTR0_H = $F9
PTR1    = $FA

8. Quick Patterns

Wait for Raster (Sync to VIC)

WAIT_RASTER:
  LDA #<RASTER_LINE  ; e.g., $80 (line 128)
  CMP $D012
  BNE WAIT_RASTER

Copy Memory Block

; Copy from $2000 to $4000, 256 bytes
LDX #$00
COPY_LOOP:
  LDA $2000,X
  STA $4000,X
  INX
  BNE COPY_LOOP

Fill Memory

; Fill $2000–$27FF with $00
LDA #$00
LDX #$00
FILL_LOOP:
  STA $2000,X
  INX
  BNE FILL_LOOP
  INC $2001   ; Move to next page
  CPX #$08    ; 8 pages × 256 bytes = 2048
  BNE FILL_LOOP

9. Useful Resources

  • nesdev.com — 6502 reference (works for C64, mostly)
  • c64-wiki.de — C64 hardware memory map and I/O
  • VICE documentation — Emulator & debugger help
  • Commodore 64 Programmer's Reference Guide (online PDF)

10. Common Mistakes

Mistake Fix
Forgetting to acknowledge interrupt ($D019) Add LDA #$01; STA $D019 before RTI
Sprite addresses hard-coded Use $D018 to configure memory address
Not disabling interrupts when modifying $D018 Use SEI before, CLI after
Assuming screen is at $0400 Verify with $D018 or use absolute address
Overflow in 8-bit math (ADC/SBC) Check carry flag after operation
Infinite loop in interrupt Ensure interrupt flag is cleared and handler returns quickly

Powered by TurnKey Linux.