Programming the MEGA65 — Appendices

Oct 4, 2026 · Updated Oct 11, 2026 · @Craig Taylor

Appendix A: Screen Codes and Colours

Screen codes

Screen codes are the values stored in screen memory, and are different from PETSCII. These are the codes of the upper-case character set; codes 128 to 255 are the same characters in reverse video.

Codes Characters
0 @
1-26 A to Z (lower-case a to z in the lower-case set)
27-31 [, £, ], ↑, ←
32 Space
33-47 ! " # $ % & ' ( ) * + , - . /
48-57 0 to 9
58-63 : ; < = > ?
64-127 Graphics characters; in the lower-case set, 65-90 are A to Z
128-255 Codes 0-127 in reverse video

To convert a letter's PETSCII code to its screen code in the upper-case set, subtract 64: PETSCII 65, A, is screen code 1. Digits and most punctuation have the same value in both. Screen codes 256 and above are used only in the VIC-IV's two-byte character modes; Chapter 12 describes them.

Colours

The first 16 palette entries are the C64's colours, used by COLOR, BORDER, BACKGROUND and colour RAM. CTRL with 1 to 8 types the first eight, and MEGA with 1 to 8 the second eight.

Code Colour Code Colour
0 Black 8 Orange
1 White 9 Brown
2 Red 10 Light red
3 Cyan 11 Dark grey
4 Purple 12 Grey
5 Green 13 Light green
6 Blue 14 Light blue
7 Yellow 15 Light grey

Entries 16 to 31 hold an alternate "rainbow" set, selected for text with ESC S and returned with ESC U, and entries 32 to 255 are free for programs to define with PALETTE.

Appendix B: PETSCII Codes

PETSCII is the character code used by PRINT, CHR$, ASC, GET and the keyboard. Codes 32 to 95 follow ASCII closely; the rest hold control codes and graphics.

Codes Contents
0-31 Control codes
32-63 Space, punctuation and digits, as in ASCII
64-95 @, letters A to Z, and [ £ ] ↑ ←
96-127 Graphics characters
128-159 Control codes
160-191 Graphics characters
192-223 The same characters as 96-127
224-254 The same characters as 160-190
255 π

In the lower-case set, 65-90 are lower-case letters and 193-218 are capitals.

Control codes

Printing these codes performs an action rather than showing a character. They can be typed into strings in quote mode, or produced with CHR$.

Code Action Code Action
5 White 129 Orange
13 Return 133-140 F1, F3, F5, F7, F2, F4, F6, F8
14 Lower-case set 141 Shifted return
17 Cursor down 142 Upper-case set
18 Reverse on 144 Black
19 Home 145 Cursor up
20 Delete 146 Reverse off
27 Escape: starts an escape sequence 147 Clear screen
28 Red 148 Insert
29 Cursor right 149-155 Brown, light red, dark grey, grey, light green, light blue, light grey
30 Green 156 Purple
31 Blue 157 Cursor left
158 Yellow
159 Cyan

These are the C64's control codes, which the MEGA65 keeps; PRINT CHR$(27); "X" sends an escape sequence, as Chapter 2 describes. The MEGA65 also defines further codes, such as for tabs and flashing text; the Book's character appendix lists them all.

Appendix C: Number Conversion

Each hexadecimal digit stands for four binary digits, so conversion between the two needs only this table:

Hex Binary Decimal Hex Binary Decimal
0 0000 0 8 1000 8
1 0001 1 9 1001 9
2 0010 2 A 1010 10
3 0011 3 B 1011 11
4 0100 4 C 1100 12
5 0101 5 D 1101 13
6 0110 6 E 1110 14
7 0111 7 F 1111 15

$D0 is therefore %11010000, and %10100101 is $A5.

Converting between hex and decimal

To convert hex to decimal, multiply each digit by its place value and add:

Place Value
1st digit from the right 1
2nd 16
3rd 256
4th 4,096
5th 65,536
6th 1,048,576
7th 16,777,216

So $D020 is 13 × 4096 + 0 × 256 + 2 × 16 + 0 = 53,280. In BASIC 65 the conversions are built in: PRINT $D020 gives 53280, PRINT HEX$(53280) gives D020, PRINT %1010 gives 10, and PRINT STRBIN$(10) gives the binary digits.

Useful values

Hex Decimal Meaning
$FF 255 Largest byte
$100 256 One page
$2000 8,192 8KB, one MAP block
$10000 65,536 64KB, one bank
$100000 1,048,576 1MB, one MAP megabyte
$8000000 134,217,728 Start of attic RAM
$FF80000 267,911,168 Start of colour RAM

Appendix D: 45GS02 Opcode Map

The row gives the opcode's high digit and the column its low digit: LDA # is in row A, column 9, so its opcode is $A9. Mode abbreviations are those of Chapter 10: bp is base page, (bp),Z indirect indexed by Z, rel16 a 16-bit branch, and (d,SP),Y stack-relative. The 45GS02's flat and quad instructions are prefixed forms of these opcodes, as Chapter 10 describes. This map follows the cc65 CPU reference and the Book's 4510/45GS02 opcode table (MEGA65 Book, Appendix L). Opcode $62 uses the cc65 name RTN; the Book writes the same instruction as RTS #$nn.

Columns 0 to 7

x0 x1 x2 x3 x4 x5 x6 x7
0x BRK ORA (bp,X) CLE SEE TSB bp ORA bp ASL bp RMB0 bp
1x BPL rel ORA (bp),Y ORA (bp),Z BPL rel16 TRB bp ORA bp,X ASL bp,X RMB1 bp
2x JSR abs AND (bp,X) JSR (abs) JSR (abs,X) BIT bp AND bp ROL bp RMB2 bp
3x BMI rel AND (bp),Y AND (bp),Z BMI rel16 BIT bp,X AND bp,X ROL bp,X RMB3 bp
4x RTI EOR (bp,X) NEG ASR A ASR bp EOR bp LSR bp RMB4 bp
5x BVC rel EOR (bp),Y EOR (bp),Z BVC rel16 ASR bp,X EOR bp,X LSR bp,X RMB5 bp
6x RTS ADC (bp,X) RTN imm BSR rel16 STZ bp ADC bp ROR bp RMB6 bp
7x BVS rel ADC (bp),Y ADC (bp),Z BVS rel16 STZ bp,X ADC bp,X ROR bp,X RMB7 bp
8x BRA rel STA (bp,X) STA (d,SP),Y BRA rel16 STY bp STA bp STX bp SMB0 bp
9x BCC rel STA (bp),Y STA (bp),Z BCC rel16 STY bp,X STA bp,X STX bp,Y SMB1 bp
Ax LDY imm LDA (bp,X) LDX imm LDZ imm LDY bp LDA bp LDX bp SMB2 bp
Bx BCS rel LDA (bp),Y LDA (bp),Z BCS rel16 LDY bp,X LDA bp,X LDX bp,Y SMB3 bp
Cx CPY imm CMP (bp,X) CPZ imm DEW bp CPY bp CMP bp DEC bp SMB4 bp
Dx BNE rel CMP (bp),Y CMP (bp),Z BNE rel16 CPZ bp CMP bp,X DEC bp,X SMB5 bp
Ex CPX imm SBC (bp,X) LDA (d,SP),Y INW bp CPX bp SBC bp INC bp SMB6 bp
Fx BEQ rel SBC (bp),Y SBC (bp),Z BEQ rel16 PHW imm16 SBC bp,X INC bp,X SMB7 bp

Columns 8 to F

x8 x9 xA xB xC xD xE xF
0x PHP ORA imm ASL A TSY TSB abs ORA abs ASL abs BBR0
1x CLC ORA abs,Y INC A INZ TRB abs ORA abs,X ASL abs,X BBR1
2x PLP AND imm ROL A TYS BIT abs AND abs ROL abs BBR2
3x SEC AND abs,Y DEC A DEZ BIT abs,X AND abs,X ROL abs,X BBR3
4x PHA EOR imm LSR A TAZ JMP abs EOR abs LSR abs BBR4
5x CLI EOR abs,Y PHY TAB MAP EOR abs,X LSR abs,X BBR5
6x PLA ADC imm ROR A TZA JMP (abs) ADC abs ROR abs BBR6
7x SEI ADC abs,Y PLY TBA JMP (abs,X) ADC abs,X ROR abs,X BBR7
8x DEY BIT imm TXA STY abs,X STY abs STA abs STX abs BBS0
9x TYA STA abs,Y TXS STX abs,Y STZ abs STA abs,X STZ abs,X BBS1
Ax TAY LDA imm TAX LDZ abs LDY abs LDA abs LDX abs BBS2
Bx CLV LDA abs,Y TSX LDZ abs,X LDY abs,X LDA abs,X LDX abs,Y BBS3
Cx INY CMP imm DEX ASW abs CPY abs CMP abs DEC abs BBS4
Dx CLD CMP abs,Y PHX PHZ CPZ abs CMP abs,X DEC abs,X BBS5
Ex INX SBC imm EOM / NOP ROW abs CPX abs SBC abs INC abs BBS6
Fx SED SBC abs,Y PLX PLZ PHW abs SBC abs,X INC abs,X BBS7

BBR and BBS take a base page address and an 8-bit branch offset.

Appendix E: Key Registers

This is a quick reference to the registers used in this book. The MEGA65 Book's register appendices document every register and bit. Most of these need the VIC-IV (MEGA65) I/O personality.

Address Name Purpose Chapter
$00 CPU port direction $41 forces full speed, $40 releases it 8
$01 CPU port C64-style banking 5
$D011, $D012 Control, raster Raster compare bit 8 and bits 7-0 8
$D019, $D01A IRQ flags, mask Raster interrupt acknowledge and enable 8
$D020, $D021 Border, background Screen colours 12
$D02F KEY Knock to select the I/O personality 5
$D030 VIC-III control ROM banking, CRAM2K 5
$D031 VIC-III control H640, FAST, ATTR, BPM, V400 8, 12
$D04C, $D04E TEXTXPOS, TEXTYPOS Text area position 12
$D051 NORRDEL, DBLRR Raster rewrite buffer timing 12
$D052, $D053 FNRASTER Physical raster line 8
$D054 CHR16, FCLRLO, FCLRHI, VFAST Two-byte characters, full colour, 40.5 MHz 8, 12
$D057 SPRX64EN 64-pixel-wide sprites 12
$D058, $D059 LINESTEP Bytes per character row 12
$D05D bit 7 HOTREG Hot register behaviour 12
$D05E CHRCOUNT Characters per row (low byte) 12
$D060-$D062 SCRNPTR Screen memory address 12
$D064, $D065 COLPTR Colour RAM offset 12
$D06C-$D06E SPRPTRADR Sprite pointer list address 12
$D06F bit 7 PALNTSC Set in NTSC mode 8, 13
$D079, $D07A RASCMP Physical raster compare 8
$D100-$D3FF Palette Red, green and blue, nybble-swapped 12
$D400-$D47F SIDs Four SIDs, $20 bytes each 13
$D600-$D606 UART Serial port 17
$D60A, $D610, $D619 Keyboard queue MODKEY, ASCIIKEY, PETSCIIKEY 16
$D611, $D613, $D614 Keyboard matrix Modifiers, column data, column select 16
$D63C SIDMODE 6581 or 8580 behaviour 13
$D640-$D67F Hypervisor traps Hypervisor services 8, 11
$D6E0 onward Ethernet Ethernet controller 17
$D6F4, $D6F5 MIXREGSEL, MIXREGDATA Audio mixer coefficients 13
$D700-$D707 DMAgic DMA list address and triggers 5, 8
$D70F DIVBUSY, MULBUSY Math accelerator status 5
$D711 AUDEN, NOMIX Audio DMA control 13
$D720-$D75F Audio DMA Four channels of 16 registers 13
$D768-$D77F Math accelerator DIVOUT, MULTINA, MULTINB, MULTOUT 5
$DC00, $DC01 CIA 1 ports Joysticks and keyboard 16
$FFD7110 RTC Real-time clock 17

Appendix F: Converting C64 and C65 Programs

Many C64 programs run unchanged in C64 mode. Converting one to MEGA65 mode lets it use the MEGA65's speed, memory and graphics, but several differences need attention.

BASIC programs

C64 MEGA65 mode
BASIC starts at $0801 BASIC starts at $2001; programs are relinked when loaded
Screen at $0400, 40 columns Screen at $0800, usually 80 columns; use PRINT, T@& and C@& rather than fixed addresses
Sprite pointers at 2040 ($07F8) Sprite pointers at $0FF8 by default; better still, use SPRITE and MOVSPR
POKE to $D000-$DFFF Works when BANK is 128, the default
Variable names that contain BASIC 65 keywords Must be renamed: BASIC 65 has many more keywords, such as COLOR, PEN and BANK
Delay loops Run about forty times faster at 40.5 MHz; replace with SLEEP or VSYNC
GET A$ : IF A$ = "" THEN ... Works, or use GETKEY
Tokens C64 BASIC tokens mean the same in BASIC 65

Machine-language programs

C65 programs

C65 BASIC 10 programs are close relatives of BASIC 65 and often run with small changes, mostly to graphics commands, which changed between BASIC 10 and BASIC 65. C65 machine language runs on the 45GS02, which executes every 4510 instruction.

Appendix G: The Built-in Monitor

The machine-language monitor is entered with MONITOR from BASIC, by a BRK instruction, or by holding RUN/STOP while pressing reset. It accepts 32-bit addresses and treats every number as hexadecimal unless it has a prefix: + decimal, & octal, % binary, ' a PETSCII character (MEGA65 Book, Appendix O).

Command Format Purpose
A A address instruction Assemble an instruction; the monitor then offers the next address
B B address Show memory as character bitmaps
C C from to with Compare two memory ranges
D D [from [to]] Disassemble
F F from to byte Fill memory with a byte
G G [address] Jump to an address
H H from to data Hunt for bytes or text in memory
J J address Call a subroutine, as with JSR
L L "name" [, unit [, address]] Load a file into memory
M M [from [to]] Show memory as hexadecimal and text
R R Show the registers
S S "name", unit, from, to Save memory to a file
T T from to destination Transfer (copy) memory
V V "name" [, unit [, address]] Verify memory against a file
X X Return to BASIC
@ @ [command] Disk command, status or directory

Memory and registers shown by M and R can be changed by moving the cursor onto the display, typing over the values and pressing RETURN, as in other Commodore monitors. Chapter 7 walks through a first program entered with the monitor, and Chapter 8 covers debugging with it, with BRK breakpoints, and with Matrix Mode.