Latheory Scrapbook

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 1299

MEGA65 TEAM

Assoc. Prof. Paul Gardner- Detlef Hastik


Stephen (deft)
(highlander) Co-founder
Founder General manager
Software and virtual hardware architect Marketing and sales
Spokesman and lead scientist
Oliver Graf
Martin Streit (lydon)
(seriously) Release management
Video and photo production VHDL and platform enhancements
Tax and organization
Social media
Antti Lukats
(antti-brain)
Dan Sanderson Host hardware design and production
(dddaaannn) Dieter Penner
Media and documentation (doubleflash)
MEGA65.ROM Host hardware support
Dr. Edilbert Kirk Mirko H.
(Bit Shifter) (sy2002)
MEGA65.ROM Additional platforms and consulting
Manual and tools
Gürçe Işıkyıldız
Gábor Lénárt (gurce)
(LGB) Tools and enhancements
Emulator
Daniel England
Farai Aschwanden (Mew Pokémon)
(Tayger) Additional code and tools
Filehost and tools
Financial advisory
Hernán Di Pietro
(indiocolifa)
Additional emulation and tools
Falk Rehwagen
(bluewaysw) Roman Standzikowski
GEOS (FeralChild)
Open ROMs
Robert Steffens
(kibo) Anton Schneider-Michallek
Network technology (adtbm)
Core bug hunting Presentation and support
Reporting Errors and Omissions

This book is being continuously refined and improved upon by the MEGA65 community.
The version of this edition is:
commit 06 a 3 5 d 2 8 5 1 7 6 7 b 1 d 9 a 5 6 0 c 8 c 3 3 b 3 b 7 a 1 7 7 0 f 5 e 4 a
date : Sun May 5 1 5 : 3 3 : 2 5 2024 +0930

We want this book to be the best that it possibly can. So if you see any errors, find
anything that is missing, or would like more information, please report them using the
MEGA65 User’s Guide issue tracker:
https://github.com/mega65/mega65-user-guide/issues
You can also check there to see if anyone else has reported a similar problem, while
you wait for this book to be updated.
Finally, you can always download the latest versions of our suite of books from these
locations:
• https://mega65.org/mega65-book
• https://mega65.org/user-guide
• https://mega65.org/developer-guide
• https://mega65.org/basic65-ref
• https://mega65.org/chipset-ref
• https://mega65.org/docs
MEGA65 REFERENCE GUIDE

Published by
the MEGA Museum of Electronic Games & Art e.V., Germany.
WORK IN PROGRESS
Copyright ©2019 – 2024 by Paul Gardner-Stephen, the MEGA Museum of Electronic
Games & Art e.V., and contributors.
This book is made available under the GNU Free Documentation License v1.3, or later,
if desired. This means that you are free to modify, reproduce and redistribute this book,
subject to certain conditions. The full text of the GNU Free Documentation License
v1.3 can be found at https://www.gnu.org/licenses/fdl-1.3.en.html.
Implicit in this copyright license, is the permission to duplicate and/or redistribute this
document in whole or in part for use in education environments. We want to support
the education of future generations, so if you have any worries or concerns, please
contact us.
May 5, 2024

ii
Contents
iv
I PREFACE 1

1 Introduction 1-1
Welcome to the MEGA65! . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-3
Other Books in this series . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-4
Come Join Us! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-4

II GETTING TO KNOW YOUR MEGA65 1-5

2 Setup 2-1
Unpacking and Connecting the MEGA65 . . . . . . . . . . . . . . . . . . . . 2-3
Rear Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-4
Side Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-5
MEGA65 Screen and Peripherals . . . . . . . . . . . . . . . . . . . . . . . . 2-6
Optional Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-7
Installing the Real-Time Clock Battery . . . . . . . . . . . . . . . . . . . 2-7
Switching the MEGA65 on for the First Time . . . . . . . . . . . . . . . . . . 2-9
The Intro Disk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-11
The Cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-13

3 Getting Started 3-1


Keyboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-3
Special Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-3
The Screen Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-7
Editor Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-10
Creating a Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-10
Additional ASCII characters . . . . . . . . . . . . . . . . . . . . . . . . 3-11
Uppercase and lowercase . . . . . . . . . . . . . . . . . . . . . . . . . 3-11
The Freezer Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-12
Running Commodore 64 Software . . . . . . . . . . . . . . . . . . . . . . . 3-13
GO64 Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-13

v
The “C64 for MEGA65” FPGA Core . . . . . . . . . . . . . . . . . . . . 3-14

4 Configuring Your MEGA65 4-1


Configuring Your MEGA65 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-3
The Configuration Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-3
Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-4
Chipset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-4
Video . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-6
Audio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-6
Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-7
Done . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-8
Introducing SD Cards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-9
Preparing a New SD Card . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-9
Inserting the SD Card . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-10
The SD Card Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-10
Obtaining the Bundled Software . . . . . . . . . . . . . . . . . . . . . 4-12

5 Upgrading the MEGA65 5-1


How a MEGA65 Can Be Upgraded . . . . . . . . . . . . . . . . . . . . . . . 5-5
What is a Core? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-5
Determining the Versions of Things . . . . . . . . . . . . . . . . . . . . . . . 5-6
Obtaining the Latest Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-7
The Core Selection Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-9
Upgrading the MEGA65 Core, ROM, and System Files . . . . . . . . . . . . . 5-10
Installing Alternate Cores and ROMs . . . . . . . . . . . . . . . . . . . . . . 5-13
Setting Core Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-14
Erasing a Core Slot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-15
Upgrading the Factory Core in Slot 0 . . . . . . . . . . . . . . . . . . . . . . 5-15
Understanding The Core Booting Process . . . . . . . . . . . . . . . . . . . . 5-17

vi
6 Using Disks and Disk Images 6-1
Disk Drives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-3
Unit Numbers and Drive Numbers . . . . . . . . . . . . . . . . . . . . . 6-3
Using Virtual Disk Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-4
Where to Get Disk Image Files . . . . . . . . . . . . . . . . . . . . . . . 6-4
Mounting Disk Images with the Freezer . . . . . . . . . . . . . . . . . . 6-4
Mounting Disk Images from BASIC . . . . . . . . . . . . . . . . . . . . . 6-5
Creating a New Disk Image . . . . . . . . . . . . . . . . . . . . . . . . 6-5
Managing SD Card Files in Sub-directories . . . . . . . . . . . . . . . . 6-6
Using the Internal 3.5” Floppy Disk Drive . . . . . . . . . . . . . . . . . . . . 6-6
Mounting the 3.5” Drive with the Freezer . . . . . . . . . . . . . . . . . 6-7
Mounting the 3.5” Drive from BASIC . . . . . . . . . . . . . . . . . . . . 6-7
DD and HD disks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-7
Formatting a Disk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-8
Using External IEC Disk Drives . . . . . . . . . . . . . . . . . . . . . . . . . . 6-9
Bootable Disks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-9
Auto-Booting Disks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-10
Accessing the SD Card from BASIC . . . . . . . . . . . . . . . . . . . . . . . 6-10
Common Disk Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-11
DIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-11
DLOAD and RUN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-12
DSAVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-12
BACKUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-12
COPY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-13
RENAME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-13
DELETE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-13
Shortcut Disk Commands . . . . . . . . . . . . . . . . . . . . . . . . . . 6-13

vii
7 Transferring Files 7-1
Getting Files to the MEGA65 . . . . . . . . . . . . . . . . . . . . . . . . . . 7-3
Understanding Networking . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-3
Obtaining M65Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-4
M65Connect for Windows . . . . . . . . . . . . . . . . . . . . . . . . . 7-4
M65Connect for macOS . . . . . . . . . . . . . . . . . . . . . . . . . . 7-4
M65Connect for Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-5
Enabling Network Listening . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-5
Transferring Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-7
Transferring Files with M65Connect . . . . . . . . . . . . . . . . . . . . 7-8
The mega65_ftp Command-Line Tool . . . . . . . . . . . . . . . . . . . 7-9

III FIRST STEPS IN CODING 7-11

8 How Computers Work 8-1


Computers are stupid. Really stupid . . . . . . . . . . . . . . . . . . . . . . . 8-3
Making an Egg Cup Computer . . . . . . . . . . . . . . . . . . . . . . . 8-3

9 Getting Started in BASIC 9-1


Your first BASIC programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-3
Exercises to try . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-11
First steps with text and numbers . . . . . . . . . . . . . . . . . . . . . . . . 9-12
Exercises to try . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-27
Making simple decisions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-28
Exercises to try . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-40
Random numbers and chance . . . . . . . . . . . . . . . . . . . . . . . . . . 9-41
Exercises to try . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-44

viii
10 Text Processing 10-1
Characters and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-3
String Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-5
String Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-5
String Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-7
Simple Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-8
Suppressing New Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-8
Automatic Tab Stops . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-8
Tabs Stops and Spacing . . . . . . . . . . . . . . . . . . . . . . . . . . 10-8
Sample Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-8
Palindromes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-9
Simple Ciphers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-9

11 C64, C65 and MEGA65 Modes 11-1


Switching Modes from BASIC . . . . . . . . . . . . . . . . . . . . . . . . . . 11-3
From MEGA65/C65 to C64-mode . . . . . . . . . . . . . . . . . . . . 11-3
From C64 to MEGA65/C65-mode . . . . . . . . . . . . . . . . . . . . 11-4
Entering Machine Code Monitor Mode . . . . . . . . . . . . . . . . . . 11-4
The KEY Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-4
Exposing Extra C65 Registers . . . . . . . . . . . . . . . . . . . . . . . 11-5
Disabling the C65/MEGA65 Extra Registers . . . . . . . . . . . . . . . 11-5
Enabling MEGA65 Extra Registers . . . . . . . . . . . . . . . . . . . . . 11-6
Traps to Look Out For . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-7
Accessing Memory from BASIC 65 . . . . . . . . . . . . . . . . . . . . . . . 11-7
The MAP Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-8

IV SOUND AND GRAPHICS 11-9

12 Graphics 12-1

ix
V MEMORY 12-13

13 Programming with Memory 13-1


Memory Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-4
Bits, Bytes, and Nibbles . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-4
Hexadecimal Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-4
Random Access Memory . . . . . . . . . . . . . . . . . . . . . . . . . . 13-5
Read-Only Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-6
I/O Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-6
Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-7
16-bit Address Translation . . . . . . . . . . . . . . . . . . . . . . . . . 13-7
Banks and Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-8
How Addresses are Stored in Memory . . . . . . . . . . . . . . . . . . . 13-8
The 28-bit Address Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-10
The Chip RAM Memory Map . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-11
How Programs Use Chip RAM . . . . . . . . . . . . . . . . . . . . . . . 13-12
The Memory Map Contract . . . . . . . . . . . . . . . . . . . . . . . . . 13-13
Using Memory from BASIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-15
BASIC Address Remapping . . . . . . . . . . . . . . . . . . . . . . . . . 13-15
BANK and SYS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-17
Using Memory from Machine Code . . . . . . . . . . . . . . . . . . . . . . . 13-19
The MAP Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-20
Examining the MAP Register . . . . . . . . . . . . . . . . . . . . . . . . 13-21
MAP and Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-22
Using 28-bit Addresses in Machine Code . . . . . . . . . . . . . . . . . 13-22
VIC-IV Video Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-24
Locating Screen Memory . . . . . . . . . . . . . . . . . . . . . . . . . . 13-24
Locating Character Data . . . . . . . . . . . . . . . . . . . . . . . . . . 13-25
Locating Sprite Memory . . . . . . . . . . . . . . . . . . . . . . . . . . 13-25
Colour Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-26
Large Memory Operations with Direct Memory Access . . . . . . . . . . . . . 13-28

x
DMA Jobs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-28
Using DMA from BASIC . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-29
Using DMA from Machine Code . . . . . . . . . . . . . . . . . . . . . . 13-29
Invoking an Enhanced Job List in Memory . . . . . . . . . . . . . . . . . 13-29
Invoking an Enhanced Job List Inline with Code . . . . . . . . . . . . . . 13-31
The Enhanced Job List Format . . . . . . . . . . . . . . . . . . . . . . . 13-31
Advanced Memory Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-35
Testing Memory Mapping with the Matrix Mode Debugger . . . . . . . . 13-35
C64-style Memory Banking . . . . . . . . . . . . . . . . . . . . . . . . 13-35
The $D030 VIC-III Banking Register . . . . . . . . . . . . . . . . . . . . 13-36
Cartridge ROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-37
I/O Personalities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-37
Converting ROM to RAM . . . . . . . . . . . . . . . . . . . . . . . . . . 13-38
Using MAP to Access Upper Memory . . . . . . . . . . . . . . . . . . . 13-39
Reading the MAP Register . . . . . . . . . . . . . . . . . . . . . . . . . 13-40
Making All Chip RAM Available . . . . . . . . . . . . . . . . . . . . . . 13-40
Why the SYS Command Can Only Use Certain Addresses . . . . . . . . 13-41

VI HARDWARE 13-43

14 Using Nexys4 boards as a MEGA65 14-1


Building your own MEGA65 Compatible Computer . . . . . . . . . . . . . . 14-5
Working Nexys4 Boards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-6
The Nexys4 board . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-6
The Nexys4DDR board . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-6
The Nexys A7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-7
Power, Jumpers, Switches and Buttons . . . . . . . . . . . . . . . . . . . . . 14-8
Micro-USB Power . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-9
External Power Supply . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-9
Other Jumpers and Switches . . . . . . . . . . . . . . . . . . . . . . . . 14-10

xi
Connections and Peripherals . . . . . . . . . . . . . . . . . . . . . . . 14-11
Communicating with your PC . . . . . . . . . . . . . . . . . . . . . . . 14-11
Onboard buttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-12
Keyboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-12
Some key mappings with a USB keyboard . . . . . . . . . . . . . . . . 14-13
Preparing microSDHC card . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-14
Preparation Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-14
Loading the bitstream from QSPI . . . . . . . . . . . . . . . . . . . . . . . . 14-15
Preparation Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-16
Widget Board . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-16
PMOD-to-Joystick Adapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-19
Useful Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-20

VII CROSS-PLATFORM DEVELOPMENT TOOLS 14-23

15 Emulators 15-1
Using The Xmega65 Emulator . . . . . . . . . . . . . . . . . . . . . . . . . . 15-3
The keyboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-3
Apple MacOS start problems . . . . . . . . . . . . . . . . . . . . . . . 15-4
Updating settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-5
Using the Live ISO image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-5
Creating a Bootable USB stick or DVD . . . . . . . . . . . . . . . . . . 15-5
Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-6
Other Features of the Live ISO . . . . . . . . . . . . . . . . . . . . . . . 15-7

16 Data Transfer and Debugging Tools 16-1


m65 command line tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-3
Screenshots using m65 tool . . . . . . . . . . . . . . . . . . . . . . . . 16-3
Load and run a program on the MEGA65 . . . . . . . . . . . . . . . . . 16-3
Reconfigure the FPGA to run a different bitstream . . . . . . . . . . . . 16-4
Remote keyboard entry . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-4

xii
Unit testing and logging support . . . . . . . . . . . . . . . . . . . . . . 16-5
Using unit tests with C . . . . . . . . . . . . . . . . . . . . . . . 16-5
Using unit tests with BASIC 65 . . . . . . . . . . . . . . . . . . 16-6
BASIC 65 example . . . . . . . . . . . . . . . . . . . . . . . . . 16-7
M65Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-8
mega65_ftp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-9
TFTP Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-9
Converting a BASIC text file listing into a PRG file . . . . . . . . . . . . . . . 16-10

17 Assemblers 17-1

18 C and C-Like Compilers 18-1


MEGA65 libc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18-3

19 MEGA65 Standard C Library 19-1


Structure and Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-3
conio.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-3
conionit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-3
setscreenaddr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-3
getscreenaddr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-4
setcolramoffset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-4
getcolramoffset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-4
setcharsetaddr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-4
getcharsetaddr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-4
clrscr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-5
getscreensize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-5
setscreensize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-5
set16bitcharmode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-5
sethotregs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-6
setextendedattrib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-6
togglecase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-6
togglecase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-6

xiii
togglecase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-6
bordercolor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-6
bgcolor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-7
textcolor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-7
revers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-7
highlight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-7
blink . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-7
underline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-8
altpal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-8
clearattr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-8
cellcolor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-8
setpalbank . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-9
setpalbanka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-9
getpalbank . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-9
getpalbanka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-9
setmapedpal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-9
getmapedpal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-10
setpalentry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-10
fillrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-10
box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-10
hline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-11
vline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-11
gohome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-11
gotoxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-12
gotox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-12
gotoy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-12
moveup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-12
movedown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-13
moveleft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-13
moveright . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-13

xiv
wherex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-13
wherey . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-13
pcputc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-14
pcputsxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-14
cputcxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-14
pcputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-14
cputc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-15
cputnc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-15
cputhex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-15
cputdec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-15
cputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-16
cputsxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-16
cputcxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-16
cputncxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-16
cprintf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-17
pcprintf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-17
cgetc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-18
kbhit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-18
getkeymodstate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-18
flushkeybuf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-18
cinput . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-19
VIC_BASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-19

20 BASIC Tokenisers 20-1

VIII APPENDICES 20-5

A Accessories A-1

xv
B BASIC 65 Command Reference B-1
Commands, Functions, and Operators . . . . . . . . . . . . . . . . . . . . . B-3
BASIC Command Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . B-19

C Screen Codes C-1


Screen Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C-3

D PETSCII Codes D-1


PETSCII Codes and CHR$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-3

E Screen Editor Keys E-1


Screen Editor Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-3
Control codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-3
Shifted codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-6
Escape Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-6

F The MEGA65 Keyboard F-1


Using the Typing Event Queue . . . . . . . . . . . . . . . . . . . . . . . . . . F-3
Reading Immediate Modifier Keys . . . . . . . . . . . . . . . . . . . . . F-4
Interpreting ASCII Typing Events . . . . . . . . . . . . . . . . . . . . . . F-4
Unicode Basic-Latin Keyboard Map . . . . . . . . . . . . . . . . . . . . F-9
Keyboard Theory of Operation . . . . . . . . . . . . . . . . . . . . . . . . . . F-13
C65 Keyboard Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . F-14
Synthetic Key Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . F-15
Keyboard LED Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . F-15
Native Keyboard Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . F-17

G System Palette G-1


System Palette . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G-3

xvi
H Decimal, Binary and Hexadecimal H-1
Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H-3
Notations and Bases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H-4
Decimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H-5
Binary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H-7
Hexadecimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H-9
Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H-10
Counting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H-11
Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H-12
Logic Gates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H-14
Signed and Unsigned Numbers . . . . . . . . . . . . . . . . . . . . . . . . . H-16
Bit-wise Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . H-16
Converting Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H-19

I System Memory Map I-1


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I-3
MEGA65 Native Memory Map . . . . . . . . . . . . . . . . . . . . . . . . . . I-4
The First Sixteen 64KB Banks . . . . . . . . . . . . . . . . . . . . . . . . I-4
Colour RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I-5
Additional RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I-5
28-bit Address Space . . . . . . . . . . . . . . . . . . . . . . . . . . . I-6
$D000 – $DFFF I/O Personalities . . . . . . . . . . . . . . . . . . . . . . . . I-8
CPU Memory Banking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I-10
C64/C65 ROM Emulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . I-10
C65 Compatibility ROM Layout . . . . . . . . . . . . . . . . . . . . . . I-12

J 45GS02 Microprocessor J-1


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J-3
Differences to the 6502 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J-3
Supervisor/Hypervisor Privileged Mode . . . . . . . . . . . . . . . . . . J-3
6502 Unintended Instructions . . . . . . . . . . . . . . . . . . . . . . . J-4

xvii
Read-Modify-Write Instruction Bug Compatibility . . . . . . . . . . . . . J-4
Variable CPU Speed . . . . . . . . . . . . . . . . . . . . . . . . . . . . J-5
Slow (1MHz – 3.5MHz) Operation . . . . . . . . . . . . . . . . . J-5
Full Speed (40MHz) Instruction Timing . . . . . . . . . . . . . . J-5
Direct Memory Access (DMA) . . . . . . . . . . . . . . . . . . . J-5
Accessing memory between the 64KB and 1MB points . . . . . . . . . J-6
C64-Style Memory Banking . . . . . . . . . . . . . . . . . . . . J-6
VIC-III “ROM” Banking . . . . . . . . . . . . . . . . . . . . . . . J-6
VIC-III Display Address Translator . . . . . . . . . . . . . . . . . J-7
The MAP instruction . . . . . . . . . . . . . . . . . . . . . . . . J-7
Direct Memory Access (DMA) Controller . . . . . . . . . . . . . J-9
Flat Memory Access . . . . . . . . . . . . . . . . . . . . . . . . J-9
Accessing memory beyond the 1MB point . . . . . . . . . . . . . . . . J-10
Using the MAP instruction to access >1MB . . . . . . . . . . . . J-10
Flat-Memory Access . . . . . . . . . . . . . . . . . . . . . . . . J-12
Virtual 32-bit Register . . . . . . . . . . . . . . . . . . . . . . . . . . . J-12
C64 CPU Memory Mapped Registers . . . . . . . . . . . . . . . . . . . . . . J-15
New CPU Memory Mapped Registers . . . . . . . . . . . . . . . . . . . . . . J-15
MEGA65 CPU Maths Acceleration Registers . . . . . . . . . . . . . . . . . . J-18
MEGA65 Hypervisor Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . J-22
Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J-22
Entering / Exiting Hypervisor Mode . . . . . . . . . . . . . . . . . . . . J-23
Hypervisor Memory Layout . . . . . . . . . . . . . . . . . . . . . . . . . J-24
Hypervisor Virtualisation Control Registers . . . . . . . . . . . . . . . . J-27
Programming for Hypervisor Mode . . . . . . . . . . . . . . . . . . . . . J-29

K 45GS02 & 6502 Instruction Sets K-1


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-3
Stack Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-3
Addressing Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-4
Implied . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-4

xviii
Accumulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-4
Q Pseudo Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-4
Immediate Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-4
Immediate Word Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . K-5
Base-Page Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-5
Base-Page Quad Mode . . . . . . . . . . . . . . . . . . . . . . . . . . K-5
Base-Page X-Indexed Mode . . . . . . . . . . . . . . . . . . . . . . . . K-6
Base-Page Quad X-Indexed Mode . . . . . . . . . . . . . . . . . . . . K-6
Base-Page Y-Indexed Mode . . . . . . . . . . . . . . . . . . . . . . . . K-7
Absolute Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-7
Absolute Quad Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-7
Absolute X-Indexed Mode . . . . . . . . . . . . . . . . . . . . . . . . . K-8
Absolute Quad X-Indexed Mode . . . . . . . . . . . . . . . . . . . . . K-8
Absolute Y-Indexed Mode . . . . . . . . . . . . . . . . . . . . . . . . . K-8
Absolute Indirect Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . K-9
Absolute Indirect X-Indexed Mode . . . . . . . . . . . . . . . . . . . . K-9
Base-Page Indirect X-Indexed Mode . . . . . . . . . . . . . . . . . . . K-9
Base-Page Indirect Y-Indexed Mode . . . . . . . . . . . . . . . . . . . K-10
Base-Page Indirect Z-Indexed Mode . . . . . . . . . . . . . . . . . . . K-10
Base-Page Quad Indirect Z-Indexed Mode . . . . . . . . . . . . . . . . K-11
32-bit Base-Page Indirect Z-Indexed Mode . . . . . . . . . . . . . . . K-11
32-bit Base-Page (Zero-Page) Indirect Quad Z-Indexed Mode . . . . . K-12
Stack Relative Indirect, Y-Indexed . . . . . . . . . . . . . . . . . . . . . K-12
Relative Addressing Mode . . . . . . . . . . . . . . . . . . . . . . . . . K-13
Relative Word Addressing Mode . . . . . . . . . . . . . . . . . . . . . . K-13
6502 Instruction Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-14
Official And Unintended Instructions . . . . . . . . . . . . . . . . . . . K-14
Opcode Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-14
4510 Instruction Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-57
Instruction Timing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-57

xix
Opcode Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K-57
45GS02 Compound Instructions . . . . . . . . . . . . . . . . . . . . . . . . K-116

L Developing System Programmes L-1


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . L-5
Flash Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . L-5
Format/FDISK Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . L-6
Keyboard Test Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . L-7
MEGA65 Configuration Utility . . . . . . . . . . . . . . . . . . . . . . . . . . L-7
Freeze Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . L-7
Freeze Menu Helper Programmes . . . . . . . . . . . . . . . . . . . . . . . . L-7
Hypervisor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . L-7
OpenROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . L-8

M MEGA65 Hyppo Services M-1


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M-3
General Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M-7
Drive/Storage Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M-11
Disk Image Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M-40
Task and Process Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . M-44
System Partition Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M-60
Freezer Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M-61

N Machine Language Monitor N-1


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-3
The MEGA65 Machine Language Monitor . . . . . . . . . . . . . . . . . . . N-3
Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-3
The Assembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-4
Differences from the C65 Monitor . . . . . . . . . . . . . . . . . . . . . N-5
Table of MEGA65 Monitor Commands . . . . . . . . . . . . . . . . . . N-6
A : ASSEMBLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-6
B : BITMAPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-7

xx
C : COMPARE . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-8
D : DISASSEMBLE . . . . . . . . . . . . . . . . . . . . . . . . . . N-9
F : FILL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-9
G : GO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-10
H : HUNT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-10
J : JUMP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-10
L : LOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-10
M : MEMORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-11
R : REGISTERS . . . . . . . . . . . . . . . . . . . . . . . . . . . N-12
S : SAVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-12
T : TRANSFER . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-12
V : VERIFY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-12
X : EXIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-13
. : ASSEMBLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-13
> : MODIFY MEMORY . . . . . . . . . . . . . . . . . . . . . . . N-13
; : MODIFY REGISTERS . . . . . . . . . . . . . . . . . . . . . . . N-13
@ : DISK COMMAND . . . . . . . . . . . . . . . . . . . . . . . . N-14
The Matrix Mode/Serial Monitor . . . . . . . . . . . . . . . . . . . . . . . . . N-14
Table of Matrix Mode Monitor Commands . . . . . . . . . . . . . . . . N-15
Calling the Monitor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-16
# : Hypervisor trap enable/disable . . . . . . . . . . . . . . . . N-16
+ : Set Serial Interface UART Divisor . . . . . . . . . . . . . . . N-16
@ : CPUMEMORY . . . . . . . . . . . . . . . . . . . . . . . . . . N-17
? or H : HELP . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-17
B : BREAKPOINT . . . . . . . . . . . . . . . . . . . . . . . . . . . N-17
D : DISASSEMBLE . . . . . . . . . . . . . . . . . . . . . . . . . . N-17
E : FLAGWATCH . . . . . . . . . . . . . . . . . . . . . . . . . . . N-18
F : FILL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-18
G : SETPC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-18
I : INTERRUPTS . . . . . . . . . . . . . . . . . . . . . . . . . . . N-19

xxi
J : DEBUGMON . . . . . . . . . . . . . . . . . . . . . . . . . . . N-19
L : LOADMEMORY . . . . . . . . . . . . . . . . . . . . . . . . . N-19
M : MEMORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-19
R : REGISTERS . . . . . . . . . . . . . . . . . . . . . . . . . . . N-20
S : SETMEMORY . . . . . . . . . . . . . . . . . . . . . . . . . . N-20
T : TRACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N-20
W : WATCHPOINT . . . . . . . . . . . . . . . . . . . . . . . . . . N-20
Z : CPUHISTORY . . . . . . . . . . . . . . . . . . . . . . . . . . N-21

O F018-Compatible Direct Memory Access (DMA) Controller O-1


F018A/B DMA Jobs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . O-3
F018 DMA Job List Format . . . . . . . . . . . . . . . . . . . . . . . . . O-4
F018 11 byte DMA List Structure . . . . . . . . . . . . . . . . . O-5
F018B 12 byte DMA List Structure . . . . . . . . . . . . . . . . O-5
Performing Simple DMA Operations . . . . . . . . . . . . . . . . O-6
MEGA65 Enhanced DMA Jobs . . . . . . . . . . . . . . . . . . . . . . . . . . O-12
Texture Scaling and Line Drawing . . . . . . . . . . . . . . . . . . . . . . . . O-15
Inline DMA Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . O-17
Audio DMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . O-18
Sample Address Management . . . . . . . . . . . . . . . . . . . . . . . O-18
Sample Playback frequency and Volume . . . . . . . . . . . . . . . . . O-19
Pure Sine Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . O-19
Sample playback control . . . . . . . . . . . . . . . . . . . . . . . . . . O-20
F018 “DMAgic” DMA Controller . . . . . . . . . . . . . . . . . . . . . . . . . O-20
MEGA65 DMA Controller Extensions . . . . . . . . . . . . . . . . . . . . . . O-20
Unimplemented Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . O-24

P VIC-IV Video Interface Controller P-1


Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-5
VIC-II/III/IV Register Access Control . . . . . . . . . . . . . . . . . . . . . . P-6
Detecting VIC-II/III/IV . . . . . . . . . . . . . . . . . . . . . . . . . . . P-7

xxii
Video Output Formats, Timing and Compatibility . . . . . . . . . . . . . . . . P-8
Integrated Marvellous Digital Hookup™ (IMDH™) Digital Video Output . P-8
Connecting to Naughty Proprietary Digital Video Standards . . P-9
Frame Timing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-10
Physical and Logical Rasters . . . . . . . . . . . . . . . . . . . . P-13
Bad Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-13
Memory Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-14
Startup Base Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . P-14
Relocating Screen Memory . . . . . . . . . . . . . . . . . . . . . . . . . P-14
Relocating Character Generator Data . . . . . . . . . . . . . . . . . . P-15
Relocating Colour / Attribute RAM . . . . . . . . . . . . . . . . . . . . P-15
Relocating Sprite Pointers and Images . . . . . . . . . . . . . . . . . . P-16
Hot Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-17
New Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-19
Why the new VIC-IV modes are Character and Bitmap modes, not Bit-
plane modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-20
Displaying more than 256 unique characters via ”Super-Extended At-
tribute Mode” . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-21
Default Bit Fields (when GOTOX bit is cleared): . . . . . . . . . P-22
Bit Fields when GOTOX bit is set: . . . . . . . . . . . . . . . . . P-23
Using Super-Extended Attribute Mode . . . . . . . . . . . . . . . . . . P-24
Full-Colour (256 colours per character) Text Mode (FCM) . . . . . . . . P-28
Nibble-colour (16 colours per character) Text Mode (NCM) . . . . . . . P-28
Alpha-Blending / Anti-Aliasing . . . . . . . . . . . . . . . . . . . . . . P-29
Flipping Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-29
Variable Width Fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-29
Raster Re-write Buffer . . . . . . . . . . . . . . . . . . . . . . . . . . . P-30
Sprites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-31
VIC-II/III Sprite Control . . . . . . . . . . . . . . . . . . . . . . . . . . . P-31
Extended Sprite Image Sets . . . . . . . . . . . . . . . . . . . . . . . . P-31
Variable Sprite Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-32

xxiii
Variable Sprite Resolution . . . . . . . . . . . . . . . . . . . . . . . . . P-32
Sprite Palette Bank . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-33
Full-Colour Sprite Mode . . . . . . . . . . . . . . . . . . . . . . . . . . P-33
VIC-III Errata Level . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-36
VIC-III Errata Levels . . . . . . . . . . . . . . . . . . . . . . . . P-36
VIC-II / C64 Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-37
VIC-III / C65 Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P-40
VIC-IV / MEGA65 Specific Registers . . . . . . . . . . . . . . . . . . . . . . P-42

Q Sound Interface Device (SID) Q-1


SID Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q-3

R 6526 Complex Interface Adapter (CIA) Registers R-1


CIA 6526 Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . R-3
CIA 6526 Hypervisor Registers . . . . . . . . . . . . . . . . . . . . . . . . . R-6

S 4551 UART, GPIO and Utility Controller S-1


C65 6551 UART Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . S-3
4551 General Purpose I/O & Miscellaneous Interface Registers . . . . . . . S-4

T 45E100 Fast Ethernet Controller T-1


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T-3
Differences to the RR-NET and similar solutions . . . . . . . . . . . . . T-3
Theory of Operation: Receiving Frames . . . . . . . . . . . . . . . . . . T-4
Accessing the Ethernet Frame Buffers . . . . . . . . . . . . . . . . . . . T-5
Theory of Operation: Sending Frames . . . . . . . . . . . . . . . . . . . T-7
Advanced Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T-7
Broadcast and Multicast Traffic and Promiscuous Mode . . . . . T-7
Debugging and Diagnosis Features . . . . . . . . . . . . . . . . T-7
Memory Mapped Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . T-8
COMMAND register values . . . . . . . . . . . . . . . . . . . . . . . . . T-10
Example Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T-10

xxiv
U 45IO27 Multi-Function I/O Controller U-1
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . U-3
F011-compatible Floppy Controller . . . . . . . . . . . . . . . . . . . . . . . U-3
Multiple Drive Support . . . . . . . . . . . . . . . . . . . . . . . . . . . U-3
Buffered Sector Operations . . . . . . . . . . . . . . . . . . . . . . . . U-4
Reading Sectors from a Disk . . . . . . . . . . . . . . . . . . . . . . . . U-4
Track Auto-Tune Function . . . . . . . . . . . . . . . . . . . . . . . . . . U-5
Sector Skew and Target Any Mode . . . . . . . . . . . . . . . . . . . . U-5
Disk Layout and 1581 Logical Sectors . . . . . . . . . . . . . . . . . . U-6
FD2000 Disks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . U-7
High-Density and Variable-Density Disks . . . . . . . . . . . . . . . . . U-7
Track Information Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . U-8
Formatting Disks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . U-9
Write Pre-Compensation . . . . . . . . . . . . . . . . . . . . . . . . . . U-9
Buffered Sector Writing . . . . . . . . . . . . . . . . . . . . . . . . . . U-10
Floppy Track DMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . U-10
Using Floppy Track DMA . . . . . . . . . . . . . . . . . . . . . . U-11
Understanding the Limitations of Floppy Drives . . . . . . . . . . U-11
F011 Floppy Controller Registers . . . . . . . . . . . . . . . . . . . . . U-12
SD card Controller and F011 Virtualisation Functions . . . . . . . . . . . . . U-14
SD card Based Disk Image Access . . . . . . . . . . . . . . . . . . . . . U-15
F011 Virtualisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . U-17
Dual-Bus SD card Controller . . . . . . . . . . . . . . . . . . . . . . . . U-17
Write Gate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . U-18
Fill Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . U-18
Selecting Among Multiple SD cards . . . . . . . . . . . . . . . . U-18
SD Controller Command Table . . . . . . . . . . . . . . . . . . U-19
Touch Panel Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . U-21
Audio Support Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . U-23
Other Audio Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . U-25

xxv
Mixer Feedback Registers . . . . . . . . . . . . . . . . . . . . . U-25
8/16 Bit Stereo Digital Audio Registers . . . . . . . . . . . . . U-25
Pulse Width vs Pulse Density Modulation . . . . . . . . . . . . . U-26
Miscellaneous I/O Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . U-27

V 4541 Serial Bus Controller V-1


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V-3
Features of the 4541 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V-3
Supports Enhanced Serial Protocol Variants . . . . . . . . . . . . . . . V-3
Interrupt Enabled Processor Offload . . . . . . . . . . . . . . . . . . . V-3
Processor Speed Independence . . . . . . . . . . . . . . . . . . . . . . V-3
Co-Existence through Open-Collector Logic . . . . . . . . . . . . . . . V-3
Theory of Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V-4
Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V-5
Reading the DOS channel status . . . . . . . . . . . . . . . . . . . . . V-5
Command Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V-7
Register Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V-10
Serial Bus Timing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V-12
Send Byte Under Attention . . . . . . . . . . . . . . . . . . . . . . . . . V-12
JiffyDOS™ Protocol Solicitation . . . . . . . . . . . . . . . . . . . . . . V-15
JiffyDOS™ Send from Controller to Peripheral . . . . . . . . . . . . . . V-17
JiffyDOS™ Controller Receive from Peripheral . . . . . . . . . . . . . . V-19
Talker to Listener Turn-Around . . . . . . . . . . . . . . . . . . . . . . . V-22
Send Byte With End-or-Indicate (EOI) . . . . . . . . . . . . . . . . . . . V-24
Receive Byte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V-26
Optional Integrated Data-Logger . . . . . . . . . . . . . . . . . . . . . . . . V-27
Extracting Data from the Data Logger . . . . . . . . . . . . . . . . . . V-28

xxvi
W 5417E Spreadsheet Hardware Integrated Technology Engine W-1
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . W-3
Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . W-3
Unimplemented Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . W-4

X Reference Tables X-1


Units of Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X-3
Base Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X-4

Y Flashing the FPGAs and CPLDs in the MEGA65 Y-1


Suggested PC specifications . . . . . . . . . . . . . . . . . . . . . . . . . . Y-5
Warning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y-6
Installing Vivado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y-6
Installing the FTDI drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y-21
Linux drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y-22
Windows drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y-22
Flashing the main FPGA using Vivado . . . . . . . . . . . . . . . . . . . . . . Y-26
Flashing the CPLD in the MEGA65’s Keyboard with Lattice Diamond . . . . . Y-39
Flashing the MAX10 FPGA on the MEGA65’s Mainboard with INTEL QUARTUS Y-46

Z Trouble shooting Z-1


Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Z-3
No Digital Video Output . . . . . . . . . . . . . . . . . . . . . . . . . . Z-3
MEGA65 R4, R5, R6 . . . . . . . . . . . . . . . . . . . . . . . . Z-3
No lights when powering on . . . . . . . . . . . . . . . . . . . . . . . . Z-3
Vivado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Z-3
RAM requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Z-4
mega65_ftp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Z-4
Missing Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Z-5

xxvii
AA Model Specific Features AA-1
Detecting MEGA65 Models . . . . . . . . . . . . . . . . . . . . . . . . . . . AA-3
MEGA65 Desktop Computer, Revisions 5 and 6 . . . . . . . . . . . . . . . . AA-3
MEGA65 Desktop Computer, Revision 4 . . . . . . . . . . . . . . . . . . . . AA-4
MEGA65 Desktop Computer, Revision 3 & Revision 3A . . . . . . . . . . . . AA-5
MEGA65 Desktop Computer, Revision 2 . . . . . . . . . . . . . . . . . . . . AA-5
MEGAphone Handheld, Revisions 1 and 2 . . . . . . . . . . . . . . . . . . . AA-7
Nexys4 DDR FPGA Board . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AA-7

AB Schematics AB-1
MEGA65 R3 Schematics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AB-3
MEGA65 R2 Schematics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AB-28
Nexys Widget Board Schematics . . . . . . . . . . . . . . . . . . . . . . . . . AB-51

AC Supporters & Donors AC-1


Organisations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AC-3
Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AC-4
Supporters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AC-5

INDEX Index-3

xxviii
PART I
PREFACE
2
CHAPTER 1
Introduction
• Welcome to the MEGA65!
• Other Books in this series
• Come Join Us!
1-2
WELCOME TO THE MEGA65!
Congratulations on your purchase of one of the most long-awaited computers in the
history of computing! The MEGA65 is community designed, and based on the never-
released Commodore® 651 computer; a computer designed in 1989 and intended
for public release in 1990. Decades have passed, and we have endeavoured to invoke
memories of an earlier time when computers were simple and friendly. They were not
only simple to operate and understand, but friendly and approachable for new users.
These 1980s computers inspired many of their owners to pursue the exciting and re-
warding technology careers they have today. Just imagine the exhilaration these early
computing pioneers experienced, as they learned they could use their new computer
to solve problems, write a letter, prepare taxes, invent new things, discover how the
universe works, and perhaps even play an exciting game or two! We want to re-awaken
that same level of excitement (which alas, is no longer found in modern computing),
so we have created the MEGA65.
The MEGA65 team believes that owning a computer is like owning a home. You don’t
just use a home; you change things, big and small, to make it your own custom living
space. After a while, when you settle in, you may decide to renovate or expand your
home to make it more comfortable, or provide more utility. Think of the MEGA65 as
your very own “computing home”.
This guide will teach you how to do more than just hang pictures on a wall; it will show
you how to build your dream home. While you read this user’s guide, you will learn
how to operate the MEGA65, write programs, add additional software, and extend
hardware capabilities. What won’t be immediately obvious is that along the journey,
you will also learn about the history of computing as you explore the many facets of
BASIC version 65 and operating system commands.
Computer graphics and music make computing more fun, and we designed the
MEGA65 to be fun! In this user’s guide, you will learn how to write programs using
the MEGA65’s built-in graphics and sound capabilities. But you don’t need to be a
programmer to have fun with the MEGA65. Because the MEGA65 includes a com-
plete Commodore® 64™2 , it can also run thousands of existing games, utilities, and
business software packages, as well as new programs being written today by Com-
modore computer enthusiasts. Excitement for the MEGA65 will grow as we all witness
the programming marvels our MEGA65 community create, as they (and you!) discover
and master the powerful capabilities of this modern Commodore computer recre-
ation. Together, we can build a new “homebrew” community, teeming with software
and projects that push the MEGA65’s capabilities far beyond what anyone thought
would be possible.
We welcome you on this journey! Thank you for becoming a part of the MEGA65
community of users, programmers, and enthusiasts!
1 Commodore is a trademark of C= Holdings
2 Commodore 64 is a trademark of C= Holdings

1-3
OTHER BOOKS IN THIS SERIES
This book is one of several within the MEGA65 documentation suite. The series in-
cludes:
• The MEGA65 User’s Guide
Provides an introduction to the MEGA65, and a condensed BASIC 65 command
reference
• The MEGA65 BASIC 65 Reference
Comprehensive documentation of all BASIC 65 commands, functions and oper-
ators
• The MEGA65 Chipset Reference
Detailed documentation about the MEGA65 and C65’s custom chips
• The MEGA65 Developer’s Guide
Information for developers who wish to write programs for the MEGA65
• The MEGA65 Complete Compendium
(Also known as The MEGA65 Book)
All volumes in a single huge PDF for easy searching. 1200 pages and growing!

COME JOIN US!


Get involved, learn more about your MEGA65, and join us online at:
• https://mega65.org/chat
• https://mega65.org/forum

1-4
PART II
GETTING TO KNOW YOUR
MEGA65
1-6
CHAPTER 2
Setup
• Unpacking and Connecting the MEGA65
• Rear Connections
• Side Connections
• MEGA65 Screen and Peripherals
• Optional Connections
• Switching the MEGA65 on for the First Time
• The Intro Disk
• The Cursor
2-2
UNPACKING AND CONNECTING THE
MEGA65
It is time to set up your MEGA65 home computer! The box contains the following:
• MEGA65 computer
• Power supply (black box with socket for mains supply)
• This book, the MEGA65 User’s Guide
• Your personal registration code, on a piece of paper (possibly tucked into the
User’s Guide)
In addition, to be able to use your MEGA65 computer you will need:
• A television or computer monitor with a VGA or digital video input, capable of
displaying an image at 480p (720x480) at 60Hz or 576p (720x576) at 50Hz
• An appropriate video cable for your display, either VGA or digital video
You may also like to use the following to get the most out of your MEGA65:
• A digital video display with built-in audio, or powered speakers and an appro-
priate audio cable with 3.5mm audio jack connector
• A microSD card, type SDHC, between 4GB and 32GB in size
• An RJ45 Ethernet cable and a network router or switch
• A joystick or gamepad compatible with Commodore computers, with a nine-pin
(DE-9) connector
• A Commodore 1351 mouse, an Amiga mouse, or a modern replacement such
as a mouSTer USB mouse adapter

2-3
REAR CONNECTIONS

1 3.5mm Audio Jack


2 External microSD Card Slot
3 Network LAN Port
4 Digital Video Connector (including sound)
5 VGA Video Connector
6 IEC Serial Bus Connector for Disk Drives and Printers
7 Cartridge Expansion Port
8 Power Supply Socket

2-4
SIDE CONNECTIONS

1 Power Switch
2 Controller Port 2
3 Controller Port 1
4 Reset Button

Various peripherals can be connected to Controller Ports 1 and 2 such as joysticks,


paddles or mouse devices.

2-5
MEGA65 SCREEN AND PERIPHERALS

To connect your MEGA65 to a display:


1. Connect the power supply to the power supply socket of the MEGA65.
2. If you have a VGA monitor and a VGA cable, connect one end to the VGA port
of the MEGA65 and the other end into your VGA monitor.
3. If you have a TV or monitor with a compatible Digital Video connector,1 connect
one end of your cable to the Digital Video port of the MEGA65, and the other
into the Digital Video port of your monitor. If you own a monitor with a DVI socket,
you can use a Digital Video to DVI adapter.

1 The Digital Video connector type has a recognizable four-letter commercial name, but the MEGA65

project has not paid the licensing fees to refer to it by this name. This User’s Guide refers to this as the
“Digital Video” connector.

2-6
OPTIONAL CONNECTIONS
1. The MEGA65 includes an internal 3.5” floppy disk drive. You can also connect
older Commodore® IEC serial floppy drives to the MEGA65, such as the Com-
modore 1541, 1571 or 1581. To use these drives, connect one end of an IEC
cable to the Commodore floppy disk drive and the other end to the Disk Drive
socket of the MEGA65. You can also connect an SD2IEC device or a Pi1541
device. With most devices, you can daisy-chain additional floppy disk drives or
Commodore compatible printers.
2. You can connect your MEGA65 to an Ethernet network using a standard Ethernet
cable.
3. For enjoying audio from your MEGA65, you can connect a 3.5mm audio jack
cable to an audio amplifier or speaker system. If your system has RCA connectors
you will need a 3.5mm audio jack to twin RCA adapter cable. The MEGA65 also
has a built-in amplifier to allow the use of headphones.
4. A microSD card, type SDHC between 4GB and 32GB, can be inserted into the
external microSD card slot at the rear of the MEGA65. For more information on
using the microSD card slot, see “Introducing SD Cards” on page 4-9.
5. Underneath the MEGA65, a small door provides access to the internal SD card
and two connectors for future hardware expansion.

Installing the Real-Time Clock Battery


The MEGA65 includes a Real-Time Clock, which is used to display the time and date
on the startup screen, to add timestamps to files that the MEGA65 writes to your SD
cards, and to provide the DT$ and TI$ BASIC variables for use in programs. This clock
uses a CR2032 coin-cell battery to keep the time when the MEGA65 is disconnected
from power for long periods of time. The MEGA65 does not include a battery in order
to avoid issues related to shipping batteries internationally.2
The RTC battery is optional. The MEGA65 can keep the RTC running without a bat-
tery, even when the computer is disconnected from power, for multiple days at a time.
Installing a battery allows the computer to remember the time for much longer periods.
(You can always set the clock again later.)
To install the battery, switch off the computer. Use a Phillips-head screwdriver to open
the case, exposing the motherboard. The case is held together with three screws, all of
which are along the bottom of the front side of the case. Once the screws have been
removed, carefully lift the top half of the case. Note the orientation of the keyboard
connector, then disconnect it.
The battery is located between the controller ports and the keyboard connector.
2 Early models of MEGA65 with the “R3A” board revision (made in the year 2022) use a battery of type

CR1220 for the Real-Time Clock, and the battery is required for the RTC to function. Revision “R6” (made
in 2024) uses a battery of type CR2032, and the battery is optional for regular use.

2-7
EXPANSION PORT
CONT PORT B

32
KEYBOARD
0
R2

C
CONT PORT A

RTC BATTERY

If you are removing an existing battery, push the battery release lever on the bottom
(flat-sided) side of the battery socket away from the battery to remove it. Insert the
new battery with the side labelled + facing up, and press it into place.
Once you have re-assembled your MEGA65, you can set the time in the Configuration
Utility. For more information on how to set the Real-Time Clock, refer to the Configu-
ration Utility section on page 4-3.

2-8
SWITCHING THE MEGA65 ON FOR THE
FIRST TIME
Switch the MEGA65 on using the power switch on the left-hand side of the computer.
When you switch your MEGA65 on for the first time, it displays the initial configuration
(“on-boarding”) screen. You can use this screen to set the time and date on the Real-
Time Clock, change the video display mode, and test the audio. All of these settings
can be changed later.

For video display modes, you can select between PAL or NTSC emulation, and you can
select whether your Digital Video display supports sound. If you are using the VGA
video output, the Digital Video sound mode has no effect.
NOTE: A DVI display that does not support sound will not work with the “enhanced”
sound mode. With such a display, you must select a video mode with “no sound,” and
connect a speaker to the 3.5 mm audio jack.
PAL and NTSC are analog video signal formats that affect the resolution and vertical
sync speed of the video output, even when using a modern digital display. Your display
may support either mode, or it may only support one or the other. You can use this
screen to test the modes with your display.
TAB
Select and test your video configuration. For example, press to switch to the
PAL 50HZ mode.

2-9
Press SPACE followed by Y to test the new video mode.

Press K to keep the new video mode.

2-10
Take this opportunity to test your sound set-up. Press A to play a sound.
The “CRT emulation” option is a fun choice when using a modern flat panel display. It
adds vertical gaps between pixels to simulate the CRT raster line. Try it to see if you
like it: press the C key to toggle it on and off.
RETURN
Finally, press to complete the configuration.
For more information about configuring your MEGA65, see chapter 4 on page 4-3.

THE INTRO DISK


After completing the on-boarding configuration, your MEGA65 starts the Intro Disk
menu. The Intro Disk is a collection of software made by the MEGA65 community that
demonstrates some of the capabilities of the computer. Take some time to browse the
menus and try some of the demos. After each demo, press the reset button on the
left-hand side of the computer to return to the Intro Disk menu.

2-11
By default, the Intro Disk menu opens each time you switch on the computer. Once
you are more familiar with the MEGA65, you may wish to disable this. Press D at
the Intro Disk menu to disable its auto-boot feature.
Press / (forward slash) to exit the Intro Disk menu and access BASIC 65. With the
Intro Disk auto-boot feature disabled, the MEGA65 goes directly to BASIC 65 when
you switch it on.

2-12
THE CURSOR
The flashing square underneath the READY prompt is called the cursor. The cursor indi-
cates that the computer is ready to accept input. Pressing keys on the keyboard will
print their respective characters onto the screen. The characters will be printed at the
current cursor position, and the cursor will advance to the next position after every key
press.
Here you can type commands that can do things such as loading a program. You can
also start entering program code!

2-13
2-14
CHAPTER 3
Getting Started
• Keyboard
• The Screen Editor
• Editor Functionality
• The Freezer Menu
• Running Commodore 64 Software
3-2
KEYBOARD
Now that everything is connected, it’s time to get familiar with the MEGA65 keyboard.
You may notice that the keyboard is a little different to the keyboards used on com-
puters today. While most keys will be in familiar positions, there are some specialised
keys, and some with special graphic symbols marked on the front.
The graphic symbols are typable in some display modes, similar to letters, numbers,
and punctuation. The complete set of characters is known as the PETSCII character
set.

Special Keys
RETURN
RETURN
Pressing enters the information you have typed into the MEGA65’s memory. The
computer will either act on a command, store some information, or display an error
message if you made a mistake.

SHIFT
SHIFT
The two keys are located on the left and the right. They work very much like the
Shift key on a regular keyboard. They also perform some special functions as well.
SHIFT
In upper case mode, holding down and pressing any key with two graphic sym-
SHIFT
bols on the front produces the right-hand symbol on that key. For example, and
J prints the J character.
SHIFT
In lower case mode, pressing and a letter key prints the upper case letter on
that key.
SHIFT
Finally, holding down and pressing a Function key accesses the function shown
SHIFT
on the front of that key. For example: and F1 activates F2 .

SHIFT LOCK
SHIFT SHIFT
In addition to is LOCK . Press this key to lock down the Shift function. Now any
SHIFT
key you press while LOCK is illuminated prints the character to the screen as if you
SHIFT
were holding down . This includes special graphic characters.

3-3
CTRL
CTRL CTRL
is the Control key. Holding down and pressing another key allows you to
CTRL
perform Control functions. For example, holding down and one of the number
keys (from 1 to 8 ) allows you to change text colours. The colour that is printed
CTRL
at the top row on the front of the number key will be used. Holding down and
pressing 9 or 0 switches reverse-text mode on and off.
There are some examples of this on page 3-7, and all of the Control functions are
listed on page E-3.
CTRL
If a program is being LISTed to the screen, holding down slows down the display
of each line. You can read more about the LIST command on page B-150.
CTRL
Holding and pressing * enters the Matrix Mode Debugger (refer to the
MEGA65 Book for more details).

RUN STOP
RUN SHIFT
Normally, pressing STOP stops the execution of a program. Holding while press-
RUN
ing STOP RUNs the first program from disk.
RUN
Some programs override the STOP key and cannot be stopped in this way.
RUN
You can boot your MEGA65 into the Machine Code Monitor by holding down STOP

and pressing reset on the left-hand side of the computer.

RESTORE
The computer screen can be restored to a clean state without clearing the memory
RUN RESTORE
by holding down STOP and pressing . This combination also resets operating
system vectors and re-initialises the screen editor, which makes it a handy combination
if the computer has become a little confused.
RUN RESTORE
Some programs override the STOP + key combination and cannot be reset in
this way.
RESTORE
You can also enter the Freezer by pressing and holding for one second, then
releasing the key. You can read more about the Freezer on page 3-12.

THE CURSOR KEYS


At the bottom right-hand side of the keyboard are the cursor keys. These four direc-
tional keys allow you move the cursor to any position for on-screen editing.

3-4
The cursor moves in the direction indicated on the keys: ← ↑ → ↓ .
You don’t have to keep pressing a cursor key over and over. If you need to move the
cursor a long way, you can keep the key pressed down. When you are finished, simply
release the key.

ARROW KEYS

These keys are different to the cursor keys! They are ← (next to 1 ), and ↑
RESTORE
(next to ). Both arrow keys are used in various BASIC functions and escape
sequences.

For example, ← can be used as a shortcut for SAVE, and ↑ is used to raise a
number to a power (which is the same as multiplying a number by itself a specified
number of times).
You can read more about the available escape sequences on page E-6.
These two PETSCII specific keys will always be shown in MEGA65 literature with a
white background.

and ↓ , and left by using


SHIFT
It is also possible to move the cursor up by using
SHIFT
and → . This owes to the MEGA65’s Commodore 64 heritage, which only had
two cursor keys.

INSerT/DELete
INST
The DEL key, the rightmost key of the top row, is the INSERT / DELETE key. When you
INST
press DEL, the character to the left is deleted, and all characters to the right are
shifted one position to the left.
SHIFT INST
To insert a character, hold and press DEL . All the characters to the right of
the cursor are shifted to the right. This allows you to type a letter, number or any other
character at the newly inserted space.

CLeaR/HOME
CLR CLR
The HOME is the CLEAR / HOME key. Pressing HOME places the cursor at the top
left-most position of the screen.
SHIFT CLR
Holding down and pressing HOME clears the entire screen and places the cursor
at the top left-most position of the screen.
CLR
If you press HOME accidentally, you can return the cursor to its prior position by pressing
ESC CLR
then HOME .

3-5
MEGA KEY

` or the MEGA key provides a number of different functions and can be used to
launch special utilities.
SHIFT
Holding and pressing ` switches between lower and uppercase character
modes.
Holding ` and pressing any key with two graphic symbols on the front prints the
left-most graphic symbol to the screen. For example, ` and D prints the d
symbol.

Holding ` and pressing any key that shows a single graphic symbol on the front
prints that graphic symbol to the screen.

Holding ` and pressing a number key switches to a secondary colour, i.e., the colour
that is printed at the bottom row on the front of the number key.
TAB
Holding ` and pressing enters the Matrix Mode Debugger (refer to the
MEGA65 Book for more details).
Switching on the MEGA65 or pressing the reset button on the left-hand side while
holding down ` switches the MEGA65 into GO64 mode.

NO SCROLL
NO
If a program is being LISTed to the screen, pressing SCROLL pauses the screen output.
Press any key to un-pause.
This feature is not available in GO64 mode.

FUNCTION KEYS

There are seven Function keys available for use by software applications. F1 F3
F5 F7 F9 F11 and F13 can be used to perform special functions.
SHIFT
Hold to access F2 through to F14 as shown on the front of each Function
key. Only Function keys F1 to F8 are available in GO64 mode.

HELP
HELP
can be used by software and also acts as F15 / F16 .

3-6
ALT
ALT
Holding down while pressing other keys can be used by software to perform
specific functions. This feature is not available in GO64 mode.
ALT
Holding down while switching the MEGA65 on activates the Utility Menu. You
can format an SD card, or enter the MEGA65 Configuration Utility to select the default
video mode and change other settings, or test your keyboard.

CAPS LOCK
CAPS SHIFT
LOCK works similarly to LOCK in C65 and MEGA65-modes, but only modifies the letter
keys.
When the MEGA65 is set to run at a reduced processor speed, such as in GO64 mode,
CAPS
you can hold down LOCK to run the processor at full speed temporarily. This is useful in
GO64 mode for things such as speeding up loading from the internal disk drive or SD
card, or to greatly speed up the de-packing process after a program is run. MEGA65
mode runs at maximum speed by default.

THE SCREEN EDITOR


When you switch on your MEGA65 or reset it, the following screen will appear:1

The colour bars in the top left-hand side of the screen can be used as a guide to help
calibrate the colours of your display. The screen also displays the name of the system,
the copyright notice, and the ROM version. The displayed date and time are taken
from the internal RTC (Real-Time Clock) at the time the computer was powered on.
You can set the date and time in the Configuration Utility.
1 This assumes you have disabled the Intro Disk menu. If the Intro Disk menu is running, press “/” (forward

slash) to exit to this screen.

3-7
Finally, you will see the READY prompt and the flashing cursor.
You can begin typing keys on the keyboard and the characters will be printed at the
cursor position. The cursor itself will advance after each key press.
CTRL
You can also produce reverse text or colour bars by holding down and pressing
9 , or R . This enters reverse text mode. When this is enabled, you can press and
hold the SPACE bar. While doing so, a white bar will be drawn across the screen.
CTRL
You can change the current colour by holding down and pressing a number key
CTRL
(from 1 to 8 ). For example, if you press and hold down and press 1 ,
the colour will change to black. Now, when you hold down the SPACE bar, a black
bar will be drawn. If you continue to change the colour and press the SPACE bar,
you will get an effect similar to the following image:

CTRL
You can disable reverse text mode by holding and pressing 0 .

A further eight colours can be selected by holding down ` and pressing a key from
1 to 8 .
The colour that is printed at the bottom row on the front of the number key will be
used. For example, if you held ` down while pressing 4 , dark grey will be used.
For access to an additional 16 colours of the alternate/rainbow palette, refer to the
CTRL
+ A shortcut described on page E-3.
NOTE:

• Quote Mode: If you were to press ” to open a string, and then try to change
CLR
colours, reverse text, move the cursor keys, or use the HOME key, instead of these
actions instantly occurring, funny PETSCII symbols will appear instead. This is due
to a BASIC facility called quote mode, which allows you to encode such actions
into a string so that they can be executed at a later time (for example, via a

3-8
PRINT statement within your programs). To end quote mode, simply type another
” to mark the end of your string.
• Insert Mode: A similar facility is called insert mode, where for the number of
SHIFT INST
times you press + DEL to insert a few spaces, the same number of key-
presses that follow it will abide by the same principles of quote mode.
ESC
• You can forcefully exit either of these modes by pressing , O .
You can create fun pictures just by using these colours and letters. Here’s an example
of what a 4th year student drew:

What will you draw?


Functions
CTRL
Functions using are called Control Codes. Functions using ` are called
SHIFT
Mega Codes. There are also functions that are called by using , which are
called Shifted Codes.
ESC
Lastly, enables the use of Escape Sequences.
You can read about all of these functions in detail on page E-3.

3-9
ESC Sequences
Escape sequences are performed a little differently than a Control function or a Shift
function. Instead of holding the modifier key down, an Escape sequence is performed
ESC
by pressing and releasing it, followed by pressing the desired key.
For example: to switch between 80 column mode and 40 column mode, press and
ESC
release , then press X .
CTRL
There are more text modes available. You can create flashing text by holding
down and pressing O . Any characters you type in will flash. Turn flash mode off by
ESC
pressing , then O .

EDITOR FUNCTIONALITY
The MEGA65 screen editor supports several ways to quickly move the cursor around
the screen to help you to be more productive.
CLR CTRL
For example, press HOME to go to the home position on the screen. Hold down
and press W several times. This is the Word Advance function, which jumps your
cursor to the next word, or printable character.
CLR
You can set custom tab positions on the screen for your convenience. Press HOME and
then → to move the cursor to the fourth column. Hold down
CTRL
and press X
CTRL
to set a tab. Move another 16 positions to the right, and press and X again
to set a second tab.
CLR CTRL
Press HOME to go back to the home position. Hold down and press I . This
CTRL
is the Forward Tab function. Your cursor will tab to the fourth position. Press
and I again. Your cursor will move to position 8. By default, every 8th position is
already set as a tabbed position. So the 4th and 20th positions have been added to
CTRL
the existing tab positions. You can continue to press and I to advance to the
16th and 20th positions.

Creating a Window
You can set a window on the MEGA65 working screen. Move your cursor to the be-
ESC
ginning of the ”BASIC 65” text. Press , then press T . Move the cursor 10 lines
down and 15 to the right.

3-10
ESC
Press , then B . Anything you type will be contained within this window.
For example, if you were to type LIST to list out a program, the listing will be confined
to the window region you have specified:

CLR
To escape from the window back to the full screen, press HOME twice.

Additional ASCII characters


You may have noticed a few ASCII characters on the MEGA65 keyboard that aren’t
traditionally a part of the PETSCII character set. In order to make use of these from
within BASIC:
• Type either FONT A or FONT B.
SHIFT
• Press ` + to switch to lowercase.
You will now be able to type those additional ASCII characters via the keyboard. To
revert back to the original PETSCII character set, type FONT C.

Uppercase and lowercase


SHIFT
` + switches between uppercase and lowercase text for the entire display.
This works even during program execution, so you can adjust it if a program is in the
wrong mode.

3-11
THE FREEZER MENU
The MEGA65 spends most of its time behaving as a Commodore 65 computer would,
either running a program or awaiting instructions in the BASIC environment. Your
MEGA65 has additional features that were not part of the original C65 design. You
can access many of these features from the Freezer menu.
RESTORE
To open the Freezer menu, hold the key for one second, then release it. The
MEGA65 will pause whatever it is doing, flicker the border colour, then open the
Freezer menu. Whatever program was running remains in memory and can be re-
F3
sumed by pressing the key. You can also abandon the running program and
F5
reset the MEGA65 by pressing .

One feature to remember when playing games is the “(J)OY SWAP.” This causes the
two joystick ports to trade numbers. If you have a joystick in port 2 and you start a
game that expects a joystick in port 1, instead of disconnecting and reconnecting the
joystick, open the Freezer menu, press J to swap the port numbers, then resume
your game.
This is called the “Freezer” menu because the state of the MEGA65 remains frozen
while using it. The Freezer menu can store multiple freeze states, and you can switch
between them. To save the current state, navigate to an unused freeze slot using the
cursor-right key, then press F7 . When the border stops blinking, the state is saved.
To restore a state, navigate to the freeze slot, then press F3 to resume operation.

3-12
The Freezer menu has several built-in options and features. For more information
about the MEGA65 Information Utility (“MEGAINFO”), see “Determining the Versions
of Things” on page 5-6. For more information about mounting disks and disk images,
see chapter 6 on page 6-3.

RUNNING COMMODORE 64
SOFTWARE
The MEGA65 is capable of running Commodore 64 software. There are two ways to
do this: the built-in GO64 mode, and the C64 for MEGA65 FPGA core.

GO64 Mode
The original Commodore 65 was designed to be capable of running some Commodore
64 software. The MEGA65 supports this feature, known as “GO64 mode.”
NOTE: Due to how Commodore designed this feature, not all C64 software is compat-
ible with this mode. Unlike the similar feature of the Commodore 128, the Commodore
65 uses a different CPU, and minor differences are known to cause compatibility issues
with some software titles.
There are three ways to switch the MEGA65 into GO64 mode:

• Switch off the computer, hold the ` and switch it back on.
• From the MEGA65 READY prompt, enter this command: GO64 Enter YES when
prompted.
• Switch off the computer, connect a Commodore 64 cartridge to the expansion
port, then switch the computer on.

3-13
GO64 mode is actually just a temporary re-configuration of the MEGA65. All of the
MEGA65’s features are still present, including the Freezer menu for mounting D81 disk
images.
Much Commodore 64 software can be found on the Internet in the form of D64 disk
images. The MEGA65 only supports D81 disk images via the SD card and Freezer
menu. You can use a peripheral such as the SD2IEC with the MEGA65’s IEC port to
use D64 disk images. Be sure to obtain an SD2IEC with an independent power supply,
and not one that depends on a Commodore 64 tape connector.2

The “C64 for MEGA65” FPGA Core


The C64 for MEGA65 FPGA core by MJoergen and sy2002 re-creates the original
Commodore 64 computer on MEGA65 hardware with a high degree of accuracy.
It does so by completely replacing the MEGA65 core with one that implements the
Commodore 64 chipset, including its CPU. MEGA65 features such as the Freezer menu
are not available when running the C64 core. Instead, the core provides its own menu
HELP
for mounting D64 disk images and other features. Press the key with the core
running to access this menu.
For information about installing FPGA cores, see chapter 5 on page 5-5. To download
the C64 for MEGA65 core and read important installation instructions, see: https:
//github.com/MJoergen/C64MEGA65

2 For more information on SD2IEC devices, see: https://www.c64-wiki.com/wiki/SD2IEC

3-14
CHAPTER 4
Configuring Your MEGA65
• Configuring Your MEGA65
• The Configuration Utility
• Introducing SD Cards
• Preparing a New SD Card
4-2
CONFIGURING YOUR MEGA65
This chapter describes how to configure your MEGA65.
Configuration data is stored on the SD card, so this chapter also describes how to
prepare a new SD card. Your MEGA65 comes with an SD card pre-installed. If you
configure your MEGA65 using the pre-installed SD card then later install a new SD or
microSD card, you will need to set your configuration settings again.
This chapter also introduces the MEGA65 Filehost website, which you can use to down-
load games, apps, tools, and system updates for your computer.

THE CONFIGURATION UTILITY


You can configure your MEGA65 using the Configuration Utility. This includes the set-
tings shown when you switched on the machine for the first time, and many others.
ALT
To access the Configuration Utility, switch off the MEGA65, hold the key and
switch it back on. The Utility menu appears with several options. Press 1 to start
the Configuration Utility.

The Configuration Utility includes several pages of settings, which you can navigate
using the keyboard or a mouse connected to port 1. Use ← and → to navi-
gate between pages, and ↑ and ↓ to select items on the page. Press
RETURN
or
SPACE to toggle a setting or change a value.

4-3
Input
The Input page configures the mouse settings for the two peripheral ports.

The MEGA65 supports the Commodore 1351 mouse, the Commodore Amiga mouse,
or modern equivalents such as a USB mouse connected with a mouSTer adapter. The
port must be set to the correct mouse type, where normal refers to the 1351 mouse.
If an Amiga mouse is connected while the port is in the normal mode, it may interfere
with the behavior of the keyboard.
The 1351 De-jitter setting adjusts the sensitivity in Commodore 1351 mouse mode to
avoid jitter in the mouse pointer. It is recommended to leave this set to on when using
a 1351 mouse in normal mode.

Chipset
The Chipset page configures several features, including the Real-Time Clock.

4-4
To set the Real-Time Clock, select the time or date field, type the complete value, then
RETURN RETURN
press . The clock setting takes effect as soon as you press , and does not
RETURN
take effect unless you press . Note that all other settings are not saved until the
end. Only the RTC is updated immediately.
The DMAGIC revision field controls the behavior of the DMA controller. In most cases,
you want the newer F018B setting. The F018 setting is for backwards compatibility
when running the C65 versions of the ROM, and is not always required.
The F011 disk controller field determines whether the MEGA65 looks for a boot disk
on the SD card or in the physical 3.5” floppy drive when the computer is switched on.
When set to SDCARD disk image, the MEGA65 uses the D81 virtual disk image named
in the default disk image field as the boot disk. When you first get your MEGA65,
this is set to the Intro Disk, named MEGA65.D81. You can change this to a different disk.
To disable auto-mounting, change the disk name to a filename that does not exist, or
rename the MEGA65.D81 file on the SD card. (Leaving the setting empty will default to
MEGA65.D81.)
If F011 disk controller is set to 3.5” floppy drive, the boot process will pause just
before the READY. prompt to check if a boot disk is inserted in the drive. If you do not
use a physical boot disk, you may wish to leave this set to SDCARD disk image for a
faster boot process.
Long FN support refers to long filename support in the MEGA65 SD card file browser
features. Leave this enabled unless there is an issue with reading files with filenames
longer than 11 characters.

4-5
Video
The Video page configures video settings. These are the same settings from the on-
boarding configuration, including the PAL or NTSC video mode, Digital Video sound,
and CRT emulation.

Video mode selects between the PAL compatibility mode and the NTSC compatibility
mode. You can also change this while running programs using the Freezer menu.
The Digital Video setting enables or disables the combined video and audio signal
over the Digital Video port. If your Digital Video display has built-in speakers, enable
this setting (Enhanced (with audio)) to use them. Some DVI displays without built-in
speakers require that this is disabled.
CRT emulation is an optional setting that makes the picture look more like that of a
vintage Cathode Ray Tube display when using a modern flat-panel display.

Audio
The Audio page configures the MEGA65 sound system. In most cases, you can leave
these at their default settings.

4-6
Audio output can be configured to use full stereo, or to send a monoaural signal to
both speakers. When in stereo mode, various audio devices in the MEGA65 can be
panned to the left or right using the audio mixer in the Freezer menu. The default
settings pan the four SID chips slightly to the left and right.
SID generation selects between the audio emulation of the two models of SID sound
chips: the original 6581 used in some Commodore 64s, and the newer 8580 used
in later Commodore 64s and 128s. Some Commodore 64 games took advantage of
flaws in the 6581 that were fixed in the 8580, and so sound better with the older
generation.
Swap stereo channels switches the stereo mix to use the opposite speakers.
Audio amplifier controls the built-in amplifier on the 3.5mm audio jack. Set this to
on when using headphones or another device that expects an amplified signal. Set
this to off for a line-level signal.

Network
The Network page gives you the opportunity to adjust the MAC address of the Ethernet
port. The MEGA65 does not have a hardware-assigned MAC address. Instead, it uses
the value entered here.
If the MAC address is set to all zeros, press the R key to generate a random address.
Networking features will not function with a MAC address set to all zeros.

4-7
Done
The Done page lets you exit the Configuration Utility. If you have made changes that
you want to keep, select Save as defaults and exit. You can also abandon changes,
restore the factory default settings, or completely restart to the on-boarding screen.

When you exit the Configuration Utility, you will be prompted to “power-cycle” the
computer. Switch the computer off, then switch it on again.

4-8
INTRODUCING SD CARDS
Your MEGA65 is equipped with two SD card slots: a full-size SD card slot inside the
case accessible from the bottom of the computer, and a microSD card slot accessible
from the rear of the computer. The MEGA65 uses the SD card for storing configura-
tion settings, loading the operating system, updating the firmware, and storing your
software and data as virtual disk images.
The MEGA65 includes a full-size SD card installed in the internal SD card slot, pre-
populated with the operating system files and bundled software.1 You can connect
your MEGA65 and start using it immediately without setting up a new SD card. You
can leave this SD card in place and pretend that it isn’t there, as if your MEGA65 is a
computer from the 1990s, with a hidden ability to store non-volatile data.
The MEGA65 only uses one of the two SD card slots at one time. If there is a microSD
card in the rear slot, the internal SD card is ignored. Which slot you use depends on
how you expect to use the computer. As you get more familiar with your MEGA65, you
may want to move the SD card between the MEGA65 and your PC to copy files and
perform system updates. This is more convenient with the external microSD card slot.
Alternatively, you can connect your MEGA65 to your PC or local network with an Ether-
net cable, and use a tool to transfer files between the two computers. The file transfer
feature accesses files on the SD card, and uses whichever card slot is active. For more
on transferring files, see chapter 7 on page 7-3.

PREPARING A NEW SD CARD


You can use the microSD memory card slot on the rear of the MEGA65 as persistent
storage for the computer’s configuration and system files. Having a prepared card in
this slot overrides the SD card installed inside the computer. Having a microSD card
installed is convenient if you wish to move it between your MEGA65 and your PC.
The following instructions apply to memory cards in either the external microSD card
slot or the internal full-size SD card slot.
The MEGA65 supports SD cards of type SDHC, with sizes between 4 gigabytes and
32 gigabytes. Older cards smaller than 4GB and newer SDXC cards larger than 32GB
are not expected to work.
An SD card must be prepared by the MEGA65 before use, using the SD Card Utility.
The utility creates two partitions: a hidden partition for configuration and freeze state
data, and a FAT32-compatible partition for disk images and system files. You can
access the FAT32 partition by connecting the SD card to your PC.2
1 You can recreate the original SD card’s contents using files that you can download from the Internet.

Nevertheless, you may wish to make a backup of the SD card contents onto your PC.
2 If you wish to make a backup of the complete SD card including the hidden partition, you must use a

disk utility that copies entire partitions, not just the files on the FAT32 partition.

4-9
An SD card formatted by another computer will not work with the MEGA65, even if it
only erases the FAT32 partition. You must use the MEGA65 SD Card Utility to format
the card.

Inserting the SD Card


Formatting an SD card erases its contents, and this operation cannot be undone. We
recommend that you do not erase the internal SD card that came with the computer.
The SD Card Utility will prompt you to select which of the cards currently inserted in
the computer to format. As a precaution, you may wish to remove the internal SD
card before opening the SD Card Utility. You can reinstall it later, or leave it out of
the machine until you need it. This is also a good opportunity to copy the bundled
software files (with filenames that end in .D81) off of the internal SD card to your PC,
so they can be copied back to the new SD card later.
The utility menu is accessible even if no valid SD card is present. You can bootstrap a
new system using just a compatible SD card and the SD Card Utility.
Insert the SD card that you wish to prepare before proceeding.

The SD Card Utility


You access the SD Card Utility from the Utility menu. Switch off the MEGA65, hold the
ALT
key and switch it on again. From the menu, select option 2 to start the SD
Card Utility (SDCARD FDISK+FORMAT UTILITY).

The SD Card Utility opens and looks for SD cards installed in the slots. If you haven’t
inserted the SD card that you want to prepare yet, do so now, then press R to
re-scan.

4-10
Select the card that you want to prepare: 0 for the internal SD card, 1 for
the external microSD card. If you have two cards installed, be careful to choose the
correct card slot.
The SD Card Utility prompts for confirmation to erase the SD card. As one last pre-
caution, you must type the phrase DELETE EVERYTHING in all capital letters, then press
RETURN
, to proceed. (If you wish to abort this process, it is safe to switch off the MEGA65
at this time.)

The utility erases the SD card and sets up the partitions. When it is finished, it prompts
to install the system files. The system files (with filenames ending in .M65 and .ROM)
are embedded in the core, and are copied to the FAT32 partition for use. If you have
installed an updated MEGA65 core in slot 1, select it, otherwise select the factory-

4-11
installed MEGA65 core in slot 0. (If you just received your MEGA65, slot 0 is the only
option.)

When prompted, reboot the machine.3

Obtaining the Bundled Software


The system files copied to the freshly formatted SD card do not include the bundled
software that was included with the original SD card in the internal card slot. You can
use your PC to copy these files off of the original SD card, then copy them back onto
the new SD card.
The MEGA65 Filehost website hosts all manner of files you can download for your
MEGA65. This includes the latest versions of the platform components, alternate
cores, and hundreds of games, demos, and applications produced by the MEGA65
community. This also includes the bundled software from the original SD card included
with the computer.
If you no longer have the bundled software files, you can obtain them from the
MEGA65 Filehost website. Visit the following URL:
https://files.mega65.org/?id=all-intros-public

3 If you select a core that does not have MEGA65.ROM as one of the embedded files, the utility will prompt

you to move the SD card to your PC to copy this file onto it. This only happens when using a MEGA65 core
from somewhere other than an official MEGA65 release package. For more information about cores and
obtaining MEGA65.ROM, see chapter 5 on page 5-5.

4-12
CHAPTER 5
Upgrading the MEGA65
• How a MEGA65 Can Be Upgraded
• Determining the Versions of Things
• Obtaining the Latest Files
• The Core Selection Menu
• Upgrading the MEGA65 Core, ROM,
and System Files

• Installing Alternate Cores and ROMs


• Setting Core Flags
• Erasing a Core Slot
• Upgrading the Factory Core in Slot 0
• Understanding The Core Booting Process

5-2
5-3
5-4
HOW A MEGA65 CAN BE UPGRADED
The MEGA65 platform consists of three major components:
1. The MEGA65 core, a description of the chipset to run on the FPGA
2. The ROM, code that defines the Commodore-style operating system (KERNAL)
and BASIC
3. System software for features such as the Freezer menu
You can upgrade these components as new releases are published. You can also
replace one or more of these components individually. In the case of the core and
ROM, you can even have multiple versions installed simultaneously and switch between
them. For example, instead of the latest MEGA65 ROM, you can switch to the original
Commodore 65 prototype ROM. Or, you could switch to another core that causes your
MEGA65 hardware to behave like a different computer entirely, such as a Commodore
64 or a ZX Spectrum.
The ROM and system software are files that reside on the SD card, and upgrading
them is as simple as replacing the files. To upgrade the core, you use a process to
install a core file into the MEGA65’s core flash memory. This chapter describes this
process.

What is a Core?
The MEGA65 hardware architecture is based on a versatile chip called a “Field Pro-
grammable Gate Array,” or FPGA. This is a special kind of computer chip that can be
programmed to impersonate other chips. It does this by configuring a giant array of
logic gates to reproduce circuits. FPGAs are not an emulation, but an electronic re-
creation of other chips. FPGA code is sometimes referred to as firmware, a term you
may recognize from modern computers and other devices.
Your MEGA65 was programmed at the factory to re-create a chipset based on the
original Commodore 65, designed by the MEGA65 team. You can re-program the
MEGA65 FPGA to upgrade to new versions of the MEGA65 chipset, or to replace the
chipset with that of an entirely different computer!
Each possible chipset is known as a core. The MEGA65 can store up to eight cores,
and you can switch between these cores by accessing a menu when you switch on the
computer. You can also use this menu to load a new core from a file on the SD card,
a process known as flashing.
Members of the MEGA65 community have made several useful and fun alternate cores
for the FPGA hardware. C64 for MEGA65 by MJoergen and sy2002 re-creates the
original Commodore 64 computer with a high degree of accuracy, perfect for run-
ning Commodore 64 games, demos, and applications. Other cores re-create the ZX
Spectrum, the Game Boy, and even the original Galaga arcade machine hardware.
The MEGA65’s FPGA is powerful enough to re-create nearly all 8-bit home comput-
ers, and likely some 16-bit computers and consoles such as the Commodore Amiga.

5-5
The MEGA65 hardware design, board layout, FPGA core, and other information are
all available for free under various open-source licenses, so anyone is free to create
other cores for the MEGA65 hardware.

DETERMINING THE VERSIONS OF


THINGS
All components of the MEGA65 platform have a version identifier. The MEGA65 can
display the version identifiers for all of its components using the MEGA65 Information
utility.
To open the MEGA65 Information utility:
1. Switch on the MEGA65, and allow it to boot to BASIC.
RESTORE
2. Open the Freezer: press and hold for one second then release it.
HELP
3. Press . The MEGA65 Information utility will open.

Take note of these version identifiers:

5-6
Label and Example Description
MEGA65 Model The revision of the hardware. You need to know
MEGA65 R6 this when downloading new core files.
Artix Version The currently running MEGA65 core. This is a
8AD00DD7 2024-01-22 string of eight letters and numbers, and also a
build date.
ROM Version The currently running ROM. For MEGA65 ROMs,
M65 V920393 this is a sequential number, with larger numbers
representing newer releases.
System files (.M65) Each of the system software files has its own
240122.21-R0.3.0-8B6C767 version identifier. Typically, you do not need
to know these: you will upgrade these along
with each core. The identifier is similar to the
core version, but does not always match the
currently running core.
F3 F3
Press to exit to the Freezer, then again to exit to BASIC.
Each core has a separate version for each hardware revision. As of the year 2024,
the production models of the MEGA65 have used two different main board revisions,
known as “R3” (more specifically “R3A”) and “R6.”1
The MEGA65 core is available for all hardware revisions. If you are installing an alter-
nate core and it is not available for your hardware revision, contact the author of the
core.

OBTAINING THE LATEST FILES


You can download the latest MEGA65 core, ROM, and system software from the
MEGA65 Filehost website. Due to distribution restrictions for the Commodore 65 ROM
code, some files require a Filehost account registered to a MEGA65 owner to access.
All owners of the MEGA65 have a license to all versions of this ROM code.2
Visit the following URL in your web browser:
https://files.mega65.org
1 The MEGA65 “DevKit” model sold in the year 2020 is revision “R3.” It is also possible to run the MEGA65

core on certain FPGA development boards, with a separate version of the core file for each.
2 There is a procedure for non-owners to get the latest MEGA65 ROM, such as to use with the Xemu

MEGA65 emulator. This involves downloading C64 Forever Free Express Edition from Cloanto, extracting
the original Commodore 65 prototype ROM file, then using a tool to apply a patch that you can download
from Filehost. The full process is described in the following article: https://mega65.org/rom-faq

5-7
To register a Filehost account with your owner code:
1. Visit the Filehost website. Click “Sign Up.” Follow the prompts to create an
account.
2. Locate your owner code. This is a code printed on a piece of paper that was in-
cluded with your MEGA65 (possibly inserted into this manual). It looks something
like this: 123-ABC-456
3. Click the user icon in the upper-right corner of the Filehost screen. In the pop-up
menu, select “Redeem Code.” Enter your owner code as prompted.

To download the latest release package:


1. Click the “Files” tab of the Filehost website.

5-8
2. In the search box on the left-hand side, type: “release” The list will update to
show only files with that word in the title.
3. Locate the entry named, “MEGA65 Core Release Package (mega65r6) incl.
ROM,” where “mega65r6” matches your hardware revision. (To confirm your
Help
hardware revision, open the Freezer menu, then press .)
4. Click the entry. Confirm that this release package is for your hardware revision,
then click “Download” to download the file.
NOTE: There is an entry for the Release Package that does not include the ROM that is
visible to everyone. To ensure you are using a compatible set of files, get the package
that says “incl. ROM.” If you don’t see an entry that says “incl. ROM,” check that you
are signed in and that you have redeemed a valid owner code.

Extract the downloaded .7z archive. You should see a file whose name ends in .cor,
and a folder of sdcard-files that includes one named MEGA65.ROM.

THE CORE SELECTION MENU


The MEGA65 decides which core to load into the FPGA when it starts up. You can
interrupt this process to select which core to load.3
NO
To open the core selection menu, switch off the computer, then hold the SCROLL key and
switch on the computer. The core selection menu appears, with the eight core slots
numbered 0 through 7.
3 Technically, the MEGA65 starts the core in slot 0 to power the core selection menu. After you have

made a selection or it chooses a default, it loads the selected core into the FPGA and continues the boot
process.

5-9
RETURN
You can select a core to boot using the cursor keys and , or you can simply press
the number key that corresponds to the slot. The boot process continues with the new
core. The MEGA65 will keep running the new core until you switch it off. (Pressing the
reset button will not reset which core is being run.)
When you switch on the computer without opening the core selection menu, the
MEGA65 looks for a default core. It first checks to see if any core is flagged as the
default core (a setting you can change). If none are flagged, then it checks to see if
there is a core in slot 1.4 If the slot is empty, it uses slot 0.
Your computer comes with the MEGA65 core in slot 0 installed at the factory. It is
recommended that you do not upgrade the factory-installed core unless advised to
do so by the MEGA65 team. Instead, install new versions of the MEGA65 core in slot
1.

UPGRADING THE MEGA65 CORE,


ROM, AND SYSTEM FILES
You can upgrade a core, or install a new core, from the core selection menu. This
process reads the .cor file from the SD card.
To upgrade the MEGA65 core, ROM, and system files:
1. Remove the SD card (or microSD card) from the MEGA65, and connect it to your
PC using an SD card reader.5
4 If DIP switch #4 is in the “on” position, the MEGA65 checks slot 2 instead of slot 1. DIP switches are

located inside the case, on the main board.


5 As an alternative to moving the SD card to your PC, you can transfer files using an Ethernet connection.

See chapter 7 on page 7-3.

5-10
2. Copy the .cor file that you extracted from the .7z archive to the SD card.
3. On your PC, open the sdcard-files folder from the .7z archive, then copy those
files to the SD card, replacing the existing files. Put them in the root of the SD
card’s file system, not a sub-folder.
4. Eject the SD card from your PC’s operating system, then move it back to the
MEGA65.
NO
5. Open the core selection menu: switch off the MEGA65, then hold SCROLL while
switching it back on.
CTRL
6. Hold then press the number of the slot you want to upgrade. The slot
editor opens.
F3
7. Press to load a core file. The file selector opens. Use the cursor keys to
RETURN
select the .cor file, then press .
F8
8. Press to flash the core slot. Allow the flashing process to complete. This
takes several minutes.
9. When the flashing process is complete, press any key to return to the core selec-
tion menu.
The slot editor looks like this:

When you load a core file, it prompts you to select the .cor file on a screen that looks
similar to this:

5-11
Once you have selected the core, the slot editor shows the change it intends to make
to the slot. After you start the flashing process, the display shows the progress.
NOTE: Do not switch off your computer or disconnect power until after this step is
complete.

When the message ”Core was successfully flashed” is displayed, the process is com-
plete.

5-12
It is now safe to switch off your computer. Press any key to return to the core selection
menu, or switch the computer off then on again to start the default core.

INSTALLING ALTERNATE CORES AND


ROMS
Installing an alternate core, such as the C64 core, uses the same steps for flashing
the core to a slot.
It is recommended to use slots 2 through 7 for alternate cores, and reserve slot 1 for
the latest MEGA65 core. Of course, there is nothing stopping you from installing an
alternate core in slot 1, so that the MEGA65 behaves as a different type of com-
puter when you switch it on. You can always choose the MEGA65 core from the core
selection menu.
You can keep more than one version of the MEGA65 ROM on the SD card. When
booting the MEGA65 core, you can select one of these ROMs by holding down a
number key during boot.
To install alternate ROMs, copy them to the root of the SD card with a filename such
as MEGA65x.ROM, where x is a number between 0 and 7. To boot the alternate ROM,
hold the corresponding number key down while the MEGA65 core starts. If you do not
hold down a number, it boots to MEGA65.ROM by default.
There are several reasons you might want to keep alternate ROMs on your SD card:
• You are helping to test a new beta release of the ROM, and do not wish to make
the beta version your default ROM.

5-13
• You want to try the original Commodore 65 prototype ROM. The MEGA65 core
maintains backwards compatibility with the C65 ROM that was in progress by
Commodore before they cancelled the project. It is buggy and incomplete, but
is still an interesting historical artifact.
• You want to try an alternate ROM developed by the MEGA65 community. One
such ROM is the MEGA65 OpenROM, a project to create an all-new ROM re-
leased under an Open Source license without any original Commodore material.
Several alternate ROMs came with your MEGA65 SD card, installed at the factory. Try
rebooting your computer while holding down a number key to see what happens!

SETTING CORE FLAGS


There are several options (”flags”) that you can select for a core in the core editor.
To change flags for a core, edit the core slot. Press the number key that corresponds
to the flag to toggle its value. Save the flags to the slot by flashing the result: press
F8
. You can either set flags before flashing new core data, or you can flash just the
new flag settings without replacing the core data.
To set a core to be the default core used when the MEGA65 is switched on without
NO
SCROLL held down, set the ”Default core” flag. If no core is set as the default core, then

slot 1 is used as the default (or slot 2 if DIP switch #4 is set to on).
The ”cartridge” flags determine which core is selected when a cartridge is present in
the expansion slot. This allows you to choose a different default core based on the
type of the cartridge. For example, you can set the MEGA65 core to handle MEGA65
cartridges, and a different core to handle C64 cartridges. By default, the MEGA65
core will handle C64 cartridges using ”GO64” mode. You may prefer to change this
to use the C64 core that you install separately.

5-14
ERASING A CORE SLOT
The flashing process replaces whatever is in a core slot with the new core. If a core is
already installed in the slot, flashing overwrites the existing core.
F4
If you wish to delete a core and leave the slot empty, edit the slot, press to set
F8
the replacement to ”Erase slot,” then press to flash the slot with empty data.

UPGRADING THE FACTORY CORE IN


SLOT 0
It is possible to upgrade the factory-installed MEGA65 core in slot 0. You only need to
do this in rare cases, such as if a newer version of the MEGA65 core includes changes
or bug fixes for the start-up process. It is recommended that you do not upgrade slot
0 unless the announcement for the release suggests that you do so. Most MEGA65
core upgrades are fully functional in slot 1, without needing to upgrade slot 0.
It is important that at least one core slot contains a functioning MEGA65 core. If
something goes wrong during the flashing process, this may result in a non-functioning
core in that slot. To help prevent accidents, the procedure for flashing slot 0 is slightly
different from that of the other slots, and only an official MEGA65 core can be flashed
to slot 0.
Please read these instructions carefully before starting the procedure. To upgrade the
core in slot 0:

5-15
1. Install the latest MEGA65 core in slot 1, using the procedure described earlier.
The core must be in the default non-zero slot to recover from any problems when
updating slot 0.
2. Launch core slot 1 to confirm that it works.
NO
3. Return to the core selection menu: switch off the MEGA65, then hold SCROLL

while switching it back on.

4. Hold the ` and press the comma key to open the editor for slot 0.
5. Read the information screen, then type the word CONFIRM using uppercase letters
RETURN
and press .
6. Repeat the remainder of the flashing procedure to select the core file and flash
the slot.
NOTE: If you have a revision R3A MEGA65 and have not previously upgraded slot 0,
the ` and the comma key will not start the procedure: you have an older slot 0
core that does not have this feature. You can work around this by restarting the core
NO
selection menu with slot 1. From the core selection menu, prepare to hold down SCROLL ,
NO
press the 1 key to boot into the core then immediately press and hold SCROLL . The
core selection menu re-opens using slot 1. Press ` and the comma key to complete
the slot 0 upgrade.
If something goes wrong during the slot 0 flashing process, your MEGA65 may not start
correctly. Before doing anything else, switch on your MEGA65, and wait a minute or
so. After a while, it should notice that there is no valid core in slot 0, then proceed to
NO
start the core in slot 1. You can hold SCROLL during this to open slot 1’s core selection
menu and restart the flashing process.
If the MEGA65 cannot boot any core after several minutes, it may be stuck. You may
be able to recover using a device known as a “JTAG interface” that connects your PC
to the MEGA65 main board. This allows you to inject a bitstream directly into the
FPGA. The part is inexpensive but not always available. Contact the MEGA65 team
on the Discord (https://mega65.org/chat) for assistance.
Core slot 0 cannot be assigned flags, such as to be the default core or to be asso-
ciated with cartridge types. Slot 0 will be used for these purposes if no other core
is installed. It is recommended that you keep the latest MEGA65 core in slot 1, in
addition to flashing slot 0.

5-16
UNDERSTANDING THE CORE BOOTING
PROCESS
This section summarises how the MEGA65 selects which core to start with
when it is switched on. The process is shown in the following figure:

The booting process is governed by two facilities:


• The Hypervisor (also known as HYPPO), which operates at a level above the KER-
NAL. One of its responsibilities is to manage aspects of the boot process. For
more details on the Hypervisor, refer to Chapter/Appendix J on page J-22. In the
diagram, activities performed by the Hypervisor have been highlighted in green.

5-17
• The Core Selection Menu program (also known as “MegaFlash”), which provides
a list of available core slots to choose from. In the diagram, activities performed
by MegaFlash have been highlighted in blue.
When the MEGA65 is switched on, it does the following:
• Loads the bitstream stored in slot 0 of flash memory. If that is the MEGA65
Factory Core, the MEGA65 HYPPO Hypervisor starts.
• If it is the first boot since power-on (which implies that you are running from slot
0), HYPPO starts the Flash Menu program (aka MegaFlash) – but note that the
Flash Menu in this mode may not show anything on the screen to indicate that it
is running!
NO
• The Flash Menu then checks if SCROLL is being held down.
• If it is, the Flash Menu program shows its display, allowing you to select or re-flash
a core.
NO
• If SCROLL is not being held down, the Flash Menu program checks if Flash Slot 1
contains a valid core.
• If it does, then the Flash Menu program attempts to load that core.
• If it succeeds, then the system reconfigures itself for that core, after which the
behaviour of the system is according to that core.
• If it fails, the keyboard will go into “ambulance mode”, showing flashing blue
lights to indicate that some first-aid is required. Note that in ambulance mode
the reset button has no effect: You must switch the MEGA65 off and on again.
If you have selected a different core in the Core Selection Menu, the process is similar,
except that the ambulance lights will appear for only a limited time, as the FPGA will
automatically search through the flash memory until it finds a valid core. If it gets to
the end of the flash memory, it will start the MEGA65 Factory Core from slot 0 again.

5-18
CHAPTER 6
Using Disks and Disk Images
• Disk Drives
• Using Virtual Disk Images
• Using the Internal 3.5” Floppy Disk Drive
• Using External IEC Disk Drives
• Bootable Disks
• Accessing the SD Card from BASIC
• Common Disk Operations
6-2
DISK DRIVES
The MEGA65 has a built-in 3.5” floppy disk drive, and supports Commodore-style ex-
ternal disk drives via the IEC serial port on the back of the computer. The IEC port also
supports other external IEC storage devices, such as the SD2IEC. Some IEC storage
devices can be connected in a chain and used at the same time.
The MEGA65 also includes a “virtual” disk drive that can mount D81 disk image files
stored on the SD card. Most MEGA65 software that you download from the Internet
is in the form of a D81 disk image. You can create a new D81 disk image directly
from the MEGA65, and start saving your BASIC programs to the SD card without any
additional hardware. You can also copy files between physical floppy disks and D81
disk images.
The Intro Disk Menu that you saw when you first switched on the computer is a pro-
gram on a D81 disk image, a file named MEGA65.D81 on the SD card. The MEGA65 is
initially configured to boot this disk image automatically. You can change this in the
Configuration Utility. (Refer back to chapter 4 on page 4-3.)
You can manage disk drives and virtual disk images from the Freezer menu. Some of
these operations can be performed with BASIC commands such as MOUNT.

Unit Numbers and Drive Numbers


Each disk drive (physical or virtual) is accessed via a unit number. With vintage Com-
modore computers, the unit number refers to an IEC device connected to the com-
puter. Commodore reserved unit numbers in the range 0 – 31 for devices of various
purposes, with 8 – 11 reserved for disk drives. If you’ve ever used a Commodore 64
and typed LOAD "*",8,1, the “8” refers to the disk drive connected as unit 8. BASIC 65
disk commands use unit 8 by default, and accept a U parameter to change it, such
as: DLOAD "MYPROGRAM",U9
With the MEGA65, you can assign a unit number to the virtual disk drive with a D81
disk image mounted, or to the internal 3.5” floppy drive. You must mount a disk image
or the internal 3.5” floppy drive to a unit number before it can be used. Any message
sent to a unit number assigned to a virtual disk or the internal floppy drive is handled
by the MEGA65. All other messages are sent to the IEC serial port.
Disk commands also accept an optional parameter to specify a drive number. This is
only needed when connecting a vintage dual floppy drive via the IEC port, such as
the Commodore 4040, 8050, or 8250. Every disk drive assigns drive number 0 to
the first drive. Dual-drive units assign a drive number of 1 to the second drive. Dual
disk drives are usually equipped with an IEEE-488 interface, and need an IEEE-488
to IEC converter to be used on the MEGA65. BASIC 65 disk commands use drive 0 by
default, and accept a D parameter to change it.

6-3
USING VIRTUAL DISK IMAGES
The MEGA65 provides two “managed drives” that supplement drives connected to the
IEC port. The first managed drive can be assigned either a D81 disk image file on the
SD card, or it can be assigned to the built-in 3.5” floppy drive. The second managed
drive can also be assigned a D81 disk image file, for up to two virtual disks mounted
at the same time.1
The first managed drive can be set to unit 8 or 10, and the second managed drive can
be set to unit 9 or 11.

Where to Get Disk Image Files


The MEGA65 Filehost website hosts a library of MEGA65 software produced by the
community. You can browse or search for software, download a title, then copy the
D81 disk image to the SD card using either your PC or the Ethernet file transfer tool.
https://files.mega65.org/

Mounting Disk Images with the Freezer


RESTORE
Open the Freezer menu: hold for one second, then release it. Notice the current
drive mounting settings in the lower-right of the screen.

1 Commodore originally intended to release a new external 3.5” floppy drive called the “1565” to go
with the Commodore 65, connecting to a dedicated non-IEC port. The MEGA65 project has ambitions to
someday produce such a drive, and if it does, this would be assigned to the second managed drive.

6-4
To mount a disk image on unit 8 or 10, select the first managed drive by pressing 0 .
To mount a disk image on unit 9 or 11, select the second managed drive by pressing
1 . This opens the SD card file browser.

RETURN
Use the cursor keys to select a D81 disk image, then press . The Freezer screen
shows the selected disk image is now associated with the managed drive.

From the main Freezer screen, press 8 or 9 to toggle the unit number assigned
to the first or second managed drive, respectively.

Mounting Disk Images from BASIC


The BASIC MOUNT command can mount a D81 disk image from the SD card without
having to open the Freezer. This command can be entered at the READY prompt, or be
used as part of a program.
To mount a disk image on unit 8, enter MOUNT with the full filename in double-quotes,
including the .D81 suffix:

MOUNT " MEGA65 . D81 "

To mount a disk image to unit 9, provide the U argument:

MOUNT " MEGA65 . D81 " , U9

Creating a New Disk Image


You can create a new empty disk image from within the MEGA65 Freezer.
1. Open the Freezer.

6-5
2. Press 0 to select the first managed drive.
3. At the top of the file list, select: - NEW D81 DD IMAGE -
4. When prompted, enter a name for the disk. (Omit the .D81 suffix; this will be
added automatically.)
The new disk image is created on the SD card and mounted to the first managed drive.
It is formatted and ready to use.

Managing SD Card Files in Sub-directories


Once you have spent some time on Filehost downloading games and applications, you
will eventually have a large collection of D81 disk images on your SD card. You may
wish to organize these files into sub-directories (folders). You can create these folders
with the SD card connected to your PC, or with the Ethernet file transfer tool.
The Freezer supports sub-directories in its file browser. Each sub-directory name be-
gins with a slash (/). Select a folder to list its files. To return to the previous folder,
select: /..
You can also create new disk images in sub-directories by navigating to the sub-
directory before selecting - NEW D81 DD IMAGE -.
The MEGA65 maintains a “current working directory” that is used as the base directory
for BASIC commands such as MOUNT. To change the current working directory from
BASIC, use the CHDIR command with the U12 argument:

CHDIR " DEMOS " , U12

MOUNT " XANADU . D81 "

NOTE: Support for sub-directories on the SD card is a work in progress. If a disk image
in a sub-directory is mounted, it will become un-mounted by any action that changes
the current working directory. Some features that use files may not support files in
sub-directories. We hope to improve this in a future update.

USING THE INTERNAL 3.5” FLOPPY


DISK DRIVE
The MEGA65 has a built-in 3.5” floppy disk drive, similar to what was intended for the
Commodore 65. You can use physical floppy disks to store your programs and data.
Some MEGA65 software can be purchased on floppy disk.
The internal 3.5” drive must be mounted before it can be used. It can be mounted to
unit 8 or unit 10, in the first managed drive.

6-6
Mounting the 3.5” Drive with the Freezer
RESTORE
Open the Freezer menu: hold for one second, then release it. Notice the current
drive mounting settings in the lower-right of the screen.

Press 0 , then use the cursor down key to: - INTERNAL 3.5" - Press
RETURN
to select it. The
Freezer menu screen shows that the internal drive is mounted to the first managed disk
device.
The UNIT # for the first device can be either 8 or 10. Press 8 to toggle between these
options. BASIC disk commands default to unit 8, so it is typical to use unit 8 unless you
are working with multiple disks at the same time.
The internal 3.5” drive can only be mounted in the first managed drive with unit num-
bers 8 or 10. It cannot be mounted in the second managed drive (unit numbers 9 or
11).

Mounting the 3.5” Drive from BASIC


You can mount the internal 3.5” disk drive to unit 8 using the BASIC MOUNT command.
This command works from either the READY prompt or from a program. To mount the
internal drive to unit 8, enter the command without arguments:

MOUNT

The MOUNT command can only mount the internal drive to unit 8. You can only mount
it to unit 10 from the Freezer menu.

DD and HD disks
The MEGA65 disk controller expects a Double Density (DD) floppy disk in the internal
3.5” floppy disk drive.2 Floppy disks are no longer manufactured, and the DD variety
can be difficult to find.
You can use a High Density (HD) floppy disk with the drive, with one important modi-
fication: you must cover both sides of the hole in the upper-left corner (as seen from
the front) of the disk with a small piece of tape. This convinces the drive that the
disk is DD, and switches it to a mode compatible with the MEGA65 disk controller. A
double-density disk does not have a hole in this location.
2 It may be possible to support full-capacity HD disks in a future firmware update. The drive hardware is

capable of reading HD disks.

6-7
HD HOLE

TAPE

NOTE: Make sure that the tape covers both sides of the hole.

Formatting a Disk
A floppy disk must be formatted before it can be used. The MEGA65’s internal 3.5”
floppy drive emulates a Commodore 1581 drive, and can use disks formatted in such
a drive. You can also format a disk with the MEGA65.
NOTE: Formatting a disk erases its contents. Be careful to only do this when you do
not need the data on the disk!
To format a physical 3.5” floppy disk using the internal drive:
1. Open the Freezer.
2. Mount the internal 3.5” floppy drive to the first managed drive, unit 8.
3. Double-check that unit 8 says: - INTERNAL 3.5" -

4. Resume the computer: press F3 .


5. Insert the floppy disk you wish to format into the internal floppy drive.
6. Enter the BASIC FORMAT command, giving it a name ("MYDISK") and a two-
character ID (XX).

6-8
FORMAT " MYDISK " , IXX

RETURN
7. When prompted, enter YES and press .
Formatting the disk takes a minute or so. The drive will make buzzing and clicking noises
during the process. Do not switch off the computer or eject the disk until formatting
is complete.
You can confirm that the formatting was successful by issuing the DIR command. You
should see an empty directory listing with the name and ID you specified. Your disk is
now ready to use.

USING EXTERNAL IEC DISK DRIVES


The MEGA65 works with external disk drives connected to the IEC serial port.
External drives do not need to be mounted. If a unit number is not assigned to the
internal 3.5” disk drive or to a disk image, disk operations intended for that unit number
will be transmitted to the IEC serial port. It is up to the device connected to the port
to recognize its unit number. Some IEC devices have switches that let you set the unit
number. Others will only work with a specific number.
If you have an external drive that expects a specific unit number, you will need to make
sure the MEGA65 isn’t assigning that number to a disk image or the internal drive.
Open the Freezer, then press 8 or 9 to toggle the unit number assignments so
that they no longer use the needed unit number.
The drive and unit assignments are temporary, and will be reset to their defaults when
the MEGA65 is switched off. You will need to re-configure the drive assignments the
next time you switch on the computer.

BOOTABLE DISKS
With older Commodore computers, it was common for software makers to organize
the file directory on a floppy disk such that the first file in the list is the main program.
The user could then enter the command LOAD "*",8,1 to load the main program, and RUN
to run it. The asterisk is a wildcard that matches any file, so it matches the first file on
the disk, without the user having to type the name of the program.
This method is still common, and the MEGA65 has a quick way to boot such disks:
and press STOP . This executes the RUN "*" command, which is similar to the
SHIFT RUN
hold
familiar command sequence that loads and runs the first program on the disk.

6-9
With the C65, Commodore introduced a new way to boot disks. Instead of relying
on file order, a disk can have a file named AUTOBOOT.C65. If this file exists and is a
program, the BASIC BOOT command will load and run this file.

BOOT

Auto-Booting Disks
As discussed in chapter 4 on page 4-3, you can use the Configuration Utility to set
the MEGA65 to mount either a virtual disk image or the internal 3.5” disk drive auto-
matically during boot.
If the mounted disk is bootable — that is, it contains a program file named
AUTOBOOT.C65 — the MEGA65 will load and run the boot program automatically.
This is how the Intro Disk works. The Intro Disk menu is a program named AUTOBOOT.C65
on the virtual disk image MEGA65.D81, which is pre-configured to be the mounted
disk on system start-up. When you disable the Intro Disk from its menu, it renames
AUTOBOOT.C65 to MENU, such that the disk is no longer considered bootable.
Setting up a boot disk for yourself can be a handy way to configure your computer. You
can write a short BASIC program that changes the system font, adjusts the background
colour, and sets KEY macros to your taste, then save the program as AUTOBOOT.C65
on a disk that you have configured to mount on system start-up. This program will run
every time you switch on your MEGA65.

ACCESSING THE SD CARD FROM


BASIC
Several BASIC 65 commands can operate directly on the MEGA65 SD card as if it
were a disk drive. In these cases, the SD card is known as unit 12.
NOTE: Unit 12 can only be accessed directly for a few specific operations. It cannot
treat the entire SD card as if it were a CBDOS disk.
To list all of the files on the SD card, use the DIR command with the U12 argument:

DIR U12

You can use the optional P flag with this command to list the SD card files one page
at a time. Press Q to stop at the current page, or any other key to advance to the next
page.

DIR U12 , P

6-10
To load or save a PRG file directly from the SD card (that isn’t in a D81 disk image),
use the U12 argument with the DLOAD and DSAVE commands. You must include the
.PRG filename suffix in this case, which is different to using PRG files on disks or disk
images.

DLOAD " M Y P R O G R A M . PRG " , U12

As shown earlier, the MEGA65 supports sub-directories (sub-folders) on the SD card,


and maintains a current working directory for disk operations. To change the current
working directory to a subdirectory:

CHDIR " SUBDIR " , U12

To change the current working directory to the parent of the current directory:

CHDIR ".." , U12

The MOUNT command can mount a D81 disk image to a unit number. Even though
this command refers to a file on the SD card, it does not use the U12 argument. Instead,
it uses the U argument to set the unit number for the disk being mounted. The MOUNT
command uses the current working directory set by CHDIR to locate the file.

COMMON DISK OPERATIONS


The following are some examples of common disk operations you can perform at the
READY prompt. See the BASIC command reference in appendix B on page B-3 for more
information.
Most commands that accept filenames also accept a U argument that says which unit
has the file. The default unit is 8.3

DIR
To display the directory (list of files) for a disk, use the DIR command.

DIR

DIR U9

Unlike the Commodore 64 method of loading the disk directory into BASIC memory,
the DIR command does not modify BASIC memory. It is safe to use DIR with a program
in memory.
3 The default disk unit for BASIC commands is 8 when the computer first starts. You can change it with

the SET DEF command.

6-11
To make larger directories easier to view, DIR W (for “wide”) displays the directory in
columns, pausing for each page.

DLOAD and RUN


The DLOAD command loads a program from disk into memory. The RUN command runs
the program currently in memory.

DLOAD " C O O L G A M E "


RUN

You can combine these into one command by providing the filename directly to the
RUN command.
RUN " C O O L G A M E "

DSAVE
The DSAVE command saves the BASIC program currently in memory to disk.

DSAVE " MYGAME "

By default, this will not overwrite an existing file with the same name. To request that
the existing file be overwritten, insert an @ (at) symbol before the filename, inside the
double-quotes.

DSAVE " @MY GAM E "

Note that save-with-replace is only recommended when using disk images and the
3.5” floppy drive. Older Commodore drives have bugs in this feature that could result
in data loss.

BACKUP
The BACKUP command copies an entire disk from one unit to another. All existing
data on the destination disk is erased as part of this process.

BACKUP U8 TO U9

You can use BACKUP to make disk images from floppy disks, or write disk images to
floppy disks, or copy everything from one disk drive to another.

6-12
COPY
The COPY command makes a copy of a file. If the source and the destination are
different filenames on the same unit, this duplicates the file on the disk.

COPY " MYGAME " , U8 TO " MYGAME " , U9

COPY " MYGAME " TO " MYGAME - V1 "

RENAME
The RENAME command changes the name of an existing file.

RENAME " MYGAME - V29 " TO " MYGAME - FINAL "

DELETE
The DELETE command deletes a file.
DELETE " J U N K F I L E "

Shortcut Disk Commands


BASIC 65 provides several shortcuts for common disk commands for use from the READY
prompt.
Shortcut Equivalent Command
/ LOAD
↑ RUN
← SAVE
@ DISK
$ DIR
These are intended to be used with a directory listing to launch programs without
having to type filenames. For example:
RETURN
1. Display the disk’s directory listing: type $, press .
2. Use the cursor keys to move the cursor to the line with the program you want to
run.
3. Type ↑, press
RETURN
.
The selected program loads and runs. Notice that you do not have to clear extra
characters from the line. The shortcut knows to ignore everything but the filename in
double-quotes, as printed by the directory listing.

6-13
6-14
CHAPTER 7
Transferring Files
• Getting Files to the MEGA65
• Understanding Networking
• Obtaining M65Connect
• Enabling Network Listening
• Transferring Files
7-2
GETTING FILES TO THE MEGA65
While there is plenty of fun to be had writing your own programs for the MEGA65,
eventually you will want to run programs written by others. You may also want to back
up your MEGA65 programs to your PC for safe keeping.
The fastest and most reliable way to transfer files between your PC and your MEGA65
is with an Ethernet cable. You connect one end of the cable to the RJ45 jack on
the rear of the MEGA65. You can connect the other end to your local area network
(LAN) router or switch, or connect it directly to your PC. You use software on your PC
to initiate file transfers, in either direction: from the PC to the MEGA65, or from the
MEGA65 to the PC.
Alternatively, you can copy D81 virtual disk images to your MEGA65-formatted SD
card using any PC with an SD card reader, without any other special tools or software.
Your PC will recognize the data region of the SD card as a FAT32 partition. If you
use this method, be aware that some PC operating systems may have unwanted side
effects, such as fragmentation of SD card files, or extraneous files created by macOS
Finder. These effects are harmless to the data, but may require maintenance to keep
the card useful in the MEGA65. If the MEGA65 reports a fragmented file, you can use
a PC disk defragmentation tool on the data partition. Alternatively, you can copy all
files off of the SD card to the PC, re-format the SD card in the MEGA65, then copy
the files back from the PC.
It is also possible to transfer files using a JTAG or UART Serial interface connected
to the main board. This is an advanced technique and is not described in this User’s
Guide. JTAG or UART Serial hardware provides access to a debugging interface that
may be useful to some programmers. JTAG is also useful for developing FPGA cores.
For more information, see the MEGA65 Developer’s Guide.
Most people will prefer the Ethernet method. This chapter describes how to do this.

UNDERSTANDING NETWORKING
The MEGA65 can use Ethernet to connect to or accept connections from other com-
puters on a network. With appropriate software, it can connect to other computers
over the Internet.
The MEGA65 Ethernet hardware presents a Media Access Control (MAC) address to
the local network. Unlike other Ethernet hardware, the MEGA65’s MAC address is
not assigned at the factory: it is set in the Configuration Utility. (See chapter 4 on
page 4-3.)
To transfer files, you instruct the MEGA65 to make itself available for incoming con-
nections, then use the M65Connect app (or another tool, such as mega65_ftp) on your
PC to initiate a connection. Your PC’s operating system may prompt for permission to
grant the tool access to the network when you run it for the first time. The tool uses

7-3
UDP port 4510 to establish the initial connection with the MEGA65, and uses a self-
assigned IPv6 address created from the MEGA65’s MAC address for the file transfer
session. This requires that IPv6 be enabled on the PC’s network interface, which is the
default in most cases.
As an alternative to connecting the MEGA65 to your local network, if your PC has
an Ethernet jack, you can connect your MEGA65 directly to your PC with an Ethernet
cable. This forms a small local network with no access to the Internet. The proce-
dure for transferring files is the same with a direct connection as with a local network
connection.

OBTAINING M65CONNECT
M65Connect is an application for Windows, Mac, or Linux that facilitates file trans-
fers and other useful features for MEGA65 users. The application has a windowed
interface, and also includes command-line tools useful for programming.
To obtain M65Connect:
1. Visit the MEGA65 Filehost website in a browser: https://files.mega65.org
2. In the search box in the top right corner, type: “M65Connect”
3. Select the version of M65Connect for your PC operating system.
4. Click the “Download” button.
5. Use your PC to unpack the downloaded archive file.

M65Connect for Windows


The Windows version of M65Connect is in the “M65Connect” folder:
M65Connect.exe. As with most open source software, Microsoft Defender
may refuse to run the software, displaying a dialog window. If this happens, click
“More info,” then click the “Run anyway” button that appears.
The command-line tools are in a sub-folder named “M65Connect Resources,” such as:
M65Connect Resources\mega65_ftp.exe

M65Connect for macOS


The macOS version of M65Connect is a Mac application bundle: M65Connect.app.
As with most open source software, macOS does not recognize it as “signed” by the
developer, and macOS will refuse to run it. You will need to remove the “quarantine”
attribute to run the application.
In most versions of macOS, the best way to remove the quarantine attribute is with a
Terminal command:

7-4
1. Move the M65Connect app to your Applications folder.
2. Open the Terminal app, included with macOS. This can be found in the Applica-
tions folder, in a sub-folder named Utilities.
3. Enter this command: xattr -cr /Applications/M65Connect.app
You can now double-click the M65Connect app to run it.
The command-line tools are inside the application bundle directory, such as:
/Applications/M65Connect.app/Contents/mega65_ftp.osx

M65Connect for Linux


The Linux version of M65Connect is in the “M65Connect” folder: M65Connect.
Double-click it to run.
The command-line tools are in a sub-folder named “M65Connect Resources,” such as:
M65Connect Resources/mega65_ftp

ENABLING NETWORK LISTENING


By default, the MEGA65 ignores all attempts by other computers to connect to it over
the network. Software running on the MEGA65 can listen for network connections,
but the MEGA65 does not do this on its own.
To transfer files with M65Connect, you must tell the MEGA65 to listen for incoming
connection attempts from M65Connect. To enable a network listening session, press
SHIFT
+ £ . The power light blinks between yellow and green when network listening
is active.

7-5
NETWORK LISTENING
ENABLED
=
BLINK
YELLOW-TO-GREEN

SHIFT
To disable network listening, press + £ again, or reset the computer.
SHIFT
If the power light does not start blinking after pressing + £ , you may need to
set DIP switch #2 on the main board. MEGA65s manufactured in the year 2024 and
later should have this switch set at the factory. Earlier MEGA65s have this switch off
by default.
To set the DIP switch, open the case, as described in chapter 2 on page 2-3. Locate
the DIP switches on the main board, then set DIP switch #2 to the “on” position. Look for
markings on the switches to identify switch #2 and the “on” direction. (The orientation
of your DIP switches may differ from this diagram.)

7-6
JTAG

FLOPPY DRIVE
4
3
2
1
ON

DIP

It is safe to leave DIP #2 in this position for regular operation.

TRANSFERRING FILES
To transfer files, you will start a file transfer session using the M65Connect application
or the mega65_ftp command-line tool. This connects to the MEGA65 and uploads a
file transfer client for use during the session. When you end the session, the MEGA65
resets.
Starting a file transfer session resets the MEGA65. Be sure to save any programs or
data before proceeding.
NOTE: If you clear memory by resetting the computer, remember to re-enable network
SHIFT
listening: press + £ , and ensure the power light is blinking.

7-7
Transferring Files with M65Connect
M65Connect detects automatically whether the MEGA65 is listening for connec-
tions. Open M65Connect, then enable the network listening session on the MEGA65.
M65Connect reports a status of ”Connected to MEGA65 via LAN,” and several buttons
including the PRG and SD Card buttons are enabled in the M65Connect window.

If M65Connect reports a status of ”Not connected to MEGA65,” check the following:


• The MEGA65 and the PC are connected to the same network, or directly to each
other via a network cable.
• The MEGA65 is in network listening mode, with a blinking power light.
• In M65Connect, open the Settings menu, and select Connections. The ”LAN
Port” field should contain an IPv6 address. If it doesn’t, wait a few seconds, or
click the ”Autodetect LAN Port” button.
To start a file transfer session, click the SD Card button. The SD Card Manager window
opens.
NOTE: Starting a file transfer session resets the MEGA65 to load the file transfer utility.
Be sure to save any data on the MEGA65 before starting the session.

7-8
Use the pane on the left to navigate files on your PC. Use the pane on the right to
navigate files on the MEGA65 SD card. To transfer a file, select the file, then click the
arrow button. The button indicates the direction the file will transfer.
You can also use M65Connect to create D81 disk images, and copy files to and from
D81 disk images. Locate a D81 disk image on your PC or click the + D81 button to
create one, then click the ”Open” command in the file browser to open the disk image
in the left pane. Transfer files to and from the image with the arrow button. Click the
X button in the upper right to return to the file browser.
Click the Close button to end the file transfer session and close the SD Card Manager
window. This resets the MEGA65.

The mega65_ftp Command-Line Tool


The mega65_ftp command-line tool initiates a file transfer session with the MEGA65.
It can run interactively in the terminal and accept multiple file transfer commands, or
it can run non-interactively with those commands provided as arguments.
To start an interactive file transfer session, run the mega65_ftp command, providing
the -e argument to say you want to use an Ethernet connection.
NOTE: Starting a file transfer session resets the MEGA65 to load the file transfer utility.
Be sure to save any data on the MEGA65 before starting the session.
% mega65_ftp -e

7-9
The tool will upload the file transfer client, and you will see it the client running on the
MEGA65. If nothing happens, press Ctrl-C (on the PC) to abort, then double-check
that the MEGA65 is connected and that network listening is enabled.
Once connected, the file transfer command prompt looks similar to this:
MEGA65 SD-Card:/>
To end the session, use the exit command. The tool will exit and return to the shell
prompt, and the MEGA65 will reset.
MEGA65 SD-Card:/> exit
%
The following are several useful commands you can use during the file transfer session.
Use the help command to see a complete list of available commands.
Command Description
put filename Send a file from the PC to the MEGA65.
get filename Retrieve a file from the MEGA65 to the PC.
dir Display a directory listing of the MEGA65 SD card.
ldir Display a directory listing of the local current working directory.
mkdir dirname Create a sub-directory on the MEGA65 SD card.
cd dirname Change the current working directory on the MEGA65 SD card.
lcd dirname Change the local current working directory.
help Display a list of available commands.
exit End the file transfer session.
To invoke mega65_ftp commands without starting an interactive prompt, use the -c
argument once for each command:
% mega65_ftp -e -c 'put mydisk.d81' -c 'exit'
The tool will start a session, execute the commands, then terminate. Be sure to issue
the exit command as the final command to reset the MEGA65, or reset the MEGA65
manually after the file transfer has completed.

7-10
PART III
FIRST STEPS IN CODING
7-12
CHAPTER 8
How Computers Work
• Computers are stupid. Really stupid
8-2
Did you know that many computer experts and programmers learned how to use com-
puters when they were still small children? Home computers only became common in
the early 1980s. They were so new, that people would often write programs to do
what they wanted to do, because no software existed to do the job for them.
It was also quite common for people working in all sorts of office jobs to learn how to
program the computers they used for their jobs. For example, the people processing
payroll for a company would often learn how to program the computer to calculate
everyone’s pay!
Things have changed a lot since then, though. Now most people choose existing pro-
grams or apps to do what they need, and think that programming is a specialised skill
that only some people have the ability to learn. But this isn’t true. Of course, like every
other field of pursuit everyone will be better at some things than others, whether it be
sports, knitting, maths or writing. But almost everyone is able to learn enough to help
them in their life.
We created the MEGA65, because we believe that YOU can learn to program, so that
computers can be more useful to you, and as with learning any new skill, that you can
have the satisfaction, enjoyment, and new adventures that this brings!

COMPUTERS ARE STUPID. REALLY


STUPID
How can this be so? Computers are able to do so many different things, often thou-
sands of times faster than a person can. So how can we say that computers are
stupid? The answer is that no computer can do anything that it hasn’t been instructed
by a person to do. Even the latest Artificial Intelligence systems were instructed how
to learn (or how to learn, how to learn). To understand why this is so, it is helpful to
understand how computers really work.

Making an Egg Cup Computer


The heart of a computer is its Central Processing Unit, or CPU for short. Many modern
computers have more than one CPU, but let’s keep things simple to begin with. The
CPU has a set of simple instructions that it understands, like, “get the thing from cup
#21,” “put this thing into cup #403,” “add these things together,” or “do the following
instruction, but only if the thing in cup #712 is the number 3.”
But what do we mean with all of these “things” and “cups”? Let’s start by thinking about
how we could pretend to be a computer using just an empty egg carton, some small
pieces of paper and a pencil or pen. Start by writing numbers, beginning with one, in
each of the little egg cups in the egg carton. Then write the number zero on a little
scrap of paper and put it in the first cup. Do the same for the other cups. You should
now have an egg carton with numbered cups, and with every cup having a scrap of

8-3
paper with the number zero written on it. Now we just need to decide on a few simple
rules that will explain how our egg-cup computer will work:
• First, each cup is allowed to hold exactly one thing at a time. Never more. Never
less. This is so that when we ask the question “what is in box such-and-such,”
that there is a single clear answer. It’s also how computer memory works: Each
piece of memory can hold only one thing at a time.
• Second, we need a way for the computer to know what to do next. On most
computers this is called the Program Counter, or PC, for short (not to be confused
with PC when people are talking about a Personal Computer). The PC is just the
number of the next memory location (or in our case, egg-cup), that the computer
will examine, when deciding what to do next. You might like to have another
piece of paper that you can use to write the PC number on as you go along.
• Third, we need to have a list of things that the egg-cup computer will do, based
on what number is in the egg-cup indicated by the PC.
So let’s come up with the set of things that the computer can do, based on the number
in the egg-cup indicated by the PC. We’ll keep things simple with just the following:

Number in
Action
the egg-cup
0 i) Add one to the PC, and do nothing else.
1 i) Add one to the PC.
ii) Set the PC to be the number stored in that egg-cup.
2 i) Add one to the PC.
ii) Add the number in the egg-cup indicated by the PC
to the number in the egg-cup indicated by the num-
ber in the egg-cup following that.
iii) Put the answer in the egg-cup indicated by the
egg-cup following that.
iv) Finally, add two more to the PC, to skip over the
egg-cups that we made use of.

Don’t worry if that sounds a bit confusing for now, especially that last one – we will
go through it in detail very soon! The best way to explain it is to go through some
examples.

8-4
CHAPTER 9
Getting Started in BASIC
• Your first BASIC programs
• First steps with text and numbers
• Making simple decisions
• Random numbers and chance
9-2
It is possible to code on the MEGA65 in many languages, however most people start
with BASIC. That makes sense, because BASIC stands for Beginner’s All-purpose Sym-
bolic Instruction Code: It was made for people like you to get started with in the world
of coding!
A few short words before we dive in: BASIC is a programming language, and like
spoken language it has conventions, grammar and vocabulary. Fortunately, it is much
quicker and easier to learn than our complex human languages. But if you pay atten-
tion, you might notice some of these structures, and that can help you along your path
in the world of coding.
If you haven’t already read Chapter/Appendix 3 on page 3-3, it might be a good
idea to do so. This will help you be able to more confidently interact with the MEGA65
computer.
It’s also great to remember that if you really confuse the MEGA65, you can always get
back to the READY. prompt by just pressing the reset button on the left-hand side of
the keyboard, or if that doesn’t help, then by turning it off and on again using the power
switch on the left-hand side of the keyboard. You don’t have to worry about shutting
the computer down properly or any of that nonsense. The only thing to remember is
that if you had any unsaved work, it will be lost when you switch the computer off and
on again or press the reset button.
Finally, if you don’t understand all of the descriptions and information with an example
– don’t worry! We have provided as much information as we can, so that it is there in
case you have questions, encounter problems are just curious to discover more. Feel
free to skip ahead to the examples and try things out, and then you can go back and
re-read it when you are motivated to find something out, or help you work though
a problem. And if you don’t find the answer to your problem, send us a message!
There are support forums for the MEGA65 at https://mega65.net, and you can report
problems with this guide at:
https://github.com/mega65/mega65-user-guide
We hope you have as much fun learning to program the MEGA65 as we have had
making it!

YOUR FIRST BASIC PROGRAMS


The MEGA65 was designed to be programmed! When you switch it on, it takes a
couple of seconds to get its house in order, and then it quickly shows you a “READY.”
prompt and flashing block called the cursor. When the cursor is blinking, it tells you
that the computer is waiting for input. The “READY.” message tells you that the BASIC
programming language is running and ready for you to start programming. You don’t
even need to load any programs – you can just get started.

9-3
Try typing the following into the computer and see what happens:

HELLO C O M P U T E R

To do this, just type the letters as you see them above. The computer will already
SHIFT CAPS
be in uppercase mode, so you don’t need to hold or LOCK down. When you
RETURN
have typed ”HELLO COMPUTER”, press . This tells the computer you want it to
accept the line of input you have typed. When you do this, you should see a message
something like the following:

If you saw a SYNTAX ERROR message something like that one, then congratulations:
You have succeeded in communicating with the computer! Error messages sound much
nastier than they are. The MEGA65 uses them, especially the syntax error to tell you
when it is having trouble understanding what you have typed, or what you have put in
a program. They are nothing to be afraid of, and experienced programmers get them
all the time.
In this case, the computer was confused because it doesn’t understand the word “hello”
or the word “computer”. That is, it didn’t know what you wanted it to do. In this
regard, computers are quite stupid. They know only a few words, and aren’t particularly
imaginative about how they interpret them.

9-4
So let’s try that again in a way that the computer will understand. Try typing the follow-
ing in. You can just type it right away. It doesn’t matter that the syntax error message
can still be seen on the screen. The computer has already forgotten about that by the
time it told you READY. again.

PRINT " HELLO C O M P U T E R "

Again, make sure you don’t use shift or shift-lock while typing it in. The symbols around
the words HELLO COMPUTER are double-quotes. If you are used to an Australian
or American keyboard, you might discover that they double-quote key is in a rather
different place to where you are used to: Double-quotes can be typed on the MEGA65
SHIFT RETURN
by holding down , and then pressing 2 . Don’t forget to press when you
are done, so that the computer knows you want it to do something with your input.
INST
If you make a mistake while typing, you can use DEL to rub out the mistake and fix
it up. You can also use the cursor keys to move back and forth on the line while you
edit the line you are typing, but there is a bit of a trick if you have already typed a
double-quote: If you try to use the cursor keys, it will print a funny reversed symbol
instead of moving the cursor. This is because the computer thinks you want to record
moving the cursor in the text itself, which can be really useful and fun, and which you
can read more about in Chapter/Appendix 3 on page 3-3. But for now, if you make
RETURN
a mistake just press and type the messed up line again.
Hopefully now you will see something like the following:

This time no new SYNTAX ERROR message should appear. But if some kind of error
message has appeared, just try typing in the command again, after taking a close look
to work out where the mistake might be.

9-5
Instead of an error, we should see HELLO COMPUTER repeated underneath the line you
typed in. The reason this happened is that the computer does understand the word
PRINT. It knows that whatever comes after the word PRINT should be printed to the
screen. We had to put HELLO COMPUTER inside double-quotes to tell the computer
that we want it to be printed literally.
If we hadn’t put the double-quotes in, the computer would have thought that HELLO
COMPUTER was the name of a stored piece of information. But because we haven’t
stored any piece of information in such a place, the computer will have zero there,
so the computer will print the number zero. If the computer prints zero or some other
number when you expected a message of some sort, this can be the reason.
You can try it, if you like, and you should see something like the following:

In the above examples we typed commands in directly, and the computer executed
RETURN
them immediately after you pressed . This is why typing commands in this way is
often called direct mode (sometimes called “immediate mode”).
But we can also tell the computer to remember a list of commands to execute one
after the other. This is done using the rather unimaginatively named non-direct mode.
To use non-direct mode, we just put a number between 0 and 63999 at the start
of the command. The computer will then remember that command. Unlike when we
executed a direct-mode command, the computer doesn’t print READY. again. Instead
the cursor just reappears on the next line, ready for us to type in more commands.

9-6
Let’s try that out with a simple little program. Type in the following three lines of input:

1 FOR I = 1 TO 10 STEP 1
2 PRINT I
3 NEXT I

When you have done this, the screen should show something like this:

If it doesn’t you can try again. Don’t forget, if you feel that the computer is getting all
muddled up, you can just press the reset button or flip the power switch off and on, at
the left-hand side of the computer to reboot it. This only takes a couple of seconds,
and doesn’t hurt the MEGA65 in anyway.
We have told the computer to remember three commands, that is, FOR I = 1 TO 10
STEP 1, PRINT I and NEXT I. We have also told the computer which order we would
like to run them in: The computer will start with the command with the lowest number,
and execute each command that has the next higher number in turn, until it reaches
the end of the list. So it’s a bit like a reminder list for the computer. This is what we
call a program, a bit like the program at a concert or the theatre, it tells us what is
coming up, and in what order. So let’s tell the computer to execute this program.
But first, let’s try to guess what will happen. Let’s start with the middle command,
PRINT I. We’ve seen the PRINT command, and we know it tells the computer to print
things to the screen. The thing it will try to print is I. Just like before, because there
are no double-quotes around the I, it will try to print a piece of stored information.
The piece of information it will try to print will be the piece associated with the thing
I.
When we give a piece of information like this a name, we call it a variable. They
are called variables because they can vary. That is, we can replace the piece of
information associated with the variable called I with another piece of information.

9-7
The old piece will be forgotten as a result. So if we gave a command like LET I = 3,
this would replace whatever was stored in the variable called I with the number 3.
Back to our program, we now know that the 2nd command will try to print the piece of
information stored in the variable I. So let’s look at the first command: FOR I = 1
TO 10 STEP 1. Although we haven’t seen the FOR command before, we can take a
bit of a guess at how it works. It looks like it is going to put something into the variable
I. That something seems to have something to do with the range of number 1 through
10, and a step or interval of 1. What do you think it will do?
If you guessed that it will put the values 1, 2, 3, 4, 5, 6, 7, 8, 9 and then 10 into the
variable I, then you can give yourself a pat on the back, because that’s exactly what
it does. It also helps us to understand the 3rd command, NEXT I: That command tells
the computer to put the next value into the variable I. And here is a little bit of magic:
When the computer does that, it goes back up the list of commands, and continues
again from the command after the FOR command.
So let’s pull that together: When the computer executes the first command, it discovers
that it has to put 10 different values into the variable I. It starts by putting the first
value in there, which in this case will be the number 1. The computer then continues to
the second command, which tells the computer to print the piece of information that
is currently stored in the variable called I. That will be the number 1, since that was
the last thing the computer was told to put there. Then the computer proceeds to the
third command, which tells it that it is time to put the next value into the variable I.
So the computer will throw away the number 1 that is currently in the variable I, and
put the number 2 in there, since that is the next number in the list. It will then continue
from the 2nd command, which will cause the computer to print out the contents of
the variable I again. Except that this time I has had the number 2 stored in it most
recently, so the computer will print the number 2. This process will repeat, until the
computer has printed all ten values that the FOR command indicated it to do.

9-8
To see this in action, we need to tell the computer to execute the program of com-
mands we typed in. We do this by using the RUN command. Because we want it to run
the program immediately, we should use direct mode. So just type in the word RUN
RETURN
and press . You should then see a display that looks something like the following:

You might notice a couple of things here:


First, the computer has told us it is READY. again as soon as it finished running the
program. This just makes it easier for us to know when we can start giving commands
to the computer again.
Second, when the computer got to the bottom of the screen it automatically scrolled
the display up to make space. This is quite normal. What is important to remember, is
that the computer forgets everything that scrolls off the top. The only exception is if
you have told the computer to remember a command by putting a number in front of it.
So our program is quite safe for now. We can see that this is the case by typing the RUN
command a couple more times: The program listing will have scrolled off the top of
the screen, but we can still RUN the program, because the computer has remembered
it. Give it a try! Did it work?

9-9
If you wish to see the program of remembered commands, you can use the LIST
command. This commands causes the computer to display the remembered program
of commands to the screen, like in the display here. If you would like to replace any of
the commands in the program, you can type a new line that has the same number as
the one you wish to change.

For example, to print the results all on one line, we could modify the second line of the
RETURN
program to PRINT I; by typing the following line of input and pressing :

2 PRINT I ;

9-10
You can make sure that the change has been remembered by running the LIST com-
mand again, as we can see here. You can then use the RUN command to run the
modified program, like this:

It is quite easy to modify your programs in this way. As you become more comfortable
with the process, there are two additional helpful tricks:
First, you can give the LIST command the number of a command, or line as they are
referred to, and it will display only that line of the program. Alternatively, you can give
a range separated by a minus sign to display only a section of the program, e.g., LIST
1 - 2 to list the first two lines of our program.
Second, you can use the cursor keys to move the cursor to a line which has already
been remembered and is displayed on the screen. If you modify what you see on the
RETURN
screen, and then press while the cursor is on that line, the BASIC interpreter will
read in the modified line and replace the old version of it. It is important to note that
RETURN
if you modify multiple lines of the program at the same time, you must press on
each line that has been modified. It is good practice to check that the program has
been correctly modified. Use the LIST command again to achieve this.

Exercises to try
1. Can you make it count to a higher or lower number?
At the moment it counts from 1 to 10. Can you change it to count to 20 instead?
Or to count from 3 to 17? Or how about from 14.5 to 21.5? What do you think you
would need to reverse the order in which it counts?
Clue: You will need to modify the FOR command.
2. Can you change the counting step?

9-11
At the moment it counts by ones, i.e., each number is one more than the last. Can you
change it to count by twos instead? Or by halves, so that it counts 1, 1.5, 2, 2.5, 3,
…?
Clue: You will need to modify the STEP clause of the FOR command.
3. Can you make it print out one of the times tables?
At the moment it prints the answers to the 1 times tables, because it counts by ones.
Can you make it count by threes, and show the three times tables?
Clue: You will need to modify the FOR command.
4. Can you make it print out the times tables from 1×1 to 10×10?
Clue: You might like to use ; on the end of PRINT command, so that you can have
more than one entry per line on the screen.
Clue: The PRINT command without any argument will just advance to the start of the
next line.
Clue: You might need to have multiple FOR loops, one inside the other.

FIRST STEPS WITH TEXT AND


NUMBERS
In the last section we started to use both numbers and text. Text on computers is
made by stringing individual letters and other symbols together. For this reason they
are called strings. We also call the individual letters and symbols characters. The
name character comes from the printing industry where it refers to each symbol that
can be printed on a page. For computers, it has much the same meaning, and the set
of characters that a computer can display is rather unimaginatively called a character
set..
When the MEGA65 expects some form of input, it is typically looking for one of four
things:
1. a keyword like PRINT or STEP, which are words that have a special meaning to
the computer;
2. a variable name like I or A$ that it will then use to either store or retrieve a piece
of information;
3. a number like 42 or -30.3137; or
4. a string like "HELLO COMPUTER" or "23 KILOMETRES".

9-12
Sometimes you have a choice of which sort of thing you can provide, while other times
you have less choice. What sort of thing the computer will accept depends on what
you are doing at the time. For example, in the previous section we discovered that
when the computer tells us that it is READY, that we can give it a keyword or a num-
ber. Do you think that the computer will accept all four kinds of things when it says
READY.? We already know that keywords and numbers and keywords can be entered,
but what about variable names or strings? Let’s try typing in a variable name, say N,
RETURN
and pressing , and see what happens. And then let’s try with a string, say "THIS
IS A STRING".

You should get a syntax error each time, telling you that the computer doesn’t under-
stand the input you have given it. Let’s start with when you typed the variable: If you
just tell the computer the name of a stored piece of information, it doesn’t have the
foggiest idea what you are wanting it to do. It’s the same when you give it a piece of
information, like a string, without telling the computer what to do with it.
But as we discovered in the last section, we can tell the computer that we want to see
the piece of information stored in a variable using the PRINT command. So instead,
we could type in PRINT N, and the computer would know what to do, and will print
the piece of information stored in the variable called N.
In fact, using the PRINT command is so common, that programmers got annoyed hav-
ing to type in the PRINT command all the time, that they made a shortcut: If you type
a question mark character, i.e., a ?, the computer knows that you mean PRINT. So for
example if you type ? N, it will do the same as typing PRINT N. Of course, you have
RETURN
to press after each command to tell the computer you want it to process what
you typed. From here on, we will assume that you remember to do that, without being
reminded.

9-13
The ? shortcut also works if you are telling the computer to remember a command as
part of a program. So if you type 1 ? N, and then LIST, you will see 1 PRINT N, as
we can see in the following screenshot:

Like we saw in the last section, the variable N has not had a value stored in it, so when
the computer looks for what is there, it finds nothing. Because N is a numeric variable,
when there is nothing there, this means zero. If it was a string variable, then it would
have found literally nothing. We can try that, but first we have to explain how we tell
the computer we are talking about a string variable. We do that by putting a dollar
sign character, i.e., a $, on the end of the variable name. So if we put a $ on the end
of the variable name N, it will refer to a string variable called N$.
We can experiment with these variables by using the hopefully now familiar PRINT
command (or the ? shortcut) to see what is in the variables. But we need a convenient
way to put values into them. Fortunately we aren’t the first people wanting to put
values into variables, and so the LET exists. The LET command is used to put a value
into a variable. For example, we can tell the computer:

LET N = 5.3

This tells the computer to put the value 5.3 into the variable N. We can then use the
PRINT command to check that it worked. Similarly, we can put a value into the variable
N$ with something like:

LET N$ = " THE KING OF THE POTATO PEOPLE "

9-14
If we try those, we will see something like the following:

We mentioned just before that N is a numeric variable and that N$ is a string variable.
This means that we can only put numbers into N and strings into N$. If we try to put
the wrong kind of information into a variable, the computer will tell us that we have
mis-matched the kind of information with the place we are trying to put it by giving us
a TYPE MISMATCH ERROR like this:

This leads us to a rather important point: N and N$ are separate variables, even though
they have similar names. This applies to all possible variable names: If the variable
name has a $ character on the end, it means it is a string variable quite separate from
the similarly named numeric variable. To use a bit of jargon, this means that each type
of variable has their own separate name spaces.

9-15
(There are also four other variable name spaces that we haven’t talked about yet:
integer variables, identified by having a % character at the end of their name, e.g., N%,
and arrays of numeric, string or integer variables. But don’t worry about those for now.
We’ll talk about those a bit later on.)
So far we have only given values to variables in direct mode, or by using constructions
like FOR loops. But we haven’t seen how we can get information from the user when
a program is running. One way that we can do this, is with the INPUT command.
INPUT is quite easy to use: We just have to say which variable we would like the input
to go into. For example, to tell the computer to ask for the user to provide something
to put into the variable A$, we could use something like INPUT A$. The only trick
with the INPUT command is that it cannot be used in direct mode. If you try it, the
computer will tell you ILLEGAL DIRECT ERROR. Try it, and you should see something
like the following

This means that the INPUT command can only be used as part of a program. So we
can instead do something like the following:

1 INPUT A$
2 PRINT " YOU TYPED "; A$
RUN

9-16
What do you think that this will do? The first line will ask the computer for something
to put into the variable A$, and the second line will print the string "YOU TYPED",
followed by what the INPUT command read from the user. Let’s try it out:

Did you expect that to happen? What is this question mark doing there? The ? here is
the computer’s way of telling you that a program is waiting for some input from you.
This means that the computer uses the same symbol, ?, to mean two different things: If
you type it as part of a program or in direct mode, then it is a short-cut for the PRINT
command. That’s when you type it. But if the computer shows it to you, it has this
other meaning, that the computer is waiting for you to type something in. There is also
a third way that the computer uses the ? character. Have you noticed what it is? It is
to indicate the start of an error message. For example, a Syntax Error is indicated by
?SYNTAX ERROR. When a character or something has different meanings in different
situations or contexts, we say that it its context dependent.

9-17
RETURN
But returning to our example, if we now type something in, and press to tell the
computer that you are done, the program will continue, like this:

Of course, we didn’t really know what to type in, because the program didn’t give any
hints to the user as to what the programmer wanted them to do. So we should try to
provide some instructions. For example, if we wanted the user to type their name, we
could print a message asking them to type their name, like this:

1 PRINT " WHAT IS YOUR NAME "


2 INPUT A$
3 PRINT " HELLO "; A$

9-18
Now if we run this program, the user will get a clue as to what we expect them to do,
and the whole experience will make a lot more sense for them:

When we run the program, we first see the WHAT IS YOUR NAME message from line
1. The computer doesn’t print the double-quote symbols, because they only told the
computer that the piece of information between them is a string. The string itself is
only the part in between.
After this we see the ? character again and the blinking cursor telling us that the
computer is waiting for some input from us. The rest of the programmed is blocked
from continuing until it we type the piece of information. Once we type the piece
of input, the computer stores it into the variable A$, and can continue. Thus when it
reaches line 3 of the program, it has everything it needs, and prints out both the HELLO
message, as well as the information stored in the variable called A$.
Notice that the word LISTER doesn’t appear anywhere in the program. It exists only
in the variable. This ability to process information that is not part of a program is one
of the things that makes computer programs so powerful and able to be used for so
many purposes. All we have to do is to change the input, and we can get different
output.

9-19
For example, with our program we run it again and again, and give it different input
each time, and the program will adapt its output to what we type. Pretty nifty, right?
Let’s have the rest of the crew try it out:

We can see that each time the program prints out the message customised with the
input that you typed in…Until we get to RIMMER, BSC. As always, Mr. Rimmer is
causing trouble. In this case, he couldn’t resist putting his Bronze Swimming Certificate
qualification on the end of his name.
We see that the computer has given us a kind of error message, ?EXTRA IGNORED. The
error is not written in red, and doesn’t have the word ERROR on the end. This means
that it is a warning, rather than an error. Because it is only a warning, the program
continues. But something has happened: The computer has ignored Mr. Rimmer’s BSC,
that is, it has ignored the extra input. This is because the INPUT command doesn’t
really read a whole line of input. Rather, it reads one piece of information. The INPUT
command thinks that a piece of information ends at the end of a line of input, or when
it encounters a comma (,) or colon (:) character.

9-20
If you want to include one of those symbols, you need to surround the whole piece of
information in double-quotes. So, if Mr. Rimmer had read this guide instead of ob-
sessing over the Space Core Directives, he would have known to type "RIMMER, BSC"
(complete with the double-quotes), to have the program run correctly. It is important
that the quotes go around the whole piece of information, as otherwise the computer
will think that the first quote marks the start of a new piece of information. We can
see the difference it makes below:

While this can all be a bit annoying at times, it has a purpose: The INPUT command
can be used to read more than one piece of information. We do this by putting more
than one variable after the INPUT command, each separated by a comma. The INPUT
command will then expect multiple pieces of information. For example, we could ask
for someone’s name and age, with a program like this:

1 PRINT " WHAT IS YOUR NAME AND AGE "


2 INPUT A$ , A
3 PRINT " HELLO "; A$
4 PRINT " YOU ARE "; A ; " YEARS OLD ."

9-21
If we run this program, we can provide the two pieces of information on the one line
when the computer presents us with the ? prompt, for example LISTER, 3000000.
Note the comma that separates the two pieces of information, LISTER and 3000000.
It’s also worth noticing that we haven’t put any thousands separators into the number
3,000,000. If we did, the computer would think we meant three separate pieces of
information, 3, 000 and 000, which is not what we meant. So let’s see what it looks
like when we give LISTER, 3000000 as input to the program:

In this case, the INPUT command reads the two pieces of information, and places
the first into the variable A$, and the second into the variable A. When the program
reaches line 3 it prints HELLO followed by the first piece of information. Then when it
gets to line 4, it prints the string YOU ARE, followed by the contents of the variable A,
which is the number 3,000,000, and finally the string YEARS OLD.
It’s also possible to just give one piece of information at a time. In that case, the
INPUT command will ask for the second piece of information with a double question-
mark prompt, i.e., ??. Once it has the second piece of information. (If we had more
than two variables on the INPUT command, it will still present the same ?? prompt,
rather than printing more and more question-marks.)

9-22
So if we try this with our program, we can see this ? and ?? prompts, and how the
first piece of information ends up in A$ because it is the first variable in the INPUT
command. The second piece of information ends up in A because A is the second
variable after the INPUT command. Here’s how it looks if we give this input to our
program:

Until now we have been asking the user to input information by using a PRINT com-
mand to display the message, and then an INPUT command to tell the computer which
variables we would like to have some information input into. But, like with the PRINT
command, this is something that happens often enough, that there is a shortcut for it.
It also has the advantage that it looks nicer when running, and makes the program a
little shorter. The short cut is to put the message to show after the INPUT command,
but before the first variable.
We can change our program to use this approach. First, we can change line 3 to
include the prompt after the INPUT command. We can do this one of two ways: First,
we could just type in a new line 3. The computer will automatically replace the old
line 3 with the new one.
But, as we have mentioned a few times now, programmers are lazy beasts, and so
there is a short-cut: If you can see the line on the screen that you want to change, you
can use the cursor keys to navigate to that line, edit it on the screen, and then press
RETURN
to tell the computer to accept the new version of the line.

9-23
Either way, you can check that the changes succeeded by typing the LIST command
on any line of the screen that is blank. This will show the revised version of the program.
For example:

We still have a little problem, though: Line 1 will print the message WHAT IS YOUR
NAME AND AGE, and then Line 2 will print it again! We only want the message to
appear once. Thus we would like to change line 1 so that it doesn’t do this any more.
Because there is no other command on line 1 that we want to keep, that line can just
become empty. So we can type in something like this:

9-24
We can confirm that the contents of the line have been deleted by running the LIST
command again, like this:

Did you notice something interesting? When we told the computer to make line 1 of
the program empty, it deleted it completely! That’s because the computer thinks that
an empty line is of no use. It also makes sure that your programs don’t get all cluttered
up with empty lines if you make lots of changes to your programs.
It is also possible to DELETE a range of lines. For example (but don’t do this now), you
could delete lines 3-4 with:
DELETE 3 -4

You can read more about the DELETE command in the BASIC 65 Command Reference.

9-25
With that out the way, let’s run our program and see what happens. As usual, just type
RETURN
in the RUN command and press . You should see something like this:

We can see our prompt of WHAT IS YOUR NAME AND AGE there, but now the cursor
is appearing without any ? character. This is because we put a comma (,) after the
message in the INPUT command. To get the question mark, we have to instead put a
semi-colon (;) after the message, like this:

INPUT " WHAT IS YOU NAME AND AGE "; A$ , A

Now if we run the program, we should see what we are looking for:

9-26
Exercises to try
1. Can you make the program ask someone for their name, and then for their
favourite colour?
At the moment it asks for their name and age. Can you change the program so that it
reports on their favourite colour instead of their age?
Clue: What type of information is age? Is it numeric or a string? Is it the same type of
information as the name of a colour?
2. Can you write a program that asks someone for their name, prints the hello
message, and then asks for their age and prints out that response?
At the moment, the program expects both pieces of information at the same time. This
means the program can’t print a message about the first message until after it has both
pieces of information. Change the program so that you can have an interaction like
the following instead:

WHAT IS YOUR NAME ? DEEP T H O U G H T


HELLO DEEP T HOU GH T
WHAT IS THE ANSWER ? 42
YOU SAID THE ANSWER IS 42

Clue: You will need more lines in your program, so that you can have more than one
INPUT and PRINT command.
3. Can you write a program that asks several questions, and then prints out the
list of answers given?
Think of several questions you would like to be able to ask someone, and then write
a program that asks them, and remembers the answers and prints them out with an
appropriate message. For example, running your program could look like this:

WHAT IS YOUR NAME ? FRODO


HOW OLD ARE YOU ? 33
WHAT IS YOUR F A V O U R I T E FOOD ? E V E R Y T H I N G !
THANK YOU FOR A N S W E R I N G .
YOUR NAME IS FRODO
YOU ARE 33 YEARS OLD
YOU F A V O U R I T E FOOD IS E V E R Y T H I N G !

Clue: You will need more lines in you program, to have the various INPUT and PRINT
commands.
Clue: You will need to think carefully about which variable names you will use.

9-27
MAKING SIMPLE DECISIONS
In the previous section we have learnt how to input text and numeric data, and how to
display it. However, the programs have just followed the lines of instruction in order,
without any way to decide what to do, based on what has been input.
In this section we will see how we can take simple decisions using the IF and THEN
commands. The IF command checks if something is true or false, and if it is true,
causes the computer to execute the command the comes after the THEN command.
The way the computer decides whether something is true or false is that it operates on
the supplied information using one of several symbols. These symbols are thus called
operators. Also, because the compare two things, they depend on the relationship
of the things. For this reason they are called relational operators. They include the
following:
• Equals (=). For example, 3 = 3 would be true, while 3 = 2 would be false.
• Less than (<). For example, 1 < 3 would be true, while both 3 < 3 and 1 < 3
would be false.
• Greater than (>). For example, 3 > 1 would be true, while both 3 > 3 and 1 >
3 would be false.
As it is common to want to consider when something might be equal or greater than, or
equal or less than, there are short cuts for this. Similarly, if you wish to test if something
is not equal to something else, there is a relational operator for this, too:
• Unequal, which we normally say as not equal (<>). This is different to the math-
ematical symbol for not equal, ̸=, because the MEGA65’s character set does
not include a character that looks like that. So the programmers who created
BASIC for the MEGA65 used the greater than and less than signs together to
mean either less than or greater than, that is, not equal to. For example, 1 <>
3 would be true, while 3 <> 3 would be false.
• Less than or equal to (<=). For example, 1 < 3 and 3 <= 3 would be true, while
both 4 < 3 would be false.
• Greater than or equal to (>=). For example, 3 >= 1 and 3 >= 3 would be true,
while both 1 >= 3 would be false.
A good trick if you have trouble remembering which way the (<) and (>) signs go, the
side with more ends of lines is the one that needs to have more. For example, the
(<) symbol has one point on the left, but two ends of lines on the right-hand side. So
for something to be true with (<), the number on the left-hand side needs to be less
than the number on the right-hand side. This trick even works for the equals sign, (=),
because it has the same number of ends on both sides, so you can remember that the
numbers on both sides need to be equal. It also works when you have two symbols
together, like (>=), it is true if the condition is true for any of the symbols in it. So in
this case the (>) symbol has more ends on the left than the right, so if the number on

9-28
the left is bigger than the number on the right, it will be true. But also because the (=)
symbol has two ends on each side, it will be true if the two numbers are the same.
Using these relational operators, we can write a line that will do something, but only
if something is true or false. Let’s try this out, with a few examples:

IF -2 < 0 THEN PRINT " -2 IS A N E G A T I V E NUMBER "


IF 2 < 0 THEN PRINT "2 IS A N E G A T I V E NUMBER "
IF 0 < -2 THEN PRINT " -2 IS A P O S I T I V E NUMBER "
IF 0 < 2 THEN PRINT "2 IS A P O S I T I V E NUMBER "

These commands work fine in direct mode, so you can just type them directly into the
computer to see what they will do. This can be handy for testing whether you have the
logic correct when planning an IF – THEN command. If you type in those commands,
you should see something like the following:

We can see that only the PRINT commands that followed an IF command that has
a true value were executed. The rest were silently ignored by the computer. But we
can of course include these into a program. So let’s make a little program that will ask
for two numbers, and say whether they are equal, or if one is greater or less than the
other. Before you have a look at the program, have a think about how you might do
it, and see if you can figure it out. The clue we will give you, is that the IF command
also accepts the name of a variables, not just numbers. So you can do something like
IF A > B THEN PRINT "SOMETHING". The program will be on the next page, to
stop you peeking before you have a think about it!

9-29
Did you have a go? There are lots of different ways it could be done, but here is what
we came up with:

1 INPUT " WHAT IS THE FIRST NUMBER "; A


2 INPUT " WHAT IS THE SECOND NUMBER "; B
3 IF A = B THEN PRINT " THE N U M B E R S ARE EQUAL "
4 IF A > B THEN PRINT " THE FIRST NUMBER IS BIGGER "
5 IF B > A THEN PRINT " THE SECOND NUMBER IS BIGGER "

We can then run the program as often as we like, and the computer can tell us which
of the two numbers we give it is biggest, or if they are equal:

Notice how in this program, we didn’t use fixed numbers in the IF command, but in-
stead gave variable names instead. This is one of the very powerful things in computer
programming, together with being able to make decision based on data. By being
able to refer to data by name, regardless of its current value or how it got there, the
programmer can create very flexible programs.
Let’s think about a bit of a more interesting example: a “guess the number” game.
For this, we need to have a number that someone has to guess, and then we need to
accept guesses, and indicate whether the guess was correct or not. If the guess is
incorrect, we should tell the user if the correct number is higher or lower.
We have already learned most the ingredients to make such a program: We can use
LET to set a variable to the secret number, INPUT to prompt the user for their guess,
and then IF, THEN and PRINT to tell the user whether their guess was correct or not.
So let’s make something. Again, if you like, stop and think and experiment for a few
minutes to see if you can make such a program yourself.
Here is how we have done it. But don’t worry if you have done it in a quite different
way: There are often many ways to write a program to perform a particular task.

9-30
1 SN =23
2 PRINT " GUESS THE NUMBER B E T W E E N 1 AND 100"
3 INPUT " WHAT IS YOUR GUESS "; G
4 IF G < SN THEN PRINT " MY NUMBER IS BIGGER "
5 IF G > SN THEN PRINT " MY NUMBER IS S M A L L E R "
6 IF G = SN THEN PRINT " C O N G R A T U L A T I O N S ! YOU G U E S S E D MY NUMBER !"

The first line puts our secret number into the variable SN. The second line prints a
message telling the user what they are supposed to do. The third line asks the user for
their guess, and puts it into the variable G. The fourth, fifth and sixth lines then check
whether the guess is correct or not, and if not, which message it should print. This is
done by using the IF command and an appropriate relative operator to make each
decision. This works well, to a point. For example:

We can see that it prints the message, and it asks for a guess, and responds appropri-
ately. But if we want to guess again, we have to use the RUN command again for each
extra guess. That’s a bit poor from the user’s perspective. However that is unlikely to
be a problem for long, because the user can see the secret number in the listing on
the screen!
So we would like to fix these problems. Let’s start with hiding the listing. We previously
mentioned that when the screen scrolls, anything that was at the top of the screen
disappears. So we could just make sure the screen scrolls enough, that any listing that
was visible is no longer visible. We could do this using PRINT and a FOR loop. The
screen is 25 lines, so we could do something like:

FOR I = 1 to 25
PRINT
NEXT I

9-31
SHIFT CLR
But there are better ways. If you hold down , and then press HOME , it clears
the screen. This is much simpler and more convenient. But how can we do something
like that in our program? It turns out to be very simple: You can type it while entering
a string! This is because the keyboard works differently based on whether you are in
quote mode.
Quote mode is just a fancy way of describing what happens when you type a double-
quote character into the computer: Until you type another double-quote or press the
RETURN
. You might remember we mentioned the problem of funny symbols coming up
when using the cursor keys. We didn’t want to distract you at the time, but that is a
symptom of being in quote mode: In quote mode many special keys show a symbol
that represents them, rather than taking their normal action. For example, if you press
the cursor left key while in quote mode, a Ƣ symbol appears. If you press the cursor
CLR SHIFT
right key, a Ž, up Ʊ, down ű and the HOME a ų, and if you are holding down and
CLR
press HOME a Ƴ.

9-32
So let’s use this to make the second line clear the screen when it prints the GUESS THE
NUMBER BETWEEN 1 AND 100 message. The first time you try it is a bit confusing,
but once you get the hang of it, it is quite easy. What we want in the end is a line that
looks like this:

2 PRINT "ƳGUESS THE NUMBER BETWEEN 1 AND 100"

SHIFT
To do this, start by typing 2 PRINT ". Then hold the key down, and press
CLR
HOME . Your line should now look like 2 PRINT"Ƴ. If so, you have succeeded! You can
now finish typing the line as normal. When you have done that, you can use the LIST
command as usual, to make sure that you have successfully modified the program. You
should see your modified line with the Ƴ symbol in it.

9-33
RETURN
If you now run the program by typing in RUN and pressing as usual, the 2nd line
tells the compute to clear the screen before printing the rest of the message, like this:

This hides the listing from the user, so that they can’t immediately see what our secret
number is. We can type our guess in, the same as before, but just like before, after
one guess it returns to the READY. prompt. We really would like people to be able to
make more than one guess, without needing to know that they need to run the program
again.
There are a few ways we could do this. We already saw the FOR – NEXT pattern. With
that, we could make the program give the user a certain number of guesses. If we
followed the NEXT command with another program line, we could even tell the user
when they have taken too many guesses. So let’s have a look at our program and see
how we might do that. Here is our current listing again:

1 SN =23
2 PRINT Ƴ" GUESS THE NUMBER B E T W E E N 1 AND 100"
3 INPUT " WHAT IS YOUR GUESS "; G
4 IF G < SN THEN PRINT " MY NUMBER IS BIGGER "
5 IF G > SN THEN PRINT " MY NUMBER IS S M A L L E R "
6 IF G = SN THEN PRINT " C O N G R A T U L A T I O N S ! YOU G U E S S E D MY NUMBER !"

If we want the user to have multiple guesses, we need to have lines 2 through 6 run
multiple times. This makes our life a bit tricky, because it means we need to insert a
line between line 1 and 2. But unless you are a mathemagican, there are no whole
numbers between 1 and 2, and the MEGA65 doesn’t understand line numbers like 1.5.

9-34
Fortunately, the MEGA65 has the RENUMBER command. This command can be typed
only in direct mode. When executed, it changes the line numbers in the program, while
keeping them in the same order. The new numbers are normally multiples of 10, so
that you have lots of spare numbers in between to add extra lines. For example, if we
use it on our program, it will renumber the lines to 10, 20, …, 60. We can see that this
has happened by using the LIST command:

Now our life is much easier: We can choose any number that is between 10 and 20 to
put our FOR command into. It’s a common choice to use the middle number, so that if
you think of other things you want to add in later, you have the space to do it. So let’s
add a FOR command to give the user 10 chances to guess the number. We can use
any variable name we like for this, except for G and SN, because we are using those.
It would be very confusing if we mixed those up! So let’s add a line like this:

15 FOR I = 1 TO 10 STEP 1

Now we need a matching NEXT I after line 60. Let’s keep the nice pattern of adding
10 to work out the next line number, and put it as line 70:

70 NEXT I

9-35
We can type those lines in, and then use LIST command to make sure the result is
correct:

That’s looking pretty good. But there are a couple of little problems still. Can you work
out what they might be? What will happen now after the user makes a guess? What
will happen if they run out of guesses?
If you worked out that making a guess that the screen will be immediately cleared, you
can give yourself a pat on the back! The user will hardly have time to see the message.
Worse, if they guess the number correctly, they won’t know, and the program will keep
going. We’d really like the program to stop or end, once the user makes a correct
guess.
We can do this using either the STOP or END commands. These two commands are
quite similar. The main difference is that if you STOP a program, the computer tells
you where it has stopped, and you have the chance to continue the program using the
CONT command. The END command, on the other hand, tells the computer that the
program has reached its end, and it should go back to being READY. The END command
makes more sense for our program, because after the user has guessed the number,
there isn’t any reason to continue.
Now we need a way to be able tell the computer to do two different things when the
user makes a correct guess. We could just add an extra IF command after line 60
which prints the congratulations message, e.g., 65 IF G=SN THEN END.
But we can be a bit more elegant than that: There is a way to have multiple commands
on a single line. If you remember back to when we were learning about the INPUT
command, you might remember that there were two different characters that separate
pieces of information: , and :. The second one, :, is called a colon, and can also be
used to separate BASIC commands on a single line. So if we want to change line 60
to PRINT the message of congratulations and then END the program, we can just add
: END to the end of the line. The line should look like this:

9-36
60 IF G = SN THEN PRINT " C O N G R A T U L A T I O N S ! YOU G U E S S E D MY NUMBER !": END

That solves that problem. But it would also be nice to not clear the screen after every
guess, so that the user can see what their last guess was, and whether it was bigger
or smaller than the number. To do this, we can remove the clear-screen code from line
20, and add a new print command to a lower line number, so that it clears the screen
once at the start of the program, before the user gets to start guessing.
For example, we could it put in line 5, so that it happens as the absolute first action of
the program. As we mentioned earlier, the line numbers themselves aren’t important:
All that is important is to remember that the computer starts at the lowest line number,
and runs the lines in order. Anyway, let’s make those changes to our program:

20 PRINT " GUESS THE NUMBER B E T W E E N 1 AND 100"


5 PRINT Ƴ""

If you type those lines in, and LIST the program again, you should see something like
the following:

9-37
We can now RUN the program, and see whether it worked. Let’s try it!

The screen still clears, which is good. Can you notice one little difference already,
though? There is a blank line above the first message. This is because our PRINT
command in line 5 goes to the next row on the screen after it has printed the clear-
screen character. We can fix this by putting a ; (semi-colon) character at the end of
the PRINT command. This tells the PRINT command that it shouldn’t go to the start
of the next row on the screen when it has done everything. So if we change line 5 to
5 PRINT "Ƴ"; this will make the empty space at the top the screen disappear.

9-38
But back to our program, we can now make guesses, and the program will tell us
whether each guess is more or less than the correct number. And after 10 guesses, it
stops asking for guesses, and goes back to the READY. prompt, like this:

It would be nice to tell the user if they have run out of guesses. We need to add this
message after the NEXT command. We should also be nice and tell them what the
secret number was, instead of leaving them wondering. So let’s add the line to the
end of our program as line 80:

80 PRINT " SORRY ! YOU RAN OUT OF G U E S S E S . MY NUMBER WAS "; SN

Now if the user doesn’t guess the number, they will get a useful message, like this:

9-39
Exercises to try
1. Can you make the program ask at the start for the secret number?
At the moment the program sets the secret number to 23 every time. To make the
game more interesting it would be great to ask the first user for the secret number,
and then start the rest of the game, so that someone else can try to guess the number.
Clue: You will need change the line that sets the SN variable so that it can be read
from the first user. You might find the INPUT statement useful.
2. Can you make the program ask for the user’s name and give personalised
responses?
At the moment, the program displays very simple messages. It would be nice to ask
the user their name, and then use their name to produce personalised messages, like
SORRY DAVE, BUT THAT NUMBER IS TOO SMALL.
Clue: You will need to add a line early in the program to ask the user their name.
Clue: You might like to review how we used the PRINT command, including with ; to
print more than one thing on a line.
3. Can you improve the appearance of the messages with colours and better
spacing?
We haven’t really made the program particularly pretty. It would be great to use
colours.
Clue: You might like to add more PRINT commands to improve the spacing and layout
of the messages.
Clue: You might like to use either the colour codes in the messages you PRINT
Clue: You might also like to use the FOREGROUND, BACKGROUND and BORDER com-
mands to set the colour of the text, screen background and border.
4. Can you make the program say if a guess is “warmer” or “colder” than the
previous guess?
At the moment the program just tells you if the guess is higher or lower than the secret
number. It would be great if it could tell you if a guess is getting closer or further away
with each guess: When they get closer, it should tell the user that they are getting
“warmer”, and “colder” when they get further away.
This is quite a bit more involved than the previous exercises, and requires you to work
out some new things.
Clue: You will need to remember the previous guess in a different variable, and then
compare it with the last one: Is it nearer or further away. You might need to have IF
commands that have another IF after the first one, or to learn how to use the AND
operator.

9-40
RANDOM NUMBERS AND CHANCE
We’ll come back to the Guess The Number game shortly, but let’s take a detour first.
Through a maze. Let’s hope we can get back out before the end of the lesson! Let’s
look at a simple way to make a maze. This program has been known for a long time.
It works by choosing at random whether to display a M or a N symbol. These symbols
SHIFT
are obtained by holding down and tapping either the N or M keys. You can see
the symbols on the front of those keys. While they are shown on the keys with a box
around them, the box does not appear, only the diagonal line. It turns out that printing
either of these two characters at random draws a decent looking maze.
Let’s give it a try. To be able to do this, we need a way to generate randomness. The
MEGA65 has the RND(1) function to do this. This function works like a variable, but
each time you try to use it, it gives a different result. Let’s see how that works. Type in
the following:

PRINT RND (1)

Each time you type this, it will give a different answer, as you can see here:

We can see that this gives us several different results: 1.07870447E-03,


.793262171, .44889513, .697215893. Each of these is a number between 0 and
1, even the first one. The first one is written in scientific notation. The E-03 means
that the value is 1.07870447 × 10−3 = 0.000107870447. That is, the E-03 means to
move the decimal place three places to the left. If there is a + after E, then it means
to move the decimal place to the right. For example, 1.23456E+3 represents the
number 1234.56.

9-41
Now, we promised a maze, so we better give you one. We can use this RND(1) to
pick between these two symbols. The first one has a character code of 205, and
the second one conveniently 206. This means that if we add the result of RND(1)
to 205.5, we will get a number between 205.5 and 206.5. Half the time it will be
205.something, and the other half of the time it will be 206.something. We can use
this to print one or the other characters by using the CHR$() function that returns the
character corresponding to the number we put between the brackets. This means we
can do something like:

LET C = 205.5+ RND (1)


PRINT CHR$ ( C );

This will print one or the other of these symbols each time. We could use this already
to print the maze by doing this over and over, making a loop. We could use FOR and
NEXT. But in this case, we want it to go forever, that is, each time the program gets
to the end, we want it to go to the start again. The people who created BASIC really
weren’t very creative, so the command to do this is called GOTO. You put the number
of the line that you want to be executed next after it, e.g., GOTO 1. We can use this
to write our little maze program so that it will run continuously:

10 LET C = 205.5+ RND (1)


20 PRINT CHR$ ( C );
30 GOTO 10

9-42
If you RUN this program, it will start drawing a maze forever, that looks like the screen
RUN
shot below. You can stop it at any time by pressing STOP , or you can pause it by
NO NO RUN
pressing , and unpause it by pressing
SCROLL again. If you press STOP , the
SCROLL

computer will tell you where it was up to at the time. In the case of the screenshot
below, it was working on line 10:

That works nicely, and draws a very famous maze [1]. We can, however, make the
program smaller. We don’t need to put the result of the calculation of which symbol
to display on a separate line. We can put the calculation directly into brackets for the
CHR$() function:

10 PRINT CHR$ (2 05. 5+ RND (1));


20 GOTO 10

And we can use what we learnt about the : (colon) symbol, and put the GOTO com-
mand onto the same line as the PRINT command:
10 PRINT CHR$ (2 05. 5+ RND (1));: GOTO 10

Can you see how there are often many ways to get the same effect from a program?
This is quite normal. For complex programs, there are many, many ways to get the
same function. This is one of the areas in computer programming where you can be
very creative.
But back to the topic of randomness. It’s all well and good using these random numbers
between 0 and 1 for drawing a maze, but it’s a bit tricky to ask people to get a really
long decimal. If we want a number in the range 1 to 100, we can multiply what we get
from RND(1) by 100. If we do that, it gets a bit better, but we will still get numbers
like 55.0304651, 30.3140154, 60.2505497 and .759229916.

9-43
That’s closer, but we really want to get rid of those fractional parts. That is, we want
whole numbers or integers. BASIC has the INT() function that works like the RND(1)
function, except that whatever number you put in the brackets, it will return just the
whole part of that. So for example INT(2.18787) will return the value 2. As we said
just now, it chops off the fractional part, that is, it always rounds down. So even if we
do INT(2.9999999) the result will still be 2, not 3. This means that if we multiply the
result of RND(1) by 100, we will get a number in the range of 0 – 99, not 1 – 100.
This is nice and easy to fix: We can just add 1 to the result. So to generate an integer,
that is a whole number, that is between 1 and 100 inclusive, we can do something
like:
PRINT INT ( RND ( 1 ) * 1 0 0 ) + 1

That looks much better. So let’s type in our “guess the number” program again. But
this time, we replace the place where we set our secret number to the number 23,
to instead set it to a random integer between 1 and 100. Don’t peek at the solution
just yet. Have a think about how we can use the above to set SN to a random integer
between 1 and 100. Once you have your guess ready, have a look what we came
up with below. You might have made a different program that can do the same job.
That’s quite fine, too!

10 SN = INT ( RND ( 1 ) * 1 0 0 ) + 1
20 PRINT Ƴ""
30 FOR I = 1 TO 10 STEP 1
40 PRINT " GUESS THE NUMBER B E T W E E N 1 AND 100"
50 INPUT " WHAT IS YOUR GUESS "; G
60 IF G < SN THEN PRINT " MY NUMBER IS BIGGER "
70 IF G > SN THEN PRINT " MY NUMBER IS S M A L L E R "
80 IF G = SN THEN PRINT " C O N G R A T U L A T I O N S ! YOU G U E S S E D MY NUMBER !": END
90 NEXT I
100 PRINT " SORRY , YOU HAVE RUN OUT OF G U E S S E S "

Now we don’t have to worry about someone guessing the number, and we don’t need
someone else to pick the number for us. This makes the program much more fun to
play. Can you beat it?

Exercises to try
1. Can you make the maze program make different mazes?
The maze program currently displays equal numbers of N and M. Can you change the
program to print twice as many of one than the other? How does the maze look then?
Clue: We used 205.5 so that when we add a random number between 0 and 1, we
end up with 205.something half the time and 206.something the other half of the the
time. If you reduce 205.5 towards 205, or increase it towards 206 you will change
the relative proportion of each character that appears.

9-44
2. Can you modify the “guess my number” program to choose a number be-
tween 1 and 10?
At the moment, the program picks a number between 1 and 100. Modify the program
so that it picks a number from a different range. Don’t forget to update the message
printed to the user. Do they still need 10 guesses? Change the maximum number of
guesses they get before losing to a more suitable amount.
Clue: You will need to modify the line that sets SN, as well as the PRINT message that
gives instruction to the user.
3. Set the screen, border and text colour to random colours
Modify either the maze or “guess my number” program to use random colours. How
might you make sure that the text is always visible?
Clue: Use the FOREGROUND, BACKGROUND and BORDER commands to set the colours.
Use colour numbers between 0 and 15, inclusive. You can put a calculation at the end
of these commands in place of a simple number.
Clue: To make sure you don’t set the text colour to the same as the background, you
might like to calculate which background colour you wish to use and keep it in one
variable, and then calculate the text colour to use and store it in a different variable.
If the two variables have the same number, then you need to change one of them.
4. Make the “guess my number” program randomly choose between two differ-
ent greeting messages when it starts.
The “guess my number” program currently always prints the same message every time
it starts. Modify it so that it prints one of two possible messages each time.
Clue: Use RND(1) to obtain a random number. If that number is less than some thresh-
old, print the first message, else print the second message.
Clue: It might be easier if you store the random number in a variable, so that you can
use two IF statements to decide whether to print each message.
Clue: If you use < (less than) as the relational operator in one of the IF statements,
you will need to use the opposite in the other one. The opposite of less than is greater
than or equal to.

9-45
9-46
CHAPTER 10
Text Processing
• Characters and Strings
• String Literals
• String Variables
• String Statements
• Simple Formatting
• Sample Programs
10-2
CHARACTERS AND STRINGS
Representing textual information in the form of printable letters, numbers and symbols
is a common requirement of many computer programs. The need for text arises in word
processing applications and word games. It is also required in natural language pro-
cessing and text-based adventure games, both of which need to understand the input.
Understanding text input is called parsing. In short, text processing is used everywhere.
In order to input, output and manipulate such information, we must introduce two key
concepts: characters and strings.
Characters can be printable or non-printable. A character most often represents a
single, primitive element of printable text which may be displayed on the screen via
the statement PRINT. It is most common and most natural to think of a character as
representing a letter of an alphabet. A character might, for example, be any of the
uppercase letters ’A’ to ’Z’, or any of the lowercase letters ’a’ to ’z’. However, charac-
ters can also represent commonly used symbols such as punctuation marks or currency
symbols. Indeed, characters can also represent the decimal digits, ’0’ to ’9’. It is worth
noting that this refers to the text-based representation of the numerals 0 to 9 as
printable symbols as opposed to their numeric counterparts. In addition, the MEGA65
provides an extensive range of special symbols that can be used together for games,
for drawing fancy borders or art. Besides displaying information, such symbols can
create simple yet intruiging visual patterns. For convenience, these special symbols
appear on the front sides of the MEGA65’s keys.
A character can also be non-printable. Using such characters (in a PRINT statement)
can activate certain behaviors or cause certain modes to become active, such as the
switching of all text on the screen to lowercase or setting the foreground colour to
orange. Other non-printable characters might represent a carriage return or clear
the screen.
For a complete catalog of available characters, refer to Chapter/Appendix D on
page D-3. The table lists the characters that correspond to a given code number.
The code number must be supplied as an argument to the statement CHR$ which,
when combined with the PRINT statement, outputs the respective characters to the
screen.
Here’s an example of printing the exclamation mark using a character code:

PRINT CHR$ (33)


!

Note that the ’!’ is actually visible on the display because it is a printable character.
Here’s an example of changing the foreground colour to white using character codes:

PRINT CHR$ (5)

10-3
Although no character is output, all subsequent printable characters displayed will be
coloured white.
Sometimes it can be useful to do the conversion in reverse: from a character to its
code number. To do this, a single character must be supplied as an argument to the
statement ASC within quotation marks which, when combined with the PRINT state-
ment, outputs the respective code number to the screen in decimal.
Here’s an example of obtaining the code number for the exclamation mark.

PRINT ASC ("!")


33

And here’s an example of obtaining the code number for the exclamation mark and
storing it in an integer variable:

A % = ASC ("!")

Although we could output individual characters repeatedly by using CHR$ it would be


tedious to do this all the time.
The concept of a string is needed because it embodies the idea of a contiguous block
of text. Thus, a string can contain multiple printable and/or multiple non-printable
characters in any combination. A string can potentially be empty and contain no char-
acters at all. To write a string we enclose the characters inside quotation marks. So
”HELLO WORLD!” is an example of a string literal.

PRINT " HELLO WORLD !"


HELLO WORLD !

All strings have a property called length which is how many printable and non-printable
characters there are present in that string. The length can be as low as 0 (the empty
string) or as high as 255. Attempting to create a string with a length in excess of 255
characters results in a ?STRING TOO LONG ERROR.
PRINT LEN (" HELLO WORLD !")
12

PRINT LEN ("")


0

It is possible to create variables specifically for strings. All such string variables have
names that begin with a leading alphabetic character, have an optional second char-
acter that is alphanumeric, and end with a $ sign. Once given a value, they can be
used with PRINT.

10-4
AB$ = " HELLO WORLD !": PRINT AB$
HELLO WORLD !

A1$ = " HELLO WORLD !": PRINT LEN ( A1$ )


12

STRING LITERALS
String literals can be joined with one or more other such string literals to form a com-
pound string. This process is called concatenation. To concatenate two or more string
literals, use the + operator to chain them together.
Here are some examples:

PRINT (" SECOND " + " HAND ")


SECONDHAND

PRINT (" COU NTER " + " CLOCK " + " WISE ")
COUNTERCLOCKWISE

Sometimes punctuation or spaces may be required to make the final output appear
correctly formatted, as in the following example.

PRINT (" FRUIT : " + " APPLE , " + " PEAR AND " + " R A S P B E R R Y .")
FRUIT : APPLE , PEAR AND R A S P B E R R Y .

STRING VARIABLES
Concatenation is more commonly used with string variables combined with string lit-
erals. For example, in a text-based adventure game you might want to list some exits
such as north or south. Because these exits will vary depending on the location you
are currently at it would make sense to use variables for the exits themselves and use
concatenation with literals such as commas, spaces and full stops to format the output
appropriately.

A$ = " PEA ": B$ = " NUT ": PRINT ( A$ + B$ + " BUTTER ")
PEANUTBUTTER

It is also possible to use strings as the parameters of DATA statements, to be read


later, using the READ statement. The following example also demonstrates that arrays
can hold strings too.

10-5
10 DIM A$ (6)
20 PRINT " R AINBO W COL O UR S : ";
30 FOR I = 0 TO 5
40 : READ A$ ( I ): PRINT ( A$ ( I ) + " , ");
50 NEXT I
60 READ A$ ( I ): PRINT (" AND " + A$ ( I ) + ".")
70 DATA " RED " , " ORANGE " , " YELLOW " , " GREEN " , " BLUE " , " INDIGO " , " VIOLET "

It is common for string data or single-character data to come directly from user input.
When the user types some text, that text will often need to be be parsed or printed
back to the screen. In general, there are three main ways that this can be done: via
the GET statement, via the GETKEY statement or via the INPUT statement.
All three statements have different behaviours, and it’s important to understand how
each one operates by constrasting and comparing them.
The GET statement is useful for storing the current keypress in a variable. The program
does not wait for a keypress: it continues executing the next statement immediately.
For this reason it is sometimes important to place the GET statement inside some kind
of loop—the loop is to be exited only when a valid keypress is detected. If the variable
to GET is a string variable and no keypress is detected, then that string variable is set
to equal an empty string.

10 GET A$ : REM DO NOT WAIT FOR A KEYPRESS - - READ ANY K E Y P R E S S INTO THE V A R I A B L E
20 PRINT A$ : IF ( A$ = " Y " OR A$ = " N ") THEN END
30 GOTO 10

The GETKEY statement is also useful for storing the current keypress in a variable. In
constast to the GET statement, the GETKEY statement, when executed, does wait for
a single keypress before it continues executing the next statement.

10 GETKEY A$ : REM WAIT FOR A KEYPRESS - - PAUSE AND READ IT INTO THE V A R I A B L E
20 PRINT A$ : IF ( A$ = " Y " OR A$ = " N ") THEN END
30 GOTO 10

While GET and GETKEY are fine for reading single characters, the INPUT statement is
useful for reading in entire strings—that is, zero or more characters at a time.
When the INPUT statement is used with a comma and a variable, the prompt string
is displayed normally with a cursor that permits the user to type in some text. When
the INPUT statement is used with a semicolon and a variable, the prompt string is
displayed with a question mark appended and a cursor that permits the user to type
in some text.
10 INPUT " ENTER YOUR NAME " , A$ : REM NOT A Q U E S T I O N
20 PRINT (" HELLO " + A$ )

10-6
10 INPUT " WHAT IS YOUR NAME "; A$ : REM A Q U E S T I O N
20 PRINT (" HELLO " + A$ )

RETURN
In either case, pressing will complete the text entry—the text entered will be
stored in the given variable. Note that if the string variable is already equal to some
RETURN
string and is pressed without entering in new data, then the old string value
currently stored in the variable is retained.

STRING STATEMENTS
There are three commonly-used string manipultion commands: MID$, LEFT$ and
RIGHT$. These are good for isolating substrings, including individual characters.
The following program asks for an input string and then prints all left substrings.

10 INPUT " ENTER A WORD :" , A$


20 PRINT " ALL LEFT S U B S T R I N G S ARE :"
30 FOR I = 0 TO LEN ( A$ )
40 : PRINT LEFT$ ( A$ , I )
50 NEXT I

The following program asks for an input string and then prints all right substrings.

10 INPUT " ENTER A WORD :" , A$


20 PRINT " ALL RIGHT S U B S T R I N G S ARE :"
30 FOR I = 0 TO LEN ( A$ )
40 : PRINT RIGHT$ ( A$ , I )
50 NEXT I

The following program ask for an input string consisting of a first name following by a
space followed by a last name. It then outputs the initial letters of both names.

10 INPUT " ENTER A FIRST NAME , A SPACE AND A LAST NAME :" , A$
20 N = -1
30 FOR I = 1 TO LEN ( A$ )
40 : IF ( MID$ ( A$ , I , 1) = " ") THEN N = I : GOTO 60
50 NEXT I
60 IF ( N = -1) THEN GOTO 10
70 PRINT " I N I T I A L S ARE : "; MID$ ( A$ , 1 , 1 ) + " . " + MID$ ( A$ , N + 1 , 1)+"."

10-7
SIMPLE FORMATTING
Suppressing New Lines
When using the PRINT statement in a program, the default behaviour is to output the
string and then move to the next line. To stop the behaviour of automatically moving
to the next line, simply append a ; (semicolon) after the end of the string. Constrast
lines 10, 20 and 30 in the following program.

10 PRINT " THIS A SINGLE LINE OF TEXT ": REM A NEW LINE IS ADDED AT THE END
20 PRINT " THE SECOND LINE "; : REM A NEW LINE IS S U P P R E S S E D
30 PRINT " USES A S E M I C O L O N " : REM A NEW LINE IS ADDED AT THE END

Automatic Tab Stops


Sometimes is can be convenient to use the PRINT statement to output information
neatly into columns. This can be done by appending a , (comma) after the end of the
string. Consider the following example program.

10 PRINT " TEXT 1" , " TEXT 2" , " TEXT 3" , " TEXT 4"

Note that each tab stop is 10 characters apart. So TEXT 1 begins at column 0, TEXT
2 begins at column 10, TEXT 3 begins at column 20, and TEXT 4 begins at column 30.

Tabs Stops and Spacing


When printing text on the screen, it is often necessary to format text by using spaces
and tabs. Two commands come in handy here: SPC and TAB.
The command SPC(5), for example, moves five characters to the right. Any intervening
characters that lie between the current cursor position and the position five characters
to the right are left unchanged.
The commmand TAB(20), for example, moves to column 20 by subtracting the cursor’s
current position away from twenty and then moving that number of characters to the
right. If the cursor’s initial position is to the right of column 20 then the command does
nothing. This command can often be used to make text line up neatly into columns.

SAMPLE PROGRAMS
We conclude with some examples.

10-8
Palindromes
A palindrome is a word or phrase or number that reads the same forwards as it does
backwards. Some examples are: CIVIC, LEVEL, RADAR, MADAM and 1234321. The
following program reverses the input text and then determines whether the original
phrase is equal to the reversed phrase.

10 REM *** PALINDROMES ***


20 INPUT "ENTER SOME TEXT: ", A$
30 B$ = ""
40 FOR I = 1 TO LEN(A$)
50 : B$ = MID$(A$, I, 1) + B$
60 NEXT I
70 IF (A$ = B$) THEN PRINT (A$ + " IS A PALINDROME"): ELSE PRINT (A$ + " IS NOT A PALINDROME")
80 GOTO 20

Simple Ciphers
We now look at three simple examples of scrambling and unscrambling English lan-
guage text messages. This scrambling and unscrambling process is the study of cryp-
tography and is used to keep information secure so that it can’t be read by others
except for those privileged to know the cipher’s method and secret key.
The process of scrambling a given message is called encryption. The ordinary, read-
able unscrambled text is called plaintext. Encrypting plaintext results in a scrambled
messsage. This scrambled text is called ciphertext. The process of unscrambling the
ciphertext is called decryption. Decrypting the ciphertext results in an unscrambled
message—the plaintext.
Suppose that we were to encrypt some plaintext and then send the resulting ciphertext
to a friend. Provided that the friend knows the method and secret key used to scramble
the message, they could then decrypt the ciphertext and would be able to recover and
read our original plaintext message.
If someone else attempts to read the ciphertext using the wrong method and/or the
wrong secret key, the resulting text will be unintelligible.
The cryptographic systems we describe here are very simple. Obviously, they shouldn’t
be used today because they are easily broken by techniques of cryptanalysis. Nev-
ertheless, they illustrate some basic techniques and show how we might structure a
sample program.
We investigate three ciphers. These are the ROT13 cipher, the Caesar Cipher and the
Atbash Cipher. These are part of a group of ciphers known as affine ciphers.
Mathematically, it is useful to think of the letters of the English alphabet as numbered.
A is 0, B is 1 and so, with Z being equal to 25.

10-9
Letter A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Value 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
A key mathematical component of a cryptographic system is modular arithmetic,
sometimes casually referred to as ”clock arithmetic” because the numbers begin at
zero and increase until they reach an upper limit, at which point they wrap around
back to zero again, much like a circle. In our case, since there are 26 letters in the
English alphabet, we use modulo 26 arithmetic—our letters are numbered from 0 to
25.
0
23 3

16 10
13

To reduce a given number using modulo 26 we can use the following function:
⌊x⌋
f (x) = x − × 26
26

This says that to obtain the value of a number x using modulo 26 we first divide x by
26 and round down, which gives us the number of times we went around the circle.
We then multiply this result by 26 again and subtract this from x. The final result is the
remainder left over and will always be a value between 0 and 25.
As an example, the number 28 in modulo 26 is equal to 2:
⌊ ⌋
28
f (28) = 28 − × 26 = 28 − 1 × 26 = 2
26

The program at the end of this chapter makes use of this formula by defining a corre-
sponding function at line 30:

DEF FN F ( X )= X - INT ( X / 26 ) * 2 6

ROT13: When we encrypt each plaintext letter we move forward 13 places. So the
plaintext letter A becomes the ciphertext letter N, B becomes O, with latter letters
”wrapping around” back to the beginning of the alphabet. Thus, the plaintext letter Z
becomes the ciphertext letter M. This covers encryption. To decrypt each ciphertext
letter we simply repeat the process by moving forward 13 places again, which brings us
full circle, back to where we started. Thus, a ciphertext letter N becomes the plaintext
letter A.

10-10
We can see this visually as a mapping in the form of a table:

English Plaintext A B C D E F G H I J K L M
ROT13 Ciphertext N O P Q R S T U V W X Y Z
English Plaintext N O P Q R S T U V W X Y Z
ROT13 Ciphertext A B C D E F G H I J K L M
To encrypt using ROT13, find the plaintext letter in the top row and move down to
the bottom row to find the corresponding ciphertext letter. To decrypt using ROT13,
find the ciphertext letter in the bottom row and move up to the top row to find the
corresponding plaintext letter.
If we consider the ROT13 cipher from a mathematical standpoint, we can see that to
both encrypt and decrypt we simply add 13 to the numerical value of a plaintext or
ciphertext letter and reduce it using modulo 26. This gives us a new number between
0 and 25 which corresponds to the encrypted or decrypted letter. Function EROT 13 is
the encryption function. It accepts the value of a plaintext letter x as an argument and
returns the value of the ciphertext letter as a result. Function DROT 13 is the decryption
function. It accepts the value of a ciphertext letter x as an argument and returns the
value of the plaintext letter as a result.

EROT 13 (x) = (x + 13) mod 26

DROT 13 (x) = (x + 13) mod 26

Notice that the definitions of both the encryption and decryption functions are, in this
case, exactly the same.
Atbash: Atbash is an ancient technique used to encrypt the 22-letter Hebrew alpha-
bet, but we can apply the same logic to encrypt the 26-letter English alphabet. To
encrypt a letter using Atbash we need to consider the English alphabet written back-
wards. So encrypting the plaintext letter A becomes the ciphertext letter Z, B becomes
Y, C becomes X and so on. Decrypting the ciphertext works the same way: the ci-
phertext letter A becomes the plaintext letter Z, B becomes Y, C becomes X and so
on.
We can see this visually as a mapping in the form of a table:

English Plaintext A B C D E F G H I J K L M
Atbash Ciphertext Z Y X W V U T S R Q P O N

10-11
English Plaintext N O P Q R S T U V W X Y Z
Atbash Ciphertext M L K J I H G F E D C B A
To encrypt using Atbash, find the plaintext letter in the top row and move down to
the bottom row to find the corresponding ciphertext letter. To decrypt using Atbash,
find the ciphertext letter in the bottom row and move up to the top row to find the
corresponding plaintext letter.
If we consider the Atbash cipher from a mathematical standpoint, we can see that
to encrypt and decrypt, we need to multiply by 25 and then add 25 to the numerical
value of the plaintext or ciphertext and reduce it using modulo 26. This gives us a new
number between 0 and 25 which corresponds to the encrypted or decrypted letter.
Function EAtbash is the encryption function. It accepts the value of a plaintext letter
x as an argument and returns the value of the ciphertext letter as a result. Function
DAtbash is the decryption function. It accepts the value of a ciphertext letter x as an
argument and returns the value of the plaintext letter as a result.

EAtbash (x) = (25 × x + 25) mod 26

DAtbash (x) = (25 × x + 25) mod 26

Notice that the definitions of both the encryption and decryption functions are, in this
case, exactly the same.
Caesar: The Caesar cipher is also an ancient technique used encrypt and decrypt
messages. To encrypt a letter using the Caesar cipher we move three positions for-
ward. So encrypting the plaintext letter A becomes the ciphertext letter D, B becomes
E, C becomes F and so on. Decrypting the ciphertext works the opposite way. In-
stead of moving forward, we move three positions backward. The ciphertext letter A
becomes the plaintext letter X, B becomes Y, C becomes Z and so on.
We can see this visually as a mapping in the form of a table:

English Plaintext A B C D E F G H I J K L M
Caesar Ciphertext D E F G H I J K L M N O P
English Plaintext N O P Q R S T U V W X Y Z
Caesar Ciphertext Q R S T U V W X Y Z A B C
To encrypt using the Caesar cipher, find the plaintext letter in the top row and move
down to the bottom row to find the corresponding ciphertext letter. To decrypt using
the Caesar cipher, find the ciphertext letter in the bottom row and move up to the top
row to find the corresponding plaintext letter.

10-12
If we consider the Casear cipher from a mathematical standpoint, we can see that to
encrypt, we need to add 3 to the numerical value of the plaintext and reduce it using
modulo 26. This gives us a new number between 0 and 25 which corresponds to the
encrypted letter. To decrypt, we need to subtract 3 from the numerical value of the
ciphertext and reduce it modulo 26. This gives us a new number between 0 and 25
which corresponds to the decrypted letter.
Function ECaesar is the encryption function. It accepts the value of a plaintext letter
x as an argument and returns the value of the ciphertext letter as a result. Function
DCaesar is the decryption function. It accepts the value of a ciphertext letter x as an
argument and returns the value of the plaintext letter as a result.

ECaesar (x) = (x + 3) mod 26

DCaesar (x) = (x − 3) mod 26

Notice that the definitions of both the encryption and decryption functions are, in this
case, different.
We can generalise all three of the above methods by stating that they use the following
encryption and decryption functions:

E(x) = (A1 x + B1 ) mod 26

D(x) = (A2 x + B2 ) mod 26

Here, A1 , A2 , B1 and B2 are constants and put together they comprise the encryption
key for an affine cipher.
Running the following program displays a text menu. The user can choose to encrypt
or decrypt a string, or quit the program. You can practice typing in a plaintext phrase
to encrypt and then decrypt the ciphertext phrase to retrieve the orginal plaintext.
A good sample text string for testing a cipher is:
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
This text string, which is 43 characters long, contains 8 spaces and 35 alphabetic
characters. Every character of the alphabet occurs at least once in this string, so
encrypting and decrypting with it checks that every letter is transformed as expected.
Encrypting the above text string using the ROT13 cipher yields:
GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT
Encrypting the above text string using the Atbash cipher yields:

10-13
GSV JFRXP YILDM ULC QFNKH LEVI GSV OZAB WLT
Encrypting the above text string using the Caesar cipher yields:
WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ

10-14
10 REM *** C R Y P T O G R A P H Y ***
20 POKE 0 ,65: PRINT CHR$ (142): PRINT CHR$ (147)
30 DEF FN F ( X )= X - INT ( X / 2 6 ) * 2 6
40 C$ ="": P$ =""
50 PRINT " SELECT AN OPTION (E , D OR Q ):": PRINT
60 PRINT "{ SPACE *3}[ E ] EN C R Y P T P L A I N T E X T ": PRINT
70 PRINT "{ SPACE *3}[ D ] DE C R Y P T C I P H E R T E X T ": PRINT
80 PRINT "{ SPACE *3}[ Q ] QUIT ": PRINT
90 GET S$
100 IF ( S$ =" Q ") THEN END
110 IF ( S$ =" E ") THEN GOSUB 150: GOTO 40
120 IF ( S$ =" D ") THEN GOSUB 270: GOTO 40
130 GOTO 90
140 REM EN CRY PT
150 INPUT " ENTER P L A I N T E X T M E S S A G E TO E N C R Y P T : " , P$
160 IF P$ ="" THEN GOTO 150
170 M$ = P$ : GOSUB 390
180 IF ( V =0) THEN GOSUB 460: GOTO 150
190 A =1: B =3
200 FOR I =1 TO LEN ( P$ )
210 : L$ = MID$ ( P$ ,I ,1)
220 : IF ( L$ =" ") THEN C$ = C$ +" ": ELSE C$ = C$ + CHR$ (65+( FN F ( A *( ASC ( L$ ) -65)+ B )))
230 NEXT I
240 PRINT : PRINT "{ R EV E R S E ON } E N C R Y P T E D C I P H E R T E X T :{ R E V E R S E OFF }" , C$ : PRINT
250 RETURN
260 REM DE CRY PT
270 INPUT " ENTER C I P H E R T E X T M E S S A G E TO D E C R Y P T : " , C$
280 IF C$ ="" THEN GOTO 270
290 M$ = C$ : GOSUB 390
300 IF ( V =0) THEN GOSUB 460: GOTO 270
310 A =1: B = -3
320 FOR I =1 TO LEN ( C$ )
330 : L$ = MID$ ( C$ ,I ,1)
340 : IF ( L$ =" ") THEN P$ = P$ +" ": ELSE P$ = P$ + CHR$ (65+( FN F ( A *( ASC ( L$ ) -65)+ B )))
350 NEXT I
360 PRINT : PRINT "{ R EV E R S E ON } D E C R Y P T E D P L A I N T E X T :{ R E V E R S E OFF }" , P$ : PRINT
370 RETURN
380 REM V A L I D A T E
390 V = 1
400 FOR I =1 TO LEN ( M$ )
410 : L$ = MID$ ( M$ ,I ,1)
420 : IF NOT ((( L$ >= " A ") AND ( L$ <= " Z ")) OR ( L$ =" ")) THEN V = 0
430 NEXT I
440 RETURN
450 REM ERROR M ESS AGE
460 PRINT : PRINT " USE L E T T E R S AND SPACES ONLY ": PRINT
470 RETURN

10-15
If you wish to use the ROT13 cipher ensure that the following lines are changed:

190 A =1: B =13


310 A =1: B =13

If you wish to use the Atbash cipher ensure that the following lines are changed:

190 A =25: B =25


310 A =25: B =25

If you wish to use the Caesar cipher ensure that the following lines are changed:

190 A =1: B =3
310 A =1: B = -3

The program listing, as written, uses the Caesar cipher by default.

10-16
CHAPTER 11
C64, C65 and MEGA65 Modes
• Switching Modes from BASIC
• The KEY Register
• Accessing Memory from BASIC 65
• The MAP Instruction
11-2
The MEGA65, like the C65 and the C128, has multiple operating modes. However,
there are important differences between the MEGA65 and both of these earlier com-
puters.
By default, the MEGA65.ROM file boots to MEGA65-mode (including BASIC 65), and
provides a method to switch to C64-mode via the GO 64 command. However, it is also
possible to use an original C65 ROM (version 91XXXX.BIN) renamed to MEGA65.ROM,
making the MEGA65 start in C65-mode with BASIC 10. This also provides the same
functionality to switch to C64-mode.
Therefore, dependent on your boot ROM choice, you have:
Boot Mode ROM version BASIC C64-mode
MEGA65 92XXXX BASIC 65 GO 64
C65 91XXXX BASIC 10 GO 64
For readers familiar with the C128, the most important difference is that all of the
MEGA65’s new features can be accessed from every mode, and that you can even
switch back and forth between the different modes. It’s also possible to create hybrid
modes that combine different features from the different modes – all you need is the
MAP instruction and the KEY register address, which is 53295 ($D02F).
This chapter explains the different modes, the MAP instruction, and the KEY register,
which allows you to change the mode of operation of the MEGA65. This chapter also
explains how to use BASIC commands to switch from one mode to another.

SWITCHING MODES FROM BASIC


The MEGA65 is used in either C64-mode (running BASIC 2), C65-mode (running BA-
SIC 10) for ROM versions 91XXXX, or MEGA65-mode (running BASIC 65) for ROM
versions 92XXXX.
However, various MEGA65 features can be accessed from all modes, and all MEGA65
features are available to programs written in assembly language / machine code.
More information on how to write such programs can be found in the various appen-
dices.

From MEGA65/C65 to C64-mode


To switch from MEGA65/C65 to C64-mode, use the familiar GO 64 command, which is
identical to switching to C64 mode on a C128:

GO 64
ARE YOU SURE? Y

11-3
Note that any programs in memory will be lost in the process of switching modes. This
is the same as the C128. Alternatively, you can hold ` down while pressing the
reset button or switching the MEGA65 on. Again, this is the same as the C128.

From C64 to MEGA65/C65-mode


To switch from C64 to MEGA65/C65-mode, use the following command. Note that
this command does not ask you for confirmation!

SYS 58552

Alternatively, you can switch back to MEGA65/C65-mode by pressing the reset button
on the left-hand side of the MEGA65, or by switching the MEGA65 off and on again.
RESTORE
Another option is to press and hold for between half to one second, and then
press F5 from the Freeze Menu. This simulates pressing the reset button.
Note that any programs in memory will be lost in the process of switching modes. This
is the same as the C128.

Entering Machine Code Monitor Mode


The Machine Code Monitor can be entered by typing either the MONITOR command
RUN
from BASIC 65/10, or by holding STOP down, and then pressing the reset button on
the left-hand side of the MEGA65.

THE KEY REGISTER


The MEGA65 has a VIC-IV video controller chip instead of the C64’s VIC-II or the
C65’s VIC-III. Just as the VIC-III has extra registers compared to the VIC-II, the VIC-IV
has even more registers. If these were visible all the time, software that was made for
the C64 and VIC-II may inadvertently use these new registers, resulting in unexpected
behaviour. Therefore, the creators of the C65 created a way to hide the extra VIC-III
registers from old C64 programs. Enabling and disabling (or hiding and un-hiding) the
extra registers is done via the KEY register. For more information about which registers
are disabled and enabled in each of the VIC-II, VIC-III and VIC-IV I/O modes, refer to
Chapter/Appendix I on page I-8.
The KEY register, located at address 53295, is an unused register of the VIC-II, which
you can POKE to and PEEK from, similar to other registers. But the KEY register has a
special function: If you write two certain values to it in quick succession, you can tell
the VIC-IV to stop hiding the VIC-III or VIC-IV registers from the rest of the MEGA65.

11-4
Exposing Extra C65 Registers
For example, to enable the VIC-III’s new registers when in C64-mode, you must POKE
the values 165 and 150 into the KEY register. The easiest way to do this is to switch
your MEGA65 off and on again, and type GO 64 and answer Y to enter C64-mode.
NOTE: If you perform these POKEs while in C65-mode, the MEGA65 may not function
correctly.
Once you are in C64-mode, try typing the following commands:

POKE 53295,165: POKE 53295,150

When you enter these commands, the MEGA65 returns a READY. prompt, and seem-
ingly nothing else has happened. This is expected, because the MEGA65 has only
enabled the VIC-III’s new registers (and some other C65-mode features). The C64
BASIC and KERNAL will still function as normal, and it may appear that nothing has
changed... But things have changed.
For example, you can do something that the C64 and its VIC-II can’t do: smoothly
change one colour to another. The VIC-III has registers that allow you to change the
red, green and blue components of the colours. Now that the VIC-III registers are
enabled, it’s possible to change the colour of the background progressively from blue
to purple, by increasing the red component of the colour that is normally blue on the
C64. The red component value registers are at 53504 – 53759 ($D100 – $D1FF).
Blue is colour 6, so a change to register 53510 (53504 + 6, or $D106) is required.
An example BASIC listing that includes a FOR loop to change the colour is:

FOR I = 0 TO 15 STEP 0.2 : POKE 53510,I : NEXT

Once the program has been entered, type RUN on a new line. This will make the
background of the screen fade from blue to purple. If you would like to make the
effect progress faster, increase the 0.2 to a larger number such as 0.5. To make it
slower, change it to a smaller number such as 0.02. You can also change the red
component by POKEing a different number to 53504 – 53759 ($D100 – $D1FF), the
green component at 53760 – 54015 ($D200 – $D2FF), or the blue component at
54016 – 54271 ($D300 – $D3FF). For example, to have the border and text (since
they are both normally “light blue”) fade from blue to green, you can try:

POKE 53518,0 : FOR I = 0 TO 15 STEP 0.1 : POKE 53774,I : POKE 54030,15-I : NEXT

Disabling the C65/MEGA65 Extra Registers


You can also disable the VIC-III registers again by POKEing any number into the KEY
register, e.g.:

11-5
POKE 53295,0

If you RUN the examples above again, the colours won’t change because the registers
are disabled. Instead, writing to those addresses changes some of the VIC-II’s regis-
ters, as on a C64 they appear several times over. Fortunately for the above example,
the registers used have no obvious side-effects. This is because the modified registers
in the examples above on a standard VIC-II are used to change the sprite positions.
Since there are no sprites on the screen, you won’t see anything change.

Enabling MEGA65 Extra Registers


The MEGA65 has even more registers than the C65. To enable these in C64-mode,
it’s required to POKE another two values into the KEY register:

POKE 53295,71: POKE 53295,83

Again, you won’t see any immediate difference, which is similar to when enabling the
VIC-III registers. However, now the MEGA65 can access not only the VIC-II and VIC-III
registers, but also the VIC-IV registers. If you like, you can try the examples from earlier
in this chapter to see that the VIC-III registers are accessible again. But now you can
also do MEGA65 specific things. For example, if you wanted to move the start of the
top border higher on the screen, you can try something such as:

POKE 53320,60

Alternatively, you can have some fun and animate the screen borders, by having them
move closer and further apart:

FOR I = 255 TO 0 STEP -1 : POKE 53320,I : POKE 53322, 255 - I : NEXT

The above example has the loop count backwards (from 255 to 0), so that your don’t
end up with only a tiny sliver of the text visible. You can make it go forwards if you like.
RUN RESTORE
If you do get stuck with only a sliver of the screen, you can press STOP and .
RUN RESTORE
You might be wondering: Why does and STOP work when these are VIC-IV
registers that the C64-mode BASIC and KERNAL don’t know about? The reason is
the VIC-IV has a feature called “hot registers”, where certain C64 and C65 registers
cause some MEGA65 registers to be reset to the C64 or C65-mode defaults. In this
particular case, it is the KERNAL resetting the VIC-II screen using 53265 ($D011),
which adjusts the vertical border size in C64/C65-mode, and is thus a “hot register”
for the MEGA65’s vertical border position registers.

11-6
See if you can make the screen shake around instead by changing the TEXTXPOS
and TEXTYPOS registers of the VIC-IV. You can find out the POKE codes for those,
and lots of other interesting new registers by looking through Chapter/Appendix P on
page P-5.

Traps to Look Out For


In all modes, the DOS for the internal 3.5” disk drive (including when you use D81
disk images from an SD card) resets the KEY register to VIC-II mode whenever it is
accessed. This means if you perform actions such as check the drive status, or LOAD or
SAVE a file, the KEY register will be reset, and only the VIC-II registers will be enabled.
You can of course enable the C65 or MEGA65 registers by POKEing the correct values
to the KEY register again.

ACCESSING MEMORY FROM BASIC


65
BASIC 65 contains powerful memory banking and Direct Memory Access (DMA) com-
mands that can be used to read, fill, copy, and write areas of memory beyond the
C65’s 128KB of RAM. The MEGA65 has 384KB of main memory, split into 6 banks of
64KB each. They are:
• BANK 0 and BANK 1 - acts as the C65’s normal 128KB RAM.
• BANK 2 and BANK 3 - normally write-protected, and contains the C65’s ROM
image.
• BANK 4 and BANK 5 - used for all graphic routines in BASIC 65 for high resolution
bitplane graphics. BASIC 10 doesn’t use banks 4 and 5.
Using the BANK, PEEK and POKE commands, this region of memory can be easily
accessed, for example:

BANK 4: POKE0,123: REM PUT 123 IN LOCATION $40000


BANK 4: PRINT PEEK(0): REM SHOW CONTENTS OF LOCATION $40000

Or, by using the DMA command, you can copy the current contents of the screen and
colour RAM into BANK 4 with:

DMA 0, 2000, 2048, 0, 0, 4 : REM SCREEN TEXT TO BANK 4


DMA 0, 2000, DEC("F800"), 1, 2000, 4 : REM COPY COLOUR RAM TO BANK 4

You can then put something else on the screen, and copy it back with:

11-7
DMA 0, 2000, 0, 4, 2048, 0 : REM SCREEN TEXT FROM BANK 4
DMA 0, 2000, 2000, 4, DEC("F800"), 1 : REM COPY COLOUR RAM FROM BANK 4

THE MAP INSTRUCTION


The above methods can be used from BASIC. In contrast, the MAP instruction is an
assembly language instruction that can be used to rearrange the memory that the
MEGA65 uses. It is used by the C65 ROM and BASIC 65 to manage what memory it
can use at any particular point in time. For further explanation of the MAP instruction,
refer to the relevant section of Chapter/Appendix J on page J-7.

11-8
PART IV
SOUND AND GRAPHICS
11-10
CHAPTER 12
Graphics
12-2
Let’s have some fun with graphics! In this part of the book, we want to examine the
MEGA65’s graphics modes by walking through example code in machine language
and BASIC to get to know the various options of the MEGA65 in the area of graphics.
First of all, it is important to know that the MEGA65 supports three different basic
graphics modes:
• Bitmap graphics
• Graphics based on character sets
• Bitplanes

BITMAP GRAPHICS
In bitmap graphics every pixel of a graphic is stored separately. The way the pixels
are held in memory varies from system to system and in most cases depends on the
performance of the hardware. If memory were unlimited, the easiest way to remember
a pixel is to save its RGB-values in three separate bytes. Example: 0xFFFFFF for white
would result in three values to be stored: $FF, $FF and $FF. To be honest, this is too
simple and not really efficient. Let’s think about another way. Why not define a colour
table (or colour palette) and store the RGB values once and finally only reference the
colour by its index in the table? This will save us a lot of memory! Let’s imagine we
would create a colourful 8x8 bitmap to represent an ”A” on the screen. Colourful
means, we want it in some brownish colours. The colour table for it may look like this:
Index Colour
0 Black
9 Brown
8 Orange
A Light Red
F Light Grey
7 Yellow
The colour values, by the way, are exact the same as the colour values from the stan-
dard C64 colour palette. Next we design the ”A”. Each pixel references a value from
the colour table above.
7 6 5 4 3 21 0
0 0 0 0 0 0 00 0
1 A F 7 F A 80 0
2 F F 0 0 8 A0 0
3 7 7 0 0 8 A0 0
4 7 F F A A A0 0
5 F A 0 0 8 A0 0
6 A A 0 0 A A0 0
7 8 9 0 0 8 A0 0
But how much memory does this little graphic use?

12-3
If we create a one-dimensional array, we will get an array with 64 elements, because
our graphic consists of 8x8 pixels = 64 colour values that have to be saved. If we
transfer that to the memory of the MEGA65, it means that we have 64 bytes to store
in memory. However, full-screen graphics are made up of far more pixels. On the
C64 and of course also on the MEGA65, 320x200 pixels are required to generate
a graphic that fills the entire screen. If we transfer this to our array, we would have
a total of 64,000 entries. Converted to the memory of the MEGA65, that is 64,000
bytes or nearly 64 kilobytes of data! If we now also consider that the good old C64
only had 64K of RAM available, we recognize the drama! That’s just too much data!
We need strategies to reduce our bitmap data. On the C64, we had two types of
bitmap graphics, each with their own mechanisms to minimise memory usage as much
as possible.
• Hires
• Multicolour (MCM)

Hires
First, a bitmap is divided into blocks of 8x8 pixels each. In order to achieve the full
resolution of 320x200 pixels, 40 of such blocks next to each other builds up a line. If
we now build up 25 lines, we arrive at a graphic that fills the complete screen.

12-4
1111111111222222222233333333334
1234567890123456789012345678901234567890
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Splitting into blocks makes sense because this gives us the chance to reduce the data
drastically. Each line of a 8x8 block are 8 bits, so why not forget the colour indexes and
just say each pixel set represents a ”1” in the line and each pixel not set corresponds
to ”0”.
7 6 5 4 3 2 1 0 dec hex
0 0 0 0 0 0 0 0 0 0 00
1 0 1 1 1 1 0 0 0 120 78
2 1 1 0 0 1 1 0 0 204 CC
3 1 1 0 0 1 1 0 0 204 CC
4 1 1 1 1 1 1 0 0 252 FC
5 1 1 0 0 1 1 0 0 204 CC
6 1 1 0 0 1 1 0 0 204 CC
7 1 1 0 0 1 1 0 0 204 CC
As shown above now you can easily convert the bits of each line to its hex value and
you finally get 8 bytes of data. This is the central idea in hires graphics and with this
concept you save a lot of memory. Here in this example it’s 8 bytes versus the prior
example where 64 bytes were needed to manage all the colour references. Let’s

12-5
count it up for a full screen picture: We have 40x25 blocks, that is 1000 blocks in
total. Each block is 8 bytes, so will result in ”only” 8K for a full screen picture.

This is a brilliant solution, but now have a problem: We lost the colours!

If you look at the first figure, it was very colourful. But do we really need so many
colours? This is the second important concept in hires bitmap graphics: Less colours
means less memory. In fact hires mode limits you to two colours per 8x8 pixel block.
This information is stored in the Screen-RAM, not in the Colour-RAM as one might
assume. And again the idea why is really clever: In Screen-RAM you can hold values
between $00 and $FF whereas in the Colour-RAM it makes only sense to store values
between $0 and $0F to reference one specific colour from the C64 colour palette
which consists of 16 colours ($0-$F). On the MEGA65 you can have even more
colours and you are able to tweak the default colours, but this will be explained later.

Back to the Screen-RAM. Here you store two colours for each 8x8 block. If you split
the byte into its high and low nibble, you have the chance to put a background and
a foreground colour into it! The hex value $0a for example can be seen as $0 (high
nibble) and $a (low nibble). This way we’ll get a black background and light red for
the pixels in the block. In the end this means, a fullscreen hires bitmap will consume
not 8 but 9 Kilobytes. 8K for the raw bitmap data as mentioned earlier and another
1K for the colours inside the Screen-RAM.

Programming simple Hires Bitmaps


Let’s code! But let’s do it in BASIC first before we switch over to machine language.
In order to bring bitmap graphics to the screen, we need to configure the VIC IV chip.
There are several things VIC needs to know before it can find and read bitmap data.
You have to do the following:
• Make sure to have activated the VIC-registers you need (remember the MEGA65
offers different versions of the VIC-chip)
• Set the resolution
• Define a location for the bitmap data
• And finally turn on bitmap mode
All these settings can be configured in different registers of your MEGA65. A reference
of the existing registers for the graphics chip (which of course is the VIC) can be found
in Chapter/Appendix P on page P-5.
Your MEGA65 contains one graphics chip, the VIC IV, which builds on its two prede-
cessors and adds new functions in the form of additional registers to it. These two
predecessors are the VIC II as it was used in the original Commodore 64 and the VIC
III aka ”Bill” as it was planned for the Commodore 65.

12-6
It is important to understand that these different VIC-versions build on each other,
think of it as modes you can turn on or off. VIC III expands the existing registers of
the VIC II while the VIC IV provides you with all existing registers of VIC II and VIC
III, building on them by adding new functionality to previously unused registers. This
means in Chapter/Appendix P on page P-5 not only the registers for the VIC IV are
important to know, but also those from VIC II and VIC III depending on which VIC-mode
you have activated or not. Please keep this in mind.
Make sure to have activated the VIC-registers you need - what does this mean?
Generally speaking, you use the new register $D02F hex or 53295 decimal to switch
between VIC-modes (i.e., to add or remove specific registers). In order to switch you
use some kind of a ”knocking-sequence” by poking two specific values one after the
other:
VIC 1st hex/dec 2nd hex/dec
II $00/0 $00/0
III $A5/165 $96/150
IV $47/71 $53/83
By the way, the two values you use to activate the VIC IV are the ASCII characters
”G” and ”S”. These are the initials of the creator of the VIC IV: Assoc. Prof. Paul
Gardner-Stephen. Funny easteregg, isn’t it?
It is important to understand that, when you turn on your MEGA65, the computer will
start in C64 mode and then looks for a C65-compatible ROM. If a C64 cartridge is
detected or the MEGA-key is pressed the system stays in C64 mode. In this case,
you only have the C64 registers available. If the system finds a C65 ROM, available
registers will be activated. In case of the MEGA65 ROM this means, you can access all
VIC-registers (II,III and IV). When you issue the GO64 command, the system will restrict
you to the VIC II registers - but remember - by poking the knock-sequence as explained
above you can add the registers again! This means it doesn’t matter in which ”mode”
you are. All features are available from everywhere. The MEGA65 is a really flexible
machine!
In this chapter we assume your are in a C65 mode using the standard MEGA65 ROM
with BASIC65.
Next step is to set the resolution. According to the registers in Chapter/Appendix P
on page P-5 you can do this by using $D031 hex, or 53297 decimal. This register is
provided by VIC III. The C65 comes with a 80 column display, the C64 only had 40.
In order to realize 80 columns, the graphics chip needs to be able to handle higher
resolutions. When you turn on the computer you are in 80 column mode with 25 lines
which is a 640x200 resolution. In order to show classic Bitmaps you need to reduce
it down to 320x200 (which are the 40 columns and 25 lines as already shown in the
table before). The C64 was not able to view 640x200, so no need for a register
to control it on the VIC II. The C65 on the other hand is able to do both so you can
use $D031 to switch between them. If you manipulate it by its bits you can control
even more: resolution (databit 7, H640), C65 fast mode (databit 6, FAST) or turning
off and on the new Bitplane-Mode as an alternative to classic bitmap- or char-based
graphics (databit 4, BPM). There are also some registers which were planned, but never

12-7
implemented. For example a H1280-Mode on databit 2 which should make the C65
able to scale up to 1280x200 or 1280x400. See Chapter/Appendix P on page P-5
for all the intricate details.
The next question is, how can we control specific bits in a register? If you turn on your
computer and enter the following command

PRINT PEEK ( $D031 )


224

you get back a decimal value like 224. The decimal value does not help, you need to
convert the number into its binary representation.
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Decimal value
H640 FAST ATTR BPM V400 H1280 MONO INT
1 1 1 0 0 0 0 0 224
0 1 1 0 0 0 0 0 96
The first line in the table shows the binary number for decimal 224, this should be
the case when you turn on your MEGA65. Databit 7, H640-mode is activated as
expected. In the second line you see the value you have to use when you want to
reduce down to 320x200: databit 7 is set to 0, so H640-mode is turned off.

POKE $D031 ,96

But wait, poking the value directly is not always the correct way. If you know exactly
what you do or better which state each bit of the register should have, can you continue
like this. Storing the value 96 means setting all the databits. This is not always what
we want. In some cases we might manipulate one specific bit, for instance databit 7
for the resolution while keeping the other bits in their existing state. You can achieve
this with logical operations using the AND or OR operator.

Operation Result Operation Result


0 AND 0 0 0 OR 0 0
1 AND 0 0 1 OR 0 1
0 AND 1 0 0 OR 1 1
1 AND 1 1 1 OR 1 1
The logic tables above are important because they show how the bits will be modified
if you put an operator on it. If you think about the idea of logical operations in the
example that follows, you will see that you can use AND to reset/clear a specific bit
to zero (via a mask), and use OR can be used to set the bit to 1. To be honest, this
method can not only be used to set a single bit, but also to change any number of
bits but to keep things simple we modify only one. Back to the ”bad” poke of 96 what
we’ve seen above, it could be better written like this:

12-8
POKE $D031 , PEEK ( $D031 ) AND 127 : REM RESET BIT 7 ( i . e . , set it to zero )
POKE $D031 , PEEK ( $D031 ) OR 128 : REM SET BIT 7 ( i . e . , set it to one )

So that you understand these operations, again you need to convert


each decimal number into its binary format. Next we apply the AND /
OR operations bit by bit according to the rules in the prior logic tables.

Binary Decimal Binary Decimal


11100000 224 01100000 96
AND 01111111 127 OR 10000000 128
Result 01100000 96 Result 11100000 224
You can test this, by the way, with some simple PRINT commands:

PRINT 224 AND 127


96

PRINT 96 OR 128
224

Armed with this knowledge, we can now start configuring the VIC to show bitmap
graphics. For this we have to fine-tune a number of registers but before we can start
with that, we need to understand a bit more about the graphics chip, how it is organ-
ised and most importantly how it accesses the memory.
Side-note:
An alternative approach available in BASIC 65 for setting/clearing bits is to use the
new SETBIT and CLRBIT commands. For assembly coders, you have the new SMBx
(set bit x) and RMBx (reset bit x) instructions available to you.

VIC IV organization and memory access basics


In contrast to the cpu of your MEGA65, which can address 64KB at once, the VIC
unfortunately is not able to this. It can only see 16KB, so you have to define exactly
which 16KB it is allowed to see. To achieve this, the 64KB of Bank 0 (this is the memory
bank where VIC is living and getting its data) is divided into blocks of 16KB each.
These 16KB blocks are called ”video banks” or ”VIC banks”.

12-9
Independent of the VIC, the memory management of the Commodore 65 or MEGA65
is somewhat more complex than that of the previous model. This is because there is
more memory available in the machine: For the Commodore 65 128KB where planned
(potentially expandable to 1MB), while the MEGA65 comes with 384KB of chip RAM
+ 8MB of attic RAM (potentially expandable to 256MB). As already mentioned, the
processor is not able to address the whole range of memory. Only 64KB can be seen.
For this reason, the memory is divided into blocks, 64KB each, and these blocks are
called ”banks”.
The system can have up to 16 banks and certain banks also have certain tasks. Banks
0 and 1 are RAM, which means you can read and write to them, while banks 2 and 3
are ROM and not so easy to override.
Bank 0 (from the perspective of the BASIC 65 operating system that runs when you
power the system on) is called the system bank. It contains regions such as:
• The screen RAM, which occupies the memory range $0800-$2000 (by default)
• Memory-mapped VIC registers (if they have been mapped in, and by default,
they are)
By the way, the BASIC65 implementation itself is stored in ROM (bank 3), while the
C64’s BASIC is also stored in ROM (bank 2).
If you want to know more about memory management in general please have a look
at Chapter/Appendix I on page I-3. In BASIC - sorry to say - the situation gets even
more complex. Right after turning on the computer you are in Bank 128 which is a
special bank with a special memory configuration. You can use the command BANK to
switch between banks. A problem here is, that you can easily lose track of what is in
which bank or in which bank you are currently working. It’s actually a bit easier when
working in machine language. For more information about the BANK-command and

12-10
banks in general, please look into Chapter/Appendix B on page B-28. Please keep
in mind that you need to know about banks before you can safely use PEEK, POKE or
SYS. Otherwise you may wonder why your program does not behave as expected. We
will come back to this later. Back to graphics.
Let’s begin to write a simple BASIC program to show hires bitmap graphics. If you fol-
lowed this chapter carefully up to this point, you should have no trouble understanding
the following lines of code:

10 POKE $D020 ,0 : POKE $D021 ,0 : REM MAKE SCREEN BLACK


20 POKE $D031 , PEEK ( $D031 ) AND 127 : REM SET R E S O L U T I O N
30 POKE $DD02 , 3 : REM MAKE V I R T U A L CIA -2 READ - AND W R I T E A B L E
40 POKE $$DD00 , PEEK ( $DD00 ) AND 252 OR 2: REM SELECT VIDEO BANK 1

As you have seen in the illustration on the page before, the VIC chip divides the memory
into 4 video banks of 16KB each. It is important to understand that you do not use a
register of the VIC to define the video bank inside the (memory-)bank 0, instead you
use the data bits 0 and 1 of $DD00 or 56576 decimal. This used to be a register
of the CIA-2 chip on the Commodore 64 but in your MEGA65 it is implemented as
a virtual register. The ”preparation” needed to set the video bank happens in line 30
while in the following line the video bank itself is set. By the way, when you convert
the decimal value 3 (line 30) into its binary format, it is 00000011 and proves: the
data bits 0 and 1 are set to 1, so reading and writing is activated.
Bits VIC bank Memory Area BASIC
00 3 $C000-$FFFF ... AND 252 OR 0 :REM AND 11111100 OR 00000000
01 2 $8000-$BFFF ... AND 252 OR 1 :REM AND 11111100 OR 00000001
10 1 $4000-$7FFF ... AND 252 OR 2 :REM AND 11111100 OR 00000010
11 0 $0000-$3FFF ... AND 252 OR 3 :REM AND 11111100 OR 00000011
The table shows which bits must be set to select a video bank.

12-11
12-12
PART V
MEMORY
12-14
CHAPTER 13
Programming with Memory
• Memory Concepts
• The 28-bit Address Space
• The Chip RAM Memory Map
• Using Memory from BASIC
• Using Memory from Machine Code
• VIC-IV Video Memory
• Large Memory Operations with Direct
Memory Access

• Advanced Memory Topics


13-2
When you write programs in assembly language, understanding how memory works is
crucial. Nearly every operation interacts with memory in some form. Data processing
happens in memory, and programs are stored in and executed from memory. With
a Commodore-style hardware register architecture, every aspect of the computer’s
input and output involves manipulating values through the memory system.
When you write programs in MEGA65 BASIC, you barely have to think about memory at
all. The BASIC system and most of its commands represent data in terms of numbers,
arrays, and strings stored in named variables. You never have to know how that data
is represented as 1’s and 0’s, or which addresses refer to which data. That said,
understanding how memory works can take your BASIC programs to the next level.
You can invent new ways to manage your program’s data, and interface directly with
MEGA65 hardware. Some of the MEGA65’s advanced capabilities are only accessible
from memory registers.
Like several systems in the MEGA65, the memory system is more sophisticated than
you might expect, with multiple modes of operation. When you first switch on your
MEGA65, it starts with a memory configuration intended to support the BASIC 65
environment. A program can reconfigure the memory to take full advantage of the
MEGA65’s capabilities, or to make the memory environment compatible with a Com-
modore 64 (as GO64 does) or a Commodore 65.
In this chapter, you will learn all about the MEGA65 memory system, with a focus
on writing programs for the MEGA65 in BASIC and assembly language. Complete
descriptions of the memory features, including backwards compatibility features for
the C64 and C65, are available in the appendices.

13-3
MEMORY CONCEPTS
A computer performs tasks by manipulating data stored in its memory. Computer
memory consists of many thousands of cells, each containing a single byte of data
capable of representing 256 possible values. Each cell has a numeric address, and
the program using the memory decides what kind of data is stored at each address.
The program itself is stored as bytes in memory, as machine code instructions to be
executed by the CPU.

Bits, Bytes, and Nibbles


A bit is a single digital signal with two possible values: off or on. A bit is often combined
with other bits to represent more possible values. A byte is 8 bits, with 256 possible
values.
Bits and bytes are often used to represent numbers, and often have their values de-
scribed as positive integers even when they represent other kinds of data. When dis-
cussing the bits of a byte, the bits are arranged in increasing place value from right
to left. Bit 0 is the rightmost bit, also known as the “least significant” bit. Bit 7 is the
leftmost bit, also known as the “most significant” bit.1
b7 b6 b5 b4 b3 b2 b1 b0
0 1 1 0 1 0 1 1 = 107
128 64 32 16 8 4 2 1
A nibble is 4 bits. In computer architecture, the term “nibble” refers to one of the two
halves of a byte. The high nibble is bits 7 – 4, and the low nibble is bits 3 – 0.

Hexadecimal Notation
Hexadecimal is a numbering system using sixteen possible values per digit, written as
numerals 0 – 9 followed by letters A – F. It is especially convenient when describing
values in computer memory because each hexadecimal digit represents a nibble (4
bits) of data. The 8-bit binary value %01101011 can be read as the two nibbles 0110
1011, or $6B in hexadecimal.
Memory addresses are often presented in hexadecimal notation. Computer memory
is typically organized in amounts that can be represented as round hexadecimal num-
bers, like $C000.
$0000 $0001 $0002 · · · $0FFE $0FFF $1000 $1001 · · ·
Round hexadecimal numbers represent common memory sizes, like so:
1 See Chapter/Appendix H on page H-3 for a complete explanation of binary and hexadecimal notation.

13-4
$0001 1 byte
$0010 16 bytes
$0100 256 bytes
$0400 1 kilobyte (1KB = 1024 bytes)
$1000 4 kilobytes (4KB = 4096 bytes)
$4000 16KB
$10000 64KB
$100000 1 megabyte (1MB = 1024KB)
Address numbering starts at 0, so regions of these common sizes tend to start with
“0” digits on the right, and stop just before the start of the next region. For example,
$2000 – $2FFF represents a 4KB region.
You can enter numbers as hexadecimal in BASIC using the dollar sign prefix ($). For
example, to display the decimal equivalent of a hexadecimal number in BASIC:
PRINT $C000

To display a number in hexadecimal notation in BASIC, use the HEX$() function:


PRINT HEX$ (127)

When programming in assembly language or using a machine language monitor, ad-


dresses and values are presented in hexadecimal by default.
This book sometimes uses a dot (.) to separate groups of four hex digits to make them
easier to read: FFF.FFFF. You do not type the dot when entering a long address into a
program or command. To enter FFF.FFFF in BASIC, type: $FFFFFFF
Each hex digit represents a nibble of a value. The value FFF.FFFF can be represented
in seven nibbles (28 bits).

Random Access Memory


Random Access Memory (RAM) is memory that contains data temporarily. A program
can read from and write to this data. When the computer is switched off, this data
is deleted. A program that needs to preserve this data must save it to a long-term
storage device like a floppy disk (or the MEGA65 SD card) before the computer is
switched off.
Try this. Enter the following command at the READY. prompt:
POKE $1800 ,127

This POKE command stores the byte value 127 at memory address $1800. Now enter
this command:
PRINT PEEK ( $1800 )

The PEEK() function evaluates to the byte value stored at the memory address $1800,
in this case 127. The PRINT command outputs this value.

13-5
Switch off your MEGA65, switch it back on, and execute PRINT PEEK($1800) again.
The RAM value is reset.

Read-Only Memory
Read-Only Memory (ROM) contains data that is written permanently at the factory.
Like other vintage microcomputers, the Commodore 65 has a ROM chip that contains
the program code for the operating system: BASIC, the KERNAL, routines for accessing
peripherals and performing common calculations. ROM data cannot be overwritten
directly by a program, and it remains in the computer when the computer is turned off.
The MEGA65 does not contain a traditional ROM chip. Instead, the MEGA65 Hypervi-
sor (the operating system that manages the features of the MEGA65) loads the “ROM”
program data from a file on the SD card into a region of RAM. The Hypervisor protects
that RAM as “read only” by default, simulating the ROM chip of a Commodore 65. You
can replace the ROM file on the SD card to upgrade to newer versions of the MEGA65
ROM.
Try this. Enter these commands, and try to predict what the second command will
display. Change 63 to another number then try again.
POKE $2100 ,63
PRINT PEEK ( $2100 )

The address $2100 refuses to accept a new value. A complete explanation of why this
is requires several concepts described in this chapter. For now, it is sufficient to say
that the memory at address $2100 is configured to behave as ROM when accessed
in this way.

I/O Registers
Some addresses refer to special memory cells used by the computer’s hardware. These
are known as I/O registers. You can interact with the hardware by writing data to and
reading data from these addresses. This is how BASIC commands display graphics,
play sounds, and read joysticks: they read and set values in the I/O registers. (“I/O”
refers to the data behaving as input to and output from these devices.)
Try this command. Try replacing 7 with another number between 0 and 31.
POKE $D020 ,7

The VIC video chip uses address $D020 to store the colour of the screen border. The
BORDER command sets this register to achieve the same effect.
BORDER 7

13-6
Addresses
The examples so far have used addresses consisting of four hexadecimal digits, such
as $1800. Each hexadecimal digit represents four bits (one nibble), so a four-digit
hexadecimal number represents a 16-bit address. Such an address is in the range
$0000 – $FFFF, with 65,536 possible addresses. The Commodore 64’s CPU uses
16-bit addresses to access up to 64 kilobytes (64KB) of memory. In other words, the
Commodore 64 has an address space of 16 bits, in the range $0000 – $FFFF.
The MEGA65 has an address space of 28 bits, in the range 000.0000 – FFF.FFFF.
Such addresses can be stored as a 32-bit value with the highest nibble set to 0. In
hexadecimal, this would be an eight-digit number with the leftmost digit of 0. (This
digit is typically omitted from notation.)
The BASIC POKE command and PEEK() function can use 28-bit addresses. For exam-
ple, to store then retrieve a value from RAM at address 800.0000:
POKE $8000000 ,63
PRINT PEEK ( $8000000 )

This example works on the MEGA65 and the DevKit. The Nexys board lacks RAM at
that address, and will ignore attempts to write it.

16-bit Address Translation


The MEGA65’s memory system allows programs to refer to memory using 16-bit ad-
dresses. To determine the full 28-bit address, the memory system translates the ad-
dress according to rules that can be set by the program. This translation is also known
as remapping, or, in some contexts, banking.
16-bit address translation provides several advantages. The 45GS02 CPU processes
16-bit addresses faster than 32-bit addresses. 16-bit addresses take up less space in
memory when stored. Most program tasks operate in a single 64KB region of memory,
so it is often convenient for a program to set the memory configuration at the beginning
of a task and use 16-bit addresses to access that region.
Address translation is a common feature of most microcomputers. The Commodore
64 uses banking to allow programs to access 64KB of RAM and additional ROM and
I/O registers using only 16-bit addresses. The Commmodore 65 was designed such
that the memory system could be configured to resemble a Commodore 64 memory
map through 16-bit address translation, and also support C64-style banking of ROM
and I/O registers.
The MEGA65 provides multiple mechanisms of address translation. Memory system
configuration is one of the more complex topics of MEGA65 programming, and this
chapter covers it in detail.

13-7
Banks and Pages
MEGA65 addresses can be divided into regions of 64KB known as banks. It’s easy to
identify the bank given an address specified in hexadecimal: the leftmost digits of the
address are the bank number, and the rightmost four digits are a location within the
bank.

$ 3 FDA8
Bank Page

For example, the address 3.FDA8 ($003FDA8) is an address in bank $3. The address
0.1800 ($0001800) is an address in bank $0. The address 880.12AB ($88012AB)
is in bank $880.2
It is important to remember that if you see a 16-bit address such as $2100, the actual
bank that it refers to may not be bank 0. The full address depends on how the memory
system is configured, and how the memory is accessed.
A bank can be further divided into regions of 256 bytes known as pages. As with
banks, the page is easy to identify from a hexadecimal address: it is the fourth and
third rightmost digits. For example, page $1C consists of $1C00 – $1CFF. The address
$1CB2 is in page $1C.

How Addresses are Stored in Memory


Computers often manipulate memory addresses as data, including storing addresses
in RAM or in registers. A 16-bit address is stored as two bytes, and a 28-bit address
is stored as four bytes (with the leftmost nibble set to zero).
To determine the bytes for an address, take the hexadecimal digits and group them in
pairs, starting from the rightmost pair. Each pair of digits is a byte value. For example,
the address $853FDA8 can be represented by the bytes $A8, $FD, $53, and $08.
This ordering of the bytes from right to left is known as little-endian byte order. The
MEGA65 stores multi-byte values using little-endian byte order by convention. The
45GS02 CPU, I/O registers, and other routines expect addresses to be stored in this
way.3
For example, to store the 28-bit address 853.FDA8, you need four bytes of memory.
To store this at memory locations 0.1800 – 0.1803, you would start by storing the
rightmost byte ($A8) in location 0.1800. The rest is as follows:
2 Ina few cases, this is better understood as “megabyte $88, bank $0, offset $12AB.”
3 There exist computers that use the opposite ordering convention,
known as big-endian byte order. Most
microcomputers use the little-endian convention.

13-8
A8 FD 53 08

0.1800

0.1801

0.1802

0.1803
When a 28-bit address is stored as four bytes, the upper four bits are unused. There
are a few cases where a 28-bit address is stored in a way that uses those bits for
something else. You must take care when writing such addresses that the upper bits
retain appropriate values. This is typically done with Boolean logic to “mask” the upper
bits.
The following BASIC example sets the variable B to $A9, then updates it such that the
upper nibble is preserved and the lower nibble is set to $3. Try to guess what this will
print before running it.
10 B = $A9
20 B = B AND $F0 OR $03
30 PRINT HEX$ (B )

The Commodore 65 uses a 20-bit address space, so it sometimes only uses five nibbles
(five hexadecimal digits) to encode an address. In a few cases, the MEGA65 extends
this to 28 bits by storing a separate “megabyte byte” in addition to a “bank nibble”
and two bytes for the lower part of the address. An example of this will be explained
later in this chapter.
BASIC 65 includes commands for reading and writing 16-bit values as bytes without
having to convert to little-endian ordering explicitly. WPOKE addr,val sets addr to
the low byte of val, and addr+1 to the high byte of val. Similarly, WPEEK(addr) reads
the bytes at addr and addr+1 and evaluates to the 16-bit number.
WPOKE $1900 , $FFD2

BASIC does not have dedicated commands for reading or writing 32-bit values, but
you can use the 16-bit commands to handle two bytes at a time. Take care to use
little-endian order for each half:
WPOKE $1802 , $0853
WPOKE $1800 , $FDA8

13-9
THE 28-BIT ADDRESS SPACE
The 28-bit addresses form an address space in the range 000.0000 – FFF.FFFF. Only
some addresses are assigned to memory cells. Others are assigned to I/O registers
and other specialty devices. The remaining addresses are unassigned, reserved for
future use by expansion hardware and future versions of the computer.
The MEGA65 and the DevKit have three major regions of assigned address space:
• Chip RAM, 384KB, in range 000.0000 – 005.FFFF
• Attic RAM, 8MB, in range 800.0000 – 87F.FFFF
• I/O registers and specialty RAM, in range F00.0000 – FFF.FFFF
The remaining regions of the address space are reserved for future expansion and fu-
ture models. Nexys boards do not have Attic RAM. See Chapter/Appendix I on page I-
3 for details on the reserved regions.
Chip RAM is the primary working space for the MEGA65. It contains program code,
the MEGA65 ROM code, and space for variables and other data. It is called “Chip
RAM” because it can be accessed by the CPU running at full speed. BASIC and KERNAL
functions use portions of Chip RAM, and your BASIC and machine code programs will
make extensive use of it as well.
Attic RAM provides expanded memory for general use, with a few limitations. Typically,
a program uses Attic RAM via the MEGA65’s Direct Memory Access (DMA) capability
to copy data between Attic RAM and Chip RAM (described later). Attic RAM cannot
be used directly by the VIC chip for graphics data, nor can it be used directly for audio
sample playback (“audio DMA”). The CPU can run code stored in Attic RAM, but it runs
more slowly than code stored in Chip RAM. In general, accessing Attic RAM is about
ten times slower than accessing Chip RAM.
The upper I/O register space is the permanent home for device registers, and memory
for the Hypervisor functions. Most programs access these features indirectly using
the memory configuration features described later in this chapter, especially the VIC
colour RAM, character ROM, and VIC and SID I/O registers. See Chapter/Appendix I
on page I-3 for a detailed list of upper I/O regions.

13-10
THE CHIP RAM MEMORY MAP
The following table summarizes how the MEGA65 KERNAL and BASIC use Chip RAM.

Start End Description


0.0000 0.0000 CPU I/O Port Data Direction
0.0001 0.0001 CPU I/O Port Data
0.0002 0.15FF KERNAL variables and data
0.1600 0.1EFF Free for program use
0.1F00 0.1FFF BASIC bitmap graphics base page
0.2000 0.F6FF BASIC: program text
0.F700 0.FEFF BASIC: scalar variables
0.FF00 0.FFFF Reserved
1.0000 1.1FFF DOS buffers and variables
1.2000 1.F6FF BASIC: arrays and strings
1.F700 1.F7FF Reserved
1.F800 1.FFFF Colour memory window
2.0000 2.FFFF ROM
3.0000 3.FFFF ROM
4.0000 4.FFFF BASIC bitmap graphics, utilities
5.0000 5.FFFF BASIC bitmap graphics, utilities

The ROM banks are arranged in regions. Most programs don’t need to access these
addresses directly.

Start End Description


2.0000 2.3FFF DOS
2.4000 2.8FFF Reserved
2.9000 2.9FFF Character set A
2.A000 2.BFFF C64 BASIC
2.C000 2.CFFF Interface
2.D000 2.DFFF C64 character set (C)
2.E000 2.FFFF C64 BASIC and KERNAL
3.0000 3.1FFF Monitor
3.2000 3.7FFF C65 BASIC
3.8000 3.BFFF C65 BASIC graphics
3.C000 3.CFFF Reserved
3.D000 3.DFFF Character set B
3.E000 3.FFFF C65 KERNAL

13-11
How Programs Use Chip RAM
The two most common kinds of MEGA65 programs are programs written entirely in
BASIC, and programs written entirely in machine code (via assembly language, or a
compiled language such as C or Rust).
A typical BASIC 65 program never accesses memory directly.4 It uses BASIC com-
mands and language features to manipulate variables, arrays, strings, sounds, sprites,
and bitmap graphics. The BASIC system uses all of Chip RAM to support these features,
and manages memory configuration to access registers on behalf of the program. This
requires that the ROM loaded and protected by the Hypervisor remain in place.
A BASIC program that does not use the bitmap graphics system can repurpose the
memory regions assigned to that feature for other purposes. This includes the region
0.1F00 – 0.1FFF, and all of banks 4 and 5. If you intend to use bitmap graphics but
need some spare Chip RAM for another purpose, you can use the MEM command to
reserve blocks in banks 4 and 5. The graphics system knows to avoid regions reserved
by MEM, at the expense of having less memory for more screens, higher resolution, or
higher colour bit depth. For a description of the MEM command, see subsection B.
Some direct mode BASIC tools, such as RENUMBER, make temporary use of memory
in banks 4 and 5. This does not affect a program that initialises its memory when it
starts, but it may interfere with interactive tasks performed at the READY. prompt that
need that memory preserved.
A common technique for using memory from a BASIC program is to take advantage
of the unused “program text” memory after the end of the BASIC program data in
0.2000 – 0.F6FF. If your program needs to do this, note that some BASIC 65 graphics
commands use some of the memory immediately following the end of the program
as temporary storage. Depending on the length of your program, it is usually safe to
choose a high address range, such as 0.C000-0.F6FF, for program use.
BASIC Gfx
KERNAL

Colour
BASIC

BASIC

2.0000 ROM
DOS

Res.


5.FFFF
0.0000
0.1600
0.2000

1.0000
1.2000

4.0000
1.F700
1.F800

A typical program written in machine code never uses the BASIC system at all, and
instead manages its own memory. It might use a short BASIC program to start the
program, but never returns control to the system after the program is invoked. Such a
program is free to use any region of Chip RAM that would otherwise be used by BASIC.
4 Commodore 64 BASIC programmers are accustomed to using POKE and PEEK to access memory and

I/O registers for most functions like graphics, sound, and input devices. BASIC 65 provides dedicated
commands for these functions.

13-12
If the program calls the KERNAL, such as for disk functions, the program must avoid the
areas of Chip RAM reserved for KERNAL use. It can do whatever it likes with the rest.
KERNAL

Colour
2.0000 ROM
DOS

Res.
… … … …

5.FFFF
0.0000
0.1600
0.2000

1.0000
1.2000

4.0000
1.F700
1.F800
If the program never needs to call the KERNAL, it can unlock and remove the ROM
entirely, and claim every byte of the 384KB Chip RAM for its own purposes. Using a
technique discussed later, if you don’t need all 32KB of the MEGA65’s colour RAM,
you can repurpose the “colour RAM window” at 1.F800 as regular Chip RAM.

The Memory Map Contract


The MEGA65 project adopted the ROM code from Commodore’s unfinished draft for
the C65, and invested time and effort into finishing incomplete features and fixing
bugs. This project is on-going, and the MEGA65 team expects to release new versions
of the ROM in the future.
This makes writing programs with the MEGA65 ROM characteristically different to
writing programs with the Commodore 64 ROM, which is etched in silicon and is no
longer under development. It is important to write code that conforms to documented
behaviors described in these manuals—and not rely on undocumented behaviors that
might change in a future version.
It is a goal of the project to keep the Chip RAM memory map consistent with the table
above across future versions of the MEGA65 ROM. To maintain future compatibility,
programs should avoid relying on “reserved” regions as if they were free space. If a
new mode or feature is introduced that changes the memory map, the feature will be
something a program must request, such that older programs that don’t use the new
feature can expect the original memory map.
Within each block of the memory map, only some addresses are guaranteed to remain
constant between ROM versions. For example, a machine code program can invoke
KERNAL routines by calling addresses in a “jump table,” a set of fixed addresses in
ROM guaranteed to remain the same in future versions.5
Except where explicitly documented, programs are not expected to read or modify
KERNAL variables directly. Some memory locations, such as the location of screen
memory, can be determined from (and adjusted by) registers. (See Chapter/Appendix
P on page P-5.)
5 The jump table is not yet described in this book. The C65 used the same jump table as the C128 with

minor changes, and so far the MEGA65 ROM has not extended it. If a ROM revision expands this table,
existing entries will remain constant. See the MEGA65 Wiki for a list: https://mega65.atlassian.net/

13-13
The region of Chip RAM in 0.1600 – 0.1EFF is guaranteed to be unused by the
MEGA65 KERNAL and BASIC. 0.1F00 – 0.1FFF is also available if you do not use the
BASIC bitmap graphics system. This region is exposed as RAM in the default memory
configuration, so it is useful for storing machine code and data that can be accessed
from a BASIC program.

13-14
USING MEMORY FROM BASIC
BASIC 65 includes several commands for accessing and manipulating memory, and
for calling machine code subroutines:
• POKE address, value : stores a value at an address
• WPOKE address, value : stores a 16-bit value starting at an address
• PEEK(address) : reads a value at an address
• WPEEK(address) : reads a 16-bit value starting at an address
• BLOAD filename [,args...] : loads data into memory from a file
• BSAVE filename, P start TO P end [,args...] : saves a region of memory to a
file
• SYS address [,registers...] : calls a machine code subroutine stored at an
address
• EDMA ... : transforms or copies large regions of memory quickly using hardware
accelleration
The BOOT and WAIT commands also operate on memory in some fashion. See the
BASIC 65 Command Reference for more information about these commands.

BASIC Address Remapping


You may have noticed that the addresses from the BASIC POKE commands described
at the beginning of this chapter all refer to areas of Chip RAM described in the memory
map as either “Free for program use,” or “BASIC: program text.” However, they seem
to behave differently:
• POKE $1800,127 behaves like RAM: it sets the memory at the address, and the
memory can be read with PRINT PEEK($1800).
• POKE $2010,63 behaves like ROM: attempting to set the memory does noth-
ing, and reading the memory with PRINT PEEK($2010) returns the original ROM
value.
• POKE $D020,7 behaves like an I/O register: it changes the colour of the border
immediately. While this value can be read with PRINT PEEK($D020), it is not
useful as memory because the border colour changes with the value.

13-15
BASIC 65 commands and functions treat addresses in the range $0000 – $FFFF ac-
cording to special remapping rules, also known as banking. In the default mode, BASIC
65 remaps these addresses as follows:
16-bit address block Mapped address block Type
$0000 – $1FFF 0.0000 – 0.1FFF Chip RAM
$2000 – $3FFF 3.2000 – 3.3FFF ROM
$4000 – $5FFF 3.4000 – 3.5FFF ROM
$6000 – $7FFF 3.6000 – 3.7FFF ROM
$8000 – $9FFF 3.8000 – 3.9FFF ROM
$A000 – $BFFF 3.A000 – 3.BFFF ROM
$C000 – $CFFF 2.C000 – 2.CFFF ROM
$D000 – $DFFF FFD.2000 – FFD.2FFF MEGA65 I/O
$E000 – $FFFF 3.E000 – 3.FFFF ROM
For example, accessing I/O registers via $D000 – $DFFF actually accesses the I/O
registers in the upper region of the address space. These two BASIC commands are
equivalent:
POKE $D020 ,7

POKE $FFD2020 ,7

The BASIC system itself uses Chip RAM directly in accordance with the Chip RAM mem-
ory map. For example, BASIC stores program text starting at 0.2000 in Chip RAM,
even though the BASIC function PEEK($2000) reads from 3.2000 using the default
mapping mode.
BASIC 65’s remapping of addresses only applies to addresses in the range $0000 –
$FFFF. When you use an address $10000 or higher with POKE or PEEK(), it accesses
that Chip RAM address directly. SYS also supports long addresses, with limitations
(discussed later).
You can control BASIC address remapping using the BANK command. This command
accepts a bank number as an argument, in the range 0 – 5. Subsequent uses of
addresses in the range $0000 – $FFFF are interpreted as being offsets in that bank.
For example, to write the value 63 to address 0.2010 in Chip RAM:
BANK 0
POKE $2010 ,63

The BANK mechanism can only be used with banks 0 – 5. It cannot be used to reach
Attic RAM or upper I/O registers.
To re-enable BASIC address remapping, execute BANK with the argument 128. This
does not refer to a bank in memory. Instead, it tells the BANK command to re-enable
mapped addresses according to the table above.
BANK 128
POKE $D020 ,9

13-16
BANK affects every BASIC command and function that accepts an address as a pa-
rameter. This includes PEEK, POKE, WAIT, BOOT, BSAVE, and BLOAD. SYS also has
special behavior regarding BANK.

BANK and SYS


The SYS command executes a machine code subroutine at a given address. It handles
the address differently from other BASIC commands, and comes with some limitations.
Because SYS transfers control to a custom routine, it needs to take extra precautions
to preserve the system’s access to memory used to support BASIC.
Specifically, SYS only uses the BANK setting for addresses in the range $2000 –
$7FFF. Other addressees always go to either bank 0 RAM, KERNAL ROM, or I/O reg-
isters, as follows:
Address range SYS destination
$0000 – $1FFF RAM in bank 0
$2000 – $7FFF Address with BANK setting
$8000 – $BFFF RAM in bank 0
$C000 – $CFFF Character ROM, or bank 0 (ROMC bit of $D030)
$D000 – $DFFF I/O registers, or bank 0 (C64-style banking register $01)
$E000 – $FFFF KERNAL ROM in bank 3
SYS ignores bit 7 of the BANK setting. BANK 128 is equivalent to BANK 0 for SYS. This
differs from PEEK, POKE, et al., which see ROM code from $2000 – $BFFF with BANK
128.
BANK 128
SYS $1800 : rem Calls subroutine at 0.1800
SYS $7000 : rem Calls subroutine at 0.7000
SYS $FFD2 ,65 : rem Calls KERNAL ROM routine
: rem ( with an argument )

BANK 1
SYS $1800 : rem Calls subroutine in bank 0 at 0.1800
SYS $7000 : rem Calls subroutine in bank 1 at 1.7000
SYS $FFD2 ,65 : rem Calls KERNAL ROM routine at 3. FFD2
: rem ( with an argument )

SYS can accept an address larger than $FFFF that refers to a location in banks 1 –
5. However, these addresses have the same limitations as when using BANK. Only
offsets $2000 – $7FFF within the bank actually refer to the memory of that bank,
such as address $47000 in bank 4. For other offsets, the SYS command behaves
according to the table (RAM in bank 0, ROM, or I/O registers).
This restriction produces the counterintuitive behavior that, for SYS, a long address
doesn’t necessarily refer to the memory at that address, and multiple addresses may
refer to the same location in memory. SYS $11800 and SYS $41800 both behave like
SYS $1800, which calls a subroutine at address 0.1800 in bank 0.

13-17
SYS $11800 : rem Calls subroutine in bank 0 at 0.1800
SYS $41800 : rem Calls subroutine in bank 0 at 0.1800
SYS $51800 : rem Calls subroutine in bank 0 at 0.1800

SYS $17000 : rem Calls subroutine in bank 1 at 1.7000


SYS $47000 : rem Calls subroutine in bank 4 at 4.7000
SYS $57000 : rem Calls subroutine in bank 5 at 5.7000

SYS $1FFD2 ,65 : rem Calls KERNAL ROM routine at 3. FFD2


: rem ( with an argument )

The SYS command cannot access every address. Address offsets $C000 – $FFFF are
hidden by ROM and I/O registers in every bank, and address offsets $0000 – $1FFF
and $8000 – $BFFF can only access bank 0 and are hidden in banks 1 – 5.
SYS is limited to banks 0 – 5. It cannot access Attic RAM or upper memory addresses,
even when using long addresses.
Despite these limitations, SYS is quite powerful. It is common for a machine code
program to start with a short BASIC program, so the user can type RUN after loading
it. This program calls SYS to start the machine code stored in memory after the end
of the BASIC text.
10 SYS $200F

In early versions of the MEGA65 ROM, it was necessary to set BANK to 0 before calling
SYS in this way. This is a best practice anyway, so that the program can start even if
the user changed the BANK setting:
10 BANK 0: SYS $2014

You can also use SYS to augment a BASIC program with machine code subroutines.
A convenient location for these subroutines is in the $1600 – $1EFF range of bank 0.
SYS can access this location regardless of the current BANK setting.

13-18
USING MEMORY FROM MACHINE
CODE
Machine code programs access memory and registers, perform calculations, and make
decisions about what code to execute next. This is all they do! A program performs
input/output operations such as displaying an image, playing a sound, or reading a
joystick all by interacting with memory and registers.
Every 45GS02 machine code instruction that operates on memory supports one or
more addressing modes that describes how the instruction accesses memory. One of
these addressing modes operates on full 28-bit addresses, reading the full address
from four consecutive bytes of memory in little-endian order. This mode is useful, but
it is not the most efficient way to access memory in many cases: the CPU must spend
time reading the 28-bit address and finding the memory location for the operation.
Addressing modes that operate on 16-bit addresses are faster and more space ef-
ficient than 28-bit indirect addressing. Also, the CPU uses 16-bit addresses when
referring to locations of machine code instructions: the CPU stores the address of the
next instruction (the program counter) as a 16-bit value, and jmp and jsr instructions
use 16-bit addresses.
To make it possible to access any memory location with a 16-bit address, the 45GS02
CPU maintains a memory map that associates 16-bit addresses with 28-bit addresses.
Your program can change the memory map using a special purpose register known as
the MAP register. Setting the MAP register involves executing a sequence of special-
purpose CPU instructions.
With the MEGA65, three other mechanisms affect 16-bit memory address translation:
• Commodore 64 ROM and I/O banking, controlled by the CPU registers at ad-
dresses $0000 and $0001
• Commodore 65 ROM banking, using a register at address $D030
• Cartridge memory: if a cartridge is inserted in the expansion port, additional
rules expose cartridge data lines at specific 16-bit address banks
Machine code programs written for the MEGA65 can rely entirely on the MAP reg-
ister for accessing memory, and can leave the C64 and C65 memory configuration
registers at their default settings. MAP overrides the other mechanisms for when the
affected regions of 16-bit addresses are needed for other purposes.
This section describes accessing memory with 45GS02 addressing modes and the
MAP register. The other mapping mechanisms are discussed briefly later in the chap-
ter. For complete documentation on addressing modes, see Chapter/Appendix K on
page K-4. For a detailed explanation of the banking mechanisms, see Chapter/Ap-
pendix J on page J-3.

13-19
The MAP Register
The MAP register associates 16-bit addresses with 28-bit addresses using an offset,
an amount added to the 16-bit address to calculate the final address.
For example, say your program needs to access memory at address $4855F using
a 16-bit addressing mode. One possible memory map would be to assign an offset
of $45200 to the address region $2000 – $3FFF. With this configuration, the 16-bit
address $335F accesses the actual address $4855F in bank 4.
$335F + $45200 = $4855F
16-bit offset actual
address address
The MAP register remaps 8KB ($2000) blocks of the 16-bit address space at a time.
The MAP register can store two offsets, one for blocks in the range $0000 – $7FFF
(“MAPLO”), and one for blocks in the range $8000 – $FFFF (“MAPHI”). It also stores a
selection flag for each 8KB block that says whether the offset should be applied to
that block.
Each 8KB address block is either “unmapped” or uses the MAP offset for its half (MAPLO
or MAPHI). All mapped address blocks in the same half must share the same offset.
MAPLO: $6000 – $7FFF $4000 – $5FFF $2000 – $3FFF $0000 – $1FFF
0 0 1 0 = $2
MAPHI: $E000 – $FFFF $C000 – $DFFF $A000 – $BFFF $8000 – $9FFF
1 0 1 1 = $B
The selection flags and the offset for MAPLO and MAPHI are encoded altogether as
four bytes, two for MAPLO and two for MAPHI. The first nibble contains the selection
flags for the four blocks of the region. Notice the order of the flag bits: the higher bits
correspond to the higher address blocks.
For example, to select just the $2000 – $3FFF block, set the MAPLO selection flag to
binary “0 0 1 0,” which is the hexadecimal digit $2.
The remaining three nibbles are the upper three hex digits of the offset. To use the
offset $45200 for the selected MAPLO blocks, set the remaining bits of MAPLO to
$452. For this example, the complete MAPLO value is $2452.
MAPLO MAPHI
X A Z Y
$slo o1 $o2 o3 $shi o1 $o2 o3
$24 $52 $B3 $00
The offset must be a multiple of 256 bytes ($100). The 4510 CPU from the Com-
modore 65, on which the MEGA65’s 45GS02 is based, supports offsets up to $FFF00.
This allows any 8KB block to be remapped anywhere in Chip RAM on a 256-byte
boundary, including possible future RAM expansions up to 1MB. (The 45GS02 also
has a way to set larger offsets, discussed later.)

13-20
To set the MAP register, load the encoded bytes for MAPLO and MAPHI into the four
CPU registers X, A, Z, and Y, then call the MAP and EOM (“end of MAP”) instructions.
Notice the order of assignment of the registers. To set MAPLO, load X with the selection
flags and the upper nibble of the offset, and load A with the lower nibbles of the offset.
To set MAPHI, load Z and Y accordingly.
LDA # $52 ; MAPLO = select $2 offset $45200
LDX # $24
LDY # $00 ; MAPHI = select $B offset $30000
LDZ # $B3
MAP
EOM

Some assemblers, including the one built into the MEGA65 monitor, do not know the
EOM instruction. You can substitute the NOP instruction for EOM, which uses the same
encoding. Assemblers that support 65CE02 instructions use the AUG instruction for
MAP.
The MAP setting stays active until it is changed. Be aware that KERNAL routines depend
on the default MAP setting, so be sure to restore the original memory map before
calling the KERNAL.

Examining the MAP Register


You can examine the value of the MAP register using the Matrix Mode debugger, a
serial console provided by the MEGA65 Hypervisor. To access the Matrix Mode de-
TAB TAB
bugger on the MEGA65, hold down ` and press . (Press ` + again
to exit.) You can also access this console over a UART serial or JTAG connection with
the appropriate hardware. While in Matrix Mode, use the R command, or just press
, to view all registers, including MAPHI and MAPLO.6
RETURN

To see this in action, try the following:


1. Start the MEGA65 monitor with the MONITOR command.
2. Assemble the following machine language program at address $1800 by enter-
ing the first line as: A1800 LDA #$52 The monitor will calculate the subsequent
RETURN
addresses for each line. Press without an instruction after the last line.
LDA # $52
LDX # $24
LDY # $00
LDZ # $B3
MAP
EOM
JMP $180A
6 For more information about the Matrix Mode debugger, see Chapter/Appendix N on page N-14.

13-21
3. Call this routine with the monitor’s “jump” command: J1800 The MEGA65 will
enter an infinite loop and not return from the call, appearing to hang.
TAB
4. Open the Matrix Mode debugger: hold ` , press .
RETURN
5. Press to print a fresh set of registers. Notice the MAPH and MAPL values.
NOTE: The MAP instruction changes the MAP register value immediately. Take care
not to change the memory map for the memory that contains the code that changes
the memory map! If the memory map changes for the code’s own address, control will
never reach the EOM instruction.

MAP and Interrupts


When a CPU interrupt occurs, it pauses execution of the program, then calls an in-
terrupt handler routine. The address of the interrupt handler routines (the interrupt
vectors) are stored at 16-bit addresses $FFFA – $FFFF, and are themselves 16-bit
addresses.
Both the location of the vectors and the addresses of the handlers are affected by
the memory map. To give your code a chance to clean up the memory map without
being interrupted, the MAP instruction disables interrupts (similar to SEI), and the EOM
instruction re-enables interrupts (similar to CLI). This is true even if interrupts are al-
ready disabled when MAP is called: EOM will re-enable interrupts. If necessary, your
program can perform additional instructions between the MAP and EOM.
The default memory map keeps the MEGA65 KERNAL ROM mapped to $E000 – $FFFF.
This includes the KERNAL interrupt handlers and their vector addresses. If your pro-
gram keeps the KERNAL interrupt handlers active, it must make sure $E000 – $FFFF
is mapped to 3.E000 – 3.FFFF (with a MAPHI offset of $30000) while interrupts are
enabled.

Using 28-bit Addresses in Machine Code


The 45GS02 CPU includes an addressing mode for accessing 28-bit addresses di-
rectly, without 16-bit address translation. While technically this mode requires more
CPU cycles to execute, the convenience often outweighs this cost when accessing
single upper-memory addresses, or when accessing memory via pointers, compared
to using the MAP register. This mode also bypasses banking and remapping, allowing
a program to preserve a MAP register value that might be used by other code.
The Base-Page Quad Indirect Z-Indexed Addressing Mode accesses a 28-bit address
stored as four bytes on the base page. This is an extension of the Base-Page Indirect
Z-Indexed Mode that accesses a 16-bit address stored as two bytes.
In an assembler that supports 45GS02 extensions, such as the ACME assembler, the
notation for Quad Indirect mode is to use square brackets around the first base page
address where the address is stored:

13-22
; Select base page $1600.
; ( This preserves compatibility with the KERNAL , which
; reserves base page $0000. )
LDA # $16
TAB

; Store address 810 .4AB0 at base page address $40 - $43.


; ( Remember to use little - endian order. )
LDA # $B0
STA $40
LDA # $4A
STA $41
LDA # $10
STA $42
LDA # $08 ; ( The leftmost digit is zero. )
STA $43

; Load the accumulator with the byte at 810 .4AB0 ( with


; a Z - index of zero ) .
LDZ # $0
LDA [ $40 ],Z

This is encoded similarly to regular Base-Page Indirect mode preceded by a NOP in-
struction. If your assembler does not support the square bracket notation, you can
write it this way, with parentheses instead of brackets:
LDZ # $0
NOP
LDA ( $40 ),Z

See Chapter/Appendix J on page J-3 for more information about addressing modes.
This is primarily how BASIC’s BANK system works. If BANK is set to 0 – 5, or a program
accesses an address greater than $FFFF, commands like POKE and PEEK use Base-
Page Quad Indirect Z-Indexed Addressing Mode, writing the full address to a location
reserved in the KERNAL’s base page. This bypasses address translation without hav-
ing to change the memory configuration. (The SYS command does something more
complex, which is why it comes with unusual limitations.)

13-23
VIC-IV VIDEO MEMORY
The VIC-IV video controller reads memory to determine what to display on the screen,
including characters of text, bitmap graphics, sprites, and colour data. A program
changes the display by updating these memory regions. The memory locations used
for these purposes can be adjusted by the program using I/O registers.
The VIC-IV can only access Chip RAM. Technically, it is capable of accessing the first
16MB of the address space. Existing models of MEGA65 provide 384KB of Chip RAM,
with potential for future expansion.
This section describes several VIC-IV features that relate to the memory system. The
following descriptions do not apply to VIC-II compatibility mode. For a complete de-
scription of the VIC-IV, see Chapter/Appendix P on page P-5.

Locating Screen Memory


The VIC-IV reads the content of the screen (characters or pixels) from a contiguous
region of memory. The starting location of this memory is controlled by registers. The
content and size of screen memory depend on the display mode.
The screen memory start address is stored as 28 bits, even though only 20 bits are
required to store a Chip RAM address. The 28-bit address is stored across four bytes
$D060 – $D063. The highest nibble of the address is stored in the lower nibble of
$D063, which will always be zero for addresses up to 005.FFFF.
For example, to set screen memory to start at 4.26F0 in bank 4 of Chip RAM:
SCRNPTRLSB SCRNPTRMSB SCRNPTRBNK SCRNPTRMB
$D060 $D061 $D062 $D063 (low 4)
$F0 $26 $04 $0
LDA # $F0
STA $D060
LDA # $26
STA $D061
LDA # $04
STA $D062

; For completeness , clear bits 0 -3 of SCRNPTRMB. The


; MEGA65 does not have VIC - accessible memory beyond
; 005 .FFFF , so this is not necessary if the previous
; value pointed to a valid address.
LDA $D063
AND # $F0 ; clear bits 0 -3
STA $D063

13-24
If you experiment with this in the MEGA65 monitor, note that the BASIC editor will not
automatically use the new screen location after you change it. You can type blindly to
RUN RESTORE
set memory and see that it’s using the new location. Press STOP + to reset.
If your program writes to screen memory without initializing this register, be sure to
read the location of screen memory from the register. Do not assume its initial value.
ESC 5
The 80x50 display mode that the user can select by pressing uses a
different location for screen memory than the default 80x25 display mode.

Locating Character Data


When using a character display mode, the VIC interprets screen data as character
screen codes. The pixel data for each character is read from a character set stored
in memory. The start address of the selected character set is controlled by registers.
The size and format of character data depends on the character display mode. The
default text mode reads character data as eight bytes per character, one line of
monochrome pixels per byte, for a total of 512 possible screen codes (4KB).
The character set start address is stored as three bytes in $D068 – $D06A. For exam-
ple, to select the character set at 3.D000:
CHARPTRLSB CHARPTRMSB CHARPTRBNK
$D068 $D069 $D06A
$00 $D0 $03
The ROM data includes three monochrome character sets (used by the BASIC FONT
command):
• 2.9000: Character set A, the C64 character set with lower ASCII characters
• 3.D000: Character set B, a stylized ASCII terminal-like set
• 2.D000: Character set C, the C64 PETSCII character set (the default)
Your program can customize any of the built-in character sets by copying the 4KB
region to RAM and setting the CHARPTR registers accordingly.
The VIC-IV character generator has another way to store character glyphs internally.
When CHARPTR is set to the special value $001000, the VIC-IV uses 4KB of internal
character memory that stores the default PETSCII character set. This allows you to
repurpose all three character set ROM regions without losing access to the PETSCII
character set.

Locating Sprite Memory


The VIC-IV supports eight hardware sprites. The image data for these sprites is re-
ferred to by a set of sprite pointers. Unlike the Commodore 64’s VIC-II, the VIC-IV
supports relocating the sprite pointers and the image data to anywhere in Chip RAM.

13-25
The VIC-IV maintains some VIC-II compatibility by default, so additional register bits
are needed to fully enable relocation.
With the VIC-IV, the sprite pointers themselves can also be located anywhere in Chip
RAM. The location of the sprite pointers is stored in registers at $D06C – $D06E. This
address must be aligned to a 16-byte boundary: when writing out the address in
hexadecimal, its rightmost digit must be 0. For example, address $2C60 is 16-byte
aligned.
Bit 7 of $D06E tells the VIC-IV that the sprite pointers are 16 bits (two bytes) wide.
If not set, the VIC-IV assumes 8-bit (one byte) values for the pointers, similar to the
VIC-II.
A sprite pointer value is the address of the sprite’s image data divided by 64. This
unusual property originally allowed the VIC-II to locate sprite data in a 16KB range
using a single byte value. The VIC-IV maintains this property for compatibility, and
also allows this value to be 16 bits wide. One consequence of this design is that the
address of a sprite image must be aligned to a 64-byte region on a page: the two
rightmost hexadecimal digits of a sprite address must be $00, $40, $80, or $C0.
For example, to relocate sprite pointers to 0.3200 and enable 16-bit pointer values:
SPRPTRADRLSB SPRPTRADRMSB SPRPTRBNK SPRPTR16
$D06C $D06D $D06E (0-6) $D06E (7)
$00 $32 $00 +$80
LDA # $00
STA $D06C
LDA # $32
STA $D06D
LDA # $80
STA $D06E

To set the first sprite to use image data at address 4.3100, set the 16-bit pointer to
4.3100 / 64 = $10C4 (in little-endian order):
LDA # $C4
STA $3200
LDA # $10
STA $3201

Colour Memory
The VIC-IV determines a complete screen image from one set of character or pixel
data in screen memory, and a separate set of colour data in colour memory. For ex-
ample, in the 80x25 text display mode, the first 2,000 bytes of screen memory contain
the screen codes for the characters, and the first 2,000 bytes of colour memory are
the colours for those characters.

13-26
The VIC-IV has 64KB of dedicated memory for colour data, capable of supporting all
of the possible screen modes. This memory can be accessed directly using the upper
memory addresses FF8.0000 – FF8.FFFF.
For convenience, the first 2KB of colour memory is also exposed at addresses 1.F800
– 1.FFFF. This window of addresses in bank 1 cannot be disabled by memory configu-
ration: it always accesses the first 2KB of colour memory.
For backwards compatibility, the first 1KB of this window is also banked into $D800 –
$DBFF along with the I/O registers. Bit 0 of the $D030 VIC-III banking register (signal
name “CRAM2K”) extends this to the full 2KB, as $D800 – $DFFF.
The VIC-IV start address of colour memory is configurable by a register, as an offset
into the FF8.0000 – FF8.FFFF colour memory region. If you do not need all 64KB of
colour memory for your display, you can offset the start address and use the beginning
of colour memory for other purposes.
For example, to offset the start of colour memory by 2KB, set the register to $0800 (in
little-endian order):
COLPTRLSB COLPTRMSB
$D064 $D065
$00 $08
Offsetting the start address does not offset the colour memory window at 1.F800 or
the colour memory banking at $D800. If you offset the start of colour memory by 2KB,
then both the window and the I/O bank will use the 2KB region unseen by the VIC-IV.
This allows you to repurpose the colour memory window as general purpose RAM.
This BASIC program sets the colour memory offset to 2KB ($0800), then demonstrates
how the value at $FF80000 is also visible at $1F800 and $D800. Finally, it changes
the colour of the first character by setting $FF80800.
10 POKE $D064 ,0: POKE $D065 ,8
20 PRINT CHR$ (5); CHR$ (147); " HI THERE . "
30 POKE $FF80000 , $BB
40 PRINT HEX$ ( PEEK ( $FF80000 ))
50 PRINT HEX$ ( PEEK ( $1F800 ))
60 PRINT HEX$ ( PEEK ( $D800 ))
70 POKE $FF80800 ,4

13-27
LARGE MEMORY OPERATIONS WITH
DIRECT MEMORY ACCESS
In early microcomputers, all memory operations are performed by the CPU. Large mem-
ory operations, such as copying a block of memory from one location to another, are
time consuming and tend to pause user interaction with the program. This limits pro-
grams to small memory operations during interactive tasks such as games and some
applications.
The Commodore 65 provides dedicated hardware for copying and processing large
amounts of memory, a system known as Direct Memory Access (DMA). The DMA hard-
ware performs memory tasks, known as jobs. The MEGA65 extends these capabilities
with higher speeds and features that specialise in graphics and audio data.
The MEGA65 DMA is unlike the C65 DMA (and DMA in other microcomputers) in an
important way: in the MEGA65, the DMA is built into the CPU, and DMA jobs pause
execution of CPU instructions. This would seem to be against the point of having
dedicated DMA hardware, except for the fact that the MEGA65 executes DMA jobs
very quickly compared to the C65 due to the higher maximum CPU speed. Copying a
large graphic onto the screen happens quickly enough to be a regular part of a game
loop’s code.
This also simplifies the programming model: a program can treat a DMA job like a
special kind of CPU instruction, without additional logic to wait for jobs to complete.
There’s even a method of invoking the DMA where you can include the DMA job list
directly in your code, without having to reserve additional memory to describe the
job. In general, if the operation you’re trying to perform is supported by DMA and
involves more than eight bytes of memory, a DMA job will be faster than equivalent
CPU instructions.
This section introduces DMA briefly, as part of this overall discussion of memory. For
a complete description of the DMA controller and the MEGA65 extended features,
including graphics and audio DMA, see Chapter/Appendix O on page O-3.

DMA Jobs
To perform a DMA job, you describe the job in memory, then invoke the DMA by writing
the job description’s address to registers. The DMA executes the job as soon as you
write the final job address value to the register. The CPU pauses to perform the job,
then continues at the next program instruction.
Conceptually, a job description contains the following fields:
1. A command: copy or fill
2. A number of bytes to process, up to 64KB
3. For copy: the source start address

13-28
4. For fill: a fill byte
5. The destination start address
6. Configuration on how the source and destination regions should be traversed
(“addressing”)
More than one job can be described in a single invocation of the DMA, in a “job list”
structure. The jobs are executed in the order they appear in the list.
The MEGA65 extends the C65 DMA job record format to include a list of job op-
tion tokens. Many of the MEGA65’s extended features, like copying image data with
transparency, use job option tokens.

Using DMA from BASIC


In BASIC 65, the EDMA command performs a single DMA job, with limited options. The
Commodore 65 DMA command is also supported, but EDMA is recommended for all
new programs that don’t need to run on a C65.
The EDMA command accepts four comma-delimited arguments: the command
(0=copy, 3=fill), the number of bytes, either a fill byte (for fill) or a source start ad-
dress (for copy), and the destination start address.
10 SC = WPEEK ( $D060 )+ PEEK ( $D062 )* $10000
20 FOR X =32 TO 40
30 EDMA 3 ,80*25 , X , SC
40 GETKEY A$
50 NEXT

Other DMA features are not easily accessible from the EDMA command. To perform
more sophisticated DMA jobs, a BASIC program can POKE job data into memory and
invoke the job via registers, as described below.

Using DMA from Machine Code


There are several ways to describe and initiate DMA jobs, including ways to write
programs compatible with the Commodore 65. This section will describe two methods:
invoking a MEGA65 enhanced DMA job list from a data structure stored at a memory
address, and invoking an enhanced job list inline with machine code. For a complete
description of the options, including the list of possible MEGA65 extended job tokens,
see Chapter/Appendix O on page O-3.

Invoking an Enhanced Job List in Memory


An enhanced DMA job list can reside anywhere in memory, and can be referred to
using either a physical 28-bit address, or a 16-bit address reassigned via MAP.
To invoke an enhanced DMA job list from a record stored at a 28-bit address, write
the address to the following registers, in this order:

13-29
1. $D704: highest address byte (the megabyte)
2. $D702: 2nd highest address byte (the bank)
3. $D701: 3rd highest addresss byte (the page)
4. $D705: lowest address byte
Notice that the register locations are not arranged consecutively.
Writing the lowest address byte to $D705 triggers execution of the job list, interpreting
the address as a 32-bit physical address. To tell it to interpret the job list address using
the CPU’s view of the 16-bit address space (honoring the MAP register), write the final
low byte to $D706 instead.7
Addresses in the job list itself are never MAP’d addresses: DMA jobs always operate
on physical addresses. Using $D706 only changes the way the address of the job list
is interpreted, and only if it’s a 16-bit address.
For example, to invoke an enhanced DMA job list stored at label dmajob:
LDA #0
STA $D704
LDA #^ dmajob
STA $D702
LDA #> dmajob
STA $D701
LDA #< dmajob
STA $D705 ; DMA executes immediately

; Program continues...
RTS

dmajob :
! byte $0B , $00 ; token list
! byte $03 , $00 , $08 ; fill ( $03 ) $0800 bytes
! byte $BB , $00 , $00 ; with value $BB
! byte $00 , $30 , $04 ; starting at 4 .3000
! byte $00 , $00 , $00 ; no funny business

The ^dmajob above (a caret followed by a symbol name) is ACME assembler syntax
for the bank byte of the 24-bit address of the dmajob symbol. Adapt this to your
assembler’s syntax, or hard-code this value if you know which bank will contain the
dmajob memory.
7 The MEGA65 supports a C65-compatible DMA job list format, which a program can request by setting

the low address byte in $D700 instead of $D705 / $D706. You’d only use this if you intend for your
program to run on compatible C65 prototype hardware. Note that some C65 prototypes have incomplete
DMA implementations.

13-30
Invoking an Enhanced Job List Inline with Code
As an alternative to preparing a job list in memory, you can put the job list inline with
your machine code. This is a convenient way to write a DMA job as if it were a CPU in-
struction with pre-determined values. To do so, use the STA $D707 instruction (with any
accumulator value), followed by assembler directives to assemble the enhanced job
list data structure. The 45GS02 CPU knows to give control to the DMA and advance
the program counter beyond the end of the DMA job data.
STA $D707 ; DMA executes immediately
! byte $0B , $00 ; token list
! byte $03 , $00 , $08 ; fill ( $03 ) $0800 bytes
! byte $BB , $00 , $00 ; with value $BB
! byte $00 , $30 , $04 ; starting at 4 .3000
! byte $00 , $00 , $00 ; no funny business

; Program continues...
RTS

The Enhanced Job List Format


This section presents a simplified version of the enhanced job list format. For a com-
plete description, including fields not yet supported by the 45GS02 DMA and the
complete list of job option tokens, see Chapter/Appendix O on page O-3.
The job list is a binary format with values packed into bytes. It consists of one or more
job records, where the “chain” bit is set for every job except the final job in the list.
An enhanced job record consists of a list of one or more job option tokens that always
ends with the “end of job option list” token ($00), followed by a 12-byte data structure.
Each job option token is a byte value, and some tokens are followed by a one-byte
argument value. Unless you’re writing a program intended for a Commodore 65, your
token list will typically use the $0B token (no arguments) to select the 12-byte job
record format.
The 12-byte structure is as follows:

13-31
Bytes Contents
$00 Command
1 – 0: 00 for copy, 11 for fill
2: 0 if this is the last job in the list, 1 if
list continues
3: Yield to interrupts
$01 – $02 Count (16 bits)
$03 – $05 Source address or fill byte
Fill byte in $03
Source address (20-bit) in $03 – $05
High bits of $05:
6: Direction: 0 to count up from start, 1
to count down from start
7: I/O: 1 to access I/O registers at
$D000 – $DFFF during DMA
$06 – $08 Destination address (20-bit)
Uses same format as source address
$09 Addressing options
1 – 0: Addressing mode of source
3 – 2: Addressing mode of destination
Addressing modes:
00: Linear: advance in direction for all
bytes
10: Hold: do not advance, only repeat
start address
$0A – $0B Reserved, always set to $00 $00
Source and destination addresses are stored in the job record as 20-bit addresses, in
little-endian order. To access the full 28-bit address space, use the job option tokens
for setting the highest byte of the start ($80 $xx) and destination ($81 $xx) addresses.
The token applies to all jobs in the job list.
Example: copy all of BASIC program text memory into Attic RAM.
dmajob :
! byte $80 , $00 ; Source highest byte : $00
! byte $81 , $80 ; Destination highest byte : $80
! byte $0B ; Use 12 - byte job record format
! byte $00 ; End of token list
! byte $00 , $00 , $d7 ; copy ( $00 ) $d700 bytes
! byte $00 , $20 , $00 ; from (00)0 .2000
! byte $00 , $00 , $00 ; to (80)0 .0000
! byte $00 , $00 , $00 ;

Example: a chain of three jobs, each performing a fill.


dmajob :
! byte $0B , $00 ; token list
! byte $07 , $00 , $01 ; fill ( $03 ) $0100 bytes

13-32
; continue job chain (+ $04 )
! byte $BB , $00 , $00 ; with value $BB
! byte $00 , $30 , $04 ; starting at 4 .3000
! byte $00 , $00 , $00 ;

! byte $0B , $00 ; token list


! byte $07 , $00 , $01 ; fill ( $03 ) $0100 bytes
; continue job chain (+ $04 )
! byte $CC , $00 , $00 ; with value $CC
! byte $00 , $31 , $04 ; starting at 4 .3100
! byte $00 , $00 , $00 ;

! byte $0B , $00 ; token list


! byte $03 , $00 , $01 ; fill ( $03 ) $0100 bytes
; end job chain
! byte $DD , $00 , $00 ; with value $DD
! byte $00 , $32 , $04 ; starting at 4 .3200
! byte $00 , $00 , $00 ;

DMA jobs ignore all mapping and banking settings. You can request that a source
or destination address treat $D000 – $DFFF as I/O registers by setting bit 23 of the
address record.
You can imagine a DMA job maintaining two cursors, one for the source (when copying)
and one for the destination. The DMA advances each cursor according to the job
description, for as many steps as requested by the count, copying or filling into the
destination at each step.
Addressing modes are one way to influence how the cursors move:
• The linear addressing mode advances the cursor by one address for each step.
• The hold addressing mode does not advance the cursor. It remains at the start
address for every step.
• The traversal direction says whether to increment or decrement for each step
during linear addressing.
Example: A copy that holds the source cursor and advances the destination cursor
linearly is similar to performing a fill with the byte at the source address.
dmajob :
! byte $0B , $00 ; token list
! byte $00 , $80 , $00 ; copy ( $00 ) $0080 bytes
! byte $00 , $19 , $00 ; from 0 .1900
! byte $40 , $31 , $04 ; to 4 .3140
! byte $02 , $00 , $00 ; hold the source

13-33
The MEGA65 extended DMA is capable of many more sophisticated traversal patterns,
controlled by job option tokens. You can use the DMA to draw lines and patterns into
screen and colour memory.
Commodore described but never completed their implementation of the Commodore
65 DMA. The MEGA65 reserves bits of the DMA job record for these incomplete fea-
tures for historical preservation purposes, even though an implementation can never
be truly compatible with the Commodore 65 prototype.

13-34
ADVANCED MEMORY TOPICS
Testing Memory Mapping with the Matrix Mode Debugger
In the Matrix Mode debugger,8 the m command displays data at a given memory loca-
tion. For example, to display the contents of RAM starting at address 0.2000:
m2000

The debugger always reads from 32-bit addresses and does not take MAP or other
memory banking features into account, even when given a four hex digit address. To
make it easier to see how the CPU sees the 16-bit addresses, the MEGA65 puts the
CPU’s view at the upper addresses 777.0000 – 777.FFFF. For example, to display
what the CPU sees at the 16-bit address $2000:
m7772000

The 777 bank takes the MAP register into account, as well as the memory mapping
mechanisms described in the following sections.

C64-style Memory Banking


The 16-bit addresses $0000 and $0001 refer to registers. These registers function
identically to the CPU registers found at these addresses in a Commodore 64. They
control mapping of the C64 ROM into the 16-bit address space, just as they do on a
C64.
In a MEGA65, these registers serve two purposes: they bank in the I/O registers at
$D000 – $DFFF to overlay Chip RAM, and they provide access to the C64 BASIC and
KERNAL for C64 mode (GO64).
To bank out the I/O registers such that the 16-bit addresses $D000 – $DFFF access
the underlying Chip RAM at 0.D000 – 0.DFFF, clear bits 0 and 1 of location $0001.
To restore the I/O registers, set bits 0 and 1 of location $0001.
This BASIC example demonstrates accessing location $D020 as an I/O register (the
border colour) then as a RAM address. Try to guess what it will print before running it.
10 POKE $D020 ,3
20 POKE 1 ,240
30 POKE $D020 ,4
40 X = PEEK ( $D020 )
50 POKE 1 ,255
60 PRINT X
70 PRINT PEEK ( $D020 )
TAB
8 Remember: To activate the Matrix Mode debugger, hold down ` and press . For more
information about the Matrix Mode debugger, see Chapter/Appendix N on page N-14.

13-35
C64-style banking only applies to 8KB address blocks not selected by the MAP register
(“unmapped” blocks). For example, if C64-style banking has I/O registers at $D000
– $DFFF, and the $C000 – $DFFF region is mapped with an offset of 0, the program
will access RAM at that location and not the I/O registers. The $C000 – $DFFF region
must be unmapped for the CPU to access the I/O registers.
Similarly, it is possible to use the MAP register to access the RAM at addresses 0.0000
and 0.0001 that are normally hidden by the C64-style banking registers. If the MAP
register selects the $0000 – $1FFF address block for mapping and applies an offset
of 0, 16-bit addresses $0000 and $0001 will access RAM at 0.0000 and 0.0001,
and will not access the C64-style banking registers. The C64-style banking registers
can only be accessed with the $0000 – $1FFF region unmapped.
It is typical for a MEGA65 program to leave I/O registers banked into $D000, and use
the MAP register when it needs to access the underlying RAM. Such a program does
not need to manipulate the C64-style banking register.

The $D030 VIC-III Banking Register


The Commodore 65 provides a banking mechanism to make additional ROM data ac-
cessible with 16-bit addresses. This banking is controlled by the I/O register $D030.9
Bits 3, 4, 5, and 7 map regions of ROM data into the 16-bit address space according
to this table. (Recall that bits are numbered right to left from 0, so bit 7 is the highest
bit.)

$D030 Signal 20-bit 16-bit


Bit Name Address Address
$28000 $8000 –
3 ROM8
– $29FFF $9FFF
$2A000 $A000 –
4 ROMA
– $2BFFF $BFFF
$2C000 $C000 –
5 ROMC
– $2CFFF $CFFF
$2E000 – $E000 –
7 ROME
$2FFFF $FFFF

For example, if $D030 is set to $64 = %01100100, then ROMC is enabled, and the
16-bit addresses $C000 – $CFFF access 2.C000 – 2.CFFF.
As with C64-style banking, $D030 banking only applies to 8KB address blocks not
selected for offsetting by the MAP register. For unmapped regions, if either C64-style
ROM banking or $D030 ROM banking is enabled for the region, then those addresses
9 Accessing the VIC-III banking register at $D030 requires that the computer be using the VIC-III/IV “I/O

personality,” described later. This is the default in MEGA65 mode.

13-36
refer to ROM in bank 2. Each of these ROM banking mechanisms use ROM in bank 2,
so there is no conflict if they are both enabled.
Notice that $D030 does not bank in any of the MEGA65 KERNAL ROM from bank 3.
The KERNAL itself uses the MAP register to access its own code, and only uses $D030
banking to access ROM code at 2.C000 with ROMC enabled. As with the C64-style
banking register, a typical MEGA65 program can leave the banking bits of $D030
alone and use MAP to access RAM or ROM at these addresses as needed.

Cartridge ROM
When a Commodore 64 cartridge is inserted in the expansion port, the memory system
overrides regions of the 16-bit address space to access lines to the port, typically
connected to ROM chips in the cartridge. The cartridge controls two additional lines
that allow it to request different memory configurations using the $0000 and $0001
CPU registers, known as EXROM and GAME. These configurations are identical to that
of a Commodore 64. See a Commodore 64 reference book for more information.
The Commodore 64 recognizes that a C64 cartridge is installed if one or both of
EXROM and GAME are low (0). A typical C64-style cartridge uses one or two 8KB
regions made accessible to the system based on the EXROM and GAME values. If
both lines are high, then no cartridge ROM is mapped to 16-bit addresses.
Cartridge hardware is connected to the entire 16-bit address bus, and can potentially
return values for all 65,536 addresses. On the MEGA65, all 64KB of the cartridge
addresses are available at the dedicated upper addresses 400.0000 – 400.FFFF.10
MAP register address translation takes precedent over C64 cartridge memory config-
uration. Cartridge ROM mapping overrides $D030-style memory mapping.

I/O Personalities
The I/O registers are the primary way the KERNAL, the BASIC interpreter, or a ma-
chine code program engage with the MEGA65 hardware. These registers behave like
memory locations for setting values in hardware such as displaying graphics or mak-
ing sound, or reading values from hardware such as user input on the keyboard or
joystick. Programs written in BASIC typically access these registers indirectly through
commands, though they can also do so directly via memory access.
The MEGA65 starts in a configuration that makes most of its features available via
registers at 16-bit addresses in $D000 – $DFFF. There are four different configurations
for these registers, known as I/O personalities:
• MEGA65. Enables all features of the MEGA65 VIC-IV and Commodore 65 VIC-
III. This is the default.
10 The MEGA65 supports a protocol for MEGA65 cartridges that boot automatically in MEGA65 mode.

This will be documented in a later version of this manual.

13-37
• Commodore 65. The VIC-III without the VIC-IV enhancements. For C65 com-
patibility.
• Commodore 64. The VIC-II. Used by C64 mode (GO64).
• MEGA65 Ethernet. A special-purpose personality for accessing the MEGA65
Ethernet port.
The registers for all four personalities are available in the 28-bit address space in each
4KB block of the range FFD.0000 – FFD.3FFF. When a given personality is configured,
$D000 – $DFFF is mapped to the corresponding block of upper addresses. For exam-
ple, the default MEGA65 personality maps these addresses to FFD.2000 – FFD.2FFF.
You can access all four personalities simultaneously using 28-bit addresses, though
beware of interactions between them (such as VIC “hot registers”).
Note that the $D030 banking register is not available in the C64 I/O personality. If
your program launches in C64 mode or otherwise switches to its I/O personality, it
must change to the C65 or MEGA65 personality before accessing this register.
A typical program written for the MEGA65 uses the MEGA65 personality and assumes
that it is already configured when it launches. For information on how to change which
personality is being used, such as to defensively set the desired personality when your
program launches, see Chapter/Appendix I on page I-3.

Converting ROM to RAM


The MEGA65 stores the code for the KERNAL and BASIC interpreter in banks 2 and
3. To protect this code from being overwritten by other programs, it enforces that
these banks are read-only, simulating having Commodore-style ROM chips connected
to those addresses. The MEGA65 Hypervisor loads the ROM data during boot, and
manages the write protection.
A program can disable write protection on banks 2 and 3 to use those regions as
Chip RAM. Most programs don’t need all of ROM in memory. For example, a program
running in C65 mode is unlikely to need C64 BASIC ROM code. The Chip RAM Memory
Map earlier in this chapter describes which ROM regions are used for each purpose.
A carefully written program that doesn’t need the built-in routines at all can repurpose
the entire 128KB region. Take care to disable interrupts and replace the interrupt
handler vectors when overwriting the KERNAL.
To toggle the read-only status of banks 2 and 3, invoke the Hypervisor Toggle ROM
Write-protect system trap (hyppo_toggle_rom_writeprotect), like so:
LDA # $70
STA $D640
CLV

You must use the MAP register, 32-bit instructions, or DMA to write to RAM in banks 2
and 3. When C64-style banking or $D030 banking is active (and the affected 16-bit
addresses are unmapped), reading those addresses will access bank 2, but writing

13-38
to those addresses will write to RAM in bank 0. This is similar to what happens when
writing to a ROM-banked address on a Commodore 64.
The state of this write-protection is not readable in a register. To test whether the
region is write-protected, simply attempt to write a value to the region. The MEGA65
boots with write protection enabled.
The $D640 register is only available in the MEGA65 I/O personality.
Notice that this is not a banking mechanism, like it is on a Commodore 64. If your
program needs access to the original ROM code after overwriting it (such as to restore
it), use DMA to copy the original ROM to Attic RAM first.

Using MAP to Access Upper Memory


As discussed earlier, the MAP register can remap any 8KB block to another location
in the first 1MB of the address space. This is useful for accessing the 384KB of Chip
RAM, including potential future expansions. The MAP instruction originates with the
Commodore 65’s 4510 CPU, which was designed to have a 1MB address space.
The MEGA65’s 45GS02 CPU extends the MAP register with the ability to access any
256 byte block in the 28-bit address space. This takes the form of an additional high
byte of offset for each of MAPLO and MAPHI.
You set a MAP offset with a high byte by calling the MAP instruction twice before call-
ing EOM. The first call sets the high byte, and the second call sets the selection flags
and remaining 12 bits of the offset, as before. Interrupts are disabled automatically
between the first MAP call and the EOM call.
To set the offset high byte, load the high byte into the A register for MAPLO, or Y
register for MAPHI. Then load the special value $0F into the X register for MAPLO, or
Z register for MAPHI. Call MAP to set it. Then load the selection flags and remaining
offset values, call MAP, then finally call EOM.
For example, to map $A000 – $BFFF to $8000000 – $8001FFF in Attic RAM, you use
an offset of $7FF6000. The high byte is $7F, and the three nibbles of the regular
offset are $F60. Setting MAPHI to this offset with the selection flag of $2 will apply
the offset to the desired block.
LDA # $00
LDX # $00
LDY # $7F ; MAPHI offset high byte of $7F
LDZ # $0F ; ( Special value for setting high byte )
MAP

LDA # $00
LDX # $00
LDY # $60 ; MAPHI offset : $F60
LDZ # $2F ; MAPHI selection flag : $2 = A000 - BFFF
MAP
EOM

13-39
Be careful not to change the high byte of the 32KB address region that contains the
code doing the mapping! The high byte setting takes effect upon the first MAP in-
struction, and if the code is accidentally mapped out, the program counter won’t be
able to reach the remaining instructions, even if the final mapping is compatible.
In most cases, it is easier for programs to access upper memory through 28-bit ad-
dressing modes or DMA. This extended MAP feature is included for completeness.

Reading the MAP Register


The 45GS02 CPU can set the MAP register using a combination of CPU instructions,
but it does not offer a way to read the register in a similar way to other CPU registers.
Instead, a program can use a Hypervisor trap for this purpose. The hyppo_get_mapping
Hypervisor trap writes the MAPHI and MAPLO register values, including megabyte off-
sets, to six bytes at a requested location in memory.
The memory location to which the Hypervisor trap writes these values must be on a
page boundary between 0.0000 and 0.7E00. You set the Y register to the most
significant byte of the starting address when calling the trap. For example, to copy
the MAP register to RAM at addresses 0.6200 – 0.6205:
LDY # $62

LDA # $74
STA $D640
CLV

Making All Chip RAM Available


Using the techniques described in this chapter, you can configure the memory system
to make all of Chip RAM available at addresses 0.0000 – 5.FFFF. A carefully written
program can take over the entire machine, access I/O registers with upper addresses,
and use all of Chip and Attic RAM.
A summary of the procedure:
1. Disable interrupts.
2. Clear all bits of $D030.
3. Set the MAP register to all zeroes.
4. Clear bits 0, 1, and 2 of $0001 to remove I/O registers from $D000 – $DFFF.
5. Move the start of colour RAM forward by at least $0800 (2KB), so the Colour
RAM Window can be used as general purpose RAM.
6. Disable ROM write-protect on banks 2 and 3.
7. Load custom interrupt handler code into bank 0, configure interrupt vectors, then
re-enable interrupts.

13-40
The program must only use display modes that need 30KB or less colour data in order
to use the first 2KB as general purpose memory. A program that uses all 32KB of colour
memory must allow the first 2KB to be visible in the Colour RAM Window at 1.F800 –
1.FFFF. (There is no requirement to bank this memory into $D800 – $DFFF.)
The program must use MAP to access RAM at 0.0000 and 0.0001, by enabling MAP
for $0000 – $1FFF with an offset of 0.

Why the SYS Command Can Only Use Certain Addresses


Earlier, this chapter explained that the BASIC SYS command has unintuitive restrictions
on which addresses it can access. This can now be explained in full, using the more
advanced concepts in this chapter.
For BASIC functions and commands such as PEEK and POKE, the KERNAL uses the
45GS02’s 32-bit indirect addressing feature to access large addresses. Given an
address of $10000 or larger, the command loads the full address into a base page
variable, then invokes 32-bit indirect addressing to access the memory. Given an ad-
dress of $0000 – $FFFF with a BANK setting of 0 – 5, the command uses the BANK
setting as the upper part of the address. 32-bit indirect addressing ignores the MAP
register and the memory banking features, and can access any address in the com-
puter.
If the address is $0000 – $FFFF and the BANK setting is 128, BASIC uses the CPU’s
16-bit addressing mode, which honors the KERNAL’s MAP register setting, as well as
D030 and C64-style memory banking settings. This is how those commands access
ROM and I/O registers with BANK 128.
SYS tells the CPU to execute code at a location in memory. The CPU’s program counter
is a 16-bit register, and it cannot access larger addresses independently of the MAP
register and other memory mapping features the way 32-bit indirect addressing can.
As a feature of the KERNAL, it must keep KERNAL ROM in memory at 16-bit addresses
$E000 – $FFFF to handle interrupts. It must also keep KERNAL variables accessible
in addresses $0000 – $1FFF for the interrupt handler code to use. Code called by
SYS can make its own decisions about whether to keep the KERNAL functional, but
SYS keeps it enabled for the common case where the machine code wants to return
control to a running BASIC program or the READY. prompt.
The KERNAL uses the MAP register to access ROM in bank 3. To keep ROM in $E000 –
$FFFF, it sets the MAPH offset to 3, and marks that memory region as “mapped.” There
is only one offset that MAP can use for all 8KB regions in $8000 – $FFFF, so on entry
to a SYS call, the other regions in that range must either be un-mapped and refer to
bank 0 (or D030/$01 banking), or mapped to bank 3. The most useful choice for SYS
is to leave the remaining upper regions un-mapped.
Similarly, for addresses in the range $0000 – $1FFF to continue to refer to KERNAL
variable memory in bank 0, either the region must be un-mapped, or mapped with an
offset of zero. Naturally, it is more useful for SYS to leave that region un-mapped so
that it can access other banks for addresses $2000 – $7FFF, so that’s what it does.

13-41
SYS uses the MAP register to access upper banks for an address whose lower word is
$2000 – $7FFF, either when using BANK or when given a large address.
The MAP register is much more flexible than this: it can allow almost any address to be
reached via 16-bit addresses $2000 – $7FFF using a wide range of possible offsets.
However, the machine code called by SYS would need to be written in a way that
is aware of what offset is being used. The program counter would be relative to the
offset, and a JMP instruction in the code would have to use an address based on the
same offset. It is possible to write machine code using only relative branch instructions
(such as BRA), but historically this has not been a requirement of the SYS command.
Instead, SYS restricts itself to 64KB offsets to keep the programming model simple.

13-42
PART VI
HARDWARE
13-44
CHAPTER 14
Using Nexys4 boards as a
MEGA65
• Building your own MEGA65 Compatible
Computer

• Working Nexys4 Boards


• Power, Jumpers, Switches and Buttons
• Keyboard
• Preparing microSDHC card
• Loading the bitstream from QSPI
• Widget Board
• PMOD-to-Joystick Adapter
• Useful Tips

14-2
14-3
14-4
BUILDING YOUR OWN MEGA65
COMPATIBLE COMPUTER
You can build your own MEGA65-compatible computer by using either a Nexys4DDR
(aka. Nexys A7) or the older Nexys4 (Non-DDR) FPGA development boards. This ap-
pendix describes the process to set up a Nexys4DDR (Nexys A7) board for this pur-
pose (which is the newer, preferred board). The older non-DDR Nexys4 board is also
supported, and the instructions are the same, except that you must use a bitstream
designed for that board. Using a Nexys4DDR bitstream on a non-DDR Nexys4 board,
or vice versa, may cause irreparable damage to your board, so make sure you have
the correct bitstream to suit your board.
DISCLAIMER: M.E.G.A cannot take any responsibility for any damage that may occur
to your Nexys4DDR/NexysA7/Nexys4 boards.

14-5
WORKING NEXYS4 BOARDS
There are currently 3 Nexys FPGA boards which can be setup as a MEGA65:
The Nexys4 board
No longer manufactured but still available for sale on some websites with old stock.

Documentation:
• https://reference.digilentinc.com/reference/programmable-logic/
nexys-4/reference-manual
• https://reference.digilentinc.com/_media/reference/
programmable-logic/nexys-4/nexys4_rm.pdf
The Nexys4DDR board
No longer manufactured but still available for sale on some websites with old stock.

Documentation:
• https://reference.digilentinc.com/reference/programmable-logic/
nexys-4-ddr/reference-manual
• https://reference.digilentinc.com/_media/reference/
programmable-logic/nexys-4-ddr/nexys4ddr_rm.pdf

14-6
The Nexys A7
This is the re-branded version of the above Nexys4 DDR board:

Documentation:
• https://reference.digilentinc.com/reference/programmable-logic/
nexys-a7/reference-manual
• https://reference.digilentinc.com/_media/reference/
programmable-logic/nexys-a7/nexys-a7_rm.pdf

14-7
POWER, JUMPERS, SWITCHES AND
BUTTONS
This top-down picture highlights the key jumper positions of interest on the Nexys4
board:

The Nexys4 boards can be powered in two ways: using an external power supply, or
from a standard USB port.

14-8
Micro-USB Power

Connect your micro-usb cable to a USB port on a USB charger or PC to provide power.
Connect the other end to the Nexys4’s micro-usb connector. Place the JP3 jumper on
pins 1 and 2 to select USB power. Use the switch to power up the Nexys4.

External Power Supply

The MEGA65 core can consume a lot of power, and a standard USB port could poten-
tionally be too little for the Nexys4 board. In particular, writing to the SD card might
hang or perform odd behaviour. Therefore you should consider a 5V power supply.
Digilent sell a power supply for the Nexys4 board, and we recommend you use this to
ensure you avoid the risk of damage to your Nexys4 board. The chosen power supply
should be center positive, 2.1mm internal diameter plug, and should deliver 4.5VDC
to 5.5VDC rated at least 1 Amp.
Connect the power supply cable to the supply plug of the Nexys4. Place the JP3
jumper on pins 2 and 3 to select WALL power. Use the switch to power up the Nexys4.

14-9
Other Jumpers and Switches
For your initial set up, we’d suggest you set the following jumpers on your Nexys4 board
to these positions:
• JP1 - USB/SD
• JP2 - SD

This will assure that the bitstream files will get loaded from your SD card on start-up.
At some later stage, you may prefer to load the bitstream from the on-board QSPI
flash, and at that point, you can revisit your JP1 jumper setting and adjust it to the
QSPI position.
All 16 switches on the lower edge of the board must be set to the off position.

14-10
Connections and Peripherals

A USB keyboard can be connected to the USB port. Only a keyboard that lacks a USB
hub will work with the Nexys4 board. Generally, extremely cheap keyboards will work,
while more expensive keyboards tend to have a USB hub integrated, and will not work.
You may need to try several keyboards before you find one that works.
You can connect a VGA monitor to the VGA port.
The mono audio-out jack can be connected to the line-in of an amplifier.

Communicating with your PC


There may be occasions where you wish to communicate with your Nexys4 board from
your PC, in order to perform activities such as:
• Flash your QSPI flash chip via Vivado
• Upload bitstream files directly from your PC (via m65 tool)
• Make use of support tools such as M65Connect, m65, mega65_ftp, m65dbg,
etc

14-11
On such occasions, you will need to connect your micro-usb cable up to your PC.

Onboard buttons

The “CPU RESET” button will reset the MEGA65 when pressed, while the “PROG” button
will cause the FPGA itself to reload the MEGA65 core. The main difference between
the two is that CPU RESET is faster, and does not clear the contents of memory, while
the FPGA button is slower, and does reset the contents of memory.

Two of the five buttons in the cross arrangement can also be used: BTND acts as though
RESTORE
you have pressed , while BTNC will trigger an IRQ, as though the IRQ line had
been pulled to ground.

KEYBOARD
The keyboard layout is positional rather than logical. This means that keys in similar
positions to the keys on a C65 keyboard will have similar function. This relationship
assumes that your USB keyboard uses a US keyboard layout.
To help you locate what the various MEGA65 keys are mapped to, the MEGA65 has a
built-in virtual keyboard test feature. This can be accessed in two ways.

14-12
ALT
The easiest way is to keep held down in while switching on the Nexys4, or reset-
ting the Nexys4 with the “PROG” button. The configure menu will be presented and
by pressing 3, the virtual keyboard will be presented on a black background.

Pressing a key on the USB keyboard will show the highlighted key on the virtual key-
board to help you identify the key mapping.
The other way to access the virtual keyboard is from within the MEGA65. Hold
TAB
` and press to access the Matrix Mode Debugger. From here, enter the
following:
s ffd3615 ff
This will open a semi-transparent virtual keyboard at the top of the screen. Alterna-
tively:
s ffd3615 ff ff
This will open a semi-transparent virtual keyboard in the centre of the screen.
TAB
Hold ` and press to exit Matrix Mode Debugger and return to the MEGA65.

Some key mappings with a USB keyboard


RESTORE
is mapped to the PAGE UP key.
RUN ESC
STOP is mapped to .

14-13
PREPARING MICROSDHC CARD
The MEGA65 requires an SDHC card of between 4GB and 64GB capacity. Some
SDXC cards may work, however, this is not officially supported.
Preparation steps for the Nexys4 board’s SD card share much in common with the
steps needed for real MEGA65 hardware, and as such, it is worth having a look over
Chapter/Appendix 4 on page 4-3 if you ever need details.
So in this section, we’ll provide more details on the distinctive steps, and be more brief
on the common steps.
One point of distinction between the Nexys board and the real MEGA65 hardware is
that the latter already has a default bitstream/core provided, which permits you to
format your SD card in the specific style required by the MEGA65.
For Nexys4 board owners however, you have no such default bitstream, so see the
MEGA65 Book for more details on where the appropriate ”nexys4.bit” or ”nexys4ddr-
widget.bit” files for your device can be downloaded from.

Preparation Steps
The steps are:
• Format the SD card in a convenient computer using the FAT32 file-system. The
MEGA65 and Nexys4 boards do not understand other file systems, especially the
exFAT file system.
• Copy your bitstream file (with name ending in “.bit”) onto the SD card.
• Insert the SD card into the SD card slot on the under-side of the Nexys4 board.
• Switch on the Nexys4 board.
ALT
• Enter the Utility Menu by holding down on the USB keyboard you have
connected to the Nexys4 board.
• Enter the FDISK/FORMAT tool by pressing 2 when the option appears on the
MEGA65 boot screen.
• Follow the prompts in the FDISK/FORMAT program to again format the SD card
for use by the MEGA65.

The FDISK tool will partition your SD card into two partitions and format
them.
– One is type $41 = MEGA65 System Partition, where the save slots, config-
uration data and other files live.
(This partition is invisible in i.e. Win PCs).

14-14
– The other partition with type $0C = VFAT32, where KERNAL, support files,
games, and so on, will be copied to later.
(This partition is visible on i.e. Win PCs).
• Once formatting is complete, switch off the Nexys4 board and remove the mi-
croSDHC card from the Nexys board and put it back into your PC
• This time, copy the following items onto the SD card:
– The bitstream file
– The extracted files from within either the ”SD essentials.rar” or ”SD es-
sentialsNoROM.rar” file that you downloaded from the MEGA65 filehost.
(See the MEGA65 Book, ?? (??) for more details).
– If you have sourced your own preferred ROM file (e.g. ”911001.BIN”), copy
it onto the SD card also, and rename it to ”MEGA65.ROM” (uppercase is
essential).
– Any .D81 disk image files you wish to make use of.
* Note that if a file named MEGA65.D81 is added to the SD card, it will
be mounted automatically on startup.
* Make sure that all .D81 files have names that fit the old DOS 8.3 char-
acter limit, and are upper case. This restriction will be removed in a
future release.
• Remove the SD card and reinsert it into your Nexys4 board.
• Power the Nexys4 board back on. The MEGA65 should boot within 15 seconds.
• On first start up, you will find yourself at the on-boarding screen, of which more
details can be found in Chapter/Appendix 4 on page 4-3 .
Congratulations. Your MEGA65 has been set up and is ready to use.
Please note that the above method of copying the bitstream file to the SD card means
that the bitstream is loaded into the Nexys FPGA each time on boot - which takes
around 13 seconds for the system to start. The bitstream can also be flashed using
Vivado software into the QSPI flash to deliver a boot up time of 0.3 seconds.
For more detailed information on preparing and configuring your MEGA65, please
refer to Chapter/Appendix 4 on page 4-3 chapter.

LOADING THE BITSTREAM FROM QSPI


While loading the bitstream from the SD card is the suggested (and well-trodden)
path this document has chosen, of late, more nexys4 users have been exploring the
alternative pathway of loading the bitstream from the QSPI flash. Some potential
reasons they have chosen this pathway are:

14-15
• Faster loading times (0.3 seconds versus 13 seconds)
• Some people were interested in the possibility of flashing multiple cores onto
their QSPI (via steps described in the Chapter/Appendix 5 on page 5-5 Chap-
ter)
• Some people have experienced niggling issues with the SD card pathway, such
as:
– System unable to reboot from on-boarding screen
– System unable to reboot from freeze-menu after switching between
PAL/NTSC
In time, if this proves to be a more popular pathway, we can revise our documentation
here to suit it. Here are some steps in brief.

Preparation Steps
For users that want to try this pathway, you will need to adjust the JP1 jumper setting
to use QSPI and then follow the steps in the Flashing the FPGAs and CPLDs in the
MEGA65 chapter in relation to Installing Vivado and Flashing the main FPGA using
Vivado.
Be forewarned that the installation of Vivado is a lengthy process (both in terms of
download time, and installation time).
Once you have flashed Slot0 of your QSPI chip via Vivado, you can then follow the
steps described in Chapter/Appendix 4 on page 4-3 to perform the custom SD card
formatting, installing of ROM and support files and on-boarding.

WIDGET BOARD
For Nexys board owners (all models), you may be interested in adding a widget board
to your nexys device, in order to allow you to connect to:
• a genuine C64 or C65 keyboard
• 2 DB-9 joysticks
• Paddles or a 1351 Mouse
• Cartridges (not functioning as yet)
The widget board connects to your nexys board via its PMOD connectors.
It presently is only available as an unpopulated PCB, purchasable from here:
• https://oshpark.com/shared_projects/Y37xg9N7
The firmware, pcb diagram, schematic diagram and bill of materials can be found
within the following github project:

14-16
• https://github.com/sy2002/DM65PIC
You will need to purchases parts from the bill of materials separately and populate the
board yourself.
You may find this forum64.de thread of interest, if you would like to read on the expe-
riences of others that undertook this process, or if you have questions of your own to
ask:
• https://www.forum64.de/index.php?thread/90465-mega-65-ports-add-on-card-s
The pcb (c65Keyb.brd) and schematic (c65Keyb.sch) files can be found within the ’ea-
gle/’ subfolder of the DM65PIC project, and can be viewed via the free tool ’AutoDesk
Eagle’, available here:
• https://www.autodesk.com/products/eagle/free-download
Here are some photos of the widget board in use:

14-17
14-18
For convenience, the pcb and schematics diagrams for the widget board have also
been provided in Chapter/Appendix AB on page AB-51.
Some additional backstory notes for the board are:
• The widget board is originally meant to sit inside a c65 case
• Expansion port is not usable and a bit needs to be cut out for c64 case
• Would be reasonable to adapt it for c64 case use (which definitely will be the
more regular use)

PMOD-TO-JOYSTICK ADAPTER
As an alternate (and cheaper) option for those that just want to add a DB9 joystick
port via the PMOD connectors, a user from the community, TheChief, has devised a
means to do so. More information can be found in the following Discord thread:
• https://discord.com/channels/719326990221574164/903079038015389716/
929369283119685643

14-19
PMOD-JA
Joystick action DB9 Connections
Connections
Fire jahi(9) pin 6
Up jalo(1) pin 1
Left jalo(2) pin 3
Down jahi(7) pin 2
Right jahi(8) pin 4

USEFUL TIPS
The following are some useful tips for getting familiar with the MEGA65:

14-20
• Press & hold ` (or the Commodore key if using a Commodore 64 or 65 key-
board) during boot to start up in C64-mode instead of C65-mode
RUN
• Press & hold STOP during boot to enter the machine language monitor, instead
of starting BASIC.
RESTORE
• Press for approximately 1/2 - 1 second to enter the MEGA65 Freeze
Menu. From this menu you have convenient tools to change the CPU speed,
switch between PAL & NTSC video mode, change Audio settings, manage
freeze-states, select D81 disk images, examine and modify memory of the frozen
program, among other features. This is in many ways the heart of the MEGA65,
so it is well worth exploring and getting familiar with.
• Type POKE0,65 in C64-mode to switch the CPU to full speed (40MHz). Some soft-
ware may behave incorrectly in this mode, while other software will work very
well, and run many times faster than on a C64.
• Type POKE0,64 in C64-mode to switch the CPU to 1MHz.
• Type SYS58552 in C64-mode to switch to C65-mode.
• Type GO64 in C65-mode and confirm, by pressing Y, to switch to C64-mode, which
is the same as on a C128.
• The C65 ROM makes device 8 the default, so you can normally leave off the ,8
from the end of LOAD and SAVE commands.
SHIFT RUN
• Pressing + STOP from either C64 or C65-mode will attempt to boot from
disk.
Have fun! The MEGA65 has been lovingly crafted over many years for your enjoyment.
We hope you have as much fun using it as we have had creating it!
The MEGA Museum of Electronic Games & Art welcomes your feedback, suggestions
and contributions to this open-source digital heritage preservation project.

14-21
14-22
PART VII
CROSS-PLATFORM
DEVELOPMENT TOOLS
14-24
CHAPTER 15
Emulators
• Using The Xmega65 Emulator
• Using the Live ISO image
15-2
At the time of writing, there is only one emulator for the MEGA65, xmega65; LGB’s
Xemu emulator suite. The LGB developers work hard to keep up with the development
of the MEGA65; however, some MEGA65 emulation may not be accurate but should
be sufficient for software development on the MEGA65.
During development, frequently test software on real hardware, such as a MEGA65 or
FPGA board capable of running a MEGA65 core.
Download the MEGA65 emulator source code from https://github.com/lgblgblgb/
xemu.
Download pre-compiled versions from https://github.lgb.hu/xemu/. Installers are
available for macOS, Windows and Linux.
A live ISO image containing the emulator, documentation, and other tools
is available from Forum64.de at https://www.forum64.de/index.php?thread/
104698-xemu-live-system-iso-file/&postID=1549927#post1549936. Should you
choose to use it you may find instructions on page 15-5.

USING THE XMEGA65 EMULATOR


The keyboard
The MEGA65 keyboard layout is based on the Commodore 65, which is unlike a mod-
ern PC keyboard. In most cases, the Xmega65 emulator recognizes PC keys as their
Shift
equivalent MEGA65 keys, such as letters, numbers, and common modifiers like .
Xmega65 assumes an American/U.S. layout.
Some keys are only present on the MEGA65 keyboard and have no PC equivalents.
Insert Home Page Page
Xmega65 uses the PC keys , Delete , , End , Up , and Down to represent
+ , £ , CLR
HOME ,
RUN
STOP ,
HELP
, and
RESTORE
, respectively.

RUN RESTORE
On most PC keyboards, this places STOP and next to each other, to make that
key combination easy to enter.

15-3
This diagram shows the PETSCII glyphs as they appear on a MEGA65 keyboard, with
the ` glyph on the left and the Shift
glyph on the right. Note that on a PC keyboard,
the key for ` is to the right of the Shift
.
Enter
Xemu lets you have two joysticks (one at a time) on the numeric keypad. over
there is used to toggle ports 1, 2 and to off when pressed repeatedly.

Please be aware the emulator by default catches F9 F10 F11 as shortcuts


of its own functions. If you want to use these keys with the emulated MEGA65, you
must configure the keyboard mapping. The files are found in the folder for Xemu’s
settings as explained on page 15-5. This is done by copying keymap-default.cfg
into keymap.cfg and then removing the following lines:

XEMU-EXIT F9
XEMU-FULLSCREEN F11

and changing:

F9 Unknown
F11 Unknown

into:

F9 F9
F11 F11

With these keys remapped, the full-screen and exit functions are still available from
the menu. Right-click (or control-click) anywhere in the window to access it.

Apple MacOS start problems


If a message macOS cannot verify that this app is free from malware
pops up use the following procedure when you open the app for the first time:
• Open Finder on your Mac.
• Control-click (or right-click) on the Xmega65 app icon.
• In the context menu, select Open.
• The message appears again, but this time there is an Open button. Click Open.
You only need to perform this procedure the first time you run the app. From now
on, you can open the app normally.

15-4
Updating settings
You may wish to edit the Xemu settings file to change the keyboard mapping or make
a backup of the SD card image file. To access these files from within Xemu, open the
menu, select Debug / Advanced then Browse system folder. Edit the keymap-
default.cfg and mega65-default.cfg files with a text editor. For specific in-
structions on how to change keymap-default.cfg please refer to page 15-3.

The Xemu system folder location varies by operating system:


• Windows (may be copied into the address bar of the file explorer):
%appdata%\xemu-lgb\mega65
• Linux: ~/.xemu-lgb/
• Macintosh: ~/Library/Application\ Support/xemu-lgb/mega65/

USING THE LIVE ISO IMAGE


The Live ISO image is the product of a volunteer community; not the MEGA65 team.
We include it for your convenience.

Creating a Bootable USB stick or DVD


There are many ways to create a live ISO image. The method you choose depends
on your operating system and whether you wish to install to a USB drive or burn it to
a DVD. Burning to a DVD is straightforward, assuming you own a computer that has a
DVD writer. If you wish to create a faster bootable USB drive, try one of the methods
below:
If you are using Windows, consider a tool like http://www.isotousb.com/.

15-5
On Linux, you can use the instructions at https://fossbytes.com/
create-bootable-usb-media-from-iso-ubuntu/.
For Apple Macs, consider these instructions at https://ubuntu.com/tutorials/
create-a-usb-stick-on-macos#1-overview.
Similar instructions are available for other popular computers, such as Ami-
gas (https://forum.hyperion-entertainment.com/viewtopic.php?t=3857), or Sun
UltraSPARC workstations (https://forums.servethehome.com/index.php?threads/
how-to-create-a-bootable-solaris-11-usb.1998/).
Finally, the popular, easy-to-use, and free cross-platform belanaEtcher is available at
https://www.balena.io/etcher/.

Getting Started
To avoid potential copyright issues, the bootable ISO image does not include propri-
etary ROMs for the MEGA65; such as legacy C65 ROMs. It does include an open-
source replacement ROM from our OpenROMs project. This ROM will boot into a
BASIC 2 environment that you can use to load and execute many C64 programs as
shown in the image below:

If you wish to use a C65 ROM that includes BASIC 10, download the appropriate ROM
file and place it on another USB stick named MEGA65.ROM. On start-up, the MEGA65
will ask if a ROM has been downloaded; as shown in the image below:

15-6
If the Live ISO cannot find a ROM, it will prompt you to download a ROM; as shown
below:

Other Features of the Live ISO


As the previous screen-shots show, the Live ISO provides various and convenient desk-
top shortcuts. On the left-hand side, there are shortcuts for launching the MEGA65
emulator and the C65 emulator so you can test that programs will run on both plat-
forms. As previously mentioned, both emulators are a work in progress and may not
be 100% compatiable.
Another link provides access to the MEGA65 Book. This all-in-one volume, of apporix-
mately 800 pages, contains the official MEGA65 documentation. The majority of this
developer’s guide is also present in the MEGA65 Book.
This ISO also includes documentation for the C65 Notepad; a program for the C65
and MEGA65 written by Snoopy (the developer of the Live ISO image). A “read me”
file contains further information about the Live ISO.

15-7
Finally, on the right-hand side, there are links to download a C65 ROM and to update
the MEGA65 Book to the latest version. This will ensure you don’t need to create a
new bootable image each time a frequent update is made to the MEGA65 Book.
To access all contents of the Live ISO image, use the file explorer.

15-8
CHAPTER 16
Data Transfer and Debugging
Tools
• m65 command line tool
• M65Connect
• mega65_ftp
• TFTP Server
• Converting a BASIC text file listing into
a PRG file
16-2
The key to effective cross-platform development is having quick and easy means to
deploy and test software on the MEGA65. This is especially true while the MEGA65
emulator continues to be developed. In fact, even once the MEGA65 emulator is com-
plete, it is unlikely that it will be able to offer full compatibility at full speed, because
the MEGA65 is much more demanding to emulate than the C64.
There are a variety of tools that can be used for data transfer and debugging.
These typically function using either the MEGA65’s serial monitor interface, or via the
MEGA65’s fast ethernet adapter. The serial monitor interface is available via the UART
lines on the JB1 header.
If you do not have access to the serial monitor interface, there are tools being devel-
oped for the fast ethernet port that provide some, but not all, of the capabilities of the
serial monitor interface. These will be documented as they become available. The re-
mainder of this chapter focusses on methods that access the serial monitor interface.
You can either connect a 3.3V UART adapter to the appropriate lines, or more con-
veniently, connect a TE-0790-03 JTAG debug module onto this connector. This gives
you a USB connection that can be used for injecting software, remote debugging and
memory inspection, as well as activating or flashing bitstreams. With this connection,
there are the following tools:

M65 COMMAND LINE TOOL


The https://github.com/mega65/mega65-tools repository contains a number of
tools, utilities and example programs. These tools are mainly for Linux but can be used
on Windows with Cygwin. One of those is the m65 command line tool. This is rather a
swiss-army knife collection of utilities in one. Common useful functions include:

Screenshots using m65 tool


To take a screenshot of the MEGA65 use:
m65 -S

This will create a file called mega65-screeen-000000.png, or if that file already


exists, the first non-used number will be used in place of 000000.
Note that this screenshot function works by having m65 emulate the function of the
VIC-IV. Thus while it produces excellent looking digital screenshots, it may not exactly
match the real display of the MEGA65. At the time of writing it does not render sprites
or bitplanes, only text and bitmap-based video modes.

Load and run a program on the MEGA65


To load and run a program on the MEGA65, you can use a command like:

16-3
m65 -F -4 -r foo . prg

The -F option tells m65 to reset the MEGA65 before loading the program.
The -4 option tells m65 to switch the MEGA65 to C64-mode before loading the pro-
gram. If this is left off, then it will attempt to load the program in C65-mode.
The -r option tells m65 to run the program immediately after loading.
Note that this command works using the normal BASIC LOAD command, and is thus
limited to loading programs into the lower 64KB of RAM

Reconfigure the FPGA to run a different bitstream


To try out a different MEGA65 bitstream, a command like the following can be used:

m65 -b b i t s t r e a m . bit

This will cause the named bitstream to be sent to the FPGA. As the FPGA will be re-
configured by this action, and program currently running will not merely be stopped,
but also main memory will be cleared. For models of the MEGA65 that are fitted with
8MB or 16MB of expansion memory, those expansion memories are implemented in
external chips, and so the contents of them will not be erased.
For non-MEGA65 bitstreams (such as zxunomega65 and gbc4mega65), use the ’-q’
argument instead:

m65 -q b i t s t r e a m . bit

Remote keyboard entry


The MEGA65’s keyboard interface logic supports the injection of synthetic key events
using the registers $D615 – $D617. The m65 utility uses this to allow remote typing
on the MEGA65 in a way that is transparent to software. There are three ways to use
this:
m65 -t s o m e t e x t

This form types the supplied text, in this case sometext, but does not simulate pressing
RETURN RETURN
. If you wish to simulate the pressing of , use -T instead of -t, e.g.:

m65 -T list

This would cause the LIST command to be typed and executed.


Finally, it is possible to begin general remote keyboard control via:

16-4
m65 -t -

In this mode, any key pressed on the keyboard of the computer where m65 is running
will be relayed to the MEGA65. Note that not all special keys are supported, and
that there is some latency, so using key repeat can cause unexpected results. But for
general remote control, it is a very helpful facility.

Unit testing and logging support


The m65 tool includes support to facilitate remote unit testing directly on MEGA65
hardware. When unit testing mode is active, m65 waits for the MEGA65 to send cer-
tain byte sequences over the serial interface which signal the current state (started,
passed, failed) of a given test. Additionally, it is possible to send log messages from
the MEGA65 to the host computer.
Unit testing mode is entered by calling m65 with the -u flag. To run a remote BASIC
program in C65-mode and simultaneously put m65 into unit testing mode, the following
command can be used:
m65 - Fur attic - ram . prg -w tests . log

The -F and -r options tell m65 to reset the MEGA65 before loading the program
”attic-ram.prg” and then automatically run it. The -u option then tells m65 go into unit
testing mode instead of exiting after launching the program. The optional -w option
makes m65 append the test results to the file ”test.log” (creating the file if it doesn’t
exist).
Please note that m65 automatically exits from unit testing mode if no test state signals
were received for over 10 seconds.
Support is provided for sending unit test signals to the host computer from C and BASIC
65 programs:

Using unit tests with C


The MEGA65 libc contains support for unit testing via functions defined in tests.h
and tests.c.
To signal the start of a test, include tests.h and use
unit_test_setup("testName",issueNumber);
where ”testName” is a human-readable name of the test (e.g. ”VIC-II”) and issueNum-
ber a reference to the corresponding bug issue (for example, the issue number from
github).
After starting a test, it’s possible to signal passed tests with the unit_test_ok() function:
unit_test_ok();

16-5
A failed test is signalled with unit_test_fail():
unit_test_fail("fail message");
Each time the unit_test_ok() or unit_test_fail() functions are called, the sub issue of the
test (reported on the host computer) is incremented. This makes it easier to combine
and identify multiple tests in one file.
You can send arbitrary log messages via unit_test_log():
unit_test_log("hello world from mega65!");
...and finally, when all is done, the end of unit testing is signalled by the use of
unit_test_done();

Using unit tests with BASIC 65


b65support.bin is a machine language module providing support for unit testing
from BASIC 65, available in the bin65 folder of the mega65-tools repository. This
module works by redirecting the USR vector to perform the functions needed to com-
municate with the testing host.
In an automated test scenario, you may want to inject the b65support.bin binary
into MEGA65 RAM by using m65:

m65 -@ mega65 - tools / bin65 / b 6 5 s u p p o r t . b i n @ 1 5 f e

Of course it’s also possible to load b65support.bin directly from the MEGA65 by
mounting the M65UTILS.D81 image from the freezer and issuing

BLOAD " B 6 5 S U P P O R T . BIN "

After loading, b65support.bin is initialised with

SYS $1600

Once initialised, the following functions are provided by b65support.bin:

A = USR ( < issueNum >)

prepares a new test with number <issueNum> and resets subissue number to 0

A = USR ("= < testName >")

sets test name and sends test start signal; for example: A=USR("=VIC-III") sets
the test name to ’VIC-III’ and signals the host computer that the test has started.

16-6
A = USR ("/ < logMessage >)

sends a log message to the host computer

A = USR (" P ")

sends the ’passed’ signal to the host computer and increases the sub issue number

A = USR (" F ")

sends the ’test failed’ signal to the host computer and increases the sub issue number

A = USR (" D ")

sends the ’test done’ signal to the host computer


All calls return the current sub issue number or ?ILLEGAL QUANTITY ERROR in case
of calling an invalid command.

BASIC 65 example
The following is a complete BASIC 65 example showing how to use m65’s unit testing
features:

16-7
100 rem attic ram cache test
110 poke $bfffff2 , $e0 : rem enable attic ram cache
120 sys $1600 : rem init test module
130 a = usr (379) : rem set issue number
140 a = usr ("= attic - ram - cache ") : rem set test name
150 ba nk1 28 : poke0 ,65 : rem just to be sure
160 b0 = $ 8 0 0 0 0 0 0 : b1 = $ 8 0 0 0 1 0 0 : rem attic ram areas to be tested
170 for r =0 to $ff
180 poke b0 +r ,0 : rem fill area 1 with 0
190 poke b1 +r , $ff : rem fill area 2 with $ff
200 next r
210 for t =1 to 10 : rem 10 tries
220 poke b0 ,32 : rem write to b0
230 for x =0 to $ff : t1 = b1 + x
240 a = peek ( b0 ) : rem read from b0
250 b = peek ( t1 ): b = peek ( t1 ) : rem read twice from t1
260 ifb < >255 thenf = t : t =11: x =256 : rem this shouldn ' t happen
270 next x
280 next t
290 if f =0 then begin
300 print " no faults d e t e c t e d after "; t ;" tries ."
310 a = usr (" p ") : rem signal ' test passed ' to host
320 bend : else begin
330 a = usr (" f ") : rem signal ' test failed ' to host
340 print " hyper ram fault d e t e c t e d after "; f ;" tries ."
350 print " peek ( $ "; hex$ ( t1 );") [ t1 ] is "; b ;" but should be 255"
360 bend
370 a = usr (" d ") : rem test done

M65CONNECT
This is a cross-platform graphical tool available for Windows, Linux and MacOSX, which
allows access to most of the functions of the m65 command-line tool, without needing
to use a command line, or being able to compile the tool for your preferred operating
system.
The repository for M65Connect is: https://github.com/MEGA65/m65connect
The latest binary version is available from https://files.mega65.org.
With the MEGA65 or Nexys FPGA switched off, connect a USB cable from your com-
puter to the MEGA65 or Nexys FPGA board. Run the M65Connect executable and
follow the prompts to connect. The program will help you identify which USB Serial
Port to communicate over.

16-8
With this tool you can easily transfer PRG programs and a variety of other files.
M65Connect can handle the transfer, switching to C64-mode, and execution of pro-
grams.

MEGA65_FTP
The mega65_ftp utility from the https://github.com/mega65/mega65-tools repos-
itory is a little misleadingly named: While it is a File Transfer Program, it does not use
the File Transfer Protocol (FTP). Rather, it uses the serial monitor interface to take re-
mote control of a MEGA65, and directly access its SD card to enable copying of files
between the MEGA65 and the host computer.
Note that it does not perfectly restore the MEGA65’s state on exit, and thus should
only be used when the MEGA65 is at the READY prompt, so that any running software
doesn’t go haywire. In particular, you should avoid using it when a sensitive program
is running, such as the Freeze Menu, MEGA65 Configuration Utility, or the MEGA65
Format/FDISK utility. (This problem could be solved with a little effort, if someone has
the time and interest to fix it).
When run, it provides an FTP-like interface that supports the get, put, rename and
dir commands. Note that when putting a file, you should make sure that it is given
a name that is all capitals and has o DOS-compatible 8.3 character file name. This
is due to limitations in both mega65_ftp and the MEGA65’s Hypervisor’s VFAT32 file
system code. Again, these problems could be fixed with a modest amount of effort
on the part of a motivated member of the community.
Finally, the mega65_ftp program is very slow to push new files to the MEGA65, typ-
ically yielding speeds of around 5KB/sec. This is partly because the serial monitor
interface is capable of transferring data at only 40KB/sec (when set to 4,000,000
bits per second), and partly because the remote control process results in a lot of
round-trips where helper routines are executed on the MEGA65 to read, write and
verify sectors on the SD card. It would be quite feasible to improve this to reach close
to 40KB/sec, and potentially faster using either some combination of data compres-
sion, de-duplication of identical sectors (especially when uploading disk images) and
other techniques. Again, this would be a very welcome contribution that someone in
the community could contribute to everyone’s benefit.

TFTP SERVER
Work on a true TFTP server for the MEGA65 that supports fast TFTP transfers over
the 100mbit ethernet has begun, and can be used to very quickly read files from the
MEGA65. Speeds of close to 1MB/sec are possible, depending on SD card perfor-
mance. Rather than using DHCP, this utility will respond to any IP address that ends in
.65. It always uses the MAC address 40:40:40:40:40:40. True DHCP support as well
as using the MEGA65’s configured ethernet MAC address may be added in the future.

16-9
More importantly, support for writing files to the SD card is not yet complete, and
is blocked by the need for the implementation of the necessary functions in the
MEGA65’s Hypervisor for creating and growing files. A particular challenge is en-
abling the creation of files with contiguous clusters as is required for D81 disk images:
If a D81 file is fragmented, then it cannot be mounted, because the mounting mech-
anism requires a pointer to the contiguous block of the SD card containing the disk
image. In the interim, mega65_ftp can be used as a substitute.

CONVERTING A BASIC TEXT FILE


LISTING INTO A PRG FILE
If you have a untokenised BASIC program in plain text format sourced from somewhere
like an internet post, and you wish to try it on the MEGA65 without typing it in, it is
possible to convert it to a PRG.
C64List is a Windows-based command-line tool that will allow you to make the con-
version. Once you have a .PRG file, you can use a tool like M65Connect to upload it
to the MEGA65 or Nexys FPGA.
C64List is available for download from http://www.commodoreserver.com/
Downloads.asp
Ensure you have a program listing saved to a file on your local computer (for example,
program.txt) encoded as ANSI or UTF8.
Use C64List to convert the file to a PRG file using:

C64List program.txt -prg

Now you can upload your newly converted program to the MEGA65 with M65Connect
or one of the other tools described previously.
It is worth noting that this method will not be 100% effective on listings with special
PETSCII characters. Programs with PETSCII will require some editing on the MEGA65
itself before saving to disk.

16-10
CHAPTER 17
Assemblers
17-2
The table below shows an overview of assemblers known to work with MEGA65. For
general use we recommend ACME as it has good support for the 45GS02 instruction
set; is open source; and finally written in C. The latter means that it may be ported to
run natively on the MEGA65 in the future.

Name 45GS02 Source Reference


ACME yes C https://sourceforge.net/projects/acme-crossass
KickAss yes Java gitlab.com/jespergravgaard/kickassembler65ce02
LLVM-MOS yes C++ https://llvm-mos.org/wiki/Welcome
Ophis yes Python https://github.com/michaelcmartin/Ophis
BSA yes C https://github.com/Edilbert/BSA
CA65 no1 C https://github.com/mega65/cc65

The BSA assembler is currently used to build the MEGA65.ROM. Most of this source
code is written in the syntax of the ancient BSO assembler (Boston Systems Office),
which was used in the years 1989 - 1991 by software developers, working on the C65.
The BSA Assembler has a compatibility mode, which makes it possible to assemble
these old source codes with minor or none modifications. The BSA Assembler has
currently only a description of commands embedded in the C-source of the assembler.
The LLVM-MOS project comes with a GNU compatible macro assembler and disas-
sembler that supports all mnemonics of the 45GS02. It can be used as a stand-alone
tool with the command llvm-mc.

1 Our fork of CA65 (part of CC65) correctly detects the MEGA65’s CPU, but has no explicit support for

the processor’s features

17-3
17-4
CHAPTER 18
C and C-Like Compilers
• MEGA65 libc
18-2
Short answer: CC65 and KickC both work on the MEGA65.
Both CC65 and KickC are known to work on the MEGA65. However, both by default
have only a C64 memory model, and use only 6502 opcodes. It would be super for
someone to create a C65 memory configuration for CC65, and should not be too
hard to do.
CC65 supports overlays, which could be powerfully used with the MEGA65’s extra
memory to allow programs larger than 64KB. However, this would require writing a
suitable loader for such programs, which also does not yet exist.
Similarly, modifying the code generator of CC65 to use 45GS02 features would
not be particularly difficult to do, and would help to overcome the otherwise horri-
bly slow and bloated code that CC65 produces. Also adding first-class support for
the 45GS02 CPU features in CA65 (or perhaps even better, making CC65 produce
ACME compatible assembly output) would be of tremendous advantage, and not par-
ticularly hard to do. These would all be great tasks to tackle while you wait for your
MEGA65 DevKit to arrive!
An example template for a C program that can be compiled using CC65 and exe-
cuted on the MEGA65 can be found in the repository https://github.com/MEGA65/
hello-world. This repository will even download and compile CC65, if you don’t al-
ready have it installed on your system. This repository should work on Linux and Mac,
and on Windows under the Windows Subsystem for Linux (WSL).
The LLVM-MOS project (https://llvm-mos.org) has a MEGA65 target that has been
tested with C99, C++11, and Rust. The LLVM MOS compiler has support for 45GS02
instructions (-mcpu=mos45gs02) and comes with an assembler and disassembler. Pre-
compiled binaries of the SDK are available for Linux, Windows, and macOS.

MEGA65 LIBC
A C library is being developed for the MEGA65, and which already includes a num-
ber of useful features. This library is available from http://github.com/mega65/
mega65-libc. The procedures, functions and definitions it provides are documented
in a separate chapter.
The MEGA65 libc is currently available only for LLVM and CC65, although we would
welcome someone maintaining a KickC port of it.

18-3
18-4
CHAPTER 19
MEGA65 Standard C Library
• Structure and Usage
• conio.h
19-2
A C library is being developed for the MEGA65, and which already includes a num-
ber of useful features. This library is available from http://github.com/mega65/
mega65-libc. The procedures, functions and definitions it provides are documented
in a separate chapter.

STRUCTURE AND USAGE


The MEGA65 libc is purposely provided in source-form only, and with groups of func-
tions in separate files, and with separate header files for including. The idea is that you
include only the header files that you require, and add only the source files required
to the list of source files of the program you are compiling. This avoids the risk of the
compiler including functions in your compiled program that are never used, and thus
wasting precious memory space.
Note that some library source files are written in C, and thus are present as files with
a .c extension, while others are written in assembly language either for efficiency or
out of necessity, and have a .s extension.
Typical usage is to either have the mega65-libc source code checked out in an adja-
cent directory, or within the source directory of your own project. In the latter case,
this can be done using the git submodule facility.
The following sections document each of the header files and the corresponding func-
tions that they provide.

CONIO.H
conionit
Description: Initialises the library internal state
Syntax: void conioinit(void)
Notes: This must be called before using any conio library function.

setscreenaddr
Description: Sets the screen RAM start address
Syntax: void setscreenaddr(long addr);
Parameters: addr: The address to set as start of screen RAM
Notes: No bounds check is performed on the selected address

19-3
getscreenaddr
Description: Returns the screen RAM start address
Syntax: long getscreenaddr(void);
Return Value: The current screen RAM address start address.

setcolramoffset
Description: Sets the color RAM start offset value
Syntax: void setcolramoffset(long offset);
Parameters: addr: The offset from the beginning of the color RAM address
($FF80000)
Notes: No bounds check is performed on the resulting address. Do not exceed
the available Color RAM size

getcolramoffset
Description: Returns the color RAM start offset value
Syntax: long getscreenaddr(void);
Return Value: The current color RAM start offset value.

setcharsetaddr
Description: Sets the character set start address
Syntax: void setcharsetaddr(long addr);
Parameters: addr: The address to set as start of character set
Notes: No bounds check is performed on the selected address

getcharsetaddr
Description: Returns the current character set start address
Syntax: long getscreenaddr(void);
Return Value: The current character set start address.

19-4
clrscr
Description: Clear the text screen.
Syntax: void clrscr(void)
Notes: Color RAM will be cleared with current text color

getscreensize
Description: Returns the dimensions of the text screen
Syntax: void getscreensize(unsigned char* width, unsigned
char* height)
Parameters: width: Pointer to location where width will be returned
height: Pointer to location where height will be returned

setscreensize
Description: Sets the dimensions of the text screen
Syntax: void setscreensize(unsigned char width, unsigned char
height)
Parameters: width: The width in columns (40 or 80)
height: The height in rows (25 or 50)
Notes: Currently only 40/80 and 25/50 are accepted. Other values are
ignored.

set16bitcharmode
Description: Sets or clear the 16-bit character mode
Syntax: void set16bitcharmode(unsigned char f)
Parameters: f: Set true to set the 16-bit character mode
Notes: This will trigger a video parameter reset if HOTREG is ENABLED. See
sethotregs function.

19-5
sethotregs
Description: Sets or clear the hot-register behavior of the VIC-IV chip.
Syntax: void set16bitcharmode(unsigned char f)
Parameters: f: Set true to enable the hotreg behavior
Notes: When this mode is ENABLED a video mode reset will be triggered when
touching $D011, $D016, $D018, $D031 or the VIC-II bank bits of
$DD00.

setextendedattrib
Description: Sets or clear the VIC-III extended attributes mode to support blink,
underline, bold and highlight.
Syntax: void setextendedattrib(unsigned char f)
Parameters: f: Set true to set the extended attributes mode

togglecase
Description: Set lower case character set
Syntax: void setlowercase(void)

togglecase
Description: Set upper case character set
Syntax: void setuppercase(void)

togglecase
Description: Toggle the current character set case
Syntax: void togglecase(void)

bordercolor
Description: Sets the current border color
Syntax: void bordercolor(unsigned char c)

19-6
Parameters: c: The color to set

bgcolor
Description: Sets the current screen (background) color
Syntax: void bgcolor(unsigned char c)
Parameters: c: The color to set

textcolor
Description: Sets the current text color
Syntax: void textcolor(unsigned char c)
Parameters: c: The color to set
Notes: This function preserves attributes in the upper 4-bits if extended at-
tributes are enabled. See setextendedattrib.

revers
Description: Enable the reverse attribute
Syntax: void revers(unsigned char c)
Parameters: enable: 0 to disable, 1 to enable
Notes: Extended attributes mode must be active. See setextendedattrib.

highlight
Description: Enable the highlight attribute
Syntax: void highlight(unsigned char c)
Parameters: enable: 0 to disable, 1 to enable
Notes: Extended attributes mode must be active. See setextendedattrib.

blink
Description: Enable the blink attribute
Syntax: void blink(unsigned char c)

19-7
Parameters: enable: 0 to disable, 1 to enable
Notes: Extended attributes mode must be active. See setextendedattrib.

underline
Description: Enable the underline attribute
Syntax: void underline(unsigned char c)
Parameters: enable: 0 to disable, 1 to enable
Notes: Extended attributes mode must be active. See setextendedattrib.

altpal
Description: Enable the alternate-palette attribute
Syntax: void altpal(unsigned char c)
Parameters: enable: 0 to disable, 1 to enable
Notes: Extended attributes mode must be active. See setextendedattrib.

clearattr
Description: Clear all text attributes
Syntax: void clearattr())
Notes: Extended attributes mode must be active. See setextendedattrib.

cellcolor
Description: Sets the color of a character cell
Syntax: void cellcolor(unsigned char x, unsigned char y, un-
signed char c)
Parameters: x: The cell X-coordinate
y: The cell Y-coordinate
c: The color to set
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

19-8
setpalbank
Description: Set current text/bitmap palette bank (BTPALSEL).
Syntax: void setpalbank(unsigned char bank)
Parameters: bank: The palette bank to set. Valid values are 0, 1, 2 or 3.
Notes: Use setpalbanka to set alternate text/bitmap palette

setpalbanka
Description: Set alternate text/bitmap palette bank.
Syntax: void setpalbanka(unsigned char bank)
Parameters: bank: The palette bank to set. Valid values are 0, 1, 2 or 3.
Notes: Use setpalbank to set main text/bitmap palette

getpalbank
Description: Get selected text/bitmap palette bank.
Syntax: unsigned char getpalbank(void)
Notes: Use getpalbanka to get alternate text/bitmap selected palette
Return Value: The current selected main text/bitmap palette bank.

getpalbanka
Description: Get selected alternate text/bitmap palette bank.
Syntax: unsigned char getpalbanka(void)
Notes: Use getpalbank to get main text/bitmap selected palette
Return Value: The current selected alternate text/bitmap palette bank.

setmapedpal
Description: Set maped-in palette bank at $D100-$D3FF.
Syntax: void setmapedpal(unsigned char bank)
Parameters: bank: The palette bank to map-in. Valid values are 0, 1, 2 or 3.

19-9
getmapedpal
Description: Get maped-in palette bank at $D100-$D3FF.
Syntax: unsigned char getmapedpal(void)

setpalentry
Description: Set color entry for the maped-in palette
Syntax: void setpalentry(unsigned char c, unsigned char r,
unsigned char g, unsigned char b)
Parameters: c: The palette entry index (0-255)
r: The red component value
g: The green component value
b: The blue component value
Notes: Use setmapedmal to bank-in the palette to modify

fillrect
Description: Fill a rectangular area with character and color value
Syntax: void fillrect(const RECT *rc, unsigned char ch, un-
signed char col)
Parameters: rc: A RECT structure specifying the box coordinates
ch: A char code to fill the rectangle
col: The color to fill
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

box
Description: Draws a box with graphic characters
Syntax: void box(const RECT *rc, unsigned char color, unsigned
char style, unsigned char clear, unsigned char shadow)
Parameters: rc: A RECT structure specifying the box coordinates
color: The color to use for the graphic characters

19-10
style: The style for the box borders. Can be set to
BOX_STYLE_NONE, BOX_STYLE_ROUNDED, BOX_STYLE_INNER,
BOX_STYLE_OUTER, BOX_STYLE_MID
clear: Set to 1 to clear the box interior with the selected color
shadow: Set to 1 to draw a drop shadow
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

hline
Description: Draws an horizontal line.
Syntax: void hline(unsigned char x, unsigned char y, unsigned
char len, unsigned char style)
Parameters: x: The line start X-coordinate
y: The line start Y-coordinate
len: The line length
style: The style for the line. See HLINE_ constants for available styles.
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

vline
Description: Draws a vertical line.
Syntax: void vline(unsigned char x, unsigned char y, unsigned
char len, unsigned char style)
Parameters: x: The line start X-coordinate
y: The line start Y-coordinate
len: The line length
style: The style for the line. See VLINE_ constants for available styles.
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

gohome
Description: Set the current position at home (0,0 coordinate)

19-11
Syntax: void gohome(void)

gotoxy
Description: Set the current position at X,Y coordinates
Syntax: void gotoxy(unsigned char x, unsigned char y)
Parameters: x: The new X-coordinate
y: The new Y-coordinate
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

gotox
Description: Set the current position X-coordinate
Syntax: void gotox(unsigned char x)
Parameters: x: The new X-coordinate
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

gotoy
Description: Set the current position Y-coordinate
Syntax: void gotoy(unsigned char y)
Parameters: y: The new Y-coordinate
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

moveup
Description: Move current position up
Syntax: void moveup(unsigned char count)
Parameters: count: The number of positions to move
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

19-12
movedown
Description: Move current position down
Syntax: void movedown(unsigned char count)
Parameters: count: The number of positions to move
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

moveleft
Description: Move current position left
Syntax: void moveleft(unsigned char count)
Parameters: count: The number of positions to move
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

moveright
Description: Move current position right
Syntax: void moveright(unsigned char count)
Parameters: count: The number of positions to move
Notes: No screen bounds checks are performed; out of screen behavior is
undefined

wherex
Description: Return the current position X coordinate
Syntax: unsigned char wherex(void)
Return Value: The current position X coordinate

wherey
Description: Return the current position Y coordinate
Syntax: unsigned char wherey(void)

19-13
Return Value: The current position Y coordinate

pcputc
Description: Output a single petscii character to screen at current position
Syntax: void cputc(unsigned char c)
Parameters: c: The petscii character to output

pcputsxy
Description: Output a petscii string at X,Y coordinates
Syntax: void pcputsxy (unsigned char x, unsigned char y, const
unsigned char* s)
Parameters: x: The X coordinate where string will be printed
y: The Y coordinate where string will be printed
s: The petscii string to print
Notes: No pointer check is performed. If s is null or invalid, behavior is unde-
fined

cputcxy
Description: Output a single petscii character at X,Y coordinates
Syntax: void pcputcxy (unsigned char x, unsigned char y, un-
signed char c)
Parameters: x: The X coordinate where character will be printed
y: The Y coordinate where character will be printed
c: The petscii character to print

pcputs
Description: Output a petscii string at current position
Syntax: void pcputs(const unsigned char* s)
Parameters: s: The string to print

19-14
Notes: No pointer check is performed. If s is null or invalid, behavior is unde-
fined

cputc
Description: Output a single screen code character to screen at current position
Syntax: void cputc(unsigned char c)
Parameters: c: The screen code of the character to output

cputnc
Description: Output N copies of a character at current position
Syntax: void cputnc(unsigned char count, unsigned char c)
Parameters: c: The screen code of the characters to output
count: The count of characters to print

cputhex
Description: Output an hex-formatted number at current position
Syntax: void cputhex(long n, unsigned char prec)
Parameters: n: The number to write
prec: The precision of the hex number, in digits. Leading zeros will be
printed accordingly
Notes: The $ symbol will be automatically added at beginning of string

cputdec
Description: Output a decimal number at current position
Syntax: void cputdec(long n, unsigned char padding, unsigned
char leadingZ)
Parameters: n: The number to write
padding: The padding space to add before number
leadingZ: The leading zeros to print

19-15
cputs
Description: Output screen codes at current position
Syntax: void cputs(const unsigned char* s)
Parameters: s: Am array of screen codes to print
Notes: This function works with screen codes only. To output ordinary ASCI-
I/PETSCII strings, use the ”pcputs” macro. No pointer check is per-
formed. If s is null or invalid, behavior is undefined.

cputsxy
Description: Output multiple screen codes at X,Y coordinates
Syntax: void cputsxy (unsigned char x, unsigned char y, const
unsigned char* s)
Parameters: x: The X coordinate where string will be printed
y: The Y coordinate where string will be printed
s: An array of screen codes to print
Notes: This function works with screen codes only. To output ordinary ASCI-
I/PETSCII strings, use the ”pcputsxy” macro. No pointer check is per-
formed. If s is null or invalid, behavior is undefined.

cputcxy
Description: Output a single character at X,Y coordinates
Syntax: void cputcxy (unsigned char x, unsigned char y, un-
signed char c)
Parameters: x: The X coordinate where character will be printed
y: The Y coordinate where character will be printed
c: The screen code of the character to print

cputncxy
Description: Output N copies of a single character at X,Y coordinates
Syntax: void cputncxy (unsigned char x, unsigned char y, un-
signed char count, unsigned char c)

19-16
Parameters: x: The X coordinate where character will be printed
y: The Y coordinate where character will be printed
count: The number of characters to output
c: The screen code of the characters to print

cprintf
Description: Prints formatted output.
Escape strings can be used to modify attributes, move cursor, etc sim-
ilar to PRINT in CBM BASIC.
Syntax: unsigned char cprintf (const unsigned char* format,
...)
Parameters: format: The string to output. The available escape codes are:

Cursor positioning
\t Go to next tab position (multiple of 8s)
\r Carriage Return
\n New line
{clr} Clear screen {home} Move cursor to home (top-left)
{d} Move cursor down {u} Move cursor up
{r} Move cursor right {l} Move cursor left
Attributes
{rvson} Reverse attribute ON {rvsoff} Reverse attribute OFF
{blon} Blink attribute ON {bloff} Blink attribute OFF
{ulon} Underline attribute ON {uloff} Underline attribute OFF
Colors (default palette)
{blk} {wht} {red} {cyan}
{pur} {grn} {blu} {yel}
{ora} {brn} {pink} {gray1}
{gray2} {lblu} {lgrn} {gray3}
Notes: This function works with screen codes only! To output ordinary ASCI-
I/PETSCII strings, use the ”pcprintf” macro. Currently no argument
replacement is done with the variable arguments.

pcprintf
Description: Prints formatted petscii string output.
Syntax: see cprintf

19-17
cgetc
Description: Waits until a character is in the keyboard buffer and returns it
Syntax: unsigned char cgetc (void);
Return Value: The last character in the keyboard buffer
Notes: Returned values are ASCII character codes

kbhit
Description: Returns the character in the keyboard buffer
Syntax: unsigned char kbhit (void);
Return Value: The character code in the keyboard buffer, 0 otherwise.
Notes: Returned values are ASCII character codes

getkeymodstate
Description: Return the key modifiers state.
Syntax: unsigned char getkeymodstate(void)
Return Value: A byte with the key modifier state bits, where bits:
Bit Meaning Constant
0 Right SHIFT State KEYMOD_RSHIFT
1 Left SHIFT state KEYMOD_LSHIFT
2 CTRL state KEYMOD_CTRL
3 MEGA state KEYMOD_MEGA
4 ALT state KEYMOD_ALT
5 NOSCRL state KEYMOD_NOSCRL
6 CAPSLOCK state KEYMOD_CAPSLOCK
7 Reserved -

flushkeybuf
Description: Flush the keyboard buffer
Syntax: void flushkeybuf(void)

19-18
cinput
Description: Get input from keyboard, printing incoming characters at current po-
sition.
Syntax: unsigned char cinput(char* buffer, unsigned char bu-
flen, unsigned char flags)
Parameters: buffer: Target character buffer preallocated by caller
buflen: Target buffer length in characters, including the null charac-
ter terminator
flags: Flags for input: (default is accept all printable characters)
CINPUT_ACCEPT_NUMERIC
Accepts numeric characters.

CINPUT_ACCEPT_LETTER
Accepts letters.

CINPUT_ACCEPT_SYM
Accepts symbols.

CINPUT_ACCEPT_ALL
Accepts all. Equals to CINPUT_ACCEPT_NUMERIC
|CINPUT_ACCEPT_LETTER |CINPUT_ACCEPT_SYM

CINPUT_ACCEPT_ALPHA
Accepts alphanumeric characters. Equals to
CINPUT_ACCEPT_NUMERIC |CINPUT_ACCEPT_LETTER

CINPUT_NO_AUTOTRANSLATE
Disables the feature that makes cinput to autodisplay uppercase
characters when standard lowercase character set is selected
and the user enters letters without the SHIFT key, that would
display graphic characters instead of alphabetic ones.

Return Value: Count of successfully read characters in buffer

VIC_BASE
VIC_BASE is a pre-processor macro that provides the base address of the VIC-IV chip,
i.e., $D000.

19-19
IS_H640 is a pre-processor macro that returns 0 if the current VIC-III/IV video mode
is set to 320 pixels accross (40 column mode), and non-zero if it is set to 640 pixels
across (80 column mode).

19-20
CHAPTER 20
BASIC Tokenisers
20-2
Various tokenisers for C64 BASIC exist, e.g., https://github.com/catseye/hatoucan,
https://www.c64-wiki.com/wiki/C64list, or the petcat utility that is part of VICE.
If you are using Ubuntu Linux, you can install petcat by using the following command:

sudo apt - get i nst all vice

We recommend petcat, because it supports both C64 BASIC 2 and C65 BASIC 10.
Some IDEs offer BASIC 65 tokenisers within them, such as:
Eleven
https://files.mega65.org?id=8b189d0b-ea1e-45a7-a4de-87bcb0b11696
C64 Studio
https://www.georg-rottensteiner.de/files/C64StudioRelease.zip
CBM prg Studio
https://www.ajordison.co.uk

20-3
20-4
PART VIII
APPENDICES
6
APPENDIX A
Accessories
A-2
APPENDIX B
BASIC 65 Command Reference
• Commands, Functions, and Operators
• BASIC Command Reference
B-2
COMMANDS, FUNCTIONS, AND
OPERATORS
This appendix describes each of the commands, functions, and other callable elements
of BASIC 65, which is an enhanced version of BASIC 10. Some of these can take one
or more arguments, which are pieces of input that you provide as part of the command
or function call, to help describe what you want to achieve. Some also require that
you use special words.
Below is an example of how commands, functions, and operators (all of which are also
known as keywords) will be described in this appendix.
KEY number, string
Here, KEY is a keyword. Keywords are special words that BASIC understands. In this
manual, keywords are always written in BOLD CAPITALS, so that you can easily recog-
nise them.
The “number” and “string” (in non-bold text) are examples of arguments. You replace
these with values or algebraic phrases (expressions) that represent the data that con-
trols the command’s behavior.
Punctuation and other letters in bold text represent other characters that are typed as
they appear. In this example, a comma must appear between the number argument
and the string argument.
Here is an example of using the KEY command based on this pattern:

KEY 8 ," LIST "+ CHR$ (13)

When you see square brackets around arguments, this indicates that the arguments are
optional. You are not meant to type the square brackets. Consider this description of
the CIRCLE command, which accepts optional arguments:
CIRCLE xc, yc, radius [, flags , start, stop]
The following examples of the CIRCLE command are both valid. They have different
behavior based on their different arguments.

CIRCLE 100 ,150 ,30

CIRCLE 100 ,150 ,30 ,0 ,45 ,135

This arrangement of keywords, symbols, and arguments is called syntax. If you leave
something out, or put the wrong thing in the wrong place, the computer will fail to
understand the command and report a syntax error.

B-3
There is nothing to worry about if you get an error from the MEGA65. It is just the
MEGA65’s way of telling you that something isn’t quite right, so that you can more
easily find and fix the problem. For example, if you omit the comma in the KEY com-
mand, or replace it with a period, the MEGA65 will respond with a ?SYNTAX ERROR:

B-4
READY .
KEY 8" FISH "

? SYNTAX ERROR
READY .
KEY 8." FISH "

? SYNTAX ERROR
READY .

Expressions can be a number value such as 23.7, a string value such as "HELLO", or a
more complex calculation that combines values, functions, and operators to describe
a number or string value: "LIST"+CHR$(13)
It is important to use the correct type of expression when writing your programs. If you
accidentally use the wrong type, the MEGA65 will display a ?TYPE MISMATCH ERROR, to say that
the type of expression you gave doesn’t match what it expected. For example, the
following command results in a ?TYPE MISMATCH ERROR, because "POTATO" is a string expression,
and a numeric expression is expected:

KEY " POTATO " ," SOUP "

Commands are statements that you can use directly from the READY. prompt, or from
within a program, for example:

READY .
PRINT " HELLO "
HELLO

READY .
10 PRINT " HELLO "
RUN
HELLO

You can place a sequence of statements within a single line by separating them with
colons, for example:

PRINT " HELLO " : PRINT " HOW ARE YOU ?" : PRINT " HOW IS THE W E A T H E R ?"
HELLO
HOW ARE YOU ?
HOW IS THE WE ATHE R ?

B-5
Direct Mode Commands
Some commands only work in direct mode (sometimes called “immediate mode”).
This means that the command can’t be part of a BASIC program, but can be entered
directly to the screen. For example, the RENUMBER command only works in direct
mode, because its function is to renumber the lines of a BASIC program.
In the two PRINT examples above, the first was entered in direct mode, whereas the
second one was part of a program. The PRINT command works in both direct mode
and in a program.

Command Syntax Descriptions


The following table describes the other symbols found in command syntax descriptions.

Symbol Meaning
[] Optional

… The bracketed syntax can be repeated zero or more


times
<|> Include one of the choices
[|] Optionally include one of the choices
One or more of the arguments is required. The
{,} commas to the left of the last argument included are
required. Trailing commas must be omitted. See
CURSOR for an example.
[{ , }] Similar to { , } but all arguments can be omitted

Fonts
Examples of text that appears on the screen, either typed by you or printed by the
MEGA65, appear in the screen font: "LIST"+CHR$(13)

B-6
BASIC 65 Constants
Values that are typed directly into an expression or program are called constants.
The values are “constant” because they do not change based on other aspects of the
program state.
The following are types of constants that can appear in a BASIC 65 expression.
Type Example Example
Decimal Integer 32000 -55
Decimal Fixed Point 3.14 -7654.321
Decimal Floating Point 1.5E03 7.7E-02
Hex $D020 $FF
Binary %11010010 %101
String "X" "TEXT"

BASIC 65 Variables
A program manipulates data by storing values in the computer’s memory, referring to
stored values, and updating them based on logic. In BASIC, elements of memory that
store values are called variables. Each variable has a name, there are separate sets
of variable names for each type of value.
For example, the variable AA can store a number value. The variable AA$ can store a string
value. Commodore BASIC considers these to be separate variables, even though the
names both begin with AA.
One way to store a value in a variable is with the assignment = operator. For example:

AA = 1.95

AA$ = " HELLO , "

Variable names must start with a letter, and contain only letters and numbers. They
can be of any length, but Commodore BASIC only recognizes the first two letters of
the name. SPEED and SP would be considered the same variable.
Variable names cannot contain any of the BASIC keywords. This makes using long
names difficult: it is easy to use a keyword accidentally. For example, ENFORCEMENT is not
a valid variable name, because FOR is a keyword. It is common to use short variable
names to avoid these hazards.
A variable can be used within an expression with other constants, variables, functions,
and operators. It is substituted with the value that it contains at that point in the
program’s execution.

B-7
10 INPUT " WHAT IS YOUR NAME "; NA$
20 MSG$ = " HELLO , "+ NA$ +"!"
20 PRINT MSG$

Unlike some programming languages, BASIC variables do not need to be declared


before use. A variable has a default value of zero for number type variables, or the
empty string ("") for string type variables.
A variable that stores a single value is also known as a scalar variable. The scalar
variable types and their value ranges are as follows.
Type Name Symbol Range Example
Byte & 0 .. 255 BY& = 23
Integer % -32768 .. 32767 I% = 5
Real none -1E37 .. 1E37 XY = 1/3
String $ length = 0 .. 255 AB$ = "TEXT"
A variable whose name is a single letter followed by the type symbol (or no symbol
for real number variables) is a fast variable. BASIC 65 stores the variable in a way
that makes it faster to access or update the value than variables with longer names.
It otherwise behaves like any other variable. This is also true for functions defined by
DEF FN.

BASIC 65 Arrays
In addition to scalar variables, Commodore BASIC also supports a type of variable that
can store multiple values, called an array.
The following example stores three string values in an array, then uses a FOR loop to
PRINT a message for each element:

10 DIM NA$ (3)


20 NA$ (0) = " DEFT "
30 NA$ (1) = " G A R D N E R S "
40 NA$ (2) = " LYDON "
50 FOR I =0 TO 3
60 PRINT " HELLO , "; NA$ ( I );"!"
70 NEXT I

Each value in an array is referenced by the name of the array variable and an integer
index. For example, AA(7) refers to the element of the array named AA() with index 7.
Indexes are “zero-based:” the first element in the array has an index of 0. The index
can be a numeric expression, which can be a powerful way to operate on multiple
elements of data.

B-8
All values in an array must be of the same type. The type is indicated in the name of
the variable, similar to scalar variables. AA() is an array of real numbers, AA$() is an array
of strings.
Array variable names are considered separate from scalar variable names. The scalar
variable AA has no relationship to the array variable AA().
BASIC needs to know the maximum size of the array before its first use, so that it
can allocate the memory for the complete array. A program can declare an array’s
size using the DIM keyword, with the “dimensions” of the array. If an array variable is
used without an explicit declaration, BASIC allocates a one-dimensional array of 10
elements, and the array cannot be re-dimensioned later (unless you CLR all variables).
An array can have multiple dimensions, each with its own index separated by a comma.
The array must be declared with the maximum value for each dimension. Keep in
mind that BASIC 65 allocates memory for the entire array, so large arrays may be
constrained by available memory.

DIM BO$ (3 ,3)


BO$ (1 ,1) = " X "
BO$ (0 ,0) = " O "
BO$ (0 ,2) = " X "
BO$ (1 ,0) = " O "

Screen Text and Colour Arrays


A BASIC 65 program can place text on the screen in several ways. The PRINT command
displays a string at the current cursor location, which is especially useful for terminal-
like output. The CURSOR command moves the cursor to a given position. A program
can use these commands together to draw pictures or user interfaces.
A program can access individual characters on the screen using the special built-in
arrays T@&() and C@&(). These arrays are two-dimensional with indexes corresponding
to the column and row of each character on the screen, starting from (0,0) at the top
left corner.
T@&(column, row) is the screen code of the character. Screen codes are not the same
as PETSCII codes. See appendix C on page C-3 for a list of screen codes.
C@&(column, row) is the colour code of the character. This is an entry number of the
system palette. See appendix G on page G-3 for the list of colours in the default
system palette. Upper bits also set text attributes, such as blinking.
Like regular arrays, the screen and colour array entries can be assigned new values,
or used in expressions to refer to their current values.

B-9
10 FOR X =10 TO 30
20 T@ &( X ,2)=1
30 C@ &( X ,2)= INT ( RND (1 ) * 16 )
40 NEXT X
50 PRINT " COLOUR AT P O S I T I O N 15: "; C@ &(15 ,2)

The dimensions of these arrays depend on the current text screen mode. In 80 × 25
text mode, the column is in the range 0 – 79, and the row is in the range 0 – 24. The
MEGA65 also supports 80 × 50 and 40 × 25 text modes.

BASIC 65 Operators
An operator is a symbol or keyword that performs a function in an expression. It oper-
ates on one or two sub-expressions, called operands. The operator and its operands
evaluate to the result of the operation.
For example, the * (asterisk) operator performs a multiplication of two number
operands. The operator and its operands evaluate to the result of the multiplication.

A =6
PRINT A *7

The + (plus) operator has a different meaning depending on the type of the operands.
If both operands are numbers, then the operator performs an addition of the numbers.
If both operands are strings, then the operator evaluates to a new string that is the
concatenation of the operands.

A =64
PRINT A +1

A$ =" MEGA "


PRINT A$ +"65"

The - (minus) operator accepts either one operand or two operands. Given one number
operand on the right-hand side, it evaluates to the negation of that number. Given
two number operands, one on either side, it evaluates to the subtraction of the second
operand from the first operand.

A =64
PRINT -A

PRINT A -16

The = symbol is used both as an assignment statement and as a relational operator. As


an assignment, the = symbol is a statement that updates the value of a variable. The

B-10
left-hand side must be a variable or array element reference, and its type must match
the type of the expression on the right-hand side. The assignment is not an operator:
it is not part of an expression.

AA =7
NA$ =" DEFT "

As a relational operator, the = symbol behaves as an expression. It evaluates the ex-


pressions on both sides of the operator, then tests whether the values are equal. If they
are equal, the equality operator evaluates to −1, BASIC’s representation of “true.” If
they are not equal, the operator evaluates to 0, or “false.” The equality expression can
be used with an IF statement to control program flow, or it can be used as part of a
numeric expression. Both expressions must be of the same type.

100 IF X =99 THEN 130


110 X = X +1
120 GOTO 100
130 PRINT " DONE ."

BASIC 65 knows the difference between assignment and equality based on context.
Consider this line of code:
A = B = 10

BASIC 65 expects a statement, and notices a variable name followed by the = symbol.
It concludes that this is a statement assigning a value to the number variable A. It then
expects a number expression on the right-hand side of the assignment, and notices
the = symbol is an operator in that expression. It concludes that the operation is an
equality test, and proceeds to evaluate the expression and assign the result.
The operators NOT, AND, OR and XOR can be used either as logical operators or as
boolean operators. A logical operator joins two conditional expressions as operands
and evaluates to the logical comparison of their truth values.

IF X =99 OR Y <5 THEN 130

IF Y >10 AND Y <20 THEN 150

A boolean operator accepts two number operands and performs a calculation on the
bits of the binary values.

A =17
PRINT A AND 20

Unlike other cases where operators have different behaviors based on how they are
used, BASIC 65 does not need to determine whether these operators are behaving as

B-11
logical operators or boolean operators. Because “true” and “false” are represented
by carefully chosen numbers, the logical operators have the same behavior whether
their operands are conditional expressions or numbers. A “true” conditional expression
is the number −1, which internally is a binary number with all bits set. The logical
expression “true and false” is equivalent to the binary boolean expression %....0000
& %....1111. In this case, the AND operator evaluates to 0, which is “false.”
Conditional expressions evaluating to numbers can be used in some clever program-
ming tricks. Consider this example:

A = A - ( B > 7)

This statement will increment the value in the A by 1 if the value in B is greater than 7.
Otherwise it leaves it unchanged. If the sub-expression B > 7 is true, then it evaluates
to -1. A - (-1) is equivalent to A + 1. If the sub-expression is false, then it evaluates to 0,
and A - 0 is equivalent to A.
When multiple operators are used in a single expression, the order in which they are
evaluated is specified by precedence. For example, in the statement A * A - B * B, both
multiplications will be performed first, then the subtraction. As in algebra, you can
use parentheses to change the order of execution. In the expression A * (A - B) * B, the
subtraction is performed first.
The complete set of operators and their order of precedence are summarised in the
sections that follow.

Assignment Statement
Symbol Description Examples
= Assignment A = 42, A$ = "HELLO", A = B < 42

Unary Mathematical Operators


Name Symbol Description Example
Plus + Positive sign A = +42
Minus - Negative sign B = -42

Binary Mathematical Operators


Name Symbol Description Example
Plus + Addition A = B + 42
Minus - Subtraction B = A - 42
Asterisk * Multiplication C=A*B
Slash / Division D = B / 13
Up Arrow ↑ Exponentiation E = 2 ↑ 10
Left Shift << Left Shift A = B << 2
Right Shift >> Right Shift A = B >> 1

B-12
NOTE: The ↑ character used for exponentiation is entered with ↑ , which is next to
RESTORE
.

Relational Operators
Symbol Description Example
> Greater Than A > 42
>= Greater Than or Equal To B >= 42
< Less Than A < 42
<= Less Than or Equal To B <= 42
= Equal A = 42
<> Not Equal B <> 42

Logical Operators
Keyword Description Example
AND And A > 42 AND A < 84
OR Or A > 42 OR A = 0
XOR Exclusive Or A > 42 XOR B > 42
NOT Negation C = NOT A > B

Boolean Operators
Keyword Description Example
AND And A = B AND $FF
OR Or A = B OR $80
XOR Exclusive Or A = B XOR 1
NOT Negation A = NOT 22

String Operator
Name Symbol Description Operand type Example
Plus + Concatenates Strings String A$ = B$ + ".PRG"

B-13
Operator Precedence
Precedence Operators
High ↑
+ - (Unary Mathematical)
*/
+ - (Binary Mathematical)
<< >> (Arithmetic Shifts)
< <= > >= = <>
NOT
AND
Low OR XOR

B-14
Keywords And Tokens Part 1
* AC COLLECT F3 EXP BD
+ AA COLLISION FE17 FAST FE25
- AB COLOR E7 FGOSUB FE48
/ AD CONCAT FE13 FGOTO FE47
< B3 CONT 9A FILTER FE03
<< FE52 COPY F4 FIND FE2B
= B2 COS BE FN A5
> B1 CURSOR FE41 FONT FE46
>> FE53 CUT E4 FOR 81
ABS B6 DATA 83 FOREGROUND FE39
AND AF DCLEAR FE15 FORMAT FE37
APPEND FE0E DCLOSE FE0F FRE B8
ASC C6 DEC D1 FREAD# FE1C
ATN C1 DEF 96 FREEZER FE4A
AUTO DC DELETE F7 FWRITE# FE1E
BACKGROUND FE3B DIM 86 GCOPY FE32
BACKUP F6 DIR EE GET A1
BANK FE02 DISK FE40 GO CB
BEGIN FE18 DLOAD F0 GOSUB 8D
BEND FE19 DMA FE1F GOTO 89
BIT FE4E DMODE FE35 GRAPHIC DE
BLOAD FE11 DO EB HEADER F1
BOOT FE1B DOPEN FE0D HELP EA
BORDER FE3C DOT FE4C HEX$ D2
BOX E1 DPAT FE36 HIGHLIGHT FE3D
BSAVE FE10 DSAVE EF IF 8B
BUMP CE03 DVERIFY FE14 INFO FE4D
BVERIFY FE28 ECTORY FE29 INPUT 85
CATALOG FE0C EDIT FE45 INPUT# 84
CHANGE FE2C EDMA FE21 INSTR D4
CHAR E0 ELLIPSE FE30 INT B5
CHDIR FE4B ELSE D5 JOY CF
CHR$ C7 END 80 KEY F9
CIRCLE E2 ENVELOPE FE0A LEFT$ C8
CLOSE A0 ERASE FE2A LEN C3
CLR 9C ERR$ D3 LET 88
CMD 9D EXIT ED LINE E5

B-15
Keywords And Tokens Part 2
LIST 9B PRINT 99 SOUND DA
LOAD 93 PRINT# 98 SPC( A6
LOADIFF FE43 PUDEF DD SPEED FE26
LOCK FE50 RCOLOR CD SPRCOLOR FE08
LOG BC RCURSOR FE42 SPRITE FE07
LOG10 CE08 READ 87 SPRSAV FE16
LOOP EC RECORD FE12 SQR BA
LPEN CE04 REM 8F STEP A9
MEM FE23 RENAME F5 STOP 90
MERGE E6 RENUMBER F8 STR$ C4
MID$ CA RESTORE 8C SYS 9E
MKDIR FE51 RESUME D6 TAB( A3
MOD CE0B RETURN 8E TAN C0
MONITOR FA RGRAPHIC CC TEMPO FE05
MOUNT FE49 RIGHT$ C9 THEN A7
MOUSE FE3E RMOUSE FE3F TO A4
MOVSPR FE06 RND BB TRAP D7
NEW A2 RPALETTE CE0D TROFF D9
NEXT 82 RPEN D0 TRON D8
NOT A8 RPLAY CE0F TYPE FE27
OFF FE24 RREG FE09 UNLOCK FE4F
ON 91 RSPCOLOR CE07 UNTIL FC
OPEN 9F RSPEED CE0E USING FB
OR B0 RSPPOS CE05 USR B7
PAINT DF RSPRITE CE06 VAL C5
PALETTE FE34 RUN 8A VERIFY 95
PASTE E3 RWINDOW CE09 VIEWPORT FE31
PEEK C2 SAVE 94 VOL DB
PEN FE33 SAVEIFF FE44 VSYNC FE54
PIXEL CE0C SCNCLR E8 WAIT 92
PLAY FE04 SCRATCH F2 WHILE FD
POINTER CE0A SCREEN FE2E WINDOW FE1A
POKE 97 SET FE2D WPEEK CE10
POLYGON FE2F SGN B4 WPOKE FE1D
POS B9 SIN BF XOR E9
POT CE02 SLEEP FE0B ^ AE

B-16
Tokens And Keywords Part 1
80 END A5 FN CA MID$
81 FOR A6 SPC( CB GO
82 NEXT A7 THEN CC RGRAPHIC
83 DATA A8 NOT CD RCOLOR
84 INPUT# A9 STEP CF JOY
85 INPUT AA + D0 RPEN
86 DIM AB - D1 DEC
87 READ AC * D2 HEX$
88 LET AD / D3 ERR$
89 GOTO AE ^ D4 INSTR
8A RUN AF AND D5 ELSE
8B IF B0 OR D6 RESUME
8C RESTORE B1 > D7 TRAP
8D GOSUB B2 = D8 TRON
8E RETURN B3 < D9 TROFF
8F REM B4 SGN DA SOUND
90 STOP B5 INT DB VOL
91 ON B6 ABS DC AUTO
92 WAIT B7 USR DD PUDEF
93 LOAD B8 FRE DE GRAPHIC
94 SAVE B9 POS DF PAINT
95 VERIFY BA SQR E0 CHAR
96 DEF BB RND E1 BOX
97 POKE BC LOG E2 CIRCLE
98 PRINT# BD EXP E3 PASTE
99 PRINT BE COS E4 CUT
9A CONT BF SIN E5 LINE
9B LIST C0 TAN E6 MERGE
9C CLR C1 ATN E7 COLOR
9D CMD C2 PEEK E8 SCNCLR
9E SYS C3 LEN E9 XOR
9F OPEN C4 STR$ EA HELP
A0 CLOSE C5 VAL EB DO
A1 GET C6 ASC EC LOOP
A2 NEW C7 CHR$ ED EXIT
A3 TAB( C8 LEFT$ EE DIR
A4 TO C9 RIGHT$ EF DSAVE

B-17
Tokens And Keywords Part 2
F0 DLOAD FE09 RREG FE2F POLYGON
F1 HEADER FE0A ENVELOPE FE30 ELLIPSE
F2 SCRATCH FE0B SLEEP FE31 VIEWPORT
F3 COLLECT FE0C CATALOG FE32 GCOPY
F4 COPY FE0D DOPEN FE33 PEN
F5 RENAME FE0E APPEND FE34 PALETTE
F6 BACKUP FE0F DCLOSE FE35 DMODE
F7 DELETE FE10 BSAVE FE36 DPAT
F8 RENUMBER FE11 BLOAD FE37 FORMAT
F9 KEY FE12 RECORD FE39 FOREGROUND
FA MONITOR FE13 CONCAT FE3B BACKGROUND
FB USING FE14 DVERIFY FE3C BORDER
FC UNTIL FE15 DCLEAR FE3D HIGHLIGHT
FD WHILE FE16 SPRSAV FE3E MOUSE
CE02 POT FE17 COLLISION FE3F RMOUSE
CE03 BUMP FE18 BEGIN FE40 DISK
CE04 LPEN FE19 BEND FE41 CURSOR
CE05 RSPPOS FE1A WINDOW FE42 RCURSOR
CE06 RSPRITE FE1B BOOT FE43 LOADIFF
CE07 RSPCOLOR FE1C FREAD# FE44 SAVEIFF
CE08 LOG10 FE1D WPOKE FE45 EDIT
CE09 RWINDOW FE1E FWRITE# FE46 FONT
CE0A POINTER FE1F DMA FE47 FGOTO
CE0B MOD FE21 EDMA FE48 FGOSUB
CE0C PIXEL FE23 MEM FE49 MOUNT
CE0D RPALETTE FE24 OFF FE4A FREEZER
CE0E RSPEED FE25 FAST FE4B CHDIR
CE0F RPLAY FE26 SPEED FE4C DOT
CE10 WPEEK FE27 TYPE FE4D INFO
FE02 BANK FE28 BVERIFY FE4E BIT
FE03 FILTER FE29 ECTORY FE4F UNLOCK
FE04 PLAY FE2A ERASE FE50 LOCK
FE05 TEMPO FE2B FIND FE51 MKDIR
FE06 MOVSPR FE2C CHANGE FE52 <<
FE07 SPRITE FE2D SET FE53 >>
FE08 SPRCOLOR FE2E SCREEN FE54 VSYNC

B-18
BASIC COMMAND REFERENCE

B-19
ABS
Token: $B6
Format: ABS(x)
Returns: The absolute value of the numeric argument x.
x numeric argument (integer or real expression)
Remarks: The result is of type real.
Example: Using ABS

PRINT ABS(-123)
123
PRINT ABS(4.5)
4.5
PRINT ABS(-4.5)
4.5

B-20
AND
Token: $AF
Format: operand AND operand
Usage: Performs a bit-wise logical AND operation on two 16-bit values.
Integer operands are used as they are. Real operands are converted to a
signed 16-bit integer (losing precision). Logical operands are converted
to 16-bit integer using $FFFF (decimal -1) for TRUE, and $0000 (decimal
0) for FALSE.
Expression Result
0 AND 0 0
0 AND 1 0
1 AND 0 0
1 AND 1 1
Remarks: The result is of type integer. If the result is used in a logical context,
the value of 0 is regarded as FALSE, and all other non-zero values are
regarded as TRUE.
Examples: Using AND

PRINT 1 AND 3
1
PRINT 128 AND 64
0

AND can be used in IF statements to require multiple conditions.

IF (C >= 0 AND C < 256) THEN PRINT "BYTE VALUE"

B-21
APPEND
Token: $FE $0E
Format: APPEND# channel, filename [,D drive] [,U unit]
Usage: Opens an existing sequential file of type SEQ or USR for writing, and
positions the write pointer at the end of the file.
channel number, where:
• 1 <= channel <= 127 line terminator is CR.
• 128 <= channel <= 255 line terminator is CR LF.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: APPEND# works similarly to DOPEN#... ,W, except that the file must al-
ready exist. The content of the file is retained, and all printed text is
appended to the end. Trying to APPEND to a non-existing file reports a
DOS error.
Examples: Open existing file in append mode:

APPEND#5,"DATA",U9
APPEND#130,(DD$),U(UN%)
APPEND#3,"USER FILE,U"
APPEND#2,"DATA BASE"

B-22
ASC
Token: $C6
Format: ASC(string)
Returns: The PETSCII code of the first character of the string argument, as a num-
ber.
Remarks: ASC returns zero for an empty string. This is different to BASIC 2, which
raised an error for ASC("").
The inverse function to ASC is CHR$. Refer to the CHR$ function on
page B-48 for more information.
The name was apparently chosen to be a mnemonic to “ASCII,” but the
returned value is a PETSCII code.
Examples: Using ASC

PRINT ASC("MEGA")
77
PRINT ASC("")
0

B-23
ATN
Token: $C1
Format: ATN(numeric expression)
Returns: The arc tangent of the argument.
The result is in the range (−π/2 to π/2)
Remarks: A multiplication of the result with 180/π converts the value to the unit
”degrees”. ATN is the inverse function to TAN.
Examples: Using ATN

PRINT ATN(0.5)
.463647609
PRINT ATN(0.5) * 180 / ~
26.5650512

B-24
AUTO
Token: $DC
Format: AUTO [step]
Usage: Enables or disables automatic line numbering during BASIC program en-
RETURN
try. After submitting a new program line to the BASIC editor with ,
the AUTO function generates a new BASIC line number for the entry of
the next line. The new number is computed by adding step to the current
line number.
step line number increment
Typing AUTO with no argument disables it.
Examples: Using AUTO

AUTO 10 : USE AUTO WITH INCREMENT 10


AUTO : SWITCH AUTO OFF

B-25
BACKGROUND
Token: $FE $3B
Format: BACKGROUND colour
Usage: Sets the background colour of the screen.
colour the palette entry number, in the range 0 – 255
All colours within this range are customisable via the PALETTE command.
On startup, the MEGA65 only has the first 32 colours configured. See
appendix G on page G-3 for the list of colours in the default system
palette.
Example: Using BACKGROUND

BACKGROUND 3 : REM SELECT BACKGROUND COLOUR CYAN

B-26
BACKUP
Token: $F6
Format: BACKUP U source TO U target
BACKUP D source TO D target [,U unit]
Usage: Copies one disk to another.
The first form of BACKUP, specifying units for source and target, can
only be used for the drives connected to the internal FDC (Floppy Disk
Controller). Units 8 and 9 are reserved for this controller. These can
be either the internal floppy drive (unit 8) and another floppy drive (unit
9) attached to the same ribbon cable, or mounted D81 disk images.
BACKUP can be used to copy from floppy to floppy, floppy to image,
image to floppy and image to image, depending on image mounts and
the existence of a second physical floppy drive.
The second form of BACKUP, specifying drives for source and target, is
meant to be used for dual drive units connected to the IEC bus. For
example: CBM 4040, 8050, 8250 via an IEEE-488 to IEC adapter. In
this case, the backup is then done by the disk unit internally.
source unit or drive # of source disk.
target unit or drive # of target disk.
Remarks: The target disk will be formatted and an identical copy of the source disk
will be written.
BACKUP cannot be used to backup from internal devices to IEC devices
or vice versa.
Examples: Using BACKUP

BACKUP U8 TO U9 : REM BACKUP INTERNAL DRIVE 8 TO DRIVE 9


BACKUP U9 TO U8 : REM BACKUP DRIVE 9 TO INTERNAL DRIVE 8
BACKUP D0 TO D1, U10 : REM BACKUP ON DUAL DRIVE CONNECTED VIA IEC

B-27
BANK
Token: $FE $02
Format: BANK bank number
Usage: Selects the memory configuration for BASIC commands that use 16-bit
addresses. These are LOAD, LOADIFF, PEEK, POKE, SAVE, SYS, and
WAIT. Refer to the system memory map in Chapter/Appendix I on page I-
3 for more information.
Remarks: A value > 127 selects memory mapped I/O. The default value at system
startup for the bank number is 128. This configuration has RAM from
$0000 to $1FFF, the BASIC and KERNAL ROM, and I/O from $2000 to
$FFFF.
Example: Using BANK

BANK 1 :REM SELECT MEMORY CONFIGURATION 1

B-28
BEGIN
Token: $FE $18
Format: BEGIN ... BEND
Usage: The beginning of a compound statement to be executed after THEN or
ELSE. This overcomes the single line limitation of the standard IF ... THEN
... ELSE clause.
Remarks: Do not jump with GOTO or GOSUB into a compound statement, as it
may lead to unexpected results.
Example: Using BEGIN and BEND

10 GET A$
20 IF A$>="A" AND A$<="Z" THEN BEGIN
30 PW$=PW$+A$
40 IF LEN(PW$)>7 THEN 90
50 BEND :REM IGNORE ALL EXCEPT (A-Z)
60 IF A$<>CHR$(13) GOTO 10
90 PRINT "PW=";PW$

B-29
BEND
Token: $FE $19
Format: BEGIN ... BEND
Usage: The end of a compound statement to be executed after THEN or ELSE.
This overcomes the single line limitation of the standard IF ... THEN ...
ELSE clause.
Remarks: The example below shows a quirk in the implementation of the compound
statement. If the condition evaluates to FALSE, execution does not re-
sume right after BEND as it should, but at the beginning of the next line.
Test this behaviour with the following program:
Example: Using BEGIN and BEND

10 IF Z > 1 THEN BEGIN:A$="ONE"


20 B$="TWO"
30 PRINT A$;" ";B$;:BEND:PRINT " QUIRK"
40 REM EXECUTION RESUMES HERE FOR Z <= 1

B-30
BLOAD
Token: $FE $11
Format: BLOAD filename [,B bank] [,P address] [,R] [,D drive] [,U unit]
Usage: Loads a file of type PRG into RAM at address P. (“Binary load.”)
BLOAD has two modes: The flat memory address mode can be used to
load a program to any address in the 28-bit (256MB) address range
where RAM is installed. This includes the standard RAM banks 0 to 5, as
well as the 8MB of ”attic RAM” at address $8000000.
This mode is triggered by specifying an address at parameter P that is
larger than $FFFF. The bank parameter is ignored in this mode.
For compatibility reasons with older BASIC versions, BLOAD accepts the
syntax with a 16-bit address at P and a bank number at B as well. The
attic RAM is out of range for this compatibility mode.
The optional parameter R (RAW MODE) does not interpret or use the first
two bytes of the program file as the load address, which is otherwise the
default behaviour. In RAW MODE every byte is read as data.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
bank specifies the RAM bank to be used. If not specified, the current
bank, as set with the last BANK statement will be used.
address overrides the load address that is stored in the first two bytes
of the PRG file.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: BLOAD cannot cross bank boundaries.
BLOAD uses the load address from the file if no P parameter is given.
Examples: Using BLOAD

B-31
BLOAD "ML DATA", B0, U9
BLOAD "SPRITES"
BLOAD "ML ROUTINES", B1, P32768
BLOAD (FI$), B(BA%), P(PA), U(UN%)
BLOAD "CHUNK",P($8000000) :REM LOAD TO ATTIC RAM

B-32
BOOT
Token: $FE $1B
Format: BOOT filename [,B bank] [,P address] [,D drive] [,U unit]
BOOT SYS
BOOT
Usage: Loads and runs a program or boot sector from a disk.
BOOT filename loads a file of type PRG into RAM at address P and bank
B, and starts executing the code at the load address.
BOOT SYS loads the boot sector (512 bytes in total) from sector 0, track
1 and unit 8 to address $0400 in bank 0, and performs a JSR $0400 after-
wards (Jump To Subroutine).
BOOT with no parameters attempts to load and execute a file named
AUTOBOOT.C65 from the default unit 8. It’s short for RUN ”AUTO-
BOOT.C65”.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
bank specifies the RAM bank to be used. If not specified, the current
bank, as set with the last BANK statement, will be used.
address overrides the load address, that is stored in the first two bytes
of the PRG file.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Examples: Using BOOT

BOOT SYS
BOOT (FI$), B(BA%), P(PA), U(UN%)
BOOT

B-33
BORDER
Token: $FE $3C
Format: BORDER colour
Usage: Sets the border colour of the screen.
colour the palette entry number, in the range 0 – 255
All colours within this range are customisable via the PALETTE command.
See appendix G on page G-3 for the list of colours in the default system
palette.
Example: Using BORDER

10 BORDER 4 : REM SELECT BORDER COLOUR PURPLE

B-34
BOX
Token: $E1
Format: BOX x0,y0, x2,y2 [, solid]
BOX x0,y0, x1,y1, x2,y2, x3,y3 [, solid]
Usage: Bitmap graphics: draws a box.
The first form of BOX with two coordinate pairs and an optional solid
parameter draws a simple rectangle, assuming that the coordinate pairs
declare two diagonally opposite corners.
The second form with four coordinate pairs declares a path of four points,
which will be connected with lines. The path is closed by connecting the
last coordinate with the first.
The quadrangle is drawn using the current drawing context set with
SCREEN, PALETTE and PEN. The quadrangle is filled if the parameter
solid is not 0.
Remarks: BOX can be used with four coordinate pairs to draw any shape that can
be defined with four points, not only rectangles. For example rhomboids,
kites, trapezoids and parallelograms. It is also possible to draw bow tie
shapes.
Examples: Using BOX

BOX 0,0, 160,0, 160,80, 0,80

BOX 0,0, 160,80, 160,0, 0,80

BOX 20,0, 140,0, 160,80, 0,80

B-35
B-36
BSAVE
Token: $FE $10
Format: BSAVE filename, P start TO P end [,B bank] [,D drive] [,U unit]
Usage: Saves a memory range to a file of type PRG. (“Binary save.”)
BSAVE has two modes: The flat memory address mode can be used to
save a memory block in the 28-bit (256MB) address range where RAM
is installed. This includes the standard RAM banks 0 to 5, as well as the
8MB of ”attic RAM” at address $8000000.
This mode is triggered by specifying addresses for the start and end pa-
rameter P, that are larger than $FFFF. The bank parameter is ignored in
this mode. This flat memory mode allows saving ranges greater than 64K.
For compatibility reasons with older BASIC versions, BSAVE accepts the
syntax with 16-bit addresses at P and a bank number at B as well. The
attic RAM is out of range for this compatibility mode. This mode cannot
cross bank boundaries, so start and end address must be in the same
bank.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$). If the first character of the file-
name is an at sign ’@’, it is interpreted as a ”save and replace” operation.
It is not recommended to use this option on 1541 and 1571 drives, as
they contain a ”save and replace bug” in their DOS.
start the first address, where the saving begins. It also becomes the load
address, which is stored in the first two bytes of the PRG file.
end address where the saving ends. end-1 is the last address to be used
for saving.
bank the RAM bank to be used. If not specified, the current bank, as set
with the last BANK statement, will be used.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: The length of the file is end - start + 2.
If the number after an argument letter is not a decimal number, it must be
set in parenthesis, as shown in the third and fourth line of the examples.
The PRG file format that is used by BSAVE requires the load address to
be written to the first two bytes. If the saving is done with a bank number

B-37
that is not zero, or a start address greater than $FFFF, this information
will not fit. For compatibility reasons, only the two low order bytes are
written. Loading the file with the BLOAD command will then require the
full 16-bit range of the load address as a parameter.
Examples: Using BSAVE

BSAVE "ML DATA", P 32768 TO P 33792, B0, U9


BSAVE "SPRITES", P 1536 TO P 2058
BSAVE "ML ROUTINES", B1, P($9000) TO P($A000)
BSAVE (FI$), B(BA%), P(PA) TO P(PE), U(UN%)

B-38
BUMP
Token: $CE $03
Format: BUMP(type)
Returns: A bitfield of sprites currently colliding with other sprites (type=1) or screen
data (type=2).
Each bit set in the returned value indicates that the sprite corresponding
to that bit position was involved in a collision since the last call of BUMP.
Calling BUMP resets the collision mask, so you will always get a summary
of collisions encountered since the last call of BUMP.
Remarks: It’s possible to detect multiple collisions, but you will need to evaluate
the sprite coordinates to detect which sprites have collided.
Example: Using BUMP

10 S% = BUMP(1) : REM SPRITE-SPRITE COLLISION


20 IF (S% AND 6) = 6 THEN PRINT "SPRITE 1 & 2 COLLISION"
30 REM ---
40 S% = BUMP(2) : REM SPRITE-DATA COLLISION
50 IF (S% <> 0) THEN PRINT "SOME SPRITE HIT DATA REGION"

Sprite Return Mask


0 1 0000 0001
1 2 0000 0010
2 4 0000 0100
3 8 0000 1000
4 16 0001 0000
5 32 0010 0000
6 64 0100 0000
7 128 1000 0000

B-39
BVERIFY
Token: $FE $28
Format: BVERIFY filename [,P address] [,B bank] [,D drive] [,U unit]
Usage: Compares a memory range to a file of type PRG. (“Binary verify.”)
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
bank specifies the RAM bank to be used. If not specified, the current
bank, as set with the last BANK statement, will be used.
address is the address where the comparison begins. If the parameter
P is omitted, it is the load address that is stored in the first two bytes of
the PRG file that will be used.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: BVERIFY can only test for equality. It gives no information about the
number, or position of different valued bytes. In direct mode BVERIFY
exits either with the message OK or with VERIFY ERROR. In program mode, a
VERIFY ERROR either stops execution or enters the TRAP error handler,
if active.
Examples: Using BVERIFY

BVERIFY "ML DATA", P 32768, B0, U9


BVERIFY "SPRITES", P 1536
BVERIFY "ML ROUTINES", B1, P(DEC("9000"))
BVERIFY (FI$), B(BA%), P(PA), U(UN%)

B-40
CATALOG
Token: $FE $0C
Format: CATALOG [filepattern] [,W] [,R] [,D drive] [,U unit]
$ [filepattern] [,W] [,R] [,D drive] [,U unit]
Usage: Prints a file catalog/directory of the specified disk.
The W (Wide) parameter lists the directory three columns wide on the
screen and pauses after the screen has been filled with a page (63 di-
rectory entries). Pressing any key displays the next page.
The R (Recoverable) parameter includes files in the directory which are
flagged as deleted but still recoverable.
filepattern is either a quoted string, for example: "DA*" or a string expres-
sion in brackets, e.g. (DI$)
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: CATALOG is a synonym of DIRECTORY and DIR, and produces the same
listing. The filepattern can be used to filter the listing. The wildcard
characters * and ? may be used. Adding ,T= to the pattern string, with T
specifying a filetype of P, S, U or R (for PRG, SEQ, USR, REL) filters the
output to that filetype.
The shortcut symbol $ can only be used in direct mode.
Examples: Using CATALOG

CATALOG
0 "BLACK SMURF " BS 2A
508 "STORY PHOBOS" SEQ
27 "C8096" PRG
25 "C128" PRG
104 BLOCKS FREE.

CATALOG "*,T=S"
0 "BLACK SMURF " BS 2A
508 "STORY PHOBOS" SEQ
104 BLOCKS FREE.

B-41
Below is an example showing how a directory looks with the wide pa-
rameter:

DIR W
0 "BASIC EXAMPLES "
1 "BEGIN" P 1 "FREAD" P 2 "PAINT.COR" P
1 "BEND" P 1 "FRE" P 3 "PALETTE.COR" P
1 "BUMP" P 2 "GET#" P 1 "PEEK" P
1 "CHAR" P 1 "GETKEY" P 3 "PEN" P
1 "CHR$" P 1 "GET" P 1 "PLAY" P
4 "CIRCLE" P 2 "GOSUB" P 2 "POINTER" P
1 "CLOSE" P 2 "GOTO.COR" P 1 "POKE" P
1 "CLR" P 2 "GRAPHIC" P 1 "POS" P
2 "COLLISION" P 1 "HELP" P 1 "POT" P
1 "CURSOR" P 1 "IF" P 1 "PRINT#" P
0 "DATA BASE" R 2 "INPUT#" P 1 "PRINT" P
1 "DATA" P 2 "INPUT" P 1 "RCOLOR.COR" P
1 "DEF FN" P 2 "JOY" P 1 "READ" P
1 "DIM" P 1 "LINE INPUT#" P 1 "RECORD" P
1 "DO" P 3 "LINE" P 1 "REM" P
5 "ELLIPSE" P 1 "LOOP" P 1 "RESTORE" P
1 "ELSE" P 1 "MID$" P 1 "RESUME" P
1 "EL" P 1 "MOD" P 1 "RETURN" P
1 "ENVELOPE" P 1 "MOVSPR" P 1 "REVERS" S
2 "EXIT" P 1 "NEXT" P 3 "RGRAPHIC" P
1 "FOR" P 2 "ON" P 1 "RMOUSE" P

B-42
CHANGE
Token: $FE $2C
Format: CHANGE /findstring/ TO /replacestring/ [, line range]
CHANGE ”findstring” TO ”replacestring” [, line range]
Usage: Edits the BASIC program that is currently in memory to replace all in-
stances of one string with another.
An optional line range limits the search to this range, otherwise the en-
tire BASIC program is searched. At each occurrence of the findstring,
the line is listed and the user is prompted for an action:
RETURN
• Y perform the replace and find the next string
RETURN
• N do not perform the replace and find the next string
RETURN
• * replace the current and all following matches
RETURN
• exit the command, and don’t replace the current match
Remarks: Almost any character that is not part of the string, including letters and
punctuation, can be used instead of /.
However, using the double quote character finds text strings that are not
tokenised, and therefore not part of a keyword.
For example, CHANGE "LOOP" TO "OOPS" will not find the BASIC keyword LOOP, be-
cause the keyword is stored as a token and not as text. However CHANGE
/LOOP/ TO /OOPS/ will find and replace it (possibly causing SYNTAX ERRORs).
Due to a limitation of the BASIC parser, CHANGE is unable to match the
REM and DATA keywords. See FIND.
Can only be used in direct mode.
Examples: Using CHANGE

CHANGE "XX$" TO "UU$", 2000-2700


CHANGE /IN/ TO /OUT/
CHANGE &IN& TO &OUT&

B-43
CHAR
Token: $E0
Format: CHAR column, row, height, width, direction, string [, address of character
set]
Usage: Bitmap graphics: displays text on a graphic screen.
column (in units of character positions) is the start position of the output
horizontally. As each column unit is 8 pixels wide, a screen width of 320
has a column range of 0 – 39, while a screen width of 640 has a column
range of 0 – 79.
row (in pixel units) is the start position of the output vertically. In contrast
to the column parameter, its unit is in pixels (not character positions), with
the top row having the value of 0.
height is a factor applied to the vertical size of the characters, where 1
is normal size (8 pixels), 2 is double size (16 pixels), and so on.
width is a factor applied to the horizontal size of the characters,
where 1 is normal size (8 pixels) 2 is double size (16 pixels), and so on.
direction controls the printing direction:

• 1 up
• 2 right
• 4 down
• 8 left
The optional address of character set can be used to select a charac-
ter set, different to the default character set at $29800, which includes
upper and lower case characters.
Three character sets (see also FONT) are available:
• $29000 Font A (ASCII)
• $3D000 Font B (Bold)
• $2D000 Font C (CBM)
The first part of the font (upper case / graphics) is stored at $xx000 –
$xx7FF.
The second part of the font (lower case / upper case) is stored at $xx800
– $xxFFF.
string is a string constant or expression which will be printed. This string
may optionally contain one or more of the following control characters:

B-44
Expression Keyboard Shortcut Description
CHR$(2) CTRL+B Blank Cell
CHR$(6) CTRL+F Flip Character
CHR$(9) CTRL+I AND With Screen
CHR$(15) CTRL+O OR With Screen
CHR$(24) CTRL+X XOR With Screen
CHR$(18) RVSON Reverse
CHR$(146) RVSOFF Reverse Off
CHR$(147) CLR Clear Viewport
CHR$(21) CTRL+U Underline
CHR$(25)+"-" CTRL+Y + ”-” Rotate Left
CHR$(25)+"+" CTRL+Y + ”+” Rotate Right
CHR$(26) CTRL+Z Mirror
CHR$(157) Cursor Left Move Left
CHR$(29) Cursor Right Move Right
CHR$(145) Cursor Up Move Up
CHR$(17) Cursor Down Move Down
Notice that the start position of the string has different units in the hor-
izontal and vertical directions. Horizontal is in columns and vertical is in
pixels.
Refer to the CHR$ function on page B-48 for more information.

Example:
Remarks: Using CHAR

10 SCREEN 640,400,2
20 CHAR 28,180,4,4,2,"MEGA65",$29000
30 GETKEY A$
40 SCREEN CLOSE

Will print the text ”MEGA65” at the centre of a 640 x 400 graphic screen.

B-45
CHARDEF
Token: $E0 $96
Format: CHARDEF index, bit-matrix
Usage: Changes the appearance of a character.
index is the screen code of the character to change (@:0, A:1, B:2, ...).
See appendix C on page C-3 for a list of screen codes.
bit-matrix is a set of 8 byte values, which define the raster representa-
tion for the character from top row to bottom row. If more than 8 values
are used as arguments, the values 9 – 16 are used for the character
index+1, 17 – 24 for index+2, etc.
Remarks: The character bitmap changes are applied to the VIC character gener-
ator, which resides in RAM at the address $FF7E000.
All changes are volatile and the VIC character set can be restored by a
reset or by using the FONT command.
Examples: Using CHARDEF

CHARDEF 1,$FF,$81,$81,$81,$81,$81,$81,$FF :REM CHANGE 'A' TO RECTANGLE


CHARDEF 9,$18,$18,$18,$18,$18,$18,$18,$00 :REM MAKE 'I' SANS SERIF

B-46
CHDIR
Token: $FE $4B
Format: CHDIR dirname [,U unit]
Usage: Changes the current working directory.
dirname the name of a directory. Either a quoted string such as "SOMEDIR",
or a string expression in brackets such as (DR$).
Dependent on the unit, CHDIR is applied to different filesystems.
UNIT 12 is reserved for the SD-Card (FAT filesystem). This command can
be used to navigate to subdirectories and mount disk images that are
stored there. CHDIR ”..”,U12 changes to the parent directory on UNIT
12.
For other units managed by CBDOS (typically 8 and 9), CHDIR is used
to change into or out of subdirectories on floppy or disk image of type
D81. Existing subdirectories are displayed as filetype CBM in the parent
directory, they are created with the command MKDIR. CHDIR ”/”,U unit
changes to the root directory.
Examples: Using CHDIR

CHDIR "ADVENTURES",U12 :REM ENTER ADVENTURES ON SD CARD


CHDIR "..",U12 :REM GO BACK TO PARENT DIRECTORY
CHDIR "RACING",U12 :REM ENTER SUBDIRECTORY RACING
0 "MEGA65 " 1D
800 "MEGA65 GAMES" CBM
800 "MEGA65 TOOLS" CBM
600 "BASIC PROGRAMS" CBM
960 BLOCKS FREE.

CHDIR "MEGA65 GAMES",U8 :REM ENTER SUBDIRECTORY ON FLOPPY DISK


CHDIR "/",U8 :REM GO BACK TO ROOT DIRECTORY

B-47
CHR$
Token: $C1
Format: CHR$(numeric expression)
Returns: A string containing one character of the given PETSCII value.
Remarks: The argument range is from 0 – 255, so this function may also be used
to insert control codes into strings. Even the NULL character, with code
0, is allowed.
CHR$ is the inverse function to ASC. The complete table of characters
(and their PETSCII codes) is on page D-3.
Example: Using CHR$

10 QUOTE$ = CHR$(34)
20 ESCAPE$ = CHR$(27)
30 PRINT QUOTE$;"MEGA65";QUOTE$ : REM PRINT "MEGA65"
40 PRINT ESCAPE$;"Q"; : REM CLEAR TO END OF LINE

B-48
CIRCLE
Token: $E2
Format: CIRCLE xc, yc, radius [, flags , start, stop]
Usage: Bitmap graphics: draws a circle.
This is a special case of ELLIPSE, using the same value for horizontal and
vertical radius.
xc the x coordinate of the centre in pixels
yc the y coordinate of the centre in pixels
radius the radius of the circle in pixels
flags controls filling, arcs and the position of the 0 degree angle. Default
setting (zero) is don’t fill, draw legs and the 0 degree radian points to 3
o’ clock.
Bit Name Value Action if set
0 fill 1 Fill circle or arc with the current pen colour
1 legs 2 Suppress drawing of the legs of an arc
2 combs 4 Let the zero radian point to 12 o’ clock
The units for the start- and stop-angle are degrees in the range of 0 to
360. The 0 radian starts at 3 o’ clock and moves clockwise. Setting bit
2 of flags (value 4) moves the zero-radian to the 12 o’ clock position.
start start angle for drawing an arc
stop stop angle for drawing an arc
Remarks: CIRCLE is used to draw circles on screens with an aspect ratio of 1:1
(for example: 320 x 200 or 640 x 400). Whilst using other resolutions
(such as 640 x 200), the shape will be an ellipse instead.
The example program uses the random number function RND for circle
colour, size and position. So it shows a different picture for each run.

B-49
B-50
Example: Using CIRCLE

100 REM CIRCLE (AFTER F.BOWEN)


110 BORDER 0 :REM BLACK
120 SCREEN 320,200,4 :REM SIMPLE SCREEN SETUP
130 PALETTE 0,0,0,0,0 :REM BLACK
140 PALETTE 0,1,RND(.)*16,RND(.)*16,15 :REM RANDOM COLOURS
150 PALETTE 0,2,RND(.)*16,15,RND(.)*16
160 PALETTE 0,3,15,RND(.)*16,RND(.)*16
170 PALETTE 0,4,RND(.)*16,RND(.)*16,15
180 PALETTE 0,5,RND(.)*16,15,RND(.)*16
190 PALETTE 0,6,15,RND(.)*16,RND(.)*16
200 SCNCLR 0 :REM CLEAR
210 FORI=0TO32 :REM CIRCLE LOOP
220 PEN 0,RND(.)*6+1 :REM RANDOM PEN
230 R=RND(.)*36+1 :REM RADIUS
240 XC=R+RND(.)*320:IF(XC+R)>319THEN240:REM X CENTRE
250 YC=R+RND(.)*200:IF(YC+R)>199THEN250:REM Y CENTRE
260 CIRCLE XC,YC,R,. :REM DRAW
270 NEXT
280 GETKEY A$ :REM WAIT FOR KEY
290 SCREEN CLOSE:BORDER 6

B-51
CLOSE
Token: $A0
Format: CLOSE channel
Usage: Closes an input or output channel.
channel number, which was given to a previous call of commands such
as APPEND, DOPEN, or OPEN.
Remarks: Closing files that have previously been opened before a program has
completed is very important, especially for output files. CLOSE flushes
output buffers and updates the directory information on disks. Failing to
CLOSE can corrupt files and disks. BASIC does not automatically close
channels nor files when a program stops.
Example: Using CLOSE

10 OPEN 2,8,2,"TEST,S,W"
20 PRINT#2,"TESTSTRING"
30 CLOSE 2 : REM OMITTING CLOSE GENERATES A SPLAT FILE

B-52
CLR
Token: $9C
Format: CLR
CLR variable
Usage: Clears BASIC variable memory.
After executing CLR, all variables and arrays will be undeclared. The run-
time stack pointers and the table of open channels are also reset. RUN
performs CLR automatically.
CLR variable clears (zeroes) the variable. variable can be a numeric
variable or a string variable, but not an array.
Remarks: CLR should not be used inside loops or subroutines, as it destroys the
return address. After CLR, all variables are unknown and will be initialised
when they are next used.
Example: Using CLR

10 A=5: P$="MEGA65"
20 CLR
30 PRINT A;P$
RUN

B-53
CLRBIT
Token: $9C $FE $4E
Format: CLRBIT address, bit number
Usage: Clears (resets) a single bit at the address.
If the address is in the range of $0000 to $FFFF (0 – 65535), the memory
bank set by BANK is used.
Addresses greater than or equal to $10000 (decimal 65536) are as-
sumed to be flat memory addresses and used as such, ignoring the BANK
setting.
The bit number is a value in the range of 0 – 7.
Remarks: CLRBIT is a short version of using a bitwise AND to clear a bit, but you
can only clear one bit at a time. Refer to SETBIT to set a bit instead.
Example: Using CLRBIT

10 BANK 128 :REM SELECT SYSTEM MAPPING


20 CLRBIT $D011,4 :REM DISABLE DISPLAY
30 CLRBIT $D016,3 :REM SWITCH TO 38 OR 76 COLUMN MODE

B-54
CMD
Token: $9D
Format: CMD channel [, string]
Usage: Redirects the standard output from screen to a channel.
This enables you to print listings and directories to other output channels.
It is also possible to redirect this output to a disk file, or a modem.
channel number, which was given to a previous call of commands such
as APPEND, DOPEN, or OPEN.
The optional string is sent to the channel before the redirection begins
and can be used, for example, for printer or modem setup escape se-
quences.
Remarks: The CMD mode is stopped with PRINT#, or by closing the channel with
CLOSE. It is recommended to use PRINT# before closing to make sure
that the output buffer has been flushed.
Example: Using CMD to print a program listing:

OPEN 1,4 :REM OPEN CHANNEL #1 TO PRINTER AT UNIT 4


CMD 1
LIST
PRINT#1
CLOSE 1

B-55
COLLECT
Token: $F3
Format: COLLECT [,D drive] [,U unit]
Usage: Rebuilds the Block Availability Map (BAM) of a disk, deleting splat files
(files which have been opened, but not properly closed) and marking
unused blocks as free.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: While this command is useful for cleaning a disk from splat files, it is
dangerous for disks with boot blocks or random access files. These blocks
are not associated with standard disk files and will therefore be marked
as free and may be overwritten by further disk write operations.
Examples: Using COLLECT

COLLECT
COLLECT U9
COLLECT D0, U9

B-56
COLLISION
Token: $FE $17
Format: COLLISION type [, line number]
Usage: Enables or disables a user-programmed interrupt handler for sprite col-
lision.
With a handler enabled, a sprite collision of the given type interrupts the
BASIC program and performs a GOSUB to line number. This handler
must give control back with RETURN.
type the collision type for this interrupt handler:
Type Description
1 Sprite - Sprite Collision
2 Sprite - Data - Collision
3 Light Pen
line number the line number of a subroutine which handles the sprite
collision and ends with RETURN
A call without the line number argument disables the handler.
Remarks: It is possible to enable the interrupt handler for all types, but only one
can execute at any time. An interrupt handler cannot be interrupted by
another interrupt handler. Functions such as BUMP, LPEN and RSPPOS
may be used for evaluation of the sprites which are involved, and their
positions.
Info: COLLISION wasn’t completed in BASIC 10. It is available in BASIC 65.
Example: Using COLLISION

10 COLLISION 1,70 : REM ENABLE


20 SPRITE 1,1 : MOVSPR 1,120, 0 : MOVSPR 1,0#5
30 SPRITE 2,1 : MOVSPR 2,120,100 : MOVSPR 2,180#5
40 FOR I=1 TO 50000:NEXT
50 COLLISION 1 : REM DISABLE
60 END
70 REM SPRITE <-> SPRITE INTERRUPT HANDLER
80 PRINT "BUMP RETURNS";BUMP(1)
90 RETURN: REM RETURN FROM INTERRUPT

B-57
COLOR
Token: $E7
Format: COLOR colour
Usage: Sets the foreground text colour for subsequent PRINT commands.
colour the palette entry number, in the range 0 – 31
See appendix G on page G-3 for the list of colours in the default system
palette.
Remarks: This is another name for FOREGROUND.
Example: Using COLOR

COLOR 2
PRINT "THIS IS RED"
COLOR 3
PRINT "THIS IS CYAN"

B-58
CONCAT
Token: $FE $13
Format: CONCAT appendfile [,D drive] TO targetfile [,D drive] [,U unit]
Usage: Appends (concatenates) the contents of the file appendfile to the file
targetfile. Afterwards, targetfile contains the contents of both files,
while appendfile remains unchanged.
appendfile is either a quoted string, for example: "DATA" or a string ex-
pression in brackets, for example: (FI$)
targetfile is either a quoted string, for example: "SAFE" or a string expres-
sion in brackets, for example: (FS$)
If the disk unit has dual drives, it is possible to apply CONCAT to files
which are stored on different disks. In this case, it is necessary to specify
the drive# for both files. This is also necessary if both files are stored on
drive#1.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: CONCAT is executed in the DOS of the disk drive. Both files must ex-
ist and no pattern matching is allowed. Only files of type SEQ may be
concatenated.
Examples: Using CONCAT

CONCAT "NEW DATA" TO "ARCHIVE" ,U9


CONCAT "ADDRESS",D0 TO "ADDRESS BOOK",D1

B-59
CONT
Token: $9A
Format: CONT
Usage: Resumes program execution after a break or stop caused by an END or
RUN
STOP statement, or by pressing STOP .
This is a useful debugging tool. The BASIC program may be stopped and
variables can be examined, and even changed. The CONT statement
resumes execution.
Remarks: CONT cannot be used if a program has stopped because of an error.
Also, any editing of a program inhibits continuation. Stopping and con-
tinuation can spoil the screen output, and can also interfere with in-
put/output operations.
Example: Using CONT

10 I=I+1:GOTO 10
RUN

BREAK IN 10
READY.
PRINT I
947
CONT

B-60
COPY
Token: $F4
Format: COPY source [,D drive] [,U unit] TO [target] [,D drive] [,U unit]
Usage: Copies a file to another file, or one or more files from one disk to another.
source is either a quoted string, e.g. "DATA" or a string expression in brack-
ets, e.g. (FI$).
target is either a quoted string, e.g. "BACKUP" or a string expression in brack-
ets, e.g. (FS$)
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
If none or one unit number is given, or the unit numbers before and after
the TO token are equal, COPY is executed on the disk drive itself, and
the source and target files will be on the same disk.
If the source unit (before TO) is different to the target unit (after TO),
COPY executes a CPU-driven routine that reads the source files into a
RAM buffer and writes to the target unit. In this case, the target file name
cannot be chosen, it will be the same as the source filename. The ex-
tended unit-to-unit copy mode allows the copying of single files, pattern
matching files or all files of a disk. Any combination of units is allowed,
internal floppy, D81 disk images, IEC floppy drives such as the 1541,
1571, 1581, or CMD floppy and hard drives.
Remarks: The file types PRG, SEQ and USR can be copied. If source and target
are on the same disk, the target filename must be different to the source
file name.
COPY cannot copy DEL files, which are commonly used as titles or sep-
arators in disk directories. These do not conform to Commodore DOS
rules and cannot be accessed by standard OPEN routines.
REL files cannot be copied from unit to unit.
Examples: Using COPY

B-61
COPY U8 TO U9 :REM COPY ALL FILES
COPY "CODES" TO "BACKUP" :REM COPY SINGLE FILE
COPY "*.TXT",U8 TO U9 :REM PATTERN COPY
COPY "M*",U9 TO U11 :REM PATTERN COPY

B-62
COS
Token: $BE
Format: COS(numeric expression)
Returns: The cosine of an angle.
The argument is expected in units of radians. The result is in the range
(-1.0 to +1.0)
Remarks: A value in units of degrees can be converted to radians by multiplying
it with π/180.
Examples: Using COS

PRINT COS(0.7)
0.76484219

X=60:PRINT COS(X * ~ / 180)


0.5

B-63
CURSOR
Format: CURSOR <ON | OFF> [{, column, row, style}]
CURSOR column, row
Usage: Moves the text cursor to the specified position on the current text screen.
ON or OFF displays or hides the cursor. When the cursor is ON, it will
appear at the cursor position during GETKEY.
column and row specify the new position.
style sets a solid (1) or flashing (0) cursor.
Example: Using CURSOR

10 SCNCLR
20 CURSOR 1,2
30 PRINT "A"; : SLEEP 1
40 PRINT "B"; : SLEEP 1
50 PRINT "C"; : SLEEP 1
60 CURSOR 20,10
70 PRINT "D"; : SLEEP 1
80 CURSOR ,5 :REM MOVE THE CURSOR TO ROW 5 BUT DO NOT CHANGE THE COLUMN
90 PRINT "E"; : SLEEP 1
100 CURSOR 0 :REM MOVE THE CURSOR TO THE START OF THE ROW
110 PRINT "F"; : SLEEP 1

B-64
CUT
Token: $E4
Format: CUT x, y, width, height
Usage: Bitmap graphics: copies the content of the specified rectangle with up-
per left position x, y and the width and height to a buffer, and fills the
region afterwards with the colour of the currently selected pen.
The cut out can be inserted at any position with the command PASTE.
Remarks: The size of the rectangle is limited by the 1K size of the buffer. The
memory requirement for a cut out region is width * height * number of
bitplanes / 8. It must not equal or exceed 1024 byte. For a 4-bitplane
screen for example, a 45 x 45 region needs 1012.5 byte.
Example: Using CUT

10 SCREEN 320,200,2
20 BOX 60,60,300,180,1 :REM DRAW A WHITE BOX
30 PEN 2 :REM SELECT RED PEN
40 CUT 140,80,40,40 :REM CUT OUT A 40 * 40 REGION
50 PASTE 10,10,40,40 :REM PASTE IT TO NEW POSITION
60 GETKEY A$ :REM WAIT FOR KEYPRESS
70 SCREEN CLOSE

B-65
DATA
Token: $83
Format: DATA [constant [, constant ...]]
Usage: Defines constants which can be read by READ statements in a program.
Numbers and strings are allowed, but expressions are not. Items are sep-
arated by commas. Strings containing commas, colons or spaces must
be placed in quotes.
RUN initialises the data pointer to the first item of the first DATA state-
ment and advances it for every read item. It is the programmer’s re-
sponsibility that the type of the constant and the variable in the READ
statement match. Empty items with no constant between commas are
allowed and will be interpreted as zero for numeric variables and an
empty string for string variables.
RESTORE may be used to set the data pointer to a specific line for sub-
sequent reads.
Remarks: It is good programming practice to put large amounts of DATA state-
ments at the end of the program, so they don’t slow down the search for
line numbers after GOTO, and other statements with line number targets.
Example: Using DATA

1 REM DATA
10 READ NA$, VE
20 READ N% : FOR I=2 TO N% : READ GL(I) : NEXT I
30 PRINT "PROGRAM:";NA$;" VERSION:";VE
40 PRINT "N-POINT GAUSSLEGENDRE FACTORS E1":
50 FOR I=2 TO N%:PRINT I;GL(I):NEXT I
60 END
80 DATA "MEGA65",1.1
90 DATA 5,0.5120,0.3573,0.2760,0.2252

RUN
PROGRAM:MEGA65 VERSION: 1.1
N-POINT GAUSSLEGENDRE FACTORS E1
2 0.512
3 0.3573
4 0.276
5 0.2252

B-66
DCLEAR
Token: $FE $15
Format: DCLEAR [,D drive] [,U unit]
Usage: Sends an initialise command to the specified unit and drive.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
The DOS of the disk drive will close all open files, clear all channels, free
buffers and re-read the BAM. All open channels on the computer will also
be closed.
Examples: Using DCLEAR

DCLEAR
DCLEAR U9
DCLEAR D0, U9

B-67
DCLOSE
Token: $FE $0F
Format: DCLOSE [U unit]
DCLOSE # channel
Usage: Closes a single file or all files for the specified unit.
channel number, which was given to a previous call to commands such
as APPEND, DOPEN, or OPEN.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
DCLOSE is used either with a channel argument or a unit number, but
never both.
Remarks: It is important to close all open files before a program ends. Otherwise
buffers will not be freed and even worse, open files that have been writ-
ten to may be incomplete (commonly called splat files), and no longer
usable.
Examples: Using DCLOSE

DCLOSE#2 :REM CLOSE FILE ASSIGNED TO CHANNEL 2


DCLOSE U9:REM CLOSE ALL FILES OPEN ON UNIT 9

B-68
DEC
Token: $D1
Format: DEC(string expression)
Returns: The decimal value of a hexadecimal string.
The argument range is “0” to “FFFFFFFF”. DEC() ignores everything after
the first non-hex digit or the eighth character.
Remarks: Allowed digits in uppercase/graphics mode are 0 – 9 and A – F
(0123456789ABCDEF) and in lowercase/uppercase mode are 0 – 9 and a – f
(0123456789abcdef).
Example: Using DEC

PRINT DEC("D000")
53248

POKE DEC("600"),255

B-69
DECBIN
Token: $CE $11
Format: DECBIN(string expression)
Returns: The decimal value of a binary string.
The argument range is “0” to “11111111111111111111111111111111”.
DECBIN() ignores everything after the first non-binary digit or the 32nd
character.
Example: Using DECBIN

PRINT DECBIN("1101000000000000")
53248

B-70
DEF FN
Token: $96
Format: DEF FN name(real variable) = [expression]
Usage: Defines a single statement user function with one argument of type real,
that returns a real value when evaluated.
The definition must be executed before the function can be used in ex-
pressions. The argument is a dummy variable, which will be replaced by
the argument when the function is used.
Remarks: The function argument is not a real variable and will not overwrite a vari-
able with that name. It only represents the argument value within the
function definition.
Example: Using DEF FN

10 PD = ~ / 180
20 DEF FN CD(X)= COS(X*PD): REM COS FOR DEGREES
30 DEF FN SD(X)= SIN(X*PD): REM SIN FOR DEGREES
40 FOR D=0 TO 360 STEP 90
50 PRINT USING "###";D
60 PRINT USING " ##.##";FNCD(D);
70 PRINT USING " ##.##";FNSD(D)
80 NEXT D
RUN
0 1.00 0.00
90 0.00 1.00
180 -1.00 0.00
270 0.00 -1.00
360 1.00 0.00

B-71
DELETE
Token: $F7
Format: DELETE [line range]
DELETE filename [,D drive] [,U unit] [,R]
Usage: The first form deletes a range of lines from the BASIC program. The
second form deletes one or more files from a disk.
line range consists of the first and last line to delete, or a single line
number. If the first number is omitted, the first BASIC line is assumed.
The second number in the range specifier defaults to the last BASIC line.
filename is either a quoted string, for example: "SAFE"" or a string expres-
sion in brackets, for example: (FS$)
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
R Recover a previously deleted file. This will only work if there were no
write operations between deletion and recovery, which may have altered
the contents of the file.
Remarks: DELETE filename is a synonym of SCRATCH filename and ERASE file-
name.
Examples: Using DELETE

DELETE 100 :REM DELETE LINE 100


DELETE 240-350 :REM DELETE ALL LINES FROM 240 TO 350
DELETE 500- :REM DELETE FROM 500 TO END
DELETE -70 :REM DELETE FROM START TO 70

DELETE "DRM",U9 :REM DELETE FILE DRM ON UNIT 9


DELETE "*=SEQ" :REM DELETE ALL SEQUENTIAL FILES
DELETE "R*=PRG" :REM DELETE PROGRAM FILES STARTING WITH 'R'

B-72
DIM
Token: $86
Format: DIM name(limits) [, name(limits) ...]
Usage: Declares the shape, bounds and the type of a BASIC array.
As a declaration statement, it must be executed only once and before
any usage of the declared arrays. An array can have one or more dimen-
sions. One dimensional arrays are often called vectors while two or more
dimensions define a matrix. The lower bound of a dimension is always
zero, while the upper bound is as declared. The rules for variable names
apply for array names as well. You can create byte arrays, integer ar-
rays, real arrays and string arrays. It is legal to use the same identifier for
scalar variables and array variables. The left parenthesis after the name
identifies array names.
Remarks: Byte arrays consume one byte per element, integer arrays two bytes, real
arrays five bytes and string arrays three bytes for the string descriptor
plus the length of the string itself.
If an array identifier is used without being previously declared, an implicit
declaration of an one dimensional array with limit of 10 is performed.
Example: Using DIM

1 REM DIM
10 DIM A%(8) : REM ARRAY OF 9 ELEMEMTS
20 DIM XX(2,3) : REM ARRAY OF 3X4 = 12 ELEMENTS
30 FOR I=0 TO 8 : A%(I)=PEEK(256+I) : PRINT A%(I);: NEXT:PRINT
40 FOR I=0 TO 2 : FOR J=0 TO 3 : READ XX(I,J):PRINT XX(I,J);: NEXT J,I
50 END
60 DATA 1,-2,3,-4,5,-6,7,-8,9,-10,11,-12

RUN
45 52 50 0 0 0 0 0 0
1 -2 3 -4 5 -6 7 -8 9 -10 11 -12

B-73
DIR
Token: $EE (DIR) $FE $29 (ECTORY)
Format: DIR [filepattern] [,W] [,P] [,R] [,D drive] [,U unit]
DIRECTORY [filepattern] [,W] [,P] [,R] [,D drive] [,U unit]
$ [filepattern] [,W] [,R] [,D drive] [,U unit]
DIR U12 [,P]
Usage: Prints a file directory/catalog of the specified disk.
The W (Wide) parameter lists the directory three columns wide on the
screen and pauses after the screen has been filled with a page (63 di-
rectory entries). Pressing any key displays the next page.
The P (Pagination) parameter lists the directory one column wide, and
pauses for each screenful of output. Press the Q key to interrupt the
listing at the current page. Press any other key to display the next page.
The R (Recoverable) parameter includes files in the directory, which are
flagged as deleted but are still recoverable.
filepattern is either a quoted string, for example: "DA*" or a string expres-
sion in brackets, e.g. (DI$)
The U12 argument lists the contents of the SD card. It can be used
with the P argument for a paginated display. It does not support other
arguments.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: DIR is a synonym of CATALOG and DIRECTORY, and produces the same
listing. The filepattern can be used to filter the listing. The wildcard
characters * and ? may be used. Adding ,T= to the pattern string, with T
specifying a filetype of P, S, U or R (for PRG, SEQ, USR, REL) filters the
output to that filetype.
The shortcut symbol $ can only be used in direct mode.
Examples: Using DIR

B-74
DIR
0 "BLACK SMURF " BS 2A
508 "STORY PHOBOS" SEQ
27 "C8096" PRG
25 "C128" PRG
104 BLOCKS FREE.

For a DIR listing with the wide parameter, please refer to the example
under CATALOG on page B-42.

B-75
DISK
Token: $FE $40
Format: DISK command [,U unit]
@ command [,U unit]
Usage: Sends a command string to the specified disk unit.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
command is a string expression.
Remarks: The command string is interpreted by the disk unit and must be compat-
ible to the used DOS version. Read the disk drive manual for possible
commands.
Using DISK with no parameters prints the disk status.

The shortcut key @ can only be used in direct mode.


Examples: Using DISK

DISK "I0" :REM INITIALISE DISK IN DRIVE 0


DISK "U0>9" :REM CHANGE UNIT# TO 9

B-76
DLOAD
Token: $F0
Format: DLOAD filename [,D drive] [,U unit]
DLOAD ”$[pattern=type]” [,D drive] [,U unit]
DLOAD ”$$[pattern=type]” [,D drive] [,U unit]
Usage: The first form loads a file of type PRG into memory reserved for BASIC
programs.
The second form loads a directory into memory, which can then be
viewed with LIST. It is structured like a BASIC program, but file sizes are
displayed instead of line numbers.
The third form is similar to the second one, but the files are numbered.
This listing can be scrolled like a BASIC program with the keys F9 or
F11 , edited, listed, saved or printed.
A filter can be applied by specifying a pattern or a pattern and a type.
The asterisk matches the rest of the name, while the ? matches any
single character. The type specifier can be a character of (P,S,U,R), that
is Program, Sequential, User, or Relative file.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: The load address that is stored in the first two bytes of the PRG file is
ignored. The program is always loaded into BASIC memory. This enables
loading of BASIC programs that were saved on other computers with
different memory configurations. After loading, the program is re-linked
and ready to be RUN or edited.
It is possible to use DLOAD in a running program. This is called overlaying,
or chaining. If you do this, then the newly loaded program replaces the
current one, and the execution starts automatically on the first line of
the new program. Variables, arrays and strings from the current run are
preserved and can also be used by the newly loaded program.
Every DLOAD, of either a program or a directory listing, will replace a
program that is currently in memory.
Examples: Using DLOAD

B-77
DLOAD "APOCALYPSE"
DLOAD "MEGA TOOLS",U9
DLOAD (FI$),U(UN%)

DLOAD "$" :REM LOAD WHOLE DIRECTORY - WITH FILE SIZES


DLOAD "$$" :REM LOAD WHOLE DIRECTORY - SCROLLABLE
DLOAD "$$X*=P" :REM DIRECTOY WITH PRG FILES STARTING with 'X'

B-78
DMA
Token: $FE $1F
Format: DMA command [, length, source address, source bank, target address,
target bank [, sub]]
Usage: DMA (”Direct Memory Access”) is obsolete, and has been replaced by
EDMA.
command The lower two bits control the function: 0: copy, 1: mix, 2:
swap, 3: fill. Note that only copy and fill are implemented in the MEGA65
DMAcontroller at the time of writing. Other DMAgic command bits can
also be set, for example, to allow copying data in the reverse direction,
or holding the source or destination address.
length number of bytes (in the range 0 to 65535). NOTE: Specifying
a length of 0 will be interpreted as a length of 65536 (exactly 64 kilo-
bytes).
source address 16-bit address of read area or fill byte
source bank bank number for source (ignored for fill mode)
target 16-bit address of write area
target bank bank number for target
sub sub command
Remarks: DMA has access to the lower 1MB address range organised in 16 banks
of 64 K. To avoid this limitation, use EDMA, which has access to the full
256MB address range.
Examples: A sequence of DMA calls to demonstrate fast screen drawing operations

DMA 0, 80*25, 2048, 0, 0, 4 :REM SAVE SCREEN TO $00000 BANK 4


DMA 3, 80*25, 32, 0, 2048, 0 :REM FILL SCREEN WITH BLANKS
DMA 0, 80*25, 0, 4, 2048, 0 :REM RESTORE SCREEN FROM $00000 BANK 4
DMA 2, 80, 2048, 0, 2048+80, 0 :REM SWAP CONTENTS OF LINE 1 & 2 OF SCREEN

B-79
DMODE
Token: $FE $35
Format: DMODE jam, complement, stencil, style, thick
Usage: Bitmap graphics: sets “display mode” parameters of the graphics con-
text, which is used by drawing commands.
Mode Values
jam 0-1
complement 0-1
stencil 0-1
style 0-3
thick 1-8

B-80
DO
Token: $EB
Format: DO ... LOOP
DO [<UNTIL | WHILE> logical expression]
. . . statements [EXIT]
LOOP [<UNTIL | WHILE> logical expression]
Usage: DO and LOOP define the start of a BASIC loop.
Using DO and LOOP alone without any modifiers creates an infinite loop,
which can only be exited by the EXIT statement. The loop can be con-
trolled by adding UNTIL or WHILE after the DO or LOOP.
Remarks: DO loops may be nested. An EXIT statement only exits the current loop.
Examples: Using DO and LOOP

10 PW$="":DO
20 GET A$:PW$=PW$+A$
30 LOOP UNTIL LEN(PW$)>7 OR A$=CHR$(13)

10 DO : REM WAIT FOR USER DECISION


20 GET A$
30 LOOP UNTIL A$="Y" OR A$="N" OR A$="y" OR A$="n"

10 DO WHILE ABS(EPS) > 0.001


20 GOSUB 2000 : REM ITERATION SUBROUTINE
30 LOOP

10 I%=0 : REM INTEGER LOOP 1-100


20 DO: I%=I%+1
30 LOOP WHILE I% < 101

B-81
DOPEN
Token: $FE $0D
Format: DOPEN# channel, filename [,L [reclen]] [,W] [,D drive] [,U unit]
Usage: Opens a file for reading or writing.
channel number, where:
• 1 <= channel <= 127 line terminator is CR.
• 128 <= channel <= 255 line terminator is CR LF.
L indicates, that the file is a relative file, which is opened for read/write,
as well as random access.
The reclen record length is mandatory for creating relative files. For
existing relative files, reclen is used as a safety check, if given.
W opens a file for write access. The file must not exist.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: DOPEN# may be used to open all file types. The sequential file type SEQ
is default. The relative file type REL is chosen by using the L parameter.
Other file types must be specified in the filename, e.g. by adding ”,P” to
the filename for PRG files or ”,U” for USR files.
If the first character of the filename is an at sign ’@’, it is interpreted as a
”save and replace” operation. It is not recommended to use this option
on 1541 and 1571 drives, as they contain a ”save and replace bug” in
their DOS.

B-82
Examples: Using DOPEN

DOPEN#5,"DATA",U9
DOPEN#130,(DD$),U(UN%)
DOPEN#3,"USER FILE,U"
DOPEN#2,"DATA BASE",L240
DOPEN#4,"MYPROG,P" : REM OPEN PRG FILE

B-83
DOT
Token: $FE $4C
Format: DOT x, y [,colour]
Usage: Bitmap graphics: draws a pixel at screen coordinates x and y. The op-
tional third parameter defines the colour to be used. If not specified, the
current pen colour will be used.
Example: Using DOT:

10 SCREEN 320,200,5
20 BOX 50,50,270,150
30 VIEWPORT 50,50,220,100
40 FORI=0TO127
50 DOT I+I+I,I+I,I
60 NEXT
70 GETKEY A
80 SCREEN CLOSE

B-84
DPAT
Token: $FE $36
Format: DPAT type [, number, pattern ...]
Usage: Bitmap graphics: sets the drawing pattern of the graphics context for
drawing commands.
There a four predefined pattern types, that can be selected by specifying
the type number (1, 2, 3, or 4) as a single parameter.
A value of zero for the type number indicates a user defined pattern.
This pattern can be set by using a bit string that consists of either 8, 16,
24, or 32 bits. The number of used pattern bytes is given as the second
parameter. It defines how many pattern bytes (1, 2, 3, or 4) follow.
• Type 0 – 4
• Number number of following pattern bytes (1 – 4)
• Pattern pattern bytes

B-85
DS
Format: DS
Usage: The status of the last disk operation.
This is a volatile variable. Each use triggers the reading of the disk status
from the current disk device in usage.
DS is coupled to the string variable DS$ which is updated at the same
time.
Reading the disk status from a disk device automatically clears any error
status on that device, so subsequent reads will return 0, if no other activity
has since occurred.
Remarks: DS is a reserved system variable.
Example: Using DS

100 DOPEN#1,"DATA"
110 IF DS<>0 THEN PRINT"COULD NOT OPEN FILE DATA":STOP

B-86
DS$
Format: DS$
Usage: The status of the last disk operation in text form of the format:
Code,Message,Track,Sector.
DS$ is coupled to the numeric variable DS. It is updated when DS is used.
DS$ is set to 00,OK,00,00 if there was no error, otherwise it is set to a DOS
error message (listed in the disk drive manuals).
Remarks: DS$ is a reserved system variable.
Example: Using DS$

100 DOPEN#1,"DATA"
110 IF DS<>0 THEN PRINT DS$:STOP

B-87
DSAVE
Token: $EF
Format: DSAVE filename [,D drive] [,U unit]
Usage: Saves the BASIC program in memory to a file of type PRG.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$). The maximum length of the
filename is 16 characters. If the first character of the filename is an at
sign ’@’ it is interpreted as a ”save and replace” operation. It is not rec-
ommended to use this option on 1541 and 1571 drives, as they contain
a ”save and replace bug” in their DOS.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: DVERIFY can be used after DSAVE to check if the saved program on disk
is identical to the program in memory.
Example: Using DSAVE

DSAVE "ADVENTURE"
DSAVE "ZORK-I",U9
DSAVE "DUNGEON",D1,U10

B-88
DT$
Format: DT$
Usage: The current date, as a string.
The date value is updated from RTC (Real-Time Clock). The string DT$ is
formatted as: ”DD-MON-YYYY”, for example: ”04-APR-2021”.
Remarks: DT$ is a reserved system variable. For more information on how to set
the Real-Time Clock, refer to Chapter/Appendix 4 on page 4-3.
Example: Using DT$

100 PRINT "TODAY IS: ";DT$

B-89
DVERIFY
Token: $FE $14
Format: DVERIFY filename [,D drive] [,U unit]
Usage: Verifies that the BASIC program in memory is equivalent to a file of type
PRG.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: DVERIFY can only test for equality. It gives no information about the
number or position of different valued bytes. DVERIFY exits either with
the message OK or with VERIFY ERROR.
Example: Using DVERIFY

DVERIFY "ADVENTURE"
DVERIFY "ZORK-I",U9
DVERIFY "DUNGEON",D1,U10

B-90
EDIT
Format: EDIT <ON | OFF>
Usage: Enables or disables the text editing mode of the screen editor.
EDIT ON enables text editing mode. In this mode, you can create, edit,
save, and load files of type SEQ as text files using the same line editor
that you use to write BASIC programs. In this mode:
• The prompt appears as OK, instead of READY.
• The editor does no tokenising/parsing. All text entered after a
linenumber remains pure text, BASIC keywords such as FOR and
GOTO are not converted to BASIC tokens, as they are whilst in pro-
gram mode.
• The line numbers are only used for text organisation, sorting, delet-
ing, listing, etc.
• When the text is saved to file with DSAVE, a sequential file (type
SEQ) is written, not a program (PRG) file. Line numbers are not
written to the file.
• DLOAD in text mode can load only sequential files. Line numbers
are automatically generated for editing purposes.
• Text mode applies to lines entered with line numbers only. Lines with
no line number are executed as BASIC commands, as usual.
EDIT OFF disables text editing mode and returns to BASIC program edit-
ing mode. The MEGA65 starts in BASIC program editing mode.
Sequential files created with the text editor can be displayed (without
loading them) on the screen by using TYPE <filename>.

B-91
Example: Using EDIT

ready.
edit on

ok.
100 This is a simple text editor.
dsave "example"

ok.
new

ok.
catalog

0 "demoempty " 00 3d
1 "example" seq
3159 blocks free

ok.
type "example"
This is a simple text editor.

ok.
dload "example"

loading

ok.
list

1000 This is a simple text editor.

ok.

B-92
EDMA
Token: $FE $21
Format: EDMA command, length, source, target
Usage: Copies or updates a large amount of memory quickly.
EDMA (”Extended Direct Memory Access”) is the fastest method to ma-
nipulate memory areas using the DMA controller. Please refer to Chap-
ter/Appendix O on page O-3 for more details on EDMA.
command 0: copy, 1: mix, 2: swap, 3: fill.
Because this two bits of the command share the same register with other
bits you can for example use bit 5 to reverse loop operation. This is also
working in overlapping memory regions for source and target. Please see
the example below.
length number of bytes (in the range 0 to 65535). NOTE: Specifying
a length of 0 will be interpreted as a length of 65536 (exactly 64 kilo-
bytes).
source 28-bit address of read area or fill byte.
target 28-bit address of write area.
Remarks: EDMA can access the entire 256MB address range, using up to 28 bits
for the addresses of the source and target.
Examples: Using EDMA

EDMA 0, $800, $F700, $8000000 :REM COPY SCALAR VARIABLES TO ATTIC RAM
EDMA 3, 80*25, 32, 2048 :REM FILL SCREEN WITH BLANKS
EDMA 0, 80*25, 2048, $8000800 :REM COPY SCREEN TO ATTIC RAM

By adding 32 (bit 5) to the command parameter, the DMA operation can


be performed in reverse order:

10 PRINT "ƳMEGA65!"
20 EDMA 0,10,2048,3020 : REM 2048 IS BEGINNING OF SCREEN RAM
30 EDMA 32,10,2048,3100 : REM 3020 AND 3100 ARE THE LOWER PART OF THE SCREEN

B-93
Listing and output of the last example:

B-94
EL
Format: EL
Usage: The line number where the most recent BASIC error occurred, or the value
-1 if there was no error.
Remarks: EL is a reserved system variable.
This variable is typically used in a TRAP routine, where the error line is
taken from EL.
Example: Using EL

10 TRAP 100
20 PRINT SQR(-1) :REM PROVOKE ERROR
30 PRINT "AT LINE 30":REM HERE TO RESUME
40 END
100 IF ER>0 THEN PRINT ERR$(ER);" ERROR"
110 PRINT " IN LINE";EL
120 RESUME NEXT :REM RESUME AFTER ERROR

B-95
ELLIPSE
Token: $FE $30
Format: ELLIPSE xc, yc, xr, yr [, flags , start, stop]
Usage: Bitmap graphics: draws an ellipse.
xc is the x coordinate of the centre in pixels
yc is the y coordinate of the centre in pixels
xr is the x radius of the ellipse in pixels
yr is the y radius of the ellipse in pixels
flags control filling, arcs and orientation of the zero radian (combs flag
named after retroCombs). Default setting (zero) is: Don’t fill, draw legs,
start drawing at 3 ’o clock.
Bit Name Value Action if set
0 fill 1 Fill ellipse or arc with the current pen colour
1 legs 2 Suppress drawing of the legs of an arc
2 combs 4 Drawing (0 degree) starts at 12 ’o clock
The units for the start- and stop-angle are degrees in the range of 0 to
360. The 0 radian starts at 3 o’ clock and moves clockwise. The combs-
flag shifts the 0 radian and the start position to the 12 ’o clock position.
start start angle for drawing an elliptic arc.
stop stop angle for drawing an elliptic arc.
Remarks: ELLIPSE is used to draw ellipses on screens at various resolutions. If a
full ellipse is to be drawn, start and stop should be either omissed or set
both to zero (not 0 and 360). Drawing and filling of full ellipses is much
faster, than using elliptic arcs.
Example: Using ELLIPSE

B-96
100 S%=2:D%=3:W%=320*S%:H%=200*S% :REM SCREEN SETTINGS
110 CX%=W%/2:CY%=H%/2 :REM CENTRE AND RADII
120 RX%=W%/2:RY%=H%/2
130 SCREEN W%,H%,D% :REM OPEN SCREEN
140 ELLIPSE CX%,CY%,CX%-4,CY%-4
150 PEN2:CIRCLE CX%,CY%,RY%-4,2
160 PEN3:CIRCLE CX%,CY%,RY%-14,2
170 PEN4:CIRCLE CX%,CY%,RY%-24,0,135,45
180 PEN5:ELLIPSE CX%,CY%/2,RX%/4,RY%/4,1
190 PEN6:CIRCLE 120*S%,CY%,40,1,45,315
200 PEN7:CIRCLE 200*S%,CY%,40,1,225,135
210 PEN0:CHAR 34,CY%/2-8,2,2,2,"MEGA65",$3D000
220 GETKEY A& :REM WAIT FOR ANY KEY
230 SCREEN CLOSE :REM CLOSE GRAPHICS SCREEN

B-97
ELSE
Token: $D5
Format: IF expression THEN true clause [:ELSE false clause]
Usage: ELSE is an optional part of an IF statement.
expression a logical or numeric expression. A numeric expression is
evaluated as FALSE if the value is zero and TRUE for any non-zero value.
true clause one or more statements starting directly after THEN on the
same line. A line number after THEN performs a GOTO to that line in-
stead.
false clause one or more statements starting directly after ELSE on the
same line. A linenumber after ELSE performs a GOTO to that line instead.
Remarks: There must be a colon before ELSE. There cannot be a colon or end-of-
line after ELSE.
The standard IF ... THEN ... ELSE structure is restricted to a single line.
But the true clause and false clause may be expanded to several lines
using a compound statement surrounded with BEGIN and BEND.
When the true clause does not use BEGIN and BEND, ELSE must be on
the same line as IF.
Example: Using ELSE

100 REM ELSE


110 RED$=CHR$(28):BLACK$=CHR$(144):WHITE$=CHR$(5)
120 INPUT "ENTER A NUMBER";V
130 IF V<0 THENPRINT RED$;:ELSEPRINT BLACK$;
140 PRINT V : REM PRINT NEGATIVE NUMBERS IN RED
150 PRINT WHITE$
160 INPUT "END PROGRAM:(Y/N)";A$
170 IF A$="Y" THENEND
180 IF A$="N" THEN120:ELSE160

Using ELSE with BEGIN and BEND.

B-98
100 A = 0 : GOSUB 200
110 A = 1 : GOSUB 200
120 END
200 IF A = 0 THEN BEGIN
210 PRINT "HELLO"
220 BEND : ELSE BEGIN
230 PRINT "GOODBYE"
240 BEND
250 RETURN

B-99
END
Token: $80
Format: END
Usage: Ends the execution of the BASIC program.
The READY. prompt appears and the computer goes into direct mode wait-
ing for keyboard input.
Remarks: END does not clear channels nor close files. Variable definitions are still
valid after END. The program may be continued with the CONT state-
ment. After executing the last line of a program, END is executed auto-
matically.
Example: Using END

10 IF V < 0 THEN END : REM NEGATIVE NUMBERS END THE PROGRAM


20 PRINT V

B-100
ENVELOPE
Token: $FE $0A
Format: ENVELOPE n [{, attack, decay, sustain, release, waveform, pw}]
Usage: Sets the parameters for the synthesis of a musical instrument for use with
PLAY.
n envelope slot (0 – 9).
attack attack rate (0 – 15).
decay decay rate (0 – 15).
sustain sustain rate (0 – 15).
release release rate (0 – 15).
waveform 0: triangle, 1: sawtooth, 2: square/pulse, 3: noise, 4: ring
modulation.
pw pulse width (0 – 4095) for waveform.
There are 10 slots for storing instrument parameters, preset with the fol-
lowing default values:
n A D S R WF PW Instrument
0 0 9 0 0 2 1536 Piano
1 12 0 12 0 1 Accordion
2 0 0 15 0 0 Calliope
3 0 5 5 0 3 Drum
4 9 4 4 0 0 Flute
5 0 9 2 1 1 Guitar
6 0 9 0 0 2 512 Harpsichord
7 0 9 9 0 2 2048 Organ
8 8 9 4 1 2 512 Trumpet
9 0 9 0 0 0 Xylophone
Example: Using ENVELOPE

10 ENVELOPE 9,10,5,10,5,2,4000
20 VOL 9,9
30 TEMPO 30
40 PLAY "T9O4Q CDEFGAB U3T8 CDEFGAB L","T5O3Q H CGEQG T7 HCGEQG L"

B-101
ER
Format: ER
Usage: The number of the most recent BASIC error that has occurred, or -1 if
there was no error.
Remarks: ER is a reserved system variable.
This variable is typically used in a TRAP routine, where the error number
is taken from ER.
Example: Using ER

10 TRAP 100
20 PRINT SQR(-1) :REM PROVOKE ERROR
30 PRINT "AT LINE 30":REM HERE TO RESUME
40 END
100 IF ER>0 THEN PRINT ERR$(ER);" ERROR"
110 PRINT " IN LINE";EL
120 RESUME NEXT :REM RESUME AFTER ERROR

B-102
ERASE
Token: $FE $2A
Format: ERASE filename [,D drive] [,U unit] [,R]
Usage: Erases (deletes) a disk file.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
R Recover a previously erased file. This will only work if there were no
write operations between erasing and recovery, which may have altered
the contents of the disk.
Remarks: ERASE filename is a synonym of SCRATCH filename and DELETE file-
name.
In direct mode, the success and the number of erased files is printed.
The second to last number from the message contains the number of
successfully erased files.
Examples: Using ERASE

ERASE "DRM",U9 :REM ERASE FILE DRM ON UNIT 9


01, FILES SCRATCHED,01,00
ERASE "OLD*" :REM ERASE ALL FILES BEGINNING WITH "OLD"
01, FILES SCRATCHED,04,00
ERASE "R*=PRG" :REM ERASE PROGRAM FILES STARTING WITH 'R'
01, FILES SCRATCHED,09,00

B-103
ERR$
Token: $D3
Format: ERR$(number)
Returns: The string description of a given BASIC error number.
number a BASIC error number (1 – 41)
This function is typically used in a TRAP routine, where the error number
is taken from the reserved variable ER.
Remarks: Arguments out of range (1 – 41) will produce an ILLEGAL QUANTITY error.
Example: Using ERR$

10 TRAP 100
20 PRINT SQR(-1) :REM PROVOKE ERROR
30 PRINT "AT LINE 30":REM HERE TO RESUME
40 END
100 IF ER>0 THEN PRINT ERR$(ER);" ERROR"
110 PRINT " IN LINE";EL
120 RESUME NEXT :REM RESUME AFTER ERROR

B-104
EXIT
Token: $FD
Format: EXIT
Usage: Exits the current DO .. LOOP and continues execution at the first state-
ment after LOOP.
Remarks: In nested loops, EXIT exits only the current loop, and continues execution
in an outer loop (if there is one).
Example: Using EXIT

1 REM EXIT
10 OPEN 2,8,0,"$" : REM OPEN CATALOG
15 IF DS THEN PRINT DS$: STOP: REM CANT READ
20 GET#2,D$,D$ : REM DISCARD LOAD ADDRESS
25 DO : REM LINE LOOP
30 GET#2,D$,D$ : REM DISCARD LINE LINK
35 IF ST THEN EXIT : REM END-OF-FILE
40 GET#2,LO,HI : REM FILE SIZE BYTES
45 S=LO + 256 * HI : REM FILE SIZE
50 LINE INPUT#2, F$ : REM FILE NAME
55 PRINT S;F$ : REM PRINT FILE ENTRY
60 LOOP
65 CLOSE 2

B-105
EXP
Token: $BD
Format: EXP(numeric expression)
Returns: The value of the mathematical constant Euler’s number (2.71828183)
raised to the power of the argument.
Remarks: An argument greater than 88 produces an OVERFLOW ERROR.
Examples: Using EXP

PRINT EXP(1)
2.71828183

PRINT EXP(0)
1

PRINT EXP(LOG(2))
2

B-106
FAST
Token: $FE $25
Format: FAST [speed]
Usage: Sets CPU clock speed to 1MHz, 3.5MHz or 40MHz.
speed CPU clock speed where:
• 1 sets CPU to 1MHz.
• 3 sets CPU to 3MHz.
• Anything other than 1 or 3 sets the CPU to 40MHz.
Remarks: Although it’s possible to call FAST with any real number, the precision
part (the decimal point and any digits after it), will be ignored.
FAST is a synonym of SPEED.
FAST has no effect if POKE 0,65 has previously been used to set the CPU to
40MHz.
Example: Using FAST

10 FAST :REM SET SPEED TO MAXIMUM (40 MHZ)


20 FAST 1 :REM SET SPEED TO 1 MHZ
30 FAST 3 :REM SET SPEED TO 3.5 MHZ
40 FAST 3.5 :REM SET SPEED TO 3.5 MHZ

B-107
FGOSUB
Token: $FE $48
Format: FGOSUB numeric expression
Usage: Evaluates the given numeric expression, then calls (GOSUBs) the subrou-
tine at the resulting line number.
Warning: Take care when using RENUMBER to change the line numbers of your
program that any FGOSUB statements still use the intended numbers.
Example: Using FGOSUB:

10 INPUT "WHICH SUBROUTINE TO EXECUTE 100,200,300";LI


20 FGOSUB LI :REM HOPEFULLY THIS LINE # EXISTS
30 GOTO 10 :REM REPEAT
100 PRINT "AT LINE 100":RETURN
200 PRINT "AT LINE 200":RETURN
300 PRINT "AT LINE 300":RETURN

B-108
FGOTO
Token: $FE $47
Format: FGOTO numeric expression
Usage: Evaluates the given numeric expression, then jumps (GOesTO) to the re-
sulting line number.
Warning: Take care when using RENUMBER to change the line numbers of your
program that any FGOTO statements still use the intended numbers.
Example: Using FGOTO:

10 INPUT "WHICH LINE # TO EXECUTE 100,200,300";LI


20 FGOTO LI :REM HOPEFULLY THIS LINE # EXISTS
30 END
100 PRINT "AT LINE 100":END
200 PRINT "AT LINE 200":END
300 PRINT "AT LINE 300":END

B-109
FILTER
Token: $FE $03
Format: FILTER sid [{, freq, lp, bp, hp, res}]
Usage: Sets the parameters for a SID sound filter.
sid 1: right SID, 2: left SID
freq filter cut off frequency (0 - 2047)
lp low pass filter (0: off, 1: on)
bp band pass filter (0: off, 1: on)
hp high pass filter (0: off, 1: on)
resonance resonance (0 - 15)
Remarks: Missing parameters keep their current value. The effective filter is the
sum of of all filter settings. This enables band reject and notch effects.
Example: Using FILTER

10 PLAY "T7X1O3P9C"
15 SLEEP 0.02
20 PRINT "LOW PASS SWEEP" :L=1:B=0:H=0:GOSUB 100
30 PRINT "BAND PASS SWEEP":L=0:B=1:H=0:GOSUB 100
40 PRINT "HIGH PASS SWEEP":L=0:B=0:H=1:GOSUB 100
50 GOTO 20
100 REM *** SWEEP ***
110 FOR F = 50 TO 1950 STEP 50
120 IF F >= 1000 THEN FF = 2000-F : ELSE FF = F
130 FILTER 1,FF,L,B,H,15
140 PLAY "X1"
150 SLEEP 0.02
160 NEXT F
170 RETURN

B-110
FIND
Token: $FE $2B
Format: FIND /string/ [, line range]
FIND ”string” [, line range]
Usage: Searches the BASIC program that is currently in memory for all instances
of a string.
It searches a given line range (if specified), otherwise the entire BASIC
program is searched.
At each occurrence of the ”find string” the line is listed with the string
highlighted.
NO
SCROLL can be used to pause the output.
Remarks: Almost any character that is not part of the string, including letters and
punctuation, can be used instead of the slash /.
Using double quotes ” as a delimiter has a special effect: The search
text is not tokenised. FIND ”FOR” will search for the three letters F, O,
and R, not the BASIC keyword FOR. Therefore, it can find the word FOR
in string constants or REM statements, but not in program code.
On the other hand, FIND /FOR/ will find all occurrences of the BASIC
keyword, but not the text ”FOR” in strings.
Partial keywords cannot be searched. For example, FIND /LOO/ will not
find the keyword LOOP.
Due to how BASIC is parsed, finding the REM and DATA keywords requires
using the colon as the delimiter: FIND :REM TODO: This does not work
with the CHANGE command.
FIND is an editor command that can only be used in direct mode.
Example: Using FIND

B-111
B-112
FN
Token: $A5
Format: FN name(numeric expression)
Usage: FN functions are user-defined functions, that accept a numeric expres-
sion as an argument and return a real value. They must first be defined
with DEF FN before being used.
Example: Using FN

10 PD = ~ / 180
20 DEF FN CD(X)= COS(X*PD): REM COS FOR DEGREES
30 DEF FN SD(X)= SIN(X*PD): REM SIN FOR DEGREES
40 FOR D=0 TO 360 STEP 90
50 PRINT USING "###";D
60 PRINT USING " ##.##";FNCD(D);
70 PRINT USING " ##.##";FNSD(D)
80 NEXT D
RUN
0 1.00 0.00
90 0.00 1.00
180 -1.00 0.00
270 0.00 -1.00
360 1.00 0.00

B-113
FONT
Token: $FE $46
Format: FONT <A | B | C>
Usage: Updates all characters to the given built-in font.
FONT A is the PETSCII font with several lowercase characters replaced
with ASCII punctuation.
FONT B is an alternate appearance of FONT A.
FONT C is the PETSCII font. This is the default when the MEGA65 is first
switched on.
This resets any changes made by the CHARDEF command.
The ASCII symbols of fonts A and B are typed by pressing the keys in
the table below, some of which also require the holding down of the
` key. The codes for uppercase and lowercase are swapped com-
pared to ASCII.
Code Key PETSCII ASCII
$5C Pound \ \ (backslash)
$5E Up Arrow (next to RESTORE) ^ ^ (caret)
$5F Left Arrow (next to 1) _ _ (underscore)
$7B MEGA + Colon ě { (open brace)
$7C MEGA + Dot Ĝ | (pipe)
$7D MEGA + Semicolon ĝ } (close brace)
$7E MEGA + Comma ~ ~ (tilde)
Remarks: The additional ASCII characters provided by FONT A and B are only avail-
able while using the lowercase character set.
Examples: Using FONT

FONT A :REM ASCII - ENABLE {|}_~^


FONT B :REM LIKE A, WITH A SERIF FONT
FONT C :REM COMMODORE FONT (DEFAULT)

B-114
FOR
Token: $81
Format: FOR index = start TO end [STEP step] ... NEXT [index]
Usage: FOR statements start a BASIC loop with an index variable.
index may be incremented or decremented by a constant value on each
iteration. The default is to increment the variable by 1. The index variable
must be a real variable.
start is used to initialise the index.
end is checked at the end of an iteration, and determines whether an-
other iteration will be performed, or if the loop will exit.
step defines the change applied to to the index variable at the end of an
iteration. Positive step values increment it, while negative values decre-
ment it. It defaults to 1.0 if not specified.
Remarks: For positive increments end must be greater than or equal to start,
whereas for negative increments end must be less than or equal to start.
It is bad programming practice to change the value of the index variable
inside the loop or to jump into or out of a loop body with GOTO.
Examples: Using FOR

10 FOR D=0 TO 360 STEP 30


20 R = D * ~ / 180
30 PRINT D;R;SIN(R);COS(R);TAN(R)
40 NEXT D

10 DIM M(20,20)
20 FOR I=0 TO 20
30 FOR J=I TO 20
40 M(I,J) = I + 100 * J
50 NEXT J,I

B-115
FOREGROUND
Token: $FE $39
Format: FOREGROUND colour
Usage: Sets the foreground text colour for subsequent PRINT commands.
colour the palette entry number, in the range 0 – 31
See appendix G on page G-3 for the list of colours in the default system
palette.
Remarks: This is another name for COLOR.
Example: Using FOREGROUND

B-116
FORMAT
Token: $FE $37
Format: FORMAT diskname [,I id] [,D drive] [,U unit]
Usage: Formats a disk. This erases all data on the disk.
I The disk ID.
diskname is either a quoted string, e.g. "DATA" or a string expression in
brackets, e.g. (DN$). The maximum length of diskname is 16 characters.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: FORMAT is another name for the HEADER command.
For new floppy disks which have not already been formatted in MEGA65
(1581) format, it is necessary to specify the disk ID with the I parame-
ter. This switches the format command to low level format, which writes
sector IDs and erases all contents. This takes some time, as every block
on the floppy disk will be written.
If the I parameter is omitted, a quick format will be performed. This is
only possible if the disk has already been formatted as a MEGA65 or
1581 floppy disk. A quick format writes the new disk name and clears
the block allocation map, marking all blocks as free. The disk ID is not
changed, and blocks are not overwritten, so contents may be recovered
with ERASE R. You can read more about ERASE on page B-103.
Examples: Using FORMAT

FORMAT "ADVENTURE",IDK : FORMAT DISK WITH NAME ADVENTURE AND ID DK


FORMAT "ZORK-I",U9 : FORMAT DISK IN UNIT 9 WITH NAME ZORK-I
FORMAT "DUNGEON",D1,U10: FORMAT DISK IN DRIVE 1 UNIT 10 WITH NAME DUNGEON

B-117
FRE
Token: $B8
Format: FRE(bank)
Returns: The number of free bytes for banks 0 or 1, or the ROM version if the
argument is negative.
FRE(0) returns the number of free bytes in bank 0, which is used for BASIC
program source.
FRE(1) returns the number of free bytes in bank 1, which is the bank for
BASIC variables, arrays and strings. FRE(1) also triggers “garbage col-
lection”, which is a process that collects strings in use at the top of the
bank, thereby defragmenting string memory.
FRE(-1) returns the ROM version, a six-digit number of the form 92XXXX.
Example: Using FRE:

10 PM = FRE(0)
20 VM = FRE(1)
30 RV = FRE(-1)
40 PRINT PM;" FREE FOR PROGRAM"
50 PRINT VM;" FREE FOR VARIABLES"
60 PRINT RV;" ROM VERSION"

B-118
FREAD
Token: $FE $1C
Format: FREAD# channel, pointer, size
Usage: Reads size bytes from channel to memory starting at the 32-bit address
pointer.
channel number, which was given to a previous call to commands such
as DOPEN, or OPEN
FREAD can be used to read data from disk directly into a variable. It is
recommended to use the POINTER statement for the pointer argument,
and to compute the size parameter by multiplying the number of ele-
ments with the item size.
Type Item Size
Byte Array 1
Integer Array 2
Real Array 5
Keep in mind that the POINTER function with a string argument does not
return the string address, but the string descriptor. It is not recommended
to use FREAD for strings or string arrays unless you are fully aware on how
to handle the string storage internals.
To read into an array, ensure that you always specify an array index so
that POINTER returns the address of an element. The start address of
array XY() is POINTER(XY(0)). POINTER(XY) returns the address of the scalar variable
XY.
Example: Using FREAD:

100 N=23
110 DIM B&(N),C&(N)
120 DOPEN#2,"TEXT"
130 FREAD#2,POINTER(B&(0)),N
140 DCLOSE#2
150 FORI=0TON-1:PRINTCHR$(B&(I));:NEXT
160 FORI=0TON-1:C&(I)=B&(N-1-I):NEXT
170 DOPEN#2,"REVERS",W
180 FWRITE#2,POINTER(C&(0)),N
190 DCLOSE#2

B-119
FREEZER
Token: $FE $4A
Format: FREEZER
Usage: Invokes the Freezer menu.
Remarks: Entering the FREEZER command is an alternative to holding and releasing
RESTORE
the key.
Examples: Using FREEZER

FREEZER :REM CALL FREEZER MENU

B-120
FWRITE
Token: $FE $1E
Format: FWRITE# channel, pointer, size
Usage: Writes size bytes to channel from memory starting at the 32-bit address
pointer.
channel number, which was given to a previous call to commands such
as APPEND, DOPEN, or OPEN.
FWRITE can be used to write the value of a variable to a file. It is rec-
ommended to use the POINTER statement for the pointer argument and
compute the size parameter by multiplying the number of elements with
the item size.
Refer to the FREAD item size table on page B-119 for the item sizes.
Keep in mind that the POINTER function with a string argument does not
return the string address, but the string descriptor. It is not recommended
to use FWRITE for strings or string arrays unless you are fully aware on
how to handle the string storage internals.
To write an array, ensure that you always specify an array index so that
POINTER returns the address of an element. The start address of array
XY() is POINTER(XY(0)). POINTER(XY) returns the address of the scalar variable XY.
Example: Using FWRITE:

100 N=23
110 DIM B&(N),C&(N)
120 DOPEN#2,"TEXT"
130 FREAD#2,POINTER(B&(0)),N
140 DCLOSE#2
150 FORI=0TON-1:PRINTCHR$(B&(I));:NEXT
160 FORI=0TON-1:C&(I)=B&(N-1-I):NEXT
170 DOPEN#2,"REVERS",W
180 FWRITE#2,POINTER(C&(0)),N
190 DCLOSE#2

B-121
GCOPY
Token: $FE $32
Format: GCOPY x, y, width, height
Usage: Bitmap graphics: copies the content of the specified rectangle with up-
per left position x, y and the width and height to a buffer.
The copied region can be inserted at any position with the command
PASTE.
Remarks: The size of the rectangle is limited by the 1K size of the buffer. The
memory requirement for a region is width * height * number of bitplanes
/ 8. It must not equal or exceed 1024 byte. For a 4-bitplane screen for
example, a 45 x 45 region needs 1012.5 byte.
Example: Using GCOPY (see also CUT).

10 SCREEN 320,200,2
20 BOX 60,60,300,180,1 :REM DRAW A WHITE BOX
30 GCOPY 140,80,40,40 :REM COPY A 40 * 40 REGION
40 PASTE 10,10,40,40 :REM PASTE IT TO NEW POSITION
50 GETKEY A$ :REM WAIT FOR KEYPRESS
60 SCREEN CLOSE

B-122
GET
Token: $A1
Format: GET variable
Usage: Gets the next character, or byte value of the next character, from the
keyboard queue.
If the variable being set to the character is of type string and the queue is
empty, an empty string is assigned to it, otherwise a one character string
is created and assigned instead. If the variable is of type numeric, the
byte value of the key is assigned to it, otherwise zero will be assigned if
the queue is empty. GET does not wait for keyboard input, so it’s useful
to check for key presses at regular intervals or in loops.
Remarks: GETKEY is similar, but waits until a key has been pressed.
Example: Using GET:

10 DO: GET A$: LOOP UNTIL A$ <> ""


40 IF A$ = "W" THEN 1000 :REM GO NORTH
50 IF A$ = "A" THEN 2000 :REM GO WEST
60 IF A$ = "S" THEN 3000 :REM GO EAST
70 IF A$ = "Z" THEN 4000 :REM GO SOUTH
80 IF A$ = CHR$(13) THEN 5000 :REM RETURN
90 GOTO 10

B-123
GET#
Token: $A1 ’#’
Format: GET# channel, variable [, variable …]
Usage: Reads a single byte from the channel argument and assigns single char-
acter strings to string variables, or an 8-bit binary value to numeric vari-
ables.
This is useful for reading characters (or bytes) from an input stream one
byte at a time.
channel number, which was given to a previous call to commands such
as DOPEN, or OPEN.
Remarks: All values from 0 to 255 are valid, so GET# can also be used to read
binary data.
Example: Using GET# to read a disk directory:

1 REM GET#
10 OPEN 2,8,0,"$" : REM OPEN CATALOG
15 IF DS THEN PRINT DS$: STOP: REM CANT READ
20 GET#2,D$,D$ : REM DISCARD LOAD ADDRESS
25 DO : REM LINE LOOP
30 GET#2,D$,D$ : REM DISCARD LINE LINK
35 IF ST THEN EXIT : REM END-OF-FILE
40 GET#2,LO,HI : REM FILE SIZE BYTES
45 S=LO + 256 * HI : REM FILE SIZE
50 LINE INPUT#2, F$ : REM FILE NAME
55 PRINT S;F$ : REM PRINT FILE ENTRY
60 LOOP
65 CLOSE 2

B-124
GETKEY
Token: $A1 $F9 (GET token and KEY token)
Format: GETKEY variable
Usage: Gets the next character, or byte value of the next character, from the
keyboard queue. If the queue is empty, the program will wait until a key
has been pressed.
After a key has been pressed, the variable will be set and program exe-
cution will continue. When used with a string variable, a one character
string is created and assigned. Otherwise if the variable is of type nu-
meric, the byte value is assigned.
Example: Using GETKEY:

10 GETKEY A$ :REM WAIT AND GET CHARACTER


40 IF A$ = "W" THEN 1000 :REM GO NORTH
50 IF A$ = "A" THEN 2000 :REM GO WEST
60 IF A$ = "S" THEN 3000 :REM GO EAST
70 IF A$ = "Z" THEN 4000 :REM GO SOUTH
80 IF A$ = CHR$(13) THEN 5000 :REM RETURN
90 GOTO 10

B-125
GO64
Token: $CB $36 $34 (GO token and 64 )
Format: GO64
Usage: Switches the MEGA65 to C64-compatible mode.
If you’re in direct mode, a security prompt ARE YOU SURE? is displayed, which
must be responded with Y to continue.
You can switch back to MEGA65 mode with this command: SYS58552
Example: Using GO64:

GO64
ARE YOU SURE?

B-126
GOSUB
Token: $8D
Format: GOSUB line
Usage: GOSUB (GOto SUBroutine) continues program execution at the given
BASIC line number, saving the current BASIC program counter and line
number on the run-time stack. This enables the resumption of execution
after the GOSUB statement, once a RETURN statement in the called sub-
routine is executed. Calls to subroutines via GOSUB may be nested, but
the subroutines must always end with RETURN, otherwise a stack over-
flow may occur.
Remarks: Unlike other programming languages, BASIC 65 does not support argu-
ments or local variables for subroutines.
Programs can be optimised by grouping subroutines at the beginning of
the program source. The GOSUB calls will then have low line numbers
with fewer digits to decode. The subroutines will also be found faster,
since the search for subroutines often starts at the beginning of the pro-
gram.
Example: Using GOSUB:

10 GOTO 100 :REM TO MAIN PROGRAM


20 REM *** SUBROUTINE DISK STATUS CHECK ***
30 DD=DS:IF DD THEN PRINT "DISK ERROR";DS$
40 RETURN
50 REM *** SUBROUTINE PROMPT Y/N ***
60 DO:INPUT "CONTINUE (Y/N)";A$
70 LOOP UNTIL A$="Y" OR A$="N"
80 RETURN
90 REM *** MAIN PROGRAM ***
100 DOPEN#2,"BIG DATA"
110 GOSUB 30: IF DD THEN DCLOSE#2:GOSUB 60:REM ASK
120 IF A$="N" THEN STOP
130 GOTO 100: REM RETRY

B-127
GOTO
Token: $89 (GOTO) or $CB $A4 (GO TO)
Format: GOTO line
GO TO line
Usage: Continues program execution at the given BASIC line number.
Remarks: If the target line number is higher than the current line number, the search
starts from the current line, proceeding to higher line numbers. If the
target line number is lower, the search starts at the first line number of
the program. It is possible to optimise the run-time speed of the program
by grouping often used targets at the start (with lower line numbers).
GOTO (written as a single word) executes faster than GO TO.
Example: Using GOTO:

10 GOTO 100 :REM TO MAIN PROGRAM


20 REM *** SUBROUTINE DISK STATUS CHECK ***
30 DD=DS:IF DD THEN PRINT "DISK ERROR";DS$
40 RETURN
50 REM *** SUBROUTINE PROMPT Y/N ***
60 DO:INPUT "CONTINUE (Y/N)";A$
70 LOOP UNTIL A$="Y" OR A$="N"
80 RETURN
90 *** MAIN PROGRAM ***
100 DOPEN#2,"BIG DATA"
110 GOSUB 30: IF DD THEN DCLOSE#2:GOSUB 60:REM ASK
120 IF A$="N" THEN STOP
130 GOTO 100: REM RETRY

B-128
GRAPHIC
Token: $DE
Format: GRAPHIC CLR
Usage: Bitmap graphics: initialises the BASIC bitmap graphics system. It clears
the graphics memory and screen, and sets all parameters of the graphics
context to their default values.
Once the graphics system has been cleared, commands such as LINE,
PALETTE, PEN, SCNCLR, and SCREEN can be used to set graphics system
parameters.
Example: Using GRAPHIC:

100 REM GRAPHIC


110 GRAPHIC CLR : REM INITIALISE
120 SCREEN DEF 1,1,1,2 : REM 640 X 400 X 2
130 SCREEN OPEN 1 : REM OPEN IT
140 SCREEN SET 1,1 : REM VIEW IT
150 PALETTE 1,0,0, 0,0 : REM BLACK
160 PALETTE 1,1,0,15,0 : REM GREEN
170 SCNCLR 0 : REM FILL SCREEN WITH BLACK
180 PEN 0,1 : REM SELECT PEN
190 LINE 50,50,590,350 : REM DRAW LINE
200 GETKEY A$ : REM WAIT FOR KEYPRESS
210 SCREEN CLOSE 1 : REM CLOSE SCREEN AND RESTORE PALETTE

B-129
HEADER
Token: $F1
Format: HEADER diskname [,I id] [,D drive] [,U unit]
Usage: Formats a disk. This erases all data on the disk.
I The disk ID.
diskname is either a quoted string, e.g. "DATA" or a string expression in
brackets, e.g. (DN$). The maximum length of diskname is 16 characters.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: HEADER is another name for the FORMAT command.
For new floppy disks which have not already been formatted in MEGA65
(1581) format, it is necessary to specify the disk ID with the I parame-
ter. This switches the format command to low level format, which writes
sector IDs and erases all contents. This takes some time, as every block
on the floppy disk will be written.
If the I parameter is omitted, a quick format will be performed. This is
only possible if the disk has already been formatted as a MEGA65 or
1581 floppy disk. A quick format writes the new disk name and clears
the block allocation map, marking all blocks as free. The disk ID is not
changed, and blocks are not overwritten, so contents may be recovered
with ERASE R. You can read more about ERASE on page B-103.
Examples: Using HEADER

HEADER "ADVENTURE",IDK : FORMAT DISK WITH NAME ADVENTURE AND ID DK


HEADER "ZORK-I",U9 : FORMAT DISK IN UNIT 9 WITH NAME ZORK-I
HEADER "DUNGEON",D1,U10: FORMAT DISK IN DRIVE 1 UNIT 10 WITH NAME DUNGEON

B-130
HELP
Token: $EA
Format: HELP
Usage: Displays information about where an error occurred in a BASIC program.
When the BASIC program stops due to an error, HELP can be used to
gain further information. The interpreted line is listed, with the erroneous
statement highlighted or underlined.
Remarks: Displays BASIC errors. For errors related to disk I/O, the disk status vari-
able DS or the disk status string DS$ should be used instead.
Example: Using HELP

10 A=1.E20
20 B=A+A:C=EXP(A):PRINT A,B,C
RUN

?OVERFLOW ERROR IN 20
READY.
HELP

20 B=A+A:ţŝťŸŰňšʼn:PRINT A,B,C

B-131
HEX$
Token: $D2
Format: HEX$(numeric expression)
Returns: A four character hexadecimal representation of the argument.
The argument must be in the range of 0 – 65535, corresponding to the
hex numbers $0000-$FFFF.
Remarks: If real numbers are used as arguments, the fractional part will be ignored.
In other words, real numbers will not be rounded.
Example: Using HEX$:

PRINT HEX$(10),HEX$(100),HEX$(1000.9)
000A 0064 03E8

B-132
HIGHLIGHT
Token: $FE $3D
Format: HIGHLIGHT colour [, mode]
Usage: Sets the colours used for code highlighting.
Different colours can be set for system messages, REM statements and
BASIC 65 keywords.
colour is one of the first 16 colours in the current palette. See appendix
G on page G-3 for the list of colours in the default system palette.
mode indicates what the colour will be used for.
• 0 system messages (the default mode)
• 1 REM statements
• 2 BASIC keywords
Remarks: The system messages colour is used when displaying error messages, and
in the output of CHANGE, FIND, and HELP. The colours for REM state-
ments and BASIC keywords are used by LIST.
Example: Using HIGHLIGHT to change the colour of BASIC keywords to red.

B-133
IF
Token: $8B
Format: IF expression THEN true clause [ELSE false clause]
Usage: Starts a conditional execution statement.
expression a logical or numeric expression. A numeric expression is
evaluated as FALSE if the value is zero and TRUE for any non-zero value.
true clause one or more statements starting directly after THEN on the
same line. A line number after THEN performs a GOTO to that line in-
stead.
false clause one or more statements starting directly after ELSE on the
same line. A linenumber after ELSE performs a GOTO to that line instead.
Remarks: The standard IF ... THEN ... ELSE structure is restricted to a single line.
But the true clause and false clause may be expanded to several lines
using a compound statement surrounded with BEGIN and BEND.
Example: Using IF

1 REM IF
10 RED$=CHR$(28) : BLACK$=CHR$(144) : WHITE$=CHR$(5)
20 INPUT "ENTER A NUMBER";V
30 IF V<0 THEN PRINT RED$; : ELSE PRINT BLACK$;
40 PRINT V : REM PRINT NEGATIVE NUMBERS IN RED
50 PRINT WHITE$
60 INPUT "END PROGRAM: (Y/N)"; A$
70 IF A$="Y" THEN END
80 IF A$="N" THEN 20 : ELSE 60

B-134
IMPORT
Token: $DD
Format: IMPORT filename [,D drive] [,U unit]
Usage: Loads BASIC code in text format from a file of type SEQ into memory
reserved for BASIC programs.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: The program is loaded into BASIC memory and converted from text to
the tokenised form of PRG files. This enables loading of BASIC programs
that were saved as plain text files as program listing.
After loading, the program is re-linked and ready to be RUN or edited. It
is possible to use IMPORT for merging a program text file from disk to a
program already in memory. Each line read from the file is processed in
the same way, as if typed from the user with the screen editor.
There is no EXPORT counterpart, because this function is already avail-
able. The sequence DOPEN#1,"LISTING",W:CMD 1:LIST:DCLOSE#1 converts the program
in memory to text and writes it to the file, that is named in the DOPEN
statement.
Examples: Using IMPORT

IMPORT "APOCALYPSE"
IMPORT "MEGA TOOLS",U9
IMPORT (FI$),U(UN%)

B-135
INFO
Token: $FE $4D
Format: INFO
Usage: Displays information about the runtime environment.
Remarks: The INFO command displays information about the BASIC runtime envi-
ronment, including:
• The video mode (PAL, NTSC)
• The version of the ROM
• The CPU speed
• The current MEM setting
• Memory used and memory available for program text and variables
Examples: Using INFO

INFO

B-136
INPUT
Token: $85
Format: INPUT [prompt <, | ;>] variable [, variable ...]
Usage: Prompts the user for keyboard input, printing an optional prompt string
and question mark to the screen.
prompt optional string expression to be printed as the prompt
If the separator between prompt and variable list is a comma, the cur-
sor is placed directly after the prompt. If the separator is a semicolon, a
question mark and a space is added to the prompt instead.
variable list list of one or more variables that receive the input
RETURN
The input will be processed after the user presses .
Remarks: The user must take care to enter the correct type of input, so it matches
the variable list types. Also, the number of input items must match the
number of variables. A surplus of input items will be ignored, whereas
too few input items trigger another request for input with the prompt ??.
Typing non numeric characters for integer or real variables will produce a
TYPE MISMATCH ERROR. Strings for string variables must be in double quotes (”) if
they contain spaces or commas. Many programs that need a safe input
routine use LINE INPUT and a custom parser, in order to avoid program
errors by wrong user input.
Example: Using INPUT:

10 DIM N$(100),A%(100),S$(100):
20 DO
30 INPUT "NAME, AGE, GENDER";NA$,AG%,SE$
40 IF NA$="" THEN 30
50 IF NA$="END" THEN EXIT
60 IF AG% < 18 OR AG% > 100 THEN PRINT "AGE?":GOTO 30
70 IF SE$ <> "M" AND SE$ <> "F" THEN PRINT "GENDER?":GOTO 30
80 REM CHECK OK: ENTER INTO ARRAY
90 N$(N)=NA$:A%(N)=AG%:S$(N)=SE$:N=N+1
100 LOOP UNTIL N=100
110 PRINT "RECEIVED";N;" NAMES"

B-137
INPUT#
Token: $84
Format: INPUT# channel, variable [, variable ...]
Usage: Reads a record from an input device, e.g. a disk file, and assigns the
data to the variables in the list.
channel number, which was given to a previous call to commands such
as DOPEN, or OPEN.
variable list list of one or more variables, that receive the input.
The input record must be terminated by a RETURN character and must
be not longer than the input buffer (160 characters).
Remarks: The type and number of data in a record must match the variable list.
Reading non numeric characters for integer or real variables will produce
a FILE DATA ERROR. Strings for string variables have to be put in quotes if they
contain spaces or commas.
LINE INPUT# may be used to read a whole record into a single string
variable.
Sequential files, that can be read by INPUT# can be generated by pro-
grams with PRINT# or with the editor of the MEGA65. For example:

EDIT ON

10 "CHUCK PEDDLE",1937,"ENGINEER OF THE 6502"


20 "JACK TRAMIEL",1928,"FOUNDER OF CBM"
30 "BILL MENSCH",1945,"HARDWARE"

DSAVE "CBM-PEOPLE"
EDIT OFF

Example: Using INPUT#:

B-138
10 DIM N$(100),B%(100),S$(100):
20 DOPEN#2,"CBM-PEOPLE":REM OPEN SEQ FILE
25 IF DS THEN PRINT DS$:STOP:REM OPEN ERROR
30 FOR I=0 TO 100
40 INPUT#2,N$(I),B%(I),S$(I)
50 IF ST AND 64 THEN 80:REM END OF FILE
60 IF DS THEN PRINT DS$:GOTO 80:REM DISK ERROR
70 NEXT I
80 DCLOSE#2
110 PRINT "READ";I+1;" RECORDS"
120 FOR J=0 TO I:PRINT N$(J):NEXT J

RUN
READ 3 RECORDS
CHUCK PEDDLE
JACK TRAMIEL
BILL MENSCH

TYPE "CBM-PEOPLE"
"CHUCK PEDDLE",1937,"ENGINEER OF THE 6502"
"JACK TRAMIEL",1928,"FOUNDER OF CBM"
"BILL MENSCH",1945,"HARDWARE"

B-139
INSTR
Token: $D4
Format: INSTR(haystack, needle [, start])
Usage: Locates the position of the string expression needle in the string expres-
sion haystack, and returns the index of the first occurrence, or zero if
there is no match.
The string expression haystack is searched for the occurrence of the
string expression needle.
An enhanced version of string search using pattern matching is used if
the first character of the search string is a pound sign ’£’. The pound sign
is not part of the search but enables the use of the ’.’ (dot) as a wildcard
character, which matches any character. The second special pattern
character is the ’*’ (asterisk) character. The asterisk in the search string
indicates that the preceding character may never appear, appear once,
or repeatedly in order to be considered as a match.
The optional argument start is an integer expression, which defines the
starting position for the search in haystack. If not present, it defaults to
one.
Remarks: If either string is empty or there is no match the function returns zero.
Examples: Using INSTR:

I = INSTR("ABCDEF","CD") : REM I = 3
I = INSTR("ABCDEF","XY") : REM I = 0
I = INSTR("RAIIIN","\A*IN") : REM I = 5
I = INSTR("ABCDEF","\C.E") : REM I = 3
I = INSTR(A$+B$,C$)

B-140
INT
Token: $B5
Format: INT(numeric expression)
Returns: The integer part of a number.
This function is NOT limited to the typical 16-bit integer range (-32768
to 32767), as it uses real arithmetic. The allowed range is therefore
determined by the size of the real mantissa which is 32-bits wide (-
2147483648 to 2147483647).
Remarks: It is not necessary to use the INT function for assigning real values to
integer variables, as this conversion will be done implicitly, but only for
the 16-bit range.
Examples: Using INT:

X = INT(1.9) :REM X=1


X = INT(-3.1) :REM X = -3
X = INT(100000.5) :REM X = 100000
N% = INT(100000.5) :REM ?ILLEGAL QUANTITY ERROR

B-141
JOY
Token: $CF
Format: JOY(port)
Returns: The state of the joystick for the selected controller port (1 or 2).
Bit 7 contains the state of the fire button. The stick can be moved in eight
directions, which are numbered clockwise starting at the upper position.
Left Centre Right
Up 8 1 2
Centre 7 0 3
Down 6 5 4
Example: Using JOY:

10 N = JOY(1)
20 IF N AND 128 THEN PRINT "FIRE! ";
30 REM N NE E SE S SW W NW
40 ON N AND 15 GOSUB 100,200,300,400,500,600,700,800
50 GOTO 10
100 PRINT "GO NORTH" :RETURN
200 PRINT "GO NORTHEAST":RETURN
300 PRINT "GO EAST" :RETURN
400 PRINT "GO SOUTHEAST":RETURN
500 PRINT "GO SOUTH" :RETURN
600 PRINT "GO SOUTHWEST":RETURN
700 PRINT "GO WEST" :RETURN
800 PRINT "GO NORTHWEST":RETURN

B-142
KEY
Token: $F9
Format: KEY
KEY <ON | OFF>
KEY <LOAD | SAVE> filename
KEY number, string
Usage: Manages the function key macros in the BASIC editor.
Each function key can be assigned a string that is typed when pressed.
The function keys have default assignments on boot, and can be changed
by the KEY command.
KEY : list current assignments.
KEY ON : switch on function key strings. The keys will send assigned
strings if pressed.
KEY OFF : switch off function key strings. The keys will send their char-
acter code if pressed.
KEY LOAD filename : loads key definitions from file.
KEY SAVE filename : saves key definitions to file.
KEY number, string : assigns the string to the key with the given number.
number can be any value within this range:

• 1 - 14: corresponds to keys ranging from F1 to F14


HELP
• 15: corresponds to
SHIFT RUN
• 16: corresponds to STOP

Default assignments:

B-143
KEY
KEY 1,CHR$(27)+"X"
KEY 2,CHR$(27)+"@"
KEY 3,"DIR"+CHR$(13)
KEY 4,"DIR "+CHR$(34)+"*=PRG"+CHR$(34)+CHR$(13)
KEY 5,"ŵ"
KEY 6,"KEY6"+CHR$(141)
KEY 7,"ŷ"
KEY 8,"MONITOR"+CHR$(13)
KEY 9,"Ű"
KEY 10,"KEY10"+CHR$(141)
KEY 11,"Ŷ"
KEY 12,"KEY12"+CHR$(141)
KEY 13,CHR$(27)+"O"
KEY 14,"Ŵ"+CHR$(27)+"O"
KEY 15,"HELP"+CHR$(13)
KEY 16,"RUN "+CHR$(34)+"*"+CHR$(34)+CHR$(13)

Remarks: The sum of the lengths of all assigned strings must not exceed 240 char-
acters. Special characters such as RETURN or QUOTE are entered using
their codes with the CHR$ function. Refer to CHR$ on page B-48 for
more information.
Examples: Using KEY:

KEY ON :REM ENABLE FUNCTION KEYS


KEY OFF :REM DISABLE FUNCTION KEYS
KEY :REM LIST ASSIGNMENTS
KEY 2,"PRINT ~"+CHR$(14) :REM ASSIGN PRINT PI TO F2
KEY SAVE "MY KEY SET" :REM SAVE CURRENT DEFINITIONS TO FILE
KEY LOAD "ELEVEN-SET" :REM LOAD DEFINITIONS FROM FILE

B-144
LEFT$
Token: $C8
Format: LEFT$(string, n)
Returns: A string containing the first n characters from the argument string.
If the length of string is equal to or less than n, the resulting string will
be identical to the argument string.
string a string expression
n a numeric expression (0 – 255)
Remarks: Empty strings and zero length strings are legal values.
Example: Using LEFT$:

PRINT LEFT$("MEGA-65",4)
MEGA

B-145
LEN
Token: $C3
Format: LEN(string)
Returns: The length of a string.
string a string expression
Remarks: Commodore BASIC strings can contain any character, including the null
character. Internally, the length of a string is stored in a string descriptor.
Example: Using LEN:

PRINT LEN("MEGA-65"+CHR$(13))
8

B-146
LET
Token: $88
Format: [LET] variable = expression
Usage: Assigns values (or results of expressions) to variables.
Remarks: The LET statement is obsolete and not required. Assignment to variables
can be done without using LET, but it has been left in BASIC 65 for back-
wards compatibility.
Examples: Using LET:

LET A=5 :REM LONGER AND SLOWER


A=5 :REM SHORTER AND FASTER

B-147
LINE
Token: $E5
Format: LINE xbeg, ybeg [, xnext1, ynext1 ...]
Usage: Bitmap graphics: draws a line or series of lines.
If only one coordinate pair is given, LINE draws a dot.
If more than one pair is defined, a line is drawn on the current graphics
screen from the coordinate (xbeg/ybeg) to the next coordinate pair(s).
All currently defined modes and values of the graphics context are used.
Example: Using LINE:

1 REM SCREEN EXAMPLE 1


10 SCREEN 320,200,2 :REM SCREEN #0 320 X 200 X 2
20 PEN 1 :REM DRAWING PEN COLOUR 1 (WHITE)
30 LINE 25,25,295,175 :REM DRAW LINE
40 GETKEY A$ :REM WAIT FOR KEYPRESS
50 SCREEN CLOSE :REM CLOSE SCREEN AND RESTORE PALETTE

B-148
LINE INPUT
Token: $E5 $85
Format: LINE INPUT [prompt <, | ;>] string variable [, string variable ...]
Usage: Prompts the user for keyboard input, printing an optional prompt string
and question mark to the screen.
prompt optional string expression to be printed as the prompt
If the separator between prompt and the first string variable is a
comma, the cursor is placed directly after the prompt. If the separa-
tor is a semicolon, a question mark and a space is added to the prompt
instead.
string variable one or more string variables that accept one line of input
each
Remarks: This differs from INPUT in how the input is parsed. LINE INPUT accepts
RETURN
every character entered on a line as a single string value. Only the
key does not produce a character.
If the variable list has more than one variable, LINE INPUT will use the
entire first line for the first variable, and present the ?? prompt for each
subsequent variable.
LINE INPUT only works with string variables. If a non-string variable is
used, LINE INPUT throws produces a TYPE MISMATCH ERROR after data has been
entered.
Example: Using LINE INPUT:

10 LINE INPUT "ENTER A PHRASE: ",PH$


20 PRINT "THE PHRASE YOU ENTERED:";CHR$(13);" ";PH$
RUN
ENTER A PHRASE: YOU SAY "POTATO," I SAY "POTATO."
THE PHRASE YOU ENTERED:
YOU SAY "POTATO," I SAY "POTATO."

B-149
LINE INPUT#
Token: $E5 $84
Format: LINE INPUT# channel, variable [, variable ...]
Usage: Reads one record per variable from an input device, (such as a disk drive)
and assigns the read data to the variable.
The records must be terminated by a RETURN character, which will not
be copied to the string variable. Therefore, an empty line consisting of
only the RETURN character will result in an empty string being assigned.
channel number, which was given to a previous call to commands such
as DOPEN, or OPEN.
variable list list of one or more variables, that receive the input.
Remarks: Only string variables or string array elements can be used in the variable
list. Unlike other INPUT commands, LINE INPUT# does not interpret or
remove quote characters in the input. They are accepted as data, as all
other characters.
Records must not be longer than the input buffer, which is 160 charac-
ters.
Example: Using LINE INPUT#:

10 DIM N$(100)
20 DOPEN#2,"DATA"
30 FOR I=0 TO 100
40 LINE INPUT#2,N$(I)
50 IF ST=64 THEN 80:REM END OF FILE
60 IF DS THEN PRINT DS$:GOTO 80:REM DISK ERROR
70 NEXT I
80 DCLOSE#2
110 PRINT "READ";I;" RECORDS"

B-150
LIST
Token: $9B
Format: LIST [P] [line range]
Usage: Lists a range of lines from the BASIC program in memory.
Given a single line number, LIST lists that line.
Given a range of line numbers, LIST lists all lines in that range. A range
can be two numbers separated by a hyphen (-), or it can omit the begin-
ning or end of the range to imply the beginning or end of the program.
(See examples below.)
Format: LIST [P] filename [,U unit]
Usage: Lists a range of lines from a BASIC program directly from a file.
Remarks: The optional parameter P enables page mode. After listing a screenful
of lines, the listing will stop and display the prompt [MORE] at the bottom of
the screen. Pressing Q quits page mode, while any other key continues
to the next page.
LIST output can be redirected to other devices via CMD.
Another way to display a program listing from memory on the screen is to
use the keys F9 and F11 , or Ctrl P and Ctrl V , to scroll
a BASIC listing on screen up or down.
Examples: Using LIST

LIST 100 :REM LIST LINE 100


LIST 240-350 :REM LIST ALL LINES FROM 240 TO 350
LIST 500- :REM LIST FROM 500 TO END
LIST -70 :REM LIST FROM START TO 70
LIST "DEMO" :REM LIST FILE "DEMO"
LIST P :REM LIST PROGRAM IN PAGE MODE
LIST P "MURX" :REM LIST FILE "MURX" IN PAGE MODE

B-151
LOAD
Token: $93
Format: LOAD filename [, unit [, flag]]
LOAD ”$[pattern=type]” [, unit]
LOAD ”$$[pattern=type]” [, unit]
/ filename [, unit [, flag]]
Usage: The first form loads a file of type PRG into memory reserved for BASIC
programs.
The second form loads a directory into memory, which can then be
viewed with LIST. It is structured like a BASIC program, but file sizes are
displayed instead of line numbers.
The third form is similar to the second one, but the files are numbered.
This listing can be scrolled like a BASIC program with the keys F9 or
F11 , edited, listed, saved or printed.
A filter can be applied by specifying a pattern or a pattern and a type.
The asterisk matches the rest of the name, while the ? matches any
single character. The type specifier can be a character of (P,S,U,R), that
is Program, Sequential, User, or Relative file.
A common use of the shortcut symbol / is to quickly load PRG files. To do
this:
1. Print a disk directory using either DIR, or CATALOG.
2. Move the cursor to the desired line.
RETURN
3. type / in the first column of the line, and press .
RETURN
After pressing , the listed file on the line with the leading / will be
loaded. Characters before and after the file name double quotes (”) will
be ignored. This applies to PRG files only.
filename is either a quoted string, e.g. "PROG", or a string expression.
The unit number is optional. If not present, the default disk device is
assumed.
If flag has a non-zero value, the file is loaded to the address which is
read from the first two bytes of the file. Otherwise, it is loaded to the
start of BASIC memory and the load address in the file is ignored.
Remarks: LOAD loads files of type PRG into RAM bank 0, which is also used for
BASIC program source.
LOAD ”*” can be used to load the first PRG from the given unit.

B-152
LOAD ”$” can be be used to load the list of files from the given unit.
When using LOAD ”$”, LIST can be used to print the listing to screen.
LOAD is implemented in BASIC 65 to keep it backwards compatible with
BASIC V2.
The shortcut symbol / can only be used in direct mode.
By default the C64 uses unit 1, which is assigned to datasette tape
recorders connected to the cassette port. However the MEGA65 uses
unit 8 by default, which is assigned to the internal disk drive. This means
you don’t need to add ,8 to LOAD commands that use it.
Examples: Using LOAD

LOAD "APOCALYPSE" :REM LOAD A FILE CALLED APOCALYPSE TO BASIC MEMORY


LOAD "MEGA TOOLS",9 :REM LOAD A FILE CALLED "MEGA TOOLS" FROM UNIT 9 TO BASIC MEMORY
LOAD "*",8,1 :LOAD THE FIRST FILE ON UNIT 8 TO RAM AS SPECIFIED IN THE FILE

LOAD "$" :REM LOAD WHOLE DIRECTORY - WITH FILE SIZES


LOAD "$$" :REM LOAD WHOLE DIRECTORY - SCROLLABLE
LOAD "$$X*=P" :REM DIRECTORY, WITH PRG FILES STARTING with 'X'

B-153
LOADIFF
Token: $FE $43
Format: LOADIFF filename [,D drive] [,U unit]
Usage: Bitmap graphics: loads an IFF file into graphics memory.
The IFF (Interchange File Format) is supported by many different appli-
cations and operating systems. LOADIFF assumes that files contain bit-
plane graphics which match the currently active graphics screen for res-
olution and colour depth.
Supported resolutions are:
Width Height Bitplanes Colours Memory
320 200 max. 8 max. 256 max. 64 K
640 200 max. 8 max. 256 max. 128 K
320 400 max. 8 max. 256 max. 128 K
640 400 max. 4 max. 16 max. 128 K
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: Tools are available to convert popular image formats to IFF. These tools
are available on several operating systems, such as AMIGA OS, macOS,
Linux, and Windows. For example, ImageMagick is a free graphics
package that includes a tool called convert, which can be used to cre-
ate IFF files in conjunction with the ppmtoilbm tool from the Netbpm
package.
To use convert and ppmtoilbm for converting a JPG file to an IFF file on
Linux:
convert <myImage.jpg> <myImage.ppm>
ppmtoilbm -aga <myImage.ppm> > <myImage.iff>
Example: Using LOADIFF

B-154
100 BANK128:SCNCLR
110 REM DISPLAY PICTURES IN 320 X 200 X 7 RESOLUTION
120 GRAPHIC CLR:SCREEN DEF 0,0,0,7:SCREEN OPEN 0:SCREEN SET 0,0
130 FORI=1TO7: READF$
140 LOADIFF(F$+".IFF"):SLEEP 4:NEXT
150 DATA ALIEN,BEAKER,JOKER,PICARD,PULP,TROOPER,RIPLEY
160 SCREEN CLOSE 0
170 PALETTE RESTORE

B-155
LOCK
Token: $FE $50
Format: LOCK filename/pattern [,D drive] [,U unit]
Usage: Locks a file on disk, preventing it from being updated or deleted.
The specified file or a set of files, that matches the pattern, is locked and
cannot be deleted with the commands DELETE, ERASE or SCRATCH.
The command UNLOCK removes the lock.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: In direct mode the number of locked files is printed. The second to last
number from the message contains the number of locked files,
Examples: Using LOCK

LOCK "DRM",U9 :REM LOCK FILE DRM ON UNIT 9


03,FILES LOCKED,01,00
LOCK "BS*" :REM LOCK ALL FILES BEGINNING WITH "BS"
03,FILES LOCKED,04,00

B-156
LOG
Token: $BC
Format: LOG(numeric expression)
Returns: The natural logarithm of a number.
The natural logarithm uses Euler’s number (2.71828183) as base, not
base 10 which is typically used in log functions on a pocket calculator.
Remarks: The log function with base 10 can be computed by dividing the result by
log(10). LOG10() provides this feature as a function.
Example: Using LOG

PRINT LOG(1)
0

PRINT LOG(0)
?ILLEGAL QUANTITY ERROR

PRINT LOG(4)
1.38629436

PRINT LOG(100) / LOG(10)


2

B-157
LOG10
Token: $CE $08
Format: LOG10(numeric expression)
Returns: The decimal logarithm of the argument.
The decimal logarithm uses 10 as base.
Example: Using LOG10

PRINT LOG10(1)
0

PRINT LOG10(0)
?ILLEGAL QUANTITY ERROR

PRINT LOG10(5)
0.69897

PRINT LOG10(100);LOG10(10);LOG10(1);LOG10(0.1);LOG10(0.01)
2 1 0 -1 -2

B-158
LOOP
Token: $EC
Format: DO ... LOOP
DO [<UNTIL | WHILE> logical expression]
. . . statements [EXIT]
LOOP [<UNTIL | WHILE> logical expression]
Usage: DO and LOOP define the start of a BASIC loop. Using DO and LOOP
alone without any modifiers creates an infinite loop, which can only be
exited by the EXIT statement. The loop can be controlled by adding
UNTIL or WHILE after the DO or LOOP.
Remarks: DO loops may be nested. An EXIT statement only exits the current loop.
Examples: Using DO and LOOP

10 PW$="":DO
20 GET A$:PW$=PW$+A$
30 LOOP UNTIL LEN(PW$)>7 OR A$=CHR$(13)

10 DO : REM WAIT FOR USER DECISION


20 GET A$
30 LOOP UNTIL A$="Y" OR A$="N" OR A$="y" OR A$="n"

10 DO WHILE ABS(EPS) > 0.001


20 GOSUB 2000 : REM ITERATION SUBROUTINE
30 LOOP

10 I%=0 : REM INTEGER LOOP 1-100


20 DO I%=I%+1
30 LOOP WHILE I% < 101

B-159
LPEN
Token: $CE $04
Format: LPEN(coordinate)
Returns: The state of a light pen peripheral.
This function requires the use of a CRT monitor (or TV), and a light pen. It
will not work with an LCD or LED screen. The light pen must be connected
to port 1.
LPEN(0) returns the X position of the light pen, the range is 60 – 320.
LPEN(1) returns the Y position of the light pen, the range is 50 – 250.
Remarks: The X resolution is two pixels, therefore LPEN(0) only returns even num-
bers. A bright background colour is needed to trigger the light pen. The
COLLISION statement may be used to enable an interrupt handler.
Example: Using LPEN

PRINT LPEN(0),LPEN(1) :REM PRINT LIGHT PEN COORDINATES

B-160
MEM
Token: $FE $23
Format: MEM mask4,mask5
Usage: Reserves memory in banks 4 or 5 such that the bitmap graphics system
will not use it.
mask4 and mask5 are byte values, that are interpreted as mask of 8
bits. Each bit set to 1 reserves an 8K segment of memory in bank 4 for
the first argument and in bank 5 for the second argument.

bit memory segment


0 $0000 - $1FFF
1 $2000 - $3FFF
2 $4000 - $5FFF
3 $6000 - $7FFF
4 $8000 - $9FFF
5 $A000 - $BFFF
6 $C000 - $DFFF
7 $E000 - $FFFF
Remarks: After reserving memory with MEM the graphics library will not use the
reserved areas, so it can be used for other purposes. Access to bank 4
and 5 is possible with the commands PEEK, WPEEK, POKE, WPOKE and
EDMA.
If a graphics screen cannot be opened, because the remaining memory
is not sufficient, the program stops with a ?OUT OF MEMORY ERROR.
Some direct mode commands like RENUMBER use memory in banks 4
and 5 and do not honour MEM reservations. Such reservations are only
guaranteed during program execution.
When 80 × 50 text mode is enabled, segment 0 is reserved automati-
cally and used for screen data. It always uses segment 0, even if it was
previously reserved with MEM or a graphic screen. If your program uses
80 × 50 text mode and also reserves a region with MEM, be sure to set
region 0 as reserved, and do not use it for other purposes.
Example: Using MEM

10 MEM 1,3 :REM RESERVE $40000 - $41FFF AND $50000 - $53FFF


20 SCREEN 320,200 :REM SCREEN WILL NOT USE RESERVED SEGMENTS
40 EDMA 3,$2000,0,$4000:REM FILL SEGMENT WITH ZEROES

B-161
MERGE
Token: $E6
Format: MERGE filename [,D drive] [,U unit]
Usage: Loads a BASIC program file from disk and appends it to the program in
memory.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: The load address that is stored in the first two bytes of the file is ignored.
The loaded program does not replace a program in memory (which is
what DLOAD does), but is appended to a program in memory. After
loading, the program is re-linked and ready to run or edit.
It is the user’s responsibility to ensure that there are no line number con-
flicts among the program in memory and the merged program. The first
line number of the merged program must be greater than the last line
number of the program in memory.
Example: Using MERGE

DLOAD "MAIN PROGRAM"


MERGE "LIBRARY"

B-162
MID$
Token: $CA
Format: MID$(string, index, n)
MID$(string variable, index, n) = string expression
Usage: As a function, the substring of a string. As a statement, replaces a sub-
string of a string variable with another string.
string a string expression.
index start index (1 – 255).
n length of sub-string (0 – 255).
Remarks: Empty strings and zero lengths are legal values.
Example: Using MID$:

10 A$ = "MEGA-65"
20 PRINT MID$(A$,3,4)
30 MID$(A$,5,1) = "+"
40 PRINT A$
RUN
GA-6
MEGA+65

B-163
MKDIR
Token: $FE $51
Format: MKDIR dirname ,L size [,U unit]
Usage: Makes (creates) a subdirectory on a floppy or D81 disk image.
dirname the name of a directory. Either a quoted string such as "SOMEDIR",
or a string expression in brackets such as (DR$).
MKDIR can only be used on units managed by CBDOS. These are the in-
ternal floppy disk drive and SD-Card images of D81 type. The command
cannot be used on external drives connected to the serial IEC bus.
The size parameter specifies the number of tracks, to be reserved for the
subdirectory, with one track = 40 sectors at 256 byte. The first track of
the reserved range is used as directory track for the subdirectory.
The minimum size is 3 tracks, the maximm 38 tracks. There must be a
contiguous region of empty tracks on the floppy (D81 image), that is
large enough for the creation of the subdirectory. The error message DISK
FULL is reported if there isn’t such a region.
Several subdirectories may be created as long as there are enough
empty tracks.
After successful creation of the subdirectory an automatic CHDIR into
this subdirectory is performed.
CHDIR ”/” changes back to the root directory.
Examples: Using MKDIR

MKDIR "SUBDIR",L5 :REM MAKE SUBDIRECTORY WITH 5 TRACKS


DIR
0 "SUBDIR " 1D
160 BLOCKS FREE.

B-164
MOD
Token: $NN
Format: MOD(dividend, divisor)
Returns: The remainder of a division operation.
Remarks: In other programming languages such as C, this function is implemented
as an operator (%). In BASIC 65 it is implemented as a function.
Example: Using MOD:

FOR I = 0 TO 8: PRINT MOD(I,4);: NEXT I


0 1 2 3 0 1 2 3 0

B-165
MONITOR
Token: $FA
Format: MONITOR
Usage: Invokes the machine language monitor.
Remarks: Using the MONITOR requires knowledge of the CSG4510 / 6502 /
6510 CPU, the assembly language they use, and their architectures.
More information on the MONITOR is available in Chapter/Appendix N
on page N-3.
To exit the monitor press X.
Help text can be displayed with either ? or H.
Example: Using MONITOR

MONITOR

B-166
MOUNT
Token: $FE $49
Format: MOUNT filename [,U unit]
Usage: Mounts a floppy image file of type D81 from SD-Card to unit 8 (default)
or unit 9.
If no argument is given, MOUNT assigns the real floppy drive of the
MEGA65 to unit 8.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: MOUNT can be used either in direct mode or in a program. It searches
the file on the SD-card and mounts it, as requested, on unit 8 or 9. After
mounting the floppy image can be used as usual with all DOS commands.
Examples: Using MOUNT

MOUNT "APOCALYPSE.D81" ;REM MOUNT IMAGE TO UNIT 8


MOUNT "BASIC.D81",U9 :REM MOUNT IMAGE TO UNIT 9
MOUNT (FI$),U(UN%) :REM MOUNT WITH VARIABLE ARGUMENTS
MOUNT :REM SELECT REAL FLOPPY DRIVE

B-167
MOUSE
Token: $FE $3E
Format: MOUSE ON [{, port, sprite, hotspot, pos}]
MOUSE OFF
Usage: Enables the mouse driver and connects the mouse at the specified port
with the mouse pointer sprite.
port mouse port 1 or 2 (default 2).
sprite sprite number for mouse pointer (default 0).
hostpot location of the ”hot spot” that determines the position and click
target (x,y) (default 0,0).
pos initial mouse position (x,y). If not specified, uses the last known po-
sition of the sprite.
MOUSE OFF disables the mouse driver and hides the associated sprite.
Remarks: The ”hot spot” of the mouse specifies where in the mouse sprite image
is considered the click target, such as the top of an arrow or the center
of a target reticle. The hot spot is always kept within the screen border.
The default hotspot is 0,0, representing the top left corner of the sprite.
When the system boots, sprite 0 is initialised to a picture of a mouse
pointer, with the hot spot at 0,0.
Use RMOUSE to test the location and button status of the mouse. This
returns the coordinates of the top-left corner of the sprite, not the coor-
dinates of the hot spot. To get the coordinates of the hot spot, add the
hot spot location to the sprite coordinates.
pos can be an absolute coordinate, or a relative coordinate to the cur-
rent mouse position, similar to MOVSPR.
Examples: Using MOUSE:

REM LOAD DATA INTO SPRITE #0 BEFORE USING IT


MOUSE ON, 1 :REM ENABLE MOUSE WITH SPRITE #0
MOUSE OFF :REM DISABLE MOUSE

MOUSE ON,1,0,2,4 :REM SET THE HOT SPOT TO (2,4)


RMOUSE X,Y,B :REM FETCH MOUSE SPRITE COORDINATES
X=X+2 : Y=Y+4 :REM CALCULATE THE COORDINATES OF THE HOT SPOT

REM SET THE INITIAL POSITION TO X=300 Y=75


MOUSE ON,1,0,0,0,300,75

B-168
MOVSPR
Token: $FE $06
Format: MOVSPR number, position
Usage: Moves a sprite to a location on screen.
Each position argument consists of two 16-bit values, which specify ei-
ther an absolute coordinate, a relative coordinate, an angle, or a speed.
The value type is determined by a prefix:
• +value relative coordinate: positive offset.
• -value relative coordinate: negative offset.
• #value speed.
If no prefix is given, the absolute coordinate or angle is used.
Therefore, the position argument can be used to either:
• set the sprite to an absolute position on screen.
• specify a displacement relative from the current position.
• trigger a relative movement from a specified position.
• describe movement with an angle and speed starting from the cur-
rent position.
MOVSPR number, position is used to set the sprite immediately to the
position or, in the case of an angle#speed argument, describe its further
movement.
Format: MOVSPR number, start-position TO end-position, speed
Usage: Places the sprite at the start position, defines the destination position,
and the speed of movement.
The sprite is placed at the start position, and will move in a straight line
to the destination at the given speed. Coordinates must be absolute or
relative. The movement is controlled by the BASIC interrupt handler and
happens concurrently with the program execution.
number sprite number (0 – 7).
position x,y | xrel,y | x,yrel | xrel,yrel | angle#speed.
x absolute screen coordinate pixel.
y absolute screen coordinate pixel.
xrel relative screen coordinate pixel.
yrel relative screen coordinate pixel.

B-169
angle compass direction for sprite movement [degrees]. 0: up, 90:
right, 180: down, 270: left, 45 upper right, etc.
speed speed of movement, configured as a floating point number in the
range of 0.0 – 127.0, in pixels per frame. PAL has 50 frames per second
whereas NTSC has 60 frames per second. A speed value of 1.0 will move
the sprite 50 pixels per second in PAL mode.
Example: Using MOVSPR:

100 CLR:SCNCLR:SPRITECLR
110 BLOAD "DEMOSPRITES1",B0,P1536
130 FORI=0TO7: C=I+1:SP=0.07*(I+1)
140 MOVSPRI, 160,120
145 MOVSPRI,45*I#SP
150 SPRITEI,1,C,,0,0
160 NEXT
170 SLEEP 3
180 FORI=0TO7:MOVSPR I,0#0:NEXT

B-170
NEW
Token: $A2
Format: NEW
NEW RESTORE
Usage: Erases the BASIC program in memory, and resets all BASIC parameters
to their default values.
Since NEW resets parameters and pointers, (but does not overwrite the
address range of a BASIC program that was in memory), it is possible to
recover the program. If there were no LOAD operations, or editing per-
formed after NEW, the program can be restored with the NEW RESTORE.
Examples: Using NEW:

NEW :REM RESET BASIC


NEW RESTORE :REM TRY TO RECOVER NEW'ED PROGRAM

B-171
NEXT
Token: $82
Format: FOR index = start TO end [STEP step] ... NEXT [index]
Usage: Marks the end of the BASIC loop associated with the given index variable.
When a BASIC loop is declared with FOR, it must end with NEXT.
The index variable may be incremented or decremented by a constant
value step on each iteration. The default is to increment the variable by
1. The index variable must be a real variable.
start value to initialise the index with.
end is checked at the end of an iteration, and determines whether an-
other iteration will be performed, or if the loop will exit.
step defines the change applied to to the index variable at the end of
every iteration. Positive step values increment it, while negative values
decrement it. It defaults to 1.0 if not specified.
Remarks: The index variable after NEXT is optional. If it is omitted, the variable for
the current loop is assumed. Several consecutive NEXT statements may
be combined by specifying the indexes in a comma separated list. The
statements NEXT I:NEXT J:NEXT K and NEXT I,J,K are equivalent.
Example: Using NEXT

10 FOR D=0 TO 360 STEP 30


20 R = D * ~ / 180
30 PRINT D;R;SIN(R);COS(R);TAN(R)
40 NEXT D

10 DIM M(20,20)
20 FOR I=0 TO 20
30 FOR J=I TO 20
40 M(I,J) = I + 100 * J
50 NEXT J,I

B-172
NOT
Token: $A8
Format: NOT operand
Usage: Performs a bit-wise logical NOT operation on a 16-bit value.
Integer operands are used as they are, whereas real operands are con-
verted to a signed 16-bit integer (losing precision). Logical operands
are converted to a 16-bit integer, using $FFFF (decimal -1) for TRUE,
and $0000 (decimal 0) for FALSE.
Expression Result
NOT 0 1
NOT 1 0
Remarks: The result is of type integer.
Examples: Using NOT

PRINT NOT 3
-4
PRINT NOT 64
-65

In most cases, NOT is used in IF statements.

OK = C < 256 AND C >= 0


IF (NOT OK) THEN PRINT "NOT A BYTE VALUE"

B-173
OFF
Token: $FE $24
Format: keyword OFF
Usage: OFF is a secondary keyword used in combination with primary keywords,
such as KEY and MOUSE.
Remarks: OFF cannot be used on its own.
Examples: Using OFF

KEY OFF :REM DISABLE FUNCTION KEY STRINGS


MOUSE OFF :REM DISABLE MOUSE DRIVER

B-174
ON
Token: $91
Format: ON expression GOSUB line number [, line number ...]
ON expression GOTO line number [, line number ...]
keyword ON
Usage: Performs GOSUB or GOTO to a line number selected by a number ex-
pression.
Depending on the result of the expression, the target for GOSUB and
GOTO is chosen from the table of line addresses at the end of the state-
ment.
When used as a secondary keyword, ON is used in combination with pri-
mary keywords, such as KEY and MOUSE.
expression is a positive numeric value. Real values are converted to
integer (losing precision). Logical operands are converted to a 16-bit
integer, using $FFFF (decimal -1) for TRUE, and $0000 (decimal 0) for
FALSE.
Remarks: Negative values for expression will stop the program with an error mes-
sage. The line number list specifies the targets for values of 1, 2, 3,
etc.
An expression result of zero, or a result that is greater than the number of
target lines will not do anything, and the program will continue execution
with the next statement.

B-175
Example: Using ON

20 KEY ON :REM ENABLE FUNCTION KEY STRINGS


30 MOUSE ON :REM ENABLE MOUSE DRIVER
40 N = JOY(1):IF N AND 128 THEN PRINT "FIRE! ";
60 REM N NE E SE S SW W NW
70 ON N AND 15 GOSUB 100,200,300,400,500,600,700,800
80 GOTO 40
100 PRINT "GO NORTH" :RETURN
200 PRINT "GO NORTHEAST":RETURN
300 PRINT "GO EAST" :RETURN
400 PRINT "GO SOUTHEAST":RETURN
500 PRINT "GO SOUTH" :RETURN
600 PRINT "GO SOUTHWEST":RETURN
700 PRINT "GO WEST" :RETURN
800 PRINT "GO NORTHWEST":RETURN

B-176
OPEN
Token: $9F
Format: OPEN channel, first address [, secondary address [, filename]]
Usage: Opens an input/output channel for a device.
channel number, where:
• 1 <= channel <= 127 line terminator is CR.
• 128 <= channel <= 255 line terminator is CR LF.
first address device number. For IEC devices the unit number is the
primary address. Following primary address values are possible:
Unit Device
0 Keyboard
1 System Default
2 RS232 Serial Connection
3 Screen
4–7 IEC Printer and Plotter
8 – 31 IEC Disk Drives
The secondary address has some reserved values for IEC disk units, 0:
load, 1: save, 15: command channel. The values 2 – 14 may be used for
disk files.
filename is either a quoted string, e.g. "DATA" or a string expression. The
syntax is different to DOPEN#, since the filename for OPEN includes all
file attributes, for example: "0:DATA,S,W".
Remarks: For IEC disk units the usage of DOPEN# is recommended.
If the first character of the filename is an at sign ’@’, it is interpreted as a
”save and replace” operation. It is not recommended to use this option
on 1541 and 1571 drives, as they contain a ”save and replace bug” in
their DOS.
Example: Using OPEN

OPEN 4,4 :REM OPEN PRINTER


CMD 4 :REM REDIRECT STANDARD OUTPUT TO 4
LIST :REM PRINT LISTING ON PRINTER DEVICE 4
OPEN 3,8,3,"0:USER FILE,U"
OPEN 2,9,2,"0:DATA,S,W"

B-177
OR
Token: $B0
Format: operand OR operand
Usage: Performs a bit-wise logical OR operation on two 16-bit values.
Integer operands are used as they are. Real operands are converted
to a signed 16-bit integer (losing precision). Logical operands are con-
verted to a 16-bit integer using $FFFF (decimal -1) for TRUE, and $0000
(decimal 0), for FALSE.
Expression Result
0 OR 0 0
0 OR 1 1
1 OR 0 1
1 OR 1 1
Remarks: The result is of type integer. If the result is used in a logical context,
the value of 0 is regarded as FALSE, and all other non-zero values are
regarded as TRUE.
Example: Using OR

PRINT 1 OR 3
3
PRINT 128 OR 64
192

In most cases, OR is used in IF statements.

IF (C < 0 OR C > 255) THEN PRINT "NOT A BYTE VALUE"

B-178
PAINT
Token: $DF
Format: PAINT x, y, mode [, region border colour]
Usage: Bitmap graphics: performs a flood fill of an enclosed graphics area using
the current pen colour.
x, y is a coordinate pair, which must lie inside the area to be painted.
mode specifies the paint mode:
• 0 The colour of pixel (x,y) defines the colour, which is replaced by
the pen colour.
• 1 The region border colour defines the region to be painted with
the pen colour.
• 2 Paint the region connected to pixel (x,y).
region border colour defines the colour index for mode 1.
Example: Using PAINT

10 SCREEN 320,200,2 :REM OPEN SCREEN


20 PALETTE 0,1,10,15,10 :REM COLOUR 1 TO LIGHT GREEN
30 PEN 1 :REM SET DRAWING PEN (PEN 0) TO LIGHT GREEN (1)
40 LINE 160,0,240,100 :REM 1ST. LINE
50 LINE 240,100,80,100 :REM 2ND. LINE
60 LINE 80,100,160,0 :REM 3RD. LINE
70 PAINT 160,10 :REM FILL TRIANGLE WITH PEN COLOUR
80 GETKEY A& :REM WAIT FOR KEY
90 SCREEN CLOSE :REM END GRAPHICS

B-179
PALETTE
Token: $FE $34
Format: PALETTE screen, colour, red, green, blue
PALETTE COLOR colour, red, green, blue
PALETTE RESTORE
Usage: PALETTE can be used to change an entry of the system colour palette,
or the palette of a screen.
PALETTE RESTORE resets the system palette to the default values.
screen screen number (0 – 3).
COLOR keyword for changing system palette.
colour index to palette entry (0 – 255). PALETTE can define colours
beyond the default system palette entries 0 – 31.
red red intensity (0 – 15).
green green intensity (0 – 15).
blue blue intensity (0 – 15).
Example: Using PALETTE

10 REM CHANGE SYSTEM COLOUR INDEX


20 REM --- INDEX 9 (BROWN) TO (DARK BLUE)
30 PALETTE COLOR 9,0,0,7

10 GRAPHIC CLR :REM INITIALISE


20 SCREEN DEF 1,0,0,2 :REM 320 X 200
30 SCREEN OPEN 1 :REM OPEN
40 SCREEN SET 1,1 :REM MAKE SCREEN ACTIVE
50 PALETTE 1,0, 0, 0, 0 :REM 0 = BLACK
60 PALETTE 1,1, 15, 0, 0 :REM 1 = RED
70 PALETTE 1,2, 0, 0,15 :REM 2 = BLUE
80 PALETTE 1,3, 0,15, 0 :REM 3 = GREEN
90 PEN 2 :REM SET DRAWING PEN (PEN 0) TO BLUE (2)
100 LINE 160,0,240,100 :REM 1ST. LINE
110 LINE 240,100,80,100 :REM 2ND. LINE
120 LINE 80,100,160,0 :REM 3RD. LINE
130 PAINT 160,10,0,2 :REM FILL TRIANGLE WITH BLUE (2)
140 GETKEY K$ :REM WAIT FOR KEY
150 SCREEN CLOSE 1 :REM END GRAPHICS

B-180
PASTE
Token: $E3
Format: PASTE x, y, width, height
Usage: Bitmap graphics: pastes the content of the CUT / GCOPY buffer onto
the screen. The arguments upper left position x, y and the width and
height specify the paste position on the screen.
Remarks: The size of the rectangle is limited by the 1K size of the buffer. The
memory requirement for region is width * height * number of bitplanes /
8. It must not equal or exceed 1024 byte. For a 4-bitplane screen for
example, a 45 x 45 region needs 1012.5 byte.
Example: Using PASTE

10 SCREEN 320,200,2
20 BOX 60,60,300,180,1 :REM DRAW A WHITE BOX
30 PEN 2 :REM SELECT RED PEN
40 CUT 140,80,40,40 :REM CUT OUT A 40 * 40 REGION
50 PASTE 10,10,40,40 :REM PASTE IT TO NEW POSITION
60 GETKEY A$ :REM WAIT FOR KEYPRESS
70 SCREEN CLOSE

B-181
PEEK
Token: $C2
Format: PEEK(address)
Returns: The byte value stored in memory at address, as an unsigned 8-bit num-
ber.
If the address is in the range of $0000 to $FFFF (0 – 65535), the memory
bank set by BANK is used.
Addresses greater than or equal to $10000 (decimal 65536) are as-
sumed to be flat memory addresses and used as such, ignoring the BANK
setting.
Remarks: Banks 0 – 127 give access to RAM or ROM banks. Banks greater than
127 are used to access I/O, and the underlying system hardware such
as the VIC, SID, FDC, etc.
Example: Using PEEK

10 BANK 128 :REM SELECT SYSTEM BANK


20 L = PEEK($02F8) :REM USR JUMP TARGET LOW
30 H = PEEK($02F9) :REM USR JUMP TARGET HIGH
40 T = L + 256 * H :REM 16-BIT JUMP ADDRESS
50 PRINT "USR FUNCTION CALLS ADDRESS";T

B-182
PEN
Token: $FE $33
Format: PEN [pen,] colour
Usage: Bitmap graphics: sets the colour of the graphic pen for the current
screen.
pen pen number (0 – 2):
• 0 drawing pen (default, if only single parameter provided).
• 1 off bits in jam2 mode.
• 2 currently unused.
colour palette index, from the palette of the current screen
See appendix G on page G-3 for the list of colours in the default system
palette.
Remarks: The colour selected by PEN will be used by all graphic/drawing com-
mands that follow it. If you intend to set the drawing pen 0 to a colour,
you can omit the first parameter, and only provide the colour parameter.
Example: Using PEN

10 GRAPHIC CLR :REM INITIALISE


20 SCREEN DEF 1,0,0,2 :REM 320 X 200
30 SCREEN OPEN 1 :REM OPEN
40 SCREEN SET 1,1 :REM MAKE SCREEN ACTIVE
50 PALETTE 1,0, 0, 0, 0 :REM 0 = BLACK
60 PALETTE 1,1, 15, 0, 0 :REM 1 = RED
70 PALETTE 1,2, 0, 0,15 :REM 2 = BLUE
80 PALETTE 1,3, 0,15, 0 :REM 3 = GREEN
90 PEN 1 :REM SET DRAWING PEN (PEN 0) TO RED (1)
100 LINE 160,0,240,100 :REM DRAW RED LINE
110 PEN 2 :REM SET DRAWING PEN (PEN 0) TO BLUE (2)
120 LINE 240,100,80,100 :REM DRAW BLUE LINE
130 PEN 3 :REM SET DRAWING PEN (PEN 0) TO GREEN (3)
140 LINE 80,100,160,0 :REM DRAW GREEN LINE
150 GETKEY K$ :REM WAIT FOR KEY
160 SCREEN CLOSE 1 :REM END GRAPHICS

B-183
PIXEL
Token: $CE $0C
Format: PIXEL(x, y)
Returns: Bitmap graphics: the colour of a pixel at the given position.
x absolute screen coordinate.
y absolute screen coordinate.

B-184
PLAY
Token: $FE $04
Format: PLAY [{string1, string2, string3, string4, string5, string6}]
Usage: Starts playing a sequence of musical notes, or stops a currently playing
sequence.
PLAY without any arguments will cause all voices to be silenced, and all
of the music system’s variables to be reset (such as TEMPO).
PLAY accepts up to six comma-separated string arguments, where each
string describes the sequence of notes and directives to be played on
a specific voice on the two available SID chips, allowing for up to 6-
channel polyphony.
PLAY uses SID1 (for voices 1 to 3) and SID3 (for voices 4 to 6) of the
4 SID chips of the system. By default, SID1 and SID2 are slightly right-
biased and SID3 and SID4 are slightly left-biased in the stereo mix.

PLAY " CEG "


PLAY " C " ," E " ," G "

Within a PLAY string, a musical note is a character (A, B, C, D, E, F, or G),


which may be preceded by an optional modifier.
Possible modifiers are:
Character Effect
# Sharp
$ Flat
. Dotted
W Whole Note
H Half Note
Q Quarter Note
I Eighth Note
S Sixteenth Note
R Pause (rest)
Notice that the dot (.) modifier appears before the note name, not after
it as in traditional sheet music.
Directives consist of a letter, followed by a digit. Directives apply to all
future notes, until the parameter is changed by another directive.

B-185
Char- Directive Argument Range
acter
O Octave 0–6
T Instrument Envelope 0–9
U Volume 0–9
X Filter 0–1
M Modulation 0–9
P Portamento 0–9
L Loop N/A
An octave is a range of notes from C to B. The default octave is 4, rep-
resenting the “middle” octave.
Instrument envelopes describe the nature of the sound. See ENVELOPE
for a list of default envelope styles, and information on how to adjust the
ten envelopes.
The modulation directive adds a pitch-based vibrato your note by the
magnitude you specify (1 – 9). A value of 0 disables it.
Similarly, the portamento directive slides between consecutive notes at
the speed you specify (1 – 9). A value of 0 disables it. Note that the
gate-off behaviour of notes is disabled while portamento is enabled. To
re-enable the gate-off behavior, you must disable portamento (P0).
If a string ends with the L directive, the pattern loops back to the begin-
ning of the string upon completion.
You can omit a string for a given voice to allow an already playing pattern
in that voice to continue, using empty arguments:

PLAY "O4EDCDEEERL",,,"O2CGEGCGEGL"

An example using voice 2 and voice 5:

PLAY ,"O5T2IGAGFEDCEGO6.QCL",,,"O3T2.QG.B O4ICO3GE.QCL"

RPLAY(voice) tests whether music is playing on the given voice, and re-
turns 1 if it is playing or 0 if it is not.
One caveat to be aware of is that BASIC strings have a maximum length
of 255 bytes. If your melody needs to exceed this length, consider break-
ing up your melody into several strings, then use RPLAY(voice) to assess
when your first string has finished and then play the next string.
Instrument envelope slots may be modified by using the ENVELOPE state-
ment. The default settings for the envelopes are on page B-101.

B-186
Remarks: The PLAY statement makes use of an interrupt driven routine that starts
parsing the string and playing the melody. Program execution continues
with the next statement, and will not block until the melody has finished.
This is different to the Commodore 128, which stops program execution
during playback.
The 6 voice channels used by the PLAY command (on SID1+SID3) are
distinct to the 6 channels used by the SOUND command (on SID2+SID4).
Sound effects will not interrupt music, and vice versa.
Example: Using PLAY

5 REM *** SIMPLE LOOPING EXAMPLE ***


10 ENVELOPE 9,10,5,10,5,0,300
20 VOL 8,8
30 TEMPO 30
40 PLAY "O5T9HCIDCDEHCG IGAGFEFDEWCL", "O2T0QCGEGCGEG DBGB CGEGL"

5 REM *** MODULATION + PORTAMENTO EXAMPLE ***


10 TEMPO 20
20 M$ = "M5 T2O5P0QD P5FP0RP5QG .AI#AQA HGQE.C IDQE HFQD .DI#CQD HEQ#CQO4HA"
30 M$ = M$ + "O5QDHFQG.AI#AQA HGQE.C IDQEFED#CO4BO5#C DO4AFD P0R L"
40 B$ = "T0QRO2H.D.F.CO1.A.#A.G.A QAIO2AGFE H.D.F.CO1.A.#A.AO2 .D DL"
50 PLAY M$,B$

B-187
POINTER
Token: $CE $0A
Format: POINTER(variable)
Returns: The current address of a variable or an array element as a 32-bit pointer.
For string variables, it is the address of the string descriptor, not the string
itself. The string descriptor consists of three bytes: length, string address
low, string address high. The string address is an offset in bank 1.
For number-type scalar variables, it is the address of the value. The for-
mat depends on the type. A byte variable (A&) is one byte, in a “two’s
complement” signed integer format. An integer variable (A%) is two bytes,
with the least significant byte first. A real variable (A) is five bytes, in a
compact floating point number format.
To get the address of an array, use POINTER with the first element of the
array (index 0 in each dimension). Array elements are stored consecu-
tively, in the format of the scalar record, with the left-most index using
the shortest stride. For example, an array dimensioned as DIM A%(3,2) starts
at address POINTER(A%(0,0)), has two-byte records, and is ordered as:
(0,0) (1,0) (2,0) (3,0) (0,1) (1,1) (2,1) (3,1) ...
Remarks: The address values of arrays and their elements are constant while the
program is executing.
However, the addresses of strings (not their descriptors) may change at
any time due to “garbage collection.”
Example: Using POINTER

10 BANK 0 :REM SCALARS ARE IN BANK 0


20 H$="HELLO" :REM ASSIGN STRING TO H$
30 P=POINTER(H$) :REM GET DESCRIPTOR ADDRESS
40 PRINT "DESCRIPTOR AT: $";HEX$(P)
50 L=PEEK(P):SP=WPEEK(P+1) :REM LENGTH & STRING POINTER
60 PRINT "LENGTH = ";L :REM PRINT LENGTH
70 BANK 1 :REM STRINGS ARE IN BANK 1
80 FOR I%=0 TOL-1:PRINT PEEK(SP+I%);:NEXT:PRINT
90 FOR I%=0 TOL-1:PRINT CHR$(PEEK(SP+I%));:NEXT:PRINT

RUN
DESCRIPTOR AT: $FD75
LENGTH = 5
72 69 76 76 79
HELLO

B-188
POKE
Token: $97
Format: POKE address, value [, value ...]
Returns: Writes one or more bytes into memory or memory mapped I/O, starting
at address.
If the address is in the range of $0000 to $FFFF (0 – 65535), the memory
bank set by BANK is used.
Addresses greater than or equal to $10000 (decimal 65536) are as-
sumed to be flat memory addresses and used as such, ignoring the BANK
setting.
If value is in the range of 0 – 255, this is poked into memory, otherwise
the low byte of value is used. So a command like POKE AD,V AND 255 can be
written as POKE AD,V because POKE uses the low byte anyway.
Remarks: The address is incremented for each data byte, so a memory range can
be written to with a single POKE.
Banks greater than 127 are used to access I/O, and the underlying sys-
tem hardware such as the VIC, SID, FDC, etc.
Example: Using POKE

10 BANK 128 :REM SELECT SYSTEM BANK


20 POKE $02F8,0,24 :REM SET USR VECTOR TO $1800

B-189
POLYGON
Token: $FE $2F
Format: POLYGON x, y, xrad, yrad, sides [{, drawsides, subtend, angle, solid}]
Usage: Bitmap graphics: draws a regular n-sided polygon. The polygon is drawn
using the current drawing context set with SCREEN, PALETTE, and PEN.
x,y centre coordinates.
xrad,yrad radius in x- and y-direction.
sides number of polygon sides.
drawsides sides to draw.
subtend draw line from centre to start (1).
angle start angle.
solid fill (1) or outline (0).
Remarks: A regular polygon is both isogonal and isotoxal, meaning all sides and
angles are alike.
Example: Using POLYGON

100 SCREEN 320,200,1 :REM OPEN 320 x 200 SCREEN


110 POLYGON 160,100,40,40,6 :REM DRAW HONEYCOMB
120 GETKEY A$ :REM WAIT FOR KEY
130 SCREEN CLOSE :REM CLOSE GRAPHICS SCREEN

Results in:

B-190
POS
Token: $B9
Format: POS(dummy)
Returns: The cursor column relative to the currently used window.
dummy a numeric value, which is ignored.
Remarks: POS gives the column position for the screen cursor. It will not work for
redirected output.
Example: Using POS

10 IF POS(0) > 72 THEN PRINT :REM INSERT RETURN

B-191
POT
Token: $CE $02
Format: POT(paddle)
Returns: The position of a paddle peripheral.
paddle paddle number (1 – 4).
The low byte of the return value is the paddle value, with 0 at the clock-
wise limit and 255 at the anticlockwise limit.
A value greater than 255 indicates that the fire button is also being
pressed.
Remarks: Analogue paddles are noisy and inexact. The range may be less than 0
– 255 and there could be some jitter in the values returned from POT.
Paddles made for Atari game consoles return different values from pad-
dles made for Commodore computers. Commodore paddles provide
more accurate values in the 0 – 255 range.
Example: Using POT

10 X = POT(1) : REM READ PADDLE #1


20 B = X > 255 : REM TRUE (-1) IF FIRE BUTTON IS PRESSED
30 V = X AND 255 : REM PADDLE #1 VALUE

B-192
PRINT
Token: $99
Format: PRINT arguments
Usage: Prints a series of values formatted to the current output stream, typically
the screen.
Values are formatted based on their type. For more control over format-
ting, see PRINT USING.
The following expressions and characters can appear in the argument
list:
• numeric the printout starts with a space for positive and zero val-
ues, or a minus sign for negative values. Integer values are printed
with the necessary number of digits. Real values are printed in ei-
ther fixed point form (typically 9 digits), or scientific form if the value
is outside the range of 0.01 to 999999999.
• string the string may consist of printable characters and control
codes. Printable characters are printed at the cursor position. Con-
trol codes are executed.
• ; (semicolon) separates arguments of the list. It does not print any
characters. A semicolon at the end of the argument list suppresses
the automatic return (carriage return) character.
• , (comma) moves the cursor to the next tab position.
Remarks: The SPC and TAB functions may be used in the argument list for posi-
tioning.
CMD can be used to redirect printed characters to a device other than
the screen.
Example: Using PRINT

10 FOR I=1 TO 10 : REM START LOOP


20 PRINT I,I*I,SQR(I)
30 NEXT

B-193
PRINT#
Token: $98
Format: PRINT# channel, arguments
Usage: Prints a series of values formatted to the device assigned to channel.
Values are formatted based on their type. For more control over format-
ting, see PRINT# USING.
channel number, which was given to a previous call to commands such
as APPEND, DOPEN, or OPEN.
The following argument types are evaluated:
• numeric the printout starts with a space for positive and zero val-
ues, or a minus sign for negative values. Integer values are printed
with the necessary number of digits. Real values are printed in ei-
ther fixed point form (typically 9 digits), or scientific form if the value
is outside the range of 0.01 to 999999999.
• string may consist of printable characters and control codes. Print-
able characters are printed at the cursor position, while control
codes are executed.
• ; (semicolon) separates arguments of the list. It does not print any
characters. A semicolon at the end of the argument list suppresses
the automatic return (carriage return) character.
• , (comma) moves the cursor to the next tab position.
Remarks: The SPC and TAB functions are not suitable for devices other than the
screen.
Example: Using PRINT# to write a file to drive 8:

10 DOPEN#2,"TABLE",W,U8
20 FOR I=1 TO 10 : REM START LOOP
30 PRINT#2,I,I*I,SQR(I)
40 NEXT
50 DCLOSE#2

You can confirm that the file ’TABLE’ has been written by typing DIR "TA*",
and then view the contents of the file by typing TYPE "TABLE".

B-194
PRINT USING
Token: $98 $FB or $99 $FB
Format: PRINT[# channel,] USING format; argument
Usage: Prints a series of values formatted using a pattern to the current output
stream (typically the screen) or an output channel.
The argument can be either a string or a numeric value. The format of
the resulting output is directed by the format string.
channel number, which was given to a previous call to commands such
as APPEND, DOPEN, or OPEN. If no channel is specified, the output goes
to the screen.
format string variable or a string constant which defines the rules for
formatting. When using a number as the argument, formatting can be
done in either CBM style, providing a pattern such as ###.## or in C style
using a <width.precision> specifier, such as %3D %7.2F %4X .
argument the number to be formatted. If the argument does not fit into
the format e.g. trying to print a 4 digit variable into a series of three
hashes (###), asterisks will be used instead.
Remarks: The format string is applied for one argument only, but it is possible to
append more with USING format;argument sequences.
argument may consist of printable characters and control codes. Print-
able characters are printed to the cursor position, while control codes
are executed. The number of # characters sets the width of the output. If
the first character of the format string is an equals ’=’ sign, the argument
string is centered. If the first character of the format string is a greater
than ’>’ sign, the argument string is right justified.

B-195
Examples: Using PRINT# USING

PRINT USING "##.##";~, USING " [%6.4F] ";SQR(2)


3.14 [1.4142]

PRINT USING " < # # # > ";12*31


<372>

PRINT USING "###"; "ABCDE"


ABC

PRINT USING ">###"; "ABCDE"


CDE

PRINT USING "ADDRESS:$%4X";65000


ADDRESS:$FDE8

A$="###,###,###.#":PRINT USING A$;1E8/3


33,333,333.3

B-196
RCOLOR
Token: $CD
Format: RCOLOR(colour source)
Returns: The current colour index for the selected colour source.
Colour sources are:
• 0 background colour (VIC $D021).
• 1 text colour ($F1).
• 2 highlight colour ($2D8).
• 3 border colour (VIC $D020).
Example: Using RCOLOR

10 C = RCOLOR(3) : REM C = colour index of border colour

B-197
RCURSOR
Token: $FE $42
Format: RCURSOR {colvar, rowvar}
Usage: Reads the current cursor column and row into variables.
Remarks: The row and column values start at zero, where the left-most column is
zero, and the top row is zero.
Example: Using RCURSOR

100 CURSOR ON,20,10


110 PRINT "[HERE]";
120 RCURSOR X,Y
130 PRINT " COL:";X;" ROW:";Y

RUN

[HERE] COL: 26 ROW: 10

B-198
READ
Token: $87
Format: READ variable [, variable ...]
Usage: Reads values from DATA statements into variables.
variable list Any legal variables.
All types of constants (integer, real, and strings) can be read, but not ex-
pressions. Items are separated by commas. Strings containing commas,
colons or spaces must be put in quotes.
RUN initialises the data pointer to the first item of the first DATA state-
ment and advances it for every read item. It is the programmer’s re-
sponsibility that the type of the constant and the variable in the READ
statement match. Empty items with no constant between commas are
allowed and will be interpreted as zero for numeric variables and an
empty string for string variables.
RESTORE may be used to set the data pointer to a specific line for sub-
sequent readings.
Remarks: It is good programming practice to put large amounts of DATA state-
ments at the end of the program, so they don’t slow down the search for
line numbers after GOTO, and other statements with line number targets.
Example: Using READ

10 READ NA$, VE
20 READ N%:FOR I=2 TO N%:READ GL(I):NEXT I
30 PRINT "PROGRAM:";NA$;" VERSION:";VE
40 PRINT "N-POINT GAUSS-LEGENDRE FACTORS E1":
50 FOR I=2 TO N%:PRINT I;GL(I):NEXT I
30 STOP
80 DATA "MEGA65",1.1
90 DATA 5,0.5120,0.3573,0.2760,0.2252

B-199
RECORD
Token: $FE $12
Format: RECORD# channel, record [, byte]
Usage: Positions the read/write pointer of a relative file.
channel number, which was given to a previous call of commands such
as DOPEN, or OPEN.
record target record (1 – 65535).
byte byte position in record.
RECORD can only be used for files of type REL, which are relative files
capable of direct access.
RECORD positions the file pointer to the specified record number. If this
record number does not exist and there is enough space on the disk which
RECORD is writing to, the file is expanded to the requested record count
by adding empty records. When this occurs, the disk status will give the
message RECORD NOT PRESENT, but this is not an error!
After a call of INPUT# or PRINT#, the file pointer will proceed to the next
record position.
Remarks: The Commodore disk drives have a bug in their DOS, which can destroy
data by using relative files. A recommended workaround is to use the
command RECORD twice, before and after the I/O operation.
Example: Using RECORD

B-200
100 DOPEN#2,"DATA BASE",L240 :REM OPEN OR CREATE
110 FOR I%=1 TO 20 :REM WRITE LOOP
120 PRINT#2,"RECORD #";I% :REM WRITE RECORD
130 NEXT I% :REM END LOOP
140 DCLOSE#2 :REM CLOSE FILE
150 :REM NOW TESTING
160 DOPEN#2,"DATA BASE",L240 :REM REOPEN
170 FOR I%=20 TO 2 STEP -2 :REM READ FILE BACKWARDS
180 RECORD#2,I% :REM POSITION TO RECORD
190 INPUT#2,A$ :REM READ RECORD
200 PRINT A$;:IF I% AND 2 THEN PRINT
210 NEXT I% :REM LOOP
220 DCLOSE#2 :REM CLOSE FILE

RUN
RECORD # 20 RECORD # 18
RECORD # 16 RECORD # 14
RECORD # 12 RECORD # 10
RECORD # 8 RECORD # 6
RECORD # 4 RECORD # 2

B-201
REM
Token: $8F
Format: REM
Usage: Ignores all subsequent characters on a line of BASIC code, as a code
comment.
Example: Using REM

10 REM *** PROGRAM TITLE ***


20 N=1000 :REM NUMBER OF ITEMS
30 DIM NA$(N)

B-202
RENAME
Token: $F5
Format: RENAME old TO new [,D drive] [,U unit]
Usage: Renames a disk file.
old is either a quoted string, e.g. "DATA" or a string expression in brackets,
e.g. (FI$).
new is either a quoted string, e.g. "BACKUP" or a string expression in brack-
ets, e.g. (FS$)
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: RENAME is executed in the DOS of the disk drive. It can rename all reg-
ular file types (PRG, REL), SEQ, USR. The old file must exist, and the new
file must not exist. Only single files can be renamed, wildcard characters
such as ’*’ and ’?’ are not allowed. The file type cannot be changed.
Example: Using RENAME

RENAME "CODES" TO "BACKUP" :REM RENAME SINGLE FILE

B-203
RENUMBER
Token: $F8
Format: RENUMBER [{new, inc, range}]
Usage: Renumbers lines of a BASIC program.
new new starting line of the line range to renumber. The default value is
10.
inc increment to be used. The default value is 10.
range line range to renumber. The default values are from first to last
line.
RENUMBER executes in either space conserving mode or optimisation
mode. Optimisation mode removes space characters before line num-
bers, thereby reducing code size and decreasing execution time, while
the space conserving leaves spaces untouched. Optimisation mode is
triggered by typing the first argument, (the new starting number), adja-
cent to the keyword RENUMBER with no space in between.
RENUMBER changes all line numbers in the chosen range and also
changes all references in statements that use GOSUB, GOTO, RESTORE,
RUN, TRAP, etc.
RENUMBER can only be executed in direct mode. If it detects a problem
such as memory overflow, unresolved references or line number overflow
(more than than 64000 lines), it will stop with an error message and
leave the program unchanged.
RENUMBER may be called with 0 – 3 parameters. Unspecified parame-
ters use their default values.
Remarks: RENUMBER may need several minutes to execute for large programs.
RENUMBER can only be used in direct mode.
This command temporarily uses memory in banks 4 and 5, and may over-
write anything stored there.
Examples: Using RENUMBER

B-204
RENUMBER :REM SPACE CONSERVING, NUMBERS WILL BE 10,20,30,...
RENUMBER 100,5 :REM SPACE CONSERVING, NUMBERS WILL BE 100,105,110,115,...
RENUMBER601,1,500 :REM OPTIMISATION, RENUMBER STARTING AT 500 TO 601,602,...
RENUMBER 100,5,120-180 :REM SPACE CONSERVING RENUMBER LINES 120-180 TO 100,105,...

10 GOTO 20
20 GOTO 10
RENUMBER 100,10 :REM SPACE CONSERVING
100 GOTO 110
110 GOTO 100
RENUMBER100,10 :REM OPTIMISATION
100 GOTO110
110 GOTO100

B-205
RESTORE
Token: $8C
Format: RESTORE [line]
Usage: Sets the internal pointer for READ from DATA statements.
line new position for the pointer. The default is the first program line.
Remarks: The new pointer target line does not need to contain DATA statements.
Every READ will advance the pointer to the next DATA statement auto-
matically.
Example: Using RESTORE

10 DATA 3,1,4,1,5,9,2,6
20 DATA "MEGA65"
30 DATA 2,7,1,8,2,8,9,5
40 FOR I=1 TO 8:READ P:PRINT P:NEXT
50 RESTORE 30
60 FOR I=1 TO 8:READ P:PRINT P:NEXT
70 RESTORE 20
80 READ A$:PRINT A$

B-206
RESUME
Token: $D6
Format: RESUME [line | NEXT]
Usage: Resumes normal program execution in a TRAP routine, after handling an
error.
RESUME with no parameters attempts to re-execute the statement that
caused the error. The TRAP routine should have examined and corrected
the issue where the error occurred.
line line number to resume program execution at.
NEXT resumes execution following the statement that caused the error.
This could be the next statement on the same line (separated with a colon
’:’), or the statement on the next line.
Remarks: RESUME cannot be used in direct mode.
Example: Using RESUME

10 TRAP 100
20 FOR I=1 TO 100
30 PRINT EXP(I)
40 NEXT
50 PRINT "STOPPED FOR I =";I
60 END
100 PRINT ERR$(ER): RESUME 50

B-207
RETURN
Token: $8E
Format: RETURN
Usage: Returns control from a subroutine that was called with GOSUB or an
event handler declared with COLLISION.
The execution continues at the statement following the GOSUB call.
In the case of the COLLISION handler, the execution continues at the
statement where it left from to call the handler.
Example: Using RETURN

10 SCNCLR :REM CLEAR SCREEN


20 FOR I=1 TO 20 :REM DEFINE LOOP
30 GOSUB 100 :REM CALL SUBROUTINE
40 NEXT I :REM LOOP
50 END :REM END OF PROGRAM
100 CURSOR ON,I,I,0 :REM ACTIVATE AND POSITION CURSOR
110 PRINT "X"; :REM PRINT X
120 SLEEP 0.5 :REM WAIT 0.5 SECONDS
130 CURSOR OFF :REM SWITCH BLINKING CURSOR OFF
140 RETURN :REM RETURN TO CALLER

B-208
RGRAPHIC
Token: $CC
Format: RGRAPHIC(screen, parameter)
Returns: Bitmap graphics: the status of a given graphic screen parameter.
Parameter Description
0 Open (1), Closed (0), or Invalid (>1)
1 Width (0=320, 1=640)
2 Height (0=200, 1=400)
3 Depth (1 – 8 Bitplanes)
4 Bitplanes Used (Bitmask)
5 Bank 4 Blocks Used (Bitmask)
6 Bank 5 Blocks Used (Bitmask)
7 Drawscreen # (0 – 3)
8 Viewscreen # (0 – 3)
9 Drawmodes (Bitmask)
10 pattern type (bitmask)
Example: Using RGRAPHIC

10 GRAPHIC CLR :REM INITIALISE


20 SCREEN DEF 0,1,0,4 :REM SCREEN 0:640 X 200 X 4
30 SCREEN OPEN 0 :REM OPEN
40 SCREEN SET 0,0 :REM DRAW = VIEW = 0
50 SCNCLR 0 :REM CLEAR
60 PEN 0,1 :REM SELECT COLOUR
70 LINE 0,0,639,199 :REM DRAW LINE
80 FOR I=0 TO 10:A(I)=RGRAPHIC(0,I) :NEXT
90 SCREEN CLOSE 0
100 FOR I=0 TO 6:PRINT I;A(I):NEXT :REM PRINT INFO

RUN
0 1
1 1
2 0
3 4
4 15
5 15
6 15

B-209
RIGHT$
Token: $C9
Format: RIGHT$(string, n)
Returns: A string containing the last n characters from string.
If the length of string is equal or less than n, the result string will be
identical to the argument string.
string a string expression.
n a numeric expression (0 – 255).
Remarks: Empty strings and zero lengths are legal values.
Example: Using RIGHT$:

PRINT RIGHT$("MEGA-65",2)
65

B-210
RMOUSE
Token: $FE $3F
Format: RMOUSE x variable, y variable, button variable
Usage: Reads mouse position and button status.
x variable numeric variable where the x-position will be stored.
y variable numeric variable where the y-position will be stored.
button variable numeric variable receiving button status.
left button sets bit 7, while right button sets bit 0.
Coordinates are reported to be compatible with sprite coordinates, lim-
ited to the visible screen inside the border. In the top-left corner, X=24
and Y=50.
Value Status
0 No Button
1 Right Button
128 Left Button
129 Both Buttons
RMOUSE places -1 into all variables if the mouse is not connected or
disabled.
Remarks: Active mice on both ports merge the results.
Example: Using RMOUSE:

10 MOUSE ON, 1, 1 :REM MOUSE ON PORT 1 WITH SPRITE 1


20 RMOUSE XP, YP, BU :REM READ MOUSE STATUS
30 IF XP < 0 THEN PRINT "NO MOUSE ON PORT 1":STOP
40 PRINT "MOUSE:";XP;YP;BU
50 MOUSE OFF :REM DISABLE MOUSE

B-211
RND
Token: $BB
Format: RND(type)
Returns: A pseudo-random number.
This is called a “pseudo-random” number as computers cannot gener-
ate numbers that are truly random. Pseudo-random numbers are derived
mathematically from another number called a “seed” that generates re-
producible sequences. type determines which seed is used:
• type = 0 use system clock.
• type < 0 use the value of type as seed.
• type > 0 derive a new random number from previous one.
Remarks: Seeded random number sequences produce the same sequence for
identical seeds.
The algorithm is initially seeded from the Real-Time Clock and other fac-
tors during boot, so RND(1) is unlikely to return the same sequence twice.
This is unlike the Commodore 64, which always used the same initial
seed. If RND() is ever called with a negative value, that value is used
as a new seed, and sequences generated by RND(1) become predictable.
Use RND(0) to re-seed with an unpredictable value.
Each call to RND(0) generates a new seed based on the system clock and
other factors. Calling RND(0) repeatedly tends to produce a better distri-
bution of values than on a Commodore 64 due to the precision of the
sources of the seed.
Example: Using RND:

10 DEF FNDI(X) = INT(RND(0)*6)+1 :REM DICE FUNCTION


20 FOR I=1 TO 10 :REM THROW 10 TIMES
30 PRINT I;FNDI(0) :REM PRINT DICE POINTS
40 NEXT

B-212
RPALETTE
Token: $CE $0D
Format: RPALETTE(screen, index, rgb)
Returns: The red, green, or blue value of a palette colour index.
screen screen number (0 – 3), or a negative value to select one of the
four system palettes: -1 for system palette 0 (the default system palette),
-2 for system palette 1, -3 for palette 2, or -4 for palette 3.
index palette colour index.
rgb (0: red, 1: green, 2:blue).
Example: Using RPALETTE

10 SCREEN 320,200,4 :REM DEFINE AND OPEN SCREEN


20 R = RPALETTE(0,3,0) :REM GET RED
30 G = RPALETTE(0,3,1) :REM GET GREEN
40 B = RPALETTE(0,3,2) :REM GET BLUE
50 SCREEN CLOSE :REM CLOSE SCREEN
60 PRINT "PALETTE INDEX 3 RGB =";R;G;B

RUN
PALETTE INDEX 3 RGB = 0 15 15

B-213
RPEN
Token: $D0
Format: RPEN(n)
Returns: The colour index of pen n.
n pen number (0 – 2), where:
• 0 draw pen
• 1 erase pen
• 2 outline pen
Example: Using RPEN

10 GRAPHIC CLR :REM INITIALISE


20 SCREEN DEF 0,1,0,4 :REM SCREEN 0:640 X 200 X 4
30 SCREEN OPEN 0 :REM OPEN
40 SCREEN SET 0,0 :REM DRAW = VIEW = 0
50 SCNCLR 0 :REM CLEAR
60 PEN 0,1 :REM SELECT COLOUR
70 X = RPEN(0)
80 Y = RPEN(1)
90 C = RPEN(2)
100 SCREEN CLOSE 0
110 PRINT "DRAW PEN COLOUR = ";X
RUN
DRAW PEN COLOUR = 1

B-214
RPLAY
Token: $FE $0F
Format: RPLAY(voice)
Returns: Tests whether music is playing on the given voice channel.
voice the voice channel to assess, ranging from 1 to 6.
Returns 1 if music is playing on the channel, otherwise 0.
Example: Using RPLAY:

10 PLAY "O4ICDEFGABO5CR","O2QCGEGCO1GCR"
30 IF RPLAY(1) OR RPLAY(2) THEN GOTO 30: REM WAIT FOR END OF SONG

B-215
RREG
Token: $FE $09
Format: RREG [{areg, xreg, yreg, zreg, sreg}]
Usage: Reads the values that were in the CPU registers after a SYS call, into the
specified variables.
areg gets accumulator value.
xreg gets X register value.
yreg gets Y register value.
zreg gets Z register value.
sreg gets status register value.
Remarks: The register values after a SYS call are stored in system memory. This is
how RREG is able to retrieve them.
Example: Using RREG:

10 POKE $1800, $18, $8A, $65, $06, $60


20 REM CLC TXA ADC 06 RTS
30 SYS $1800, 77, 11 : REM A=77 X=11
40 RREG AC,X,Y,Z,S
50 PRINT "REGISTER:";AC;X;Y;Z;S

B-216
RSPCOLOR
Token: $CE $07
Format: RSPCOLOR(n)
Returns: The colour setting of a multi-colour sprite colour.
n sprite multi-colour number:
• 1 get multi-colour # 1.
• 2 get multi-colour # 2.
Remarks: Refer to SPRITE and SPRCOLOR for more information.
Example: Using RSPCOLOR:

10 SPRITE 1,1 :REM TURN SPRITE 1 ON


20 C1% = RSPCOLOR(1) :REM READ COLOUR #1
30 C2% = RSPCOLOR(2) :REM READ COLOUR #2

B-217
RSPEED
Token: $CE $0E
Format: RSPEED(n)
Returns: The current CPU clock in MHz.
n numeric dummy argument, which is ignored.
Remarks: RSPEED(n) will not return the correct value if POKE 0,65 has previously been
used to enable the highest speed (40MHz).
Refer to the SPEED command for more information.
Example: Using RSPEED:

10 X=RSPEED(0) :REM GET CLOCK


20 IF X=1 THEN PRINT "1 MHZ" :GOTO 50
30 IF X=3 THEN PRINT "3.5 MHZ" :GOTO 50
40 IF X=40 THEN PRINT "40 MHZ"
50 END

B-218
RSPPOS
Token: $CE $05
Format: RSPPOS(sprite, n)
Returns: A sprite’s position or speed.
sprite sprite number.
n sprite parameter to retrieve:
• 0 X position.
• 1 Y position.
• 2 speed.
Remarks: Refer to the MOVSPR and SPRITE commands for more information.
Example: Using RSPPOS:

10 SPRITE 1,1 :REM TURN SPRITE 1 ON


20 XP = RSPPOS(1,0) :REM GET X OF SPRITE 1
30 YP = RSPPOS(1,1) :REM GET Y OF SPRITE 1
30 SP = RSPPOS(1,2) :REM GET SPEED OF SPRITE 1

B-219
RSPRITE
Token: $CE $06
Format: RSPRITE(sprite, n)
Returns: A sprite parameter.
sprite sprite number (0 – 7).
n the sprite parameter to return (0 – 5):
• 0 turned on (0 or 1) A 0 means the sprite is off.
• 1 foreground colour (0 – 15).
• 2 background priority (0 or 1).
• 3 x-expanded (0 or 1). 0 means it’s not expanded.
• 4 y-expanded (0 or 1). 0 means it’s not expanded.
• 5 multi-colour (0 or 1). 0 means it’s not multi-colour.
Remarks: Refer to the MOVSPR and SPRITE commands for more information.
Example: Using RSPRITE:

10 SPRITE 1,1 :REM TURN SPRITE 1 ON


20 EN = RSPRITE(1,0) :REM SPRITE 1 ENABLED ?
30 FG = RSPRITE(1,1) :REM SPRITE 1 FOREGROUND COLOUR INDEX
40 BP = RSPRITE(1,2) :REM SPRITE 1 BACKGROUND PRIORITY
50 XE = RSPRITE(1,3) :REM SPRITE 1 X EXPANDED ?
60 YE = RSPRITE(1,4) :REM SPRITE 1 Y EXPANDED ?
70 MC = RSPRITE(1,5) :REM SPRITE 1 MULTI-COLOUR ?

B-220
RUN
Token: $8A
Format: RUN [line number]
RUN filename [,D drive] [,U unit] ↑ filename
Usage: Runs the BASIC program in memory, or loads and runs a program from
disk.
If a filename is given, the program file is loaded into memory and run,
otherwise the program that is currently in memory will be used instead.
The ↑ can be used as shortcut, if used in direct mode at the leftmost
column. It can be used to load and run a program from a dir listing by
moving the cursor to the row with the filename, typing the ↑ at the start
of the row and pressing return. Characters before and after the quoted
filename, will be ignored (like the PRG for example).
line number an existing line number of the program in memory to run
from.
filename either a quoted string, e.g. "PROG" or a string expression in brack-
ets, e.g. (PR$). The filetype must be PRG.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
RUN first resets all internal pointers to their default values. Therefore,
there will be no variables, arrays or strings defined. The run-time stack is
also reset, and the table of open files is cleared.
Remarks: To start or continue program execution without resetting everything, use
GOTO instead.
Examples: Using RUN

RUN "FLIGHTSIM" :REM LOAD AND RUN PROGRAM FLIGHTSIM


RUN 1000 :REM RUN PROGRAM IN MEMORY, START AT LINE# 1000
RUN :REM RUN PROGRAM IN MEMORY

B-221
RWINDOW
Token: $CE $09
Format: RWINDOW(n)
Returns: A parameter of the current text window.
n the screen parameter to retrieve:
• 0 width of current text window.
• 1 height of current text window.
• 2 number of columns on screen (40 or 80).
Remarks: Older versions of RWINDOW reported the width - 1 and the height - 1
for arguments 0 and 1.
Refer to the WINDOW command for more information.
Example: Using RWINDOW:

10 W = RWINDOW(2) :REM GET SCREEN WIDTH


20 IF W=80 THEN BEGIN :REM IS 80 COLUMNS MODE ACTIVE?
30 PRINT CHR$(27)+"X"; :REM YES, SWITCH TO 40COLUMNS
40 BEND

B-222
SAVE
Token: $94
Format: SAVE filename [, unit]
← filename [, unit]

Usage: Saves a BASIC program to a file of type PRG.


filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
The maximum length of the filename is 16 characters, not counting the
optional save and replace character ’@’ and the in-file drive definition. If
the first character of the filename is an at sign ’@’, it is interpreted as a
”save and replace” operation. It is not recommended to use this option
on 1541 and 1571 drives, as they contain a ”save and replace bug” in
their DOS. The filename may be preceded by the drive number definition
”0:” or ”1:”, which is only relevant for dual drive disk units.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: SAVE is obsolete, implemented only for backwards compatibility. DSAVE
should be used instead. The shortcut symbol ← is next to 1 . Can
only be used in direct mode.
Examples: Using SAVE

SAVE "ADVENTURE"
SAVE "ZORK-I",8
SAVE "1:DUNGEON",9

B-223
SAVEIFF
Token: $FE $44
Format: SAVEIFF filename [,D drive] [,U unit]
Usage: Bitmap graphics: saves the current graphics screen to a disk file in IFF
format.
The IFF (Interchange File Format) is supported by many different appli-
cations and operating systems. SAVEIFF saves the image, the palette
and resolution parameters.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$). The maximum length of the
filename is 16 characters. If the first character of the filename is an at
sign ’@’ it is interpreted as a ”save and replace” operation. It is not rec-
ommended to use this option on 1541 and 1571 drives, as they contain
a ”save and replace bug” in their DOS.
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: Files saved with SAVEIFF can be loaded with LOADIFF. Tools are avail-
able to convert popular image formats to IFF. These tools are available
on several operating systems, such as Amiga OS, macOS, Linux, and Win-
dows. For example, ImageMagick is a free graphics package that in-
cludes a tool called convert, which can be used to create IFF files in
conjunction with the ppmtoilbm tool from the Netbpm package.
Example: Using SAVEIFF

10 SCREEN 320,200,2 :REM SCREEN #0 320 X 200 X 2


20 PEN 1 :REM DRAWING PEN COLOUR 1 (WHITE)
30 LINE 25,25,295,175 :REM DRAW LINE
40 SAVEIFF "LINE-EXAMPLE",U8 :REM SAVE CURRENT VIEW TO FILE
50 SCREEN CLOSE :REM CLOSE SCREEN AND RESTORE PALETTE

B-224
SCNCLR
Token: $E8
Format: SCNCLR [colour]
Usage: Clears a text window or bitmap graphics screen.
SCNCLR (with no arguments) clears the current text window. The default
window occupies the whole screen.
SCNCLR colour clears the graphic screen by filling it with the given
colour.
Example: Using SCNCLR:

1 REM SCREEN EXAMPLE 2


10 GRAPHIC CLR :REM INITIALISE
20 SCREEN DEF 1,0,0,2 :REM SCREEN #1 320 X 200 X 2
30 SCREEN OPEN 1 :REM OPEN SCREEN 1
40 SCREEN SET 1,1 :REM USE SCREEN 1 FOR RENDERING AND VIEWING
50 SCREEN CLR 0 :REM CLEAR SCREEN
60 PALETTE 1,1,15,15,15 :REM DEFINE COLOUR 1 AS WHITE
70 PEN 0,1 :REM DRAWING PEN
80 LINE 25,25,295,175 :REM DRAW LINE
90 SLEEP 10 :REM WAIT FOR 10 SECONDS
100 SCREEN CLOSE 1 :REM CLOSE SCREEN AND RESTORE PALETTE

B-225
SCRATCH
Token: $F2
Format: SCRATCH filename [,D drive] [,U unit] [,R]
Usage: Erases (“scratches”) a disk file.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
R Recover a previously erased file. This will only work if there were no
write operations between erasure and recovery, which may have altered
the contents of the disk.
Remarks: SCRATCH filename is a synonym of ERASE filename and DELETE file-
name.
In direct mode the success and the number of erased files is printed.
The second to last number from the message contains the number of
successfully erased files,
Examples: Using SCRATCH

SCRATCH "DRM",U9 :REM ERASE FILE DRM ON UNIT 9


01, FILES SCRATCHED,01,00
SCRATCH "OLD*" :REM ERASE ALL FILES BEGINNING WITH "OLD"
01, FILES SCRATCHED,04,00
SCRATCH "R*=PRG" :REM ERASE PROGRAM FILES STARTING WITH 'R'
01, FILES SCRATCHED,09,00

B-226
SCREEN
Token: $FE $2E
Format: SCREEN [screen,] width, height, depth
SCREEN CLR colour
SCREEN DEF width flag, height flag, depth
SCREEN SET drawscreen, viewscreen
SCREEN OPEN [screen]
SCREEN CLOSE [screen]
Usage: Bitmap graphics: manages a graphics screen.
There are two approaches available when preparing the screen for the
drawing of graphics: a simplified approach, and a detailed approach.

Simplified approach:
The first version of SCREEN (which has pixel units for width and height) is
the easiest way to start a graphics screen, and is the preferred method
if only a single screen is needed (i.e., a second screen isn’t needed for
double buffering). This does all of the preparatory work for you, and
will call commands such as GRAPHIC CLR, SCREEN CLR, SCREEN DEF,
SCREEN OPEN and, SCREEN SET on your behalf. It takes the following
parameters:
SCREEN [screen,] width, height, depth
• screen the screen number (0 – 3) is optional. If no screen number is
given, screen 0 is used. To keep this approach as simple as possible,
it is suggested to use the default screen 0.
• width 320 or 640 (default 320)
• height 200 or 400 (default = 200)
• depth 1..8 (default = 8), colours = 2 ^depth.
The argument parser is error tolerant and uses default values for width
(320) and height (200) if the parsed argument is not valid.
This version of SCREEN starts with a predefined palette and sets the
background to black, and the pen to white, so drawing can start imme-
diately using the default values.
On the other hand, the detailed approach will require the setting of
palette colours and pen colour before any drawing can be done.
The colour value must be in the range of 0 to 15. See appendix G on
page G-3 for the list of colours in the default system palette.

B-227
When you are finished with your graphics screen, simply call SCREEN
CLOSE [screen] to return to the text screen.

Detailed approach:
The other versions of SCREEN perform special actions, used for advanced
graphics programs that open multiple screens, or require ”double buffer-
ing”. If you have chosen the simplified approach, you will not require any
of these versions below, apart from SCREEN CLOSE.
SCREEN CLR colour (or SCNCLR colour)
Clears the active graphics screen by filling it with colour.
SCREEN DEF screen, width flag, height flag, depth
Defines resolution parameters for the chosen screen. The width flag and
height flag indicate whether high resolution (1) or low resolution (0) is
chosen.
• screen screen number 0 – 3
• width flag 0 – 1 (0:320, 1:640 pixel)
• height flag 0 – 1 (0:200, 1:400 pixel)
• depth 1 – 8 (2 – 256 colours)
Note that the width and height values here are flags, and not pixel units.
SCREEN SET drawscreen, viewscreen
Sets screen numbers (0 – 3) for the drawing and the viewing screen, i.e.,
while one screen is being viewed, you can draw on a separate screen and
then later flip between them. This is what’s known as double buffering.
SCREEN OPEN screen
Allocates resources and initialises the graphics context for the selected
screen (0 – 3). An optional variable name as a further argument, gets
the result of the command that can be tested afterwards for success.
SCREEN CLOSE [screen]
Closes screen (0 – 3) and frees resources. If no value is given, it will
default to 0. Also note that upon closing a screen, PALETTE RESTORE is
automatically performed for you.
Examples: Using SCREEN:

5 REM *** SIMPLIFIED APPROACH ***


10 SCREEN 320,200,2 :REM SCREEN #0: 320 X 200 X 2
20 PEN 1 :REM DRAWING PEN COLOUR = 1 (WHITE)
30 LINE 25,25,295,175 :REM DRAW LINE
40 GETKEY A$ :REM WAIT KEYPRESS
50 SCREEN CLOSE :REM CLOSE SCREEN 0 (RESTORE PALETTE)

B-228
5 REM *** DETAILED APPROACH ***
10 GRAPHIC CLR :REM INITIALISE
20 SCREEN DEF 1,0,0,2 :REM SCREEN #1: 320 X 200 X 2
30 SCREEN OPEN 1 :REM OPEN SCREEN 1
40 SCREEN SET 1,1 :REM USE SCREEN 1 FOR RENDERING AND VIEWING
50 SCREEN CLR 0 :REM CLEAR SCREEN
60 PALETTE 1,1,15,15,15:REM DEFINE COLOUR 1 AS WHITE
70 PEN 0,1 :REM DRAWING PEN
80 LINE 25,25,295,175 :REM DRAW LINE
90 SLEEP 10 :REM WAIT 10 SECONDS
100 SCREEN CLOSE 1 :REM CLOSE SCREEN 1 (RESTORE PALETTE)

B-229
SET
Token: $FE $2D
Format: SET DEF unit
SET DISK old TO new
SET VERIFY <ON | OFF>
Usage: SET DEF redefines the default unit for disk access, which is initialised to
8 by the DOS. Commands that do not explicitly specify a unit will use this
default unit.
SET DISK is used to change the unit number of a disk drive temporarily.
SET VERIFY enables or disables the DOS verify-after-write mode for 3.5
drives.
Remarks: These settings are valid until a reset or shutdown.
Examples: Using SET:

DIR :REM SHOW DIRECTORY OF UNIT 8


SET DEF 11 :REM UNIT 11 BECOMES DEFAULT
DIR :REM SHOW DIRECTORY OF UNIT 11
DLOAD "*" :REM LOAD FIRST FILE FROM UNIT 11
SET DISK 8 TO 9 :REM CHANGE UNIT# OF DISK DRIVE 8 TO 9
DIR U9 :REM SHOW DIRECTORY OF UNIT 9 (FORMER 8)
SET VERIFY ON :REM ACTIVATE VERIFY-AFTER-WTITE MODE

B-230
SETBIT
Token: $FE $2D $FE $4E
Format: SETBIT address, bit number
Usage: Sets a single bit at the address.
If the address is in the range of $0000 to $FFFF (0 – 65535), the memory
bank set by BANK is used.
Addresses greater than or equal to $10000 (decimal 65536) are as-
sumed to be flat memory addresses and used as such, ignoring the BANK
setting.
The bit number is a value in the range of 0 – 7.
A bank value > 127 is used to access I/O, and the underlying system
hardware such as the VIC, SID, FDC, etc.
Example: Using SETBIT

10 BANK 128 :REM SELECT SYSTEM MAPPING


20 SETBIT $D011,6 :REM ENABLE EXTENDED BACKGROUND MODE
30 SETBIT $D01B,0 :REM SET BACKGROUND PRIORITY FOR SPRITE 0

B-231
SGN
Token: $B4
Format: SGN(numeric expression)
Returns: The sign of a numeric expression, as a number.
• -1 negative argument.
• 0 zero.
• 1 positive, non-zero argument.
Example: Using SGN

10 ON SGN(X)+2 GOTO 100,200,300 :REM TARGETS FOR MINUS,ZERO,PLUS


20 Z = SGN(X) * ABS(Y) : REM COMBINE SIGN OF X WITH VALUE OF Y

B-232
SIN
Token: $BF
Format: SIN(numeric expression)
Returns: The sine of an angle.
The argument is expected in units of radians. The result is in the range
(-1.0 to +1.0)
Remarks: A value in units of degrees can be converted to radians by multiplying it
with π/180.
Examples: Using SIN

PRINT SIN(0.7)
.644217687

X=30:PRINT SIN(X * ~ / 180)


.5

B-233
SLEEP
Token: $FE $0B
Format: SLEEP seconds
Usage: Pauses execution for the given duration.
The argument is a positive floating point number of seconds. The preci-
sion is 1 microsecond.
RUN
Remarks: Pressing STOP interrupts the sleep.
Example: Using SLEEP

20 SLEEP 10 :REM WAIT 10 SECONDS


40 SLEEP 0.0005 :REM SLEEP 500 MICRO SECONDS
50 SLEEP 0.01 :REM SLEEP 10 MILLI SECONDS
60 SLEEP DD :REM TAKE SLEEP TIME FROM VARIABLE DD
70 SLEEP 600 :REM SLEEP 10 MINUTES

B-234
SOUND
Token: $DA
Format: SOUND voice, freq, dur [{, dir, min, sweep, wave , pulse}]
SOUND CLR
Usage: SOUND plays a sound effect.
voice voice number (1 – 6).
freq frequency (0 – 65535).
dur duration in jiffies (0 – 32767). The duration of a jiffy depends on
the display standard. There are 50 jiffies per second with PAL, 60 per
second with NTSC.
dir direction (0:up, 1:down, 2:oscillate).
min minimum frequency (0 – 65535).
sweep sweep range (0 – 65535).
wave waveform (0:triangle, 1:sawtooth, 2:square, 3:noise).
pulse pulse width (0 – 4095).
SOUND CLR silences all sound from SOUND and PLAY, and resets the
sound system and all parameters.
Remarks: SOUND starts playing the sound effect and immediately continues with
the execution of the next BASIC statement while the sound effect is
played. This enables the showing of graphics or text and playing sounds
simultaneously.
SOUND uses SID2 (for voices 1 to 3) and SID4 (for voices 4 to 6) of the
4 SID chips of the system. By default, SID1 and SID2 are slightly right-
biased and SID3 and SID4 are slightly left-biased in the stereo mix.
The 6 voice channels used by the SOUND command (on SID2+SID4) are
distinct to the 6 channels used by the PLAY command (on SID1+SID3).
Sound effects will not interrupt music, and vice versa.
Examples: Using SOUND

IF PEEK($D06F) AND $80 THEN J = 60: ELSE J = 50 :REM J IS JIFFIES PER SECOND
SOUND 1, 7382, J :REM PLAY SQUARE WAVE ON VOICE 1 FOR 1 SECOND
SOUND 2, 800, J*60 :REM PLAY SQUARE WAVE ON VOICE 2 FOR 1 MINUTE
SOUND 3, 4000, 120, 2, 2000, 400, 1 :REM PLAY SWEEPING SAWTOOTH WAVE ON VOICE 3

SOUND CLR :REM SILENCE SOUND, RESET PARAMETERS

B-235
SPC
Token: $A6
Format: SPC(columns)
Returns: As an argument to PRINT, a string of cursor-right PETSCII codes, suitable
for printing to advance the cursor the given number of columns.

Printing this is similar to pressing → <column> times.


This is not a real function and does not generate a string. It can only be
used as an argument to PRINT.
Remarks: The name of this function is derived from “spaces,” which is misleading.
The function prints cursor right characters, not spaces. The contents
of those character cells that are skipped will not be changed.
Example: Using SPC

10 FOR I=8 TO 12
20 PRINT SPC(-(I<10));I :REM TRUE = -1, FALSE = 0
30 NEXT I
RUN
8
9
10
11
12

B-236
SPEED
Token: $FE $26
Format: SPEED [speed]
Usage: Sets the CPU clock speed to 1MHz, 3.5MHz, or 40MHz.
speed CPU clock speed where:
• 1 sets CPU to 1MHz.
• 3 sets CPU to 3MHz.
• Anything other than 1 or 3 sets the CPU to 40MHz.
Remarks: Although it’s possible to call SPEED with any real number, the precision
part (the decimal point and any digits after it), will be ignored.
SPEED is a synonym of FAST.
SPEED has no effect if POKE 0,65 has previously been used to set the CPU
to 40MHz.
Example: Using SPEED

10 SPEED :REM SET SPEED TO MAXIMUM (40 MHZ)


20 SPEED 1 :REM SET SPEED TO 1 MHZ
30 SPEED 3 :REM SET SPEED TO 3.5 MHZ
40 SPEED 3.5 :REM SET SPEED TO 3.5 MHZ

B-237
SPRCOLOR
Token: $FE $08
Format: SPRCOLOR [{mc1, mc2}]
Usage: Sets multi-colour sprite colours.
SPRITE, which sets the attributes of a sprite, only sets the foreground
colour. For setting the additional two colours of multi-colour sprites, use
SPRCOLOR instead.
Remarks: The colours used with SPRCOLOR will affect all sprites. Refer to the
SPRITE command for more information.
The final argument to SPRITE enables multi-colour mode for the sprite.
Example: Using SPRCOLOR:

10 SPRITE 1,1,2,,,,1 :REM TURN SPRITE 1 ON (FG = 2)


20 SPRCOLOR 4,5 :REM MC1 = 4, MC2 = 5

B-238
SPRITE
Token: $FE $07
Format: SPRITE CLR
SPRITE LOAD filename [,D drive] [,U unit]
SPRITE SAVE filename [,D drive] [,U unit]
SPRITE num [{, switch, colour, prio, expx, expy, mode}]
Usage: SPRITE CLR clears all sprite data and sets all pointers and attributes to
their default values.
SPRITE LOAD loads sprite data from filename to sprite memory.
SPRITE SAVE saves sprite data from sprite memory to filename.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
The last form switches a sprite on or off and sets its attributes:
num sprite number
switch 1: on, 0: off
colour sprite foreground colour
prio 0: sprite in front of text, 1: sprite behind text
expx 1: sprite X expansion
expy 1: sprite Y expansion
mode 1: multi-colour sprite
Remarks: SPRCOLOR must be used to set additional colours for multi-colour sprites
(mode = 1).
Example: Using SPRITE:

2290 CLR:SCNCLR:SPRITE CLR


2300 SPRITE LOAD "DEMOSPRITES1"
2320 FORI=0TO7: C=I: IFC=6THENC=8
2330 MOVSPR I, 60+30*I,0 TO 60+30*I,65+20*I, 3:SPRITE I,1,C,,1,1:NEXT: SLEEP3
2340 FORI=0TO7: SPRITE I,,,,0,0 :NEXT: SLEEP3: SPRITE CLR
2350 FORI=0TO7: MOVSPR I,45*I#5 :NEXT: FORI=0TO7: SPRITE I,1: NEXT
2360 FORI=0TO7:X=60+30*I:Y=65+20*I:DO
2370 LOOPUNTIL(X=RSPPOS(I,.))AND(Y=RSPPOS(I,1)):MOVSPRI,.#.:NEXT

B-239
SPRSAV
Token: $FE $16
Format: SPRSAV source, destination
Usage: Copies sprite data between two sprites, or between a sprite and a string
variable.
source sprite number or string variable.
destination sprite number or string variable.
Remarks: Source and destination can either be a sprite number or a string variable,
SPRSAV can be used with the basic form of sprites (C64 compatible)
only. These sprites occupy 64 bytes of memory, and create strings of
length 64, if the destination parameter is a string variable.
Extended sprites and variable height sprites cannot be used with
SPRSAV.
A string array of sprite data can be used to store many shapes and copy
them fast to the sprite memory with the command SPRSAV.
It’s also a convenient method to read or write shapes of single sprites
from or to a disk file.
Example: Using SPRSAV:

10 SPRITE LOAD "SPRITEDATA" :REM LOAD DATA FOR 8 SPRITES


20 SPRITE 1,1 :REM TURN SPRITE 1 ON
30 SPRSAV 1,2 :REM COPY SPRITE 1 DATA TO SPRITE 2
40 SPRITE 2,1 :REM TURN SPRITE 2 ON
50 SPRSAV 1,A$ :REM SAVE SPRITE 1 DATA IN STRING A$

B-240
SQR
Token: $BA
Format: SQR(numeric expression)
Returns: The square root of a numeric expression.
Remarks: The argument must not be negative.
Example: Using SQR

PRINT SQR(2)
1.41421356

B-241
ST
Format: ST
Usage: The status of the last I/O operation.
If ST is zero, there was no error, otherwise it is set to a device dependent
error code.
Remarks: ST is a reserved system variable.
Example: Using ST

100 MX=100:DIM T$(MX) :REM DATA ARRAY


110 DOPEN#1,"DATA" :REM OPEN FILE
120 IF DS THEN PRINT"COULD NOT OPEN":STOP
130 LINE INPUT#1,T$(N):N=N+1 :REM READ ONE RECORD
140 IF N>MX THEN PRINT "TOO MANY DATA":GOTO 160
150 IF ST=0 THEN 130 :REM ST = 64 FOR END-OF-FILE
160 DCLOSE#1
170 PRINT "READ";N;" RECORDS"

B-242
STEP
Token: $A9
Format: FOR index = start TO end [STEP step] ... NEXT [index]
Usage: STEP is an optional part of a FOR loop.
The index variable may be incremented or decremented by a constant
value after each iteration. The default is to increment the variable by 1.
The index variable must be a real variable.
start initial value of the index.
end is checked at the end of an iteration, and determines whether an-
other iteration will be performed, or if the loop will exit.
step defines the change applied to to the index at the end of a loop iter-
ation. Positive step values increment it, while negative values decrement
it. It defaults to 1.0 if not specified.
Remarks: For positive increments, end must be greater than or equal to start. For
negative increments, end must be less than or equal to start.
It is bad programming practice to change the value of the index variable
inside the loop or to jump into or out of a loop body with GOTO.
Example: Using STEP

10 FOR D=0 TO 360 STEP 30


20 R = D * ~ / 180
30 PRINT D;R;SIN(R);COS(R);TAN(R)
40 NEXT D

B-243
STOP
Token: $90
Format: STOP
Usage: Stops the execution of the BASIC program.
A message will be displayed showing the line number where the program
stopped. The READY. prompt appears and the computer goes into direct
mode, waiting for keyboard input.
Remarks: All variable definitions are still valid after STOP. They may be inspected
or altered, and the program may be continued with CONT. However, any
editing of the program source will disallow any further continuation.
Program execution can be resumed with CONT.
Example: Using STOP

10 IF V < 0 THEN STOP : REM NEGATIVE NUMBERS STOP THE PROGRAM


20 PRINT SQR(V) : REM PRINT SQUARE ROOT

B-244
STR$
Token: $C4
Format: STR$(numeric expression)
Returns: A string of the formatted value of the argument, as if it were PRINTed to
the string.
Example: Using STR$:

A$ = "THE VALUE OF PI IS " + STR$(~)


PRINT A$
THE VALUE OF PI IS 3.14159265

B-245
STRBIN$
Token: $C2 $12
Format: STRBIN$(numeric expression)
Returns: The number value as a string of its binary representation.
Example: Using STRBIN$:

PRINT STRBIN$(245)
11110101

B-246
SYS
Token: $9E
Format: SYS address [{, areg, xreg, yreg, zreg, sreg}]
Usage: Calls a machine language subroutine.
address start address of the subroutine. This can be a ROM-resident
KERNAL routine or any other routine which has previously been loaded or
POKEd to RAM.
areg CPU accumulator value.
xreg CPU X register value.
yreg CPU Y register value.
zreg CPU Z register value.
sreg Status register value.
SYS loads the arguments (if any) into registers, then calls the subroutine.
The called routine must exit with an RTS instruction. After the subroutine
has returned, it saves the new register contents, then returns control to
the BASIC program.
If the address value is 16 bit ($0000 - $FFFF), the BANK value is used
to determine the actual address. If the address is higher than $FFFF, it is
interpreted as a linear 24 bit address and the value of BANK is ignored.
Unlike other BASIC commands that access memory, there are restrictions
on which addresses SYS can access:
• SYS can only access banks 0 – 5, and cannot access Attic RAM or
upper memory, even when using long addresses.
• Only offsets $2000 – $7FFF within a given bank actually refer to
the memory of that bank.
• SYS can only access offsets $0000 – $1FFF in bank 0.
• Accessing offsets $8000 – $FFFF always accesses memory as if
BANK is set to 128 (including ROM and I/O register mappings),
even when BANK is set to a different bank or when using long ad-
dresses.
Remarks: The register values after a SYS call are stored in system memory. RREG
can be used to retrieve these values.
Despite the unusual restrictions on addresses, the SYS command is a
powerful way to combine BASIC and machine language code. For short
routines, memory in bank 0 offsets $1800 – $1EFF are available for pro-
gram use. If care is taken to avoid overwriting the end of the BASIC

B-247
program, machine language routines can be loaded elsewhere in bank
0 up to offset $BFFF.
Using SYS properly (i.e. without corrupting the system) requires some
technical skill, which is out of scope of the User’s Guide. For more infor-
mation and examples, see Chapter/Appendix 13 on page 13-3.
Example: Using SYS:

10 REM DEMO FOR SYS:CHANGING THE BORDER COLOUR


20 BANK 0
30 POKE $4000,$EE,$20,$D0,$60 :REM INC $D020:RTS
40 SYS $4000 :REM CALL SUBROUTINE AT $4000 / BANK $00
50 GETKEY A$:IF A$ <> "Q" THEN 40

B-248
TAB
Token: $A3
Format: TAB(column)
Returns: Positions the cursor at column.
This is only done if the target column is right of the current cursor column,
otherwise the cursor will not move. The column count starts with 0 being
the left-most column.
TAB
Remarks: This function shouldn’t be confused with , which advances the cur-
sor to the next tab-stop.
Example: Using TAB

10 FOR I=1 TO 5
20 READ A$
30 PRINT "* " A$ TAB(10) " *"
40 NEXT I
50 END
60 DATA ONE,TWO,THREE,FOUR,FIVE

RUN
* ONE *
* TWO *
* THREE *
* FOUR *
* FIVE *

B-249
TAN
Token: $C0
Format: TAN(numeric expression)
Returns: The tangent of an angle.
The argument is expected in units of radians. The result is in the range
(-1.0 to +1.0)
Remarks: A value in units of degrees can be converted to radians by multiplying it
with π/180.
Example: Using TAN

PRINT TAN(0.7)
.84228838

X=45:PRINT TAN(X * ~ / 180)


.999999999

B-250
TEMPO
Token: $FE $05
Format: TEMPO speed
Usage: Sets the playback speed for PLAY.
speed 1 – 255
The duration (in seconds) of a whole note is computed with duration =
24/speed.
Example: Using TEMPO

10 VOL 8,8
20 FOR T = 24 TO 18 STEP -2
30 TEMPO T
40 PLAY "T0M3O4QGAGFED","T2O4M5P0H.DP5GB","T5O3IGAGAGAABABAB"
50 IF RPLAY(1) THEN GOTO 50
60 NEXT T
70 PLAY "T0O5QCO4GEH.C","T2O5IEFEDEDCEGO6P8CP0R","T5O3ICDCDEFEDCO4C"

B-251
THEN
Token: $A7
Format: IF expression THEN true clause [ELSE false clause]
Usage: THEN is part of an IF statement.
expression is a logical or numeric expression. A numeric expression is
evaluated as FALSE if the value is zero and TRUE for any non-zero value.
true clause one or more statements starting directly after THEN on the
same line. A line number after THEN performs a GOTO to that line in-
stead.
false clause one or more statements starting directly after ELSE on the
same line. A linenumber after ELSE performs a GOTO to that line instead.
Remarks: The standard IF ... THEN ... ELSE structure is restricted to a single line.
But the true clause and false clause may be expanded to several lines
using a compound statement surrounded with BEGIN and BEND.
Example: Using THEN

1 REM THEN
10 RED$=CHR$(28) : BLACK$=CHR$(144) : WHITE$=CHR$(5)
20 INPUT "ENTER A NUMBER";V
30 IF V<0 THEN PRINT RED$; : ELSE PRINT BLACK$;
40 PRINT V : REM PRINT NEGATIVE NUMBERS IN RED
50 PRINT WHITE$
60 INPUT "END PROGRAM: (Y/N)"; A$
70 IF A$="Y" THEN END
80 IF A$="N" THEN 20 : ELSE 60

B-252
TI
Format: TI
Usage: A high precision timer variable with a resolution of 1 micro second.
It is started or reset with CLR TI, and can be accessed in the same way
as any other variable in expressions.
Remarks: TI is a reserved system variable. The value in TI is the number of seconds
(to 6 decimal places) since it was last cleared or started.
Example: Using TI

100 CLR TI :REM START TIMER


110 FOR I%=1 TO 10000:NEXT :REM DO SOMETHING
120 ET = TI :REM STORE ELAPSED TIME IN ET
130 PRINT "EXECUTION TIME:";ET;" SECONDS"

B-253
TI$
Format: TI$
Usage: The current time of day, as a string.
The time value is updated from the RTC (Real-Time Clock). The string TI$
is formatted as: ”hh:mm:ss”.
TI$ is a read-only variable, which reads the registers of the RTC and for-
mats the values to a string. This differs from other Commodore computers
that do not have an RTC.
Remarks: TI$ is a reserved system variable.
It is possible to access the RTC registers directly via PEEK. The start ad-
dress of the registers is at $FFD7110.
For more information on how to set the Real-Time Clock, refer to the
Configuration Utility section on page Chapter/Appendix 4 on page 4-
3.

100 REM ****** READ RTC ****** ALL VALUES ARE BCD ENCODED
110 RT = $FFD7110 :REM ADDRESS OF RTC
120 FOR I=0 TO 5 :REM SS,MM,HH,DD,MO,YY
130 T(I)=PEEK(RT+I) :REM READ REGISTERS
140 NEXT I :REM USE ONLY LAST TWO DIGITS
150 T(2) = T(2) AND 127 :REM REMOVE 24H MODE FLAG
160 T(5) = T(5) + $2000 :REM ADD YEAR 2000
170 FOR I=2 TO 0 STEP -1 :REM TIME INFO
180 PRINT USING ">## ";HEX$(T(I));
190 NEXT I
RUN
12 52 36

Example: Using TI$

PRINT DT$;TI$
05-APR-2021 15:10:00

B-254
TO
Token: $A4
Format: keyword TO
Usage: TO is a secondary keyword used in combination with primary keywords,
such as BACKUP, BSAVE, CHANGE, CONCAT, COPY, FOR, GO, RE-
NAME, and SET DISK
Remarks: TO cannot be used on its own.
Example: Using TO

10 GO TO 1000 :REM AS GOTO 1000


20 GOTO 1000 :REM SHORTER AND FASTER
30 FOR I=1 TO 10 :REM TO IS PART OF THE LOOP
40 PRINT I:NEXT :REM LOOP END
50 COPY "CODES" TO "BACKUP" :REM COPY SINGLE FILE

B-255
TRAP
Token: $D7
Format: TRAP [line number]
Usage: Registers (or clears) a BASIC error handler subroutine.
With an error handler registered, when a BASIC program encounters an
error, it calls the subroutine instead of exiting the program. During the
subroutine, the system variable ER contains the error number. The TRAP
error handler can then decide whether to STOP or RESUME execution.
TRAP with no argument disables the error handler, and errors will then
be handled by the normal system routines.
Example: Using TRAP

10 TRAP 100
20 FOR I=1 TO 100
30 PRINT EXP(I)
40 NEXT
50 PRINT "STOPPED FOR I =";I
60 END
100 PRINT ERR$(ER): RESUME 50

B-256
TROFF
Token: $D9
Format: TROFF
Usage: Turns off trace mode (switched on by TRON).
When trace mode is active, each line number is printed before it is exe-
cuted. TROFF turns off trace mode.
Example: Using TROFF

10 TRON :REM ACTIVATE TRACE MODE


20 FOR I=85 TO 100
30 PRINT I;EXP(I)
40 NEXT
50 TROFF :REM DEACTIVATE TRACE MODE

RUN
[10][20][30] 85 8.22301268E+36
[40][30] 86 2.2352466E+37
[40][30] 87 6.0760302E+37
[40][30] 88 1.65163625E+38
[40][30] 89
?OVERFLOW ERROR IN 30
READY.

B-257
TRON
Token: $D8
Format: TRON
Usage: Turns on trace mode.
When trace mode is active, each line number is printed before it is exe-
cuted. TRON turns on trace mode.
This is useful for debugging the control flow of a BASIC program. To use
it, add TRON and TROFF statements to the program around the lines that
need debugging.
Example: Using TRON

10 TRON :REM ACTIVATE TRACE MODE


20 FOR I=85 TO 100
30 PRINT I;EXP(I)
40 NEXT
50 TROFF :REM DEACTIVATE TRACE MODE

RUN
[10][20][30] 85 8.22301268E+36
[40][30] 86 2.2352466E+37
[40][30] 87 6.0760302E+37
[40][30] 88 1.65163625E+38
[40][30] 89
?OVERFLOW ERROR IN 30
READY.

B-258
TYPE
Token: $FE $27
Format: TYPE [P] filename [,D drive] [,U unit]
Usage: Prints the contents of a file containing text encoded as PETSCII.
If the P flag is specified, the listing will pause for each screenful of text.
Pressing Q quits page mode, while any other key continues to the next
page.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: TYPE cannot be used to print BASIC programs. Use LIST for programs
instead. TYPE can only process SEQ or USR files containing records of
PETSCII text, delimited by the CR character. (The CR (carriage return)
character can be written to a file using CHR$(13).)
See the EDIT command for a way to create and modify text files inter-
actively with the MEGA65.
Example: Using TYPE

TYPE "README"
TYPE "README 1ST",U9

TYPE P "MOBYDICK"

B-259
UNLOCK
Token: $FE $4F
Format: UNLOCK filename/pattern [,D drive] [,U unit]
Usage: Unlocks a locked file on disk.
The specified file or a set of files, that matches the pattern, is unlocked
and no more protected. It can be deleted afterwards with the commands
DELETE, ERASE or SCRATCH
The LOCK command locks a file.
filename the name of a file. Either a quoted string such as "DATA", or a
string expression in brackets such as (FI$).
drive drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units such
as the 1541, 1571, or 1581.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: Unlocking a file that is already unlocked has no effect.
In direct mode the number of unlocked files is printed. The second to last
number from the message contains the number of unlocked files,
Examples: Using UNLOCK

UNLOCK "SNOOPY",U9 :REM UNLOCK FILE SNOOPY ON UNIT 9


03,FILES UNLOCKED,01,00
UNLOCK "BS*" :REM UNLOCK ALL FILES BEGINNING WITH "BS"
03,FILES UNLOCKED,04,00

B-260
UNTIL
Token: $FC
Format: DO ... LOOP
DO [<UNTIL | WHILE> logical expression]
. . . statements [EXIT]
LOOP [<UNTIL | WHILE> logical expression]
Usage: DO and LOOP define the start of a BASIC loop. Using DO and LOOP
alone without any modifiers creates an infinite loop, which can only be
exited by the EXIT statement. The loop can be controlled by adding
UNTIL or WHILE after the DO or LOOP.
Remarks: DO loops may be nested. An EXIT statement exits the current loop only.
Examples: Using DO and LOOP.

10 PW$="":DO
20 GET A$:PW$=PW$+A$
30 LOOP UNTIL LEN(PW$)>7 OR A$=CHR$(13)

10 DO : REM WAIT FOR USER DECISION


20 GET A$
30 LOOP UNTIL A$="Y" OR A$="N" OR A$="y" OR A$="n"

10 DO WHILE ABS(EPS) > 0.001


20 GOSUB 2000 : REM ITERATION SUBROUTINE
30 LOOP

10 I%=0 : REM INTEGER LOOP 1-100


20 DO I%=I%+1
30 LOOP WHILE I% < 101

B-261
USING
Token: $FB
Format: PRINT[# channel,] USING format; argument
Usage: Parses the format string and evaluates the argument. The argument can
be either a string or a numeric value. The format of the resulting output
is directed by the format string.
channel number, which was given to a previous call to commands such
as APPEND, DOPEN, or OPEN. If no channel is specified, the output goes
to the screen.
format string variable or a string constant which defines the rules for
formatting. When using a number as the argument, formatting can be
done in either CBM style, providing a pattern such as ###.## or in C style
using a <width.precision> specifier, such as %3D %7.2F %4X .
argument the number to be formatted. If the argument does not fit into
the format e.g. trying to print a 4 digit variable into a series of three
hashes (###), asterisks will be used instead.
Remarks: The format string is only applied for one argument, but it is possible to
append more than one USING format;argument sequences.
argument may consist of printable characters and control codes. Print-
able characters are printed to the cursor position, while control codes
are executed. The number of # characters sets the width of the output. If
the first character of the format string is an equals ’=’ sign, the argument
string is centered. If the first character of the format string is a greater
than ’>’ sign, the argument string is right justified.

B-262
Example: USING with a corresponding PRINT#

PRINT USING "##.##";~, USING " [%6.4F] ";SQR(2)


3.14 [1.4142]

PRINT USING " < # # # > ";12*31


<372>

PRINT USING "###"; "ABCDE"


ABC

PRINT USING ">###"; "ABCDE"


CDE

PRINT USING "ADDRESS:$%4X";65000


ADDRESS:$FDE8

A$="###,###,###.#":PRINT USING A$;1E8/3


33,333,333.3

B-263
USR
Token: $B7
Format: USR(numeric expression)
Usage: Invokes an assembly language routine whose memory address is stored
at $02F8 – $02F9.
The result of the numeric expression is written to floating point accu-
mulator 1.
After executing the assembly routine, BASIC returns the contents of the
floating point accumulator 1.
Remarks: Banks 0 – 127 give access to RAM or ROM banks. Banks greater than
127 are used to access I/O, and the underlying system hardware such
as the VIC, SID, FDC, etc.
The floating point accumulator is a facility of the KERNAL that is outside
the scope of the User’s Guide.
Example: Using USR

10 WPOKE $2F8, $7F33 : REM NEGATE ROUTINE


20 PRINT USR(~)
30 PRINT USR(-5)

B-264
VAL
Token: $C5
Format: VAL(string expression)
Returns: The decimal floating point value represented by a string.
Remarks: VAL parses characters from the beginning of the string that resemble a
BASIC decimal number, including a leading negative sign, digits, a deci-
mal point, and an exponent. If it encounters an invalid character, it stops
parsing and returns the result up to that point in the string.
Example: Using VAL

PRINT VAL("78E2")
7800

PRINT VAL("7+5")
7

PRINT VAL("1.256")
1.256

PRINT VAL("$FFFF")
0

B-265
VERIFY
Token: $95
Format: VERIFY filename [, unit [, binflag]]
Usage: VERIFY with no binflag compares a BASIC program in memory with a
disk file of type PRG. It does the same as DVERIFY, but the syntax is
different.
VERIFY with binflag compares a binary file in memory with a disk file of
type PRG. It does the same as BVERIFY, but the syntax is different.
filename is either a quoted string, e.g. "PROG" or a string expression.
unit device number on the IEC bus. Typically in the range from 8 to 11
for disk units. If a variable is used, it must be placed in brackets. The unit
# defaults to 8.
Remarks: VERIFY can only test for equality. It gives no information about the num-
ber or position of different valued bytes. VERIFY exits with either the
message OK or with VERIFY ERROR.
VERIFY is obsolete in BASIC 65. It is only here for backwards compati-
bility. It is recommended to use DVERIFY and BVERIFY instead.
Examples: Using VERIFY

VERIFY "ADVENTURE"
VERIFY "ZORK-I",9
VERIFY "1:DUNGEON",10

B-266
VIEWPORT
Token: $FE $31
Format: VIEWPORT CLR
VIEWPORT DEF x, y, width, height
Usage: Bitmap graphics: manages the viewport of a screen.
VIEWPORT DEF defines a clipping region with the origin (upper left po-
sition) set to x, y and the width and height. All following graphics com-
mands are limited to the VIEWPORT region.
VIEWPORT CLR fills the clipping region with the colour of the drawing
pen.
Remarks: The clipping region can be reset to full screen by the command
VIEWPORT DEF 0,0,WIDTH,HEIGHT using the same values for WIDHTH and HEIGHT as
in the SCREEN command.
Example: Using VIEWPORT

10 SCREEN 320,200,2
20 VIEWPORT DEF 20,30,100,120 :REM REGION 20->119, 30->149
30 PEN 1 :REM SELECT COLOUR 1
40 VIEWPORT CLR :REM FILL REGION WITH COLOUR OF PEN
50 GETKEY A$ :REM WAIT FOR KEYPRESS
60 SCREEN CLOSE

B-267
VOL
Token: $DB
Format: VOL right, left
Usage: Sets the volume for sound output with SOUND or PLAY.
right is the volume for SIDs 1 and 2, and left is the volume for SIDs 3 and
4. The value ranges from 0 (off) to 15 (loudest).
Remarks: The terms ”right” and ”left” refer to the default pan settings for the
MEGA65 SID chips in the audio mixer. The actual volume and pan posi-
tion for each pair of SIDs depends on the audio mixer settings. You can
adjust the audio settings in the Freezer.
Example: Using VOL

10 TEMPO 22
20 FOR V = 2 TO 12 STEP 2
30 VOL V,16-V
40 PLAY "T0M3O4QGAGFED","T2O4M5P0H.DP5GB","T5O3IGAGAGAABABAB","G"
50 IF RPLAY(1) THEN GOTO 50
60 NEXT V
70 PLAY "T0O5QCO4GEH.C","T2O5IEFEDEDCEGO6P9CP0R","T5O3ICDCDEFEDCO4C","C"

B-268
VSYNC
Token: $FE $54
Format: VSYNC raster line
Usage: Waits until the selected raster line is active.
raster line (0 - 311) for PAL, (0 - 262) for NTSC mode.
This pauses execution of the BASIC program until the screen update
reaches the given vertical pixel coordinate. This is a very brief pause:
the screen updates 50 times per second in PAL mode, and 60 times per
second in NTSC mode. This is useful to change graphics parameters at
specific points in the screen update, and to synchronize BASIC program
logic with the screen refresh rate.
Example: Using VSYNC

10 IF FRE(-1)<920364 THEN PRINT"UPDATE ROM":END


20 BORDER 3 :REM CHANGE BORDER COLOUR TO CYAN
30 VSYNC 100 :REM WAIT UNTIL RASTER LINE 100
40 BORDER 7 :REM CHANGE BORDER COLOUR TO YELLOW
50 VSYNC 260 :REM WAIT UNTIL RASTER LINE 260
60 GOTO 20 :REM LOOP

B-269
WAIT
Token: $92
Format: WAIT address, andmask [, xormask]
Usage: Pauses the BASIC program until a requested bit pattern is read from the
given address.
address the address at the current memory bank, which is read.
andmask AND mask applied.
xormask XOR mask applied.
WAIT reads the byte value from address and applies the masks:
result = PEEK(address) AND andmask XOR xormask.
The pause ends if the result is non-zero, otherwise reading is repeated.
This may hang the computer indefinitely if the condition is never met.
Remarks: WAIT is typically used to examine hardware registers or system variables
and wait for an event, e.g. joystick event, mouse event, keyboard press
or a specific raster line is about to be drawn to the screen.
Example: Using WAIT

10 BANK 128
20 WAIT 211,1 :REM WAIT FOR SHIFT KEY BEING PRESSED

B-270
WHILE
Token: $ED
Format: DO ... LOOP
DO [<UNTIL | WHILE> logical expression]
. . . statements [EXIT]
LOOP [<UNTIL | WHILE> logical expression]
Usage: DO and LOOP define the start of a BASIC loop. Using DO and LOOP
alone without any modifiers creates an infinite loop, which can only be
exited by the EXIT statement. The loop can be controlled by adding
UNTIL or WHILE after the DO or LOOP.
Remarks: DO loops may be nested. An EXIT statement exits the current loop only.
Examples: Using DO and LOOP

10 PW$="":DO
20 GET A$:PW$=PW$+A$
30 LOOP UNTIL LEN(PW$)>7 OR A$=CHR$(13)

10 DO : REM WAIT FOR USER DECISION


20 GET A$
30 LOOP UNTIL A$="Y" OR A$="N" OR A$="y" OR A$="n"

10 DO WHILE ABS(EPS) > 0.001


20 GOSUB 2000 : REM ITERATION SUBROUTINE
30 LOOP

10 I%=0 : REM INTEGER LOOP 1-100


20 DO I%=I%+1
30 LOOP WHILE I% < 101

B-271
WINDOW
Token: $FE $1A
Format: WINDOW left, top, right, bottom [, clear]
Usage: Sets the text screen window.
left left column
top top row
right right column
bottom bottom row
clear clear text window flag
By default, text updates occur on the entire available text screen. WIN-
DOW narrows the update region to a rectangle of the available screen
space.
Remarks: The row values range from 0 to 24. The column values range from 0 to
either 39 or 79. This depends on the screen mode.
CLR
There can be only one window on the screen. Pressing HOME twice or
PRINTing CHR$(19)CHR$(19) will reset the window to the default (full
screen).
Example: Using WINDOW

10 WINDOW 0,1,79,24 :REM SCREEN WITHOUT TOP ROW


20 WINDOW 0,0,79,24,1 :REM FULL SCREEN WINDOW CLEARED
30 WINDOW 0,12,79,24 :REM LOWER HALF OF SCREEN
40 WINDOW 20,5,59,15 :REM SMALL CENTRED WINDOW

B-272
WPEEK
Token: $CE $10
Format: WPEEK(address)
Returns: The 16-bit word value stored in memory at address (low byte) and ad-
dress + 1 (high byte), as an unsigned 16-bit number.
If the address is in the range of $0000 to $FFFF (0 – 65535), the memory
bank set by BANK is used.
Addresses greater than or equal to $10000 (decimal 65536) are as-
sumed to be flat memory addresses and used as such, ignoring the BANK
setting.
Remarks: Banks 0 – 127 give access to RAM or ROM banks. Banks greater than
127 are used to access I/O, and the underlying system hardware such
as the VIC, SID, FDC, etc.
Example: Using WPEEK

20 UA = WPEEK($02F8) :REM USR JUMP TARGET


50 PRINT "USR FUNCTION CALL ADDRESS";UA

B-273
WPOKE
Token: $FE $1D
Format: WPOKE address, word [, word ...]
Returns: Writes one or more 16-bit words into memory or memory mapped I/O,
starting at address.
If the address is in the range of $0000 to $FFFF (0 – 65535), the memory
bank set by BANK is used.
Addresses greater than or equal to $10000 (decimal 65536) are as-
sumed to be flat memory addresses and used as such, ignoring the BANK
setting.
word a value from 0 – 65535. The first word is stored at address (low
byte) and address+1 (high byte). The second word is stored at address+2
(low byte) and address+3 (high byte), etc. If a value is larger than 65535,
only the lower two bytes are used.
Remarks: The address is increased by two for each data word, so a memory range
can be written to with a single WPOKE.
Banks greater than 127 are used to access I/O, and the underlying sys-
tem hardware such as the VIC, SID, FDC, etc.
Example: Using WPOKE

10 BANK 128 :REM SELECT SYSTEM BANK


20 WPOKE $02F8,$1800 :REM SET USR VECTOR TO $1800

B-274
XOR
Token: $E9
Format: operand XOR operand
Usage: Performs a bit-wise logical Exclusive OR operation on two 16-bit values.
Integer operands are used as they are. Real operands are converted
to a signed 16-bit integer (losing precision). Logical operands are con-
verted to 16-bit integer using $FFFF, (decimal -1) for TRUE, and $0000
(decimal 0) for FALSE.
Expression Result
0 XOR 0 0
0 XOR 1 1
1 XOR 0 1
1 XOR 1 0
Remarks: The result is of type integer. If the result is used in a logical context,
the value of 0 is regarded as FALSE, and all other non-zero values are
regarded as TRUE.
Example: Using XOR

FOR I = 0 TO 8: PRINT I XOR 5;: NEXT I


5 4 7 6 1 0 3 2 13

B-275
B-276
APPENDIX C
Screen Codes
• Screen Codes
C-2
SCREEN CODES
A text character is represented in screen memory by a screen code. There are 256
possible screen codes, each referring to an image in the current character set.
A complete character set contains two groups of 256 images, one for the uppercase
mode and one for the lowercase mode, for a total of 512 images. Only one mode
can be displayed at a time. The built-in character sets use the first 128 characters of
each group for normal characters and the next 128 for reversed versions of the same
characters.
In BASIC, the T@&() special array provides access to the characters on the screen us-
ing column and row indexes. The values in this special array are screen codes. The
FONT command changes between the built-in character sets. The CHARDEF com-
mand changes the image associated with a screen code.
Note: Screen codes are different to PETSCII codes. PETSCII codes are used to store,
transmit, and receive textual data, and control the way strings are printed to the
screen. When a PETSCII character is printed to the screen, the corresponding screen
code is written to screen memory. For a list of PETSCII codes, see appendix D on
page D-3.
The following table lists the screen codes. When a code produces a different character
based on the mode, the character is listed as “uppercase / lowercase.”

0 @ 15 O / o 30 ↑ 45 -
1 A/a 16 P / p 31 ← 46 .
2 B/b 17 Q / q 32 space 47 /
3 C/c 18 R / r 33 ! 48 0
4 D/d 19 S / s 34 ” 49 1
5 E/e 20 T / t 35 # 50 2
6 F/f 21 U / u 36 $ 51 3
7 G/g 22 V / v 37 % 52 4
8 H/h 23 W / w 38 & 53 5
9 I/i 24 X / x 39 ’ 54 6
10 J / j 25 Y / y 40 ( 55 7
11 K / k 26 Z / z 41 ) 56 8
12 L / l 27 [ 42 * 57 9
13 M / m 28 £ 43 + 58 :
14 N / n 29 ] 44 , 59 ;

C-3
60 < 77 M / M 94 3 / > 111 p
61 = 78 N / N 95 ] / : 112 a
62 > 79 O / O 96 space 113 e
63 ? 80 P / P 97 j 114 r
64 C 81 Q / Q 98 i 115 w
65 A / A 82 R / R 99 t 116 h
66 B / B 83 S / S 100 [ 117 j
67 C / C 84 T / T 101 g 118 l
68 D / D 85 U / U 102 < 119 y
69 E / E 86 V / V 103 m 120 u
70 F / F 87 W / W 104 / 121 p
71 G / G 88 X / X 105 ? / ) 122 { / 8
72 H / H 89 Y / Y 106 n 123 f
73 I / I 90 Z / Z 107 q 124 c
74 J / J 91 + 108 d 125 x
75 K / K 92 - 109 z 126 v
76 L / L 93 B 110 s 127 b

Note: In the built-in character sets, codes 128-255 are reversed versions of 0-127.

C-4
APPENDIX D
PETSCII Codes
• PETSCII Codes and CHR$
D-2
PETSCII CODES AND CHR$
In BASIC, PRINT CHR$(X) can be used to print a character from a PETSCII code. Below is the
full table of PETSCII codes you can print by index. For example, while in the default
uppercase/graphics mode, by using index 65 from the table below as: PRINT CHR$(65) you
will print the letter A. You can read more about CHR$ on page B-48.
You can also do the reverse with the ASC statement. For example: PRINT ASC("A") will
output 65, which matches the code in the table.
NOTE: Function key (F1-F14 + HELP) values in this table are not intended to be printed
via CHR$(), but rather to allow function-key input to be assessed in BASIC programs via
the GET / GETKEY commands.

0 19
CLR
HOME 41 ) 64 @
1 ALTERNATE PALETTE INST
42 * 65 A
20 DEL
2 UNDERLINE ON 43 + 66 B
21 F10 / BACK WORD
3 44 , 67 C
22 F11
4 DEFAULT PALETTE 45 - 68 D
23 F12 / NEXT WORD
5 WHITE 46 . 69 E
24 SET/CLEAR TAB
47 / 70 F
6
25 F13
48 0 71 G
7 BELL
26 F14 / BACK TAB
49 1 72 H
8 27 ESCAPE
50 2 73 I
TAB
9 28 RED
51 3 74 J
10 LINEFEED 29 →
52 4 75 K
11 DISABLE 30 GREEN 53 5 76 L
SHIFT
` 31 BLUE 54 6 77 M
12 ENABLE 32 SPACE 55 7 78 N
SHIFT
`
33 ! 56 8 79 O
RETURN
13 34 ” 57 9 80 P

14 LOWER CASE 35 # 58 : 81 Q
36 $ 59 ; 82 R
15 BLINK/FLASH ON
37 % 60 < 83 S
16 F9
38 & 61 = 84 T
17 ↓
39 ’ 62 > 85 U
RVS ON
18 40 ( 63 ? 86 V

D-3
87 W 113 Q 140 F8 165 g
88 X 114 R 141
SHIFT RETURN 166 �
89 Y 115 S 167 m
142 UPPERCASE
90 Z 116 T 168 /
143 BLINK/FLASH OFF
91 [ 117 U 169 ?
144 BLACK
92 £ 118 V 170 v
145 ↑
93 ] 119 W 171 q
RVS
120 X 146 OFF
172 d
94 ↑
121 Y 147
SHIFT CLR 173 z
95 ← HOME

122 Z 174 s
SHIFT INST
96 C 148 DEL
123 + 175 n
97 A 124 - 149 BROWN
176 a
98 B 125 B 150 LT. RED (PINK)
177 e
99 C 126 \ 151 DK. GREY
178 r
100 D 127 ] 152 GREY
179 w
101 E 128 153 LT. GREEN
180 h
102 F 129 ORANGE 154 LT. BLUE
181 j
103 G 130 UNDERLINE OFF 155 LT. GREY
182 l
104 H SHIFT RUN 156 PURPLE
131 STOP 183 y
157 ←
105 I 132 HELP 184 u
106 J 158 YELLOW 185 p
133 F1
107 K 159 CYAN 186 {
134 F3
108 L 135 F5 160 SPACE 187 f
109 M 136 F7 161 k 188 c
110 N 137 F2 162 i 189 x
111 O 138 F4 163 t 190 v
112 P 139 F6 164 [ 191 b

Note 1: Codes from 192 to 223 are equal to 96 to 127. Codes from 224 to 254 are
equal to 160 to 190, and code 255 is equal to 126.
SHIFT
Note 2: While using lowercase/uppercase mode (by pressing ` + ), be aware
that:

D-4
• The uppercase letters in region 65-90 of the above table are replaced with
lowercase letters.
• The graphical characters in region 97-122 of the above table are replaced with
uppercase letters.
• PETSCII’s lowercase (65-90) and uppercase (97-122) letters are in ASCII’s up-
percase (65-90) and lowercase (97-122) letter regions.

D-5
D-6
APPENDIX E
Screen Editor Keys
• Screen Editor Keys
• Control codes
• Shifted codes
• Escape Sequences
E-2
SCREEN EDITOR KEYS
The following key combinations perform actions in the MEGA65 screen editor.
In some cases, a program can print the equivalent PETSCII codes to perform the same
CTRL
actions. For example, + G , which plays a bell sound, can be printed by a
program as CHR$(7). To print an sequence, use CHR$(27) to represent the
ESC ESC
key,
followed by the next key in the sequence.

CONTROL CODES
Keyboard Control Function
Colours
Choose from the first range of
CTRL
+ 1 to 8 colours. See appendix G on
page G-3 for the list of colours in
the system palette.
` + 1 to 8 Choose from the second range of
colours.
CTRL
+ E Restores the colour of the cursor
back to the default (white).
Switches the VIC-IV to colour range
0-15 (default colours). These
CTRL
colours can be accessed with
CTRL
+ D
and keys 1 to 8 (for the first 8
colours), or ` and keys 1 to
8 (for the remaining 8 colours).
Switches the VIC-IV to colour range
16-31 (alternate/rainbow colours).
These colours can be accessed with
CTRL
CTRL
+ A and keys 1 to 8 (for the
first 8 colours), or ` and keys
1 to 8 (for the remaining 8
colours).
Tabs

E-3
Keyboard Control Function
Tabs the cursor to the left. If there
CTRL
+ Z are no tab positions remaining, the
cursor will remain at the start of the
line.
Tabs the cursor to the right. If there
CTRL
+ I are no tab positions remaining, the
cursor will remain at the end of the
line.
Sets or clears the current screen
CTRL
CTRL
column as a tab position. Use
+ X
+ Z and I to jump back and
forth to all positions set with X .
Movement
CTRL Moves the cursor down one line at a
+ Q
time. Equivalent to ↓ .
Moves the cursor down a position. If
CTRL
you are on a long line of BASIC
+ J code that has extended to two lines,
then the cursor will move down two
rows to be on the next line.
Equivalent to → .
CTRL
+ ]
Backspace the character
immediately to the left and to shift
CTRL
+ T all rightmost characters one position
to the left. This is equivalent to
INST
DEL .
CTRL Performs a carriage return,
+ M RETURN
equivalent to .
Word movement
Moves the cursor backward to the
start of the previous word. If there is
CTRL
no previous word on the current line,
+ U it moves to the first column of the
current line, then to the previous
line, until a line with a word is
encountered.

E-4
Keyboard Control Function
Advances the cursor forward to the
start of the next word. If there is no
CTRL
+ W next word on the current line, it
moves to the first column of the next
line, until a line with a word is
encountered.
Scrolling

CTRL Scroll BASIC listing down one line.


+ P
Equivalent to F9 .
CTRL Scroll BASIC listing up one line.
+ V
Equivalent to F11 .
CTRL
+ S Equivalent to
NO
SCROLL .
Formatting
Enables underline text mode. You
CTRL
+ B can disable underline mode by
ESC
pressing , then O .
Enables flashing text mode. You can
CTRL
+ O disable flashing mode by pressing
ESC
, then O .
Casing
CTRL
+ N Changes the text case mode from
uppercase to lowercase.
Locks the uppercase/lowercase
CTRL
+ K mode switch usually performed with
SHIFT
` + .
Enables the uppercase/lowercase
CTRL
+ L mode switch that is performed with
SHIFT
the ` + .
Miscellaneous
CTRL
+ G Produces a bell tone.
CTRL ESC
+ [ Equivalent to pressing .
CTRL
+ * Enters the Matrix Mode Debugger.

E-5
SHIFTED CODES
Keyboard Control Function
Insert a character at the current
SHIFT
+
INST
DEL
cursor position and move all
characters to the right by one
position.

SHIFT HOME
Clear home, clear the entire screen,
+ and move the cursor to the home
position.

ESCAPE SEQUENCES
ESC
To perform an Escape Sequence, briefly press and release , then press one of
the following keys to perform the sequence.

Key Sequence
Editor behaviour

ESC
Clears the screen and toggles
X between 40 × 25 and 80 × 25 text
modes.
ESC
4 Clears the screen and switches to
40 × 25 text mode.
ESC
8 Clears the screen and switches to
80 × 25 text mode.
ESC
5 Switches to 80 × 50 text mode.
Note that some programs expect to be started
in 80 × 25 mode, and may not behave
correctly when started in 80 × 50 mode.

E-6
Key Sequence
Clears a region of the screen,
ESC @ starting from the current cursor
position, to the end of the screen.
ESC
O Cancels the quote, reverse,
underline, and flash modes.
Scrolling
ESC
V Scrolls the entire screen up one line.
ESC
W Scrolls the entire screen down one
line.
ESC
L Enables scrolling when ↓ is
pressed at the bottom of the screen.
Disables scrolling. When pressing
↓ at the bottom of the screen,
ESC
M the cursor will move to the top of
the screen. However, when pressing
↑ at the top of the screen, the
cursor will remain on the first line.
Enables ”line pushing:” typing or
ESC
N printing in the rightmost column
pushes subsequent lines down by
one.
Disables ”line pushing:” typing or
printing in the rightmost column
moves the cursor to the beginning of
the next line, but does not push any
ESC
R lines. Disable both line pushing (
ESC
R ) and scrolling ( ESC
M ) to allow PRINTing in the
rightmost column without disturbing
the rest of the display.
Insertion and deletion

ESC
Inserts an empty line at the current
I cursor position and moves all
subsequent lines down one position.

E-7
Key Sequence

ESC
Deletes the current line and moves
D lines below the cursor up one
position.
ESC
P Erases all characters from the cursor
to the start of the current line.
ESC
Q Erases all characters from the cursor
to the end of the current line.
Movement
ESC
J Moves the cursor to the start of the
current line.

ESC
Moves the cursor to the last
K non-whitespace character on the
current line.
Saves the current cursor position.
Use
ESC ← (next to 1 ) to
ESC
↑ move it back to the saved position.
Note that the ↑ used here is next
RESTORE
to .
Restores the cursor position to the
position stored via a prior a press of
ESC ← the
ESC
↑ (next to RESTORE ) key
sequence. Note that the ← used
here is next to 1 .
Restores the cursor position to the
ESC HOME
position stored via a prior a press of
HOME
.
Windowing
Sets the top-left corner of the
windowed area. All typed
ESC
characters and screen activity will
T be restricted to the area. Also see
ESC
B . Windowed mode can be
CLR
disabled by pressing HOME twice.

E-8
Key Sequence
Sets the bottom right corner of the
windowed area. All typed
ESC
characters and screen activity will
B be restricted to the area. Also see
ESC
T . Windowed mode can be
CLR
disabled by pressing HOME twice.
Cursor behaviour
Enables auto-insert mode. Any keys
pressed will be inserted at the
ESC
A current cursor position, shifting all
characters on the current line after
the cursor to the right by one
position.
ESC
C Disables auto-insert mode, reverting
back to overwrite mode.
ESC
E Sets the cursor to non-flashing
mode.
ESC
F Sets the cursor to regular flashing
mode.
Bell behaviour
ESC Enables the bell which can be
G CTRL
sounded using and G .
ESC Disable the bell so that pressing
H CTRL
and G will have no effect.
Colours
Switches the VIC-IV to colour range
0-15 (default colours). These
CTRL
colours can be accessed with
ESC
U
and keys 1 to 8 (for the first 8
colours), or ` and keys 1 to
8 (for the remaining colours).

E-9
Key Sequence
Switches the VIC-IV to colour range
16-31 (alternate/rainbow colours).
These colours can be accessed with
CTRL
ESC
S and keys 1 to 8 (for the
first 8 colours), or ` and keys
1 to 8 (for the remaining
colours).
Tabs
ESC
Y Set the default tab stops (every 8
spaces) for the entire screen.
Clears all tab stops. Any tabbing
ESC
Z with
CTRL
and I will move the
cursor to the end of the line.

E-10
APPENDIX F
The MEGA65 Keyboard
• Using the Typing Event Queue
• Keyboard Theory of Operation
• C65 Keyboard Matrix
• Synthetic Key Events
• Keyboard LED Control
• Native Keyboard Matrix
F-2
The MEGA65 has a full mechanical keyboard which is compatible with the C65 and
C64 keyboards, and features four distinct cursor keys which work in both C64 and
C65-mode, as well as eleven new C65 keys that normally work only in C65-mode.
There are several ways to read the keyboard from programs. BASIC programs can use
the GET or GETKEY commands, which read a PETSCII keycode into a variable, without
or with waiting for a typing event. Machine language programs that keep the KERNAL
active can use the KERNAL getin routine at $FFE4, which loads a PETSCII code into
the accumulator. These routines have the advantage of supporting other features of
the KERNAL input stream, such as function key macros and input redirection.
The Commodore 64 uses the CIA chip as the hardware interface to the keyboard, and
some C64 programs (including the C64 KERNAL) read the keyboard matrix directly off
of the CIA lines. This is implemented in the MEGA65 chipset to support these programs.
Reading the keyboard from the CIA has the potential to miss key presses, requires
translating CIA signals to keyboard characters in software, and requires managing
typing features such as key repeat in software as well.
For greater accuracy and ease of coding in common typing-style keyboard applica-
tions, the MEGA65 provides a typing event queue implemented directly in hardware.
A typing event occurs when the user presses a non-modifier key, holding zero or more
modifier keys down while doing so. The typing event queue remembers the key being
pressed and the modifiers being held, for up to a certain number of events. The pro-
gram is expected to dequeue each event as it is processed, making room in hardware
memory for new events. A program can read typing events as either PETSCII or ASCII
values directly from hardware registers. The modifier keys associated with the event
are also readable from a register.
The MEGA65 KERNAL uses the typing event queue to power getin and the BASIC GET
and GETKEY commands. Reading a key using any of these methods dequeues a typing
event from the queue.

USING THE TYPING EVENT QUEUE


The status of the typing event queue is visible on these registers:
Name I/O address Description
ASCIIKEY $D610 The top event as ASCII, $FF if no interpretation, or
$00 if queue is empty
PETSCIIKEY $D619 The top event as PETSCII, or $FF if no interpretation
MODKEY $D60A[0:6] Modifier keys held during the event
KEYQUEUE $D60A[7] 1 if the queue is non-empty
The bits of MODKEY correspond to these modifier keys, with 1 meaning the key was
held during the event:

F-3
Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
CAPS NO ALT CTRL SHIFT SHIFT
LOCK SCROLL ` right left

If ASCIIKEY ($D610) reads as $00, then the typing queue is empty. A program must
test ASCIIKEY for $00, or test KEYQUEUE (bit 7 of $D60A), to determine if the queue
is empty. The PETSCIIKEY register does not have a value that represents the empty
queue.
A given typing event may or may not have an ASCII or PETSCII interpretation. A typing
event that has neither is not added to the queue. If an event has an ASCII interpre-
tation but not a PETSCII interpretation, then ASCIIKEY will contain the ASCII value,
and PETSCIIKEY will contain $FF. Similarly, ASCIIKEY will contain $FF for typing events
without an ASCII interpretation. The program is expected to use the other registers
to determine whether the queue is empty, and skip typing events that do not have an
interpretation useful to the program.
NOTE: ASCII also uses $FF to represent the ”umlaut-y” character (Alt+Y). In this case
(and only in this case), PETSCIIKEY is $59 (regular Y). If your program needs to distin-
guish between a non-ASCII typing event and Alt+Y, test whether PETSCIIKEY is $59
when ASCIIKEY is $FF.
To dequeue the top typing event, write any value to either ASCIIKEY ($D610) or
PETSCIIKEY ($D619). If the queue has another event, it becomes visible on the regis-
ters. Otherwise, the registers go to their empty queue state.

Reading Immediate Modifier Keys


In addition to recording the modifier keys pressed during a typing event, a program
can read the immediate state of the modifier keys with register $D611. This uses the
same bit pattern as MODKEY. See the table, above.
Remember that the immediate modifier key register represents the current state of the
modifier keys being held, which may be different from the modifier keys held during
the typing event at the top of the queue.

Interpreting ASCII Typing Events


The ASCIIKEY register makes it possible to read entry of the ASCII symbols not available
in PETSCII, including {, _ and |, which are not possible to type on a normal C64 and
C128 keyboards. The keyboard and the ASCII interpretation supports most Latin-1
code-page characters, allowing the entry of many accented characters. These keys
are entered by holding down ` and pressing other keys or key-combinations. The
use of ASCII or Unicode basic-Latin symbols not present in the PETSCII character set
requires the use of a font that contains these symbols, and software which supports
them.

F-4
The following tables show the hex value and Unicode character that will be produced
by each key combination on the ASCIIKEY register. One table is provided for pressing
SHIFT CTRL ALT
a key on its own, and one table for each of the , , ` , and keys.
Keys pressed alone:
Key Code Unicode Key Code Unicode Key Code Unicode
INST
DEL $14 �
RETURN
$0D → $1D �
F7 $F7 ÷ F1 $F1 ñ F3 $F3 ó
F5 $F5 õ ↓ $11 � 3 $33 3
W $77 w A $61 a 4 $34 4
Z $7A z S $73 s E $65 e
SHIFT
left $00 5 $35 5 R $72 r
D $64 d 6 $36 6 C $63 c
F $66 f T $74 t X $78 x
7 $37 7 Y $79 y G $67 g
8 $38 8 B $62 b H $68 h
U $75 u V $76 v 9 $39 9
I $69 i J $6A j 0 $30 0
M $6D m K $6B k O $6F o
N $6E n + $2B + P $70 p
L - .
$6C l $2D - $2E .
: @ ,
$3A : $40 @ $2C ,
£ $A3 £ * $2A * ; $3B ;
CLR
HOME $13 �
SHIFT
right $00 = $3D =
↑ $AF ¯ / $2F / 1 $31 1
← $5F _
CTRL
$00 2 $32 2
SPC $20 ` $00 Q $71 q
RUN NO TAB
STOP $03 � SCROLL $00 $09 �
ALT
$00
HELP
$1F � F9 $F9 ù
F11 $FB û F13 $FD ý
ESC
$1B �

F-5
SHIFT
Keys pressed with
Key Code Unicode Key Code Unicode Key Code Unicode
INST
DEL $94 �
RETURN
$0D → $9D �
F7 $F8 ø F1 $F2 ò F3 $F4 ô
F5 $F6 ö ↓ $91 � 3 $23 #
W $57 W A $41 A 4 $24 $
Z $5A Z S $53 S E $45 E
SHIFT
left $00 5 $25 % R $52 R
D $44 D 6 $26 & C $43 C
F $46 F T $54 T X $58 X
7 $27 ' Y $59 Y G $47 G
8 $28 ( B $42 B H $48 H
U $55 U V $56 V 9 $29 )
I $49 I J $4A J 0 $7B {
M $4D M K $4B K O $4F O
N $4E N + $00 P $50 P
L - .
$4C L $00 $3E >
: @ ,
$5B [ $00 $3C <
£ $E0 à * $00 ; $5D ]
CLR
HOME $93 �
SHIFT
right $00 = $5F _
↑ $00 / $3F ? 1 $21 !
← $60 `
CTRL
$00 2 $22 "
SPC $20 ` $00 Q $51 Q
RUN NO TAB
STOP $A3 £ SCROLL $00 $0F �
ALT
$00
HELP
$1F � F9 $FA ú
F11 $FC ü F13 $FE þ
ESC
$1B �

F-6
CTRL
Keys pressed with
Key Code Unicode Key Code Unicode Key Code Unicode
INST
DEL $94 �
RETURN
$0D → $9D �
F7 $F8 ø F1 $F2 ò F3 $F4 ô
F5 $F6 ö ↓ $91 � 3 $1C �
W $17 � A $01 � 4 $9F �
Z $1A � S $13 � E $05 �
SHIFT
left $00 5 $9C � R $12 �
D $04 � 6 $1E � C $03 �
F $06 � T $14 � X $18 �
7 $1F � Y $19 � G $07 �
8 $9E � B $02 � H $08 �
U $15 � V $16 � 9 $12 �
I $09 � J $0A � 0 $00
M $0D K $0B � O $0F �
N $0E � + $2B + P $10 �
L - .
$0C � $2D - $2E .
: @ ,
$3A : $40 @ $2C ,
£ $00 * $EF ï ; $3B ;
CLR
HOME $93 �
SHIFT
right $00 = $3D =
↑ $00 / $2F / 1 $90 �
← $60 `
CTRL
$00 2 $05 �
SPC $20 ` $00 Q $11 �
RUN NO TAB
STOP $A3 £ SCROLL $00 $0F �
ALT
$00
HELP
$1F � F9 $FA ú
F11 $FC ü F13 $FE þ
ESC
$1B �

F-7
Keys pressed with `
Key Code Unicode Key Code Unicode Key Code Unicode
INST
DEL $94 �
RETURN
$0D → $ED í
F7 $F8 ø F1 $F2 ò F3 $F4 ô
F5 $F6 ö ↓ $EE î 3 $96 �
W $D7 × A $C1 Á 4 $97 �
Z $DA Ú S $D3 Ó E $C5 Å
SHIFT
left $00 5 $98 � R $D2 Ò
D $C4 Ä 6 $99 � C $C3 Ã
F $C6 Æ T $D4 Ô X $D8 Ø
7 $9A � Y $D9 Ù G $C7 Ç
8 $9B � B $C2 Â H $C8 È
U $D5 Õ V $D6 Ö 9 $92 �
I $C9 É J $CA Ê 0 $81 �
M $CD Í K $CB Ë O $CF Ï
N $CE Î + $2B + P $D0 Ð
L - .
$CC Ì $2D - $7C |
: @ ,
$7B { $40 @ $7E ~
£ $00 * $2A * ; $7D }
CLR
HOME $93 �
SHIFT
right $00 = $5F _
↑ $00 / $5C \ 1 $81 �
← $60 `
CTRL
$00 2 $95 �
SPC $20 ` $00 Q $D1 Ñ
RUN NO TAB
STOP $A3 £ SCROLL $00 $EF ï
ALT
$00
HELP
$1F � F9 $FA ú
F11 $FC ü F13 $FE þ
ESC
$1B �

F-8
ALT
Keys pressed with
Key Code Unicode Key Code Unicode Key Code Unicode
INST
DEL $7F �
RETURN
$00 → $DF ß
F7 $DE Þ F1 $B9 ¹ F3 $B2 ²
F5 $B3 ³ ↓ $00 3 $A4 ¤
W $AE ® A $E5 å 4 $A2 ¢
Z $F7 ÷ S $A7 § E $E6 æ
SHIFT
left $00 5 $B0 ° R $AE ®
D $F0 ð 6 $A5 ¥ C $E7 ç
F $00 T $FE þ X $D7 ×
7 $B4 ´ Y $FF ÿ G $E8 è
8 $E2 â B $FA ú H $FD ý
U $FC ü V $D3 Ó 9 $DA Ú
I $ED í J $E9 é 0 $DB Û
M $B5 µ K $E1 á O $F8 ø
N $F1 ñ + $B1 ± P $B6 ¶
L - .
$F3 ó $AC ¬ $BB »
: @ ,
$E4 ä $A8 ¨ $AB «
£ $A3 £ * $B7 · ; $E4 ä
CLR
HOME $DC Ü
SHIFT
right $DD Ý = $A6 ¦
↑ $AF ¯ / $BF ¿ 1 $A1 ¡
← $B8 ¸
CTRL
$00 2 $AA ª
SPC $A0 ` $00 Q $A9 ©
RUN NO TAB
STOP $BA º SCROLL $00 $C0 À
ALT
$00
HELP
$1F � F9 $BC ¼
F11 $BD ½ F13 $BE ¾
ESC
$DB Û

Unicode Basic-Latin Keyboard Map


The following tables are a convenient reference to help you find a key combination
that will produce the desired ASCII/Unicode basic-Latin character code. Note that
a very few codes are difficult to type in practice, because they are mapped to key

F-9
TAB
combinations that perform other functions. In particular, the combination of `+
is normally overridden by the Matrix Mode hardware debug feature.

+$00 +$10 +$20 +$30


$00
ALT
+
RETURN
� F9 SPC 0 0
$01 � A � ↓ ! 1 1 1
$02 � B � 9 " 2 2 2
$03 �
RUN
STOP �
CLR
HOME # 3 3 3
$04 � D �
INST
DEL $ 4 4 4
$05 � 2 � F9 % 5 5 5
$06 � F � F11 & 6 6 6
$07 � G � F11 ' 7 7 7
$08 � H �
TAB
( 8 8 8
$09 �
TAB
� F13 ) 9 9 9
$0a � J � F13 * * : :

$0b � K �
ESC
+ + ; ;
L £ , ,
$0c � � , <
$0d
RETURN
� → - - = =
. .
$0e � N � ↑ . >
$0f � O �
ALT
+
HELP
/ / ? /

F-10
+$40 +$50 +$60 +$70
$00 @ @ P P ` ← p P
$01 A A Q Q a A q Q
$02 B B R R b B r R
$03 C C S S c C s S
$04 D D T T d D t T
$05 E E U U e E u U
$06 F F V V f F v V
$07 G G W W g G w W
$08 H H X X h H x X
$09 I I Y Y i I y Y
$0a J J Z Z j J z Z
$0b K K [ : k K { :
L £ L .
$0c L \ l |
$0d M M ] ; m M } ;
,
$0e N N ^ ↑ n N ~
$0f O O _ ← o O �
ALT
+
INST
DEL

F-11
+$80 +$90 +$A0 +$B0
$00 � � 1 ALT
+ SPC °
ALT
+ 5
$01 � 1 � ↓ ¡
ALT
+ 1 ±
ALT
+ +
$02 � � 0 ¢
ALT
+ 4 ²
ALT
+ F3
$03 �
RUN
STOP �
CLR
HOME £
ALT
+ £ ³
ALT
+ F5
$04 �
HELP

INST
DEL ¤
ALT
+ 3 ´
ALT
+ 7
$05 � F1 � 2 ¥
ALT
+ 6 µ
ALT
+ M
$06 � F3 � 3 ¦
ALT
+ = ¶
ALT
+ P
$07 � F5 � 4 §
ALT
+ S ·
ALT
+ *
$08 � F7 � 5 ¨
ALT
+ @ ¸
ALT
+ ←

$09 � F1 � 6 ©
ALT
+ Q ¹
ALT
+ F1
$0a � F3 � 7 ª
ALT
+ 2 º
ALT
+
RUN
STOP

F5 8 ALT , ALT .
$0b � � « + » +
$0c � F7 � 5 ¬
ALT
+ - ¼
ALT
+ F9
$0d �
RETURN
� → Z ½
ALT
+ F11
$0e � � 8 ®
ALT
+ W ¾
ALT
+ F13
$0f � � 4 ¯
ALT
+ ↑ ¿
ALT
+ /

F-12
+$C0 +$D0 +$E0 +$F0
$00 À
ALT
+
TAB
Ð P à
SHIFT
+ £ ð
ALT
+ D
$01 Á A Ñ Q á
ALT
+ K ñ
ALT
+ N
$02 Â B Ò R â
ALT
+ 8 ò ` + F1
$03 Ã C Ó
ALT
+ V ã ó
ALT
+ L
$04 Ä D Ô T ä
ALT
+ : ô ` + F3
$05 Å E Õ U å
ALT
+ A õ F5
$06 Æ F Ö V æ
ALT
+ E ö ` + F5
$07 Ç G ×
ALT
+ X ç
ALT
+ C ÷
ALT
+ Z
$08 È H Ø X è
ALT
+ G ø
ALT
+ O
$09 É I Ù Y é
ALT
+ J ù F9
$0a Ê J Ú
ALT
+ 9 ê ú
ALT
+ B
$0b Ë K Û
ALT
+ 0 ë û F11
$0c Ì L Ü
ALT
+
CLR
HOME ì ü
ALT
+ U
$0d Í M Ý
ALT
+
SHIFT
right í
ALT
+ I ý
ALT
+ H
$0e Î N Þ
ALT
+ F7 î ` + ↓ þ
ALT
+ T
$0f Ï O ß
ALT
+ → ï ` +
TAB
ÿ
ALT
+ Y

KEYBOARD THEORY OF OPERATION


The MEGA65 keyboard is a full mechanical keyboard, constructed as a matrix. Every
key switch is fitted with a diode, which allows the keyboard hardware to detect when
any combination of keys are pressed at the same time. This matrix is scanned by the
firmware in the CPLD chip on the keyboard PCB many thousands of times per second.
The matrix arrangement of the MEGA65 keyboard does not use the C65 matrix layout.
Instead, the CPLD also sorts the natural matrix of the keyboard into the C65 key-
board matrix order, and transmits this serially via the keyboard cable to the MEGA65
mainboard. The MEGA65 core reads this serial data and uses it to reconstruct a C65-
compatible virtual keyboard in the FPGA. This virtual keyboard also takes input from the
on-screen-keyboard, synthetic keyboard injection mechanism and/or other keyboard
input sources depending on the MEGA65 model.
The end-to-end latency of the keyboard is less than one milli-second.

F-13
C65 KEYBOARD MATRIX
The MEGA65 keyboard presents to legacy software as a C65-compatible keyboard.
In this mode all keys are available for standard PETSCII scanning as per normal. There
is also a hardware accelerated mechanism for detecting arbitrary combinations of
keys that are held down. This is via $D614 (decimal 54804). Writing a value between
0 and 8 to this register selects the corresponding row of the C65 keyboard matrix,
which can then be read back from $D613. If a bit is zero, then it means that the key
is being pressed. If the bit is one, then the key is not being pressed.
The left and up cursor keys are special, because they logically press cursor right or
down, and the right shift key. To be able to differentiate between these two situations,
you can read $D60F: Bit 0 is the state of the left cursor key and bit 1 is the state of
the up cursor key.
The C65 keyboard matrix layout is as follows:

0 1 2 3 4 5 6 7 8
INST NO
0 DEL 3 5 7 9 + £ 1 SCROLL

RETURN TAB
1 W R Y I P * ←
2 → A D G J L ;
CTRL ALT

3 F7 4 6 8 0 -
CLR
HOME 2
HELP

4 F1 Z C B M .
SHIFT
right SPC F9
5 F3 S F H K : = ` F11
6 F5 E T U O @ ↑ Q F13
7 ↓ SHIFT
left X V N , /
RUN
STOP
ESC

Note that the keyboard matrix is identical to the C64 keyboard matrix, except for the
addition of one extra column on the right-hand side. The cursor left and up keys on
the MEGA65 and C65 are implemented as cursor right and down, but with the right
CAPS
shift key applied. This enables them to work in C64-mode. LOCK is not part of the
matrix, but has its own dedicated line. Its status can be read from bit 6 of register
$D611 (decimal 54801):
The numbers across the top indicate the columns of the matrix, and the numbers down
the left indicate the rows. The unique scan code of a key is calculated by multiplying
CLR
the column by eight, and adding the row. For example, HOME is in column 6 and row
3. Thus its scan code is 6 × 8 + 3 = 51.

F-14
SYNTHETIC KEY EVENTS
The MEGA65 keyboard interface logic allows the use of a variety of keyboard types
and alternatives. This is partly to cater for the early development on general purpose
FPGA boards, the MEGAphone with its touch interface, and the desktop versions of
the MEGA65 architecture. The depressing of up to 3 three keys can be simulated via
the registers $D615 – $D617 (decimal 54,805 – 54,807). By setting the lower 7 bits
of these registers to any C65 keyboard scan code, the MEGA65 will behave as though
RESTORE
that key is being held down. exists outside of the keyboard matrix, as on the
RESTORE
C64. To simulate holding down, write $52 (ASCII code for a capital R), and to
RESTORE
simulate a quick tap of the , write $72 (ASCII code for a lowercase R). Another
value must be written after the $72 value has been written, if you wish to simulate
RESTORE
multiple presses of .
To release a key, write $7F (decimal 127) to the register containing the active key
press. For example, to simulate briefly pressing the * key, the following could be used:

POKE DEC("D615"),6*8+1:FORI=1TO100:NEXT:POKE DEC("D615"),127

The FOR loop provides a suitable delay to simulate holding the key for a short time.
All statements should be on a single line like this, if entered directly into the BASIC
interpreter, because otherwise the MEGA65 will continue to act as though the * key
is being held down, making it rather difficult to enter the other commands!

KEYBOARD LED CONTROL


The LEDs on the MEGA65’s keyboard are normally controlled automatically by the sys-
tem. However, it is also possible to place them under user control. This is activated
by setting bit 7 (decimal 128) of $D61D (decimal 54813). The lower bits indicate
which keyboard LED to set. Values 0 through 11 correspond to the red, green and
blue channels of the four LEDs. The table below shows the specific values:
0 left-half of DRIVE LED, RED
1 left-half of DRIVE LED, GREEN
2 left-half of DRIVE LED, BLUE
3 right-half of DRIVE LED, RED
4 right-half of DRIVE LED, GREEN
5 right-half of DRIVE LED, BLUE
6 left-half of POWER LED, RED

F-15
7 left-half of POWER LED, GREEN
8 left-half of POWER LED, BLUE
9 right-half of POWER LED, RED
10 right-half of POWER LED, GREEN
11 right-half of POWER LED, BLUE
Register $D61E (decimal 54814) is used to specify the intensity that should be given
to a specific LED (value between 0 and 255).
Note that whatever value is in $D61E gets written to whatever register is currently
selected in $D61D. Therefore to safely change the intensity of one specific LED en-
sure $D61D is set to 255 first. This prevents affecting another LED when we set the
intended intensity value into $D61E. Now select the target LED by setting $D61D to
128 + x, where x is a value from the table above. Hold the $D61D, $D61E configura-
tion for approximately one millisecond to give the keyboard logic enough time to pick
up the new intensity value for the selected LED.
To return the keyboard LEDs to hardware control, clear bit 7 of $D61D.
For example to pulse the keyboard LEDs red and blue, the following program could be
used:

10 REM ENABLE SOFTWARE CONTROL OF LEDS


20 POKEDEC("D61D"),128
30 REM SET ALL LEDS TO OFF
40 POKEDEC("D61E"),0
50 FORI=0TO11:POKEDEC("D61D"),128+I:NEXT
60 REM SELECT RED CHANNEL OF RIGHT MOST LED
70 POKEDEC("D61D"),128
80 REM CYCLE FROM BLACK TO RED AND BACK
90 FORI=0TO255:POKEDEC("D61E"),I:NEXT
100 FORI=255TO0STEP-1:POKEDEC("D61E"),I:NEXT
110 REM SELECT BLUE CHANNEL OF LEFT MOST LED
120 POKEDEC("D61D"),128+8
130 REM CYCLE FRO BLACK TO BLUE AND BACK
140 FORI=0TO255:POKEDEC("D61E"),I:NEXT
150 FORI=255TO0STEP-1:POKEDEC("D61E"),I:NEXT
160 GOTO70

F-16
NATIVE KEYBOARD MATRIX
The native keyboard matrix is accessible only from the CPLD on the MEGA65’s key-
board. If you are programming the MEGA65 computer, you should not need to use
this.

0
F5
25 6
1 9 26 T
2 I 27 G
3 K 28 B
4 < 29 ← (cursor left)
INST
5 DEL 30 +
CLR 31 :
6 HOME
NO
7 O 32 SCROLL

8 F3 33 5

9 8 34 R

10 U 35 F

11 J 36 V
12 M 37 SPACE

13 → 38 0
14 £ 39 L
15 = 40
CAPS
LOCK

16 F1 41 4
17 7 42 E
18 Y 43 D
19 H 44 C
20 N 45 Reserved
21 ↓ 46
HELP

22 -
RETURN
47
23 ;
ALT
24 Reserved 48

F-17
49 3 65 1
50 W 66 Reserved
51 S 67 Reserved
52 X 68 left
SHIFT
and
SHIFT
LOCK

53 ↑ (cursor up)
69 /
54 F13 70 F9
55 ↑ (next to RESTORE
) 71 @
RUN
56
ESC 72 STOP

57 2 73 ← (next to 1)
58 Q TAB
74
59 A
CTRL
60 Z 75
SHIFT
61 right 76 `

62 F11 77 >
63 * 78 F7
64 Reserved 79 P

F-18
APPENDIX G
System Palette
• System Palette
G-2
SYSTEM PALETTE
The following table describes the system colour palette as it is defined by default.
Colour palette indexes are used as values in the C@&() special array, and as argu-
ments for BASIC commands such as BACKGROUND, BORDER, COLOR, FOREGROUND,
HIGHLIGHT, PEN, and SCREEN CLR.
Index Red Green Blue Colour
0 0 0 0 Black
1 15 15 15 White
2 15 0 0 Red
3 0 15 15 Cyan
4 15 0 15 Purple
5 0 15 0 Green
6 0 0 15 Blue
7 15 15 0 Yellow
8 15 6 0 Orange
9 10 4 0 Brown
10 15 7 7 Light Red (Pink)
11 5 5 5 Dark Grey
12 8 8 8 Medium Grey
13 9 15 9 Light Green
14 9 9 15 Light Blue
15 11 11 11 Light Grey
16 14 0 0 Guru Meditation
17 15 5 0 Rambutan
18 15 11 0 Carrot
19 14 14 0 Lemon Tart
20 7 15 0 Pandan
21 6 14 6 Seasick Green
22 0 14 3 Soylent Green
23 0 15 9 Slimer Green
24 0 13 13 The Other Cyan
25 0 9 15 Sea Sky
26 0 3 15 Smurf Blue
27 0 0 14 Screen of Death
28 7 0 15 Plum Sauce
29 12 0 15 Sour Grape
30 15 0 11 Bubblegum
31 15 3 6 Hot Tamales

G-3
G-4
APPENDIX H
Decimal, Binary and
Hexadecimal
• Numbers
• Notations and Bases
• Operations
• Signed and Unsigned Numbers
• Bit-wise Logical Operators
• Converting Numbers
H-2
NUMBERS
Simple computer programs, such as most of the introductory BASIC programs in this
book, do not require an understanding of mathematics or much knowledge about the
inner workings of the computer. This is because BASIC is considered a high-level pro-
gramming language. It lets us program the computer somewhat indirectly, yet still
gives us control over the computer’s features. Most of the time, we don’t need to con-
cern ourselves with the computer’s internal architecture, which is why BASIC is user
friendly and accessible.
As you acquire deeper knowledge and become more experienced, you will often want
to instruct the computer to perform complex or specialised tasks that differ from the
examples given in this book. Perhaps for reasons of efficiency, you may also want to
exercise direct and precise control over the contents of the computer’s memory. This
is especially true for applications that deal with advanced graphics and sound. Such
operations are closer to the hardware and are therefore considered low-level. Some
simple mathematical knowledge is required to be able to use these low-level features
effectively.
The collective position of the tiny switches inside the computer—whether each switch
is on or off—is the state of the computer. It is natural to associate numerical concepts
with this state. Numbers let us understand and manipulate the internals of the machine
via logic and arithmetic operations. Numbers also let us encode the two essential and
important pieces of information that lie within every computer program: instructions
and data.
A program’s instructions tell a computer what to do and how to do it. For example, the
action of outputting a text string to the screen via the statement PRINT is an instruction.
The action of displaying a sprite and the action of changing the screen’s border colour
are instructions too. Behind the scenes, every instruction you give to the computer is
associated with one or more numbers (which, in turn, correspond to the tiny switches
inside the computer being switched on or off). Most of the time these instructions
won’t look like numbers to you. Instead, they might take the form of statements in
BASIC.
A program’s data consists of information. For example, the greeting “HELLO MEGA65!”
is PETSCII character data in the form of a text string. The graphical design of a sprite
might be pixel data in the form of a hero for a game. And the colour data of the
screen’s border might represent orange. Again, behind the scenes, every piece of
data you give to the computer is associated with one or more numbers. Data is some-
times given directly next to the statement to which it applies. This data is referred to
as a parameter or argument (such as when changing the screen colour with a BACK-
GROUND 1 statement). Data may also be given within the program via the BASIC
statement DATA which accepts a list of comma-separated values.
All such numbers—regardless of whether they represent instructions or data—reside in
the computer’s memory. Although the computer’s memory is highly structured, the com-
puter does not distinguish between instructions and data, nor does it have separate

H-3
areas of memory for each kind of information. Instead, both are stored in whichever
memory location is considered convenient. Whether a given memory location’s con-
tents is part of the program’s instructions or is part of the program’s data largely de-
pends on your viewpoint, the program being written and the needs of the programmer.
Although BASIC is a high-level language, it still provides statements that allow pro-
grammers to manipulate the computer’s memory efficiently. The statement PEEK lets
us read the information from a specified memory location: we can inspect the con-
tents of a memory address. The statement POKE lets us store information inside a
specified memory location: we can modify the contents of a memory address so that
it is set to a given value.

NOTATIONS AND BASES


We now take a look at numbers.
Numbers are ideas about quantity and magnitude. In order to manipulate numbers and
determine relationships between them, it’s important for them to have a unique form.
This brings us to the idea of the symbolic representation of numbers using a positional
notation. In this appendix we’ll restrict our discussion to whole numbers, which are
also called integers.
The decimal representation of numbers is the one with which you will be most com-
fortable since it is the one you were taught at school. Decimal notation uses the ten
Hindu-Arabic numerals 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9 and is thus referred to as a base
10 numeral system. As we shall see later, in order to express large numbers in decimal,
we use a positional system in which we juxtapose digits into columns to form a bigger
number.
For example, 53280 is a decimal number. Each such digit (0 to 9) in a decimal number
represents a multiple of some power of 10. When a BASIC statement (such as PEEK
or POKE) requires an integer as a parameter, that parameter is given in the decimal
form.
Although the decimal notation feels natural and comfortable for humans to use, mod-
ern computers, at their most fundamental level, use a different notation. This notation
is called binary. It is also referred to as a base 2 numeral system because it uses only
two Hindu-Arabic numerals: 0 and 1. Binary reflects the fact that each of the tiny
switches inside the computer must be in exactly one of two mutually exclusive states:
on or off. The number 0 is associated with off and the number 1 is associated with on.
Binary is the simplest notation that captures this idea. In order to express large num-
bers in binary, we use a positional system in which we juxtapose digits into columns to
form a bigger number and prefix it with a % sign.
For example, %1001 0110 is a binary number. Each such digit (0 or 1) in a binary
number represents a multiple of some power of 2.

H-4
We’ll see later how we can use special BASIC statements to manipulate the patterns
of ones and zeros present in a binary number to change the state of the switches
associated with it. Effectively, we can toggle individual switches on or off, as needed.
A third notation called hexadecimal is also often used. This is a base 16 numeral
system. Because it uses more than ten digits, we need to use some letters to represent
the extra digits. Hexadecimal uses the ten Hindu-Arabic digits 0 to 9 as well as the six
Latin alphabetic characters as “digits” (A, B, C, D, E and F) to represent the numbers
10 to 15. This gives a total of sixteen symbols for the numbers 0 to 15. To express a
large number in hexadecimal, we use a positional system in which we juxtapose digits
into columns to form a bigger number and prefix it with a $ sign.
For example, $E7 is a hexadecimal number. Each such digit (0 to 9 and A to F) in a
hexadecimal number represents a multiple of some power of 16.
Hexadecimal is not often used when programming in BASIC. It is more commonly used
when programming in low-level languages like machine code or assembly language.
It also appears in computer memory maps and its brevity makes it a useful notation,
so it is described here.
Always remember that decimal, binary and hexadecimal are just different notations
for numbers. A notation just changes the way the number is written (i.e., the way it
looks on paper or on the screen), but its intrinsic value remains unchanged. A notation
is essentially different ways of representing the same thing. The reason that we use
different notations is that each notation lends itself more naturally to a different task.
When using decimal, binary and hexadecimal for extended periods you may find it
handy to have a scientific pocket calculator with a programmer mode. Such cal-
culators can convert between bases with the press of a button. They can also add,
subtract, multiply and divide, and perform various bit-wise logical operations. See
Chapter/Appendix X on page X-3 as it contains a Base Conversion table for decimal,
binary, and hexadecimal for integers between 0 and 255.
The BASIC listing for this appendix is a utility program that converts individual numbers
into different bases. It can also convert multiple numbers within a specified range.
Although these concepts might be new now, with some practice they’ll soon seem like
second nature. We’ll look at ways of expressing numbers in more detail. Later, we’ll
also investigate the various operations that we can perform on such numbers.

Decimal
When representing integers using decimal notation, each column in the number is for a
different power of 10. The rightmost position represents the number of units (because
100 = 1) and each column to the left of it is 10 times larger than the column before
it. The rightmost column is called the units column. Columns to the left of it are
labelled tens (because 101 = 10), hundreds (because 102 = 100), thousands (because
103 = 1000), and so on.

H-5
To give an example, the integer 53280 represents the total of 5 lots of 10000, 3 lots
of 1000, 2 lots of 100, 8 lots of 10 and 0 units. This can be seen more clearly if we
break the integer up into distinct parts, by column.
Since
53280 = 50000 + 3000 + 200 + 80 + 0
we can present this as a table with the sum of each column at the bottom.
TEN THOUSANDS THOUSANDS HUNDREDS TENS UNITS
104 = 10000 103 = 1000 102 = 100 101 = 10 100 = 1
5 0 0 0 0
3 0 0 0
2 0 0
8 0
0
5 3 2 8 0
Another way of stating this is to write the expression using multiples of powers of 10.
53280 = (5 × 104 ) + (3 × 103 ) + (2 × 102 ) + (8 × 101 ) + (0 × 100 )
Alternatively
53280 = (5 × 10000) + (3 × 1000) + (2 × 100) + (8 × 10) + (0 × 1)
We now introduce some useful terminology that is associated with decimal numbers.
The rightmost digit of a decimal number is called the least significant digit, because,
being the smallest multiplier of a power of 10, it contributes the least to the number’s
magnitude. Each digit to the left of this digit has increasing significance. The leftmost
(non-zero) digit of the decimal number is called the most significant digit, because,
being the largest multiplier of a power of 10, it contributes the most to the number’s
magnitude.
For example, in the decimal number 53280, the digit 0 is the least significant digit
and the digit 5 is the most significant digit.
A decimal number a is m orders of magnitude greater than the decimal number b if a =
b×(10m ). For example, 50000 is three orders of magnitude greater than 50, because
it has three more zeros. This terminology can be useful when making comparisons
between numbers or when comparing the time efficiency or space efficiency of two
programs with respect to the sizes of the given inputs.
Note that unlike binary (which uses a conventional % prefix) and hexadecimal (which
uses a conventional $ prefix), decimal numbers are given no special prefix. In some
textbooks you might see such numbers with a subscript instead. So decimal numbers
will have a sub-scripted 10, binary numbers will have a sub-scripted 2, and hexadec-
imal numbers will have a sub-scripted 16.
Another useful concept is the idea of signed and unsigned decimal integers.

H-6
A signed decimal integer can be positive or negative or zero. To represent a signed
decimal integer, we prefix it with either a + sign or a – sign. (By convention, zero,
which is neither positive nor negative, is given the + sign.)
If, on the other hand, a decimal integer is unsigned it must be either zero or positive
and does not have a negative representation. This can be illustrated with the BASIC
statements PEEK and POKE. When we use PEEK to return the value contained within a
memory location, we get back an unsigned decimal number. For example, the state-
ment PRINT (PEEK (49152)) outputs the contents of memory location 49152 to the
screen as an unsigned decimal number. Note that the memory address that we gave
to PEEK is itself an unsigned integer. When we use POKE to store a value inside a
memory location, both the memory address and the value to store inside it are given
as unsigned integers. For example, the statement POKE 49152, 128 stores the un-
signed decimal integer 128 into the memory address given by the unsigned decimal
integer 49152.
Each memory location in the MEGA65 can store a decimal integer between 0 and
255. This corresponds to the smallest and largest decimal integers that can be repre-
sented using eight binary digits (eight bits). Also, the memory addresses are decimal
integers between 0 and 65535. This corresponds to the smallest and largest decimal
integers that can be represented using sixteen binary digits (sixteen bits).
Note that the largest number expressible using d decimal digits is 10d −1. (This number
will have d nines in its representation.)

Binary
Binary notation uses powers of 2 (instead of 10 which is for decimal). The rightmost
position represents the number of units (because 20 = 1) and each column to the left
of it is 2 times larger than the column before it. Columns to the left of the rightmost
column are the twos column (because 21 = 2), the fours column (because 22 = 4), the
eights column (because 23 = 8), and so on.
As an example, the integer %1101 0011 uses exactly eight binary digits and repre-
sents the total of 1 lot of 128, 1 lot of 64, 0 lots of 32, 1 lot of 16, 0 lots of 8, 0 lots
of 4, 1 lot of 2 and 1 unit.
We can break this integer up into distinct parts, by column.
Since
%1101 0011 = %1000 0000 + %100 0000 + %00 0000 + %1 0000 + %0000 + %000 + %10
+ %1
we can present this as a table with the sum of each column at the bottom.

H-7
ONE
HUNDRED AND SIXTY- THIRTY-
TWENTY-EIGHTS FOURS TWOS SIXTEENS EIGHTS FOURS TWOS UNITS
27 = 128 26 = 64 25 = 32 24 = 16 23 = 8 22 = 4 21 = 2 20 = 1
1 0 0 0 0 0 0 0
1 0 0 0 0 0 0
0 0 0 0 0 0
1 0 0 0 0
0 0 0 0
0 0 0
1 0
1
1 1 0 1 0 0 1 1
Another way of stating this is to write the expression in decimal, using multiples of
powers of 2.
%11010011 = (1×27 )+(1×26 )+(0×25 )+(1×24 )+(0×23 )+(0×22 )+(1×21 )+(1×20 )
Alternatively
%11010011 = (1×128)+(1×64)+(0×32)+(1×16)+(0×8)+(0×4)+(1×2)+(1×1)
which is the same as writing
%11010011 = 128 + 64 + 16 + 2 + 1
Binary has terminology of its own. Each binary digit in a binary number is called a bit.
In an 8-bit number the bits are numbered consecutively with the least significant (i.e.,
rightmost) bit as bit 0 and the most significant (i.e., leftmost) bit as bit 7. In a 16-bit
number the most significant bit is bit 15. A bit is said to be set if it equals 1. A bit is
said to be clear if it equals 0. When a particular bit has a special meaning attached
to it, we sometimes refer to it as a flag.
1 1 0 1 0 0 1 1
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

As mentioned earlier, each memory location can store an integer between 0 and 255.
The minimum corresponds to %0000 0000 and the maximum corresponds to %1111
1111, which are the smallest and largest numbers that can be represented using ex-
actly eight bits. The memory addresses use 16 bits. The smallest memory address,
represented in exactly sixteen bits, is %0000 0000 0000 0000 and this corresponds
to the smallest 16-bit number. Likewise, the largest memory address, represented in
exactly sixteen bits, is %1111 1111 1111 1111 and this corresponds to the largest
16-bit number.
It is often convenient to refer to groups of bits by different names. For example, eight
bits make a byte and 1024 bytes make a kilobyte. Half a byte is called a nibble. See
Chapter/Appendix X on page X-3 for the Units of Storage table for further informa-
tion.

H-8
Note that the largest number expressible using d binary digits is (in decimal) 2d − 1.
(This number will have d ones in its representation.)

Hexadecimal
Hexadecimal notation uses powers of 16. Each of the sixteen hexadecimal numerals
has an associated value in decimal.
Hexadecimal Decimal
Numeral Equivalent
$0 0
$1 1
$2 2
$3 3
$4 4
$5 5
$6 6
$7 7
$8 8
$9 9
$A 10
$B 11
$C 12
$D 13
$E 14
$F 15
The rightmost position in a hexadecimal number represents the number of ones (since
160 = 1). Each column to the left of this digit is 16 times larger than the column before
it. Columns to the left of the rightmost column are the 16-column (since 161 = 16),
the 256-column (since 162 = 256), the 4096-column (since 163 = 4096), and so on.
As an example, the integer $A3F2 uses exactly four hexadecimal digits and represents
the total of 10 lots of 4096 (because $A = 10), 3 lots of 256 (because $3 = 3), 15
lots of 16 (because $F = 15) and 2 units (because $2 = 2). We can break this integer
up into distinct parts, by column.
Since
$A3F2 = $A000 + $300 + $F0 + $2
we can present this as a table with the sum of each column at the bottom.

H-9
FOUR THOUSAND TWO HUNDRED
AND NINETY-SIXES AND FIFTY-SIXES SIXTEENS UNITS
163 = 4096 162 = 256 161 = 16 160 = 1
A 0 0 0
3 0 0
F 0
2
A 3 F 2
Another way of stating this is to write the expression in decimal, using multiples of
powers of 16.
$A3F2 = (10 × 163 ) + (3 × 162 ) + (15 × 161 ) + (2 × 160 )
Alternatively
$A3F2 = (10 × 4096) + (3 × 256) + (15 × 16) + (2 × 1)
which is the same as writing
$A3F2 = 40960 + 768 + 240 + 2
Again, like binary and decimal, the rightmost digit is the least significant and the left-
most digit is the most significant.
Each memory location can store an integer between 0 and 255, and this corresponds
to the hexadecimal numbers $00 and $FF. The hexadecimal number $FFFF corre-
sponds to 65535—the largest 16-bit number.
Hexadecimal notation is often more convenient to use and manipulate than binary.
Binary numbers consist of a longer sequence of ones and zeros, while hexadecimal is
much shorter and more compact. This is because one hexadecimal digit is equal to
exactly four bits. So a two-digit hexadecimal number comprises of eight bits with the
low nibble equalling the right digit and the high nibble equalling the left digit.
Note that the largest number expressible using d hexadecimal digits is (in decimal)
16d − 1. (This number will have d $F symbols in its representation.)

OPERATIONS
In this section we’ll take a tour of some familiar operations like counting and arithmetic,
and we’ll see how they apply to numbers written in binary and hexadecimal.
Then we’ll take a look at various logical operations using logic gates. These operations
are easy to understand. They’re also very important when it comes to writing programs
that have extensive numeric, graphic or sound capabilities.

H-10
Counting
If we consider carefully the process of counting in decimal, this will help us to under-
stand how counting works when using binary and hexadecimal.
Let’s suppose that we’re counting in decimal and that we’re starting at 0. Recall that
the list of numerals for decimal is (in order) 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9. Notice that
when we add 1 to 0 we obtain 1, and when we add 1 to 1 we obtain 2. We can
continue in this manner, always adding 1:
0+1=1
1+1=2
2+1=3
3+1=4
4+1=5
5+1=6
6+1=7
7+1=8
8+1=9
Since 9 is the highest numeral in our list of numerals for decimal, we need some way
of handling the following special addition: 9 + 1. The answer is that we can reuse our
old numerals all over again. In this important step, we reset the units column back to
0 and (at the same time) add 1 to the tens column. Since the tens column contained
a 0, this gives us 9 + 1 = 10. We say we “carried” the 1 over to the tens column while
the units column cycled back to 0.
Using this technique, we can count as high as we like. The principle of counting for
binary and hexadecimal is very much same, except instead of using ten symbols, we
get to use two symbols and sixteen symbols, respectively.
Let’s take a look at counting in binary. Recall that the list of numerals for binary is (in
order) just 0 and 1. So, if we begin counting at %0 and then add %1, we obtain %1
as the result:
%0 + %1 = %1
Now, the sum %1 + %1 will cause us to perform the analogous step: we reset the units
column back to zero and (at the same time) add %1 to the twos column. Since the
twos column contained a %0, this gives us %1 + %1 = %10. We say we “carried” the
%1 over to the twos column while the units column cycled back to %0. If we continue
in this manner we can count higher.
%1 + %1 = %10
%10 + %1 = %11
%11 + %1 = %100
%100 + %1 = %101
%101 + %1 = %110
%110 + %1 = %111
%111 + %1 = %1000

H-11
Now we’ll look at counting in hexadecimal. The list of numerals for hexadecimal is (in
order) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E and F. If we begin counting at $0 and
repeatedly add $1 we obtain:
$0 + $1 = $1
$1 + $1 = $2
$2 + $1 = $3
$3 + $1 = $4
$4 + $1 = $5
$5 + $1 = $6
$6 + $1 = $7
$7 + $1 = $8
$8 + $1 = $9
$9 + $1 = $A
$A + $1 = $B
$B + $1 = $C
$C + $1 = $D
$D + $1 = $E
$E + $1 = $F
Now, when we compute $F + $1 we must reset the units column back to $0 and add
$1 to the sixteens column as that number is “carried”.
$F + $1 = $10
Again, this process allows us to count as high as we like.

Arithmetic
The standard arithmetic operations of addition, subtraction, multiplication and division
are all possible using binary and hexadecimal.
Addition is done in the same way that addition is done using decimal, except that
we use base 2 or base 16 as appropriate. Consider the following example for the
addition of two binary numbers.
% 1 1 0
+ % 1 1 1
% 1 1 0 1

We obtain the result by first adding the units columns of both numbers. This gives us %0
+ %1 = %1 with nothing to carry into the next column. Then we add the twos columns
of both numbers: %1 + %1 = %0 with a %1 to carry into the next column. We then
add the fours columns (plus the carry) giving (%1 + %1) + %1 = %1 with a %1 to carry
into the next column. Last of all are the eights columns. Because these are effectively
both zero we only concern ourselves with the carry which is %1. So (%0 + %0) + %1 =
%1. Thus, %1101 is the sum.
Next is an example for the addition of two hexadecimal numbers.

H-12
$ 7 D
+ $ 6 9
$ E 6

We begin by adding the units columns of both numbers. This gives us $D + $9 = $6


with a $1 to carry into the next column. We then add the sixteens columns (plus the
carry) giving ($7 + $6) + $1 = $E with nothing to carry and so $E6 is the sum.
We now look at subtraction. As you might suspect, binary and hexadecimal subtraction
follows a similar process to that of subtraction for decimal integers.
Consider the following subtraction of two binary numbers.
% 1 0 1 1
- % 1 1 0
% 1 0 1

Starting in the units columns we perform the subtraction %1 - %0 = %1. Next, in the
twos columns we perform another subtraction %1 - %1 = %0. Last of all we subtract
the fours columns. This time, because %0 is less than %1, we’ll need to borrow a %1
from the eights column of the top number to make the subtraction. Thus we compute
%10 - %1 = %1 and deduct %1 from the eights column. The eights columns are now
both zeros. Since %0 - %0 = %0 and because this is the leading digit of the result we
can drop it from the final answer. This gives %101 as the result.
Let’s now look at the subtraction of two hexadecimal numbers.
$ 3 D
- $ 1 F
$ 1 E

To perform this subtraction we compute the difference of the units columns. In order
to do this, we note that because $D is less than $F we will need to borrow $1 from the
sixteens column of the top number to make the subtraction. Thus, we compute $1D -
$F = $E and also compute $3 - $1 = $2 in the sixteens column for the for the $1 that
we just borrowed. Next, we compute the difference of the sixteens column as $2 - $1
= $1. This gives us a final answer of $1E.
We won’t give in depth examples of multiplication and division for binary and hex-
adecimal notation. Suffice to say that principles parallel those for the decimal system.
Multiplication is repeated addition and division is repeated subtraction.
We will, however, point out a special type of multiplication and division for both binary
and hexadecimal. This is particularly useful for manipulating binary and hexadecimal
numbers.
For binary, multiplication by two is simple—just shift all bits to the left by one position
and fill in the least significant bit with a %0. Division by two is simple too—just shift all
bits to the right by one position and fill in the most significant bit with a %0. By doing
these repeatedly we can multiply and divide by powers of two with ease.

H-13
Thus the binary number %111, when multiplied by eight has three extra zeros on the
end of it and is equal to %111000. (Recall that 23 = 8.) And the binary number
%10100, when divided by four has two less digits and equals %101. (Recall that
22 = 4.)
These are called left and right bit shifts. So if we say that we shift a number to the left
four bit positions, we really mean that we multiplied it by 24 = 16.
For hexadecimal, the situation is similar. Multiplication by sixteen is simple—just shift
all digits to the left by one position and fill in the rightmost digit with a $0. Division
by sixteen is simple too—just shift all digits to the right by one position. By doing this
repeatedly we can multiply and divide by powers of sixteen with ease.
Thus the hexadecimal number $F, when multiplied 256 has two extra zeros on the end
of it and is equal to $F00. (Recall that 162 = 256.) And the hexadecimal number $EA0,
when divided by sixteen has one less digit and equals $EA. (Recall that 161 = 16.)

Logic Gates
There exist several so-called logic gates. The fundamental ones are NOT, AND, OR
and XOR.
They let us set, clear and invert specific binary digits. For example, when dealing with
sprites, we might want to clear bit 6 (i.e., make it equal to 0) and set bit 1 (i.e., make
it equal to 1) at the same time for a particular graphics chip register. Certain logic
gates will, when used in combination, let us do this.
Learning how these logic gates work is very important because they are the key to
understanding how and why the computer executes programs as it does.
All logic gates accept one or more inputs and produce a single output. These inputs
and outputs are always single binary digits (i.e., they are 1-bit numbers).
The NOT gate is the only gate that accepts exactly one bit as input. All other gates—
AND, OR, and XOR—accept exactly two bits as input. All gates produce exactly one
output, and that output is a single bit.
First, let’s take a look at the simplest gate, the NOT gate.
The NOT gate behaves by inverting the input bit and returning this resulting bit as its
output. This is summarised in the following table.
INPUT X OUTPUT
0 1
1 0
We write NOT x where x is the input bit.
Next, we take a look at the AND gate.

H-14
As mentioned earlier, the AND gate accepts two bits as input and produces a single
bit as output. The AND gate behaves in the following manner. Whenever both input
bits are equal to 1 the result of the output bit is 1. For all other inputs the result of the
output bit is 0. This is summarised in the following table.
INPUT X INPUT Y OUTPUT
0 0 0
0 1 0
1 0 0
1 1 1
We write x AND y where x and y are the input bits.
Next, we take a look at the OR gate.
The OR gate accepts two bits as input and produces a single bit as output. The OR
gate behaves in the following manner. Whenever both input bits are equal to 0 the
result is 0. For all other inputs the result of the output bit is 1. This is summarised in
the following table.
INPUT X INPUT Y OUTPUT
0 0 0
0 1 1
1 0 1
1 1 1
We write x OR y where x and y are the input bits.
Last of all we look at the XOR gate.
The XOR gate accepts two bits as input and produces a single bit as output. The XOR
gate behaves in the following manner. Whenever both input bits are equal in value the
output bit is 0. Otherwise, both input bits are unequal in value and the output bit is 1.
This is summarised in the following table.
INPUT X INPUT Y OUTPUT
0 0 0
0 1 1
1 0 1
1 1 0
We write x XOR y where x and y are the input bits.
Note that there do exist some other gates. They are easy to construct.
• NAND gate: this is an AND gate followed by a NOT gate
• NOR gate: this is an OR gate followed by a NOT gate
• XNOR gate: this is an XOR gate followed by a NOT gate

H-15
SIGNED AND UNSIGNED NUMBERS
So far we’ve largely focused on unsigned integers. Unsigned integer have no positive
or negative sign. They are always assumed to be positive. (For this purpose, zero is
regarded as positive.)
Signed numbers, as mentioned earlier, can have a positive sign or a negative sign.
Signed numbers are represented by treating the most significant bit as a sign bit. This
bit cannot be used for anything else. If the most significant bit is 0 then the result is
interpreted as having a positive sign. Otherwise, the most significant bit is 1, and the
result is interpreted as having a negative sign.
A signed 8-bit number can represent positive-sign numbers between 0 and 127, and
negative-sign numbers between -1 and -128.
A signed 16-bit number can represent positive-sign numbers between 0 and 32767,
and negative-sign numbers between -1 and -32768.
Reserving the most significant bit as the sign of the signed number effectively halves
the range of the available positive numbers (i.e., compared to unsigned numbers), with
the trade-off being that we gain an equal quantity of negative numbers instead.
To negate any signed number, every bit in the signed number must be inverted and then
%1 must added to the result. Thus, negating %0000 0101 (which is the signed number
+5) gives %1111 1011 (which is the signed number -5). As expected, performing the
negation of this negative number gives us +5 again.

BIT-WISE LOGICAL OPERATORS


The BASIC statements NOT, AND, OR and XOR have functionality similar to that of the
logic gates that they are named after.
The NOT statement must be given a 16-bit signed decimal integer as a parameter. It
returns a 16-bit signed decimal integer as a result.
In the following example, all sixteen bits of the signed decimal number +0 are equal to
0. The NOT statement inverts all sixteen bits as per the NOT gate. This sets all sixteen
bits. If we interpret the result as a signed decimal number, we obtain the answer of
-1.

PRINT (NOT 0)
-1

As expected, repeating the NOT statement on the parameter of -1 gets us back to


where we started, since all sixteen set bits become cleared.

H-16
PRINT (NOT -1)
0

The AND statement must be given two 16-bit signed decimal integers as parameters.
The second parameter is called the bit mask. The statement returns a 16-bit signed
decimal integer as a result, having changed each bit as per the AND gate.
In the following example, the number +253 is used as the first parameter. As a 16-bit
signed decimal integer, this is equivalent to the following number in binary: %0000
0000 1111 1101. The AND statement uses a bit mask as the second parameter with
a 16-bit signed decimal value of +239. In binary this is the number %0000 0000
1110 1110. If we use the AND logic gate table on corresponding pairs of bits, we
obtain the 16-bit signed decimal integer +237 (which is %0000 0000 1110 1100 in
binary).

PRINT (253 AND 239)


237

We can see this process more clearly in the following table.


% 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1
AND % 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 0
% 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0

Notice that each bit in the top row passes through unchanged wherever there is a 1
in the mask bit below it. Otherwise the bit in that position gets cleared.
The OR statement must be given two 16-bit signed decimal integers as parameters.
The second parameter is called the bit mask. The statement returns a 16-bit signed
decimal integer as a result, having changed each bit as per the OR gate.
In the following example, the number +240 is used as the first parameter. As a 16-bit
signed decimal integer, this is equivalent to the following number in binary: %0000
0000 1111 0000. The OR statement uses a bit mask as the second parameter with a
16-bit signed decimal value of +19. In binary this is the number %0000 0000 0001
0011. If we use the OR logic gate table on corresponding pairs of bits, we obtain the
16-bit signed decimal integer +243 (which is %0000 0000 1111 0011 in binary).

PRINT (240 OR 19)


243

We can see this process more clearly in the following table.


% 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0
OR % 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1
% 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1

H-17
Notice that each bit in the top row passes through unchanged wherever there is a 0
in the mask bit below it. Otherwise the bit in that position gets set.
Next we look at the XOR statement. This statement must be given two 16-bit unsigned
decimal integers as parameters. The second parameter is called the bit mask. The
statement returns a 16-bit unsigned decimal integer as a result, having changed each
bit as per the XOR gate.
In the following example, the number 14091 is used as the first parameter. As a 16-bit
unsigned decimal integer, this is equivalent to the following number in binary: %0011
0111 0000 1011. The XOR statement uses a bit mask as the second parameter with
a 16-bit unsigned decimal value of 8653. In binary this is the number %0010 0001
1100 1101. If we use the XOR logic gate table on corresponding pairs of bits, we
obtain the 16-bit unsigned decimal integer 5830 (which is %0001 0110 1100 0110
in binary).

PRINT (XOR(14091,8653))
5830

We can see this process more clearly in the following table.


% 0 0 1 1 0 1 1 1 0 0 0 0 1 0 1 1
XOR % 0 0 1 0 0 0 0 1 1 1 0 0 1 1 0 1
% 0 0 0 1 0 1 1 0 1 1 0 0 0 1 1 0

Notice that when the bits are equal the resulting bit is 0. Otherwise the resulting bit
is 1.
Much of the utility of these bit-wise logical operators comes through combining them
together into a compound statement. For example, the VIC II register to enable sprites
is memory address 53269. There are eight sprites (numbered 0 to 7) with each bit
corresponding to a sprite’s status. Now suppose we want to switch off sprite 5 and
switch on sprite 1, while leaving the statuses of the other sprites unchanged. We can
do this with the following BASIC statement which combines an AND statement with
an OR statement.

POKE 53269, (((PEEK(53269)) AND 223) OR 2)

The technique of using PEEK on a memory address and combining the result with bit-
wise logical operators, followed by a POKE to that same memory address is very com-
mon.

H-18
CONVERTING NUMBERS
The program below is written in BASIC. It does number conversion for you. Type it in
and save it under the name “CONVERT.BAS”.
RETURN
To execute the program, type RUN and press .
The program presents you with a series of text menus. You may choose to convert
a single decimal, binary or hexadecimal number. Alternatively, you may choose to
convert a range of such numbers.
The program can convert numbers in the range of 0 to 65535.

H-19
10 REM ****************************
20 REM * *
30 REM * INTEGER BASE CONVERTER *
40 REM * *
50 REM ****************************
60 POKE 0,65: BORDER 6: BACKGROUND 6: FOREGROUND 1
70 DIM P(15)
80 E$ = "STARTING INTEGER MUST BE LESS THAN OR EQUAL TO ENDING INTEGER"
90 FOR N = 0 TO 15
100 : P(N) = 2 ^ N
110 NEXT N
120 REM *** OUTPUT MAIN MENU ***
130 PRINT CHR$(147)
140 PRINT: PRINT "INTEGER BASE CONVERTER"
150 L = 22: GOSUB 1930: PRINT L$
160 PRINT: PRINT "SELECT AN OPTION (S, M OR Q):": PRINT
170 PRINT "[S]{SPACE*2}SINGLE INTEGER CONVERSION"
180 PRINT "[M]{SPACE*2}MULTIPLE INTEGER CONVERSION"
190 PRINT "[Q]{SPACE*2}QUIT PROGRAM"
200 GET M$
210 IF (M$="S") THEN GOSUB 260: GOTO 140
220 IF (M$="M") THEN GOSUB 380: GOTO 140
230 IF (M$="Q") THEN END
240 GOTO 200
250 REM *** OUTPUT SINGLE CONVERSION MENU ***
260 PRINT: PRINT "{SPACE*2}SELECT AN OPTION (D, B, H OR R):": PRINT
270 PRINT "{SPACE*2}[D]{SPACE*2}CONVERT A DECIMAL INTEGER"
280 PRINT "{SPACE*2}[B]{SPACE*2}CONVERT A BINARY INTEGER"
290 PRINT "{SPACE*2}[H]{SPACE*2}CONVERT A HEXADECIMAL INTEGER"
300 PRINT "{SPACE*2}[R]{SPACE*2}RETURN TO TOP MENU"
310 GET M1$
320 IF (M1$="D") THEN GOSUB 500: GOTO 260
330 IF (M1$="B") THEN GOSUB 760: GOTO 260
340 IF (M1$="H") THEN GOSUB 810: GOTO 260
350 IF (M1$="R") THEN RETURN
360 GOTO 310
370 REM *** OUTPUT MULTIPLE CONVERSION MENU ***
380 PRINT: PRINT "{SPACE*2}SELECT AN OPTION (D, B, H OR R):": PRINT
390 PRINT "{SPACE*2}[D]{SPACE*2}CONVERT A RANGE OF DECIMAL INTEGERS"
400 PRINT "{SPACE*2}[B]{SPACE*2}CONVERT A RANGE OF BINARY INTEGERS"
410 PRINT "{SPACE*2}[H]{SPACE*2}CONVERT A RANGE OF HEXADECIMAL INTEGERS"

H-20
420 PRINT "{SPACE*2}[R]{SPACE*2}RETURN TO TOP MENU"
430 GET M2$
440 IF (M2$="D") THEN GOSUB 1280: GOTO 380
450 IF (M2$="B") THEN GOSUB 1670: GOTO 380
460 IF (M2$="H") THEN GOSUB 1800: GOTO 380
470 IF (M2$="R") THEN RETURN
480 GOTO 430
490 REM *** CONVERT SINGLE DECIMAL INTEGER ***
500 D$ = ""
510 PRINT: INPUT "ENTER DECIMAL INTEGER (UP TO 65535): ",D$
520 GOSUB 1030: REM VALIDATE DECIMAL INPUT
530 IF (V = 0) THEN GOTO 510
540 PRINT: PRINT " DEC";SPC(4);"BIN";SPC(19);"HEX"
550 L = 5: GOSUB 1930: L1$ = L$
560 L = 20: GOSUB 1930: L2$ = L$
570 PRINT SPC(1);L1$;SPC(2);L2$;SPC(2);L1$
580 FOREGROUND 7
590 B$ = ""
600 D1 = 0
610 IF (D < 256) THEN GOTO 660
620 D1 = INT(D / 256)
630 FOR N = 1 TO 8
640 : IF ((D1 AND P(8 - N)) > 0) THEN B$ = B$ + "1": ELSE B$ = B$ + "0"
650 NEXT N
660 IF (D < 256) THEN B$ = "%" + B$: ELSE B$ = "%" + B$ + " "
670 D2 = D - 256*D1
680 FOR N = 1 TO 8
690 : IF ((D2 AND P(8 - N)) > 0) THEN B$ = B$ + "1": ELSE B$ = B$ + "0"
700 NEXT N
710 H$ = HEX$(D)
720 IF (D < 256) THEN H$ = "{SPACE*2}$" + RIGHT$(H$,2): ELSE H$ = "$" + H$
730 IF (D < 256) THEN PRINT SPC(6 - LEN(D$)); D$;SPC(12) + MID$(B$,1,5) +
" " + MID$(B$,6,10); "{SPACE*2}" + H$: FOREGROUND 1: RETURN
740 PRINT SPC(6 - LEN(D$));D$;"{SPACE*2}" + MID$(B$,1,5) + " " + MID$(B$,6,4) +
MID$(B$,10,5) + " " + MID$(B$,15,4); "{SPACE*2}" + H$: FOREGROUND 1: RETURN
750 REM *** CONVERT SINGLE BINARY INTEGER ***
760 I$=""
770 PRINT: INPUT "ENTER BINARY INTEGER (UP TO 16 BITS): ",I$
780 GOSUB 1110: REM VALIDATE BINARY INPUT
790 IF (V = 0) THEN GOTO 760: ELSE GOTO 540
800 REM *** CONVERT SINGLE HEXADECIMAL INTEGER ***

H-21
810 H$=""
820 PRINT: INPUT "ENTER HEXADECIMAL INTEGER (UP TO 4 DIGITS): ",H$
830 GOSUB 1220: REM VALIDATE HEXADECIMAL INPUT
840 IF (V = 0) THEN GOTO 810: ELSE GOTO 540
850 REM *** VALIDATE DECIMAL INPUT STRING ***
860 FOR N = 1 TO LEN(D$)
870 : M = ASC(MID$(D$,N,1)) - ASC("0")
880 : IF ((M < 0) OR (M > 9)) THEN V = 0
890 NEXT N: RETURN
900 REM *** VALIDATE BINARY INPUT STRING ***
910 FOR N = 1 TO LEN(I$)
920 : M = ASC(MID$(I$,N,1)) - ASC("0")
930 : IF ((M < 0) OR (M > 1)) THEN V = 0
940 NEXT N: RETURN
950 REM *** VALIDATE HEXADECIMAL INPUT STRING ***
960 FOR N = 1 TO LEN(H$)
970 : M = ASC(MID$(H$,N,1)) - ASC("0")
980 : IF (NOT (((M >= 0) AND (M <= 9)) OR
((M >= 17) AND (M <= 22)))) THEN V = 0
990 NEXT N: RETURN
1000 REM *** OUTPUT ERROR MESSAGE ***
1010 FOREGROUND 2: PRINT: PRINT A$: FOREGROUND 1: RETURN
1020 REM *** VALIDATE DECIMAL INPUT ***
1030 V = 1: GOSUB 860: REM VALIDATE DECIMAL INPUT STRING
1040 IF (V = 0) THEN A$ = "INVALID DECIMAL NUMBER": GOSUB 1010
1050 IF (V = 1) THEN BEGIN
1060 : D = VAL(D$)
1070 : IF ((D < 0) OR (D > 65535)) THEN A$ = "DECIMAL NUMBER OUT OF RANGE":
GOSUB 1010: V = 0
1080 BEND
1090 RETURN
1100 REM *** VALIDATE BINARY INPUT ***
1110 V = 1: GOSUB 910: REM VALIDATE BINARY INPUT STRING
1120 IF (V = 0) THEN A$ = "INVALID BINARY NUMBER": GOSUB 1010: RETURN
1130 IF (LEN(I$) > 16) THEN A$ = "BINARY NUMBER OUT OF RANGE":
GOSUB 1010: V = 0 : RETURN
1140 IF (V = 1) THEN BEGIN
1150 : I = 0
1160 : FOR N = 1 TO LEN(I$)
1170 : I = I + VAL(MID$(I$,N,1)) * P(LEN(I$) - N)
1180 : NEXT N

H-22
1190 BEND
1200 D$ = STR$(I): D = I: RETURN
1210 REM *** VALIDATE HEXADECIMAL INPUT ***
1220 V = 1: GOSUB 960: REM VALIDATE HEXADECIMAL INPUT STRING
1230 IF (V = 0) THEN A$ = "INVALID HEXADECIMAL NUMBER": GOSUB 1010: RETURN
1240 IF (LEN(H$) > 4) THEN A$ = "HEXADECIMAL NUMBER OUT OF RANGE":
GOSUB 1010: V = 0: RETURN
1250 D = DEC(H$): D$ = STR$(D): H = D: RETURN
1260 RETURN
1270 REM *** CONVERT MULTIPLE DECIMAL INTEGERS ***
1280 DB$=""
1290 PRINT: INPUT "ENTER STARTING DECIMAL INTEGER (UP TO 65535): ", DB$
1300 D$=DB$: GOSUB 1030: D$="": REM VALIDATE DECIMAL INPUT
1310 IF (V = 0) THEN GOTO 1290
1320 DE$=""
1330 PRINT: INPUT "ENTER ENDING DECIMAL INTEGER (UP TO 65535): ", DE$
1340 D$=DE$: GOSUB 1030: D$="": REM VALIDATE DECIMAL INPUT
1350 IF (V = 0) THEN GOTO 1330
1360 DB=VAL(DB$): DE=VAL(DE$)
1370 IF (DE < DB) THEN A$ = E$: GOSUB 1010: GOTO 1280
1380 SC = 1: SM = INT(((DE - DB) / 36) + 1)
1390 D = DB
1400 FOR J = SC TO SM
1410 : PRINT CHR$(147) + "RANGE: " + DB$ + " TO " + DE$ + "{SPACE*10}SCREEN: "
+ STR$(J) + " OF " + STR$(SM)
1420 : PRINT: PRINT "DEC";SPC(4);"BIN";SPC(19);"HEX";SPC(8);"DEC";SPC(4);
"BIN";SPC(19);"HEX"
1430 L = 5: GOSUB 1930: L1$ = L$
1440 L = 20: GOSUB 1930: L2$ = L$
1450 : PRINT SPC(1);L1$;SPC(2);L2$;SPC(2);L1$;SPC(6);L1$;SPC(2);
L2$;SPC(2);L1$
1460 : FOR K = 0 TO 17
1470 : FOREGROUND (7 + MOD(K,2))
1480 : D$ = STR$(D): GOSUB 590: D = D + 1
1490 : IF (D > DE) THEN GOTO 1630
1500 : NEXT K
1510 : PRINT CHR$(19): PRINT: PRINT: PRINT
1520 : FOR K = 0 TO 17
1530 : FOREGROUND (7 + MOD(K,2))
1540 : D$ = STR$(D): PRINT TAB(40): GOSUB 590: D = D + 1

H-23
1550 : IF (D > DE) THEN GOTO 1630
1560 : NEXT K
1570 : FOREGROUND 1: PRINT: PRINT SPC(19);"PRESS X TO EXIT OR SPACEBAR TO CONTINUE..."
1580 : GET B$
1590 : IF B$="X" THEN RETURN
1600 : IF B$=" " THEN GOTO 1620
1610 : GOTO 1580
1620 NEXT J
1630 PRINT CHR$(19): FOR I = 1 TO 22: PRINT: NEXT I
1640 PRINT SPC(20); "COMPLETE. PRESS SPACEBAR TO CONTINUE..."
1650 GET B$: IF B$<>" " THEN GOTO 1650: ELSE RETURN
1660 REM *** CONVERT MULTIPLE BINARY INTEGERS ***
1670 IB$=""
1680 PRINT: INPUT "ENTER STARTING BINARY INTEGER (UP TO 16 BITS): ", IB$
1690 I$=IB$: GOSUB 1110: I$="": REM VALIDATE BINARY INPUT
1700 IF (V = 0) THEN GOTO 1680
1710 IB = I
1720 IE$=""
1730 PRINT: INPUT "ENTER ENDING BINARY INTEGER (UP TO 16 BITS): ", IE$
1740 I$=IE$: GOSUB 1110: I$="": REM VALIDATE BINARY INPUT
1750 IF (V = 0) THEN GOTO 1730
1760 IE = I
1770 IF (IE < IB) THEN A$ = E$: GOSUB 1010: GOTO 1670
1780 DB = IB: DE = IE: DB$ = STR$(IB): DE$ = STR$(IE): GOTO 1380
1790 REM *** CONVERT MULTIPLE HEXADECIMAL INTEGERS ***
1800 HB$=""
1810 PRINT: INPUT "ENTER STARTING HEXADECIMAL INTEGER (UP TO 4 DIGITS): ", HB$
1820 H$=HB$: GOSUB 1220: H$="": REM VALIDATE HEXADECIMAL INPUT
1830 IF (V = 0) THEN GOTO 1810
1840 HB = H
1850 HE$=""
1860 PRINT: INPUT "ENTER ENDING HEXADECIMAL INTEGER (UP TO 4 DIGITS): ", HE$
1870 H$=HE$: GOSUB 1220: H$="": REM VALIDATE HEXADECIMAL INPUT
1880 IF (V = 0) THEN GOTO 1860
1890 HE = H
1900 IF (HE < HB) THEN A$ = E$: GOSUB 1010: GOTO 1800
1910 DB = HB: DE = HE: DB$ = STR$(HB): DE$ = STR$(HE): GOTO 1380
1920 REM *** MAKE LINES ***
1930 L$=""
1940 FOR K = 1 TO L: L$ = L$ + "-": NEXT K
1950 RETURN

H-24
APPENDIX I
System Memory Map
• Introduction
• MEGA65 Native Memory Map
• $D000 – $DFFF I/O Personalities
• CPU Memory Banking
• C64/C65 ROM Emulation
I-2
INTRODUCTION
The MEGA65 computer has a large 28-bit address space, which allows it to address
up to 256MB of memory and memory-mapped devices. This memory map has several
different views, depending on which mode the computer is operating in. Broadly,
there are five main modes: (1) Hypervisor mode; (2) C64 compatibility mode; (3)
C65 compatibility mode; (4) UltiMAX compatibility mode; and (5) MEGA65-mode, or
one of the other modes, where the programmer has made use of MEGA65 enhanced
features.
It is important to understand that, unlike the C128, the C65 and MEGA65 allow access
to all enhanced features from C64-mode, if the programmer wishes to do so. This
means that while we frequently talk about “C64-mode,” “C65-mode” and “MEGA65-
mode,” these are simply terms of convenience for the MEGA65 with its memory map
(and sometimes other features) configured to provide an environment that matches
the appropriate mode. The heart of this is the MEGA65’s flexible memory map.
In this appendix, we will begin by describing the MEGA65’s native memory map, that
is, where all of the memory, I/O devices and other features appear in the 28-bit ad-
dress space. We will then explain how C64 and C65 compatible memory maps are
accessed from this 28-bit address space.

I-3
MEGA65 NATIVE MEMORY MAP
The First Sixteen 64KB Banks
The MEGA65 uses a similar memory map to that of the C65 for the first MB of memory,
i.e., 16 memory banks of 64KB each. This is because the C65’s 4510 CPU can access
only 1MB of address space. These banks can be accessed from BASIC 65 using the
BANK, DMA, PEEK and POKE commands. The following table summarises the contents
of the first 16 banks:

HEX DEC Address Contents


0 0 $0xxxx First 64KB RAM. This is the RAM visible in
C64-mode.
1 1 $1xxxx Second 64KB RAM. This is the 2nd 64KB
of RAM present on a C65.
2 2 $2xxxx First half of C65 ROM (C64-mode and
shared components) or RAM
3 3 $3xxxx Second half of C65 ROM (C65-mode
components) or RAM
4 4 $4xxxx Additional RAM (384KB or larger chip-
RAM models)
5 5 $5xxxx Additional RAM (384KB or larger chip-
RAM models)
6 6 $6xxxx Additional RAM (*512KB or larger chip-
RAM models)
7 7 $7xxxx Additional RAM (*512KB or larger chip-
RAM models)
8 8 $8xxxx Additional RAM (*1MB or larger chip-
RAM models)
9 9 $9xxxx Additional RAM (*1MB or larger chip-
RAM models)
A 10 $Axxxx Additional RAM (*1MB or larger chip-
RAM models)
B 11 $Bxxxx Additional RAM (*1MB or larger chip-
RAM models)
C 12 $Cxxxx Additional RAM (*1MB or larger chip-
RAM models)
D 13 $Dxxxx Additional RAM (*1MB or larger chip-
RAM models)
E 14 $Exxxx Additional RAM (*1MB or larger chip-
RAM models)
F 15 $Fxxxx Additional RAM (*1MB or larger chip-
RAM models)

I-4
* Note that the MEGA65 presently only provides a model featuring 384KB of chip-
RAM. Future models may feature larger amounts of chip-RAM (such as 512KB and
1MB).
The key features of this address space are the 128KB of RAM in the first two banks,
which is also present on the C65. If you intend to write programs which can also run
on a C65, you should only use these two banks of RAM.
On all models it is possible to use all or part of the 128KB of “ROM” space as RAM. To
do this, you must first request that the Hypervisor removes the read-only protection on
this area, before you will be able to change its contents. If you are writing a program
which will start from C64-mode, or otherwise switch to using the C64 part of the ROM,
instead of the C65 part), then the second half of that space, i.e., BANK 3, can be safely
used for your programs. This gives a total of 192KB of RAM, which is available on all
models of the MEGA65.
On models that have 384KB or more of chip RAM, BANK 4 and 5 are also available.
Similarly, models which provide 1MB or more of chip RAM will have BANK 6 through 15
also available, giving a total of 896KB (or 960KB, if only the C64 part of the ROM is
required) of RAM available for your programs. Note that the MEGA65’s built-in freeze
cartridge currently freezes only the first 384KB of RAM.

Colour RAM
The MEGA65’s VIC-IV video controller supports much larger screens than the VIC-II
or VIC-III. For this reason, it has access to a separate colour RAM, similar to on the
C64. For compatibility with the C65, the first two kilo-bytes of this are accessible at
$1F800 – $1FFFF. The full 32KB or 64KB of colour RAM is located at $FF80000. This
is most easily accessed through the use of advanced DMA operations, or the 32-bit
base-page indirect addressing mode of the processor.
At the time of writing, the BANK and DMA commands cannot be used to access the
rest of the colour RAM, because the colour RAM is not located in the first mega-byte
of address space. This may be corrected in a future revision of the MEGA65, allowing
access to the full colour RAM via BANK 15 or an equivalent DMA job.

Additional RAM
Apart from the 384kb of chip-RAM found as standard on all MEGA65 models, most
models (devkit, release boards and xemu, but NOT on Nexys boards currently) also
have an extra 8MB of RAM starting at $8000000, referred to as ’ATTIC RAM’. It is not
visible to the other chips (vic/sid/etc) and can’t be used for audio DMA, but code can
run from it (more slowly) or it can be used to store content and DMA it in/out of the
chip-RAM.

I-5
There are also plans underway to support a PMOD hyperRAM module (installed via the
trapdoor beneath the MEGA65) in order to provide a further 8MB of RAM starting at
$8800000, referred to as ’CELLAR RAM’.

28-bit Address Space


In addition to the C65-style 1MB address space, the MEGA65 extends this to 256MB,
by using 28-bit addresses. The following shows the high-level layout of this address
space.

HEX DEC Size Contents


0000000 0 1 CPU I/O Port Data Direction Register
0000001 1 1 CPU I/O Port Data
0000002
– 005FFFF
2 – 384KB 384KB Fast chip RAM (40MHz)
0060000
384KB – 16MB 15.6MB Reserved for future chip RAM expansion
– 0FFFFFF
1000000
16MB – 64MB 48MB Reserved
– 3FFFFFF
4000000 64MB –
– 7FFFFFF 128MB
64MB Cartridge port and other devices on the
slow bus (1 – 10 MHz)
8000000 128MB –
– 87FFFFF 135MB
8MB 8MB ATTIC RAM (all models apart from
Nexys, presently)
8800000 135MB –
– 8FFFFFF 144MB
8MB 8MB CELLAR RAM (planned PMOD mod-
ule installed via trapdoor)
9000000 144MB –
– EFFFFFF 240MB
96MB Reserved for future expansion RAM
F000000 240MB –
– FF7DFFF 255.49MB
15.49MB Reserved for future I/O expansion
FF7E000 – 255.49MB –
FF7EFFF 255.49MB
4KB VIC-IV Character ROM (write only)
FF80000 – 255.5MB –
FF87FFF 255.53MB
32KB VIC-IV Colour RAM (32KB colour RAM -
available on all models)
FF88000 – 255.53MB –
FF8FFFF 255.57MB
32KB Additional VIC-IV Colour RAM (64KB
colour RAM - planned to be available on
R3 models and beyond)
FF90000 – 255.53MB –
FFCAFFF 255.80MB
216KB Reserved
FFCB000 255.80MB –
– FFCBFFF 255.80MB
4KB Emulated C1541 RAM
FFCC000 255.80MB –
– FFCFFFF 255.81MB
16KB Emulated C1541 ROM
continued …

I-6
…continued
HEX DEC Size Contents
FFD0000 255.81MB –
– FFD0FFF 255.81MB
4KB C64 $Dxxx I/O Personality
FFD1000 255.81MB –
– FFD1FFF 255.82MB
4KB C65 $Dxxx I/O Personality
FFD2000 255.82MB –
– FFD2FFF 255.82MB
4KB MEGA65 $Dxxx Ethernet I/O Personality
FFD3000 255.82MB –
– FFD3FFF 255.82MB
4KB MEGA65 $Dxxx Normal I/O Personality
FFD4000 255.82MB –
– FFD5FFF 255.83MB
8KB Reserved
FFD6000 255.83MB –
– FFD67FF 255.83MB
2KB Hypervisor scratch space
FFD6000 255.83MB –
– FFD6BFF 255.83MB
3KB Hypervisor scratch space
FFD6C00 255.83MB –
– FFD6DFF 255.83MB
512 F011 floppy controller sector buffer
FFD6E00 – 255.83MB –
FFD6FFF 255.83MB
512 SD Card controller sector buffer
FFD7000 255.83MB –
– FFD70FF 255.83MB
256 MEGAphone r1 I2C peripherals
FFD7100 255.83MB –
– FFD71FF 255.83MB
256 MEGA65 r2 I2C peripherals
FFD7200 – 255.83MB –
FFD72FF 255.83MB
256 MEGA65 HDMI I2C registers (only for
R2 and older models fitted with the
ADV7511 HDMI driver chip)
FFD7300 255.83MB –
– FFD7FFF 255.84MB
3.25KB Reserved for future I2C peripherals
FFD8000 255.83MB –
– FFDBFFF 255.86MB
16KB Hypervisor ROM (only visible in Hypervi-
sor Mode)
FFDC000 255.86MB –
– FFDDFFF 255.87MB
8KB Reserved for Hypervisor Mode ROM ex-
pansion
FFDE000 – 255.87MB –
FFDE7FF 255.87MB
2KB Reserved for Ethernet buffer expansion
FFDE800 – 255.87MB –
FFDEFFF 255.87MB
2KB Ethernet frame read buffer (read only)
and Ethernet frame write buffer (write
only)
FFDF000 – 255.87MB –
FFDFFFF 255.87MB
4KB Virtual FPGA registers (selected models
only)
FFE0000 – 255.87MB –
FFFFFFF 256MB
128KB Reserved

I-7
$D000 – $DFFF I/O PERSONALITIES
The MEGA65 supports four different I/O personalities. These are selected by writing
the appropriate values to the $D02F KEY register, which is visible in all four I/O per-
sonalities. There is more information in Chapter/Appendix 11 on page 11-3 about
the use of the KEY register.
The following table shows which I/O devices are visible in each of these I/O modes,
as well as the KEY register values that are used to select the I/O personality.

I-8
MEGA65
HEX C64 C65 MEGA65
ETHERNET
KEY $00 $A5, $96 $45, $54 $47, $53
$D000 – $D02F VIC-II VIC-II VIC-II VIC-II
$D030 – $D07F VIC-II1 VIC-III VIC-III VIC-III
$D080 – $D08F VIC-II F011 F011 F011
$D090 – $D09F VIC-II – SD card SD card
RAM EXPAND
$D0A0 – $D0FF VIC-II – –
CONTROL
$D100 – $D1FF VIC-II RED Palette RED Palette RED Palette
GREEN GREEN GREEN
$D200 – $D2FF VIC-II
Palette Palette Palette
$D300 – $D3FF VIC-II BLUE Palette BLUE Palette BLUE Palette
$D400 – $D41F SID Right #1 SID Right #1 SID Right #1 SID Right #1
$D420 – $D43F SID Right #2 SID Right #2 SID Right #2 SID Right #2
$D440 – $D45F SID Left #1 SID Left #1 SID Left #1 SID Left #1
$D460 – $D47F SID Left #2 SID Left #2 SID Left #2 SID Left #2
$D480 – $D49F SID Right #1 SID Right #1 SID Right #1 SID Right #1
$D4A0 – $D4BF SID Right #2 SID Right #2 SID Right #2 SID Right #2
$D4C0 – $D4DF SID Left #1 SID Left #1 SID Left #1 SID Left #1
$D4E0 – $D4FF SID Left #2 SID Left #2 SID Left #2 SID Left #2
$D500 – $D5FF SID images – Reserved Reserved
$D600 – $D63F – UART UART UART
HyperTrap HyperTrap
$D640 – $D67F – UART images
Registers Registers
MEGA65 MEGA65
$D680 – $D6FF – –
Devices Devices
MEGA65 MEGA65
$D700 – $D7FF – –
Devices Devices
COLOUR ETHERNET COLOUR
$D800 – $DBFF COLOUR RAM
RAM Buffer RAM
CIAs / CIAs /
ETHERNET
$DC00 – $DDFF CIAs COLOUR COLOUR
Buffer
RAM RAM
ETHERNET CART I/O /
$DE00 – $DFFF CART I/O CART I/O
Buffer SD SECTOR
1
In the C64 I/O personality, $D030 behaves as on C128, allowing
toggling between 1MHz and 2MHz CPU speed.
2
The additional MEGA65 SIDs are visible in all I/O personalities.
3
Some models may replace the repeated images of the first four
SIDs with four additional SIDs, for a total of 8 SIDs.

I-9
CPU MEMORY BANKING
The 45GS02 processor, like the 6502, can only “see” 64KB of memory at a time.
Access to additional memory is via a selection of bank-switching mechanisms. For
backward-compatibility with the C64 and C65, the memory banking mechanisms for
both of these computers are supported on the MEGA65:
1. C65-style MAP instruction banking
2. C65-style $D030 banking
3. C64-style cartridge banking
4. C64-style $00 / $01 banking
The MAP register overrides all other banking mechanisms. This mechanism selects
which of the eight 8KB regions of the 16-bit address space $0000 – $FFFF are
mapped to other addresses via an offset. If a region is mapped, then the other bank-
ing mechanisms do not apply. This is true even if the offset is 0, allowing the 16-bit
addresses to access RAM in bank 0 (such as address 0.D000).
C65-style $D030 banking and C64-style $00 / $01 banking both select regions to
map to bank 2, which (by default) contains C64 ROM code. These two mechanisms
overlap in which regions they can map to ROM. If either mechanism maps a region to
ROM (and it is not mapped elsewhere by the MAP register), then it is mapped to ROM.
The following diagram shows the different types of banking that can apply to the
different areas of the 64KB that the CPU can see.
MAP LO MAP HI
MAP
(4 x 8KB slabs) (4 x 8KB slabs)
CART CART CART
I/O/CART I/O
ROMLO ROMHI ROMHI
INTER-
D030 CHARROM BASIC KERNAL
FACE
CHAR
C64 BASIC KERNAL
ROM
RAM RAM RAM RAM RAM RAM RAM
$0000 – $8000 – $A000 – $C000 – $D000 – $E000 –
$7FFF $9FFF $BFFF $CFFF $DFFF $FFFF
There are actually a few further complications. For example, if the cartridge selects
the UltiMAX™ game mode, then only the first 4KB of RAM will be visible, and the re-
maining address space will be un-mapped, and able to be supplied by the cartridge.

C64/C65 ROM EMULATION


The C64 and C65 use ROM memories to hold the KERNAL and BASIC system. The
MEGA65 is different: It uses 128KB of its 384KB fast chip RAM at $20000 - $3FFFF

I-10
(banks 2 and 3) to hold these system programs. This makes it possible to change or
upgrade the “ROM” that the MEGA65 is running, without having to open the computer.
It is even possible to use the MEGA65’s Freeze Menu to change the “ROM” being used
while a program is running.
The C64 and C65 memory banking methods use this 128KB of area when making ROM
banks visible. When the RAM banks are mapped, they are always read-only. However,
if the MAP instruction or DMA is used to access that address area, it is possible to
write to it. For improved backward compatibility, the whole 128KB region of memory
is normally set to read-only.
A program can, however, request read-write access to this 128KB area of memory, so
that it can make full use of the MEGA65’s 384KB of chip RAM. This is accomplished by
triggering the Toggle Rom Write-protect system trap of the hypervisor. The following
code-fragment demonstrates how to do this. Calling it a second time will re-activate
the write-protection.

LDA # $70
STA $D640
NOP

This fragment works by calling sub-function $70 (toggle ROM write-protect) of Hyper-
visor trap $00. Note that the NOP is mandatory. The MEGA65 I/O personality must be
first selected, so that the $D640 register is un-hidden.
The current write-protection state can be tested by attempting to write to this area of
memory. Also, you can examine and toggle the current state in the MEGA65 Freeze
Menu.
NOTE: If you are starting your program from C65-mode, you must first make sure that
the I/O area is visible at $D000-$DFFF. The simplest way to do this is to use the MAP
instruction with all zero values in the registers. The following fragment demonstrates
this, and also makes sure that the MEGA65 I/O context is active, so that the hypervisor
trap will be able to trigger:

I-11
; Clear C65 memory map
LDA # $00
TAX
TAY
TAZ
MAP
; Bank I / O in via C64 m e c h a n i s m
LDA # $35
STA $01
; Do MEGA65 / VIC - IV I / O knock
LDA # $47
STA $D02F
LDA # $53
STA $D02F
; End MAP sequence , thus a l l o w i n g i n t e r r u p t s to occur again
EOM
; Do H y p e r v i s o r call to un - write - p r o t e c t the ROM area
LDA # $70
STA $D640
NOP

C65 Compatibility ROM Layout


The layout of the C65 compatibility 128KB ROM area is identical to that of the C65:
HEX Contents
$3E000 -- $3FFFF C65 KERNAL
$3D000 -- $3DFFF CHARSET B
$3C000 -- $3CFFF RESERVED
$38000 -- $3BFFF C65 BASIC GRAPHICS ROUTINES
$32000 -- $37FFF C65 BASIC
$30000 -- $31FFF MONITOR (gets mapped at $6000 -- $7FFF)
$2E000 -- $2FFFF C64 KERNAL
$2D000 -- $2DFFF CHARSET C
$2C000 -- $2CFFF INTERFACE
$2A000 -- $2BFFF C64 BASIC
$29000 -- $29FFF CHARSET A
$24000 -- $28FFF RESERVED
$20000 -- $23FFF DOS (gets mapped at $8000 -- $BFFF)
The INTERFACE program is a series of routines that are used by the C65 to switch
between C64-mode, C65-mode and the C65’s built-in DOS. The DOS is located in
the lower-eighth of the ROM.

I-12
APPENDIX J
45GS02 Microprocessor
• Introduction
• Differences to the 6502
• C64 CPU Memory Mapped Registers
• New CPU Memory Mapped Registers
• MEGA65 CPU Maths Acceleration Registers
• MEGA65 Hypervisor Mode
J-2
INTRODUCTION
The 45GS02 is an enhanced version of the processor portion of the CSG4510 and of
the F018 ”DMAgic” DMA controller used in the Commodore 65 computer prototypes.
The 4510 is, in turn, an enhanced version of the 65CE02. The reader is referred to
the considerable documentation available for the 6502 and 65CE02 processors for
the backwards-compatible operation of the 45GS02.
This chapter will focus on the differences between the 45GS02 and the earlier 6502-
class processors, and the documentation of the many built-in memory-mapped I/O
registers of the 45GS02.

DIFFERENCES TO THE 6502


The 45GS02 has a number of key differences to earlier 6502-class processors:

Supervisor/Hypervisor Privileged
Mode
Unlike the earlier 6502 variants, the 45GS02 has a privileged mode of operation. This
mode is intended for use by an operating system or type-1 hypervisor. The ambiguity
between operating system and Hypervisor on the MEGA65 stems from the fact that
the operating system of the MEGA65 is effectively little more than a loader and task-
switcher for C64 and C65 environments, i.e., effectively operating as a hypervisor,
but provides only limited virtualisation of the hardware.
The key differences between normal and supervisor mode on the MEGA65, are that in
supervisor mode:
• A special 16KB memory area is mapped to $8000 - $BFFF, which is used to
contain both the program and data of the Hypervisor / supervisor program. This
is normally the Hyppo program. This memory is not mappable by any means
when the processor is in the normal mode (the chip-select line to it is inhibited),
protecting it from accidental or malicious access.
• The 64 SYSCALL trap registers in the MEGA65 I/O-mode at $D640 - $D67F are
replaced by the virtualisation control registers. These registers allow complete
control over the system, and it is their access that truly defines the privilege of
the supervisor mode.
• The processor always operates at full speed (40MHz) and in the 4510 processor
personality.
The Hypervisor Mode is described in more detail later in this appendix.

J-3
6502 Unintended Instructions
The 65C02, 65CE02 and CSG4510 processors extended the original 6502 proces-
sor by using previously unallocated opcodes of the 6502 to provide additional instruc-
tions. All software that followed the official documentation of the 6502 processor will
therefore work on these newer processors, possibly with different instruction timing.
However, the common practice on the C64 and other home computers of using unde-
fined or unintended opcodes (often called “illegal opcodes”, although there is no law
against using them), means that many existing programs will not work on these newer
processors.
To alleviate this problem the 45GS02 has the ability to switch processor personalities
between the 4510 and 6502. The effect is that in 6502 mode, none of the new
opcodes of the 65C02, 65CE02, 4510 or 45GS02 are available, and are replaced
with the original, often strange, behaviour of the undefined opcodes of the 6502.
WARNING: This feature is incomplete and untested. Most unintended
6502 instructions do not operate correctly when the 6502 personality is
enabled.

Read-Modify-Write Instruction Bug


Compatibility
The 65CE02 processor optimised a group of instructions called the Read-Modify-Write
(RMW) instructions. For such instructions, such as INC, that increments the contents of
a memory location, the 6502 would read the original value and then write it back un-
changed, before writing it back with the new increased value. For most purposes, this
did not cause any problems. However, it turned out to be a fast way to acknowledge
VIC-II interrupts, because writing the original value back (which the instruction doesn’t
need to do) acknowledges the interrupt. This method is faster and uses fewer bytes
than any alternative, and so became widely used in C64 software.
The problem came with the C65 with its 65CE02 derived CSG4510 that didn’t do
this extra write during the RMW instructions. This made the RMW instructions one cycle
faster, which made software run slightly faster. Unfortunately, it also meant that a
lot of existing C64 software simply won’t run on a C65, unless the interrupt acknowl-
edgement code in each program is patched to work around this problem. This is the
single most common reason why many C64 games and other software titles won’t run
on a C65.
Because this problem is so common, the MEGA65’s 45GS02 includes bug compati-
bility with this commonly used feature of the original 6502. It does this by checking if
the target of an RMW instruction is $D019, i.e., the interrupt status register of the VIC-
II. If it is, then the 45GS02 performs the dummy write, allowing many C64 software
titles to run unmodified on the MEGA65, that do not run on a C65 prototype. By only
performing the dummy write if the address is $D019, the MEGA65 maintains C64

J-4
compatibility, without sacrificing the speed improvement for all other uses of these
instructions.

Variable CPU Speed


The 45GS02 is able to run at 1MHz, 2MHz, 3.5MHz and 40MHz, to support running
software designed for the C64, C128 in C64-mode, C65 and MEGA65.

Slow (1MHz – 3.5MHz) Operation


In these modes, the 45GS02 processor slows down, so that the same number of in-
structions per video frame are executed as on a PAL or NTSC C64, C128 in C64-mode
or C65 prototype. This is to allow existing software to run on the MEGA65 at the cor-
rect speed, and with minimal display problems. The VIC-IV video controller provides
cycle indication pulses to the 45GS02 that are used to keep time.
In these modes, opcodes take the same number of cycles as an 6502. However mem-
ory accesses within an instruction are not guaranteed to occur in the same cycle as
on a 1MHz 6502. Normally the effect is that instructions complete faster, and the
processor idles until the correct number of cycles have passed. This means that timing
may be incorrect by up to 7 micro-seconds. This is not normally a problem, and even
many C64 fast loaders will function correctly. For example, the GEOS™ Graphical
Operating System for the C64 can be booted and used from a 1541 connected to
the MEGA65’s serial port.
However, some advanced VIC-II graphics tricks, such as Variable Screen Position (VSP)
are highly unlikely to work correctly, due to the uncertainty in timing of the memory write
cycles of instructions. However, in most cases such problems can be easily solved by
using the advanced features of the MEGA65’s VIC-IV video controller. For example,
VSP is unnecessary on the MEGA65, because you can set the screen RAM address to
any location in memory.

Full Speed (40MHz) Instruction Timing


When the MEGA65’s processor is operating at full speed (currently 40MHz), the in-
struction timing no longer exactly mirrors the 6502: Instructions that can be executed
in fewer cycles will do so. For example, branches are typically require fewer instruc-
tions on the 45GS02. There are also some instructions that require more cycles on
the 45GS02, in particular the LDA, LDX, LDY and LDZ instructions. Those instructions
typically require one additional cycle. However as the processor is running at 40MHz,
these instructions still execute much more quickly than on even a C65 or C64 with an
accelerator.

Direct Memory Access (DMA)


Direct Memory Access (DMA) is a method for quickly filling, copying or swapping mem-
ory regions. The MEGA65 implements an improved version of the F018 “DMAgic” DMA

J-5
controller of the C65 prototypes. Unlike on the C65 prototypes, the DMA controller is
part of the CPU on the MEGA65.
Detailed information on how to use the DMA controller and these advanced features
can be found in Chapter/Appendix O on page O-3

Accessing memory between the 64KB


and 1MB points
The C65 included four ways to access memory beyond the 64KB point: three methods
that are limited, specialised or both, and two general-purpose methods. We will first
consider the limited methods, before documenting the general-purpose methods.

C64-Style Memory Banking


The first method, is to use the C64-style $00/$01 ROM/RAM banking. This method is
very limited, however, as it allows only the banking in and out of the two 8KB regions
that correspond to the C64 BASIC and KERNAL ROMs. These are located at $2A000
and $2E000 in the 20-bit C65 address space, i.e., $002A000 and $002E000 in
the 28-bit address space of the MEGA65. It can also provide access to the C64
character ROM data at $D000, which is located at $2D000 in the C65 memory map,
and thus $002D0000 in the MEGA65 address space. In addition to being limited to
which regions this method can access, it also only provides read-only access to these
memory regions, i.e., it cannot be used to modify these memory regions.

VIC-III “ROM” Banking


Similar to the C64-style memory banking, the C65 included the facility to bank several
other regions of the C65’s 128KB ROM. These are banked in and out using various bits
of the VIC-III’s $D030 register:

$D030 Signal 20-bit 16-bit Read-Write


Bit Name Address Address Access?
$1F800 –
$1FFFF, $D800 –
0 CRAM2K Y
$FF80000 $DFFF
– $FF807FF
$28000 – $8000 –
3 ROM8 N
$29FFF $9FFF
$2A000 – $A000 –
4 ROMA N
$2BFFF $BFFF
$2C000 – $C000 –
5 ROMC N
$2CFFF $CFFF
continued …

J-6
…continued
$D030 Signal 20-bit 16-bit Read-Write
Bit Name Address Address Access?
$2E000 – $E000 –
7 ROME N
$2FFFF $FFFF

The first 2KB of colour RAM is always visible at $1F800 – $1FFFF. The first 1KB of this
is also visible at $D800 – $DBFF. When the CRAM2K signal is 1, the second kilobyte is
made available at $DC00 – $DFFF. Unlike on the C64, the colour RAM on the MEGA65
is always visible as 8-bit bytes. Also, on the MEGA65, the colour RAM is 32KB in size,
and exists at $FF80000 – $FF87FFF. The visibility of the colour RAM at $1F800 –
$1FFFF is achieved by mirroring writes to both regions when accessing the colour
RAM via this mechanism.
Both VIC-III banking and C64-style banking can apply to $A000 – $BFFF and $E000
– $FFFF. They have the same effect of mapping those regions to ROM addresses in
bank 2. If either mechanism is active for a region, then the region is mapped to ROM.

VIC-III Display Address Translator


The third specialised manner to access to memory above the 64KB point is to use the
VIC-III’s Display Address Translator. Use of this mechanism is documented in Chap-
ter/Appendix P on page P-5.

The MAP instruction


The first general-purpose means of access to memory is the MAP instruction of the
4510 processor. The MEGA65’s 45GS02 processor also supports this mechanism.
This instruction divides the 64KB address of the 6502 into eight blocks of 8KB each.
For each of these blocks, the block may either be accessed normally, i.e., accessing
an 8KB region of the first 64KB of RAM of the system. Alternatively, each block may
instead be re-mapped (hence the name of the MAP instruction) to somewhere else in
the address space, by adding an offset to the address. Mapped addresses in the first
32KB use one offset, the lower offset, and the second 32KB uses another, the upper
offset. Re-mapping of memory using the MAP instruction takes precedence over all
other banking mechanisms.
The offsets must be a multiple of 256 bytes, and thus consist of 12 bits in order to
allow an arbitrary offset in the 1MB address space of the C65. As each 8KB block
in a 32KB half of memory can be either mapped or not, this requires one bit per 8KB
block. Thus the processor requires 16 bits of information for each half of memory, for a
total of 32 bits of information. This is achieved by setting the A and X registers for the
lower half of memory and the Y and Z registers for the upper half of memory, before
executing the MAP instruction.
The MAP instruction copies the contents of these registers into the processors internal
registers that hold the mapping information.

J-7
The following diagram illustrates how the MAP instruction takes the values of the four
A, X, Y and Z registers, and uses them to compute the upper and lower address offsets,
and sets the bank enable bits for each of the eight 8KB memory regions of the 6502
address space:

C65 Memory Offset C64 16-Bit


Bank Offset Enable? Address Space

X7 +$E000-$FFFF
LDY #$BC

Upper 32KB X6 +$C000-$DFFF


LDZ #$XA Offset
X5 +$A000-$BFFF
$ABC00
LDA #$EF X4 +$8000-$9FFF

Z7 +$6000-$7FFF
LDX #$ZD
Lower 32KB Z6 +$4000-$5FFF
Offset
MAP
$DEF00 Z5 +$2000-$3FFF

EOM Z4 +$0000-$1FFF

That is, the contents of the A register and the lower-nibble of the X register form a
12-bit value that is multiplied by 256 to produce the offset used for any of the 8KB
banks in the lower 32KB half of the 6502’s 16-bit address space. The upper nibble
of the X register is used as flags to indicate which of the four 8KB blocks in that 32KB
half of the 6502 address space should have the offset added to their addresses to
compute the actual address.
The Y and Z registers are used in a similar way to produce the offset for the upper
32KB half of the 6502 address space, and the flags to indicate whether the offset is
used for each of the four 8KB blocks in that half of the address space.
Note that the lower 8 bits of the offset cannot be set. That is, the offset will be a
multiple of 256 bytes, unlike on some extended 6502 processors. However, in practice
this restriction is rarely limiting.
To understand how this works in practice, the following example shows how this works
with a concrete example, showing the address ranges that would be visible in each of
the 8KB slices of the 6502’s 64KB address space:

J-8
C65 Memory Offset C64 16-Bit
Bank Offset Enable? Address Space

0 $0E000-$0FFFF
LDY #$80

Upper 32KB 0 $0C000-$0DFFF


LDZ #$34 Offset
1 $52000-$53FFF
$48000
LDA #$00 1 $50000-$51FFF

0 $06000-$07FFF
LDX #$11
Lower 32KB 0
MAP $04000-$05FFF
Offset

EOM $10000 0 $02000-$03FFF

1 $10000-$11FFF

Notice that the offsets for each of the two 32KB address ranges get added to the
6502 address. This is why the offset of $48000 for the upper 32KB generates an
address of $50000 at the 6502 address $8000.
See also under “Using the MAP instruction to access >1MB” for further explanation.

Direct Memory Access (DMA) Controller


The C65’s F018/F018A DMA controller allows for rapid filling, copying and swapping
of the contents of memory anywhere in the 1MB address space. Detailed information
about the F018 DMA controller, and the MEGA65’s enhancements to this, refer to
Chapter/Appendix O on page O-3

Flat Memory Access

J-9
Accessing memory beyond the 1MB
point
The MEGA65 can support up to 256MB of memory. This is more than the 1MB address
space of the CSG4510 on which it is based. There are several ways of performing
this.

Using the MAP instruction to access >1MB


The full address space is available to the MAP instruction for legacy C65-style memory
mapping, although some care is required, as the MAP instruction must be called up
to three times. The reason for this is that the MAP instruction must be called to first
select which mega-byte of memory will be used for the lower and upper map regions,
before it is again called in the normal way to set the memory mapping. Because
between these two calls the memory mapping offset will be a mix of the old and new
addresses, all mapping should be first disabled via the MAP instruction. This means
that the code to re-map memory should live in the bottom 64KB of RAM or in one of
the ROM-bankable regions, so that it can remain visible during the mapping process.
Failure to handle this situation properly will result in the processor executing instruc-
tions from somewhere unexpected half-way through the process, because the routine
it is executing to perform the mapping will suddenly no longer be mapped.
Because of the relative complexity of this process, and the other problems with the
MAP instruction as a means of memory access, we recommend that for accessing
data outside of the current memory map that you use either DMA or the flat-memory
address features of the 45GS02 that are described below. Indeed, access to the full
address space via the MAP instruction is only provided for completeness.
As another example of how the MAP instruction can be used to map an area of mem-
ory from the expanded address space, the following program maps the Ethernet frame
buffer from its natural location at $FFDE8000 to appear at $6800. To keep the ex-
ample as simple as possible, we assume that the code is running in the bottom 64KB
of RAM, and not in the region between $6000 – $8000.
As the MAP instruction normally is only aware of the C65-style 20-bit addresses, the
MEGA65 extension to the instruction must be used to set the upper 8 bits of the 28-
bit MEGA65 addresses, i.e., which mega-byte of address space should be used for
the address translation. This is done by setting the X register to $0F when setting the
mega-byte number for the lower-32KB of the C64-style 64KB address space. This
does not create any incompatibility with any sensible use of the MAP instruction on a
C65, because this value indicates that none of the four 8KB memory blocks will be re-
mapped, but at the same time specifies that the upper 4 bits of the address offset for
re-mapped block is the non-zero value of $F. The mega-byte number is then specified
by setting the A register.
The same approach applies to the upper 32KB, but using the Z and Y registers instead
of the X and A registers. However, in this case, we do not need to re-map the upper

J-10
32KB of memory in this example, we will leave the Z and Y registers set to zero. We
must however set X and A to set the mega-byte number for the lower-32KB to $FF.
Therefore A must have the value $FF. To set the lower 20-bits of the address offset we
use the MAP instruction a second time, this time using it in the normal C65 manner.
As we want to remap $6800 to $FFDE800, and have already dealt with the $FFxxxxx
offset via the mega-byte number, we need only to apply the offset to make $6800
point to $DE800. $DE800 minus $6800 = $D8000. As the MAP instruction operates
with a mapping granularity of 256 bytes = $100, we can drop the last two digits from
$D8000 to obtain the MAP offset of $D80. The lower 8-bits, $80, must be loaded
into the A register. The upper 4-bits, $D, must be loaded into the low-nibble of the
X register. As we wish to apply the mapping to only the fourth of the 8KB blocks that
make up the lower 32KB half of the C64 memory map, we must set the 4th bit of the
upper nibble. That is, the upper nibble must be set to %1000, i.e., $8. Therefore the
X register must be loaded with $8D. Thus we yield the complete example program:

; Map E t h e r n e t r e g i s t e r s at $6000 - $7FFF

; E t h e r n e t c o n t r o l l e r really lives $ F F D E 0 0 0 - $FFDEFFF , so select $FF m e g a b y t e s e c t i o n for


LDA # $ff
LDX # $0f
LDY # $00
LDZ # $00
map

; now enable m app ing of $DE000 - $DFFFF at $6000


; MAPs are offset based , so we need to s u b t r a c t $6000 from the target ad d r e s s
; $DE000 - $6000 = $D8000
LDA # $80
LDX # $8d
LDY # $00
LDZ # $00
map
EOM

; E t h e r n e t buffer now v is i b l e at $6800 - $6FFF

Note that the EOM (End Of Mapping) instruction (which is the same as NOP on a 6502,
i.e., opcode $EA) was only supplied after the last MAP instruction, to make sure that no
interrupts could occur while the memory map contained mixed values with the mega-
byte number set, but the lower-bits of the mapping address had not been updated.
No example in BASIC for the MAP instruction is possible, because the MAP is an ma-
chine code instruction of the 4510 / 45GS02 processors.

J-11
Flat-Memory Access
The 45GS02 makes it easy to read or write a byte from anywhere in memory by al-
lowing the Zero-Page Indirect addressing mode to use a 32-bit pointer instead of the
normal 16-bit pointer. This is accomplished by using the Z-indexed Zero-Page Indi-
rect Addressing Mode for the access, and having the instruction directly preceded by
a NOP instruction (opcode $EA). For example:

NOP
LDA ( $45 ) , Z

If you are using the ACME assembler, or another assembler that supports the 45GS02
extensions, you can instead use square-brackets to indicate that you are performing
a flat-memory operation. Such assemblers will insert the $EA prefix automatically for
you. For example:

LDA [ $45 ] , Z

Regardless which tool you are using, this example would read the four bytes of Zero-
Page memory at $45 – $48 to form a 32-bit memory address, and add the value of
the Z register to this to form the actual address that will be read from. The byte order
in the address is the same as the 6502, i.e., the right-most (least significant) byte of
the address will be read from the first address ($45 in this case), and so on, until the
left-most (most significant) byte will be read from $48. For example, to read from
memory location $12345678, the contents of memory beginning at $45 should be
78 56 34 12.
This method is much more efficient and also simpler than either using the MAP in-
struction or the DMA controller for single memory accesses, and is what we generally
recommend. The DMA controller can be used for moving/filler larger regions of mem-
ory. We recommend the MAP instruction only be used for banking code, or in rare
situations where extensive access to a small region of memory is required, and the
extra cycles of reading the 32-bit addresses is problematic.

Virtual 32-bit Register


The 45GS02 allows the use of its four general purpose registers, A, X, Y and Z (A
is LSB, Z is MSB) as a single virtual 32-bit register, also called the Q pseudo register.
This can greatly simplify and speed up many common operations, and help avoid many
common programming errors. For example, adding two 16-bit or 32-bit values can
now be easily accomplished with something like:

J-12
; Clear carry before p e r f o r m i n g addition , as normal
CLC
; Prefix an i n s t r u c t i o n with two NEG i n s t r u c t i o n s to select v i r t u a l 32 - bit r e g i s t e r mode
NEG
NEG
LDA $1234 ; Load the c o n t e n t s of $1234 - $1237 into A ,X , Y and Z r e s p e c t i v e l y
; And again , for the a d d i t i o n
NEG
NEG
ADC $1238 ; Add the c o n t e n t s of $1238 - $123B
; The result of the a d d i t i o n is now in A , X , Y and Z .
; And can be w rit t en out in whole or part

; To write it all out , again , we need the NEG + NEG prefix


NEG
NEG
STA $123C ; Write the whole out to $123C - $123F

; Or to write out the bottom bytes , we can just write the c o n t e n t s of A and X as normal
STA $1240
STX $1241

This approach works with the LDA, STA, ADC, SBC, CMP, EOR, AND, BIT, ORA, ASL,
ASR, LSR, ROL, ROR, INC and DEC instructions. If you are using ACME or another
45GS02 aware assembler, you can instead use the new LDQ, STQ, ADCQ, SBCQ, CPQ,
EORQ, ANDQ, BITQ, ORQ, ASLQ, ASRQ, LSRQ, ROLQ, RORQ, INQ and DEQ mnemonics. The
previous example would thus become:

; Clear carry before p e r f o r m i n g addition , as normal


CLC
LDQ $1234 ; Load the c o n t e n t s of $1234 - $1237 into A ,X , Y and Z r e s p e c t i v e l y
ADCQ $1238 ; Add the c o n t e n t s of $1238 - $123B
; The result of the a d d i t i o n is now in A , X , Y and Z .
; And can be w rit t en out in whole or part

STQ $123C ; Write the whole out to $123C - $123F

; Or to write out the bottom bytes , we can just write the c o n t e n t s of A and X as normal
STA $1240
STX $1241

The virtual 32-bit addressing mode works with any addressing mode. However, in-
dexed addressing modes, where X, Y or Z are added to the address should be used
with care, because these registers may in fact be holding part of a 32-bit value.
The exception is the Zero-Page Indirect Z-Indexed addressing mode: In this case the Z
register is NOT added to the target address (with the exception of the LDQ opcode),

J-13
unlike would normally be the case. This is to allow the virtual 32-bit register to be
able to be used with flat-memory access with the combined prefix of NEG NEG NOP,
before the instruction to allow accessing a 32-bit value anywhere in memory in a single
instruction.
Note that the virtual 32-bit register cannot be used in immediate mode, e.g., to load
a constant into the four general purpose registers, or to add or subtract a constant
value. This is to avoid problems with variable length instructions.
For LDQ and STQ, it would save at most one byte compared to LDA #$nn ... LDZ #$nn,
and would be no faster. In fact, for many common values, such as #$00000000, there
are short-cuts, such as:

LDA # $00
TAX
TAY
TAZ

If you need to add or subtract a 32-bit immediate value, this may require you to re-
order the arguments, or perform other minor gymnastics. For example, to compute the
sum of the contents of memory and an immediate value, you can load the A, X, Y and
Z registers with the immediate value, and then use ADCQ with the memory address,
e.g.:

; Get the i m m e d i a t e value # $ 1 2 3 4 5 6 7 8 into Q


LDA # $78
LDX # $56
LDY # $34
LDZ # $12
; Add the c o n t e n t s of memory l o c a t i o n s $1234 - $1237
NEG
NEG
ADC $1234
; Store the result back in $1234 - $1237
NEG
NEG
STA $1234

Again, if you are using the ACME or another 45GS02-aware assembler, this can be
more compactly and clearly written as follows. But note that in both cases the same
byte-sequence of machine code is produced, and the program will take the same
number of cycles to execute.

J-14
; Get the i m m e d i a t e value # $ 1 2 3 4 5 6 7 8 into Q
LDA # $78
LDX # $56
LDY # $34
LDZ # $12
; Add the c o n t e n t s of memory l o c a t i o n s $1234 - $1237
ADCQ $1234
; Store the result back in $1234 - $1237
STQ $1234

C64 CPU MEMORY MAPPED


REGISTERS
HEX DEC Signal Description
00 0 PORTDDR 6510/45GS10 CPU port DDR
01 1 PORT 6510/45GS10 CPU port data

NEW CPU MEMORY MAPPED


REGISTERS
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D640 54848 HTRAP00
D641 54849 HTRAP01
D642 54850 HTRAP02
D643 54851 HTRAP03
D644 54852 HTRAP04
D645 54853 HTRAP05
D646 54854 HTRAP06
D647 54855 HTRAP07
D648 54856 HTRAP08
D649 54857 HTRAP09
D64A 54858 HTRAP0A
D64B 54859 HTRAP0B
D64C 54860 HTRAP0C
D64D 54861 HTRAP0D
D64E 54862 HTRAP0E
D64F 54863 HTRAP0F
continued …

J-15
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D650 54864 HTRAP10
D651 54865 HTRAP11
D652 54866 HTRAP12
D653 54867 HTRAP13
D654 54868 HTRAP14
D655 54869 HTRAP15
D656 54870 HTRAP16
D657 54871 HTRAP17
D658 54872 HTRAP18
D659 54873 HTRAP19
D65A 54874 HTRAP1A
D65B 54875 HTRAP1B
D65C 54876 HTRAP1C
D65D 54877 HTRAP1D
D65E 54878 HTRAP1E
D65F 54879 HTRAP1F
D660 54880 HTRAP20
D661 54881 HTRAP21
D662 54882 HTRAP22
D663 54883 HTRAP23
D664 54884 HTRAP24
D665 54885 HTRAP25
D666 54886 HTRAP26
D667 54887 HTRAP27
D668 54888 HTRAP28
D669 54889 HTRAP29
D66A 54890 HTRAP2A
D66B 54891 HTRAP2B
D66C 54892 HTRAP2C
D66D 54893 HTRAP2D
D66E 54894 HTRAP2E
D66F 54895 HTRAP2F
D670 54896 HTRAP30
D671 54897 HTRAP31
D672 54898 HTRAP32
D673 54899 HTRAP33
D674 54900 HTRAP34
D675 54901 HTRAP35
D676 54902 HTRAP36
D677 54903 HTRAP37
D678 54904 HTRAP38
continued …

J-16
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D679 54905 HTRAP39
D67A 54906 HTRAP3A
D67B 54907 HTRAP3B
D67C 54908 HTRAP3C
D67D 54909 HTRAP3D
D67E 54910 HTRAP3E
D67F 54911 HTRAP3F
D710 55056 – BADEXTRA BRCOST – SLIEN BADLEN
D7EF 55279 HWRNGRAND
D7FA 55290 FRAMECOUNT
D7FB 55291 – CARTEN –
D7FD 55293 NOGAME – POWEREN
NOEXROM
HWRNG- SLOWS- SELS-
D7FE 55294 – – OCEANA
NOTRDY DRAM DRAM PREFETCH

• BADEXTRA Cost of badlines minus 40. ie. 00=40 cycles, 11 = 43 cycles.


• BADLEN Enable badline emulation
• BRCOST 1=charge extra cycle(s) for branches taken
• CARTEN 1= enable cartridges
• FRAMECOUNT Count number of elapsed video frames
• HTRAPXX Writing triggers hypervisor trap $XX
• HWRNGNOTRDY Hardware Real RNG random number not ready
• HWRNGRAND Hardware Real RNG random number (reading triggers generation)
• NOEXROM Override for /EXROM : Must be 0 to enable /EXROM signal
• NOGAME Override for /GAME : Must be 0 to enable /GAME signal
• OCEANA Enable Ocean Type A cartridge emulation
• POWEREN Set to zero to power off computer on supported systems. WRITE ONLY.
• PREFETCH Enable expansion RAM pre-fetch logic
• SELSDRAM Selects SDRAM instead of HyperRAM for Attic RAM where available
• SLIEN Enable 6502-style slow (7 cycle) interrupts
• SLOWSDRAM Selects slow (81MHz) SDRAM clock

J-17
MEGA65 CPU MATHS ACCELERATION
REGISTERS
Every MEGA65 contains a combined 32-bit hardware multiplier and divider. This de-
vice takes two 32-bit inputs, MULTINA and MULTINB, and simultaneously calculates:
• the 64-bit product MULTOUT of MULTINA and MULTINB
• the 32-bit whole part DIVOUT(4-7) of MULTINA divided by MULTINB
• the 32-bit fractional part DIVOUT(0-3) of MULTINA divided by MULTINB
It is always updating the outputs based on the inputs, so there is no need to take
special action when changing the inputs. The multiplier takes 1 cycle to calculate,
and the updated result will thus be available immediately (a MULBUSY bit is defined,
but currently it won’t be set at all). The hardware divider, however, can take upto 20
cycles depending on the particular inputs. The programmer should check the DIVBUSY
bit if the divider is still calculating:

loop : BIT $D70F ; t r a n s f e r D I V B U S Y bit into N flag


BMI loop ; as long as it is set , we need to wait

The MEGA65 is planned to also include a programmable math unit, which helps to
accelerate the calculation of fixed-point formulae. This is presently disabled and will
be further documented if and when it becomes available (addresses $D780 - $D7E3).

HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D70F 55055 DIVBUSY MULBUSY –
D768 55144 DIVOUT
D769 55145 DIVOUT
D76A 55146 DIVOUT
D76B 55147 DIVOUT
D76C 55148 DIVOUT
D76D 55149 DIVOUT
D76E 55150 DIVOUT
D76F 55151 DIVOUT
D770 55152 MULTINA
D771 55153 MULTINA
D772 55154 MULTINA
D773 55155 MULTINA
D774 55156 MULTINB
D775 55157 MULTINB
D776 55158 MULTINB
D777 55159 MULTINB
continued …

J-18
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D778 55160 MULTOUT
D779 55161 MULTOUT
D77A 55162 MULTOUT
D77B 55163 MULTOUT
D77C 55164 MULTOUT
D77D 55165 MULTOUT
D77E 55166 MULTOUT
D77F 55167 MULTOUT
D780 55168 MATHIN0
D781 55169 MATHIN0
D782 55170 MATHIN0
D783 55171 MATHIN0
D784 55172 MATHIN1
D785 55173 MATHIN1
D786 55174 MATHIN1
D787 55175 MATHIN1
D788 55176 MATHIN2
D789 55177 MATHIN2
D78A 55178 MATHIN2
D78B 55179 MATHIN2
D78C 55180 MATHIN3
D78D 55181 MATHIN3
D78E 55182 MATHIN3
D78F 55183 MATHIN3
D790 55184 MATHIN4
D791 55185 MATHIN4
D792 55186 MATHIN4
D793 55187 MATHIN4
D794 55188 MATHIN5
D795 55189 MATHIN5
D796 55190 MATHIN5
D797 55191 MATHIN5
D798 55192 MATHIN6
D799 55193 MATHIN6
D79A 55194 MATHIN6
D79B 55195 MATHIN6
D79C 55196 MATHIN7
D79D 55197 MATHIN7
D79E 55198 MATHIN7
D79F 55199 MATHIN7
D7A0 55200 MATHIN8
continued …

J-19
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D7A1 55201 MATHIN8
D7A2 55202 MATHIN8
D7A3 55203 MATHIN8
D7A4 55204 MATHIN9
D7A5 55205 MATHIN9
D7A6 55206 MATHIN9
D7A7 55207 MATHIN9
D7A8 55208 MATHINA
D7A9 55209 MATHINA
D7AA 55210 MATHINA
D7AB 55211 MATHINA
D7AC 55212 MATHINB
D7AD 55213 MATHINB
D7AE 55214 MATHINB
D7AF 55215 MATHINB
D7B0 55216 MATHINC
D7B1 55217 MATHINC
D7B2 55218 MATHINC
D7B3 55219 MATHINC
D7B4 55220 MATHIND
D7B5 55221 MATHIND
D7B6 55222 MATHIND
D7B7 55223 MATHIND
D7B8 55224 MATHINE
D7B9 55225 MATHINE
D7BA 55226 MATHINE
D7BB 55227 MATHINE
D7BC 55228 MATHINF
D7BD 55229 MATHINF
D7BE 55230 MATHINF
D7BF 55231 MATHINF
D7C0 55232 UNIT0INB UNIT0INA
D7C1 55233 UNIT1INB UNIT1INA
D7C2 55234 UNIT2INB UNIT2INA
D7C3 55235 UNIT3INB UNIT3INA
D7C4 55236 UNIT4INB UNIT4INA
D7C5 55237 UNIT5INB UNIT5INA
D7C6 55238 UNIT6INB UNIT6INA
D7C7 55239 UNIT7INB UNIT7INA
D7C8 55240 UNIT8INB UNIT8INA
D7C9 55241 UNIT9INB UNIT9INA
continued …

J-20
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D7CA 55242 UNITAINB UNITAINA
D7CB 55243 UNITBINB UNITBINA
D7CC 55244 UNITCINB UNITCINA
D7CD 55245 UNITDINB UNITDINA
D7CE 55246 UNITEINB UNITEINA
D7CF 55247 UNITFINB UNITFINA
U0-
D7D0 55248 U0LATCH U0MLADD U0HIOUT UNIT0OUT
LOWOUT
U1-
D7D1 55249 U1LATCH U1MLADD U1HIOUT UNIT1OUT
LOWOUT
U2-
D7D2 55250 U2LATCH U2MLADD U2HIOUT UNIT2OUT
LOWOUT
U3-
D7D3 55251 U3LATCH U3MLADD U3HIOUT UNIT3OUT
LOWOUT
U4-
D7D4 55252 U4LATCH U4MLADD U4HIOUT UNIT4OUT
LOWOUT
U5-
D7D5 55253 U5LATCH U5MLADD U5HIOUT UNIT5OUT
LOWOUT
U6-
D7D6 55254 U6LATCH U6MLADD U6HIOUT UNIT6OUT
LOWOUT
U7-
D7D7 55255 U7LATCH U7MLADD U7HIOUT UNIT7OUT
LOWOUT
U8-
D7D8 55256 U8LATCH U8BSADD U8HIOUT UNIT8OUT
LOWOUT
U9-
D7D9 55257 U9LATCH U9BSADD U9HIOUT UNIT9OUT
LOWOUT
UA-
D7DA 55258 UALATCH UABSADD UAHIOUT UNITAOUT
LOWOUT
UB-
D7DB 55259 UBLATCH UBBSADD UBHIOUT UNITBOUT
LOWOUT
UC-
D7DC 55260 UCLATCH UCDVADD UCHIOUT UNITCOUT
LOWOUT
UD-
D7DD 55261 UDLATCH UDDVADD UDHIOUT UNITDOUT
LOWOUT
UE-
D7DE 55262 UELATCH UEDVADD UEHIOUT UNITEOUT
LOWOUT
UF-
D7DF 55263 UFLATCH UFDVADD UFHIOUT UNITFOUT
LOWOUT
D7E0 55264 LATCHINT
D7E1 55265 – CALCEN WREN
D7E2 55266 RESERVED
D7E3 55267 RESERVED

• CALCEN Enable committing of output values from math units back to math reg-
isters (clearing effectively pauses iterative formulae)
• DIVBUSY Set if hardware divider is busy

J-21
• DIVOUT 64-bit output of MULTINA ÷ MULTINB
• LATCHINT Latch interval for latched outputs (in CPU cycles)
• MATHINX Math unit 32-bit input X
• MULBUSY Set if hardware multiplier is busy
• MULTINA Multiplier input A / Divider numerator (32 bit)
• MULTINB Multiplier input B / Divider denominator (32 bit)
• MULTOUT 64-bit output of MULTINA × MULTINB
• RESERVED Reserved
• UNITXINA Select which of the 16 32-bit math registers is input A for Math Func-
tion Unit X.
• UNITXINB Select which of the 16 32-bit math registers is input B for Math Func-
tion Unit X.
• UNITXOUT Select which of the 16 32-bit math registers receives the output of
Math Function Unit X
• UXBSADD If set, Math Function Unit Y acts as a 32-bit adder instead of 32-bit
barrel-shifter.
• UXDVADD If set, Math Function Unit X acts as a 32-bit adder instead of 32-bit
divider.
• UXHIOUT If set, the high-half of the output of Math Function Unit X is written to
math register UNITXOUT.
• UXLATCH If set, Math Function Unit X’s output is latched.
• UXLOWOUT If set, the low-half of the output of Math Function Unit X is written
to math register UNITXOUT.
• UXMLADD If set, Math Function Unit X acts as a 32-bit adder instead of 32-bit
multiplier.
• WREN Enable setting of math registers (must normally be set)

MEGA65 HYPERVISOR MODE


Reset
On power-up or reset, the MEGA65 starts up in hypervisor mode, and expects to find a
program in the 16KB hypervisor memory, and begins executing instructions at address
$8100. Normally a JMP instruction will be located at this address, that will jump into
a reset routine. That is, the 45GS02 does not use the normal 6502 reset vector. It’s

J-22
function is emulated by the Hyppo hypervisor program, which fetches the address from
the 6502 reset vector in the loaded client operating system when exiting hypervisor
mode.
The hypervisor memory is automatically mapped on reset to $8000 - $BFFF. This spe-
cial memory is not able to mapped or in anyway accessed, except when in hypervisor
mode. It can, however, always be accessed from the serial monitor/debugger inter-
face via its 28-bit address, $FFF8000 – $FFFBFFF. This is to protect it from accidental
or malicious access from a guest operating system.

Entering / Exiting Hypervisor Mode


Entering the Hypervisor occurs whenever any of the following events occurs:
• Power-on When the MEGA65 is first powered on.
• Reset If the reset line is lowered, or a watch-dog triggered reset occurs.
• SYSCALL register accessed The registers $D640 - $D67F in the MEGA65 I/O
context trigger SYSCALLs when accessed. This is intended to be the mechanism
by which a client operating system or process requests the attention of the hy-
pervisor or operating system.
• Page Fault On MEGA65s that feature virtual memory, a page fault will cause a
trap to hypervisor mode.
RESTORE
• Certain keyboard events Pressing for >0.5 seconds, or the ` and
TAB
key combination traps to the hypervisor. Typically the first is used to launch
the Freeze Menu and the second to toggle the display of the debug interface.
• Accessing virtualised I/O devices For example, if the F011 (internal 3.5” disk
drive controller) has been virtualised, then attempting to read or write sectors
using this device will cause traps to the hypervisor.
• Executing an instruction that would lock up the CPU A number of undocu-
mented opcodes on the 6502 will cause the CPU to lockup. On the MEGA65,
instead of locking up, the computer will trap to the hypervisor. This could be
used to implement alternative instruction behaviours, or simply to tell the user
that something bad has happened.
• Certain special events Some devices can generate hypervisor-level interrupts.
These are implemented as traps to the hypervisor.
The 45GS02 handles all of these in a similar manner internally:
1. The SYSCALL or trap address is calculated, based on the event.
2. The contents of all CPU registers are saved into the virtualisation control regis-
ters.

J-23
3. The hypervisor mode memory layout is activated, the CPU decimal flag and spe-
cial purpose registers are all set to appropriate values. The contents of the A,X,Y
and Z and most other CPU flags are preserved, so that they can be accessed
from the Hypervisor’s SYSCALL/trap handler routine, without having to load them,
thus saving a few cycles for each call.
4. The hypervisor-mode flag is asserted, and the program counter (PC) register is
set to the computed address.
All of the above happens in one CPU cycle, i.e., in 25 nano-seconds. Returning from
a SYSCALL or trap consists simply of writing to $D67F, which requires 125 nano-
seconds, for a total overhead of 150 nano-seconds. This gives the MEGA65 SYSCALL
performance rivalling – even beating – even the fastest modern computers, where the
system call latency is typically hundreds to tens of thousands of cycles [2].

Hypervisor Memory Layout


The hypervisor memory is 16KB in size. The first 512 bytes are reserved for SYSCALL
and system trap entry points, with four bytes for each. For example, the reset entry
point is at $8100 - $8100 + 3 = $8100 - $8103. This allows 4 bytes for an instruction,
typically a JMP instruction, followed by a NOP to pad it to 4 bytes.
The full list of SYSCALLs and traps is:

HEX DEC Name Description


8000 32768 SYSCALL00 SYSCALL 0 entry point
8004 32772 SYSCALL01 SYSCALL 1 entry point
8008 32776 SYSCALL02 SYSCALL 2 entry point
800C 32780 SYSCALL03 SYSCALL 3 entry point
8010 32784 SYSCALL04 SYSCALL 4 entry point
8014 32788 SYSCALL05 SYSCALL 5 entry point
8018 32792 SYSCALL06 SYSCALL 6 entry point
801C 32796 SYSCALL07 SYSCALL 7 entry point
8020 32800 SYSCALL08 SYSCALL 8 entry point
8024 32804 SYSCALL09 SYSCALL 9 entry point
8028 32808 SYSCALL0A SYSCALL 10 entry point
802C 32812 SYSCALL0B SYSCALL 11 entry point
8030 32816 SYSCALL0C SYSCALL 12 entry point
8034 32820 SYSCALL0D SYSCALL 13 entry point
8038 32824 SYSCALL0E SYSCALL 14 entry point
803C 32828 SYSCALL0F SYSCALL 15 entry point
8040 32832 SYSCALL10 SYSCALL 16 entry point
8044 32836 SECURENTR Enter secure container trap entry point
8048 32840 SECUREXIT Leave secure container trap entry point.
804C 32844 SYSCALL13 SYSCALL 19 entry point
continued …

J-24
…continued
HEX DEC Name Description
8050 32848 SYSCALL14 SYSCALL 20 entry point
8054 32852 SYSCALL15 SYSCALL 21 entry point
8058 32856 SYSCALL16 SYSCALL 22 entry point
805C 32860 SYSCALL17 SYSCALL 23 entry point
8060 32864 SYSCALL18 SYSCALL 24 entry point
8064 32868 SYSCALL19 SYSCALL 25 entry point
8068 32872 SYSCALL1A SYSCALL 26 entry point
806C 32876 SYSCALL1B SYSCALL 27 entry point
8070 32880 SYSCALL1C SYSCALL 28 entry point
8074 32884 SYSCALL1D SYSCALL 29 entry point
8078 32888 SYSCALL1E SYSCALL 30 entry point
807C 32892 SYSCALL1F SYSCALL 31 entry point
8080 32896 SYSCALL20 SYSCALL 32 entry point
8084 32900 SYSCALL21 SYSCALL 33 entry point
8088 32904 SYSCALL22 SYSCALL 34 entry point
808C 32908 SYSCALL23 SYSCALL 35 entry point
8090 32912 SYSCALL24 SYSCALL 36 entry point
8094 32916 SYSCALL25 SYSCALL 37 entry point
8098 32920 SYSCALL26 SYSCALL 38 entry point
809C 32924 SYSCALL27 SYSCALL 39 entry point
80A0 32928 SYSCALL28 SYSCALL 40 entry point
80A4 32932 SYSCALL29 SYSCALL 41 entry point
80A8 32936 SYSCALL2A SYSCALL 42 entry point
80AC 32940 SYSCALL2B SYSCALL 43 entry point
80B0 32944 SYSCALL2C SYSCALL 44 entry point
80B4 32948 SYSCALL2D SYSCALL 45 entry point
80B8 32952 SYSCALL2E SYSCALL 46 entry point
80BC 32956 SYSCALL2F SYSCALL 47 entry point
80C0 32960 SYSCALL30 SYSCALL 48 entry point
80C4 32964 SYSCALL31 SYSCALL 49 entry point
80C8 32968 SYSCALL32 SYSCALL 50 entry point
80CC 32972 SYSCALL33 SYSCALL 51 entry point
80D0 32976 SYSCALL34 SYSCALL 52 entry point
80D4 32980 SYSCALL35 SYSCALL 53 entry point
80D8 32984 SYSCALL36 SYSCALL 54 entry point
80DC 32988 SYSCALL37 SYSCALL 55 entry point
80E0 32992 SYSCALL38 SYSCALL 56 entry point
80E4 32996 SYSCALL39 SYSCALL 57 entry point
80E8 33000 SYSCALL3A SYSCALL 58 entry point
80EC 33004 SYSCALL3B SYSCALL 59 entry point
80F0 33008 SYSCALL3C SYSCALL 60 entry point
continued …

J-25
…continued
HEX DEC Name Description
80F4 33012 SYSCALL3D SYSCALL 61 entry point
80F8 33016 SYSCALL3E SYSCALL 62 entry point
80FC 33020 SYSCALL3F SYSCALL 63 entry point
8100 33024 RESET Power-on/reset entry point
Page fault entry point (not currently
8104 33028 PAGFAULT
used)
8108 33032 RESTORKEY Restore-key long press trap entry point
810C 33036 ALTTABKEY ALT+TAB trap entry point
F011 virtualised disk read trap entry
8110 33040 VF011RD
point
F011 virtualised disk write trap entry
8114 33044 VF011WR
point
8118 33048 BREAKPT CPU break-point encountered
33048
811C –
81FB
– RESERVED Reserved traps point entry
33275
KIL instruction in 6502-mode trap entry
81FC 33276 CPUKIL
point

The remainder of the 16KB hypervisor memory is available for use by the programmer,
but will typically use the last 512 bytes for the stack and zero-page, giving an overall
memory map as follows:

HEX DEC Description


32768
8000 –
81FF
– SYSCALL and trap entry points
33279
33280
8200 –
BDFF
– Available for hypervisor or operating system program
48639
48640
8E00 –
BEFF
– Processor stack for hypervisor or operating system
48895
48896
8F00 – Processor zero-page storage for hypervisor or

BFFF
49151 operating system

The stack is used for holding the return address of function calls. The zero-page stor-
age is typically used for holding variables and other short-term storage, as is customary
on the 6502.

J-26
Hypervisor Virtualisation Control Reg-
isters
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D640 54848 REGA
D641 54849 REGX
D643 54851 REGZ
D644 54852 REGB
D645 54853 SPL
D646 54854 SPH
D647 54855 PFLAGS
D648 54856 PCL
D649 54857 PCH
D64A 54858 MAPLO
D64B 54859 MAPLO
D64C 54860 MAPHI
D64D 54861 MAPHI
D64E 54862 MAPLOMB
D64F 54863 MAPHIMB
D650 54864 PORT00
D651 54865 PORT01
D652 54866 – EXSID VICMODE
D653 54867 DMASRCMB
D654 54868 DMADSTMB
D655 54869 DMALADDR
D656 54870 DMALADDR
D657 54871 DMALADDR
D658 54872 DMALADDR
D659 54873 – VFLOP VFLOP
D670 54896 GEORAMBASE
D671 54897 GEORAMMASK
D672 54898 – MATRIXEN –
D67C 54908 UARTDATA
D67D 54909 WATCHDOG
D67E 54910 HICKED
D67F 54911 ENTEREXIT

• ASCFAST Hypervisor enable ASC/DIN CAPS LOCK key to enable/disable CPU


slow-down in C64/C128/C65 modes
• CPUFAST Hypervisor force CPU to 48MHz for userland (userland can override
via POKE0)

J-27
• DMADSTMB Hypervisor DMAgic destination MB
• DMALADDR Hypervisor DMAGic list address bits 0-7
• DMASRCMB Hypervisor DMAgic source MB
• ENTEREXIT Writing trigger return from hypervisor
• EXSID 0=Use internal SIDs, 1=Use external(1) SIDs
• F4502 Hypervisor force CPU to 4502 personality, even in C64 IO mode.
• GEORAMBASE Hypervisor GeoRAM base address (x MB)
• GEORAMMASK Hypervisor GeoRAM address mask (applied to GeoRAM block
register)
• HICKED Hypervisor already-upgraded bit (writing sets permanently)
• JMP32EN Hypervisor enable 32-bit JMP/JSR etc
• MAPHI Hypervisor MAPHI register storage (high bits)
• MAPHIMB Hypervisor MAPHI mega-byte number register storage
• MAPLO Hypervisor MAPLO register storage (high bits)
• MAPLOMB Hypervisor MAPLO mega-byte number register storage
• MATRIXEN Enable composited Matrix Mode, and disable UART access to serial
monitor.
• PCH Hypervisor PC-high register storage
• PCL Hypervisor PC-low register storage
• PFLAGS Hypervisor P register storage
• PIRQ Hypervisor flag to indicate if an IRQ is pending on exit from the hypervisor
/ set 1 to force IRQ/NMI deferal for 1,024 cycles on exit from hypervisor.
• PNMI Hypervisor flag to indicate if an NMI is pending on exit from the hypervisor.
• PORT00 Hypervisor CPU port $00 value
• PORT01 Hypervisor CPU port $01 value
• REGA Hypervisor A register storage
• REGB Hypervisor B register storage
• REGX Hypervisor X register storage
• REGZ Hypervisor Z register storage
• ROMPROT Hypervisor write protect C65 ROM $20000-$3FFFF
• RSVD RESERVED

J-28
• SPH Hypervisor SPH register storage
• SPL Hypervisor SPL register storage
• UARTDATA (write) Hypervisor write serial output to UART monitor
• VFLOP 1=Virtualise SD/Floppy0 access (usually for access via serial debugger
interface)
• VICMODE VIC-II/VIC-III/VIC-IV mode select
• WATCHDOG Hypervisor watchdog register: writing any value clears the watch
dog

Programming for Hypervisor Mode


The easiest way to write a program for Hypervisor Mode on the MEGA65 is to use KickC,
which is a special version of C made for writing programs for 6502-class processors.
The following example programs are from KickC’s supplied examples. KickC produces
very efficient code, and directly supports the MEGA65’s hypervisor mode quite easily
through the use of a linker definition file with the following contents:

. file [ name ="% O . bin " , type =" bin " , s e g m e n t s =" X M e g a 6 5 B i n "]
. s e g m e n t d e f X M e g a 6 5 B i n [ s e g m e n t s =" Syscall , Code , Data , Stack , Z e r o p a g e "]
. s e g m e n t d e f S ysc all [ start = $8000 , max = $81ff ]
. s e g m e n t d e f Code [ start = $8200 , min = $8200 , max = $bdff ]
. s e g m e n t d e f Data [ s t a r t A f t e r =" Code " , min = $8200 , max = $bdff ]
. s e g m e n t d e f Stack [ min = $be00 , max = $beff , fill ]
. s e g m e n t d e f Z e r o p a g e [ min = $bf00 , max = $bfff , fill ]

This file instructs KickC’s assembler to create a 16KB file with the 512 byte SYSCAL-
L/trap entry point region at the start, followed by code and data areas, and then the
stack and zero-page areas. It enforces the size and location of these fields, and will
give an error during compilation if anything is too big to fit.
With this file in place, you can then create a KickC source file that provides data
structures for the SYSCALL/trap table, e.g.:

J-29
// XMega6 5 KERNAL D e v e l o p m e n t T e m p l a t e
// Each f u n c t i o n of the KERNAL is a no - args f u n c t i o n
// The f u n c t i o n s are placed in the S Y S C A L L S table s u r r o u n d e d by JMP and NOP

import " string "

// Use a linker d e f i n i t i o n file ( put the p r e v i o u s l i s t i n g into that file )


# pragma link (" m e g a 6 5 h y p e r . ld ")

// Some d e f i n i t i o n s of a d d r e s s e s and s p e ci a l values that this p r o g r a m uses


const char * RASTER = 0 xd012 ;
const char * V I C _ M E M O R Y = 0 xd018 ;
const char * SCREEN = 0 x0400 ;
const char * BGCOL = 0 xd021 ;
const char * COLS = 0 xd800 ;
const char BLACK = 0;
const char WHITE = 1;

// Some text to dis p la y


char [] ME SSA GE = " hello world !";

J-30
void main () {
// I n i t i a l i s e screen memory , and select c o r r e c t font
* V I C _ M E M O R Y = 0 x14 ;
// Fill the screen with spaces
memset ( SCREEN , ' ', 4 0 * 2 5 ) ;
// Set the colour of every c h a r a c t e r on the screen to white
memset ( COLS , WHITE , 4 0 * 2 5 ) ;
// Print the " hello world !" m e s s a g e
char * sc = SCREEN +40; // D i s p l a y it one line down on the screen
char * msg = M ESS A GE ; // The m a s s a g e to d i s p l a y
// A simple copy r o ut i n e to copy the string
while (* msg ) {
* sc ++ = * msg ++;
}
// Loop for eve r sh o w i n g two white lines as raster bars
while ( true ) {
if (* RASTER ==54 || * RASTER ==66) {
* BGCOL = WHITE ;
} else {
* BGCOL = BLACK ;
}
}
}

// Here are a couple sample S Y S C A L L h a n d l e r s that just d i s p l a y a c h a r a c t e r on the screen


void s y s c a l l 1 () {
*( SCREEN +79) = ' > ';
}

void s y s c a l l 2 () {
*( SCREEN +78) = ' < ';
}

// Now we select the S Y S CA L L s e g m e n t to hold the S Y S C A L L / trap entry point table .


# pragma d a t a _ s e g ( Sy s ca l l )

// The s t r u c t u r e of each entry point is JMP < h a n d l e r address > + NOP .


// We have a char ( xjmp ) to hold the opcode for the JMP instruction ,
// and then put the a dd r e s s of the S Y S C A L L / trap h a n d l e r in the next
// two points as a pointer , and end with the NOP i n s t r u c t i o n opcode .

J-31
struct S ysC all {
char xjmp ; // Holds $4C , the JMP $nnnn opcode
void ()* sysc all ; // Holds h a n d l e r address , will be the target of the JMP
char xnop ; // Holds $EA , the NOP opcode
};

// To save wr iti ng 0 x4C and 0 xEA all the time , we define them as c o n s t a n t s
const char JMP = 0 x4c ;
const char NOP = 0 xea ;

// Now we can have a nice table of up to 64 S Y S C A L L h a n d l e r s e x p r e s s e d


// in a fairly r e a d a b l e and easy format .
// Each line is an i n s t a n c e of the struct S y s C a l l from above , with the JMP
// opcode value , the a d d re s s of the h a n d l e r r o u t i n e and the NOP opcode value .
export struct Sy sCa l l [] S Y S C A L L S = {
{ JMP , & syscall1 , NOP } ,
{ JMP , & syscall2 , NOP }
};

// In this ex amp le we had only two S Y S C A L L s defined , so rather than having


// anothe r 62 lines , we can just ask KickC to make the TRAP table begin
// at the next m u l t i p l e of $100 , i . e . , at $8100 .
export align (0 x100 ) struct S y s C a l l [] S Y S C A L L \ _RESET = {
{ JMP , & main , NOP }
};

If you save the first listing into a file called mega65hyper.ld, and the second into a file
called mega65hyper.kc, you can then compile them using KickC with a command like:

kickc -a m e g a 6 5 h y p e r

It will then produce a file called mega65hyper.bin, which you can then try out on your
MEGA65, or run in the XMega65 emulator with a command like:

xmega6 5 - kickup m e g a 6 5 h y p e r . bin

J-32
APPENDIX K
45GS02 & 6502 Instruction
Sets
• Introduction
• Stack Operations
• Addressing Modes
• 6502 Instruction Set
• 4510 Instruction Set
• 45GS02 Compound Instructions
K-2
INTRODUCTION
The 45GS02 CPU is able to operate in native mode, where it is compatible with the
CSG 4510, and in 6502 compatibility mode, where 6502 undocumented instructions,
also known as illegal instructions, are supported for compatibility.
WARNING: This feature is incomplete and untested. Most undocumented
6502 opcodes do not operate correctly when the 6502 personality is en-
abled.
When in 4510 compatibility mode, the 45GS02 also supports a number of extensions
through compound instructions. These work be prefixing the desired instruction’s op-
code with one or more prefix bytes, which represent sequences of instructions that
should not normally occur. For example, two NEG instructions in a row acts as a pre-
fix to tell the 45GS02 that the following instruction will operate on 32 bits of data,
instead of the usual 8 bits of data. This means that a 45GS02 instruction stream
can be readily decoded or disassembled, without needing to set special instruction
length flags, as is the case with the 65816 family of microprocessors. The trade-off
is increased execution time, as the 45GS02 must skip over the prefix bytes.
The remainder of this chapter introduces the addressing modes, instructions, opcodes
and instruction timing data of the 45GS02, beginning with 6502 compatibility mode,
before moving on to 4510 compatibility mode, and the 45GS02 extensions.

STACK OPERATIONS
The stack is a area of memory where you can push data onto or fetch (pop) the latest
piece of data from it. Every stack operation that puts data to the stack (push) also
changes the Stack Pointer (SP) downwards (the stack starts at the top of the area
and grows down), and every stack operation that takes data from the stack (pop) will
change the SP upwards.
So if you find something like
STACK ← VALUE
implies that VALUE is pushed onto the STACK and SP is reduced by the number of bytes
VALUE is big. When pushing more than one byte, the MSB is pushed first followed by
the LSB.
And in the opposite direction a operation like
MEMORY or REGISTER ← STACK
will pop data from the STACK and increment SP for each byte removed.

K-3
ADDRESSING MODES
The 45GS02 supports 34 different addressing modes, which are explained below.
Many of these are very similar to one another, being variations of the normal 6502 or
65CE02 addressing modes, except that they accept either 32-bit pointers, operate
on 32-bits of data, or both.

Implied
In this mode, there are no operands, as the precise function of the instruction is implied
by the instruction itself. For example, the INX instruction increments the X Register.

Accumulator
In this mode, the Accumulator is the operand. This is typically used to shift, rotate or
modify the value of the Accumulator Register in some way. For example, INC A incre-
ments the value in the Accumulator Register.

Q Pseudo Register
In this mode, the Q Pseudo Register is the operand. This is typically used to shift, rotate
or modify the value of the Q Pseudo Register in some way. For example, ASLQ shifts the
value in the Q Pseudo Register left one bit.
Remember that the Q Pseudo Register is simply the A, X, Y and Z registers acting
together as a virtual 32-bit register, where A contains the least significant bits, and
Z the most significant bits. If you modify Q, you will modify the true registers, and
similarly, if you modify a true register, this will change the respective part of the Q
register.
There are some cases where using a Q mode instruction can be helpful for operating
on the four true registers, for example, being able to quickly load or store all four
registers.

Immediate Mode
In this mode, the argument to the instruction is a value that is used directly. This is
indicated by proceeding the value with a # character. Most assemblers allow values
to be entered in decimal, or in hexadecimal by preceding the value with a $ sign, in
binary, by preceding the value with a % sign. For example, to set the Accumulator
Register to the value 5, you could use the following:

K-4
LDA #5

The immediate argument is encoded as a single byte following the instruction. For the
above case, the instruction stream would contain $A9, the opcode for LDA immediate
mode, followed by $05, the immediate operand.

Immediate Word Mode


In this mode, the argument is a 16-bit value that is used directly. There is only one
instruction which uses this addressing mode, PHW. For example, to push the word $1234
onto the stack, you could use:

PHW # $1234

The low byte of the immediate value follows the opcode of the instruction. The high
byte of the immediate value then follows that. For the above example, the instruction
stream would thus be $F4 $34 $12.

Base-Page Mode
In this mode, the argument is an 8-bit address. The upper 8-bits of the address are
taken from the Base-Page Register. On 6502 processors, there is no Base-Page Reg-
ister, and instead, the upper 8-bits are always set to zero – hence the name of this
mode on the 6502: Zero-Page. On the 45GS02, it is possible to move this “Zero-
Page” to any page in the processor’s 64KB view of memory by setting the Base-Page
Register using the TAB instruction. Base-Page Mode allows faster access to a 256 re-
gion of memory, and uses less instruction bytes to do so.
The argument is encoded as a single byte that immediately follows the instruction
opcode. For example,

LDA $12

would read the value stored in location $12 in the Base-Page, and put it into the
Accumulator Register. The instruction byte stream for this would be $85 $12.

Base-Page Quad Mode


This mode is identical to Base-Page Mode, except that it reads a 32-bit word starting
at the specified address.
The argument is encoded as a single byte that immediately follows the instruction
opcode. For example,

K-5
LDQ $12

would read the value stored in locations $12 – $15 in the Base-Page, and put them
into the Q Pseudo Register. The instruction byte stream for this would be $42 $42
$85 $12. Note that this is the same as for the Base-Page (Zero-Page) Mode, with the
addition of the two $42 prefix bytes. Opcode $42 is normally NEG (negate the value
in the A register). When executed twice in a row, this returns the A value to its original
value. The 45GS02 processor has special logic to recognises this sequence, so that it
knows to execute the next instruction using the Q Pseudo Register for that instruction.
See the note on page K-5 for more information about Base-Page and Zero-Page.

Base-Page X-Indexed Mode


This mode is identical to Base-Page Mode, except that the address is formed by taking
the argument, and adding the value of the X Register t<o it. In 6502 mode, the result
will always be in the Base-Page, that is, any carry due to the addition from the low
byte into the high byte of the address will be ignored. The encoding for this addressing
mode is identical to Base-Page Mode.
The argument is encoded as a single byte that immediately follows the instruction
opcode. For example,

LDA $12 , X

would read the value stored in location ($12 + X) in the Base-Page, and put it into the
A register. The instruction byte stream for this would be $B5 $12.
See the note on page K-5 for more information about Base-Page and Zero-Page.

Base-Page Quad X-Indexed Mode


This mode is identical to Base-Page Quad Mode, except that the address is formed
by taking the argument, and adding the value of the X Register to it. In 6502 mode,
the result will always be in the Base-Page, that is, any carry due to the addition from
the low byte into the high byte of the address will be ignored. The encoding for this
addressing mode is identical to Base-Page Quad Mode.
The argument is encoded as a single byte that immediately follows the instruction
opcode. For example,

DEQ $12 , X

K-6
would increment the 32-bit word stored at ($12 + X) through to ($15 + X) in the Base-
Page, and put it into the X register. The instruction byte stream for this would be $42
$42 $D6 $12.
Note that LDQ is not available in this addressing mode.
See the note on page K-5 for more information about Base-Page and Zero-Page. See
the note on page K-5 for more information on Quad Mode instructions.

Base-Page Y-Indexed Mode


This mode is identical to Base-Page Mode, except that the address is formed by taking
the argument, and adding the value of the Y Register to it. In 6502 mode, the result
will always be in the Base-Page, that is, any carry due to the addition from the low
byte into the high byte of the address will be ignored. The encoding for this addressing
mode is identical to Base-Page Mode.
The argument is encoded as a single byte that immediately follows the instruction
opcode. For example,

LDX $12 , Y

would read the value stored in location ($12 + Y) in the Base-Page, and put it into the
X register. The instruction byte stream for this would be $B6 $12.
See the note on page K-5 for more information about Base-Page and Zero-Page.

Absolute Mode
In this mode, the argument is an 16-bit address. The low 8-bits of the address are
taken from the byte immediately following the instruction opcode. The upper 8-bits
are taken from the byte following that. For example, the instruction

LDA $1234

would read the memory location $1234, and place the read value into the Accumu-
lator Register. This would be encoded as $AD $34 $12.

Absolute Quad Mode


In this mode, the argument is an 16-bit address. The low 8-bits of the address are
taken from the byte immediately following the instruction opcode. The upper 8-bits
are taken from the byte following that. For example, the instruction

K-7
LDQ $1234

would read the memory locations $1234 – $1237, and place the read values into the
Q Pseudo Register. This would be encoded as $42 $42 $AD $34 $12.
See the note on page K-5 for more information on Quad Mode instructions.

Absolute X-Indexed Mode


This mode is identical to Absolute Mode, except that the address is formed by taking
the argument, and adding the value of the X Register to it. If the indexing causes the
address to cross a page boundary, i.e., if the upper byte of the address changes, this
may incur a 1 cycle penalty, depending on the processor mode and speed setting.
The encoding for this addressing mode is identical to Absolute Mode. For example,
the instruction
LDA $1234 , X

would read the memory location ($1234 + X), and place the value read from there
into the A Register. This would be encoded as $BD $34 $12.

Absolute Quad X-Indexed Mode


This mode is identical to Absolute Quad Mode, except that the address is formed by
taking the argument, and adding the value of the X Register to it. If the indexing causes
the address to cross a page boundary, i.e., if the upper byte of the address changes,
this may incur a 1 cycle penalty, depending on the processor mode and speed setting.
The encoding for this addressing mode is identical to Absolute Quad Mode.
For example, the instruction

ROLQ $1234 , X

would rotate left the 32-bit value at memory locations ($1234+X) – ($1237+X), and
write the result back to these same memory locations. This would be encoded as $42
$42 $3E $34 $12.
See the note on page K-5 for more information on Quad Mode instructions.

Absolute Y-Indexed Mode


This mode is identical to Absolute Mode, except that the address is formed by taking
the argument, and adding the value of the Y Register to it. If the indexing causes the

K-8
address to cross a page boundary, i.e., if the upper byte of the address changes, this
may incur a 1 cycle penalty, depending on the processor mode and speed setting.
The encoding for this addressing mode is identical to Absolute Mode. For example,
the instruction
LDA $1234 , Y

would read the memory location ($1234 + Y), and place the value read from there
into the A Register. This would be encoded as $B9 $34 $12.

Absolute Indirect Mode


In this mode, the 16-bit argument is the address that points to, i.e., contains the ad-
dress of actual byte to read. For example, if memory location $1234 contains $78
and memory location $1235 contains $56, then

JMP ( $1234 )

would jump to address $5678. The encoding for this addressing mode is identical to
Absolute Mode, and thus this instruction would be encoded as $6C $34 $12.

Absolute Indirect X-Indexed Mode


In this mode, the 16-bit argument is the address that points to, i.e., contains the ad-
dress of actual byte to read. It is identical to Absolute Indirect Mode, except that the
value of the X Register is added to the pointer address. For example, if the X Register
contains the value $04, memory location $1238 contains $78 and memory location
$1239 contains $56, then

JMP ( $1234 , X )

would jump to address $5678. The encoding for this addressing mode is identical to
Absolute Mode, and thus this instruction would be encoded as $7C $34 $12.

Base-Page Indirect X-Indexed Mode


This addressing mode is identical to Absolute Indirect X-Indexed Mode, except that the
address of the pointer is formed from the Base-Page Register (high byte) and the 8-bit
operand (low byte). The encoding for this addressing mode is identical to Base-Page
Mode.
For example, if the X Register contains the value $04, and the memory locations $16
and $17 in the current Base-Page contained $34 and $12, respectively, then

K-9
LDA ( $12 , X )

would read the contents of memory location $1234, and store the result in the A
register. This instruction would be encoded as $A1 $12.
See the note on page K-5 for more information about Base-Page and Zero-Page.

Base-Page Indirect Y-Indexed Mode


This addressing mode differs from the X-Indexed Indirect modes, in that the Y Regis-
ter is added to the address that is read from the pointer, instead of being added to
the pointer. This is a very useful mode, that is frequently used because it effectively
provides access to “the Y-th byte of the memory at the address pointed to by the
operand.” That is, it de-references a pointer. The encoding for this addressing mode
is identical to Base-Page Mode.
For example, if the Y Register contains the value $04, and the memory locations $12
and $13 in the current Base-Page contained $78 and $56, respectively, then

LDA ( $12 ) , Y

would read the contents of memory location $567C (i.e., $5678 + Y), and store the
result in the A register. This instruction would be encoded as $B1 $12.
See the note on page K-5 for more information about Base-Page and Zero-Page.

Base-Page Indirect Z-Indexed Mode


This addressing mode differs from the X-Indexed Indirect modes, in that the Z Regis-
ter is added to the address that is read from the pointer, instead of being added to
the pointer. This is a very useful mode, that is frequently used because it effectively
provides access to “the Z-th byte of the memory at the address pointed to by the
operand.” That is, it de-references a pointer. The encoding for this addressing mode
is identical to Base-Page Mode.
For example, if the Z Register contains the value $04, and the memory locations $12
and $13 in the current Base-Page contained $78 and $56, respectively, then

LDA ( $12 ) , Z

would read the contents of memory location $567C (i.e., $5678 + Z), and store the
result in the A register. This instruction would be encoded as $B2 $12.
That is, it is equivalent to the Base-Page Indirect Y-Indexed Mode, but using the Z
register instead of the Y register to calculate the offset.

K-10
See the note on page K-5 for more information about Base-Page and Zero-Page.

Base-Page Quad Indirect Z-Indexed


Mode
This addressing mode is identical to the Base-Page Indirect Z-Indexed Mode, except
that 32-bits of data are operated on. The encoding for this addressing mode is iden-
tical to Base-Page Mode, except that it is prefixed by $42, $42. For example, if the
Z Register contains the value $04, and the memory locations $12, and $13 in the
current Base-Page contained $CD and $AB, respectively, then

LDQ ( $12 ) , Z

would read the contents of memory location $ABD1 (i.e., $ABCD + Y) – $ABD4 and
store the result in the Q Pseudo Register. This instruction would be encoded as $42
$42 $B2 $12.
Currently the only instruction that offers this mode is LDQ.
See the note on page K-5 for more information about Base-Page and Zero-Page. See
the note on page K-5 for more information on Quad Mode instructions.

32-bit Base-Page Indirect Z-Indexed


Mode
This mode is formed by preceding a Base-Page Indirect Z-Indexed Mode instruction
with the NOP instruction (opcode $EA). This causes the 45GS02 to read a 32-bit
address instead of a 16-bit address from the Base-Page address indicated by its
operand. The Z index is added to that pointer. Importantly, the 32-bit address does
not refer to the processor’s current 64KB view of memory, but rather to the 45GS02’s
true 28-bit address space. This allows easy access to any memory, without requiring
the use of complex bank-switching or DMA operations.
For example, if addresses $12 to $15 contained the bytes $20, $30, $FD, $0F, rep-
resenting the 32-bit address $FFD3020, i.e., the VIC-IV border colour register’s nat-
ural address, and the Z index contained the value $01, the following instruction se-
quence would change the screen colour to blue, because the screen colour register is
at $FFD3021, i.e., $FFD3020 + Z:

LDA # $06
LDZ # $01
STA [ $12 ] , Z

K-11
See the note on page K-5 for more information about Base-Page and Zero-Page.

32-bit Base-Page (Zero-Page) Indirect


Quad Z-Indexed Mode
This addressing mode is identical to the 32-bit Base-Page Indirect Z-Indexed Mode,
except that it operates on 32-bits of data at the 32-bit address formed by the argu-
ment, in comparison to 32-bit Base-Page Indirect Z-Indexed Mode which operates on
only 8 bits of data. The encoding of this addressing mode is $42, $42, $EA, followed
by the natural 6502 opcode for the instruction being performed.
It is also important to note that most of the time Z is actually not added to the pointer,
as it is part of the Q Pseudo Register. Only LDQ ($nn),Z will add Z. For example,

LDQ [ $12 ] , Z

would read the memory locations at $12 through $15 from the Base-Page, and use
those values to form the 32-bit address from which to load the Q Pseudo Register.
The Z index is added to the 32-bit address. This instruction would be encoded as $42
$42 $EA $B2 $12.
See the note on page K-5 for more information about Base-Page and Zero-Page. See
the note on page K-5 for more information on Quad Mode instructions. See the note
on page K-11 for more information on 32-bit Base-Page Indirect addressing.

Stack Relative Indirect, Y-Indexed


This addressing mode is similar to Base-Page Indirect Y-Indexed Mode, except that
instead of providing the address of the pointer in the Base-Page, the operand indi-
cates the offset in the stack to find the pointer. This addressing mode effectively
de-references a pointer that has been placed on the stack, e.g., as part of a function
call from a high-level language. It is encoded identically to the Base-Page Mode.
For example,

LDA ( $12 , SP ) , Y

This would use the contents of memory at the current stack pointer plus $12 to com-
pute the address of the pointer. This pointer would then have the Y-Register value
added to it to obtain the final address to read from, and to store the value into the
Accumulator. The instruction byte stream for this instruction would be $E2 $12.
If the Stack Pointer currently pointed to $01E0, then the pointer address would be
read from addresses $1F2 and $1F3, i.e., the two bytes at $1E0 + $12 and $1E0 +

K-12
$13. If locations $1F2 and $1F3 contained $78 and $56 respectively, and the Y-
Register contained the value $34, then the final memory location that would be read
would be $5678 + $34 = $56AC, and the contents of that memory location would be
read into the Accumulator.

Relative Addressing Mode


In this addressing mode, the operand is an 8-bit signed offset to the current value of
the Program Counter (PC). It is used to allow branches to encode the nearby address
at which execution should proceed if the branch is taken.
For example,

BNE $2003

would jump to $2003, if the Z flag of the processor was not set. If this instruction
were located at address $2000, it would be encoded as $D0 $01, i.e., branching
to +1 bytes after the PC. Branch offsets greater than $7F branch backwards, with
$FD branching to the byte immediately preceeding the branch instruction, and lower
values branching progressively further back. In this way, a branch can effectively be
made between -125 and +127 bytes from the opcode byte of the branch instruction.
For longer branches, the 45GS02 supports Relative Word Addressing Mode, where
the offset is encoded using 2 bytes instead of 1.

Relative Word Addressing Mode


This addressing mode is identical to Relative Addressing Mode, except that the ad-
dress offset is a 16-bit value. This allows a relative branch or jump to any location in
the current 64KB memory view. This makes it possible to write software that is fully
relocatable, by avoiding the need for absolute addresses when calling routines.
For example,

BNE $3000

would jump to $3000 if the Z flag of the process was not set. If this instruction were
located at address $2002, it would be encoded as $D3 $FC $0F, i.e., branching to
+$FFC = 4,092 bytes following the second byte of the instruction. The fact that the
instruction is 3 bytes long is ignored in this calculation.

K-13
6502 INSTRUCTION SET
NOTE: The mechanisms for switching from 4510 to 6502 CPU personality have yet to
be finalised.

Official And Unintended Instructions


The 6502 opcode matrix has a size of 16 x 16 = 256 possible opcodes. Those, that
are officially documented, form the set of the legal instructions. All instructions of this
legal set are headed by a blue coloured mnemonic.
The remaining opcodes form the set of the unintended instructions (sometimes called
”illegal” instructions). For the sake of completeness these are documented too. All
instructions of the unintended set are headed by a red coloured mnemonic.
NOTE: The unintended instructions are currently unimplemented, and are guaranteed
not to produce exactly the same results as on other CPU’s of the 65xx family. Many of
these instructions are known to be unstable, even running on old hardware.

Opcode Table
The Opcode Table lists all possible opcodes, their size, cycles and addressing mode in
a conscise format.
A cell with a light red background signifies an unintended instruction.
$x0 $x1
size cyc size cyc
$0x OPC OPC
mode mode

The letters attached to the cycle count have the following meaning:
Meaning
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
p Add one cycle if indexing crosses a page boundary.

K-14
K-15
Opcode Table 6502
$x0 $x1 $x2 $x3 $x4 $x5 $x6 $x7
1 7 2 6 1 9 2 8 2 3 2 3 2 5 2 5
$0x BRK ORA KIL SLO NOP ORA ASL SLO
imp bpiX imp bpiX bp bp bp bp
2 2b 2 5p 1 9 2 8 2 4 2 4p 2 6 2 6
$1x BPL ORA KIL SLO NOP ORA ASL SLO
rel ibpY imp ibpY bpX bpX bpX bpX
3 6 2 6 1 9 2 8 2 3 2 3 2 5 2 5
$2x JSR AND KIL RLA BIT AND ROL RLA
abs bpiX imp bpiX bp bp bp bp
2 2b 2 5p 1 9 2 8 2 4 2 4 2 6 2 6
$3x BMI AND KIL RLA NOP AND ROL RLA
rel ibpY imp ibpY bpX bpX bpX bpX
1 6 2 6 1 9 2 8 2 3 2 3 2 5 2 5
$4x RTI EOR KIL SRE NOP EOR LSR SRE
imp bpiX imp bpiX bp bp bp bp
2 2b 2 5p 1 9 2 8 2 4 2 4 2 6 2 6
$5x BVC EOR KIL SRE NOP EOR LSR SRE
rel ibpY imp ibpY bpX bpX bpX bpX
1 6 2 6 1 9 2 8 2 3 2 3 2 5 2 5
$6x RTS ADC KIL RRA NOP ADC ROR RRA
imp bpiX imp bpiX bp bp bp bp
2 2b 2 5p 1 9 2 8 2 4 2 4 2 6 2 6
$7x BVS ADC KIL RRA NOP ADC ROR RRA
rel ibpY imp ibpY bpX bpX bpX bpX
2 2 2 6 2 2 2 6 2 3 2 3 2 3 2 3
$8x NOP STA NOP SAX STY STA STX SAX
imm bpiX imm bpiX bp bp bp bp
2 2b 2 6 1 9 2 6 2 4 2 4 2 4 2 4
$9x BCC STA KIL SHA STY STA STX SAX
rel ibpY imp ibpY bpX bpX bpY bpY
2 2 2 6 2 2 2 6 2 3 2 3 2 3 2 3
$Ax LDY LDA LDX LAX LDY LDA LDX LAX
imm bpiX imm bpiX bp bp bp bp
2 2b 2 5p 1 9 2 5p 2 4 2 4 2 4 2 4
$Bx BCS LDA KIL LAX LDY LDA LDX LAX
rel ibpY imp ibpY bpX bpX bpY bpY
2 2 2 6 2 2 2 8 2 3 2 3 2 5 2 5
$Cx CPY CMP NOP DCP CPY CMP DEC DCP
imm bpiX imm bpiX bp bp bp bp
2 2b 2 5p 1 9 2 8 2 4 2 4 2 6 2 6
$Dx BNE CMP KIL DCP NOP CMP DEC DCP
rel ibpY imp ibpY bpX bpX bpX bpX
2 2 2 6 2 2 2 8 2 3 2 3 2 5 2 5
$Ex CPX SBC NOP ISC CPX SBC INC ISC
imm bpiX imm bpiX bp bp bp bp
2 2b 2 5p 1 9 2 8 2 4 2 4 2 6 2 6
$Fx BEQ SBC KIL ISC NOP SBC INC ISC
rel ibpY imp ibpY bpX bpX bpX bpX

K-16
Opcode Table 6502
$x8 $x9 $xA $xB $xC $xD $xE $xF
1 3 2 2 1 2 2 2 3 4 3 4 3 6 3 6
PHP ORA ASL ANC NOP ORA ASL SLO $0x
imp imm acc imm abs abs abs abs
1 2 3 4p 1 2 3 7 3 4p 3 4p 3 7 3 7
CLC ORA NOP SLO NOP ORA ASL SLO $1x
imp absY imp absY absX absX absX absX
1 4 2 2 1 2 2 2 3 4 3 4 3 6 3 6
PLP AND ROL ANC BIT AND ROL RLA $2x
imp imm acc imm abs abs abs abs
1 2 3 4p 1 2 3 7 3 4p 3 4p 3 7 3 7
SEC AND NOP RLA NOP AND ROL RLA $3x
imp absY imp absY absX absX absX absX
1 3 2 2 1 2 2 2 3 3 3 4 3 6 3 6
PHA EOR LSR ALR JMP EOR LSR SRE $4x
imp imm acc imm abs abs abs abs
1 2 3 4p 1 2 3 7 3 4p 3 4p 3 7 3 7
CLI EOR NOP SRE NOP EOR LSR SRE $5x
imp absY imp absY absX absX absX absX
1 4 2 2 1 2 2 2 3 5 3 4 3 6 3 6
PLA ADC ROR ARR JMP ADC ROR RRA $6x
imp imm acc imm ind abs abs abs
1 2 3 4p 1 2 3 7 3 4p 3 4p 3 7 3 7
SEI ADC NOP RRA NOP ADC ROR RRA $7x
imp absY imp absY absX absX absX absX
1 2 2 2 1 2 2 2 3 4 3 4 3 4 3 4
DEY NOP TXA XAA STY STA STX SAX $8x
imp imm imp imm abs abs abs abs
1 2 3 5 1 2 3 5 3 5 3 5 3 5 3 5
TYA STA TXS TAS SHY STA SHX SHA $9x
imp absY imp absY absX absX absY absY
1 2 2 2 1 2 2 2 3 4 3 4 3 4 3 4
TAY LDA TAX LAX LDY LDA LDX LAX $Ax
imp imm imp imm abs abs abs abs
1 2 3 4p 1 2 3 4p 3 4p 3 4p 3 4p 3 4p
CLV LDA TSX LAS LDY LDA LDX LAX $Bx
imp absY imp absY absX absX absY absY
1 2 2 2 1 2 2 2 3 4 3 4 3 6 3 6
INY CMP DEX SBX CPY CMP DEC DCP $Cx
imp imm imp imm abs abs abs abs
1 2 3 4p 1 2 3 7 3 4p 3 4p 3 7 3 7
CLD CMP NOP DCP NOP CMP DEC DCP $Dx
imp absY imp absY absX absX absX absX
1 2 2 2 1 2 2 2 3 4 3 4 3 6 3 6
INX SBC NOP SBC CPX SBC INC ISC $Ex
imp imm imp imm abs abs abs abs
1 2 3 4p 1 2 3 7 3 4p 3 4p 3 7 3 7
SED SBC NOP ISC NOP SBC INC ISC $Fx
imp absY imp absY absX absX absX absX

K-17
ADC
This instruction adds the argument and the Carry Flag to the contents of the Accumu-
lator Register. If the D flag is set, then the addition is performed using Binary Coded
Decimal.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The V flag will be set if the result has a different sign to both of the arguments,
otherwise it will be cleared. If the flag is set, this indicates that a signed overflow
has occurred.
• The C flag will be set if the unsigned result is >255, or >99 if the D flag is set.
ADC : Add with carry 6502
A←A+M+C
N Z I C D V E
+ + · + · + ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) ADC ($nn,X) 61 2 6
zero-page ADC $nn 65 2 3
immediate 8bit ADC #$nn 69 2 2
absolute ADC $nnnn 6D 3 4
p
(indirect),Y ADC ($nn),Y 71 2 5
zero-page,X ADC $nn,X 75 2 4
p
absolute,Y ADC $nnnn,Y 79 3 4
p
absolute,X ADC $nnnn,X 7D 3 4
p Add one cycle if indexing crosses a page boundary.

ALR [unintended]
This instruction shifts the Accumulator one bit right after performing a binary AND of
the Accumulator and the immediate mode argument. Bit 7 will be set to zero, and the
bit 0 will be shifted out into the Carry Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-18
• The C flag will be set to bit 0 of the AND result, prior to being shifted.
ALR : Binary AND and Logical Shift Right 6502
A ← A AND M, C ← A(0), A ← A≫1, A(7) ← 0
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit ALR #$nn 4B 2 2

ANC [unintended]
This instruction performs a binary AND operation of the argument with the accumu-
lator, and stores the result in the accumulator. Only bits that were already set in the
accumulator, and that are set in the argument will be set in the accumulator on com-
pletion. Unlike the AND instruction, the Carry Flag is set as though the result were
shifted left one bit. That is, the Carry Flag is set in the same way as the Negative Flag.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The C flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
ANC : Binary AND, and Set Carry 6502
A ← A AND M, C ← A(7)
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit ANC #$nn 0B 2 2
immediate 8bit ANC #$nn 2B 2 2

AND
This instruction performs a binary AND operation of the argument with the accumu-
lator, and stores the result in the accumulator. Only bits that were already set in the
accumulator, and that are set in the argument will be set in the accumulator on com-
pletion.

K-19
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
AND : Binary AND 6502
A ← A AND M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) AND ($nn,X) 21 2 6
zero-page AND $nn 25 2 3
immediate 8bit AND #$nn 29 2 2
absolute AND $nnnn 2D 3 4
p
(indirect),Y AND ($nn),Y 31 2 5
zero-page,X AND $nn,X 35 2 4
p
absolute,Y AND $nnnn,Y 39 3 4
p
absolute,X AND $nnnn,X 3D 3 4
p Add one cycle if indexing crosses a page boundary.

ARR [unintended]
This instruction shifts the Accumulator one bit right after performing a binary AND of
the Accumulator and the immediate mode argument M . Bit 7 is exchanged with the
carry.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The V flag will be apparently be affected in some way.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
ARR : Binary AND and Rotate Right 6502
A ← A AND M, A ← A≫1, C ↔ A(7)
N Z I C D V E
+ + · + · + ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit ARR #$nn 6B 2 2

K-20
ASL
This instruction shifts either the Accumulator or contents of the provided memory lo-
cation one bit left. Bit 0 will be set to zero, and the bit 7 will be shifted out into the
Carry Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
ASL : Arithmetic Shift Left Memory or Accumulator 6502
A ← A≪1 or M ← M≪1
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
zero-page ASL $nn 06 2 5
accumulator ASL A 0A 1 2
absolute ASL $nnnn 0E 3 6
zero-page,X ASL $nn,X 16 2 6
absolute,X ASL $nnnn,X 1E 3 7

BCC
This instruction branches to the indicated address if the Carry Flag is clear.
BCC : Branch on Carry Flag Clear 6502
C=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BCC $rr 90 2 2
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BCS
This instruction branches to the indicated address if the Carry Flag is set.

K-21
BCS : Branch on Carry Flag Set 6502
C=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BCS $rr B0 2 2
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BEQ
This instruction branches to the indicated address if the Zero Flag is set. BEQ stands
for branch if equal, because a CMP will result in the zero flag being set if the operants
are equal.
BEQ : Branch on Zero Flag Set 6502
Z=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BEQ $rr F0 2 2
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BIT
This instruction is used to test the bits stored in a memory location or the immediate
argument of the opcode.
Bits 6 and 7 of the memory location’s contents are directly copied into the Overflow
Flag and Negative Flag. The Zero Flag is set or cleared based on the result of per-
forming the binary AND of the Accumulator Register and the contents of the indicated
memory location.
The immediate test will set the N and V flags with valid states (treating the argument
as the memory value), which was not the case with the earlier 65C02 implementation.

Side effects
• The N flag will be set if the bit 7 of the memory location is set, otherwise it will
be cleared.
• The V flag will be set if the bit 6 of the memory location is set, otherwise it will
be cleared.

K-22
• The Z flag will be set if the result of A AND M is zero, otherwise it will be cleared.
BIT : Perform Bit Test 6502
N ← M(7), V ← M(6), Z ← A AND M
N Z I C D V E
+ + · · · + ·
Addressing Mode Assembly Code Bytes Cycles
zero-page BIT $nn 24 2 3
absolute BIT $nnnn 2C 3 4

BMI
This instruction branches to the indicated address if the Negative Flag is set. BMI
stands for branch on minus.
BMI : Branch on Negative Flag Set 6502
N=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BMI $rr 30 2 2
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BNE
This instruction branches to the indicated address if the Zero Flag is clear. BNE stands
for Branch if not equal, because a CMP will result in the zero flag being cleared if the
operants are not equal.
BNE : Branch on Zero Flag Clear 6502
Z=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BNE $rr D0 2 2
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

K-23
BPL
This instruction branches to the indicated address if the Negative Flag is clear. BPL
stands for branch on plus.
BPL : Branch on Negative Flag Clear 6502
N=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BPL $rr 10 2 2
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BRK
The break command causes the microprocessor to go through an interrupt sequence
under program control. The address of the BRK instruction + 2 is pushed to the stack
along with the status register with the Break flag set. This allows the interrupt service
routine to distinguish between IRQ events and BRK events. For example:
PLA ; load status
PHA ; restore stack
AND #$10 ; mask break flag
BNE DO_BREAK ; -> it was a BRK
... ; else continue with IRQ server
Cite from: MCS6500 Microcomputer Family Programming Manual, January 1976,
Second Edition, MOS Technology Inc., Page 144:
”The BRK is a single byte instruction and its addressing mode is Implied.”
There are debates, that BRK could be seen as a two byte instruction with the addressing
mode immediate, where the operand byte is discarded. The byte following the BRK
could then be used as a call argument for the break handler. Commodore however
used the BRK, as stated in the manual, as a single byte instruction, which breaks into
the ML monitor, if present. These builtin monitors decremented the stacked PC, so that
it could be used to return or jump directly to the code byte after the BRK.
BRK : Break to Interrupt 6502
STACK ← PC + 2; PC ← ($FFFE)
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied BRK 00 1 7

K-24
BVC
This instruction branches to the indicated address if the Overflow (V) Flag is clear.
BVC : Branch on Overflow Flag Clear 6502
V=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BVC $rr 50 2 2
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BVS
This instruction branches to the indicated address if the Overflow (V) Flag is set.
BVS : Branch on Overflow Flag Set 6502
V=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BVS $rr 70 2 2
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

CLC
This instruction clears the Carry Flag.

Side effects
• The C flag is cleared.
CLC : Clear Carry Flag 6502
C←0
N Z I C D V E
· · · + · · ·
Addressing Mode Assembly Code Bytes Cycles
implied CLC 18 1 2

K-25
CLD
This instruction clears the Decimal Flag. Arithmetic operations will use normal binary
arithmetic, instead of Binary-Coded Decimal (BCD).

Side effects
• The D flag is cleared.
CLD : Clear Decimal Flag 6502
D←0
N Z I C D V E
· · · · + · ·
Addressing Mode Assembly Code Bytes Cycles
implied CLD D8 1 2

CLI
This instruction clears the Interrupt Disable Flag. Interrupts will now be able to occur.

Side effects
• The I flag is cleared.
CLI : Clear Interrupt Disable Flag 6502
I←0
N Z I C D V E
· · + · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied CLI 58 1 2

CLV
This instruction clears the Overflow Flag.

Side effects
• The V flag is cleared.

K-26
CLV : Clear Overflow Flag 6502
V←0
N Z I C D V E
· · · · · + ·
Addressing Mode Assembly Code Bytes Cycles
implied CLV B8 1 2

CMP
This instruction performs A − M, and sets the processor flags accordingly, but does not
modify the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result of A − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of A − M is zero or positive, i.e., if A is not less
than M, otherwise it will be cleared.
• The Z flag will be set if the result of A − M is zero, otherwise it will be cleared.
CMP : Compare Accumulator 6502
N,C,Z ⇐ [A − M]
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) CMP ($nn,X) C1 2 6
zero-page CMP $nn C5 2 3
immediate 8bit CMP #$nn C9 2 2
absolute CMP $nnnn CD 3 4
p
(indirect),Y CMP ($nn),Y D1 2 5
zero-page,X CMP $nn,X D5 2 4
p
absolute,Y CMP $nnnn,Y D9 3 4
p
absolute,X CMP $nnnn,X DD 3 4
p Add one cycle if indexing crosses a page boundary.

CPX
This instruction performs X − M, and sets the processor flags accordingly, but does not
modify the contents of the Accumulator Register.

K-27
Side effects
• The N flag will be set if the result of X − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of X − M is zero or positive, i.e., if X is not less
than M, otherwise it will be cleared.
• The Z flag will be set if the result of X − M is zero, otherwise it will be cleared.
CPX : Compare X Register 6502
N,C,Z ⇐ [X − M]
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit CPX #$nn E0 2 2
zero-page CPX $nn E4 2 3
absolute CPX $nnnn EC 3 4

CPY
This instruction performs Y − M, and sets the processor flags accordingly, but does not
modify the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result of Y − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of Y − M is zero or positive, i.e., if Y is not less
than M, otherwise it will be cleared.
• The Z flag will be set if the result of Y − M is zero, otherwise it will be cleared.
CPY : Compare Y Register 6502
N,C,Z ⇐ [Y − M]
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit CPY #$nn C0 2 2
zero-page CPY $nn C4 2 3
absolute CPY $nnnn CC 3 4

K-28
DCP [unintended]
This instruction decrements the contents of the indicated memory location, and then
performs A − M, and sets the processor flags accordingly, but does not modify the
contents of the Accumulator Register.

Side effects
• The N flag will be set if the result of A − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of A − M is zero or positive, i.e., if A is not less
than M, otherwise it will be cleared.
• The Z flag will be set if the result of A − M is zero, otherwise it will be cleared.
DCP : Decrement and Compare Accumulator 6502
M ← M − 1, N,C,Z ⇐ [A − M]
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) DCP ($nn,X) C3 2 8
zero-page DCP $nn C7 2 5
absolute DCP $nnnn CF 3 6
(indirect),Y DCP ($nn),Y D3 2 8
zero-page,X DCP $nn,X D7 2 6
absolute,Y DCP $nnnn,Y DB 3 7
absolute,X DCP $nnnn,X DF 3 7

DEC
This instruction decrements the Accumulator Register or indicated memory location.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-29
DEC : Decrement 6502
A ← A − 1 or M ← M − 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
zero-page DEC $nn C6 2 5
absolute DEC $nnnn CE 3 6
zero-page,X DEC $nn,X D6 2 6
absolute,X DEC $nnnn,X DE 3 7

DEX
This instruction decrements the X Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
DEX : Decrement X Register 6502
X←X−1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied DEX CA 1 2

DEY
This instruction decrements the Y Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-30
DEY : Decrement Y Register 6502
Y←Y−1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied DEY 88 1 2

EOR
This instruction performs a binary exclusive-OR operation of the argument with the
accumulator, and stores the result in the accumulator. Only bits that were already set
in the accumulator, or that are set in the argument will be set in the accumulator on
completion, but not both.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
EOR : Binary Exclusive OR 6502
A ← A XOR M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) EOR ($nn,X) 41 2 6
zero-page EOR $nn 45 2 3
immediate 8bit EOR #$nn 49 2 2
absolute EOR $nnnn 4D 3 4
p
(indirect),Y EOR ($nn),Y 51 2 5
zero-page,X EOR $nn,X 55 2 4
p
absolute,Y EOR $nnnn,Y 59 3 4
p
absolute,X EOR $nnnn,X 5D 3 4
p Add one cycle if indexing crosses a page boundary.

INC
This instruction increments the Accumulator Register or indicated memory location.

K-31
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
INC : Increment Memory or Accumulator 6502
A ← A + 1 or M ← M + 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
zero-page INC $nn E6 2 5
absolute INC $nnnn EE 3 6
zero-page,X INC $nn,X F6 2 6
absolute,X INC $nnnn,X FE 3 7

INX
This instruction increments the X Register, i.e., adds 1 to it.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
INX : Increment X Register 6502
X←X+1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied INX E8 1 2

INY
This instruction increments the Y Register, i.e., adds 1 to it.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-32
INY : Increment Y Register 6502
Y←Y+1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied INY C8 1 2

ISC [unintended]
This instruction increments the indicated memory location, and then performs A − M -
1 + C, and sets the processor flags accordingly. The result is stored in the Accumulator
Register.
NOTE: This instruction is affected by the status of the Decimal Flag.

Side effects
• The N flag will be set if the result of A − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of A − M is zero or positive, i.e., if A is not less
than M, otherwise it will be cleared.
• The V flag will be set if the result has a different sign to both of the arguments,
otherwise it will be cleared. If the flag is set, this indicates that a signed overflow
has occurred.
• The Z flag will be set if the result of A − M is zero, otherwise it will be cleared.
ISC : Increment Memory, Subtract With Carry 6502
M ← M + 1, A ← − M − 1 + C
N Z I C D V E
+ + · + · + ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) ISC ($nn,X) E3 2 8
zero-page ISC $nn E7 2 5
absolute ISC $nnnn EF 3 6
(indirect),Y ISC ($nn),Y F3 2 8
zero-page,X ISC $nn,X F7 2 6
absolute,Y ISC $nnnn,Y FB 3 7
absolute,X ISC $nnnn,X FF 3 7

K-33
JMP
This instruction sets the Program Counter (PC) Register to the address indicated by the
instruction, causing execution to continue from that address.
JMP : Jump to Address 6502
PC ← M2:M1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
absolute JMP $nnnn 4C 3 3
(indirect) JMP ($nnnn) 6C 3 5

JSR
This instruction saves the address of the instruction following the JSR instruction onto
the stack, and then sets the Program Counter (PC) Register to the address indicated by
the instruction, causing execution to continue from that address. Because the return
address has been saved on the stack, the RTS instruction can be used to return from
the called sub-routine and resume execution following the JSR instruction.
NOTE: This instruction actually pushes the address of the last byte of the JSR instruction
onto the stack. The RTS instruction naturally is aware of this, and increments the ad-
dress on popping it from the stack, before setting the Program Counter (PC) register.
JSR : Jump to Sub-Routine 6502
PC ← M2:M1, STACK ← PCH:PCL
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
absolute JSR $nnnn 20 3 6

KIL [unintended]
On a 6502, these instructions cause the processor to enter an infinite loop in their in-
ternal logic that can only be aborted by resetting the computer. On the 45GS02 these
instructions cause Hypervisor Traps, once this functionality has been implemented. Thus
they can be used to detect whether running on a 6502 or a 45GS02: If on a 6502
processor, the instruction will never return, while they will cause an exception on a
45GS02, likely causing the calling program to be aborted or crash.

K-34
KIL : Lock-up 6502 Processor 6502

N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied KIL 02 1 9
implied KIL 12 1 9
implied KIL 22 1 9
implied KIL 32 1 9
implied KIL 42 1 9
implied KIL 52 1 9
implied KIL 62 1 9
implied KIL 72 1 9
implied KIL 92 1 9
implied KIL B2 1 9
implied KIL D2 1 9
implied KIL F2 1 9

LAS [unintended]
NOTE: This monstrosity of an instruction, aside from being devoid of any conceivable
useful purpose is unstable on many 6502 processors and should therefore also be
avoided for that reason, if you had not already been put off.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• A feeling of hollow satisfaction, when you actually discover a useful purpose for
this instruction.
LAS : Set A, X and SPL Register With Useless Value 6502
SP, A, X ← SP AND M
N Z I C D V E
+ · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
p
absolute,Y LAS $nnnn,Y BB 3 4
p Add one cycle if indexing crosses a page boundary.

K-35
LAX [unintended]
This instruction loads both the Accumulator Register and X Register with the indicated
value, or with the contents of the indicated location.
NOTE: The LAX instruction is known to be unstable on many 6502 processors, and
should not be used. Non-immediate modes MAY be stable enough to be usable, but
should generally be avoided.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
LAX : Load Accumulator and X Registers 6502
A, X ← M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) LAX ($nn,X) A3 2 6
zero-page LAX $nn A7 2 3
immediate 8bit LAX #$nn AB 2 2
absolute LAX $nnnn AF 3 4
p
(indirect),Y LAX ($nn),Y B3 2 5
zero-page,Y LAX $nn,Y B7 2 4
p
absolute,Y LAX $nnnn,Y BF 3 4
p Add one cycle if indexing crosses a page boundary.

LDA
This instruction loads the Accumulator Register with the indicated value, or with the
contents of the indicated location.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-36
LDA : Load Accumulator 6502
A←M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) LDA ($nn,X) A1 2 6
zero-page LDA $nn A5 2 3
immediate 8bit LDA #$nn A9 2 2
absolute LDA $nnnn AD 3 4
p
(indirect),Y LDA ($nn),Y B1 2 5
zero-page,X LDA $nn,X B5 2 4
p
absolute,Y LDA $nnnn,Y B9 3 4
p
absolute,X LDA $nnnn,X BD 3 4
p Add one cycle if indexing crosses a page boundary.

LDX
This instruction loads the X Register with the indicated value, or with the contents of
the indicated location.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
LDX : Load X Register 6502
X←M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit LDX #$nn A2 2 2
zero-page LDX $nn A6 2 3
absolute LDX $nnnn AE 3 4
zero-page,Y LDX $nn,Y B6 2 4
p
absolute,Y LDX $nnnn,Y BE 3 4
p Add one cycle if indexing crosses a page boundary.

K-37
LDY
This instruction loads the Y Register with the indicated value, or with the contents of
the indicated location.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
LDY : Load Y Register 6502
Y←M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit LDY #$nn A0 2 2
zero-page LDY $nn A4 2 3
absolute LDY $nnnn AC 3 4
zero-page,X LDY $nn,X B4 2 4
p
absolute,X LDY $nnnn,X BC 3 4
p Add one cycle if indexing crosses a page boundary.

LSR
This instruction shifts either the Accumulator or contents of the provided memory lo-
cation one bit right. Bit 7 will be set to zero, and the bit 0 will be shifted out into the
Carry Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted.

K-38
LSR : Logical Shift Right 6502
A ← A≫1, C ← A(0) or M ← M≫1, C ← M(0)
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
zero-page LSR $nn 46 2 5
accumulator LSR A 4A 1 2
absolute LSR $nnnn 4E 3 6
zero-page,X LSR $nn,X 56 2 6
absolute,X LSR $nnnn,X 5E 3 7

NOP
These instructions act as null instructions: They perform the bus accesses as though
they were real instructions, but then do nothing with the retrieved value. They can thus
be used either as delay instructions, or to read from registers that have side-effects
when read, without corrupting a register.
Only $EA is an intended opcode for NOP on the 6502. All others are only available
on NMOS versions of the processor, or the 45GS02 in 6502 mode.

K-39
NOP : No-Operation (some are unintended opcodes) 6502

N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
zero-page NOP $nn 04 2 3
absolute NOP $nnnn 0C 3 4
zero-page,X NOP $nn,X 14 2 4
implied NOP 1A 1 2
p
absolute,X NOP $nnnn,X 1C 3 4
zero-page,X NOP $nn,X 34 2 4
implied NOP 3A 1 2
p
absolute,X NOP $nnnn,X 3C 3 4
zero-page NOP $nn 44 2 3
zero-page,X NOP $nn,X 54 2 4
implied NOP 5A 1 2
p
absolute,X NOP $nnnn,X 5C 3 4
zero-page NOP $nn 64 2 3
zero-page,X NOP $nn,X 74 2 4
implied NOP 7A 1 2
p
absolute,X NOP $nnnn,X 7C 3 4
immediate 8bit NOP #$nn 80 2 2
immediate 8bit NOP #$nn 82 2 2
immediate 8bit NOP #$nn 89 2 2
immediate 8bit NOP #$nn C2 2 2
zero-page,X NOP $nn,X D4 2 4
implied NOP DA 1 2
p
absolute,X NOP $nnnn,X DC 3 4
immediate 8bit NOP #$nn E2 2 2
implied NOP EA 1 2
zero-page,X NOP $nn,X F4 2 4
implied NOP FA 1 2
p
absolute,X NOP $nnnn,X FC 3 4
p Add one cycle if indexing crosses a page boundary.

ORA
This instruction performs a binary OR operation of the argument with the accumulator,
and stores the result in the accumulator. Only bits that were already set in the accu-
mulator, or that are set in the argument will be set in the accumulator on completion,
or both.

K-40
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
ORA : Binary OR 6502
A ← A OR M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) ORA ($nn,X) 01 2 6
zero-page ORA $nn 05 2 3
immediate 8bit ORA #$nn 09 2 2
absolute ORA $nnnn 0D 3 4
p
(indirect),Y ORA ($nn),Y 11 2 5
p
zero-page,X ORA $nn,X 15 2 4
p
absolute,Y ORA $nnnn,Y 19 3 4
p
absolute,X ORA $nnnn,X 1D 3 4
p Add one cycle if indexing crosses a page boundary.

PHA
This instruction pushes the contents of the Accumulator Register onto the stack, and
decrements the value of the Stack Pointer by 1.
PHA : Push Accumulator Register onto the Stack 6502
STACK ← A, SP ← SP − 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied PHA 48 1 3

PHP
This instruction pushes the contents of the Processor Flags onto the stack, and decre-
ments the value of the Stack Pointer by 1.

K-41
PHP : Push Processor Flags onto the Stack 6502
STACK ← P, SP ← SP − 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied PHP 08 1 3

PLA
This instruction replaces the contents of the Accumulator Register with the top value
from the stack, and increments the value of the Stack Pointer by 1.
PLA : Pull Accumulator Register from the Stack 6502
A ← STACK, SP ← SP + 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied PLA 68 1 4

PLP
This instruction replaces the contents of the Processor Flags with the top value from
the stack, and increments the value of the Stack Pointer by 1.
NOTE: This instruction does NOT replace the Extended Stack Disable Flag (E Flag), or
the Software Interrupt Flag (B Flag)
PLP : Pull Processor Flags from the Stack 6502
A ← STACK, SP ← SP + 1
N Z I C D V E
+ + + + + + ·
Addressing Mode Assembly Code Bytes Cycles
implied PLP 28 1 4

RLA [unintended]
This instruction shifts the contents of the provided memory location one bit left. Bit 0
will be set to the current value of the Carry Flag, and the bit 7 will be shifted out into
the Carry Flag The result is then ANDed with the Accumulator.

K-42
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
RLA : Rotate Left Memory, and AND with Accumulator 6502
M ← M≪1, M(0) ← C, C ← M(7), A ← A AND M
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) RLA ($nn,X) 23 2 8
zero-page RLA $nn 27 2 5
absolute RLA $nnnn 2F 3 6
(indirect),Y RLA ($nn),Y 33 2 8
zero-page,X RLA $nn,X 37 2 6
absolute,Y RLA $nnnn,Y 3B 3 7
absolute,X RLA $nnnn,X 3F 3 7

ROL
This instruction shifts either the Accumulator or contents of the provided memory lo-
cation one bit left. Bit 0 will be set to the current value of the Carry Flag, and the bit
7 will be shifted out into the Carry Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.

K-43
ROL : Rotate Left Memory or Accumulator 6502
M ← M≪1, C ← M(7), M(0) ← C
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
zero-page ROL $nn 26 2 5
accumulator ROL A 2A 1 2
absolute ROL $nnnn 2E 3 6
zero-page,X ROL $nn,X 36 2 6
absolute,X ROL $nnnn,X 3E 3 7

ROR
This instruction shifts either the Accumulator or contents of the provided memory lo-
cation one bit right. Bit 7 will be set to the current value of the Carry Flag, and the bit
0 will be shifted out into the Carry Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
ROR : Rotate Right Memory or Accumulator 6502
M ← M≫1, C ← M(0), M(7) ← C
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
zero-page ROR $nn 66 2 5
accumulator ROR A 6A 1 2
absolute ROR $nnnn 6E 3 6
zero-page,X ROR $nn,X 76 2 6
absolute,X ROR $nnnn,X 7E 3 7

RRA [unintended]
This instruction shifts either the contents of the provided memory location one bit right.
Bit 7 will be set to the current value of the Carry Flag, and the bit 0 will be shifted out
into the Carry Flag. The result is added to the Accumulator.

K-44
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if the addition results in an overflow in the Accumulator.
RRA : Rotate Right Memory, and Add to Accumulator 6502
M ← M≫1, C ← M(0), M(7) ← C, A ← A + M
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) RRA ($nn,X) 63 2 8
zero-page RRA $nn 67 2 5
absolute RRA $nnnn 6F 3 6
(indirect),Y RRA ($nn),Y 73 2 8
zero-page,X RRA $nn,X 77 2 6
absolute,Y RRA $nnnn,Y 7B 3 7
absolute,X RRA $nnnn,X 7F 3 7

RTI
This instruction pops the processor flags from the stack, and then pops the Program
Counter (PC) register from the stack, allowing an interrupted program to resume.
• The 6502 Processor Flags are restored from the stack.
• Neither the B (Software Interrupt) nor E (Extended Stack) flags are set by this
instruction.
RTI : Return From Interrupt 6502
P ← STACK, PC ← STACK
N Z I C D V E
+ + + + + + ·
Addressing Mode Assembly Code Bytes Cycles
implied RTI 40 1 6

RTS
This instruction adds an optional argument to the Stack Pointer (SP) Register, and then
pops the Program Counter (PC) register from the stack, allowing a routine to return to
its caller.

K-45
RTS : Return From Subroutine 6502
PC ← STACK or PC ← STACK + M, SP ← SP − 2
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied RTS 60 1 6

SAX [unintended]
This instruction acts as a combination of AND and CMP. The result is stored in the X
Register. Because it includes functionality from CMP rather than SBC, the Carry Flag
is not used in the subtraction, although it is modified by the instruction.
NOTE: This instruction is affected by the status of the Decimal Flag.

Side effects
• The N flag will be set if the result of A − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of A − M is zero or positive, i.e., if A is not less
than M, otherwise it will be cleared.
• The V flag will be set if the result has a different sign to both of the arguments,
otherwise it will be cleared. If the flag is set, this indicates that a signed overflow
has occurred.
• The Z flag will be set if the result of A − M is zero, otherwise it will be cleared.
SAX : AND Accumulator and X, and Subtract Without Carry 6502
X ← (A AND X) − M
N Z I C D V E
+ + · + · + ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) SAX ($nn,X) 83 2 6
zero-page SAX $nn 87 2 3
absolute SAX $nnnn 8F 3 4
zero-page,Y SAX $nn,Y 97 2 4

SBC
This instruction performs A − M − 1 + C, and sets the processor flags accordingly.
The result is stored in the Accumulator Register.
NOTE: If the D flag is set, then the addition is performed using binary Coded Decimal.

K-46
Side effects
• The N flag will be set if the result of A − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of A − M is zero or positive, i.e., if A is not less
than M, otherwise it will be cleared.
• The V flag will be set if the result has a different sign to both of the arguments,
otherwise it will be cleared. If the flag is set, this indicates that a signed overflow
has occurred.
• The Z flag will be set if the result of A − M is zero, otherwise it will be cleared.
SBC : Subtract With Carry 6502
A←−M−1+C
N Z I C D V E
+ + · + · + ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) SBC ($nn,X) E1 2 6
zero-page SBC $nn E5 2 3
immediate 8bit SBC #$nn E9 2 2
immediate 8bit SBC #$nn EB 2 2
absolute SBC $nnnn ED 3 4
p
(indirect),Y SBC ($nn),Y F1 2 5
zero-page,X SBC $nn,X F5 2 4
p
absolute,Y SBC $nnnn,Y F9 3 4
p
absolute,X SBC $nnnn,X FD 3 4
p Add one cycle if indexing crosses a page boundary.

SBX [unintended]
This instruction loads the X Register with the binary AND of the Accumulator Register
and X Register, less the immediate argument.
NOTE: The subtraction effect in this instruction is due to CMP , not . Thus the Negative
Flag is set according to the function of CMP, not SBC. That is, the carry flag is not
used in the calculation.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if the result is zero or positive, otherwise it will be cleared.

K-47
SBX : AND and Subtract 6502
X ← ( A AND X ) − M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit SBX #$nn CB 2 2

SEC
This instruction sets the Carry Flag.

Side effects
• The C flag is set.
SEC : Set Carry Flag 6502
C←1
N Z I C D V E
· · · + · · ·
Addressing Mode Assembly Code Bytes Cycles
implied SEC 38 1 2

SED
This instruction sets the Decimal Flag. Binary arithmetic will now use Binary-Coded
Decimal (BCD) mode.
NOTE: The C64’s interrupt handler does not clear the Decimal Flag, which makes it
dangerous to set the Decimal Flag without first setting the Interrupt Disable Flag.

Side effects
• The D flag is set.
SED : Set Decimal Flag 6502
D←1
N Z I C D V E
· · · · + · ·
Addressing Mode Assembly Code Bytes Cycles
implied SED F8 1 2

K-48
SEI
This instruction sets the Interrupt Disable Flag. Normal (IRQ) interrupts will no longer
be able to occur. Non-Maskable Interrupts (NMI) will continue to occur, as their name
suggests.

Side effects
• The I flag is set.
SEI : Set Interrupt Disable Flag 6502
I←1
N Z I C D V E
· · + · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied SEI 78 1 2

SHA [unintended]
NOTE: This instruction is unstable on many 6502 processors, and should be avoided.
This instruction stores the binary AND of the contents of the Accumulator Register, X
Register and the third byte of the instruction into the indicated location.
SHA : Store binary AND of A, X and 3rd Instruction Byte 6502
M ← A AND X AND B3
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect),Y SHA ($nn),Y 93 2 6
absolute,Y SHA $nnnn,Y 9F 3 5

SHX [unintended]
NOTE: This instruction is unstable on many 6502 processors, and should be avoided.
This instruction stores the binary AND of the contents of the X Register and the third
byte of the instruction into the indicated location.

K-49
SHX : Store Binary AND of X Register and 3rd Instruction Byte 6502
M ← X AND B3
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
absolute,Y SHX $nnnn,Y 9E 3 5

SHY [unintended]
NOTE: This instruction is unstable on many 6502 processors, and should be avoided.
This instruction stores the binary AND of the contents of the Y Register and the third
byte of the instruction into the indicated location.
SHY : Store Binary AND of Y Register and 3rd Instruction Byte 6502
M ← Y AND B3
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
absolute,X SHY $nnnn,X 9C 3 5

SLO [unintended]
This instruction shifts either contents of the provided memory location one bit left,
and then ORs the result with the Accumulator Register, and places the result in the
Accumulator.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the Accumulator contains $00 after the instruction has
completed, otherwise it will be cleared.
• The C flag will be set if bit 7 of the memory contents was set, prior to being
shifted.

K-50
SLO : Shift Left and OR 6502
C ← M(7), M ← M≪1, A ← A OR M
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) SLO ($nn,X) 03 2 8
zero-page SLO $nn 07 2 5
absolute SLO $nnnn 0F 3 6
(indirect),Y SLO ($nn),Y 13 2 8
zero-page,X SLO $nn,X 17 2 6
absolute,Y SLO $nnnn,Y 1B 3 7
absolute,X SLO $nnnn,X 1F 3 7

SRE [unintended]
This instruction shifts the contents of the provided memory location one bit right. Bit
7 will be set to zero, and the bit 0 will be shifted out into the Carry Flag. The result is
exclusive ORed with the Accumulator and stored in the Accumulator.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted.
SRE : Logical Shift Right and Exclusive OR with Accumulator 6502
C ← M(0), M ← M≫1, A ← A XOR M
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) SRE ($nn,X) 43 2 8
zero-page SRE $nn 47 2 5
absolute SRE $nnnn 4F 3 6
(indirect),Y SRE ($nn),Y 53 2 8
zero-page,X SRE $nn,X 57 2 6
absolute,Y SRE $nnnn,Y 5B 3 7
absolute,X SRE $nnnn,X 5F 3 7

K-51
STA
This instruction stores the contents of the Accumulator Register into the indicated lo-
cation.
STA : Store Accumulator 6502
M←A
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
(indirect,X) STA ($nn,X) 81 2 6
zero-page STA $nn 85 2 3
absolute STA $nnnn 8D 3 4
(indirect),Y STA ($nn),Y 91 2 6
zero-page,X STA $nn,X 95 2 4
absolute,Y STA $nnnn,Y 99 3 5
absolute,X STA $nnnn,X 9D 3 5

STX
This instruction stores the contents of the X Register into the indicated location.
STX : Store X Register 6502
M←X
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
zero-page STX $nn 86 2 3
absolute STX $nnnn 8E 3 4
zero-page,Y STX $nn,Y 96 2 4

STY
This instruction stores the contents of the Y Register into the indicated location.

K-52
STY : Store Y Register 6502
M←Y
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
zero-page STY $nn 84 2 3
absolute STY $nnnn 8C 3 4
zero-page,X STY $nn,X 94 2 4

TAS [unintended]
NOTE: This monstrosity of an instruction, aside from being devoid of any conceivable
useful purpose is unstable on many 6502 processors and should therefore also be
avoided for that reason, if you had not already been put off.

Side effects
• Remarkably, despite the over complicated operation that it performs, it modifies
none of the processor flags.
• Loss of sanity if you attempt to use it, or even figure out exactly how it works.
TAS : Munge X Register and Stack Pointer 6502
SP ← A AND X, M ← SP AND B3
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
absolute,Y TAS $nnnn,Y 9B 3 5

TAX
This instruction loads the X Register with the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-53
TAX : Transfer Accumulator Register into the X Register 6502
X←A
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied TAX AA 1 2

TAY
This instruction loads the Y Register with the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
TAY : Transfer Accumulator Register into the Y Register 6502
Y←A
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied TAY A8 1 2

TSX
This instruction loads the X Register with the contents of the Stack Pointer Low (SPL)
Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
TSX : Transfer Stack Pointer Low Register into the X Register 6502
X ← SPL
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied TSX BA 1 2

K-54
TXA
This instruction loads the Accumulator Register with the contents of the X Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
TXA : Transfer X Register into the Accumulator Register 6502
A←X
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied TXA 8A 1 2

TXS
This instruction sets the low byte of the Stack Pointer (SPL) register to the contents of
the X Register.
TXS : Transfer X Register into Stack Pointer Low Register 6502
SPL ← X
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied TXS 9A 1 2

TYA
This instruction loads the Accumulator Register with the contents of the Y Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-55
TYA : Transfer Y Register into the Accumulator Register 6502
A←Y
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied TYA 98 1 2

XAA [unintended]
This instruction loads the Accumulator Register with the binary AND of the X Register
and the immediate mode argument.
NOTE: This instruction is unstable on many 6502 processors, and should not be used.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
XAA : Transfer X into A and AND with operand 6502
A ← X AND VALUE
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit XAA #$nn 8B 2 2

K-56
4510 INSTRUCTION SET
Instruction Timing
Note that the number of cycles depends on the speed setting of the processor: Some
instructions take more or fewer cycles when the processor is running at full-speed, or a
C65 compatibility 3.5MHz speed, or at C64 compatibility 1MHz/2MHz speed. More
detailed information on this is listed under each each instruction’s information, but the
high-level view is:
• When the processor is running at 1MHz, all instructions take at least two cycles,
and dummy cycles are re-inserted into Read-Modify-Write instructions, so that
all instructions take exactly the same number of cycles as on a 6502.
• The Read-Modify-Write instructions and all instructions that read a value from
memory all require an extra cycle when operating at full speed, to allow signals
to propagate within the processor.
• The Read-Modify-Write instructions require an additional cycle if the operand is
$D019, as the dummy write is performed in this case. This is to improve com-
patibility with C64 software that frequently uses this “bug” of the 6502 to more
rapidly acknowledge VIC-II interrupts.
• Page-crossing and branch-taking penalties do not apply when the processor is
running at full speed.
• Many instructions require fewer cycles when the processor is running at full
speed, as generally most non-bus cycles are removed. For example, Pushing
and Pulling values to and from the stack requires only 2 cycles, instead of the 4
that that the 6502 requires for these instructions.

Opcode Table
The coloured cells indicate an extended 45GS02 Opcode. A Q pseudo register op-
code is marked blue, a base-page indirect Z indexed opcode that can use 32-bit
pointers is cyan.
$x0 $x1 $x2
size cyc size cyc size cyc
$0x OPC QOP FARQ
mode Q mode Q IbpZ

The letters attached to the cycle count have the following meaning:

K-57
Meaning
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
d Subtract one cycle when CPU is at 3.5MHz.
i Add one cycle if clock speed is at 40 MHz.
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

K-58
K-59
Opcode Table 4510/45GS02
$x0 $x1 $x2 $x3 $x4 $x5 $x6 $x7
1 7 2 6rp 1 1 1 1 2 3r 2 3r 2 4r 2 4rb
$0x BRK ORA CLE SEE TSB ORA ASL RMB0
imp bpiX imp imp bp Q bp Q bp bp
2 2b 2 5rp 2 5rp 3 3b 2 5r 2 3r 2 4r 2 4rb
$1x BPL ORA ORA BPL TRB ORA ASL RMB1
rel ibpY Q ibpZ relfar bp bpX Q bpX bp
3 5s 2 5rp 3 5r 3 5rp 2 3r 2 3r 2 4r 2 4r
$2x JSR AND JSR JSR BIT AND ROL RMB2
abs bpiX ind indX Q bp Q bp Q bp bp
2 2r 2 5rp 2 5rp 3 3b 2 3rp 2 4rp 2 5rp 2 4r
$3x BMI AND AND BMI BIT AND ROL RMB3
rel ibpY Q ibpZ relfar bpX bpX Q bpX bp
1 6m 2 5r 1 1 1 1 2 4r 2 3r 2 4r 2 4r
$4x RTI EOR NEG ASR ASR EOR LSR RMB4
imp bpiX acc Q acc Q bp Q bp Q bp bp
2 2b 2 5rp 2 5rp 3 3b 2 5rp 2 3p 2 3rp 2 4r
$5x BVC EOR EOR BVC ASR EOR LSR RMB5
rel ibpY Q ibpZ relfar Q bpX bpX Q bpX bp
1 6m 2 5r 2 4 3 3b 2 3 2 3r 2 5r 2 5r
$6x RTS ADC RTS BSR STZ ADC ROR RMB6
imp bpiX imm relfar bp Q bp Q bp bp
2 2b 2 5rp 2 5rp 3 3b 2 3 2 3r 2 5rmdp 2 4r
$7x BVS ADC ADC BVS STZ ADC ROR RMB7
rel ibpY Q ibpZ relfar bpX bpX Q bpX bp
2 2b 2 5p 2 6p 3 3b 2 3 2 3 2 3 2 4r
$8x BRA STA STA BRA STY STA STX SMB0
rel Q bpiX Q ispY relfar bp Q bp bp bp
2 2b 2 5p 2 5p 3 3b 2 3p 2 3p 2 3p 2 4r
$9x BCC STA STA BCC STY STA STX SMB1
rel Q ibpY Q ibpZ relfar bpX Q bpX bpY bp
2 2 2 5rp 2 2 2 2 2 3r 2 3r 2 3r 2 4r
$Ax LDY LDA LDX LDZ LDY LDA LDX SMB2
imm Q bpiX imm imm bp Q bp bp bp
2 2b 2 5rp 2 5rp 3 3b 2 3rp 2 3rp 2 5rp 2 4r
$Bx BCS LDA LDA BCS LDY LDA LDX SMB3
rel ibpY Q ibpZ relfar bpX bpX bpY bp
2 2 2 5rp 2 2 2 7mdr 2 3r 2 3r 2 5mdr 2 4r
$Cx CPY CMP CPZ DEW CPY CMP DEC SMB4
imm Q bpiX imm bp bp Q bp Q bp bp
2 2b 2 5rp 2 5rp 3 3b 2 3r 2 3rp 2 5mdrp 2 4r
$Dx BNE CMP CMP BNE CPZ CMP DEC SMB5
rel Q ibpY Q ibpZ relfar bp Q bpX Q bpX bp
2 2 2 3pm 2 6rmp 2 7mdr 2 3r 2 3r 2 5mdr 2 4r
$Ex CPX SBC LDA INW CPX SBC INC SMB6
imm Q bpiX ispY bp bp Q bp Q bp bp
2 2b 2 3rp 2 5rp 3 3b 3 5m 2 3rp 2 5dmrp 2 4r
$Fx BEQ SBC SBC BEQ PHW SBC INC SMB7
rel Q ibpY Q ibpZ relfar im16 Q bpX Q bpX bp

K-60
Opcode Table 4510/45GS02
$x8 $x9 $xA $xB $xC $xD $xE $xF
1 2 2 2 1 1 1 1 3 5r 3 4r 3 5r 3 0rb
PHP ORA ASL TSY TSB ORA ASL BBR0 $0x
imp imm Q acc imp abs Q abs Q abs bpr8
1 1 3 4r 1 1 1 1 3 4r 3 4rp 3 5rp 3 5b
CLC ORA INC INZ TRB ORA ASL BBR1 $1x
imp absY Q acc imp abs absX Q absX bpr8
1 4m 2 2 1 1 1 1 3 4r 3 4r 3 5r 3 5b
PLP AND ROL TYS BIT AND ROL BBR2 $2x
imp imm Q acc imp Q abs Q abs Q abs bpr8
1 1 3 4r 1 1 1 1 3 4rp 3 4rp 3 5rp 3 4b
SEC AND DEC DEZ BIT AND ROL BBR3 $3x
imp absY Q acc imp absX absX Q absX bpr8
1 2 2 2 1 1 1 1 3 3 3 4r 3 5r 3 4rb
PHA EOR LSR TAZ JMP EOR LSR BBR4 $4x
imp imm Q acc imp abs Q abs Q abs bpr8
1 1 3 4rp 1 2 1 1 1 1 3 4rp 3 5rp 3 4rb
CLI EOR PHY TAB MAP EOR LSR BBR5 $5x
imp absY imp imp imp absX Q absX bpr8
1 4m 2 2 1 1 1 1 3 5r 3 4r 3 6r 3 4rb
PLA ADC ROR TZA JMP ADC ROR BBR6 $6x
imp imm Q acc imp ind Q abs Q abs bpr8
1 1s 3 4r 1 4m 1 1 3 6mp 3 4r 3 5rmdp 3 4br
SEI ADC PLY TBA JMP ADC ROR BBR7 $7x
imp absY imp imp indX absX Q absX bpr8
1 1s 2 2 1 1 3 4p 3 4 3 4 3 4 3 4br
DEY BIT TXA STY STY STA STX BBS0 $8x
imp imm imp absX abs Q abs abs bpr8
1 1 3 4p 1 1 3 4p 3 4 3 4p 3 4p 3 4br
TYA STA TXS STX STZ STA STZ BBS1 $9x
imp Q absY imp absY abs Q absX absX bpr8
1 1 2 2 1 1 3 4r 3 4r 3 4r 3 4r 3 4br
TAY LDA TAX LDZ LDY LDA LDX BBS2 $Ax
imp imm imp abs abs Q abs abs bpr8
1 1 3 4rp 1 1 3 4rp 3 4rp 3 4rp 3 4rp 3 4br
CLV LDA TSX LDZ LDY LDA LDX BBS3 $Bx
imp absY imp absX absX absX absY bpr8
1 1s 2 2 1 1s 3 7rmd 3 4r 3 4r 3 6mdr 3 4br
INY CMP DEX ASW CPY CMP DEC BBS4 $Cx
imp imm imp abs abs Q abs Q abs bpr8
1 1 3 4rp 1 3m 1 3m 3 4r 3 4rp 3 6mdrp 3 4br
CLD CMP PHX PHZ CPZ CMP DEC BBS5 $Dx
imp Q absY imp imp abs Q absX Q absX bpr8
1 1s 2 2 1 1 3 5rmd 3 4r 3 4r 3 6dmr 3 4br
INX SBC EOM ROW CPX SBC INC BBS6 $Ex
imp imm imp abs abs Q abs Q abs bpr8
1 1s 3 4rp 1 4m 1 4m 3 7m 3 4rp 3 6drp 3 4br
SED SBC PLX PLZ PHW SBC INC BBS7 $Fx
imp Q absY imp imp abs Q absX Q absX bpr8

K-61
ADC
This instruction adds the argument and the Carry Flag to the contents of the Accumu-
lator Register. If the D flag is set, then the addition is performed using Binary Coded
Decimal.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The V flag will be set if the result has a different sign to both of the arguments,
otherwise it will be cleared. If the flag is set, this indicates that a signed overflow
has occurred.
• The C flag will be set if the unsigned result is >255, or >99 if the D flag is set.
ADC : Add with carry 4510
A←A+M+C
N Z I C D V E
+ + · + · + ·
Addressing Mode Assembly Code Bytes Cycles
r
(indirect,X) ADC ($nn,X) 61 2 5
r
base-page ADC $nn 65 2 3
immediate 8bit ADC #$nn 69 2 2
r
absolute ADC $nnnn 6D 3 4
pr
(indirect),Y ADC ($nn),Y 71 2 5
pr
(indirect),Z ADC ($nn),Z 72 2 5
r
base-page,X ADC $nn,X 75 2 3
r
absolute,Y ADC $nnnn,Y 79 3 4
r
absolute,X ADC $nnnn,X 7D 3 4
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

AND
This instruction performs a binary AND operation of the argument with the accumu-
lator, and stores the result in the accumulator. Only bits that were already set in the
accumulator, and that are set in the argument will be set in the accumulator on com-
pletion.

K-62
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
AND : Binary AND 4510
A ← A AND M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
pr
(indirect,X) AND ($nn,X) 21 2 5
r
base-page AND $nn 25 2 3
immediate 8bit AND #$nn 29 2 2
r
absolute AND $nnnn 2D 3 4
pr
(indirect),Y AND ($nn),Y 31 2 5
pr
(indirect),Z AND ($nn),Z 32 2 5
pr
base-page,X AND $nn,X 35 2 4
r
absolute,Y AND $nnnn,Y 39 3 4
pr
absolute,X AND $nnnn,X 3D 3 4
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

ASL
This instruction shifts either the Accumulator or contents of the provided memory lo-
cation one bit left. Bit 0 will be set to zero, and the bit 7 will be shifted out into the
Carry Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.

K-63
ASL : Arithmetic Shift Left Memory or Accumulator 4510
A ← A≪1 or M ← M≪1
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page ASL $nn 06 2 4
s
accumulator ASL A 0A 1 1
r
absolute ASL $nnnn 0E 3 5
r
base-page,X ASL $nn,X 16 2 4
pr
absolute,X ASL $nnnn,X 1E 3 5
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

ASR
This instruction shifts either the Accumulator or contents of the provided memory loca-
tion one bit right. Bit 7 is considered to be a sign bit, and is preserved. The contents
of bit 0 will be shifted out into the Carry Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted.
ASR : Arithmetic Shift Right 4510
A ← A>>1 or M ← M>>1
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
s
accumulator ASR A 43 1 1
r
base-page ASR $nn 44 2 4
pr
base-page,X ASR $nn,X 54 2 5
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

K-64
ASW
This instruction shifts a 16-bit value in memory left one bit.
For example, if location $1234 contained $87 and location $1235 contained $A9,
ASW $1234 would result in location $1234 containing $0E and location $1235 con-
taining $53, and the Carry Flag being set.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 7 of the upper byte was set, prior to being shifted,
otherwise it will be cleared.
ASW : Arithmetic Shift Word Left 4510
M ← M≪1
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
dmr
absolute ASW $nnnn CB 3 7
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
r Add one cycle if clock speed is at 40 MHz.

BBR0
This instruction branches to the indicated address if bit 0 is clear in the indicated
base-page memory location.
BBR0 : Branch on Bit 0 Reset 4510
M(0)=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBR0 $nn,$rr 0F 3 0
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

K-65
BBR1
This instruction branches to the indicated address if bit 1 is clear in the indicated
base-page memory location.
BBR1 : Branch on Bit 1 Reset 4510
M(1)=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
base-page+rel BBR1 $nn,$rr 1F 3 5
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BBR2
This instruction branches to the indicated address if bit 2 is clear in the indicated
base-page memory location.
BBR2 : Branch on Bit 2 Reset 4510
M(2)=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
base-page+rel BBR2 $nn,$rr 2F 3 5
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BBR3
This instruction branches to the indicated address if bit 3 is clear in the indicated
base-page memory location.
BBR3 : Branch on Bit 3 Reset 4510
M(3)=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
base-page+rel BBR3 $nn,$rr 3F 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

K-66
BBR4
This instruction branches to the indicated address if bit 4 is clear in the indicated
base-page memory location.
BBR4 : Branch on Bit 4 Reset 4510
M(4)=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBR4 $nn,$rr 4F 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BBR5
This instruction branches to the indicated address if bit 5 is clear in the indicated
base-page memory location.
BBR5 : Branch on Bit 5 Reset 4510
M(5)=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBR5 $nn,$rr 5F 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BBR6
This instruction branches to the indicated address if bit 6 is clear in the indicated
base-page memory location.

K-67
BBR6 : Branch on Bit 6 Reset 4510
M(6)=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBR6 $nn,$rr 6F 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BBR7
This instruction branches to the indicated address if bit 7 is clear in the indicated
base-page memory location.
BBR7 : Branch on Bit 7 Reset 4510
M(7)=0 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBR7 $nn,$rr 7F 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BBS0
This instruction branches to the indicated address if bit 0 is set in the indicated base-
page memory location.
BBS0 : Branch on Bit 0 Set 4510
M(0)=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBS0 $nn,$rr 8F 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

K-68
BBS1
This instruction branches to the indicated address if bit 1 is set in the indicated base-
page memory location.
BBS1 : Branch on Bit 1 Set 4510
M(1)=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBS1 $nn,$rr 9F 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BBS2
This instruction branches to the indicated address if bit 2 is set in the indicated base-
page memory location.
BBS2 : Branch on Bit 2 Set 4510
M(2)=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBS2 $nn,$rr AF 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BBS3
This instruction branches to the indicated address if bit 3 is set in the indicated base-
page memory location.

K-69
BBS3 : Branch on Bit 3 Set 4510
M(3)=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBS3 $nn,$rr BF 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BBS4
This instruction branches to the indicated address if bit 4 is set in the indicated base-
page memory location.
BBS4 : Branch on Bit 4 Set 4510
M(4)=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBS4 $nn,$rr CF 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BBS5
This instruction branches to the indicated address if bit 5 is set in the indicated base-
page memory location.
BBS5 : Branch on Bit 5 Set 4510
M(5)=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBS5 $nn,$rr DF 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

K-70
BBS6
This instruction branches to the indicated address if bit 6 is set in the indicated base-
page memory location.
BBS6 : Branch on Bit 6 Set 4510
M(6)=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBS6 $nn,$rr EF 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BBS7
This instruction branches to the indicated address if bit 7 is set in the indicated base-
page memory location.
BBS7 : Branch on Bit 7 Set 4510
M(7)=1 =⇒ PC ← PC + R8
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page+rel BBS7 $nn,$rr FF 3 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BCC
This instruction branches to the indicated address if the Carry Flag is clear.

K-71
BCC : Branch on Carry Flag Clear 4510
C=0 =⇒ PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BCC $rr 90 2 2
b
16-bit relative BCC $rrrr 93 3 3
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BCS
This instruction branches to the indicated address if the Carry Flag is set.
BCS : Branch on Carry Flag Set 4510
C=1 =⇒ PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BCS $rr B0 2 2
b
16-bit relative BCS $rrrr B3 3 3
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BEQ
This instruction branches to the indicated address if the Zero Flag is set. BEQ stands
for branch if equal, because a CMP will result in the zero flag being set if the operants
are equal.
BEQ : Branch on Zero Flag Set 4510
Z=1 =⇒ PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BEQ $rr F0 2 2
b
16-bit relative BEQ $rrrr F3 3 3
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

K-72
BIT
This instruction is used to test the bits stored in a memory location or the immediate
argument of the opcode.
Bits 6 and 7 of the memory location’s contents are directly copied into the Overflow
Flag and Negative Flag. The Zero Flag is set or cleared based on the result of per-
forming the binary AND of the Accumulator Register and the contents of the indicated
memory location.
The immediate test will set the N and V flags with valid states (treating the argument
as the memory value), which was not the case with the earlier 65C02 implementation.

Side effects
• The N flag will be set if the bit 7 of the memory location is set, otherwise it will
be cleared.
• The V flag will be set if the bit 6 of the memory location is set, otherwise it will
be cleared.
• The Z flag will be set if the result of A AND M is zero, otherwise it will be cleared.
BIT : Perform Bit Test 4510
N ← M(7), V ← M(6), Z ← A AND M
N Z I C D V E
+ + · · · + ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page BIT $nn 24 2 3
r
absolute BIT $nnnn 2C 3 4
pr
base-page,X BIT $nn,X 34 2 3
pr
absolute,X BIT $nnnn,X 3C 3 4
immediate 8bit BIT #$nn 89 2 2
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BMI
This instruction branches to the indicated address if the Negative Flag is set. BMI
stands for branch on minus.

K-73
BMI : Branch on Negative Flag Set 4510
N=1 =⇒ PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
relative BMI $rr 30 2 2
b
16-bit relative BMI $rrrr 33 3 3
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

BNE
This instruction branches to the indicated address if the Zero Flag is clear. BNE stands
for Branch if not equal, because a CMP will result in the zero flag being cleared if the
operants are not equal.
BNE : Branch on Zero Flag Clear 4510
Z=0 =⇒ PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BNE $rr D0 2 2
b
16-bit relative BNE $rrrr D3 3 3
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BPL
This instruction branches to the indicated address if the Negative Flag is clear. BPL
stands for branch on plus.
BPL : Branch on Negative Flag Clear 4510
N=0 =⇒ PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BPL $rr 10 2 2
b
16-bit relative BPL $rrrr 13 3 3
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

K-74
BRA
This instruction branches to the indicated address.
BRA : Branch Unconditionally 4510
PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BRA $rr 80 2 2
b
16-bit relative BRA $rrrr 83 3 3
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BRK
The break command causes the microprocessor to go through an interrupt sequence
under program control. The address of the BRK instruction + 2 is pushed to the stack
along with the status register with the Break flag set. This allows the interrupt service
routine to distinguish between IRQ events and BRK events. For example:
PLA ; load status
PHA ; restore stack
AND #$10 ; mask break flag
BNE DO_BREAK ; -> it was a BRK
... ; else continue with IRQ server
Cite from: MCS6500 Microcomputer Family Programming Manual, January 1976,
Second Edition, MOS Technology Inc., Page 144:
”The BRK is a single byte instruction and its addressing mode is Implied.”
There are debates, that BRK could be seen as a two byte instruction with the addressing
mode immediate, where the operand byte is discarded. The byte following the BRK
could then be used as a call argument for the break handler. Commodore however
used the BRK, as stated in the manual, as a single byte instruction, which breaks into
the ML monitor, if present. These builtin monitors decremented the stacked PC, so that
it could be used to return or jump directly to the code byte after the BRK.
BRK : Break to Interrupt 4510
STACK ← PC + 2; PC ← ($FFFE)
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied BRK 00 1 7

K-75
BSR
This instruction branches to the indicated address, saving the address of the follow-
ing instruction on the stack, so that the routine can be returned from using an RTS
instruction.
This instruction is helpful for using relocatable code, as it provides a relative-addressed
alternative to JSR.
BSR : Branch Sub-Routine 4510
STACK ← PC + len(V), PC ← PC + V
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
16-bit relative BSR $rrrr 63 3 3
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BVC
This instruction branches to the indicated address if the Overflow (V) Flag is clear.
BVC : Branch on Overflow Flag Clear 4510
V=0 =⇒ PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BVC $rr 50 2 2
b
16-bit relative BVC $rrrr 53 3 3
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

BVS
This instruction branches to the indicated address if the Overflow (V) Flag is set.

K-76
BVS : Branch on Overflow Flag Set 4510
V=1 =⇒ PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
b
relative BVS $rr 70 2 2
b
16-bit relative BVS $rrrr 73 3 3
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.

CLC
This instruction clears the Carry Flag.

Side effects
• The C flag is cleared.
CLC : Clear Carry Flag 4510
C←0
N Z I C D V E
· · · + · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied CLC 18 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

CLD
This instruction clears the Decimal Flag. Arithmetic operations will use normal binary
arithmetic, instead of Binary-Coded Decimal (BCD).

Side effects
• The D flag is cleared.
CLD : Clear Decimal Flag 4510
D←0
N Z I C D V E
· · · · + · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied CLD D8 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

K-77
CLE
This instruction clears the Extended Stack Disable Flag. This causes the stack to be
able to exceed 256 bytes in length, by allowing the processor to modify the value of
the high byte of the stack address (SPH).

Side effects
• The E flag is cleared.
CLE : Clear Extended Stack Disable Flag 4510
E←0
N Z I C D V E
· · · · · · +
Addressing Mode Assembly Code Bytes Cycles
s
implied CLE 02 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

CLI
This instruction clears the Interrupt Disable Flag. Interrupts will now be able to occur.

Side effects
• The I flag is cleared.
CLI : Clear Interrupt Disable Flag 4510
I←0
N Z I C D V E
· · + · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied CLI 58 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

CLV
This instruction clears the Overflow Flag.

Side effects
• The V flag is cleared.

K-78
CLV : Clear Overflow Flag 4510
V←0
N Z I C D V E
· · · · · + ·
Addressing Mode Assembly Code Bytes Cycles
s
implied CLV B8 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

CMP
This instruction performs A − M, and sets the processor flags accordingly, but does not
modify the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result of A − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of A − M is zero or positive, i.e., if A is not less
than M, otherwise it will be cleared.
• The Z flag will be set if the result of A − M is zero, otherwise it will be cleared.
CMP : Compare Accumulator 4510
N,C,Z ⇐ [A − M]
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
pr
(indirect,X) CMP ($nn,X) C1 2 5
r
base-page CMP $nn C5 2 3
immediate 8bit CMP #$nn C9 2 2
r
absolute CMP $nnnn CD 3 4
pr
(indirect),Y CMP ($nn),Y D1 2 5
pr
(indirect),Z CMP ($nn),Z D2 2 5
pr
base-page,X CMP $nn,X D5 2 3
pr
absolute,Y CMP $nnnn,Y D9 3 4
pr
absolute,X CMP $nnnn,X DD 3 4
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

K-79
CPX
This instruction performs X − M, and sets the processor flags accordingly, but does not
modify the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result of X − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of X − M is zero or positive, i.e., if X is not less
than M, otherwise it will be cleared.
• The Z flag will be set if the result of X − M is zero, otherwise it will be cleared.
CPX : Compare X Register 4510
N,C,Z ⇐ [X − M]
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit CPX #$nn E0 2 2
r
base-page CPX $nn E4 2 3
r
absolute CPX $nnnn EC 3 4
r Add one cycle if clock speed is at 40 MHz.

CPY
This instruction performs Y − M, and sets the processor flags accordingly, but does not
modify the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result of Y − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of Y − M is zero or positive, i.e., if Y is not less
than M, otherwise it will be cleared.
• The Z flag will be set if the result of Y − M is zero, otherwise it will be cleared.

K-80
CPY : Compare Y Register 4510
N,C,Z ⇐ [Y − M]
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit CPY #$nn C0 2 2
r
base-page CPY $nn C4 2 3
r
absolute CPY $nnnn CC 3 4
r Add one cycle if clock speed is at 40 MHz.

CPZ
This instruction performs Z − M, and sets the processor flags accordingly, but does not
modify the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result of Z − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of Z − M is zero or positive, i.e., if Z is not less
than M, otherwise it will be cleared.
• The Z flag will be set if the result of Z − M is zero, otherwise it will be cleared.
CPZ : Compare Z Register 4510
N,C,Z ⇐ [Z − M]
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit CPZ #$nn C2 2 2
r
base-page CPZ $nn D4 2 3
r
absolute CPZ $nnnn DC 3 4
r Add one cycle if clock speed is at 40 MHz.

DEC
This instruction decrements the Accumulator Register or indicated memory location.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.

K-81
• The Z flag will be set if the result is zero, otherwise it will be cleared.
DEC : Decrement 4510
A ← A − 1 or M ← M − 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
accumulator DEC A 3A 1 1
dmr
base-page DEC $nn C6 2 5
dmr
absolute DEC $nnnn CE 3 6
dmpr
base-page,X DEC $nn,X D6 2 5
dmpr
absolute,X DEC $nnnn,X DE 3 6
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

DEW
This instruction decrements the indicated memory word in the Base Page. The low
numbered address contains the least significant bits. For example, if memory location
$12 contains $78 and memory location $13 contains $56, the instruction DEW $12
would cause memory location $12 to be set to $77.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
DEW : Decrement Memory Word 4510
M16 ← M16 − 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
dmr
base-page DEW $nn C3 2 7
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
r Add one cycle if clock speed is at 40 MHz.

K-82
DEX
This instruction decrements the X Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
DEX : Decrement X Register 4510
X←X−1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied DEX CA 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

DEY
This instruction decrements the Y Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
DEY : Decrement Y Register 4510
Y←Y−1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied DEY 88 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

DEZ
This instruction decrements the Z Register.

K-83
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
DEZ : Decrement Z Register 4510
Z←Z−1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied DEZ 3B 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

EOM
In contrast with the 6502, the NOP instruction on the 45GS02 performs two additional
roles when in 4502 mode.
First, indicate the end of a memory mapping sequence caused by a MAP instruction,
allowing interrupts to occur again.
Second, it instructs the processor that if the following instruction uses Base-Page In-
direct Z Indexed addressing, that the processor should use a 32-bit pointer instead
of a 16-bit 6502 style pointer. Such 32-bit addresses are unaffected by C64, C65
or MEGA65 memory banking. This allows fast and easy access to the entire address
space of the MEGA65 without having to perform or be aware of any banking, or using
the DMA controller. This addressing mode causes a two cycle penalty, caused by the
time required to read the extra two bytes of the pointer.
NOTE: please take care if you use EOM/NOP after a Hypervisor Call for delay, as this
might change your next instruction. CLV can be used as an alternative.

Side effects
• Removes the prohibition on all interrupts caused by the the MAP instruction, al-
lowing Non-Maskable Interrupts to again occur, and IRQ interrupts, if the Inter-
rupt Disable Flag is not set.
EOM : End of Mapping Sequence / No-Operation 4510
Special
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied EOM EA 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

K-84
EOR
This instruction performs a binary exclusive-OR operation of the argument with the
accumulator, and stores the result in the accumulator. Only bits that were already set
in the accumulator, or that are set in the argument will be set in the accumulator on
completion, but not both.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
EOR : Binary Exclusive OR 4510
A ← A XOR M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
(indirect,X) EOR ($nn,X) 41 2 5
r
base-page EOR $nn 45 2 3
immediate 8bit EOR #$nn 49 2 2
r
absolute EOR $nnnn 4D 3 4
pr
(indirect),Y EOR ($nn),Y 51 2 5
pr
(indirect),Z EOR ($nn),Z 52 2 5
p
base-page,X EOR $nn,X 55 2 3
pr
absolute,Y EOR $nnnn,Y 59 3 4
pr
absolute,X EOR $nnnn,X 5D 3 4
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

INC
This instruction increments the Accumulator Register or indicated memory location.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-85
INC : Increment Memory or Accumulator 4510
A ← A + 1 or M ← M + 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
accumulator INC A 1A 1 1
dmr
base-page INC $nn E6 2 5
dmr
absolute INC $nnnn EE 3 6
dmpr
base-page,X INC $nn,X F6 2 5
dpr
absolute,X INC $nnnn,X FE 3 6
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

INW
This instruction increments the indicated memory word in the Base Page. The low
numbered address contains the least significant bits. For example, if memory location
$12 contains $78 and memory location $13 contains $56, the instruction INW $12
would cause memory location $12 to be set to $79.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
INW : Increment Memory Word 4510
M16 ← M16 + 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
dmr
base-page INW $nn E3 2 7
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
r Add one cycle if clock speed is at 40 MHz.

K-86
INX
This instruction increments the X Register, i.e., adds 1 to it.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
INX : Increment X Register 4510
X←X+1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied INX E8 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

INY
This instruction increments the Y Register, i.e., adds 1 to it.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
INY : Increment Y Register 4510
Y←Y+1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied INY C8 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

INZ
This instruction increments the Z Register, i.e., adds 1 to it.

K-87
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
INZ : Increment Z Register 4510
Z←Y+1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied INZ 1B 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

JMP
This instruction sets the Program Counter (PC) Register to the address indicated by the
instruction, causing execution to continue from that address.
JMP : Jump to Address 4510
PC ← M2:M1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
absolute JMP $nnnn 4C 3 3
r
(indirect) JMP ($nnnn) 6C 3 5
mp
(indirect,X) JMP ($nnnn,X) 7C 3 6
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

JSR
This instruction saves the address of the instruction following the JSR instruction onto
the stack, and then sets the Program Counter (PC) Register to the address indicated by
the instruction, causing execution to continue from that address. Because the return
address has been saved on the stack, the RTS instruction can be used to return from
the called sub-routine and resume execution following the JSR instruction.
NOTE: This instruction actually pushes the address of the last byte of the JSR instruction
onto the stack. The RTS instruction naturally is aware of this, and increments the ad-
dress on popping it from the stack, before setting the Program Counter (PC) register.

K-88
JSR : Jump to Sub-Routine 4510
PC ← M2:M1, STACK ← PCH:PCL
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
absolute JSR $nnnn 20 3 5
r
(indirect) JSR ($nnnn) 22 3 5
pr
(indirect,X) JSR ($nnnn,X) 23 3 5
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

LDA
This instruction loads the Accumulator Register with the indicated value, or with the
contents of the indicated location.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
LDA : Load Accumulator 4510
A←M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
pr
(indirect,X) LDA ($nn,X) A1 2 5
r
base-page LDA $nn A5 2 3
immediate 8bit LDA #$nn A9 2 2
r
absolute LDA $nnnn AD 3 4
pr
(indirect),Y LDA ($nn),Y B1 2 5
pr
(indirect),Z LDA ($nn),Z B2 2 5
pr
base-page,X LDA $nn,X B5 2 3
pr
absolute,Y LDA $nnnn,Y B9 3 4
pr
absolute,X LDA $nnnn,X BD 3 4
mpr
(immediate,SP),Y LDA ($nn,SP),Y E2 2 6
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

K-89
LDX
This instruction loads the X Register with the indicated value, or with the contents of
the indicated location.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
LDX : Load X Register 4510
X←M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit LDX #$nn A2 2 2
r
base-page LDX $nn A6 2 3
r
absolute LDX $nnnn AE 3 4
pr
base-page,Y LDX $nn,Y B6 2 5
pr
absolute,Y LDX $nnnn,Y BE 3 4
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

LDY
This instruction loads the Y Register with the indicated value, or with the contents of
the indicated location.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-90
LDY : Load Y Register 4510
Y←M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit LDY #$nn A0 2 2
r
base-page LDY $nn A4 2 3
r
absolute LDY $nnnn AC 3 4
pr
base-page,X LDY $nn,X B4 2 3
pr
absolute,X LDY $nnnn,X BC 3 4
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

LDZ
This instruction loads the Z Register with the indicated value, or with the contents of
the indicated location.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
LDZ : Load Z Register 4510
Z←M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
immediate 8bit LDZ #$nn A3 2 2
r
absolute LDZ $nnnn AB 3 4
pr
absolute,X LDZ $nnnn,X BB 3 4
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

LSR
This instruction shifts either the Accumulator or contents of the provided memory lo-
cation one bit right. Bit 7 will be set to zero, and the bit 0 will be shifted out into the
Carry Flag

K-91
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted.
LSR : Logical Shift Right 4510
A ← A≫1, C ← A(0) or M ← M≫1, C ← M(0)
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page LSR $nn 46 2 4
s
accumulator LSR A 4A 1 1
r
absolute LSR $nnnn 4E 3 5
pr
base-page,X LSR $nn,X 56 2 3
pr
absolute,X LSR $nnnn,X 5E 3 5
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

MAP
This instruction sets the C65 or MEGA65 style memory map, depending on the values
in the Accumulator, X, Y and Z registers.
Care should be taken to ensure that after the execution of an MAP instruction that
appropriate memory is mapped at the location of the following instruction. Failure to
do so will result in unpredictable results.
Further information on this instruction is available in Appendix J.

Side effects
• The memory map is immediately changed to that requested.
• All interrupts, including Non-Maskable Interrupts (NMIs) are blocked from occur-
ring until an EOM (NOP) instruction is encountered.

K-92
MAP : Set Memory Map 4510
Special
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied MAP 5C 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

NEG
This instruction replaces the contents of the Accumulator Register with the twos-
complement of the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
NEG : Negate Accumulator 4510
A ← (A XOR $FF) + 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
accumulator NEG A 42 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

ORA
This instruction performs a binary OR operation of the argument with the accumulator,
and stores the result in the accumulator. Only bits that were already set in the accu-
mulator, or that are set in the argument will be set in the accumulator on completion,
or both.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-93
ORA : Binary OR 4510
A ← A OR M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
pr
(indirect,X) ORA ($nn,X) 01 2 6
r
base-page ORA $nn 05 2 3
immediate 8bit ORA #$nn 09 2 2
r
absolute ORA $nnnn 0D 3 4
pr
(indirect),Y ORA ($nn),Y 11 2 5
pr
(indirect),Z ORA ($nn),Z 12 2 5
r
base-page,X ORA $nn,X 15 2 3
r
absolute,Y ORA $nnnn,Y 19 3 4
pr
absolute,X ORA $nnnn,X 1D 3 4
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

PHA
This instruction pushes the contents of the Accumulator Register onto the stack, and
decrements the value of the Stack Pointer by 1.
PHA : Push Accumulator Register onto the Stack 4510
STACK ← A, SP ← SP − 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied PHA 48 1 2

PHP
This instruction pushes the contents of the Processor Flags onto the stack, and decre-
ments the value of the Stack Pointer by 1.
PHP : Push Processor Flags onto the Stack 4510
STACK ← P, SP ← SP − 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied PHP 08 1 2

K-94
PHW
This instruction pushes either a 16-bit literal value or the memory word indicated onto
the stack, and decrements the value of the Stack Pointer by 2.
PHW : Push Word onto the Stack 4510
STACK ← M1:M2, SP ← SP − 2
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
m
immediate 16bit PHW #$nnnn F4 3 5
m
absolute PHW $nnnn FC 3 7
m Subtract non-bus cycles when at 40MHz.

PHX
This instruction pushes the contents of the X Register onto the stack, and decrements
the value of the Stack Pointer by 1.
PHX : Push X Register onto the Stack 4510
STACK ← X, SP ← SP − 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
m
implied PHX DA 1 3
m Subtract non-bus cycles when at 40MHz.

PHY
This instruction pushes the contents of the Y Register onto the stack, and decrements
the value of the Stack Pointer by 1.
PHY : Push Y Register onto the Stack 4510
STACK ← Y, SP ← SP − 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
implied PHY 5A 1 2

K-95
PHZ
This instruction pushes the contents of the Z Register onto the stack, and decrements
the value of the Stack Pointer by 1.
PHZ : Push Z Register onto the Stack 4510
STACK ← z, SP ← SP − 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
m
implied PHZ DB 1 3
m Subtract non-bus cycles when at 40MHz.

PLA
This instruction replaces the contents of the Accumulator Register with the top value
from the stack, and increments the value of the Stack Pointer by 1.
PLA : Pull Accumulator Register from the Stack 4510
A ← STACK, SP ← SP + 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
m
implied PLA 68 1 4
m Subtract non-bus cycles when at 40MHz.

PLP
This instruction replaces the contents of the Processor Flags with the top value from
the stack, and increments the value of the Stack Pointer by 1.
NOTE: This instruction does NOT replace the Extended Stack Disable Flag (E Flag), or
the Software Interrupt Flag (B Flag)
PLP : Pull Processor Flags from the Stack 4510
A ← STACK, SP ← SP + 1
N Z I C D V E
+ + + + + + ·
Addressing Mode Assembly Code Bytes Cycles
m
implied PLP 28 1 4
m Subtract non-bus cycles when at 40MHz.

K-96
PLX
This instruction replaces the contents of the X Register with the top value from the
stack, and increments the value of the Stack Pointer by 1.
PLX : Pull X Register from the Stack 4510
X ← STACK, SP ← SP + 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
m
implied PLX FA 1 4
m Subtract non-bus cycles when at 40MHz.

PLY
This instruction replaces the contents of the Y Register with the top value from the
stack, and increments the value of the Stack Pointer by 1.
PLY : Pull Y Register from the Stack 4510
Y ← STACK, SP ← SP + 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
m
implied PLY 7A 1 4
m Subtract non-bus cycles when at 40MHz.

PLZ
This instruction replaces the contents of the Z Register with the top value from the
stack, and increments the value of the Stack Pointer by 1.
PLZ : Pull Z Register from the Stack 4510
Z ← STACK, SP ← SP + 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
m
implied PLZ FB 1 4
m Subtract non-bus cycles when at 40MHz.

K-97
RMB0
This instruction clears bit zero of the indicated address. No flags are modified, re-
gardless of the result.
RMB0 : Reset Bit 0 in Base Page 4510
M(0) ← 0
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page RMB0 $nn 07 2 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

RMB1
This instruction clears bit 1 of the indicated address. No flags are modified, regardless
of the result.
RMB1 : Reset Bit 1 in Base Page 4510
M(1) ← 0
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
br
base-page RMB1 $nn 17 2 4
b Add one cycle if branch is taken.
Add one more cycle if branch taken crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

RMB2
This instruction clears bit 2 of the indicated address. No flags are modified, regardless
of the result.
RMB2 : Reset Bit 2 in Base Page 4510
M(2) ← 0
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page RMB2 $nn 27 2 4
r Add one cycle if clock speed is at 40 MHz.

K-98
RMB3
This instruction clears bit 3 of the indicated address. No flags are modified, regardless
of the result.
RMB3 : Reset Bit 3 in Base Page 4510
M(3) ← 0
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page RMB3 $nn 37 2 4
r Add one cycle if clock speed is at 40 MHz.

RMB4
This instruction clears bit 4 of the indicated address. No flags are modified, regardless
of the result.
RMB4 : Reset Bit 4 in Base Page 4510
M(4) ← 0
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page RMB4 $nn 47 2 4
r Add one cycle if clock speed is at 40 MHz.

RMB5
This instruction clears bit 5 of the indicated address. No flags are modified, regardless
of the result.
RMB5 : Reset Bit 5 in Base Page 4510
M(5) ← 0
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page RMB5 $nn 57 2 4
r Add one cycle if clock speed is at 40 MHz.

K-99
RMB6
This instruction clears bit 6 of the indicated address. No flags are modified, regardless
of the result.
RMB6 : Reset Bit 6 in Base Page 4510
M(6) ← 0
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page RMB6 $nn 67 2 5
r Add one cycle if clock speed is at 40 MHz.

RMB7
This instruction clears bit 7 of the indicated address. No flags are modified, regardless
of the result.
RMB7 : Reset Bit 7 in Base Page 4510
M(7) ← 0
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page RMB7 $nn 77 2 4
r Add one cycle if clock speed is at 40 MHz.

ROL
This instruction shifts either the Accumulator or contents of the provided memory lo-
cation one bit left. Bit 0 will be set to the current value of the Carry Flag, and the bit
7 will be shifted out into the Carry Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.

K-100
ROL : Rotate Left Memory or Accumulator 4510
M ← M≪1, C ← M(7), M(0) ← C
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page ROL $nn 26 2 4
s
accumulator ROL A 2A 1 1
r
absolute ROL $nnnn 2E 3 5
pr
base-page,X ROL $nn,X 36 2 5
pr
absolute,X ROL $nnnn,X 3E 3 5
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

ROR
This instruction shifts either the Accumulator or contents of the provided memory lo-
cation one bit right. Bit 7 will be set to the current value of the Carry Flag, and the bit
0 will be shifted out into the Carry Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
ROR : Rotate Right Memory or Accumulator 4510
M ← M≫1, C ← M(0), M(7) ← C
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page ROR $nn 66 2 5
s
accumulator ROR A 6A 1 1
r
absolute ROR $nnnn 6E 3 6
dmpr
base-page,X ROR $nn,X 76 2 5
dmpr
absolute,X ROR $nnnn,X 7E 3 5
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

K-101
ROW
This instruction rotates the contents of the indicated memory word one bit left. Bit 0
of the low byte will be set to the current value of the Carry Flag, and the bit 7 of the
high byte will be shifted out into the Carry Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 7 of the upper byte was set, prior to being shifted.
ROW : Rotate Word Left 4510
M2:M1 ← M2:M1≪1, C ← M2(7), M1(0) ← C
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
dmr
absolute ROW $nnnn EB 3 5
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
r Add one cycle if clock speed is at 40 MHz.

RTI
This instruction pops the processor flags from the stack, and then pops the Program
Counter (PC) register from the stack, allowing an interrupted program to resume.
• The 6502 Processor Flags are restored from the stack.
• Neither the B (Software Interrupt) nor E (Extended Stack) flags are set by this
instruction.
RTI : Return From Interrupt 4510
P ← STACK, PC ← STACK
N Z I C D V E
+ + + + + + ·
Addressing Mode Assembly Code Bytes Cycles
m
implied RTI 40 1 6
m Subtract non-bus cycles when at 40MHz.

K-102
RTS
This instruction adds an optional argument to the Stack Pointer (SP) Register, and then
pops the Program Counter (PC) register from the stack, allowing a routine to return to
its caller.
RTS : Return From Subroutine 4510
PC ← STACK or PC ← STACK + M, SP ← SP − 2
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
m
implied RTS 60 1 6
immediate 8bit RTS #$nn 62 2 4
m Subtract non-bus cycles when at 40MHz.

SBC
This instruction performs A − M − 1 + C, and sets the processor flags accordingly.
The result is stored in the Accumulator Register.
NOTE: If the D flag is set, then the addition is performed using binary Coded Decimal.

Side effects
• The N flag will be set if the result of A − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of A − M is zero or positive, i.e., if A is not less
than M, otherwise it will be cleared.
• The V flag will be set if the result has a different sign to both of the arguments,
otherwise it will be cleared. If the flag is set, this indicates that a signed overflow
has occurred.
• The Z flag will be set if the result of A − M is zero, otherwise it will be cleared.

K-103
SBC : Subtract With Carry 4510
A←−M−1+C
N Z I C D V E
+ + · + · + ·
Addressing Mode Assembly Code Bytes Cycles
mp
(indirect,X) SBC ($nn,X) E1 2 3
r
base-page SBC $nn E5 2 3
immediate 8bit SBC #$nn E9 2 2
r
absolute SBC $nnnn ED 3 4
pr
(indirect),Y SBC ($nn),Y F1 2 3
pr
(indirect),Z SBC ($nn),Z F2 2 5
pr
base-page,X SBC $nn,X F5 2 3
pr
absolute,Y SBC $nnnn,Y F9 3 4
pr
absolute,X SBC $nnnn,X FD 3 4
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

SEC
This instruction sets the Carry Flag.

Side effects
• The C flag is set.
SEC : Set Carry Flag 4510
C←1
N Z I C D V E
· · · + · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied SEC 38 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

SED
This instruction sets the Decimal Flag. Binary arithmetic will now use Binary-Coded
Decimal (BCD) mode.
NOTE: The C64’s interrupt handler does not clear the Decimal Flag, which makes it
dangerous to set the Decimal Flag without first setting the Interrupt Disable Flag.

K-104
Side effects
• The D flag is set.
SED : Set Decimal Flag 4510
D←1
N Z I C D V E
· · · · + · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied SED F8 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

SEE
This instruction sets the Extended Stack Disable Flag. This causes the stack to operate
as on the 6502, i.e., limited to a single page of memory. The page of memory in
which the stack is located can still be modified by setting the Stack Pointer High (SPH)
Register.

Side effects
• The E flag is set.
SEE : Set Extended Stack Disable Flag 4510
E←1
N Z I C D V E
· · · · · · +
Addressing Mode Assembly Code Bytes Cycles
s
implied SEE 03 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

SEI
This instruction sets the Interrupt Disable Flag. Normal (IRQ) interrupts will no longer
be able to occur. Non-Maskable Interrupts (NMI) will continue to occur, as their name
suggests.

Side effects
• The I flag is set.

K-105
SEI : Set Interrupt Disable Flag 4510
I←1
N Z I C D V E
· · + · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied SEI 78 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

SMB0
This instruction sets bit zero of the indicated address. No flags are modified, regardless
of the result.
SMB0 : Set Bit 0 in Base Page 4510
M(0) ← 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page SMB0 $nn 87 2 4
r Add one cycle if clock speed is at 40 MHz.

SMB1
This instruction sets bit 1 of the indicated address. No flags are modified, regardless
of the result.
SMB1 : Set Bit 1 in Base Page 4510
M(1) ← 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page SMB1 $nn 97 2 4
r Add one cycle if clock speed is at 40 MHz.

SMB2
This instruction sets bit 2 of the indicated address. No flags are modified, regardless
of the result.

K-106
SMB2 : Set Bit 2 in Base Page 4510
M(2) ← 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page SMB2 $nn A7 2 4
r Add one cycle if clock speed is at 40 MHz.

SMB3
This instruction sets bit 3 of the indicated address. No flags are modified, regardless
of the result.
SMB3 : Set Bit 3 in Base Page 4510
M(3) ← 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page SMB3 $nn B7 2 4
r Add one cycle if clock speed is at 40 MHz.

SMB4
This instruction sets bit 4 of the indicated address. No flags are modified, regardless
of the result.
SMB4 : Set Bit 4 in Base Page 4510
M(4) ← 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page SMB4 $nn C7 2 4
r Add one cycle if clock speed is at 40 MHz.

SMB5
This instruction sets bit 5 of the indicated address. No flags are modified, regardless
of the result.

K-107
SMB5 : Set Bit 5 in Base Page 4510
M(5) ← 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page SMB5 $nn D7 2 4
r Add one cycle if clock speed is at 40 MHz.

SMB6
This instruction sets bit 6 of the indicated address. No flags are modified, regardless
of the result.
SMB6 : Set Bit 6 in Base Page 4510
M(6) ← 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page SMB6 $nn E7 2 4
r Add one cycle if clock speed is at 40 MHz.

SMB7
This instruction sets bit 7 of the indicated address. No flags are modified, regardless
of the result.
SMB7 : Set Bit 7 in Base Page 4510
M(7) ← 1
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page SMB7 $nn F7 2 4
r Add one cycle if clock speed is at 40 MHz.

STA
This instruction stores the contents of the Accumulator Register into the indicated lo-
cation.

K-108
STA : Store Accumulator 4510
M←A
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
p
(indirect,X) STA ($nn,X) 81 2 5
p
(immediate,SP),Y STA ($nn,SP),Y 82 2 6
base-page STA $nn 85 2 3
absolute STA $nnnn 8D 3 4
p
(indirect),Y STA ($nn),Y 91 2 5
p
(indirect),Z STA ($nn),Z 92 2 5
p
base-page,X STA $nn,X 95 2 3
p
absolute,Y STA $nnnn,Y 99 3 4
p
absolute,X STA $nnnn,X 9D 3 4
p Add one cycle if indexing crosses a page boundary.

STX
This instruction stores the contents of the X Register into the indicated location.
STX : Store X Register 4510
M←X
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
base-page STX $nn 86 2 3
absolute STX $nnnn 8E 3 4
p
base-page,Y STX $nn,Y 96 2 3
p
absolute,Y STX $nnnn,Y 9B 3 4
p Add one cycle if indexing crosses a page boundary.

STY
This instruction stores the contents of the Y Register into the indicated location.

K-109
STY : Store Y Register 4510
M←Y
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
base-page STY $nn 84 2 3
p
absolute,X STY $nnnn,X 8B 3 4
absolute STY $nnnn 8C 3 4
p
base-page,X STY $nn,X 94 2 3
p Add one cycle if indexing crosses a page boundary.

STZ
This instruction stores the contents of the Z Register into the indicated location.
STZ : Store Z Register 4510
M←Z
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
base-page STZ $nn 64 2 3
base-page,X STZ $nn,X 74 2 3
absolute STZ $nnnn 9C 3 4
p
absolute,X STZ $nnnn,X 9E 3 4
p Add one cycle if indexing crosses a page boundary.

TAB
This instruction sets the Base Page register to the contents of the Accumulator Register.
This allows the relocation of the 6502’s Zero-Page into any page of memory.
TAB : Transfer Accumulator into Base Page Register 4510
B←A
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TAB 5B 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

K-110
TAX
This instruction loads the X Register with the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
TAX : Transfer Accumulator Register into the X Register 4510
X←A
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TAX AA 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

TAY
This instruction loads the Y Register with the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
TAY : Transfer Accumulator Register into the Y Register 4510
Y←A
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TAY A8 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

TAZ
This instruction loads the Z Register with the contents of the Accumulator Register.

K-111
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
TAZ : Transfer Accumulator Register into the Z Register 4510
Z←A
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TAZ 4B 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

TBA
This instruction loads the Accumulator Register with the contents of the Base Page
Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
TBA : Transfer Base Page Register into the Accumulator 4510
A←B
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TBA 7B 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

TRB
This instruction sets performs a binary AND of the negation of the Accumulator Register
and the indicated memory location, storing the result there. That is, any bits set in the
Accumulator Register will be reset in the indicated memory location.
It also performs a test for any bits in common between the accumulator and indicated
memory location. This can be used to construct simple shared-memory multi-processor
systems, by providing an atomic means of setting a semaphore or acquiring a lock.

K-112
Side effects
• The Z flag will be set if the binary AND of the Accumulator Register and contents
of the indicated memory location prior are zero, prior to the execution of the
instruction.
TRB : Test and Reset Bit 4510
M ← M AND (NOT A)
N Z I C D V E
· + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page TRB $nn 14 2 5
r
absolute TRB $nnnn 1C 3 4
r Add one cycle if clock speed is at 40 MHz.

TSB
This instruction sets performs a binary OR of the Accumulator Register and the indi-
cated memory location, storing the result there. That is, any bits set in the Accumulator
Register will be set in the indicated memory location.
It also performs a test for any bits in common between the accumulator and indicated
memory location. This can be used to construct simple shared-memory multi-processor
systems, by providing an atomic means of setting a semaphore or acquiring a lock.

Side effects
• The Z flag will be set if the binary AND of the Accumulator Register and contents
of the indicated memory location prior are zero, prior to the execution of the
instruction.
TSB : Test and Set Bit 4510
M ← M OR A
N Z I C D V E
· + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page TSB $nn 04 2 3
r
absolute TSB $nnnn 0C 3 5
r Add one cycle if clock speed is at 40 MHz.

TSX
This instruction loads the X Register with the contents of the Stack Pointer Low (SPL)
Register.

K-113
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
TSX : Transfer Stack Pointer Low Register into the X Register 4510
X ← SPL
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TSX BA 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

TSY
This instruction loads the Y Register with the contents of the Stack Pointer High (SPH)
Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
TSY : Transfer Stack Pointer High Register into the Y Register 4510
Y ← SPH
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TSY 0B 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

TXA
This instruction loads the Accumulator Register with the contents of the X Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-114
TXA : Transfer X Register into the Accumulator Register 4510
A←X
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TXA 8A 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

TXS
This instruction sets the low byte of the Stack Pointer (SPL) register to the contents of
the X Register.
TXS : Transfer X Register into Stack Pointer Low Register 4510
SPL ← X
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TXS 9A 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

TYA
This instruction loads the Accumulator Register with the contents of the Y Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
TYA : Transfer Y Register into the Accumulator Register 4510
A←Y
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TYA 98 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

K-115
TYS
This instruction sets the high byte of the Stack Pointer (SPH) register to the contents
of the Y Register. This allows changing the memory page where the stack is located
(if the Extended Stack Disable Flag (E) is set), or else allows setting the current Stack
Pointer to any page in memory, if the Extended Stack Disable Flag (E) is clear.
TYS : Transfer Y Register into Stack Pointer High Register 4510
SPH ← Y
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TYS 2B 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

TZA
This instruction loads the Accumulator Register with the contents of the Z Register.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
TZA : Transfer Z Register into the Accumulator Register 4510
A←Z
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
s
implied TZA 6B 1 1
s Instruction requires 2 cycles when CPU is run at 1MHz or 2MHz.

45GS02 COMPOUND INSTRUCTIONS


As the 4510 has no unallocated opcodes, the 45GS02 uses compound instructions
to implement its extension. These compound instructions consist of one or more single
byte instructions placed immediately before a conventional instruction. These pre-
fixes instruct the 45GS02 to treat the following instruction differently, as described in
Chapter/Appendix J on page J-3.

K-116
You can find them highlighted in the 4510 Opcode Table (see Chapter/Appendix K
on page K-60)

ADC
This instruction adds the argument and the Carry Flag to the contents of the Accumu-
lator Register. If the D flag is set, then the addition is performed using Binary Coded
Decimal.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The V flag will be set if the result has a different sign to both of the arguments,
otherwise it will be cleared. If the flag is set, this indicates that a signed overflow
has occurred.
• The C flag will be set if the unsigned result is >255, or >99 if the D flag is set.
ADC : Add with carry 45GS02
A←A+M+C
N Z I C D V E
+ + · + · + ·
Addressing Mode Assembly Code Bytes Cycles
ipr
[indirect],Z ADC [$nn],Z EA 72 3 7
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

ADCQ
This instruction adds the argument and the Carry Flag to the contents of the 32-bit Q
Pseudo Register.
NOTE: the indicated memory location is treated as the first byte of a 32-bit little-
endian value.
NOTE: If the D flag is set, the operation is undefined and subject to change.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.

K-117
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The V flag will be set if the result has a different sign to both of the arguments,
otherwise it will be cleared. If the flag is set, this indicates that a signed overflow
has occurred.
• The C flag will be set if the unsigned result is ≥ 232 .
ADCQ : Add with carry Quad 45GS02
Q←Q+M+C
N Z I C D V E
+ + · + · + ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page quad ADCQ $nn 42 42 65 4 8
r
absolute quad ADCQ $nnnn 42 42 6D 5 9
ipr
(indirect quad) ADCQ ($nn) 42 42 72 4 10
ipr
[indirect quad] ADCQ [$nn] 42 42 EA 72 5 13
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

AND
This instruction performs a binary AND operation of the argument with the accumu-
lator, and stores the result in the accumulator. Only bits that were already set in the
accumulator, and that are set in the argument will be set in the accumulator on com-
pletion.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
AND : Binary AND 45GS02
A ← A AND M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
ipr
[indirect],Z AND [$nn],Z EA 32 3 7
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

K-118
ANDQ
This instruction performs a binary AND operation of the argument with the Q pseudo
register, and stores the result in the accumulator. Only bits that were already set in
the Q pseudo register, and that are set in the argument will be set in the Q pseudo
register on completion.
NOTE: the indicated memory location is treated as the first byte of a 32-bit little-
endian value.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
ANDQ : Binary AND Quad 45GS02
Q ← Q AND M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page quad ANDQ $nn 42 42 25 4 8
r
absolute quad ANDQ $nnnn 42 42 2D 5 9
ipr
(indirect quad) ANDQ ($nn) 42 42 32 4 10
ipr
[indirect quad] ANDQ [$nn] 42 42 EA 32 5 13
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

ASLQ
This instruction shifts either the Q pseudo-register or contents of the provided memory
location and following three one bit left, treating them as holding a little-endian 32-
bit value. Bit 0 will be set to zero, and the bit 31 will be shifted out into the Carry
Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 31 of the value was set, prior to being shifted, oth-
erwise it will be cleared.

K-119
ASLQ : Arithmetic Shift Left Quad 45GS02
Q ← Q<<1 or M ← M<<1
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
dmr
base-page quad ASLQ $nn 42 42 06 4 12
Q Pseudo Register ASLQ Q 42 42 0A 3 3
dmr
absolute quad ASLQ $nnnn 42 42 0E 5 13
dmpr
base-page quad,X ASLQ $nn,X 42 42 16 4 12
dmpr
absolute quad,X ASLQ $nnnn,X 42 42 1E 5 13
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

ASRQ
This instruction shifts either the Q pseudo-register or contents of the provided memory
location and following three one bit right, treating them as holding a little-endian 32-
bit value. Bit 31 is considered to be a sign bit, and is preserved. The content of bit 0
will be shifted out into the Carry Flag

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted, otherwise
it will be cleared.
ASRQ : Arithmetic Shift Right Quad 45GS02
Q ← Q>>1 or M ← M>>1
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
Q Pseudo Register ASRQ Q 42 42 43 3 3
dmr
base-page quad ASRQ $nn 42 42 44 4 12
dmpr
base-page quad,X ASRQ $nn,X 42 42 54 4 12
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

K-120
BITQ
This instruction is used to test the bits stored in a memory location and following three,
treating them as holding a little-endian 32-bit value. Bits 30 and 31 of the memory
location’s contents are directly copied into the Overflow Flag and Negative Flag. The
Zero Flag is set or cleared based on the result of performing the binary AND of the Q
Register and the contents of the indicated memory location.

Side effects
• The N flag will be set if the bit 31 of the memory location is set, otherwise it will
be cleared.
• The V flag will be set if the bit 30 of the memory location is set, otherwise it will
be cleared.
• The Z flag will be set if the result of Q AND M is zero, otherwise it will be cleared.
BITQ : Perform Bit Test Quad 45GS02
N ← M(31), V ← M(30), Z ← Q AND M
N Z I C D V E
+ + · · · + ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page quad BITQ $nn 42 42 24 4 8
r
absolute quad BITQ $nnnn 42 42 2C 5 9
r Add one cycle if clock speed is at 40 MHz.

CMP
This instruction performs A − M, and sets the processor flags accordingly, but does not
modify the contents of the Accumulator Register.

Side effects
• The N flag will be set if the result of A − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of A − M is zero or positive, i.e., if A is not less
than M, otherwise it will be cleared.
• The Z flag will be set if the result of A − M is zero, otherwise it will be cleared.

K-121
CMP : Compare Accumulator 45GS02
N,C,Z ⇐ [A − M]
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
ipr
[indirect],Z CMP [$nn],Z EA D2 3 7
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

CMPQ
This instruction performs Q − M, and sets the processor flags accordingly, but does
not modify the contents of the Q Register.
NOTE: the indicated memory location is treated as the first byte of a 32-bit little-
endian value.

Side effects
• The N flag will be set if the result of A − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of A − M is zero or positive, i.e., if A is not less
than M, otherwise it will be cleared.
• The Z flag will be set if the result of A − M is zero, otherwise it will be cleared.
CMPQ : Compare Q Pseudo Register 45GS02
N,C,Z ⇐ [Q − M]
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page quad CMPQ $nn 42 42 C5 4 8
r
absolute quad CMPQ $nnnn 42 42 CD 5 9
ipr
(indirect quad) CMPQ ($nn) 42 42 D2 4 10
ipr
[indirect quad] CMPQ [$nn] 42 42 EA D2 5 13
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

DEQ
This instruction decrements the Q psuedo register or indicated memory location.

K-122
NOTE: the indicated memory location is treated as the first byte of a 32-bit little-
endian value.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
DEQ : Decrement Quad 45GS02
Q ← Q − 1 or M ← M − 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
Q Pseudo Register DEQ Q 42 42 3A 3 3
dmr
base-page quad DEQ $nn 42 42 C6 4 12
dmr
absolute quad DEQ $nnnn 42 42 CE 5 13
dmpr
base-page quad,X DEQ $nn,X 42 42 D6 4 12
dmpr
absolute quad,X DEQ $nnnn,X 42 42 DE 5 13
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

EOR
This instruction performs a binary exclusive-OR operation of the argument with the
accumulator, and stores the result in the accumulator. Only bits that were already set
in the accumulator, or that are set in the argument will be set in the accumulator on
completion, but not both.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.

K-123
EOR : Binary Exclusive OR 45GS02
A ← A XOR M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
ipr
[indirect],Z EOR [$nn],Z EA 52 3 7
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

EORQ
This instruction performs a binary exclusive-OR operation of the argument with the Q
pseudo register, and stores the result in the Q pseudo register. Only bits that were
already set in the Q pseudo register, or that are set in the argument will be set in the
accumulator on completion, but not bits that were set in both.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
EORQ : Binary Exclusive OR Quad 45GS02
Q ← Q XOR M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page quad EORQ $nn 42 42 45 4 8
r
absolute quad EORQ $nnnn 42 42 4D 5 9
ipr
(indirect quad) EORQ ($nn) 42 42 52 4 10
ipr
[indirect quad] EORQ [$nn] 42 42 EA 52 5 13
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

INQ
This instruction increments the Q pseudo register or indicated memory location.
Note that the indicated memory location is treated as the first byte of a 32-bit little-
endian value.

K-124
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
INQ : Increment Memory or Accumulator 45GS02
Q ← Q + 1 or M ← M + 1
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
Q Pseudo Register INQ Q 42 42 1A 3 3
dmr
base-page quad INQ $nn 42 42 E6 4 13
dmr
absolute quad INQ $nnnn 42 42 EE 5 14
dmpr
base-page quad,X INQ $nn,X 42 42 F6 4 13
dpr
absolute quad,X INQ $nnnn,X 42 42 FE 5 14
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

LDA
This instruction loads the Accumulator Register with the indicated value, or with the
contents of the indicated location.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
LDA : Load Accumulator 45GS02
A←M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
ipr
[indirect],Z LDA [$nn],Z EA B2 3 7
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

K-125
LDQ
This instruction loads the Q pseudo register with the indicated value, or with the con-
tents of the indicated location. As the Q register is an alias for A, X, Y and Z used
together, this operation will set those four registers. A contains the least significant
bits, X the next least significant, then Y, and Z contains the most significant bits.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
LDQ : Load Q Pseudo Register 45GS02
Q←M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page quad LDQ $nn 42 42 A5 4 8
r
absolute quad LDQ $nnnn 42 42 AD 5 9
ipr
(indirect quad),Z LDQ ($nn),Z 42 42 B2 4 10
ipr
[indirect quad],Z LDQ [$nn],Z 42 42 EA B2 5 13
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

LSRQ
This instruction shifts either the Q pseudo register or contents of the provided memory
location one bit right. Bit 31 will be set to zero, and the bit 0 will be shifted out into
the Carry Flag.
Note that the memory address is treated as the first address of a little-endian encoded
32-bit value.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted, otherwise
it will be cleared.

K-126
LSRQ : Logical Shift Right Quad 45GS02
Q ← Q≫1, C ← A(0) or M ← M≫1
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
dmr
base-page quad LSRQ $nn 42 42 46 4 12
Q Pseudo Register LSRQ Q 42 42 4A 3 3
dmr
absolute quad LSRQ $nnnn 42 42 4E 5 13
dmpr
base-page quad,X LSRQ $nn,X 42 42 56 4 12
dmpr
absolute quad,X LSRQ $nnnn,X 42 42 5E 5 13
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

ORA
This instruction performs a binary OR operation of the argument with the accumulator,
and stores the result in the accumulator. Only bits that were already set in the accu-
mulator, or that are set in the argument will be set in the accumulator on completion,
or both.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
ORA : Binary OR 45GS02
A ← A OR M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
ipr
[indirect],Z ORA [$nn],Z EA 12 3 7
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

K-127
ORQ
This instruction performs a binary OR operation of the argument with the Q pseudo
register, and stores the result in the Q pseudo register. Only bits that were already set
in the Q pseudo register, or that are set in the argument, or both, will be set in the Q
pseudo register on completion.
Note that this operation treats the memory address as the first address of a 32-bit
little-endian value. That is, the memory address and the three following will be used.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
ORQ : Binary OR Quad 45GS02
Q ← Q OR M
N Z I C D V E
+ + · · · · ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page quad ORQ $nn 42 42 05 4 8
r
absolute quad ORQ $nnnn 42 42 0D 5 9
pr
(indirect quad) ORQ ($nn) 42 42 12 4 10
pr
[indirect quad] ORQ [$nn] 42 42 EA 12 5 13
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

RESQ
These extended opcodes are reserved, and their function is undefined and subject to
change in future revisions of the 45GS02. They should therefore not be used in any
program.

K-128
RESQ : Reserved extended opcode 45GS02
UNDEFINED
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
ipr
(indirect quad,X) RESQ ($nn,X) 42 42 01 4 10
ipr
(indirect quad),Y RESQ ($nn),Y 42 42 11 4 10
pr
base-page quad,X RESQ $nn,X 42 42 15 4 8
pr
absolute quad,Y RESQ $nnnn,Y 42 42 19 5 9
pr
absolute quad,X RESQ $nnnn,X 42 42 1D 5 9
ir
(indirect quad,X) RESQ ($nn,X) 42 42 21 4 10
ipr
(indirect quad),Y RESQ ($nn),Y 42 42 31 4 10
pr
base-page quad,X RESQ $nn,X 42 42 34 4 8
pr
base-page quad,X RESQ $nn,X 42 42 35 4 8
pr
absolute quad,Y RESQ $nnnn,Y 42 42 39 5 10
pr
absolute quad,X RESQ $nnnn,X 42 42 3C 5 9
pr
absolute quad,X RESQ $nnnn,X 42 42 3D 5 10
ipr
(indirect quad,X) RESQ ($nn,X) 42 42 41 4 10
ipr
(indirect quad),Y RESQ ($nn),Y 42 42 51 4 10
pr
base-page quad,X RESQ $nn,X 42 42 55 4 8
pr
absolute quad,Y RESQ $nnnn,Y 42 42 59 5 9
pr
absolute quad,X RESQ $nnnn,X 42 42 5D 5 9
ir
(indirect quad,X) RESQ ($nn,X) 42 42 61 4 10
ipr
(indirect quad),Y RESQ ($nn),Y 42 42 71 4 10
pr
base-page quad,X RESQ $nn,X 42 42 75 4 8
pr
absolute quad,Y RESQ $nnnn,Y 42 42 79 5 10
pr
absolute quad,X RESQ $nnnn,X 42 42 7D 5 10
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

ROLQ
This instruction shifts either the Q pseudo register or contents of the provided memory
location one bit left. Bit 0 will be set to the current value of the Carry Flag, and the
bit 31 will be shifted out into the Carry Flag.
NOTE: The memory address is treated as the first address of a little-endian encoded
32-bit value.

K-129
Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 31 of the value was set, prior to being shifted, oth-
erwise it will be cleared.
ROLQ : Rotate Left Quad 45GS02
M ← M≪1, C ← M(31), M(0) ← C
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
dmr
base-page quad ROLQ $nn 42 42 26 4 12
Q Pseudo Register ROLQ Q 42 42 2A 3 3
dmr
absolute quad ROLQ $nnnn 42 42 2E 5 13
dmpr
base-page quad,X ROLQ $nn,X 42 42 36 4 12
dmpr
absolute quad,X ROLQ $nnnn,X 42 42 3E 5 13
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

RORQ
This instruction shifts either the Q pseudo register or contents of the provided memory
location one bit right. Bit 31 will be set to the current value of the Carry Flag, and the
bit 0 will be shifted out into the Carry Flag
Note that the address is treated as the first address of a little-endian 32-bit value.

Side effects
• The N flag will be set if the result is negative, i.e. has it’s most significant bit set,
otherwise it will be cleared.
• The Z flag will be set if the result is zero, otherwise it will be cleared.
• The C flag will be set if bit 31 of the value was set, prior to being shifted, oth-
erwise it will be cleared.

K-130
RORQ : Rotate Right Quad 45GS02
M ← M≫1, C ← M(0), M(31) ← C
N Z I C D V E
+ + · + · · ·
Addressing Mode Assembly Code Bytes Cycles
dmr
base-page quad RORQ $nn 42 42 66 4 12
Q Pseudo Register RORQ Q 42 42 6A 3 3
dmr
absolute quad RORQ $nnnn 42 42 6E 5 13
dmpr
base-page quad,X RORQ $nn,X 42 42 76 4 12
dmpr
absolute quad,X RORQ $nnnn,X 42 42 7E 5 13
d Subtract one cycle when CPU is at 3.5MHz.
m Subtract non-bus cycles when at 40MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

RSVQ
These extended opcodes are reserved, and their function is undefined and subject to
change in future revisions of the 45GS02. They should therefore not be used in any
program.

K-131
RSVQ : Reserved extended opcode 45GS02
UNDEFINED
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
ip
(indirect quad,X) RSVQ ($nn,X) 42 42 81 4 10
ip
(indirect quad,SP),Y RSVQ ($nn,SP),Y 42 42 82 4 10
ip
(indirect quad),Y RSVQ ($nn),Y 42 42 91 4 10
p
base-page quad,X RSVQ $nn,X 42 42 95 4 8
p
absolute quad,Y RSVQ $nnnn,Y 42 42 99 5 9
p
absolute quad,X RSVQ $nnnn,X 42 42 9D 5 9
ipr
(indirect quad,X) RSVQ ($nn,X) 42 42 A1 4 10
ipr
(indirect quad,X) RSVQ ($nn,X) 42 42 C1 4 10
ipr
(indirect quad),Y RSVQ ($nn),Y 42 42 D1 4 10
pr
base-page quad,X RSVQ $nn,X 42 42 D5 4 8
pr
absolute quad,Y RSVQ $nnnn,Y 42 42 D9 5 9
pr
absolute quad,X RSVQ $nnnn,X 42 42 DD 5 9
ipr
(indirect quad,X) RSVQ ($nn,X) 42 42 E1 4 10
ipr
(indirect quad),Y RSVQ ($nn),Y 42 42 F1 4 10
pr
base-page quad,X RSVQ $nn,X 42 42 F5 4 8
pr
absolute quad,Y RSVQ $nnnn,Y 42 42 F9 5 8
pr
absolute quad,X RSVQ $nnnn,X 42 42 FD 5 9
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

SBC
This instruction performs A − M − 1 + C, and sets the processor flags accordingly.
The result is stored in the Accumulator Register.
NOTE: If the D flag is set, then the addition is performed using binary Coded Decimal.

Side effects
• The N flag will be set if the result of A − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of A − M is zero or positive, i.e., if A is not less
than M, otherwise it will be cleared.
• The V flag will be set if the result has a different sign to both of the arguments,
otherwise it will be cleared. If the flag is set, this indicates that a signed overflow
has occurred.

K-132
• The Z flag will be set if the result of A − M is zero, otherwise it will be cleared.
SBC : Subtract With Carry 45GS02
A←−M−1+C
N Z I C D V E
+ + · + · + ·
Addressing Mode Assembly Code Bytes Cycles
[indirect],Z SBC [$nn],Z EA F2 3 0

SBCQ
This instruction performs Q − M − 1 + C, and sets the processor flags accordingly.
The result is stored in the Q pseudo register.
NOTE: the indicated memory location is treated as the first byte of a 32-bit little-
endian value.
NOTE: If the D flag is set, the operation is undefined and subject to change.

Side effects
• The N flag will be set if the result of A − M is negative, i.e. has it’s most significant
bit set, otherwise it will be cleared.
• The C flag will be set if the result of A − M is zero or positive, i.e., if A is not less
than M, otherwise it will be cleared.
• The V flag will be set if the result has a different sign to both of the arguments,
otherwise it will be cleared. If the flag is set, this indicates that a signed overflow
has occurred.
• The Z flag will be set if the result of A − M is zero, otherwise it will be cleared.
SBCQ : Subtract With Carry Quad 45GS02
Q←Q−M−1+C
N Z I C D V E
+ + · + · + ·
Addressing Mode Assembly Code Bytes Cycles
r
base-page quad SBCQ $nn 42 42 E5 4 8
r
absolute quad SBCQ $nnnn 42 42 ED 5 9
ipr
(indirect quad) SBCQ ($nn) 42 42 F2 4 10
ipr
[indirect quad] SBCQ [$nn] 42 42 EA F2 5 13
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.
r Add one cycle if clock speed is at 40 MHz.

K-133
STA
This instruction stores the contents of the Accumulator Register into the indicated lo-
cation.
STA : Store Accumulator 45GS02
M←A
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
ip
[indirect],Z STA [$nn],Z EA 92 3 8
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.

STQ
This instruction stores the contents of the Q pseudo register into the indicated location.
As Q is composed of A, X, Y and Z, this means that these four registers will be written
to the indicated memory location through to the indicated memory location plus 3,
respectively.
STQ : Store Q 45GS02
M ← A, M+1 ← X, M+2 ← Y, M+3 ← Z
N Z I C D V E
· · · · · · ·
Addressing Mode Assembly Code Bytes Cycles
base-page quad STQ $nn 42 42 85 4 8
absolute quad STQ $nnnn 42 42 8D 5 9
ip
(indirect quad) STQ ($nn) 42 42 92 4 10
ip
[indirect quad] STQ [$nn] 42 42 EA 92 5 13
i Add one cycle if clock speed is at 40 MHz.
p Add one cycle if indexing crosses a page boundary.

K-134
APPENDIX L
Developing System
Programmes
• Introduction
• Flash Menu
• Format/FDISK Utility
• Keyboard Test Utility
• MEGA65 Configuration Utility
• Freeze Menu
• Freeze Menu Helper Programmes
• Hypervisor
• OpenROM

L-2
L-3
L-4
INTRODUCTION
The MEGA65 has a number of system programs and utilities that are used at various
times to perform various functions. This includes the utilities accessible via the Utility
Menu , the Freeze Menu and its own helper programs, as well as the Flash Menu .
A number of these system programs are pre-loaded into the MEGA65 bitstream, while
others live on the SD card. For those that are pre-loaded into the MEGA65 bitstream,
this works by having areas of pre-initialised memory, that contain the appropriate
program. For example, the utilities accessible via the Utility Menu are all located in
the colour RAM, while the Flash Menu is located at $50000 – $57FFF.
In one sense, the easiest way to test new versions of these utilities is to generate
a new bitstream with the updated versions. However, synthesising a new bitstream is
very time consuming, typically taking an hour on a reasonably fast computer. Therefore
this chapter explains the procedure for loading an alternate version of each of these
system programs, as well as providing some useful information about these programs,
how they operate, and the environment in which they operate compared with normal
C64 or C65-mode programs.

FLASH MENU
The flash menu is located in pre-initialised RAM at $50000 – $57FFF. It is executed
during the first boot each time the MEGA65 is switched on. It is unusual in that it
executes in the hypervisor context. This is so that it has access to the QSPI flash, which
is not available outside of Hypervisor Mode, so that user programs cannot corrupt the
cores stored in the flash.
It is also important to note that the flash menu program must fit entirely below $8000
when loaded and executing, as the Hypervisor is still mapped at $8000 – $BFFF, and
can easily be corrupted by an ill behaved flash menu program. In this regard, the
flash menu can be regarded as an extension of the hypervisor that is discarded after
the first boot. This is unlike all other system programs, that operate in a dedicated
memory context, from where the Hypervisor is safe from corruption. It also means that
you can’t crunch the flash menu to make it fit, as it would overwrite the Hypervisor
during decrunching.
Also, as the flash menu is executed very early in the boot process, only the pre-included
OpenROM ROM image is available. Thus you must ensure that your flash menu program
is compatible with that ROM.
The Hypervisor maintains a flag that indicates whether the flash menu has been ex-
ecuted or not. This flag is updated at the point where the Hypervisor exits to user
mode for the first time, since after that point, the contents of $50000 – $57FFF can
no longer be trusted to contain the flash menu. This means that if you wish to have the
Hypervisor run a new version of the flash menu that you have loaded, you must prevent
the Hypervisor from exiting to user mode first.

L-5
The easiest way to achieve this is to hold the ALT key down while powering on the
MEGA65. This will cause the Hypervisor to display the Utility Menu, rather than exiting
to user mode. It is safe at this time to use the m65 utility to load the replacement flash
menu program using a command similar to the following:

m65 -@ newflashmenu.prg@50000

That command would load the file newflashmenu.prg at memory location $50000.
After that, you can simply press the reset button on the side of the MEGA65 while
NO
holding SCROLL down, and it will boot again, and because it never left Hypervisor Mode
during the previous boot cycle, it will run your updated flash menu program.
It should also be possible to completely automate this process, by first using m65 -b to
load a new bitstream, thus simulating a cold boot, and then quickly calling m65 again
to simulate depressing the ALT key (or herhaps simply halting the processor), then m65
-@ ... and finally m65 -F to reset the machine. Writing a script or utility that correctly
implements this automation is left as an exercise for the reader.

FORMAT/FDISK UTILITY
The Format/FDISK utility is accessed as part of the Utility Menu system. These utilities
are compiled, crunched and linked using the utilpacker program. If you have checked
out the mega65-core source repository, you can re-build the colour RAM image by
using:

make bin/COLOURRAM.BIN

You will of course need to first have modified the Format/FDISK utility, which is normally
located in the src/mega65-freeze-menu subdirectory.
You need to then load this modified colour RAM image into the running machine. Sim-
ilar to when updating the flash menu, the Hypervisor will only present the utility menu
on the first boot, before exiting to user mode for the first time, because it cannot
otherwise be sure that the colour RAM contains the valid utility programs.
So as for the flash menu, you would power the MEGA65 off, and then holding the ALT
key down, you switch the MEGA65 back on, so that it displays the utility menu. At this
point you can use the following command to load your modified COLOURRAM.BIN file:

m65 -c COLOURRAM.BIN

L-6
ALT
You can now hold down, and press the reset button on the left-hand side of the
MEGA65, which should again present the utility menu, but this time with your modified
format/fdisk utility in place.

KEYBOARD TEST UTILITY


The process for updating the Keyboard test utility is essentially the same as for the
format/FDISK utility, as it lives in the colour RAM

MEGA65 CONFIGURATION UTILITY


The process for updating the MEGA65 Configuration utility is essentially the same as
for the format/FDISK utility, as it lives in the colour RAM

FREEZE MENU
The Freeze Menu is a normal program, which is stored in FREEZER.M65 on the SD card’s
FAT32 file system.
To updated the Freeze Menu, simply use the m65ftp utility or some other means to
upload your updated FREEZER.M65 file to the SD card’s FAT32 file system. The format
of the program is simply a C64-mode PRG file, just renamed to FREEZER.M65.

FREEZE MENU HELPER PROGRAMMES


The Freeze Menu helper programs are updated in the same way as the Freeze Menu
itself.

HYPERVISOR
The Hypervisor is normally built as HICKUP.M65, a 16KB file that contains the com-
plete Hypervisor program. MEGA65 bitstreams contain a pre-build version located at
$FFF8000 – $FFFBFFF. Updated versions of the Hypervisor can be tested using two
main approaches:
• 1. Place the updated HICKUP.M65 file on the FAT32 file system of the SD card,
and then power the MEGA65 off and on. This works because the Hypervi-
sor contains code that checks for an updated version of itself, and if found,

L-7
loads it. However this approach is problematic in that if you install a newer bit-
stream, it will still downgrade the Hypervisor to whatever version is found in the
HICKUP.M65 file on the SD card. This method is only recommended for devel-
opers who have a need to test their modified Hypervisor code from a cold start.
Even then, it is recommended to remove the HICKUP.M65 file immediately after
testing to avoid unexpected down-grading in the future.
• 2. Use the m65 command’s -k option to replace the Hypervisor in place, and
then reset the MEGA65 using the reset button on the left-hand side of the case.
This should be done when the Hypervisor is not active, so that corruption of cur-
rent execution cannot occur. However, it must also occur before any ROM has
been loaded to replace the default OpenROM image. This is because the Hyper-
visor will attempt to call into the ROM on first-boot in prepration for calling the
flash menu, and assumes that the OpenROM is present, because it uses a spe-
cial OpenROM-specific call to initialise parts of the system state for the flash
menu. This is best done by using a command like m65 -k bin/HICKUP.M65 -R
bin/MEGA65.ROM to load both a new Hypervisor program and re-load an Open-
ROM image.

OPENROM
To load a new version of a ROM, there are several options, including replacing both
the Hypervisor and ROM at the same time, as described above. However, typically
the easiest is to copy the new ROM onto the FAT32 filesystem of the SD card as ei-
ther MEGA65.ROM, or MEGA65x.ROM, where x is replaced by a digit between 0 and
9. When reseting the MEGA65, MEGA65.ROM will then be loaded as normal, or if
a digit between 0 and 9 is held down on the keyboard while resetting, the Hypervi-
sor will instead load MEGA65x.ROM, where x is the number being held down on the
keyboard.

L-8
APPENDIX M
MEGA65 Hyppo Services
• Introduction
• General Services
• Drive/Storage Services
• Disk Image Services
• Task and Process Services
• System Partition Services
• Freezer Services
M-2
INTRODUCTION
A part of the MEGA65 is the system program called Hyppo that:
• Boots the MEGA65.
• Loads the ROMs and other files from the SD card.
• Makes memory banks 2 and 3 ROM-like by protecting them from being written
to.
• Virtualises the floppy disk controller so you can use disk images.
• Launches various utilities like the freezer and the Matrix Mode Debugger.
• Provides services specific to the MEGA65 that you can use in your programs.
If you know about hypervisors and virtual machines, Hyppo is a very limited hypervisor.
Don’t expect to be able to run multiple virtual machines concurrently with full isolation.
Hyppo runs things that are more akin to the task and processes of a modern operating
system than the virtual machines of a hypervisor as you might know it.
Hyppo provides 3 operating modes.
• The C64-like operating mode runs C64 programs and MEGA65 programs that
run in the MEGA65’s C64 mode. When you boot with ` pressed or use the
GO64 command, Hyppo starts a process in the C64-like operating mode to run
BASIC 2 or the MEGA65 program.
• The C65-like operating mode is the MEGA65’s normal operating mode. This
is where regular MEGA65 program run, including BASIC 65 programs.
• The MEGA65 operating mode runs the MEGA65’s system programs like the
freezer, the configuration utility and the Matrix Mode Debugger. Maybe surpris-
ingly, normal MEGA65 programs do not run in the MEGA65 operating mode.
They run in the C65-like operating mode. The MEGA65 operating mode is de-
signed solely for the MEGA65 and does not attempt to be compatible with or
even be similar to previous systems.
Unlike on the C128, it is possible for a program to effectively change the operat-
ing mode while it’s is running, by simply enabling or disabling the various hardware
features.
Hyppo provides very limited virtualisation of the MEGA65’s hardware. It can virtualise
the floppy controller. There are plans to virtualise the serial bus so the MEGA65 can
use disk images for units like the 1541.
There are some parts of the hardware that only Hyppo can access. It is the only com-
ponent that can directly access the internal and external SD cards. You need to use
Hyppo’s services if you want to access the files and directories on the SD cards from
within your programs.

M-3
Terminology
When you start to learn about Hyppo, there can be some terminology that might be
confusing if you already know about other parts of the MEGA65.
On the SD card there is likely to be a file called HICKUP.M65. This file updates Hyppo
to new versions without having to install an upgraded core. You might find occasions
where Hyppo might be called Hickup because of this strong association.
There are 3 distinct disk operating systems in the MEGA65.
• Inside Hyppo is Hyppo DOS, or HDOS for short. HDOS is for accessing the FAT32
file system on the SD cards. HDOS does not know anything about Commodore
file systems. It can attach an image of a Commodore file system, but it does not
understand what is inside the image.
• Inside the KERNAL is CBDOS. CBDOS is for accessing 1581-like file systems.
CBDOS uses the 45IO27 multi-function I/O controller to access the sectors of
a physical disk. CBDOS does not know anything about SD cards and the FAT32
file system on them. Hyppo virtualises part of the 45IO27 so CBDOS can access
disk images like they’re physical disks.
• The external disk units attached to the serial bus each have their own DOS. They
are used for accessing the file systems on their respective physical disks.
The word drive means different things for each of these DOS’s.
• The drives in Hyppo are the partitions of the internal and external SD cards. When
the MEGA65 boots, Hyppo assigns numbers to the partitions it can read.
• The drives in CBDOS are the physical disk drives attached to the 45IO27 multi-
function I/O controller — such as the internal disk drive — or the disk images
attached to the virtualised 45IO27. The CBDOS drives are normally seen as
units 8 and 9.
• The drives in an external unit attached to the serial bus are the disk drives inside
that unit.

M-4
Versions
This chapter describes the services available in Hyppo 1.2.
New Hyppo services may become available and existing Hyppo services may change
or be deprecated. A robust program will use the hyppo_getversion service to check
whether it is compatible with the Hyppo in the MEGA65 it’s running on.

Using
When you want to use a Hyppo service, you don’t use JSR. This is because Hyppo exists
in a space that’s separate from regular code. In order to access it, the CPU needs to
switch into its hypervisor mode.
At addresses $D640 – $D67F are a set of hypervisor traps. Writing to these addresses
are not like writing to other addresses. Instead of writing to memory or I/O, the CPU
switches into the hypervisor mode and starts a Hyppo service. How the CPU does this
is described in Chapter/Appendix J on page J-3.
Which Hyppo service starts depends on what value from the A register you write and
which trap you write to. Each of the services described in this chapter tells you what
value to write and which trap to use. You have to use the A register when triggering a
trap. Writing the same value from another register won’t work.
When the Hyppo service finishes, the CPU will switch back to your program. Except for
the registers a service uses to return values, the registers are otherwise preserved.
Important The CPU may or may not execute the next byte in your program after the
Hyppo service finishes. Put a CLV instruction after the STA. The CPU executing the CLV
or not shouldn’t matter to your program. If your program does rely on the V flag, you
can use the NOP instruction instead. When you use NOP you must be mindful of when
the CPU interprets the NOP as a prefix for the following instruction. For this reason,
you should prefer using CLV over NOP.

Errors
If the service was successful, it will set the C flag.
If the service was unsuccessful, it will clear the C flag and put an error code in the A
register. There is a table of error codes in the description for hyppo_geterrorcode.

Examples
The examples use the ACME assembler. The ACME assembler is not required. The
Hyppo services can be used with any assembler.

M-5
The examples are often not complete. They assume an error handler called error is
defined somewhere. They also assume a transfer area has been defined somewhere.
hyppo_setup_transfer_area and hyppo_setname show how to define a transfer area.

M-6
GENERAL SERVICES
hyppo_geterrorcode
Trap: LDA #$38 : STA $D640 : CLV
Service: Returns the current error code from Hyppo.
Precondition: The previous service used cleared the C flag.
Outputs: A The error code of the previously failed service.
History: Available since Hyppo 1.2
Remarks: The error code is only valid if the previous Hyppo service cleared the
C flag. If the C flag was set there was no error and the Hyppo error
code is undefined.
The meanings here are generic. See the sections for the services for
more specific meanings.
Error codes: This is possibly not an exhaustive list.

Hex Dec Name General meaning


$01 1 partition not The partition is not of a supported type.
interesting
$02 2 bad signature The signature bytes at the end of a partition table or of
the first sector of a partition were missing or incorrect.
$03 3 is small FAT This is partition is FAT12 or FAT16 partition. Only
FAT32 is supported.
$04 4 too many reserved The partition has more than 65,535 reserved sectors.
clusters
$05 5 not two FATs The partition does not have exactly two copies of the
FAT structure.
$06 6 too few clusters The partition contains too few clusters.
$07 7 read timeout It took to long to read from the SD card.
$08 8 partition error An unspecified error occurred while handling a parti-
tion.
$10 16 invalid address An invalid address was supplied in an argument.
$11 17 illegal value An illegal value was supplied in an argument.
$20 32 read error An unspecified error occurred while reading.
$21 33 write error An unspecified error occurred while writing.

M-7
Hex Dec Name General meaning
$80 128 no such drive The supplied Hyppo drive number does not exist.
$81 129 name too long The supplied filename was too long.
$82 130 not implemented The Hyppo service is not implemented.
$83 131 file too long The file is larger than 16MB.
$84 132 too many All of the file descriptors are in use.
open files
$85 133 invalid cluster The supplied cluster number is invalid.
$86 134 is a directory An attempt was made to operate on a directory,
where a normal file was expected.
$87 135 not a directory An attempt was made to operate on a normal file,
where a directory was expected.
$88 136 file not found The file could not be located in the current directory
of the current drive.
$89 137 invalid file An invalid or closed file descriptor was supplied.
descriptor
$8A 138 image wrong The disk image file has the wrong length.
length
$8B 139 image fragmented The disk image is not stored contiguously on the SD
card.
$8C 140 no space The SD card has no free space for the requested op-
eration.
$8D 141 file exists A file already exists with the given name.
$8E 142 directory full The directory cannot accommodate any more entries.
$FF 255 eof The end of a file or directory was encountered.
$FF 255 no such trap There is no Hyppo service available for the trap. The
program may be incompatible with this version of
Hyppo.

M-8
hyppo_getversion
Trap: LDA #$00 : STA $D640 : CLV
Service: Returns the version of Hyppo A.X and HDOS Y.Z.
Outputs: A The major version number of Hyppo
X The minor version number of Hyppo
Y The major version number of HDOS
Z The minor version number of HDOS
History: Available since Hyppo 1.2
Remarks: The HDOS in Hyppo is not related to the CBDOS inside the KERNAL
or the DOS in the disk drive units attached to the serial port.
Example: Tests if Hyppo’s version is ≥ 1.2 and < 2.0.

; Get the version numbers


LDA #$00 : STA $D640 : CLV
; Test if the major version number of Hyppo in A is 1
CMP #1 : BNE incompatible
; Test if the minor version number of Hyppo in X is 2 or more
TXA : CMP #2 : BMI incompatible
; This Hyppo version is compatible

M-9
hyppo_setup_transfer_area
Trap: LDA #$3A : STA $D640 : CLV
Service: Sets up the area Hyppo uses to transfer data to and from your pro-
gram.
Inputs: Y The MSB of the transfer area’s address
Errors: $10 invalid address The transfer area address in Y > $7E
History: Available since Hyppo 1.2
Remarks: The transfer area must be between $0000 and $7E00. It must also
begin on a page boundary. The LSB of its address must be $00.
The transfer area is 256 bytes long for most services.
The transfer area is indicated using the CPU’s current memory map-
ping at the time that a service is used. However, it is good practice
to always place it in the bottom 32KB of bank 0.
Example: Reserves 256 bytes on a page boundary and sets it up as the transfer
area.

;---------------------------------------------------------------------------------------
; Somewhere in the program’s data area

; Align with the new page boundary


!align 255, 0

transferarea:
; Reserve 256 bytes
!skip 256

;---------------------------------------------------------------------------------------
; Elsewhere in the progrma’s code

setuptransferarea:
; Set the transferarea as the Hyppo transfer area
LDY #>transferarea : LDA #$3A : STA $D640 : CLV : BCC error

M-10
DRIVE/STORAGE SERVICES
In Hyppo, drives are the partitions of the internal and external SD cards. They are not
the drive 0 and drive 1 of the F011 floppy controller. They are also not the drive 0
and drive 1 of dual-drive units attached to the serial bus.

hyppo_chdir
Trap: LDA #$0C : STA $D640 : CLV
Service: Changes the current working directory.
Preconditions: The FAT dir entry for the directory you want to change to has been
found. hyppo_findfile is typically used to find a FAT dir entry.
hyppo_findfirst , hyppo_findnext and hyppo_readdir can also
be used.
Errors: $87 not a directory The FAT dir entry last found isn’t for a directory.
Bit 4 of the FAT dir entry’s attribute byte is set for directories.
History: Available since Hyppo 1.2
Remarks: You can move up to the parent directory by finding the .. FAT dir
entry.
You cannot move up or down more than one directory at a time.
Use hyppo_cdrootdir to directly change back to the root directory.
Example: Changes to an arbitrary path on the current drive. Call with Y:X be-
ing the address of the path. The last character of each component
in the path needs to have bit 7 set. The whole path is terminated
with a $00. For example, to change into DIR1 and then DIR2 the
path would be !text "DIR", '1'+$80, "DIR" '2'+$80, 0.
If successful, returns with the C flag set. If some part of the path
doesn’t exist, returns with the C flag cleared and the current working
directory will be whatever directory was last successfully navigated
to.

!addr pathptr = $C4


chdirpath:
STX pathptr : STY pathptr+1 ; Set pathptr to Y:Z
@chdirpath10:
JSR @copycomponent ; Get the next component of the path
BEQ @chdirpath20 ; Stop at a 0 byte in the path
JSR @trychdir ; Try to change into the directory
BCC @chdirpath30 ; Stop if we cannot change into the directory
… continues on the next page …

M-11
BRA @chdirpath10 ; Repeat with the next component
@chdirpath20: SEC
@chdirpath30: RTS
;----------------------------------------------------------------------------------------
@trychdir:
; Set the Hyppo filename from transferbuffer
LDY #>transferbuffer : LDA #$2E : STA $D640 : CLV : BCC @trychdir10
; Find the FAT dir entry
LDA #$34 : STA $D640 : CLV : BCC @trychdir10
; Chdir into the directory
LDA #$0C : STA $D640 : CLV
@trychdir10:
RTS
;----------------------------------------------------------------------------------------
; Copy the next component of the path into transferbuffer
@copycomponent:
LDY #0
@copycomponent10:
LDA (pathptr),Y
BEQ @copycomponent20
TAX
AND #$7F : STA transferbuffer,Y
INY
TXA : BPL @copycomponent10
; Add a 0 terminating byte to transferbuffer
LDA #0 : STA transferbuffer,Y
; Move pathptr
TYA
CLC : ADC pathptr : STA pathptr : LDA #0 : ADC pathptr+1 : STA pathptr+1
@copycomponent20:
RTS

M-12
hyppo_cdrootdir
Trap: LDA #$3C : STA $D640 : CLV
Service: Change drive by calling hyppo_selectdrive and set the current
directory to the root directory.
Inputs: X The drive number to become the new current drive
Precondition: None.
Outputs: A Any error code that can be returned by hyppo_selectdrive
History: Available since Hyppo 1.16

M-13
hyppo_closeall
Trap: LDA #$22 : STA $D640 : CLV
Service: Closes all the file descriptors.
Postconditions: Using any file descriptor with hyppo_closedir or hyppo_closefile
succeeds.
Using any file descriptor with hyppo_readdir or hyppo_readfile
fails.
hyppo_opendir and hyppo_openfile reuse the file descriptor.
History: Available since Hyppo 1.2
Remarks: You can also close individual file descriptors using hyppo_closedir
or hyppo_closefile .

M-14
hyppo_closedir
Trap: LDA #$16 : STA $D640 : CLV
Service: Closes a file descriptor for a directory.
Preconditions: The file descriptor given in the X register was opened using
hyppo_opendir .
Inputs: X The file descriptor for the directory
Postconditions: Using the file descriptor again with hyppo_closedir succeeds.
Using the file descriptor again with hyppo_readdir fails.
hyppo_opendir and hyppo_openfile reuse the file descriptor.
History: Available since Hyppo 1.2
Remarks: You can also close all the open file descriptors using hyppo_closeall
.
Example: See the example in hyppo_opendir .

M-15
hyppo_closefile
Trap: LDA #$20 : STA $D640 : CLV
Service: Closes a file descriptor for a file.
Preconditions: The file descriptor given in the X register was opened using
hyppo_openfile .
Inputs: X The file descriptor for the file
Postconditions: Using the file descriptor again with hyppo_closefile succeeds.
Using the file descriptor again with hyppo_readfile fails.
hyppo_opendir and hyppo_openfile reuse the file descriptor.
History: Available since Hyppo 1.2
Remarks: You can also close all the open file descriptors using hyppo_closeall
.

M-16
hyppo_filedate
Trap: LDA #$2C : STA $D640 : CLV
Service: Sets time stamp of a file.
Remarks: NOT IMPLEMENTED

M-17
hyppo_findfile
Trap: LDA #$34 : STA $D640 : CLV
Service: Finds the first file whose filename matches the current Hyppo file-
name.
Preconditions: The current Hyppo filename has been set using hyppo_setname .
Postconditions: No additional file descriptors are open.
Errors: $88 file not found A matching file was not found in the current
directory of the current drive.
History: Available since Hyppo 1.2
Remarks: Hyppo will only find files whose long filename is all in uppercase.
Hyppo converts the current filename to ASCII uppercase before try-
ing to match it. Bytes $61 – $7B change to $41 – $5A.
Hyppo does not yet support the wildcard characters * and ?. Sup-
port for that is planned in a future version.
This only finds the first matching file. You can find multiple matches
by using hyppo_findfirst and hyppo_findnext .
Example: See the example in hyppo_openfile .

M-18
hyppo_findfirst
Trap: LDA #$30 : STA $D640 : CLV
Service: Finds the first file whose filename matches the current Hyppo file-
name.
Preconditions: The current Hyppo filename has been set using hyppo_setname .
Outputs: A The file descriptor for reading the current working directory.
You might be responsible for closing this file descriptor using
hyppo_closedir . See the remarks.
Postconditions: hyppo_findnext find the next matching file or fails with a file not
found error.
Side effects: Sets the current file descriptor.
Errors: $88 file not found A matching file was not found in the current
directory of the current drive.
History: Available since Hyppo 1.2
Remarks: If Hyppo finds an initial matching file, it will set the C flag and return
a file descriptor in the A register. This is a file descriptor for reading
the current working directory. You are responsible for closing it using
hyppo_closedir . It’s a standard directory file descriptor. You can
use hyppo_readdir to read the FAT dir entries after the file that
was found.
If Hyppo doesn’t find any matching files, it will fail with a file not
found error. In this case Hyppo will have already closed the file de-
scriptor and you don’t have to close it.
Hyppo will only find files whose long filename is all in uppercase.
Hyppo converts the current filename to ASCII uppercase before try-
ing to match it. Bytes $61 – $7B change to $41 – $5A.
Hyppo does not yet support the wildcard characters * and ?. Sup-
port for that is planned in a future version.
If you are only interested in the first match, you can use
hyppo_findfile instead. hyppo_findfile always closes the file
descriptor for you. But you can’t use it to find multiple matching
files.
Example: See the example in hyppo_findnext .

M-19
hyppo_findnext
Trap: LDA #$32 : STA $D640 : CLV
Service: Finds a subsequent file whose filename matches the current Hyppo
filename.
Preconditions: The current Hyppo filename has been set using hyppo_setname .
The first matching file has already been found successfully using
hyppo_findfirst .
Postconditions: Using hyppo_findnext again finds the next matching file or fails
with a file not found error.
Errors: $88 file not found A subsequent matching file was not found in the
current directory of the current drive.
History: Available since Hyppo 1.2
Remarks: If Hyppo doesn’t find a subsequent matching file, it will fail with a
file not found error. Hyppo will also close the file descriptor it output
in hyppo_findfirst .
If you don’t exhaust the search by using hyppo_findnext until it
fails with a file not found error, you are required to close the file
descriptor yourself using hyppo_closedir .
Example: Returns with X register containing the number of files matching the
current Hyppo filename in the current working directory of the cur-
rent drive. While a directory can in theory have multiple files with
an indentical name, this example will be more useful once Hyppo
supports * and ? wildcards.

; Assume the current Hyppo filename has already been set.


; Reset the count in X.
LDX #0
; Try to find the first matching file.
LDA #$30
@10:
STA $D640 : CLV : BCC @20
; Increment the count in X
INX
; Try to find the next matching file.
LDA #$32
BRA @10
@20:
; If the error code in A is $88 there are no more matching files,
; otherwise an error occurred.

… continues on the next page …

M-20
CMP #$88 : BNE error
; No need to close the file handle because the search exhausted.

M-21
hyppo_fstat
Trap: LDA #$28 : STA $D640 : CLV
Service: Returns information about a file.
Remarks: NOT IMPLEMENTED

M-22
hyppo_getcurrentdrive
Trap: LDA #$04 : STA $D640 : CLV
Service: Returns the number of the currently selected drive (SD card parti-
tion).
Outputs: A The current drive number
History: Available since Hyppo 1.2
Remarks: hyppo_selectdrive changes the current drive number.
hyppo_cdrootdir can also change it.
Example: Prints the number of the currently selected drive in the top-left of
the screen. This example assumes that there aren’t more than 10
drives (drives 0 to 9). It also assumes the screen memory hasn’t
been moved from $800.

; Get the current drive


LDA #$04 : STA $D640 : CLV : BCC error

; Convert the drive number in A into a screen code


CLC : ADC #$30

; Put the screen code into the top-left of screen memory


STA $0800

M-23
hyppo_getcwd
Trap: LDA #$0A : STA $D640 : CLV
Service: Returns information on the currently selected directory or sub-
directory.
Remarks: NOT IMPLEMENTED

M-24
hyppo_getdefaultdrive
Trap: LDA #$02 : STA $D640 : CLV
Service: Returns the drive number (SD card partition) Hyppo selected while
booting.
Outputs: A The default drive number
History: Available since Hyppo 1.2
Example: Selects the default drive.

; Get the default drive


LDA #$02 : STA $D640 : CLV : BCC @error

; Transfer the drive number in A to X


TAX

; Select the default drive


LDA #$06 : STA $D640 : CLV : BCC @error

M-25
hyppo_getdrivesize
Trap: LDA #$08 : STA $D640 : CLV
Service: Returns information on the size of the currently selected drive (SD
card partition).
Remarks: NOT IMPLEMENTED

M-26
hyppo_loadfile
Trap: LDA #$36 : STA $D640 : CLV
Service: Loads a file into chip memory.
Preconditions: The name of the file to load has been set using hyppo_setname .
Inputs: X The LSB of the address to start loading from
Y The middle byte of the address to start loading from
Z The MSB of the address to start loading from
Postconditions: No additional file descriptors are open.
Errors: $84 too many open files hyppo_loadfile uses one file descriptor
internally, but all the file descriptors are in use. Close some or all
of the file descriptors using hyppo_closedir , hyppo_closefile or
hyppo_closeall .
$88 file not found The file was not found in the current directory of
the current drive.
History: Available since Hyppo 1.2
Remarks: This service can load files up to 16MB in size into the first 16MB of
chip memory. Chip memory is the 384KB or more of memory inside
the CPU module.
Loading will start at 28-bit address $00ZZYYXX. If loading tries
to go beyond $00FFFFFF, it wraps around and continue at
$00000000.
You can use hyppo_loadfile_attic to load a file into hyper memory.
The hyper memory is the 8MB or more of memory in the external RAM
chips.
Example: Loads a file into memory starting at $48000.

; Assume the current Hyppo filename has already been set.


; No need to find the file first.
LDZ #$04 ; Most significant byte
LDY #$80 ; Middle byte
LDX #$00 ; Least significant byte
LDA #$36 : STA $D640 : CLV : BCC error

M-27
hyppo_loadfile_attic
Trap: LDA #$3E : STA $D640 : CLV
Service: Loads a file into hyper memory.
Preconditions: The name of the file to load has been set using hyppo_setname .
Inputs: X The LSB of the address to start loading from
Y The middle byte of the address to start loading from
Z The MSB of the address to start loading from
Postconditions: No additional file descriptors are open.
Errors: $84 too many open files hos_loadfile_attic uses one file descriptor
internally, but all the file descriptors are in use. Close some or all of
the file descriptors using hyppo_closedir , hyppo_closefile or
hyppo_closeall .
$88 file not found The file was not found in the current directory of
the current drive.
History: Available since Hyppo 1.2
Remarks: This service can load files up to 16MB in size into the first 16MB of
hyper memory. Hyper memory is the 8MB or more of memory in the
external RAM chips.
Loading will start at 28-bit address $08ZZYYXX. If loading tries to
go beyond $08FFFFFF, the loading will wrap around and continue
at $08000000.
You can use hyppo_loadfile to load a file into chip memory. The
chip memory is the 384KB or more of memory inside the CPU module.

M-28
hyppo_mkdir
Trap: LDA #$0E : STA $D640 : CLV
Service: Creates a sub-directory.
Errors: $8D file exists A sub-directory or file already exists with the current
Hyppo filename in the current working directory of the current drive.
Remarks: NOT IMPLEMENTED

hyppo_mkfile
Trap: LDA #$1E : STA $D640 : CLV
Service: Creates a file.
Errors: $8D file exists A sub-directory or file already exists with the current
Hyppo filename in the current working directory of the current drive.
Remarks: NOT IMPLEMENTED

M-29
hyppo_opendir
Trap: LDA #$12 : STA $D640 : CLV
Service: Opens the current working directory for reading the file entries in it.
Preconditions: The drive and directory you want to read have already been set up
using hyppo_selectdrive and hyppo_chdir if necessary.
Outputs: A The file descriptor for reading the directory. You are responsible
for closing this file descriptor using hyppo_closedir .
Postconditions: hyppo_readdir reads the first FAT dir entry in the directory.
Errors: $84 too many open files All the file descriptors are in use.
hyppo_opendir and hyppo_openfile share the same very small
pool of file descriptors. Close some or all of the file descriptors us-
ing hyppo_closedir , hyppo_closefile or hyppo_closeall .
$87 not a directory The FAT dir entry last found is for a file. Use
hyppo_openfile for files.
History: Available since Hyppo 1.2
Example: Calls processdirentry for each FAT dir entry in the current working
directory. processdirentry is assumed to be defined elsewhere.

; Open the current working directory


LDA #$12 : STA $D640 : CLV : BCC error
; Transfer the directory file descriptor into X
TAX
; Set Y to the MSB of the transfer area
LDY #>transferarea
@10:
; Read the directory entry
LDA #$14 : STA $D640 : CLV : BCC @20
; Call processdirentry (assumed to be defined elsewhere)
PHX : PHY : JSR processdirentry : PLY : PLX
BRA @10
@20:
; If the error code in A is $85 we have reached the end of the
; directory otherwise there’s been an error
CMP #$85 : BNE error
; Close the directory file descriptor in X
LDA #$16 : STA $D640 : CLV : BCC error

M-30
hyppo_openfile
Trap: LDA #$18 : STA $D640 : CLV
Service: Opens a file on a drive.
Preconditions: The file has already been found. Files can be found us-
ing hyppo_findfile , hyppo_findfirst and hyppo_findnext .
hyppo_readdir can also be used to find a file.
Outputs: A The file descriptor for accessing the file. You are responsible for
closing this file descriptor using hyppo_closefile .
Postconditions: Using hyppo_readfile with this file descriptor reads the first sector
of the file.
Side effects: Sets the current file to the newly opened file. hyppo_readfile
reads from the current file.
Errors: $84 too many open files All the file descriptors are in use.
hyppo_opendir and hyppo_openfile share the same very small
pool of file descriptors. Close some or all of the file descriptors us-
ing hyppo_closedir , hyppo_closefile or hyppo_closeall .
$86 is a directory The FAT dir entry last found is for a directory. Use
hyppo_opendir for directories.
History: Available since Hyppo 1.2
Remarks: You cannot use this to open a file inside a disk image. To do that
you use hyppo_d81attach0 or hyppo_d81attach1 to attach the
disk image and then use either use the KERNAL to read the file or
program the virtualised F011 floppy controller.
Example: Finds and opens a file.

; Assume the current Hyppo filename has already been set.


; Find the file
LDA #$34 : STA $D640 : CLV : BCC error
; Open the file
LDA #$18 : STA $D640 : CLV : BCC error

M-31
hyppo_readdir
Trap: LDA #$14 : STA $D640 : CLV
Service: Reads the next FAT dir entry into a destination area.
Preconditions: The file descriptor given in the X register was opened using
hyppo_opendir and hyppo_closedir hasn’t since been used to
close it.
The destination area is on a page boundary between $0000 and
$7E00 and is at least 87 bytes.
Inputs: X The file descriptor for the directory.
Y The MSB of the destination area.
Outputs: Starting at $YY00, the FAT dir entry has this structure.
Offset Type Description
$00 asciiz The long file name
$40 byte The length of long file name
$41 ascii The ”8.3” file name. The name part is padded
with spaces to make it exactly 8 bytes. The
3 bytes of the extension follow. There is no .
between the name and the extension. There is
no NULL byte.
$4E dword The cluster number where the file begins. For
sub-directories, this is where the FAT dir entries
start for that sub-directory.
$52 dword The length of file in bytes.
$56 byte The type and attribute bits.

This is what the bits in the last byte mean. Bits 6 and 7 are undefined.
Bit Meaning if bit is set
0 Read only
1 Hidden
2 System
3 Volume label
4 Sub-directory
5 Archive
Postconditions: Using hyppo_readdir again reads the next FAT dir entry in the di-
rectory.
Errors: $08 partition error An unspecified error occurred while handling
the currently selected partition.
$10 invalid address The Y register is > $7E.
$85 invalid cluster An attempt was made to read past the end of
the directory.

M-32
Remarks: If the long file name in the FAT dir entry is too long to copy into the
destination area, Hyppo skips the entry entirely.
The file names in FAT are encoded as UTF-16. Hyppo only reads the
LSB of each 16-bit character. Hyppo does not convert file names
into PETSCII.
See hyppo_setup_transfer_area for more details about the value
for the Y register.
History: Available since Hyppo 1.2
Example: See the example in hyppo_opendir .

M-33
hyppo_readfile
Trap: LDA #$1A : STA $D640 : CLV
Service: Reads the next sector of the current file into the sector buffer.
Preconditions: There is a current file open. Files can be opened with
hyppo_openfile .
Outputs: X The LSB of the number of bytes read
Y The MSB of the number of bytes read
Postconditions: The next call to hyppo_readfile will read the next sector of the
current file or signal the end of the file.
Errors: $89 invalid file descriptor There is no current file.
History: Available since Hyppo 1.2
Remarks: To access the data, you need to either:
• map the sector buffer into the 16-bit address space;
• use an enhanced DMA transfer to copy the sector buffer at
$FFD6E00 – $FFD6FFF into a buffer already mapping into the
16-bit address space; or
• use 32-bit load instructions to access the sector buffer directly.
If a full sector was read, Y:X will be $0200. For the last sector of
the file, Y:X may be less than that. Any bytes in the sector buffer
after Y:X are undefined and will not necessarily be zero.
If you read past the end of the last sector, Y:X will be $0000, the A
register will be $FF and the C flag will be set.
While multiple files can be opened simultaneously, only the current
file can be read. The current file is often the last file opened, but
not always.
Example: Maps the sector buffer to $DE00 and then reads each sector of the
file calling proccesssector for each sector read. proccesssector is
assumed to be defined elsewhere.

; Assume the file is already open.


; Unmap the colour RAM from $DC00 because that will prevent us
; from mapping in the sector buffer
LDA $D030 : PHA : AND #%11111110 : STA $D030
@10:
; Read the next sector
LDA #$1A : STA $D640 : CLV : BCC @20
… continues on the next page …

M-34
; Map the sector buffer to $DE00
LDA #$81 : STA $D680
; Call processsector (assumed to be defined elsewhere)
JSR processsector
; Unmap the sector buffer from $DE00
LDA #$82 : STA $D680
BRA @10
@20:
; If the error code in A is $FF we have reached the end of the file
; otherwise there’s been an error
CMP #$FF : BNE error
; Map the colour RAM at $DC00 if it was previously mapped
PLA : STA $D030

M-35
hyppo_rename
Trap: LDA #$2A : STA $D640 : CLV
Service: Renames a file or sub-directory.
Errors: $8D file exists A sub-directory or file already exists with the current
Hyppo filename in the current working directory of the current drive.
Remarks: NOT IMPLEMENTED

hyppo_rmdir
Trap: LDA #$10 : STA $D640 : CLV
Service: Removes a sub-directory.
Remarks: NOT IMPLEMENTED

hyppo_rmfile
Trap: LDA #$26 : STA $D640 : CLV
Service: Removes a files.
Remarks: NOT IMPLEMENTED

hyppo_seekfile
Trap: LDA #$24 : STA $D640 : CLV
Service: Seeks to a given sector in a file.
Remarks: NOT IMPLEMENTED

M-36
hyppo_selectdrive
Trap: LDA #$06 : STA $D640 : CLV
Service: Sets the currently selected drive (SD card partition).
Preconditions: Hyppo has assigned a drive number to the SD card partition.
Inputs: X The drive number to become the new current drive
Postconditions: hyppo_getcurrentdrive returns the value that was in the X register.
Hyppo services operate on the newly selected drive.
Errors: $80 no such drive The drive in the X register does not exist. Hyppo
only assigns drive numbers to the SD card partitions it can read.
History: Available since Hyppo 1.2
Example: Tests if drive 2 exists by trying to select it. Returns with the C flag
set if drive 2 exists.

doesdrive2exist:
; Preserve the current drive so we can restore it later
LDA #$04 : STA $D640 : CLV : BCC error
PHA
; Try to select drive 2
LDX #2 : LDA #$06 : STA $D640 : CLV : BCC @10
; Restore the previously selected drive
PLX
LDA #$06 : STA $D640 : CLV : BCC error
; The C flag was already set by the Hyppo service
RTS

@10:
; If the error code in A is $80, the drive doesn’t exist; otherwise
; some other kind of error occurred
CMP #$80
BNE error
; Forget about the current drive we preserved because it wasn’t
; changed
PLX
; Clear the C flag because the drive doesn’t exist
CLC
RTS

M-37
hyppo_setname
Trap: LDA #$2E : STA $D640 : CLV
Service: Sets the current Hyppo filename.
Preconditions: The filename is stored in ASCII and ends with a $00 byte.
The filename starts on a page boundary between $0000 and $7E00
and is less than 63 characters, excluding the $00 byte.
Inputs: Y The MSB of the filename address.
Postconditions: Hyppo has copied the filename into it’s own data area.
The hyppo_find* and hyppo_load* services use this filename.
Side effects: Sets the transfer area to $YY00.
Errors: $10 invalid address The Y register is > $7E.
$81 name too long The filename is longer than 63 characters.
History: Available since Hyppo 1.2
Remarks: The filename must be between $0000 and $7E00. It must also
begin on a page boundary. That is, its address must end with $00.
The current memory mapping is used. However, it is good practice
to place it in the bottom 32KB of bank 0.
The filenames in FAT are encoded in UTF-16. Hyppo only reads the
LSB of each 16-bit character. Hyppo does not convert between
ASCII and PETSCII.
Hyppo accesses the files in the FAT file system on the internal and
external SD cards. It does not access files on disks in floppy drives
or in disk images.
Example: Set the current Hyppo filename to GAME.MAP.

; Somewhere in the program’s data area


!align 255, 0 ; Align with the next page boundary
filename:
!text "GAME.MAP", 0 ; Must end with a 0 byte

; Elsewhere in the progrma’s code


setfilename:
LDY #>filename : LDA #$2E : STA $D640 : CLV : BCC error

M-38
hyppo_writefile
Trap: LDA #$1C : STA $D640 : CLV
Service: Writes the sector buffer to the current file.
Remarks: NOT IMPLEMENTED

M-39
DISK IMAGE SERVICES
The 45IO27 multi-function I/O controller includes a F011-compatible floppy con-
troller. The internal floppy drive is attached to this as drive 0.
Hyppo can virtualise the F011 floppy controller so that disk images can be attached
instead of floppy drives. Once a disk image is attached, Hyppo traps the F011’s I/O
registers and emulates the commands on the disk image.
You can use BASIC, the KERNAL and the F011 I/O registers to operate on a disk image
just as you would a physical disk. The virtualisation does not behave the same as a
floppy drive in all cases. If you intend for your program to work with both disk images
and physical disks, be sure to test it with both.

hyppo_d81attach0
Trap: LDA #$40 : STA $D640 : CLV
Service: Attach a D81 disk image to virtualised F011 drive 0.
Preconditions: The current Hyppo filename has been set using hyppo_setname .
Errors: $88 file not found The disk image file was not found in the current
directory of the current drive.
History: Available since Hyppo 1.2
Remarks: Unless it’s been changed, drive 0 of the virtualised F011 floppy con-
troller is unit 8.
Example: Attaches the disk image DISK2.D81 to virtualised F011 drive 0.

; Somewhere in the program’s data area


!align 255, 0 ; Align with the next page boundary
disk2name:
!text "DISK2.D81", 0 ; Must end with a 0 byte

; Elsewhere in the progrma’s code


attachdisk2:
; Set the Hyppo filename to DISK2.D81
LDY #>disk2name : LDA #$2E : STA $D640 : CLV : BCC error
; Attach the disk image
LDA #$40 : STA $D640 : CLV : BCC error

M-40
hyppo_d81attach1
Trap: LDA #$46 : STA $D640 : CLV
Service: Attach a D81 disk image to virtualised F011 drive 1.
Preconditions: The current Hyppo filename has been set using hyppo_setname .
History: Available since Hyppo 1.2
Remarks: Unless it’s been changed, drive 1 of the virtualised F011 floppy con-
troller is unit 9.

M-41
hyppo_d81detach
Trap: LDA #$42 : STA $D640 : CLV
Service: Detaches any disk images from virtualised F011 drives 0 and 1.
History: Available since Hyppo 1.2

M-42
hyppo_d81write_en
Trap: LDA #$44 : STA $D640 : CLV
Service: Enables writing to any disk images attached to virtualised F011
drives 0 and 1.
History: Available since Hyppo 1.2

M-43
TASK AND PROCESS SERVICES
hyppo_create_task_c64
Trap: LDA #$66 : STA $D640 : CLV
Service: Creates a Hyppo task in the C64-like operating mode.
Remarks: NOT IMPLEMENTED

hyppo_create_task_c65
Trap: LDA #$68 : STA $D640 : CLV
Service: Creates a Hyppo task in the C65-like operating mode.
Remarks: NOT IMPLEMENTED

hyppo_create_task_native
Trap: LDA #$62 : STA $D640 : CLV
Service: Creates a Hyppo task in the MEGA65 operating mode.
Remarks: NOT IMPLEMENTED

hyppo_exit_and_switch_to_task
Trap: LDA #$6A : STA $D640 : CLV
Service: Exits the current Hyppo task and switches context to another Hyppo
task.
Remarks: NOT IMPLEMENTED

hyppo_exit_task
Trap: LDA #$6E : STA $D640 : CLV
Service: Exits the current Hyppo task.
Remarks: NOT IMPLEMENTED

M-44
hyppo_get_mapping
Trap: LDA #$74 : STA $D640 : CLV
Service: Copies the current 45GS02 memory mapping into a destination
area.
Preconditions: The destination area starts on a page boundary between $0000
and $7E00 and is at least 6 bytes.
Inputs: Y The MSB of the destination area.
Outputs: Starting at $YY00, the current mapping info has this structure.
Offset Type Description
0 word MAPLO
2 word MAPHI
4 byte The megabyte offset for MAPLO
5 byte The megabyte offset for MAPHI
Errors: $10 invalid address The Y register is > $7E.
History: Available since Hyppo 1.2
Remarks: MAPLO is the mapping for $0000 - $7FFF.
MAPHI is the mapping for $8000 - $FFFF.
See Chapter/Appendix J on page J-3 for more information on
MEGA65 memory mapping and banking.

M-45
hyppo_get_proc_desc
Trap: LDA #$48 : STA $D640 : CLV
Service: Copies the current task block into a destination area.
Preconditions: The destination area starts on a page boundary between $0000
and $7E00 and is at least 256 bytes.
Inputs: Y The MSB of the destination area.
Outputs: Starting at $YY00, the current task block has this structure.
Offset Type Description
$00 byte The ID of the current task.
$01 text The name of the current task. A maximum of
16 characters. Padded with $00 bytes. If it’s
16 characters, there are no trailing $00 bytes.
$11 byte Flags for the D81 disk image attached to drive
0 of the virtualised F011 floppy controller.
$12 byte Same as above but for drive 1.
$13 byte The length of the D81 disk image filename at-
tached to drive 0.
$14 byte Same as above but for drive 1.
$15 text The filename of the D81 disk image attached
to drive 0. A maximum of 32 characters.
Padded with $20 bytes. There is no trailing
$00 byte.
$35 text Same as above but for drive 1.
$55 The meaning of these bytes are undefined and
subject to change.
$80 File descriptor 0.
$A0 File descriptor 1.
$C0 File descriptor 2.
$E0 File descriptor 3.

M-46
Each of the file descriptors has this structure.
Offset Type Description
$00 byte The number of the SD card partition where the
file resides. $FF means the file descriptor is
closed.
$01 dword The cluster where the file starts
$05 dword The current cluster
$09 byte The current sector within the current cluster
$0A dword The length of the file
$0E dword The current position within the file’s buffer
$12 dword The cluster of the directory in which the file re-
sides
$16 word The index of the file within its directory
$18 dword The absolute 32-bit address of the file’s buffer
$1C word The number of bytes used in the file’s buffer
$1E word The current offset within the file’s buffer
Errors: $10 invalid address The Y register is > $7E.
History: Available since Hyppo 1.2

M-47
hyppo_gettasklist
Trap: LDA #$50 : STA $D640 : CLV
Service: Gets the list of tasks in Hyppo.
Remarks: NOT IMPLEMENTED

hyppo_load_into_task
Trap: LDA #$64 : STA $D640 : CLV
Service: Loads a file from an SD card partition into the memory of a Hyppo
task.
Remarks: NOT IMPLEMENTED

hyppo_readoutoftask
Trap: LDA #$58 : STA $D640 : CLV
Service: Reads from the memory of another Hyppo task.
Remarks: NOT IMPLEMENTED

hyppo_receivemessage
Trap: LDA #$54 : STA $D640 : CLV
Service: Receives messages sent from other Hyppo tasks.
Remarks: NOT IMPLEMENTED

M-48
hyppo_reset
Trap: LDA #$7E : STA $D640 : CLV
Service: Warm boots the MEGA65.
History: Available since Hyppo 1.2

M-49
hyppo_rom_writeenable
Trap: LDA #$02 : STA $D641 : CLV
Service: Changes $20000 – $3FFFF to behave like RAM by disabling the
write-protection.
History: Available since Hyppo 1.2
Remarks: $20000 – $3FFFF normally has the KERNAL, BASIC, CBDOS, and
font ROMs.
hyppo_rom_writeprotect enables the write-protection and blocks
writes. hyppo_toggle_rom_writeprotect toggles the write-
protection.

M-50
hyppo_rom_writeprotect
Trap: LDA #$00 : STA $D641 : CLV
Service: Changes $20000 – $3FFFF to behave like ROM by enabling the
write-protection.
History: Available since Hyppo 1.2
Remarks: $20000 – $3FFFF normally has the KERNAL, BASIC, CBDOS, and
font ROMs.
hyppo_rom_writeenable disables the write-protection and allows
writes. hyppo_toggle_rom_writeprotect toggles the write-
protection.

M-51
hyppo_sendmessage
Trap: LDA #$52 : STA $D640 : CLV
Service: Sends a message to another Hyppo task.
Remarks: NOT IMPLEMENTED

M-52
hyppo_serial_monitor_wait_and_write
Trap: LDA #$xx : STA $D643 : CLV
Service: Waits for the serial monitor or Matrix Mode Debugger to be ready to
receive and then writes a character to it.
Inputs: A The ASCII character to write.
History: Available since Hyppo 1.2
Remarks: The service waits for the serial monitor to be ready to receive. This
could slow down or hang your program. If you don’t want this and
you are happy for the character to be lost if the serial monitor is not
ready to receive, use hyppo_serial_monitor_write .

M-53
hyppo_serial_monitor_write
Trap: LDA #$7C : STA $D640 : CLV
Service: Writes a character to the serial monitor or the Matrix Mode Debug-
ger.
Preconditions: The serial monitor is ready to receive.
Inputs: Y The ASCII character to write.
History: Available since Hyppo 1.2
Remarks: The character will be lost if the serial monitor is not ready
to receive, If you don’t want the character to be lost, use
hyppo_serial_monitor_wait_and_write .

M-54
hyppo_set_mapping
Trap: LDA #$76 : STA $D640 : CLV
Service: Copies the source area into the current 45GS02 memory mapping.
Preconditions: The source area starts on a page boundary between $0000 and
$7E00 and is at least 6 bytes.
Inputs: Y The MSB of the source area.
Starting at $YY00, the current mapping info has this structure.
Offset Type Description
0 word MAPLO
2 word MAPHI
4 byte The megabyte offset for MAPLO
5 byte The megabyte offset for MAPHI
Postconditions: The CPU continues execution with the new memory mapping.
Errors: $10 invalid address The Y register is > $7E.
History: Available since Hyppo 1.2
Remarks: You must take care when changing the memory mapping. Hyppo
will not take any steps to ensure the instructions after the STA are
executed regardless of the mapping. If you change the mapping of
the block where the program counter points to, the CPU will resume
with the instructions in the newly mapped block.
MAPLO is the mapping for $0000 - $7FFF.
MAPHI is the mapping for $8000 - $FFFF.
See Chapter/Appendix J on page J-3 for more information on
MEGA65 memory mapping and banking.

M-55
hyppo_switch_to_task
Trap: LDA #$6C : STA $D640 : CLV
Service: Switches context to another Hyppo task.
Remarks: NOT IMPLEMENTED

hyppo_terminateothertask
Trap: LDA #$60 : STA $D640 : CLV
Service: Terminates another Hyppo task.
Remarks: NOT IMPLEMENTED

M-56
hyppo_toggle_force_4502
Trap: LDA #$72 : STA $D640 : CLV
Service: Toggles the CPU personality between 45GS02 and 6502.
Outputs: A If bit 5 is set, the CPU is in the 45GS02 personality. If bit 5 is
clear, the CPU is in the 6502 personality.
History: Available since Hyppo 1.2
Remarks: The others bits of the A register are undefined. Do not expect them
to be zero.
In the 6502 personality, none of the new opcodes of the 65C02,
65CE02, 4510 or 45GS02 are available. These are replaced with
the original — and often strange — behaviour of the undefined op-
codes of the 6502.
Warning This feature is incomplete and untested. Most undocu-
mented 6502 opcodes do not operate correctly when the 6502
personality is enabled.
Example: Enables the 45GS02 personality regardless of the CPU’s current
personality.

@10
; Toggle the CPU personality
LDA #$72 : STA $D640 : CLV : BCC error
; Toogle again if bit 5 of A is clear
AND #%00100000 : BEQ @10

M-57
hyppo_toggle_rom_writeprotect
Trap: LDA #$70 : STA $D640 : CLV
Service: Toggles the write-protection for $20000 – $3FFFF.
Outputs: A If bit 2 is set, $20000 – $3FFFF cannot be written to.
History: Available since Hyppo 1.2
Remarks: The others bits of the A register are undefined. Do not expect them
to be zero.
If you simply want to disable or enable the protection, you can use
hyppo_rom_writeenable and hyppo_rom_writeprotect .

M-58
hyppo_writeintotask
Trap: LDA #$56 : STA $D640 : CLV
Service: Writes into the memory of another Hyppo task.
Remarks: NOT IMPLEMENTED

M-59
SYSTEM PARTITION SERVICES
hyppo_configsector_apply
Trap: LDA #$04 : STA $D642 : CLV
Service: Applies the system configuration sector currently loaded into mem-
ory.
History: Available since Hyppo 1.2

hyppo_configsector_read
Trap: LDA #$00 : STA $D642 : CLV
Service: Reads the system configuration sector into memory.
History: Available since Hyppo 1.2

hyppo_configsector_write
Trap: LDA #$02 : STA $D642 : CLV
Service: Writes the system configuration sector from memory.
History: Available since Hyppo 1.2

hyppo_dmagic_autoset
Trap: LDA #$06 : STA $D642 : CLV
Service: Sets the DMAgic revision based on the loaded ROM.
History: Available since Hyppo 1.2

M-60
FREEZER SERVICES
hyppo_freeze_self
Trap: LDA #$xx : STA $D67F : CLV
Service: Launches the freezer.
History: Available since Hyppo 1.2

hyppo_get_slot_count
Trap: LDA #$16 : STA $D642 : CLV
Service: Gets the number of freeze slots.
History: Available since Hyppo 1.2

hyppo_locate_freeze_slot
Trap: LDA #$10 : STA $D642 : CLV
Service: Locates the first sector of a freeze slot.
History: Available since Hyppo 1.2

hyppo_read_freeze_region_list
Trap: LDA #$14 : STA $D642 : CLV
Service: Reads the freeze region list.
History: Available since Hyppo 1.2

hyppo_unfreeze_from_slot
Trap: LDA #$12 : STA $D642 : CLV
Service: Unfreezes from a freeze slot.
History: Available since Hyppo 1.2

M-61
M-62
APPENDIX N
Machine Language Monitor
• Introduction
• The MEGA65 Machine Language Monitor
• The Matrix Mode/Serial Monitor
N-2
INTRODUCTION
A machine language monitor is a program for inspecting and experimenting with
the internal state of a computer’s CPU and memory, useful for debugging machine
language programs and exploring how the computer works. A typical monitor can
view and modify the contents the CPU registers and memory, disassemble machine
code, assemble instructions directly to memory, and manipulate memory in other ways,
among other features.
The MEGA65 has two separate machine language monitors built in: one in the ROM
(the MEGA65 monitor), and one that is part of the Matrix Mode debug interface (the
Matrix Mode/serial monitor). Each monitor has different features and uses.
The monitor in the MEGA65 ROM is similar to one that was included with the original
C65 ROM, more complete and with more features. It is included in both the MEGA65
closed ROM and the enhanced MEGA65 OpenROM. If you are using an original C65
ROM, its monitor works similarly.

THE MEGA65 MACHINE LANGUAGE


MONITOR
The machine language monitor included with the MEGA65 ROM can be invoked in
several ways. From BASIC, you can invoke the monitor with the MONITOR command.
STOP
You can also cause the MEGA65 to boot directly into the monitor by holding the
key during start-up.
The MEGA65 monitor activates automatically when program execution encounters the
BRK instruction (byte value 00). You can cause your program to pause and open the
monitor at a specific point by including a BRK instruction in the program code at that
point.
When the monitor starts, it displays the register contents, then waits for a command:

MONITOR
PC SR AC XR YR ZR BP SP
; 000000 00 00 00 00 00 00 F8

Numbers
The monitor uses hexadecimal (base 16) to display numbers, such as memory ad-
dresses and values. Hexadecimal values are printed without a leading ‘$‘ character,
such as 5A or D020.

N-3
You can enter a value in hexadecimal, decimal (base 10), octal (base 8), or binary
(base 2). Each number format uses a character prefix, as shown in the table below.
If you omit the prefix, the monitor assumes the value is in hexadecimal. (This is unlike
BASIC, which assumes decimal without a prefix.) You can also enter a byte value as a
PETSCII character, with the appropriate prefix.
Hexadecimal is the default number format for assembly instructions as well. This can
be confusing! Consider what happens when you tell the monitor to assemble the
following instruction:
LDA #10
A typical assembler interprets this as loading the decimal value 10 (hex 0A) into the
accumulator. The monitor assumes this is the hexadecimal value $10 (decimal 16). To
avoid confusion, always provide an explicit prefix character for numbers in assembly
instructions. The monitor’s disassembler shows all values as hexadecimal starting with
the $ prefix.
All numbers must be literal values. The monitor does not understand arithmetic expres-
sions.
You can use the monitor to show all the base conversions of a given number or PETSCII
character. To do this, enter the number as if it were a command, using its prefix. The
$ is required for hexadecimal numbers in this case to distinguish it from other monitor
commands.
The following table shows the prefixes for each way a value can be entered:
base name prefix digits characters example
16 hexadecimal 0123456789ABCDEF 100
16 hexadecimal $ 0123456789ABCDEF $100
10 decimal + 0123456789 +256
8 octal & 01234567 &400
2 binary % 01 %100000000
character ' all 'A

The Assembler
The monitor has a builtin mini-assembler that can be used to write machine language
code using the standard mnemonics like LDA or STA.
This is not a full assembler like you might use to write large programs. In particular, it
does not support symbols, such as labels for subroutines or KERNAL addresses. Instead
of JSR CHROUT, you must look up the address of CHROUT and enter the number value:
JSR FFD2
For convenience, you can provide a full address to a branch instruction. The monitor
calculates the relative address offset to assemble the instruction.

N-4
The assembler knows all of the instructions and address modes of the MEGA65 CPU
45GS02. An instruction like LDA [TXTPTR],Z will be assembled as loading the ac-
cumulator using a 32-bit pointer at the addresses TXTPTR, TXTPTR+1, TXTPTR+2,
TXTPTR+3.

Differences from the C65 Monitor


The MEGA65 monitor is similar to the monitor included with the C65. It includes multi-
ple enhancements beyond the C65 monitor, both to make the monitor more generally
useful and to extend it to support features specific to the MEGA65 architecture.
The MEGA65 monitor has the following exclusive features:
Adddresses:
All addresses are used as 32-bit (4 bytes) addresses. This allows access to the
whole MEGA65 address range, which needs 28-bit. This is especially useful for
the access to the 8MB RAM blocks called attic RAM at $8000000 (builtin) and
cellar RAM at $8800000 (optional). Setting bit 31 of an address to 1 gives
access to a special (banked) configuration. In this case the I/O area at $D000
and the ROM area $6000 - $7FFF (monitor ROM) and $E000 - $FFFF (KERNAL
ROM) overlay the current bank.
Commands:
The additional command B displays character bitmaps.
Disk access:
The disk command character knows two more functions: U1 for reading a se-
quence of disk blocks to memory and U2 for writing a memory range to disk
blocks. This enables disk disk editing, for example modifying directory entries
or can be even used to backup whole floppy contents or disk images. The attic
RAM is large enough to hold the contents of 8 complete 1581 floppies.
Disassembler:
The disassembler can decode all additional address modes, like the 32-bit in-
direct mode [$nn], Z and the compound instructions involving the use of the
32-bit Q register.
Register:
The register displays the full 16-bit stack pointer and the base page register
and accepts new settings for ithem.

N-5
Table of MEGA65 Monitor Commands
C mnemonic description
A ASSEMBLE Assemble a line of 45GS02 code
B BITMAPS Display 8x8 bitmaps (characters)
C COMPARE Compare two sections of memory
D DISASSEMBLE Disassemble a line of 45GS02 code
F FILL Fill a section of memory with a value
G GO Start execution at specified address
H HUNT Find specified data in a section of memory
J JUMP Jump to a subroutine at specified address
L LOAD Load a file from disk
M MEMORY Dump a section of memory
R REGISTERS Display the contents of the 45GS02 registers
S SAVE Save a section of memory to a disk file
T TRANSFER Transfer memory to another location
V VERIFY Compare a section of memory with a disk file
X EXIT Exit Monitor mode
. <period> Assembles a line of 45GS02 code
> <greater> Modifies memory
; <semicolon> Modifies register contents
@ <at sign> Disk command, directory or status
$ <hex> Display hex, decimal, octal, and binary value
+ <decimal> Display hex, decimal, octal, and binary value
& <octal> Display hex, decimal, octal, and binary value
% <binary> Display hex, decimal, octal, and binary value

A : ASSEMBLE
Format: A address mnemonic operand
Usage: The mini assembler allows entry of machine language instructions using
easy to remember mnemonics instead of opcodes. The operand may be
entered as hex, decimal, binary or character. Branch targets are auto-
matically converted to relative distances. After each entered instruction,
the mini assembler generates the 1-5 byte long machine code, prints this
code along with the instruction and advances the program counter. A
new line is generated with the command A and the new value of the
program counter printed. This eases the fast entry of instructions. The
assembly input mode is stopped by pressing RETURN only. Any line of the
entered code or a line in disassembly format can be changed by moving
the cursor into that line and changing the desired element, for example
the mnemonic or the operand. Listed hex values before the mnemonic
are ignored.

N-6
If the monitor shall be reentered after executing the code, the last in-
struction must be a BRK instruction and the program must be called with
I/O and monitor ROM active. This is done by setting the bit 31 of the
execution address. If the program was entered in bank 0 on address
1500, it should be started with: G 80001500.
If the entered code is a subroutine, it must end with a RTS instruction.
Remarks: The assembler recognises all 45GS02 instructions of the MEGA65, in-
cluding the instructions that use the Q register. NOP and AUG can be
entered, but will be interpreted as EOM and MAP, respectively.
32-bit Base-Page Indirect instructions use square brackets ([ and ]).

B : BITMAPS
Format: B start
Usage: Displays memory values interpreted as character bitmaps.
Remarks: The B command displays the contents of memory cells bitwise by printing
an asterisk for 1 and a dot for 0. The special arrangement of character

N-7
data with 8 bytes forming one character cell, is considered. 8 characters
are displayed for each call.
There are three ROM character sets builtin in the 92XXXX ROMs:

FONT A : REM $029000 : ASCII [\]^_ {|}~ included


FONT B : REM $03D000 : serif version of A
FONT C : REM $02D000 : original C64 font

C : COMPARE
Format: C start end start-b
Usage: Compares two regions of memory, then lists the addresses whose values
differ.
Remarks: The end address is one beyond the last address to compare.
The second memory region to compare starts at start-b and is the same
size as the region described by start and end.
Addresses are printed as hex values.

N-8
D : DISASSEMBLE
Format: D [from [to]]
Usage: Prints a machine language listing for the specified address range as-
suming, that it contains code. If only one argument is present, the dis-
assembler disassembles the next 21 bytes. If no argument is given, the
disassembly continues with the last used disassemble address. The con-
tents are printed as hex values.
Remarks: The rows start with the dot character ’.’. This enables direct full screen
editing of the disassembly. Typing return in any row will assemble the
changed command of the cursor row back to memory, if writable RAM is
there. See monitor command ..
The disassembler knows the instruction set of the MEGA65 CPU, the
45GS02. When an instruction is prefixed by NEG NEG, those hex values
are elided and instead an asterisk (*) is displayed between the address
and the hex values.
Example: Using D

F : FILL
Format: F start end value

N-9
Usage: Fills a region of memory with a value.
Remarks: The end address is one beyond the last address to fill.

G : GO
Format: G [addr]
Usage: Executes code at an address. If addr is omitted, the current program
counter is used as the address.
Remarks: This is equivalent to a JMP instruction.
The G command without an argument is a convenient way to resume
execution of a program after starting the monitor with a BRK instruction.
Because this uses a JMP, it must not be used to call subroutines. See J.

H : HUNT
Format: H start end byte [byte...]
Usage: Searches for every occurrence of a byte sequence in a range of memory,
then lists the starting address of each occurrence.
Remarks: The end address is one beyond the last address to search.
Addresses are printed as hex values.

J : JUMP
Format: J addr
Usage: Jumps to a subroutine at an address.
Remarks: This is equivalent to a JSR instruction. When the subroutine returns with
RTS, the monitor resumes.
To simply continue execution at an address without expecting to return
to the monitor, use G.

L : LOAD
Format: L ”filename”,unit [start]
Usage: Loads data from a file into memory.

N-10
Remarks: The filename must be surrounded by double-quotes.
The unit number (such as 8 or 9) is required. Unit is specified using the
monitor’s normal number system (defaulting to hex). See Numbers.
If the start address is omitted, the starting address is taken from the first
two bytes of the file. The file must be of type PRG. If start is provided,
the two byte PRG header is ignored.

M : MEMORY
Format: M [from [,to]]
Usage: Prints a memory dump for the given address range. The dump displays
memory contents, organised in rows of 16 consecutive addresses starting
with the address, given as 1st. argument. The dump continues until a
row has been printed, containing the value of the address given as 2nd.
argument. If no 2nd. argument is present, the dump displays a full page
of 256 bytes in 16 rows. The contents are printed as 16 byte values in
hex, followed by the character representation.
Remarks: The rows start with the character ’>’. This enables direct full screen edit-
ing of the dump. Typing return in any row will write the changed values
of the cursor row back to memory, if writable RAM is there. See monitor
command >.
Example: Using M

N-11
R : REGISTERS
Format: R
Usage: Displays the contents of the registers from just before the monitor was
started.
Remarks: The output begins with a ; character so that you can change the register
values by moving the cursor up to the line, changing the values, then
Return
pressing .

S : SAVE
Format: S ”filename”,unit start end
Usage: Saves a region of memory to a file on disk, of type PRG.
Remarks: The filename must be surrounded by double-quotes.
The unit number (such as 8 or 9) is required. Unit is specified using the
monitor’s normal number system (defaulting to hex). See Numbers.
The end address is one beyond the last address to save.
To overwrite an existing file, put 0: before the filename, such as:
"0:MYFILE"

T : TRANSFER
Format: T start end destination-start
Usage: Transfers (copies) a region of memory to another region.
Remarks: The end address is one beyond the last address to copy.
The destination region is assumed to be the same length as the source
region. All bytes are copied.

V : VERIFY
Format: V ”filename”,unit start
Usage: Verifies that a region of memory matches a file on disk.
Remarks: The filename must be surrounded by double-quotes.
The unit number (such as 8 or 9) is required. Unit is specified using the
monitor’s normal number system (defaulting to hex). See Numbers.

N-12
The length of the data to verify is assumed to be the length of the file.
If the data in memory does not match, an error will be shown. Otherwise,
nothing more is shown, and success should be assumed.

X : EXIT
Format: X
Usage: Exits the monitor to BASIC.
Remarks: If the monitor was started by a BRK instruction in a program, exiting the
monitor effectively aborts the program. To continue a paused program,
use G instead.

. : ASSEMBLE
Format: . address opcode operand
Usage: An alias for A.
Remarks: The output of the disassembler starts each line with a . character. You
can edit the assembly instructions printed by the disassembler by moving
Return
the cursor up to a line, editing it, and pressing . This changes the .
to a A so you can see which lines have been reassembled.

> : MODIFY MEMORY


Format: > addr byte [byte...]
Usage: Modifies one or more bytes starting at an address.
Remarks: The output of the M command starts each line with a > character. You
can edit the memory values printed by the M command by moving the
Return
cursor up to a line, editing it, and pressing .

; : MODIFY REGISTERS
Format: ; pc sr ac xr yr zr bp sp nvebdizc
Usage: Modifies the CPU registers. Arguments are in the format output by the R
command.

N-13
Remarks: The output of the R command starts the line with a ; character. You can
edit the memory values printed by the R command by moving the cursor
Return
up to the line, editing it, and pressing .

@ : DISK COMMAND
Format: @ [unit] [,command]
Usage: Perform a disk command.
Remarks: Without a command, this displays the drive status.
The default unit is 8. Unit is specified using the monitor’s normal number
system (defaulting to hex). See Numbers.
A command of $[pattern] will request a directory listing from the spec-
ified unit and display it. An optional pattern may be given to limit the
files listed. The wildcard characters * and ? may be used
The command can be any Commodore DOS command. For example, to
rename a file: @R0:NEWNAME=OLDNAME
The command can be U1 to load raw disk sectors to memory, or U2 to
save memory to raw disk sectors. These commands take this form:
@8,U1 mem-start track sector [sector-count]
Tracks are numbered 1-80, and sectors are numbered 0-39. If sector-
count is omitted, only one sector is read from or written to.

THE MATRIX MODE/SERIAL MONITOR


The Matrix Mode monitor can do something that the MEGA65 monitor cannot: instead
of pausing a program to run the monitor, the Matrix Mode monitor runs concurrently
with the active program. That is, you can view and modify the memory the MEGA65,
while a program is running.
This works using dedicated hardware in the MEGA65 design that implements a little
helper processor that runs this monitor interface. This hardware has a special access
mechanism to the memory and CPU of the MEGA65.
In comparison with the ROM-based monitors that execute on the MEGA65’s primary
processor, the Matrix Mode monitor has several advantages and disadvantages:
• It can be used while a program is running.
• It can be used, even if the ROM area is being used for program code or data,
instead of containing a standard C65 or MEGA65 ROM.

N-14
• It can be accessed via the serial debug interface, via the JB1 connector.
• It can be instructed to stop the processor as soon as the program counter (PC)
register of the main processor reaches a user specified address. That is, it sup-
ports a (single) hardware breakpoint.
• It can be instructed to stop the processor whenever a specified memory address
is written to. That is, it suppors a “write watch” on a single memory address.
The memory address is specified as a full 28-bit address, allowing it to detect
memory writes via any means. Note that DMA operations will complete, before
the watch point takes effect.
• It can be instructed to stop the processor whenever specific CPU flags are set
or cleared, which can also be used to support debugging of programs.
• On some models of the MEGA65, the integrated ROM of the monitor processor is
very small, which means that functionality may be limited. This is why, for exam-
ple, there is no “assemble” command for this monitor. This may be corrected in
future core updates for MEGA65 models that have capacity for a larger monitor
processor ROM.

Table of Matrix Mode Monitor Com-


mands
C mnemonic description
# HYPERTRAP Enable/disable CPU hypervisor traps
+ UARTDIVISOR Set UART bitrate divisor
? HELP help
@ CPUMEM (show memory from CPU context)
B BREAKPOINT Set/clear CPU execution break point
D DISASSEMBLE Disassemble memory
E FLAGWATCH Set/clear CPU flags watch point
F FILL Fill memory with a value
G SETPC Set CPU program counter
H HELP help
I INTERRUPTS Enable/disable CPU interrupts
J DEBUGMON Various debug functions for the monitor itself
L LOADMEMORY Load data into memory
M MEMORY Show memory contents
R REGISTERS show registers
S SETMEMORY Set memory contents
T TRACE set CPU trace/run mode
W MEMORYWATCH Set/clear memory write watch point
Z CPUHISTORY CPU history

N-15
Calling the Monitor
TAB
To enter or exit the monitor hold down ` and press . You will see an animation
of green characters raining down from the top of the screen, and then be presented
with a simple text terminal interface which is transparent, so that you can see the
screen output of your running program at the same time.

# : Hypervisor trap enable/disable


Format: # Enable or disable Hypervisor Traps
Usage: #[0|1]
Remarks: If the argument is 1, then Hypervisor traps are enabled, otherwise they
are disabled.
It is not confirmed if this command is currently functional.

+ : Set Serial Interface UART Divisor


Format: + Set Serial Interface UART Divisor
Usage: + divisor
Remarks: Sets the divisor for the serial monitor interface. This allows changing the
baud rate of the serial monitor interface from the default 2,000,000 bits
per second. The baud rate will be equal to 40, 500, 000 ÷ (divisor − 1).
This affects only the serial UART interface, and does not affect accessing
this monitor via the Matrix Mode composited display.
For example, to slow the serial monitor interface down to 19,200 bits per
second, the divisor would need to be 40, 500, 000 ÷ (19, 200 − 1) = 2108.
The + command then requires that you convert this value to hexadecimal,
thus the command would be +83c.
Note that this command does no sanity checking of the provided value.
If you accidentally provide an incorrect value for your needs, you can
recover from this situation by activating the Matrix Mode interface by
TAB
holding down ` and tapping , and entering the appropriate
command to correct the divisor, e.g., +14 to return to the default of
2,000,000 bits per second.
TAB
You must then exit the Matrix Mode again by repeating the ` +
key combination, before the serial UART interface will become active
again. This is because the Matrix Mode disables the serial UART interface
when active.

N-16
@ : CPUMEMORY
Format: @ [address]
Usage: Prints a memory dump for the given 16-bit address, as interpretted by
the current CPU memory mapping. If you wish to inspect the contents
of memory anywhere in the 28-bit address space, use the M command
instead.
The dump displays memory contents, organised in rows of 16 consecutive
addresses starting with the address. The dump displays a full page of
256 bytes in 16 rows. The contents are printed as 16 byte values in hex,
followed by the character representation.
Remarks: If no address is provided, it will show the next 256 bytes.

? or H : HELP
Format: ? or h
Usage: Displays a (very) brief message identifying the monitor. On some models
of the MEGA65 that have more memory available to the monitor proces-
sor, this command may display information about each of the available
commands.

B : BREAKPOINT
Format: b [address]
Usage: Sets or clears the hardware breakpoint. If no address is provided, then
the breakpoint will be disabled. Otherwise the breakpoint is set to the
provided 16-bit address.
Whenever the program counter (PC) register of the MEGA65’s processor
equals the value provided to this command, the processor will halt, and
the Matrix Mode monitor interface will display the last instruction exe-
cuted and current register values to alert the user to this event. It does
not activate the Matrix Mode display when this occurs. It is normally ex-
pected that Matrix Mode will either already be active, or that the user is
interacting via the serial interface.

D : DISASSEMBLE
Format: <d|D> [address]

N-17
Usage: Disassembles and displays the instruction stored at the indicated 28-bit
address.
To disassemble instructions from the CPU’s current memory context, tak-
ing into account current memory banking, prefix the address with 777,
e.g., d777080D would disassemble the instruction at $080D, as currently
visible to the MEGA65’s processor.
Use D instead of d to disassemble 16 instructions at a time, instead of
just one.

E : FLAGWATCH
Format: e [value]
Usage: Sets or clears the CPU flag watch point: If no argument is provided, the
flag watch point is disabled. If a value is provided, it is assumed to be
a 16-bit value, where the first two hexadecimal digits indicate the pro-
cessor flags that will trigger the watch point if they are set. The second
two hexadecimal digits indicate which processor flags will trigger the
watch point if they are clear. In this way any combination of processor
flag values can be monitored.
This command does not function correctly at the time of writing.
Example: To cause the watch point to trigger when the Negative Flag is asserted,
the command e8000 would be used.

F : FILL
Format: f [start] [end+1] [value]
Usage: Fills the indicated 28-bit address range with the indicated value.
Remarks: The end address should be one more than the last address that is desired
to be filled.

G : SETPC
Format: g address
Usage: Sets the Program Counter (PC) register of the MEGA65’s processor to the
supplied 16-bit address. If the processor is running at the time, execution
will immediately proceed from that address. If the processor is halted at
the time, e.g., due to the use of the t1 command, the processor remains
halted, but with the Program Counter set to the indicated address, ready
for when the processor is again allowed to run.

N-18
I : INTERRUPTS
Format: i[0|1]
Usage: Enables or disables interrupts on the MEGA65’s processor. Disabling
interrupts can be helpful when single-stepping through a program, as
otherwise you will tend to end up only stepping through the interrupt
handler code, because the interrupts will happen more frequently than
the steps through the code.
Remarks: This command is known to have problems, and may not currently function.

J : DEBUGMON
Format: j [value]
Usage: Display, and optionally set, internal signals of the matrix mode monitor
interface.

L : LOADMEMORY
Format: l <start addr> <end addr + 1>
Usage: Fast-load a block of memory via the serial monitor interface. Immediately
after sending this command, the bytes of memory to be loaded should
be sent to the serial monitor interface. The bytes are read as-is, and thus
should be provided as natural bytes, not encoded in hexadecimal. This
allows loading data at approximately 200KB per second at the default
serial baud rate of 2,000,000 bits per second.

M : MEMORY
Format: <m|M> [address]
Usage: Prints a memory dump for the given 28-bit address. If you wish to inspect
the contents of memory as currently seen by the processor’s current bank-
ing configuration, use the @ command instead.
The dump displays memory contents, organised in rows of 16 consecutive
addresses starting with the address. The dump displays a full page of
256 bytes in 16 rows. The contents are printed as 16 byte values in hex,
followed by the character representation.
To view memory from the CPU’s current memory context, taking into
account current memory banking, prefix the address with 777, e.g.,

N-19
m777080D would view memory at $080D, as currently visible to the
MEGA65’s processor.
Remarks: If not address is provided, it will show the next 256 bytes.

R : REGISTERS
Format: r
Usage: Displays the current value of various processor registers and flags, as well
as a disassembly of the most recently executed instruction.

S : SETMEMORY
Format: s addr <value ...>
Usage: Sets the contents of the indicated memory location to the supplied value.
If more than one space-separated value is provided, then multiple con-
secutive memory locations will be set.
This command uses 28-bit addresses, and therefore ignores the current
selected memory banking configuration.

T : TRACE
Format: t<0|1|c>
Usage: Selects the trace or run mode of the processor: t0 means that the pro-
cessor runs freely, t1 halts the processor, and tc runs the processor in
continuous-trace mode, where it displays each instruction and the reg-
ister values immediately following its execution, as though t1 had been
selected, and the user were to then immediately press return or enter to
request the next instruction to be executed.
If t1 is selected, pressing enter or return in the Matrix Mode monitor will
cause the next instruction to be executed.
The t0 command is also used following the triggering of a break-point
or watch-point, to allow the processor to resume.

W : WATCHPOINT
Format: w [address]

N-20
Usage: Sets or clears the hardware watch-point. If no address is provided, then
the watch-point will be disabled. Otherwise the watch-point is set to the
provided 28-bit address.
Whenever the MEGA65’s processor writes to the address provided to this
command, the processor will halt, and the Matrix Mode monitor interface
will display the last instruction executed and current register values to
alert the user to this event. It does not activate the Matrix Mode display
when this occurs. It is normally expected that Matrix Mode will either
already be active, or that the user is interacting via the serial interface.

Z : CPUHISTORY
Format: z [address]
Usage: Displays information about the instructions recently executed by the
MEGA65’s processor.
Remarks: This command is suspected to not be correctly operational at the time of
writing.

N-21
N-22
APPENDIX O
F018-Compatible Direct
Memory Access (DMA)
Controller
• F018A/B DMA Jobs
• MEGA65 Enhanced DMA Jobs
• Texture Scaling and Line Drawing
• Inline DMA Lists
• Audio DMA
• F018 “DMAgic” DMA Controller
• MEGA65 DMA Controller Extensions
• Unimplemented Functionality
O-2
The MEGA65 includes an F018/F018A backward-compatible DMA controller. Unlike
in the C65, where the DMA controller exists as a separate chip, it is part of the 45GS02
processor in the MEGA65. However, as the use of the DMA controller is a logically
separate topic, it is documented separately in this appendix.
The MEGA65’s DMA controller provides several important improvements over the
F018/F018A DMAgic chips of the C65:
• Speed The MEGA65 performs DMA operations at 40MHz, allowing filling 40MB
or copying 20MB per second. For example, it is possible to copy a complete 8KB
C64-style bitmap display in about 200 micro-seconds, equivalent to less than
four raster lines!
• Large Memory Access The MEGA65’s DMA controller allows access to all
256MB of address space.
• Texture Copying Support The MEGA65’s DMA controller can do fractional ad-
dress calculations to support hardware texture scaling, as well as address strid-
ing, to make it possible in principle to simultaneously scale-and-draw a texture
from memory to the screen. This would be useful, should anyone be crazy enough
to try to implement a Wolfenstein or Doom style-game on the MEGA65.
• Transparency/Mask Value Support The MEGA65’s DMA controller can be told
to ignore a special value when copying memory, leaving the destination memory
contents unchanged. This allows masking of transparent regions when perform-
ing a DMA copy, which considerably simplifies blitting of graphics shapes.
• Per-Job Option List A number of options can be configured for each job in a
chained list of DMA jobs, for example, selecting F018 or F018B mode, changing
the transparency value, fractional address stepping or the source or destination
memory region.
• Background Audio DMA The MEGA65 includes background audio DMA capa-
bilities similar to the Amiga™ series of computers. Key differences are that the
MEGA65 can use either 8 or 16-bit samples, supports very high sample rates
up to approximately 1 MHz, has 256 volume settings per channel, and no inter-
channel modulation.

F018A/B DMA JOBS


To execute a DMA job using the F018 series of DMA controllers, you must construct
the list of DMA jobs in memory, and then write the address of this list into the DMA ad-
dress registers. The DMA job will execute when you write to the ADDRLSBTRIG register
($D700). For this reason you must write the MSB and bank number of the DMA list int0
$D701 and $D702 first, and the LSB only after having set these other two registers. If
you wish to execute multiple DMA jobs using the same list structure in memory, you can
simply write to ADDRLSBTRIG again after updating the list contents – provided that no
other program has modified the contents of $D701 or $D702. Note that BASIC 65

O-3
uses the DMA controller to scroll the screen, so it is usually safest to always write to all
three registers.
When ADDRLSBTRIG has been written to, the DMA job completes immediately. Unlike
on the C65, the DMA controller is part of the processor of the MEGA65. This means
that the processor stops trying to execute instructions until the DMA job has completed.
The only exception to this, is that Audio DMA continues, and will steal cycles from any
other DMA activity, to ensure that audio playback is not affected.
This behaviour means that unlike on the C65, DMA jobs cannot be interrupted. If your
program has sensitive timing requirements, you may need to break larger DMA jobs into
several smaller jobs. This is somewhat mitigated by the high speed of the MEGA65’s
DMA, which is able to fill memory at 40.5MB per second and copy memory at 20.25MB
per second, compared with circa 3.5MB and 1.7MB per second on a C65. This allows
larger DMA jobs to be executed, without needing to worry about the impact on real-
time elements of a program. For example, it is possible to fill an 80 column 50 row
text screen using the MEGA65’s DMA controller in just 200 microseconds.

F018 DMA Job List Format


The MEGA65’s DMA controller supports the two different DMA job list formats used by
the original F018 part that was used in the earlier C65 prototypes (upto Revision 2B)
and the F018B and later revisions used in the Revision 3 – 5 C65 prototypes. The main
difference is the addition of a second command byte, as the following tables show:
It is important to know which style the DMA controller is expecting. The MEGA65’s
Hypervisor sets the mode based on the detected version of C65 ROM, if one is running.
If it is an older one, then the F018 style is expected, otherwise the newer F018B style
is expected. You can check which style has been selected by querying bit 0 of $D703:
If it is a 1, then the newer F018B 12 byte list format is expected. If it is a 0, then the
older F018 11 byte list format is expected. The expected style can be set by writing
to this register.
Unless you are writing software that must also run on a C65 prototype, you should
most probably use the MEGA65’s Enhanced DMA Jobs, where the list format is ex-
plicitly specified in the list itself. As the Enhanced DMA Jobs are an extension of the
F018/F018B DMA jobs, you should still read the following, unless you are already
familiar with the behaviour of the F018 DMA controller.

O-4
F018 11 byte DMA List Structure
Offset Contents
$00 Command LSB
$01 Count LSB
$02 Count MSB
$03 Source Address LSB
$04 Source Address MSB
$05 Source Address BANK and FLAGS
$06 Destination Address LSB
$07 Destination Address MSB
$08 Destination Address BANK and FLAGS
$09 Modulo LSB
$0a Modulo MSB
* The Command MSB is $00 when using this list format.

F018B 12 byte DMA List Structure


Offset Contents
$00 Command LSB
$01 Count LSB
$02 Count MSB
$03 Source Address LSB
$04 Source Address MSB
$05 Source Address BANK and FLAGS
$06 Destination Address LSB
$07 Destination Address MSB
$08 Destination Address BANK and FLAGS
$09 Command MSB
$0a Modulo LSB / Mode
$0b Modulo MSB / Mode
The structure of the command word is as follows:
Bit(s) Contents
0–1 DMA Operation Type
2 Chain (i.e., another DMA list follows)
3 Yield to interrupts
4 MINTERM -SA,-DA bit
5 MINTERM -SA,DA bit
6 MINTERM SA,-DA bit
7 MINTERM SA,DA bit
8–9 Addressing mode of source
10 – 11 Addressing mode of destination
12 – 15 RESESRVED. Always set to 0’s

O-5
The command field take the following four values:
Value Contents
%00 (0) Copy
%01 (1) Mix (via MINTERMs)
%10 (2) Swap
%11 (3) Fill
* Only Copy and Fill are implemented at the time of writing.
The addressing mode fields take the following four values:
Value Contents
%00 (0) Linear (normal) addressing
%01 (1) Modulo (rectangular) addressing
%10 (2) Hold (constant address)
%11 (3) XY MOD (bitmap rectangular) addressing
* Only Linear, Modulo and Hold are implemented at the time of
writing.
The BANK and FLAGS field for the source address allow selection of addresses within
a 1MB address space. To access memory beyond the first 1MB, it is necessary to use
an Enhanced DMA Job with the appropriate option bytes to select the source and/or
destination MB of memory. The BANK and FLAGS field has the following structure:
Bit(s) Contents
0–3 Memory BANK within the selected MB
4 HOLD, i.e., do not change the address
5 MODULO, i.e., apply the MODULO field to wrap-
around within a limited memory space
6 DIRECTION. If set, then the address is decremented
instead of incremented.
7 I/O. If set, then I/O registers are visible during the
DMA controller at $D000 – $DFFF.

Performing Simple DMA Operations


For information on using the DMA controller from BASIC 65, refer to the DMA BASIC
command in Chapter/Appendix B on page B-79.
To use the DMA controller from assembly language, set up a data structure with the
DMA list, and then set $D702 – $D700 to the address of the list. For example, to clear
the screen in C65-mode by filling it with spaces, the following routine could be used:

O-6
LDA # $00 ; DMA list exists in BANK 0
STA $D702
LDA # > d mal ist ; Set MSB of DMA list a d d r e s s
STA $D701
LDA # < d mal ist ; Set LSB of DMA list address , and e x e c u t e DMA
STA $D700
RTS

dmalist :
. byte $03 ; Com man d low byte : FILL
. word 2000 ; Count : 80 x25 = 2000 bytes
. word $0020 ; Fill with value $20
. byte $00 ; Source bank ( i g n o r e d with FILL o p e r a t i o n )
. word $0800 ; D e s t i n a t i o n a d d r e s s where screen lives
. byte $00 ; Screen is in bank 0
. byte $00 ; Com man d high byte
. word $0000 ; Modulo ( i g n o r e d due to s e l e c t e d c o m m m a n d )

It is also possible to execute more than one DMA job at the same time, by setting the
CHAIN bit in the low byte of the command word. For example to clear the screen as
above, and also clear the colour RAM for the screen, you could use something like:

O-7
LDA # $00 ; DMA list exists in BANK 0
STA $D702
LDA # > d mal ist ; Set MSB of DMA list a d d r e s s
STA $D701
LDA # < d mal ist ; Set LSB of DMA list address , and e x e c u t e DMA
STA $D700
RTS

dmalist :
. byte $07 ; Com man d low byte : FILL + CHAIN
. word 2000 ; Count : 80 x25 = 2000 bytes
. word $0020 ; Fill with value $20
. byte $00 ; Source bank ( i g n o r e d with FILL o p e r a t i o n )
. word $0800 ; D e s t i n a t i o n a d d r e s s where screen lives
. byte $00 ; Screen is in bank 0
. byte $00 ; Com man d high byte
. word $0000 ; Modulo ( i g n o r e d due to s e l e c t e d c o m m m a n d )

; Second DMA job i m m e d i a t e l y f o l l o w s the first


. byte $03 ; Com man d low byte : FILL
. word 2000 ; Count : 80 x25 = 2000 bytes
. word $0001 ; Fill with value $01 = white
. byte $00 ; Source bank ( i g n o r e d with FILL o p e r a t i o n )
. word $F800 ; D e s t i n a t i o n a d d r e s s where colour RAM lives
. byte $01 ; colour RAM is in bank 1 ( $1F800 - $1FFFF )
. byte $00 ; Com man d high byte
. word $0000 ; Modulo ( i g n o r e d due to s e l e c t e d c o m m m a n d )

Copying memory is very similar to filling memory, except that the command low byte
must be modified, and the source address field must be correctly initialised. For ex-
ample, to copy the character set from where it lives in the ROM at $2D000 – $2DFFF
to $5000, you could use something like:

O-8
LDA # $00 ; DMA list exists in BANK 0
STA $D702
LDA # > d mal ist ; Set MSB of DMA list a d d r e s s
STA $D701
LDA # < d mal ist ; Set LSB of DMA list address , and e x e c u t e DMA
STA $D700
RTS

dmalist :
. byte $00 ; Com man d low byte : COPY
. word $1000 ; Count : 4 KB = 4096
. word $D000 ; Copy from $xD000
. byte $02 ; Source bank = $02 for $2xxxx
. word $5000 ; D e s t i n a t i o n a d d r e s s where screen lives
. byte $00 ; Screen is in bank 0
. byte $00 ; Com man d high byte
. word $0000 ; Modulo ( i g n o r e d due to s e l e c t e d c o m m m a n d )

It is also possible to perform a DMA operation from BASIC 2 in C64 mode by POKEing
the necessary values, after first making sure that MEGA65 or C65 I/O mode has been
selected by writing the appropriate values to $D02F (53295). For example, to clear
the screen in C64 BASIC 2 using the DMA controller, you could use something like:

10 rem enable mega65 I/O


20 poke53295,asc("g"):poke53295,asc("s")
30 rem dma list in data statements
40 data 3: rem command lsb = fill
50 data 232,3 : rem screen is 1000 bytes = 3*256+232
60 data 32,0: rem fill with space = 32
70 data 0: rem source bank (unused for fill)
80 data 0,4: rem screen address = 1024 = 4*256
90 data 0: rem screen lives in bank 0
100 data 0: rem command high byte
110 data 0,0: rem modulo (unused in this job)
120 rem put dma list at $c000 = 49152
130 fori=0to11:reada:poke49152+i,a:next
140 rem execute job
150 poke55042,0: rem dma list is in bank 0
160 poke55041,192: rem dma list is in $c0xx
170 poke55040,0: rem dma list is in $xx00, and execute

While this is rather cumbersome to do each time, if you wanted to clear the screen
again, all you would need to do would be to POKE 55040,0 again, assuming that the
DMA list and DMA controller registers had not been modified since the previous time
the DMA job had been run.

O-9
The HOLD, I/O and other options can also be used to create interesting effects. For
example, to write a new value to the screen background colour very quickly, you could
copy a region of memory to $D021, with the I/O flag set to make the I/O register
visible for writing in the DMA job, and the HOLD flag set, so that the same address gets
written to repeatedly. This will write to the background colour at a rate of 20.5MHz,
which is almost as fast as the video pixel clock (27MHz). Thus we can change the
colour almost every pixel.
With a little care, we can make this routine such that it takes exactly one raster-line to
run, and thus draw vertical raster bars, or to create a kind of frankenstein video mode
that uses a linear memory layout – at the cost of consuming all of the processor’s time
during the active part of the display.
The following example does this to draw vertical raster bars on the screen. This pro-
gram assumes that the MEGA65 is set to PAL. For NTSC, the size of the DMA transfer
would need to be decreased a little. The other thing to note with this program, is that
it uses MEGA65 Enhanced DMA Job option $81 to set the destination megabyte in
memory to $FFxxxxx, and the bank is set to $D, and the destination address to $0021,
to form the complete address $FFD0021. This is the true location of the VIC-IV’s
border colour register. The program is written using ACME-compatible syntax.

O-10
basicheader :
^^ I ;; 2020 SYS 2061
^^ I ! word $80a ,2020
^^ I ! byte $9e , $32 , $30 , $36 , $31 ,0 ,0 ,0

^^ I ;; Actual code b e g i n i n g at $080d = 2061


main :
^^ Isei
^^ Ilda # $47 ^^ I ; enable MEGA65 I / O
^^ Ista $D02f
^^ Ilda # $53
^^ Ista $d02f
^^ Ilda #65 ^^ I ^^ I ; Set CPU speed to fast
^^ Ista 0
^^ Ilda #0 ^^ I ; d i s a b l e screen to show only the border
^^ Ista $d011

^^ Ilda $d012 ^^ I ; Wait until start of the next raster


r a s t e r _ s y n c :^^ I ^^ I ^^ I ; before b e g i n n i n g loop for h o r i z o n t a l a l i g n m e n t
^^ Icmp $d012
^^ Ibeq r a s t e r _ s y n c

^^ I ;; The f o l l o w i n g loop takes e x a c t l y one raster line at 40.5 MHz in PAL


loop :
^^ Ijsr t r i g g e r d m a
^^ Ijmp loop

triggerdma :
^^ Ilda #0^^ I ^^ I ^^ I ; make sure F018 list format
^^ Ista $d703

^^ Ilda #0 ^^ I ^^ I ; dma list bank


^^ Ista $d702
^^ Ilda #> rasterdmalist
^^ Ista $d701
^^ Ilda #< rasterdmalist
^^ Ista $d705
^^ Irts

O-11
rasterdmalist :
^^ I ! byte $81 , $ff , $00
^^ I ! byte $00 ^^ I ^^ I ; COPY
^^ I ! word 619 ^^ I ^^ I ; DMA t r a n s f e r is 619 bytes long
^^ I ! word r a s t e r c o l o u r s ^^ I ; source a d d r e s s
^^ I ! byte $00 ; source bank
^^ I ! word $0020 ^^ I ^^ I ; d e s t i n a t i o n a d d r e s s
^^ I ! byte $1d ; d e s t i n a t i o n bank + HOLD
^^ I ;; unused modulo field
^^ I ! word $0000

rastercolours :
^^ I ! byte 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,11 ,11 ,11 ,12 ,12 ,12 ,15 ,15 ,15 ,1 ,1 ,1 ,15 ,15 ,15 ,12 ,12 ,12 ,11 ,11 ,11 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,6 ,6 ,6 ,4 ,4 ,4 ,14 ,14 ,14 ,3 ,3 ,3 ,1 ,1 ,1 ,3 ,3 ,3 ,14 ,14 ,14 ,4 ,4 ,4 ,6 ,6 ,6 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,11 ,11 ,11 ,12 ,12 ,12 ,15 ,15 ,15 ,1 ,1 ,1 ,15 ,15 ,15 ,12 ,12 ,12 ,11 ,11 ,11 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,6 ,6 ,6 ,4 ,4 ,4 ,14 ,14 ,14 ,3 ,3 ,3 ,1 ,1 ,1 ,3 ,3 ,3 ,14 ,14 ,14 ,4 ,4 ,4 ,6 ,6 ,6 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,11 ,11 ,11 ,12 ,12 ,12 ,15 ,15 ,15 ,1 ,1 ,1 ,15 ,15 ,15 ,12 ,12 ,12 ,11 ,11 ,11 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,6 ,6 ,6 ,4 ,4 ,4 ,14 ,14 ,14 ,3 ,3 ,3 ,1 ,1 ,1 ,3 ,3 ,3 ,14 ,14 ,14 ,4 ,4 ,4 ,6 ,6 ,6 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,11 ,11 ,11 ,12 ,12 ,12 ,15 ,15 ,15 ,1 ,1 ,1 ,15 ,15 ,15 ,12 ,12 ,12 ,11 ,11 ,11 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,6 ,6 ,6 ,4 ,4 ,4 ,14 ,14 ,14 ,3 ,3 ,3 ,1 ,1 ,1 ,3 ,3 ,3 ,14 ,14 ,14 ,4 ,4 ,4 ,6 ,6 ,6 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,11 ,11 ,11 ,12 ,12 ,12 ,15 ,15 ,15 ,1 ,1 ,1 ,15 ,15 ,15 ,12 ,12 ,12 ,11 ,11 ,11 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,6 ,6 ,6 ,4 ,4 ,4 ,14 ,14 ,14 ,3 ,3 ,3 ,1 ,1 ,1 ,3 ,3 ,3 ,14 ,14 ,14 ,4 ,4 ,4 ,6 ,6 ,6 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,11 ,11 ,11 ,12 ,12 ,12 ,15 ,15 ,15 ,1 ,1 ,1 ,15 ,15 ,15 ,12 ,12 ,12 ,11 ,11 ,11 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,6 ,6 ,6 ,4 ,4 ,4 ,14 ,14 ,14 ,3 ,3 ,3 ,1 ,1 ,1 ,3 ,3 ,3 ,14 ,14 ,14 ,4 ,4 ,4 ,6 ,6 ,6 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,11 ,11 ,11 ,12 ,12 ,12 ,15 ,15 ,15 ,1 ,1 ,1 ,15 ,15 ,15 ,12 ,12 ,12 ,11 ,11 ,11 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,6 ,6 ,6 ,4 ,4 ,4 ,14 ,14 ,14 ,3 ,3 ,3 ,1 ,1 ,1 ,3 ,3 ,3 ,14 ,14 ,14 ,4 ,4 ,4 ,6 ,6 ,6 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,11 ,11 ,11 ,12 ,12 ,12 ,15 ,15 ,15 ,1 ,1 ,1 ,15 ,15 ,15 ,12 ,12 ,12 ,11 ,11 ,11 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,6 ,6 ,6 ,4 ,4 ,4 ,14 ,14 ,14 ,3 ,3 ,3 ,1 ,1 ,1 ,3 ,3 ,3 ,14 ,14 ,14 ,4 ,4 ,4 ,6 ,6 ,6 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,11 ,11 ,11 ,12 ,12 ,12 ,15 ,15 ,15 ,1 ,1 ,1 ,15 ,15 ,15 ,12 ,12 ,12 ,11 ,11 ,11 ,0 ,0 ,0
^^ I ! byte 0 ,0 ,0 ,6 ,6 ,6 ,4 ,4 ,4 ,14 ,14 ,14 ,3 ,3 ,3 ,1 ,1 ,1 ,3 ,3 ,3 ,14 ,14 ,14 ,4 ,4 ,4 ,6 ,6 ,6 ,0 ,0 ,0

MEGA65 ENHANCED DMA JOBS


The MEGA65’s implementation of the DMAgic supports significantly enhanced DMA
jobs. An enhanced DMA job is indicated by writing the low byte of the DMA list address
to $D705 instead of to $D700. The MEGA65 will then look for one or more job option
tokens at the start of the DMA list. Those tokens will be interpretted, before executing
the DMA job which immediately follows the end of job options token ($00).
Job option tokens that take an argument have the most-significant bit set, and al-
ways take a 1 byte option. Job option tokens that take no argument have the most-
significant-bit clear. Unsupported job option tokens are simply ignored. This allows for

O-12
future revisions of the DMAgic to add support for additional options, without breaking
backward compatibility.
These options are also used to achieve advanced features, such as hardware texture
scaling at up to 20Mpixels per second, and hardware line drawing at up to 40Mpixels
per second. These advanced functions are implemented by allowing complex cal-
culations to be made to the source and/or destination address of DMA jobs as they
execute.
The list of valid job option tokens is:

O-13
$00 End of job option list
$06 Disable use of transparent value
$07 Enable use of transparent value
$0A Use 11 byte F011A DMA list format
$0B Use 12 byte F011B DMA list format
$0D Write raw flux to floppy drive (see ??)
$0E Read raw flux to floppy drive (see ??)
$0F Read raw flux to floppy drive (see ??)
$53 Enable ‘Shallan Spiral’ Mode
$80 Source address bits 20 – 27
$81 Destination address bits 20 – 27
$82 Source skip rate (256ths of bytes)
$83 Source skip rate (whole bytes)
$84 Destination skip rate (256ths of bytes)
$85 Destination skip rate (whole bytes)
$86 Transparent value (bytes with matching value are not written)
$87 Set X column bytes (LSB) for line drawing destination address
$88 Set X column bytes (MSB) for line drawing destination address
$89 Set Y row bytes (LSB) for line drawing destination address
$8A Set Y row bytes (MSB) for line drawing destination address
$8B Slope (LSB) for line drawing destination address
$8C Slope (MSB) for line drawing destination address
$8D Slope accumulator initial fraction (LSB) for line drawing destination
address
$8E Slope accumulator initial fraction (MSB) for line drawing destination
address
$8F Line Drawing Mode enable and options for destination address (set
in argument byte): Bit 7 = enable line mode, Bit 6 = select X or Y
direction, Bit 5 = slope is negative.
$97 Set X column bytes (LSB) for line drawing source address
$98 Set X column bytes (MSB) for line drawing source address
$99 Set Y row bytes (LSB) for line drawing source address
$9A Set Y row bytes (MSB) for line drawing source address
$9B Slope (LSB) for line drawing source address
$9C Slope (MSB) for line drawing source address
$9D Slope accumulator initial fraction (LSB) for line drawing source ad-
dress
$9E Slope accumulator initial fraction (MSB) for line drawing source ad-
dress
$9F Line Drawing Mode enable and options for source address (set in
argument byte): Bit 7 = enable line mode, Bit 6 = select X or Y
direction, Bit 5 = slope is negative.

O-14
TEXTURE SCALING AND LINE DRAWING
The DMAgic supports an advanced internal address calculator that allows it to draw
scaled textures and draw lines with arbitrary slopes on VIC-IV FCM video displays.
For texture scaling, the FCM screen must be arranged vertically, as shown below:

0 25
1 26
2 27
By lining the characters into vertical columns like this, advancing vertically by one pixel
adds a constant 8 bytes each time, as shown below:

O-15
$000 $001 $002 $003 $004 $005 $006 $007

$008 $008 $00A $00B $00C $00D $00E $00F

$010 $011 $012 $013 $014 $015 $016 $017

$018 $019 $01A $01B $01C $01D $01E $01F

$020 $021 $022 $023 $024 $025 $026 $027

$028 $029 $02A $02B $02C $02D $02E $02F

$030 $031 $032 $033 $034 $035 $036 $037

$038 $039 $03A $03B $03C $03D $03E $03F

$040 $041 $042 $043 $044 $045 $046 $047

$048 $048 $04A $04B $04C $04D $04E $04F

$050 $051 $052 $053 $054 $055 $056 $057

$058 $059 $05A $05B $05C $05D $05E $05F

$060 $061 $062 $063 $064 $065 $066 $067

$068 $069 $06A $06B $06C $06D $06E $06F

$070 $071 $072 $073 $074 $075 $076 $077

$078 $079 $07A $07B $07C $07D $07E $07F

$080 $081 $082 $083 $084 $085 $086 $087

$088 . . . ... ...

The source and destination skip rates also allow setting the scaling factors. A skip rate
of $0100 this corresponds to stepping $01.00 pixels. To use the vertically stacked
FCM layout as the target for copying vertical lines of textrures, then the destination
skip rate should be $0800, i.e., 8.0 bytes per pixel. This would copy a vertical line
of texture data without scaling. By setting the source stepping to < $0100 will cause
some pixels to be repeated, effectively zooming the texture in, while setting the source
stepping to > $0100 will cause some pixels to be skipped, effectively zooming the
texture out. The destination stepping does not ordinary need to be adjusted. Note
that the texture data must be stored with each vertical stripe stored contiguously, so
that this mode can be used.
For line drawing, the DMA controller needs to know the screen layout, specifically,
what number must be added to the address of a rightmost pixel in one column of FCM
characters in order to calculate the address of the pixel appearing immediately to its
right. Similarly, it must also know how much must be added to the address of a bottom
most pixel in one row of FCM characters in order to calculate the address of the pixel

O-16
appearing immediately below it. This allows for flexible screen layout options, and
arbitrary screen sizes. You must then also specify the slope of the line, and whether
the line has the X or Y as its major axis, and whether the slope is positive or negative.
The file test_290.c in the https://github.com/mega65/mega65-tools repository pro-
vides an example of using these facilities to implement hardware accelerated line
drawing. This is very fast, as it draws lines at the full DMA fill speed, i.e., approxi-
mately 40,500,000 pixels per second.

INLINE DMA LISTS


Normally you have to setup a separate area of memory that contains the DMA list, and
then load the address of that area into the DMA address registers at $D70x. Because
the MEGA65’s DMA controller is part of the CPU, it supports an additional mode that
is very convenient, called inline DMA list mode.
This mode works like Enhanced DMA mode, except that the DMA list is read starting
from the current value of the Program Counter (PC) register. To use this mode, write
any value to $D707, to immediately a trigger a DMA job, with the list in the bytes
immediately following the instruction that writes to $D707.
The DMA list can be a single job, or chained, as with any other DMA job. The real
magic is that the Program Counter gets set to the next address after the end of the
DMA list, and that the DMA list is read from the CPU’s current memory mapping. This
means that you can execute code with DMA lists from any bank of memory, without
having to worry about which bank it is in.
For example, the following code would clear the C65-mode screen, before flashing
the border endlessly:

STA $D707
. byte $00 ; end of job o p t i o n s
. byte $03 ; fill
. word 2000 ; count
. word $0020 ; value
. byte $00 ; src bank
. word $0800 ; dst
. byte $00 ; dst bank
. byte $00 ; cmd hi
. word $0000 ; modulo / i g n o r e d
foo :
INC $d020
JMP foo

O-17
AUDIO DMA
The MEGA65 includes four channels of DMA-driven audio playback that can be used
in place of the direct digital audio registers at $D6F8-$D6FB. That is, you must select
which of these two sources to feed to the audio cross-bar mixer. This is selected via
the AUDEN signal ($D711 bit 7), which simultaneously enables the audio DMA function
in the processor, as well as instructing the audio cross-bar mixer to use the audio from
this instead of the $D6F8-$D6FB digital audio registers. If you wish to have no other
audio than the audio DMA channels, the audio cross-bar mixer can be bypassed, and
the DMA audio played at full volume by setting the NOMIX signal ($D711 bit 4). In that
mode no audio from the SIDs, FM, microphones or other sources will be available. All
other bits in $D711 should ordinarily be left clear, i.e., write $80 to $D711 to enable
audio DMA.
Two channels form the left digital audio channel, and the other two channels form the
right digital audio channel. It is these left and right channels that are then fed into the
MEGA65’s audio cross-bar mixer.
As the DMA controller is part of the processor of the MEGA65, and the MEGA65
does not have reserved bus slots for multi-media operations, the MEGA65 uses idle
CPU cycles to perform background DMA. This requires that the MEGA65 CPU be set
to the “full speed” mode, i.e., approximately 40MHz. In this mode, there is a wait-
state whenever reading an operand from memory. Thus each instruction that loads
a byte from memory will create one implicit audio DMA slot. This is rarely a problem
in practice, except if the processor idles in a very tight loop. To ensure that audio
continues to play in the background, such loops should include a read instruction, such
as:
loop : LDA $1234 // Ensure loop has at least one idle cycle for
// audio DMA
JMP loop

Each of the four DMA channels is configured using a block of 16 registers at $D720,
$D730, $D740 and $D750, respectively. We will explain the registers for the first
channel, channel 0, at $D720 – $D72F.

Sample Address Management


To play an audio sample you must first supply the start address of the sample. This is a
24-bit address, and must be in the main chip memory of the MEGA65. This is done by
writing the address into $D72A – $D72C. This is the address of the first sample value
that will be played. You must then provide the end address of the sample in $D727
– $D728. But note that this is is only 16 bits. This is because the MEGA65 compares
only the bottom 16 bits of the address when checking if it has reached the end of a
sample. In practice, this means that samples cannot be more than 64KB in size. If
the sample contains a section that should be repeated, then the start address of the

O-18
repeating part should be loaded into $D721 – $D723, and the CH0LOOP bit should
be set ($D720 bit 6).
You can determine the current sample address at any time by reading the registers at
$D72A – $D72C. But beware: These registers are not latched, so it is possible that
the values may be updated as you read the registers, unless you stop the channel first
by clearing the CH0EN signal.

Sample Playback frequency and Vol-


ume
The MEGA65 controls the playback rate of audio DMA samples by using a 24-bit
counter. Whenever the 24-bit counter overflows, the next sample value is requested.
Sample speed control is achieved by setting the value added to this counter each
CPU cycle. Thus a value of $FFFFFF would result in a sample rate of almost 40.5
MHz. In practice, sample rates above a few megahertz are not possible, because
there are insufficient idle CPU cycles, and distorted audio will result. Even below this,
care must be taken to ensure that idle cycles come sufficiently often and dispersed
throughout the processor’s instruction stream to prevent distortion. At typical sample
rates below 16KHz and using 8-bit samples these effects are typically negligible for
normal instruction streams, and so no special action is normally required for typical
audio playback.
At the other end of the scale, sample rates as low as 40.5MHz/224 = 2.4 samples
per second are possible. This is sufficiently low enough for even the most demanding
infra-sound applications.
Volume is controlled by setting $D729. Maximum volume is obtained with the value
$FF, while a value of $00 will effectively mute the channel. The first two audio channels
are normally allocated to the left, and the second two to the right. However, the
MEGA65 includes separate volume controls for the opposite channels. For example,
to play audio DMA channel 0 at full volume on both left and right-hand sides of the
audio output, set both $D729 and $D71C to $FF. This allows panning of the four audio
DMA channels.
Both the frequency and volume can be freely adjusted while a sample is playing to
produce various effects.

Pure Sine Wave


Where it is necessary to produce a stable sine wave, especially at higher frequencies,
there is a special mode to support this. By setting the CH0SINE signal, the audio
channel will play a 32 byte 16-bit sine wave pattern. The sample addresses still need
to be set, as though the sine wave table were located in the bottom 64 bytes of
memory, as the normal address generation logic is used in this mode. However, no

O-19
audio DMA fetches are performed when a channel is in this mode, thus avoiding all
sources of distortion due to irregular spacing of idle cycles in the processor’s instruction
stream.
This can be used to produce sine waves in both the audible range, as well as well into
the ultrasonic range, at frequencies exceeding 60,000Hz, provided that the MEGA65
is connected to an appropriately speaker arrangement.

Sample playback control


To begin a channel playing a sample, set the CH0EN signal ($D720 bit 7). The sample
will play until its completion, unless the CH0LOOP signal has also been set. When a
sample completes playing, the CH0STP flag will be set. The audio DMA subsystem
cannot presently generate interrupts.
Unlike on the Amiga™, the MEGA65 audio DMA system supports both 8 and 16-bit
samples. It also supports packed 4-bit samples, playing either the lower or upper
nibble of each sample byte. This allows two separate samples to occupy the same
byte, thus effectively halving the amount of space required to store two equal length
samples.

F018 “DMAGIC” DMA CONTROLLER


HEX DEC Signal Description
ADDRLSB- DMAgic DMA list address LSB, and
D700 55040
TRIG trigger DMA (when written)
DMA list address high byte (address bits
D701 55041 ADDRMSB
8 – 15).
DMA list address bank (address bits 16
D702 55042 ADDRBANK
– 22). Writing clears $D704.

MEGA65 DMA CONTROLLER


EXTENSIONS
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D703 55043 – EN018B
D704 55044 ADDRMB
D705 55045 ETRIG
D706 55046 ETRIGMAPD
continued …

O-20
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D70E 55054 ADDRLSB
AUD-
D711 55057 AUDEN BLKD NOMIX – AUDBLKTO
WRBLK
D71C 55068 CH0RVOL
D71D 55069 CH1RVOL
D71E 55070 CH2LVOL
D71F 55071 CH3LVOL
D720 55072 CH0EN CH0LOOP CH0SGN CH0SINE CH0STP – CH0SBITS
D721 55073 CH0BADDRL
D722 55074 CH0BADDRC
D723 55075 CH0BADDRM
D724 55076 CH0FREQL
D725 55077 CH0FREQC
D726 55078 CH0FREQM
D727 55079 CH0TADDRL
D728 55080 CH0TADDRM
D729 55081 CH0VOLUME
D72A 55082 CH0CURADDRL
D72B 55083 CH0CURADDRC
D72C 55084 CH0CURADDRM
D72D 55085 CH0TMRADDRL
D72E 55086 CH0TMRADDRC
D72F 55087 CH0TMRADDRM
D730 55088 CH1EN CH1LOOP CH1SGN CH1SINE CH1STP – CH1SBITS
D731 55089 CH1BADDRL
D732 55090 CH1BADDRC
D733 55091 CH1BADDRM
D734 55092 CH1FREQL
D735 55093 CH1FREQC
D736 55094 CH1FREQM
D737 55095 CH1TADDRL
D738 55096 CH1TADDRM
D739 55097 CH1VOLUME
D73A 55098 CH1CURADDRL
D73B 55099 CH1CURADDRC
D73C 55100 CH1CURADDRM
D73D 55101 CH1TMRADDRL
D73E 55102 CH1TMRADDRC
D73F 55103 CH1TMRADDRM
D740 55104 CH2EN CH2LOOP CH2SGN CH2SINE CH2STP – CH2SBITS
D741 55105 CH2BADDRL
D742 55106 CH2BADDRC
continued …

O-21
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D743 55107 CH2BADDRM
D744 55108 CH2FREQL
D745 55109 CH2FREQC
D746 55110 CH2FREQM
D747 55111 CH2TADDRL
D748 55112 CH2TADDRM
D749 55113 CH2VOLUME
D74A 55114 CH2CURADDRL
D74B 55115 CH2CURADDRC
D74C 55116 CH2CURADDRM
D74D 55117 CH2TMRADDRL
D74E 55118 CH2TMRADDRC
D74F 55119 CH2TMRADDRM
D750 55120 CH3EN CH3LOOP CH3SGN CH3SINE CH3STP – CH3SBITS
D751 55121 CH3BADDRL
D752 55122 CH3BADDRC
D753 55123 CH3BADDRM
D754 55124 CH3FREQL
D755 55125 CH3FREQC
D756 55126 CH3FREQM
D757 55127 CH3TADDRL
D758 55128 CH3TADDRM
D759 55129 CH3VOLUME
D75A 55130 CH3CURADDRL
D75B 55131 CH3CURADDRC
D75C 55132 CH3CURADDRM
D75D 55133 CH3TMRADDRL
D75E 55134 CH3TMRADDRC
D75F 55135 CH3TMRADDRM

• ADDRLSB DMA list address low byte (address bits 0 – 7) WITHOUT STARTING A
DMA JOB (used by Hypervisor for unfreezing DMA-using tasks)
• ADDRMB DMA list address mega-byte
• AUDBLKTO Audio DMA block timeout (read only) DEBUG
• AUDEN Enable Audio DMA
• AUDWRBLK Audio DMA block writes (samples still get read)
• BLKD Audio DMA blocked (read only) DEBUG
• CH0RVOL Audio DMA channel 0 right channel volume
• CH1RVOL Audio DMA channel 1 right channel volume

O-22
• CH2LVOL Audio DMA channel 2 left channel volume
• CH3LVOL Audio DMA channel 3 left channel volume
• CHXBADDRC Audio DMA channel X base address middle byte
• CHXBADDRL Audio DMA channel X base address LSB
• CHXBADDRM Audio DMA channel X base address MSB
• CHXCURADDRC Audio DMA channel X current address middle byte
• CHXCURADDRL Audio DMA channel X current address LSB
• CHXCURADDRM Audio DMA channel X current address MSB
• CHXEN Enable Audio DMA channel X
• CHXFREQC Audio DMA channel X frequency middle byte
• CHXFREQL Audio DMA channel X frequency LSB
• CHXFREQM Audio DMA channel X frequency MSB
• CHXLOOP Enable Audio DMA channel X looping
• CHXSBITS Audio DMA channel X sample bits (11=16, 10=8, 01=upper nybl,
00=lower nybl)
• CHXSGN Enable Audio DMA channel X signed samples
• CHXSINE Audio DMA channel X play 32-sample sine wave instead of DMA data
• CHXSTP Audio DMA channel X stop flag
• CHXTADDRL Audio DMA channel X top address LSB
• CHXTADDRM Audio DMA channel X top address MSB
• CHXTMRADDRC Audio DMA channel X timing counter middle byte
• CHXTMRADDRL Audio DMA channel X timing counter LSB
• CHXTMRADDRM Audio DMA channel X timing counter MSB
• CHXVOLUME Audio DMA channel X playback volume
• EN018B DMA enable F018B mode (adds sub-command byte)
• ETRIG Set low-order byte of DMA list address, and trigger Enhanced DMA job,
with list address specified as 28-bit flat address (uses DMA option list)
• ETRIGMAPD Set low-order byte of DMA list address, and trigger Enhanced DMA
job, with list in current CPU memory map (uses DMA option list)
• NOMIX Audio DMA bypasses audio mixer

O-23
UNIMPLEMENTED FUNCTIONALITY
The MEGA65’s DMAgic does not currently support either memory-swap or mini-term
operations.
Miniterms were intended for bitplane blitting, which is not required for the MEGA65
which offers greatly advanced character modes and stepped and fractional DMA ad-
dress incrementing which allows efficient texture copying and scaling. Also there ex-
ists no known software which ever used this facility, and it remains uncertain if it was
ever implemented in any revision of the DMAgic chip used in C65 prototypes.
The memory-swap operation is intended to be implemented, but can be worked around
in the meantime by copying the first region to a 3rd region that acts as a temporary
buffer, then copying the 2nd region to the 1st, and the 3rd to the 2nd.

O-24
APPENDIX P
VIC-IV Video Interface
Controller
• Features
• VIC-II/III/IV Register Access Control
• Video Output Formats, Timing and
Compatibility

• Memory Interface
• Hot Registers
• New Modes
• Sprites
• VIC-III Errata Level
• VIC-II / C64 Registers
• VIC-III / C65 Registers
• VIC-IV / MEGA65 Specific Registers

P-2
P-3
P-4
FEATURES
The VIC-IV is a fourth generation Video Interface Controller developed especially for
the MEGA65, and featuring very good backwards compatibility with the VIC-II that
was used in the C64, and the VIC-III that was used in the C65. The VIC-IV can be
programmed as though it were either of those predecessor systems. In addition it
supports a number of new features. It is easy to mix older VIC-II/III features with the
new VIC-IV features, making it easy to transition from the VIC-II or VIC-III to the VIC-IV,
just as the VIC-III made it easy to transition from the VIC-II. Some of the new features
and enhancements of the VIC-IV include:
• Direct access to 384KB RAM (up from 16KB/64KB with the VIC-II and 128KB
with the VIC-III).
• Support for 32KB of 8-bit Colour/Attribute RAM (up from 2KB on the VIC-III),
to support very large screens.
• HDTV 720×576 / 800×600 native resolution at both 50Hz and 60Hz for PAL
and NTSC, with VGA and digital video output.
• 81MHz pixel clock (up from ∼ 8MHz with the VIC-II/III), which enables a wide
range of new features.
• New 16-colour (16×8 pixels per character cell) and 256-colour (8×8 pixels per
character cell) full-colour text modes.
• Support for up to 8,192 unique characters in a character set.
• Four 256-colour palette banks (versus the VIC-III’s single palette bank), each
supporting 23-bit colour depth (versus the VIC-III’s 12-bit colour depth), and
which can be rapidly alternated to create even more colourful graphics than is
possible with the VIC-III.
• Screen, bitmap, colour and character data can be positioned at any address
with byte-level granularity (compared with fixed 1KB – 16KB boundaries with
the VIC-II/III).
• Virtual screen dimensioning, which combined with byte-level data position
granularity provides effective hardware support for scrolling and panning in
both X and Y directions.
• New sprite modes: Bitplane modification, full-colour (15 foreground colours
+ transparency) and tiled modes, allowing a wide variety of new and exciting
sprite-based effects.
• The ability to stack sprites in a bit-planar manner to produce sprites with up to
256 colours.
• Sprites can use 64 bits of data per raster line, allowing sprites to be 64 pixels
wide when using VIC-II/III mono/multi-colour mode, or 16 pixels wide when
using the new VIC-IV full-colour sprite mode.

P-5
• Sprite tile mode, which allows a sprite to be repeated horizontally across an
entire raster line, allowing sprites to be used to create animated backgrounds
in a memory-efficient manner.
• Sprites can be configured to use a separate 256-colour palette to that used
to draw other text and graphics, allowing for a more colourful display.
• Super-extended attribute mode which uses two screen RAM bytes and two
colour RAM bytes per character mode, which supports a wide variety of new fea-
tures including alpha-blending/anti-aliasing, hardware kerning/variable-
width characters, hardware horizontal/vertical flipping, alternate palette se-
lection and other powerful features that make it easy to create highly dynamic
and colourful displays.
• Raster-Rewrite Buffer which allows hardware-generated pseudo-sprites,
similar to “bobs” on Amiga™ computers, but with the advantage that they are
rendered in the display pipeline, and thus do not need to be un-drawn and re-
drawn to animate them.
• Multiple 8-bit colour play-fields are also possible using the Raster-Rewrite
Buffer.
In short, the VIC-IV is a powerful evolution of the VIC-II/III, while retaining the character
and distinctiveness of the VIC-series of video controllers.
For a full description of the additional registers that the VIC-IV provides, as well as
documentation of the legacy VIC-II and VIC-III registers, refer to the corresponding
sections of this appendix. The remainder of the appendix will focus on describing the
capabilities and use of many of the VIC-IV’s new features.

VIC-II/III/IV REGISTER ACCESS


CONTROL
Because the new features of the VIC-IV are all extensions to the existing VIC-II/III de-
signs, there is no concept of having to select the mode in which the VIC-IV will operate:
It is always in VIC-IV mode. However, for backwards compatibility with software, the
many additional registers of the VIC-IV can be hidden, so that it appears to be either
a VIC-II or VIC-III. This is done in the same manner that the VIC-III uses to hide its new
features from legacy VIC-II software.
The mechanism is the VIC-III write-only KEY register ($D02F, 53295 decimal). The
VIC-III by default conceals its new features until a “knock” sequence is performed.
This consists of writing two special values one after the other to $D02F. The following
table summarises the knock sequences supported by the VIC-IV, and indicates which
are VIC-IV specific, and which are supported by the VIC-III:

P-6
First Value Second Value VIC-IV
Effect
Hex (Decimal) Hex (Decimal) Specific?
Only VIC-II registers
visible (all VIC-III and
$00 (0) $00 (0) No
VIC-IV new registers
are hidden)
VIC-III new registers
$A5 (165) $96 (150) No
visible
Both VIC-III and VIC-IV
$47 (71) $53 (83) Yes
new registers visible
No VIC-II/III/IV
registers visible.
$45 (69) $54 (84) 45E100 Ethernet Yes
controller buffers are
visible instead

Detecting VIC-II/III/IV
Detecting which generation of the VIC-II/III/IV a machine is fitted with can be impor-
tant for programs that support only particular generations, or that wish to vary their
graphical display based on the capabilities of the machine. While there are many pos-
sibilities for this, the following is a simple and effective method. It relies on the fact
that the VIC-III and VIC-IV do not repeat the VIC-II registers throughout the I/O ad-
dress space. Thus while $D000 and $D100 are synonymous when a VIC-II is present
(or a VIC-III/IV is hiding their additional registers), this is not the case when a VIC-III
or VIC-IV is making all of its registers visible. Therefore presence of a VIC-III/IV can
be determined by testing whether these two locations are aliases for the same regis-
ter, or represent separate registers. The detection sequence consists of using the KEY
register to attempt to make either VIC-IV or VIC-III additional registers visible. If either
succeeds, then we can assume that the corresponding generation of VIC is installed.
As the VIC-IV supports the VIC-III KEY knocks, we must first test for the presence of a
VIC-IV. Also, we assume that the MEGA65 starts in VIC-IV mode, even when running
C65 BASIC. Thus the test can be done in BASIC from either C64 or C65-mode as
follows:

P-7
0 REM IN C65 - MODE WE CANNOT SAFELY WRITE TO $D02F , SO WE TEST A D I F F E R E N T WAY
10 IF PEEK ( $D018 ) AND 32 THEN GOTO 65
20 POKE $D000 ,1: POKE $D02F ,71: POKE $D02F ,83
30 POKE $D000 +256 ,0: IF PEEK ( $D000 )=1 THEN PRINT " VIC - IV P R E S E N T ": END
40 POKE $D000 ,1: POKE $D02F ,165: POKE $D02F ,150
50 POKE $D000 +256 ,0: IF PEEK ( $D000 )=1 THEN PRINT " VIC - III P R E S E N T ": END
60 PRINT " VIC - II PR E SE N T ": END
65 REM WE ASSUME WE HAVE A C65 HERE
70 V1 = PEEK ( $D050 ): V2 = PEEK ( $D050 ): V3 = PEEK ( $D050 )
80 IF V1 < > V2 OR V1 < > V3 OR V2 < > V3 THEN PRINT " VIC - IV P R E S E N T ": END
90 GOTO 40

Line 10 of this program checks whether the screen is a multiple of 2KB. As the screen
on the C64 is located at 1KB, this test will fail, and execution will continue to line 20.
Line 20 writes 1 to one of the VIC-II sprite position registers, 53248, before writing
the MEGA65 knock to the key register, 53295. Line 30 writes to 53248 + 256, which
on the C64 is a mirror of 53248, but on a MEGA65 with VIC-IV I/O enabled will be
one of the red palette registers. After writing to 53248 + 256, the program checks
if the register at 53248 has been modified by the write to 53248 + 256. If it has,
then the two addresses point to the same register. This will happen on either a C64 or
C65, but not on a computer with a VIC-IV. Thus if 53248 has not changed, we report
that we have detected a VIC-IV. If writing to 53248 + 256 did change the value in
register 53248, then we proceed to line 40, which writes to 53248 again, and this
time writes the VIC-III knock to the key register. Line 50 is like line 30, but as it appears
after a VIC-III knock, it allows the detection of a VIC-III. Finally, if neither a VIC-IV nor
VIC-III is detected, we conclude that only a VIC-II must be present.
As the MEGA65 is the only C64-class computer that is fitted with a VIC-IV, this can
be used as a de facto test for the presence of a MEGA65 computer. Detection of a
VIC-III can be similarity assumed to indicate the presence of a C65.

VIDEO OUTPUT FORMATS, TIMING


AND COMPATIBILITY
Integrated Marvellous Digital
Hookup™ (IMDH™) Digital Video Out-
put
The MEGA65 features VGA analog video output and Integrated Marvellous Digital
Hookup™ (IMDH™). This is different to existing common digital video standards in
several key points:

P-8
1. We didn’t invent a new connector for it: We instead used the most common
digital video connector already in use. So your existing cables should work fine!
2. We didn’t make it purposely incompatible with any existing digital video stan-
dard. So your existing TVs and monitors should work fine!
3. We don’t engage in highway-robbery for other vendors to use the IMDH™ dig-
ital video standard, by trying to charge them $10,000 every year, just for the
permission to be able to sell a single device. This means that the MEGA65 is
cheaper for you!
4. The IMDH™ standard does not allow content-protection or other sovereignty
eroding flim-flam. If you produced the video, you can do whatever you like with
it!

Connecting to Naughty Proprietary


Digital Video Standards
There are digital video standards that are completely backwards compared with
IMDH™. Fortunately because of IMDH™’s open approach to interoperability, these
should, in most cases, function with the MEGA65 without difficulty. Simply find a
video cable fits the IMDH™ connector on the back of your MEGA65, and connect it to
your MEGA65 and a TV, Monitor or Projector that has the same connector.
However, regrettably, not all manufacturers have submitted their devices for IMDH™
compliance testing with the MEGA65 team. This means that some TVs and Monitors
are, unfortunately, not IMDH™ compliant. Thus while most TVs and Monitors will work
with the MEGA65, you might find that you need to try a couple to get a satisfactory
result. If you do find a monitor that doesn’t work with the MEGA65, please let us know,
and also report the problem to the Monitor vendor, recommending that they submit
their devices for IMDH™ compliance testing.
The VIC-IV was designed for use in the MEGA65 and related systems, including the
MEGAphone family of portable devices. The VIC-IV supports both VGA and digital
video output, using the non-proprietary IMDH™ interface. It also supports parallel
digital video output suitable for driving LCD display panels. Considerable care has
been taken to create a common video front-end that supports these three output
modes.
For simplicity and accuracy of frame timing for legacy software, the video format is
normally based on the HDTV PAL and NTSC 720×576/480 (576p and 480p) modes
using a 27MHz output pixel clock. This is ideal for digital video and LCD display panels.
However not all VGA displays support these modes, especially 720×576 at 50Hz.
In terms of VIC-II and VIC-III backwards compatibility, this display format has several
effects that do not cause problems for most programs, but can cause some differences
in behaviour:

P-9
1. Because the VIC-IV display is progressive rather than interlaced, two physical
raster lines are produced for each logical VIC-II or VIC-III raster line. This means
that there are either 63 or 65 cycles per logical double raster, rather than per
physical 576p/480p physical raster. This can cause some minor visual artefacts,
when programs make assumptions about where on a horizontal line the VIC is
drawing when, for example, the border or screen colour is changed.
2. The VIC-IV does not follow the behaviour of the VIC-III, which allowed changes
in video modes, e.g., between text and bitmap mode, on characters. Nor does
it follow the VIC-II’s policy of having such changes take effect immediately. In-
stead, the VIC-IV applies changes at the start of each raster line. This can cause
some minor artefacts.
3. The VIC-IV uses a single-raster rendering buffer which is populated using the
VIC-IV’s internal 81MHz pixel clock, before being displayed using the 27MHz
output pixel clock. This means that a raster lines display content tends to be
rendered much earlier in a raster line than on either the VIC-II or VIC-III. This can
cause some artefacts with displays, particularly in demos that rely on specific
behaviour of the VIC-II at particular cycles in a raster line, for example for effects
such as VSP or FLI. At present, such effects are unlikely to display correctly on
the current revision of the VIC-IV. Improved support for these features is planned
for a future revision of the VIC-IV.
4. The 1280×200 and 1280×400 display modes of the VIC-III are not currently
supported, as they cannot be meaningfully displayed on any modern monitor,
and no software is known to support or use this feature.

Frame Timing
Frame timing is designed to match that of the 6502 + VIC-II combination of the C64.
Both PAL and NTSC timing is supported, and the number of cycles per logical raster
line, the number of raster lines per frame, and the number of cycles per frame are
all adjusted accordingly. To achieve this, the VIC-IV ordinarily uses HDTV 576p 50Hz
(PAL) and 480p 60Hz (NTSC) video modes, with timing tweaked to be as close as
possible to double-scan PAL and NTSC composite TV modes as used by the VIC-II.
The VIC-IV produces timing impulses at approximately 1MHz which are used by the
45GS02 processor, so that the correct effective frequency is provided when operating
at the 1MHz, 2MHz and 3.5MHz C64, C128 and C65 compatibility modes. This allows
the single machine to switch between accurate PAL and NTSC CPU timing, as well as
video modes. The exact frequency varies between PAL and NTSC modes, to mimic the
behaviour of PAL versus NTSC C64, C128 and C65 processor and video timing.
The PAL frame is constructed from 624 physical raster lines, consisting of 864 pixel
clock ticks. The pixel clock is 27MHz, which is 1/3 the VIC-IV pixel clock. The visible
frame is 720×576 pixels, the entirety of which can be used in VIC-IV mode. In VIC-II
and VIC-III modes, the border area reduces the usable size to 640×400 pixels. In
VIC-II mode and VIC-III 200H modes, the display is double scanned, with two 31.5

P-10
micro-second physical rasters corresponding to a single 63 micro-second VIC-II-style
raster line. Thus each frame consists of 312 VIC-II raster lines of 63 micro-seconds
each, exactly matching that of a PAL C64.
864 Horizontal Ticks
(31.5 μSec per line)

Vertical Fly-Back Area


VIC-II/III Border Area

576 PAL Frame Timing Horiz-


Visible ontal 624
Lines Fly-Back Lines
VIC-II/III Screen Area Area

VIC-II/III Border Area

720 Visible Pixels

The NTSC frame is constructed from 526 physical raster lines, consisting of 858 pixel
clock ticks. The pixel clock is 27MHz, which is 1/3 the VIC-IV pixel clock. The visible
frame is 720×480 pixels, the entirety of which can be used in VIC-IV mode. In VIC-
II and VIC-III modes, the border area reduces the usable size to 640×400 pixels.
In VIC-II mode and VIC-III 200H modes, the display is double scanned, with two 32
micro-second physical rasters corresponding to a single 64 micro-second VIC-II-style
raster line. Thus each frame consists of 263 VIC-II raster lines of 64 micro-seconds
each, matching the most common C64 NTSC video timing.

P-11
858 Horizontal Ticks
(32 μSec per line)

Vertical Fly-Back Area


VIC-II/III Border Area

480 NTSC Frame Timing Horiz-


Visible ontal 526
Lines Fly-Back Lines
VIC-II/III Screen Area Area

VIC-II/III Border Area

720 Visible Pixels

As these HDTV video modes are not supported by all VGA monitors, a compatibility
mode is included that provides a 640×480 VGA-style mode. However, as the pixel
clock of the MEGA65 is fixed at 27MHz, this mode runs at 63Hz. Nonetheless, this
should work on the vast majority of VGA monitors. There should be no problem with
the PAL / NTSC modes when using the digital video output of the MEGA65 with the
vast majority of IMDH™-enabled monitors and TVs.
To determine whether the MEGA65 is operating in PAL or NTSC, you can enter the
Freeze Menu, which displays the current video mode, or from a program you can check
the PALNTSC signal (bit 7 of $D06F, 53359 decimal). If this bit is set, then the machine
is operating in NTSC mode, and clear if operating in PAL mode. This bit can be modified
to change between the modes, e.g.:

P-12
10 REM ENABLE C65 + MEGA65 I / O
20 IF PEEK ( $D018 ) <32 THEN POKE $D02F , ASC (" G "): POKE $D02F , ASC (" S ")
30 REM CHECK NTSC BIT
40 NTSC = PEEK ( $D06F ) AND 128
50 REM DI SPL AY STATE AND ASK FOR TOGGLE
60 PRINT " MEGA65 IS IN ";: IF NTSC THEN PRINT " NTSC MODE ": ELSE PRINT " PAL MODE "
70 INPUT " SWITCH MODES ( Y / N )? " , A$
80 REM TOGGLE NTSC BIT
90 IF A$ =" Y " THEN POKE $D06F , PEEK ( $D06F ) XOR 128: ELSE END
100 REM DI SPL AY NEW STATE
110 NTSC = PEEK ( $D06F ) AND 128
120 PRINT " MEGA65 IS IN ";: IF NTSC THEN PRINT " NTSC MODE ": ELSE PRINT " PAL MODE "

Physical and Logical Rasters


Physical rasters per frame refers to the number of actual raster lines in the PAL or NTSC
Enhanced Definition TV (EDTV) video modes used by the MEGA65. Logical Rasters
refers to the number of VIC-II-style rasters per frame. Each logical raster consists of
two physical rasters per line, since EDTV modes are double-scan modes compared
with the original PAL and NTSC Standard Definition TV modes used by the C64. The
frame parameters of the VIC-IV for PAL and NTSC are as follows:

Physical
Cycles per Logical Rasters
Standard Rasters per
Raster per Frame
Frame
PAL 63 626 312
NTSC 65 526 263

The result is that the frames on the VIC-IV consist of exactly the same number of
∼1MHz CPU cycles as on the VIC-II.

Bad Lines
The VIC-IV does not natively incur any “bad lines”, because the VIC-IV has its own
dedicated memory busses to the main memory and colour RAM of the MEGA65. This
means that both the processor and VIC-IV can access the memory at the same time,
unlike on the C64 or C65, where they are alternated.
However, to improve compatibility, the VIC-IV signals when a “bad line” would have
occurred on the VIC-II. The 45GS02 processor of the MEGA65 accepts these bad line
signals, and pauses the CPU for 40 clock cycles, except if the processor is running at
full speed, in which case they are ignored. This improves the timing compatibility with
the VIC-II considerably. However, the timing is not exact, because the current revision

P-13
of the 45GS02 pauses for exactly 40 cycles, instead of 40 – 43 cycles, depending
on the instruction being executed at the time. Also, the VIC-IV and 45GS02 do not
currently pause for sprite fetches.
The bad line emulation is controlled by bit 0 of $D710: setting this bit enables bad line
emulation, and clearing it prevents any bad line from stealing time from the processor.

MEMORY INTERFACE
The VIC-IV supports up to 16MB of direct access RAM for video data, however at
present, all existing models provide only 384KB of addressable RAM. In MEGA65 sys-
tems, the second block of 128KB of RAM (spanning from 128KB-256KB in the memory
map) is typically used to hold a C65-compatible ROM, leaving 256KB of RAM avail-
able to the user. If software is written to avoid the need to use C65 ROM routines,
then the entire 384KB of RAM can be used by the program.
All MEGA65 models presently support 32KB of colour RAM, however there are plans
for the latest R3 board to support 64KB of colour RAM (or possibly even 128KB).
The VIC-IV supports all legacy VIC-II and VIC-III methods for accessing this RAM, in-
cluding the VIC-II’s use of 16KB banks, and the VIC-III’s Display Address Translator
(DAT). This additional memory can be used for character and bitmap displays, as well
as for sprites. However, the VIC-III bitplane modes remain limited to using only the first
128KB of RAM, as the VIC-IV does not enhance the bitplane mode.

Startup Base Addresses


If no mappings are changed and no screen memory is relocated (see the following
paragraph for more on this) the base addresses can be used to place characters on
the screen and set colour and attributes accordingly:
• $0800 Screen RAM
• $ff80000 Colour RAM
These values are the upper left character on the screen no matter if in 40 or 80 column
mode. In BASIC you can use the dollar sign directly to use the hexadecimal format.
For a far better method in BASIC see Chapter/Appendix B on page B-9 .

Relocating Screen Memory


To use the additional memory for screen RAM, the screen RAM start address can be
adjusted to any location in memory with byte-level granularity by setting the SCRNPTR
registers ($D060 – $D063, 53344 – 53347 decimal). For example, to set the screen
memory to address 12345:

P-14
REM ENABLE C65 + MEGA65 I / O
IF PEEK ( $D018 ) <32 THEN POKE $D02F , ASC (" G "): POKE $D02F , ASC (" S ")
POKE $D060 , $45 : POKE $D061 , $23 : POKE $D062 , $1

Relocating Character Generator Data


The location of the character generator data can also be set with byte-level precision
via the CHARPTR registers at $D068 – $D06A (53352 – 53354 decimal). As usual,
the first of these registers holds the lowest-order byte, and the last the highest-order
byte. The three bytes allow for placement of character data anywhere in the first
16MB of RAM. For systems with less than 16MB of RAM accessible by the VIC-IV, the
upper address bits should be zero.
For example, to indicate that character generator data should be sourced beginning
at $41200 (266752 decimal), the following could be used. Note that the command
WPOKE can be used to write two bytes as a word into a memory or I/O location.
Therefore, we use WPOKE to write $00 into $D068 and $12 into $D069, and an
additional POKE to write the high byte $A into $D06A by dividing the address by
65536:
REM ENABLE C65 + MEGA65 I / O
IF PEEK ( $D018 ) <32 THEN POKE $D02F , ASC (" G "): POKE $D02F , ASC (" S ")
REM HEX $41200 IS EASILY DI V I D E D IN ITS 3 BYTES $00 , $12 , $4
REM WPOKE SETS THE LOWER TWO BYTES IN ONE C O M M A N D AND
REM THE F O L L O W I N G POKE SETS THE UPPER BYTE
A = $41200
WPOKE $D068 , A
POKE $D06A , A /65536

Relocating Colour / Attribute RAM


The area of colour RAM being used can be similarly set using the COLPTR registers
($D064 – $D065, 53348 – 53349 decimal). That is, the value is an offset from the
start of the colour / attribute RAM. This is because, like on the C64, the colour / at-
tribute RAM of the MEGA65 is a separate memory component, with its own dedicated
connection to the VIC-IV. By default, the COLPTRs are set to zero, which replicates
the behaviour of the VIC-II/III. To set the display to use the colour / attribute RAM
beginning at offset $4000, one could use something like:

P-15
REM ENABLE C65 + MEGA65 I / O
IF PEEK ( $D018 ) <32 THEN POKE $D02F , ASC (" G "): POKE $D02F , ASC (" S ")
REM SET COLPTR TO $4000 , SPLITS INTO $00 LSB and $40 MSB
POKE $D064 , $00
POKE $D065 , $40

Relocating Sprite Pointers and Images


The location of the sprite pointers can also be moved, and sprites can be made to have
their data anywhere in first 4MB of memory. This is accomplished by first setting the
location of the sprite pointers by setting the SPRPTRADR registers ($D06C – $D06E,
53356 – 53358 decimal, but note that only the bottom 7 bits of $D06E are used,
as the highest bit is used for the SPRPTR16 signal). This allows the list of eight sprite
pointers to be moved from the end of screen RAM to an arbitrary location in the first
8MB of RAM. SPRPTRADR must be aligned to a 16-byte boundary (a multiple of 16).
To allow sprites themselves to be located anywhere in the first 4MB of RAM, the
SPRPTR16 bit in $D06E must be set. In this mode, two bytes are used to indicate
the location of each sprite, instead of one. That is, the list of sprite pointers will be
16 bytes long, instead of 8 bytes long as on the VIC-II/III. When SPRPTR16 is enabled,
the location of the sprite pointers should always be set explicitly via the SPRPTRADR
registers.
For example, to position the sprite pointers at location 800 – 815, you could use
something like the following code. Note that a little gymnastics is required to keep
the SPRPTR16 bit unchanged, and also to work around the AND binary operator not
working with values greater than 65535:

REM ENABLE C65 + MEGA65 I / O


IF PEEK ( $D018 ) <32 THEN POKE $D02F , ASC (" G "): POKE $D02F , ASC (" S ")
POKE $D06C ,(800 - INT ( 8 0 0 / 6 5 5 3 6 ) * 6 5 5 3 6 ) AND 255
POKE $D06D , INT ( 8 0 0 / 2 5 6 ) AND 255
POKE $D06E ,( PEEK ( $D06E ) AND 128)+ INT ( 8 0 0 / 6 5 5 3 6 )

The location of each sprite image remains a multiple of 64 bytes, thus allowing for
up to 65,536 unique sprite images to be used at any point in time, if the system is
equipped with sufficient RAM (4MB or more). In this mode, the VIC-II 16KB banking is
ignored, and the location of sprite data is simply 64 × the pointer value. For example,
to have the data for a sprite at $C000 (49152 decimal), this would be sprite location
768, because 49152 divided by 64 = 768. We then need to split 768 into high and
low bytes, to set the two pointer bytes: 768 = 256×3, with remainder 0, so this would
require the two sprite pointer bytes to be 0 (low byte, which comes first) and 3 (high
byte). Thus if the sprite pointers were located at $7F8 (2040 decimal), setting the
first sprite to sprite image 768 could be done with something like:

P-16
POKE 2040 ,768 -256* INT ( 7 6 8 / 2 5 6 )
POKE 2041 , INT ( 7 6 8 / 2 5 6 )

HOT REGISTERS
Some VIC-IV registers support features similar to the VIC-II and VIC-III, but with ex-
panded capabilities. For backwards compatibility, writing to specific VIC-II and VIC-III
registers also causes related VIC-IV registers to reset with consistent values. This be-
havior can be configured with the HOTREG flag in bit 7 of $D05D.
For example, the lower four bits of register $D018 (CB) set the VIC-II character set ad-
dress, as a multiple of 1 KiB. VIC-IV can locate the character set to any 24-bit address
using $D06A (CHARPTRBNK), $D068 (CHARPTRLSB), and $D069 (CHARPTRMSB).
If you set CB, the VIC-IV registers will also be updated to match.
The complete set of VIC-II “hot” registers that affect VIC-IV registers include:
• $D011 (53265): RB8, ECM, BMM, BLNK, RSEL, YSCL
• $D016 (53270): RST, MCM, CSEL, XSCL
• $D018 (53272): VS, CB
• $D031 (53297): VIC-III modes: H640, FAST, ATTR, BPM, V400, H1280, MONO,
INT
• The VIC-II bank bits of $DD00 (56576) (CIA 2 PORTA)
Whenever any of those registers are modified, even by writing the existing value back
into them, all of the corresponding VIC-IV registers will be updated based on the VIC-
II register values, even those unrelated to the register that was written to. This includes
the FAST flag, which resides in a hot register byte location ($D031) but is unrelated
to video parameters and does not have a corresponding VIC-IV register.
The registers that are modified during this process are listed below. Note that some of
these registers are internal to the VIC-IV, and cannot be directly queried or modified
by the user. Where this is the case, no addresses are listed for the registers.
• X position of the left side border edge. This internal register is updated set the
left side border to the width indicated in the Single Side Border Width registers
($D05C contains the LSB, and bits 0 – 5 of $D05D contain the MSB of the side
border width. Note that the width of the side border is based on the low-level
video frame dimensions, not the display screen size of the video mode. The
38/40 column field of $D016 is set to 38 columns, the left border edge will
appear 14 pixels to the right of its normal position.
• X position of the right side border edge. This is the same as the left side
border edge, but for the right-hand edge of the screen. Note that if the 38/40

P-17
column flag is set to 38 columns, that the right border edge is moved 17 pixels
to the left of its normal position.
• Y position of the top border edge ($D048 LSB, bits 0 – 3 of $D049 MSB).
This internal register is set to the normal top position of the screen, minus the
value of the RASLINE0 field in bits 0 – 5 of $D06F. If the 24/25 rows field of
$D011 is set to 24 rows, then the edge of the top border will be lowed by 8
raster lines.
• Y position of the bottom border edge ($D04A LSB, bits 0 – 3 of $D04B MSB).
This internal register is set to the normal top position of the screen, plus 400
raster lines, to create the normal 400px tall primary display area within the bor-
ders. If the 24/25 rows field of $D011 is set to 24 rows, then the edge of the
top border will be raised by 8 raster lines.
• Character Generator Vertical Scale ($D05B). This register is set to 0 for V200
or 1 for V400 modes, to cause each row of pixels in a character to be either 1
or 2 pixels tall, respectively, according to the V400 flag.
• Number of character rows to display ($D07B). This register is set to either
25-1 = 24 or 50-1 = 49 to display either 25 or 50 rows of text. Note that when
$D011 is used to bring the vertical borders inwards to reduce the number of
visible character rows, that the VIC-IV still draws all 25 or 50 rows.
• X Position Where Character Display Starts ($D04C LSB, bits 0 – 3 of $D04D
MSB). This register is set to a position relative to the edge of the 40-column
wide text display, plus 2× the smooth scrolling position indicated in $D016.
• Y Position Where Character Display Starts ($D04E LSB, buts 0 – 3 of $D04F
MSB). This register is set to the top edge of the vertical border, minus the VIC-II
First Raster adjustment register (bits 0 –5 of $D06F), plus any offset due to the
vertical smooth-scroll bits in $D011.
• Virtual Row Width ($D058 LSB, $D059 MSB), i.e., the number of bytes of
screen and colour RAM that the VIC-IV advances when displaying each
successive row of characters. This register is set to 40 if the H640 flag is
clear, or to 80 if the H640 flag is set, making the advance match the number of
characters to be displayed.
• Display Row Width ($D05E LSB, bits 4 – 5 of $D063 MSB). This register is set
to 40 if the H640 flag is clear, or to 80 if the H640 flag is set.
• Base Address of Screen RAM ($D060 – $D062, representing a 24-bit ad-
dress). This address is reset to the address as computed by reference to $D018
and $DD00, as on the C64.
• VIC-II Sprite Pointer Address ($D06C – $D06E, representing a 24-bit ad-
dress). This register is reset to the normal location at the end of the screen
memory of the current mode. If the H640 flag is set, then this will be at the end
of 2KB screen RAM area, or if the H640 flag is not set, it will point to the end of
the 1KB screen RAM area, as on a C64.

P-18
• Character Set Base Address ($D068 – $D06A, representing a 24-bit ad-
dress). Note that the hot register function sets only the lower 16 bits of the
character set address. That is, $D06A is not cleared. This is an intentional
behaviour, that makes it easier to replace the character set in existing VIC-II-
oriented software with another character set in another bank of RAM.
• Colour RAM Base Address ($D064 LSB, $D065 MSB). These registers are re-
set to zero, causing the VIC-IV to expect the colour RAM for the screen to be in
the first part of the colour RAM, to be compatible with the VIC-II and VIC-III.
This behavior of the VIC-II registers is intended primarily for legacy software that is not
aware of (and therefore never writes to) VIC-IV registers. Hot register propagation can
be disabled by clearing the HOTREG (“hot register”) signal: bit 7 of $D05D (53341).
If you clear the HOTREG flag, you will need to update VIC-IV registers directly when
you wish to change video mode parameters.
If you make a change to a hot register while HOTREG is disabled then re-enable
HOTREG, all hot registers update immediately. There are rare cases where you might
want to make a change to a hot register without updating VIC-IV registers but also
want hot registers enabled after the change. To do this, you can cancel the pending
update by writing a 0 to HOTREG again just before re-enabling hot registers. The full
procedure is:
1. Write 0 to HOTREG to disable hot registers.
2. Update the VIC-II register you want to change.
3. Write 0 to HOTREG to cancel the pending update.
4. Write 1 to HOTREG to re-enable hot registers.
In assembly language:

lda # % 1 0 0 0 0 0 0 0
trb $d05d ; dis a bl e hot r e g i s t e r s

lda # % 0 1 0 0 0 0 0 0
tsb $d031 ; update a VIC - II / III r e g i s t e r

lda # % 1 0 0 0 0 0 0 0
trb $d05d ; clear p e n d i n g update
tsb $d05d ; re - enable hot r e g i s t e r s

NEW MODES

P-19
Why the new VIC-IV modes are Char-
acter and Bitmap modes, not Bitplane
modes
The new VIC-IV video modes are derived from the VIC-II character and bitmap modes,
rather than the VIC-III bitplane modes. This decision was based on several realities of
programming a memory-constrained 8-bit home computer:
1. Bitplanes require that the same amount of memory is given to each area on
screen, regardless of whether it is showing empty space, or complex graphics.
There is no way with bitplanes to reuse content from within an image in another
part of the image. However, most C64 games use highly repetitive displays, with
common elements appearing in various places on the screen, of which Boulder
Dash and Super Giana Sisters would be good examples.
2. Bitplanes also make it difficult to update a display, because every pixel is unique,
in that there is no way to make a change, for example to the animation in an
onscreen element, and have it take effect in all places at the same time. The
diamond animations in Boulder Dash are a good example of this problem. The
requirement to modify multiple separate bytes in each bitplane create an in-
creased computational burden, which is why there were calls for the Amiga AAA
chip-set to include so-called “chunky” modes, rather than just bitplane based
modes. While the Display Address Translator (DAT) and DMAgic of the C65 pro-
vide some relief to this problem, the relief is only partial.
3. Scrolling using the C65 bitplanes requires copying the entire bitplane, as the
hardware support for smooth scrolling does not extend to changing the bitplane
source address in a fine manner. Even using the DMAgic to assist, scrolling a
320×200 256-colour display requires 128,000 clock cycles in the best case
(reading and writing 320×200 = 64000 bytes). At 3.5MHz on the C65 this
would require about 36 milli-seconds, or about 2 complete video frames. Thus
for smooth scrolling of such a display, a double buffered arrangement would be
required, which would consume 128,000 of the 131,072 bytes of memory.
In contrast, the well known character modes of the VIC-II are widely used in
games, due to their ability to allow a small amount of screen memory to select
which 8×8 block of pixels to display, allowing very rapid scrolling, reduced mem-
ory consumption, and effective hardware acceleration of animation of common
elements. Thus the focus of improvements in the VIC-IV has been on character
mode. As bitmap mode on the VIC-II is effectively a special case of character
mode, with implied character numbers, it comes along free for the ride on the
VIC-IV, and will only be mentioned in the context of a very few bitmap-mode
specific improvements that were trivial to make, and it thus seemed foolish to
not implement, in case they find use.

P-20
Displaying more than 256 unique
characters via ”Super-Extended At-
tribute Mode”
The primary innovation is the addition of the Super-Extended Attribute Mode. The
VIC-II already uses 12 bits per character: Each 8×8 cell is defined by 12 bits of data:
8 bits of screen RAM data, by default from $0400 – $07E7 (1024 – 2023 decimal),
indicating which characters to show, and 4 bits of colour data from the 1K nibble
colour RAM at $D800 – $DBFF (55296 – 56319 decimal). The VIC-III of the C65
uses 16 bits, as the colour RAM is now 8 bits, instead of 4, with the extra 4 bits of
colour RAM being used to support attributes (blink, bold, underline and reverse video).
It is recommended to revise how this works, before reading the following. A good
introduction to the VIC-II text mode can be found in many places. Super-Extended
Attribute mode doubles the number of bits per character used from the VIC-III’s 16,
to 32: Two bytes of screen RAM and two bytes of colour/attribute RAM.
Super-Extended Attribute Mode is enabled by setting bit 0 in $D054 (53332 decimal).
Remember to first enable VIC-IV mode, to make this register accessible. When this bit
is set, two bytes are used for each of the screen memory and colour RAM for each
character shown on the display. Thus, in contrast to the 12 bits of information that
the C64 uses per character, and the 16 bits that the VIC-III uses, the VIC-IV has 32
bits of information. How those 32 bits are used varies slightly among the particular
modes, as described in the following tables, including whether the GOTOX bit is set.
Note also that enabling BOLD and REVERSE attributes at the same time on the
MEGA65 selects an alternate palette, effectively allowing 512 colours on screen, but
each 8×8 character can use colours only from one 256 colour palette.

P-21
Default Bit Fields (when GOTOX bit is
cleared):
Bit(s) Function when GOTOX bit is cleared
Screen RAM byte 0
Bits 7 - 0 Low byte of character number, the same as the VIC-II and VIC-III
Screen RAM byte 1
Bits 7 – 5 Trim pixels from right-hand side of character (bits 0 – 2)
Upper 5 bits of character number (bits 8 – 12), allowing
Bits 4 - 0
addressing of 8,192 unique characters
Colour RAM byte 0
Bit 7 Vertically flip the character
Bit 6 Horizontally flip the character
Enable alpha blend mode, pixel values are treated as alpha values
Bit 5 blending between foreground colour and background colour
(needs bit 7 of $d054 set)
GOTOX is cleared (set to 0)
GOTOX allows repositioning of characters along a raster via the
Raster-Rewrite Buffer, discussed later). Must be set to 0 for
Bit 4
displaying characters – when set, it moves the position where the
next character will be drawn, without actually drawing anything.
See the following table for more explanation of this mode.
If set, Full-Colour characters use 4 bits per pixel and are 16 pixels
wide (less any right-hand side trim bits), instead of using 8 bits per
Bit 3
pixel. When using 8 bits per pixels, the characters are the normal
8 pixels wide
Bit 2 Trim pixels from right-hand side of character (bit 3)
Bits 1 – 0 Number of pixels to trim from top or bottom of character
Colour RAM byte 1
If VIC-II multi-colour mode is enabled:
Bits 7 – 4 Upper 4 bits of colour of character
If VIC-III extended attributes are enabled:
Bit 7 Hardware underlining of character
Bit 6 Hardware bold attribute of character *
Bit 5 Hardware reverse video enable of character *
Bit 4 Hardware blink of character
Remaining bit-field is common:
Bits 3 – 0 Low 4 bits of colour of character

P-22
Bit Fields when GOTOX bit is set:
Bit(s) Function when GOTOX bit is set
Screen RAM byte 0
Lower 8 bits of new X position to start drawing the next character,
relative to the start of character drawing. Setting to 0 causes the
Bits 7 - 0
next character to be drawn over the top of the left-most
character.
Screen RAM byte 1
FCM Character data Y offset: Characters display normally when
set to zero. When non-zero, 8 × the value is added to the
Bits 7 - 5
character address. With careful planning, this can be used to
smoothly vertically scroll multiple layers of RRB content.
Bits 4 - 3 RESERVED, set to 0
Upper 2 bits of new X position (Highest bit is 2’s complement
Bits 1 - 0
signed bit)
Colour RAM byte 0
If set, then background/transparent pixels will not be drawn for
Bit 7
subsequent characters, allowing layering
If set, the following characters will be rendered as background,
Bit 6 allowing sprites to appear in front of them, even when sprites are
set to background.
Bit 5 RESERVED, set to 0
GOTOX, set to 1. GOTOX allows repositioning of characters
Bit 4
along a raster via the Raster-Rewrite Buffer, discussed later).
ROWMASK. If set, then the pixel row mask is used to determine
which pixel rows of the following characters should be rendered.
This can be used to vertically scroll characters using the
Raster-Rewrite Buffer, by drawing each character twice, once
Bit 3 shifted down on the screen line on which it appears, and a second
time, shifted up in the following screen line, and masked so that
only the pixel rows belonging to the scrolled character are
displayed, and not data from either before or after that
character’s data.
If set, the following characters will be drawn as foreground,
Bit 2
regardless of their colour, allowing sprites to appear behind them.
Bits 1 - 0 RESERVED, set to 0
Colour RAM byte 1
Bits 7 - 0 Pixel row mask flags

We can see that we still have the C64 style bottom 8 bits of the character number
in the first screen byte. The second byte of screen memory gets five extra bits for
that, allowing 213 = 8,192 different characters to be used on a single screen. That’s
more than enough for unique characters covering an 80×50 screen (which is possible

P-23
to create with the VIC-IV). The remaining bits allow for trimming of the character.
This allows for variable width characters, which can be used to do things that would
not normally be possible, such as using text mode for free horizontal placement of
characters (or parts thereof). This was originally added to provide hardware support
for proportional width fonts.
For the colour RAM, the second byte (byte 1) is the same as the C65, i.e., the lower
half providing four bits of foreground colour, as on the C64, plus the optional VIC-
III extended attributes. The C65 specifications document describes the behaviour
when more than one of these are used together, most of which are logical, but there
are a few combinations that behave differently than one might expect. For example,
combining bold with blink causes the character to toggle between bold and normal
mode. Bold mode itself is implemented by effectively acting as bit 4 of the foreground
colour value, causing the colour to be drawn from different palette entries than usual.
However, if you do not need VIC-III extended attributes, you can instead use the upper
four bits of the second byte of colour RAM to contain more bits for the colour index,
allowing selection from the full range of 256 colour entries. This mode is activated by
enabling the VIC-II’s multi-colour mode while full-colour mode is active.
The C65 / VIC-III attributes and the use of 256 colour 8-bit values for various VIC-II
colour registers is enabled by setting bit 5 of $D031 (53297 decimal). Therefore this
is highly recommended when using the VIC-IV mode, as otherwise certain functions
will not behave as expected. Note that BOLD+REVERSE together has the meaning of
selecting an alternate palette on the MEGA65, which differs from the C65.
Many effects are possible due to Super-Extended Attribute Mode. A few possibilities
are explained in the following sub-sections.

Using Super-Extended Attribute Mode


Super-Extended Attribute Mode requires double the screen RAM and colour RAM as
the VIC-II/III text modes. This is because two bytes of each are required to define each
character, instead of one. The screen RAM can be located anywhere in the 384KB of
main memory using registers $D060 – $D062 (53344 – 53346 decimal). The colour
RAM can be located anywhere in the 32KB colour RAM. Only the first 1 or 2KB of
the colour RAM is visible at $D800 – $DBFF or $D800 – $DFFF (if the CRAM2K signal
is set in bit 0 of $D030, 53296 decimal). Thus if using a screen larger than 40×25
characters use of the DMA controller or some other means is required to access the full
amount of colour RAM. Therefor we will initially discuss using Super-Extended Attribute
Mode with a 40x25 character display.
The first step is to enable the Super-Extended Attribute Mode by asserting the FCLRHI
and CHR16 signals, by setting bits 2 and 0 of $D054 (53332 decimal). As this is
a VIC-IV register, we must first enable the VIC-IV I/O mode. The VIC-IV must also
be configured to 40 column mode, by clearing the H640 signal by clearing bit 7 of
$D031 (53297 decimal). This is because each pair of characters will be used to form
a single character on screen, with one character requiring two screen RAM bytes, thus

P-24
80 screen RAM bytes are required to display 40 characters. Similarly 80 colour RAM
bytes are required as well.
To understand this visually, it is helpful to first consider the normal C64 screen memory
layout:

$400 $401 $402 $403 $404 $405 $406 $407 $408 $409 $40a $40b $40c $40d $40e $40f $410 $411 $412 $413 $414 $415 $416 $417 $418 $419 $41a $41b $41c $41d $41e $41f $420 $421 $422 $423 $424 $425 $426 $427

$428 $429 $42a $42b $42c $42d $42e $42f $430 $431 $432 $433 $434 $435 $436 $437 $438 $439 $43a $43b $43c $43d $43e $43f $440 $441 $442 $443 $444 $445 $446 $447 $448 $449 $44a $44b $44c $44d $44e $44f

$450 $451 $452 $453 $454 $455 $456 $457 $458 $459 $45a $45b $45c $45d $45e $45f $460 $461 $462 $463 $464 $465 $466 $467 $468 $469 $46a $46b $46c $46d $46e $46f $470 $471 $472 $473 $474 $475 $476 $477

$478 $479 $47a $47b $47c $47d $47e $47f $480 $481 $482 $483 $484 $485 $486 $487 $488 $489 $48a $48b $48c $48d $48e $48f $490 $491 $492 $493 $494 $495 $496 $497 $498 $499 $49a $49b $49c $49d $49e $49f

$4a0 $4a1 $4a2 $4a3 $4a4 $4a5 $4a6 $4a7 $4a8 $4a9 $4aa $4ab $4ac $4ad $4ae $4af $4b0 $4b1 $4b2 $4b3 $4b4 $4b5 $4b6 $4b7 $4b8 $4b9 $4ba $4bb $4bc $4bd $4be $4bf $4c0 $4c1 $4c2 $4c3 $4c4 $4c5 $4c6 $4c7

$4c8 $4c9 $4ca $4cb $4cc $4cd $4ce $4cf $4d0 $4d1 $4d2 $4d3 $4d4 $4d5 $4d6 $4d7 $4d8 $4d9 $4da $4db $4dc $4dd $4de $4df $4e0 $4e1 $4e2 $4e3 $4e4 $4e5 $4e6 $4e7 $4e8 $4e9 $4ea $4eb $4ec $4ed $4ee $4ef

$4f0 $4f1 $4f2 $4f3 $4f4 $4f5 $4f6 $4f7 $4f8 $4f9 $4fa $4fb $4fc $4fd $4fe $4ff $500 $501 $502 $503 $504 $505 $506 $507 $508 $509 $50a $50b $50c $50d $50e $50f $510 $511 $512 $513 $514 $515 $516 $517

$518 $519 $51a $51b $51c $51d $51e $51f $520 $521 $522 $523 $524 $525 $526 $527 $528 $529 $52a $52b $52c $52d $52e $52f $530 $531 $532 $533 $534 $535 $536 $537 $538 $539 $53a $53b $53c $53d $53e $53f

$540 $541 $542 $543 $544 $545 $546 $547 $548 $549 $54a $54b $54c $54d $54e $54f $550 $551 $552 $553 $554 $555 $556 $557 $558 $559 $55a $55b $55c $55d $55e $55f $560 $561 $562 $563 $564 $565 $566 $567

$568 $569 $56a $56b $56c $56d $56e $56f $570 $571 $572 $573 $574 $575 $576 $577 $578 $579 $57a $57b $57c $57d $57e $57f $580 $581 $582 $583 $584 $585 $586 $587 $588 $589 $58a $58b $58c $58d $58e $58f

$590 $591 $592 $593 $594 $595 $596 $597 $598 $599 $59a $59b $59c $59d $59e $59f $5a0 $5a1 $5a2 $5a3 $5a4 $5a5 $5a6 $5a7 $5a8 $5a9 $5aa $5ab $5ac $5ad $5ae $5af $5b0 $5b1 $5b2 $5b3 $5b4 $5b5 $5b6 $5b7

$5b8 $5b9 $5ba $5bb $5bc $5bd $5be $5bf $5c0 $5c1 $5c2 $5c3 $5c4 $5c5 $5c6 $5c7 $5c8 $5c9 $5ca $5cb $5cc $5cd $5ce $5cf $5d0 $5d1 $5d2 $5d3 $5d4 $5d5 $5d6 $5d7 $5d8 $5d9 $5da $5db $5dc $5dd $5de $5df

$5e0 $5e1 $5e2 $5e3 $5e4 $5e5 $5e6 $5e7 $5e8 $5e9 $5ea $5eb $5ec $5ed $5ee $5ef $5f0 $5f1 $5f2 $5f3 $5f4 $5f5 $5f6 $5f7 $5f8 $5f9 $5fa $5fb $5fc $5fd $5fe $5ff $600 $601 $602 $603 $604 $605 $606 $607

$608 $609 $60a $60b $60c $60d $60e $60f $610 $611 $612 $613 $614 $615 $616 $617 $618 $619 $61a $61b $61c $61d $61e $61f $620 $621 $622 $623 $624 $625 $626 $627 $628 $629 $62a $62b $62c $62d $62e $62f

$630 $631 $632 $633 $634 $635 $636 $637 $638 $639 $63a $63b $63c $63d $63e $63f $640 $641 $642 $643 $644 $645 $646 $647 $648 $649 $64a $64b $64c $64d $64e $64f $650 $651 $652 $653 $654 $655 $656 $657

$658 $659 $65a $65b $65c $65d $65e $65f $660 $661 $662 $663 $664 $665 $666 $667 $668 $669 $66a $66b $66c $66d $66e $66f $670 $671 $672 $673 $674 $675 $676 $677 $678 $679 $67a $67b $67c $67d $67e $67f

$680 $681 $682 $683 $684 $685 $686 $687 $688 $689 $68a $68b $68c $68d $68e $68f $690 $691 $692 $693 $694 $695 $696 $697 $698 $699 $69a $69b $69c $69d $69e $69f $6a0 $6a1 $6a2 $6a3 $6a4 $6a5 $6a6 $6a7

$6a8 $6a9 $6aa $6ab $6ac $6ad $6ae $6af $6b0 $6b1 $6b2 $6b3 $6b4 $6b5 $6b6 $6b7 $6b8 $6b9 $6ba $6bb $6bc $6bd $6be $6bf $6c0 $6c1 $6c2 $6c3 $6c4 $6c5 $6c6 $6c7 $6c8 $6c9 $6ca $6cb $6cc $6cd $6ce $6cf

$6d0 $6d1 $6d2 $6d3 $6d4 $6d5 $6d6 $6d7 $6d8 $6d9 $6da $6db $6dc $6dd $6de $6df $6e0 $6e1 $6e2 $6e3 $6e4 $6e5 $6e6 $6e7 $6e8 $6e9 $6ea $6eb $6ec $6ed $6ee $6ef $6f0 $6f1 $6f2 $6f3 $6f4 $6f5 $6f6 $6f7

$6f8 $6f9 $6fa $6fb $6fc $6fd $6fe $6ff $700 $701 $702 $703 $704 $705 $706 $707 $708 $709 $70a $70b $70c $70d $70e $70f $710 $711 $712 $713 $714 $715 $716 $717 $718 $719 $71a $71b $71c $71d $71e $71f

$720 $721 $722 $723 $724 $725 $726 $727 $728 $729 $72a $72b $72c $72d $72e $72f $730 $731 $732 $733 $734 $735 $736 $737 $738 $739 $73a $73b $73c $73d $73e $73f $740 $741 $742 $743 $744 $745 $746 $747

$748 $749 $74a $74b $74c $74d $74e $74f $750 $751 $752 $753 $754 $755 $756 $757 $758 $759 $75a $75b $75c $75d $75e $75f $760 $761 $762 $763 $764 $765 $766 $767 $768 $769 $76a $76b $76c $76d $76e $76f

$770 $771 $772 $773 $774 $775 $776 $777 $778 $779 $77a $77b $77c $77d $77e $77f $780 $781 $782 $783 $784 $785 $786 $787 $788 $789 $78a $78b $78c $78d $78e $78f $790 $791 $792 $793 $794 $795 $796 $797

$798 $799 $79a $79b $79c $79d $79e $79f $7a0 $7a1 $7a2 $7a3 $7a4 $7a5 $7a6 $7a7 $7a8 $7a9 $7aa $7ab $7ac $7ad $7ae $7af $7b0 $7b1 $7b2 $7b3 $7b4 $7b5 $7b6 $7b7 $7b8 $7b9 $7ba $7bb $7bc $7bd $7be $7bf

$7c0 $7c1 $7c2 $7c3 $7c4 $7c5 $7c6 $7c7 $7c8 $7c9 $7ca $7cb $7cc $7cd $7ce $7cf $7d0 $7d1 $7d2 $7d3 $7d4 $7d5 $7d6 $7d7 $7d8 $7d9 $7da $7db $7dc $7dd $7de $7df $7e0 $7e1 $7e2 $7e3 $7e4 $7e5 $7e6 $7e7

That is, each character cell uses one byte of screen RAM, and the addresses increase
smoothly, both within lines, and between lines. Super-Extended Attribute Mode re-
quires two bytes per character cell. So if you set $D054 to $05, for example, you will
get screen addresses like this:

P-25
$400 $402 $404 $406 $408 $40a $40c $40e $410 $412 $414 $416 $418 $41a $41c $41e $420 $422 $424 $426 $428 $42a $42c $42e $430 $432 $434 $436 $438 $43a $43c $43e $440 $442 $444 $446 $448 $44a $44c $44e

$428 $42a $42c $42e $430 $432 $434 $436 $438 $43a $43c $43e $440 $442 $444 $446 $448 $44a $44c $44e $450 $452 $454 $456 $458 $45a $45c $45e $460 $462 $464 $466 $468 $46a $46c $46e $470 $472 $474 $476

$450 $452 $454 $456 $458 $45a $45c $45e $460 $462 $464 $466 $468 $46a $46c $46e $470 $472 $474 $476 $478 $47a $47c $47e $480 $482 $484 $486 $488 $48a $48c $48e $490 $492 $494 $496 $498 $49a $49c $49e

$478 $47a $47c $47e $480 $482 $484 $486 $488 $48a $48c $48e $490 $492 $494 $496 $498 $49a $49c $49e $4a0 $4a2 $4a4 $4a6 $4a8 $4aa $4ac $4ae $4b0 $4b2 $4b4 $4b6 $4b8 $4ba $4bc $4be $4c0 $4c2 $4c4 $4c6

$4a0 $4a2 $4a4 $4a6 $4a8 $4aa $4ac $4ae $4b0 $4b2 $4b4 $4b6 $4b8 $4ba $4bc $4be $4c0 $4c2 $4c4 $4c6 $4c8 $4ca $4cc $4ce $4d0 $4d2 $4d4 $4d6 $4d8 $4da $4dc $4de $4e0 $4e2 $4e4 $4e6 $4e8 $4ea $4ec $4ee

$4c8 $4ca $4cc $4ce $4d0 $4d2 $4d4 $4d6 $4d8 $4da $4dc $4de $4e0 $4e2 $4e4 $4e6 $4e8 $4ea $4ec $4ee $4f0 $4f2 $4f4 $4f6 $4f8 $4fa $4fc $4fe $500 $502 $504 $506 $508 $50a $50c $50e $510 $512 $514 $516

$4f0 $4f2 $4f4 $4f6 $4f8 $4fa $4fc $4fe $500 $502 $504 $506 $508 $50a $50c $50e $510 $512 $514 $516 $518 $51a $51c $51e $520 $522 $524 $526 $528 $52a $52c $52e $530 $532 $534 $536 $538 $53a $53c $53e

$518 $51a $51c $51e $520 $522 $524 $526 $528 $52a $52c $52e $530 $532 $534 $536 $538 $53a $53c $53e $540 $542 $544 $546 $548 $54a $54c $54e $550 $552 $554 $556 $558 $55a $55c $55e $560 $562 $564 $566

$540 $542 $544 $546 $548 $54a $54c $54e $550 $552 $554 $556 $558 $55a $55c $55e $560 $562 $564 $566 $568 $56a $56c $56e $570 $572 $574 $576 $578 $57a $57c $57e $580 $582 $584 $586 $588 $58a $58c $58e

$568 $56a $56c $56e $570 $572 $574 $576 $578 $57a $57c $57e $580 $582 $584 $586 $588 $58a $58c $58e $590 $592 $594 $596 $598 $59a $59c $59e $5a0 $5a2 $5a4 $5a6 $5a8 $5aa $5ac $5ae $5b0 $5b2 $5b4 $5b6

$590 $592 $594 $596 $598 $59a $59c $59e $5a0 $5a2 $5a4 $5a6 $5a8 $5aa $5ac $5ae $5b0 $5b2 $5b4 $5b6 $5b8 $5ba $5bc $5be $5c0 $5c2 $5c4 $5c6 $5c8 $5ca $5cc $5ce $5d0 $5d2 $5d4 $5d6 $5d8 $5da $5dc $5de

$5b8 $5ba $5bc $5be $5c0 $5c2 $5c4 $5c6 $5c8 $5ca $5cc $5ce $5d0 $5d2 $5d4 $5d6 $5d8 $5da $5dc $5de $5e0 $5e2 $5e4 $5e6 $5e8 $5ea $5ec $5ee $5f0 $5f2 $5f4 $5f6 $5f8 $5fa $5fc $5fe $600 $602 $604 $606

$5e0 $5e2 $5e4 $5e6 $5e8 $5ea $5ec $5ee $5f0 $5f2 $5f4 $5f6 $5f8 $5fa $5fc $5fe $600 $602 $604 $606 $608 $60a $60c $60e $610 $612 $614 $616 $618 $61a $61c $61e $620 $622 $624 $626 $628 $62a $62c $62e

$608 $60a $60c $60e $610 $612 $614 $616 $618 $61a $61c $61e $620 $622 $624 $626 $628 $62a $62c $62e $630 $632 $634 $636 $638 $63a $63c $63e $640 $642 $644 $646 $648 $64a $64c $64e $650 $652 $654 $656

$630 $632 $634 $636 $638 $63a $63c $63e $640 $642 $644 $646 $648 $64a $64c $64e $650 $652 $654 $656 $658 $65a $65c $65e $660 $662 $664 $666 $668 $66a $66c $66e $670 $672 $674 $676 $678 $67a $67c $67e

$658 $65a $65c $65e $660 $662 $664 $666 $668 $66a $66c $66e $670 $672 $674 $676 $678 $67a $67c $67e $680 $682 $684 $686 $688 $68a $68c $68e $690 $692 $694 $696 $698 $69a $69c $69e $6a0 $6a2 $6a4 $6a6

$680 $682 $684 $686 $688 $68a $68c $68e $690 $692 $694 $696 $698 $69a $69c $69e $6a0 $6a2 $6a4 $6a6 $6a8 $6aa $6ac $6ae $6b0 $6b2 $6b4 $6b6 $6b8 $6ba $6bc $6be $6c0 $6c2 $6c4 $6c6 $6c8 $6ca $6cc $6ce

$6a8 $6aa $6ac $6ae $6b0 $6b2 $6b4 $6b6 $6b8 $6ba $6bc $6be $6c0 $6c2 $6c4 $6c6 $6c8 $6ca $6cc $6ce $6d0 $6d2 $6d4 $6d6 $6d8 $6da $6dc $6de $6e0 $6e2 $6e4 $6e6 $6e8 $6ea $6ec $6ee $6f0 $6f2 $6f4 $6f6

$6d0 $6d2 $6d4 $6d6 $6d8 $6da $6dc $6de $6e0 $6e2 $6e4 $6e6 $6e8 $6ea $6ec $6ee $6f0 $6f2 $6f4 $6f6 $6f8 $6fa $6fc $6fe $700 $702 $704 $706 $708 $70a $70c $70e $710 $712 $714 $716 $718 $71a $71c $71e

$6f8 $6fa $6fc $6fe $700 $702 $704 $706 $708 $70a $70c $70e $710 $712 $714 $716 $718 $71a $71c $71e $720 $722 $724 $726 $728 $72a $72c $72e $730 $732 $734 $736 $738 $73a $73c $73e $740 $742 $744 $746

$720 $722 $724 $726 $728 $72a $72c $72e $730 $732 $734 $736 $738 $73a $73c $73e $740 $742 $744 $746 $748 $74a $74c $74e $750 $752 $754 $756 $758 $75a $75c $75e $760 $762 $764 $766 $768 $76a $76c $76e

$748 $74a $74c $74e $750 $752 $754 $756 $758 $75a $75c $75e $760 $762 $764 $766 $768 $76a $76c $76e $770 $772 $774 $776 $778 $77a $77c $77e $780 $782 $784 $786 $788 $78a $78c $78e $790 $792 $794 $796

$770 $772 $774 $776 $778 $77a $77c $77e $780 $782 $784 $786 $788 $78a $78c $78e $790 $792 $794 $796 $798 $79a $79c $79e $7a0 $7a2 $7a4 $7a6 $7a8 $7aa $7ac $7ae $7b0 $7b2 $7b4 $7b6 $7b8 $7ba $7bc $7be

$798 $79a $79c $79e $7a0 $7a2 $7a4 $7a6 $7a8 $7aa $7ac $7ae $7b0 $7b2 $7b4 $7b6 $7b8 $7ba $7bc $7be $7c0 $7c2 $7c4 $7c6 $7c8 $7ca $7cc $7ce $7d0 $7d2 $7d4 $7d6 $7d8 $7da $7dc $7de $7e0 $7e2 $7e4 $7e6

$7c0 $7c2 $7c4 $7c6 $7c8 $7ca $7cc $7ce $7d0 $7d2 $7d4 $7d6 $7d8 $7da $7dc $7de $7e0 $7e2 $7e4 $7e6 $7e8 $7ea $7ec $7ee $7f0 $7f2 $7f4 $7f6 $7f8 $7fa $7fc $7fe $800 $802 $804 $806 $808 $80a $80c $80e

There are two things to notice in the above table: First, the address advances by
two bytes for each character cell, because two bytes are required to define each
character. Second, the start address of each screen line still only advances by 40
($28 in hexadecimal). This isn’t what we really want, because it means that half of
the previous row will get displayed again on each current row. This is fixed by setting
the number of bytes to advance each screen row in $D058 (LSB) and $D059 (MSB).
So in this case, we want to increase the number of bytes skipped each line from 40
bytes, to 80 bytes, which we can do by setting $D058 to 80 ($50 in hexadecimal),
and $D059 to 0. This gives us a screen layout like this:

P-26
$400 $402 $404 $406 $408 $40a $40c $40e $410 $412 $414 $416 $418 $41a $41c $41e $420 $422 $424 $426 $428 $42a $42c $42e $430 $432 $434 $436 $438 $43a $43c $43e $440 $442 $444 $446 $448 $44a $44c $44e

$450 $452 $454 $456 $458 $45a $45c $45e $460 $462 $464 $466 $468 $46a $46c $46e $470 $472 $474 $476 $478 $47a $47c $47e $480 $482 $484 $486 $488 $48a $48c $48e $490 $492 $494 $496 $498 $49a $49c $49e

$4a0 $4a2 $4a4 $4a6 $4a8 $4aa $4ac $4ae $4b0 $4b2 $4b4 $4b6 $4b8 $4ba $4bc $4be $4c0 $4c2 $4c4 $4c6 $4c8 $4ca $4cc $4ce $4d0 $4d2 $4d4 $4d6 $4d8 $4da $4dc $4de $4e0 $4e2 $4e4 $4e6 $4e8 $4ea $4ec $4ee

$4f0 $4f2 $4f4 $4f6 $4f8 $4fa $4fc $4fe $500 $502 $504 $506 $508 $50a $50c $50e $510 $512 $514 $516 $518 $51a $51c $51e $520 $522 $524 $526 $528 $52a $52c $52e $530 $532 $534 $536 $538 $53a $53c $53e

$540 $542 $544 $546 $548 $54a $54c $54e $550 $552 $554 $556 $558 $55a $55c $55e $560 $562 $564 $566 $568 $56a $56c $56e $570 $572 $574 $576 $578 $57a $57c $57e $580 $582 $584 $586 $588 $58a $58c $58e

$590 $592 $594 $596 $598 $59a $59c $59e $5a0 $5a2 $5a4 $5a6 $5a8 $5aa $5ac $5ae $5b0 $5b2 $5b4 $5b6 $5b8 $5ba $5bc $5be $5c0 $5c2 $5c4 $5c6 $5c8 $5ca $5cc $5ce $5d0 $5d2 $5d4 $5d6 $5d8 $5da $5dc $5de

$5e0 $5e2 $5e4 $5e6 $5e8 $5ea $5ec $5ee $5f0 $5f2 $5f4 $5f6 $5f8 $5fa $5fc $5fe $600 $602 $604 $606 $608 $60a $60c $60e $610 $612 $614 $616 $618 $61a $61c $61e $620 $622 $624 $626 $628 $62a $62c $62e

$630 $632 $634 $636 $638 $63a $63c $63e $640 $642 $644 $646 $648 $64a $64c $64e $650 $652 $654 $656 $658 $65a $65c $65e $660 $662 $664 $666 $668 $66a $66c $66e $670 $672 $674 $676 $678 $67a $67c $67e

$680 $682 $684 $686 $688 $68a $68c $68e $690 $692 $694 $696 $698 $69a $69c $69e $6a0 $6a2 $6a4 $6a6 $6a8 $6aa $6ac $6ae $6b0 $6b2 $6b4 $6b6 $6b8 $6ba $6bc $6be $6c0 $6c2 $6c4 $6c6 $6c8 $6ca $6cc $6ce

$6d0 $6d2 $6d4 $6d6 $6d8 $6da $6dc $6de $6e0 $6e2 $6e4 $6e6 $6e8 $6ea $6ec $6ee $6f0 $6f2 $6f4 $6f6 $6f8 $6fa $6fc $6fe $700 $702 $704 $706 $708 $70a $70c $70e $710 $712 $714 $716 $718 $71a $71c $71e

$720 $722 $724 $726 $728 $72a $72c $72e $730 $732 $734 $736 $738 $73a $73c $73e $740 $742 $744 $746 $748 $74a $74c $74e $750 $752 $754 $756 $758 $75a $75c $75e $760 $762 $764 $766 $768 $76a $76c $76e

$770 $772 $774 $776 $778 $77a $77c $77e $780 $782 $784 $786 $788 $78a $78c $78e $790 $792 $794 $796 $798 $79a $79c $79e $7a0 $7a2 $7a4 $7a6 $7a8 $7aa $7ac $7ae $7b0 $7b2 $7b4 $7b6 $7b8 $7ba $7bc $7be

$7c0 $7c2 $7c4 $7c6 $7c8 $7ca $7cc $7ce $7d0 $7d2 $7d4 $7d6 $7d8 $7da $7dc $7de $7e0 $7e2 $7e4 $7e6 $7e8 $7ea $7ec $7ee $7f0 $7f2 $7f4 $7f6 $7f8 $7fa $7fc $7fe $800 $802 $804 $806 $808 $80a $80c $80e

$810 $812 $814 $816 $818 $81a $81c $81e $820 $822 $824 $826 $828 $82a $82c $82e $830 $832 $834 $836 $838 $83a $83c $83e $840 $842 $844 $846 $848 $84a $84c $84e $850 $852 $854 $856 $858 $85a $85c $85e

$860 $862 $864 $866 $868 $86a $86c $86e $870 $872 $874 $876 $878 $87a $87c $87e $880 $882 $884 $886 $888 $88a $88c $88e $890 $892 $894 $896 $898 $89a $89c $89e $8a0 $8a2 $8a4 $8a6 $8a8 $8aa $8ac $8ae

$8b0 $8b2 $8b4 $8b6 $8b8 $8ba $8bc $8be $8c0 $8c2 $8c4 $8c6 $8c8 $8ca $8cc $8ce $8d0 $8d2 $8d4 $8d6 $8d8 $8da $8dc $8de $8e0 $8e2 $8e4 $8e6 $8e8 $8ea $8ec $8ee $8f0 $8f2 $8f4 $8f6 $8f8 $8fa $8fc $8fe

$900 $902 $904 $906 $908 $90a $90c $90e $910 $912 $914 $916 $918 $91a $91c $91e $920 $922 $924 $926 $928 $92a $92c $92e $930 $932 $934 $936 $938 $93a $93c $93e $940 $942 $944 $946 $948 $94a $94c $94e

$950 $952 $954 $956 $958 $95a $95c $95e $960 $962 $964 $966 $968 $96a $96c $96e $970 $972 $974 $976 $978 $97a $97c $97e $980 $982 $984 $986 $988 $98a $98c $98e $990 $992 $994 $996 $998 $99a $99c $99e

$9a0 $9a2 $9a4 $9a6 $9a8 $9aa $9ac $9ae $9b0 $9b2 $9b4 $9b6 $9b8 $9ba $9bc $9be $9c0 $9c2 $9c4 $9c6 $9c8 $9ca $9cc $9ce $9d0 $9d2 $9d4 $9d6 $9d8 $9da $9dc $9de $9e0 $9e2 $9e4 $9e6 $9e8 $9ea $9ec $9ee

$9f0 $9f2 $9f4 $9f6 $9f8 $9fa $9fc $9fe $a00 $a02 $a04 $a06 $a08 $a0a $a0c $a0e $a10 $a12 $a14 $a16 $a18 $a1a $a1c $a1e $a20 $a22 $a24 $a26 $a28 $a2a $a2c $a2e $a30 $a32 $a34 $a36 $a38 $a3a $a3c $a3e

$a40 $a42 $a44 $a46 $a48 $a4a $a4c $a4e $a50 $a52 $a54 $a56 $a58 $a5a $a5c $a5e $a60 $a62 $a64 $a66 $a68 $a6a $a6c $a6e $a70 $a72 $a74 $a76 $a78 $a7a $a7c $a7e $a80 $a82 $a84 $a86 $a88 $a8a $a8c $a8e

$a90 $a92 $a94 $a96 $a98 $a9a $a9c $a9e $aa0 $aa2 $aa4 $aa6 $aa8 $aaa $aac $aae $ab0 $ab2 $ab4 $ab6 $ab8 $aba $abc $abe $ac0 $ac2 $ac4 $ac6 $ac8 $aca $acc $ace $ad0 $ad2 $ad4 $ad6 $ad8 $ada $adc $ade

$ae0 $ae2 $ae4 $ae6 $ae8 $aea $aec $aee $af0 $af2 $af4 $af6 $af8 $afa $afc $afe $b00 $b02 $b04 $b06 $b08 $b0a $b0c $b0e $b10 $b12 $b14 $b16 $b18 $b1a $b1c $b1e $b20 $b22 $b24 $b26 $b28 $b2a $b2c $b2e

$b30 $b32 $b34 $b36 $b38 $b3a $b3c $b3e $b40 $b42 $b44 $b46 $b48 $b4a $b4c $b4e $b50 $b52 $b54 $b56 $b58 $b5a $b5c $b5e $b60 $b62 $b64 $b66 $b68 $b6a $b6c $b6e $b70 $b72 $b74 $b76 $b78 $b7a $b7c $b7e

$b80 $b82 $b84 $b86 $b88 $b8a $b8c $b8e $b90 $b92 $b94 $b96 $b98 $b9a $b9c $b9e $ba0 $ba2 $ba4 $ba6 $ba8 $baa $bac $bae $bb0 $bb2 $bb4 $bb6 $bb8 $bba $bbc $bbe $bc0 $bc2 $bc4 $bc6 $bc8 $bca $bcc $bce

It is possible to use Super-Extended Attribute Mode from C65-mode, by setting the


screen to 80 columns, as the C65 ROM sets up 2KB for both the screen RAM and
colour RAM, and this automatically sets $D058 and $D059 to the correct value for
40×2 = 80 bytes per screen line. The user need only to treat each character pair as a
single Super-Extended Attribute character, and to enable Super-Extended Attribute
Mode, as described above.
Because pairs of colour RAM and screen RAM bytes are used to define each character,
care must be taken to initialise and manipulate the screen. A good approach is to set
the text colour to black, because this is colour code 0, and then to fill the screen with
@ characters, because that is character code 0. You can then have several ways to
manipulate the screen. You can use the normal PRINT command and carefully construct
strings that will put the correct values into each screen and colour byte pair. Another
approach is to use the BANK and POKE commands to directly set the contents of the
screen and colour RAM.
Managing a Super-Extended Attribute Mode screen in this way using BASIC 65 is
of course rather a hack, and is only suggested as a relatively simple way to begin
experimenting. You will almost certainly want to quickly move to using custom screen
handling code, most probably in assembly, to manipulate Super-Extended Attribute
Mode screens, although this approach of using BASIC 65 can be quite powerful, by
allowing use of existing screen scrolling and other manipulations.
XXX Example program
The following descriptions assume that you have implemented one of the methods
described above to set the screen and colour RAM.

P-27
Full-Colour (256 colours per charac-
ter) Text Mode (FCM)
In normal VIC-II/III text mode, one byte is used for each row of pixels in a character.
As a reminder for how those modes work, in hi-res mode, each pixel is either the back-
ground or foreground colour, based on the state of one bit in the byte. Multi-colour
mode uses two bits to select between four possible colours, but as there are still only
8 bits to describe each row of 8 pixels, each pair of pixels has the same colour. The
VIC-IV’s full-colour text mode removes these limitations, and allows each pixel of a
character to be chosen from the 256 colour of either the primary or alternate palette
bank, without sacrificing horizontal resolution.
To do this, each character now requires 64 bytes of data. The address of the data
is 64 × the character number, regardless of the character set address. FCM should
normally be used with Super-Extended Attribute Mode (SEAM), so that more than 256
unique characters can be address. As SEAM allows the selection of 8,192 unique
characters, this allows FCM character data to be placed anywhere in the first 512KB
of chip RAM (but note that most models of the MEGA65 have only 384KB of chip RAM).
Please note that the pixel value $ff will not select the corresponding colour code di-
rectly. Instead, it will select the colour code defined by the colour RAM.

Nibble-colour (16 colours per charac-


ter) Text Mode (NCM)
The Nibble-Colour Mode (NCM) for text is similar to Full-Colour Text Mode, except that
each byte of data describes two pixels using 4 bits each. This makes the NCM unique,
because the characters will be 16 pixels wide, instead of the usual 8 pixels wide.
This can be used to create colourful displays, without using as much memory as FCM,
because fewer characters are required to cover the screen. Unlike the VIC-II’s MCM,
this mode does not result in a loss of horizontal resolution.
In NCM the lower four bits of the pixel colour comes from the upper or lower four bits of
the pixel data. The upper four bits of the colour code come from the colour RAM data
for the displayed character. This makes it possible to use all palette entries in NCM,
although the limitation of 16 colours per character remains. Similar to the behaviour
of FCM, the pixel data value $f will select the pixel colour set in the colour RAM.
A further advantage of NCM is that it uses fewer bus cycles per pixel than FCM, be-
cause fewer character data fetches need to occur per raster line. Together with the
reduced memory requirements, this makes NCM particularly useful for creating colour-
ful multiple layers of graphics. This allows the VIC-IV to display arcade style displays
with more colours than many 16-bit computers.
XXX

P-28
Alpha-Blending / Anti-Aliasing
The VIC-IV supports blending of characters with the background colour, enabling ef-
fects such as anti-aliased font rendering. Blending is possible on a per character basis.
It is enabled for a specific character if the following conditions are met:
1. The ALPHAEN signal is set in bit 7 of $D054.
2. The CHR16 signal is set in bit 0 of $D054 to enable Super-Extended Attribute
Mode (SEAM).
3. Full-Colour Text Mode (FCM) is enabled for the character.
If alpha-blending is enabled for a character, its 8-bit pixel values are treated as alpha
values instead of palette indices. The actual pixel colour is determined by blending
the background colour with the character’s foreground colour defined in the colour
RAM. An alpha value of 0 represents full transparency, showing only the background
colour for that pixel.
Note that the alpha-blending is only applied between the background colour and the
character’s foreground colour. This means that any characters behind the current
character will effectively not be visible (character layers can be composed by using
GOTOX repositioning). However, programmers should assume that blending with pre-
vious layers will be supported in a future implementation. To avoid issues with such
a change you should not put any characters behind a character with alpha-blending
enabled.

Flipping Characters
XXX

Variable Width Fonts


There are 4 bits that allow trimming pixels from the right edge of characters when they
are displayed. This has the effect of making characters narrower. This can be useful
for making more attractive text displays, where narrow characters, such as “i” take
less space than wider characters, such as “m”, without having to use a bitmap display.
This feature can be used to make it very efficient to display such variable-width text
displays – both in terms of memory usage and processing time.
This feature can be combined with full-colour text mode, alpha blending mode and
4-bits per pixel mode to allow characters that consist of 15 levels of intensity between
the background and foreground colour, and that are up to 16 pixels wide. Further,
the GOTO bit can be used to implement negative kerning, so that character pairs like
A and T do not have excessive white space between them when printed adjacently.
The prudent use of these features can result in highly impressive text display, similar to

P-29
that on modern 32-bit and 64-bit systems, but that are still efficient enough to be im-
plemented on a relatively constrained system such as the MEGA65. The “MegaWAT!?”
presentation software for the MEGA65 uses several of these features to produce its
attractive anti-aliased proportional text display on slides.
XXX MEGAWat!? screenshot
XXX Example program

Raster Re-write Buffer


If the GOTO bit is set for a character in Super-Extended Attribute Mode, instead of
painting a character, the position on the raster is back-tracked (or advanced forward
to) the pixel position specified in the low 10 bits of the screen memory bytes. If the
vertical flip bit is set, then this has the alternate meaning of preventing the background
colour from being painted. This combination can be used to print text material over
the top of other text material, providing a crude supplement to the 8 hardware sprites.
The amount of material is limited only by the raster time of the VIC-IV. Some experi-
mentation will be required to determine how much can be achieved in PAL and NTSC
modes.
If the GOTO bit is set for a character, and the character width reduction bits are also
set, they are interpretted as a Y offset to add to the character data address, but
only in Full Colour Mode. Setting Y=1 causes the character data to be fetched from
8 bytes later, i.e., the first row of character data will come from the address where
the second row of character data would normally be fetched. Similary for increased
values the character data will be fetched from further character rows. With careful
arrangement of characters in memory, it is possible to use this feature to provide free
vertical placement of soft sprites, without needing to copy the character data.
If the GOTO bit is set for a character, and the Nybl Colour Mode (NCM) bit is also
set, then the second colour RAM byte for that character is used to set the Row Mask
bits. For each bit set in the row mask, the corresponding row of characters in the line
will not be displayed. This can be used in combination with the Y offset feature to
effectively provide a character by character smooth vertical scrolling function.
This ability to draw multiple layers of text and graphics is highly powerful. For example,
it can be used to provide multiple overlapping layers of separately scrollable graphics.
This gives many of the advantages of bitplane-based play-fields on other computers,
such as the Amiga, but without the disadvantages of bitplanes.
A good introduction to the Raster Re-write Buffer and its uses can be found in this
video:
https://www.youtube.com/watch?v=00bm5uBeBos&feature=youtu.be
One important aspect of the RRB, is that the VIC-IV will display only the character
data to the left of, and including, the last drawn character. This means that if you use
the GOTO token to overwrite multiple layers of graphics, you must either make sure

P-30
that the last layer reaches to the right-hand edge of the display, or you must include
a GOTO token that moves the render position to the right-hand edge of the display.
XXX Example program

SPRITES
VIC-II/III Sprite Control
The control of sprites for C64 / VIC-II/III compatibility is unchanged from the C64. The
only practical differences are very minor. In particular the VIC-IV uses ring-buffer for
each sprites data when rendering a raster. This means that a sprite can be displayed
multiple times per raster line, thus potentially allowing for horizontal multiplexing.

Extended Sprite Image Sets


On the VIC-II and VIC-III, all sprites must draw their image data from a single 16KB
region of memory at any point in time. This limits the number of different sprite images
to 256, because each sprite image occupies 64 bytes. In practice, the same 16KB
region must also contain either bitmap, text or bitplane data, considerably reducing
the number of sprite images that can be used at the same time.
The VIC-IV removes this limitation, by allowing sprite data to be placed anywhere in
memory, although still on 64-byte boundaries. This is done by setting the SPRPTR16
signal (bit 7, $D06E, decimal 53358), which tells the VIC-IV to expect two bytes per
sprite pointer instead of one. These addresses are then absolute addresses, and ignore
the 16KB VIC-II bank selection logic. Thus 16 bytes are required instead of 8 bytes.
The list of pointers can also be placed anywhere in memory by setting the SPRPTRADR
($D06C – $D06D, 53356 – 53357 decimal) and SPRPTRBNK signals (bits 0 – 6, $D06E,
53358 decimal). This allows for sprite data to be located anywhere in the first 4MB of
RAM, and the sprite pointer list to be located anywhere in the first 8MB of RAM. Note
that typical installations of the VIC-IV have only 384KB of connected RAM, so these
limitations are of no practical effect. However, the upper bits of the SPRPTRBNK signal
should be set to zero to avoid forward-compatibility problems.
One reason for supporting more sprite images is that sprites on the VIC-IV can require
more than one 64 byte image slot. For example, enabling Extra-Wide Sprite Mode
means that a sprite will require 8×21 = 168 bytes, and will thus occupy four VIC-II
style 64 byte sprite image slots. If variable height sprites are used, this can grow to
as much as 8×255 = 2,040 bytes per sprite.

P-31
Variable Sprite Size
Sprites can be one of three widths with the VIC-IV:
1. Normal VIC-II width (24 pixels wide).
2. Extra Wide, where 64 bits (8 bytes) of data are used per raster line, instead of
the VIC-II’s 24. This results in sprites that are 64 pixels wide, unless Full-Colour
Sprite Mode is selected for a sprite, in which case the sprite will be 64 bits ÷ 4
bits per pixel = 16 pixels wide.
3. Tiled mode, where the sprite is drawn repeatedly until the end of the raster line.
Tiled mode should normally only be used with Extra Wide sprite mode, as the
tiling always occurs using 64 bits of sprite data per line. Enabling tiled mode
with normal 24 bit wide mono or multi-colour sprite data will draw 2 and 2/3
rows of sprite data as a single row, even if the given sprite is not in Extra Wide
mode, resulting in garbled displays.
To enable a sprite to be 64 pixels (or 16 pixels if in Full-Colour Sprite Mode), set the
corresponding bit for the sprite in the SPRX64EN register at ($D057, 53335 decimal).
Enabling Full Colour mode for a sprite implicitly enables extended width mode, causes
these sprites to be 16 pixels wide.
Similarly, sprites can be various heights: Sprites will be either the 21 pixels high of
the VIC-II, or if the corresponding bit for the sprite is enabled in the SPRHGTEN signal
($D055, 53333 decimal), then that sprite will be the number of pixels tall that is set in
the SPRHGT register ($D056, 53334 decimal), from 0 to 255. Notice that all sprites
with SPRHGTEN enabled share the same height. A sprite can always leave the bottom
of its image data transparent.
To enable tiled mode for a sprite, set the corresponding bit of SPRTILEN. For sprites 0
through 3, set bits 4 through 7 of $D04D (53325 decimal). For sprites 4 through 7,
set bits 4 through 7 of $D04F (55327 decimal).

Variable Sprite Resolution


By default, sprites are the same resolution as on the VIC-II, i.e., each sprite pixel is
two physical pixels wide and high. However, sprites can be made to use the native
resolution, where sprite pixels are one physical pixel wide and/or high. This is achieved
by setting the relevant bit for the sprite in the SPRENV400 ($D076, 53366 decimal)
registers to increase the vertical resolution on a sprite-by-sprite basis. The horizontal
resolution for all sprites is either the normal VIC-II resolution, or if the SPR640 signal
is set (bit 4 of $D054, 53332 decimal), then sprites will have the same horizontal
resolution as the physical pixels of the display.

P-32
Sprite Palette Bank
The VIC-IV has four palette banks, compared with the single palette bank of the VIC-
III. The VIC-IV allows the selection of separate palette banks for bitmap/text graphics
and for sprites. This makes it easy to have very colourful displays, where the sprites
have different colours to the rest of the display, or to use palette animation to achieve
interesting visual effects in sprites, without disturbing the palette used by other ele-
ments of the display.
The sprite palette bank is selected by setting the SPRPALSEL signal in bits 2 and 3 of
the register $D070 (53360 decimal). It is possible to set this to the same bank as
the bitmap/text display, or to select a different palette bank. Palette bank selection
takes effect immediately. Don’t forget that to be able to modify a palette, you have
to also bank it to be the palette accessible via the palette bank registers at $D100 –
$D3FF by setting the MAPEDPAL signal in bits 6 and 7 of $D070.

Full-Colour Sprite Mode


In addition to monochrome and multi-colour modes, the VIC-IV supports a new full-
colour sprite mode. In this mode, four bits are used to encode each sprite pixel. How-
ever, unlike multi-colour mode where pairs of bits encode pairs of pixels, in full-colour
mode the pixels remain at their normal horizontal resolution. The colour zero is consid-
ered transparent. If you wish to use black in a full-colour sprite, you must configure the
palette bank that is selected for sprites so that one of the 15 colours for the specific
sprite encodes black.
Full-colour sprite mode is selectable for each sprite by setting the appropriate bit in
the SPR16EN register ($D06B, 53355 decimal).
To enable the eight sprites to have 15 unique colours each, the sprite colour is drawn
using the palette entry corresponding to: spritenumber × 16 + nibblevalue, where
spritenumber is the number of the sprite (from 0 to 7), and nibblevalue is the value of
the half-byte that contains the sprite data for the pixel. In addition, if bitplane mode
is enabled for this sprite, then 128 is added to the colour value, which makes it easy
to switch between two colour schemes for a given sprite by changing only one bit in
the SPRBPMEN register.
Because Full-Colour Sprite Mode requires four bits per pixel, sprites will be only six
pixels wide, unless Extra Wide Sprite Mode is enabled for a sprite, in which case the
sprite will be 16 pixels wide. Tiled Mode also works with Full-Colour Sprite Mode, and
will result in the 16 full-colour pixels of the sprite being repeated until the end of the
raster line.
The following BASIC program draws a Full-Colour Sprite in either C64 or C65-mode:

P-33
10 PRINT CHR$ (147)
20 REM C65 / C64 - MODE DETECT
30 IF PEEK ( 532 72) AND 32 THEN GOTO 100
40 POKE 53295 , ASC (" G "): POKE 53295 , ASC (" S ")
100 REM SETUP SPRITE
110 AD =4096 : REM $1000 SPRITE ADDR
120 TC =10 : REM T R A N S P A R E N T COLOUR
130 SPR = PEEK ( 5 3 3 5 6 ) + PEEK ( 5 3 3 5 7 ) * 2 5 6 : REM GET SPRITE TABLE A D D R E S S
140 POKE SPR , AD /64 : REM SET SPRITE A D D R E S S
150 FOR I = AD TO AD +168 : REM CLEAR SPRITE WITH TC
160 POKE I , TC + TC *16 : REM ONE BYTE = 2 PIXEL
170 NEXT
180 POKE 53287 , TC : REM SET T R A N S P A R E N T COLOUR
190 POKE 53248 ,100 : REM PUT SPRITE ...
200 POKE 53249 ,100 : REM ON SCREEN AT 100 ,100
210 POKE 53355 ,1 : REM MAKE SPRITE 0 16 - COLOUR
220 POKE 53335 ,1 : REM MAKE SPRITE 0 USE 16 X4 - BITS
230 POKE 53269 ,1 : REM ENABLE SPRITE 0
240 GOSUB 900 : REM READ MULTI - COLOUR SPRITE
250 END

900 REM LOAD SPRITE FROM DATA


910 READ N$ : IF N$ =" END " THEN RETURN
920 GOSUB 1000 : REM DECODE LINE
930 GOTO 910

P-34
1000 REM DECODE STRING OF N I B B L E S IN N$ AT A D D R E S S AD
1010 IF LEN ( N$ ) < >16 THEN PRINT " I L L E G A L SPR DATA !": END
1020 FOR I =1 TO 16 STEP 2
1030 N =( ASC ( MID$ ( N$ ,I ,1)) - ASC (" @ ")) : REM HIGH NYB
1040 IF N <0 THEN N = TC : REM . IS T R A N S P A R E N T
1050 M =( ASC ( MID$ ( N$ , I +1 ,1)) - ASC (" @ ")) : REM LOW NYB
1060 IF M <0 THEN M = TC : REM . IS T R A N S P A R E N T
1070 POKE AD ,( N AND 15)*16 + ( M AND 15): REM SET 2 PIXELS
1080 AD = AD +1 : REM A D V A N C E AD
1090 NEXT I
1100 RETURN

1998 REM SPRITE DATA


1999 REM . = TRANSPARENT , @ - O = C O L O U R S 0 TO 15
2000 DATA ".. AAFF ... HHCC ..."
2010 DATA ". AAFF ..... HHCC .."
2020 DATA " AAFF . ... ... HHCC ."
2030 DATA " AFF ... @@@ ... HHC ."
2040 DATA " FF .. @ @GG G @@ .. HH ."
2050 DATA ".. @ @ G G G G G G G @ @ ..."
2060 DATA ". @ G G G G G G G G G G G @ .."
2070 DATA ". @ G G G G G G G G G G G @ .."
2080 DATA " @ G G G @ @ G G G @ @ G G G @ ."
2090 DATA " @ G G @ G G G G G G G @ G G @ ."
2100 DATA " @ G G G G G G G G G G G G G @ ."
2110 DATA " @ G G G G G B G B G G G G G @ ."
2120 DATA " @ G G G B B B B B B B G G G @ ."
2130 DATA ". @ G G G G B B B G G G G @ .."
2140 DATA ". @ G G G G G B G G G G G @ .."
2150 DATA ".. @ @ G G G G G G G @ @ ..."
2160 DATA " II .. @ @GG G @@ .. KK ."
2170 DATA " DII ... @@@ ... KKE ."
2180 DATA " DDII . ... ... KKEE ."
2190 DATA ". DDII ..... KKEE .."
2200 DATA ".. DDII ... KKEE ..."
2210 DATA " END "

P-35
VIC-III ERRATA LEVEL
There are a few cases where the VIC-III chip in the Commodore 65 prototypes that are
known to exist either do not behave as specified, the specification lacks detail and the
implementation is oddly inconsistent, or the design itself has flaws or inconsistencies.
The default behavior of the VIC-IV is to emulate the VIC-III as closely as possible in
these cases. In some cases where the VIC-III behavior is lacking, the VIC-IV provides
improved behaviors that can be selected by software using the HWERRATA register at
$D08F.
Because these fixes are backwards incompatible with the VIC-III and with earlier ver-
sions of the VIC-IV and the MEGA65 core, software must opt in to these fixes by
setting the HWERRATA register. This protects software from further changes that may
be introduced in future versions of the MEGA65 core. The boot state of this register is
$00, which requests full compatibility with the VIC-III, including buggy behaviors. The
MEGA65 ROM will always leave this set to $00 when launching programs. A program
can set HWERRATA to enable a set of fixes known to the developer at the time the pro-
gram is written, and exclude backwards incompatible fixes that might be introduced
in later versions.
Requesting an errata level enables all fixes up to that level. By design, there is no
way to request a level and exclude specific fixes at lower levels. You must write your
program to accommodate all fixes up to the requested level.
In cases where enabling a fix changes the behavior of a hot register, setting the errata
level does not trigger hot register propagation. The program must trigger hot register
propagation by writing a 1 to the HOTREG register.
The errata levels implemented so far are as follows:

VIC-III Errata Levels


Level Fixed behavior Release
introduced
0 No fixes. Fully VIC-III compatible. N/A
1 X scroll position shifted in H640 mode. The v0.96
VIC-III renders the text smooth scroll X position
($D016 XSCL) incorrectly in H640 mode. The
fix offsets the scroll position 1 logical pixel (2
physical pixels) to the right. This does not take
effect until hot register propagation.
continued …

P-36
Level Fixed behavior Release
introduced
2 Character attribute combinations. When the v0.96
upper palette (”bold”) character attribute (bit
6) is set, the VIC-III has counterintuitive behav-
iors when ”blink” (bit 4) or ”reverse” (bit 5) are
also set: blink will toggle the upper palette at-
tribute and not blink the character, and reverse
has no effect. With this fix, upper palette + blink
will blink the character, and bold + reverse will
reverse the character, displayed with the upper
palette in both cases.
3 SD Card Busy Flag behaviour. The SD card
busy flag (bit 1 of $D680) indicates if the low-
level SD card controller is busy. The addition
of the SD card controller read-ahead function-
ality means that older software that expectes
this bit to clear on completion of a read op-
eration will incorrectly wait for the entire read-
ahead sequence to complete. This may in turn
result in software incorrectly believing the sec-
tor read has failed due to the longer time re-
quired, or that another read request cannot be
immediately submitted. Therefore below this er-
rata level the SD card busy flag does not indi-
cate if the SD card controller is performing a
background sector read-ahead operation. At
or above this errata level this information is not
concealed, i.e., bit 0 will clear when the re-
quested sector is available, but bit 1 will remain
set while any read-ahead operation continues.

VIC-II / C64 REGISTERS


HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D000 53248 S0X
D001 53249 S0Y
D002 53250 S1X
D003 53251 S1Y
D004 53252 S2X
D005 53253 S2Y
D006 53254 S3X
continued …

P-37
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D007 53255 S3Y
D008 53256 S4X
D009 53257 S4Y
D00A 53258 S5X
D00B 53259 S5Y
D00C 53260 S6X
D00D 53261 S6Y
D00E 53262 S7X
D00F 53263 S7Y
D010 53264 SXMSB
D011 53265 RC8 ECM BMM BLNK RSEL YSCL
D012 53266 RC
D013 53267 LPX
D014 53268 LPY
D015 53269 SE
D016 53270 – RST MCM CSEL XSCL
D017 53271 SEXY
D018 53272 VS CB –
D019 53273 – ILP ISSC ISBC RIRQ
D01A 53274 – MISSC MISBC MRIRQ
D01B 53275 BSP
D01C 53276 SCM
D01D 53277 SEXX
D01E 53278 SSC
D01F 53279 SBC
D020 53280 – BORDERCOL
D021 53281 – SCREENCOL
D022 53282 – MC1
D023 53283 – MC2
D024 53284 – MC3
D025 53285 SPRMC0
D026 53286 SPRMC1
D027 53287 SPR0COL
D028 53288 SPR1COL
D029 53289 SPR2COL
D02A 53290 SPR3COL
D02B 53291 SPR4COL
D02C 53292 SPR5COL
D02D 53293 SPR6COL
D02E 53294 SPR7COL
C128-
D030 53296 – FAST

P-38
• BLNK Enable display: 0 = blank the display, 1 = show the display
• BMM bitmap mode
• BORDERCOL display border colour (16 colour)
• BSP sprite background priority bits
• C128FAST 2MHz select (for C128 2MHz emulation)
• CB character set address location (× 1KiB)
• CSEL 38/40 column select
• ECM extended background mode
• ILP light pen indicate or acknowledge
• ISBC sprite:bitmap collision indicate or acknowledge
• ISSC sprite:sprite collision indicate or acknowledge
• LPX Coarse horizontal beam position (was lightpen X)
• LPY Coarse vertical beam position (was lightpen Y)
• MC1 multi-colour 1 (16 colour)
• MC2 multi-colour 2 (16 colour)
• MC3 multi-colour 3 (16 colour)
• MCM Multi-colour mode
• MISBC mask sprite:bitmap collision IRQ
• MISSC mask sprite:sprite collision IRQ
• MRIRQ mask raster IRQ
• RC raster compare bits 0 to 7
• RC8 raster compare bit 8
• RIRQ raster compare indicate or acknowledge
• RSEL 24/25 row select
• RST Disables video output on MAX Machine(tm) VIC-II 6566. Ignored on normal
C64s and the MEGA65
• SBC sprite/foreground collision indicate bits
• SCM sprite multicolour enable bits
• SCREENCOL screen colour (16 colour)
• SE sprite enable bits
• SEXX sprite horizontal expansion enable bits

P-39
• SEXY sprite vertical expansion enable bits
• SNX sprite N horizontal position
• SNY sprite N vertical position
• SPRMC0 Sprite multi-colour 0
• SPRMC1 Sprite multi-colour 1
• SPRNCOL sprite N colour / 16-colour sprite transparency colour (lower nybl)
• SSC sprite/sprite collision indicate bits
• SXMSB sprite horizontal position MSBs
• VS screen address (× 1KiB)
• XSCL horizontal smooth scroll
• YSCL 24/25 vertical smooth scroll

VIC-III / C65 REGISTERS


HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D020 53280 BORDERCOL
D021 53281 SCREENCOL
D022 53282 MC1
D023 53283 MC2
D024 53284 MC3
D025 53285 SPRMC0
D026 53286 SPRMC1
D02F 53295 KEY
D030 53296 ROME CROM9 ROMC ROMA ROM8 PAL EXTSYNC CRAM2K
D031 53297 H640 FAST ATTR BPM V400 H1280 MONO INT
D033 53299 B0ADODD – B0ADEVN –
D034 53300 B1ADODD – B1ADEVN –
D035 53301 B2ADODD – B2ADEVN –
D036 53302 B3ADODD – B3ADEVN –
D037 53303 B4ADODD – B4ADEVN –
D038 53304 B5ADODD – B5ADEVN –
D039 53305 B6ADODD – B6ADEVN –
D03A 53306 B7ADODD – B7ADEVN –
D03B 53307 BPCOMP
D03C 53308 BPX
D03D 53309 BPY
D03E 53310 HPOS
continued …

P-40
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D03F 53311 VPOS
D040 53312 B0PIX
D041 53313 B1PIX
D042 53314 B2PIX
D043 53315 B3PIX
D044 53316 B4PIX
D045 53317 B5PIX
D046 53318 B6PIX
D047 53319 B7PIX
D100 – 53504 –
D1FF 53759 PALRED
D200 – 53760 –
D2FF 54015 PALGREEN
D300 – 54016 –
D3FF 54271 PALBLUE

• ATTR Enable extended attributes and 8 bit colour entries


• BNPIX Display Address Translater (DAT) Bitplane N port
• BORDERCOL display border colour (256 colour)
• BPCOMP Complement bitplane flags
• BPM Bit-Plane Mode
• BPX Bitplane X
• BPY Bitplane Y
• BXADEVN Bitplane X address, even lines
• BXADODD Bitplane X address, odd lines
• CRAM2K Map 2nd KB of colour RAM $DC00-$DFFF
• CROM9 Select between C64 and C65 charset.
• EXTSYNC Enable external video sync (genlock input)
• FAST Enable C65 FAST mode (∼3.5MHz)
• H1280 Enable 1280 horizontal pixels (not implemented)
• H640 Enable C64 640 horizontal pixels / 80 column mode
• HPOS Bitplane X Offset
• INT Enable VIC-III interlaced mode
• KEY Write $A5 then $96 to enable C65/VIC-III IO registers

P-41
• MC1 multi-colour 1 (256 colour)
• MC2 multi-colour 2 (256 colour)
• MC3 multi-colour 3 (256 colour)
• MONO Enable VIC-III MONO composite video output (colour if disabled)
• PAL Use PALETTE ROM (0) or RAM (1) entries for colours 0 - 15
• PALBLUE blue palette values (reversed nybl order)
• PALGREEN green palette values (reversed nybl order)
• PALRED red palette values (reversed nybl order)
• ROM8 Map C65 ROM $8000
• ROMA Map C65 ROM $A000
• ROMC Map C65 ROM $C000
• ROME Map C65 ROM $E000
• SCREENCOL screen colour (256 colour)
• SPRMC0 Sprite multi-colour 0 (8-bit for selection of any palette colour)
• SPRMC1 Sprite multi-colour 1 (8-bit for selection of any palette colour)
• V400 Enable 400 vertical pixels
• VPOS Bitplane Y Offset

VIC-IV / MEGA65 SPECIFIC


REGISTERS
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D020 53280 BORDERCOL
D021 53281 SCREENCOL
D022 53282 MC1
D023 53283 MC2
D024 53284 MC3
D025 53285 SPRMC0
D026 53286 SPRMC1
D02F 53295 KEY
D048 53320 TBDRPOS
D049 53321 SPRBPMEN TBDRPOS
D04A 53322 BBDRPOS
continued …

P-42
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D04B 53323 SPRBPMEN BBDRPOS
D04C 53324 TEXTXPOS
D04D 53325 SPRTILEN TEXTXPOS
D04E 53326 TEXTYPOS
D04F 53327 SPRTILEN TEXTYPOS
D050 53328 XPOSLSB
D051 53329 NORRDEL DBLRR XPOSMSB
D052 53330 FNRASTERLSB
RE-
D053 53331 FNRST SHDEMU UPSCALE – FNRASTERMSB
SERVED
D054 53332 ALPHEN VFAST PALEMU SPRH640 SMTH FCLRHI FCLRLO CHR16
D055 53333 SPRHGTEN
D056 53334 SPRHGHT
D057 53335 SPRX64EN
D058 53336 LINESTEPLSB
D059 53337 LINESTEPMSB
D05A 53338 CHRXSCL
D05B 53339 CHRYSCL
D05C 53340 SDBDRWDLSB
D05D 53341 HOTREG RSTDELEN SDBDRWDMSB
D05E 53342 CHRCOUNT
D05F 53343 SPRXSMSBS
D060 53344 SCRNPTRLSB
D061 53345 SCRNPTRMSB
D062 53346 SCRNPTRBNK
D063 53347 EXGLYPH CHRCOUNT SCRNPTRMB
FCOLMCM
D064 53348 COLPTRLSB
D065 53349 COLPTRMSB
D068 53352 CHARPTRLSB
D069 53353 CHARPTRMSB
D06A 53354 CHARPTRBNK
D06B 53355 SPR16EN
D06C 53356 SPRPTRADRLSB
D06D 53357 SPRPTRADRMSB
D06E 53358 SPRPTR16 SPRPTRBNK
D06F 53359 PALNTSC VGAHDTV RASLINE0
D070 53360 MAPEDPAL BTPALSEL SPRPALSEL ABTPALSEL
D071 53361 BP16ENS
D072 53362 SPRYADJ
D073 53363 RASTERHEIGHT ALPHADELAY
D074 53364 SPRENALPHA
continued …

P-43
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D075 53365 SPRALPHAVAL
D076 53366 SPRENV400
D077 53367 SPRYMSBS
D078 53368 SPRYSMSBS
D079 53369 RASCMP
FNRST- NOBUG- SPTR-
D07A 53370 EXTIRQS CHARY16 RASCMPMSB
CMP COMPAT CONT
D07B 53371 DISPROWS
D07C 53372 DEBUGC VSYNCP HSYNCP RESV BITPBANK

• ABTPALSEL VIC-IV bitmap/text palette bank (alternate palette)


• ALPHADELAY Alpha delay for compositor
• ALPHEN Alpha compositor enable
• BBDRPOS bottom border position
• BITPBANK Set which 128KB bank bitplanes
• BORDERCOL display border colour (256 colour)
• BP16ENS VIC-IV 16-colour bitplane enable flags
• BTPALSEL bitmap/text palette bank
• CHARPTRBNK Character set precise base address (bits 23 - 16)
• CHARPTRLSB Character set precise base address (bits 0 - 7)
• CHARPTRMSB Character set precise base address (bits 15 - 8)
• CHARY16 Alternate char ROM bank on alternate raster lines in V200
• CHR16 enable 16-bit character numbers (two screen bytes per character)
• CHRCOUNT Number of characters to display per row (LSB)
• CHRXSCL Horizontal hardware scale of text mode (pixel 120ths per pixel)
• CHRYSCL Vertical scaling of text mode (number of physical rasters per char text
row)
• COLPTRLSB colour RAM base address (bits 0 - 7)
• COLPTRMSB colour RAM base address (bits 15 - 8)
• DBLRR When set, the Raster Rewrite Buffer is only updated every 2nd raster line,
limiting resolution to V200, but allowing more cycles for Raster-Rewrite actions.
• DEBUGC VIC-IV debug pixel select red(01), green(10) or blue(11) channel vis-
ible in $D07D

P-44
• DISPROWS Number of text rows to display
• EXGLYPH source full-colour character data from expansion RAM
• EXTIRQS Enable additional IRQ sources, e.g., raster X position.
• FCLRHI enable full-colour mode for character numbers >$FF
• FCLRLO enable full-colour mode for character numbers <=$FF
• FCOLMCM enable 256 colours in multicolour text mode
• FNRASTERLSB Read physical raster position
• FNRASTERMSB Read physical raster position
• FNRST Read raster compare source (0=VIC-IV fine raster, 1=VIC-II raster), pro-
vides same value as set in FNRSTCMP
• FNRSTCMP Raster compare is in physical rasters if clear, or VIC-II rasters if set
• HOTREG Enable VIC-II hot registers. When enabled, touching many VIC-II reg-
isters causes the VIC-IV to recalculate display parameters, such as border po-
sitions and sizes. Touching registers while this is disabled will trigger a change
when reenabling. Setting this to 0 will clear the recalc flag, canceling the re-
calculation.
• HSYNCP hsync polarity
• KEY Write $47 then $53 to enable C65GS/VIC-IV IO registers
• LINESTEPLSB number of bytes to advance between each text row (LSB)
• LINESTEPMSB number of bytes to advance between each text row (MSB)
• MAPEDPAL palette bank mapped at $D100-$D3FF
• MC1 multi-colour 1 (256 colour)
• MC2 multi-colour 2 (256 colour)
• MC3 multi-colour 3 (256 colour)
• NOBUGCOMPAT Disables VIC-III / C65 Bug Compatibility Mode if set
• NORRDEL When clear, raster rewrite double buffering is used
• PALEMU Enable PAL CRT-like scan-line emulation
• PALNTSC NTSC emulation mode (max raster = 262)
• RASCMP Physical raster compare value to be used if FNRSTCMP is clear
• RASCMPMSB Raster compare value MSB
• RASLINE0 first VIC-II raster line
• RASTERHEIGHT physical rasters per VIC-II raster (1 to 16)

P-45
• RESERVED Reserved
• RSTDELEN Enable raster delay (delays raster counter and interrupts by one line
to match output pipeline latency)
• SCREENCOL screen colour (256 colour)
• SCRNPTRBNK screen RAM precise base address (bits 23 - 16)
• SCRNPTRLSB screen RAM precise base address (bits 0 - 7)
• SCRNPTRMB screen RAM precise base address (bits 31 - 24)
• SCRNPTRMSB screen RAM precise base address (bits 15 - 8)
• SDBDRWDLSB Width of single side border (LSB)
• SDBDRWDMSB side border width (MSB)
• SHDEMU Enable simulated shadow-mask (PALEMU must also be enabled)
• SMTH video output horizontal smoothing enable
• SPR16EN sprite 16-colour mode enables
• SPRALPHAVAL Sprite alpha-blend value
• SPRBPMEN Sprite bitplane-modify-mode enables
• SPRENALPHA Sprite alpha-blend enable
• SPRENV400 Sprite V400 enables
• SPRH640 Sprite H640 enable
• SPRHGHT Sprite extended height size (sprite pixels high)
• SPRHGTEN sprite extended height enable (one bit per sprite)
• SPRMC0 Sprite multi-colour 0 (8-bit for selection of any palette colour)
• SPRMC1 Sprite multi-colour 1 (8-bit for selection of any palette colour)
• SPRPALSEL sprite palette bank
• SPRPTR16 16-bit sprite pointer mode (allows sprites to be located on any 64
byte boundary in chip RAM)
• SPRPTRADRLSB sprite pointer address (bits 7 - 0)
• SPRPTRADRMSB sprite pointer address (bits 15 - 8)
• SPRPTRBNK sprite pointer address (bits 23 - 16)
• SPRTILEN Sprite horizontal tile enables.
• SPRX64EN Sprite extended width enables (8 bytes per sprite row = 64 pixels
wide for normal sprites or 16 pixels wide for 16-colour sprite mode)

P-46
• SPRXSMSBS Sprite H640 X Super-MSBs
• SPRYADJ Sprite Y position adjustment
• SPRYMSBS Sprite V400 Y position MSBs
• SPRYSMSBS Sprite V400 Y position super MSBs
• SPTRCONT Continuously monitor sprite pointer, to allow changing sprite data
source while a sprite is being drawn
• TBDRPOS top border position
• TEXTXPOS character generator horizontal position
• TEXTYPOS Character generator vertical position
• UPSCALE Enable integrated low-latency (130usec) 720p upscaler
• VFAST C65GS FAST mode (48MHz)
• VGAHDTV Select more VGA-compatible mode if set, instead of HDMI/HDTV
VIC-II cycle-exact frame timing. May help to produce a functional display on
older VGA monitors.
• VSYNCP vsync polarity
• XPOSLSB Read horizontal raster scan position LSB
• XPOSMSB Read horizontal raster scan position MSB

P-47
P-48
APPENDIX Q
Sound Interface Device (SID)
• SID Registers
Q-2
SID REGISTERS
The MEGA65 has 4 SIDs build in, which can be access through the register ranges
starting at $D400, $D420, $D440, and $D460. The registers in each of these ranges
are exactly the same, so the following table only lists the first SID. Add 32 the get to
the next SID respectively.

HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D400 54272 VOICE1FRQLO
D401 54273 VOICE1FRQHI
D402 54274 VOICE1PWLO
D403 54275 VOICE1UNSD VOICE1PWHI
VOICE1- VOICE1- VOICE1- VOICE1- VOICE1- VOICE1- VOICE1- VOICE1-
D404 54276
CTRLRNW CTRLPUL CTRLSAW CTRLTRI CTRLTST CTRLRMO CTRLRMF CTRLGATE
D405 54277 ENV1ATTDUR ENV1DECDUR
D406 54278 ENV1SUSDUR ENV1RELDUR
D407 54279 VOICE2FRQLO
D408 54280 VOICE2FRQHI
D409 54281 VOICE2PWLO
D40A 54282 VOICE2UNSD VOICE2PWHI
VOICE2- VOICE2- VOICE2- VOICE2- VOICE2- VOICE2- VOICE2- VOICE2-
D40B 54283
CTRLRNW CTRLPUL CTRLSAW CTRLTRI CTRLTST CTRLRMO CTRLRMF CTRLGATE
D40C 54284 ENV2ATTDUR ENV2DECDUR
D40D 54285 ENV2SUSDUR ENV2RELDUR
D40E 54286 VOICE3FRQLO
D40F 54287 VOICE3FRQHI
D410 54288 VOICE3PWLO
D411 54289 VOICE3UNSD VOICE3PWHI
VOICE3- VOICE3- VOICE3- VOICE3- VOICE3- VOICE3- VOICE3- VOICE3-
D412 54290
CTRLRNW CTRLPUL CTRLSAW CTRLTRI CTRLTST CTRLRMO CTRLRMF CTRLGATE
D413 54291 ENV3ATTDUR ENV3DECDUR
D414 54292 ENV3SUSDUR ENV3RELDUR
D415 54293 FLTRCUTFRQLO
D416 54294 FLTRCUTFRQHI
FLTR- FLTR- FLTR- FLTR-
D417 54295 FLTRRESON EXTINP V1OUT V2OUT V3OUT
FLTR- FLTR- FLTR- FLTR-
D418 54296 FLTRVOL
CUTV3 HIPASS BDPASS LOPASS
D419 54297 PADDLE1
D41A 54298 PADDLE2
D41B 54299 OSC3RNG
D41C 54300 ENV3OUT
D63C 54844 – SIDMODE

• ENV3OUT Envelope Generator 3 Output

Q-3
• ENVXATTDUR Envelope Generator X Attack Cycle Duration
• ENVXDECDUR Envelope Generator X Decay Cycle Duration
• ENVXRELDUR Envelope Generator X Release Cycle Duration
• ENVXSUSDUR Envelope Generator X Sustain Cycle Duration
• FLTRBDPASS Filter Band-Pass Mode
• FLTRCUTFRQHI Filter Cutoff Frequency High
• FLTRCUTFRQLO Filter Cutoff Frequency Low
• FLTRCUTV3 Filter Cut-Off Voice 3 Output (1 = off)
• FLTREXTINP Filter External Input
• FLTRHIPASS Filter High-Pass Mode
• FLTRLOPASS Filter Low-Pass Mode
• FLTRRESON Filter Resonance
• FLTRVOL Filter Output Volume
• FLTRVXOUT Filter Voice X Output
• OSC3RNG Oscillator 3 Random Number Generator
• PADDLE1 Analog/Digital Converter: Game Paddle 1 (0-255)
• PADDLE2 Analog/Digital Converter Game Paddle 2 (0-255)
• SIDMODE Select SID mode: 0=6581, 1=8580
• VOICE1CTRLRMF Voice 1 Synchronize Osc. 1 with Osc. 3 Frequency
• VOICE1CTRLRMO Voice 1 Ring Modulate Osc. 1 with Osc. 3 Output
• VOICE2CTRLRMF Voice 2 Synchronize Osc. 2 with Osc. 1 Frequency
• VOICE2CTRLRMO Voice 2 Ring Modulate Osc. 2 with Osc. 1 Output
• VOICE3CTRLRMF Voice 3 Synchronize Osc. 3 with Osc. 2 Frequency
• VOICE3CTRLRMO Voice 3 Ring Modulate Osc. 3 with Osc. 2 Output
• VOICEXCTRLGATE Voice X Gate Bit (1 = Start, 0 = Release)
• VOICEXCTRLPUL Voice X Pulse Waveform
• VOICEXCTRLRNW Voice X Control Random Noise Waveform
• VOICEXCTRLSAW Voice X Sawtooth Waveform
• VOICEXCTRLTRI Voice X Triangle Waveform
• VOICEXCTRLTST Voice X Test Bit - Disable Oscillator

Q-4
• VOICEXFRQHI Voice X Frequency High
• VOICEXFRQLO Voice X Frequency Low
• VOICEXPWHI Voice X Pulse Waveform Width High
• VOICEXPWLO Voice X Pulse Waveform Width Low
• VOICEXUNSD Unused

Q-5
Q-6
APPENDIX R
6526 Complex Interface
Adapter (CIA) Registers
• CIA 6526 Registers
• CIA 6526 Hypervisor Registers
R-2
CIA 6526 REGISTERS
CIA1 Registers
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
DC00 56320 PORTA
DC01 56321 PORTB
DC02 56322 DDRA
DC03 56323 DDRB
DC04 56324 TIMERA
DC05 56325 TIMERA
DC06 56326 TIMERB
DC07 56327 TIMERB
DC08 56328 – TODJIF
DC09 56329 – TODSEC
DC0A 56330 – TODMIN
TOD-
DC0B 56331 – TODHOUR
AMPM
DC0C 56332 SDR
DC0D 56333 IR ISRCLR FLG SP ALRM TB TA
DC0E 56334 TOD50 SPMOD IMODA – RMODA OMODA PBONA STRTA
DC0F 56335 TODEDIT IMODB LOAD RMODB OMODB PBONB STRTB

• ALRM TOD alarm


• DDRA Port A DDR
• DDRB Port B DDR
• FLG FLAG edge detected
• IMODA Timer A tick source
• IMODB Timer B tick source
• IR Interrupt flag
• ISRCLR Placeholder - Reading clears events
• LOAD Strobe input to force-load timers
• OMODA Timer A toggle or pulse
• OMODB Timer B toggle or pulse
• PBONA Timer A PB6 out
• PBONB Timer B PB7 out

R-3
• PORTA Port A
• PORTB Port B
• RMODA Timer A one-shot mode
• RMODB Timer B one-shot mode
• SDR shift register data register(writing starts sending)
• SP shift register full/empty
• SPMOD Serial port direction
• STRTA Timer A start
• STRTB Timer B start
• TA Timer A underflow
• TB Timer B underflow
• TIMERA Timer A counter (16 bit)
• TIMERB Timer B counter (16 bit)
• TOD50 50/60Hz select for TOD clock
• TODAMPM TOD PM flag
• TODEDIT TOD alarm edit
• TODHOUR TOD hours
• TODJIF TOD tenths of seconds
• TODMIN TOD minutes
• TODSEC TOD seconds

CIA2 Registers
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
DD00 56576 PORTA
DD01 56577 PORTB
DD02 56578 DDRA
DD03 56579 DDRB
DD04 56580 TIMERA
DD05 56581 TIMERA
DD06 56582 TIMERB
DD07 56583 TIMERB
DD08 56584 – TODJIF
continued …

R-4
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
DD09 56585 – TODSEC
TOD-
DD0B 56587 – TODHOUR
AMPM
DD0C 56588 SDR
DD0D 56589 IR ISRCLR FLG SP ALRM TB TA
DD0E 56590 TOD50 SPMOD IMODA – RMODA OMODA PBONA STRTA
DD0F 56591 TODEDIT IMODB LOAD RMODB OMODB PBONB STRTB

• ALRM TOD alarm


• DDRA Port A DDR
• DDRB Port B DDR
• FLG FLAG edge detected
• IMODA Timer A tick source
• IMODB Timer B tick source
• IR Interrupt flag
• ISRCLR Placeholder - Reading clears events
• LOAD Strobe input to force-load timers
• OMODA Timer A toggle or pulse
• OMODB Timer B toggle or pulse
• PBONA Timer A PB6 out
• PBONB Timer B PB7 out
• PORTA Port A
• PORTB Port B
• RMODA Timer A one-shot mode
• RMODB Timer B one-shot mode
• SDR shift register data register(writing starts sending)
• SP shift register full/empty
• SPMOD Serial port direction
• STRTA Timer A start
• STRTB Timer B start
• TA Timer A underflow

R-5
• TB Timer B underflow
• TIMERA Timer A counter (16 bit)
• TIMERB Timer B counter (16 bit)
• TOD50 50/60Hz select for TOD clock
• TODAMPM TOD PM flag
• TODEDIT TOD alarm edit
• TODHOUR TOD hours
• TODJIF TOD tenths of seconds
• TODSEC TOD seconds

CIA 6526 HYPERVISOR REGISTERS


In addition to the standard CIA registers available on the C64 and C65, the MEGA65
provides an additional set of registers that are visible only when the system is in Hyper-
visor Mode. These additional registers allow the internal state of the CIA to be more
fully extracted when freezing, thus allowing more programs to function correctly after
being frozen. They are not visible when using the MEGA65 normally, and can be safely
ignored by programmers who are not programming the MEGA65 in Hypervisor Mode.

CIA1 Hypervisor Registers


HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
DC10 56336 TALATCH
DC11 56337 TALATCH
DC12 56338 TALATCH
DC13 56339 TALATCH
DC14 56340 TALATCH
DC15 56341 TALATCH
DC16 56342 TALATCH
DC17 56343 TALATCH
DC18 56344 IMFLG IMSP IMALRM IMTB TODJIF
DC19 56345 TODSEC
DC1A 56346 TODMIN
TOD-
DC1B 56347 TODHOUR
AMPM
DD00-
DC1C 56348 ALRMJIF
DELAY
continued …

R-6
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
DC1D 56349 ALRMSEC
DC1E 56350 ALRMMIN
ALRM-
DC1F 56351 ALRMHOUR
AMPM

• ALRMAMPM TOD Alarm AM/PM flag


• ALRMHOUR TOD Alarm hours value
• ALRMJIF TOD Alarm 10ths of seconds value (actually all 8 bits)
• ALRMMIN TOD Alarm minutes value
• ALRMSEC TOD Alarm seconds value
• DD00DELAY Enable delaying writes to $DD00 by 3 cycles to match real 6502
timing
• IMALRM Interrupt mask for TOD alarm
• IMFLG Interrupt mask for FLAG line
• IMSP Interrupt mask for shift register (serial port)
• IMTB Interrupt mask for Timer B
• TALATCH Timer A latch value (16 bit)
• TODAMPM TOD AM/PM flag
• TODHOUR TOD hours value
• TODJIF TOD 10ths of seconds value
• TODMIN TOD Alarm minutes value
• TODSEC TOD Alarm seconds value

CIA2 Hypervisor Registers


HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
DD10 56592 TALATCH
DD11 56593 TALATCH
DD12 56594 TALATCH
DD13 56595 TALATCH
DD14 56596 TALATCH
DD15 56597 TALATCH
DD16 56598 TALATCH
continued …

R-7
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
DD17 56599 TALATCH
DD18 56600 IMFLG IMSP IMALRM IMTB TODJIF
DD19 56601 TODSEC
DD1A 56602 TODMIN
TOD-
DD1B 56603 TODHOUR
AMPM
DD00-
DD1C 56604 ALRMJIF
DELAY
DD1D 56605 ALRMSEC
DD1E 56606 ALRMMIN
ALRM-
DD1F 56607 ALRMHOUR
AMPM

• ALRMAMPM TOD Alarm AM/PM flag


• ALRMHOUR TOD Alarm hours value
• ALRMJIF TOD Alarm 10ths of seconds value (actually all 8 bits)
• ALRMMIN TOD Alarm minutes value
• ALRMSEC TOD Alarm seconds value
• DD00DELAY Enable delaying writes to $DD00 by 3 cycles to match real 6502
timing
• IMALRM Interrupt mask for TOD alarm
• IMFLG Interrupt mask for FLAG line
• IMSP Interrupt mask for shift register (serial port)
• IMTB Interrupt mask for Timer B
• TALATCH Timer A latch value (16 bit)
• TODAMPM TOD AM/PM flag
• TODHOUR TOD hours value
• TODJIF TOD 10ths of seconds value
• TODMIN TOD Alarm minutes value
• TODSEC TOD Alarm seconds value

R-8
APPENDIX S
4551 UART, GPIO and Utility
Controller
• C65 6551 UART Registers
• 4551 General Purpose I/O & Miscella-
neous Interface Registers
S-2
C65 6551 UART REGISTERS
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D600 54784 DATA
RXOVR-
D601 54785 – FRMERR PTYERR RXRDY
RUN
D602 54786 TXEN RXEN SYNCMOD CHARSZ PTYEN PTYEVEN
D603 54787 DIVISOR
D604 54788 DIVISOR
D605 54789 IMTXIRQ IMRXIRQ IMTXNMI IMRXNMI –
D606 54790 IFTXIRQ IFRXIRQ IFTXNMI IFRXNMI –

• CHARSZ UART character size: 00=8, 01=7, 10=6, 11=5 bits per byte
• DATA UART data register (read or write)
• DIVISOR UART baud rate divisor (16 bit). Baud rate = 7.09375MHz / DIVISOR,
unless MEGA65 fast UART mode is enabled, in which case baud rate = 80MHz
/ DIVISOR
• FRMERR UART RX framing error flag (clear by reading $D600)
• IFRXIRQ UART interrupt flag: IRQ on RX (not yet implemented on the MEGA65)
• IFRXNMI UART interrupt flag: NMI on RX (not yet implemented on the MEGA65)
• IFTXIRQ UART interrupt flag: IRQ on TX (not yet implemented on the MEGA65)
• IFTXNMI UART interrupt flag: NMI on TX (not yet implemented on the MEGA65)
• IMRXIRQ UART interrupt mask: IRQ on RX (not yet implemented on the MEGA65)
• IMRXNMI UART interrupt mask: NMI on RX (not yet implemented on the MEGA65)
• IMTXIRQ UART interrupt mask: IRQ on TX (not yet implemented on the MEGA65)
• IMTXNMI UART interrupt mask: NMI on TX (not yet implemented on the MEGA65)
• PTYEN UART Parity enable: 1=enabled
• PTYERR UART RX parity error flag (clear by reading $D600)
• PTYEVEN UART Parity: 1=even, 0=odd
• RXEN UART enable receive
• RXOVRRUN UART RX overrun flag (clear by reading $D600)
• RXRDY UART RX byte ready flag (clear by reading $D600)
• SYNCMOD UART synchronisation mode flags (00=RX & TX both async, 01=RX
sync, TX async, 1x=TX sync, RX async (unused on the MEGA65)

S-3
• TXEN UART enable transmit

4551 GENERAL PURPOSE I/O &


MISCELLANEOUS INTERFACE
REGISTERS
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D609 54793 – UFAST
MODKEY- MOD- MOD- MOD- MODK- MOD- MOD-
D60A 54794
KEYQUEUE CAPS KEYSCRL KEYALT KEYMEGA EYCTRL KEYRSHFT KEYLSHFT
D60B 54795 OSKZEN OSKZON PORTF
D60C 54796 PORTFDDR PORTFDDR
D60D 54797 HDSCL HDSDA SDBSH SDCS SDCLK SDDATA RST41 CONN41
D60E 54798 BASHDDR
AC-
D60F 54799 OSKDIM REALHW – KEYUP KEYLEFT
CESSKEY
D610 54800 ASCIIKEY
D611 54801 MDISABLE MCAPS MSCRL MALT MMEGA MCTRL MRSHFT MLSHFT
OSKDE-
D612 54802 LJOYB LJOYA JOYSWAP –
BUG
D615 54805 OSKEN VIRTKEY1
D616 54806 OSKALT VIRTKEY2
D617 54807 OSKTOP VIRTKEY3
D618 54808 KSCNRATE
D619 54809 PETSCIIKEY
D61A 54810 SYSCTL
KEYLED-
D61D 54813 KEYLEDREG
ENA
D61E 54814 KEYLEDVAL
D620 54816 POTAX
D621 54817 POTAY
D622 54818 POTBX
D623 54819 POTBY
D625 54821 J21L
D626 54822 J21H
D627 54823 J21LDDR
D628 54824 BOARDMINOR J21HDDR
D629 54825 M65MODEL

• ACCESSKEY Enable accessible keyboard input via joystick port 2 fire button

S-4
• ASCIIKEY Top of typing event queue as ASCII. Write to clear event ready for
next.
• BASHDDR Data Direction Register (DDR) for $D60D bit bashing port.
• BOARDMINOR Read PCB minor revision (R5+ only, else reads zeroes)
• CONN41 Internal 1541 drive connect (1=connect internal 1541 drive to IEC
bus)
• HDSCL HDMI I2C control interface SCL clock
• HDSDA HDMI I2C control interface SDA data line
• J21H J21 pins 11 – 14 input/output values
• J21HDDR J21 pins 11 – 14 data direction register
• J21L J21 pins 1 – 6, 9 – 10 input/output values
• J21LDDR J21 pins 1 – 6, 9 – 10 data direction register
• JOYSWAP Exchange joystick ports 1 & 2
• KEYLEDENA Keyboard LED control enable
• KEYLEDREG Keyboard LED register select (R,G,B channels x 4 = 0 to 11)
• KEYLEDVAL Keyboard LED register value (write only)
• KEYLEFT Directly read C65 Cursor left key
• KEYQUEUE 1 = Typing event queue is non-empty. Write 0 to this bit to flush
queue.
• KEYUP Directly read C65 Cursor up key
• KSCNRATE Physical keyboard scan rate ($00=50MHz, $FF=∼200KHz)
• LJOYA Rotate inputs of joystick A by 180 degrees (for left handed use)
• LJOYB Rotate inputs of joystick B by 180 degrees (for left handed use)
• M65MODEL MEGA65 model ID. Can be used to determine the model of
MEGA65 a programme is running on, e.g., to enable touch controls on MEGA-
phone.
• MALT ALT key state (immediate; read only).
• MCAPS CAPS LOCK key state (immediate; read only).
• MCTRL CTRL key state (immediate; read only).
• MDISABLE Disable modifiers.
• MLSHFT Left shift key state (immediate; read only).
• MMEGA MEGA/C= key state (immediate; read only).

S-5
• MODKEYALT ALT key state at top of typing event queue. 1 = held during event.
• MODKEYCAPS CAPS LOCK key state at top of typing event queue. 1 = held
during event.
• MODKEYCTRL CTRL key state at top of typing event queue. 1 = held during
event.
• MODKEYLSHFT Left shift key state at top of typing event queue. 1 = held during
event.
• MODKEYMEGA MEGA/C= key state at top of typing event queue. 1 = held
during event.
• MODKEYRSHFT Right shift key state at top of typing event queue. 1 = held
during event.
• MODKEYSCRL NOSCRL key state at top of typing event queue. 1 = held during
event.
• MRSHFT Right shift key state (immediate; read only).
• MSCRL NOSCRL key state (immediate; read only).
• OSKALT Display alternate on-screen keyboard layout (typically dial pad for
MEGA65 telephone)
• OSKDEBUG Debug OSK overlay (WRITE ONLY)
• OSKDIM Light or heavy dimming of background material behind on-screen key-
board
• OSKEN Enable display of on-screen keyboard composited overlay
• OSKTOP 1=Display on-screen keyboard at top, 0=Disply on-screen keyboard at
bottom of screen.
• OSKZEN Display hardware zoom of region under first touch point for on-screen
keyboard
• OSKZON Display hardware zoom of region under first touch point always
• PETSCIIKEY Top of typing event queue as PETSCII. Write to clear event ready
for next.
• PORTF PMOD port A on FPGA board (data) (Nexys4 boards only)
• PORTFDDR PMOD port A on FPGA board (DDR)
• POTAX Read Port A paddle X, without having to fiddle with SID/CIA settings.
• POTAY Read Port A paddle Y, without having to fiddle with SID/CIA settings.
• POTBX Read Port B paddle X, without having to fiddle with SID/CIA settings.
• POTBY Read Port B paddle Y, without having to fiddle with SID/CIA settings.

S-6
• REALHW Set to 1 if the MEGA65 is running on real hardware, set to 0 if emulated
(Xemu) or simulated (ghdl)
• RST41 Internal 1541 drive reset (1=reset, 0=operate)
• SDBSH Enable SD card bitbash mode
• SDCLK SD card SCLK
• SDCS SD card CS_BO
• SDDATA SD card MOSI/MISO
• SYSCTL System control flags (target specific)
• UFAST C65 UART BAUD clock source: 1 = 7.09375MHz, 0 = 80MHz (VIC-IV
pixel clock)
• VIRTKEY1 Set to $7F for no key down, else specify virtual key press.
• VIRTKEY2 Set to $7F for no key down, else specify 2nd virtual key press.
• VIRTKEY3 Set to $7F for no key down, else specify 3nd virtual key press.

S-7
S-8
APPENDIX T
45E100 Fast Ethernet
Controller
• Overview
• Memory Mapped Registers
• Example Programs
T-2
OVERVIEW
The 45E100 is a new and simple Fast Ethernet controller that has been designed
specially for the MEGA65 and for 8-bit computers generally. In addition to supporting
100Mbit Fast Ethernet, it is radically different from other Ethernet controllers, such as
the RR-NET.
The 45E100 includes four receive buffers, allowing upto three frames to be received
while another is being processed, or to allow less frequent processing of interrupts.
These receive buffers can be memory mapped, and also directly accessed using the
MEGA65’s DMA controller. Together with automatic CRC32 checking on reception,
and automatic CRC32 generation for transmit, these features considerably reduce
the burden on the processor, and make it much simpler to write ethernet-enabled
programs.
The 45E100 also supports true full-duplex operation at 100Mbit per second, allowing
for total bi-directional throughput exceeding 100Mbit per second. The MAC address
is software configurable, and promiscuous mode is supported, as are individual control
of the reception of broadcast and multi-cast Ethernet frames.
The 45E100 also supports both transmit and receive interrupts, allowing greatly im-
proved real-world performance. When especially low latency is required, it is also
possible to immediately abort the transmission of the current Ethernet frame, so that
a higher-priority frame can be immediately sent. These features combine to enable
sub-millisecond round trip latencies, which can be of particular value for interactive
applications, such as multi-player network games.

Differences to the RR-NET and similar


solutions
The RR-NET and other Ethernet controllers for the Commodore™ line of 8-bit home
computers generally use an Ethernet controller that was designed for 16-bit PCs, but
that also supports a so-called “8-bit mode,” which suffers from a number of disadvan-
tages. These disadvantages include the lack of working interrupts, as well as processor
intensive access to the Ethernet frame buffers. The lack of interrupts forces programs
to use polling to check for the arrival of new Ethernet frames. This, together with the
complexities of accessing the buffers results in an Ethernet interface that is very slow,
and whose real-world throughput is considerably less than its theoretical 10Mbits per
second. Even a Commodore 64 with REU cannot achieve speeds above several tens
of kilobytes per second.
In contrast, the 45E100 supports both RX (Ethernet frame received) interrupts and
TX (ready to transmit) interrupts, freeing the processor from having to poll the device.
Because the 45E100 supports RX interrupts, there is no need for large numbers of
receive buffers, which is why the 45E100 requires only two RX buffers to achieve very
high levels of performance.

T-3
Further, the 45E100 supports direct memory mapping of the Ethernet frame buffers,
allowing for much more efficient access, including by DMA. Using the MEGA65’s in-
tegrated DMA controller it is quite possible to achieve transfer rates of several mega-
bytes per second – some 100x faster than the RR-NET.

Theory of Operation: Receiving


Frames
The 45E100 is simple to operate: To begin receiving Ethernet frames, the programmer
needs only to clear the RST and TXRST bits (bit 0 of register $D6E0) to ensure that the
Ethernet controller is reset, and then set these bits to 1, to release the controller from
the reset state. It will then auto-negotiate connection at the highest available speed,
typically 100Mbit, full-duplex.
If you wish to simply poll for the arrival of ethernet frames, check the RXQ bit (bit 5 of
$D6E1). If it is set, then there is at least one frame that has been received. To access
the next frame that has been received, write $01 to $D6E1, and then $03 to $D6E1.
This will rotate the ring of receive buffers, to make the next received frame accessible
by the processor. The receive buffer that was previously accessible by the processor
is marked free, and the 45E100 will use it to receive another ethernet frame when
required.
Because the 45E100 has four receive buffers, it is possible that to process multiple
frames in succession by following this procedure. If all receive buffers contain received
frames, and the processor has not accepted them, then the RXBLKD signal will be
asserted, so that the processor knows that it if any more frames are received, they
will be lost. Programmers should take care to avoid this situation. As the 45E100
supports receive interrupts, this is generally easy to manage – but don’t underestimate
how often ethernet frames can arrive on a 100mbit Fast Ethernet connection: If a
sender sends a continuous stream of minimum-length ethernet frames, they can arrive
every 6 microseconds or so! While, it is unlikely that you will have to deal with such a
high rate of packet reception, you should anticipate the need to process packets at
least every milli-second. In particular, a once-per-frame CIA or raster IRQ may cause
some packets to be lost, more than three arrive in a 16 – 20 ms video frame. The
RXBLKD signal can be used to determine if this situation is likely to have occurred. But
note that it indicates only when all receive buffers are occupied, not if any further
frames arrived while there were no free receive buffers.
The receive buffers are 2KB bytes each, and can each hold only one received ethernet
frame at a time. This is different to some ethernet controllers that use their total receive
buffer memory as a simple ring buffer. The reason for this is to keep the mechanism
for programmers as simple as possible. By having the fixed buffers, it means that the
controller can memory map the received ethernet frames in exactly the same location
each time, making it possible to write much simpler receiver programs, because the
location of the received ethernet frames can be assumed to be constant.

T-4
The structure of a receive buffer containing an ethernet frame is quite simple: The first
two bytes indicate the length of the received frame. The frame then follows immedi-
ately. The effective Maximum Transport Unit (MTU) length is 2,042 bytes, as the last
four bytes are occupied by the CRC32 checksum of the received ethernet frame. The
layout of the receive buffers is thus as follows:

HEX DEC Length Description


The low byte of the length of the received
0000 0 1
ethernet frame.
The lower four bits contain the upper bits of
the length of the received ethernet frame. Bit
4 is set if the received ethernet frame is a
multi-cast frame. Bit 5 if it is a broadcast
frame. Bit 6 is set if the frame’s destination
0001 1 1
address matches the 45E100’s programmed
MAC address. Bit 7 is set if the CRC32 check
for the received frame failed, i.e., that the
frame is either truncated or was corrupted in
transit.
0002 – 2 – The received frame. Frames shorter than
2,042
07FB 2,043 2,042 bytes will begin at offset 2.
Reserved space for holding the CRC32 code
during reception. The CRC32 code is,
07FC – 2,044 – however, always located directly after the
4
07FF 2,047 received frame, and thus will only occupy this
space if the received frame is more than
2,038 bytes long. ”

Because of the very rapid rate at which Fast Ethernet frames can be received, a pro-
grammer should use the receive interrupt feature, enabled by setting RXQEN (bit 7
of $D6E1). Polling is possible as an alternative, but is not recommended with the
45E100, because at the 100Mbit Fast Ethernet speed, packets can arrive as often
as every 5 microseconds. Fortunately, at the MEGA65’s 40MHz full speed mode, and
using the 20MB per second DMA copy functionality, it is possible to keep up with such
high data rates.

Accessing the Ethernet Frame Buffers


Unlike on the RR-NET, the 45E100’s ethernet frame buffers are able to be memory
mapped, allowing rapid access via DMA or through assembly language programs. It
is also possible to access the buffers from BASIC with some care.
The frame buffers can either be accessed from their natural location in the MEGA65’s
extended address space at address $FFDE800 – $FFDEFFF, or they can be mapped

T-5
into the normal C64/C65 $D000 I/O address space. Care must be taken as map-
ping the ethernet frame buffers into the $D000 I/O address space causes all other
I/O devices to unavailable during this time. Therefore CIA-based interrupts MUST be
disabled before doing so, whether using BASIC or machine code. Therefore when
programming in assembly language or machine code, it is recommended to use the
natural location, and to access this memory area using one of the three mechanisms
for accessing extended address space, which are described in Chapter/Appendix J
on page J-10.
The method of disabling interrupts differs depending on the context in which a program
is being written. For programs being written using C64-mode’s BASIC 2, the following
will work:
POKE56333 ,127: REM D I S AB L E CIA TIMER IRQS

While for MEGA65’s BASIC 65, the following must instead be used, because a VIC-III
raster interrupt is used instead of a CIA-based timer interrupt:

POKE53274 ,0: REM D ISA B L E VIC - II / III / IV RASTER IRQS

Once this has been done, the I/O context for the ethernet controller can be activated
by writing $45 (69 in decimal, equal to the character ’E’ in PETSCII)) and $54 (84 in
decimal, equal to the character ’T’ in PETSCII) into the VIC-IV’s KEY register ($D02F,
53295 in decimal), for example:

POKE53295 , ASC (" E "): POKE53295 , ASC (" T ")

At this point, the ethernet RX buffer can be read beginning at location $D000 (53248
in decimal), and the TX buffer can be written to at the same address. Refer to ‘Theory
of Operation: Receiving Frames’ above for further explanation on this.
Once you have finished accessing the ethernet frame buffer, you can restore the nor-
mal C64, C65 or MEGA65 I/O context by writing to the VIC-III/IV’s KEY register. In
most cases, it will make the most sense to revert to the MEGA65’s I/O context by
writing $47 (71 decimal) in and $53 (83 in decimal) to the KEY register, for example:

POKE53295 , ASC (" G "): POKE53295 , ASC (" S ")

Finally, you should then re-enable interrupts, which will again depend on whether you
are programming from C64 or C65-mode. For C64-mode:

POKE56333 ,129

For C65-mode it would be:


POKE53274 ,129

T-6
Theory of Operation: Sending Frames
Sending frames is similarly simple: The program must simply load the frame to be trans-
mitted into the transmit buffer, write its length into TXSZLSB and TXSZMSB registers,
and then write $01 into the COMMAND register. The frame will then begin to transmit,
as soon as the transmitter is idle. There is no need to calculate and attach an ethernet
CRC32 field, as the 45E100 does this automatically.
Unlike for the receiver, there is only one frame buffer for the transmitter (this may be
changed in a future revision). This means that you cannot prepare the next frame until
the previous frame has already been sent. This slightly reduces the maximum data
throughput, in return for a very simple architecture.
Also, note that the transmit buffer is write-only from the processor bus interface. This
means that you cannot directly read the contents of the transmit buffer, but must load
values “blind”. Finally, the 45E100 allows you to send ethernet.

Advanced Features
In addition to operating as a simple and efficient ethernet frame transceiver, the
45E100 includes a number of advanced features, described here.

Broadcast and Multicast Traffic and


Promiscuous Mode
The 45E100 supports filtering based on the destination Ethernet address, i.e., MAC
address. By default, only frames where the destination Ethernet address matches
the ethernet address programmed into the MACADDR1 – MACADDR6 registers will be
received. However, if the MCST bit is set, then multicast ethernet frames will also
be received. Similarly, setting the BCST bit will allow all broadcast frames, i.e., with
MAC address ff:ff:ff:ff:ff:ff, to be received. Finally, if the NOPROM bit is cleared, the
45E100 disables the filter entirely, and will receive all valid ethernet frames.

Debugging and Diagnosis Features


The 45E100 also supports several features to assist in the diagnosis of ethernet prob-
lems. First, if the NOCRC bit is set, then even ethernet frames that have invalid CRC32
values will be received. This can help debug faulty ethernet devices on a network.
If the STRM bit is set, the ethernet transmitter transmits a continuous stream of de-
bugging frames supplied via a special high-bandwidth logging interface. By default,

T-7
the 45E100 emits a stream of approximately 2,200 byte ethernet frames that con-
tain compressed video provided by a VIC-IV or compatible video controller that sup-
ports the MEGA65 video-over-ethernet interface. By writing a custom decoder for this
stream of ethernet frames, it is possible to create a remote display of the MEGA65 via
ethernet. Such a remote display can be used, for example, to facilitate digital capture
of the display of a MEGA65.
The size and content of the debugging frames can be controlled by writing special
values to the COMMAND register. Writing $F1 allows the selection of frames that are
1,200 bytes long. While this reduces the performance of the debugging and streaming
features, it allows the reception of these frames on systems whose ethernet controllers
cannot be configured to receive frames of 2,200 bytes.
If the STRM bit is set and bit 2 of $D6E1 is also set, a compressed log of instructions
executed by the 45gs02 CPU will instead be streamed, if a compatible processor is
connected to this interface. This mechanism includes back-pressure, and will cause
the 45gs02 processor to slowdown, so that the instruction data can be emitted. This
typically limits the speed of the connected 45gs02 processor to around 5MHz, de-
pending on the particular instruction mix.
Note also that the status of bit 2 of $D6E1 cannot currently be read directly. This may
be corrected in a future revision.
Finally, if the video streaming functionality is enabled, this also enables reception of
synthetic keyboard events via ethernet. These are delivered to the MEGA65’s Keyboard
Complex Interface Adapter (KCIA), allowing full remote interaction with a MEGA65 via
its ethernet interface. This feature is primarily intended for development.

MEMORY MAPPED REGISTERS


The 45E100 Fast Ethernet controller is a MEGA65-specific feature. It is therefore only
available in the MEGA65 I/O context. This is enabled by writing $53 and then $47 to
VIC-IV register $D02F. If programming in BASIC, this can be done with:

POKE53295 , ASC (" G "): POKE53295 , ASC (" S ")

The 45E100 Fast Ethernet controller has the following registers

HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D6E0 55008 TXIDLE RXBLKD – DRXDV DRXD TXRST RST
RCENABLED
D6E1 55009 RXQEN TXQEN RXQ TXQ STRM RXBF –
D6E2 55010 TXSZLSB
D6E3 55011 TXSZMSB
D6E4 55012 COMMAND
D6E5 55013 RXPH MCST BCST TXPH NOCRC NOPROM
continued …

T-8
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D6E6 55014 MIIMPHY MIIMREG
D6E7 55015 MIIMVLSB
D6E8 55016 MIIMVMSB
D6E9 55017 MACADDR1
D6EA 55018 MACADDR2
D6EB 55019 MACADDR3
D6EC 55020 MACADDR4
D6ED 55021 MACADDR5
D6EE 55022 MACADDR6

• BCST Accept broadcast frames


• COMMAND Ethernet command register (write only)
• DRXD Read ethernet RX bits currently on the wire
• DRXDV Read ethernet RX data valid (debug)
• MACADDRX Ethernet MAC address
• MCST Accept multicast frames
• MIIMPHY Ethernet MIIM PHY number (use 0 for Nexys4, 1 for MEGA65 r1 PCBs)
• MIIMREG Ethernet MIIM register number
• MIIMVLSB Ethernet MIIM register value (LSB)
• MIIMVMSB Ethernet MIIM register value (MSB)
• NOCRC Disable CRC check for received packets
• NOPROM Ethernet disable promiscuous mode
• RCENABLED (read only) Ethernet remote control enable status
• RST Write 0 to hold ethernet controller under reset
• RXBF Number of free receive buffers
• RXBLKD Indicate if ethernet RX is blocked until RX buffers freed
• RXPH Ethernet RX clock phase adjust
• RXQ Ethernet RX IRQ status
• RXQEN Enable ethernet RX IRQ
• STRM Enable streaming of CPU instruction stream or VIC-IV display on ethernet
• TXIDLE Ethernet transmit side is idle, i.e., a packet can be sent.
• TXPH Ethernet TX clock phase adjust

T-9
• TXQ Ethernet TX IRQ status
• TXQEN Enable ethernet TX IRQ
• TXRST Write 0 to hold ethernet controller transmit sub-system under reset
• TXSZLSB TX Packet size (low byte)
• TXSZMSB TX Packet size (high byte)

COMMAND register values


The following values can be written to the COMMAND register to perform the de-
scribed functions. In normal operation only the STARTTX command is required, for
example, by performing the following POKE:

POKE55012 ,1

HEX DEC Signal Description


Immediately stop transmitting the
current ethernet frame. Will cause a
00 0 STOPTX partially sent frame to be received,
most likely resulting in the loss of that
frame.
01 1 STARTTX Transmit packet
D0 208 RXNORMAL Disable the effects of RXONLYONE
Select VIC-IV debug stream via
D4 212 DEBUGVIC
ethernet when $D6E1.3 is set
Select CPU debug stream via ethernet
DC 220 DEBUGCPU
when $D6E1.3 is set
Receive exactly one ethernet frame
DE 222 RXONLYONE only, and keep all signals states (for
debugging ethernet sub-system)
Select 1KiB frames for video/cpu
debug stream frames (for receivers that
F1 241 FRAME1K
do not support MTUs of greater than
2KiB)
Select 2KiB frames for video/cpu
F2 242 FRAME2K debug stream frames, for optimal
performance.

EXAMPLE PROGRAMS
Example programs for the ethernet controller exist in imperfect states for in the
MEGA65 Core repository on github in the src/tests and src/examples directories.

T-10
If you wish to use the ethernet controller for TCP/IP traffic, you may wish to examine
the port of WeeIP to the MEGA65 at https://github.com/mega65/mega65-weeip. The
code that controls the ethernet controller is located in eth.c.

T-11
T-12
APPENDIX U
45IO27 Multi-Function I/O
Controller
• Overview
• F011-compatible Floppy Controller
• SD card Controller and F011 Virtuali-
sation Functions

• Touch Panel Interface


• Audio Support Functions
• Miscellaneous I/O Functions
U-2
OVERVIEW
The 45IO27 is a multi-purpose I/O controller that incorporates the functions of the
C65’s F011 floppy controller, together with the MEGA65’s SD card controller inter-
face, and a number of other miscellaneous I/O functions.
Each of these major functions is covered in a separate section of this chapter.

F011-COMPATIBLE FLOPPY
CONTROLLER
The MEGA65 computer is one of the very few modern computers that still includes
first-class support for magnetic floppy drives. It includes a floppy controller that is
backwards compatible with the C65’s F011D floppy drive controller.
However, unlike the F011D, the MEGA65’s floppy disk controller supports HD and ED
media, and similar to the 1541 floppy drive, it also supports variable data rates, so
that a determined user could develop disk formats that store more data, include robust
copy protection schemes, or both.
Other disk formats, such as the GCR scheme used by the 1541 and 1571, or the
track-at-once MFM scheme used by the Amiga™ family of computers can also be
used, with varying amounts of effort. This is possible via the track DMA functionality
that is jointly provided by the 45IO27 and the 45GS02 processor. These two devices
work together to allow reading or writing raw flux signals from and to diskettes, thus
allowing the reading or reproduction of practically any disk format.
Also, for Amiga™ diskettes, there is experimental special circuitry in the 45IO27 to
ease the reading of these diskettes. Specifically, the 45IO27 is able to detect the
unique sector sync signals used on Amiga™ diskettes, and read the data sectors. How-
ever, it does not retrieve the 16 bytes per sector of operating-system specific data,
nor does it perform the de-interleaving of the separated vectors of odd and even bits
from the order that the Amiga™ computer writes them to disk. Use of this special cir-
cuitry is optional. That is, the track DMA functionality can also be used to read Amiga™
diskettes.

Multiple Drive Support


Like the C65’s F011 floppy drive controller, the 45IO27 supports up to 8 drives. The
first two of those drives, drive 0 and drive 1, are assumed to be connected to a stan-
dard 34-pin floppy cable, the same as used in standard PCs, i.e., with a twist in the
cable to allow the use of two unjumpered drives.

U-3
As is described in later sections, it is possible to switch drive 0 and drive 1’s position,
without having to change cabling. Similarly, either or both of the first two drives may
reference a real floppy drive, a D81 disk image stored on an attached SD card, or
redirected to the floppy drive virtualisation service, so that the sector accesses can
be handled by a connected computer, e.g., as part of a comfortable and efficient
cross-development environment.
The remaining six drives are supported only in conjunction with a future C1565-
compatible external drive port.

Buffered Sector Operations


The 45IO27 support two main modes of reading sectors from a disk: byte-by-byte,
and via a memory-mapped sector buffer.
The byte-by-byte mechanism consists of having a loop wait for the DRQ signal to be
asserted, and then reading the byte of data from the DATA register ($D087).
The memory-mapped sector buffer method consists of waiting for the BUSY flag to
clear, indicating that the entire sector has been read, and then directly accessing
the sector buffer located at $FFD6C00 – $FFD6DFF. Care should be taken to ensure
that the BUFSEL signal (bit 7 of $D689) is cleared, so that the floppy sector buffer is
visible, rather than the SD card sector buffer for programs other than the Hypervisor.
This is because only the Hypervisor has access to the full 4KB SD controller buffer
space: Normal programs see either the floppy sector buffer or the SD card sector
buffer repeated 8 times between $FFD6000 and $FFD6FFF.
Alternatively, the sector buffer can be mapped at $DE00 – $DFFF, i.e., in the 4KB I/O
area, by writing the $81 to the SD command register at $D680. This will hide any I/O
peripherals that are otherwise using this area, e.g., from cartridges, or REU emulation.
This function can be disabled again by writing $82 to the SD command register. As
with the normal sector buffer memory mapping at $FFD6xxx, the BUFSEL signal (bit 7
of $D689) affects whether the FDC or the SD card sector buffer is visible, for software
not running in Hypervisor mode. Note that if you use the Matrix Mode / serial monitor
interface to inspect the contents of the sector buffer, that this occurs in the Hypervisor
context, and so the BUFSEL signal will be ignored, and the full 4KB buffer will be visible.
The memory-mapped sector buffer has the advantage that it can be accessed via
DMA, allowing for very efficient copies. Also, it allows for loading a sector to occur
in the background, while your program gets on with more interesting things in the
meantime.

Reading Sectors from a Disk


There are several steps that you must follow in order to successfully read a sector from
a disk. If you follow these instructions, your code will work with both physical disks, as
well as D81 disk images that exist on the SD card:

U-4
• First, enable the motor and select the appropriate drive. The F011 supports
upto 8 physical drives, although it is rare for more than two to be physically
connected. To enable the motor, write $60 to $D080. You should then write a
SPINUP command ($20) to $D081, and wait for the BUSY flag (bit 7 of $D082)
to clear. The drive is now spinning at speed, and ready to service requests.
• Next, select the correct side of the disk by either setting or clearing the SIDE1
flag (bit 3 of $D080). This takes effect immediately.
• Third, use the step-in and step-out commands (writing $10 and $18 to $D081)
as required to move the head to the correct track. Again, after each command,
you should wait for the BUSY flag (bit 7 of $D082) to clear, before issuing the
next command.
Note that you can check if the head is at track 0 by checking the TRACK0 flag,
but there is no fool-proof way to know if you are on any other specific track. You
can use the registers at $D6A3 – $D6A5 to see the track, sector and side value
from the last sector header which passed under the head to make an informed
guess as to which track is currently selected. Note that this only works for real
disks, as disk images do not spin under the read head. Also note that it is possible
for tracks to contain sectors which purposely or accidently have incorrect track
numbers in the sector headers.
• Fourth, you need to load the desired track, sector and side number into the
TRACK, SECTOR and SIDE registers ($D084, $D085 and $D086, respectively).
The FDC is now primed ready to read a sector.
• Fifth, you should write an appropriate read command value into $D081. This will
normally be $40 (64). You then wait for the RDREQ signal ($D083, bit 7) to go
high, to indicate that the sector has been found. You then either wait for each
occassion when DRQ goes high, and read byte-by-byte in such a loop, or wait
for the BUSY flag to clear and the DRQ and EQ flags to go high, which indicates
that the complete sector has been read into the buffer.

Track Auto-Tune Function


The 45IO27 also includes a track “auto-tune” function, which is enabled by clearing
bit 7 of $D696. That function reads the sector headers to determine which track the
head is currently over, and steps the head in or out to try to get to the correct track.
Auto-tune is enabled by default.

Sector Skew and Target Any Mode


It is also worth noting that the TARGANY signal can be asserted to tell the floppy
controller to simply read the next sector that passes under the head. This applies only
when using real floppy disks, where it offers the considerable advantage of letting you
read the sectors in the order in which they exist on the disk. This allows you to read a

U-5
track at once, without having to wait for the index hole to pass by, or having to know
which sector will next pass under the head.
For example, the C65 DOS formats disks using a skew factor of 7, while PCs may
use a different skew-factor. If you don’t know the skew factor of the disk, you may
schedule the reading of the sectors on the track in a sub-optimal order. This can result
in transfer rates as low as 5 sectors per second, compared with the optimal case of
50 sectors per second. Thus with either correct sector order, or using the target any
mode, it is possible to read approximately two full tracks per second, i.e., two sides
× two tracks, or approximately 20KB/second on DD disks, or double that on HD disks,
at around 40KB/second. This compares very favourably with the C65 DOS loading
speed, which is typically nearer 1KB/sec in C64-mode.

Disk Layout and 1581 Logical Sectors


The 1581 disk format is unusual in that the physical sectors on the disk are a different
size of the size of the data blocks that it presents to the user. Specifically, the disks
use 512 byte sectors, while the 1581 (and C65) DOS present 256 byte data blocks.
Two blocks are stored in each physical sector. Also, the physical track numbers are
from 0 to 79, while the logical track numbers of the DOS are 1 to 80. Physical sectors
are also numbered from 1 to 10, while logical block numbers begin are 0 to 39.
This means that if you want to find a 1581 logical sector, you need to know which
physical sector it will be found in. To determine the physical sector that contains a
block, you first subtract one from the track number, and then divide the sector number
by two. Logical sectors 0 to 19 of each track are located in physical sectors 1 to 10
on the first side of the disk. Logical sectors 20 to 39 are located in physical sectors 1
to 10 on the reverse side of the disk.
Thus we can map a some logical track and sector t,s to the physical track, side and
sector as follows:
track = t − 1
sector = (s/2) + 1, IF F s < 20, ELSE = ((s − 20)/2) + 1
side = 0IF F sector < 20
It is also worth noting that the 45IO27 is capable of reading from tracks beyond track
80, provided that the disk drive is capable of this. Almost all 3.5 inch floppy drives
are capable of reading at least one extra track, as historically manufacturers of floppy
disks stored information about the disk on the 81st track. In our experience almost all
drives will also be able to access an 82nd track.

U-6
FD2000 Disks
The CMD™ FD2000™ high-density 3.5” disk drives for Commodore™ computers use
an unusual disk layout that is quite different from PCs: They use 10 sectors, the same
as on 720KB double-density (DD) disks, but double the sector size from 512 bytes to
1,024 bytes. The 45IO27 does not currently support these larger sectors for buffered
sector operation. At least read-only support is planned to be added via a core update
in the future. However, FD2000™ and FD4000™ diskettes can be read and written
using the track DMA functionality.
Also, for creating new diskettes, the 45IO27 does already support high-density disks
and drives, with much higher capacities than the FD2000 was able to support.

High-Density and Variable-Density


Disks
The 45IO27 supports variable data rates, allowing the use of HD drives and media,
with a flexible approach to disk formats to support user experimentation, and the easy
manipulation of high-capacity software distribution formats.
You are really only limited by your imagination, available time, and the limited number
of people who are still interested in inserting a floppy disk into their computer!
The standard high-density (HD) disk format is “1.44MB”, using 18 sectors per track
over 80 tracks. This results in 80 tracks × 18 sectors × 2 sides = 2,880 sectors. As
each sector is 512 bytes, this corresponds to 1,440KB. This leads us into the interesting
wonderland of “floppy disk marketing megabytes,” a phenomena which long predates
SD card and hard drive manufacturers using 1,000,000 byte megabytes.
Curiously for floppy disks, the 1,024,000 byte “megabyte” was used, i.e., “1MB” = 1KB
× 1KB, that is a strange hybrid of binary and decimal conventions. Perhaps it was be-
cause the previous standard was 720KB, and they thought people would think it odd if
double 720KB was 1.41MB, and complain about the missing kilo-bytes. We will con-
tinue to use the 1,024KB = 1,000KB floppy disk marketing mega-byte for consistency
with this historical inconsistency.
However, HD floppy disks are fundamentally capable of holding much more than
1.44MB. For example, the FD2000 stored 1.6MB by using double-sized sectors to
squeeze the equivalent of 20 sectors per track, and the Amiga went further by using
track-at-once writing to fit 22 sectors per track. Both these formats used a constant
data rate over all tracks, and thus a constant number of sectors per track.
However, the circumference of the tracks on a 3.5” floppy disk vary quite a lot: The
inner track has a diameter of around 2.5cm, while the outside track is 1.6× longer.
The 1.44MB disk format is designed so that the data is reliably stored on those shorter
inner tracks. This means that we should be able to fit 160% more data on the outer-
most track compared with the inner-most track, subject to a number of terms and

U-7
conditions imposed by The Laws of Physics, the design of floppy drive electronics,
the quality of media being used and various other annoying things. Because of this
variability and uncertainty, the MEGA65’s floppy controller supports fully variable data
rate on a track-by-track basis.

Track Information Blocks


To support variable data rates, the 45GS27 supports the use of Track Information
Blocks (TIBs) that contain information on the data rate and encoding used on the track.
This allows users to experiment with various densities on various tracks, and yet have
the disks function automatically for buffered sector operations.
The Track Information Block is automatically created when using the automatic track
format function, but must be manually created if using unbuffered formatting. The TIB
itself consists of the following data:
1. 3× $A1 Sync bytes (written with clock byte $FB)
2. $65 MEGA65 Track Information Block marker (written with clock byte $FF, as are
all following bytes in the block)
3. The track number
4. The data rate divisor, in the same format as $D6A2, i.e., data rate = 40.5MHz /
value.
5. Track encoding information: Bit 7 = Track-at-once flag, 1 = no inter-sector gaps
(Amiga style), 0 = with inter-sector gaps (normal), Bit 6 = data encoding, 0 =
MFM, 1=RLL2,7. Other bits are reserved, and should be 0 when written.
6. Sector count, i.e., number of sectors on the track.
7. CRC byte 1, using the normal floppy disk CRC algorithm.
8. CRC byte 2, using the normal floppy disk CRC algorithm.
The Track Information Block is always written a the data rate for a 720KB Double-
Density disk, so that they can be present on any disk. Writing the Track Information
Block and start-of-track gaps at the DD data rate also ensures that at very high data
rates, the head still has sufficient time to switch to write mode, thus avoiding one of
the many problems that arise when writing data at very high data rates.
If formatting disks unbuffered, it is the programmer’s responsibility to switch the data
rate after having written the Track Information Block, and several more bytes to allow
the floppy encoding pipeline to flush out the last byte of the Track Information Block.
This is all automatically managed if using the automatic track formatting function.
The inclusion of the TIB allows users to play and explore the possibilities of different
data rates on different drives and media, while still being automatically readable in
all MEGA65s, because the TIB allows the controller to switch to the correct data rate
and encoding. It is likely that over time somewhat standardised formats will develop,

U-8
quite likely in the range of 2MB to 3.5MB – thus approaching the capacity of ED media
in ED drives, without the need for those drives or media.

Formatting Disks
Formatting disks is now possible with the 45IO27, either unbuffered or fully-automatic.
To format a track issue one of the following commands to $D081:
• $A0 – Automatic format, with inter-sector gaps, and write pre-compensation
disabled.
• $A1 – Manual format, write-precompensation disabled.
• $A4 – Automatic format, with inter-sector gaps, and write pre-compensation
enable.
• $A5 – Manual format, write-precompensation enabled.
• $A8 – Automatic format, Amiga-style track-at-once, and write pre-
compensation disabled.
• $AC – Automatic format, Amiga-style track-at-once, and write pre-
compensation enable.
Manual formatting is not recommended, unless mastering track-at-once formatted
disks for software distribution, because of the relative complexity of doing so. Also,
at the higher data rates, bytes have to be delivered to the floppy controller as often
as every 20 cycles, which requires considerable care when writing the format routine.
For more information on manual formatting tracks, refer to the C64 Specifications
Manual or the C65 ROM DOS source code, for examples of manual formatting.
The automatic modes, in contrast, format a track with a single command, and are thus
much easier to use, and are recommended for general use. Write pre-compensation
should normally be enabled, as it is required at higher data rates, and does not cause
problems at lower data rates.

Write Pre-Compensation
Write pre-compensation is a family of algorithms used when writing high data-rate
signals to floppy disks. It is used to anticipate and cancel out the predictable com-
ponent of timing variation of magnetic recording. There are a variety of sources of
this timing variation, which have been the subject of PhD theses, and a lot of propri-
etary research by hard drive manufacturers. What is important for us to understand
is that adjacent pulses (really magnetic inversions) get pushed together, if they are
surrounded by longer pulses, or tend to spread apart if surrounded by shorter pulses.
There are also other fascinatingly complex and difficult to predict factors, that cause
things such as the “negative shift of mid-length pulses”, “inverse F-distribution of pulse

U-9
arrival times” and goodness knows what else. But we shall leave those to the hard
drive manufacturers. We limit ourselves to the data pattern induced effect described
in the previous paragraph.
The 45GS27 supports two tunable coefficients for small and large corrections to this,
which are used with an internal look-up table. However, this is all automatically han-
dled if you enable write pre-compensation. This allows data rates that much more
closely approach the expected limit of HD media, although due to the other horrors of
magnetic media recording alluded to above, the actual limit is not reached.

Buffered Sector Writing


The 45IO27 can write to disk images that are located on the SD card, or when using
virtualised disk access.
To write a sector, you follow a similar process to reading, except that you write $84 to
the command byte instead of $40. The $80 indicates a write, and the $04 activates
write-precompensation. This is important when writing to real floppy disks, especially
HD and ED disks. Write-precompensation causes bits to be written slightly early or
slightly late, using an algorithm that models how the magnetic domains on a disk tend
to move after being written.
If you do not wish to use the sector buffer, but instead provide each byte one at a
time during the write operation, you must add $01 to the command code. However,
this is not recommended on the MEGA65, because when writing to the SD card or
using virtualised disk images the entire sector operation can happen instantaneously
from the perspective of your program. This means that it is not possible to supply data
reliably when in this mode. Thus apart from being less convenient, it is also less reliable.
Once a write operation has been triggered, the DRQ signal indicates when you should
provide the next byte if performing a byte-by-byte write. Otherwise, it is assumed
that you will have pre-filled the sector buffer with the complete 512 bytes of data
required.
To write to disks that contain Track Information Blocks, you should first wait for the TIB
to be read when changing tracks. This is done by waiting for $D6A9 (sectors per track
from the TIB) to contain a non-zero value.

Floppy Track DMA


As previously described, the 45IO27 connects to the 45GS02 CPU, and specifically
its internal DMA controller, to provide a simple mechanism for reading and writing the
raw magnetic flux transitions of floppy disks. In addition to allowing writing softwar
that can read any possible disk format, it also allows for the writing and duplication
of almost any disk format. I say almost, because it is possible for diskettes to be
written using special machines that have capabilities that exceed that of the floppy
drive mechanism of the MEGA65. Fat tracks is one example of this. Another example

U-10
is where the magnetic flux transitions are placed and/or spaced in a manner that
prevents a normal floppy drive from reproducing them exactly.

Using Floppy Track DMA


The following DMA options tell the DMAgic controller to read or write raw floppy flux
values instead of memory location. In this mode, the DMAgic controller waits for each
successive pulse interval to be received from the 45IO27. Thus the data that it reads
(or writes) is the duration between each successive flux inversion, in units of 50ns.
• $0D - Write raw flux intervals. Set DMA to COPY mode to use this.
• $0E - Read raw flux intervals, ignoring implausibly long intervals. Set DMA mode
to FILL to use this.
• $0F - Read raw flux intervals, returning implausibly long intervals as $FF. Set
DMA mode to FILL to use this.
See floppytest.c in the mega65-tools repository of the MEGA65 github site at https:
//github.com/mega65-tools for example code that reads tracks using this function-
ality.

Understanding the Limitations of


Floppy Drives
When writing raw flux transitions, care must be taken to understand the limitations of
standard floppy drives. There are three key factors to be considered:
• No two transitions can be placed too close togther. The drive will simply refuse to
write them if they are below some distance apart. Also, even if you do manage
to write them, the read filtering circuitry of the floppy drive will merge pulses
that are too close together.
• No two transitions can be placed too far apart. In this case, the drive will happily
write them, but the read filter circuitry will start getting worried if it doesn’t see a
pulse for a while, and will start thinking that the background noise is real signals,
and introduce false pulses into the read stream that are not really there on the
disk.
• Magnetic pulses move on the disk when you write them! The physics behind this is
really complex, and depends on the sequence of distances between successive
pulses, the data that was previously written to the track, and, it feels like, also
the phase of the moon and colour of your underpants. There are some general
rules of thumb that can be used at “typical” pulse distance intervals to partially
mitigate this. These rules are called Write Pre-compensation, where the pulses
are moved before writing, so that after writing they end up in the right place.

U-11
The 45IO27 already implements write pre-compensation for HD formatted disks.
The effects of moving pulses is especially pronounced for pulses that are closer
together.
• The higher numbered tracks are shorter. This means that the pulses have to be
further apart in time, to be the same distance apart on a track. This is why the
1541 fits less data on higher numbered tracks. This is especially pronounced at
higher data rates, where the “magnetic resolution” of the disks becomes an issue.
To make matters worse, the strength of the magnetic signals is proportional to
the speed of the track going past. This means for the higher numbered tracks
that are nearer the middle of the disk, not only is the “magnetic resolution” lower
due to the shorter tracks, the linear velocity of the disk under the head is also
lower, resulting in weaker signals.
It is the combination of these factors that will tend to limit how densly you can pack
data onto a floppy disk – together of course with the quality and condition of the
diskette and disk drive. The MEGA65’s HD+ disk formats that are able to fit around
3MiB on a standard 1.44MiB diskette take special care to manage these factors. This
is why those formats use many different density zones, as well as using RLL27 encoding
instead of MFM encoding, because it increases the minimum distance between pulses.

F011 Floppy Controller Registers


The following are the set of F011 compatibility registers of the 45IO47. Note that
registers related to the use of SD card based storage are found in the corresponding
section below.

HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D080 53376 IRQ LED MOTOR SWAP SIDE DS
D081 53377 WRCMD RDCMD FREE STEP DIR ALGO ALT NOBUF
D082 53378 BUSY DRQ EQ RNF CRC LOST PROT TK0
D083 53379 RDREQ WTREQ RUN WGATE DISKIN INDEX IRQ DSKCHG
D084 53380 TRACK
D085 53381 SECTOR
D086 53382 SIDE
D087 53383 DATA
D088 53384 CLOCK
D089 53385 STEP
D08A 53386 PCODE

• ALGO Selects reading and writing algorithm (currently ignored).


• ALT Selects alternate DPLL read recovery method (not implemented)
• BUSY F011 FDC busy flag (command is being executed) (read only)

U-12
• CLOCK Set or read the clock pattern to be used when writing address and data
marks. Should normally be left $FF
• COMMAND F011 FDC command register
• CRC F011 FDC CRC check failure flag (read only)
• DATA F011 FDC data register (read/write) for accessing the floppy controller’s
512 byte sector buffer
• DIR Sets the stepping direction (inward vs
• DISKIN F011 Disk sense (read only)
• DRQ F011 FDC DRQ flag (one or more bytes of data are ready) (read only)
• DS Drive select (0 to 7). Internal drive is 0. Second floppy drive on internal cable
is 1. Other values reserved for C1565 external drive interface.
• DSKCHG F011 disk change sense (read only)
• EQ F011 FDC CPU and disk pointers to sector buffer are equal, indicating that
the sector buffer is either full or empty. (read only)
• FREE Command is a free-format (low level) operation
• INDEX F011 Index hole sense (read only)
• IRQ The floppy controller has generated an interrupt (read only). Note that in-
terrupts are not currently implemented on the 45GS27.
• LED Drive LED blinks when set
• LOST F011 LOST flag (data was lost during transfer, i.e., CPU did not read data
fast enough) (read only)
• MOTOR Activates drive motor and LED (unless LED signal is also set, causing the
drive LED to blink)
• NOBUF Reset the sector buffer read/write pointers
• PCODE (Read only) returns the protection code of the most recently read sector.
Was intended for rudimentary copy protection. Not implemented.
• PROT F011 Disk write protect flag (read only)
• RDCMD Command is a read operation if set
• RDREQ F011 Read Request flag, i.e., the requested sector was found during a
read operation (read only)
• RNF F011 FDC Request Not Found (RNF), i.e., a sector read or write operation
did not find the requested sector (read only)
• RUN F011 Successive match. A synonym of RDREQ on the 45IO47 (read only)
• SECTOR F011 FDC sector selection register

U-13
• SIDE Directly controls the SIDE signal to the floppy drive, i.e., selecting which
side of the media is active.
• STEP Writing 1 causes the head to step in the indicated direction
• SWAP Swap upper and lower halves of data buffer (i.e. invert bit 8 of the sector
buffer)
• TK0 F011 Head is over track 0 flag (read only)
• TRACK F011 FDC track selection register
• WGATE F011 write gate flag. Indicates that the drive is currently writing to
media. Bad things may happen if a write transaction is aborted (read only)
• WRCMD Command is a write operation if set
• WTREQ F011 Write Request flag, i.e., the requested sector was found during a
write operation (read only)
The following registers apply to the 45IO27 only, i.e., are MEGA65 specific:

HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
DBGMO- DBGMO- DBGW- DBGW- DBGW-
D6A0 54944 DENSITY DBGDIR DBGDIR
TORA TORA DATA GATE GATE
D6A2 54946 DATARATE

• DATARATE Set number of bus cycles per floppy magnetic interval (decrease to
increase data rate)
• DBGDIR Control floppy drive STEPDIR line
• DBGMOTORA Control floppy drive MOTOR line
• DBGWDATA Control floppy drive WDATA line
• DBGWGATE Control floppy drive WGATE line
• DENSITY Control floppy drive density select line

SD CARD CONTROLLER AND F011


VIRTUALISATION FUNCTIONS
For those situations where you do not wish to use real floppy disks, the 45IO27 supports
two complementary alternative modes:
• SD card Based Disk Image Access.
• Virtualised Disk Image Access.
This is in addition to providing direct access to a dual-bus SD card interface.

U-14
SD card Based Disk Image Access
The 45IO27 is both a floppy drive and SD card controller. This enables it to trans-
parently allow access to D81 disk images stored on the SD card. Further, because
the controller is combined, it is possible to still have the floppy drive step and spin as
though it were being used, providing considerable atmosphere and sense of realism,
even when using disk images.
The 45IO27 supports both 800KB standard D81 disk images, as well as 64MB “MEGA
Images”. While an operating system may impose restrictions based on the name of
a file, the 45IO27 is blind to these requirements. Instead, it requires only that a
contiguous 800KB or 64MB of the SD card is used to contain a disk image.
When a disk image is enabled, the corresponding set of sectors on the SD card are
effectively placed under user control, and the operating system is no longer able to
prevent the reading or writing of any of those sectors. Thus you should never enable
access to an image that is shorter than the required size, as it will otherwise allow the
user to unwittingly or maliciously access and/or modify data that is not part of the
image file.
For the same reason, only the hypervisor can change the sector number where a disk
image starts (the D?STARTSEC? signals), or allow the use of disk images instead of the
real floppy drive (USEREAL0 and USEREAL1 signals). Once the Hypervisor has set the
start sector of a disk image, and cleared the USEREAL0 or USEREAL1 signal, the user
can still controll whether an access will go to the real floppy drive or to the disk image
by respectively clearing or setting the appropriate signal. For drive 0, this is D0IMG,
and for drive 1, it is D1IMG.
There are also signals to control whether a disk image is an 800KB D81 image or a
64MB MEGA Disk image, and whether a disk image is present, and whether it is write
protected. These are all located in the $D68B register. Because of the ability of
manipulation of these registers to corrupt or improperly access data, these signals are
all read-only, except from within the hypervisor.
The following table lists the registers that are used to control access to disk images
resident on the SD card:

HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D68A 54922 D1D64 D0D64 –
D68B 54923 D1MD D0MD D1WP D1P D1IMG D0WP D0P D0IMG
D68C 54924 D0STARTSEC0
D68D 54925 D0STARTSEC1
D68E 54926 D0STARTSEC2
D68F 54927 D0STARTSEC3
D690 54928 D1STARTSEC0
D691 54929 D1STARTSEC1
D692 54930 D1STARTSEC2
continued …

U-15
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D693 54931 D1STARTSEC3
USE- USE-
D6A1 54945 – SILENT TARGANY
REAL1 REAL0

• D0D64 F011 drive 0 disk image is D64 mega image if set (otherwise 800KiB
1581 or D65 image)
• D0IMG F011 drive 0 use disk image if set, otherwise use real floppy drive.
• D0MD F011 drive 0 disk image is D65 image if set (otherwise 800KiB 1581
image)
• D0P F011 drive 0 media present
• D0STARTSEC0 F011 drive 0 disk image address on SD card (LSB)
• D0STARTSEC1 F011 drive 0 disk image address on SD card (2nd byte)
• D0STARTSEC2 F011 drive 0 disk image address on SD card (3rd byte)
• D0STARTSEC3 F011 drive 0 disk image address on SD card (MSB)
• D0WP Write enable F011 drive 0
• D1D64 F011 drive 1 disk image is D64 image if set (otherwise 800KiB 1581 or
D65 image)
• D1IMG F011 drive 1 use disk image if set, otherwise use real floppy drive.
• D1MD F011 drive 1 disk image is D65 image if set (otherwise 800KiB 1581
image)
• D1P F011 drive 1 media present
• D1STARTSEC0 F011 drive 1 disk image address on SD card (LSB)
• D1STARTSEC1 F011 drive 1 disk image address on SD card (2nd byte)
• D1STARTSEC2 F011 drive 1 disk image address on SD card (3rd byte)
• D1STARTSEC3 F011 drive 1 disk image address on SD card (MSB)
• D1WP Write enable F011 drive 1
• SILENT Disable floppy spinning and tracking for SD card operations.
• TARGANY Read next sector under head if set, ignoring the requested side, track
and sector number.
• USEREAL0 Use real floppy drive for drive 0 if set (read-only, except for from
hypervisor)
• USEREAL1 Use real floppy drive for drive 1 if set (read-only, except for from
hypervisor)

U-16
F011 Virtualisation
In addition to allowing automatic read and write access to SD card based D81 images,
it is possible to connect a program to the serial monitor interface that provides and
accepts data as though it were the floppy disk.
This is commonly used in a cross-development environment, where you wish to fre-
quently modify a disk image that is used by a program you are developing – without
the need to continually push new versions of the disk image on the MEGA65’s SD card
first. It also has the added benefit that it allows you to easily visualise which sec-
tors are being read from and written to, which can help speed up development and
debugging of your program.
This function operates together with the MEGA65’s Hypervisor by triggering hyperrupts
(that is, interrupts that activate the Hypervisor). There is then special code in the
Hypervisor that communicates with the m65 program via the serial monitor interface.
If that all sounds rather complex, all you need to know is that to use this function,
you run the m65 utility with arguments like -d image.d81. This should automatically
establish the link with the MEGA65. If the BASIC interprettor stops responding, press
the reset button (not the power switch) on the left-hand side of your MEGA65, and
it should return to the BASIC’s READY. prompt – and if your supplied disk image has a
C65 auto-boot function, then it should automatically start booting.
This function works very well if the host computer runs Linux, and will allow loading at
a speed of around 60KB per second. However, it may be much slower on Windows or
Apple OSX-based systems.
Of course to use this, you will also need an interface module and/or cable to connect
your cross-development system to the MEGA65’s serial monitor interface. This is most
easily done using a Trenz TE0790-03 JTAG adapter and mini-USB cable.
More information on using this interface and the m65 tool can be found in Chapter/Ap-
pendix 16 on page 16-3.

Dual-Bus SD card Controller


The 45IO27 contains a high-speed dual-bus SD card controller. This controller oper-
ates in SPI x1 mode at a clock speed of 20MHz, providing a maximum throughput of
approximately 2MB/sec. The quality of the SD card makes a signficant difference to
performance, with some cards routinely delivering 1.7MB/sec, while others 1MB/sec
or less. Generally speaking, newer cards marketted as being suitable for video record-
ing perform better. The controller supports SDHC cards, and has experimental support
for SDXC cards. Legacy SD cards with a capacity of 2GB or less are not supported,
as these use a different addressing mode.
The SD controller itself is very simple to drive: Supply the sector number in $D861-
$D684, and then issue a read or write command to the command register ($D680).

U-17
The SD controller supports only sector-based buffered operations, using the sector
buffer. In hypervisor mode, the sector buffer is located at $FFD6E00 – $FFD6FFF,
while when the computer is in normal operating mode, the SD card and the floppy
controller share a single address for both the floppy drive and SD card sector buffers.
Which buffer is visible at that address is dictated by the BUFSEL signal. If it is 1, then
the SD card buffer is visible, while if it is 0, then the floppy drive sector buffer is visible.
See also Sub-section U on page U-4 for further discussion on the precise behaviour
of this buffer with regard to normal mode versus Hypervisor mode, and how it can also
be mapped at $DE00.

Write Gate
When writing a sector, you must, however, first open the “write gate”. This is a mech-
anism to prevent accidental corruption of data on the SD card, as it requires two
different values to be written to the command register ($D680) in quick succession:
You have approximately 1 milli second after opening the write gate to command the
write, before the write gate effectively closes again, write-protecting the SD card until
the write gate is opened again. There are two different write gates: One for the mas-
ter boot record (sector 0), and the other for all other sectors, both of which are listed
in the command table below. This is designed to provide additional protection to the
very important master boot record sector against programs accidentally calculating
sector 0 as the target for an ordinary write.

Fill Mode
Where you wish to fill sectors with a constant value, the 45IO27 supports a mode for
this, so that you do not need to overwrite the contents of the sector buffer. This is
activated by placing the desired fill value into the FILLVAL register ($D686), and then
issuing the enable fill mode command ($83), performing the sector write operations,
and then issuing the disable fill mode command ($84).

Selecting Among Multiple SD cards


The controller supports two SD card interfaces, and it is possible to have a card in both
at the same time. However, each card needs to be reset and commanded separately.
Only one card can be commanded at a time. That said, it is possible to reset each
card once, and then switch between the cards to perform individual operations.
To select the first SD card slot, write $C0 to the SD Controller Command Register
($D680). To select the second SD card slot, write $C1 instead.

U-18
SD Controller Command Table
The SD controller supports the following commands that can be written to the com-
mand register at $D680:

Command Function
Place SD card under reset (deprecated. Use
$00 (0)
command $10 instead)
$01 (1) Release SD card from reset
$02 (2) Read a sector from the SD card
$03 (3) Write a single sector to the SD card
Write the first sector of a multi-sector write to the SD
$04 (4)
card
Write a subsequent sector of a multi-sector write to
$05 (5)
the SD card
Write the final sector of a multi-sector write to the
$06 (6)
SD card
$0C (12) Request flush of SD card write buffers (experimental)
$0E (14) Pull SD handshake line low (debug only)
$0F (15) Pull SD handshake line high (debug only)
Place SD card under reset with flags set (preferred
$10 (16)
method)
$11 (17) Release SD card from reset (alternate method)
Clear the SDHC/SDXC flag, selecting legacy SD
$40 (64)
card mode (deprecated)
$41 (65) Set the SDHC/SDXC mode flag
End force clearing of SD card state machine error
$44 (68)
flag
Begin force clearing of SD card state machine error
$45 (69)
flag
Open write-gate to sector 0 (master boot record) for
$4D (77)
approximately 1 milli-second
Open write-gate for all sectors > 0 for approximately
$57 (87)
1 milli-second
Enable mapping of the SD/FDC sector buffer at
$81 (129)
$DE00 – $DFFF
Disable mapping of the SD/FDC sector buffer at
$82 (130)
$DE00 – $DFFF
$83 (131) Enable SD card Fill Mode
$84 (132) Disable SD card Fill Mode
$C0 (192) Select SD card Slot 0
$C1 (193) Select SD card Slot 1

U-19
Note that the hypervisor can enable or disable direct access to the SD controller. The
hypervisor operating system may provide a mechanism for requesting permission to
access the SD card controller, e.g., for disk management utilities.
The SD card controller registers are as follows:

HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D680 54912 CMDANDSTAT
D681 54913 SECTOR0
D682 54914 SECTOR1
D683 54915 SECTOR2
D684 54916 SECTOR3
D686 54918 FILLVAL
D68A 54922 – VFDC1 VFDC0 VICIII CDC00
FDC- FDC- AUTO-
D6AE 54958 FDCTIBEN FDCENC
2XSEL VARSPD 2XSEL
VW-
D6AF 54959 – VLOST VDRQ VRNF VEQINH VRFOUND
FOUND

• AUTO2XSEL Automatically select DD or HD decoder for last sector display


• CDC00 (read only) Set if colour RAM at $DC00
• CMDANDSTAT SD controller status/command
• FDC2XSEL Select HD decoder for last sector display
• FDCENC Select floppy encoding (0=MFM, 1=RLL2,7, F=Raw encoding)
• FDCTIBEN Enable use of Track Info Block settings
• FDCVARSPD Enable automatic variable speed selection for floppy controller us-
ing Track Information Blocks on MEGA65 HD floppies
• FILLVAL WRITE ONLY set fill byte for use in fill mode, instead of SD buffer data
• SECTOR0 SD controller SD sector address (LSB)
• SECTOR1 SD controller SD sector address (2nd byte)
• SECTOR2 SD controller SD sector address (3rd byte)
• SECTOR3 SD controller SD sector address (MSB)
• VDRQ Manually set f011_drq signal (indented for virtual F011 mode only)
• VEQINH Manually set f011_eq_inhibit signal (indented for virtual F011 mode
only)
• VFDC0 (read only) Set if drive 0 is virtualised (sectors delivered via serial monitor
interface)

U-20
• VFDC1 (read only) Set if drive 1 is virtualised (sectors delivered via serial monitor
interface)
• VICIII (read only) Set if VIC-IV or ethernet IO bank visible
• VLOST Manually set f011_lost signal (indented for virtual F011 mode only)
• VRFOUND Manually set f011_rsector_found signal (indented for virtual F011
mode only)
• VRNF Manually set f011_rnf signal (indented for virtual F011 mode only)
• VWFOUND Manually set f011_wsector_found signal (indented for virtual F011
mode only)

TOUCH PANEL INTERFACE


Some MEGA65 variants include an LCD touch panel, primarily the MEGAphone hand-
held version of the MEGA65. The touch interface supports the detection of two simul-
taneous touch events. Some variants may also support gesture detection, however,
this is still very experimental.
The touch detection interface that is contained in the 45IO27 is complemented by
the on-screen-keyboard interface of the 4551 UART and GPIO controller. Refer to
section S for further information. Of particular relevance are bit 7 of the registers
$D615 – $D617 which allow activating the on-screen keyboard interface, selecting
whether the on-screen keyboard is placed in the upper or lower portion of the screen,
and whether the primary or secondary on-screen keyboard is displayed.
Direct connections between the 4551 and the 45IO27 combine information about
any currently displayed on-screen keyboard and the touch interface controller, al-
lowing synthetic keyboard events to be automatically triggered when the on-screen
keyboard portion of the touch interface is pressed. This allows the touch interface
to be used to drive the on-screen keyboard without requiring any support from user
programs. This works even when the on-screen keyboard is moving during activation
or transitioning between the top and bottom of the screen.
As touch interfaces can require calibration, the 45IO27 allows for a linear transfor-
mation of both the X and Y coordinates of a touch event. Specifically, there are scale
(TCHXSCALE and TCHYSCALE) and offset registers (TCHXDELTA and TCHYDELTA) that
provide for this transformation. It is also possible to flip the touch screen coordinates
in either or both the X and Y axes. These calibration registers also affect the operation
of the on-screen keyboard.
It should also be noted that some touch interfaces do not have constant horizontal or
vertical resolution. For example, some panels have a low horizontal resolution region
in the middle of the panel, which can require some care to accommodate.
To detect the primary touch event, the TOUCH1XLSB, TOUCH1XMSB, TOUCH1YLSB,
TOUCH1YMSB registers can be read. Similar registers exist for the 2nd touch event:

U-21
TOUCH2XLSB, TOUCH2XMSB, TOUCH2YLSB, TOUCH2YMSB. Each touch event has a
signle bit flag that indicates whether the touch event is currently valid: the EV1 and
EV2 bits of the register $D6B0. There are also corresponding bit-fields that indicate
whether a given touch event has been made or released, allowing the detection of
when a finger both makes and breaks contact with the screen. The UPDN1 and UPDN2
signals provide this information. Binary values of 01 and 10, respectively indicate if
the finger has been removed or pressed against the touch panel. Values of 00 and
11 mean that a finger is either being held or not being held against the touch panel.
The primary touch event is also fed into the lightpen input of the VIC-IV, and can be
detected using the normal light pen registers of the VIC-IV.
The registers for the touch panel interface are as follows:

HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D6B0 54960 YINV XINV UPDN2 UPDN1 EV2 EV1
D6B1 54961 CALXSCALELSB
D6B2 54962 CALXSCALEMSB
D6B3 54963 CALYSCALELSB
D6B4 54964 CALYSCALEMSB
D6B5 54965 CALXDELTALSB
D6B7 54967 CALYDELTALSB
D6B8 54968 CALYDELTAMSB
D6B9 54969 TOUCH1XLSB
D6BA 54970 TOUCH1YLSB
D6BB 54971 – TOUCH1YMSB – TOUCH1XMSB
D6BC 54972 TOUCH2XLSB
D6BD 54973 TOUCH2YLSB
D6BE 54974 – TOUCH2YMSB – TOUCH2XMSB
D6C0 54976 GESTUREID GESTUREDIR

• CALXDELTALSB Touch pad X delta LSB


• CALXSCALELSB Touch pad X scaling LSB
• CALXSCALEMSB Touch pad X scaling MSB
• CALYDELTALSB Touch pad Y delta LSB
• CALYDELTAMSB Touch pad Y delta MSB
• CALYSCALELSB Touch pad Y scaling LSB
• CALYSCALEMSB Touch pad Y scaling MSB
• EV1 Touch event 1 is valid
• EV2 Touch event 2 is valid
• GESTUREDIR Touch pad gesture directions (left,right,up,down)

U-22
• GESTUREID Touch pad gesture ID
• TOUCH1XLSB Touch pad touch #1 X LSB
• TOUCH1XMSB Touch pad touch #1 X MSBs
• TOUCH1YLSB Touch pad touch #1 Y LSB
• TOUCH1YMSB Touch pad touch #1 Y MSBs
• TOUCH2XLSB Touch pad touch #2 X LSB
• TOUCH2XMSB Touch pad touch #2 X MSBs
• TOUCH2YLSB Touch pad touch #2 Y LSB
• TOUCH2YMSB Touch pad touch #2 Y MSBs
• UPDN1 Touch event 1 up/down state
• UPDN2 Touch event 2 up/down state
• XINV Invert horizontal axis
• YINV Invert vertical axis

AUDIO SUPPORT FUNCTIONS


The 45IO27 provides the primary interface into the MEGA65’s full cross-bar audio
mixer. This includes the interface for reading or modifying the mixer co-efficients, as
well as accessing the mixer feedback registers, and setting the 16-bit digital sample
values that are two of the input channels into the audio mixer.
The audio mixer consists of 128 coefficients, each of which is 16 bits. Each audio out-
put channel, e.g., left speaker, right speaker, left headphone, right headphone, cellular
modem 1 (MEGAphone models only) and so on, are generated by taking each of the
audio input channels, multiplying them by the appropriate coefficient, and adding it
to the total output of the audio output channel.
Because each audio output channel has its own set of coefficients that are applied to
all of the audio input channels, this means that it is possible to produce totally different
audio out each audio channel: For example, it is possible to play your favourite quadro-
phonic SID music out of the headphones while rick-rolling passers by with Amiga-style
MOD audio. This is why the audio mixer is refered to as a full cross-bar mixer, be-
cause there are no restrictions on how you mix each audio output channel. In this
regard, it is very similar to a full-function audio desk, allowing different mixing levels
for different speakers.
Because the audio coefficients are 16 bits each, each one is formed using two suc-
cessive bytes of the audio co-efficient space. Changes to the audio coefficients take
effect immediately, so care should be taken when changing coefficients to avoid au-
dible clicks and pops. Also, you must allow 32 cycles to elapse before changing the

U-23
selected audio coefficient, as otherwise the change may be discarded if the audio
mixer accumulator has not had time to re-visit that coefficient.
The audio sources on the MEGA65 and MEGAphone devices are as follows:

Input Channel
Connection
ID
$0 (0) Left SIDs
$1 (1) Right SIDs
$2 (2) Modem Bay 1 (MEGAphone only)
$3 (3) Modem Bay 2 (MEGAphone only)
$4 (4) Bluetooth™ Left
$5 (5) Bluetooth™ Right
$6 (6) Headphone Interface 1
$7 (7) Headphone Interface 2
$8 (8) Digital audio Left
$9 (9) Digital audio Right
$A (10) MEMs Microphone 0 (Nexys4 and MEGAphone only)
$B (11) MEMs Microphone 1 (MEGAphone only)
$C (12) MEMs Microphone 2 (MEGAphone only)
$D (13) MEMs Microphone 3 (MEGAphone only)
Headphone jack microphone (Nexys4 and
$E (14)
MEGAphone only)
OPL-compatible FM audio (shares co-efficient with
$F (15)
input 14)

The OPL-compatible FM audio which is on source 15 is controlled by the coefficient for


source 14. This is because the coefficient for source 15 provides the master volume
level for each output. The OPL-compatible FM audio device is not currently functional
in the MEGA65 core.
The audio cross-bar mixer supports the following eight output channels:

Output
Connection
Channel ID
Left Primary Speaker (digital audio on MEGA65
$0 (0) R2/R3, physical speaker on MEGAphone, headphone
jack audio on Nexys4)
Right Primary Speaker (digital audio on MEGA65
$1 (1) R2/R3, physical speaker on MEGAphone, headphone
jack audio on Nexys4)
$2 (2) Modem Bay 1 audio output (MEGAphone only)
$3 (3) Modem Bay 2 audio output (MEGAphone only)
$4 (4) Bluetooth Left Audio (MEGAphone only)
$5 (5) Bluetooth Right Audio (MEGAphone only)
continued …

U-24
…continued
Output
Connection
Channel ID
Headphone Left output (MEGA65 R2/R3 and
$6 (6) MEGAphone only. On Nexys4 boards the primary
speaker drives the 3.5mm jack)
Headphone Right output (MEGA65 R2/R3 and
$7 (7) MEGAphone only. On Nexys4 boards the primary
speaker drives the 3.5mm jack)

To determine the coefficient register number for a given source and output, multiply
the output number by 32 and multiply the source number by 2. This will be the register
number for the LSB of the 16-bit coefficient. The MSB will be the next register. For
example, to set the coefficient of the right SIDs to the 2nd modem bay audio output,
the coefficient would be 32 × 3 + 1 × 2 = 96 + 2 = 98.

Other Audio Features


The audio sub-system supports several other features, that are currently pending fur-
ther documentation.

Mixer Feedback Registers


These registers allow the processor to access the mixed audio for a particular output
channel. This can be used to implement displays of audio waveforms, or implement
certain audio-effects, such as reverb.

8/16 Bit Stereo Digital Audio Registers


Registers are provided for injecting 8 or 16 bit audio samples directly into dedicated
input channels of the audio mixer, providing a simple way to play digital audio data.
This is particularly useful for procedurally generated audio data. For recorded sam-
ples, it is generally simpler and better to use the Audio DMA functionality that fully
automates the play-back of digital audio. Audio DMA is especially heplful at higher
sample rates, as it reduces the burden on the CPU, and greatly reduces sample jitter.

U-25
Pulse Width vs Pulse Density Modula-
tion
For models of the MEGA65 that use a 1-bit over-sampled output for audio (upto and
including the R3/R3A model), it is possible to select between these two different over-
sampling methods. Both have similar performance, but users may prefer one over the
other. This choice has no effect on the R4 or newer models that use a dedicated
audio DAC to feed audio to the 3.5mm audio jack, and that has intrinsically better
audio quality. For owners of older models, the planned internal expansion board for
the MEGA65 may include an improved audio output circuit, depending on the final
configuration of that board. No timeline is currently available for the availability of
this board. In the interim, use of HDMI audio output is the recommended solution, as
the audio is encoded digitally over the HDMI cable.

HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D6F4 55028 MIXREGSEL
D6F5 55029 MIXREGDATA
D6F8 55032 DIGILLSB
D6F9 55033 DIGILMSB
D6FA 55034 DIGIRLSB
D6FB 55035 DIGIRMSB
D6FC 55036 READBACKLSB
D6FD 55037 READBACKMSB
D711 55057 – PWMPDM –

• DIGILEFTLSB Digital audio, left channel, LSB


• DIGILEFTMSB Digital audio, left channel, MSB
• DIGILLSB 16-bit digital audio out (left LSB)
• DIGILMSB 16-bit digital audio out (left MSB)
• DIGIRIGHTLSB Digital audio, left channel, LSB
• DIGIRIGHTMSB Digital audio, left channel, MSB
• DIGIRLSB 16-bit digital audio out (right LSB)
• DIGIRMSB 16-bit digital audio out (right MSB)
• MIXREGDATA Audio Mixer register read port
• MIXREGSEL Audio Mixer register select
• PWMPDM PWM/PDM audio encoding select
• READBACKLSB audio read-back LSB (source selected by $D6F4)
• READBACKMSB audio read-back MSB (source selected by $D6F4)

U-26
MISCELLANEOUS I/O FUNCTIONS

U-27
U-28
APPENDIX V
4541 Serial Bus Controller
• Overview
• Features of the 4541
• Theory of Operation
• Examples
• Command Reference
• Register Table
• Serial Bus Timing
• Optional Integrated Data-Logger
V-2
OVERVIEW
The 4541 is a Commodore™ serial peripheral bus compatible bus controller, that
greatly reduces the effort required to communicate with devices on this bus.

FEATURES OF THE 4541


Supports Enhanced Serial Protocol
Variants
The 4541 supports the JiffyDOS™ extensions to this protocol, that allow data transfers
approximately 10× faster than using the original protocol. It is also expected that
a future revision of the 4541 will support Commodore’s fast serial protocol, that is
present in the 1571 and 1581 disk drives.

Interrupt Enabled Processor Offload


The 4541 performs serial communications independent of the microprocessor. To-
gether with an IRQ functionality, this allows software to continue on other tasks while
serial peripheral communications occurs, requiring only to be briefly interrupted when
the next event on the serial peripheral bus occurs.

Processor Speed Independence


A major advantage of the 4541, is that it also handles all timing requirements of
communications on this bus, allowing the bus to be driven by a processor that can run
at different speeds, without having to modify the the bus controller software.

Co-Existence through Open-Collector


Logic
Because the 4541 uses open-collector logic, it can be used in parallel with existing
software-based implementations of the bus protocol, ensuring compatibility with ex-
isting software. It is installed in this configuration in the MEGA65, allowing the legacy
software-based serial peripheral communications software that controls the serial pe-
ripheral bus to continue to be used unmodified.

V-3
THEORY OF OPERATION
The 4541 presents a quite simple interface: You issue commands, wait for a response,
and retrieve any data that the command retrieved. Some commands also require a
data byte, which is provided by a dedicated register. There is also a device info regis-
ter, that lets you see what the 4541 believes about the current status of the most re-
cently requested device, including whether it is present, and whether it supports either
or both of the JiffyDOS™ or Commodore™ 128 extensions to the standard protocol.
So, for example, to release the Attention line, you can simply write the appropriate
command byte value (65 = $41) to the command register at $D698, and then check
for the completion status in the status register at $D697, as shown in the following
example written in BASIC65:

10 POKE $D698 , $41


20 IF ( PEEK ( $D697 ) AND $20 ) = $00 GOTO 20
30 PRINT " DONE "

The 4541 implements a set of commands that map very closely to the KERNAL calls
that are used to control the IEC bus on the C64 and related computers. In most cases,
there is a single corresponding command for the 4541, although in a few cases, you
may need to issue two commands, as summarised in the following table:

KERNAL Call Meaning and Equivalent 4541 Command(s)


$FF93 LSTNSA Send LISTEN secondary address.
4541 Equivalent: Data = Binary OR of $60 and the
desired secondary address. Command $30. Then
Command $41 to release the Attention line.
$FF96 TALKSA Sent TALK secondary address.
4541 Equivalent: Data = Binary OR of $60 and the
desired secondary address. Command $30. Then
Command $41 to release the Attention line.
$FFA5 IECIN Receive a byte from the serial peripheral bus.
4541 Equivalent : Command $32. Received byte is
available in the data register on completion.
$FFA8 IECOUT Send a byte to the serial peripheral bus.
4541 Equivalent : Data = the byte to send.
Command $31 (or $30 if the byte is to be sent under
Attention).
$FFA8 UNTALK Send UNTALK command to serial peripheral bus.

V-4
KERNAL Call Meaning and Equivalent 4541 Command(s)
4541 Equivalent : Data = $5F. Command $30.
$FFAB UNLISTN Send UNLISTEN command to serial peripheral bus.
4541 Equivalent : Data = $3F. Command $30.
$FFB1 LISTEN Send LISTEN command to the serial peripheral bus.
4541 Equivalent : Data = $20 plus the device
number. Command $30.
$FFB4 TALK Send TALK command to the serial peripheral bus.
4541 Equivalent : Data = $40 plus the device
number. Command $30.
$FFB7 READST Read the status of the serial peripheral bus.
4541 Equivalent : Read the status bits from $D698.
For convenience, the upper bits of this status byte
have the same layout as used in the KERNAL.

The 4541 is very obedient: If you ask it to do something new, it will start doing that
immediately, even if it was in the middle of doing something else – even if it was half-
way through sending a byte of data to the serial peripheral bus!
You should therefore always wait until the IRQREADY bit in $D697 is set before issuing
each command, or reading the status bits, to make sure that the controller has finished
whatever it was last asked to do.

EXAMPLES
Reading the DOS channel status
The following BASIC65 program can be used to talk to a device connected to the
serial peripheral bus. Note that because it uses the 4541, and not the C65/MEGA65
CBDOS, it ignores the presence of the internal 3.5” disk drive, because that drive is
not connected to the serial peripheral bus.

V-5
10 REM ABORT ANY E X I S T I N G 4541 C O M M A N D IN P R O G R E S S
20 POKE $D698 , $00
30 REM RESET THE SERIAL P E R I P H E R A L BUS BY P U L L I N G
40 REM THE RESET PIN LOW FOR 1 SECOND
50 POKE $D698 , $72 : SLEEP 1 : POKE $D698 , $52
60 REM GIVE C O N N E C T E D D E V I C E S TIME TO GET READY AFTER RESET
70 SLEEP 2: REM THE 1541 TAKES QUITE A WHILE TO RESET !
80 REM SELECT THE DEVICE NUMBER TO TALK TO
90 D = 8
100 PRINT " DEVICE "; D ; " TALK "
110 POKE $D699 , $40 + D : POKE $D698 , $30 : GOSUB 1000
120 PRINT " S E C O N D A R Y A D DR E S S 15"
130 POKE $D699 , $6F : POKE $D698 , $30 : GOSUB 1000
140 PRINT " TURN AROUND TO LISTEN "
150 POKE $D698 , $35 : GOSUB 1000
160 PRINT " READ DOS STATUS "
170 POKE $D698 , $32 : GOSUB 1000
180 PRINT CHR$ ( PEEK ( $D699 ) );
190 CC = CC + 1 : IF CC < 200 GOTO 180
999 END
1000 REM WAIT FOR 4541 TO FINISH C O M M A N D
1010 S = PEEK ( $D697 ) : IF ( S AND 32) = 32 GOTO 1020
1020 GOTO 1000
1030 IF S AND 128 THEN PRINT " DEVICE NOT P R E S E N T " : END
1040 RETURN

If you have a 1581 with a JiffyDOS™ ROM connected, this program will display some-
thing like the following when run:

READY .
RUN
DEVICE 8 TALK
S E C O N D A R Y ADDR ESS 15
TURN AROUND TO LISTEN
READ DOS STATUS
73 ,( C ) 1989 J I F F Y D O S 6.0 1581 ,00 ,00
00 , OK ,00 ,00
00 , OK ,00 ,00
00 , OK ,00 ,00
...
00 , OK ,0
READY .

V-6
COMMAND REFERENCE
The following table lists the set of command codes suppoprted by the 4541.

Command Byte Action


Abort Running Commands
$00 Abort any executing command.

$01 Reset controller state: Release ATN, CLK, DATA, SRQ


and enable default protocol selection.
Bit-Bashing Commands
$41 Release Attention (ATN) line to 5V.
$61 Pull Attention (ATN) line to 0V.
$43 Release clock (CLK) line to 5V.
$63 Pull clock (CLK) line to 0V.
$44 Release data (DATA) line to 5V.
$64 Pull data (DATA) line to 0V.
$53 Release fast serial clock (SRQ) line to 5V.
$73 Pull fast serial clock (SRQ) line to 0V.
$52 Pull reset (RESET) line to 0V.
$72 Release reset (RESET) line to 5V.
Protocol Variant Control Commands

$4A Enable solicitation of JiffyDOS™ extension to the


serial protocol.

$6A Disable solicitation of JiffyDOS™ extension to the


serial protocol.

$46 Enable solicitation of Commodore™ 1571/1581


fast serial extension to the serial protocol.

$66 Disable solicitation of Commodore™ 1571/1581


fast serial extension to the serial protocol.
Serial Bus Protocol Commands

$30 Send byte in $D699 under attention. Attention line is


held at 0V at the end of the transaction.

V-7
Command Byte Action

$31 Send bye in $D699 without attention. The attention


line is released, if it was previously asserted.
Receive a byte from the peripheral serial bus. There
$32 must be a previously activated talker. The received
byte is stored in $D699.
$33 RESERVED

$34 Send a byte and indicate EOI. Attention is released


prior to transmission, if was asserted.
$35 Turn around from talker to listener.
Protocol Timing Commands
$80 Reset protocol timing to defaults.

$81 Set TR delay (1 – 255 microseconds). Old value can


be read from $D699.

$82 Set TTK delay (1 – 255 microseconds). Old value can


be read from $D699.

$83 Set TDC timeout (1 – 255 milliseconds). Old value


can be read from $D699.

$84 Set TBB delay (1 – 255 microseconds). Old value can


be read from $D699.

$85 Set THA delay (1 – 255 microseconds). Old value can


be read from $D699.

$86 Set TST delay (1 – 255 microseconds). Old value can


be read from $D699.

$87 Set TVT delay (1 – 255 microseconds). Old value can


be read from $D699.

$88 Set TAL delay (1 – 255 microseconds). Old value can


be read from $D699.

$89 Set TAC delay (1 – 255 microseconds). Old value can


be read from $D699.

$8A Set TAT delay (1 – 255 milliseconds). Old value can


be read from $D699.

V-8
Command Byte Action
Set TH delay (1 – 255 milliseconds). Old value can
be read from $D699. This value currently has no
$8B effect, as the 4541 allows truly infinite data-hold off
by a listener, except for bytes sent under attention,
where THA is used instead.

$8C Set TNE delay (1 – 255 microseconds). Old value can


be read from $D699.

$8D Set TF delay (4 – 1020 microseconds). Old value can


be read from $D699, scaled by 4.

$8E Set TYE delay (1 – 255 microseconds). Old value can


be read from $D699.

$8F Set TEI delay (1 – 255 microseconds). Old value can


be read from $D699.

$90 Set TAR delay (1 – 255 microseconds). Old value can


be read from $D699.

$91 Set TJT delay (4 – 1020 microseconds). Old value


can be read from $D699, scaled by 4.

$92 Set TJ0 delay (1 – 255 microseconds). Old value can


be read from $D699.

$93 Set TJ1 delay (1 – 255 microseconds). Old value can


be read from $D699.

$94 Set TJ2 delay (1 – 255 microseconds). Old value can


be read from $D699.

$95 Set TJ3 delay (1 – 255 microseconds). Old value can


be read from $D699.

$96 Set TJ4 delay (1 – 255 microseconds). Old value can


be read from $D699.

$97 Set TJ5 delay (1 – 255 microseconds). Old value can


be read from $D699.

$98 Set TJ6 delay (1 – 255 microseconds). Old value can


be read from $D699.

$99 Set TJ7 delay (1 – 255 microseconds). Old value can


be read from $D699.

$9A Set TJ8 delay (1 – 255 microseconds). Old value can


be read from $D699.

V-9
Command Byte Action

$9B Set TJ9 delay (1 – 255 microseconds). Old value can


be read from $D699.

$9C Set TJ10 delay (1 – 255 microseconds). Old value


can be read from $D699.

$9D Set TJ11 delay (1 – 255 microseconds). Old value


can be read from $D699.

$9E Set TJR delay (1 – 255 microseconds). Old value can


be read from $D699.

$9F Set TFS delay (1 – 255 microseconds). Old value can


be read from $D699.

$A0 Set TFF delay (1 – 255 microseconds). Old value can


be read from $D699.

$A1 Set TPULLUP delay (1 – 255 microseconds). Old value


can be read from $D699.

$A2 Set TJD delay (4 – 1020 microseconds). Old value


can be read from $D699, scaled by 4.

$A3 Set TJ12 delay (1 – 255 microseconds). Old value


can be read from $D699.
Diagnostic Commands
$D0 Trigger optional integrated data logger, if enabled.
Begin transmitting a 1KHz pulse train on the CLK and
$D1 DATA lines. Continues until aborted by another
command.

REGISTER TABLE
The 4541 has the following registers:

HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D694 54932 DATALOG0
D695 54933 DATALOG1
D697 54935 IRQFLAG IRQRX IRQRDY IRQTO IRQEN IRQRXEN IRQRDYEN IRQTOEN
D698 54936 STNODEV STNOEOI STSRQ STVERIFY STC STD STTO STDDIR
continued …

V-10
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D699 54937 DATA
D69A 54938 PRESENT PROT DIATN DEVNUM

• DATA Data byte read from IEC bus


• DATALOG0 Access integrated data logger in IEC controller
• DATALOG1 Access integrated data logger in IEC controller
• DEVNUM Lower 4 bits of currently selected device number
• DIATN Device is currently held under attention
• IRQEN Enable interrupts if set
• IRQFLAG Interrupt flag. Set if any IRQ event is triggered.
• IRQRDY Set if ready to process a command
• IRQRDYEN Enable TX interrupt source if set
• IRQRX Set if a byte has been received from a listener.
• IRQRXEN Enable RX interrupt source if set
• IRQTO Set if a protocol timeout has occurred, e.g., device not found.
• IRQTOEN Enable timeout interrupt source if set
• PRESENT Device is present
• PROT Device protocol support (5=C128/C65 FAST, bit 6 = JiffyDOS(tm))
• STC State of CLK line
• STD State of DATA line
• STDDIR Data direction when timeout occurred.
• STNODEV Device not present
• STNOEOI End of Indicate (EOI/EOF)
• STSRQ State of SRQ line
• STTO Timeout occurred
• STVERIFY Verify error occurred

V-11
SERIAL BUS TIMING
This section describes the timing requirements primarily from the perspective of a bus
controller. If you are designing serial bus peripherals, please take care to carefully
understand how these time requirements affect peripherals: The

Send Byte Under Attention


When the controller wishes to get the attention of one or more peripherals on the bus,
it uses the attention (ATN) line to indicate this: It pulls it low to 0V, and then sends one
or more bytes that will be received by all devices on the bus.
The SRQ line is not active in this transaction.
To summarise:
1. The controller pulls the ATN to 0V and releases the CLK, DATA and SRQ lines if it
was holding any of them at 0V.
2. All peripherals on the bus as they notice the ATN line at 0V begin to indicate this
by pulling the DATA line to 0V. The controller can’t tell how many, or whether all
the devices on the bus have responded: Rather, it can only tell that at least one
device has.
3. If no device responds, DATA stays at 5V, because no one is pulling it down, and
the controller will indicate a DEVICE NOT PRESENT error.
4. While the controller is waiting for devices to respond, it also pulls the CLK line to
0V, typically a short time after pulling the ATN line to 0V.
5. After the controller has waited a while, typically 1 millisecond, it assumes that
all peripherals who are going to answer the ATN request have.
6. Next, the controller releasing the CLK line to 5V to indicate that it wants to
send a byte of data on the bus. This is the start of the transmission of a byte
under ATN. All of the previous steps have had the purpose of establishing the
ATN communications.
7. The controller now waits for all devices to indicate their readiness to receive a
byte by releasing the DATA line back to 5V. Because the bus is open-collector,
if even a single device is not ready, it will be able to keep pulling the DATA line
down to 0V, causing the controller to wait. If this takes too long, the controller
may give up and indicate a timeout condition.
8. Once the last device has indicate it is ready to receive data, the controller waits
a little longer, to make sure that all of the devices are able to do their final
preparations to receive a byte. This doesn’t take very long.
9. After that delay, the controller begins sending the 8 bits of data, beginning with
the least significant bit (LSB), that is bit 0. For each bit, it first brinks the CLK line

V-12
low to indicate that data is being loaded onto the bus, pulls the DATA line to 0V
if it wants to send a 0 bit, or lets it float to 5V if it wants to send a 1 bit, and
then releases the CLK line back to 5V, and holds it there for a while. The timing
of this process is critical: If the CLK is low or high for too short a period of time,
the peripherals will get confused, and possibly miss one or more bits, resulting in
general chaos on the bus.
10. After the controller has sent the last bit, it holds the CLK line low, and releases
the DATA line. It expects one or more peripherals to pull the DATA line to 0V
within a short time to acknowledge reception of the byte. If this does not occur,
the controller may report a timeout or DEVICE NOT PRESENT error.
11. At the conclusion of this, the controller is holding the CLK line at 0V, and the
peripheral(s) are holding the DATA line at 0V. This combination serves to tell
each other that the controller is not yet wanting to send the next byte, and that
the peripheral(s) are not yet ready to receive the next byte.
12. If the controller wishes to send more bytes under attention, it will repeat this
process from the step where it released the CLK line to 5V.
13. Alternatively, if it was the last byte to be sent under this attention request, the
controller waits a short time, and then releases the ATN line.

ATN

CLK

DATA 0 1 2 3 4 5 6 7

SRQ
TAT THA TST TF
TAC TAL TNE TVT TR

First listener Listeners are Listener(s) have Stop here to


responds to all ready to accepted the send more
ATN request receive byte byte of data under ATN

V-13
Symbol Min 4541 Max Description
Device attention response timeout. A
device must respond to the ATN request
within this time. If not device responds
TAT – 1000 ∞ within this time, a DEVICE NOT
PRESENT error will result. Peripherals
should therefore conform to the 1,000
microsecond typical value.

TAC – 20 ∞? Time between pulling ATN low, before


CLK is also pulled low.
Time between first device responds to
TAL – 1000 ∞? ATN and the controller releases CLK to
5V.
Listener hold-off. The protocol allows a
listener can hold of for any desired
THA – 64 ms ∞ period of time, or for no time at all. The
4541 does not allow this during ATN
requests.
Non-EOI timing-channel response to
Ready For Data. If this interval is too
TNE – 40 200 long, the byte will be interpreted as an
EOI byte, and the peripherals will
require an EOI response (see TEI ).
Data bit setup time. Referred to as TS in
TST 20* 35 ∞ the C64 Programmer’s Reference
Guide.
Data bit valid hold time. Referred to as
TVT 20* 35 ∞ TV in the C64 Programmer’s Reference
Guide.

TF – 1000 1000 Frame handshake (acknowledge)


timeout.
Time between receiving end of frame
TR 20 200 ∞ acknowledgement and releasing the
ATN line to 5V.
All time units are in micro seconds, unless otherwise indicated.
* The Commodore™ 64 Programmer’s Reference Guide suggests that TS
and TV each have a minimum duration of 20 micro seconds. Our
investigations suggest that when communicating with a 1541, that
safe values for TST and TVT are closer to 70 micro seconds.

V-14
JiffyDOS™ Protocol Solicitation
If support for the JiffyDOS™ protocol extension is enabled, the 4541 will solicit this
during the transmission of TALK and LISTEN commands only. That is, when sending a
byte under attention that is in the range $20 – $5F.
The SRQ line is not active in this transaction.
To summarise:
1. The transmission of the byte occurs normally, until the TST period just before the
last bit (bit 7) of the byte.
2. Instead of waiting TST , the controller must instead wait for a much longer period,
typically 300 microseconds, so that the listener will recognise that it is being
asked if it supports the JiffyDOS™ protocol. The controller also releases the
DATA line to 5V.
3. If the listener supports the JiffyDOS™ protocol, it pulls DATA to 0V when it ob-
serves that the CLK line has been held low for the longer period.
4. After the listener has held DATA at 0V long enough for it to be sure the controller
has had the chance to notice, it releases the DATA line to 5V. The device will
now use the JiffyDOS™ for the requested TALK or LISTEN session.
5. The controller notes if the DATA line was pulled to 0V, and if so, records that the
listener has selected the JiffyDOS™ protocol, and will use this protocol for the
requested TALK or LISTEN session.
6. The controller now sends the final bit of the byte.
7. The controller ensures that the data bit value is visible on DATA before asserting
CLK, typically 1 – 4 microseconds.
8. The controller releases the CLK line to 5V to indicate to the listener that the final
data bit is ready.
9. The remainder of the byte transfers as normal.

V-15
ATN

CLK

DATA 0 1 2 3 4 5 6 7

SRQ
TAT THA TST TJD TF
TAC TAL TNE TVT TIJ TJA TR
TVT
Offer JD by JD-Enabled
holding CLK listener pulses
TPULLUP
low longer DATA low

Symbol Min 4541 Max Description


Time that CLK is held at 0V between
the two final bits of the byte to provide
TJD 320 320 ∞ the side-channel indication that the
controller wishes to use the JiffyDOS™
protocol extension.
Time before the listener accepts and
TIJ 100 – 295 begins to acknowledge the selection of
the JiffyDOS™ protocol extension.
The duration that the listener holds the
TIJ 4/100* – 200 DATA line low to acknowledge the
selection of the JiffyDOS™ protocol
extension.
All other timing values are identical to the sending a byte under attention case.
All time units are in micro seconds, unless otherwise indicated.
* The 4541 can detect pulse-widths as narrow as 4 microseconds.
However, software implementations of the protocol will require a larger
value. JiffyDOS™uses 100 microseconds.

V-16
JiffyDOS™ Send from Controller to Pe-
ripheral
Unlike the standard serial protocol, the JiffyDOS™ protocol uses different protocols for
sending and receiving. This is necessary on software imeplementations to obtain the
maximum speed, because the serial peripheral lines are mapped to different register
bits, and part of the magic of the JiffyDOS™ protocol is how it cleverly manipulates the
received bits to reconstruct the complete byte in the least possible time, and similarly
when transmitting.
The result is quite amazing: JiffyDOS™ can send a byte in approximately the same
time it takes the original protocol to send a bit!
Note that the JiffyDOS™ protocol transmits data bits with the opposite polarity to the
standard protocol, that is a 1 bit is indicated by 0V, while a 0 bit is indicated by 5V.
The SRQ line is not active in this transaction.
In summary,
1. Depending on the state of the controller when it begins transmitting, it may be
holding the CLK line at 0V. If so it releases it immediately.
2. Next, after some arbitrary time, the peripheral indicates it’s readiness to receive
a byte from the controller by releasing the DATA line to 5V.
3. The timing for the remainder of the byte transfer is now critical, because imme-
diately following releasing DATA, the peripheral will start reading the CLK and
DATA signals to transfer the byte.
4. The controller waits a few microseconds (TJ6 ).
5. The controller sets CLK to 0V if data bit 4 is 1, else releases it to 5V. The controller
sets DATA to 0V if data bit 5 is 1, else releases it to 5V.
6. The controller waits a few microseconds (TJ7 ).
7. The controller sets CLK to 0V if data bit 6 is 1, else releases it to 5V. The controller
sets DATA to 0V if data bit 7 is 1, else releases it to 5V.
8. The controller waits a few microseconds (TJ8 ).
9. The controller sets CLK to 0V if data bit 3 is 1, else releases it to 5V. The controller
sets DATA to 0V if data bit 1 is 1, else releases it to 5V.
10. The controller waits a few microseconds (TJ9 ).
11. The controller sets CLK to 0V if data bit 2 is 1, else releases it to 5V. The controller
sets DATA to 0V if data bit 0 is 1, else releases it to 5V.
12. The controller waits a few microseconds (TJ10 ).

V-17
13. The controller pulls the DATA line to 0V. It also releases the CLK line to 5V, unless
it wishes to indicate EOI, in which case it pulls the CLK line to 0V.
14. The controller waits a few microseconds, during which time the peripheral reads
the EOI value, and then pulls DATA to 0V. (TJ11 ).
15. The byte transfer is complete.
Note when sending the first byte under the JiffyDOS™ protocol, that the CLK signal
may be at 0V. The time between bytes (TJBB ) is not required (set to zero), because the
tight receive loop on the peripheral simply indicates when it is ready to receive each
next byte, which also contributes to it’s high speed.
Note also that the timing below is based on when the signals should be set. For soft-
ware implementations, the latency of the necessary processor instructions must be
taken into account. This is not a problem with the 4541, because it has a latency of
less than 50ns.

ATN

EOI
CLK 4632

DATA 5710

SRQ
TJBB TJ6
TH

Talker is Listener is
ready to ready to TJ8 TJ10 TJ12
send byte receive byte TJ7 TJ9 TJ11

Symbol Min 4541 Max Description


Time between bytes. There is no
minimum time between bytes with the
TJBB 0 0 ∞ JiffyDOS™ protocol, provided TJ12 is
sufficiently large, as that effectively
hides the latency of the receive routine.
TJ6 10 10 10 JiffyDOS™ transmit receiver setup time.

TJ7 13 13 13 JiffyDOS™ transmit hold time, first


di-bit.

V-18
Symbol Min 4541 Max Description

TJ8 11 11 11 JiffyDOS™ transmit hold time, second


di-bit.

TJ9 11 11 11 JiffyDOS™ transmit hold time, third


di-bit.

TJ10 12 12 12 JiffyDOS™ transmit hold time, fourth


di-bit.
JiffyDOS™ transmit hold time, status
bits. CLK carries the EOI notification,
TJ11 15 15 15 and DATA is set to 0V to indicate
successful transmission. The receiver
may indicate a frame error if DATA is
observed to be 5V.
JiffyDOS™ post transmit recovery time.
CLK is pulled to 0V, and DATA is set to
TJ12 18 18 18 0V to indicate successful transmission.
The receiver may indicate a frame error
if DATA is observed to be 5V.
TJR 15 15 15
All other timing values are identical to the sending a byte under attention case.
All time units are in micro seconds, unless otherwise indicated.

JiffyDOS™ Controller Receive from Pe-


ripheral
Unlike the standard serial protocol, the JiffyDOS™ protocol uses different protocols for
sending and receiving. This is necessary on software imeplementations to obtain the
maximum speed, because the serial peripheral lines are mapped to different register
bits, and part of the magic of the JiffyDOS™ protocol is how it cleverly manipulates the
received bits to reconstruct the complete byte in the least possible time, and similarly
when transmitting.
The result is quite amazing: JiffyDOS™ can send a byte in approximately the same
time it takes the original protocol to send a bit!
Unlike when transmitting via the JiffyDOS™ protocol where the data bits are inverted,
when receiving from a peripheral speaking the JiffyDOS™ protocol, the bits are rep-
resented naturally, i.e., with 1 = 5V and 0 = 0V.

V-19
The SRQ line is not active in this transaction.
To summarise:
1. The peripheral may wait an arbitrary period of time, before it has a byte to send
to the controller. When it does, it releases CLK to 5V.
2. When the controller notices this, it releases DATA to 5V, and begins the critical
timing section of the protocol.
3. The peripheral waits a short while. For peripherals using a software-
implementation, i.e., all Commodore™ drives, the delay is a natural consequence
of the processor instruction involved in commencing sending of the byte, similarly
for the following steps.
4. The peripheral places the first di-bit of data on the CLK and DATA lines, and waits
a short while.
5. The peripheral places the second di-bit of data on the CLK and DATA lines, and
waits a short while.
6. The peripheral places the third di-bit of data on the CLK and DATA lines, and
waits a short while.
7. The peripheral places the fourth di-bit of data on the CLK and DATA lines, and
waits a short while.
8. The peripheral places the status bits for the byte onto the CLK and DATA lines,
and waits a short while.
9. The controller pulls DATA to 0V to acknowledge receipt of the byte, and to pre-
vent the peripheral from sending another byte before it is ready.
10. The peripheral pulls the CLK line to 0V if it does not have another byte ready to
send immediately, lease it remains at 5V.
The status bits have the following interpretation:

CLK DATA Meaning


0V 0V An error occurred.
0V 5V Byte received with EOI.
5V 0V Normal byte received (no EOI).
5V 5V An error occurred.

V-20
ATN

SB0
CLK 0246

SB1
DATA 1357

SRQ
TH TJ1
TJ0

Controller is
ready to TJ3 TJ5
receive byte TJ2 TJ4 TJH

Symbol Min 4541 Max Description

TJH 10 – ∞ Peripheral hold-off until it has data to


send.

TJ0 0 – ∞ Controller hold-off until ready to


receive a byte.
The time is used by software
TJ1 37 37 ∞ implementations to prepare the byte
for immediate transmission.
TJ2 14 14 14 Send first di-bit of data
TJ3 10 10 10 Send first di-bit of data
TJ4 11 11 11 Send first di-bit of data
TJ5 11 11 11 Send first di-bit of data
TJH 13 13 13 Send status bits
All other timing values are identical to the sending a byte under attention case.
All time units are in micro seconds, unless otherwise indicated.

V-21
Talker to Listener Turn-Around
When the bus controller is commanding a device to talk, it finished the transmission
with ATN asserted to 0V. The controller is holding the CLK line at 0V, and the device
it was talking to is holding the DATA line. This situation needs to be reversed: The
controller needs to give up control of the bus, and hand it over to the device.
The SRQ line is not active in this transaction.
To summarise:
1. The controller waits long enough before releasing the ATN line, to make sure
that the peripheral(s) has finished acknowledging the byte that was just sent to
it under attention. This is the TR delay.
2. The controller releases the ATN line to 5V.
3. The controller waits a while. This is the TTK delay.
4. The controller releases the CLK line to 5V, and pulls the DATA line to 0V. From this
point forward, the controller has relinquished control of the bus, and becomes a
listener.
5. After some period of time, the peripheral that has been commanded to talk
asserts the CLK line to 0V, and releases the DATA line, which remains at 0V,
because the the controller is still pulling it down to 0V in preparation to be the
listener. From this point in time, the peripheral has become the sole talker on the
bus. The delay before the CLK line is pulled to 0V by the peripheral is the TDC
timeout.
6. The peripheral waits a while, before it is allowed to begin talking. This is the TDA
delay.
Once this process is complete, the roles of the controller and peripheral have reversed,
with the peripheral now having the role of talker, and the controller (and possibly other
devices on the bus) of listener.

V-22
ATN

CLK

DATA

SRQ
TR TDC TH
TTK TDA

Peripheral Controller Peripheral Peripheral Peripheral


acknowledged becomes becomes requests to begins
byte under ATN listener talker 1st send byte sending

Symbol Min 4541 Max Description

TDA 4/80* – ∞ Talk-Attention acknowledge hold


duration. Controller holds CLK
Talk-Attention acknowledge duration,
i.e., the time a peripheral is permitted
TDC 0 64 ms ∞ to take before becoming talker. Can
commence immediately when CLK is
observed at 5V.
Listener hold-off. Listener can hold of
TH – N/A ∞ for any desired period of time, or for no
time at all.
TR 0/20^ 200 – Frame to release of ATN.
TTK 20 40 100 Talk Attention Release.
All time units are in micro seconds, unless otherwise indicated.
* TDA is provided by the peripheral, not the controller. The 4541 is able to
respond much faster than a C64 to serial bus events, and thus requires
only 4 microsecond to ensure the CLK line has time to rise to 5V. For
controllers using software implementations of the protocol, such as the
C64, the minimum is 80 microsecond. Therefore peripherals should
always use a value of at least 80 microsecond for TDA .
^ The Commodore™ 64 Programmer’s Reference Guide lists TR as having
a minimum duration of 20 microsecond. We see no evidence that
would suggest that any implementation requires a delay before the ATN
line can be released following the transfer of a byte.

V-23
Send Byte With End-or-Indicate (EOI)
After sending a stream of data, a device will often wish to indicate to the listener that
it has reached the end of the data, for example, so that it can begin processing it. This
is accomplished by specially marking the byte with the End-or-Indicate (EOI) attribute.
This is implemented using a timing side-channel, so that it does not require a whole
dedicated wire. When the talker has floated CLK to 5V to indicate it wishes to send
a byte, and when the listener has floated DATA to 5V to indicate that it is ready to
receive, the talker can wait at least 200 microseconds, to indicate to the listener that
the byte should be received with EOI status. The listener signals this to the talker by
pulling the DATA line to 0V for a while, after which the transmission occurs much the
same as normal.
The SRQ line is not active in this transaction.
To summarise:
1. The talker releases CLK to 5V to indicate that it wishes to send a byte.
2. After an arbitrary period of time, the listener releases the DATA line to 5V to
indicate its readiness to receive a byte.
3. Normally at this point, the talker would begin sending the bits after a short period
of time. However, to indicate EOI, it instead waits silently, until the listener gets
the idea that this byte is different, resulting in the listener pulling the DATA line
back down to 0V.
4. The listener holds the DATA line at 0V for just long enough for it to be sure that
the talker has noticed, and then releases it again.
5. As soon as the talker has seen the listener pull the DATA line to 0V and release
it again, it begins sending the byte normally after a short delay.
6. If it waits too long, the listener will assume that the talker wanted to indicate
EOI without actually sending a byte.
7. The transmission of the byte completes in an identical manner to the non-EOI
case.

V-24
ATN

CLK

DATA 0 1 2 3 4 5 6 7

SRQ
TBB TYE TRY TVT TF
TH TEI TST TFR

Listener is Listener
ready to assumes EOI,
receive byte and ACKs it

Symbol Min 4541 Max Description


Time between bytes. Talkers must wait
long enough to allow the listener to
TBB 100 100 ∞ register the end of the transmission of
the previous byte, before the next byte
can be sent.
Listener hold-off. Listener can hold of
TH – N/A ∞ for any desired period of time, or for no
time at all.
EOI indication delay. The sender must
wait at least 200 microseconds for the
TYE 200 250 ∞ receiver to recognise that a byte is
being sent with EOI. If the delay is less
than this, the receiver will not
acknowledge the EOI.
EOI acknowledge hold time. The
receiver must pull the DATA line to 0V
TEI 60 80 ∞ again for at least 60 microseconds, to
allow the sender to detect this EOI
acknowledgement pulse.

V-25
Symbol Min 4541 Max Description
The talker response limit is a relatively
narrow time window during which the
talker must commence transmission of
the byte. If it is too early, the listener
TRY 60 80 100 may become desynchronised, because
it has not hat time to prepare for
reception after sending the EOI
acknowledgement. If it is too long, the
receiver may conclude the talker has
stopped talking.
Data bit setup time. Referred to as TS in
TST 20* 35 ∞ the C64 Programmer’s Reference
Guide.
Data bit valid hold time. Referred to as
TVT 20* 35 ∞ TV in the C64 Programmer’s Reference
Guide.

TF – 1000 1000 Frame handshake (acknowledge)


timeout.
EOI Frame acknowledge. The listener
TFR 0/60� 0 ∞ pulls DATA to 0V after a short period of
time to acknowledge the byte sent with
EOI.
All time units are in micro seconds, unless otherwise indicated.
* TST is provided by the peripheral, not the controller. The 4541 is able to
respond much faster than a C64 to serial bus events, and thus requires
only 4 microsecond to ensure the CLK line has time to rise to 5V. For
controllers using software implementations of the protocol, such as the
C64, the minimum is 80 microsecond. Therefore peripherals should
always use a value of at least 80 microsecond for TDA .
^ The Commodore™ 64 Programmer’s Reference Guide lists TFR as having
a minimum duration of 60 microsecond. We see no evidence that would
suggest that any implementation requires a delay before the DATA line
can be pulled low by the listener to acknowledge receipt of a byte.

Receive Byte
Receiving bytes on the IEC bus occurs identically to the sending case. The key differ-
ence is that the 4541 is tolerant of a much wider range of timing parameters than

V-26
software implementations of the bus protocol. The 4541 requires not more than 4
microseconds for any given bus state, which is the time required for the pull-up resis-
tors on the bus to allow lines to float back to 5V. Internally, the 4541 is capable of
detecting bit times shorter than 1 microsecond.

OPTIONAL INTEGRATED DATA-LOGGER


The 4541 is available in a variant that contains an embedded serial peripheral bus
data-logger. This is designed to aid with debugging protocol errors on this bus. It
commences capturing data whenever command $D0 is issued to the 4541, and will
capture data for approximately 4 milliseconds.
• DATALOG0 The low-byte of the optional integrated serial peripheral bus data
logger. Writing $00 to this register causes the read pointer to the data log to
be reset to the beginning of the capture. Writing $01 to this register, causes the
read point of the data logger to be advanced by one time step. The time steps
are approximately 1 microsecond, with additional time steps added whenever
one of the signals on the serial peripheral bus changes state.
• DATALOG1 The high-byte of the optional integrated serial peripheral bus data
logger. Different fields can be read at this address by writing the following
values to the DATALOG0 register:
– $02 - Read low byte of IEC controller state machine state number.
– $03 - Read high byte of IEC controller state machine state number.
– $04 - Read low byte of number of cycles the previous bus state was held
for.
– $05 - Read high byte of number of cycles the previous bus state was held
for.
Each time-step records 16 bits of information about the serial peripheral bus:
• DATALOG0 Bit 0 DATA line input value
• DATALOG0 Bit 1 CLK line input value
• DATALOG0 Bit 2 SRQ line input value
• DATALOG0 Bit 3 DATA line output state
• DATALOG0 Bit 4 CLK line output state
• DATALOG0 Bit 5 SRQ line output state
• DATALOG0 Bit 6 ATN line output state
• DATALOG0 Bit 7 RESET line output state
• DATALOG1 Access to the additional data logger fields.

V-27
The input values are the voltages that the 4541 reads on the respective pins. Sepa-
rately, the data-logger records whether the 4541 is pulling each of those lines low.
This allows determination as to whether a connected peripheral or the 4541 is pulling
a given signal low. This provides much more information than simply probing the lines
of the serial peripheral bus, where you cannot readily determine who has pulled a
given line low.
The following truth table explains how to interpret these signals:

Input Value Output Value Meaning


1 1 Signal is floating at 5V. No device is pulling it low.

0 1 Signal is at 0V. The 4541 is not pulling it low, either


a connected peripheral or the CIA is pulling it low.
Signal is 0V. The 4541 is pulling it low. Other
0 0 devices might also be pulling it low, but it’s not
possible to discriminate between these two
situations. low.
Signal is floating at 5V, but the 4541 is pulling it to
0V. Your computer is probably broken, or someone
1 0 has connected 5V to the signal without a
current-limiting resistor in between, in which case,
your computer is about to be broken.

Extracting Data from the Data Logger


The following program extracts and displays the contents of the Data Logger as a
PETSCII waveform, like the one shown here:

V-28
10 WK=$50000
20 NL=PEEK($ED)
30 FETCH 3, 4096*2, 0, WK
40 PRINT"ƳDUMPING..."
50 POKE$D694,0
60 FORI=0 TO 4095*2 STEP 2
70 POKEWK+I,PEEK($D694):POKE WK+1+I,PEEK($D695)
80 POKE$D694,1
90 NEXT I
100 PRINT"ƳPROCESSING..."
110 PRINT"ƳŲDűűƽCűűƽSűűƽAűűƽSűƽSűƽSűűƽTűƽIűƽMűƽEƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƲ";
120 PV%=0:PS%=0:C%=0:DV=1:CV=1:SV=1:AV=1
130 FORD=0 TO 4095*2 STEP 2
140 V%=PEEK(WK+D):S%=PEEK(WK+D+1)
150 IF V%=PV% AND S%=PS% THEN GOTO 460
160 C%=C%+1
170 DD=C%>1 AND DV<>(V%AND$01) : DV=(V% AND $01)
180 CD=C%>1 AND CV<>(V%AND$02) : CV=(V% AND $02)
190 SD=C%>1 AND SV<>(V%AND$04) : SV=(V% AND $04)
200 AD=C%>1 AND AV<>(V%AND$40) : AV=(V% AND $40)
210 IFDV=0THEN BEGIN:IFDD=0 THEN D$="ķ":ELSE D$="ď":BEND
220 IFDV>0THEN BEGIN:IFDD=0 THEN D$="į":ELSE D$="Č":BEND
230 IFCV=0THEN BEGIN:IFCD=0 THEN C$="ķ":ELSE C$="ď":BEND
240 IFCV>0THEN BEGIN:IFCD=0 THEN C$="į":ELSE C$="Č":BEND
250 IFSV=0THEN BEGIN:IFSD=0 THEN S$="ķ":ELSE S$="ď":BEND
260 IFSV>0THEN BEGIN:IFSD=0 THEN S$="į":ELSE S$="Č":BEND
270 IFAV=0THEN BEGIN:IFAD=0 THEN A$="ķ":ELSE A$="ď":BEND
280 IFAV>0THEN BEGIN:IFAD=0 THEN A$="į":ELSE A$="Č":BEND
290 PRINTCHR$(27);"K";
300 IF(V% AND $08)=0 THEN PRINT"ż"; :ELSE PRINT"ť";
310 PRINT D$
320 PRINT"":PRINTCHR$(27);"K";
330 IF(V% AND $10)=0 THEN PRINT"ż"; :ELSE PRINT"ť";
340 PRINT C$
350 PRINT"":PRINTCHR$(27);"K";
360 IF(V% AND $20)=0 THEN PRINT"ż"; :ELSE PRINT"ť";
370 PRINT S$
380 PRINT"":PRINTCHR$(27);"K";
390 PRINT"ż";

V-29
400 PRINT A$;"űű";
410 GOSUB 550:GOSUB 490
420 PRINT"ƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱ";
430 PS%=S%
440 PV%=V%
450 IF C%=77 THEN 0,18:C%=0
460 NEXT D
470 PRINT"ų";:FORL=0TONL-3:PRINT"ű";:NEXTL
480 END
490 N$=LEFT$(STR$(D/2)+".........",6)
500 PRINT"ť";
510 FORI=1TO6
520 PRINTCHR$(27);"K";MID$(N$,I,1)
530 NEXT I
540 RETURN
550 S$=MID$(STR$(S%),2,LEN(STR$(S%))):N$=RIGHT$("000"+S$,3)
560 PRINT"ť";
570 FORI=1TO3
580 PRINTCHR$(27);"K";MID$(N$,I,1)
590 NEXT I
600 RETURN

V-30
APPENDIX W
5417E Spreadsheet Hardware
Integrated Technology Engine
• Overview
• Architecture
• Unimplemented Functionality
W-2
OVERVIEW
Introducing the MEGA SheetStorm 65 Spreadsheet Hardware Integrated Technology
Engine (aka SHITE), the groundbreaking chip designed for the MEGA65 system, set to
revolutionize spreadsheet processing in ways the industry has never seen before. With
the innovative ”Data Fan” technology, this chip is not just an improvement over existing
solutions; it’s a complete redefinition of speed and efficiency in data management.
When your sheet data hits the Data Fan of the MEGA SheetStorm 65, it’s an experience
unlike any other. The Data Fan, a unique innovation in data distribution, ensures that
your cells are coated with updated data faster and more thoroughly than you’ve ever
witnessed. It’s like a gust of fresh air sweeping through your spreadsheets, revitalizing
every cell with newfound speed and accuracy. In the world of data processing, if
speed is the game, the MEGA SheetStorm 65 is the undisputed champion.
The power of the MEGA SheetStorm 65 is so formidable that it effectively flushes away
the competition. Where others falter and clog under the pressure of massive data
sets, the SheetStorm 65 maintains a flow of information so smooth, it’s like watching
a masterfully engineered system handle what others would consider a deluge of data.
This is not just processing; this is data management artistry.
In today’s fast-paced business world, being bogged down by sluggish data process-
ing is like throwing money down the drain. The MEGA SheetStorm 65 addresses this
head-on, offering a level of efficiency that not only keeps your data flowing but also
enhances the overall health of your information systems. It’s a chip that doesn’t just
work hard; it works smart, ensuring that every bit of data is where it needs to be, exactly
when it needs to be there.
In summary, the MEGA SheetStorm 65 is more than just a technological advancement;
it’s a revolution in spreadsheet processing. It’s an affirmation that in the realm of data,
the right tool doesn’t just make a difference; it makes all the difference. With the
SheetStorm 65, prepare to see your data, and your business, in a whole new light.
Welcome to the future of data processing. Welcome to the MEGA SheetStorm 65.

ARCHITECTURE
The SHITE processor consists of a shared memory mapped region that allows both the
main processor and the SHITE processor simultaneous access to spread-sheet data.
Correctly described spreadsheet cells are continously updated at high-speed in hard-
ware by the SHITE, providing a dramatically faster performance than can be obtained
using a convention processor.
For rapid access by the processor, a sub-set of these cells can also be plumbed into
16-bit address space using the Streamlined Electronic Workflow for Easy Retrieval
(SEWER) connection.

W-3
UNIMPLEMENTED FUNCTIONALITY
The SHITE processor is in the process of being implemented, and is not currently avail-
able. It is expected to be made available in a future core update of the MEGA65.

W-4
APPENDIX X
Reference Tables
• Units of Storage
• Base Conversion
X-2
UNITS OF STORAGE
Unit Equals Abbreviation
1 Bit
1 Nibble 4 Bits
1 Byte 8 bits B
1 Kilobyte 1024 B KB
1 Megabyte1024KB or 1,048,576 B MB

X-3
BASE CONVERSION
Decimal Binary Hexadecimal Decimal Binary Hexadecimal
0 %0 $0 32 %100000 $20
1 %1 $1 33 %100001 $21
2 %10 $2 34 %100010 $22
3 %11 $3 35 %100011 $23
4 %100 $4 36 %100100 $24
5 %101 $5 37 %100101 $25
6 %110 $6 38 %100110 $26
7 %111 $7 39 %100111 $27
8 %1000 $8 40 %101000 $28
9 %1001 $9 41 %101001 $29
10 %1010 $A 42 %101010 $2A
11 %1011 $B 43 %101011 $2B
12 %1100 $C 44 %101100 $2C
13 %1101 $D 45 %101101 $2D
14 %1110 $E 46 %101110 $2E
15 %1111 $F 47 %101111 $2F
16 %10000 $10 48 %110000 $30
17 %10001 $11 49 %110001 $31
18 %10010 $12 50 %110010 $32
19 %10011 $13 51 %110011 $33
20 %10100 $14 52 %110100 $34
21 %10101 $15 53 %110101 $35
22 %10110 $16 54 %110110 $36
23 %10111 $17 55 %110111 $37
24 %11000 $18 56 %111000 $38
25 %11001 $19 57 %111001 $39
26 %11010 $1A 58 %111010 $3A
27 %11011 $1B 59 %111011 $3B
28 %11100 $1C 60 %111100 $3C
29 %11101 $1D 61 %111101 $3D
30 %11110 $1E 62 %111110 $3E
31 %11111 $1F 63 %111111 $3F

X-4
Decimal Binary Hexadecimal Decimal Binary Hexadecimal
64 %1000000 $40 96 %1100000 $60
65 %1000001 $41 97 %1100001 $61
66 %1000010 $42 98 %1100010 $62
67 %1000011 $43 99 %1100011 $63
68 %1000100 $44 100 %1100100 $64
69 %1000101 $45 101 %1100101 $65
70 %1000110 $46 102 %1100110 $66
71 %1000111 $47 103 %1100111 $67
72 %1001000 $48 104 %1101000 $68
73 %1001001 $49 105 %1101001 $69
74 %1001010 $4A 106 %1101010 $6A
75 %1001011 $4B 107 %1101011 $6B
76 %1001100 $4C 108 %1101100 $6C
77 %1001101 $4D 109 %1101101 $6D
78 %1001110 $4E 110 %1101110 $6E
79 %1001111 $4F 111 %1101111 $6F
80 %1010000 $50 112 %1110000 $70
81 %1010001 $51 113 %1110001 $71
82 %1010010 $52 114 %1110010 $72
83 %1010011 $53 115 %1110011 $73
84 %1010100 $54 116 %1110100 $74
85 %1010101 $55 117 %1110101 $75
86 %1010110 $56 118 %1110110 $76
87 %1010111 $57 119 %1110111 $77
88 %1011000 $58 120 %1111000 $78
89 %1011001 $59 121 %1111001 $79
90 %1011010 $5A 122 %1111010 $7A
91 %1011011 $5B 123 %1111011 $7B
92 %1011100 $5C 124 %1111100 $7C
93 %1011101 $5D 125 %1111101 $7D
94 %1011110 $5E 126 %1111110 $7E
95 %1011111 $5F 127 %1111111 $7F

X-5
Decimal Binary Hexadecimal Decimal Binary Hexadecimal
128 %10000000 $80 160 %10100000 $A0
129 %10000001 $81 161 %10100001 $A1
130 %10000010 $82 162 %10100010 $A2
131 %10000011 $83 163 %10100011 $A3
132 %10000100 $84 164 %10100100 $A4
133 %10000101 $85 165 %10100101 $A5
134 %10000110 $86 166 %10100110 $A6
135 %10000111 $87 167 %10100111 $A7
136 %10001000 $88 168 %10101000 $A8
137 %10001001 $89 169 %10101001 $A9
138 %10001010 $8A 170 %10101010 $AA
139 %10001011 $8B 171 %10101011 $AB
140 %10001100 $8C 172 %10101100 $AC
141 %10001101 $8D 173 %10101101 $AD
142 %10001110 $8E 174 %10101110 $AE
143 %10001111 $8F 175 %10101111 $AF
144 %10010000 $90 176 %10110000 $B0
145 %10010001 $91 177 %10110001 $B1
146 %10010010 $92 178 %10110010 $B2
147 %10010011 $93 179 %10110011 $B3
148 %10010100 $94 180 %10110100 $B4
149 %10010101 $95 181 %10110101 $B5
150 %10010110 $96 182 %10110110 $B6
151 %10010111 $97 183 %10110111 $B7
152 %10011000 $98 184 %10111000 $B8
153 %10011001 $99 185 %10111001 $B9
154 %10011010 $9A 186 %10111010 $BA
155 %10011011 $9B 187 %10111011 $BB
156 %10011100 $9C 188 %10111100 $BC
157 %10011101 $9D 189 %10111101 $BD
158 %10011110 $9E 190 %10111110 $BE
159 %10011111 $9F 191 %10111111 $BF

X-6
Decimal Binary Hexadecimal Decimal Binary Hexadecimal
192 %11000000 $C0 224 %11100000 $E0
193 %11000001 $C1 225 %11100001 $E1
194 %11000010 $C2 226 %11100010 $E2
195 %11000011 $C3 227 %11100011 $E3
196 %11000100 $C4 228 %11100100 $E4
197 %11000101 $C5 229 %11100101 $E5
198 %11000110 $C6 230 %11100110 $E6
199 %11000111 $C7 231 %11100111 $E7
200 %11001000 $C8 232 %11101000 $E8
201 %11001001 $C9 233 %11101001 $E9
202 %11001010 $CA 234 %11101010 $EA
203 %11001011 $CB 235 %11101011 $EB
204 %11001100 $CC 236 %11101100 $EC
205 %11001101 $CD 237 %11101101 $ED
206 %11001110 $CE 238 %11101110 $EE
207 %11001111 $CF 239 %11101111 $EF
208 %11010000 $D0 240 %11110000 $F0
209 %11010001 $D1 241 %11110001 $F1
210 %11010010 $D2 242 %11110010 $F2
211 %11010011 $D3 243 %11110011 $F3
212 %11010100 $D4 244 %11110100 $F4
213 %11010101 $D5 245 %11110101 $F5
214 %11010110 $D6 246 %11110110 $F6
215 %11010111 $D7 247 %11110111 $F7
216 %11011000 $D8 248 %11111000 $F8
217 %11011001 $D9 249 %11111001 $F9
218 %11011010 $DA 250 %11111010 $FA
219 %11011011 $DB 251 %11111011 $FB
220 %11011100 $DC 252 %11111100 $FC
221 %11011101 $DD 253 %11111101 $FD
222 %11011110 $DE 254 %11111110 $FE
223 %11011111 $DF 255 %11111111 $FF

X-7
X-8
APPENDIX Y
Flashing the FPGAs and CPLDs
in the MEGA65
• Suggested PC specifications
• Warning
• Installing Vivado
• Installing the FTDI drivers
• Flashing the main FPGA using Vivado
• Flashing the CPLD in the MEGA65’s
Keyboard with Lattice
Diamond
• Flashing the MAX10 FPGA on the
MEGA65’s Mainboard
with INTEL QUARTUS

Y-2
Y-3
Y-4
The MEGA65 is an open-source and open-hardware computer. This means you are
free, not only to write programs that run on the MEGA65 as a finished computer, but
also to use the re-programmable chips in the MEGA65 to turn it into all sorts of other
things.
If you just want to install an upgrade core for the MEGA65, or a core that lets you use
your MEGA65 as another type of computer, you probably want to look in Chapter/Ap-
pendix 5 on page 5-5 instead.
This chapter is more intended for people who want to help develop cores for the
MEGA65. This chapter may also be of interest to Nexys4 board owners that are inter-
ested booting their devices from the on-board QSPI flash memory chip (rather than a
bitstream file on the SD card). This will require flashing an .mcs file onto their board’s
QSPI chip, so as to provide an initial bistream in the ’Slot 0’ position.
These re-programmable chips are called Field Programmable Gate Arrays (FPGAs) or
Complex Programmable Logic Devices (CPLDs), and can implement a wide variety of
circuits. They are normally programmed using a language like VHDL or Verilog. These
are languages that are not commonly encountered by most people. They are also
quite different in some ways to “normal” programming languages, and it can take a
while to understand how they work. But with some effort and perseverance, exciting
things can be created with them.

SUGGESTED PC SPECIFICATIONS
Be prepared to install many gigabytes of software on a Linux or Windows PC, before
you will be able to write programs for the FPGAs and CPLDs in the MEGA65. Also,
”compiling” complex designs can take up to several hours, depending on the speed
and memory capacity of your computer. We recommend a computer with at least
12GB RAM (preferably 16GB) if you want to write programs for FPGAs and CPLDs. On
the other hand, if all you want to do is load programs onto your MEGA65’s FPGAs and
CPLDs that other people have written, then most computers running a recent version
of Windows or Linux should be able to cope.
• OS: Linux or Windows
• CPU Speed: As fast as you can get your hands on!
• Number of cores: Ideally, 8 or more, as the free license of Vivado can make use
of a max of 8 cores.
• Hard disk space: Have about 70GB or more. The exact amount used depends
on how many components within Vivado you install (bear in mind that the full
install file is about 50GB in itself)
• Memory: minimum of 12GB (ideally, have more, to play it safe)

Y-5
WARNING
Before we go any further, we do have to provide a warning about reprogramming the
FPGAs and CPLDs in the MEGA65. Re-programming the MEGA65 FPGA can poten-
tially cause damage, or leave your MEGA65 in an unresponsive state from which it is
very difficult to recover, i.e., “bricked”. Therefore if you choose to open your MEGA65
and reprogram any of the FPGAs it contains, it is no longer possible to guarantee its
correct operation. Therefore, we cannot reasonably honour the warranty of the device
as a computer. You have been warned!

INSTALLING VIVADO
Installation of Vivado is required to flash the QSPI flash memory within
your MEGA65 target device, whether it be a MEGA65 R2/R3/R3A/R4,
Nexys4/Nexys4DDR/NexysA7, MEGAphone or other.
Vivado is also the tool used to perform compilation (synthesis, as it is preferably called)
of FPGA bitstreams.
To get started, connect to https://www.xilinx.com/support/download.html
Select 2020.2 version

NOTE : Some users still have success with using older versions, as the main aim here
is to install a version that supports the FPGA of your target hardware.

I.e., the Artix7 100T (for Nexys and R2) or 200T (R3/R3A/R4).

Y-6
Click on Xilinx Unified Installer 2020.2: Windows Self Extracting Web Installer EXE -
248.44MB

You will be asked to create an account in order to sign in and be able to download
the installation program.

Your credentials will also be requested when doing the installation.

Y-7
After having signed in, you have to provide some personal information and then click
on Download

Execute the installer as Administrator (Xilinx_Unified_2020.2_1118_1232_Win64.exe).

Click on Allow Access.

Y-8
Click on Next.

Enter your credentials and click on Next.

Y-9
Select Vivado and click on Next.

Select ”Vivado HL WebPACK” and click on ”Next”

Y-10
We’d suggest selecting only the ”7 Series” devices, as our chosen FPGA is within this
series, and de-selecting the other series will save you about 6GB in download size.
Then click on ”Next”

Warning: As stated, disconnect any USB cable that would be connected to your PC
from the Nexys board.
Agree with all the End User Licence Agreement and Terms and conditions and click
on ”Next”.

Y-11
Choose the location where you want to install the software and click on ”Next”.

Warning : You are about to download 20GB of software and you need 70GB to per-
form the installation.
Click on ”Yes”

Y-12
Click on ”Install”

Wait for the installation to complete. At the very end of the installation you will be
asked if you want to install Xilinx device software.

Y-13
Click on ”Install”

Let the installation complete.


The installation is completed. Click on ”OK”

Y-14
You end up with the following icons on your desktop:

Note: Ubuntu users might need to install one missing dependency with: sudo apt
install libtinfo5
Launch Vivado 2020.2

Y-15
Click on ”Help”->”Obtain a licence Key”

This launches the Vivado licence manager

Select ”Get Free ISE WebPACK, ISE/Vivado IP or PetaLinux Licenses”

Click on ”Connect Now”

Y-16
Connect with the user account you have created to be able to download the Vivado
software. If you were not already connected to Xilinx website, this will take you to the
main webpage. Go back in the licence manager (which is not closed)

Click again on ”Connect Now” (ensure ”Get Free ISE WebPACK, ISE/Vivado IP or
PetaLinux Licenses” is still selected)

Y-17
You then register your personal information on the Vivado website, and click on ”Next”.

Select ”ISE WebPACK Licence” and ”Vivado Design Suite: HL WebPACK 2015 and
Earlier License”

Then click on ”Generate Node-Locked Licence”

Y-18
Click on ”Next”

Click on ”Next”

Y-19
Check your email box : You should have received an email from Xilinx, Inc. with a
licence file attached and named ”Xilinc.lic”.

Retrieve this file on your PC and keep it in safe place.

Go back to the licence manager (which is still running).

Set ”Load License” and click on ”Copy License”

Y-20
Browse to the location where you saved ”Xilinc.lic” file, select it and click on ”Open”.

Click on ”OK” and close the Vivado licence manager.

Your Vivado software is registered and you can now use it.

INSTALLING THE FTDI DRIVERS


The FTDI drivers are needed in order for your PC to communicate with the hardware’s
JTAG port and serial comms port (note that the single physical USB connection made
to your PC actually provides these two ports).

Y-21
Linux drivers
Some Linux users have reported that they have found the FTDI drivers to be installed
within their Linux distributions out-of-the-box, while others have found they needed to
run this extra command after installing Vivado:
cd /opt/Xilinx/Vivado/2018.3/data/xicom/cable_drivers/lin64/install_script/install_drive
sudo ./install_drivers

Windows drivers
Download the following archive to install the drivers:
• https://www.ftdichip.com/Drivers/CDM/CDM21228_Setup.zip
Unzip the file CDM21228_Setup.zip, you get the file CDM21228_Setup.exe.
Warning:
Before installing the drivers, it is imperative to switch off the Nexys4 board and to
disconnect the USB cable from the PC.
Review the devices already installed before the installation:

Y-22
Run the file CDM21228_Setup.exe as administrator:

Confirm that you want to run the program.


Click on ”Extract”.

Y-23
Click on ”Next >”

Accept the agreement and click on ”Next >”.

The installation of the drivers starts.

Y-24
Click on ”Finish”.

Connect the USB cable to a USB port on the PC without turning on the Nexys4 board.
Connecting the USB cable triggers the appearance of new devices.

• An additional COM port has been installed: This is the COM port that will be
used to communicate with the Nexys4 board.
• An additional USB composite device has been installed.

Y-25
• Two USB serial converter devices have been installed.
At this point the Nexys4 board has still not been powered up.
For more information about the installed drivers, you can download the corresponding
documentation:
• https://ftdichip.com/wp-content/uploads/2020/08/AN_
396-FTDI-Drivers-Installation-Guide-for-Windows-10.pdf
• https://ftdichip.com/wp-content/uploads/2021/01/AN_119_FTDI_
Drivers_Installation_Guide_for_Windows7.pdf

FLASHING THE MAIN FPGA USING


VIVADO
Firstly, to clarify that when we say ’flashing the FPGA’, in reality, what we mean is that
we are flashing the QSPI flash memory chip that the FPGA makes use of upon startup
in order to quickly load the bitstream from.
The diagram below shows two common pathways that the FPGA can load bitstreams
at startup:

• We can first flash a bitstream/core-file onto the QSPI flash memory chip, and
the FPGA can load this quickly at power-up. Flashing the QSPI is quite slow, but
the reward of a fast boot-up time is an advantage.
• Nexys board users can drop a bitstream file onto our SD card and let the FPGA
load it (somewhat more slowly) from there at power-up. This allows them to

Y-26
swap/upgrade bitstreams quickly without the need for a TE0790-03 JTAG pro-
gramming module. This feature is planned to be added to the MEGA65 later,
though.
In this section, we describe the pathway that makes use of the QSPI.
Many of the following steps in this section are applicable not only to MEGA65
R2/R3/R3A/R4 owners, but Nexys4 board owners too. There are a few points of
distinction along the way that readers will be made aware of.
If you choose to proceed, you will need a functioning installation of Xilinx’s Vivado
software, and the FTDI drivers installed, as described in the earlier sections.
You will also need to download or build an .mcs bitstream file (and optional .prm check-
sum verification file) that you intend to flash onto the QSPI chip via Vivado. See the
MEGA65 Book for more details on where such files can be downloaded.

Y-27
For MEGA65 R2/R3/R3A/R4 owners:

You will need a TE0790-03 JTAG programming module. It is also neces-


sary to have dip-switches 1 and 3 in the ON position and dip-switches 2 and 4
in the OFF position on the TE-0790. With your MEGA65 disconnected from the
power, the TE-0790 must be installed on the JB1 connector which is located
between the floppy data cable and the audio jack. The gold-plated hole of the
TE-0790 must line up with the screw hole below. The mini-USB cable will then
connect on the side towards the 3.5” floppy drive. The following image shows
the correct position: The TE0790 is surrounded by the yellow box, and the dip-
switches by the red box. Dip-switch 1 is the one nearest the floppy data cable.

Y-28
For Nexys4 board owners:

Simply connect your micro-usb cable between your Nexys4 board and
your PC via the port labeled ’PROG UART’ (J6), as shown:

Also, set J1 jumper to the QSPI position:

• Connect your non-8-bit computer to the FPGA programming device using the
appropriate USB cable.
• Switch the MEGA65 computer ON.
• Open Vivado.

Y-29
Step 1a: Create a new Vivado project with ”File”, ”Project”, ”New...”.
NOTE: On future occasions that you need to flash the QSPI, just re-open this project
(no need to create a new project each time).

Step 1b: The ’New Project’ wizard appears. Click on ”Next”:

Y-30
Step 1c: Name your project and choose the location you like, then click on ”Next”:

Step 1d: Keep the default selected options and click on ”Next”:

Y-31
Step 1e: Do not add any sources, keep the default selected options and click on
”Next”:

Step 1f: Keep the default selected options and click on ”Next”:

Y-32
Step 1g: Click on ”Finish”:

Step 2: In the left column, select ”Open Hardware Manager” at the very bottom.

Y-33
Step 3: Connect to the FPGA:
Under ”Open Hardware Manager”, choose ”Open Target”, then ”Auto Connect”.

Step 4: Wait a moment, ”Connecting to server...” should automatically close without


dropping an error to the console.

Y-34
Step 5: Under ”Open Hardware Manager”, choose ”Add Configuration Memory De-
vice”, then:
• For MEGA65R3/R3A/R4: ”xc7a200t_0”
• For Nexys4 and MEGA65R2: ”xc7a100t_0”.

Step 6a: Select Memory Part:

In the newly opened dialogue:


• For MEGA65R2/R3: type ”S25fl256s” (without quotes), then select
”s25fl256sxxxxxxx0-spi-x1_x2_x4” (the upper one) and click ”OK”.
• For MEGA65R3A/R4: Vivado cannot flash the larger flash part on these boards.
Use the flash menu on the MEGA65.
• For Nexys4: type ”S25fl128s” (without quotes), then select ”s25fl128sxxxxxxx0-
spi-x1_x2_x4” (the upper one) and click ”OK”.

Y-35
Step 6b: Click on ”OK” to confirm you want to program the configuration memory
device now.

Step 6c: If you do not see such a popup, or wish to reprogram the QSPI on a future
occasion, in ”Hardware” window, right click on the memory configuration and select
”Program Configuration Memory Device”:

Y-36
Step 7: Set programming options:
In the next dialogue, set the ”Configuration file” to the path of your ”.mcs” bitstream
file. You can also optionally set the ”PRM file” field to the path of your ”.prm” file.
Leave all other parameters as they are (see screenshot below).

Step 8: Patiently wait for the programming to finish. This can take several minutes
as the Vivado software erases and then reprograms the flash memory that is used to
initialise the FPGA on power-up.

Y-37
Step 9: If your screen looks like the screenshot below, your new bitstream has been
successfully flashed into Slot0 of your QSPI flash memory!

Step 10: If you want to reflash the FPGA, you might find the ”Add Configuration
Memory Device” option in step 5 greyed out. Instead, select ”s25fl256sxxxxxxx0-spi-
x1_x2_x4” in the ”Hardware” window, press right mouse button and select ”Program
Configuration Memory Device” to flash.

Y-38
FLASHING THE CPLD IN THE MEGA65’S
KEYBOARD WITH LATTICE DIAMOND
If you choose to proceed, you will need a TE0790-03 JTAG programming module and
a functioning installation of Lattice Diamond Programmer software. This can be done
on either Windows or Linux, but in both cases you will need to install any necessary
USB drivers. It is also necessary to have dip-switches 1 and 3 in the ON position
and dip-switches 2 and 4 in the OFF position on the TE-0790. With your MEGA65
disconnected from the power, the TE-0790 must be installed on the JB1 connector,
which is located between the floppy data cable and the audio jack. The gold-plated
hole of the TE-0790 must line up with the screw hole below. The mini-USB cable will
then connect on the side towards the 3.5” floppy drive. The following image shows the
correct position: The TE0790 is surrounded by the yellow box, and the dip-switches
by the red box. Dip-switch 1 is the one nearest the floppy data cable.

Y-39
Y-40
On the PCB of a R2/R3/R3A/R4 MEGA65 mainboard, dip switch 1 (the one nearest to
the user sitting in front of the machine) must be in the ON position. The other switches
must be OFF. The keyboard will go into “ambulance mode” (blue flashing lights) when
set correctly.
Connect your non-8-bit computer to the FPGA programming device using a mini-USB
cable. Switch the MEGA65 computer ON. Open the Diamond Programmer which can
be downloaded from the Internet.
Step 1: Open DIAMOND PROGRAMMER:
Select ”Create a new project from a JTAG scan”. If entry under ”Cable:” is empty,
click ”Detect Cable”.

Step 2: Create a new project:


If dialog ”Programmer: Multiple Cables Detected” appears, select the first entry (”Lo-
cation 0000”) and click ”OK”.

Y-41
Step 3: Select cable:
You have now created a new project which should display ”MachXO2” under ”Device
Family” and ”LCMXO2-1200HC” under ”Device”

Step 4: New Diamond Programmer project:


Choose ”File” then ”Open File” to load the Diamond Pprogrammer project with the
MEGA65 keyboard firmware update.

Y-42
Step 5: Open project:
Navigate into the folder with the extracted MEGA65 keyboard firmware files you have
received and select the file ending with ”.xcf”.

Step 6: Select project file:


Click the three dots under ”File Name” to set the correct path and find the file ending
with ”.jed”.

Y-43
Step 7: Choose correct path of .jed file:
Select the file ending with ”.jed” and click ”OK”.

Step 8: Select .jed file:


Click on the icon with the green arrow facing down ”PROGRAM”, which looks similar
to the Diamond Programmer program icon.

Y-44
Step 9: Select cable:
After a moment the Output window should display ”INFO - Operation: successful.”
and the ”Status” cell should go green (does not always happen).

Step 10: Operation successful:


You have now successfully flashed the MEGA65 keyboard. If you wish you can now
save the project for later use.

Y-45
FLASHING THE MAX10 FPGA ON THE
MEGA65’S MAINBOARD WITH INTEL
QUARTUS
If you choose to proceed, you will need a TEI0004 - Arrow USB Programmer2 module
with TEI0004 driver installed and a functioning installation of Quartus Prime Program-
mer Lite Edition. This can be done on either Windows or Linux, but in both cases you
will need to install any necessary USB drivers. With your MEGA65 disconnected from
the power, the TEI0004 must be installed on the J17 connector, which is located be-
tween the floppy data cable and the ARTIX 7 FPGA on the Mainboard. The micro-USB
port of the TEI0004 must face in the opposite direction of the HDMI and LAN sockets,
towards the trap door. The following image shows the correct position.
On the PCB R2/R3/R3A/R4 MEGA65 mainboard, all dip switches must be in the OFF
position. The main FPGA of the MEGA65 must not contain a valid bitstream. The
easiest way to do this is if you have a TE0790 JTAG adapter: you can then use the
m65 tool from a connected computer to begin sending a bitstream via JTAG, and then
using control-C to abort the m65 tool before it can finish loading the bitstream.

Y-46
Y-47
Connect your non-8-bit computer to the FPGA programming device using a micro-USB
cable. Open Quartus Prime Programmer Lite Edition, which can be downloaded from
the Internet.
Step 1: Open Quartus Prime Programmer Lite Edition:
Click the ”Hardware Setup” button in the top left corner of the Quartus Prime Pro-
grammer window.

Step 2: Enter Hardware Setup:


In the newly appeared window under ”Currently selected hardware” choose ”Arrow-
USB-Blaster”. If ”Arrow-USB-Blaster” does not appear, verify cable and drivers being
correctly installed.

Y-48
Step 3: Select Arrow USB-Blaster:
Click the ”Add File” button from the left row and choose the latest ”.pof” file. Then
click ”Open”.

Step 4: Select Programming File:


Tick at least the three boxes under ”Program/Configure”. Also enabling all boxes under
”Verify” and ”Blank-Check” will make the process more reliable.

Y-49
Step 5: Select Program/Configure Options:

While keeping the Reset-Button pressed, switch the MEGA65 computer ON. The key-
board will go into “ambulance mode” (blue flashing lights). If it does not, the main
FPGA is not empty - restart the whole process.
Now click on ”Start” in the left row of buttons. The progress bar in the top right corner
should quickly go to 100 percent and turn green. You have now successfully updated
your MAX10 FPGA.
If you receive an error message instead, make sure the main FPGA bitstream has been
erased and that you did not release the reset-button on the MEGA65 beforehand.
Switch off the MEGA65 and restart this step.

Y-50
Step 6: Programming successful:

Y-51
Y-52
APPENDIX Z
Trouble shooting
• Hardware
• Vivado
• mega65_ftp
Z-2
HARDWARE
No Digital Video Output
MEGA65 R4, R5, R6
The digital video port has improved back-power isolation, to correct the “No lights
when powering on” problem. A side effect of this is that some digital video cables
incorrectly use only the shell of the connector to provide the ground signal, instead of
using the ground signals from the pins of the connector. Long-story-short: If you don’t
get an image on the digital video port, you can try one of the following solutions:
• Try different digital video cables you have. This problem only occurs with certain
brands of cables, especially thinner ones (see the image in Figure ??), that we
strongly suspect are missing the internal ground wires to save money. This is the
best solution, as it is actually the cable that is the cause of the fault, by being
non-compliant. Even if you use one of the following work-arounds, you should
still go and find a better HDMI cable that solves the problem at the root-cause.
• Connect a VGA cable to the MEGA65 and to the same monitor. This will provide
a ground connection through the VGA connector, and seemingly magically allow
the HDMI to work.
• Connect a TE0790 JTAG adapter. One user reported that this also magically
worked-around the problem.
• Bridge the digital video connector shell to the shell of the internal full-size SD
card shell.
• Connect an splitter or repeater to the digital video port.

No lights when powering on


If there are occasions when your MEGA65 display any lights when powering on, they
relate to having certain Digital Video devices plugged in while the MEGA65 is off,
that don’t provide enough power for the keyboard’s CPLD to be properly powered on,
but enough to stop it properly resetting when the MEGA65 powers on. Removing the
Digital Video cable and switching the machine off and on again fixes the issue.

VIVADO

Z-3
Figure Z.1: Example of bad (top) and good (bottom) digital video cables. Note how
the bad cable is suspiciously thinner than the good one. This is a sign that it likely is
missing dedicated ground wires, and will cause problems on the MEGA65 R4 and later
revisions. Any “normal thickness” cable should work fine, though. You don’t need to buy
one of those over-priced “oxygen-free unobtanium-plated hand-assembled in zero-
gravity by world-famous artisans” cables. Those cables offer about as much practical
benefit sprinkling some glitter or drawing a unicorn on one end, but with much less
class.

RAM requirements
INFO: [Synth 8-256] done synthesizing module 'ram32x1024' [/home/....]
INFO: [Synth 8-256] synthesizing module 'charrom' [/home/....]
/opt/Xilinx/Vivado/2019.2/bin/loader: line 280: 2317 killed
WARNING: [Vivado 12-8222] Failed run(s) : 'synth\_1'
ERROR: Application Exception: failed to launch run 'impl\_1' due
to failures in the following run(s):
synth\_1
These failed run(s) need to be reset prior to launching 'impl\_1'
again.

This error is due to Vivado crashing because the machine doesn’t have enough RAM
for Vivado to run. Vivado requires at least 4GB to synthesise the MEGA65 target, but
8GB is better.

MEGA65_FTP

Z-4
Missing Library
/usr/bin/ld: cannot find -lncurses
collect2: error: ld returned 1 exit status
Makefile:474: recipe for target 'bin/mega65_ftp' failed
make: *** [bin/mega65_ftp] Error 1

This error occurs when the ncurses library is missing from the computer when building
the mega65_ftp program. To rectify this issue you will need to ensure that you install
this dependency.

sudo apt-get install libncurses5-dev libncursesw5-dev

Z-5
Z-6
APPENDIX AA
Model Specific Features
• Detecting MEGA65 Models
• MEGA65 Desktop Computer, Revisions
5 and 6

• MEGA65 Desktop Computer, Revision 4


• MEGA65 Desktop Computer, Revision 3
& Revision 3A

• MEGA65 Desktop Computer, Revision 2


• MEGAphone Handheld, Revisions 1 and 2
• Nexys4 DDR FPGA Board
AA-2
DETECTING MEGA65 MODELS
While we expect the production version of the MEGA65 to be a stable platform, there
may still be cases where detecting which hardware your program is running on. This
is particularly important for the MEGA65 system software, which may need to ini-
tialise different pieces of hardware on the different models. Also, because there is a
hand-held version of the MEGA65 already in development, which uses a slightly dif-
ferent resolution screen (800x480 instead of 720x576), and has a touch screen but
no hardware keyboard, you may wish to make programs that adapt to the hand-held
devices in a more graceful way. For example, you may enable touch-screen input, and
restructure on-screen selections to be large enough to be easily activated by a finger.
The simple way to detect which model of MEGA65 your program is running on, is to
check the $D629 register (but don’t forget to enable the MEGA65 I/O personality
first, via $D02F). This contains an 8-bit hardware identifier. The following values are
currently defined:
$01 (1) MEGA65 R1
$02 (2) MEGA65 R2
$03 (3) MEGA65 R3
$04 (4) MEGA65 R4
$05 – $0F (5 – 15) MEGA65 R5 – MEGA65 R15
$21 (33) MEGAphone (hand-held) R1
$40 (64) Nexys4 PSRAM
$41 (65) Nexys4DDR
$42 (66) Nexys4DDR with widget board
$FD (253) QMTECH Wukong A100T board
$FE (254) Simulation run of VHDL

MEGA65 DESKTOP COMPUTER,


REVISIONS 5 AND 6
The R5 and R6 desktop PCBs are a relatively minor reworkings of the R4 desktop PCB,
initially undertaken to address supply-chain problems for some of the power regulator
components. However, the opportunity was also taken to implement a few improve-
ments:
• Several signals on the expansion port that were previously output or input only,
are now bi-directional, which should allow the C64 core to support all known

AA-3
cartridges, as well as allow further improvement of cartridge compatibility for
the MEGA65 core.
• Four additional dip-switches have been added to the mainboard. All 8 dip-
switches are now connected via an I2C IO expander, rather than consuming
direct FPGA pins.
• This new IO expander also provides both major and minor board revision infor-
mation. Major revision is set to 5, and the minor revision initially to 0. The minor
revision may change if non-compatibility breaking changes occur to the board,
such as changing the QSPI flash chip, HyperRAM and/or SDRAM chips. This al-
lows software, especially the MEGA65’s Hypervisor, to detect this situation and
act accordingly.
• The microphone interface on the 3.5mm audio jack is now able to supply bias
voltage to enable the use of certain types of microphones that would not have
previously worked. Currently the MEGA65 core does not support use of the
microphone port, although it may in future.
R6 is electrically identical to R5, and is the model that was included with MEGA65
production units shipped in the year 2024.

MEGA65 DESKTOP COMPUTER,


REVISION 4
The R4 desktop PCB is a significant reworking of the R3 desktop PCB, with several
important changes:
• The Intel™ MAX10™ helper FPGA has been completely removed from the board,
simplifying the design, and helping to offset some of the cost increases that have
occurred since the R3 board was designed. This also eliminates some difficult
failure modes that could occur if the MAX10 FPGA were accidentally deconfig-
ured.
• The joystick ports now have the ability to be driven low by the MEGA65. This
should allow devices such as the protopad™ to be used with the MEGA65.
• The on-board internal speaker ports have been removed, as these were not
widely used, added cost, and could have problems with overheating speakers
due to the type of DACs used.
• The Real-Time Clock (RTC) has been replaced by a RV-3032-C7. This eliminates
the problems experienced with the R3 boards due to variable-quality RTC chips
of the previous type, that in many cases required replacement.
• A driver IC has been added to the digital video output to prevent back-powering
problems.

AA-4
• A new 16-pin header, J21, has been added that has direct access to the joystick
output lines, as well as two additional FPGA pins. This is intended to assist with
certain low-level development tasks, as well as to potentially support further
improvements through the addition of a specialised daughter-board.
• A 64MiB SDRAM has been added in addition to the 8MiB HyperRAM. This will
allow the porting of more of the MiSTer cores, as well as provide a larger and
higher performance Attic RAM for the MEGA65 core. It is likely that the Hyper-
RAM will not be populated on production units of the R4 board, once the SDRAM
is supported by the MEGA65 core, as the SDRAM is superior in every way to the
HyperRAM: It is higher speed, with lower latency, and has 8× larger capacity.
• Greatly improved audio quality on the 3.5mm external audio jack through the
addition of a high-performance audio DAC chip.

MEGA65 DESKTOP COMPUTER,


REVISION 3 & REVISION 3A
The R3 desktop PCB is very similar to the R2 desktop PCB, with two key changes:
• First, the R3 PCB does not have an ADV7511 digital video driver chip, and so
the I2C register block for that device is not present.
• Second, the R3 PCB uses a different on-board amplifier for the PC speakers,
which are now present in stereo, rather than mono as on the R2 PCB. The ampli-
fier on the R3 PCB is the same as on the MEGAphone R1 – R2 PCBs. However, the
I2C registers are at a different address. On the MEGA65 R3 PCB, the registers
are located at $FFD71DC – $FFD71EF.
The only difference between the R3 and R3A is the QSPI flash chip loaded onto the
board. The PCB itself is unchanged. The QSPI flash chip on the R3 has capacity for
only 4 core slots (0 – 3), including the factory core in slot 0. The R3A uses a higher-
capacity QSPI flash chip that has capacity for 8 core slots (0 – 7), including the factory
core in slot 0.
R3 boards were used for the MEGA65 DevKit models that shipped in the year 2020.
R3A boards were used for the MEGA65 production units shipped in 2022 and 2023.

MEGA65 DESKTOP COMPUTER,


REVISION 2
The desktop version of the MEGA65 contains a Real-Time Clock (RTC), which also
includes a small amount of non-volatile memory (NVRAM) that retains its value, even
if the computer is turned off and disconnected from its power supply. The NVRAM will

AA-5
hold its values for as long as the internal battery has sufficient charge. This battery also
powers the Real-Time Clock (RTC) itself, which includes a 100 year calendar spanning
the years 2000 – 2099.
The main trick with accessing the RTC from BASIC, is that we will need to use a
MEGA65 Enhanced DMA operation to fetch the RTC registers, because the RTC regis-
ters sit above the 1MB barrier, which is the limit of the C65’s normal DMA operations.
The easiest way to do this is to construct a little DMA list in memory somewhere, and
make an assembly language routine that uses it. Something like this (using BASIC 65
in C65-mode):

10 RESTORE 110:FORI=0TO43:READA$:POKE1024+I,DEC(A$):NEXT:BANK 128:SYS1042


20 S=PEEK(1056):M=PEEK(1057):H=PEEK(1058)
30 D=PEEK(1059):MM=PEEK(1060):Y=PEEK(1061)+DEC("2000")
40 IF H AND 128 GOTO 80
50 PRINT "THE TIME IS ";RIGHT$(HEX$(H AND 63),2);":";RIGHT$(HEX$(M),2);".";RIGHT$(HEX$(S),2)
60 IF H AND 32 THEN PRINT "PM": ELSE PRINT "AM"
70 GOTO 90
80 PRINT "THE TIME IS ";RIGHT$(HEX$(H AND 63),1);":";RIGHT$(HEX$(M),2);".";RIGHT$(HEX$(S),2)
90 PRINT "THE DATE IS ";RIGHT$(HEX$(D),2);".";RIGHT$(HEX$(MM),2);".";HEX$(Y)
100 END
110 DATA 0B,80,FF,81,00,00,00,08,00,10,71,0D,20,04,00,00,00,00
120 DATA A9,47,8D,2F,D0,A9,53,8D,2F,D0,A9,00,8D,02,D7,A9
130 DATA 04,8D,01,D7,A9,00,8D,05,D7,60

This program works by setting up a DMA list in memory at 1,024 ($0400) (unused
normally on the C65), followed by a routine at 1,042 ($0412) which ensures we have
MEGA65 registers un-hidden, and then sets the DMA controller registers appropriately
to trigger the DMA job, and then returns. The rest of the BASIC code PEEKs out the RTC
registers that the DMA job copied to 1,024 - 1,032 ($0400 – $0407), and interprets
them appropriately to print the time.
The curious can use the MONITOR command, and then D1012 to see the routine.
If you want a running clock, you could replace line 100 with GOTO 10. Doing that,
you will get a result something like the following:

THE TIME IS 10:05:36 PM


THE DATE IS 20.02.2020
THE TIME IS 10:05:36 PM
THE DATE IS 20.02.2020
THE TIME IS 10:05:36 PM
THE DATE IS 20.02.2020
THE TIME IS 10:05:36 PM
THE DATE IS 20.02.2020
...

AA-6
If you first POKE0,65 to set the CPU to full speed, the whole program can run many
times per second. There is an occasional glitch, if the RTC registers are read while
being updated by the machine, so we really should de-bounce the values by reading
the time a couple of times in succession, and if the values aren’t the same both times,
then repeat the process until they are. This is left as an exercise for the reader.
NOTE: These registers are not yet fully documented.

MEGAPHONE HANDHELD, REVISIONS 1


AND 2
The MEGAphone revision 1 and 2 contain a Real-Time Clock (RTC), however this RTC
does not include a non-volatile memory (NVRAM) area. Other specific features of
the MEGAphone revisions 1 and 2 include a 3-axis accelerometer, including analog
to digital converters (ADCs), amplifier controller for loud speakers, and several I2C
I/O expanders, that are used to connect the joy-pad and other peripherals. The I/O
expanders are fully integrated into the MEGAphone design, and thus there should be
no normal need to read these registers directly. The I/O expanders are, however, also
responsible for power control of the various sub-systems of the MEGAphone.
NOTE: These registers are not yet fully documented.

NEXYS4 DDR FPGA BOARD


NOTE: These registers are not yet fully documented.

AA-7
AA-8
APPENDIX AB
Schematics
• MEGA65 R3 Schematics
• MEGA65 R2 Schematics
• Nexys Widget Board Schematics
AB-2
MEGA65 R3 SCHEMATICS

AB-3
1 2 3 4
U_HDMI U_B15 U_POWER
HDMI.SchDoc B15.SchDoc POWER.SchDoc

U_Ethernet U_B16 U_PowerMain COPM1


PM1 COPM2
PM2 COPM3
PM3
Ethernet.SchDoc B16.SchDoc PowerMain.SchDoc

U_B34 U_VGA
B34.SchDoc VGA.SchDoc
A A
U_LED_SW_BUT U_FPGA-CFG U_EXT_HEADER
LED_SW_BUT.SchDoc FPGA-CFG.SchDoc EXT_HEADER.SchDoc FIDU-DOT - small FIDU-DOT - small FIDU-DOT - small

U_SYS_MAX10_CTRL U_FPGA-MGT U_EXP_Slot


SYS_MAX10_CTRL.SchDoc FPGA-MGT.SchDoc EXP_Slot.SchDoc COPM4
PM4 COPM5
PM5 COPM6
PM6

U_SOUND U_FPGA-PWR U_Floppy


SOUND.SchDoc FPGA-PWR.SchDoc Floppy.SchDoc

U_B13 U_JOY
B13.SchDoc JOY.SchDoc
FIDU-DOT - small FIDU-DOT - small FIDU-DOT - small
U_B14 U_KEYBOARD
B14.SchDoc KEYBOARD.SchDoc

B COSerial1 B
Serial1
Serial
Serialnumber 6,3 x 6.3mm

COLOGO1
LOGO1

TE Logo PRINT Layer


LOGO PRINT

C COH5 COH7 COH8 COH1 COH2 COH3 C

PIH501 PIH701 PIH801 PIH10 PIH201 PIH301


GND GND GND GND GND GND
Mount.Hole 3.2mm Mount.Hole 3.2mm Mount.Hole 3.2mm Mount.Hole 3.2mm Mount.Hole 3.2mm Mount.Hole 3.2mm

Title:
Design drawn by: IG
MEGA65
Checked by: MR
D D
Number: Rev.
Assembly variant: [No Variations] A4 TE0765
[No Variations] 03
Created by: VariantCreatedBy
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 1 of 23
Modified by: VariantModifiedBy
Modified at: VariantDateModification Filename: TE0765.SchDoc
1 2 3 4
1 2 3 4

Grove CONN
PMOD CONN
COD1
D1
1 PID101 5
PID105 3.3V COD2 COD3
Grove_SCL0 3 PID103 D2 D3
NLB350L20N
B35_L2_N 1 PID201 5
PID205 B35_L5_N 1 PID301 5
PID305
A NLB350L20P 3.3V 3.3V A
Grove_SDA0 4 PID104 B35_L2_P 3 PID203 B35_L5_P 3 PID303
6 PID106
2
PID102 GND NLB350L10P
B35_L1_P 4 PID204 B35_L3_P 4 PID304
WE-TVS-824013 NLB350L10N
B35_L1_N 6 PID206 2
PID202 B35_L3_N 6 PID306 2
PID302
GND GND
WE-TVS-824013 WE-TVS-824013

COJ18
J18
COR128
R128PIR12801 PIR12802 4K7 NLGrove0SCL0
Grove_SCL0 1 PIJ1801 COP1
P1
3.3V COR129 NLGrove0SDA0 NLB350L50N NLB350L50P
R129 PIR12901 PIR12902 4K7 Grove_SDA0 2 PIJ1802 B35_L5_N 1 PIP101 7
PIP107 B35_L5_P
3 PIJ1803 NLB350L30N
B35_L3_N 2 PIP102 8
PIP108
NLB350L30P
B35_L3_P
3.3V
4 PIJ1804 B35_L2_N 3 PIP103
9
PIP109 B35_L2_P
GND
B35_L1_N 4 PIP104 10
PIP1010 B35_L1_P
110990037 5 PIP105 11
PIP1011
GND GND
GND GND
6 12
PIP1012
PMOD1_VCC PIC14501 PIC14601 PIP106 VCC VCC PMOD1_VCC
COC145
C145 COC146
C146 PMod 2x6 SMD Host Socket 90°
10µF
PIC14502 470nF PIC14602
10V
B COP2 B
GND GND P2
B35_L6_P 1 PIP201 7
PIP207
B35_L4_P
B35_L6_N 2 PIP202 8
PIP208 B35_L4_N
NLB350L120P
B35_L12_P 3 PIP203 9
PIP209
NLB350L120N
B35_L12_N
NLB350L100N
B35_L10_N 4 PIP204 10
PIP2010
NLB350L100P
B35_L10_P
CPLD CONFIG 5 PIP205 11
PIP2011
GND GND
GND GND
6 12
PIP2012
PMOD2_VCC PIC16201 PIC16301 PIP206 VCC VCC PMOD2_VCC
COJ17
J17 COC162
C162 COC163
C163 PMod 2x6 SMD Host Socket 90°
CPLD_JTAGi NLM0TCK
M_TCK 1 PIJ1701 2
PIJ1702
PIC1620
10µF PIC16302 470nF
PIR15602 NLM0TDO
M_TDO 3 PIJ1703 4
PIJ1704
10V
COR156
R156 NLM0TMS
M_TMS 5 PIJ1705 6 PIC13701 3.3V GND GND
PIJ1706
4K7 7 PIJ1707 8 COC137
C137 COD4
D4 COD11
D11
PIJ1708
PIR15601 NLM0TDI
M_TDI 9 PIJ1709 10
PIJ17010 PIC13702 470nF NLB350L40N
B35_L4_N 1 PID401 5
PID405 B35_L10_P 1 PID1101
5
PID1105
NLB350L60N 3.3V 3.3V
B35_L6_N 3 PID403 B35_L10_N 3 PID1103
GND SMD-254-9132-14-10 GND GND
NLB350L60P
B35_L6_P 4 PID404
B35_L12_P 4 PID1104
NLB350L40P
B35_L4_P 6 PID406 PID402
2 B35_L12_N 6 PID1106
2
PID1102
GND GND
C C
WE-TVS-824013 WE-TVS-824013

COU35
U35
7 PIU3507 8
PIU3508
3.3V IN OUT1 PMOD2_VCC
PIC16401
COC164
C164 COR146
R146 10K NLPMOD20FLG
PMOD2_FLG2 5
PIR14601 PIR14602 PIU3502 FLG1
OUT2 PIU3505 PMOD1_VCC
PIC16402 10µF COR147
R147
PIR14701 PIR1470210K
NLPMOD10FLG
PMOD1_FLG3 PIU3503
10V NLPMOD20EN FLG2
TE0790-Base SMT PMOD2_EN 1 PIU3501
NLPMOD10EN EN1
GND PMOD1_EN 4 PIU3504
COJB1 EN2
JB1
5
PIJB105 6 PIU3506
3.3V GND
6
PIJB106
TE_JTAGi VIO PIC13801 3.3V
GND AP2196SG-13
UART COC138
NLTE0TCK
TE_TCK 4 PIJB104 3
PIJB103
NLTE0UART0RX
TE_UART_RX C138
NLTE0TDO
C TCK A
NLTE0UART0TX 470nF
PIR15702 TE_TDO 8 PIJB108 7
PIJB107
TE_UART_TX PIC13802
COR157
R157 D TDO B
NLTE0TDI
TE_TDI 10 PIJB1010 9
PIJB109
PIR15802
4K7 F TDI E
COR158
R158
NLTE0TMS
TE_TMS 12 PIJB1012 11
PIJB1011
GND Title:
PIR15701 H TMSG
10K MEGA65
D GND
1 PIJB101
GND
PIR15801 D
GND 2 PIJB102 H1
PIJB10H1
Number: Rev.
GND GND
GND GND TE0765
GND A4 03
[No Variations]
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 2 of 23

Filename: EXT_HEADER.SchDoc
1 2 3 4
1 2 3 4

5V COU2
U2 COU8
U8
NLC640IRQ
C64_IRQ COR37
R37PIR3701
4K7
PIR3702
31 PIU2031 7
PIU207
31 PIU8031 7
PIU807
NLC640RW COR38 3.3V VCCA VCCB 5V 3.3V VCCA VCCB 5V
C64_RW R38PIR3801 4K7
PIR3802 EXP 42 PIU2042 18
PIU2018 EXP 42 PIU8042 18
PIU8018
NLC640CLOCK COR39 VCCA VCCB VCCA VCCB
C64_CLOCK R39PIR3901 4K7
PIR3902 i EXP i EXP
NLC640IO1
C64_IO1 COR40
R40PIR4001 4K7
PIR4002
A CARTi i i A
C64_GAME COR41
R41PIR4101 4K7
PIR4102
NLF0DATA0DIR
F_DATA_DIR 1 PIU201 48
PIU2048
NLF0DATA0EN
F_DATA_EN NLF0CTRL0DIR
F_CTRL_DIR 1 PIU801 48
PIU8048
NLF0CTRL0EN
F_CTRL_EN
1DIR 1OE i CART 1DIR 1OE i CART
C64_EXROM COR42
R42PIR4201
4K7
PIR4202
NLC640IO2 COR43 NLF0C640D7 CARTi NLF0C640RW
C64_IO2 R43PIR4301 4K7
PIR4302 F_C64_D7 47 PIU2047 2
PIU202 C64_D7 F_C64_RW 47 PIU8047 2
PIU802 C64_RW
NLC640ROMLCOR45 NLF0C640D6 1A1 1B1 NLF0C640ROMH 1A1 1B1
C64_ROML R45PIR4501 4K7
PIR4502 F_C64_D6 46 PIU2046 3
PIU203 C64_D6 F_C64_ROMH 46 PIU8046 3
PIU803 C64_ROMH
NLC640BA COR71 DATAi NLF0C640D5 1A2 1B2 NLF0C640IO1 1A2 1B2
C64_BA R71PIR7101 4K7
PIR7102 F_C64_D5 44 PIU2044 5
PIU205 C64_D5 F_C64_IO1 44 PIU8044 5
PIU805 C64_IO1
NLC640DMA COR90 NLF0C640D4 1A3 1B3 1A3 1B3
C64_DMA R90PIR9001 4K7
PIR9002 F_C64_D4 43 PIU2043 6
PIU206 C64_D4 43 PIU8043 6
PIU806
NLC640D7 COR91 NLF0C640D3 1A4 1B4 1A4 1B4
C64_D7 R91PIR9101
4K7
PIR9102
F_C64_D3 41 PIU2041 8
PIU208
C64_D3 41 PIU8041 8
PIU808
NLC640D6 COR92 NLF0C640D2 1A5 1B5 NLF0C640IO2 1A5 1B5
C64_D6 R92PIR9201 4K7
PIR9202 F_C64_D2 40 PIU2040 9
PIU209 C64_D2 F_C64_IO2 40 PIU8040 9
PIU809 C64_IO2
NLC640D5 COR93 NLF0C640D1 1A6 1B6 NLF0C640ROML 1A6 1B6
C64_D5 R93PIR9301 4K7
PIR9302 F_C64_D1 38 PIU2038 11
PIU2011 C64_D1 F_C64_ROML 38 PIU8038 11
PIU8011 C64_ROML
NLC640D4 COR94 NLF0C640D0 1A7 1B7 NLF0C640BA 1A7 1B7
C64_D4 R94PIR9401 4K7
PIR9402 F_C64_D0 37 PIU2037 12 EXP
PIU2012 C64_D0 F_C64_BA 37 PIU8037 12 EXP
PIU8012 C64_BA
NLC640D3 COR95 1A8 1B8 1A8 1B8
C64_D3 R95PIR9501 4K7
PIR9502 i i
NLC640D2
C64_D2 COR96
R96PIR9601
4K7
PIR9602
NLF0LADDR0DIR
F_LADDR_DIR 24 PIU2024 25
PIU2025
NLF0ADDR0EN
F_ADDR_EN NLF0HADDR0DIR
F_HADDR_DIR 24 PIU8024 25
PIU8025
F_ADDR_EN
NLC640D1 COR97 2DIR 2OE i CART 2DIR 2OE i CART
C64_D1 R97PIR9701 4K7
PIR9702
NLC640D0
C64_D0 COR98
R98PIR9801 4K7
PIR9802
NLF0C640A7
F_C64_A7 36 PIU2036 13
PIU2013 C64_A7 NLF0C640A15
F_C64_A15 36 PIU8036 13
PIU8013 C64_A15
NLF0C640A6 2A1 2B1 NLF0C640A14 2A1 2B1
F_C64_A6 35 PIU2035 14
PIU2014 C64_A6 F_C64_A14 35 PIU8035 14
PIU8014 C64_A14
ADRi NLF0C640A5 2A2 2B2 ADRi NLF0C640A13 2A2 2B2
F_C64_A5 33 PIU2033 16
PIU2016
C64_A5 F_C64_A13 33 PIU8033 16
PIU8016
C64_A13
NLF0C640A4 2A3 2B3 NLF0C640A12 2A3 2B3
F_C64_A4 32 PIU2032 17
PIU2017
C64_A4 F_C64_A12 32 PIU8032 17
PIU8017
C64_A12
NLF0C640A3 2A4 2B4 NLF0C640A11 2A4 2B4
F_C64_A3 30 PIU2030 19
PIU2019 C64_A3 F_C64_A11 30 PIU8030 19
PIU8019 C64_A11
NLF0C640A2 2A5 2B5 NLF0C640A10 2A5 2B5
F_C64_A2 29 PIU2029 20
PIU2020 C64_A2 F_C64_A10 29 PIU8029 20
PIU8020 C64_A10
B NLF0C640A1 2A6 2B6 NLF0C640A9 2A6 2B6 B
F_C64_A1 27 PIU2027 22
PIU2022 C64_A1 F_C64_A9 27 PIU8027 22
PIU8022 C64_A9
NLF0C640A0 2A7 2B7 NLF0C640A8 2A7 2B7
F_C64_A0 26 PIU2026 23
PIU2023
C64_A0 F_C64_A8 26 PIU8026 23
PIU8023
C64_A8
2A8 2B8 2A8 2B8
3.3V COU30
U30 28 PIU2028 4
PIU204 28 PIU8028 4
PIU804
GND GND GND GND
1 PIU3001 5
PIU3005 34 PIU2034 10
PIU2010 34 PIU8034 10
PIU8010
NLC640EXROM OE
VCC 3.3V GND GND GND GND
C64_EXROM2 PIU3002 39 PIU2039 15
PIU2015 39 PIU8039 15
PIU8015
A NLF0C640EXROM GND GND GND GND
3 PIU3003
4
PIU3004
F_C64_EXROM 45 PIU2045 21
PIU2021
45 PIU8045 21
PIU8021
GND GND
Y i EXP GND GND GND GND GND GND GND GND
NC7SZ126P5X SN74LVCH16T245DGV SN74LVCH16T245DGV
COJ8
J8
44 PIJ8044 43
PIJ8043
COU31 COU9 GND GND
3.3V U31 U9 42 PIJ8042 41
PIJ8041
C64_ROMH
1 PIU3101 5
PIU3105
31 PIU9031 7
PIU907
40 PIJ8040 39
PIJ8039
C64_RESET
NLC640GAME OE
VCC 3.3V 3.3V VCCA VCCB 5V 5V
C64_GAME 2 PIU3102 A
42 PIU9042 18
PIU9018
C64_IRQ 38 PIJ8038 37
PIJ8037
C64_NMI
NLF0C640GAME VCCA VCCB
3 PIU3103 4
PIU3104
F_C64_GAME EXP C64_RW 36 PIJ8036 35
PIJ8035
C64_O2
GND GNDY i EXP
i C64_CLOCK 34 PIJ8034 33
PIJ8033 C64_A15
NC7SZ126P5X 1 PIU901 48
PIU9048
C64_IO1 32 PIJ8032 31
PIJ8031
C64_A14
GND 1DIR 1OE GND
C64_GAME 30 PIJ8030 29
PIJ8029
C64_A13
NLF0C640NMI
F_C64_NMI 47 PIU9047 2
PIU902 C64_NMI C64_EXROM 28 PIJ8028 27
PIJ8027 C64_A12
C CARTi NLF0C640IRQ 1A1 1B1 C
F_C64_IRQ 46 PIU9046 3
PIU903 C64_IRQ C64_IO2 26 PIJ8026 25
PIJ8025 C64_A11
CARTi NLF0C640DMA 1A2 1B2
5V F_C64_DMA 44 PIU9044 5
PIU905 C64_DMA C64_ROML 24 PIJ8024 23
PIJ8023 C64_A10
NLC640ROMH COR99 CARTi NLFB0RIGHT 1A3 1B3 NLJB0RIGHT
C64_ROMH R99PIR9901
4K7
PIR9902
FB_RIGHT 43 PIU9043 6
PIU906
JB_RIGHT C64_BA 22 PIJ8022 21
PIJ8021
C64_A9
NLC640RESET COR100 NLFB0LEFT 1A4 1B4 NLJB0LEFT
C64_RESET R100
PIR10001
4K7
PIR10002
FB_LEFT 41 PIU9041 8
PIU908
JB_LEFT C64_DMA 20 PIJ8020 19
PIJ8019
C64_A8
NLC640NMI COR101 NLFB0DOWN 1A5 1B5 NLJB0DOWN
C64_NMI R101
PIR10101
4K7
PIR10102
FB_DOWN 40 PIU9040 9
PIU909
JB_DOWN C64_D7 18 PIJ8018 17
PIJ8017
C64_A7
NLC640O2 COR102 NLFB0FIRE 1A6 1B6 NLJB0FIRE
C64_O2 R102PIR10201
4K7
PIR10202
FB_FIRE 38 PIU9038 11
PIU9011
JB_FIRE C64_D6 16 PIJ8016 15
PIJ8015
C64_A6
NLC640A15 COR103 NLFB0UP 1A7 1B7 NLJB0UP
C64_A15 R103
PIR10301 4K7
PIR10302 FB_UP 37 PIU9037 12
PIU9012 JB_UP C64_D5 14 PIJ8014 13
PIJ8013 C64_A5
NLC640A14 COR104 1A8 1B8
C64_A14 R104
PIR10401
4K7
PIR10402
C64_D4 12 PIJ8012 11
PIJ8011
C64_A4
NLC640A13
C64_A13 COR105
R105
PIR10501
4K7
PIR10502
24 PIU9024 25
PIU9025
C64_D3 10 PIJ8010 9
PIJ809
C64_A3
NLC640A12 COR106 3.3V 2DIR 2OE GND
C64_A12 R106PIR10601
4K7
PIR10602
C64_D2 8 PIJ808 7
PIJ807
C64_A2
NLC640A11
C64_A11 COR107
R107
PIR10701 4K7
PIR10702
NLF0C640RESET
F_C64_RESET 36 PIU9036 13
PIU9013 C64_RESET C64_D1 6 PIJ806 5
PIJ805 C64_A1
CARTi 2A1 2B1
NLC640A10
C64_A10 COR108
R108
PIR10801
4K7
PIR10802
NLF0C640CLOCK
F_C64_CLOCK 35 PIU9035 14
PIU9014
C64_CLOCK C64_D0 4 PIJ804 3
PIJ803
C64_A0
NLC640A9 COR109 CARTi NLF0C640O2 2A2 2B2
C64_A9 R109
PIR10901
4K7
PIR10902
F_C64_O2 33 PIU9033 16
PIU9016
C64_O2 2 PIJ802 1
PIJ801
NLC640A8 COR110 CARTi NLF0SER0ATN 2A3 2B3 NLSER0ATN GND GND
C64_A8 R110
PIR11001
4K7
PIR11002
F_SER_ATN 32 PIU9032 17
PIU9017
SER_ATN
NLC640A7 COR111 NLF0SER0RESET 2A4 2B4 NLSER0RESET
C64_A7 R111
PIR11101
4K7
PIR11102
F_SER_RESET 30 PIU9030 19
PIU9019
SER_RESET 120-044-60
NLC640A6 COR112 NLF0MOTEB 2A5 2B5 NLMOTEB
C64_A6 R112
PIR11201
4K7
PIR11202
F_MOTEB 29 PIU9029 20
PIU9020
MOTEB
2A6 2B6
NLC640A5
C64_A5 COR113
R113
PIR11301
4K7
PIR11302
NLF0DRVSB
F_DRVSB 27 PIU9027 22
PIU9022
NLDRVSB
DRVSB Title:
NLC640A4 COR114 2A7 2B7
C64_A4 R114
PIR11401
4K7
PIR11402
26 PIU9026 23
PIU9023 MEGA65
NLC640A3 COR115 GND 2A8 2B8
C64_A3 R115
PIR11501
4K7
PIR11502
D NLC640A2 COR116 D
C64_A2 R116
PIR11601
4K7
PIR11602
28 PIU9028 4
PIU904
Number: Rev.
NLC640A1 COR117 i GND GND TE0765
C64_A1 R117
PIR11701 4K7
PIR11702 34 PIU9034 10
PIU9010 A4 03
GND GND [No Variations]
NLC640A0
C64_A0 COR118
R118
PIR11801
4K7
PIR11802
EXP 39 PIU9039 15
PIU9015
GND GND
45 PIU9045 21
PIU9021
GND GND GND GND Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 3 of 23
SN74LVCH16T245DGV
Filename: EXP_Slot.SchDoc
1 2 3 4
1 2 3 4

A A

B13
i
COU1A
U1A
BANK 13 AB11
PIU10AB11
NLB4
B4
IO_L7P_T1_13 NLB2
V16 PIU10V16 AB12
PIU10AB12 B2
3.3V VCCO_13 IO_L7N_T1_13 NLVDAC0CLK
PIC5101 PIC5201 PIC5401 COC1
PIC101C1 PIC50COC50
1C50 PIC201 W13 PIU10W13 AA9
PIU10AA9 VDAC_CLK
COC51
C51 COC52
C52 COC54
C54 COC2
C2 VCCO_13 IO_L8P_T1_13 NLB6
Y10 PIU10Y10 AB10
PIU10AB10 B6
PIC5102 470nF PIC5202 470nF PIC5402 470nF PIC1024.7µF PIC50 24.7µF PIC202 47µF VCCO_13 IO_L8N_T1_13 NLB7
AA17 PIU10AA17
AA10
PIU10AA10
B7
VCCO_13 IO_L9P_T1_DQS_13 NLB3
AB14 PIU10AB14
AA11
PIU10AA11
B3
VCCO_13 IO_L9N_T1_DQS_13 NLVDAC0SYNC0N
GND V10
PIU10V10 VDAC_SYNC_N COR159 3.3V
NLR3 IO_L10P_T1_13 NLB0 NLCPLD0CLK R159
R3 Y17 PIU10Y17 W10
PIU10W10 B0 CPLD_CLK PIR15901 PIR15902 COC77
C77
B B13i IO_0_13 IO_L10N_T1_13 NLB5 B
Y11
PIU10Y11 B5 22R PIC7701 PIC7702
IO_L11P_T1_SRCC_13 NLB1 GND
Y12
PIU10Y12
B1 1%
NLR4 IO_L11N_T1_SRCC_13 470nF
R4 Y16 PIU10Y16
W11 NLVDAC0BLANK0N
PIU10W11
VDAC_BLANK_N
B13i NLR6 IO_L1P_T0_13 IO_L12P_T1_MRCC_13 NLHSYNC COU17
R6 AA16 PIU10AA16 W12
PIU10W12 HSYNC COR126 U17
NLR7 IO_L1N_T0_13 IO_L12N_T1_MRCC_13 NLCLOCK0FPGA0MRCC R126
R7 AB16 PIU10AB16 V13
PIU10V13 CLOCK_FPGA_MRCC PIR12601 PIR12602 3 PIU1703 4
PIU1704
NLR5 IO_L2P_T0_13 IO_L13P_T2_MRCC_13 NLVSYNC CLK VDD
R5 AB17 PIU10AB17 V14
PIU10V14 VSYNC 22R
NLG6 IO_L2N_T0_13 IO_L13N_T2_MRCC_13 NLR0
G6 AA13 PIU10AA13
U15
PIU10U15
R0 1% 2 PIU1702
1
PIU1701
NLG7 IO_L3P_T0_DQS_13
IO_L14P_T2_SRCC_13 NLR1 GND
OE/ST
G7 AB13 PIU10AB13
V15
PIU10V15
R1
NLG2 IO_L3N_T0_DQS_13
IO_L14N_T2_SRCC_13 NLR2
G2 AA15 PIU10AA15 T14
PIU10T14 R2 GND
NLG3 IO_L4P_T0_13 IO_L15P_T2_DQS_13 NLVGA0SDA
G3 AB15 PIU10AB15 T15
PIU10T15 VGA_SDA SiT8008BI-73-XXS-100.000000E
NLG4 IO_L4N_T0_13 IO_L15N_T2_DQS_13 NLVGA0SCL
G4 Y13 PIU10Y13 W15
PIU10W15 VGA_SCL
NLG5 IO_L5P_T0_13 IO_L16P_T2_13
G5 AA14 PIU10AA14
W16
PIU10W16
RSVD2
NLG1 IO_L5N_T0_13 IO_L16N_T2_13
G1 W14 PIU10W14
T16
PIU10T16
RSVD0
NLG0 IO_L6P_T0_13 IO_L17P_T2_13
G0 Y14 PIU10Y14
U16
PIU10U16
RSVD1
IO_L6N_T0_VREF_13 IO_L17N_T2_13
XC7A200T-2FBG484C
i COU18
U18
B13 1 PIU1801 5
PIU1805
3.3V OE
VCC 3.3V
HSYNC 2 PIU1802
C A NLVGA0HSync C
3 PIU1803 4
PIU1804 VGA_HSync
GND GND Y

COTP1 NC7SZ126P5X
NLRSVD0 TP1
RSVD0 PITP101

Testpoint 0.8mm

COTP2 COU19
U19
NLRSVD1 TP2
RSVD1 PITP201
1 PIU1901 5
PIU1905
3.3V OE
VCC 3.3V
VSYNC 2 PIU1902
Testpoint 0.8mm A NLVGA0VSync
3 PIU1903 4
PIU1904
VGA_VSync
GND GND Y
COTP3
TP3
NLRSVD2
RSVD2 PITP301
NC7SZ126P5X
Testpoint 0.8mm

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 4 of 23

Filename: B13.SchDoc
1 2 3 4
1 2 3 4

A A

B14
i

COU1B
U1B
NLF0SER0RESET COR58
R58
BANK 14 AB21
PIU10AB21 F_SER_RESET PIR5802 PIR5801
3.3V IO_L10P_T1_D14_14 NLF0SER0DATA0I GND
PIC5801 PIC5901 PIC60 1 PIC6101 PIC5 0COC55
1C55 PIC570COC57
1C57 PIC5302 M14 PIU10M14
VCCO_14 IO_L10N_T1_D15_14
AB22
PIU10AB22 F_SER_DATA_I 1K
COC58
C58 COC59
C59 COC60
C60 COC61
C61 COC53
C53 P18 PIU10P18 U20 NLF0SER0SRQ0O
F_SER_SRQ_O
VCCO_14 IO_L11P_T1_SRCC_14 PIU10U20 1%
PIC5802 470nF PIC5902 470nF PIC60 2 470nF PIC6102 470nF PIC5 024.7µF PIC57024.7µF PIC5301 47µF R15 PIU10R15 V20
PIU10V20
VCCO_14 IO_L11N_T1_SRCC_14 NLFB0UP
T22 PIU10T22 W19
PIU10W19 FB_UP
VCCO_14 IO_L12P_T1_MRCC_14 NLF0C640D6
GND U19 PIU10U19 W20
PIU10W20 F_C64_D6
VCCO_14 IO_L12N_T1_MRCC_14 NLF0SER0CLK0I
Y20 PIU10Y20 Y18
PIU10Y18 F_SER_CLK_I
VCCO_14 IO_L13P_T2_MRCC_14 NLF0SER0CLK0O
Y19
PIU10Y19
F_SER_CLK_O
NLF0C640D2 IO_L13N_T2_MRCC_14 NLF0C640D5
F_C64_D2 P20 PIU10P20 V18
PIU10V18
F_C64_D5
B14i IO_0_14 IO_L14P_T2_SRCC_14
V19
PIU10V19
NLF0C640IO1 IO_L14N_T2_SRCC_14 NLF0C640CLOCK
F_C64_IO1 N15 PIU10N15 AA19
PIU10AA19 F_C64_CLOCK
B B14i IO_25_14 IO_L15P_T2_DQS_RDWR_B_14 NLF0SER0SRQ0EN B
AB20
PIU10AB20 F_SER_SRQ_EN
NLSPI0DQO IO_L15N_T2_DQS_DOUT_CSO_B_14 NLF0C640O2
SPI-DQO P22 PIU10P22 V17
PIU10V17
F_C64_O2
NLSPI0DQ1 IO_L1P_T0_D00_MOSI_14 IO_L16P_T2_CSI_B_14 NLF0C640NMI
SPI-DQ1 R22 PIU10R22 W17
PIU10W17
F_C64_NMI
NLSPI0DQ2 IO_L1N_T0_D01_DIN_14 IO_L16N_T2_A15_D31_14 NLF0SER0SRQ0I
SPI-DQ2 P21 PIU10P21 AA18
PIU10AA18 F_SER_SRQ_I
NLSPI0DQ3 IO_L2P_T0_D02_14 IO_L17P_T2_A14_D30_14 NLF0C640ROML
SPI-DQ3 R21 PIU10R21 AB18
PIU10AB18 F_C64_ROML
IO_L2N_T0_D03_14 IO_L17N_T2_A13_D29_14 NLF0CTRL0DIR
ULED U22 PIU10U22 U17
PIU10U17 F_CTRL_DIR
NLF0DATA0DIR IO_L3P_T0_DQS_PUDC_B_14 IO_L18P_T2_A12_D28_14 NLF0C640D4
F_DATA_DIR V22 PIU10V22 U18
PIU10U18
F_C64_D4
IO_L3N_T0_DQS_EMCCLK_14 IO_L18N_T2_A11_D27_14 NLF0C640IRQ
T21 PIU10T21 P14
PIU10P14
F_C64_IRQ
NLF0DATA0EN IO_L4P_T0_D04_14 IO_L19P_T3_A10_D26_14 NLETH0LED2
F_DATA_EN U21 PIU10U21 R14
PIU10R14 ETH_LED2
IO_L4N_T0_D05_14 IO_L19N_T3_A09_D25_VREF_14 NLF0C640RW
P19 PIU10P19 R18
PIU10R18 F_C64_RW
NLF0C640EXROM IO_L5P_T0_D06_14 IO_L20P_T3_A08_D24_14 NLF0C640ROMH
F_C64_EXROMR19 PIU10R19 T18
PIU10T18 F_C64_ROMH
NLSPI0CS IO_L5N_T0_D07_14 IO_L20N_T3_A07_D23_14 NLF0SER0ATN
SPI-CS T19 PIU10T19 N17
PIU10N17
F_SER_ATN
IO_L6P_T0_FCS_B_14 IO_L21P_T3_DQS_14 NLFB0DOWN
T20 PIU10T20 P17
PIU10P17
FB_DOWN
NLF0C640D7 IO_L6N_T0_D08_VREF_14 IO_L21N_T3_DQS_A06_D22_14 NLF0C640DMA
F_C64_D7 W21 PIU10W21 P15
PIU10P15
F_C64_DMA
NLF0C640GAME IO_L7P_T1_D09_14 IO_L22P_T3_A05_D21_14 NLF0C640D3
F_C64_GAME W22 PIU10W22 R16
PIU10R16
F_C64_D3
NLF0C640IO2 IO_L7N_T1_D10_14 IO_L22N_T3_A04_D20_14 NLF0C640BA
F_C64_IO2 AA20 PIU10AA20 N13
PIU10N13 F_C64_BA
NLF0SER0CLK0EN IO_L8P_T1_D11_14 IO_L23P_T3_A03_D19_14 NLF0C640RESET
F_SER_CLK_ENAA21 PIU10AA21 N14
PIU10N14
F_C64_RESET
B14i NLF0SER0DATA0EN IO_L8N_T1_D12_14 IO_L23N_T3_A02_D18_14 NLF0C640D0
F_SER_DATA_ENY21 PIU10Y21 P16
PIU10P16
F_C64_D0
NLF0SER0DATA0O IO_L9P_T1_DQS_14 IO_L24P_T3_A01_D17_14 NLF0C640D1
F_SER_DATA_O Y22 PIU10Y22 R17
PIU10R17 F_C64_D1
C IO_L9N_T1_DQS_D13_14 IO_L24N_T3_A00_D16_14 C
XC7A200T-2FBG484C

COD9
D9
NLULED
ULED
COR67
R67
PID90A PID90K PIR6701 PIR6702 GND
240R 1%
LED Red LTST-C191KRKT

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 5 of 23

Filename: B14.SchDoc
1 2 3 4
1 2 3 4

B15
i
COU1C
U1C
3.3V BANK 15
G19 PIU10G19 M21
PIU10M21
PIC6401 PIC6501 PIC6 01 PIC6701 PIC401 VCCO_15 IO_L10P_T1_AD11P_15 NLF0LADDR0DIR
PIC6201COC62
C62 COC63
PIC6301C63 H16 PIU10H16 L21
PIU10L21 F_LADDR_DIR
COC64
C64 COC65
C65 COC66
C66 COC67
C67 COC4
C4 VCCO_15 IO_L10N_T1_AD11N_15 NLF0C640A5
J13 PIU10J13 J20
PIU10J20 F_C64_A5
A PIC6402 470nF PIC6502 470nF PIC6 02 470nF PIC6702 470nF PIC62024.7µF PIC63024.7µF PIC402 47µF VCCO_15 IO_L11P_T1_SRCC_15 NLF0C640A6 A
K20 PIU10K20 J21
PIU10J21 F_C64_A6
VCCO_15 IO_L11N_T1_SRCC_15 NLRSVD0MRCC COTP4
L17 PIU10L17 J19
PIU10J19
RSVD_MRCC PITP401
TP4
VCCO_15 IO_L12P_T1_MRCC_15 NLF0C640A12
GND N21 PIU10N21 H19
PIU10H19 F_C64_A12
VCCO_15 IO_L12N_T1_MRCC_15 NLF0C640A1
K18
PIU10K18 F_C64_A1
IO_L13P_T2_MRCC_15 NLF0C640A0
K19
PIU10K19 F_C64_A0
IO_L13N_T2_MRCC_15 NLF0ADDR0EN
J16 PIU10J16 L19
PIU10L19 F_ADDR_EN
IO_0_15 IO_L14P_T2_SRCC_15 NLF0C640A4
L20
PIU10L20
F_C64_A4
B15i IO_L14N_T2_SRCC_15 NLF0C640A14
M17 PIU10M17 N22
PIU10N22 F_C64_A14
IO_25_15 IO_L15P_T2_DQS_15 NLF0C640A3
M22
PIU10M22 F_C64_A3
IO_L15N_T2_DQS_ADV_B_15
CP0 H13 PIU10H13 M18
PIU10M18
IO_L1P_T0_AD0P_15 IO_L16P_T2_A28_15 NLF0HADDR0DIR
G13 PIU10G13 L18
PIU10L18 F_HADDR_DIR
IO_L1N_T0_AD0N_15 IO_L16N_T2_A27_15
CP1 G15 PIU10G15 N18
PIU10N18
IO_L2P_T0_AD8P_15 IO_L17P_T2_A26_15 COTP6
G16 PIU10G16 N19
PIU10N19 PITP601 TP6
NLCP2 IO_L2N_T0_AD8N_15 IO_L17N_T2_A25_15 COTP7
CP2 J14 PIU10J14 N20
PIU10N20 PITP701 TP7
IO_L3P_T0_DQS_AD1P_15 IO_L18P_T2_A24_15 NLF0C640A13
H14 PIU10H14 M20
PIU10M20 F_C64_A13
NLF0DRVSB IO_L3N_T0_DQS_AD1N_15 IO_L18N_T2_A23_15
F_DRVSB G17 PIU10G17 K13
PIU10K13
NLF0CTRL0EN IO_L4P_T0_15 IO_L19P_T3_A22_15
F_CTRL_EN G18 PIU10G18 K14
PIU10K14
NLF0C640A11 IO_L4N_T0_15 IO_L19N_T3_A21_VREF_15 NLFPGA0RESET0N
F_C64_A11 J15 PIU10J15 M13
PIU10M13 FPGA_RESET_N
NLF0MOTEB IO_L5P_T0_AD9P_15 IO_L20P_T3_A20_15 NLDBG0UART0TX
F_MOTEB H15 PIU10H15 L13
PIU10L13 DBG_UART_TX
B NLF0C640A8 IO_L5N_T0_AD9N_15 IO_L20N_T3_A19_15 COTP5 B
F_C64_A8 H17 PIU10H17 K17
PIU10K17 PITP501 TP5
NLF0C640A15 IO_L6P_T0_15 IO_L21P_T3_DQS_15
F_C64_A15 H18 PIU10H18 J17
PIU10J17
NLCP3 IO_L6N_T0_VREF_15 IO_L21N_T3_DQS_A18_15 NLDBG0UART0RX
CP3 J22 PIU10J22 L14
PIU10L14
DBG_UART_RX
IO_L7P_T1_AD2P_15 IO_L22P_T3_A17_15
Pulse-discharge H22 PIU10H22 L15
PIU10L15
NLF0C640A9 IO_L7N_T1_AD2N_15 IO_L22N_T3_A16_15 NLFPGA0TX GND
F_C64_A9 H20 PIU10H20 L16
PIU10L16 FPGA_TX
NLF0C640A10 IO_L8P_T1_AD10P_15 IO_L23P_T3_FOE_B_15 NLFPGA0RX
F_C64_A10 G20 PIU10G20 K16
PIU10K16 FPGA_RX
NLF0C640A2 IO_L8N_T1_AD10N_15 IO_L23N_T3_FWE_B_15 NLCT0HPD
GND F_C64_A2K21 PIU10K21 M15
PIU10M15
CT_HPD
NLF0C640A7 IO_L9P_T1_DQS_AD3P_15 IO_L24P_T3_RS1_15
F_C64_A7 K22 PIU10K22 M16
PIU10M16
IO_L9N_T1_DQS_AD3N_15 IO_L24N_T3_RS0_15
PIC7801
COC78
C78 XC7A200T-2FBG484C
PIC7802 1.2nF i
50V COU41
U41 B15
1 PIU4101 5
PIU4105
NLJA0AX COR14
R14 3.3V OE
VCC 3.3V
JA_AX PIR1401 PIR1402
2 PIU4102
A NLCP0
1K 3 PIU4103 4
PIU4104
CP0
GND PIT803 GND
Y
1% GND GND
COT8
T8 NC7SZ126P5X
2N7002,215 PIC7901 PIC80 1
NLPulse0discharge
Pulse-discharge
PIT801
COC79
C79 COC80
C80
C 1.2nF 1.2nF C
PIC7902 PIC80 2
50V COU6
U6 50V COU40
U40
PIT802 COR22
R22 3.3V
1 PIU601
OE
VCC
5
PIU605 3.3V COR23
R23 3.3V
1 PIU4001 VCC
OE
5
PIU4005 3.3V
NLJB0AX
JB_AX PIR2201 PIR2202
2 PIU602 NLJB0AY
JB_AY PIR2301 PIR2302
2 PIU4002
A A
GND 1K 3 PIU603 4
PIU604
CP2 1K 3 PIU4003
4
PIU4004
CP3
GNDPIT703 GND
Y GNDPIT903 GND
Y
1% COT7 1% COT9
GND T7 NC7SZ126P5X T9 NC7SZ126P5X
2N7002,215 2N7002,215
PIC8101 Pulse-discharge PIT701 Pulse-discharge PIT901
COC81
C81
PIC8102 1.2nF PIT702 PIT902
50V COU42
U42
1 PIU4201 5
PIU4205
NLJA0AY COR46
R46 3.3V OE
VCC 3.3V
JA_AY PIR4601 PIR4602
2 PIU4202 GND GND
A NLCP1
1K 3 PIU4203 4
PIU4204
CP1
GND PIT10 3 GNDY
1% COT10
T10 NC7SZ126P5X Title:
2N7002,215 MEGA65
Pulse-discharge
PIT1001
D D
Number: Rev.
A4 TE0765
PIT10 2 [No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 6 of 23
GND
Filename: B15.SchDoc
1 2 3 4
1 2 3 4

COU1D
U1D
BANK 16
NLKB0IO2 i B16
A17 PIU10A17 A13
PIU10A13 KB_IO2
3.3V PIC9101 PIC9201 PIC9301 PIC9801 PIC501 VCCO_16 IO_L10P_T1_16 NLKB0IO1
PIC680COC68
1C68 PIC90COC90
1C90 B14 PIU10B14 A14
PIU10A14 KB_IO1
COC91
C91 COC92
C92 COC93
C93 COC98
C98 COC5
C5 VCCO_16 IO_L10N_T1_16 NLSD20CLK
C21 PIU10C21 B17
PIU10B17 SD2_CLK
A PIC9102 470nF PIC9202 470nF PIC9302 470nF PIC9802 470nF PIC68024.7µF PIC90 24.7µF PIC502 47µF VCCO_16 IO_L11P_T1_SRCC_16 NLSD20D0 A
D18 PIU10D18 B18
PIU10B18 SD2_D0
VCCO_16 IO_L11N_T1_SRCC_16 NLSD20CD
E15 PIU10E15
D17
PIU10D17
SD2_CD
VCCO_16 IO_L12P_T1_MRCC_16 NLSD20WP
GND F22 PIU10F22 C17
PIU10C17 SD2_WP
VCCO_16 IO_L12N_T1_MRCC_16 NLSD20D1
C18
PIU10C18 SD2_D1
IO_L13P_T2_MRCC_16 NLSD20D2
C19
PIU10C19 SD2_D2
NLFB0FIRE IO_L13N_T2_MRCC_16 NLAUDIO0BCLK
FB_FIRE F15 PIU10F15 E19
PIU10E19 AUDIO_BCLK
IO_0_16 IO_L14P_T2_SRCC_16
D19
PIU10D19
NLFB0LEFT IO_L14N_T2_SRCC_16 NLnSD0AUDIO
FB_LEFT F21 PIU10F21 F18
PIU10F18 nSD_AUDIO
IO_25_16 IO_L15P_T2_DQS_16
E18
PIU10E18
NLFA0RIGHT IO_L15N_T2_DQS_16
FA_RIGHT F13 PIU10F13 B20
PIU10B20 DQ4
NLFA0LEFT IO_L1P_T0_16 IO_L16P_T2_16
FA_LEFT F14 PIU10F14 A20
PIU10A20 DQ3
NLFA0DOWN IO_L1N_T0_16 IO_L16N_T2_16
FA_DOWN F16 PIU10F16
A18
PIU10A18
NLFA0FIRE IO_L2P_T0_16 IO_L17P_T2_16
FA_FIRE E17 PIU10E17 A19
PIU10A19 DQ5
NLFA0UP IO_L2N_T0_16 IO_L17N_T2_16 NLAUDIO0LRCLK
FA_UP C14 PIU10C14 F19
PIU10F19 AUDIO_LRCLK
NLFB0RIGHT IO_L3P_T0_DQS_16 IO_L18P_T2_16
FB_RIGHT C15 PIU10C15 F20
PIU10F20
NLKB0TCK IO_L3N_T0_DQS_16 IO_L18N_T2_16 COTP8
KB_TCK E13 PIU10E13
D20
PIU10D20 PITP801
TP8
NLKB0TDO IO_L4P_T0_16 IO_L19P_T3_16
KB_TDO E14 PIU10E14
C20
PIU10C20
DQ2
NLAUDIO0SDATA IO_L4N_T0_16 IO_L19N_T3_VREF_16
AUDIO_SDATAE16 PIU10E16 C22
PIU10C22 CS0
NLAUDIO0MCLK IO_L5P_T0_16 IO_L20P_T3_16
3.3V AUDIO_MCLKD16 PIU10D16 B22
PIU10B22 H_RES
B COU39 NLKB0TMS IO_L5N_T0_16 IO_L20N_T3_16 B
U39 KB_TMS D14 PIU10D14 B21
PIU10B21 RWDS
NLKB0TDI IO_L6P_T0_16 IO_L21P_T3_DQS_16
1 PIU3901 8
PIU3908
KB_TDI D15 PIU10D15
A21
PIU10A21
DQ0
GND A0
VCC NLFPGA0SDA NLSD20D3 IO_L6N_T0_VREF_16 IO_L21N_T3_DQS_16
2 PIU3902 5
PIU3905
FPGA_SDA SD2_D3 B15 PIU10B15
E22
PIU10E22
DQ7
A1
SDA NLFPGA0SCL NLSD20CMD IO_L7P_T1_16 IO_L22P_T3_16
3 PIU3903 6
PIU3906 FPGA_SCL SD2_CMD B16 PIU10B16 D22
PIU10D22 H_CLK
3.3V A2
SCL NLKB0IO3 IO_L7N_T1_16 IO_L22N_T3_16
7 PIU3907 4
PIU3904 KB_IO3 C13 PIU10C13 E21
PIU10E21 DQ6
WP
VSS GND B16i NLKB0JTAGEN IO_L8P_T1_16 IO_L23P_T3_16
KB_JTAGEN B13 PIU10B13 D21
PIU10D21 DQ1
IO_L8N_T1_16 IO_L23N_T3_16 NLGrove0SCL0
GND 24LC128-I/ST FPGA_SCL A15 PIU10A15
G21
PIU10G21
Grove_SCL0
IO_L9P_T1_DQS_16 IO_L24P_T3_16 NLGrove0SDA0
FPGA_SDA A16 PIU10A16
G22
PIU10G22
Grove_SDA0
I2C addr: 0x54 IO_L9N_T1_DQS_16 IO_L24N_T3_16
XC7A200T-2FBG484C

3.3V
3.3V COU36
U36 COU38
U38
6 PIU3606
1
PIU3601
FPGA_SCL COR151
R151PIR15101 PIR15102
4K7 NLX2
X2
1 PIU3801 20 NLX1
X1
PIU38020
VCC
SCL X2 X1
PIC17501 5 PIU3605
2
PIU3602
3V 2 PIU3802 19
PIU38019
COC175
C175 A0VSS GND COR152 COD14 X2 X1
4 PIU3604 3
PIU3603 FPGA_SDA R152PIR15201 PIR15202 4K7 D14 3 PIU3803 18
PIU38018
PIC17502 470nF A1SDA COB1 X2 X1
B1 4 PIU3804 17
PIU38017
X2 X1
GND 24AA025E48T-I/OT PID1401
5 PIU3805 16
PIU38016
X2 X1
GND 3.3V
C C
I2C addr: 0x50 -
PIB100 +
PIB100 PID1403 7 PIU3807 14
PIU38014
VBAT VDD
PIC18401 PIR16302 PIC18501
COU29
U29 GND COC184
C184 6 COR163
R163 COC185
C185
PID1402 PIU3806 NC
B1 PIU290B1 B4
PIU290B4
PIC18402 470nF9 PIU3809 4K7 PIC18502 470nF
NLH0CLK CK VCC 3.3V NC 6.3V
H_CLK B2 PIU290B2 D1
PIU290D1
Batteriehalter CR1220 6.3V10 PIU38010 13
PIU38013 PIR16301
CK VCCQ NC
IRQ/FOUT
E4
PIU290E4
BAT54C GND 15 PIU38015 GND
VCCQ NC
21 PIU38021 12
PIU38012 FPGA_SCL
NLH0RES NC SCL
A4
PIU290A4
H_RES
NLRWDS RESET
RWDS C3 PIU290C3 8 PIU3808 11
PIU38011
FPGA_SDA
RWDS NLCS0 GND SDA
A3
PIU290A3
CS0
CS
A2
PIU290A2 GND ISL12020MIRZ
RFU
A5
PIU290A5
NLDQ0 RFU
DQ0 D3 PIU290D3 C2
PIU290C2
I2C addr: 0x6F for RTC
NLDQ1 DQ0 RFU
DQ1 D2 PIU290D2 B5
PIU290B5
NLDQ2 DQ1 RFU
DQ2 C4 PIU290C4 C5
PIU290C5
I2C addr: 0x57 for SRAM
NLDQ3 DQ2 RFU
DQ3 D4 PIU290D4 3.3V
DQ3
NLDQ4
DQ4 D5 PIU290D5 B3
PIU290B3
Title:
NLDQ5 DQ4 VSS PIC2501 PIC2601
DQ5 E3 PIU290E3 A1
PIU290A1 MEGA65
NLDQ6 DQ5 NC/VSS COC25
C25 COC26
C26
DQ6 E2 PIU290E2 C1
PIU290C1
D NLDQ7 DQ6 VSSQ D
DQ7 E1 PIU290E1 E5
PIU290E5
PIC2502 470nF PIC2602 470nF Number: Rev.
DQ7 VSSQ TE0765
A4 03
IS66WVH8M8BLL-100B1LI GND GND [No Variations]
GND
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 7 of 23

Filename: B16.SchDoc
1 2 3 4
1 2 3 4

3.3V
3.3V 1
PIC120COC12 PIC15901COC159 PIC16 01 PIC16701 PIC16801 PIC16901 PIC160 1COC160 PIC16 COC161
C12 C159 C160 01C161
COC166
C166 COC167
C167 COC168
C168 COC169
C169
2
PIC1204.7µF PIC159024.7µF PIC16 02 470nF PIC16702 470nF P IC16 802 470nF PI C16 902 470nF PIC160 24.7µF PIC16 024.7µF
B35
A A
GND GND i
COU1E
COU1F
U1E U1F
BANK 34 BANK 35
R5 PIU10R5 AA5 NLHDMI0TX20P
HDMI_TX2_P J5 NLB350L100P
B35_L10_P
3.3V VCCO_34 IO_L10P_T1_34 PIU10AA5 3.3V
C1 PIU10C1
VCCO_35 IO_L10P_T1_AD15P_35 PIU10J5
T2 PIU10T2 AB5
PIU10AB5
NLHDMI0TX20N
HDMI_TX2_N F2 PIU10F2 H5
PIU10H5
NLB350L100N
B35_L10_N
VCCO_34 IO_L10N_T1_34 VCCO_35 IO_L10N_T1_AD15N_35 NLSD0D1
V6 PIU10V6 Y4
PIU10Y4
H6 PIU10H6 H3
PIU10H3
SD_D1
VCCO_34 IO_L11P_T1_SRCC_34 VCCO_35 IO_L11P_T1_SRCC_35
W3 PIU10W3 AA4
PIU10AA4 J3 PIU10J3 G3
PIU10G3
VCCO_34 IO_L11N_T1_SRCC_34 VCCO_35 IO_L11N_T1_SRCC_35 NLB350L120P
AA7 PIU10AA7 V4
PIU10V4 M4 PIU10M4 H4
PIU10H4 B35_L12_P
VCCO_34 IO_L12P_T1_MRCC_34 VCCO_35 IO_L12P_T1_MRCC_35 NLB350L120N
AB4 PIU10AB4 W4
PIU10W4 N1 PIU10N1 G4
PIU10G4 B35_L12_N
VCCO_34 IO_L12N_T1_MRCC_34 VCCO_35 IO_L12N_T1_MRCC_35 NLETH0CRS0DV
R4
PIU10R4 K4
PIU10K4 ETH_CRS_DV
IO_L13P_T2_MRCC_34 IO_L13P_T2_MRCC_35 NLETH0TX0EN
T4
PIU10T4
J4
PIU10J4
ETH_TX_EN
IO_L13N_T2_MRCC_34 NLPWM0R IO_L13N_T2_MRCC_35 NLETH0TX0D0
T3 PIU10T3 T5
PIU10T5 PWM_R F4 PIU10F4 L3
PIU10L3 ETH_TX_D0
IO_0_34 IO_L14P_T2_SRCC_34 IO_0_35 IO_L14P_T2_SRCC_35 NLETH0TX0D1
U5
PIU10U5 K3
PIU10K3 ETH_TX_D1
IO_L14N_T2_SRCC_34 NLPWM0L IO_L14N_T2_SRCC_35 NLF0SIDE1
U7 PIU10U7 W6
PIU10W6 PWM_L L6 PIU10L6 M1
PIU10M1 F_SIDE1
IO_25_34 IO_L15P_T2_DQS_34 IO_25_35 IO_L15P_T2_DQS_35 NLETH0RX0D1
W5
PIU10W5
L1
PIU10L1
ETH_RX_D1
IO_L15N_T2_DQS_34 NLB350L10P IO_L15N_T2_DQS_35 NLF0STEP
T1 PIU10T1 U6
PIU10U6 B35_L1_P B1 PIU10B1 M3
PIU10M3
F_STEP
IO_L1P_T0_34 IO_L16P_T2_34 NLB350L10N IO_L1P_T0_AD4P_35 IO_L16P_T2_35 NLF0INDEX
U1 PIU10U1 V5
PIU10V5 B35_L1_N A1 PIU10A1 M2
PIU10M2 F_INDEX
IO_L1N_T0_34 IO_L16N_T2_34 NLB350L20P IO_L1N_T0_AD4N_35 IO_L16N_T2_35 NLETH0RST
U2 PIU10U2 R6
PIU10R6 B35_L2_P C2 PIU10C2 K6
PIU10K6 ETH-RST
B IO_L2P_T0_34 IO_L17P_T2_34 NLB350L20N IO_L2P_T0_AD12P_35 IO_L17P_T2_35 NLETH0MDC B
V2 PIU10V2 T6
PIU10T6 B35_L2_N B2 PIU10B2 J6
PIU10J6 ETH_MDC
IO_L2N_T0_34 IO_L17N_T2_34 NLB350L30P IO_L2N_T0_AD12N_35 IO_L17N_T2_35 NLETH0MDIO
R3 PIU10R3 Y6
PIU10Y6
B35_L3_P E1 PIU10E1 L5
PIU10L5
ETH_MDIO
IO_L3P_T0_DQS_34 IO_L18P_T2_34 NLB350L30N IO_L3P_T0_DQS_AD5P_35 IO_L18P_T2_35 NLETH0CLK
R2 PIU10R2 AA6
PIU10AA6 B35_L3_N D1 PIU10D1 L4
PIU10L4
ETH_CLK
IO_L3N_T0_DQS_34 IO_L18N_T2_34 NLB350L40P IO_L3N_T0_DQS_AD5N_35 IO_L18N_T2_35 NLF0WDATE
W2 PIU10W2 V7
PIU10V7 B35_L4_P E2 PIU10E2 N4
PIU10N4 F_WDATE
IO_L4P_T0_34 IO_L19P_T3_34 NLB350L40N IO_L4P_T0_35 IO_L19P_T3_35 NLF0WGATE
Y2 PIU10Y2 W7
PIU10W7 B35_L4_N D2 PIU10D2 N3
PIU10N3 F_WGATE
NLHDMI0TXC0P IO_L4N_T0_34 IO_L19N_T3_VREF_34 NLSCL0A NLB350L50P IO_L4N_T0_35 IO_L19N_T3_VREF_35 NLF0DSCKCHG
HDMI_TXC_P W1 PIU10W1 AB7
PIU10AB7 SCL_A B35_L5_P G1 PIU10G1 R1
PIU10R1 F_DSCKCHG
NLHDMI0TXC0N IO_L5P_T0_34 IO_L20P_T3_34 NLB350L50N IO_L5P_T0_AD13P_35 IO_L20P_T3_35 NLF0RDATA1
HDMI_TXC_N Y1 PIU10Y1 AB6
PIU10AB6
B35_L5_N F1 PIU10F1 P1
PIU10P1
F_RDATA1
IO_L5N_T0_34 IO_L20N_T3_34 NLSDA0A NLB350L60P
IO_L5N_T0_AD13N_35 IO_L20N_T3_35 NLF0DIR
U3 PIU10U3 V9
PIU10V9 SDA_A B35_L6_P F3 PIU10F3 P5
PIU10P5
F_DIR
IO_L6P_T0_34 IO_L21P_T3_DQS_34 NLB350L60N IO_L6P_T0_35 IO_L21P_T3_DQS_35 NLETH0RX0D0
V3 PIU10V3 V8
PIU10V8 B35_L6_N E3 PIU10E3 P4
PIU10P4 ETH_RX_D0
NLHDMI0TX00P IO_L6N_T0_VREF_34 IO_L21N_T3_DQS_34 NLSD0CD IO_L6N_T0_VREF_35 IO_L21N_T3_DQS_35 NLF0WPT
HDMI_TX0_P AA1 PIU10AA1 AA8
PIU10AA8 SD_CD K1 PIU10K1 P2
PIU10P2 F_WPT
IO_L7P_T1_34 IO_L22P_T3_34 NLSD0D2 IO_L7P_T1_AD6P_35 IO_L22P_T3_35 NLF0TRCK0
NLHDMI0TX00N
HDMI_TX0_N AB1 PIU10AB1 AB8
PIU10AB8
NLLS0OE
LS_OE SD_D2 J1 PIU10J1 N2
PIU10N2 F_TRCK0
NLHDMI0TX10P IO_L7N_T1_34 IO_L22N_T3_34 NLHPD0A NLSD0D0 IO_L7N_T1_AD6N_35 IO_L22N_T3_35 NLETH0RXER
HDMI_TX1_P AB3 PIU10AB3 Y8
PIU10Y8
HPD_A SD_D0 H2 PIU10H2 M6
PIU10M6
ETH_RXER
NLHDMI0TX10N IO_L8P_T1_34 IO_L23P_T3_34 NLSD0CLK IO_L8P_T1_AD14P_35 IO_L23P_T3_35 NLF0MOTEA
HDMI_TX1_N AB2 PIU10AB2 Y7
PIU10Y7
SD_CLK G2 PIU10G2 M5
PIU10M5
F_MOTEA
IO_L8N_T1_34 IO_L23N_T3_34 NLCEC0A NLSD0D3 IO_L8N_T1_AD14N_35 IO_L23N_T3_35 NLF0REDWC
Y3 PIU10Y3 W9
PIU10W9 CEC_A SD_D3 K2 PIU10K2 P6
PIU10P6
F_REDWC
IO_L9P_T1_DQS_34 IO_L24P_T3_34 NLSD0CMD IO_L9P_T1_DQS_AD7P_35 IO_L24P_T3_35 NLF0DRVSA
AA3 PIU10AA3 Y9
PIU10Y9
SD_CMD J2 PIU10J2 N5
PIU10N5
F_DRVSA
IO_L9N_T1_DQS_34 IO_L24N_T3_34 IO_L9N_T1_DQS_AD7N_35 IO_L24N_T3_35
XC7A200T-2FBG484C XC7A200T-2FBG484C
i i i
B34 B34 B35
C C

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 8 of 23

Filename: B34.SchDoc
1 2 3 4
1 2 3 4

3.3V

COU1G
U1G
BANK0
COC170
C170F12 PIU10F12 K10
PIU10K10
A VCCO_0 VCCADC_0 AVCC A
GND PIC17001 PIC17002
T12 PIU10T12
VCCO_0
M10
PIU10M10
4.7µF VREFP_0 AGND
E12 PIU10E12 L9
PIU10L9
GND VCCBATT_0 VREFN_0 AGND
NLSPI0SCK
SPI-SCK L12 L10 NLV0P
V_P PIC12 01
PIU10L12 CCLK_0 VP_0 PIU10L10
M9 NLV0N
V_N COC122
C122
VN_0 PIU10M9
3.3V
U11 PIU10U11
M0_0
PIC12 02 10nF
3.3V BOOTMODE = MASTER SPI U10 PIU10U10 N10
PIU10N10
16V
M1_0 DXP_0 X7R
CFG U9 PIU10U9 N9
PIU10N9
GND M2_0 DXN_0
PIR6801 1%
COR3
R3 i
COR68
R68 NLFPGA0DONE K9
PIR301 PIR302 FPGA_DONEG11 PIU10G11
DONE_0 GNDADC_0 PIU10K9 AGND
4K873.3V
1K
FPGA_PROG_B PIR6802 1% NLFPGA0PROG0B
FPGA_PROG_B
N12 PIU10N12
PROGRAM_B_0
i U8 PIU10U8
3.3V CFGBVS_0 COL3
L3
CFG PIL302 PIL301
NLFPGA0TDI 1.8V AVCC
FPGA_TDI R13 PIU10R13
NLFPGA0TDO TDI_0 BKP0603HS121-T
FPGA_TDO U13 PIU10U13
FPGA_JTAGi NLFPGA0TCK TDO_0
B
FPGA_TCK V12 PIU10V12
TCK_0
301
2C23
PICCOC23 B
NLFPGA0TMS
FPGA_TMS T13 PIU10T13 TMS_0
COR8
R8
302
PIC2470nF
PIR802 PIR801
NLFPGA0INIT
FPGA_INIT U12 PIU10U12 COL2
3.3V INIT_B_0 L2
4K87 GND PIL202 PIL201
i XC7A200T-2FBG484C
1% BKP0603HS121-T
CFG AGND

SPIFLASH
i
3.3V COC14
C14
COU5A
COU5B
U5A PIC1401 PIC1402
COR7
R7 NLSPI0CS GND
PIR702 PIR701
SPI-CS C2 PIU50C2 B4
PIU50B4
3.3V CS VCC 100nF
4K87 SPI-SCK B2 PIU50B2
NLSPI0DQO CLK NLSPI0DQ1
COR1
1% SPI-DQO D3 PIU50D3 D2
PIU50D2 SPI-DQ1
R1 NLSPI0DQ3 DI/IO0
DO/IO1 i SPIFLASH
PIR102 PIR101 SPI-DQ3 D4 PIU50D4
3.3V HOLD/RESET/IO3
4K87 NLSPI0DQ2
SPI-DQ2 C4 PIU50C4 B3
PIU50B3
WP/IO2GND GND
1%
S25FL256SAGBHI20
C C
U5B
A2 PIU50A2
NC
A3 PIU50A3 3.3V 3.3V
NC COS2
A4 PIU50A4 S2
NC NLRESET
A5 PIU50A5 PIR14502 PIR14802 RESET
NC COR145
R145 COR148
R148
B1 PIU50B1 1 PIS201
NC 4K87 4K87 PIV102
B5 PIU50B5 2 PIS202
NC COR134
R134 NLCPLD0JTAGEN
C1 PIU50C1 3
PIS203 PIR13401 PIR13402 PIR14501 1% PIR14801 1% PIV101COV1 CPLD_JTAGEN
NC
C3 PIU50C3
NC 49R9 PIC7501
C5 PIU50C5 4 COC75
C75 PIT603
NC PIS204
D1 PIU50D1 5 PIS205 10nF
PIC7502 COT6
T6
NC 16V 2N7002,215
D5 PIU50D5 6
PIS206
NC
E1 PIU50E1 GND X7R PIT601
NC
E2 PIU50E2 SPUJ191500 PIJ20 2
NC COJ20
J20
E3 PIU50E3 GND
NC PIT602
E4 PIU50E4 Title:
NC PIJ20 1
E5 PIU50E5 JUMPER2.54-2 MEGA65
NC
D D
S25FL256SAGBHI20 GND GND Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 9 of 23

Filename: FPGA-CFG.SchDoc
1 2 3 4
1 2 3 4

A A

COU1H
U1H
D6 PIU10D6 B5
PIU10B5
GND MGTAVCC MGTAVTT GND
D10 PIU10D10 B7
PIU10B7
MGTAVCC MGTAVTT
E8 PIU10E8 B9
PIU10B9
MGTAVCC MGTAVTT
F7 PIU10F7 B11
PIU10B11
MGTAVCC MGTAVTT
F9 PIU10F9 C4
PIU10C4
MGTAVCC MGTAVTT
C8
PIU10C8
MGTAVTT
B B
F6 PIU10F6 F8
PIU10F8
MGTREFCLK0P_216MGTRREF_216 GND
E6 PIU10E6
MGTREFCLK0N_216
F10 PIU10F10
MGTREFCLK1P_216
E10 PIU10E10
MGTREFCLK1N_216
B8 PIU10B8 B4
PIU10B4
MGTPRXP0_216 MGTPTXP0_216
A8 PIU10A8 A4
PIU10A4
MGTPRXN0_216 MGTPTXN0_216
D11 PIU10D11 D5
PIU10D5
MGTPRXP1_216 MGTPTXP1_216
C11 PIU10C11 C5
PIU10C5
MGTPRXN1_216 MGTPTXN1_216
B10 PIU10B10 B6
PIU10B6
MGTPRXP2_216 MGTPTXP2_216
A10 PIU10A10 A6
PIU10A6
MGTPRXN2_216 MGTPTXN2_216
D9 PIU10D9 D7
PIU10D7
MGTPRXP3_216 MGTPTXP3_216
C9 PIU10C9 C7
PIU10C7
GND MGTPRXN3_216 MGTPTXN3_216
XC7A200T-2FBG484C

C C

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 10 of 23

Filename: FPGA-MGT.SchDoc
1 2 3 4
1 2 3 4

1V VCCINT CAPS

PIC901 PIC10 1 PIC1 01 PIC20 1 PIC2401 PIC4201 PIC4301 PIC4901 PIC5601 PIC140 1 PIC14 01 PIC14201 PIC14301
COC9
C9 COC10
C10 COC11
C11 COC20
C20 COC24
C24 COC42
C42 COC43
C43 COC49
C49 COC56
C56 COC140
C140 COC141
C141 COC142
C142 COC143
C143
PIC902 470nF PIC10 2 470nF PIC1 02 470nF PIC20 2 470nFPIC2402 470nF PIC4202 470nF PIC4302 470nF PIC4902 470nF PIC5602 470nF PIC140 2 470nF PIC14 02 470nF PIC1420 470nF PIC14302 470nF
GND
A A
1V
U1J
PIC690COC69
1C69 PIC70 COC70
1C70 PIC710COC71
1C71 PIC7401COC74
C74 PIC4 0COC44
1C44 PIC760COC76
1C76 A2 PIU10A2 H7
PIU10H7
GND GND
A3 PIU10A3 H9
PIU10H9
PIC69024.7µF PIC70 24.7µF PIC71024.7µF PIC74024.7µF PIC4 024.7µF PIC76024.7µF GND GND
A5 PIU10A5 H11
PIU10H11
GND GND
A7 PIU10A7
H21
PIU10H21
GND GND
GND A9 PIU10A9 J8
PIU10J8
GND GND
A11 PIU10A11 J10
PIU10J10
COU1I
COU1J GND GND
1V U1I A12 PIU10A12 J12
PIU10J12
GND GND
H10 PIU10H10 H12
PIU10H12 A22 PIU10A22 J18
PIU10J18
PIC147COC147 2 1V VCCINT VCCAUX 1.8V GND GND
02C147 PIC1480COC148
2C148 PIC1490COC149
C149 H8 PIU10H8 K12
PIU10K12
AA2 PIU10AA2
K5
PIU10K5
VCCINT VCCAUX GND GND
J7 PIU10J7 M12
PIU10M12 AA12 PIU10AA12 K7
PIU10K7
VCCINT VCCAUX GND GND
1
PIC14701100µF PIC14801100µF PIC1490100µF J9 PIU10J9 P12
PIU10P12 AA22 PIU10AA22 K11
PIU10K11
VCCINT VCCAUX GND GND
K8 PIU10K8 R11
PIU10R11 AB9 PIU10AB9 K15
PIU10K15
VCCINT VCCAUX GND GND
GND L7 PIU10L7 AB19 PIU10AB19
L2
PIU10L2
VCCINT GND GND
M8 PIU10M8 B3 PIU10B3
L8
PIU10L8
VCCINT GND GND
1V VCCBRAM CAPS N7 PIU10N7 B12 PIU10B12 L22
PIU10L22
VCCINT GND GND
P8 PIU10P8 B19 PIU10B19 M7
PIU10M7
B VCCINT GND GND B
PIC150 1 PIC15101 PIC15201 P10 PIU10P10
VCCINT
C3 PIU10C3 GND GND
M11
PIU10M11
COC150
C150 COC151
C151 COC152
C152 R7 PIU10R7 C6 M19
VCCINT PIU10C6 GND GND PIU10M19
PIC150 2 470nF PIC15102 470nF PIC15202 470nF R9 PIU10R9
VCCINT VCCBRAM
J11
PIU10J11 1V
C10 PIU10C10 GND GND
N6
PIU10N6
T10 PIU10T10 L11
PIU10L11 C12 PIU10C12 N8
PIU10N8
VCCINT VCCBRAM GND GND
GND T8 PIU10T8 N11
PIU10N11 C16 PIU10C16 N16
PIU10N16
VCCINT VCCBRAM GND GND
D3 PIU10D3 P3
PIU10P3
GND GND
XC7A200T-2FBG484C D4 PIU10D4
P7
PIU10P7
GND GND
1.8V VCCAUX CAPS D8 PIU10D8
P9
PIU10P9
GND GND
D12 PIU10D12 P11
PIU10P11
GND GND
PIC15301 PIC15401 PIC15 01 PIC15601 PIC15701 PIC460COC46
1C46 PIC470COC47
1C47 PIC480COC48
1C48 PIC15801 D13 PIU10D13 P13
PIU10P13
COC153
C153 COC154
C154 COC155
C155 COC156
C156 COC157
C157 COC158
C158 GND GND
E4 PIU10E4 R8
PIU10R8
PIC15302 470nF PIC15402 470nF PIC15 02 470nF PIC15602 470nF PIC15702 470nF PIC46024.7µF PIC47024.7µF PIC48024.7µF PIC15802 47µF GND GND
E5 PIU10E5
R10
PIU10R10
GND GND
E7 PIU10E7
R12
PIU10R12
GND GND
GND E9 PIU10E9
R20
PIU10R20
GND GND
E11 PIU10E11
T7
PIU10T7
GND GND
F5 PIU10F5 T9
PIU10T9
GND GND
F11 PIU10F11
T11
PIU10T11
GND GND
F17 PIU10F17
T17
PIU10T17
GND GND
E20 PIU10E20 U4
PIU10U4
C GND GND C
G5 PIU10G5 U14
PIU10U14
GND GND
G6 PIU10G6 V1
PIU10V1
GND GND
G7 PIU10G7
V11
PIU10V11
GND GND
G8 PIU10G8
V21
PIU10V21
GND GND
G9 PIU10G9
W8
PIU10W8
GND GND
G10 PIU10G10
W18
PIU10W18
GND GND
G12 PIU10G12 Y5
PIU10Y5
GND GND
G14 PIU10G14
Y15
PIU10Y15
GND GND
H1 PIU10H1 GND
GND XC7A200T-2FBG484C GND

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 11 of 23

Filename: FPGA-PWR.SchDoc
1 2 3 4
1 2 3 4
Bank8
COL10
L10 i
PIC16501
COC165
PIC16502C165
NL303V0REF
3.3V_REF PIL1001 PIL1002 3.3V U32C 3.3V U32F
3.3V
4.7µF MPZ1608S221A BANK 3 BANK 8
L8 PIU320L8 L4
PIU320L4 C8 PIU320C8 C10
PIU320C10
VCCIO3 IO_3/DIFFIO_TX_RX_B1P VCCIO8 IO_8/DIFFIO_RX_T14P
COC202
C202 L7 PIU320L7
VCCIO3 IO_3/DIFFIO_TX_RX_B1N
L5
PIU320L5
C7 PIU320C7 VCCIO8 IO_8/DIFFIO_RX_T14N
C9
PIU320C9
PIC20201 PIC20202
COU32A
COU32B
COU32C
COU32D
COU32E
COU32F
COU32G
U32A L6 PIU320L6 M5
PIU320M5
NLCPLD0DBG10
CPLD_DBG10 C6 PIU320C6 A8
PIU320A8
NLCPLD0ADC1 PIC24 01 VCCIO3 IO_3/DIFFIO_RX_B2P PIC24501 VCCIO8 IO_8/DIFFIO_RX_T15P
D3 PIU320D3 D2
PIU320D2 CPLD_ADC1 M4
PIU320M4 A9
PIU320A9
470nF ADC_VREF ANAIN1 COC244
C244 IO_3/DIFFIO_RX_B2N NLFPGA0TCK COC245
C245 IO_8/DIFFIO_RX_T15N
E2 PIU320E2 J5
PIU320J5 FPGA_TCK B10
PIU320B10
A REFGND 470nF
PIC24 02 IO_3/DIFFIO_TX_RX_B3P PIC24502 470nF IO_8/DIFFIO_RX_T16P A
K5
PIU320K5 B9
PIU320B9
IO_3/DIFFIO_TX_RX_B3N NLCPLD0DBG11 IO_8/DEV_CLRN/DIFFIO_RX_T16N
GND 3.3V BANK 1A N11 PIU320N11 N5
PIU320N5
CPLD_DBG11 B7 PIU320B7 A10
PIU320A10
NLCPLD0ADC2 VREFB3N0 IO_3/DIFFIO_RX_B4P VREFB8N0 IO_8/DIFFIO_RX_T17P NLCPLD0CFG2
F2 PIU320F2 C2
PIU320C2 CPLD_ADC2 GND N4
PIU320N4 GND A11
PIU320A11 CPLD_CFG2
VCCIO1A
IO_1A/ADC1IN2/DIFFIO_RX_L1P NLCPLD0ADC3 IO_3/DIFFIO_RX_B4N NLCPLD0DBG9 IO_8/DIFFIO_RX_T17N
D1
PIU320D1 CPLD_ADC3 M7
PIU320M7 CPLD_DBG9 D8
PIU320D8
PIC24601 IO_1A/ADC1IN1/DIFFIO_RX_L1N IO_3/DIFFIO_TX_RX_B5P NLCPLD0DBG8 IO_8/DEV_OE/DIFFIO_RX_T18P
E4
PIU320E4 N6
PIU320N6 CPLD_DBG8 E8
PIU320E8
COC246
C246 IO_1A/ADC1IN4/DIFFIO_RX_L3P IO_3/DIFFIO_TX_RX_B5N NLCPLD0DBG5 IO_8/DIFFIO_RX_T18N
E3
PIU320E3 N8
PIU320N8 CPLD_DBG5 D7 PIU320D7 A7
PIU320A7
PIC24602 470nF IO_1A/ADC1IN3/DIFFIO_RX_L3N IO_3/DIFFIO_RX_B6P NLCPLD0DBG7 GND IO_8/CONFIG_SEL IO_8/DIFFIO_RX_T19P
B1
PIU320B1
N7
PIU320N7
CPLD_DBG7 A6
PIU320A6
IO_1A/ADC1IN6/DIFFIO_RX_L5P IO_3/DIFFIO_RX_B6N NLFPGA0INIT IO_8/DIFFIO_RX_T19N
C1
PIU320C1 K6
PIU320K6 FPGA_INIT E7 PIU320E7 B6
PIU320B6
IO_1A/ADC1IN5/DIFFIO_RX_L5N IO_3/DIFFIO_TX_RX_B7P NLFPGA0DONE I_8/NCONFIG IO_8/DIFFIO_RX_T20P NLTE0TCK
GND E1
PIU320E1 J6
PIU320J6 FPGA_DONE B5
PIU320B5 TE_TCK
IO_1A/ADC1IN8/DIFFIO_RX_L7P IO_3/DIFFIO_TX_RX_B7N NLCPLD0DBG4 IO_8/DIFFIO_RX_T20N NLTE0TDO
F1
PIU320F1 M9
PIU320M9 CPLD_DBG4 A4
PIU320A4 TE_TDO
IO_1A/ADC1IN7/DIFFIO_RX_L7N i Bank1 IO_3/DIFFIO_RX_B8P NLCPLD0DBG6 IO_8/DIFFIO_RX_T21P NLTE0TDI
M8
PIU320M8 CPLD_DBG6 A3
PIU320A3 TE_TDI
IO_3/DIFFIO_RX_B8N NLFPGA0TDO IO_8/DIFFIO_RX_T21N
3.3V BANK 1B K7
PIU320K7 FPGA_TDO E6
PIU320E6
NLCPLD0JTAGEN IO_3/DIFFIO_TX_RX_B9P NLFPGA0TDI IO_8/DIFFIO_RX_T22P
G3 PIU320G3 E5
PIU320E5 CPLD_JTAGEN J7
PIU320J7 FPGA_TDI D6
PIU320D6
VCCIO1B IO_1B/JTAGEN NLM0TCK IO_3/DIFFIO_TX_RX_B9N NLK0TCK IO_8/CRC_ERROR/DIFFIO_RX_T22N NLTE0TMS
G2
PIU320G2 M_TCK M12
PIU320M12 K_TCK NLM10nCONF B3
PIU320B3 TE_TMS
IO_1B/TCK/DIFFIO_RX_L11P NLM0TMS IO_3/DIFFIO_TX_RX_B10P NLK0TDI IO_8/DIFFIO_RX_T23P NLTE0UART0TX
TE_UART_TX

M10_nCONF
PIC24701 H1 PIU320H1 G1
PIU320G1 M_TMS M13
PIU320M13 K_TDI B4
PIU320B4
COC247
C247 VREFB1N0 IO_1B/TMS/DIFFIO_RX_L11N NLM0TDO IO_3/DIFFIO_TX_RX_B10N NLCPLD0DBG3 IO_8/DIFFIO_RX_T23N NLM100nSTATUS
F6
PIU320F6
M_TDO N9
PIU320N9
CPLD_DBG3 C4
PIU320C4
M10_nSTATUS
PIC24702 470nF IO_1B/TDO/DIFFIO_RX_L12P NLM0TDI IO_3/DIFFIO_RX_B11P NLCPLD0DBG1 IO_8/NSTATUS/DIFFIO_RX_T24P NLM100CONF0DONE
F5
PIU320F5 M_TDI N10
PIU320N10
CPLD_DBG1 C5
PIU320C5
M10_CONF_DONE
IO_1B/TDI/DIFFIO_RX_L12N IO_3/DIFFIO_RX_B11N NLFPGA0RX IO_8/CONF_DONE/DIFFIO_RX_T24N NLM0TX
G4
PIU320G4 L11
PIU320L11 FPGA_RX A2
PIU320A2 M_TX
IO_1B/DIFFIO_RX_L14P IO_3/DIFFIO_TX_RX_B12P NLK0JTAGEN IO_8/DIFFIO_RX_T26P NLM0RX
GND F4
PIU320F4 M11
PIU320M11 K_JTAGEN B2
PIU320B2 M_RX
B IO_1B/DIFFIO_RX_L14N IO_3/DIFFIO_TX_RX_B12N NLFPGA0TMS IO_8/DIFFIO_RX_T26N NLTE0UART0RX B
H3
PIU320H3 K8
PIU320K8 FPGA_TMS A5
PIU320A5 TE_UART_RX
IO_1B/DIFFIO_RX_L16P IO_3/DIFFIO_TX_RX_B14P i Bank3 IO_8
H2
PIU320H2
J8
PIU320J8
IO_1B/DIFFIO_RX_L16N IO_3/DIFFIO_TX_RX_B14N NLCPLD0DBG0
L10
PIU320L10
CPLD_DBG0 10M08SAU169C8G
IO_3/DIFFIO_TX_RX_B16P NLCPLD0DBG2
10M08SAU169C8G M10
PIU320M10 CPLD_DBG2 3.3V U32G
IO_3/DIFFIO_TX_RX_B16N NLK0TMS
Bank2 N12
PIU320N12 K_TMS H7 PIU320H7 A1
PIU320A1
IO_3 VCC_ONE GND
U32B i PIC24801 G8 PIU320G8
VCC_ONE GND
A13
PIU320A13
3.3V 10M08SAU169C8G COC248
C248 G6 B8
BANK 2 VCC_ONE GND PIU320B8
K3 PIU320K3 H6
PIU320H6
NLCPLD0CLK
CPLD_CLK U32E PIC24802 470nF F7 PIU320G6
PIU320F7
C3
PIU320C3
VCCIO2 IO_2/CLK0P/DIFFIO_RX_L18P i Bank6 VCC_ONE GND
J3 PIU320J3 G5
PIU320G5 3.3V D5
PIU320D5
VCCIO2 IO_2/CLK0N/DIFFIO_RX_L18N BANK 6 NLKB0IO2 GND
PIC24901 J2
PIU320J2 G11 PIU320G11 G9
PIU320G9 KB_IO2 GND K4 PIU320K4 E11
PIU320E11
COC249
C249 IO_2/DIFFIO_RX_L19P VCCIO6 IO_6/CLK2P/DIFFIO_RX_R14P i KB VCCA1 GND
J1
PIU320J1 F11 G10
PIU320G10
NLKB0TCK
KB_TCK D10 PIU320D10 F3
PIU320F3
PIC24902 470nF IO_2/DIFFIO_RX_L19N PIC250 1 PIU320F11 VCCIO6 IO_6/CLK2N/DIFFIO_RX_R14N NLKB0IO3 i KB VCCA2 GND
H4
PIU320H4
F13
PIU320F13
KB_IO3 D4 PIU320D4 G7
PIU320G7
IO_2/CLK1P/DIFFIO_RX_L20P COC250
C250 IO_6/CLK3P/DIFFIO_RX_R16P i KB VCCA3 GND
L1 PIU320L1 H5
PIU320H5
E13
PIU320E13
K9 PIU320K9 H12
PIU320H12
VREFB2N0IO_2/CLK1N/DIFFIO_RX_L20N IO_6/CLK3N/DIFFIO_RX_R16N NLKB0TMS 3.3V VCCA4 GND
GND M2
PIU320M2 PIC250 2 470nF F12
PIU320F12 KB_TMS PIC17301 J4
PIU320J4
IO_2/DIFFIO_RX_L21P IO_6/DIFFIO_RX_R18P i KB COC173
C173 GND
M1
PIU320M1
D13 PIU320D13 E12
PIU320E12
L9
PIU320L9
IO_2/DIFFIO_RX_L21N VREFB6N0 IO_6/DIFFIO_RX_R18N NLKB0JTAGEN GND
IO_2/DPCLK1/DIFFIO_RX_L22P
N3
PIU320N3 GND
IO_6/DPCLK3/DIFFIO_RX_R26P
F9
PIU320F9 KB_JTAGEN
i KB
PIC17302 470nF GND
M6
PIU320M6
N2
PIU320N2
NLVDAC0PSAVE0N
VDAC_PSAVE_N F10
PIU320F10
NLKB0TDO
KB_TDO N1
PIU320N1
IO_2/DPCLK0/DIFFIO_RX_L22N IO_6/DPCLK2/DIFFIO_RX_R26N i KB GND
L3
PIU320L3
F8
PIU320F8
GND N13
PIU320N13
IO_2/PLL_L_CLKOUTP/DIFFIO_RX_L27P IO_6/DIFFIO_RX_R27P NLKB0IO1 COJ21 GND
M3
PIU320M3 E9
PIU320E9 KB_IO1 J21
C IO_2/PLL_L_CLKOUTN/DIFFIO_RX_L27N IO_6/DIFFIO_RX_R27N i KB C
K2
PIU320K2 B12
PIU320B12 LED_R CPLD_DBG01 PIJ2101 10M08SAU169C8G GND
IO_2/DIFFIO_RX_L28P IO_6/DIFFIO_RX_R28P NLCPLD0CFG3
K1
PIU320K1 B11
PIU320B11 CPLD_CFG3 CPLD_DBG12 PIJ2102
IO_2/DIFFIO_RX_L28N IO_6/DIFFIO_RX_R28N NLPMOD20EN
L2
PIU320L2
C12
PIU320C12
PMOD2_EN CPLD_DBG23 PIJ2103
IO_2 IO_6/DIFFIO_RX_R29P NLCPLD0CFG1
C11
PIU320C11
CPLD_CFG1 CPLD_DBG34 PIJ2104
IO_6/DIFFIO_RX_R29N COR28
R28
10M08SAU169C8G B13
PIU320B13
LED_G CPLD_DBG45 PIJ2105 M10_nCONF PIR2801 PIR2802
IO_6/DIFFIO_RX_R30P NLCPLD0CFG0
A12
PIU320A12
CPLD_CFG0 CPLD_DBG56 PIJ2106 10K
IO_6/DIFFIO_RX_R30N
U32D E10
PIU320E10 CPLD_DBG67 PIJ2107
3.3V
i Bank5 IO_6/DIFFIO_RX_R31P NLKB0TDI COR29
BANK 5 D9
PIU320D9
KB_TDI CPLD_DBG78 PIJ2108 M10_CONF_DONE PIR2901R29 PIR2902
NLDBG0UART0TX IO_6/DIFFIO_RX_R31N NLPMOD10FLG i KB
J11 PIU320J11 K10
PIU320K10
DBG_UART_TX D12
PIU320D12
PMOD1_FLG CPLD_DBG89 PIJ2109 10K
VCCIO5 IO_5/DIFFIO_RX_R1P NLDBG0UART0RX IO_6/DIFFIO_RX_R33P NLPMOD10EN
H11 PIU320H11 J10
PIU320J10
DBG_UART_RX D11
PIU320D11
PMOD1_EN CPLD_DBG9
10 PIJ21010
VCCIO5 IO_5/DIFFIO_RX_R1N NLFPGA0TX IO_6/DIFFIO_RX_R33N NLPMOD20FLG COR30
R30
PIC25 01 K11
PIU320K11 FPGA_TX C13
PIU320C13 PMOD2_FLG CPLD_DBG10
11 PIJ21011 M10_nSTATUS PIR3001 PIR3002
COC252
C252 IO_5/DIFFIO_RX_R2P IO_6 3.3V
L12
PIU320L12
NLK0TDO
K_TDO 10M08SAU169C8G CPLD_DBG11
12 PIJ21012 10K
PIC25 02 470nF IO_5/DIFFIO_RX_R2N NLK0IO2
K12
PIU320K12
K_IO2 13 PIJ21013
IO_5/DIFFIO_RX_R7P NLK0IO3
K13 PIU320K13 J12
PIU320J12
K_IO3 14 PIJ21014
VREFB5N0 IO_5/DIFFIO_RX_R7N NLFPGA0RESET0N COD10
D10
GND J9
PIU320J9
FPGA_RESET_N
IO_5/DIFFIO_RX_R8P COR70
R70 NLLED0G
H10
PIU320H10 PID100A PID100K PIR7001 PIR7002
LED_G GND Pin Header 2.54 2Row 14Pins
IO_5/DIFFIO_RX_R8N 3.3V
J13
PIU320J13
NLRESET
RESET 240R Title:
IO_5/DIFFIO_RX_R9P NLEN05V0JOY0N
H13
PIU320H13
EN_5V_JOY_N LED Green LTST-C191KGKT1% MEGA65
IO_5/DIFFIO_RX_R9N
H9
PIU320H9
D IO_5/DIFFIO_RX_R10P COD12
D12 D
H8
PIU320H8
Number: Rev.
IO_5/DIFFIO_RX_R10N NL5V0JOY0PG COR130
R130 NLLED0R TE0765
G13
PIU320G13 5V_JOY_PG PID120A PID120K PIR13001 PIR13002 LED_R A4 03
IO_5/DIFFIO_RX_R11P 3.3V [No Variations]
G12
PIU320G12
NLFPGA0PROG0B
FPGA_PROG_B 240R
IO_5/DIFFIO_RX_R11N NLK0IO1
L13
PIU320L13
K_IO1 LED Red LTST-C191KRKT
1%
IO_5 Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 12 of 23
10M08SAU169C8G
Filename: SYS_MAX10_CTRL.SchDoc
1 2 3 4
1 2 3 4

COU15
U15 COJ7
J7
NLF0SER0CLK0EN
F_SER_CLK_EN 1 PIU1501 5 5 NLJA0AY
JA_AY
OE
VCC PIU1505 5V PIJ705
IEC - 1541 style Diskdrive NLF0SER0CLK0O
F_SER_CLK_O 2 PIU1502 9
PIJ709
NLJA0AX
JA_AX
A COR87
R87 COR164
3 PIU1503 4
PIU1504
SER_CLK PIR8702 PIR8701
4
PIJ704
JA_RIGHT R164PIR16402 PIR16401
4K7
COJ6 GND GND
Y 5V
J6 4K7 GND 8
PIJ708
NLSER0SRQ GND COR165
1
PIJ601 SER_SRQ NC7SZ126P5X GND 3
PIJ703 JA_LEFT R165PIR16502 PIR16501 4K7
5
PIJ605
NLSER0DATA
SER_DATA COU16
U16 7
PIJ707
A NLF0SER0DATA0EN PIR8602 COR166 PIC4502 5V_JOY A
F_SER_DATA_EN1 PIU1601 OE 5
PIU1605 2
PIJ702 JA_DOWN R166PIR16602 PIR16601 4K7
NLSER0RESET NLF0SER0DATA0O VCC 5V PIC13502 COR86
R86 COR167 COC45
C45
6
PIJ606
SER_RESET F_SER_DATA_O 2 PIU1602 COR168 6
PIJ706
JA_FIRE R167PIR16702 PIR16701
4K7
A R168 COC135
C135 1M COR169 PIC4501 10µF
3 PIU1603 4
PIU1604 SER_DATA PIR16802 PIR16801 1
PIJ701 JA_UP R169PIR16902 PIR16901 4K7
NLSER0CLK GND GND
Y 5V PIC13501 100pF PIR8601 5%
4
PIJ604 SER_CLK 4K7
3 NLSER0ATN
SER_ATN NC7SZ126P5X 1000V GND
PIJ603 PIJ70H2 PIJ70H1
2
PIJ602
COU27
U27 X7R
GND NLF0SER0SRQ0EN
7
PIJ607
F_SER_SRQ_EN 1 PIU2701 5
PIU2705 DSUB-9-M UNC 4-40 rivet, w/o bolts
GND OE
VCC 5V

H2
H1
8
PIJ608
NLF0SER0SRQ0O
F_SER_SRQ_O 2 PIU2702
GND A COR170
R170
3 PIU2703 4
PIU2704 SER_SRQ PIR17002 PIR17001
GND GND
Y 5V COJ3
J3
61PC6F 4K7
NC7SZ126P5X 5
PIJ305
NLJB0AY
JB_AY
GND COU20
U20 9
PIJ309
NLJB0AX
JB_AX
1 PIU2001 5
PIU2005 4
PIJ304
NLJB0RIGHT
JB_RIGHT COR171
R171PIR17102 PIR17101 4K7
3.3V VCC
OE 3.3V
SER_CLK 2 PIU2002 8
PIJ308
A NLF0SER0CLK0I GND NLJB0LEFT COR172
3 PIU2003 4
PIU2004 F_SER_CLK_I 3
PIJ303 JB_LEFT R172PIR17202 PIR17201 4K7
GND GND
Y
7
PIJ307
NLJB0DOWN COR173 PIC7202 5V_JOY
NC7SZ126P5X 2
PIJ302
JB_DOWN R173PIR17302 PIR17301
4K7
COU21
U21 6 NLJB0FIRE
JB_FIRE COR174 4K7 COC72
C72
PIJ306 R174PIR17402 PIR17401
1 PIU2101 5
PIU2105 1
PIJ301
NLJB0UP
JB_UP COR175
R175PIR17502 PIR17501 4K7 PIC7201 10µF
B 3.3V VCC
OE 3.3V B
SER_DATA 2 PIU2102
A NLF0SER0DATA0I
3 PIU2103 4
PIU2104
F_SER_DATA_I GND
GND GND
Y PIJ30H2 PIJ30H1
NC7SZ126P5X DSUB-9-M UNC 4-40 rivet, w/o bolts

H2
H1
COU28
U28
1 PIU2801 5
PIU2805
3.3V OE
VCC 3.3V
SER_SRQ 2 PIU2802 3.3V
A NLF0SER0SRQ0I
3 PIU2803 4
PIU2804
F_SER_SRQ_I
GND GND Y COU33
U33
NC7SZ126P5X PIR12702 11 PIU33011 1
PIU3301
COR127
R127 5V VCC SOURCE 5V_JOY
PIR12 02 SOURCE
2
PIU3302
COU22
U22 4K7 COR122
R122 6 PIU3306 3
NC SOURCE PIU3303
1 PIU2201 5
PIU2205
NL5V0JOY0PG
5V_JOY_PG PIR12701 DNP 4
PIU3304
3.3V
NLJA0RIGHT VCC
OE 3.3V SOURCE
JA_RIGHT 2 PIU2202 PIR12 01 8 PIU3308 5
PIU3305
A NLFA0RIGHT PIT203 Enable/Fault
SOURCE
3 PIU2203 4
PIU2204
FA_RIGHT PIR12302 COC73
C73 PIR12401
GND GND
Y COR123
R123 COR124
R124
GND PIC7301 PIC7302
9 PIU3309
dv/dt
NC7SZ126P5X COT2
T2 200K 22R
COU23
U23 2N7002,215 1%
PIR 1230 1 1nF 7 PIR12402 1%
PIT201
10 PIU33010 PIU3307
50V GND I-Limit
1 PIU2301 5
PIU2305 PIR12502
C NLJA0LEFT3.3V VCC
OE 3.3V COR125
R125 X7R C
JA_LEFT 2 PIU2302 MP5010BDQ-LF-Z
A NLFA0LEFT PIT20 200K
3 PIU2303 4
PIU2304 FA_LEFT
GND GND
Y PIR12501 1% GND
NC7SZ126P5X GND PIT103
COU24
U24 GND COT1
T1
1 PIU2401 5 2N7002,215
3.3V OE
VCC PIU2405 3.3V
NLJA0DOWN
JA_DOWN 2 PIU2402 NLEN05V0JOY0N
EN_5V_JOY_NPIT101
A NLFA0DOWN
3 PIU2403 4
PIU2404
FA_DOWN
GND GND Y
3.3V 5V
NC7SZ126P5X PIT102
PIC17902 PIC180 2
COC179
C179 COC180
C180 COU25
U25 GND
PIC17901 10µF PIC180 1 10µF 1 PIU2501 5
PIU2505
10V NLJA0FIRE 3.3V VCC
OE 3.3V
JA_FIRE 2 PIU2502
A NLFA0FIRE
GND GND 3 PIU2503 4
PIU2504
FA_FIRE
GND GND
Y
NC7SZ126P5X Title:
MEGA65
COU26
U26
D D
1 PIU2601 5
PIU2605
Number: Rev.
NLJA0UP 3.3V VCC
OE 3.3V TE0765
JA_UP 2 PIU2602 A4 03
A [No Variations]
3 PIU2603 4
PIU2604
NLFA0UP
FA_UP
GND GND
Y
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 13 of 23
NC7SZ126P5X
Filename: JOY.SchDoc
1 2 3 4
1 2 3 4

A A

COJ5
J5
KBi i KB
1 PIJ501 2
PIJ502
NLK0JTAGEN GND 3.3V NLK0TMS
K_JTAGEN 3 PIJ503 4
PIJ504 K_TMS
NLK0TCK
K_TCK 5 PIJ505 6
PIJ506
NLK0TDI
K_TDI
NLK0TDO
K_TDO 7 PIJ507 8
PIJ508
NLK0IO1
K_IO1
NLK0IO2
K_IO2 9 PIJ509 10
PIJ5010
NLK0IO3
K_IO3

SMD-254-9132-14-10
B B

COJ12
J12
1 PIJ1201 2
PIJ1202
GND 3.3V
3 PIJ1203 4
PIJ1204
5 PIJ1205 6
PIJ1206
7 PIJ1207 8
PIJ1208
9 PIJ1209 10
PIJ12010

1-338069-0

C C

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 14 of 23

Filename: KEYBOARD.SchDoc
1 2 3 4
1 2 3 4

A A

COU7
U7
COJ13
J13 31 PIU7031 7
PIU707
3.3V VCCA VCCB 5V
1 PIJ1301 42 PIU7042 18
PIU7018
12V_FUSED VCCA VCCB
2 PIJ1302 FLOPPY
GND
3 PIJ1303 i
GND
4 PIJ1304 1 PIU701 48
PIU7048
5V 3.3V 1DIR 1OE GND
Stiftleiste 4 Pol. 2,54mm NLF0REDWC
F_REDWC 47 PIU7047 2
PIU702 REDWC
COJ16 NLF0MOTEA 1A1 1B1
J16 F_MOTEA 46 PIU7046 3
PIU703
MOTEA
NLF0DRVSA 1A2 1B2
1 PIJ1601 F_DRVSA 44 PIU7044 5
PIU705
DRVSA
12V_FUSED NLF0DIR 1A3 1B3
2 PIJ1602 F_DIR 43 PIU7043 6
PIU706 DIR
GND NLF0STEP 1A4 1B4
3 PIJ1603 F_STEP 41 PIU7041 8
PIU708 STEP
B GND NLF0WDATE 1A5 1B5 B
4 PIJ1604 F_WDATE 40 PIU7040 9
PIU709 WDATE
5V NLF0WGATE 1A6 1B6
F_WGATE 38 PIU7038 11
PIU7011
WGATE
NLF0SIDE1 1A7 1B7
Stiftleiste 4 Pol. 2,54mm F_SIDE1 37 PIU7037 12
PIU7012
SIDE1
1A8 1B8
24 PIU7024 25
PIU7025
GND 2DIR 2OE GND
NLF0INDEX
F_INDEX 36 PIU7036 13
PIU7013
INDEX
NLF0TRCK0 2A1 2B1
F_TRCK0 35 PIU7035 14
PIU7014
TRCK0
NLF0WPT 2A2 2B2
F_WPT 33 PIU7033 16
PIU7016 WPT
NLF0RDATA1 2A3 2B3
F_RDATA1 32 PIU7032 17
PIU7017 RDATA1
NLF0DSCKCHG 2A4 2B4
F_DSCKCHG 30 PIU7030 19
PIU7019 DSCKCHG
2A5 2B5
29 PIU7029 20
PIU7020
2A6 2B6
27 PIU7027 22
PIU7022
COJ14 2A7 2B7
J14 26 PIU7026 23
PIU7023
NLREDWC 2A8 2B8
1 PIJ1401
2
PIJ1402
REDWC
3 PIJ1403 4
PIJ1404 28 PIU7028 4
PIU704
GND GND
5 PIJ1405
6
PIJ1406
34 PIU7034 10
PIU7010
NLINDEX COR176
R176 GND GND
7 PIJ1407
8
PIJ1408
INDEX PIR17602 PIR17601
39 PIU7039 15
PIU7015
NLMOTEA 5V GND GND
9 PIJ1409 10
PIJ14010 MOTEA 4K7 45 PIU7045 21
PIU7021
C NLDRVSB GND GND GND GND C
11 PIJ14011 12
PIJ14012 DRVSB
13 PIJ14013 14
PIJ14014
NLDRVSA
DRVSA SN74LVCH16T245DGV
15 PIJ14015
16
PIJ14016
NLMOTEB
MOTEB
17 PIJ14017
18
PIJ14018
NLDIR
DIR
19 PIJ14019
20
PIJ14020
NLSTEP
STEP
21 22 NLWDATE
WDATE
PIJ14021 PIJ14022
23 PIJ14023 24
PIJ14024
NLWGATE
WGATE
NLTRCK0
TRCK0
COR177
R177
25 PIJ14025
26
PIJ14026 PIR17702
NLWPT COR178
R178PIR17701 5V
27 PIJ14027
28
PIJ14028
WPT PIR17802
4K7
NLRDATA1 COR179
R179PIR17801 5V
29 PIJ14029
30
PIJ14030
RDATA1 PIR179024K7 PIR17901
NLSIDE1 5V
31 PIJ14031 32
PIJ14032 SIDE1 4K7
33 34 NLDSCKCHG
DSCKCHG
COR180
R180
PIJ14033 PIJ14034 PIR18002 PIR18001 5V
4K7
WANNE2,54-34 GERADE
GND
Title:
MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 15 of 23

Filename: Floppy.SchDoc
1 2 3 4
1 2 3 4

GND

COU3A
COU3B
U3A
NLG0
G0 3 PIU303 31
PIU3031
A NLG1 G0 IOG NLVGA0Green0Out A
G1 4 PIU304 32
PIU3032 VGA_Green_Out
NLG2 G1 IOG PIR1301
G2 5 PIU305
NLG3 G2 COR13
R13
G3 6 PIU306
NLG4 G3 75R COJ1
J1
G4 7 PIU307 DSUB-15-F-HD 8.89
NLG5 G4 PIR1302 1%
G5 8 PIU308 VGA_Red_Out 1 PIJ101
NLG6 G5
G6 9 PIU309 GND 6 PIJ106
NLG7 G6 GND
G7 10 PIU3010 GND 11 PIJ1011
G7
VGA_Green_Out 2 PIJ102
NLB0
B0 16 PIU3016 27
PIU3027 7 PIJ107
NLB1 B0 IOB NLVGA0Blue0Out GND
B1 17 PIU3017 28
PIU3028 VGA_Blue_Out VGA_ID1/SDA 12 PIJ1012
NLB2 B1 IOB PIR1501
B2 18 PIU3018 VGA_Blue_Out 3 PIJ103
NLB3 B2 COR15
R15
B3 19 PIU3019 8 PIJ108
NLB4 B3 75R NLVGA0HSync COR44
R44 GND
B4 20 PIU3020 VGA_HSync PIR4401 PIR4402 13 PIJ1013
NLB5 B4
B5 21 PIU3021 PIR1502 1% 49R9 4 PIJ104
NLB6 B5
B6 22 PIU3022 GND 9 PIJ109
NLB7 B6 NLVGA0VSync COR53
R53
B7 23 PIU3023 GND VGA_VSync PIR5301 PIR5302
14 PIJ1014
B7
49R9 GND 5 PIJ105
NLR0
R0 41 PIU3041 33
PIU3033 10 PIJ1010
NLR1 R0 IOR NLVGA0Red0Out GND
R1 42 PIU3042 34
PIU3034 VGA_Red_Out VGA_ID3/SCL 15 PIJ1015
B NLR2 R1 IOR B
R2 43 PIU3043
R2
PIR1601
NLR3
R3 44 PIU3044 COR16
R16
NLR4 R3 75R PIJ10H1 PIJ10H2
R4 45 PIU3045
NLR5 R4 1%
R5 46 PIU3046 PIR1602
R5
H1
H2

NLR6
R6 47 PIU3047
NLR7 R6
R7 48 PIU3048 GND
R7
ADV7125BCPZ170

5V PIR8501 PIC13401
3.3V COR85
R85 COC134
C134
U3B VAA COL7 1M PIC13402 100pF
NLVDAC0CLK L7 PIR6902 PIR13 02 PIR8502 5% 1000V
VDAC_CLK 24 PIU3024 13
PIU3013 PIL701 PIL702
CLOCK VAA 3.3V COR69
R69 PIT301 COR131
R131 X7R
29
PIU3029 PIC3401 PIC3501
NLVDAC0BLANK0N VAA COC34
C34 COC35
C35 MPZ1608S221A 10K 10K
VDAC_BLANK_N 11 PIU3011 30
PIU3030
BLANK VAA NLVGA0SDA NLVGA0ID10SDA
PIC3402 100nF PIC3502 10nF VGA_SDA PIR6901 PIT302
PIR13 01
PIT303 VGA_ID1/SDA GND GND
NLVDAC0SYNC0N
VDAC_SYNC_N 12 PIU3012 1
PIU301
25V 16V
SYNC GND X5R X7R
2
PIU302
NLVDAC0PSAVE0N GND COT3
VDAC_PSAVE_N 38 PIU3038 14
PIU3014
T3
C PSAVEGND C
COC36
C36 15
PIU3015
2N7002,215
GND
PIC3601 PIC3602 36 PIU3036 25
PIU3025 GND 5V
VAA VREF GND
COC118
C118 26
PIU3026
3.3V
100nF GND
PIC11801 PIC11802
35 PIU3035 39
PIU3039
25V VAA COMP GND
40
PIU3040 PIR1320 PIR13 02
X5R 100nF GND COR132
R132 PIT401 COR133
R133
37 PIU3037 49
PIU3049
25V RSET EP 10K 10K
X5R PIR1801 ADV7125BCPZ170 GND NLVGA0SCL
VGA_SCL PIR13201 PIR13 01 NLVGA0ID30SCL
VGA_ID3/SCL
PIT402 PIT403
COR18
R18
560R
PIR1802 1% COT4
T4
2N7002,215

GND

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 16 of 23

Filename: VGA.SchDoc
1 2 3 4
1 2 3 4

3.3V
A A

PIR4802 PIR7302
COR48
R48 COR73
R73 GND
4K7 4K7
PIR4801 PIR7301 PIC106 2 COJ4
J4
COC106
C106 3.3V HDMI_TX2_P 1 PIJ401
COU10 PIC106 1 100nF Data2+
U10 2 PIJ402
NLCEC0A Data2 Shield
CEC_A 1 PIU1001 24
PIU10024 HDMI_TX2_N 3 PIJ403
NLSCL0A CEC_A VCCA NLHDMI0TX20P Data2-
SCL_A 2 PIU1002 23
PIU10023 HDMI_TX2_P HDMI_TX1_P 4 PIJ404
NLSDA0A SCL_A D2+ NLHDMI0TX20N Data1+
SDA_A 3 PIU1003 22
PIU10022 HDMI_TX2_N 5 PIJ405
NLHPD0A SDA_A D2- NLHDMI0TX10P Data1 Shield
HPD_A 4 PIU1004 21
PIU10021 HDMI_TX1_P HDMI_TX1_N 6 PIJ406
NLLS0OE HPD_A D1+ NLHDMI0TX10N Data1-
LS_OE 5 PIU1005 20
PIU10020 HDMI_TX1_N HDMI_TX0_P 7 PIJ407
LS_OE D1- Data0+
6 PIU1006 19
PIU10019 8 PIJ408
GND GND GND GND Data0 Shield
NLCEC0B
CEC_B 7 PIU1007 18
PIU10018
NLHDMI0TX00P
HDMI_TX0_P HDMI_TX0_N 9 PIJ409
NLSCL0B CEC_B D0+ NLHDMI0TX00N Data0-
SCL_B 8 PIU1008 17
PIU10017
HDMI_TX0_N HDMI_TXC_P 10 PIJ4010
NLSDA0B SCL_B D0- NLHDMI0TXC0P Clock+
SDA_B 9 PIU1009 16
PIU10016 HDMI_TXC_P 11 PIJ4011
NLHPD0B SDA_B CLK+ NLHDMI0TXC0N Clock Shield
HPD_B 10 PIU10010 15
PIU10015 HDMI_TXC_N HDMI_TXC_N 12 PIJ4012
HPD_B CLK- Clock-
11 PIU10011 14
PIU10014 CEC_B 13 PIJ4013
B 5V NLCT0HPD VCC5V GND GND NL5V0HDMI CEC B
CT_HPD 12 PIU10012 13
PIU10013 5V_HDMI 14 PIJ4014
CT_HPD5V_OUT NC
SCL_B 15 PIJ4015
PIC1 701 PIC17 01 SCL
TPD12S016PWR SDA_B 16 PIJ4016
COC117
C117 COC171
C171 SDA
17 PIJ4017
100nF DDC/CEC GND
PIC1 702 100nF PIC17 02 5V_HDMI 18 PIJ4018
+5V
HPD_B 19 PIJ4019
Hot Plug Detect
GND GND H1 PIJ40H1
FRAME
H2 PIJ40H2
FRAME
H3 PIJ40H3
FRAME
H4 PIJ40H4
FRAME
HDMI Connector
GND

C C

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 17 of 23

Filename: HDMI.SchDoc
1 2 3 4
1 2 3 4

COU4A
COU4B
U4A
23
PIU4023 ETH_LED
NLETH0RD0P LED0/ANEN_SPEED
3.3V ETH_RD_P4 PIU404
NLETH0RD0N RXP NLETH0CRS0DV
ETH_RD_N 3 PIU403 15
PIU4015 ETH_CRS_DV
RXM CRS_DV/PHYAD[1:0] i ETH
PIR501 PIR601 NLETH0TD0P
ETH_TD_P6 PIU406
A COR5
R5 COR6
R6 NLETH0TD0N TXP A
ETH_TD_N 5 PIU405
1K 1K TXM
7
PIU407
PIR502 1%PIR602 1% XO
NLETH0MDIO
ETH_MDIO 10 PIU4010 8
PIU408
NLETH0CLK
ETH_CLK
NLETH0MDC MDIO XI i ETH
ETH_MDC 11 PIU4011
MDC NLETH0RST COJ10A
COJ10B
COJ10C
24
PIU4024 ETH-RST J10A
RST
ETH_TD_P 1 PIJ1001
COR9
R9 6K4991% TD+ J1
GND PIR901 PIR902
PIU409 REXT
NLETH0INT
ETH_INT 18 PIU4018 16
PIU4016
INTRP REF_CLK NLETH0RXER 75R 75R
J4
17
PIU4017 ETH_RXER 4 PIJ1004
NLETH0TX0EN RXER i ETH PIC1802 TCT
ETH_TX_EN 19 PIU4019
ETHi TXEN COC18
C18 J5
NLETH0TX0D0
ETH_TX_D0 20 PIU4020 13
PIU4013
NLETH0RX0D0
ETH_RX_D0 100nF
PIC1801 ETH_TD_N 2 PIJ1002
ETHi NLETH0TX0D1 TXD0 RXD0 NLETH0RX0D1 i ETH 25V TD- J2
ETH_TX_D1 21 PIU4021 12
PIU4012 ETH_RX_D1
ETHi TXD1 RXD1 i ETH
GND X5R
KSZ8081RNDCA ETH_RD_P 3 PIJ1003
RD+ J3

75R 75R
J7
5 PIJ1005
B RCT B
PIC1902 J8
1% COC19
C19
COR10
R10 NLETH0LED 100nF
PIC1901
J10B
PIJ1009 PIJ10010 PIR1001 PIR1002
ETH_LED ETH_RD_N 6 PIJ1006
3.3V 25V RD- J6
L-GN 220R
GND X5R
RJ45 - 7499011222A
8 PIJ1008
COR11
R11 GND GND
PIR1101 PIR1102 GND
10K 7 PIJ1007
NC
1%
1% 15 PIJ10015
J10C COR72
R72 NLETH0LED2
ETH_LED2
Frame
3.3V PIJ10011 PIJ10012 PIR7201 PIR7202 16 PIJ10016
Frame
R-GN 220R
RJ45 - 7499011222A
RJ45 - 7499011222A

GND
PIR1201 PIC2901
PIC2101 PIC2801 COR12
R12 COC29
C29
COC21
C21 COC28
C28 1M PIC2902 100pF
C 22µF 470nF 1000V C
PIC2102 PIC2802 PIR1202 5%
6.3V 6.3V X7R
X5R X5R U4B
14 PIU4014 1
PIU401
NLVDD0102V
VDD_1.2V GND GND
3.3V VDDIO VDD_1.2
PIC30 1 PIC3101
COC30
C30 COC31
C31
22
PIU4022
PIC30 2 2.2µF PIC3102 470nF
COL4
L4 GND
PIL401 PIL402
2 PIU402 25
PIU4025
6.3V 6.3V
VDDA_3.3 GND X7R X5R
BKP0603HS121-T PIC3201 PIC3 01 KSZ8081RNDCA
COC32
C32 COC33
C33
PIC3202 22µF PIC3 02 470nF GND
6.3V 6.3V
X5R X5R

GND Title:
MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 18 of 23

Filename: Ethernet.SchDoc
1 2 3 4
1 2 3 4

A A

http://linux-sunxi.org/MicroSD_Breakout
3.3V

COJ2 COR27
R27 NLM0TCK
J2 SD_D2 PIR2701 PIR2702 M_TCK
COR52
R52PIR5202
12K1
PIR5201
1% NLSD0D2
SD_D2 1
PIJ201 DAT2 0R
COR55
R55PIR5502 12K1
PIR5501 1% NLSD0D3
SD_D3 2
PIJ202
COR56 NLSD0CMD CD/DAT3 1%
R56PIR5602 12K1
PIR5601 1% SD_CMD 3
PIJ203 CMD
4
PIJ204
NLSD0CLK VDD COR32
R32 NLM0TMS
SD_CLK 5
PIJ205 SD_D1 PIR3201 PIR3202 M_TMS
CLK
6
PIJ206 GND 0R
COR57
R57PIR5702 12K1
PIR5701 1% NLSD0D0
SD_D0 7
PIJ207
COR88 NLSD0D1 DAT0 1%
R88PIR8802 12K1
PIR8801 1% SD_D1 8
PIJ208 DAT1
COR33
R33 NLM0TDO
G1
PIJ20G1 GND
SD_CMD PIR3301 PIR3302
M_TDO
G2
PIJ20G2 GND 0R
G3
PIJ20G3 GND 1%
G4
B GND PIJ20G4 GND B
COR89 NLSD0CD COR34
R34 NLM0TDI
R89PIR8902
12K1
PIR8901
1% SD_CD 9
PIJ209 Card
SD_D0 PIR3401 PIR3402
M_TDI
Detect 0R
Switch 1%
COC22
C22 10
PIJ2010
GND
3.3V PIC2201 PIC2202 GND COR35
R35
Micro SD Socket SD_D3 PIR3501 PIR3502
NLM0RX
M_RX
10µF
10V 0R
X5R 1%

COR36
R36 NLM0TX
3.3V SD_CLK PIR3601 PIR3602
M_TX
COJ15
J15
COR119 0R
R119 12K1
PIR11901
NLSD20D3
SD2_D3 1 PIJ1501
COR21
R21 PIR11902 NLSD20CMD CD/DAT3 1%
PIR2101
12K1
PIR2102
SD2_CMD 2 PIJ1502
CMD
3 PIJ1503
GND VSS1
4 PIJ1504
3.3V
NLSD20CLK VDD COS3A
COS3B
COS3C
COS3D
S3A
SD2_CLK 5 PIJ1505
CLK COR142 NLCPLD0CFG0
6 PIJ1506 R142
PIR14202 12K1
PIR14201 1% CPLD_CFG0 8 PIS308 1
PIS301
C COR24
R24 GND
NLSD20D0 VSS2 3.3V C
PIR2401COR25 12K1 SD2_D0 7 PIJ1507 CHS-04TA
R25 PIR2402 NLSD20D1 DAT0
PIR2501COR26 12K1 SD2_D1 8 PIJ1508
R26 PIR2502 NLSD20D2 DAT1 S3B
PIR2601
12K1
PIR2602
SD2_D2 9 PIJ1509
DAT2 COR143 NLCPLD0CFG1
R143
PIR14302
12K1
PIR14301
1% CPLD_CFG1 7 PIS307 2
PIS302
COR120
R120 NLSD20CD
PIR12001
12K1
PIR12002
SD2_CD 10 PIJ15010 CHS-04TA
CD Card
COR121 Detect
R121 12K1
PIR12101 PIR12102
NLSD20WP
SD2_WP 11 PIJ15011 Switch
S3C
WP COR144 NLCPLD0CFG2
R144
PIR14402
12K1
PIR14401
1% CPLD_CFG2 6 PIS306 3
PIS303
CHS-04TA
COC27
C27 12 PIJ15012
GND
PIC2701 PIC2702
S3D
3.3V GND
MMC SD Socket COR31
R31PIR3102
12K1
PIR3101
1% NLCPLD0CFG3
CPLD_CFG3 5 PIS305 4
PIS304
10µF
CHS-04TA
10V GND
X5R

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 19 of 23

Filename: LED_SW_BUT.SchDoc
1 2 3 4
1 2 3 4

COU12
U12
1 PIU1201 7
PIU1207 VOUT
12V_FUSED PIC302 PIC702 Vin Vout PIR201 PIC802 PIC1301 PIC1501 PIC1601 PIR15 01 5V
4.67V
COC3
C3 COC7
C7 2 PIU1202 5 COR2
R2 COC8
C8 COC13
C13 COC15
C15 COC16
C16 COR155
R155
GND SYNC FB PIU1205
PIC301 22µF PIC701 47nF 5K6 PIC801 47nF PIC1302 100µF PIC1502 100µF PIC1602 100µF 27K
A 25V 50V PIR202 1% 50V 10V 10V 10V PIR15 02 1% A
3 PIU1203 6
PIU1206

AGND
GND
X7R EN SS/TRK PIC1701 X7R X5R X5R X5R PIC18 01 PIR160 1
X5R
GND GND COC17
C17 PIR401 COC181
C181 COR160
R160
PIU1204 PIU1208 PIC1702 470nF COR4
R4 GND 10nFPIC18 02 27K
50V 1K15 50V PIR160 2 1%

4
8
171050601
GND GND X7R PIR402 1% NLCPLD0ADC1
CPLD_ADC1 X7R
GND GND GND
GND
COU14
U14
1 PIU1401 7
PIU1407 VOUT
12V_FUSED PIC3702 PIC3802 Vin Vout PIR1901 PIC3902 PIC40 1 PIC9 01 PIC10 01 3.3V
3.30V
COC37
C37 COC38
C38 2 PIU1402 5 COR19
R19 COC39
C39 COC40
C40 COC99
C99 COC100
C100
GND SYNC FB PIU1405
PIC3701 22µF PIC3801 47nF 3K3 PIC3901 47nF PIC40 2 100µF PIC9 02 100µF PIC10 02 100µF
25V 50V 3 PIU1403 6
PIU1406 PIR1902 1% 50V 10V 10V 10V

AGND
GND
X7R 1.8V EN SS/TRK X7R X5R X5R X5R
X5R PIC102 1
GND GND COC102
C102 PIR20 1
PIU140 PIU1408 PIC102 470nF COR20
R20 GND
50V 1K05

4
8
171050601
GND GND X7R PIR20 2 1%
B B
GND
AO4832 AO4832 GND
T5B COT5A
COT5B
T5A
8 PIT508 6
PIT506
7 PIT507 13
PIT501
PIT503 5
PIT505

PIT502 PIT504

2
4
PIR13501 PIR13601
COR135
R135 COR136
R136
10R 10R
PIR13502 PIR13602 SR= 2V/ms
COR137
R137
COC139
C139
PIR13701 PIR13702
PIC13901 PIC13902
5K1 10nF
GND
50V
Fuse 3A 35V SMD 1206 fast X7R
C COS1 C
HV S1

8
COJ11
J11 COF1
F1 i COL5
L5 NLVIN
1 VIN
PIS101
COU34
U34 PIU3408
1
PIJ1101 PIF101 PIF102
1 PIL501
4 2
PIL504 PIS102
1 7
PIU3407
PID501 PIR13801 PIR13901 PIU3401 Vin Vout PIC14 01 12V_FUSED
3
PIS103
3
PIJ1103
COD5
D5 2 PIL502 PIL503
3 COR138
R138 COR139
R139 COC144
C144
1M 470K GATE PIC14 02 10µF
2
PIJ1102 9µH PIS10F1 PIS10F2 PIR13802 1% PIR139502 1%
PIU3405 SHDN FAULT
6
PIU3406
16V
NLPOWER0GND
POWER_GND PID502 2 PIU3402 GND X5R
UV

F1
F2
Power Jack 2.1mm 90° SMD GND PIR140 1
SMBJ20A, 20V, 600W GND COR140
R140
A101J1AV2Q004 27K
OV = 14V
PIR14032 1% OV
UV = 10V
PIR14 01 PIU3403
COR141
R141
37K4
PIR14402 1% PIU3404 GND
Title:
GND LTC4365ITS8#TRMPBF MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 20 of 23

Filename: PowerMain.SchDoc
1 2 3 4
1 2 3 4

5V 1V
COU11
U11 COC6
C6
COR17
R17
PIR1701 PIR1702
PG_1V0 28 PIU11028
5
PIU1105 PIC601
X5R
PIC602
5V POK VOUT GND
10K COC41
C41 6
PIU1106 6.3V
VOUT 47µF
PIC4101 PIC4102 19 PIU11019 7
PIU1107
GND PVIN VOUT
20 PIU11020 8
PIU1108
A 22µF PVIN VOUT PIR4901 PIC1 101 A
21 PIU11021 9
PIU1109
25V PVIN VOUT COR49
R49 COC111
C111
10
PIU11010
X5R VOUT 200K PIC1 102 22pF
33 PIU11033 11
PIU11011
AVIN VOUT PIR4902
1% 6.3V
27 PIU11027 31
PIU11031 NP0
ENABLE VFB
1 PIU1101 NC(SW)
PIR50 1
2 COR50
R50
PIU1102 NC(SW)
12 PIU11012 26
PIU11026
604K
NC(SW) LLM/SYNC
3 PIU1103 NC
02
PIR51%
4 PIU1104 NC
22 PIU11022 NC
23 PIU11023 NC
24 PIU11024 29
PIU11029
NC RLLM
25 PIU11025 NC
34 PIU11034 NC(SW)
35 PIU11035
30
PIU11030
NC(SW) SS Soft-start 3.8ms
36 PIU11036
PIC1 901
NC(SW) COC119
C119
37 PIU11037 32
PIU11032
B NC(SW) AGND 47nF B
38 PIU11038 NC(SW)
PIC1 902
13
PIU11013
6.3V
PGND
17 PIU11017
14
PIU11014
GND X5R
PGND PGND
18 PIU11018 15
PIU11015
PGND PGND
16 PIU11016 39
PIU11039
PGND PGND
GND EN6347QI GND

1V
C C
PIR16 02
5V COR161
R161
COU13
U13 10K
14 PIU13014 7
PIU1307
NLCPLD0ADC3
CPLD_ADC3 PIR16 01
PVIN VOUT 1.8V
PIC120 1 8
PIU1308
PIC12101 PIR1620 PIC18201
COC120
C120 VOUT COC121
C121 COR162
R162 COC182
C182
10µF
PIC120 2 COR51
R51 PIC12102 10µF 10K PIC1820 10nF
PIR5101 PIR5102
13 PIU13013 5
PIU1305
10V AVIN VSENSE 10V NLCPLD0ADC2 50V
100R CPLD_ADC2 PIR16201
GND X5R 12 PIU13012 4 GND X5R PIC18301 X7R
1% ENABLE NC PIU1304
1 COC183
C183 GND
NC(SW) PIU1301
NLPG01V0
PG_1V0 3 PIU1303 15 PIC18302 10nF
LLM NC(SW) PIU13015
16
PIU13016
50V
NC(SW) X7R
11 PIU13011
VS0
10 PIU13010 6
PIU1306
GND
VS1 AGND
9 PIU1309 2
PIU1302
5V VS2 PGND GND
Title:
EP53A7HQI MEGA65
D D
Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH / TT Page 21 of 23

Filename: POWER.SchDoc
1 2 3 4
1 2 3 4

NLV0P
V_P
COR54
R54 COR59
R59
PIR5401 PIR5402 PIR5901 PIR5902 1V
240R 1%
PIC12301 2K61
COC123
C123
PIR60 2 PID602 PID601 PIC12302 4.7µF
COR60
R60 COD6
D6
A 200K GND A
PIR60 1 1% PIC12402
BAV199LT1G COC124
C124 COC125
C125
NLV0N COR66
R66 COR61
33nF R61
V_N PIR6601 PIR6602
PID603 PIC12401 PIR6101 PIR6102 PIC12502 PIC12501

240R 1% 240R 1% 10µF


3.3V GND
10V
PID702 PID701 BAV199LT1G X5R
COJ9
J9

1 PIJ901
COD7
D7
PID703 GND
2 PIJ902
COR62
R62
COC126
C126
NLPWM0R
PWM_R PIR6201 PIR6202 PIC12602 PIC12601 3 PIJ903
240R
PIC12701 PIR6301 COR64
R64
COC128
C128
COC127
C127 COR63
R63 10µF NLPWM0L
PWM_L PIR6401 PIR6402 PIC12802 PIC12801
1% 4 PIJ904
PIC12702 33nF 150R 10V PIC12901 PIR6501
X5R 240R COC129 COR65 10µF
25V 02
PIR631% C129 R65
B 1% 10V B
X7R PIC12902 33nF 150R 3.5RCA
25V 02
PIR651% X5R
GND COD8
D8 PID803 X7R

GND

COL11
L11
NL5V0PVDD
5V_PVDD PIL1102 PIL1101
PID801 PID802 BAV199LT1G
5V
PIC8201 PIC8301 PIC8401 PIC8501 MPZ1608S221A
COC82
C82 COC83
C83 COC84
C84 COC85
C85 GND 3.3V
PIC8202 47µF PIC8302 47µF PIC8402 470pF PIC8502 470pF
6.3V 6.3V 50V 50V
GND GND GND GND
3.3V
PIC8601
COC86
C86 COJ22
J22
I2S PIC8602 470nF COU37
U37 NLSPKL0P
SPKL_P 1 PIJ2201
i 12 PIU37012 16
PIU37016
PIL101 NLSPKL0N
SPKL_N 2 PIJ2202
DVDD PVDD COL1
GND 20
PIU37020 L1 PIL601
C PVDD COL6 C
2A L6 PIC8701 PIC8 01 JST-S2B-XH-A
NLAUDIO0MCLK
AUDIO_MCLK 6 PIU3706 BLM15PX121SN1D 2A COC87
C87 COC88
C88
NLAUDIO0SDATA MCLK PIL102 PIC8702 470pF PIC8 02 470pF
AUDIO_SDATA 10 PIU37010 1
PIU3701
BLM15PX121SN1D
SDATA OUTL+ PIL602 50V 50V
2
PIU3702
NLAUDIO0BCLK OUTL-
AUDIO_BCLK 7 PIU3707 GND GND
NLAUDIO0LRCLK BCLK
AUDIO_LRCLK 9 PIU3709 15
PIU37015
LRCLKOUTR+
OUTR-
14
PIU37014
PIL801
NLFPGA0SCL
FPGA_SCL 5 PIU3705 PIL901 COL8
L8
NLFPGA0SDA SCL
FPGA_SDA 4 PIU3704 BLM15PX121SN1D 2A
SDA COL9 COJ19
21
PIU37021
L9 BLM15PX121SN1D J19
EP NLSPKR0P
11 PIU37011 8
PIU3708 2A PIL802 SPKR_P 1 PIJ1901
SAMOD GND
3 PIU3703 17
PIU37017
PIL902 NLSPKR0N
SPKR_N 2 PIJ1902
GND ADDR GND
18
PIU37018
NLnSD0AUDIO GND
nSD_AUDIO 13 PIU37013 19
PIU37019
PIC8901 PIC9401 JST-S2B-XH-A
SD GND COC89
C89 COC94
C94
PIR4702
COR47
R47 SSM2518CPZ-R7 NOT CHECKED!!! GND PIC8902 470pF PIC9402 470pF
4K7 50V 50V Title:
PIR4701 I2C addr: 0x34 GND GND MEGA65
D D
GND Number: Rev.
A4 TE0765
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 22 of 23

Filename: SOUND.SchDoc
1 2 3 4
1 2 3 4

REVISION HISTORY

REV Description

-03 IG
1. Added a VRP resistor on bank 65;
A A
2. LDO U33 is changed on ADP7102ACPZ;
3. Signal FPGA IO0 is connected on AE18 pin of FPGA;
4. Signal DBG_LED3 is connected on AD18 pin of FPGA;
5. Signal MIO13_25 connected to J1 pin 33 instead MIO25.
6. Resistor R84 is removed;
7. LED D1 moved on edge of PCB;
8. Added THT testpoints J4 on CPLD_JTAGEN, R76 was removed;
9. Signals B49_XX_X are renamed in B88_XX_X;
10. C241 is changed on 1nF;
11. Length of CLK signals on RFADC and RFDAC are adjusted;
12. Wrong connection on U8 is fixed (PCB);
13. Wrong connection PGOOD1 pin of U7 is fixed;

B B

C C

Title:
MEGA65
D D
Number: Rev.
A4 TE0835
[No Variations] 03
Date: 2020-06-29 Copyright: Trenz Electronic GmbH Page 23 of 23

Filename: Revision_Changes.SchDoc
1 2 3 4
COJ9 COH7

PAJ902 PAC12601 PAC12602


PAR6301
COC126 COR63 PAR6302
PAJ130H1
PAJ1403 PAJ14031 PAJ14029 PAJ14027 PAJ14025 PAJ14023 PAJ14021 PAJ14019 PAJ14017 PAJ14015 PAJ14013 PAJ1401 PAJ1409 PAJ1407 PAJ1405 PAJ1403 PAJ1401
PAJ90H1 PAJ90H2
PAC12801 PAC12802 PAC12701
COC128 COC127 PAC12702
COJ14
PAJ901 PAJB10H1 COJ13 PAJ1301 PAJ1302 PAJ1303 PAJ1304
PAR6501 PAR6502 COR65 PAJ14034 PAJ14032 PAJ14030 PAJ14028 PAJ14026 PAJ14024 PAJ14022 PAJ14020 PAJ14018 PAJ14016 PAJ14014 PAJ14012 PAJ14010 PAJ1408 PAJ1406 PAJ1404 PAJ1402 PAH701
PAJ904 PAJ903 PAC12901 PAC12902 COR62
PAD702 PAD701
CO 129 PAD703 COD7 COPM2
COPM4
COJ2 PAD803 PAR6202
PAR6201
PAJB102 PAJB101 COR180 COR179COR178COR177 COR176 PAPM200
PAPM400
PAJ20G3 PAJ20G4 PAR6402 PAR6401
PAC12501
PAR18002 PAR17902 PAR17802 PAR17702 PAR17602
PAJ160H1
PAJ208 PAD802 PAD801
PAR3601 PAR3602 PAR18001 PAR17901 PAR17801 PAR17701 PAR17601
PAJ207
COR36
COD8COR64 PAJB104
COC138
PAJB103 COC124
COR61 COR59
PAC12502COC123
COJ16 PAJ1601 PAJ1602 PAJ1603 PAJ1604 COR130COD12
PAR8801
PAR3201 PAR8802
PAR3202
PAJ206 COR88 COC125 COD6 PAR6102 PAC12402 PAC12302 PAR5902 PAD120K PAD120A
PAR13002 PAR13001
PAC13802 COR70
COR34 PAR6101 PAC12401 PAC12301 PAR5901
PAR537401 PAR354702 PAC13801
PAJ205 COR57
COR89
COR32 PAJB106 PAJB105 PAD601 PAR7002 PAR70 1 PAD100K PAD100A
PAJ204 PAR5601
PAR3301 PAR5602
PAR3302
AR8901 PAR8902
PAJ209 PCOR56
COR33 PAD603 COD10
PAJ203 PAJB108
COR35 COR158PAJB107
PAR53 01 PAR35 02
COR55 PAD602
PAJ202 PAR15801 PAR15802
PAJ201 COR52
COR27 PAR5201
PAR2701 PAR5202
PAR2702 COR66
COR54 PAR6001 PAR6002
COR60 PAU7024 PAU7023 PAU702 PAU7021 PAU702 PAU7019 PAU7018 PAU701 PAU7016 PAU7015 PAU7014 PAU7013 PAU7012 PAU701 U701 PAU709 PAU708 U70 PAU706 PAU705 U704PAU703PAU702PAU701
PAC2202 PAJB1010 PAJB109 PAR6602 PAR5402
PAR6601 PAR5401
PAJ2010 COU7
PAC2201
PAJB1012 PAJB1011
PAJ20G1 PAJ20G2
COC22 PAU7025 PAU7026 PAU702 PAU7028 PAU7029 PAU703 PAU7031 PAU7032 PAU703 PAU7034 PAU7035 PAU7036 PAU703 PAU7038 U7039 PAU704 PAU7041 U7042PAU7043 PAU704 U7045PAU7046PAU7047PAU7048 PAS304 PAS303 PAS302 PAS301 COP2
PAJ10015 COJ10 PAR902 PAR901
COJB1 COD4
PAJ1009 COC32 COR9 PAR502 PAR501
PAJ100H1 COR5 COS3 PAD406 PAD405 PAD404 PAP201 PAP207
PAJ10010 PAJ1001 COC21
COU4 PAP20H1
PAJ1002 PAC3202 PAU407 PAU408 PAU409PAU4010PAU401 PAU4012 COC28
PAU406 PAU4013 PAS305 PAS306 PAS307 PAS308 PAD401 PAD402 PAD403
PAR10 1 PAR10 2 COR10 PAC3201PAU405 PAU4014 PAC2802 PAC2102
COR31
COR144
COR143
COR142 PAP202 PAP208
PAU404
PAC3301PAC3302COC33 PAU4015 PAC2801 COD11
PAR1 01 PAR1 02 COR11 PAJ1003 PAU403
PAL402PAL401
PAU402
PAU4025 PAU4016
PAU4017 PAC2101 PAR3101 PAR14401 PAR14301 PAR14201
PAJ1004 PAC1802PAC3101 PAU401
COL4 PAU4018
PAP203 PAP209
PAR3102 PAR14402 PAR14302 PAR14202 PAD1 06 PAD1 05 PAD1 04
PAC3001PAC1801PAC3102 PAU4024 PAU4023 PAU402 PAU4021PAU4020 PAU4019
PAJ1005 PAC3002PAC1902COC31
COC18 PAR601 PAR602 COR6
PAJ1006 PAC1901
COR157 PAD1 01 PAD1 02 PAD1 03 PAP204 PAP2010
PAR15701
PAJ1007 COC30 COC19 PAR15702 COC162
PAJ10 1 PAJ1008
COC163
PAC16202 PAP205 PAP2011
PAC16302 PAP20H2
PAJ10 12 PAC16301 PAC16201 PAP206 PAP2012
COR72 COR162
PAJ100H2 PAJ10016
PAR7201 COC183
COR30COR29
PAR16202 PAR16201
COC164
COR147 PAU3501 PAU3508
PAR7202 COR161 PAR30 2 PAR2902
PAJ17010 PAJ1709 PAC18302 PAC18301 PAC16401
PAC2902 PAC2901 PAR1201 COC182 PAU320A1 PAU320A2 PAU320A3 PAU320A4 PAU320A5 PAU320A6 PAU320A7 PAU320A8 PAU320A9 PAU320A10 PAU320A11 PAU320A12 PAU320A13 PAR14602 PAU3502 PAU3507
COC165 COC245
COC202
COC29 PAR3001 PAR2901 PAC24702
PAR1202 COR12 PAR16102 PAR16101 PAC16501
PAU320B1 PAU320B2 PAU320B3 PAU320B4 PAU320B5 PAU320B6 PAU320B7 PAU320B8 PAU320B9 PAU320B10 PAU320B11 PAU320B12
COR28COC247COC173 PAU320B13
COR146 PAR14601 PAR14701
PAC201 PAC24501 PAC24701 PAU3503 PAU3506
COR155 COL10
AC18202 PAC18201 PAC16502 PAC16402
PCOR160 PAU320C1 PAU320C2 PAU320C3 PAU320C4 PAU320C5 PAU320C6 PAU320C7 PAU320C8 PAU320C9 PAU320C10 PAU320C11 PAU320C12 PAU320C13 PAR14702
PAC20 PAR2802 PAC24502 COC250 PAC16101 PAC17301
PAJ1708 PAJ1707 PAU320D1 PAU320D2 PAU320D3COC248
AR15 01 PAR15502COC246
PCOC181 PAU320D4 PAU320D5 PAU320D6 PAU320D7 PAU320D8 PAU320D9 PAU320D10 PAU320D11 PAU320D12 PAU320D13
PAJ40H4 PAJ40H3 PAL10 1 PAL10 2 PAR2801 PAC16102 PAC17302 PAU3504 PAU3505
PAR16002 PAR16001 PAU320E1 PAU320E2 PAU320E3 PAU320E4 PAU320E5 PAU320E6 PAU320E7 PAU320E8 PAU320E9 PAU320E10 PAC25002
PAU320E11 PAU320E12 PAU320E13
COR68 PAC25001
PAC18102 PAC18101 PAU320F1 PAC2460PAU320F2 PAU320F3 PAU320F4 PAU320F5 PAU320F6PAC24801PAC24802
PAU320F7 PAU320F8 PAU320F9 COV1 PAU320F10 PAU320F11 PAU320F12 PAU320F13
PAC24601 PAC16602 PAC160 COC161 COP1
COJ17 PAJ1706 PAJ1705 COR156 PAU320G1
COC249 PAU320G2 PAU320G3 PAU320G4 PAU320G5 PAU320G6 PAU320G7 PAU320G8 PAU320G9 PAU320G10 PAU320G11 PAU320G12 PAU320G13
PAR6802
PAJ4019
PAJ4018 PAR15602 PAR15601
PAU320H1 PAU320H2 PAU320H3 PAU320H4 PAU320H5 PAU320H6
PAR302PAU320H7PAR301PAU320H8 COR3 PAU320H9 PAU320H10 PAU320H11 PAV102PAU320H12 PAU320H13
PAR6801
COU35 COD3
PAJ4017 COU10 COC117 COC137 PAU320J1 PAU320J2 PAU320J3PAC24901PAU320J4PAC2490 PAU320J5
COC16 PAU320J6 PAU320J7 PAU320J8 PAU320J9 PAU320J10 PAU320J11 PAU320J12 PAU320J13
PAJ4016 PAJ1704 PAJ1703 PAU320K1 PAU320K2
COC244COC252
PAU320K3 PAU320K4 PAU320K5 PAU320K6 PAU320K7 PAU320K8 PAU320K9 PAU320K10 PAU320K11 PAU320K12 PAU320K13 PAD30 PAD302 PAD301 PAP101 PAP107
PAJ40H6 PAJ4015 PAC17101 PAC11702
PAJ4014 PAU10013 PAU10012 PAU320L1 PAU320L2 PAU320L3 PAU320L4 PAU320L5 PAC2401 PAU320L6 PAU320L7 PAU320L8 PAC25201
PAU320L9 PAU320L10 PAU320L11 PAU320L12 PAU320L13
PAJ4013 PAU10014 PAU10011
PAC11701 PAC1370 PAC25202 PAP10H1
PAC17102 PAC13702 PAU320M1 PAU320M2 PAU320M3 PAU320M4 PAU320M5 PAC240 PAU320M6 PAU320M7 PAU320M8 PAU320M9 PAU320M10 PAU320M11 PAU320M12 PAU320M13
PAJ4012 PAU10015 PAU10010
PAJ4011
PAJ4010 PAU10016 COC171 PAU1009
PAJ1702 PAJ1701
COU32 PAU320N1 PAU320N2 PAU320N3 PAU320N4 PAU320N5 PAU320N6 PAU320N7 PAU320N8 PAU320N9 PAU320N10 PAU320N11 PAU320N12 PAU320N13 PAD304 PAD305 PAD306 PAP102 PAP108
PAJ409 PAU10017 PAU1008 COD2
PAJ408 PAU10018 PAU1007
PAJ407 COR73
PAJ406 PAU10019 PAU1006 PAP103 PAP109
PAJ40H5 PAJ405 PAU10020 PAU1005 COR48 PAD203 PAD20 PAD201
PAJ404 PAU10021 PAU1004 PAR7302
PAJ403 PAU10022 PAU1003 PAR7301
PAJ402
PAJ401 PAU10023 PAU1002 PAR4801 PAD204 PAD205 PAD206
PAU10024
PAC10601 PAC10602
CO 106 PAU1001 PAP104 PAP1010
PAR4802

PAJ40H2 PAJ40H1 COJ4 COC145PAP105 PAP1011


COC146 PAC14502 PAP10H2
PAJ21013 PAJ2101 PAJ2109 PAJ2107 PAJ2105 PAJ2103 PAJ2101 PAC14602
PAC14601

COJ21 PAC14501 PAP106 PAP1012


PAJ21014 PAJ21012 PAJ21010 PAJ2108 PAJ2106 PAJ2104 PAJ2102
COR85 COC134
PAR8501 PAC13401
COR132
COT4
PAR13202 PAR13201
PAJ10H2 PAR8502 PAC13402
PAT401 PAT402
COR133 COR26 PAR2601PAR2602 PAJ1509 PAJ150H2
PAT403 PAU1904 PAU1903 PAU10AB1 PAU10AA1 PAU10Y1 PAU10W1 PAU10V1 PAU10U1 PAU10T1 PAU10R1 PAU10P1 PAU10N1 PAU10M1 PAU10L1 COC167
PAU10K1 PAU10J1 PAU10H1 PAU10G1PAC16002PAU10F1
PAC16001PAU10E1 PAU10D1 PAU10C1
PAC1201PAU10B1 PAU10A1
COU1
PAU1902
PAR13302 PAR13301 PAJ1015 PAJ105 COR53 PAR5302 PAR5301 PAU1905 PAU1901
COU19 PAU10AB2 PAU10AA2 PAU10Y2 PAU10W2 PAU10V2 PAU10U2 PAU10T2 PAU10R2 PAU10P2 PAU10N2 PAU10M2 PAU10L2
COC160 COC12 PAU10K2 PAU10J2 PAC16702
PAU10H2
PAC16701
PAU10G2 PAU10F2 PAU10E2 PAU10D2 PAU10C2PAC1202PAU10B2 PAU10A2
PAR11901PAR11902 PAJ1501
PAU10AB3 PAU10AA3 PAU10Y3 PAU10W3 PAU10V3 PAU10U3 PAU10T3 PAU10R3 PAU10P3 PAU10N3 PAU10M3 PAU10L3 PAU10K3 PAU10J3 PAU10H3 PAU10G3 PAU10F3 PAU10E3 PAU10D3 PAU10C3 PAU10B3 PAU10A3
PAJ1010 PAR4 02 PAR4 01 PAU1804 PAU1803
COR1 9
PAU1802 PAU10AB4 PAU10AA4 PAU10Y4 PAU10W4 PAU10V4 PAU10U4 PAU10T4 PAU10R4 PAU10P4 PAU10N4 PAU10M4 PAU10L4 PAU10K4 PAU10J4 PAU10H4 PAU10G4 PAU10F4 PAU10E4 PAU10D4 PAU10C4 PAU10B4 PAU10A4
PAJ1014 PAJ104 PAR1501
COR44 PAU1805 PAU1801 COU18 PAU10AB5 PAU10AA5 PAU10Y5 PAU10W5 PAU10V5 PAU10U5 PAU10T5 PAU10R5 PAU10P5 PAU10N5 PAU10M5 PAU10L5 PAU10K5 PAU10J5 PAU10H5 PAU10G5 PAU10F5 PAU10E5 PAU10D5 PAU10C5 PAU10B5 PAU10A5 PAR2101PAR2102 PAJ1502
PAJ109 PAC16801 PAC16802 COR21
COR131 COR15 COC150
PAU10AB6 PAU10AA6 PAU10Y6 PAU10W6 PAU10V6 PAU10U6 PAU10T6 PAU10R6PAC4202
PAC4201 PAU10P6 PAC15201PAC15202
PAU10N6 PAU10M6 PAC70 2PAU10L6 PAC5601PAC5602PAU10K6 PAU10J6 PAC14301PAC14302
PAU10H6 PAU10G6 PAU10F6
PAC6901 PAU10E6 PAU10D6 PAU10C6 PAU10B6 PAU10A6
COT3 PAJ1013 PAJ103
CO 152 COC70 COC56 COC143COC168
PAR13101 PAR13102 PAR1502 PAU10AB7 PAU10AA7 PAU10Y7 PAU10W7 PAU10V7 PAU10U7PAC1502 PAU10T7 PAU10R7
COC24COC42 PAU10P7 PAU10N7 PAU10M7 PAC70 1PAU10L7 PAU10K7 PAU10J7 PAU10H7 PAU10G7 PAU10F7
PAC6902 PAU10E7 PAU10D7 PAU10C7 PAU10B7 PAU10A7
PAJ108 PAC150 PAC2401 PAC240 PAC1001 PAC1002 PAC4902 PAC4901 COC69 PAC901 PAC902
PAU3024 PAU3023PAU302 PAU3021 PAU302 PAU3019PAU3018PAU3017 PAU3016 PAU3015PAU3014PAC3401PAU3013 PAC7102COC23 COC141 COC147 COC148 PAC2702 PAJ1503
PAJ1012 PAJ102 PAR1301 PAU3025
PAU3026
PAC3402PAU3012
PAU3011
PAU10AB8 PAU10AA8 PAU10Y8 PAU10W8 PAU10V8
PAC16901
PAC16902
PAU10U8 PAC20PAU10T8PAC201 PAU10R8 PAU10P8 PAU10N8
PAC7402
PAU10M8 PAU10L8
PAC7101
PAL202PAU10K8PAC14101PAU10J8PAC1402 PAC14202
PAL201
PAU10H8 PAC14201 PAU10G8 PAU10F8PAC7601 PAU10E8 PAU10D8 PAU10C8 PAU10B8 PAU10A8
COU11
PAT303 COU3COC35 COC77 PAU10AB9 PAU10AA9 PAU10Y9 PAU10W9
COC10 COC140
PAU10V9
COL2 COC9
PAU10U9PAC102 PAU10T9 PAC15101PAC15102
PAU10R9 PAU10P9 PAU10N9 PAU10M9 PAU10L9 PAU10K9 PAC2302PAU10J9 PAU10H9 PAU10G9 PAU10F9 PAC7602 PAU10E9 PAU10D9 PAU10C9 PAU10B9 PAU10A9 PAC14702 PAC14802 PAU1106 PAU105 PAU1104PAU1103 PAU102 PAU10
COR13 PAU3027 PAU3010 COC20 COC11 PAC10 PAC12202 PAC12201 PAC2301 PAC4301 PAC4302 PAC14902 PAU1107 PAU11038
PAJ107 PAR1302 PAU3028 COC34
PAU309 PAC7702 PAC701 COR8
COC169
COC48
COC154
COC157COC44COC155
COC156 PAC7401 PAC14002 PAC15801 PAU1108 PAU11037
COC27 PAC2701 PAJ1504
CO 15 COC74 COC49COCC7O1142 COC76 COC43
PAC3501 PAU3029 PAU308 COC2 PAC201 PAU10AB10 PAU10AA10PAC5401PAU10Y10 PAU10W10 PAU10V10 PAU10U10 PAC15302PAU10T10PAC1530 PAU10R10 PAU10P10 PAU10N10 PAU10M10 PAU10L10 PAU10K10 PAU10J10 PAU10H10 PAU10G10 PAU10F10 PAU10E10 PAU10D10 PAU10C10 PAU10B10 PAU10A10
COR69
PAT302 PAT301 PAU3030 PAU307 PAU1704 PAU1701 PAC14001 PAC601 PAU1109 PAU11036 COR49COC1 1
PAJ1011 PAJ101 PAC3502 PAU3031 PAU306 PAU10AB11 PAU10AA11PAC5402PAU10Y11 PAU10W11 PAR802PAU10U11
PAU10V11 PAU10T11 PAU10R11 PAU10P11 PAU10N11 PAU10M11 PAU10L11 PAU10K11 PAU10J11 PAU10H11 PAU10G11 PAU10F11 PAU10E11 PAU10D11 PAU10C11 PAU10B11 PAU10A11 PAU11010 PAU11035
PAR1601 COU17 PAC202 PAC4802 PAC4801 PAC15402 PAC15702PAC4402 PAC4401 COC66 PAC15602PAL301 PAC15502 PAC15802 PAU11011 PAU11034
PAR6901 PAR6902 PAU3032 PAU305 PAC15501 PAC4701 PAC4702 PAC170 2 PAC170 1 PAC14701 PAU11012 PAU11033 PAR5002 PAR4901
PAU3033 COR159COR126
PAU304 PAU1703 PAU1702 PAU10Y12 PAU10W12 PAR801 PAU10G12 PAU10F12 PAU10E12 PAU10D12 PAU10C12 PAU10B12 PAU10A12 PAU11013 PAU11032 PAC11101
PAJ106
PAR1602
COR16 PAC1 802 PAC3602
PAU3034
PAU3035
PAU3036
PAU3049 PAU303
PAU302
PAR15901 PAR15902
PAU301
PAR12602 PAR12601
PAU10AB12 PAU10AA12COC54 PAU10V12 PAU10U12 PAU10T12 PAU10R12 PAC15401PAU10P12 PAU10N12 PAC15701PAC4601
COC50PAU10AB13 PAU10AA13 PAU10Y13PAC5201 PAU10W13 PAU10V13 PAU10U13COC60 PAU10T13 PAU10R13 PAU10P13 PAU10N13
PAU10M12 PAU10L12PAC4602 PAU10K12PAC15601PAL302PAU10J12 PAU10H12
PAU10M13 PAU10L13
COC153 COC12 COL3 COC170 CO 158 PAU10K13 PAU10J13 PAU10H13
PAC6602
PAC6601 COC47 PAU10G13 PAU10F13 PAU10E13 PAU10D13 PAU10C13 PAU10B13 PAU10A13
CO 149 PAC14801
PAC14901 PAC602
PAU11014
PAU11015
PAU11016 PAU11039
PAU11031
PAU11030
PAU11029
PAC11901
PAR5001 PAR4902
PAC1902
COC119
COR50 PAC11102

COJ15
PAJ1505
PAU10AB14 PAU10AA14 PAC5202PAU10Y14 PAU10W14 PAU10V14 PAU10U14 PAU10T14 PAU10R14 PAU10P14 PAU10N14 PCOC46 AU10M14 PAU10L14 PAU10K14 PAU10J14 PAU10H14 PAU10G14 PAU10F14 PAU10E14 PAU10D14 PAU10C14 PAU10B14 PAU10A14 COC92 PAC4101
COC6 PAU11017 PAU11028 PAR1702
PAC11801 PAC3601 PAU307 PAU3038PAU3039 PAU304 PAU3041 PAU3042PAU3043PAU304 PAU3045 PAU3046PAU3047PAU3048 PAC5002 PAC5001 PAC5801 PAC15901 PAC9201PAC9202
PAJ1506
PAU10AB15 PAU10AA15 PAU10Y15 PAU10W15 PAU10V15 PAU10U15 PAU10T15 PAU10R15
PAC6002 PAU10P15 PAU10N15 PAU10M15 PAU10L15 PAU10K15 PAU10J15 PAU10H15 PAU10G15 PAU10F15 PAU10E15 PAU10D15 PAU10C15 PAU10B15 PAU10A15 PAU11018 PAU11027 PAR1701
PAL701 COC52 PAC6001 COC62 PAC5802 PAC15902 PAU11019 PAU11026
PAR1802 PAR1801 PAU10AB16 PAC102PAU10AA16 PAU10Y16 PAU10W16 PAU10V16 PAU10U16 PAU10T16 PAU10R16 PAU10P16 PAU10N16 PAU10M16 PAU10L16 PAU10K16 PAU10J16 PAU10H16 PAU10G16 PAU10F16 PAU10E16 PAU10D16 PAU10C16 PAU10B16 PAU10A16 COC41 PAU1 020 PAU102 PAU1 02 PAU1 023 PAU1024 PAU1025
PAL702 CO 1 8COC36 COR18 PAU10AB17 PAU10AA17
PAC101 PAU10Y17COC1PAU10W17PAC5102PAC5101 PAU10V17 PAU10U17 PAU10T17 PAU10R17 PAU10P17 PAU10N17COC58
PAC6202PAU10M17COC159
PAC6201PAU10L17 PAU10K17 PAU10J17 PAU10H17PAC6501PAC6502PAU10G17 PAU10F17 PAU10E17 PAU10D17 PAU10C17 PAU10B17 PAU10A17
COC65 PAC910 PAC9102
COR17
PATP301 PATP201 PATP101 COC51 PAC4102 COR24 PAR2401PAR2402 PAJ1507
COJ1 COL7 PAU10AB18 PAU10AA18 PAU10Y18 PAU10W18 PAU10V18 PAU10U18 PAU10T18 PAU10R18 PAU10P18 PAU10N18 PAU10M18 PAU10L18 PAU10K18 PAU10J18 PAU10H18 PAU10G18 PAU10F18 PAU10E18 PAU10D18 PAU10C18 PAU10B18 PAU10A18 COC91
PAC5901
COU27 PAU10AB19 PAU10AA19 PAU10Y19 PAU10W19 PAU10V19 PAU10U19 PAU10T19 PAU10R19PAC5902 PAU10P19 PAU10N19 PAU10M19 PAU10L19 PAU10K19 PAU10J19 PAU10H19 PAU10G19 PAU10F19 PAU10E19
COC64 PAU10D19PAC9801PAU10C19
PAC9802
COC98
PAU10B19 PAU10A19
PAU1306PAU1305 PAU1304 PAU1303PAU1302PAU1301
COR120
PAR2501PAR2502 PAJ1508
COTP3 COTP2COTP1 PAC6402
PAU10M20 PAU10L20 PAU10K20 PAU10J20 PAU10H20 PAU10G20PAC6401PAU10F20 PAU10E20 PAU10D20 PAU10C20 PAU10B20 PAU10A20 PAC12102 COR121
PAU2705 PAU2701 AU10R20 PAU10P20 PAU10N20 PAC6302 PAR12001PAR12002 PAJ15010
PAJ10H1 PAU2702
COU20 PAR8702 COU15
PAR8701
PAU10AB20 PAU10AA20 PAU10Y20 PAU10W20 PAU10V20 PAU10U20PAC5501 PAC5502PAU10T20 PCOC59
PAU10AB21 PAU10AA21 PAU10Y21 PAU10W21 PAU10V21 PAU10U21 PAU10T21 PAU10R21 PAU10P21 PAU10N21 PAU10M21 PAU10L21
COC63 COC67 PAU1307
PAU1308
PAU13016
PAU13015
PAC12002 COR25 PAJ150H1
COC55 PAC6102 PAC5702 PAC6301 PAU10K21PAC6701PAC6702PAU10J21 PAU10H21 PAU10G21 PAU10F21 PAU10E21 PAU10D21 PAU10C21 PAU10B21 PAU10A21 COC120 PAR12101PAR12102 PAJ15011
PAU2704 PAU2703 PAU2005 PAU2001
COR87 PAU1505 PAU1501 COC61COC57 COC121PAC12101
COR170 PAU10AB2 PAU10AA22 PAU10Y2 PAU10W2 PAU10V2 PAU10U2 PAC6101PAU10T2 COC53 PAC5701
PAU10R2 PAU10P2 PAU10N2 PAU10M2 PAU10L2 PAU10K2 PAU10J2 PAU10H22 PAU10G2 PAU10F22 PAU10E2 PAU10D22 PAU10C2 PAC9301PAU10B22 PAU10A2 PAU1309PAU13010 PAU130 PAU13012PAU13013PAU13014 PAC12001
PAU2002 PAU1502 PAC501 PAC9302
PAU2004 PAU2003 PAU1504 PAU1503 COC5 PAC6801 PAJ15012
PAU2805 PAU2801 PAR5102 PAR5101
PAU2802 COU28 PAR17002 PAC5302 PAC5301 COC4 COR152
COR151
PAU2804 PAU2803
PAR170 1
COR58 COD9
COC68 PAC6802 PAC502 COC93
COC25 PAR15202 PAR15102
COU13 COR51
COH1 PAR5802 PAC402 PAC401 PAU290A5 PAU290B5 PAU290C5 PAU290D5 PAU290E5 PAR15201 PAR15101 COH3
PAU1605 PAU1601 PAC2502
COU16 PAR5801 PAD90K PAD90A PAC2501
PAU1602 COR1 PAU290A4 PAU290B4 PAU290C4 PAU290D4 PAU290E4
PAU1604 PAU1603 PAR6701 PAU3603 PAU3602 PAU3601 PAU3905 PAU3904
PAR16801 PAU290A3 PAU290B3 PAU290C3 PAU290D3 PAU290E3
PAR6702 PAU3906 PAU3903
PAJ60F1 PAJ605 PAR16802
COR67 PAR702 PAR701 PAR102 PAR101 COU29
PAU290A2 PAU290B PAU290C2 PAU290D2 PAU290E2
COU36 COU39 PAU3907 PAU3902
PAU2103 PAU2104 PAU3604 PAU3COC175
605 PAU360 PAU3908 PAU3901
PAU2102 PAU290A1 PAU290B1 PAU290C1PAC2602PAU290D1
PAC2601 PAU290E1
COR168 COR7
PAJ604 PAU2101 PAU2105 PAU50E1 PAU50D1 PAU50C1 PAU50B1 PAC17502 PAC17501
PAU50E2 PAU50D2 PAU50C2 PAU50B2 PAU50A2
COU21
PAH101 COC26 PAH301
PAU50E3 PAU50D3 PAU50C3 PAU50B3 PAU50A3 COU5
PAJ607 PAC1402
PAU50E4 PAU50D4 PAU50C4 PAU50B4 COC14 PAU50A4
PAC1401 COJ5
PAU50E5 PAU50D5 PAU50C5 PAU50B5 PAU50A5 COTP8 PATP801
PAJ603 PAJ606 PAJ501 PAJ502 PAJ1201
PAJ1202
PAJ608 PATP701 COTP7 PATP601 COTP6 PATP401 PAJ1203
COTP4 PAJ503 PAJ504 PAJ1204
PAJ602 COH8 PAJ1205 COC37 PAC3702 PAC3701
PATP501
PAJ505 PAJ506
COTP5 PAJ1206
PAJ60F2 PAJ601 PAJ507 PAJ508 PAJ1207 PAC3802 PAU1401
COJ6 PAJ1208 COC38 PAC3801
PAU1402
PAJ509 PAJ5010 PAJ1209 PAU1403
PAH801 PAJ12010 COR20 PAU1404 COU14
PAR2002
PAR1901 PAR1902 PAR2001 PAU1405
COU2
COR19
COC102 PAC10202 PAC10201 PAU1406
PAU1408
PAU2024 PAU2025 COJ12 PAC3901
PAU2023 PAU2026 PAU1407
PAU2022 PAU2027 PAC3902
PAU2021 PAU2028 COC39
PAU2020 PAU2029
PAU2019 PAU2030
PAU2018 PAU2031
PAU2017 PAU2032
PAU2016 PAU2033
PAU2015 PAU2034
PAU2014 PAU2035 COC185 PAR16302 PAR1630 COR163 PAC10 01 COR128
PAU2013 PAU2036 PAC18502 PAC18501 PAR12801
PAJ801 PAJ802 PAU2012
PAU2011
PAU2037
PAU2038 PAU38019 PAU38018PAU38017 PAU38016 AU38015P PAU38014PAU38013PAU38012 PAU3801
COC10 PAC10 02 COD1 PAR12802 COJ18
PAU2010 PAU2039
PAU209 PAU2040 PAU38020
PAU208 PAU2041
PAU207 PAU2042
PAR1 802 PAR1 801 PAJ803 PAJ804 PAU206
PAU205
PAU2043
PAU2044
PAU38021 COU38 COC99 PAC9 02 PAC9 01 PAD103PAD102 PAD10 PAJ1801
PAU204 PAU2045
PAR9802 PAR9801 PAU203 PAU2046 PAU3801PAU3805
PAU202 PAU2047 PAU3802 PAU3803PAU3804 PAU3806 PAU3807PAU3808PAU3809 PAU3801
COR1 8
COR98 PAR11702 PAR11701 PAJ805 PAJ806 PAU201 PAU2048
COC40 PAC40 2 PAC40 1 PAD104PAD105 PAD106
COR129 PAJ1802
PAC18402 PAC18401
PAR9702 PAR9701 PAR12902
COC184 PAD1403 PAJ1803
PAR12901
PAR11602 PAR11601
COR97COR1 7 PAJ807 PAJ808 COD14 PAJ1804
COR1 6 PAR9602 PAR9601 PAD1401 PAD1402
COR96 PAR1 502 PAR1 501 PAJ809 PAJ8010
COR1 5 PAR9502 PAR9501 COC3 PAC302 PAC301
COR95 PAR11402 PAR11401 PAJ8011 PAJ8012
COR94COR1 4 PAR9402

PAR11302
PAR9401

PAR11301
PAB100 PAC702
PAJ8013 PAJ8014 PAU1201
COR1 3 PAR9302 PAR9301
COC7 PAC701 PAU1202
COR93 PAR1 202 PAR1 201 PAJ8015 PAJ8016 PAB10H1 PAU1203
COR1 2 PAR9202 PAR9201 PAR402 PAU1204 COU12
COR92 PAR1 102 PAR1 101 PAJ8017 PAJ8018 COU8 COR4 PAR401
PAU1205 PAU1208
PAU8024 PAU8025 COB1
COR1 1 PAR9102 PAR9101 PAU8023 PAU8026 COU30 PAC801 PAR202 PAU1206
PAU8022 PAU8027
COR91 PAU8021 PAU8028 PAC802 PAR201
PAR11002 PAR11001 PAJ8019 PAJ8020 PAU8020 PAU8029 PAU1207
PAU8019 PAU8030 PAU3004 PAU3003
PAU8018 PAU8031 PAU3002
PAR9002 PAR9001 PAU8017 PAU8032 COC8COR2
PAU8016 PAU8033 PAU3005 PAU3001 PAB10H2
PAU8015 PAU8034
COR90COR1 0 PAR10902 PAR10901 PAU8014 PAU8035 PAC1701
PAJ8021 PAJ8022 PAU8013 PAU8036
PAU8012 PAU8037
PAR7102 PAR7101 PAU8011 PAU8038 PAC1702
COR109
COR71 PAU8010
PAU809
PAU8039
PAU8040
PAU3104 PAU3103
COC16 PAC1601 PAC1602 COC17
PAR10802 PAR10801 PAU808 PAU8041 PAU3102 COJ2
PAJ8023 PAJ8024 PAU807 PAU8042 PAU3105 PAU3101
PAU806 PAU8043 COC15 PAC1501 PAC1502
PAU805 PAU8044
PAR4502 PAR4501 PAU804 PAU8045 PAB100
COR108 PAU803 PAU8046 COU31
COR45 PAU802 PAU8047
PAR10702 PAR10701 PAJ8025 PAJ8026 PAU801 PAU8048 COC13 PAC1301 PAC1302
COR107 PAR4302 PAR4301
COR43 PAR10602 PAR10601
COC88
COL6 COC87 PAJ2202
COL1
PAJ8027 PAJ8028 PAU9024 PAU9025
PAU9023 PAU9026 COC89 PAJ2201 PAC8801PAL601 PAL101 PAC8701 COL11
PAL1101
PAR4202 PAR4201 PAU9022 PAU9027
PAU9021 PAU9028 PAC8802PAL602 PAL102 PAC8702
PAU9020 PAU9029 COC84
COL8
PAU9019 PAU9030 PAL1102
COR42COR106 PAR10502 PAR10501 PAJ8029 PAJ8030 PAU9018
PAU9017
PAU9031
PAU9032
COLOGO1 COU37 COC83
COC82
COL9 PAU3705PAU3704PAU3703 PAU3702 PAU3701
PAU9016 PAU9033 COC85
COC94 PAC8401
PAR4102 PAR4101 PAU9015 PAU9034 PAU3706 PAU37020
PAU9014 PAU9035 PAU3707 PAU37019 PAC8402
COR105
COR41 PAR10402 PAR10401 PAJ8031 PAJ8032 PAU9013
PAU9012
PAU9036
PAU9037 COC86 PAU3708
PAU3709
PAU37018
PAU37017 PAC8502
PAU9011 PAU9038
PAR4002 PAR4001
PAU9010
PAU909
PAU9039
PAU9040
COR47 PAU37021 PAC8201PAC8301 PAC83202 PAU37010 PAU37016 PAC8501
PAU908 PAU9041 PAU3701 PAU37012PAU37013 PAU37014 PAU37015
PAU907 PAU9042 PAR4701 PAC8602PAC8601
PAR10302 PAR10301 PAU906 PAU9043 PAR4702
COR40COR104 PAJ8033 PAJ8034 PAU905
PAU904
PAU9044
PAU9045
PAC9402 PAL901 PAL801 PAC8902
PAJ1902
PAU903 PAU9046
PAR3902 PAR3901 PAU902 PAU9047 COC179 PAC9401 PAL902 PAL802 PAC8901
PAU901 PAU9048
COR39COR103 PAR10202 PAR10201 PAJ8035 PAJ8036 COU9
COSerial1 PAC17902 PAC17901 PAJ1901
COR102 PAR3802 PAR3801
COR38 PAR10102 PAR10101 PAJ8037 PAJ8038 COH5
COR101 PAR3702 PAR3701
COR37 PAR10002 PAR10001 PAJ8039 PAJ8040 PAU2504 PAU250
PAC9001 COU25 COJ19
COR10 PAC90 2 COC90
PAU2503PAU2502 PAU2501
PAR9902 PAR9901

COR99 PAJ8041 PAJ8042 PAH501


PAU2 04 PAU2 05 PAU2404 PAU2405 COR127 COR148
PAJ8043 PAJ8044 COJ8 COT5 COU22 COU24 COT2 COT1 COT6
PAU4204 PAU4205 PAR12702 PAR12701 PAR14801 PAR14802
COC144 PAU2 03 PAU2 02 PAU2 01 PAU2403 PAU2402PAU2401 PAU4104 PAU4105

PAT508 PAT507 PAT506 PAT505 PAC14401


PAT203 PAT102 PAT101 PAT603
PAU2604 PAU2605 PAU2304 PAU2305 PAU4203 PAU4202PAU4201 COU42 PAU4103PAU4102 PAU4101 COU41
PAS103 PAC14402 COU26 COT8PAT10 2 COR125 PAT201 PAT202 COR123 PAT103 PAT601
COC75PAT602
PAU2603 PAU2602 PAU2601 PAU2303 PAU2302PAU2301 COT10COU23PAT101 PAT801 PAT802 PAR12501 PAR12502 COR122
PAR12301 PAR12302
COR145
PAC7501 PAC7502
COR134 COC73 PAR14501 PAR14502
PAU40 4 PAU40 5 PAU604 PAU605 COR46 PAT10 3 COR14 PAT803 PAR12 02 PAR12201 COS2
COC180 PAR13402 PAR13401
COR138PAT501 COR135
PAT502 COR136
PAT503 PAT504COC139 PAC7301 PAC7302
PAC8102PAR4602 PAC7802 PAR1402 COJ20
PAS102 PAR17501 PAR17401 PAR17301 PAR17201 PAR17101
PAR13801 PAR13501 PAR13502COR137
PAR13602 PAR13601PAC13902 PAU40 3PAU40 2 PAU40 1 PAU603PAU602 PAU601
COU40 COU6 PAC8101PAR4601 COC81 PAC7801 PAR1401
COC78 PAC18001 PAU3 010PAU3 09 PAU308 PAU307 PAU3 06 COR124 PAS203 PAS206
PAR17502 PAR17402 PAR17302 PAR17202 PAR17102 COR140 PAR12402
PAR13802 PAU3401 PAU3408 PAR13701 PAR13702PAC13901 COT9 PAT901 COT7PAT902 PAT701 PAT702
COS1 PAU33011 PAR12401 PAJ2002 PAJ2001
PAR14001 PAU3402 PAU3407 PAR16901 PAR16701 PAR16601 PAR16501 PAR16401 PAC18002
COD5 COR175
COR174
COR173
COR172
COR171
COR141 PAU3 01PAU3 02 PAU30 PAU304 PAU3 05 PAS202 PAS205
PAF102 PAR14002 PAU3403 PAU3406 COU34 PAR16902 PAR16702 PAR16602 PAR16502 PAR16402
PAD502 PAD501 PAL501 PAL504 PAU3404 COR139
PAU3405 PAT903
PAR14101
PAS101 COC135 COR86 PAR14102
COR23
PAR13901 PAR13902
PAT703 COR22
COC45 COR166
COR169COR167 COR165
COR164 COC72 COU33
PAC80 2 PAR2302 PAC7902PAR2202 PAS201 PAS204
COC80 PAC8001 PAR2301 PAC7901PAR2201

COJ11 PAF101COL5 PAC13502 PAC13501 PAR8601 PAR8602 PAC4502COC79PAC4501 PAC7202 PAC7201


PAJ1101 COF1
COJ3 COJ7
PAL502 PAL503 PAJ301 PAJ302 PAJ303 PAJ304 PAJ305 PAJ701 PAJ702 PAJ703 PAJ704 PAJ705
COH2

PAJ110H1 PAJ110H2
PAJ30H2 PAJ306 PAJ307 PAJ308 PAJ309
PAJ30H1 PAJ70H2 PAJ706 PAJ707 PAJ708 PAJ709
PAJ70H1
COPM5
COPM6 PAS10F1 PAS10F2 COPM1
COPM3

PAJ1102 PAJ1103 PAPM650


PAH201 PAPM100
PAPM300
MEGA65 R2 SCHEMATICS

AB-28
1 2 3 4
U_HDMI U_B15 U_POWER
HDMI.SchDoc B15.SchDoc POWER.SchDoc

U_Ethernet U_B16 U_PowerMain COPM1


PM1 COPM2
PM2 COPM3
PM3
Ethernet.SchDoc B16.SchDoc PowerMain.SchDoc

U_B34 U_VGA
B34.SchDoc VGA.SchDoc
A A
U_LED_SW_BUT U_FPGA-CFG U_EXT_HEADER
LED_SW_BUT.SchDoc FPGA-CFG.SchDoc EXT_HEADER.SchDoc FIDU-DOT - small FIDU-DOT - small FIDU-DOT - small

U_SYS_MAX10_CTRL U_FPGA-MGT U_EXP_Slot


SYS_MAX10_CTRL.SchDoc FPGA-MGT.SchDoc EXP_Slot.SchDoc COPM4
PM4 COPM5
PM5 COPM6
PM6

U_SOUND U_FPGA-PWR U_Floppy


SOUND.SchDoc FPGA-PWR.SchDoc Floppy.SchDoc

U_B13 U_JOY
B13.SchDoc JOY.SchDoc
FIDU-DOT - small FIDU-DOT - small FIDU-DOT - small
U_B14 U_KEYBOARD
B14.SchDoc KEYBOARD.SchDoc

B COSerial1 B
Serial1
Serial
Serialnumber 6,3 x 6.3mm

COS0N1
S/N1
1
PIS0N101 0R 2
PIS0N102

Serialnumber

C C

COH5 COH7 COH8 COH1 COH2 COH3

Title:
MEGA65
D D
Number: Rev.
PIH501 PIH701 PIH801 PIH10 PIH201 PIH301 A4 TE0765
Default 02
GND GND GND GND GND GND
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page1 of 23
Mount.Hole 3.2mm Mount.Hole 3.2mmMount.Hole 3.2mm Mount.Hole 3.2mm Mount.Hole 3.2mm Mount.Hole 3.2mm
Filename: TE0765.SchDoc
1 2 3 4
1 2 3 4

PMOD CONN
COD1
D1
1PID101 5
PID105 3.3V COD2 COD3
GROVE_SCL0 3PID103 D2 D3
Grove CONN NLB350L20N
B35_L2_N 1
PID201 5
PID205 B35_L5_N 1
PID301 5
PID305
A NLB350L20P 3.3V 3.3V A
GROVE_SDA0 4PID104 B35_L2_P 3
PID203 B35_L5_P 3
PID303
6PID106 2
PID102 GND NLB350L10P
B35_L1_P 4
PID204 B35_L3_P 4
PID304
WE-TVS-824013 NLB350L10N
B35_L1_N 6
PID206 2
PID202 B35_L3_N 6
PID306 2
PID302
COJ18 GND GND
J18
COR128
R128PIR12801 PIR12802 4K7 NLGrove0SCL0
GROVE_SCL0 1
PIJ1801 WE-TVS-824013 WE-TVS-824013
3.3V COR129 NLGrove0SDA0
R129PIR12901 PIR12902
4K7 GROVE_SDA0 2
PIJ1802
3
PIJ1803
3.3V COP1
4
PIJ1804 P1
GND NLB350L50N NLB350L50P
B35_L5_N 1
PIP101 7
PIP107 B35_L5_P
110990037 NLB350L30N
B35_L3_N 2
PIP102 8
PIP108
NLB350L30P
B35_L3_P
B35_L2_N 3
PIP103
9
PIP109 B35_L2_P
B35_L1_N 4
PIP104 10
PIP1010 B35_L1_P
5
PIP105 11
PIP1011
GND GND GND GND
6
PIP106 12
PIP1012
PMOD1_VCC PIC14501 PIC14601 VCC VCC PMOD1_VCC
COC145
C145 COC146
C146 PMod 2x6 SMD Host Socket 90°
10µF 470nF
PIC14502 PIC14602
10V
B COP2 B
GND GND P2
B35_L6_P 1
PIP201
7
PIP207
B35_L4_P
B35_L6_N 2
PIP202
8
PIP208 B35_L4_N
NLB350L120P
B35_L12_P 3
PIP203 9
PIP209
NLB350L120N
B35_L12_N
NLB350L100N
B35_L10_N 4
PIP204 10
PIP2010
NLB350L100P
B35_L10_P
CPLD CONFIG 5 11
GND PIP205 GND GND PIP2011 GND
6 12
PMOD2_VCC PIC16201 PIC16301 PIP206 VCC VCC PIP2012 PMOD2_VCC
COJ17
J17 COC162
C162 COC163
C163 PMod 2x6 SMD Host Socket 90°
CPLD_JTAG i NLM0TCK
M_TCK 1
PIJ1701 2
PIJ1702
PIC1620
10µF PIC16302 470nF
PIR15602 NLM0TDO
M_TDO 3
PIJ1703 4
PIJ1704
10V
COR156
R156 NLM0TMS
M_TMS 5 6 PIC13701 3.3V GND GND
PIJ1705 PIJ1706
4K7 7 8 COC137
C137 COD4
D4 COD11
D11
PIJ1707 PIJ1708
PIR15601 NLM0TDI
M_TDI 9
PIJ1709 10
PIJ17010 PIC13702 470nF NLB350L40N
B35_L4_N 1PID401 5
PID405 B35_L10_P 1PID1101 PID11055
NLB350L60N 3.3V 3.3V
B35_L6_N 3PID403 B35_L10_N 3PID1103
GND SMD-254-9132-14-10 GND GND
NLB350L60P
B35_L6_P 4PID404 B35_L12_P 4PID1104
NLB350L40P
B35_L4_P 6PID406 PID402
2 B35_L12_N 6PID1106 2
PID1102
GND GND
C C
WE-TVS-824013 WE-TVS-824013

COU35
U35
7
PIU3507
8
PIU3508
3.3V IN OUT1 PMOD2_VCC
PIC16401
COC164
C164 COR146
R146 NLPMOD20FLG
PMOD2_FLG 2 5
PIR14601 PIR1460210K PIU3502 FLG1 OUT2 PIU3505 PMOD1_VCC
10µF
PIC16402 COR147
R147
PIR14701 PIR1470210K
NLPMOD10FLG
PMOD1_FLG 3
PIU3503
10V NLPMOD20EN FLG2
TE0790-Base SMT PMOD2_EN 1
PIU3501
NLPMOD10EN EN1
GND PMOD1_EN 4
PIU3504
COJB1 EN2
JB1
5
PIJB105 6
PIU3506
3.3V GND
6
PIJB106
TE_JTAG i VIO PIC13801 3.3V
GND AP2196SG-13
UART COC138
NLTE0TCK
TE_TCK 4
PIJB104 TCK
3
PIJB103
NLTE0UART0RX
TE_UART_RX C138
NLTE0TDO C A NLTE0UART0TX 470nF
PIR15702 TE_TDO 8
PIJB108 TDO
7 TE_UART_TX PIC13802
COR157
R157 D B PIJB107
NLTE0TDI
TE_TDI 10
PIJB1010 F TDI
9 PIR15802
4K7 E PIJB109 R158
NLTE0TMS
TE_TMS 12
PIJB1012 H TMS
11
PIJB1011
COR158GND Title:
PIR15701 G 10K MEGA65
1
PIJB101 PIR15801
D GND GND D
GND 2
PIJB102 GND GND
H1
PIJB10H1
Number: Rev.
GND GND A4 TE0765
GND 02
Default
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page2 of 23

Filename: EXT_HEADER.SchDoc
1 2 3 4
1 2 3 4

5V COU2
U2 COU8
U8
NLC640IRQ
C64_IRQ COR37
R37PIR3701
4K7
PIR3702
31
PIU2031
7
PIU207
31
PIU8031
7
PIU807
NLC640RW COR38 3.3V VCCA VCCB 5V 3.3V VCCA VCCB 5V
C64_RW R38PIR3801 4K7
PIR3802 EXP 42
PIU2042 18
PIU2018 EXP 42
PIU8042 18
PIU8018
NLC640CLOCK COR39 VCCA VCCB VCCA VCCB
C64_CLOCK R39PIR3901 4K7
PIR3902 i EXP i EXP
NLC640IO1
C64_IO1 COR40
R40PIR4001 4K7
PIR4002
A CART i i i A
C64_GAME COR41
R41PIR4101 4K7
PIR4102
NLF0DATA0DIR
F_DATA_DIR 1
PIU201 48
PIU2048
NLF0DATA0EN
F_DATA_EN NLF0CTRL0DIR
F_CTRL_DIR 1
PIU801 48
PIU8048
NLF0CTRL0EN
F_CTRL_EN
1DIR 1OE i CART 1DIR 1OE i CART
C64_EXROM COR42
R42PIR4201
4K7
PIR4202
NLC640IO2 COR43 NLF0C640D7 CART i NLF0C640RW
C64_IO2 R43PIR4301 4K7
PIR4302 F_C64_D7 47
PIU2047 2
PIU202 C64_D7 F_C64_RW 47
PIU8047 2
PIU802 C64_RW
NLC640ROMLCOR45 NLF0C640D6 1A1 1B1 NLF0C640ROMH 1A1 1B1
C64_ROML R45PIR4501 4K7
PIR4502 F_C64_D6 46
PIU2046 3
PIU203 C64_D6 F_C64_ROMH 46
PIU8046 3
PIU803 C64_ROMH
NLC640BA COR71 DATA i NLF0C640D5 1A2 1B2 NLF0C640IO1 1A2 1B2
C64_BA R71PIR7101 4K7
PIR7102 F_C64_D5 44
PIU2044 5
PIU205 C64_D5 F_C64_IO1 44
PIU8044 5
PIU805 C64_IO1
NLC640DMA COR90 NLF0C640D4 1A3 1B3 1A3 1B3
C64_DMA R90PIR9001 4K7
PIR9002 F_C64_D4 43
PIU2043 6
PIU206 C64_D4 43
PIU8043 6
PIU806
NLC640D7 COR91 NLF0C640D3 1A4 1B4 1A4 1B4
C64_D7 R91PIR9101
4K7
PIR9102
F_C64_D3 41
PIU2041
8
PIU208
C64_D3 41
PIU8041
8
PIU808
NLC640D6 COR92 NLF0C640D2 1A5 1B5 NLF0C640IO2 1A5 1B5
C64_D6 R92PIR9201 4K7
PIR9202 F_C64_D2 40
PIU2040 9
PIU209 C64_D2 F_C64_IO2 40
PIU8040 9
PIU809 C64_IO2
NLC640D5 COR93 NLF0C640D1 1A6 1B6 NLF0C640ROML 1A6 1B6
C64_D5 R93PIR9301 4K7
PIR9302 F_C64_D1 38
PIU2038 11
PIU2011 C64_D1 F_C64_ROML 38
PIU8038 11
PIU8011 C64_ROML
NLC640D4 COR94 NLF0C640D0 1A7 1B7 NLF0C640BA 1A7 1B7
C64_D4 R94PIR9401 4K7
PIR9402 F_C64_D0 37
PIU2037 12
PIU2012 EXP C64_D0 F_C64_BA 37
PIU8037 12
PIU8012 EXP C64_BA
NLC640D3 COR95 1A8 1B8 1A8 1B8
C64_D3 R95PIR9501 4K7
PIR9502 i i
NLC640D2
C64_D2 COR96
R96PIR9601
4K7
PIR9602
NLF0LADDR0DIR
F_LADDR_DIR 24
PIU2024
25
PIU2025
NLF0ADDR0EN
F_ADDR_EN NLF0HADDR0DIR
F_HADDR_DIR 24
PIU8024
25
PIU8025
F_ADDR_EN
NLC640D1 COR97 2DIR 2OE i CART 2DIR 2OE i CART
C64_D1 R97PIR9701 4K7
PIR9702
NLC640D0
C64_D0 COR98
R98PIR9801 4K7
PIR9802
NLF0C640A7
F_C64_A7 36
PIU2036 13
PIU2013 C64_A7 NLF0C640A15
F_C64_A15 36
PIU8036 13
PIU8013 C64_A15
NLF0C640A6 2A1 2B1 NLF0C640A14 2A1 2B1
F_C64_A6 35
PIU2035 14
PIU2014 C64_A6 F_C64_A14 35
PIU8035 14
PIU8014 C64_A14
ADR i NLF0C640A5 2A2 2B2 ADR i NLF0C640A13 2A2 2B2
F_C64_A5 33
PIU2033
16
PIU2016
C64_A5 F_C64_A13 33
PIU8033
16
PIU8016
C64_A13
NLF0C640A4 2A3 2B3 NLF0C640A12 2A3 2B3
F_C64_A4 32
PIU2032
17
PIU2017
C64_A4 F_C64_A12 32
PIU8032
17
PIU8017
C64_A12
NLF0C640A3 2A4 2B4 NLF0C640A11 2A4 2B4
F_C64_A3 30
PIU2030 19
PIU2019 C64_A3 F_C64_A11 30
PIU8030 19
PIU8019 C64_A11
NLF0C640A2 2A5 2B5 NLF0C640A10 2A5 2B5
F_C64_A2 29
PIU2029 20
PIU2020 C64_A2 F_C64_A10 29
PIU8029 20
PIU8020 C64_A10
B NLF0C640A1 2A6 2B6 NLF0C640A9 2A6 2B6 B
F_C64_A1 27
PIU2027 22
PIU2022 C64_A1 F_C64_A9 27
PIU8027 22
PIU8022 C64_A9
NLF0C640A0 2A7 2B7 NLF0C640A8 2A7 2B7
F_C64_A0 26
PIU2026
23
PIU2023
C64_A0 F_C64_A8 26
PIU8026
23
PIU8023
C64_A8
2A8 2B8 2A8 2B8
3.3V COU30
U30 28
PIU2028 4
PIU204 28
PIU8028 4
PIU804
GND GND GND GND
1
PIU3001 5
PIU3005 34
PIU2034 10
PIU2010 34
PIU8034 10
PIU8010
NLC640EXROM OE VCC 3.3V GND GND GND GND
C64_EXROM 2
PIU3002 39
PIU2039 15
PIU2015 39
PIU8039 15
PIU8015
A NLF0C640EXROM GND GND GND GND
3 4
PIU3004
F_C64_EXROM 45
PIU2045
21
PIU2021
45
PIU8045
21
PIU8021
GND PIU3003 GND Y i EXP GND GND GND GND GND GND GND GND
NC7SZ126P5X SN74LVCH16T245DGV SN74LVCH16T245DGV
COJ8
J8
44 43
PIJ8043
COU9 GND PIJ8044 GND
3.3V COU31
U31 U9 42
PIJ8042
41
PIJ8041
C64_ROMH
1
PIU3101 OE VCC
5
PIU3105
31
PIU9031
7
PIU907
40
PIJ8040
39
PIJ8039
C64_RESET
NLC640GAME 3.3V 3.3V VCCA VCCB 5V 5V
C64_GAME 2
PIU3102 42
PIU9042 18
PIU9018 C64_IRQ 38
PIJ8038 37
PIJ8037 C64_NMI
A NLF0C640GAME VCCA VCCB
3 4
PIU3104 F_C64_GAME EXP C64_RW 36
PIJ8036 35
PIJ8035 C64_O2
GND PIU3103 GND Y i EXP
i C64_CLOCK 34
PIJ8034 33
PIJ8033 C64_A15
NC7SZ126P5X 1
PIU901
48
PIU9048
C64_IO1 32
PIJ8032
31
PIJ8031
C64_A14
GND 1DIR 1OE GND
C64_GAME 30
PIJ8030
29
PIJ8029
C64_A13
NLF0C640NMI
F_C64_NMI 47
PIU9047 2
PIU902 C64_NMI C64_EXROM 28
PIJ8028 27
PIJ8027 C64_A12
C CART i NLF0C640IRQ 1A1 1B1 C
F_C64_IRQ 46
PIU9046 3
PIU903 C64_IRQ C64_IO2 26
PIJ8026 25
PIJ8025 C64_A11
CART i NLF0C640DMA 1A2 1B2
5V F_C64_DMA 44
PIU9044 5
PIU905 C64_DMA C64_ROML 24
PIJ8024 23
PIJ8023 C64_A10
NLC640ROMH COR99 CART i NLFB0RIGHT 1A3 1B3 NLJB0RIGHT
C64_ROMH R99PIR9901
4K7
PIR9902
FB_RIGHT 43
PIU9043
6
PIU906
JB_RIGHT C64_BA 22
PIJ8022
21
PIJ8021
C64_A9
NLC640RESET COR100 NLFB0LEFT 1A4 1B4 NLJB0LEFT
C64_RESET R100
PIR10001
4K7
PIR10002
FB_LEFT 41
PIU9041
8
PIU908
JB_LEFT C64_DMA 20
PIJ8020
19
PIJ8019
C64_A8
NLC640NMI COR101 NLFB0DOWN 1A5 1B5 NLJB0DOWN
C64_NMI R101
PIR10101 4K7
PIR10102 FB_DOWN 40
PIU9040 9
PIU909 JB_DOWN C64_D7 18
PIJ8018 17
PIJ8017 C64_A7
NLC640O2 COR102 NLFB0FIRE 1A6 1B6 NLJB0FIRE
C64_O2 R102PIR10201 4K7
PIR10202 FB_FIRE 38
PIU9038 11
PIU9011 JB_FIRE C64_D6 16
PIJ8016 15
PIJ8015 C64_A6
NLC640A15 COR103 NLFB0UP 1A7 1B7 NLJB0UP
C64_A15 R103
PIR10301 4K7
PIR10302 FB_UP 37
PIU9037 12
PIU9012 JB_UP C64_D5 14
PIJ8014 13
PIJ8013 C64_A5
NLC640A14 COR104 1A8 1B8
C64_A14 R104
PIR10401
4K7
PIR10402
C64_D4 12
PIJ8012
11
PIJ8011
C64_A4
NLC640A13
C64_A13 COR105
R105
PIR10501
4K7
PIR10502
24
PIU9024
25
PIU9025
C64_D3 10
PIJ8010
9
PIJ809
C64_A3
NLC640A12 COR106 3.3V 2DIR 2OE GND
C64_A12 R106PIR10601
4K7
PIR10602
C64_D2 8
PIJ808
7
PIJ807
C64_A2
NLC640A11
C64_A11 COR107
R107
PIR10701 4K7
PIR10702
NLF0C640RESET
F_C64_RESET 36
PIU9036 13
PIU9013 C64_RESET C64_D1 6
PIJ806 5
PIJ805 C64_A1
NLC640A10 COR108 CART i NLF0C640CLOCK 2A1 2B1
C64_A10 R108
PIR10801
4K7
PIR10802
F_C64_CLOCK 35
PIU9035
14
PIU9014
C64_CLOCK C64_D0 4
PIJ804
3
PIJ803
C64_A0
NLC640A9 COR109 CART i NLF0C640O2 2A2 2B2
C64_A9 R109
PIR10901
4K7
PIR10902
F_C64_O2 33
PIU9033
16
PIU9016
C64_O2 2 1
PIJ801
NLC640A8 COR110 CART i NLF0SER0ATN 2A3 2B3 NLSER0ATN GND PIJ802 GND
C64_A8 R110
PIR11001
4K7
PIR11002
F_SER_ATN 32
PIU9032
17
PIU9017
SER_ATN
NLC640A7 COR111 NLF0SER0RESET 2A4 2B4 NLSER0RESET
C64_A7 R111
PIR11101 4K7
PIR11102 F_SER_RESET 30
PIU9030 19
PIU9019 SER_RESET 120-044-60
NLC640A6 COR112 NLF0MOTEB 2A5 2B5 NLMOTEB
C64_A6 R112
PIR11201
4K7
PIR11202
F_MOTEB 29
PIU9029
20
PIU9020
MOTEB
2A6 2B6
NLC640A5
C64_A5 COR113
R113
PIR11301
4K7
PIR11302
NLF0DRVSB
F_DRVSB 27
PIU9027
22
PIU9022
NLDRVSB
DRVSB Title:
NLC640A4 COR114 2A7 2B7
C64_A4 R114
PIR11401
4K7
PIR11402
26
PIU9026
23
PIU9023 MEGA65
NLC640A3 COR115 GND 2A8 2B8
C64_A3 R115
PIR11501
4K7
PIR11502
D NLC640A2 COR116 D
C64_A2 R116
PIR11601
4K7
PIR11602
28
PIU9028
4
PIU904
Number: Rev.
NLC640A1 COR117 i GND GND A4 TE0765
C64_A1 R117
PIR11701 4K7
PIR11702 34
PIU9034 10
PIU9010 02
GND GND Default
NLC640A0
C64_A0 COR118
R118
PIR11801
4K7
PIR11802
EXP 39
PIU9039
15
PIU9015
GND GND
45
PIU9045
21
PIU9021
GND GND GND GND Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page3 of 23
SN74LVCH16T245DGV
Filename: EXP_Slot.SchDoc
1 2 3 4
1 2 3 4

A A

B13
i
COU1A
U1A
BANK 13 AB11
PIU10AB11
NLB4
B4
IO_L7P_T1_13 NLB2
V16
PIU10V16 AB12
PIU10AB12 B2
3.3V VCCO_13 IO_L7N_T1_13 NLVDAC0CLK
PIC5101 PIC5201 PIC5401 COC1
PIC101C1 PIC50COC50
1C50 PIC201 W13
PIU10W13 AA9
PIU10AA9 VDAC_CLK
COC51
C51 COC52
C52 COC54
C54 COC2
C2 VCCO_13 IO_L8P_T1_13 NLB6
Y10
PIU10Y10 AB10
PIU10AB10 B6
PIC5102 470nF PIC5202 470nF PIC5402 470nF PIC1024.7µF PIC50 24.7µF PIC202 47µF VCCO_13 IO_L8N_T1_13 NLB7
AA17
PIU10AA17
AA10
PIU10AA10
B7
VCCO_13 IO_L9P_T1_DQS_13 NLB3
AB14
PIU10AB14
AA11
PIU10AA11
B3
VCCO_13 IO_L9N_T1_DQS_13 NLVDAC0SYNC0N
GND V10
PIU10V10 VDAC_SYNC_N COR159 3.3V
NLR3 IO_L10P_T1_13 NLB0 NLCPLD0CLK R159
R3 Y17
PIU10Y17 W10
PIU10W10 B0 CPLD_CLK PIR15901 PIR15902 COC77
C77
B B13 i IO_0_13 IO_L10N_T1_13 NLB5 B
Y11
PIU10Y11 B5 22R PIC7701 PIC7702
IO_L11P_T1_SRCC_13 NLB1 GND
Y12
PIU10Y12
B1 1%
NLR4 IO_L11N_T1_SRCC_13 470nF
R4 Y16
PIU10Y16
W11 NLVDAC0BLANK0N
PIU10W11
VDAC_BLANK_N
B13 i NLR6 IO_L1P_T0_13 IO_L12P_T1_MRCC_13 NLHSYNC COU17
R6 AA16
PIU10AA16 W12
PIU10W12 HSYNC COR126 U17
NLR7 IO_L1N_T0_13 IO_L12N_T1_MRCC_13 NLCLOCK0FPGA0MRCC R126
R7 AB16
PIU10AB16 V13
PIU10V13 CLOCK_FPGA_MRCC PIR12601 PIR12602 3
PIU1703 4
PIU1704
NLR5 IO_L2P_T0_13 IO_L13P_T2_MRCC_13 NLVSYNC CLK VDD
R5 AB17
PIU10AB17 V14
PIU10V14 VSYNC 22R
NLG6 IO_L2N_T0_13 IO_L13N_T2_MRCC_13 NLR0
G6 AA13
PIU10AA13
U15
PIU10U15
R0 1% 2
PIU1702
1
PIU1701
NLG7 IO_L3P_T0_DQS_13 IO_L14P_T2_SRCC_13 NLR1 GND OE/ST
G7 AB13
PIU10AB13
V15
PIU10V15
R1
NLG2 IO_L3N_T0_DQS_13 IO_L14N_T2_SRCC_13 NLR2
G2 AA15
PIU10AA15 T14
PIU10T14 R2 GND
NLG3 IO_L4P_T0_13 IO_L15P_T2_DQS_13 NLVGA0SDA
G3 AB15
PIU10AB15 T15
PIU10T15 VGA_SDA SiT8008BI-73-XXS-100.000000E
NLG4 IO_L4N_T0_13 IO_L15N_T2_DQS_13 NLVGA0SCL
G4 Y13
PIU10Y13 W15
PIU10W15 VGA_SCL
NLG5 IO_L5P_T0_13 IO_L16P_T2_13
G5 AA14
PIU10AA14
W16
PIU10W16
RSVD2
NLG1 IO_L5N_T0_13 IO_L16N_T2_13
G1 W14
PIU10W14
T16
PIU10T16
RSVD0
NLG0 IO_L6P_T0_13 IO_L17P_T2_13
G0 Y14
PIU10Y14 U16
PIU10U16 RSVD1
IO_L6N_T0_VREF_13 IO_L17N_T2_13
XC7A100T-2FGG484C
i COU18
U18
B13 1
PIU1801
5
PIU1805
3.3V OE VCC 3.3V
HSYNC 2
PIU1802
C A NLVGA0HSync C
3
PIU1803 4
PIU1804 VGA_HSYNC
GND GND Y

COTP1 NC7SZ126P5X
NLRSVD0 TP1
RSVD0 PITP101

Testpoint 0.8mm

COTP2 COU19
U19
NLRSVD1 TP2
RSVD1 PITP201
1
PIU1901
5
PIU1905
3.3V OE VCC 3.3V
VSYNC 2
PIU1902
Testpoint 0.8mm A NLVGA0VSync
3
PIU1903 GND Y
4
PIU1904
VGA_VSYNC
GND
COTP3
TP3
NLRSVD2
RSVD2 PITP301
NC7SZ126P5X
Testpoint 0.8mm

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page4 of 23

Filename: B13.SchDoc
1 2 3 4
1 2 3 4

A A

B14
i

COU1B
U1B
NLF0SER0RESET COR58
R58
BANK 14 AB21
PIU10AB21 F_SER_RESET PIR5802 PIR5801
3.3V IO_L10P_T1_D14_14 NLF0SER0DATA0I GND
PIC5801 PIC5901 PIC60 1 PIC6101 PIC5 0COC55
1C55 PIC570COC57
1C57 PIC5302 M14
PIU10M14 VCCO_14 IO_L10N_T1_D15_14
AB22
PIU10AB22 F_SER_DATA_I 1K
COC58
C58 COC59
C59 COC60
C60 COC61
C61 COC53
C53 P18 U20 NLF0SER0SRQ0O
F_SER_SRQ_O
PIU10P18 VCCO_14 IO_L11P_T1_SRCC_14 PIU10U20 1%
PIC5802 470nF PIC5902 470nF PIC60 2 470nF PIC6102 470nF PIC5 024.7µF PIC57024.7µF PIC5301 47µF R15
PIU10R15
V20
PIU10V20
VCCO_14 IO_L11N_T1_SRCC_14 NLFB0UP
T22
PIU10T22 W19
PIU10W19 FB_UP
VCCO_14 IO_L12P_T1_MRCC_14 NLF0C640D6
GND U19
PIU10U19 W20
PIU10W20 F_C64_D6
VCCO_14 IO_L12N_T1_MRCC_14 NLF0SER0CLK0I
Y20
PIU10Y20 Y18
PIU10Y18 F_SER_CLK_I
VCCO_14 IO_L13P_T2_MRCC_14 NLF0SER0CLK0O
Y19
PIU10Y19
F_SER_CLK_O
NLF0C640D2 IO_L13N_T2_MRCC_14 NLF0C640D5
F_C64_D2 P20
PIU10P20
V18
PIU10V18
F_C64_D5
B14 i IO_0_14 IO_L14P_T2_SRCC_14 NLCEC0CLK
V19
PIU10V19 CEC_CLK
NLF0C640IO1 IO_L14N_T2_SRCC_14 NLF0C640CLOCK
F_C64_IO1 N15
PIU10N15 AA19
PIU10AA19 F_C64_CLOCK
B B14 i IO_25_14 IO_L15P_T2_DQS_RDWR_B_14 NLF0SER0SRQ0EN B
AB20
PIU10AB20 F_SER_SRQ_EN
NLSPI0DQO IO_L15N_T2_DQS_DOUT_CSO_B_14 NLF0C640O2
SPI-DQO P22
PIU10P22
V17
PIU10V17
F_C64_O2
NLSPI0DQ1 IO_L1P_T0_D00_MOSI_14 IO_L16P_T2_CSI_B_14 NLF0C640NMI
SPI-DQ1 R22
PIU10R22
W17
PIU10W17
F_C64_NMI
NLSPI0DQ2 IO_L1N_T0_D01_DIN_14 IO_L16N_T2_A15_D31_14 NLF0SER0SRQ0I
SPI-DQ2 P21
PIU10P21 AA18
PIU10AA18 F_SER_SRQ_I
NLSPI0DQ3 IO_L2P_T0_D02_14 IO_L17P_T2_A14_D30_14 NLF0C640ROML
SPI-DQ3 R21
PIU10R21 AB18
PIU10AB18 F_C64_ROML
IO_L2N_T0_D03_14 IO_L17N_T2_A13_D29_14 NLF0CTRL0DIR
ULED U22
PIU10U22 U17
PIU10U17 F_CTRL_DIR
NLF0DATA0DIR IO_L3P_T0_DQS_PUDC_B_14 IO_L18P_T2_A12_D28_14 NLF0C640D4
F_DATA_DIR V22
PIU10V22
U18
PIU10U18
F_C64_D4
IO_L3N_T0_DQS_EMCCLK_14 IO_L18N_T2_A11_D27_14 NLF0C640IRQ
T21
PIU10T21
P14
PIU10P14
F_C64_IRQ
NLF0DATA0EN IO_L4P_T0_D04_14 IO_L19P_T3_A10_D26_14 NLETH0LED2
F_DATA_EN U21
PIU10U21 R14
PIU10R14 ETH_LED2
IO_L4N_T0_D05_14 IO_L19N_T3_A09_D25_VREF_14 NLF0C640RW
P19
PIU10P19 R18
PIU10R18 F_C64_RW
NLF0C640EXROM IO_L5P_T0_D06_14 IO_L20P_T3_A08_D24_14 NLF0C640ROMH
F_C64_EXROM R19
PIU10R19 T18
PIU10T18 F_C64_ROMH
NLSPI0CS IO_L5N_T0_D07_14 IO_L20N_T3_A07_D23_14 NLF0SER0ATN
SPI-CS T19
PIU10T19
N17
PIU10N17
F_SER_ATN
IO_L6P_T0_FCS_B_14 IO_L21P_T3_DQS_14 NLFB0DOWN
T20
PIU10T20
P17
PIU10P17
FB_DOWN
NLF0C640D7 IO_L6N_T0_D08_VREF_14 IO_L21N_T3_DQS_A06_D22_14 NLF0C640DMA
F_C64_D7 W21
PIU10W21 P15
PIU10P15 F_C64_DMA
NLF0C640GAME IO_L7P_T1_D09_14 IO_L22P_T3_A05_D21_14 NLF0C640D3
F_C64_GAME W22
PIU10W22 R16
PIU10R16 F_C64_D3
NLF0C640IO2 IO_L7N_T1_D10_14 IO_L22N_T3_A04_D20_14 NLF0C640BA
F_C64_IO2 AA20
PIU10AA20 N13
PIU10N13 F_C64_BA
NLF0SER0CLK0EN IO_L8P_T1_D11_14 IO_L23P_T3_A03_D19_14 NLF0C640RESET
F_SER_CLK_EN AA21
PIU10AA21
N14
PIU10N14
F_C64_RESET
B14 i NLF0SER0DATA0EN IO_L8N_T1_D12_14 IO_L23N_T3_A02_D18_14 NLF0C640D0
F_SER_DATA_EN Y21
PIU10Y21
P16
PIU10P16
F_C64_D0
NLF0SER0DATA0O IO_L9P_T1_DQS_14 IO_L24P_T3_A01_D17_14 NLF0C640D1
F_SER_DATA_O Y22PIU10Y22 R17
PIU10R17 F_C64_D1
C IO_L9N_T1_DQS_D13_14 IO_L24N_T3_A00_D16_14 C
XC7A100T-2FGG484C

COD9
D9
NLULED
ULED
COR67
R67
PID90A PID90K PIR6701 PIR6702 GND
240R 1%
LED Red LTST-C191KRKT

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page5 of 23

Filename: B14.SchDoc
1 2 3 4
1 2 3 4

B15
i
COU1C
U1C
3.3V BANK 15
G19
PIU10G19 M21
PIU10M21
PIC6401 PIC6501 PIC6 01 PIC6701 PIC401 VCCO_15 IO_L10P_T1_AD11P_15 NLF0LADDR0DIR
PIC6201COC62
C62 COC63
PIC6301C63 H16
PIU10H16 L21
PIU10L21 F_LADDR_DIR
COC64
C64 COC65
C65 COC66
C66 COC67
C67 COC4
C4 VCCO_15 IO_L10N_T1_AD11N_15 NLF0C640A5
J13
PIU10J13 J20
PIU10J20 F_C64_A5
A PIC6402 470nF PIC6502 470nF PIC6 02 470nF PIC6702 470nF PIC62024.7µF PIC63024.7µF PIC402 47µF VCCO_15 IO_L11P_T1_SRCC_15 NLF0C640A6 A
K20
PIU10K20 J21
PIU10J21 F_C64_A6
VCCO_15 IO_L11N_T1_SRCC_15 NLRSVD0MRCC COTP4
L17
PIU10L17
J19
PIU10J19
RSVD_MRCC PITP401
TP4
VCCO_15 IO_L12P_T1_MRCC_15 NLF0C640A12
GND N21
PIU10N21 H19
PIU10H19 F_C64_A12
VCCO_15 IO_L12N_T1_MRCC_15 NLF0C640A1
K18
PIU10K18 F_C64_A1
IO_L13P_T2_MRCC_15 NLF0C640A0
K19
PIU10K19 F_C64_A0
IO_L13N_T2_MRCC_15 NLF0ADDR0EN
J16
PIU10J16 L19
PIU10L19 F_ADDR_EN
IO_0_15 IO_L14P_T2_SRCC_15 NLF0C640A4
L20
PIU10L20
F_C64_A4
B15 i IO_L14N_T2_SRCC_15 NLF0C640A14
M17
PIU10M17 N22
PIU10N22 F_C64_A14
IO_25_15 IO_L15P_T2_DQS_15 NLF0C640A3
M22
PIU10M22 F_C64_A3
IO_L15N_T2_DQS_ADV_B_15
AD0_P H13
PIU10H13 M18
PIU10M18
IO_L1P_T0_AD0P_15 IO_L16P_T2_A28_15 NLF0HADDR0DIR
AD0_N G13
PIU10G13 L18
PIU10L18 F_HADDR_DIR
IO_L1N_T0_AD0N_15 IO_L16N_T2_A27_15
AD8_P G15
PIU10G15
N18
PIU10N18
IO_L2P_T0_AD8P_15 IO_L17P_T2_A26_15 COTP6
AD8_N G16
PIU10G16 N19
PIU10N19 PITP601 TP6
NLAD10P IO_L2N_T0_AD8N_15 IO_L17N_T2_A25_15 COTP7
AD1_P J14
PIU10J14 N20
PIU10N20 PITP701 TP7
NLAD10N IO_L3P_T0_DQS_AD1P_15 IO_L18P_T2_A24_15 NLF0C640A13
AD1_N H14
PIU10H14 M20
PIU10M20 F_C64_A13
NLF0DRVSB IO_L3N_T0_DQS_AD1N_15 IO_L18N_T2_A23_15
F_DRVSB G17
PIU10G17
K13
PIU10K13
NLF0CTRL0EN IO_L4P_T0_15 IO_L19P_T3_A22_15
F_CTRL_EN G18
PIU10G18
K14
PIU10K14
NLF0C640A11 IO_L4N_T0_15 IO_L19N_T3_A21_VREF_15 NLFPGA0RESET0N
F_C64_A11 J15
PIU10J15 M13
PIU10M13 FPGA_RESET_N
NLF0MOTEB IO_L5P_T0_AD9P_15 IO_L20P_T3_A20_15 NLDBG0UART0TX
F_MOTEB H15
PIU10H15 L13
PIU10L13 DBG_UART_TX
B NLF0C640A8 IO_L5N_T0_AD9N_15 IO_L20N_T3_A19_15 COTP5 B
F_C64_A8 H17
PIU10H17 K17
PIU10K17 PITP501 TP5
NLF0C640A15 IO_L6P_T0_15 IO_L21P_T3_DQS_15
F_C64_A15 H18
PIU10H18
J17
PIU10J17
NLAD20P IO_L6N_T0_VREF_15 IO_L21N_T3_DQS_A18_15 NLDBG0UART0RX
AD2_P J22
PIU10J22
L14
PIU10L14
DBG_UART_RX
NLAD20N IO_L7P_T1_AD2P_15 IO_L22P_T3_A17_15
AD2_N H22
PIU10H22 L15
PIU10L15
NLF0C640A9 IO_L7N_T1_AD2N_15 IO_L22N_T3_A16_15 NLFPGA0TX GND
F_C64_A9 H20
PIU10H20 L16
PIU10L16 FPGA_TX
NLF0C640A10 IO_L8P_T1_AD10P_15 IO_L23P_T3_FOE_B_15 NLFPGA0RX
F_C64_A10 G20
PIU10G20 K16
PIU10K16 FPGA_RX
NLF0C640A2 IO_L8N_T1_AD10N_15 IO_L23N_T3_FWE_B_15 NLCT0HPD
F_C64_A2 K21
PIU10K21
M15
PIU10M15
CT_HPD
NLF0C640A7 IO_L9P_T1_DQS_AD3P_15 IO_L24P_T3_RS1_15
F_C64_A7 K22
PIU10K22
M16
PIU10M16
IO_L9N_T1_DQS_AD3N_15 IO_L24N_T3_RS0_15
XC7A100T-2FGG484C
i
B15

C C
NLJA0AX
JA_AX
COR73
R73 NLAD00P
AD0_P NLJB0AX
JB_AX
COR74
R74 AD1_P
PIR7301 PIR7302 PIR7401 PIR7402
47K
PIR7501 PIC130 2 47K
PIR7601 PIC13 02
COR75
R75 COC130
C130 COR76
R76 COC131
C131
1% 1%
10K PIC130 1 33nF 10K PIC13 01 33nF
COR77
R77 PIR7502 1% NLAD00N
AD0_N
COR78
R78 PIR7602 1% AD1_N
GND PIR7702 PIR7701 GND PIR7802 PIR7801
10K 10K
1% 1%

NLJA0AY
JA_AY
COR79
R79 NLAD80P
AD8_P NLJB0AY
JB_AY
COR80
R80 AD2_P
PIR7901 PIR7902 PIR8001 PIR8002
47K
PIR8101 PIC1320 47K
PIR8201 PIC13 02
COR81
R81 COC132
C132 COR82
R82 COC133
C133
1% 1%
10K PIC13201 33nF 10K PIC13 01 33nF
COR83
R83 PIR8102 1% NLAD80N
AD8_N
COR84
R84 PIR8202 1% AD2_N
GND PIR8302 PIR8301 GND PIR8402 PIR8401
10K 10K Title:
1% 1% MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page6 of 23

Filename: B15.SchDoc
1 2 3 4
1 2 3 4

COU1D
U1D
BANK 16
NLKB0IO2 i B16
A17
PIU10A17 A13
PIU10A13 KB_IO2
3.3V PIC9101 PIC9201 PIC9301 PIC9801 PIC501 VCCO_16 IO_L10P_T1_16 NLKB0IO1
PIC680COC68
1C68 PIC90COC90
1C90 B14
PIU10B14 A14
PIU10A14 KB_IO1
COC91
C91 COC92
C92 COC93
C93 COC98
C98 COC5
C5 VCCO_16 IO_L10N_T1_16 NLSD20CLK
C21
PIU10C21 B17
PIU10B17 SD2_CLK
A PIC9102 470nF PIC9202 470nF PIC9302 470nF PIC9802 470nF PIC68024.7µF PIC90 24.7µF PIC502 47µF VCCO_16 IO_L11P_T1_SRCC_16 NLSD20D0 A
D18
PIU10D18 B18
PIU10B18 SD2_D0
VCCO_16 IO_L11N_T1_SRCC_16 NLSD20CD
E15
PIU10E15
D17
PIU10D17
SD2_CD
VCCO_16 IO_L12P_T1_MRCC_16 NLSD20WP
GND F22
PIU10F22 C17
PIU10C17 SD2_WP
VCCO_16 IO_L12N_T1_MRCC_16 NLSD20D1
C18
PIU10C18 SD2_D1
IO_L13P_T2_MRCC_16 NLSD20D2
C19
PIU10C19 SD2_D2
NLFB0FIRE IO_L13N_T2_MRCC_16
FB_FIRE F15
PIU10F15 E19
PIU10E19
IO_0_16 IO_L14P_T2_SRCC_16
D19
PIU10D19
NLFB0LEFT IO_L14N_T2_SRCC_16 NLSPEAKER0MUTE0N
FB_LEFT F21
PIU10F21 F18
PIU10F18 SPEAKER_MUTE_N
IO_25_16 IO_L15P_T2_DQS_16
E18
PIU10E18
NLFA0RIGHT IO_L15N_T2_DQS_16
FA_RIGHT F13
PIU10F13 B20
PIU10B20 DQ4
NLFA0LEFT IO_L1P_T0_16 IO_L16P_T2_16
FA_LEFT F14
PIU10F14 A20
PIU10A20 DQ3
NLFA0DOWN IO_L1N_T0_16 IO_L16N_T2_16
FA_DOWN F16
PIU10F16
A18
PIU10A18
NLFA0FIRE IO_L2P_T0_16 IO_L17P_T2_16
FA_FIRE E17
PIU10E17 A19
PIU10A19 DQ5
NLFA0UP IO_L2N_T0_16 IO_L17N_T2_16
FA_UP C14
PIU10C14 F19
PIU10F19
NLFB0RIGHT IO_L3P_T0_DQS_16 IO_L18P_T2_16
FB_RIGHT C15
PIU10C15 F20
PIU10F20
NLKB0TCK IO_L3N_T0_DQS_16 IO_L18N_T2_16 COTP8
KB_TCK E13
PIU10E13
D20
PIU10D20 PITP801
TP8
NLKB0TDO IO_L4P_T0_16 IO_L19P_T3_16
KB_TDO E14
PIU10E14
C20
PIU10C20
DQ2
NLPWM0SPEAKER IO_L4N_T0_16 IO_L19N_T3_VREF_16
PWM_SPEAKER E16
PIU10E16 C22
PIU10C22 CS0
IO_L5P_T0_16 IO_L20P_T3_16
3.3V D16
PIU10D16 B22
PIU10B22 H_RES
B COU39 NLKB0TMS IO_L5N_T0_16 IO_L20N_T3_16 B
U39 KB_TMS D14
PIU10D14 B21
PIU10B21 RWDS
NLKB0TDI IO_L6P_T0_16 IO_L21P_T3_DQS_16
1
PIU3901
8
PIU3908
KB_TDI D15
PIU10D15
A21
PIU10A21
DQ0
GND A0 VCC NLFPGA0SDA NLSD20D3 IO_L6N_T0_VREF_16 IO_L21N_T3_DQS_16
2
PIU3902 A1 SDA
5
PIU3905
FPGA_SDA SD2_D3 B15
PIU10B15
E22
PIU10E22
DQ7
NLFPGA0SCL NLSD20CMD IO_L7P_T1_16 IO_L22P_T3_16
3
PIU3903 6
PIU3906 FPGA_SCL SD2_CMD B16
PIU10B16 D22
PIU10D22 H_CLK
3.3V A2 SCL NLKB0IO3 IO_L7N_T1_16 IO_L22N_T3_16
7
PIU3907 4
PIU3904 KB_IO3 C13
PIU10C13 E21
PIU10E21 DQ6
WP VSS GND B16 i NLKB0JTAGEN IO_L8P_T1_16 IO_L23P_T3_16
KB_JTAGEN B13
PIU10B13 D21
PIU10D21 DQ1
IO_L8N_T1_16 IO_L23N_T3_16 NLGrove0SCL0
GND 24LC128-I/ST FPGA_SCL A15
PIU10A15
G21
PIU10G21
GROVE_SCL0
IO_L9P_T1_DQS_16 IO_L24P_T3_16 NLGrove0SDA0
FPGA_SDA A16
PIU10A16
G22
PIU10G22
GROVE_SDA0
I2C addr: 0x54 IO_L9N_T1_DQS_16 IO_L24N_T3_16
XC7A100T-2FGG484C

3.3V
3.3V COU36
U36 COU38
U38
6
PIU3606 1
PIU3601 FPGA_SCL COR151
R151PIR15101 PIR15102 4K7 NLX2 1
X2PIU3801 20 NLX1
X1
PIU38020
VCC SCL X2 X1
PIC17501 5
PIU3605 2
PIU3602 3V 2
PIU3802 19
PIU38019
COC175
C175 A0 VSS GND COR152 COD14 X2 X1
4
PIU3604 3
PIU3603 FPGA_SDA R152PIR15201 PIR15202 4K7 D14 3
PIU3803 18
PIU38018
PIC17502 470nF A1 SDA COB1 X2 X1
B1 4
PIU3804
17
PIU38017
X2 X1
GND 24AA025E48T-I/OT PID1401
5
PIU3805
16
PIU38016
X2 X1
GND 3.3V
C C
I2C addr: 0x50 -
PIB100 +
PIB100 PID1403 7
PIU3807 14
PIU38014
VBAT VDD
PIC18401 PIR16302 PIC18501
COU29
U29 GND COC184
C184
6 COR163
R163 COC185
C185
PID1402 PIU3806 NC
B1
PIU290B1
B4
PIU290B4
PIC18402 9
470nF PIU3809 4K7 470nF
PIC18502
NLH0CLK CK VCC 3.3V NC 6.3V
H_CLK B2
PIU290B2 D1
PIU290D1 Batteriehalter CR1220 10
6.3V PIU38010 13
PIU38013 PIR16301
CK VCCQ NC IRQ/FOUT
E4
PIU290E4 BAT54C GND 15
PIU38015 GND
VCCQ NC
21
PIU38021 12
PIU38012 FPGA_SCL
NLH0RES NC SCL
A4
PIU290A4
H_RES
NLRWDS RESET
RWDS C3
PIU290C3
8
PIU3808
11
PIU38011
FPGA_SDA
RWDS NLCS0 GND SDA
A3
PIU290A3
CS0
CS
A2
PIU290A2 GND ISL12020MIRZ
RFU
A5
PIU290A5
NLDQ0 RFU
DQ0 D3
PIU290D3
C2
PIU290C2
I2C addr: 0x6F for RTC
NLDQ1 DQ0 RFU
DQ1 D2
PIU290D2
B5
PIU290B5
NLDQ2 DQ1 RFU
DQ2 C4
PIU290C4 C5
PIU290C5
I2C addr: 0x57 for SRAM
NLDQ3 DQ2 RFU
DQ3 D4
PIU290D4
3.3V
DQ3
NLDQ4
DQ4 D5
PIU290D5
B3 PIU290B3
Title:
NLDQ5 DQ4 VSS PIC2501 PIC2601
DQ5 E3
PIU290E3
A1 MEGA65
NLDQ6 DQ5 NC/VSS PIU290A1 COC25
C25 COC26
C26
DQ6 E2
PIU290E2
C1
D NLDQ7 DQ6 VSSQ PIU290C1 D
DQ7 E1
PIU290E1
E5 PIC2502 470nF PIC2602 470nF Number: Rev.
DQ7 VSSQ PIU290E5 A4 TE0765
Default 02
IS66WVH8M8BLL-100B1LI GND GND
GND
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page7 of 23

Filename: B16.SchDoc
1 2 3 4
1 2 3 4

3.3V
3.3V 1
PIC120COC12 PIC15901COC159 PIC16 01 PIC16701 PIC16801 PIC16901 PIC160 1COC160 PIC16 COC161
C12 C159 C160 01C161
COC166
C166 COC167
C167 COC168
C168 COC169
C169
2
PIC1204.7µF PIC159024.7µF PIC16 02 470nF PIC16702 470nF P IC16 802 470nF PI C16 902 470nF PIC160 24.7µF PIC16 024.7µF
B35
A A
GND GND i
COU1E
COU1F
U1E U1F
BANK 34 BANK 35
R5 AA5 NLHDMI0D31
HDMI_D31 C1 J5 NLB350L100P
B35_L10_P
3.3V PIU10R5 VCCO_34 IO_L10P_T1_34 PIU10AA5 3.3V PIU10C1 VCCO_35 IO_L10P_T1_AD15P_35 PIU10J5
T2
PIU10T2 AB5
PIU10AB5
NLHDMI0D32
HDMI_D32 F2
PIU10F2 H5
PIU10H5
NLB350L100N
B35_L10_N
VCCO_34 IO_L10N_T1_34 NLHDMI0D29 VCCO_35 IO_L10N_T1_AD15N_35 NLSD0D1
V6
PIU10V6
Y4
PIU10Y4 HDMI_D29 H6
PIU10H6
H3
PIU10H3
SD_D1
VCCO_34 IO_L11P_T1_SRCC_34 NLHDMI0D30 VCCO_35 IO_L11P_T1_SRCC_35
W3
PIU10W3 AA4
PIU10AA4 HDMI_D30 J3
PIU10J3 G3
PIU10G3
VCCO_34 IO_L11N_T1_SRCC_34 NLHDMI0D10 VCCO_35 IO_L11N_T1_SRCC_35 NLB350L120P
AA7
PIU10AA7 V4
PIU10V4 HDMI_D10 M4
PIU10M4 H4
PIU10H4 B35_L12_P
VCCO_34 IO_L12P_T1_MRCC_34 NLHDMI0D18 VCCO_35 IO_L12P_T1_MRCC_35 NLB350L120N
AB4
PIU10AB4 W4
PIU10W4 HDMI_D18 N1
PIU10N1 G4
PIU10G4 B35_L12_N
VCCO_34 IO_L12N_T1_MRCC_34 NLHDMI0HS VCCO_35 IO_L12N_T1_MRCC_35 NLETH0CRS0DV
R4
PIU10R4 HDMI_HS K4
PIU10K4 ETH_CRS_DV
IO_L13P_T2_MRCC_34 NLHDMI0D1 IO_L13P_T2_MRCC_35 NLETH0TX0EN
T4
PIU10T4 HDMI_D1 J4
PIU10J4
ETH_TX_EN
NLHDMI0SCL IO_L13N_T2_MRCC_34 NLHDMI0D0 NLPWM0R IO_L13N_T2_MRCC_35 NLETH0TX0D0
HDMI_SCL T3
PIU10T3 T5
PIU10T5 HDMI_D0 PWM_R F4
PIU10F4 L3
PIU10L3 ETH_TX_D0
IO_0_34 IO_L14P_T2_SRCC_34 NLHDMI0D6 IO_0_35 IO_L14P_T2_SRCC_35 NLETH0TX0D1
U5
PIU10U5 HDMI_D6 K3
PIU10K3 ETH_TX_D1
NLHDMI0SDA IO_L14N_T2_SRCC_34 NLHDMI0D23 NLPWM0L IO_L14N_T2_SRCC_35 NLF0SIDE1
HDMI_SDA U7
PIU10U7 W6
PIU10W6 HDMI_D23 PWM_L L6
PIU10L6 M1
PIU10M1 F_SIDE1
IO_25_34 IO_L15P_T2_DQS_34 NLHDMI0D19 IO_25_35 IO_L15P_T2_DQS_35 NLETH0RX0D1
W5
PIU10W5
HDMI_D19 L1
PIU10L1
ETH_RX_D1
NLHDMI0D3 IO_L15N_T2_DQS_34 NLHDMI0D7 NLB350L10P IO_L15N_T2_DQS_35 NLF0STEP
HDMI_D3 T1
PIU10T1
U6
PIU10U6 HDMI_D7 B35_L1_P B1
PIU10B1
M3
PIU10M3
F_STEP
NLHDMI0D5 IO_L1P_T0_34 IO_L16P_T2_34 NLHDMI0D13 NLB350L10N IO_L1P_T0_AD4P_35 IO_L16P_T2_35 NLF0INDEX
HDMI_D5 U1
PIU10U1 V5
PIU10V5 HDMI_D13 B35_L1_N A1
PIU10A1 M2
PIU10M2 F_INDEX
NLHDMI0D8 IO_L1N_T0_34 IO_L16N_T2_34 NLHDMI0VS NLB350L20P IO_L1N_T0_AD4N_35 IO_L16N_T2_35 NLETH0RST
HDMI_D8 U2
PIU10U2 R6
PIU10R6 HDMI_VS B35_L2_P C2
PIU10C2 K6
PIU10K6 ETH-RST
B NLHDMI0D11 IO_L2P_T0_34 IO_L17P_T2_34 NLHDMI0D4 NLB350L20N IO_L2P_T0_AD12P_35 IO_L17P_T2_35 NLETH0MDC B
HDMI_D11 V2
PIU10V2 T6
PIU10T6 HDMI_D4 B35_L2_N B2
PIU10B2 J6
PIU10J6 ETH_MDC
NLHDMI0D2 IO_L2N_T0_34 IO_L17N_T2_34 NLHDMI0D33 NLB350L30P IO_L2N_T0_AD12N_35 IO_L17N_T2_35 NLETH0MDIO
HDMI_D2 R3
PIU10R3
Y6
PIU10Y6
HDMI_D33 B35_L3_P E1
PIU10E1
L5
PIU10L5
ETH_MDIO
NLHDMI0DE IO_L3P_T0_DQS_34 IO_L18P_T2_34 NLHDMI0D34 NLB350L30N IO_L3P_T0_DQS_AD5P_35 IO_L18P_T2_35 NLETH0CLK
HDMI_DE R2
PIU10R2
AA6
PIU10AA6 HDMI_D34 B35_L3_N D1
PIU10D1
L4
PIU10L4
ETH_CLK
NLHDMI0D15 IO_L3N_T0_DQS_34 IO_L18N_T2_34 NLHDMI0D20 NLB350L40P IO_L3N_T0_DQS_AD5N_35 IO_L18N_T2_35 NLF0WDATE
HDMI_D15 W2
PIU10W2 V7
PIU10V7 HDMI_D20 B35_L4_P E2
PIU10E2 N4
PIU10N4 F_WDATE
NLHDMI0CLK IO_L4P_T0_34 IO_L19P_T3_34 NLHDMI0D25 NLB350L40N IO_L4P_T0_35 IO_L19P_T3_35 NLF0WGATE
HDMI_CLK Y2
PIU10Y2 W7
PIU10W7 HDMI_D25 B35_L4_N D2
PIU10D2 N3
PIU10N3 F_WGATE
NLHDMI0D14 IO_L4N_T0_34 IO_L19N_T3_VREF_34 NLSCL0A NLB350L50P IO_L4N_T0_35 IO_L19N_T3_VREF_35 NLF0DSCKCHG
HDMI_D14 W1
PIU10W1 AB7
PIU10AB7 SCL_A B35_L5_P G1
PIU10G1 R1
PIU10R1 F_DSCKCHG
NLHDMI0D16 IO_L5P_T0_34 IO_L20P_T3_34 NLHDMI0D35 NLB350L50N IO_L5P_T0_AD13P_35 IO_L20P_T3_35 NLF0RDATA1
HDMI_D16 Y1
PIU10Y1
AB6
PIU10AB6
HDMI_D35 B35_L5_N F1
PIU10F1
P1
PIU10P1
F_RDATA1
NLHDMI0D9
IO_L5N_T0_34 IO_L20N_T3_34 NLSDA0A NLB350L60P
IO_L5N_T0_AD13N_35 IO_L20N_T3_35 NLF0DIR
HDMI_D9 U3
PIU10U3
V9
PIU10V9 SDA_A B35_L6_P F3
PIU10F3
P5
PIU10P5
F_DIR
NLHDMI0D12 IO_L6P_T0_34 IO_L21P_T3_DQS_34 NLHDMI0D21 NLB350L60N IO_L6P_T0_35 IO_L21P_T3_DQS_35 NLETH0RX0D0
HDMI_D12 V3
PIU10V3 V8
PIU10V8 HDMI_D21 B35_L6_N E3
PIU10E3 P4
PIU10P4 ETH_RX_D0
NLHDMI0SPDIF IO_L6N_T0_VREF_34 IO_L21N_T3_DQS_34 NLHDMI0SPDIFOUT NLSD0CD IO_L6N_T0_VREF_35 IO_L21N_T3_DQS_35 NLF0WPT
HDMI_SPDIF AA1
PIU10AA1 AA8
PIU10AA8 HDMI_SPDIFOUT SD_CD K1
PIU10K1 P2
PIU10P2 F_WPT
NLHDMI0D22 IO_L7P_T1_34 IO_L22P_T3_34 NLLS0OE NLSD0D2 IO_L7P_T1_AD6P_35 IO_L22P_T3_35 NLF0TRCK0
HDMI_D22 AB1
PIU10AB1 AB8
PIU10AB8 LS_OE SD_D2 J1
PIU10J1 N2
PIU10N2 F_TRCK0
NLHDMI0D28 IO_L7N_T1_34 IO_L22N_T3_34 NLHPD0A NLSD0D0 IO_L7N_T1_AD6N_35 IO_L22N_T3_35 NLETH0RXER
HDMI_D28 AB3
PIU10AB3
Y8
PIU10Y8
HPD_A SD_D0 H2
PIU10H2
M6
PIU10M6
ETH_RXER
NLHDMI0D24 IO_L8P_T1_34 IO_L23P_T3_34 NLHDMI0D27 NLSD0CLK IO_L8P_T1_AD14P_35 IO_L23P_T3_35 NLF0MOTEA
HDMI_D24 AB2
PIU10AB2
Y7
PIU10Y7 HDMI_D27 SD_CLK G2
PIU10G2
M5
PIU10M5
F_MOTEA
NLHDMI0D17 IO_L8N_T1_34 IO_L23N_T3_34 NLCEC0A NLSD0D3 IO_L8N_T1_AD14N_35 IO_L23N_T3_35 NLF0REDWC
HDMI_D17 Y3
PIU10Y3 W9
PIU10W9 CEC_A SD_D3 K2
PIU10K2 P6
PIU10P6 F_REDWC
NLHDMI0D26 IO_L9P_T1_DQS_34 IO_L24P_T3_34 NLHDMI0INT NLSD0CMD IO_L9P_T1_DQS_AD7P_35 IO_L24P_T3_35 NLF0DRVSA
HDMI_D26 AA3
PIU10AA3 Y9
PIU10Y9 HDMI_INT SD_CMD J2
PIU10J2 N5
PIU10N5 F_DRVSA
IO_L9N_T1_DQS_34 IO_L24N_T3_34 IO_L9N_T1_DQS_AD7N_35 IO_L24N_T3_35
XC7A100T-2FGG484C XC7A100T-2FGG484C
i i i
B34 B34 B35
C C

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page8 of 23

Filename: B34.SchDoc
1 2 3 4
1 2 3 4

A A
3.3V

COU1G
U1G
BANK0
COC170
C170 F12 PIU10F12 K10
PIU10K10
VCCO_0 VCCADC_0 AVCC
GND PIC17001 PIC17002 T12
PIU10T12 VCCO_0
M10
PIU10M10
4.7µF E12 VREFP_0 AGND
PIU10E12 L9
PIU10L9
GND VCCBATT_0 VREFN_0 AGND
SPI-SCK L12 L10 NLV0P
V_P PIC12 01
PIU10L12 CCLK_0 VP_0 PIU10L10
M9 NLV0N
V_N COC122
C122
VN_0 PIU10M9
3.3V
U11
PIU10U11 M0_0
PIC12 02 10nF
3.3V BOOTMODE = MASTER SPI U10
PIU10U10 M1_0 N10
PIU10N10
16V
DXP_0 X7R
CFG U9
PIU10U9 N9
PIU10N9
GND M2_0 DXN_0
PIR6801 1%
COR3
R3 i
COR68
R68 NLFPGA0DONE
FPGA_DONE G11 K9
3.3V PIR301 PIR302 PIU10G11 DONE_0 GNDADC_0 PIU10K9 AGND
4K87
1K
FPGA_PROG_B PIR6802 1% NLFPGA0PROG0B
FPGA_PROG_B N12
PIU10N12 PROGRAM_B_0
B i B
U8
PIU10U8
3.3V CFGBVS_0
CFG
NLFPGA0TDI
FPGA_TDI R13
PIU10R13 TDI_0
NLFPGA0TDO
FPGA_TDO U13
PIU10U13 TDO_0
FPGA_JTAG i NLFPGA0TCK
FPGA_TCK V12
PIU10V12 TCK_0
NLFPGA0TMS
FPGA_TMS T13
PIU10T13 TMS_0
COR8
R8 NLFPGA0INIT
PIR802 PIR801 FPGA_INIT U12
PIU10U12
3.3V INIT_B_0
4K87 i
1% XC7A100T-2FGG484C
CFG

SPIFLASH
i

3.3V C14 COC14


COU5A
COU5B
U5A PIC1401 PIC1402
COR7
R7 NLSPI0CS
GND
PIR702 PIR701 SPI-CS C2
PIU50C2 B4 COL3
C 3.3V NLSPI0SCK CS VCC PIU50B4 100nF L3 C
4K87 SPI-SCK B2
PIU50B2 PIL302 PIL301
NLSPI0DQO CLK NLSPI0DQ1 1.8V AVCC
1% SPI-DQO D3
PIU50D3 D2
PIU50D2 SPI-DQ1
COR1
R1 NLSPI0DQ3 DI/IO0 DO/IO1 i SPIFLASH BKP0603HS121-T
PIR102 PIR101
SPI-DQ3 D4
PIU50D4 HOLD/RESET/IO3
3.3V NLSPI0DQ2 301
PICCOC23
4K87 SPI-DQ2 C4
PIU50C4 WP/IO2
B3 2C23
GND PIU50B3 GND
1%
S25FL256SAGBHI20 302
PIC2470nF
U5B COL2
L2
A2
PIU50A2 PIL202 PIL201
NC GND
A3
PIU50A3
3.3V 3.3V
NC COS2 BKP0603HS121-T
A4
PIU50A4 NC
S2 AGND
A5
PIU50A5 NC
PIR14502 PIR14802
B1 1 COR145
R145 COR148
R148
PIU50B1 NC PIS201
B5 2
PIS202
4K87 4K87
PIU50B5 NC COR134
R134 NLRST0BTN NLCPLD0JTAGEN0RESET0BTN
C1
PIU50C1 NC
3
PIS203 PIR13401 PIR13402
RST_BTN PIR14501 1% PIR14801 1% CPLD_JTAGEN/RESET_BTN
C3
PIU50C3 NC 49R9 PIC7501
C5 4 COC75
C75 PIT603
PIU50C5 NC PIS204
D1 5 10nF
PIC7502 COT6
T6 Title:
PIU50D1 NC PIS205
D5
PIU50D5 NC
6
PIS206
16V 2N7002,215 MEGA65
E1 GNDX7R PIT601
D PIU50E1 NC D
E2
PIU50E2 NC
SPUJ191500 PIJ20 2 Number: Rev.
E3 GND COJ20
J20 A4 TE0765
PIU50E3 NC PIT602 02
E4
PIU50E4 NC
Default
E5
PIU50E5 NC
JUMPER2.54-2 PIJ20 1 Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page9 of 23
S25FL256SAGBHI20 GND GND
Filename: FPGA-CFG.SchDoc
1 2 3 4
1 2 3 4

A A

COU1H
U1H
D6
PIU10D6 B5
PIU10B5
GND MGTAVCC MGTAVTT GND
D10
PIU10D10 MGTAVCC B7
PIU10B7
MGTAVTT
E8
PIU10E8 B9
PIU10B9
MGTAVCC MGTAVTT
F7
PIU10F7 MGTAVCC
B11
PIU10B11
MGTAVTT
F9
PIU10F9 MGTAVCC
C4
PIU10C4
MGTAVTT
C8
PIU10C8
MGTAVTT
B B
F6
PIU10F6 F8
PIU10F8
MGTREFCLK0P_216 MGTRREF_216 GND
E6
PIU10E6 MGTREFCLK0N_216
F10
PIU10F10 MGTREFCLK1P_216
E10
PIU10E10 MGTREFCLK1N_216

B8
PIU10B8 B4
PIU10B4
MGTPRXP0_216 MGTPTXP0_216
A8
PIU10A8
A4
PIU10A4
MGTPRXN0_216 MGTPTXN0_216
D11
PIU10D11
D5
PIU10D5
MGTPRXP1_216 MGTPTXP1_216
C11
PIU10C11 C5
PIU10C5
MGTPRXN1_216 MGTPTXN1_216
B10
PIU10B10 B6
PIU10B6
MGTPRXP2_216 MGTPTXP2_216
A10
PIU10A10 A6
PIU10A6
MGTPRXN2_216 MGTPTXN2_216
D9
PIU10D9
D7
PIU10D7
MGTPRXP3_216 MGTPTXP3_216
C9
PIU10C9
C7
PIU10C7
GND MGTPRXN3_216 MGTPTXN3_216
XC7A100T-2FGG484C

C C

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page10 of 23

Filename: FPGA-MGT.SchDoc
1 2 3 4
1 2 3 4

1V VCCINT CAPS

PIC901 PIC10 1 PIC1 01 PIC20 1 PIC2401 PIC4201 PIC4301 PIC4901 PIC5601 PIC140 1 PIC14 01 PIC14201 PIC14301
COC9
C9 COC10
C10 COC11
C11 COC20
C20 COC24
C24 COC42
C42 COC43
C43 COC49
C49 COC56
C56 COC140
C140 COC141
C141 COC142
C142 COC143
C143
PIC902 470nF PIC10 2 470nF PIC1 02 470nF PIC20 2 470nFPIC2402 470nF PIC4202 470nF PIC4302 470nF PIC4902 470nF PIC5602 470nF PIC140 2 470nF PIC14 02 470nF PIC1420 470nF PIC14302 470nF
GND
A A
1V
U1J
PIC690COC69
1C69 PIC70 COC70
1C70 PIC710COC71
1C71 PIC7401COC74
C74 PIC4 0COC44
1C44 PIC760COC76
1C76 A2
PIU10A2 H7
PIU10H7
GND GND
A3
PIU10A3 H9
PIU10H9
PIC69024.7µF PIC70 24.7µF PIC71024.7µF PIC74024.7µF PIC4 024.7µF PIC76024.7µF GND GND
A5
PIU10A5 H11
PIU10H11
GND GND
A7
PIU10A7
H21
PIU10H21
GND GND
GND A9
PIU10A9 J8
PIU10J8
GND GND
A11
PIU10A11 J10
PIU10J10
COU1I
COU1J GND GND
1V U1I A12
PIU10A12 J12
PIU10J12
GND GND
H10
PIU10H10 VCCINT H12
PIU10H12 A22
PIU10A22 J18
PIU10J18
PIC147COC147 2 1V VCCAUX 1.8V GND GND
02C147 PIC1480COC148
2C148 PIC1490COC149
C149 H8
PIU10H8 VCCINT
K12
PIU10K12
AA2
PIU10AA2
K5
PIU10K5
VCCAUX GND GND
J7
PIU10J7 M12
PIU10M12 AA12
PIU10AA12 K7
PIU10K7
VCCINT VCCAUX GND GND
1
PIC14701100µF PIC14801100µF PIC1490100µF J9
PIU10J9 P12
PIU10P12 AA22
PIU10AA22 K11
PIU10K11
VCCINT VCCAUX GND GND
K8
PIU10K8 R11
PIU10R11 AB9
PIU10AB9 K15
PIU10K15
VCCINT VCCAUX GND GND
GND L7
PIU10L7 VCCINT
AB19
PIU10AB19
L2
PIU10L2
GND GND
M8
PIU10M8 VCCINT
B3
PIU10B3
L8
PIU10L8
GND GND
1V VCCBRAM CAPS N7
PIU10N7 B12
PIU10B12 L22
PIU10L22
VCCINT GND GND
P8
PIU10P8 B19
PIU10B19 M7
PIU10M7
B VCCINT GND GND B
PIC150 1 PIC15101 PIC15201 P10
PIU10P10 VCCINT C3
PIU10C3 GND GND
M11
PIU10M11
COC150
C150 COC151
C151 COC152
C152 R7 C6 M19
PIU10R7 VCCINT PIU10C6 GND GND PIU10M19
PIC150 2 470nF PIC15102 470nF PIC15202 470nF R9
PIU10R9 VCCINT VCCBRAM
J11
PIU10J11 1V
C10
PIU10C10 GND GND
N6
PIU10N6
T10
PIU10T10 VCCINT L11 C12
PIU10C12 N8
PIU10N8
VCCBRAM PIU10L11 GND GND
GND T8
PIU10T8 N11 C16
PIU10C16 N16
PIU10N16
VCCINT VCCBRAM PIU10N11 GND GND
D3
PIU10D3 P3
PIU10P3
GND GND
XC7A100T-2FGG484C D4
PIU10D4
P7
PIU10P7
GND GND
1.8V VCCAUX CAPS D8
PIU10D8
P9
PIU10P9
GND GND
D12
PIU10D12 P11
PIU10P11
GND GND
PIC15301 PIC15401 PIC15 01 PIC15601 PIC15701 PIC460COC46
1C46 PIC470COC47
1C47 PIC480COC48
1C48 PIC15801 D13
PIU10D13 P13
PIU10P13
COC153
C153 COC154
C154 COC155
C155 COC156
C156 COC157
C157 COC158
C158 GND GND
E4
PIU10E4 R8
PIU10R8
PIC15302 470nF PIC15402 470nF PIC15 02 470nF PIC15602 470nF PIC15702 470nF PIC46024.7µF PIC47024.7µF PIC48024.7µF PIC15802 47µF GND GND
E5
PIU10E5
R10
PIU10R10
GND GND
E7
PIU10E7
R12
PIU10R12
GND GND
GND E9
PIU10E9 R20
PIU10R20
GND GND
E11
PIU10E11 T7
PIU10T7
GND GND
F5
PIU10F5 T9
PIU10T9
GND GND
F11
PIU10F11
T11
PIU10T11
GND GND
F17
PIU10F17
T17
PIU10T17
GND GND
E20
PIU10E20 U4
PIU10U4
C GND GND C
G5
PIU10G5 U14
PIU10U14
GND GND
G6
PIU10G6 V1
PIU10V1
GND GND
G7
PIU10G7
V11
PIU10V11
GND GND
G8
PIU10G8
V21
PIU10V21
GND GND
G9
PIU10G9 W8
PIU10W8
GND GND
G10
PIU10G10 W18
PIU10W18
GND GND
G12
PIU10G12 Y5
PIU10Y5
GND GND
G14
PIU10G14
Y15
PIU10Y15
GND GND
H1
PIU10H1 GND
GND XC7A100T-2FGG484C GND

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page11 of 23

Filename: FPGA-PWR.SchDoc
1 2 3 4
1 2 3 4
Bank8
COL10
L10 i
PIC16501
COC165
PIC16502C165
NL303V0REF
3.3V_REF PIL1001 PIL1002 3.3V U32C 3.3V U32F
3.3V
4.7µF MPZ1608S221A BANK 3 BANK 8
L8
PIU320L8 L4
PIU320L4 C8
PIU320C8 C10
PIU320C10
VCCIO3 IO_3/DIFFIO_TX_RX_B1P VCCIO8 IO_8/DIFFIO_RX_T14P
COC202
C202 L7
PIU320L7 VCCIO3 IO_3/DIFFIO_TX_RX_B1N
L5
PIU320L5
C7
PIU320C7 VCCIO8 IO_8/DIFFIO_RX_T14N
C9
PIU320C9
PIC20201 PIC20202
COU32A
COU32B
COU32C
COU32D
COU32E
COU32F
COU32G
U32A L6
PIU320L6 M5
PIU320M5
NLCPLD0DBG10
CPLD_DBG10 C6
PIU320C6 A8
PIU320A8
NLCPLD0ADC1 PIC24 01 VCCIO3 IO_3/DIFFIO_RX_B2P PIC24501 VCCIO8 IO_8/DIFFIO_RX_T15P
D3 PIU320D3 D2
PIU320D2 CPLD_ADC1 M4
PIU320M4 A9
PIU320A9
470nF ADC_VREF ANAIN1 COC244
C244 IO_3/DIFFIO_RX_B2N NLFPGA0TCK COC245
C245 IO_8/DIFFIO_RX_T15N
E2
PIU320E2 J5
PIU320J5 FPGA_TCK B10
PIU320B10
A REFGND 470nF
PIC24 02 IO_3/DIFFIO_TX_RX_B3P PIC24502 470nF IO_8/DIFFIO_RX_T16P A
K5
PIU320K5 B9
PIU320B9
IO_3/DIFFIO_TX_RX_B3N NLCPLD0DBG11 IO_8/DEV_CLRN/DIFFIO_RX_T16N
GND 3.3V BANK 1A N11
PIU320N11 VREFB3N0
N5
PIU320N5
CPLD_DBG11 B7
PIU320B7
A10
PIU320A10
NLCPLD0ADC2 IO_3/DIFFIO_RX_B4P VREFB8N0 IO_8/DIFFIO_RX_T17P NLCPLD0CFG2
F2
PIU320F2 C2
PIU320C2 CPLD_ADC2 GND N4
PIU320N4 GND A11
PIU320A11 CPLD_CFG2
VCCIO1A IO_1A/ADC1IN2/DIFFIO_RX_L1P NLCPLD0ADC3 IO_3/DIFFIO_RX_B4N NLCPLD0DBG9 IO_8/DIFFIO_RX_T17N
D1
PIU320D1 CPLD_ADC3 M7
PIU320M7 CPLD_DBG9 D8
PIU320D8
PIC24601 IO_1A/ADC1IN1/DIFFIO_RX_L1N IO_3/DIFFIO_TX_RX_B5P NLCPLD0DBG8 IO_8/DEV_OE/DIFFIO_RX_T18P
E4
PIU320E4 N6
PIU320N6 CPLD_DBG8 E8
PIU320E8
COC246
C246 IO_1A/ADC1IN4/DIFFIO_RX_L3P IO_3/DIFFIO_TX_RX_B5N NLCPLD0DBG5 IO_8/DIFFIO_RX_T18N
E3
PIU320E3 N8
PIU320N8 CPLD_DBG5 D7
PIU320D7 A7
PIU320A7
PIC24602 470nF IO_1A/ADC1IN3/DIFFIO_RX_L3N IO_3/DIFFIO_RX_B6P NLCPLD0DBG7 GND IO_8/CONFIG_SEL IO_8/DIFFIO_RX_T19P
B1
PIU320B1
N7
PIU320N7
CPLD_DBG7 A6
PIU320A6
IO_1A/ADC1IN6/DIFFIO_RX_L5P IO_3/DIFFIO_RX_B6N NLFPGA0INIT IO_8/DIFFIO_RX_T19N
C1
PIU320C1 K6
PIU320K6 FPGA_INIT E7
PIU320E7 B6
PIU320B6
IO_1A/ADC1IN5/DIFFIO_RX_L5N IO_3/DIFFIO_TX_RX_B7P NLFPGA0DONE I_8/NCONFIG IO_8/DIFFIO_RX_T20P NLTE0TCK
GND E1
PIU320E1 J6
PIU320J6 FPGA_DONE B5
PIU320B5 TE_TCK
IO_1A/ADC1IN8/DIFFIO_RX_L7P IO_3/DIFFIO_TX_RX_B7N NLCPLD0DBG4 IO_8/DIFFIO_RX_T20N NLTE0TDO
F1
PIU320F1 M9
PIU320M9 CPLD_DBG4 A4
PIU320A4 TE_TDO
IO_1A/ADC1IN7/DIFFIO_RX_L7N i Bank1 IO_3/DIFFIO_RX_B8P NLCPLD0DBG6 IO_8/DIFFIO_RX_T21P NLTE0TDI
M8
PIU320M8 CPLD_DBG6 A3
PIU320A3 TE_TDI
IO_3/DIFFIO_RX_B8N NLFPGA0TDO IO_8/DIFFIO_RX_T21N
3.3V BANK 1B K7
PIU320K7 FPGA_TDO E6
PIU320E6
IO_3/DIFFIO_TX_RX_B9P NLFPGA0TDI IO_8/DIFFIO_RX_T22P
G3
PIU320G3 E5 NLCPLD0JTAGEN0RESET0BTN
PIU320E5 CPLD_JTAGEN/RESET_BTN J7
PIU320J7 FPGA_TDI D6
PIU320D6
VCCIO1B IO_1B/JTAGEN NLM0TCK IO_3/DIFFIO_TX_RX_B9N NLK0TCK IO_8/CRC_ERROR/DIFFIO_RX_T22N NLTE0TMS
G2
PIU320G2 M_TCK M12
PIU320M12 K_TCK
NLM10nCONF B3
PIU320B3 TE_TMS
IO_1B/TCK/DIFFIO_RX_L11P NLM0TMS IO_3/DIFFIO_TX_RX_B10P NLK0TDI IO_8/DIFFIO_RX_T23P NLTE0UART0TX
TE_UART_TX

M10_NCONF
H1
PIC24701 PIU320H1 G1
PIU320G1 M_TMS M13
PIU320M13 K_TDI B4
PIU320B4
COC247
C247 VREFB1N0 IO_1B/TMS/DIFFIO_RX_L11N NLM0TDO IO_3/DIFFIO_TX_RX_B10N NLCPLD0DBG3 IO_8/DIFFIO_RX_T23N NLM100nSTATUS
F6
PIU320F6
M_TDO N9
PIU320N9
CPLD_DBG3 C4
PIU320C4
M10_NSTATUS
PIC24702 470nF IO_1B/TDO/DIFFIO_RX_L12P NLM0TDI IO_3/DIFFIO_RX_B11P NLCPLD0DBG1 IO_8/NSTATUS/DIFFIO_RX_T24P NLM100CONF0DONE
F5
PIU320F5 M_TDI N10
PIU320N10
CPLD_DBG1 C5
PIU320C5
M10_CONF_DONE
IO_1B/TDI/DIFFIO_RX_L12N IO_3/DIFFIO_RX_B11N NLFPGA0RX IO_8/CONF_DONE/DIFFIO_RX_T24N NLM0TX
G4
PIU320G4 L11
PIU320L11 FPGA_RX A2
PIU320A2 M_TX
IO_1B/DIFFIO_RX_L14P IO_3/DIFFIO_TX_RX_B12P NLK0JTAGEN IO_8/DIFFIO_RX_T26P NLM0RX
GND F4
PIU320F4 M11
PIU320M11 K_JTAGEN B2
PIU320B2 M_RX
B IO_1B/DIFFIO_RX_L14N IO_3/DIFFIO_TX_RX_B12N NLFPGA0TMS IO_8/DIFFIO_RX_T26N NLTE0UART0RX B
H3
PIU320H3 K8
PIU320K8 FPGA_TMS A5
PIU320A5 TE_UART_RX
IO_1B/DIFFIO_RX_L16P IO_3/DIFFIO_TX_RX_B14P i Bank3 IO_8
H2
PIU320H2
J8
PIU320J8
IO_1B/DIFFIO_RX_L16N IO_3/DIFFIO_TX_RX_B14N NLCPLD0DBG0
L10
PIU320L10
CPLD_DBG0 10M08SAU169C8G
IO_3/DIFFIO_TX_RX_B16P NLCPLD0DBG2
10M08SAU169C8G M10
PIU320M10 CPLD_DBG2 3.3V U32G
IO_3/DIFFIO_TX_RX_B16N NLK0TMS
Bank2 N12
PIU320N12 K_TMS H7
PIU320H7 A1
PIU320A1
IO_3 PIC24801 VCC_ONE GND
U32B i G8
PIU320G8 A13
PIU320A13
COC248
C248 VCC_ONE GND
3.3V 10M08SAU169C8G G6
PIU320G6
B8
PIU320B8
BANK 2 NLCPLD0CLK PIC24802 470nF VCC_ONE GND
K3
PIU320K3 VCCIO2
H6
PIU320H6
CPLD_CLK U32E F7 C3
PIU320C3
IO_2/CLK0P/DIFFIO_RX_L18P i Bank6 PIU320F7 VCC_ONE GND
J3
PIU320J3 G5
PIU320G5 3.3V D5
PIU320D5
VCCIO2 IO_2/CLK0N/DIFFIO_RX_L18N BANK 6 NLKB0IO2 GND
PIC24901 J2
PIU320J2 G11 G9
PIU320G9 KB_IO2 GND K4
PIU320K4 E11
PIU320E11
COC249
C249 IO_2/DIFFIO_RX_L19P PIU320G11 VCCIO6
IO_6/CLK2P/DIFFIO_RX_R14P NLKB0TCK i KB VCCA1 GND
J1
PIU320J1 F11 G10
PIU320G10 KB_TCK D10 F3
PIU320F3
PIC24902 470nF IO_2/DIFFIO_RX_L19N PIC250 1 PIU320F11 VCCIO6
IO_6/CLK2N/DIFFIO_RX_R14N NLKB0IO3 i KB PIU320D10 VCCA2 GND
H4
PIU320H4
F13
PIU320F13
KB_IO3 D4 G7
PIU320G7
IO_2/CLK1P/DIFFIO_RX_L20P COC250
C250 IO_6/CLK3P/DIFFIO_RX_R16P i KB PIU320D4 VCCA3 GND
L1
PIU320L1 VREFB2N0
H5
PIU320H5
E13
PIU320E13
K9 H12
PIU320H12
IO_2/CLK1N/DIFFIO_RX_L20N 470nF IO_6/CLK3N/DIFFIO_RX_R16N NLKB0TMS 3.3V PIU320K9 VCCA4 GND
GND M2
PIU320M2 PIC250 2 F12
PIU320F12 KB_TMS PIC17301 J4
PIU320J4
IO_2/DIFFIO_RX_L21P NLHDMI0PD IO_6/DIFFIO_RX_R18P i KB COC173
C173 GND
M1
PIU320M1 HDMI_PD D13 E12
PIU320E12 L9
PIU320L9
IO_2/DIFFIO_RX_L21N PIU320D13 VREFB6N0 IO_6/DIFFIO_RX_R18N NLKB0JTAGEN PIC17302 470nF GND
N3
PIU320N3 GND F9
PIU320F9 KB_JTAGEN M6
PIU320M6
IO_2/DPCLK1/DIFFIO_RX_L22P NLVDAC0PSAVE0N IO_6/DPCLK3/DIFFIO_RX_R26P NLKB0TDO i KB GND
N2
PIU320N2
VDAC_PSAVE_N F10
PIU320F10
KB_TDO N1
PIU320N1
IO_2/DPCLK0/DIFFIO_RX_L22N IO_6/DPCLK2/DIFFIO_RX_R26N i KB GND
L3
PIU320L3
F8
PIU320F8
GND N13
PIU320N13
IO_2/PLL_L_CLKOUTP/DIFFIO_RX_L27P IO_6/DIFFIO_RX_R27P NLKB0IO1 COJ21 GND
M3
PIU320M3 E9
PIU320E9 KB_IO1 J21
C IO_2/PLL_L_CLKOUTN/DIFFIO_RX_L27N IO_6/DIFFIO_RX_R27N i KB C
K2
PIU320K2 B12
PIU320B12 LED_R 1
CPLD_DBG0 PIJ2101 10M08SAU169C8G GND
IO_2/DIFFIO_RX_L28P IO_6/DIFFIO_RX_R28P NLCPLD0CFG3
K1
PIU320K1 B11
PIU320B11 CPLD_CFG3 2
CPLD_DBG1 PIJ2102
IO_2/DIFFIO_RX_L28N IO_6/DIFFIO_RX_R28N NLPMOD20EN
L2
PIU320L2
C12
PIU320C12
PMOD2_EN 3
CPLD_DBG2 PIJ2103
IO_2 IO_6/DIFFIO_RX_R29P NLCPLD0CFG1
C11
PIU320C11
CPLD_CFG1 4
CPLD_DBG3 PIJ2104
IO_6/DIFFIO_RX_R29N COR28
R28
10M08SAU169C8G B13
PIU320B13 LED_G 5
CPLD_DBG4 PIJ2105 M10_NCONF PIR2801 PIR2802
IO_6/DIFFIO_RX_R30P NLCPLD0CFG0
A12
PIU320A12 CPLD_CFG0 6
CPLD_DBG5 PIJ2106 10K
IO_6/DIFFIO_RX_R30N
U32D E10
PIU320E10 7
CPLD_DBG6 PIJ2107
3.3V
i Bank5 IO_6/DIFFIO_RX_R31P NLKB0TDI COR29
BANK 5 D9
PIU320D9
KB_TDI 8
CPLD_DBG7 PIJ2108 M10_CONF_DONE PIR2901R29 PIR2902
NLDBG0UART0TX IO_6/DIFFIO_RX_R31N NLPMOD10FLG i KB
J11
PIU320J11 VCCIO5
K10
PIU320K10
DBG_UART_TX D12
PIU320D12
PMOD1_FLG 9
CPLD_DBG8 PIJ2109 10K
IO_5/DIFFIO_RX_R1P NLDBG0UART0RX IO_6/DIFFIO_RX_R33P NLPMOD10EN
H11
PIU320H11 VCCIO5
J10
PIU320J10
DBG_UART_RX D11
PIU320D11
PMOD1_EN 10
CPLD_DBG9 PIJ21010
IO_5/DIFFIO_RX_R1N NLFPGA0TX IO_6/DIFFIO_RX_R33N NLPMOD20FLG COR30
R30
PIC25 01 K11
PIU320K11 FPGA_TX C13
PIU320C13 PMOD2_FLG 11
CPLD_DBG10 PIJ21011 M10_NSTATUS PIR3001 PIR3002
COC252
C252 IO_5/DIFFIO_RX_R2P NLK0TDO IO_6 3.3V
L12
PIU320L12
K_TDO 10M08SAU169C8G 12
CPLD_DBG11 PIJ21012 10K
PIC25 02 470nF IO_5/DIFFIO_RX_R2N NLK0IO2
K12
PIU320K12
K_IO2 13
PIJ21013
IO_5/DIFFIO_RX_R7P NLK0IO3
K13
PIU320K13 VREFB5N0
J12
PIU320J12
K_IO3 14
PIJ21014
IO_5/DIFFIO_RX_R7N NLFPGA0RESET0N COD10
D10
GND J9
PIU320J9 FPGA_RESET_N
IO_5/DIFFIO_RX_R8P COR70
R70 NLLED0G
H10
PIU320H10 PID100K PIR7001 PIR7002
LED_G GND Pin Header 2.54 2Row 14Pins
IO_5/DIFFIO_RX_R8N 3.3V PID100A
J13
PIU320J13
NL5V0JOY0PG
5V_JOY_PG 240R Title:
IO_5/DIFFIO_RX_R9P NLEN05V0JOY0N
H13
PIU320H13
EN_5V_JOY_N LED Green LTST-C191KGKT 1% MEGA65
IO_5/DIFFIO_RX_R9N
H9
PIU320H9
D IO_5/DIFFIO_RX_R10P COD12
D12 D
H8
PIU320H8
Number: Rev.
IO_5/DIFFIO_RX_R10N COR130
R130 NLLED0R A4 TE0765
G13
PIU320G13 PID120A PID120K PIR13001 PIR13002 LED_R 02
IO_5/DIFFIO_RX_R11P 3.3V Default
G12
PIU320G12
NLFPGA0PROG0B
FPGA_PROG_B 240R
IO_5/DIFFIO_RX_R11N NLK0IO1
L13
PIU320L13
K_IO1 LED Red LTST-C191KRKT
1%
IO_5 Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page12 of 23
10M08SAU169C8G
Filename: SYS_MAX10_CTRL.SchDoc
1 2 3 4
1 2 3 4

NLV0P COR54
R54 COR59
R59
V_P PIR5401 PIR5402 PIR5901 PIR5902
PIC12301 1V
240R 1% COC123 2K61
C123
PIR60 2 PID602 PID601 PIC12302 4.7µF
COR60
R60 COD6
D6
200K GND
A PIR60 1 1% PIC12402 A
BAV199LT1G COC124
C124 COC125
C125
NLV0N COR66
R66 PID603 PIC12401 33nF
COR61
R61
V_N PIR6601 PIR6602 PIR6101 PIR6102 PIC12502 PIC12501

240R 1% 240R 1% 10µF


3.3V GND
10V
PID702 PID701 BAV199LT1G X5R
COJ9
J9

4
PIJ904
COD7
D7
PID703 GND
3
PIJ903

COR62 COC126
C126
NLPWM0R
PWM_R R62 2
PIR6201 PIR6202 PIC12602 PIC12601 PIJ902

240R PIC12701 PIR6301 COR64


R64
COC128
C128
COC127
C127 COR63
R63 10µF NLPWM0L
PWM_L 1
1% PIR6401 PIR6402 PIC12802 PIC12801 PIJ901
PIC12702 33nF 150R 10V PIC12901 PIR6501
X5R 240R COC129 COR65 10µF
25V 02
PIR631% C129 R65
1% 10V
X7R PIC12902 33nF 150R 3.5RCA
B 25V X5R B
502
PIR61%
GND COD8
D8 PID803 X7R

GND

PID801 PID802 BAV199LT1G


COC172
C172
GND 3.3V PIC17201 PIC17202

2.2nF
25V
C0G, NP0
COR153
R153
PIR15301 PIR15302

22K
1%
COC177
C177 COU37
U37
NLPWM0SPEAKER COR149
R149 COR154
R154 COJ19
PWM_SPEAKER PIR14901 PIR14902 PIC17701 PIC17702 PIR15401 PIR15402 4
PIU3704 PIU37055 J19
C VIN- VOUT1 C
240R PIC17401 PIR150 1 22K 3
PIU3703 1
PIJ1901
COC174
C174 COR150
R150 470nF VIN+
1% 1% 2
PIU3702 8
PIU3708 2
PIJ1902
PIC17402 33nF 150R 6.3V BYPASS VOUT2
25V 02
PIR151% X5R NLSPEAKER0MUTE0N
SPEAKER_MUTE_N 1 JST-S2B-XH-A
PIU3701 SB
COD13
D13 PID1303 X7R COC176
C176
PIC17801 6
PIU3706 7
PIU3707
COC178
C178 GND PIC17602 PIC17601 VCC GND
GND
PIC17802 1µF 10µF TS4990IST GND
16V 10V
PID1301 PID1302 BAV199LT1G X5R
COL11
L11
3.3V PIL1102 PIL1101
GND 3.3V GND
MPZ1608S221A

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page14 of 23

Filename: SOUND.SchDoc
1 2 3 4
1 2 3 4

COJ6
J6 COU15
U15 COJ7
J7
1 NLSER0SRQ
SER_SRQ NLF0SER0CLK0EN
F_SER_CLK_EN 1 5 5 NLJA0AY
JA_AY
PIJ601 PIU1501 OE VCC PIU1505 5V PIJ705
5
PIJ605
NLSER0DATA
SER_DATA NLF0SER0CLK0O
F_SER_CLK_O 2
PIU1502 9
PIJ709
NLJA0AX
JA_AX
A
3
PIU1503
4
PIU1504
SER_CLK 4
PIJ704
JA_RIGHT
NLSER0RESET GND GND Y
PIJ6066 SER_RESET GND 8
PIJ708 GND
NC7SZ126P5X GND 3
PIJ703 JA_LEFT
PIJ6044 NLSER0CLK
SER_CLK COU16
U16 7
PIJ707
A NLSER0ATN NLF0SER0DATA0EN PIR8602 PIC4502 5V_JOY A
3
PIJ603 SER_ATN F_SER_DATA_EN 1
PIU1601 5
PIU1605 2
PIJ702 JA_DOWN
NLF0SER0DATA0O OE VCC 5V PIC13502 COR86
R86 COC45
C45
2
PIJ602
F_SER_DATA_O 2
PIU1602
6
PIJ706
JA_FIRE
GND A COC135
C135 1M PIC4501 10µF
7
PIJ607 3
PIU1603 4
PIU1604 SER_DATA 1
PIJ701 JA_UP
GND GND GND Y PIC13501 100pF PIR8601 5%
8
GND PIJ608 1000V
NC7SZ126P5X DSUB-9-M GND
COU27 X7R PIJ70H2 PIJ70H1

H2
H1
61PC6F U27
NLF0SER0SRQ0EN
F_SER_SRQ_EN 1
PIU2701
5
PIU2705
NLF0SER0SRQ0O OE VCC 5V
GND F_SER_SRQ_O 2
PIU2702 A
3
PIU2703 4
PIU2704 SER_SRQ
GND GND Y COJ3
J3
NC7SZ126P5X 5
PIJ305
NLJB0AY
JB_AY
COU20
U20 9
PIJ309
NLJB0AX
JB_AX
1
PIU2001 5
PIU2005 4
PIJ304
NLJB0RIGHT
JB_RIGHT
3.3V OE VCC 3.3V
SER_CLK 2
PIU2002 8
PIJ308
A NLF0SER0CLK0I GND NLJB0LEFT
3
PIU2003 4
PIU2004 F_SER_CLK_I 3
PIJ303 JB_LEFT
GND GND Y
7
PIJ307
NLJB0DOWN PIC7202 5V_JOY
NC7SZ126P5X 2
PIJ302
JB_DOWN
COU21
U21 6 NLJB0FIRE
JB_FIRE COC72
C72
PIJ306
1
PIU2101 5
PIU2105 1
PIJ301
NLJB0UP
JB_UP PIC7201 10µF
B 3.3V OE VCC 3.3V B
SER_DATA 2
PIU2102 A NLF0SER0DATA0I
3
PIU2103 GND Y
4
PIU2104
F_SER_DATA_I DSUB-9-M GND
GND PIJ30H2 PIJ30H1

H2
H1
NC7SZ126P5X
COU28
U28
1
PIU2801 5
PIU2805
3.3V OE VCC 3.3V
SER_SRQ 2
PIU2802
3.3V
A NLF0SER0SRQ0I
3
PIU2803
4
PIU2804
F_SER_SRQ_I
GND GND Y COU33
U33
NC7SZ126P5X PIR12702 11
PIU33011 1
PIU3301
COR127
R127 5V VCC SOURCE 5V_JOY
PIR12 02 SOURCE
2
PIU3302
COU22
U22 4K7 COR122
R122 6 3
PIU3306 NC SOURCE PIU3303
1
PIU2201
5
PIU2205
NL5V0JOY0PG
5V_JOY_PG PIR12701 DNP 4
PIU3304
NLJA0RIGHT 3.3V OE VCC 3.3V SOURCE
JA_RIGHT 2
PIU2202 PIR12 01 8
PIU3308 5
PIU3305
A NLFA0RIGHT PIT203 Enable/Fault SOURCE
3
PIU2203 4
PIU2204 FA_RIGHT PIR12302 COC73
C73 PIR12401
GND GND Y COR123
R123 COR124
R124
PIC7301 PIC7302 9
PIU3309
COT2 200K GND dv/dt 22R
NC7SZ126P5X T2
COU23
U23 2N7002,215 1%
PIR 1230 1
PIT201
1nF 10
PIU33010 GND
7
PIU3307
PIR12402 1%
50V I-Limit
1
PIU2301 5
PIU2305 PIR12502
C NLJA0LEFT 3.3V OE VCC 3.3V COR125
R125 X7R C
JA_LEFT 2
PIU2302 MP5010BDQ-LF-Z
A NLFA0LEFT PIT20 200K
3
PIU2303 4
PIU2304 FA_LEFT
GND GND Y PIR12501 1% GND
NC7SZ126P5X GND PIT103
COU24
U24 GND COT1
T1
1
PIU2401 5
PIU2405
2N7002,215
NLJA0DOWN 3.3V OE VCC 3.3V NLEN05V0JOY0N
JA_DOWN 2
PIU2402 EN_5V_JOY_NPIT101
A NLFA0DOWN
3
PIU2403
4
PIU2404
FA_DOWN
GND GND Y
3.3V 5V
NC7SZ126P5X PIT102
PIC17902 PIC180 2
COC179
C179 COC180
C180 COU25
U25 GND
PIC17901 10µF PIC180 1 10µF 1
PIU2501
5
PIU2505
10V NLJA0FIRE 3.3V OE VCC 3.3V
JA_FIRE 2
PIU2502 A NLFA0FIRE
GND GND 3
PIU2503 4
PIU2504 FA_FIRE
GND GND Y
NC7SZ126P5X Title:
MEGA65
COU26
U26
D D
1
PIU2601
5
PIU2605
Number: Rev.
NLJA0UP 3.3V OE VCC 3.3V A4 TE0765
JA_UP 2
PIU2602 02
A Default
3
PIU2603
4
PIU2604
NLFA0UP
FA_UP
GND GND Y
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page15 of 23
NC7SZ126P5X
Filename: JOY.SchDoc
1 2 3 4
1 2 3 4

A A

COJ5
J5
KB i i KB
1
PIJ501
2
PIJ502
NLK0JTAGEN GND 3.3V NLK0TMS
K_JTAGEN 3
PIJ503 4
PIJ504 K_TMS
NLK0TCK
K_TCK 5
PIJ505 6
PIJ506
NLK0TDI
K_TDI
NLK0TDO
K_TDO 7
PIJ507 8
PIJ508
NLK0IO1
K_IO1
NLK0IO2
K_IO2 9
PIJ509
10
PIJ5010
NLK0IO3
K_IO3

SMD-254-9132-14-10
B B

COJ12
J12
1
PIJ1201 2
PIJ1202
GND 3.3V
3
PIJ1203 4
PIJ1204
5
PIJ1205 6
PIJ1206
7
PIJ1207
8
PIJ1208
9
PIJ1209
10
PIJ12010

1-338069-0

C C

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page16 of 23

Filename: KEYBOARD.SchDoc
1 2 3 4
1 2 3 4

A A

COU7
U7
COJ13
J13 31
PIU7031 7
PIU707
3.3V VCCA VCCB 5V
1
PIJ1301 42
PIU7042 18
PIU7018
12V_FUSED VCCA VCCB
2
PIJ1302 FLOPPY
GND
3
PIJ1303 i
GND
4
PIJ1304 1
PIU701 48
PIU7048
5V 3.3V 1DIR 1OE GND
Stiftleiste 4 Pol. 2,54mm NLF0REDWC
F_REDWC 47
PIU7047 2
PIU702 REDWC
COJ16 NLF0MOTEA 1A1 1B1
J16 F_MOTEA 46
PIU7046
3
PIU703
MOTEA
NLF0DRVSA 1A2 1B2
1
PIJ1601
F_DRVSA 44
PIU7044
5
PIU705
DRVSA
12V_FUSED NLF0DIR 1A3 1B3
2
PIJ1602 F_DIR 43
PIU7043 6
PIU706 DIR
GND NLF0STEP 1A4 1B4
3
PIJ1603 F_STEP 41
PIU7041 8
PIU708 STEP
B GND NLF0WDATE 1A5 1B5 B
4
PIJ1604 F_WDATE 40
PIU7040 9
PIU709 WDATE
5V NLF0WGATE 1A6 1B6
F_WGATE 38
PIU7038
11
PIU7011
WGATE
NLF0SIDE1 1A7 1B7
Stiftleiste 4 Pol. 2,54mm F_SIDE1 37
PIU7037
12
PIU7012
SIDE1
1A8 1B8
24
PIU7024 25
PIU7025
GND 2DIR 2OE GND
NLF0INDEX
F_INDEX 36
PIU7036
13
PIU7013
INDEX
NLF0TRCK0 2A1 2B1
F_TRCK0 35
PIU7035
14
PIU7014
TRCK0
NLF0WPT 2A2 2B2
F_WPT 33
PIU7033 16
PIU7016 WPT
NLF0RDATA1 2A3 2B3
F_RDATA1 32
PIU7032 17
PIU7017 RDATA1
NLF0DSCKCHG 2A4 2B4
F_DSCKCHG 30
PIU7030 19
PIU7019 DSCKCHG
2A5 2B5
29
PIU7029
20
PIU7020
2A6 2B6
27
PIU7027
22
PIU7022
COJ14 2A7 2B7
J14 26
PIU7026 23
PIU7023
NLREDWC 2A8 2B8
1
PIJ1401 2
PIJ1402 REDWC
3
PIJ1403 4
PIJ1404 28
PIU7028 4
PIU704
GND GND
5
PIJ1405
6
PIJ1406
34
PIU7034
10
PIU7010
NLINDEX GND GND
7
PIJ1407
8
PIJ1408
INDEX 39
PIU7039
15
PIU7015
NLMOTEA GND GND
9
PIJ1409 10
PIJ14010 MOTEA 45 21
PIU7021
C NLDRVSB GND PIU7045 GND GND GND C
11
PIJ14011 12
PIJ14012 DRVSB
13
PIJ14013 14
PIJ14014
NLDRVSA
DRVSA SN74LVCH16T245DGV
15
PIJ14015
16
PIJ14016
NLMOTEB
MOTEB
17
PIJ14017
18
PIJ14018
NLDIR
DIR
19
PIJ14019 20
PIJ14020
NLSTEP
STEP
21 22 NLWDATE
WDATE
PIJ14021 PIJ14022
23
PIJ14023 24
PIJ14024
NLWGATE
WGATE
25
PIJ14025
26
PIJ14026
NLTRCK0
TRCK0
27
PIJ14027
28
PIJ14028
NLWPT
WPT
29 30 NLRDATA1
RDATA1
PIJ14029 PIJ14030
31
PIJ14031 32
PIJ14032
NLSIDE1
SIDE1
33
PIJ14033
34
PIJ14034
NLDSCKCHG
DSCKCHG

WANNE2,54-34 GERADE
GND
Title:
MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page17 of 23

Filename: Floppy.SchDoc
1 2 3 4
1 2 3 4

GND

COU3A
COU3B
U3A
NLG0
G0 3
PIU303 31
PIU3031
A NLG1 G0 IOG NLVGA0Green0Out A
G1 4
PIU304 32
PIU3032 VGA_GREEN_OUT
NLG2 G1 IOG PIR1301
G2 5
PIU305
NLG3 G2 COR13
R13
G3 6
PIU306
NLG4 G3 75R COJ1
J1
G4 7
PIU307 DSUB-15-F-HD 8.89
NLG5 G4 PIR1302 1%
G5 8
PIU308 VGA_RED_OUT 1
PIJ101
NLG6 G5
G6 9
PIU309 GND 6
PIJ106
NLG7 G6 GND
G7 10
PIU3010
GND 11
PIJ1011
G7
VGA_GREEN_OUT 2
PIJ102
NLB0
B0 16
PIU3016 27
PIU3027 7
PIJ107
NLB1 B0 IOB NLVGA0Blue0Out GND
B1 17
PIU3017 28
PIU3028 VGA_BLUE_OUT VGA_ID1/SDA 12
PIJ1012
NLB2 B1 IOB PIR1501
B2 18
PIU3018 VGA_BLUE_OUT 3
PIJ103
NLB3 B2 COR15
R15
B3 19
PIU3019 COR44 8
PIJ108
NLB4 B3 75R NLVGA0HSync R44 GND
B4 20
PIU3020 VGA_HSYNC PIR4401 PIR4402 13
PIJ1013
NLB5 B4
B5 21
PIU3021 PIR1502 1% 49R9 4
PIJ104
NLB6 B5
B6 22
PIU3022 GND 9
PIJ109
NLB7 B6 NLVGA0VSync COR53
R53
B7 23
PIU3023
GND VGA_VSYNC PIR5301 PIR5302
14
PIJ1014
B7
49R9 5
PIJ105
NLR0 GND
R0 41
PIU3041 33
PIU3033 10
PIJ1010
NLR1 R0 IOR NLVGA0Red0Out GND
R1 42
PIU3042 34
PIU3034 VGA_RED_OUT VGA_ID3/SCL 15
PIJ1015
B NLR2 R1 IOR B
R2 43
PIU3043 R2
PIR1601
NLR3
R3 44 COR16
R16
PIU3044 R3
NLR4 75R PIJ10H1 PIJ10H2
H1
H2

R4 45
PIU3045
NLR5 R4 1%
R5 46
PIU3046
PIR1602
NLR6 R5
R6 47
PIU3047
NLR7 R6
R7 48
PIU3048 GND
R7
ADV7125BCPZ170

5V PIR8501 PIC13401
3.3V COR85
R85 COC134
C134
U3B VAA COL7 1M PIC13402 100pF
NLVDAC0CLK L7 PIR6902 PIR13 02 PIR8502 5% 1000V
VDAC_CLK 24
PIU3024
13
PIU3013 PIL701 PIL702
CLOCK VAA 3.3V COR69
R69 PIT301 COR131
R131 X7R
29
PIU3029 PIC3401 PIC3501
NLVDAC0BLANK0N VAA COC34
C34 COC35
C35 MPZ1608S221A 10K 10K
VDAC_BLANK_N 11
PIU3011 30
PIU3030
BLANK VAA PIC3402 100nF PIC3502 10nF NLVGA0SDA PIR6901 PIR13 01 NLVGA0ID10SDA
VGA_SDA PIT302 PIT303 VGA_ID1/SDA GND GND
NLVDAC0SYNC0N
VDAC_SYNC_N 12
PIU3012
1
PIU301
25V 16V
SYNC GND X5R X7R
2
PIU302
NLVDAC0PSAVE0N GND COT3
VDAC_PSAVE_N 38
PIU3038 14
PIU3014
T3
C PSAVE GND C
COC36
C36 15
PIU3015
2N7002,215
GND
PIC3601 PIC3602 36
PIU3036 25
PIU3025 GND 5V
VAA VREF GND
COC118
C118 26
PIU3026
3.3V
100nF GND
PIC11801 PIC11802
35
PIU3035
39
PIU3039
25V VAA COMP GND
40
PIU3040 PIR1320 PIR13 02
X5R 100nF GND COR132
R132 PIT401 COR133
R133
37
PIU3037 49
PIU3049
25V RSET EP 10K 10K
X5R PIR1801 ADV7125BCPZ170 GND NLVGA0SCL
VGA_SCL PIR13201 PIR13 01 NLVGA0ID30SCL
VGA_ID3/SCL
PIT402 PIT403
COR18
R18
560R
PIR1802 1% COT4
T4
2N7002,215

GND

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page18 of 23

Filename: VGA.SchDoc
1 2 3 4
1 2 3 4

COU6A
COU6B
COU6C
U6A U6B
Video HDMI COJ4
J4 Audio
NLHDMI0VS
HDMI_VS 2
PIU602 33
PIU6033 HDMI_TXC_P HDMI_TX2_P 1
PIJ401
NLHDMI0SPDIF
HDMI_SPDIF 10
PIU6010
NLHDMI0SPDIFOUT
46 HDMI_SPDIFOUT
PIU6046
VSYNC TXC+ Data2+ SPDIF SPDIF_OUT
PixelC 32
PIU6032 HDMI_TXC_N 2
PIJ402
NLHDMI0HS TXC– Data2 Shield
HDMI_HS 98
PIU6098 HDMI_TX2_N 3
PIJ403 11
PIU6011
HSYNC Data2- MCLK
36
PIU6036 HDMI_TX0_P HDMI_TX1_P 4
PIJ404
NLHDMI0CLK TX0+ Data1+
HDMI_CLK 79
PIU6079 Blue 35
PIU6035 HDMI_TX0_N 5
PIJ405 16
PIU6016
A CLK TX0– Data1 Shield SCLK A
HDMI_TX1_N 6
PIJ406
NLHDMI0DE Data1-
HDMI_DE 97
PIU6097
40
PIU6040 HDMI_TX1_P HDMI_TX0_P 7
PIJ407
17
PIU6017
DE TX1+ Data0+ LRCLK
Green 39
PIU6039 HDMI_TX1_N 8
PIJ408
NLHDMI0D0 TX1– Data0 Shield
HDMI_D0 96
PIU6096 HDMI_TX0_N 9
PIJ409 9
PIU609
NLHDMI0D1 D0 Data0- DSD_CLK
HDMI_D1 95
PIU6095 43
PIU6043 HDMI_TX2_P HDMI_TXC_P 10
PIJ4010
NLHDMI0D2 D1 TX2+ Clock+ NLHDMI0PD
HDMI_D2 94
PIU6094 Red 42
PIU6042 HDMI_TX2_N 11
PIJ4011 HDMI_PD 38
PIU6038
NLHDMI0D3 D2 TX2– Clock Shield PD
HDMI_D3 93
PIU6093 GND GND HDMI_TXC_N 12
PIJ4012
NLHDMI0D4 D3 Clock-
HDMI_D4 92
PIU6092 30
PIU6030 HPD_A CEC_B 13
PIJ4013 12
PIU6012
NLHDMI0D5 D4 HPD CEC I2S0
HDMI_D5 91
PIU6091 PIC9402 PIC9502 14
PIJ4014 13
PIU6013
NLHDMI0D6 D5 COC94 COC95 NC I2S1
HDMI_D6 90
PIU6090 48
PIU6048 CEC_A C94 C95 SCL_B 15
PIJ4015 14
PIU6014
NLHDMI0D7 D6 CEC SCL I2S2
HDMI_D7 89
PIU6089 PIC9401 1µF PIC9501 100nF SDA_B 16
PIJ4016 15
PIU6015
NLHDMI0D8 D7 NLCEC0CLK SDA I2S3
HDMI_D8 88
PIU6088
50
PIU6050 CEC_CLK 6.3V 17
PIJ4017
NLHDMI0D9 D8 CEC_CLK DVDD_HDMI DDC/CEC GND
HDMI_D9 87
PIU6087 5V_HDMI 18
PIJ4018 3
PIU603
NLHDMI0D10 D9 +5V DSD0
HDMI_D10 86
PIU6086 53
PIU6053 SCL_A PIR2 01 PIR2301 HPD_B 19
PIJ4019 4
PIU604
NLHDMI0D11 D10 DDCSCL COR22
R22 COR23
R23 Hot Plug Detect DSD1
HDMI_D11 85
PIU6085 H1
PIJ40H1 5
PIU605
NLHDMI0D12 D11 49R9 49R9 FRAME DSD2
HDMI_D12 84
PIU6084
54
PIU6054
SDA_A H2
PIJ40H2
6
NLHDMI0D13 D12 DDCSDA PIR2 02 PIR2302 FRAME PIU606 DSD3
HDMI_D13 83
PIU6083
H3
PIJ40H3
7
NLHDMI0D14 D13 COC78 FRAME PIU607 DSD4
HDMI_D14 82
PIU6082 52
PIU6052 C78 1µF
PIC7801 PIC7802 H4
PIJ40H4 8
PIU608
NLHDMI0D15 D14 HEAC+ FRAME DSD5
HDMI_D15 81
PIU6081 51
PIU6051 6.3V
B NLHDMI0D16 D15 HEAC- COC79 B
HDMI_D16 80
PIU6080 C79PIC7901 1µF
PIC7902 HDMI Connector ADV7511KSTZ
NLHDMI0D17 D16 NLHDMI0SCL GND
HDMI_D17 78
PIU6078
55
PIU6055
HDMI_SCL PIR4601 PIR4602
6.3V GND
NLHDMI0D18 D17 SCL 3.3V
HDMI_D18 74
PIU6074
1% 2K COR46
NLHDMI0D19 D18 NLHDMI0SDA R46
HDMI_D19 73
PIU6073 56
PIU6056 HDMI_SDA PIR4701 PIR4702
NLHDMI0D20 D19 SDA
HDMI_D20 72
PIU6072 1% 2K COR47
D20 R47
NLHDMI0D21
HDMI_D21 71
PIU6071 45
PIU6045
NLHDMI0INT
HDMI_INT PIR4801 PIR4802
NLHDMI0D22 D21 INT
HDMI_D22 70
PIU6070
1% 2K COR48
NLHDMI0D23
D22 R48
HDMI_D23 69
PIU6069
NLHDMI0D24 D23 COL1
L1
HDMI_D24 68
PIU6068
NLHDMI0D25 D24 PIL101 PIL102 DVDD_HDMI
HDMI_D25 67
PIU6067
NLHDMI0D26 D25 MPZ1608S221A
HDMI_D26 66
PIU6066 PIC80 2 PIC8101 PIC8201 PIC8301 PIC8401 PIC8501 PIC8601 PIC8701 PIC8 01
NLHDMI0D27 D26 U6C
HDMI_D27 65
PIU6065 COC80
C80 COC81
C81 COC82
C82 COC83
C83 COC84
C84 COC85
C85 COC86
C86 COC87
C87 COC88
C88
NLHDMI0D28 D27
HDMI_D28 64
PIU6064 PIC80 1 10µF PIC8102 100nF PIC8202 100nF PIC8302 100nF PIC8402 100nF PIC8502 10nF PIC8602 10nF PIC8702 10nF PIC8 02 10nF Power
NLHDMI0D29 D28
HDMI_D29 63
PIU6063 1
PIU601 28
PIU6028
NLHDMI0D30 D29 DVDD_HDMI DVDD R_EXT
HDMI_D30 62
PIU6062 GND GND GND GND GND GND GND GND GND 19
PIU6019
NLHDMI0D31 D30 COL8
L8 DVDD PIR1401
HDMI_D31 61
PIU6061 49
PIU6049
NLHDMI0D32 D31 PIL801 PIL802 AVDD_HDMI DVDD COR14
R14
HDMI_D32 60
PIU6060
76
PIU6076
NLHDMI0D33
D32 MPZ1608S221A DVDD 887R
HDMI_D33 59
PIU6059 PIC8902 PIC9601 PIC9701 PIC10101 PIC10301 PIC104 1 PIC105 1 77
PIU6077
NLHDMI0D34 D33 DVDD PIR1402
HDMI_D34 58
PIU6058 COC89
C89 COC96
C96 COC97
C97 COC101
C101 COC103
C103 COC104
C104 COC105
C105
C NLHDMI0D35 D34 C
HDMI_D35 57
PIU6057 GND PIC8901 10µF PIC9602 100nF PIC9702 100nF PIC10102 100nF PIC10302 100nF PIC104 2 10nF PIC105 2 10nF 24
PIU6024
D35 AVDD_HDMI PVDD GND
25
PIU6025 18
PIU6018
PIC106 2 PVDD GND
ADV7511KSTZ GND GND GND GND GND GND GND 20
PIU6020
COC106
C106 GND
3.3V 21
PIU6021
22
PIU6022
COU10 100nF COL9
L9 PLVDD_HDMI PLVDD GND
U10 PIC106 1 23
PIU6023
NLCEC0A 1.8V PIL901 PIL902 PLVDD_HDMI GND
CEC_A 1
PIU1001 24
PIU10024 26
PIU6026 27
PIU6027
NLSCL0A CEC_A VCCA NLHDMI0TX20P MPZ1608S221A BGVDD GND
SCL_A 2
PIU1002 23
PIU10023 HDMI_TX2_P PIC107 2 PIC108 1 PIC109 1 PIC1 0 1 PIC1 201 31
PIU6031
NLSDA0A SCL_A D2+ NLHDMI0TX20N GND
SDA_A 3
PIU1003
22
PIU10022
HDMI_TX2_N COC107
C107 COC108
C108 COC109
C109 COC110
C110 COC112
C112 29
PIU6029
37
PIU6037
NLHPD0A
SDA_A D2- NLHDMI0TX10P
AVDD_HDMI AVDD GND
HPD_A 4
PIU1004
21
PIU10021 HDMI_TX1_P PIC107 1 10µF PIC108 2 100nF PIC109 2 100nF PIC1 0 2 10nF PIC1 202 10nF 34
PIU6034
44
PIU6044
NLLS0OE HPD_A D1+ NLHDMI0TX10N AVDD GND
LS_OE 5
PIU1005
20
PIU10020 HDMI_TX1_N 41 75
PIU6075
LS_OE D1- PIU6041 AVDD GND
6
PIU1006 19
PIU10019 GND GND GND GND GND 99
PIU6099
NLCEC0B GND GND GND GNDNLHDMI0TX00P GND
CEC_B 7
PIU1007
18
PIU10018
HDMI_TX0_P 47
PIU6047
100
PIU60100
NLSCL0B CEC_B D0+ NLHDMI0TX00N COL6
L6 MVDD_HDMI MVDD GND
SCL_B 8
PIU1008
17
PIU10017
HDMI_TX0_N
NLSDA0B
SCL_B D0- NLHDMI0TXC0P 3.3V PIL601 PIL602 MVDD_HDMI
SDA_B 9
PIU1009
16
PIU10016 HDMI_TXC_P ADV7511KSTZ
NLHPD0B SDA_B CLK+ NLHDMI0TXC0N MPZ1608S221A
HPD_B 10
PIU10010 15
PIU10015 HDMI_TXC_N
PIC1 302 PIC1 402 PIC1 501 PIC1 601 GND
HPD_B CLK-
11
PIU10011
14
PIU10014 COC113
C113 COC114
C114 COC115
C115 COC116
C116
5V VCC5V GND GND
NLCT0HPD
CT_HPD 12
PIU10012
13
PIU10013
NL5V0HDMI
5V_HDMI PIC1 301 10µF PIC1 401 10µF PIC1 502 100nF PIC1 602 10nF Title:
CT_HPD 5V_OUT
MEGA65
PIC1 701 TPD12S016PWR PIC17 01 GND GND GND GND
D COC117
C117 COC171
C171 D
Number: Rev.
PIC1 702 100nF PIC17 02 100nF A4 TE0765
Default 02
GND GND
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page19 of 23

Filename: HDMI.SchDoc
1 2 3 4
1 2 3 4

COU4A
COU4B
U4A
23
PIU4023 ETH_LED
NLETH0RD0P LED0/ANEN_SPEED
3.3V 4
ETH_RD_P PIU404
NLETH0RD0N RXP NLETH0CRS0DV
3
ETH_RD_N PIU403 15
PIU4015 ETH_CRS_DV
RXM CRS_DV/PHYAD[1:0] i ETH
PIR501 PIR601 NLETH0TD0P
ETH_TD_P 6
PIU406
A COR5
R5 COR6
R6 NLETH0TD0N TXP A
5
ETH_TD_N PIU405
1K 1K TXM
7
PIU407
PIR502 1%PIR602 1% XO
NLETH0MDIO
ETH_MDIO 10
PIU4010 8
PIU408
NLETH0CLK
ETH_CLK
NLETH0MDC MDIO XI i ETH
ETH_MDC 11
PIU4011 MDC NLETH0RST COJ10A
COJ10B
COJ10C
24
PIU4024 ETH-RST J10A
RST
ETH_TD_P 1
PIJ1001
COR9
R9 6K49 1% 9 TD+ J1
GND PIR901 PIR902
PIU409 REXT
NLETH0INT
ETH_INT 18
PIU4018 16
PIU4016
INTRP REF_CLK NLETH0RXER 75R 75R J4
17
PIU4017 ETH_RXER 4
PIJ1004
NLETH0TX0EN RXER i ETH PIC1802 TCT
ETH_TX_EN 19
PIU4019
ETH i TXEN COC18
C18 J5
NLETH0TX0D0
ETH_TX_D0 20
PIU4020 13
PIU4013
NLETH0RX0D0
ETH_RX_D0 PIC1801
100nF ETH_TD_N 2
PIJ1002
ETH i NLETH0TX0D1 TXD0 RXD0 NLETH0RX0D1 i ETH 25V TD- J2
ETH_TX_D1 21
PIU4021 12
PIU4012 ETH_RX_D1
ETH i TXD1 RXD1 i ETH
GNDX5R
KSZ8081RNDCA ETH_RD_P 3
PIJ1003 RD+ J3

75R 75R J7
5
PIJ1005
B RCT B
PIC1902 J8
1% COC19
C19
COR10
R10 NLETH0LED 100nF
PIC1901
J10B
PIJ1009 PIJ10010 PIR1001 PIR1002
ETH_LED ETH_RD_N 6
PIJ1006
3.3V L-GN 25V RD- J6
220R
GNDX5R
RJ45 - 7499011222A
8
PIJ1008
COR11
R11 GND GND
PIR1101 PIR1102 GND
10K 7
PIJ1007 NC
1%
1% 15
PIJ10015
J10C COR72
R72 NLETH0LED2
ETH_LED2 16
Frame
3.3V PIJ10011 PIJ10012
R-GN PIR7201 PIR7202 PIJ10016 Frame
220R
RJ45 - 7499011222A
RJ45 - 7499011222A

GND
PIR1201 PIC2901
PIC2101 PIC2801 COR12
R12 COC29
C29
COC21
C21 COC28
C28 1M PIC2902 100pF
C 22µF 470nF 1000V C
PIC2102 PIC2802 PIR1202 5%
6.3V 6.3V X7R
X5R X5R U4B
14
PIU4014 VDDIO
1
PIU401
NLVDD0102V
VDD_1.2V GND GND
3.3V VDD_1.2
PIC30 1 PIC3101
COC30
C30 COC31
C31
22
PIU4022
PIC30 2 2.2µF PIC3102 470nF
COL4
L4 GND
PIL401 PIL402 PIU402
2 25
PIU4025
6.3V 6.3V
VDDA_3.3 GND X7R X5R
BKP0603HS121-T PIC3201 PIC3 01 KSZ8081RNDCA
COC32
C32 COC33
C33
PIC3202 22µF PIC3 02 470nF GND
6.3V 6.3V
X5R X5R

GND Title:
MEGA65
D D
Nummer: Rev.
A4 TE0765
Default 02
Datum: 2019-03-11 Zeichner: Trenz Electronic GmbH Blatt 20 von 23

Filename: Ethernet.SchDoc
1 2 3 4
1 2 3 4

A A

http://linux-sunxi.org/MicroSD_Breakout

COJ2 COR27
R27 NLM0TCK
J2 SD_D2 PIR2701 PIR2702 M_TCK
COR52
R52PIR5202
12K1
PIR5201
1% NLSD0D2
SD_D2 1
PIJ201
3.3V DAT2 0R
COR55
R55PIR5502 12K1
PIR5501 1% NLSD0D3
SD_D3 2
PIJ202
3.3V COR56 NLSD0CMD CD/DAT3 1%
R56PIR5602 12K1
PIR5601 1% SD_CMD 3
PIJ203
3.3V CMD
4
PIJ204
3.3V NLSD0CLK VDD COR32
R32 NLM0TMS
SD_CLK 5
PIJ205 SD_D1 PIR3201 PIR3202 M_TMS
CLK
6
PIJ206 GND 0R
COR57
R57PIR5702 12K1
PIR5701 1% NLSD0D0
SD_D0 7
PIJ207
3.3V COR88 NLSD0D1 DAT0 1%
R88PIR8802 12K1
PIR8801 1% SD_D1 8
PIJ208
3.3V DAT1
COR33
R33 NLM0TDO
G1
PIJ20G1
SD_CMD PIR3301 PIR3302
M_TDO
GND
G2
PIJ20G2 0R
GND
G3
PIJ20G3 1%
GND
G4
B GND PIJ20G4 GND B
COR89 NLSD0CD COR34
R34 NLM0TDI
R89PIR8902
12K1
PIR8901
1% SD_CD 9
PIJ209 Card
SD_D0 PIR3401 PIR3402
M_TDI
3.3V
Detect 0R
Switch 1%
COC22
C22 10
PIJ2010
GND
3.3V PIC2201 PIC2202 GND COR35
R35
Micro SD Socket SD_D3 PIR3501 PIR3502
NLM0RX
M_RX
10µF
10V 0R
X5R 1%

COR36
R36 NLM0TX
SD_CLK PIR3601 PIR3602
M_TX
COJ15
J15
COR119 0R
R119 12K1
PIR11901
NLSD20D3
SD2_D3 1
PIJ1501
3.3V COR21
R21 PIR11902 NLSD20CMD CD/DAT3 1%
PIR2101 12K1
PIR2102 SD2_CMD 2
PIJ1502 CMD
3
GND PIJ1503 VSS1
4
NLSD20CLK 3.3V PIJ1504 VDD
COS3A
COS3B
COS3C
COS3D
S3A
SD2_CLK 5
PIJ1505 CLK
6 COR142
R142
PIR14202 12K1
PIR14201 1% NLCPLD0CFG0
CPLD_CFG0 8
PIS308 1
PIS301
C COR24
R24 NLSD20D0 GND PIJ1506 VSS2 3.3V C
PIR2401COR25 12K1 SD2_D0 7
PIJ1507 CHS-04TA
R25 PIR2402 NLSD20D1 DAT0
PIR2501COR26 12K1 SD2_D1 8
PIJ1508
R26 PIR2502 NLSD20D2 DAT1 S3B
PIR2601
12K1
PIR2602
SD2_D2 9
PIJ1509 DAT2
COR143
R143
PIR14302
12K1
PIR14301
1% NLCPLD0CFG1
CPLD_CFG1 7
PIS307
2
PIS302
COR120
R120 NLSD20CD
PIR12001 12K1
PIR12002 SD2_CD 10
PIJ15010 CHS-04TA
CD Card
COR121 Detect
R121 12K1
PIR12101 PIR12102
NLSD20WP
SD2_WP 11
PIJ15011 Switch
S3C
WP COR144 NLCPLD0CFG2
R144
PIR14402
12K1
PIR14401
1% CPLD_CFG2 6
PIS306
3
PIS303
CHS-04TA
COC27
C27 12
PIJ15012 GND S3D
3.3V PIC2701 PIC2702 GND
MMC SD Socket COR31
R31PIR3102
12K1
PIR3101
1% NLCPLD0CFG3
CPLD_CFG3 5
PIS305
4
PIS304
10µF
CHS-04TA
10V GND
X5R

Title:
MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page21 of 23

Filename: LED_SW_BUT.SchDoc
1 2 3 4
1 2 3 4

COU12
U12
PIU1201
1 7
PIU1207 VOUT
12V_FUSED PIC302 PIC702 Vin Vout PIR201 PIC802 PIC1301 PIC1501 PIC1601 PIR15 01 5V
4.67V
COC3
C3 COC7
C7 2 5 COR2
R2 COC8
C8 COC13
C13 COC15
C15 COC16
C16 COR155
R155
GND PIU1202 SYNC FB PIU1205
22µF
PIC301 47nF
PIC701 5K6 PIC801 47nF PIC1302 100µF PIC1502 100µF PIC1602 100µF 27K
A 25V 50V PIR202 1% 50V 10V 10V 10V PIR15 02 1% A
3
PIU1203 6
PIU1206

AGND
GND
X7R EN SS/TRK PIC1701 X7R X5R X5R X5R PIC18 01 PIR160 1
X5R
GND GND COC17
C17 PIR401 COC181
C181 COR160
R160

4
8
PIU1204 PIU1208 470nF
PIC1702 COR4
R4 GND 10nF
PIC18 02 27K
171050601 50V 1K15 50V PIR160 2 1%
GND GND X7R PIR402 1% NLCPLD0ADC1
CPLD_ADC1 X7R
GND GND GND
GND
COU14
U14
1
PIU1401 7
PIU1407 VOUT
12V_FUSED PIC3702 PIC3802 Vin Vout PIR1901 PIC3902 PIC40 1 PIC9 01 PIC10 01 3.3V
3.30V
COC37
C37 COC38
C38 2 5 COR19
R19 COC39
C39 COC40
C40 COC99
C99 COC100
C100
GND PIU1402 SYNC FB PIU1405
PIC3701
22µF PIC3801
47nF 3K3 PIC3901 47nF PIC40 2 100µF PIC9 02 100µF PIC10 02 100µF
25V 50V 3
PIU1403 6
PIU1406 PIR1902 1% 50V 10V 10V 10V

AGND
GND
X7R 1.8V EN SS/TRK X7R X5R X5R X5R
X5R PIC102 1
GND GND COC102
C102 PIR20 1

4
8
PIU140 PIU1408 470nF
PIC102 COR20
R20 GND
171050601 50V 1K05
GND GND X7R PIR20 2 1%
B B
GND
AO4832 AO4832 GND
T5B COT5A
COT5B
T5A
PIT508 8 6
PIT506
PIT507 7 1
PIT501
PIT503 3 5
PIT505

2
4
PIT502 PIT504
PIR13501 PIR13601
COR135
R135 COR136
R136
10R 10R
PIR13502 PIR13602 SR= 2V/ms
COR137
R137
COC139
C139
PIR13701 PIR13702
PIC13901 PIC13902
5K1 10nF GND
50V
X7R
C COS1 C
HV S1

8
COJ11
J11 i COL5
L5 1 VIN
PIS101
NLVIN COU34
U34 PIU3408
1
PIJ1101
1
PIL501
4
PIL504
2
PIS102
1
PIU3401 Vin
7
PIU3407
PID501 PIR13801 PIR13901 Vout PIC14 01 12V_FUSED
3
PIS103
3 COD5
D5 2 3 COR138
R138 COR139
R139 COC144
C144
GATE
PIJ1103 PIL502 PIL503
1M 470K PIC14 02 10µF
PIS10F1 PIS10F2

F1
F2
2
PIJ1102 9µH PIR13802 1% PIR13902 1% 5
PIU3405 6
PIU3406
16V
NLPOWER0GND SHDN FAULT
POWER_GND PID502 2
PIU3402 UV
GNDX5R
Power Jack 2.1mm 90° SMD GND PIR140 1
SMBJ20A, 20V, 600W GND COR140
R140
A101J1AV2Q004 27K
OV = 14V
PIR140 2 1% 3
OV
UV = 10V
PIR14 01 PIU3403
COR141
R141
37K4
PIR14 02 1% 4
PIU3404 GND
Title:
GND LTC4365ITS8#TRMPBF MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH Page22 of 23

Filename: PowerMain.SchDoc
1 2 3 4
1 2 3 4

5V 1V
COU11
U11 COC6
C6
COR17
R17
PIR1701 PIR1702
PG_1V0 28
PIU11028
5
PIU1105 PIC601
X5R
PIC602
5V POK VOUT GND
10K COC41
C41 6
PIU1106 6.3V
VOUT 47µF
PIC4101 PIC4102 19
PIU11019 7
PIU1107
GND PVIN VOUT
20
PIU11020 8
PIU1108
A 22µF PVIN VOUT PIR4901 PIC1 101 A
21
PIU11021 9
PIU1109
25V PVIN VOUT COR49
R49 COC111
C111
10
PIU11010
X5R VOUT 200K PIC1 102 22pF
33
PIU11033 11
PIU11011
AVIN VOUT PIR4902
1% 6.3V
27
PIU11027 31
PIU11031 NP0
ENABLE VFB
1
PIU1101 NC(SW)
PIR50 1
2 COR50
R50
PIU1102 NC(SW)
12
PIU11012 26
PIU11026
604K
NC(SW) LLM/SYNC
3
PIU1103 NC
02
PIR51%
4
PIU1104 NC
22
PIU11022 NC
23
PIU11023 NC
24
PIU11024 29
PIU11029
NC RLLM
25
PIU11025 NC
34
PIU11034 NC(SW)
35
PIU11035
30
PIU11030
NC(SW) SS Soft-start 3.8ms
36
PIU11036
PIC1 901
NC(SW) COC119
C119
37
PIU11037 32
PIU11032
B NC(SW) AGND 47nF B
38
PIU11038 NC(SW)
PIC1 902
13
PIU11013
6.3V
PGND
17
PIU11017
14
PIU11014
GNDX5R
PGND PGND
18
PIU11018 15
PIU11015
PGND PGND
16
PIU11016 39
PIU11039
PGND PGND
GND EN6347QI GND

1V
C C
PIR16 02
5V COR161
R161
COU13
U13 10K
14
PIU13014 7
PIU1307
NLCPLD0ADC3
CPLD_ADC3 PIR16 01
PVIN VOUT 1.8V
PIC120 1 8
PIU1308
PIC12101 PIR1620 PIC18201
COC120
C120 VOUT COC121
C121 COR162
R162 COC182
C182
10µF
PIC120 2 COR51
R51 PIC12102 10µF 10K 10nF
PIC1820
PIR5101 PIR5102
13
PIU13013
5
PIU1305
10V AVIN VSENSE 10V NLCPLD0ADC2 50V
100R CPLD_ADC2 PIR16201
GNDX5R 12 4 GNDX5R PIC18301 X7R
1% PIU13012 ENABLE NC PIU1304
1 COC183
C183 GND
NLPG01V0 NC(SW) PIU1301 10nF
PG_1V0 3
PIU1303 LLM
15
NC(SW) PIU13015
PIC18302
16 50V
NC(SW) PIU13016 X7R
11
PIU13011 VS0
10
PIU13010 6
PIU1306 GND
VS1 AGND
9
PIU1309 VS2
2
PIU1302
5V PGND GND
Title:
EP53A7HQI MEGA65
D D
Number: Rev.
A4 TE0765
Default 02
Date: 2019-03-11 Copyright: Trenz Electronic GmbH / TT Page23 of 23

Filename: POWER.SchDoc
1 2 3 4
NEXYS WIDGET BOARD SCHEMATICS

AB-51
C65 Keyboard Connector C64 Keyb Con
SV2
1 1
C65_ROW8 2 2
GND C65_REST 3 GND /REST 3
C65_COL8 4 4
C65_ROW7 5 ROW3 5
C65_ROW6 6 +3V3 ROW6 6
C65_ROW5 7 ROW5 7

+3V3
C65_ROW4 8 ROW4 8
C65_ROW3 9 ROW7 9
U1A U1B C65_ROW2 10 ROW2 10
G1 C65_ROW1 11 ROW1 11

C21
33pF
+3V3
- + 6 91 C65_ROW0 12 ROW0 12
VBAT VDD_2

Q1
GND
31 NRST 136 C65_COL7 13 COL0 13
NRST VDD_3

L1
GND CR2032H 36 30 149 C65_COL6 14 COL6 14
VDDA_2 PH1 R4 VDD_4

8Mhz
39 29 127 132 ST_D1 C65_COL5 15 COL5 15

C22
33pF
R3 VDDA PH0 VDD_5 PI1
49 103 131 ST_D0 C65_COL4 16 COL4 16
VDD_2 220R VDD_6 PI0

+3V3
GND
C17 C18 15 5 C65_ROW6 159 130 C64_/RW C65_COL3 17 COL3 17
47R VDD_3 PE6 VDD_7 PH15
23 4 C65_ROW5 114 129 C64_/IRQ C65_COL2 18 COL2 18
VDD_4 PE5 VDD_8 PH14
100nF 1µF 62 3 C65_ROW4 172 128 C64_/DMA C65_COL1 19 COL1 19
VDD_5 PE4 VDD PH13
72 2 C65_ROW3 89 C64_/EXROM C65_COL0 20 COL7 20
VDD_6 PE3 PH12
82 1 C65_ROW2 XADC3_N 92 176 ST_D7 C65_K1 21
VDD PE2 PB12 PI7
GND C20 C19 XADC3_P 93 175 ST_D6 C65_K2 22 SV1
PB13 PI6
PI8 7 88 C64_/GAME XADC4_N 94 174 ST_D5 23
PI8 PH11 PB14 PI5

R39 10k +3V3


100nF 1µF J2_BUTTON 8 87 C64_/ROMH XADC4_P 95 173 ST_D4 PWR_LED R5 POWER_LED 24
PC13 PH10 PB15 PI4 +3V3
/REST 9 86 C64_/ROML COL0 96 171 FDD_LED R6 100R FLOPPY_LED 25
PC14 PH9 PD8 PDR_ON
C65_REST 10 85 C64_I/O1 COL1 97 170 C65_ROW1 100R
PC15 PH8 PD9 PE1
PI9 11 84 C64_I/O2 COL2 98 169 C65_ROW0
PI9 PH7 PD10 PE0
PI10 12 83 C64_/NMI COL3 99 168 XADC1_P
PI10 PH6 PD11 PB9
PI11 13 81 COL4 100 167 XADC1_N
PI11 VCAP_1 PD12 PB8

+3V3
80 XADC2_P C30 COL5 101 166 BOOT0
PB11 PD13 BOOT0
ST_A0 16 79 XADC2_N 165 PB7 Joystick1
PF0 PB10 PB7
+3V3

ST_A1 17 78 C65_COL6 2,2µF COL6 104 164 PB6 R1 1k J1_UP


PF1 PE15 PD14 PB6 X3-1
ST_A2 18 77 C65_COL5 COL7 105 163 PWR_LED R23 1k J1_DOWN
PF2 PE14 PD15 PB5

R28 10k
R29 10k
1k X3-2
ST_A3 19 76 C65_COL4 JA3 106 162 FDD_LED R24 J1_LEFT
PF3 PE13 GND PG2 PB4 X3-3
ST_A4 20 75 C65_COL3 JA4 107 161 /R_W_D0-D7 R25 1k J1_RIGHT
PF4 PE12 PG3 PB3 X3-4
ST_A5 21 74 C65_COL2 JA7 108 160 JB10 POT1_Y
PF5 PE11 PG4 PG15 BOOT0 BOOT1 X3-5
ST_A6 24
PF6 PE10
73 C65_COL1 JA8 109
PG5 PG14
157 JB9 R27 1k J1_BUTTON X3-6
ST_A7 25 70 C65_COL0 JA9 110 156 JB8 R26 47R
PF7 PE9 PG6 PG13 X3-7
ST_A8 26 69 C65_ROW8 JA10 111 155 JB7
PF8 PE8 PG7 PG12 X3-8
ST_A9 27 68 C65_ROW7 JB1 112 154 JB4 POT1_X
PF9 PE7 PG8 PG11 X3-9
ST_A10 28 67 JA2 153 JB3 GND
PF10 PG1 PG10
R31 510R
R30 510R

C65_COL7 32 66 JA1 J1_LEFT 115 152 JB2


PC0 PG0 PC6 PG9
C65_COL8 33 65 ST_A15 J1_RIGHT 116 151 ROW7
PC1 PF15 PC7 PD7
C65_K1 34 64 ST_A14 J2_DOWN 117 150 ROW6
PC2 PF14 PC8 PD6
C65_K2 35 63 ST_A13 J2_UP 118 147 ROW5
PC3 PF13 PC9 PD5 GND GND
60 ST_A12 PA8 119 146 ROW4
PF12 PA8 PD4
38 59 ST_A11 PA9 120 145 ROW3
VREF+ PF11 PA9 PD3
58 BOOT1 PA10 121 144 ROW2 SV8
PB2 PA10 PD2
POT1_Y 40 57 /R_W_A8-15 USB_D_N 122 143 ROW1 1 Joystick2
PA0 PB1 PA11 PD1 VCC
+3V3

POT1_X 41 56 /R_W_A0-7 USB_D_P 123 142 ROW0 USB_D_N 2 R2 1k J2_UP


PA1 PB0 PA12 PD0 DM X5-1
POT2_Y 42 55 J1_DOWN PA13 124 141 J1_BUTTON USB_D_P 3 R7 1k J2_DOWN
PA2 PC5 PA13 PC12 DP X5-2
USB

RESET 43
PH2 PC4
54 J1_UP 125
VCAP_2 PC11
140 J2_RIGHT 4
GND R8 1k J2_LEFT X5-3
PH3 44
PH3 PA7
53 PA7 C29 PC10
139 J2_LEFT R9 1k J2_RIGHT X5-4
52 C64_CLOCK 135 138 PA15 USB-B-G-B POT2_Y
PA6 VSS_2 PA15 X5-5
14 51 C64_02 2,2µF 113 137 PA14 R22 1k J2_BUTTON
VSS_2 PA5 VSS_3 PA14 X5-6
71 50 C64_BA 126 134 ST_D3 R21 47R
VSS_3 PA4 VSS_4 PI3 GND X5-7
22 48 90 133 ST_D2
VSS_4 BYPASS_REG VSS_5 PI2 X5-8
61 47 POT2_X 148 POT2_X
VSS PA3 VSS_6 X5-9
46 C64_/RESET 102 GND
PH5 VSS_7
37 45 158
VSSA PH4 VSS

R38 10k
GND STM32F407IET6__FI__ STM32F407IET6__FI__
GND
GND
R36 100k +3V3
R32 +3V3
47R

NRST 1
PA14 R33 47R 2
C31 3
1 JP1
PA13 R34 47R 4
2
100nF R35 47R 5
GND NRST 6

+3V3
SV4
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16
GND
100nF 100nF 100nF 100nF 100nF 100nF 100nF 100nF 100nF 100nF 100nF 100nF 100nF 100nF 1µF 1µF

GND

TITLE: c65Keyb

Document Number: REV:

Date: 6/05/2022 10:40 AM Sheet: 1/2


Nexys 4 Input Output Driver Expansion Slot
SV3
GND 1 A GND
VCC 2 B C64_/ROMH
VCC 3 C C64_/RESET GND

+3V3
+3V3
U2 GND VCC C64_/IRQ 4 D C64_/NMI
SV5
C64_A0 3 21 ST_A0 C64_/RW 5 E C64_02
12 11 A1 B1
C64_A1 4 20 ST_A1 C64_CLOCK 6 F C64_A15
10 9 A2 B2
C64_A2 5 19 ST_A2 C64_I/O1 7 H C64_A14
JB4 8 7 JB10 A3 B3
C64_A3 6 18 ST_A3 C64_/GAME 8 J C64_A13
GND JB3 6 5 JB9 GND A4 B4
C64_A4 7 17 ST_A4 C64_/EXROM 9 K C64_A12
JB2 4 3 JB8 A5 B5
C64_A5 8 16 ST_A5 C64_I/O2 10 L C64_A11
JB1 2 1 JB7 A6 B6
C64_A6 9 15 ST_A6 C64_/ROML 11 M C64_A10
A7 B7
C64_A7 10 14 ST_A7 C64_BA 12 N C64_A9
A8 B8
C64_/DMA 13 P C64_A8
/R_W_A0-7 2 C64_D7 14 R C64_A7
DIR
22 C64_D6 15 S C64_A6
OE
+3V3 C64_D5 16 T C64_A5
1 23 C64_D4 17 U C64_A4
VCCA VCCB
13 24 C64_D3 18 V C64_A3
VCC GND2 VCCB1
SV6 12 11 C64_D2 19 W C64_A2
GND1 GND

+3V3
+3V3
12 11 C64_D1 20 X C64_A1
10 9 744245 C64_D0 21 Y C64_A0
JA4 8 7 JA10 GND GND GND 22 Z GND
GND JA3 6 5 JA9 GND
JA2 4 3 JA8 EDGE-CON-44P
JA1 2 1 JA7 U3 GND GND
C64_A8 3 21 ST_A8
A1 B1
C64_A9 4 20 ST_A9
A2 B2
C64_A10 5 19 ST_A10
A3 B3
C64_A11 6 18 ST_A11
A4 B4
C64_A12 7 17 ST_A12
A5 B5

VCC
C64_A13 8 16 ST_A13
A6 B6
SV7 C64_A14 9 15 ST_A14
A7 B7 R11

+3V3
+3V3
C64_A15 10 14 ST_A15 C64_/RW
12 11 A8 B8
VCC
VCC

10 9 3k3 SV9
+3V3
+3V3

/R_W_A8-15 2
XADC4_P 8 7 XADC4_N DIR R12 20 19
22 C64_/IRQ
GND XADC3_P 6 5 XADC3_N GND OE 18 17
4 3 +3V3 3k3 16 15
XADC2_P XADC2_N 1 23 PH3
XADC1_P 2 1 XADC1_N VCCA VCCB R13 PH2 14 13 PI11
13 24 C64_/DMA
VCC GND2 VCCB1 PI10 12 11 PI9
12 11
GND1 GND 3k3 PI8 10 9 PB7
R14 PB6 8 7 PA15
744245 C64_/EXROM 6 5
PA10 PA9
3k3 PA8 4 3 PA7
GND GND R15 2 1
C64_/GAME
U4 3k3
3 21
R16 GND GND
C64_D0 A1 B1 ST_D0 C64_/ROMH
C64_D1 4 20 ST_D1
A2 B2 3k3
C64_D2 5 19 ST_D2
A3 B3 R17
C64_D3 6 18 ST_D3 C64_/ROML
A4 B4
C64_D4 7 17 ST_D4
A5 B5 3k3
C64_D5 8 16 ST_D5
A6 B6 R18
C64_D6 9 15 ST_D6 C64_I/O1
A7 B7
C64_D7 10 14 ST_D7
A8 B8 3k3

VCC
S1

+3V3
2
R19
/R_W_D0-D7 DIR C64_I/O2
22
1 OE 3k3
J2 2 +3V3 R20
3 1 23 C64_/NMI
3 VCCA VCCB
2 X4-3 13 24
B1 VCC GND2 VCCB1 3k3
1 12 11
GND1 GND R10
X4-2 C64_/RESET
GND
744245 3k3
X4-1
MKDS_5/3-6,35 GND GND

C32
100nF
GND

RESET SW1

VCC
+3V3

+3V3
R37 2 1
3k3 C23 C24 C25 C26 C27 C28
3 4
100nF 100nF 100nF 100nF 100nF 100nF

GND GND GND

GND

TITLE: c65Keyb

Document Number: REV:

Date: 6/05/2022 10:40 AM Sheet: 2/2


71R

31R
61R

81R
51R

91R
41R
21R
01R

11R
02R

1R
72R
32R
62R
42R
52R

2R 3R
22R
7R 83R 71C 7C
81C 3C
12R 51C
8R
9R 21C
92R 03R 41C

61C
5C
6C
23C

2C
1C

03C
6R
5R
73R

33R 23R
63R

43R
53R
13C

mottoB
APPENDIX AC
Supporters & Donors
• Organisations
• Contributors
• Supporters
AC-2
The MEGA65 would not have been possible to create without the generous support
of many organisations and individuals.
We are still compiling these lists, so apologies if we haven’t included you yet. If you
know anyone we have left out, please let us know, so that we can recognise the con-
tribution of everyone who has made the MEGA65 possible, and into the great retro-
computing project that it has become.

ORGANISATIONS
The MEGA Museum of Electronic Games & Art e.V. Germany
EVERYTHING
Trenz Electronic, Germany
MOTHERBOARD MANUFACTURING SALES
Hintsteiner, Austria
CASE
GMK, Germany
KEYBOARD
KEVAG Telekom, Germany
WEB HOSTING

AC-3
CONTRIBUTORS
Andreas Liebeskind Dr. Canan Hastik
(libi in paradize) (indica)
CFO MEGA eV Chairwoman MEGA eV
Simon Jameson
Thomas Hertzler (Shallan)
(grumpyninja) Platform enhancements
USA spokesman
Stephan Kleinert
(ubik)
Russell Peake Destroyer of BASIC 10
(rdpeake)
Bug herding Wayne Johnson
(sausage)
Alexander Nik Petra Manual additions
(n0d) L. Kleiss
Early case design (LAK132)
MegaWAT presentation software
Ralph Egas
(0-limits) Maurice van Gils
Business advisor (Maurice)
BASIC 65 example programs
Lucas Moss Andrew Owen
MEGAphone PCB design (Cheveron)
Keyboard, Sinclair support
Daren Klamer
(Impakt) Adam Barnes
Manual proof-reading (amb5l)
HDMI expert and board revision
Daniël Mantione Wayne Rittimann, Jr.
(dmantione) (johnwayner)
C64 hardware guru Bug squashing on all levels

AC-4
SUPPORTERS
3c74ce64 Arne Neumann Christian Gräfe
8-Bit Classics Arne Richard Tyarks Christian Heffner
@11110110100 Axel Klahr Christian Kersting
Aaron Smith Balaz Ondrej Christian Schiller
Achim Mrotzek Barry Thompson Christian Streck
Adolf Nefischer Bartol Filipovic Christian Weyer
Adrian Esdaile Benjamin Maas Christian Wyk
Adrien Guichard Bernard Alaiz Christoph Haug
Ahmed Kablaoui Bernhard Zorn Christoph Huck
Alan Bastian Witkowski Bieno Marti-Braitmaier Christoph Pross
Alan Field Bigby Christopher Christopher
Alastair Paulin-Campbell Bill LaGrue Christopher Kalk
Alberto Mercuri Bjoerg Stojalowski Christopher Kohlert
Alexander Haering Björn Johannesson Christopher Nelson
Alexander Kaufmann Bjørn Melbøe Christopher Taylor
Alexander Niedermeier Bo Goeran Kvamme Christopher Whillock
Alexander Soppart Boerge Noest Claudio Piccinini
Alfonso Ardire Bolko Beutner Claus Skrepek
Amiga On The Lake Brett Hallen Collen Blijenberg
André Kudra Brian Gajewski Constantine Lignos
André Simeit Brian Green Crnjaninja
André Wösten Brian Juul Nielsen Daniel Auger
Andrea Farolfi Brian Reiter Daniel Julien
Andrea Minutello Bryan Pope Daniel Lobitz
Andreas Behr Burkhard Franke Daniel O’Connor
Andreas Freier Byron Goodman Daniel Teicher
Andreas Grabski Cameron Roberton (KONG) Daniel Tootill
Andreas Millinger Carl Angervall Daniel Wedin
Andreas Nopper Carl Danowski Daniele Benetti
Andreas Ochs Carl Stock Daniele Gaetano Capursi
Andreas Wendel Manufaktur Carl Wall Dariusz Szczesniak
Andreas Zschunke Carlo Pastore Darrell Westbury
Andrew Bingham Carlos Silva David Asenjo Raposo
Andrew Dixon Carsten Sørensen David Dillard
Andrew Mondt Cenk Miroglu Miroglu David Gorgon
Andrzej Hłuchyj Chang sik Park David Norwood
Andrzej Sawiniec Charles A. Hutchins Jr. David Raulo
Andrzej Śliwa Chris Guthrey David Ross
Anthony W. Leal Chris Hooper de voughn accooe
Arkadiusz Bronowicki Chris Stringer Dean Scully
Arkadiusz Kwasny Christian Boettcher Dennis Jeschke
Arnaud Léandre Christian Eick Dennis Schaffers
Arne Drews Christian Gleinser Dennis Schierholz

AC-5
Dennis Schneck Frank Haaland Helge Förster
denti Frank Hempel Hendrik Fensch
Dick van Ginkel Frank Koschel Henning Harperath
Diego Barzon Frank Linhares Henri Parfait
Dierk Schneider Frank Sleeuwaert Henrik Kühn
Dietmar Krueger Frank Wolf Holger Burmester
Dietmar Schinnerl FranticFreddie Holger Sturk
Dirk Becker Fredrik Ramsberg Howard Knibbs
Dirk Wouters Fridun Nazaradeh Hubert de Hollain
Domingo Fivoli Friedel Kropp Huberto Kusters
DonChaos Garrick West Hugo Maria Gerardus v.d. Aa
Donn Lasher Gary Lake-Schaal Humberto Castaneda
Douglas Johnson Gary Pearson Ian Cross
Dr. Leopold Winter Gavin Jones IDE64 Staff
Dusan Sobotka Geir Sigmund Straume Igor Ianov
Earl Woodman Gerd Mitlaender Igor Kurtes
Ed Reilly Giampietro Albiero Immo Beutler
Edoardo Auteri Giancarlo Valente Ingo Katte
Eduardo Gallardo Gianluca Girelli Ingo Keck
Eduardo Luis Arana Giovanni Medina Insanely Interested Publishing
Eirik Juliussen Olsen Glen Fraser IT-Dienstleistungen Obsieger
Emilio Monelli Glen R Perye III Ivan Elwood
EP Technical Services Glenn Main Jaap HUIJSMAN
Epic Sound Gordon Rimac Jace Courville
Erasmus Kuhlmann GRANT BYERS Jack Wattenhofer
ergoGnomik Grant Louth Jakob Schönpflug
Eric Hilaire Gregor Bubek Jakub Tyszko
Eric Hildebrandt Gregor Gramlich James Hart
Eric Hill Guido Ling James Marshburn
Eric Jutrzenka Guido von Gösseln James McClanahan
Erwin Reichel Guillaume Serge James Sutcliffe
Espen Skog Gunnar Hemmerling Jan Bitruff
Evangelos Mpouras Günter Hummel Jan Hildebrandt
Ewan Curtis Guy Simmons Jan Iemhoff
Fabio Zanicotti Guybrush Threepwood Jan Kösters
Fabrizio Di Dio Hakan Blomqvist Jan Peter Borsje
Fabrizio Lodi Hans Pronk Jan Schulze
FARA Gießen GmbH Hans-Jörg Nett Jan Stoltenberg-Lerche
FeralChild Hans-Martin Zedlitz Janne Tompuri
First Choice Auto’s Harald Dosch Jannis Schulte
Florian Rienhardt Harri Salokorpi Jari Loukasmäki
Forum64. de Harry Culpan Jason Smith
Francesco Baldassarri Harry Venema Javier Gonzalez Gonzalez
Frank Fechner Heath Gallimore Jean-Paul Lauque
Frank Glaush Heinz Roesner Jeffrey van der Schilden
Frank Gulasch Heinz Stampfli Jens Schneider

AC-6
Jens-Uwe Wessling Kenneth Joensson Marco Cappellari
Jesse DiSimone Kevin Edwards Marco Rivela
Jett Adams Kevin Thomasson Marco van de Water
Johan Arneklev Kim Jorgensen Marcus Gerards
Johan Berntsson Kim Rene Jensen Marcus Herbert
Johan Svensson Kimmo Hamalainen Marcus Linkert
Johannes Fitz Konrad Buryło Marek Pernicky
John Cook Kosmas Einbrodt Mario Esposito
John Deane Kurt Klemm Mario Fetka
John Dupuis Lachlan Glaskin Mario Teschke
John Nagi Large bits collider Mariusz Tymków
John Rorland Lars Becker Mark Adams
John Sargeant Lars Edelmann Mark Anderson
John Traeholt Lars Slivsgaard Mark Green
Jon Sandelin Lasse Lambrecht Mark Hucker
Jonas Bernemann Lau Olivier Mark Leitiger
Jonathan Prosise Lee Chatt Mark Spezzano
Joost Honig Loan Leray Mark Watkin
Jordi Pakey-Rodriguez Lorenzo Quadri Marko Rizvic
Jöre Weber Lorenzo Travagli Markus Bieler
Jörg Jungermann Lorin Millsap Markus Bonet
Jörg Schaeffer Lothar James Foss Markus Dauberschmidt
Jörg Weese Lothar Serra Mari Markus Fehr
Josef Hesse Luca Papinutti Markus Fuchs
Josef Soucek Ludek Smetana Markus Guenther-Hirn
Josef Stohwasser Lukas Burger Markus Liukka
Joseph Clifford Lutz-Peter Buchholz Markus Merz
Joseph Gerth Luuk Spaetgens Markus Roesgen
Jovan Crnjanin Mad Web Skills Markus Uttenweiler
Juan Pablo Schisano MaDCz Martin Bauhuber
Juan S. Cardona Iguina Magnus Wiklander Martin Benke
JudgeBeeb Maik Diekmann Martin Gendera
Juliussen Olsen Malte Mundt Martin Groß
Juna Luis Fernandez Garcia Manfred Wittemann Martin Gutenbrunner
Jürgen Endras Manuel Beckmann Martin Johansen
Jürgen Herm Stapelberg Manzano Mérida Martin Marbach
Jyrki Laurila Marc ”3D-vice” Schmitt Martin Sonnleitner
Kai Pernau Marc Bartel Martin Steffen
Kalle Pöyhönen Marc Jensen Marvin Hardy
Karl Lamford Marc Schmidt Massimo Villani
Karl-Heinz Blum Marc Theunissen Mathias Dellacherie
Karsten Engstler Marc Tutor Mathieu Chouinard
Karsten Westebbe Marc Wink Matthew Adams
katarakt Marcel Buchtmann Matthew Browne
Keith McComb Marcel Kante Matthew Carnevale
Kenneth Dyke Marco Beckers Matthew Palmer

AC-7
Matthew Santos Michele Porcu Paul Jackson
Matthias Barthel Miguel Angel Rodriguez Jodar Paul Johnson
Matthias Dolenc Mikael Lund Paul Kuhnast (mindrail)
Matthias Fischer Mike Betz Paul Massay
Matthias Frey Mike Kastrantas Paul Westlake
Matthias Grandis Mike Pikowski Paul Woegerer
Matthias Guth Mikko Hämäläinen Pauline Brasch
Matthias Lampe Mikko Suontausta Paulo Apolonia
Matthias Meier Mirko Roller Pete Collin
Matthias Mueller Miroslav Karkus Pete of Retrohax.net
Matthias Nofer Morgan Antonsson Peter Eliades
Matthias Schonder Moritz Peter Gries
Maurice Al-Khaliedy Morten Nielsen Peter Habura
Max Ihlenfeldt MUBIQUO APPS,SL Peter Herklotz
Meeso Kim Myles Cameron-Smith Peter Huyoff
Michael Dailly Neil Moore Peter Knörzer
Michael Dötsch Nelson Peter Leswell
Michael Dreßel neoman Peter Weile
Michael Fichtner Nicholas Melnick Petri Alvinen
Michael Fong Nikolaj Brinch Jørgensen Philip Marien
Michael Geoffrey Stone Nils Andreas Philip Timmermann
Michael Gertner Nils Eilers Philipp Rudin
Michael Grün Nils Hammerich Pierre Kressmann
Michael Habel Nils77 Pieter Labie
Michael Härtig Norah Smith Piotr Kmiecik
Michael Haynes Norman King Power-on.at
Michael J Burkett Normen Zoch Przemysław Safonow
Michael Jensen Olaf Grunert Que Labs
Michael Jurisch Ole Eitels R Welbourn
Michael Kappelgaard Oliver Boerner R-Flux
Michael Kleinschmidt Oliver Brüggmann Rafał Michno
Michael Lorenz Oliver Graf Rainer Kappler
Michael Mayerhofer Oliver Smith Rainer Kopp
Michael Nurney Olivier Bori Rainer Weninger
Michael Rasmussen ONEPSI LLC Ralf Griewel
Michael Richmond oRdYNe Ralf Pöscha
Michael Sachse Osaühing Trioflex Ralf Reinhardt
Michael Sarbak OSHA-PROS USA Ralf Schenden
Michael Schneider Padawer Ralf Smolarek
Michael Scholz Patrick Becher Ralf Zenker
Michael Timm Patrick Bürckstümmer Ralph Bauer
Michael Traynor Patrick de Zoete Ralph Wernecke
Michael Whipp Patrick Toal Rédl Károly
Michal Ursiny Patrick Vogt Reiner Lanowski
Michele Chiti Paul Alexander Warren Remi Veilleux
Michele Perini Paul Gerhardt (KONG) Riccardo Bianchi

AC-8
Richard Englert Sigurbjorn Larusson Thomas Niemann
Richard Good Sigurdur Finnsson Thomas Scheelen
Richard Menedetter Simon Lawrence Thomas Schilling
Richard Sopuch Simon Wolf Thomas Tahsin-Bey
Rick Reynolds spreen.digital Thomas Walter
Rico Gruninger Stefan Haberl Thomas Wirtzmann
Rob Dean Stefan Kramperth Thorsten Knoll
Robert Bernardo Stefan Richter Thorsten Nolte
Robert Eaglestone Stefan Schultze Tim Krome
Robert Grasböck Stefan Sonnek Tim Waite
Robert Miles Stefan Theil Timo Weirich
Robert Schwan Stefan Vrampe Timothy Blanks
Robert Shively Stefano Canali Timothy Henson
Robert Tangmar Stefano Mozzi Timothy Prater
Robert Trangmar Steffen Reiersen Tobias Butter
Rodney Xerri Stephan Bielmann Tobias Heim
Roger Olsen Stephen Jones Tobias Köck
Roger Pugh Stephen Kew Tobias Lüthi
Roland Attila Kett Steve Gray Tommi Vasarainen
Roland Evers Steve Kurlin Toni Ammer
Roland Schatz Steve Lemieux Tore Olsen
Rolf Hass Steven Combs Torleif Strand
Ronald Cooper Stewart Dunn Torsten Schröder
Ronald Hunn Stuart Marsh Tuan Nguyen
Ronny Hamida Sven Neumann Uffe Jakobsen
Ronny Preiß Sven Stache Ulrich Hintermeier
Roy van Zundert Sven Sternberger Ulrich Nieland
Rüdiger Wohlfromm Sven Wiegand Ulrik Kruse
Ruediger Schlenter Szabolcs Bence Urban Lindeskog
Rutger WIllemsen Tantrumedia Limited Ursula Förstle
Sampo Peltonen Techvana Operations Ltd. Uwe Anfang
Sarmad Gilani Teddy Turmeaux Uwe Boschanski
SAS74 Teemu Korvenpää Vedran Vrbanc
Sascha Hesse The Games Foundation Verm Project
Scott Halman Thierry Supplisson Wayne Rittimann
Scott Hollier Thieu-Duy Thai Wayne Sander
Scott Robison Thomas Bierschenk Wayne Steele
Sebastian Baranski Thomas Edmister Who Knows
Sebastian Bölling Thomas Frauenknecht Winfried Falkenhahn
Sebastian Felzmann Thomas Gitzen Wolfgang Becker
Sebastian Lipp Thomas Gruber Wolfgang Stabla
Sebastian Rakel Thomas Haidler Worblehat
Şemseddin Moldibi Thomas Jager www.patop69.net
Seth Morabito Thomas Karlsen Yan B
Shawn McKee Thomas Laskowski Zoltan Markus
Siegfried Hartmann Thomas Marschall Zsolt Zsila
Zytex Online Store

AC-9
AC-10
Bibliography
AC-12
[1] N. Montfort, P. Baudoin, J. Bell, I. Bogost, J. Douglass, M. C. Marino, M. Mateas,
C. Reas, M. Sample, and N. Vawter, 10 PRINT CHR $(205.5+ RND (1));: GOTO 10.
MIT Press, 2012.
[2] L. Soares and M. Stumm, “Flexsc: Flexible system call scheduling with exception-
less system calls.” in Osdi, vol. 10, 2010, pp. 1–8.
[3] Actraiser, “Vic-ii for beginners: Screen modes, cheaper by the
dozen,” 2013. [Online]. Available: http://dustlayer.com/vic-ii/2013/4/26/
vic-ii-for-beginners-screen-modes-cheaper-by-the-dozen

Index-1
Index-2
INDEX
Index-4
, (comma), 9-20, 9-36 BEND, B-30
: (colon), 9-20, 9-36 BLOAD, 13-17, B-31
<> (not equal to), 9-28 BOOT, 6-10, 13-17, B-33
$00 (PORTDDR), J-15 BORDER, 9-40, B-34
$00 (STOPTX), T-10 BOX, B-35
$01 (PORT), J-15 BSAVE, 13-17, B-37
$01 (STARTTX), T-10 BVERIFY, B-40
$D0 (RXNORMAL), T-10 CATALOG, B-41
$D4 (DEBUGVIC), T-10 CHANGE, B-43
$DC (DEBUGCPU), T-10 CHAR, B-44
$DE (RXONLYONE), T-10 CHARDEF, B-46
$F1 (FRAME1K), T-10 CHDIR, 6-6, 6-11, B-47
$F2 (FRAME2K), T-10 CIRCLE, B-49
CLOSE, B-52
ADC, K-18, K-62, K-117 CLR, B-53
ADCQ, J-13, K-117 CLRBIT, B-54
ALR, K-18
CMD, B-55
altpal, 19-8
COLLECT, B-56
Amiga™ style audio, O-18
COLLISION, B-57
ANC, K-19
COLOR, B-58
AND, 9-40, K-19, K-62, K-118
CONCAT, B-59
ANDQ, J-13, K-119
CONT, 9-36, B-60
Apple, 15-4
COPY, 6-13, B-61
ARR, K-20
CURSOR, B-64
ASL, K-21, K-63
CUT, B-65
ASLQ, J-13, K-119
DATA, B-66
ASR, K-64
ASRQ, J-13, K-120 DCLEAR, B-67
ASSEMBLE, N-6 DCLOSE, B-68
ASW, K-65 DEF FN, B-71
audio cross-bar switch, U-23 DELETE, 6-13, B-72
audio mixer, U-23 DIM, B-73
AUTOBOOT.C65 file, 6-10 DIR, 6-9–6-11, B-74
Direct Mode, B-6
BACKGROUND, 9-40 DISK, B-76
BASIC 65 Arrays, B-8 DLOAD, 6-11, 6-12, B-77
BASIC 65 Commands DMA, I-4, B-79
APPEND, B-22 DMODE, B-80
AUTO, B-25 DO, B-81
BACKGROUND, 9-40, B-26 DOT, B-84
BACKUP, 6-12, B-27 DPAT, B-85
BANK, I-4, 13-16, B-28 DSAVE, 6-11, 6-12, B-88
BEGIN, B-29 DVERIFY, B-90

Index-5
EDMA, B-93 LOAD, B-152
ELLIPSE, B-96 LOADIFF, B-154
ELSE, B-98 LOCK, B-156
END, 9-36, B-100 LOOP, B-159
ENVELOPE, B-101 MEM, B-161
ERASE, B-103 MERGE, B-162
EXIT, B-105 MKDIR, B-164
FAST, B-107 MONITOR, B-166
FGOSUB, B-108 MOUNT, 6-3, 6-5, B-167
FGOTO, B-109 MOUSE, B-168
FILTER, B-110 MOVSPR, B-169
FIND, B-111 NEW, B-171
FONT, B-114 NEXT, B-172
FOR, 9-7, B-115 OFF, B-174
FOREGROUND, 9-40, B-116 ON, B-175
FORMAT, 6-8, B-117 OPEN, B-177
FREAD, B-119 PAINT, B-179
FREEZER, B-120 PALETTE, B-180
FWRITE, B-121 PASTE, B-181
GCOPY, B-122 PEEK, 13-5
GET, B-123 PEN, B-183
GET#, B-124 PLAY, B-185
GETKEY, B-125 POKE, 13-5, 13-17
GO64, 3-13, B-126 POLYGON, B-190
GOSUB, B-127 PRINT, 9-10, 13-5, B-193
GOTO, 9-42, B-128 PRINT USING, B-195
GRAPHIC, B-129 PRINT#, B-194
HEADER, B-130 RCURSOR, B-198
HELP, B-131 READ, B-199
HIGHLIGHT, B-133 RECORD, B-200
IF, 9-28, B-134 REM, B-202
IMPORT, B-135 RENAME, 6-13, B-203
INFO, B-136 RENUMBER, 9-35, B-204
INPUT, 9-16, 9-22, B-137 RESTORE, B-206
INPUT#, B-138 RESUME, B-207
INSTR, B-140 RETURN, B-208
KEY, B-143 RMOUSE, B-211
LET, 9-14, B-147 RREG, B-216
LINE, B-148 RUN, 3-4, 6-9, 6-12, B-221
LINE INPUT, B-149 SAVE, 3-5, B-223
LINE INPUT#, B-150 SAVEIFF, B-224
LIST, 3-4, 9-10, 9-11, B-151 SCNCLR, B-225

Index-6
SCRATCH, B-226 BOOT, 6-10
SCREEN, B-227 CATALOG, B-41
SET, 6-11, B-230 CHARDEF, B-46
SETBIT, B-231 CHDIR, 6-6, 6-11
SLEEP, B-234 CHR, B-29, B-48, B-81, B-98,
SOUND, B-235 B-123, B-125, B-134,
SPEED, B-237 B-144, B-146, B-149,
SPRCOLOR, B-238 B-159, B-188, B-222,
SPRITE, B-239 B-252, B-261, B-271
SPRSAV, B-240 CIRCLE, B-51, B-97
STEP, 9-12, B-243 CLRBIT, B-54
STOP, 9-36, B-244 CMD, B-55, B-177
SYS, 13-17, B-247 CONCAT, B-59
TEMPO, B-251 CONT, B-60
THEN, 9-28, B-252 COPY, 6-13, B-62, B-255
TO, B-255 CUT, B-65, B-181
TRAP, B-256 DATA, B-66, B-73, B-155, B-199,
TROFF, B-257 B-206, B-249
TRON, B-258 DECBIN, B-70
TYPE, B-259 DELETE, 6-13
UNLOCK, B-260 DIR, 6-10, 6-11, B-42, B-75,
UNTIL, B-261 B-164, B-230
USING, B-262 DLOAD, 6-3, 6-11, 6-12
VERIFY, B-266 DMA, 11-7
VIEWPORT, B-267 DSAVE, 6-12, B-88, B-138
VOL, B-268 EDMA, B-93, B-161
VSYNC, B-269 ELLIPSE, B-97
WAIT, 13-17, B-270 ELSE, B-99, B-110, B-134,
WHILE, B-271 B-235, B-252
WINDOW, B-272 END, B-57, B-66, B-73, B-95,
BASIC 65 Constants, B-7 B-99, B-100, B-102, B-104,
BASIC 65 Examples B-109, B-134, B-207,
AND, B-21, B-29, B-39, B-117, B-208, B-218, B-249,
B-130, B-137, B-139, B-252, B-256, B-269
B-142, B-173, B-176, ENVELOPE, B-101, B-187
B-192, B-201, B-235, FGOTO, B-109
B-239, B-254 FORMAT, 6-8, B-117, B-130
APPEND, B-22 GCOPY, B-122
BACKGROUND, B-26 GET, B-29, B-81, B-105, B-123,
BACKUP, 6-12 B-124, B-159, B-261,
BANK, 11-7 B-271
BLOAD, B-32, B-170 GO64, 11-3

Index-7
IF, B-21, B-29, B-30, B-39, B-51, B-66, B-69–B-71, B-73,
B-86, B-87, B-95, B-87, B-89, B-93, B-95,
B-98–B-100, B-102, B-104, B-98–B-100, B-102,
B-105, B-110, B-104–B-106,
B-123–B-125, B-127, B-108–B-110,
B-128, B-134, B-137, B-113–B-115, B-118,
B-139, B-142, B-150, B-124, B-127, B-128,
B-173, B-176, B-178, B-131, B-132, B-134,
B-191, B-201, B-211, B-137, B-139, B-142,
B-215, B-218, B-222, B-145, B-146, B-149,
B-235, B-242, B-244, B-150, B-157, B-158,
B-248, B-251, B-252, B-160, B-163, B-165,
B-268, B-269 B-172, B-173, B-176,
INFO, B-136 B-178, B-182, B-188,
JOY, B-142, B-176 B-191, B-193, B-194,
LEN, B-29, B-81, B-146, B-159, B-196, B-198, B-199,
B-261, B-271 B-201, B-206–B-214,
LINE, B-105, B-124, B-129, B-216, B-218, B-222,
B-148–B-150, B-179, B-233, B-236,
B-180, B-183, B-209, B-241–B-246, B-249,
B-224, B-225, B-228, B-250, B-252–B-258,
B-229, B-242 B-263–B-265, B-273,
LIST, B-55, B-151, B-177 B-275
LOAD, 6-3 READ, B-66, B-73, B-139,
LOADIFF, B-155 B-199, B-206, B-249
LOCK, B-156 RENAME, 6-13
LOG, B-106, B-157 RENUMBER, B-205
LOG10, B-158 RETURN, B-57, B-99, B-108,
MAP, 11-8 B-110, B-127, B-128,
MOD, B-165 B-142, B-176, B-208
MOUNT, 6-6, 6-7, B-167 RGRAPHIC, B-209
NEW, B-171 RSPPOS, B-219, B-239
NOT, B-173 RSPRITE, B-220
PAINT, B-179, B-180 RUN, 6-12
PEEK, 11-7, B-73, B-182, B-188, SAVE, B-144, B-223
B-235, B-254 SCREEN, B-45, B-51, B-65,
POKE, 11-5, 11-7 B-84, B-97, B-122, B-129,
POS, B-191 B-148, B-155, B-161,
PRINT, B-20, B-21, B-23, B-24, B-179–B-181, B-183,
B-29, B-30, B-39, B-48, B-190, B-209, B-213,
B-52, B-53, B-55, B-57, B-214, B-224, B-225,
B-58, B-60, B-63, B-64, B-228, B-229, B-267

Index-8
SET, B-129, B-155, B-180, EXP, B-106
B-183, B-209, B-214, FN, B-71, B-113
B-225, B-229, B-230 FRE, B-118
SETBIT, B-231 HEX$, 13-5, B-132
SGN, B-232 INT, B-141
SLEEP, B-64, B-110, B-155, JOY, B-142
B-170, B-208, B-225, LEFT$, B-145
B-229, B-234 LEN, B-146
SOUND, B-235 LOG, B-157
SPC, B-236 LOG10, B-158
SPRITE, B-57, B-217, B-219, LPEN, B-160
B-220, B-238–B-240 MID$, B-163
SPRSAV, B-240 MOD, B-165
STOP, B-86, B-87, B-105, PEEK, 13-17, B-182
B-124, B-127, B-128, PIXEL, B-184
B-139, B-199, B-211, POINTER, B-188
B-242, B-244 POKE, B-189
STR, B-245 POS, B-191
STRBIN, B-246 POT, B-192
TEMPO, B-101, B-187, B-251, RCOLOR, B-197
B-268 RGRAPHIC, B-209
TRAP, B-95, B-102, B-104, RIGHT$, B-210
B-207, B-256 RND, 9-41, B-212
USING, B-71, B-113, B-114, RPALETTE, B-213
B-196, B-254, B-263 RPEN, B-214
USR, B-264 RPLAY, B-215
VOL, B-101, B-187, B-251, RSPCOLOR, B-217
B-268 RSPEED, B-218
VSYNC, B-269 RSPPOS, B-219
WAIT, B-270 RSPRITE, B-220
WINDOW, B-272 RWINDOW, B-222
WPEEK, B-188, B-273 SGN, B-232
BASIC 65 Functions SIN, B-233
ABS, B-20 SPC, B-236
ASC, B-23 SQR, B-241
ATN, B-24 STR$, B-245
BUMP, B-39 STRBIN$, B-246
CHR$, B-48 TAB, B-249
COS, B-63 TAN, B-250
DEC, B-69 USR, B-264
DECBIN, B-70 VAL, B-265
ERR$, B-104 WPEEK, B-273

Index-9
WPOKE, B-274 BIT, K-22, K-73
BASIC 65 Operators, B-10 BITMAPS, N-7
AND, 9-40, B-21 BITQ, J-13, K-121
NOT, B-173 blink, 19-7
OR, B-178 blocked, 9-19
XOR, B-275 BMI, K-23, K-73
BASIC 65 System Commands BNE, K-23, K-74
EDIT, B-91 BORDER, 9-40
BASIC 65 System Variables bordercolor, 19-6
DS, B-86 box, 19-10
DS$, B-87 BPL, K-24, K-74
DT$, B-89 BRA, K-75
EL, B-95 BREAKPOINT, N-17
ER, B-102 BRK, K-24, K-75
ST, B-242 BSR, K-76
TI, B-253 BVC, K-25, K-76
TI$, B-254 BVS, K-25, K-76
BASIC 65 Variables, B-7
Case
DT, 2-7
Connections, 2-4
TI$, 2-7
Opening, 2-7
BASIC Commands
cellcolor, 19-8
MEM, 13-12 cgetc, 19-18
BBR0, K-65 character, 9-12
BBR1, K-66 character set, 9-12
BBR2, K-66 cinput, 19-19
BBR3, K-66 CLC, K-25, K-77
BBR4, K-67 CLD, K-26, K-77
BBR5, K-67 CLE, K-78
BBR6, K-67 clearattr, 19-8
BBR7, K-68 CLI, K-26, K-78
BBS0, K-68 clrscr, 19-5
BBS1, K-69 CLV, K-26, K-78
BBS2, K-69 CMP, K-27, K-47, K-79, K-121
BBS3, K-69 CMPQ, K-122
BBS4, K-70 colour RAM, P-14
BBS5, K-70 Commodore 1351 mouse, 2-3, 4-4
BBS6, K-71 Commodore 64
BBS7, K-71 Core, 3-14
BCC, K-21, K-71 GO64 mode, 3-6, 3-7, 3-13,
BCS, K-21, K-72 B-126
BEQ, K-22, K-72 Commodore Amiga mouse, 2-3, 4-4
bgcolor, 19-7 COMPARE, N-8

Index-10
Configuration, 4-3 DEBUGVIC, T-10
Audio, 4-6 DEC, K-29, K-81
Boot Disk, 4-4, 4-5 DEQ, J-13, K-122
MAC address, 4-7 DEW, K-82
Mouse, 4-4 DEX, K-30, K-83
Network, 4-7 DEY, K-30, K-83
On-boarding, 2-9, 4-6 DEZ, K-83
Real-Time Clock, 4-5 Digital Audio, O-18
Utility, 3-7, 4-3, 6-3, 6-10 Digital Video, 2-6
Video, 4-6 digital video, P-9
conionit, 19-3 DIP switches, 7-6
Connections Direct Mode, 9-16
IEC, 2-7, 6-3, 6-9 DISASSEMBLE, N-9, N-17
CONT, 9-36 Disk Drives, 6-3
context dependent, 9-17 Bootable Disks, 6-9
Core, 5-5 Connecting, 2-7
C64 core, 3-14, 5-13 D81 Images, 6-4, 6-5
Core Selection Menu, 5-9 Double-Density (DD) Disks, 6-7
definition, 5-5 Formatting a Disk, 6-8
Upgrading, 5-10 High-Density (HD) Disks, 6-7
Upgrading Slot 0, 5-15 Terminology, 6-3
Version, 5-7 Display
CPQ, J-13 Connecting, 2-6
cprintf, 19-17 Setting PAL/NTSC, 2-9, 4-6
CPUHISTORY, N-21 DMA
CPUMEMORY, N-17 Inline DMA Lists, O-17
cputc, 19-15 DMA Audio, O-18
cputcxy, 19-14, 19-16 Drive number (IEC devices), 6-3
cputdec, 19-15
cputhex, 19-15 emulator, 15-3
cputnc, 19-15 END, 9-36
cputncxy, 19-16 EOM, K-84
cputs, 19-16 EOR, K-31, K-85, K-123
cputsxy, 19-16 EORQ, J-13, K-124
CPX, K-27, K-80 Errors
CPY, K-28, K-80 Extra Ignored, 9-20
CPZ, K-81 Illegal Direct, 9-16
cross-bar switch, audio, U-23 Syntax, 9-4
Type mismatch, 9-15
D81 disk image, 6-3 EXIT, N-13
DCP, K-29 Extra Ignored, 9-20
DEBUGCPU, T-10
DEBUGMON, N-19 F011 Disk Controller, 4-5

Index-11
Field Programmable Gate Array $01, M-7
(FPGA), 5-5 $02, M-7
Filehost website, 4-12, 5-7, 6-4, 7-4 $03, M-7
FILL, N-9, N-18 $04, M-7
fillrect, 19-10 $05, M-7
FLAGWATCH, N-18 $06, M-7
Flash Menu, L-5 $07, M-7
Floppy DMA, U-10 $08, M-7, M-32
flushkeybuf, 19-18 $10, M-7, M-10, M-32, M-38,
FOR, 9-7 M-45, M-47, M-55
FOREGROUND, 9-40 $11, M-7
FRAME1K, T-10 $20, M-7
FRAME2K, T-10 $21, M-7
Freeze Menu, L-5 $80, M-8, M-37
Freezer menu, 3-4, 3-12, 5-5, 5-6, $81, M-8, M-38
6-3–6-5, 6-7–6-9 $82, M-8
$83, M-8
Games
$84, M-8, M-27, M-28, M-30,
Guess the number, 9-30
M-31
getcharsetaddr, 19-4
$85, M-8, M-32
getcolramoffset, 19-4
$86, M-8, M-31
getkeymodstate, 19-18
$87, M-8, M-11, M-30
getmapedpal, 19-10
$88, M-8, M-18–M-20, M-27,
getpalbank, 19-9
M-28, M-40
getpalbanka, 19-9
$89, M-8, M-34
getscreenaddr, 19-4
$8A, M-8
getscreensize, 19-5
$8B, M-8
GO, N-10
gohome, 19-11 $8C, M-8
GOTO, 9-42 $8D, M-8, M-29, M-36
gotox, 19-12 $8E, M-8
gotoxy, 19-12 $FF, M-8
gotoy, 19-12 Hyppo Move to Root Directory, M-13
Guess the number, 9-30 Hyppo Services, M-3
$D640 $00, M-9
Hardware revisions, 5-7 $D640 $02, M-25
HELP, N-17 $D640 $04, M-23
highlight, 19-7 $D640 $06, M-37
hline, 19-11 $D640 $08, M-26
Hot Registers, P-17 $D640 $0A, M-24
HUNT, N-10 $D640 $0C, M-11
HYPERTRAP, N-16 $D640 $0E, M-29
Hyppo Error Codes, M-5, M-7 $D640 $10, M-36

Index-12
$D640 $12, M-30 $D640 $72, M-57
$D640 $14, M-32 $D640 $74, M-45
$D640 $16, M-15 $D640 $76, M-55
$D640 $18, M-31 $D640 $7C, M-54
$D640 $1A, M-34 $D640 $7E, M-49
$D640 $1C, M-39 $D641 $00, M-51
$D640 $1E, M-29 $D641 $02, M-50
$D640 $20, M-16 $D642 $00, M-60
$D640 $22, M-14 $D642 $02, M-60
$D640 $24, M-36 $D642 $04, M-60
$D640 $26, M-36 $D642 $06, M-60
$D640 $28, M-22 $D642 $10, M-61
$D640 $2A, M-36 $D642 $12, M-61
$D640 $2C, M-17 $D642 $14, M-61
$D640 $2E, M-38 $D642 $16, M-61
$D640 $30, M-19 $D643 $xx, M-53
$D640 $32, M-20 $D67F $xx, M-61
$D640 $34, M-18
I/O
$D640 $36, M-27
blocking, 9-19
$D640 $38, M-7
IEC Controller Commands, V-4
$D640 $3A, M-10
IF, 9-28
$D640 $3C, M-13
Illegal Direct Error, 9-16
$D640 $3E, M-28
IMDH™, P-8
$D640 $40, M-40
INC, K-31, K-85
$D640 $42, M-42
Inline DMA Lists, O-17
$D640 $44, M-43
INPUT, 9-16, 9-22
$D640 $46, M-41 INQ, J-13, K-124
$D640 $48, M-46 Integrated Marvellous Digital
$D640 $50, M-48 Hookup™, P-8
$D640 $52, M-52 INTERRUPTS, N-19
$D640 $54, M-48 Intro Disk, 2-11, 4-5, 6-3
$D640 $56, M-59 Disabling, 2-12
$D640 $58, M-48 INW, K-86
$D640 $60, M-56 INX, K-32, K-87
$D640 $62, M-44 INY, K-32, K-87
$D640 $64, M-48 INZ, K-87
$D640 $66, M-44 ISC, K-33
$D640 $68, M-44
$D640 $6A, M-44 JMP, K-34, K-88
$D640 $6C, M-56 Joystick, 2-3
$D640 $6E, M-44 JSR, K-34, K-88
$D640 $70, M-58 JUMP, N-10

Index-13
kbhit, 19-18 LOAD, N-10
Keyboard, 3-3 LOADMEMORY, N-19
ALT, 3-7 LSR, K-38, K-91
Arrow Keys, 3-5 LSRQ, J-13, K-126
CAPS LOCK, 3-7
CLR HOME, 3-5 M65Connect Application, 7-4, 7-8
CTRL, 3-4, 3-8, E-3 Machine Code Monitor, 3-4
Cursor Keys, 3-4, E-8 MONITOR command, B-166
Escape Sequences, 3-10, E-6 macOS, 15-4
Function Keys, 3-6 MAP, J-7–J-9, K-92
HELP, 3-6 MEGA Flash, L-5
INST DEL, 3-5 MEGA65 Information Utility, 5-6
matrix, F-14 mega65_ftp command, 7-9
MEGA Key, 3-6, 3-8, 11-4 MEMORY, N-11, N-19
NO SCROLL, 3-6 Memory banking, J-7–J-9
PETSCII Codes and CHR$, B-48, mixer, audio, U-23
D-3 MOD-file style audio, O-18
RESTORE, 3-4 MONITOR
RETURN, 3-3 Matrix Mode/Serial Monitor,
RUN STOP, 3-4 N-14
Screen Codes, C-3 MEGA65 Monitor, N-3
Shift Keys, 3-3, 3-6, E-6 MONITOR Commands, N-14
SHIFT LOCK, 3-3 ., N-13
keyboard, 15-3 >, N-13
Keywords, B-3 ASSEMBLE, N-6
KIL, K-34 BITMAPS, N-7
BREAKPOINT, N-17
LAS, K-35 COMPARE, N-8
LAX, K-36 CPUHISTORY, N-21
LDA, K-36, K-89, K-125 CPUMEMORY, N-17
LDQ, J-13, K-126 DEBUGMON, N-19
LDX, K-37, K-90 DISASSEMBLE, N-9, N-17
LDY, K-38, K-90 EXIT, N-13
LDZ, K-91 FILL, N-9, N-18
LET, 9-14 FLAGWATCH, N-18
light pen, U-22 GO, N-10
Line Drawing, O-13 HELP, N-17
DMA Option Bytes, O-13 HUNT, N-10
Lines HYPERTRAP, N-16
editing, 9-23 INTERRUPTS, N-19
renumbering, 9-35 JUMP, N-10
replacing, 9-23 LOAD, N-10
LIST, 9-10, 9-11 LOADMEMORY, N-19

Index-14
MEMORY, N-11, N-19 PHX, K-95
REGISTERS, N-12, N-20 PHY, K-95
SAVE, N-12 PHZ, K-96
SETMEMORY, N-20 Pi1541 device, 2-7
SETPC, N-18 PLA, K-42, K-96
TRACE, N-20 PLP, K-42, K-96
TRANSFER, N-12 PLX, K-97
UARTDIVISOR, N-16 PLY, K-97
VERIFY, N-12 PLZ, K-97
WATCHPOINT, N-20 PORT, J-15
mouSTer adapter, 2-3, 4-4 PORTDDR, J-15
movedown, 19-13 PRINT, 9-10
moveleft, 19-13 Programmes
moveright, 19-13 editing, 9-23
moveup, 19-12 replacing lines, 9-23

name spaces, 9-15 quote mode, 9-32


NEG, K-93
Networking READY prompt, 2-13
Ethernet, 7-3 Real-Time Clock
MAC address, 4-7, 7-3 Installing the Battery, 2-7
Network Listening Mode, 7-5 Setting the Date/Time, 4-5
NO SCROLL, 9-43 REGISTERS, N-12, N-20
NOP, K-39 Registers
not equal, 9-28 $D000, P-37
NTSC display mode, 2-9 $D001, P-37
$D002, P-37
OpenROMs, 15-6 $D003, P-37
operators $D004, P-37
relational, 9-28 $D005, P-37
ORA, K-40, K-93, K-127 $D006, P-37
ORQ, J-13, K-128 $D007, P-38
Owner Code, 5-8 $D008, P-38
$D009, P-38
PAL display mode, 2-9 $D00A, P-38
pcprintf, 19-17 $D00B, P-38
pcputc, 19-14 $D00C, P-38
pcputs, 19-14 $D00D, P-38
pcputsxy, 19-14 $D00E, P-38
PETSCII, 3-3, 3-8, 3-11 $D00F, P-38
PHA, K-41, K-94 $D010, P-38
PHP, K-41, K-94 $D011, P-38
PHW, K-95 $D012, P-38

Index-15
$D013, P-38 $D03E, P-40
$D014, P-38 $D03F, P-41
$D015, P-38 $D040, P-41
$D016, P-38 $D041, P-41
$D017, P-38 $D042, P-41
$D018, P-38 $D043, P-41
$D019, P-38 $D044, P-41
$D01A, P-38 $D045, P-41
$D01B, P-38 $D046, P-41
$D01C, P-38 $D047, P-41
$D01D, P-38 $D048, P-42
$D01E, P-38 $D049, P-42
$D01F, P-38 $D04A, P-42
$D020, P-38, P-40, P-42 $D04B, P-43
$D021, P-38, P-40, P-42 $D04C, P-43
$D022, P-38, P-40, P-42 $D04D, P-43
$D023, P-38, P-40, P-42 $D04E, P-43
$D024, P-38, P-40, P-42 $D04F, P-43
$D025, P-38, P-40, P-42 $D050, P-43
$D026, P-38, P-40, P-42 $D051, P-43
$D027, P-38 $D052, P-43
$D028, P-38 $D053, P-43
$D029, P-38 $D054, P-43
$D02A, P-38 $D055, P-43
$D02B, P-38 $D056, P-43
$D02C, P-38 $D057, P-43
$D02D, P-38 $D058, P-43
$D02E, P-38 $D059, P-43
$D02F, P-40, P-42 $D05A, P-43
$D030, P-38, P-40 $D05B, P-43
$D031, P-40 $D05C, P-43
$D033, P-40 $D05D, P-43
$D034, P-40 $D05E, P-43
$D035, P-40 $D05F, P-43
$D036, P-40 $D060, P-43
$D037, P-40 $D061, P-43
$D038, P-40 $D062, P-43
$D039, P-40 $D063, P-43
$D03A, P-40 $D064, P-43
$D03B, P-40 $D065, P-43
$D03C, P-40 $D068, P-43
$D03D, P-40 $D069, P-43

Index-16
$D06A, P-43 $D409, Q-3
$D06B, P-43 $D40A, Q-3
$D06C, P-43 $D40B, Q-3
$D06D, P-43 $D40C, Q-3
$D06E, P-43 $D40D, Q-3
$D06F, P-43 $D40E, Q-3
$D070, P-43 $D40F, Q-3
$D071, P-43 $D410, Q-3
$D072, P-43 $D411, Q-3
$D073, P-43 $D412, Q-3
$D074, P-43 $D413, Q-3
$D075, P-44 $D414, Q-3
$D076, P-44 $D415, Q-3
$D077, P-44 $D416, Q-3
$D078, P-44 $D417, Q-3
$D079, P-44 $D418, Q-3
$D07A, P-44 $D419, Q-3
$D07B, P-44 $D41A, Q-3
$D07C, P-44 $D41B, Q-3
$D080, U-12 $D41C, Q-3
$D081, U-12 $D600, S-3
$D082, U-12 $D601, S-3
$D083, U-12 $D602, S-3
$D084, U-12 $D603, S-3
$D085, U-12 $D604, S-3
$D086, U-12 $D605, S-3
$D087, U-12 $D606, S-3
$D088, U-12 $D609, S-4
$D089, U-12 $D60A, S-4
$D08A, U-12 $D60B, S-4
$D100 – $D1FF, P-41 $D60C, S-4
$D200 – $D2FF, P-41 $D60D, S-4
$D300 – $D3FF, P-41 $D60E, S-4
$D400, Q-3 $D60F, S-4
$D401, Q-3 $D610, S-4
$D402, Q-3 $D611, S-4
$D403, Q-3 $D612, S-4
$D404, Q-3 $D615, S-4
$D405, Q-3 $D616, S-4
$D406, Q-3 $D617, S-4
$D407, Q-3 $D618, S-4
$D408, Q-3 $D619, S-4

Index-17
$D61A, S-4 $D65D, J-16, M-3
$D61D, S-4 $D65E, J-16, M-3
$D61E, S-4 $D65F, J-16, M-3
$D620, S-4 $D660, J-16, M-3
$D621, S-4 $D661, J-16, M-3
$D622, S-4 $D662, J-16, M-3
$D623, S-4 $D663, J-16, M-3
$D625, S-4 $D664, J-16, M-3
$D626, S-4 $D665, J-16, M-3
$D627, S-4 $D666, J-16, M-3
$D628, S-4 $D667, J-16, M-3
$D629, S-4 $D668, J-16, M-3
$D63C, Q-3 $D669, J-16, M-3
$D640, J-15, J-27, M-3 $D66A, J-16, M-3
$D641, J-15, J-27, M-3 $D66B, J-16, M-3
$D642, J-15, M-3 $D66C, J-16, M-3
$D643, J-15, J-27, M-3 $D66D, J-16, M-3
$D644, J-15, J-27, M-3 $D66E, J-16, M-3
$D645, J-15, J-27, M-3 $D66F, J-16, M-3
$D646, J-15, J-27, M-3 $D670, J-16, J-27, M-3
$D647, J-15, J-27, M-3 $D671, J-16, J-27, M-3
$D648, J-15, J-27, M-3 $D672, J-16, J-27, M-3
$D649, J-15, J-27, M-3 $D673, J-16, M-3
$D64A, J-15, J-27, M-3 $D674, J-16, M-3
$D64B, J-15, J-27, M-3 $D675, J-16, M-3
$D64C, J-15, J-27, M-3 $D676, J-16, M-3
$D64D, J-15, J-27, M-3 $D677, J-16, M-3
$D64E, J-15, J-27, M-3 $D678, J-16, M-3
$D64F, J-15, J-27, M-3 $D679, J-17, M-3
$D650, J-16, J-27, M-3 $D67A, J-17, M-3
$D651, J-16, J-27, M-3 $D67B, J-17, M-3
$D652, J-16, J-27, M-3 $D67C, J-17, J-27, M-3
$D653, J-16, J-27, M-3 $D67D, J-17, J-27, M-3
$D654, J-16, J-27, M-3 $D67E, J-17, J-27, M-3
$D655, J-16, J-27, M-3 $D67F, J-17, J-27, M-3
$D656, J-16, J-27, M-3 $D680, U-20
$D657, J-16, J-27, M-3 $D681, U-20
$D658, J-16, J-27, M-3 $D682, U-20
$D659, J-16, J-27, M-3 $D683, U-20
$D65A, J-16, M-3 $D684, U-20
$D65B, J-16, M-3 $D686, U-20
$D65C, J-16, M-3 $D68A, U-15, U-20

Index-18
$D68B, U-15 $D6E7, T-9
$D68C, U-15 $D6E8, T-9
$D68D, U-15 $D6E9, T-9
$D68E, U-15 $D6EA, T-9
$D68F, U-15 $D6EB, T-9
$D690, U-15 $D6EC, T-9
$D691, U-15 $D6ED, T-9
$D692, U-15 $D6EE, T-9
$D693, U-16 $D6F4, U-26
$D694, V-10 $D6F5, U-26
$D695, V-10 $D6F8, U-26
$D697, V-10 $D6F9, U-26
$D698, V-10 $D6FA, U-26
$D699, V-11 $D6FB, U-26
$D69A, V-11 $D6FC, U-26
$D6A0, U-14 $D6FD, U-26
$D6A1, U-16 $D700, O-20
$D6A2, U-14 $D701, O-20
$D6AE, U-20 $D702, O-20
$D6AF, U-20 $D703, O-20
$D6B0, U-22 $D704, O-20
$D6B1, U-22 $D705, O-20
$D6B2, U-22 $D706, O-20
$D6B3, U-22 $D70E, O-21
$D6B4, U-22 $D70F, J-18
$D6B5, U-22 $D710, J-17
$D6B7, U-22 $D711, O-21, U-26
$D6B8, U-22 $D71C, O-21
$D6B9, U-22 $D71D, O-21
$D6BA, U-22 $D71E, O-21
$D6BB, U-22 $D71F, O-21
$D6BC, U-22 $D720, O-21
$D6BD, U-22 $D721, O-21
$D6BE, U-22 $D722, O-21
$D6C0, U-22 $D723, O-21
$D6E0, T-8 $D724, O-21
$D6E1, T-8 $D725, O-21
$D6E2, T-8 $D726, O-21
$D6E3, T-8 $D727, O-21
$D6E4, T-8 $D728, O-21
$D6E5, T-8 $D729, O-21
$D6E6, T-9 $D72A, O-21

Index-19
$D72B, O-21 $D755, O-22
$D72C, O-21 $D756, O-22
$D72D, O-21 $D757, O-22
$D72E, O-21 $D758, O-22
$D72F, O-21 $D759, O-22
$D730, O-21 $D75A, O-22
$D731, O-21 $D75B, O-22
$D732, O-21 $D75C, O-22
$D733, O-21 $D75D, O-22
$D734, O-21 $D75E, O-22
$D735, O-21 $D75F, O-22
$D736, O-21 $D768, J-18
$D737, O-21 $D769, J-18
$D738, O-21 $D76A, J-18
$D739, O-21 $D76B, J-18
$D73A, O-21 $D76C, J-18
$D73B, O-21 $D76D, J-18
$D73C, O-21 $D76E, J-18
$D73D, O-21 $D76F, J-18
$D73E, O-21 $D770, J-18
$D73F, O-21 $D771, J-18
$D740, O-21 $D772, J-18
$D741, O-21 $D773, J-18
$D742, O-21 $D774, J-18
$D743, O-22 $D775, J-18
$D744, O-22 $D776, J-18
$D745, O-22 $D777, J-18
$D746, O-22 $D778, J-19
$D747, O-22 $D779, J-19
$D748, O-22 $D77A, J-19
$D749, O-22 $D77B, J-19
$D74A, O-22 $D77C, J-19
$D74B, O-22 $D77D, J-19
$D74C, O-22 $D77E, J-19
$D74D, O-22 $D77F, J-19
$D74E, O-22 $D780, J-19
$D74F, O-22 $D781, J-19
$D750, O-22 $D782, J-19
$D751, O-22 $D783, J-19
$D752, O-22 $D784, J-19
$D753, O-22 $D785, J-19
$D754, O-22 $D786, J-19

Index-20
$D787, J-19 $D7B1, J-20
$D788, J-19 $D7B2, J-20
$D789, J-19 $D7B3, J-20
$D78A, J-19 $D7B4, J-20
$D78B, J-19 $D7B5, J-20
$D78C, J-19 $D7B6, J-20
$D78D, J-19 $D7B7, J-20
$D78E, J-19 $D7B8, J-20
$D78F, J-19 $D7B9, J-20
$D790, J-19 $D7BA, J-20
$D791, J-19 $D7BB, J-20
$D792, J-19 $D7BC, J-20
$D793, J-19 $D7BD, J-20
$D794, J-19 $D7BE, J-20
$D795, J-19 $D7BF, J-20
$D796, J-19 $D7C0, J-20
$D797, J-19 $D7C1, J-20
$D798, J-19 $D7C2, J-20
$D799, J-19 $D7C3, J-20
$D79A, J-19 $D7C4, J-20
$D79B, J-19 $D7C5, J-20
$D79C, J-19 $D7C6, J-20
$D79D, J-19 $D7C7, J-20
$D79E, J-19 $D7C8, J-20
$D79F, J-19 $D7C9, J-20
$D7A0, J-19 $D7CA, J-21
$D7A1, J-20 $D7CB, J-21
$D7A2, J-20 $D7CC, J-21
$D7A3, J-20 $D7CD, J-21
$D7A4, J-20 $D7CE, J-21
$D7A5, J-20 $D7CF, J-21
$D7A6, J-20 $D7D0, J-21
$D7A7, J-20 $D7D1, J-21
$D7A8, J-20 $D7D2, J-21
$D7A9, J-20 $D7D3, J-21
$D7AA, J-20 $D7D4, J-21
$D7AB, J-20 $D7D5, J-21
$D7AC, J-20 $D7D6, J-21
$D7AD, J-20 $D7D7, J-21
$D7AE, J-20 $D7D8, J-21
$D7AF, J-20 $D7D9, J-21
$D7B0, J-20 $D7DA, J-21

Index-21
$D7DB, J-21 $DC1C, R-6
$D7DC, J-21 $DC1D, R-7
$D7DD, J-21 $DC1E, R-7
$D7DE, J-21 $DC1F, R-7
$D7DF, J-21 $DD00, R-4
$D7E0, J-21 $DD01, R-4
$D7E1, J-21 $DD02, R-4
$D7E2, J-21 $DD03, R-4
$D7E3, J-21 $DD04, R-4
$D7EF, J-17 $DD05, R-4
$D7FA, J-17 $DD06, R-4
$D7FB, J-17 $DD07, R-4
$D7FD, J-17 $DD08, R-4
$D7FE, J-17 $DD09, R-5
$DC00, R-3 $DD0B, R-5
$DC01, R-3 $DD0C, R-5
$DC02, R-3 $DD0D, R-5
$DC03, R-3 $DD0E, R-5
$DC04, R-3 $DD0F, R-5
$DC05, R-3 $DD10, R-7
$DC06, R-3 $DD11, R-7
$DC07, R-3 $DD12, R-7
$DC08, R-3 $DD13, R-7
$DC09, R-3 $DD14, R-7
$DC0A, R-3 $DD15, R-7
$DC0B, R-3 $DD16, R-7
$DC0C, R-3 $DD17, R-8
$DC0D, R-3 $DD18, R-8
$DC0E, R-3 $DD19, R-8
$DC0F, R-3 $DD1A, R-8
$DC10, R-6 $DD1B, R-8
$DC11, R-6 $DD1C, R-8
$DC12, R-6 $DD1D, R-8
$DC13, R-6 $DD1E, R-8
$DC14, R-6 $DD1F, R-8
$DC15, R-6 53504 – 53759, P-41
$DC16, R-6 53760 – 54015, P-41
$DC17, R-6 54016 – 54271, P-41
$DC18, R-6 53248, P-37
$DC19, R-6 53249, P-37
$DC1A, R-6 53250, P-37
$DC1B, R-6 53251, P-37

Index-22
53252, P-37 53294, P-38
53253, P-37 53295, P-40, P-42
53254, P-37 53296, P-38, P-40
53255, P-38 53297, P-40
53256, P-38 53299, P-40
53257, P-38 53300, P-40
53258, P-38 53301, P-40
53259, P-38 53302, P-40
53260, P-38 53303, P-40
53261, P-38 53304, P-40
53262, P-38 53305, P-40
53263, P-38 53306, P-40
53264, P-38 53307, P-40
53265, P-38 53308, P-40
53266, P-38 53309, P-40
53267, P-38 53310, P-40
53268, P-38 53311, P-41
53269, P-38 53312, P-41
53270, P-38 53313, P-41
53271, P-38 53314, P-41
53272, P-38 53315, P-41
53273, P-38 53316, P-41
53274, P-38 53317, P-41
53275, P-38 53318, P-41
53276, P-38 53319, P-41
53277, P-38 53320, P-42
53278, P-38 53321, P-42
53279, P-38 53322, P-42
53280, P-38, P-40, P-42 53323, P-43
53281, P-38, P-40, P-42 53324, P-43
53282, P-38, P-40, P-42 53325, P-43
53283, P-38, P-40, P-42 53326, P-43
53284, P-38, P-40, P-42 53327, P-43
53285, P-38, P-40, P-42 53328, P-43
53286, P-38, P-40, P-42 53329, P-43
53287, P-38 53330, P-43
53288, P-38 53331, P-43
53289, P-38 53332, P-43
53290, P-38 53333, P-43
53291, P-38 53334, P-43
53292, P-38 53335, P-43
53293, P-38 53336, P-43

Index-23
53337, P-43 53384, U-12
53338, P-43 53385, U-12
53339, P-43 53386, U-12
53340, P-43 54272, Q-3
53341, P-43 54273, Q-3
53342, P-43 54274, Q-3
53343, P-43 54275, Q-3
53344, P-43 54276, Q-3
53345, P-43 54277, Q-3
53346, P-43 54278, Q-3
53347, P-43 54279, Q-3
53348, P-43 54280, Q-3
53349, P-43 54281, Q-3
53352, P-43 54282, Q-3
53353, P-43 54283, Q-3
53354, P-43 54284, Q-3
53355, P-43 54285, Q-3
53356, P-43 54286, Q-3
53357, P-43 54287, Q-3
53358, P-43 54288, Q-3
53359, P-43 54289, Q-3
53360, P-43 54290, Q-3
53361, P-43 54291, Q-3
53362, P-43 54292, Q-3
53363, P-43 54293, Q-3
53364, P-43 54294, Q-3
53365, P-44 54295, Q-3
53366, P-44 54296, Q-3
53367, P-44 54297, Q-3
53368, P-44 54298, Q-3
53369, P-44 54299, Q-3
53370, P-44 54300, Q-3
53371, P-44 54784, S-3
53372, P-44 54785, S-3
53376, U-12 54786, S-3
53377, U-12 54787, S-3
53378, U-12 54788, S-3
53379, U-12 54789, S-3
53380, U-12 54790, S-3
53381, U-12 54793, S-4
53382, U-12 54794, S-4
53383, U-12 54795, S-4

Index-24
54796, S-4 54865, J-16, J-27
54797, S-4 54866, J-16, J-27
54798, S-4 54867, J-16, J-27
54799, S-4 54868, J-16, J-27
54800, S-4 54869, J-16, J-27
54801, S-4 54870, J-16, J-27
54802, S-4 54871, J-16, J-27
54805, S-4 54872, J-16, J-27
54806, S-4 54873, J-16, J-27
54807, S-4 54874, J-16
54808, S-4 54875, J-16
54809, S-4 54876, J-16
54810, S-4 54877, J-16
54813, S-4 54878, J-16
54814, S-4 54879, J-16
54816, S-4 54880, J-16
54817, S-4 54881, J-16
54818, S-4 54882, J-16
54819, S-4 54883, J-16
54821, S-4 54884, J-16
54822, S-4 54885, J-16
54823, S-4 54886, J-16
54824, S-4 54887, J-16
54825, S-4 54888, J-16
54844, Q-3 54889, J-16
54848, J-15, J-27 54890, J-16
54849, J-15, J-27 54891, J-16
54850, J-15 54892, J-16
54851, J-15, J-27 54893, J-16
54852, J-15, J-27 54894, J-16
54853, J-15, J-27 54895, J-16
54854, J-15, J-27 54896, J-16, J-27
54855, J-15, J-27 54897, J-16, J-27
54856, J-15, J-27 54898, J-16, J-27
54857, J-15, J-27 54899, J-16
54858, J-15, J-27 54900, J-16
54859, J-15, J-27 54901, J-16
54860, J-15, J-27 54902, J-16
54861, J-15, J-27 54903, J-16
54862, J-15, J-27 54904, J-16
54863, J-15, J-27 54905, J-17
54864, J-16, J-27 54906, J-17

Index-25
54907, J-17 54971, U-22
54908, J-17, J-27 54972, U-22
54909, J-17, J-27 54973, U-22
54910, J-17, J-27 54974, U-22
54911, J-17, J-27 54976, U-22
54912, U-20 55008, T-8
54913, U-20 55009, T-8
54914, U-20 55010, T-8
54915, U-20 55011, T-8
54916, U-20 55012, T-8
54918, U-20 55013, T-8
54922, U-15, U-20 55014, T-9
54923, U-15 55015, T-9
54924, U-15 55016, T-9
54925, U-15 55017, T-9
54926, U-15 55018, T-9
54927, U-15 55019, T-9
54928, U-15 55020, T-9
54929, U-15 55021, T-9
54930, U-15 55022, T-9
54931, U-16 55028, U-26
54932, V-10 55029, U-26
54933, V-10 55032, U-26
54935, V-10 55033, U-26
54936, V-10 55034, U-26
54937, V-11 55035, U-26
54938, V-11 55036, U-26
54944, U-14 55037, U-26
54945, U-16 55040, O-20
54946, U-14 55041, O-20
54958, U-20 55042, O-20
54959, U-20 55043, O-20
54960, U-22 55044, O-20
54961, U-22 55045, O-20
54962, U-22 55046, O-20
54963, U-22 55054, O-21
54964, U-22 55055, J-18
54965, U-22 55056, J-17
54967, U-22 55057, O-21, U-26
54968, U-22 55068, O-21
54969, U-22 55069, O-21
54970, U-22 55070, O-21

Index-26
55071, O-21 55113, O-22
55072, O-21 55114, O-22
55073, O-21 55115, O-22
55074, O-21 55116, O-22
55075, O-21 55117, O-22
55076, O-21 55118, O-22
55077, O-21 55119, O-22
55078, O-21 55120, O-22
55079, O-21 55121, O-22
55080, O-21 55122, O-22
55081, O-21 55123, O-22
55082, O-21 55124, O-22
55083, O-21 55125, O-22
55084, O-21 55126, O-22
55085, O-21 55127, O-22
55086, O-21 55128, O-22
55087, O-21 55129, O-22
55088, O-21 55130, O-22
55089, O-21 55131, O-22
55090, O-21 55132, O-22
55091, O-21 55133, O-22
55092, O-21 55134, O-22
55093, O-21 55135, O-22
55094, O-21 55144, J-18
55095, O-21 55145, J-18
55096, O-21 55146, J-18
55097, O-21 55147, J-18
55098, O-21 55148, J-18
55099, O-21 55149, J-18
55100, O-21 55150, J-18
55101, O-21 55151, J-18
55102, O-21 55152, J-18
55103, O-21 55153, J-18
55104, O-21 55154, J-18
55105, O-21 55155, J-18
55106, O-21 55156, J-18
55107, O-22 55157, J-18
55108, O-22 55158, J-18
55109, O-22 55159, J-18
55110, O-22 55160, J-19
55111, O-22 55161, J-19
55112, O-22 55162, J-19

Index-27
55163, J-19 55205, J-20
55164, J-19 55206, J-20
55165, J-19 55207, J-20
55166, J-19 55208, J-20
55167, J-19 55209, J-20
55168, J-19 55210, J-20
55169, J-19 55211, J-20
55170, J-19 55212, J-20
55171, J-19 55213, J-20
55172, J-19 55214, J-20
55173, J-19 55215, J-20
55174, J-19 55216, J-20
55175, J-19 55217, J-20
55176, J-19 55218, J-20
55177, J-19 55219, J-20
55178, J-19 55220, J-20
55179, J-19 55221, J-20
55180, J-19 55222, J-20
55181, J-19 55223, J-20
55182, J-19 55224, J-20
55183, J-19 55225, J-20
55184, J-19 55226, J-20
55185, J-19 55227, J-20
55186, J-19 55228, J-20
55187, J-19 55229, J-20
55188, J-19 55230, J-20
55189, J-19 55231, J-20
55190, J-19 55232, J-20
55191, J-19 55233, J-20
55192, J-19 55234, J-20
55193, J-19 55235, J-20
55194, J-19 55236, J-20
55195, J-19 55237, J-20
55196, J-19 55238, J-20
55197, J-19 55239, J-20
55198, J-19 55240, J-20
55199, J-19 55241, J-20
55200, J-19 55242, J-21
55201, J-20 55243, J-21
55202, J-20 55244, J-21
55203, J-20 55245, J-21
55204, J-20 55246, J-21

Index-28
55247, J-21 56336, R-6
55248, J-21 56337, R-6
55249, J-21 56338, R-6
55250, J-21 56339, R-6
55251, J-21 56340, R-6
55252, J-21 56341, R-6
55253, J-21 56342, R-6
55254, J-21 56343, R-6
55255, J-21 56344, R-6
55256, J-21 56345, R-6
55257, J-21 56346, R-6
55258, J-21 56347, R-6
55259, J-21 56348, R-6
55260, J-21 56349, R-7
55261, J-21 56350, R-7
55262, J-21 56351, R-7
55263, J-21 56576, R-4
55264, J-21 56577, R-4
55265, J-21 56578, R-4
55266, J-21 56579, R-4
55267, J-21 56580, R-4
55279, J-17 56581, R-4
55290, J-17 56582, R-4
55291, J-17 56583, R-4
55293, J-17 56584, R-4
55294, J-17 56585, R-5
56320, R-3 56587, R-5
56321, R-3 56588, R-5
56322, R-3 56589, R-5
56323, R-3 56590, R-5
56324, R-3 56591, R-5
56325, R-3 56592, R-7
56326, R-3 56593, R-7
56327, R-3 56594, R-7
56328, R-3 56595, R-7
56329, R-3 56596, R-7
56330, R-3 56597, R-7
56331, R-3 56598, R-7
56332, R-3 56599, R-8
56333, R-3 56600, R-8
56334, R-3 56601, R-8
56335, R-3 56602, R-8

Index-29
56603, R-8 B5ADODD, P-40
56604, R-8 B5PIX, P-41
56605, R-8 B6ADEVN, P-40
56606, R-8 B6ADODD, P-40
56607, R-8 B6PIX, P-41
ABTPALSEL, P-43, P-44 B7ADEVN, P-40
ACCESSKEY, S-4 B7ADODD, P-40
ADDRBANK, O-20 B7PIX, P-41
ADDRLSB, O-21, O-22 BADEXTRA, J-17
ADDRLSBTRIG, O-20 BADLEN, J-17
ADDRMB, O-20, O-22 BASHDDR, S-4, S-5
ADDRMSB, O-20 BBDRPOS, P-42–P-44
ALGO, U-12 BCST, T-9
ALPHADELAY, P-43, P-44 BITPBANK, P-44
ALPHEN, P-44 BLKD, O-22
ALRM, R-3, R-5 BLNK, P-39
ALRMAMPM, R-7, R-8 BMM, P-39
ALRMHOUR, R-7, R-8 BNPIX, P-41
ALRMJIF, R-6–R-8 BOARDMINOR, S-4, S-5
ALRMMIN, R-7, R-8 BORDERCOL, P-38–P-42, P-44
ALRMSEC, R-7, R-8 BP16ENS, P-43, P-44
ALT, U-12 BPCOMP, P-40, P-41
ASCFAST, J-27 BPM, P-41
ASCIIKEY, S-4, S-5 BPX, P-40, P-41
ATTR, P-41 BPY, P-40, P-41
AUDBLKTO, O-21, O-22 BRCOST, J-17
AUDEN, O-22 BSP, P-38, P-39
AUDWRBLK, O-22 BTPALSEL, P-43, P-44
AUTO2XSEL, U-20 BUSY, U-12
B1ADEVN, P-40 BXADEVN, P-40, P-41
B1ADODD, P-40 BXADODD, P-40, P-41
B1PIX, P-41 C128FAST, P-39
B2ADEVN, P-40 CALCEN, J-21
B2ADODD, P-40 CALXDELTALSB, U-22
B2PIX, P-41 CALXSCALELSB, U-22
B3ADEVN, P-40 CALXSCALEMSB, U-22
B3ADODD, P-40 CALYDELTALSB, U-22
B3PIX, P-41 CALYDELTAMSB, U-22
B4ADEVN, P-40 CALYSCALELSB, U-22
B4ADODD, P-40 CALYSCALEMSB, U-22
B4PIX, P-41 CARTEN, J-17
B5ADEVN, P-40 CB, P-38, P-39

Index-30
CDC00, U-20 CH3FREQC, O-22
CH0RVOL, O-21, O-22 CH3FREQL, O-22
CH1BADDRC, O-21 CH3FREQM, O-22
CH1BADDRL, O-21 CH3LVOL, O-21, O-23
CH1BADDRM, O-21 CH3SBITS, O-22
CH1CURADDRC, O-21 CH3TADDRL, O-22
CH1CURADDRL, O-21 CH3TADDRM, O-22
CH1CURADDRM, O-21 CH3TMRADDRC, O-22
CH1FREQC, O-21 CH3TMRADDRL, O-22
CH1FREQL, O-21 CH3TMRADDRM, O-22
CH1FREQM, O-21 CH3VOLUME, O-22
CH1RVOL, O-21, O-22 CHARPTRBNK, P-43, P-44
CH1SBITS, O-21 CHARPTRLSB, P-43, P-44
CH1TADDRL, O-21 CHARPTRMSB, P-43, P-44
CH1TADDRM, O-21 CHARSZ, S-3
CH1TMRADDRC, O-21 CHARY16, P-44
CH1TMRADDRL, O-21 CHR16, P-44
CH1TMRADDRM, O-21 CHRCOUNT, P-43, P-44
CH1VOLUME, O-21 CHRXSCL, P-43, P-44
CH2BADDRC, O-21 CHRYSCL, P-43, P-44
CH2BADDRL, O-21 CHXBADDRC, O-21, O-23
CH2BADDRM, O-22 CHXBADDRL, O-21, O-23
CH2CURADDRC, O-22 CHXBADDRM, O-21, O-23
CH2CURADDRL, O-22 CHXCURADDRC, O-21, O-23
CH2CURADDRM, O-22 CHXCURADDRL, O-21, O-23
CH2FREQC, O-22 CHXCURADDRM, O-21, O-23
CH2FREQL, O-22 CHXEN, O-23
CH2FREQM, O-22 CHXFREQC, O-21, O-23
CH2LVOL, O-21, O-23 CHXFREQL, O-21, O-23
CH2SBITS, O-21 CHXFREQM, O-21, O-23
CH2TADDRL, O-22 CHXLOOP, O-23
CH2TADDRM, O-22 CHXSBITS, O-21, O-23
CH2TMRADDRC, O-22 CHXSGN, O-23
CH2TMRADDRL, O-22 CHXSINE, O-23
CH2TMRADDRM, O-22 CHXSTP, O-23
CH2VOLUME, O-22 CHXTADDRL, O-21, O-23
CH3BADDRC, O-22 CHXTADDRM, O-21, O-23
CH3BADDRL, O-22 CHXTMRADDRC, O-21, O-23
CH3BADDRM, O-22 CHXTMRADDRL, O-21, O-23
CH3CURADDRC, O-22 CHXTMRADDRM, O-21, O-23
CH3CURADDRL, O-22 CHXVOLUME, O-21, O-23
CH3CURADDRM, O-22 CLOCK, U-12, U-13

Index-31
CMDANDSTAT, U-20 DEVNUM, V-11
COLPTRLSB, P-43, P-44 DIATN, V-11
COLPTRMSB, P-43, P-44 DIGILEFTLSB, U-26
COMMAND, T-8, T-9, U-13 DIGILEFTMSB, U-26
CONN41, S-5 DIGILLSB, U-26
CPUFAST, J-27 DIGILMSB, U-26
CRAM2K, P-41 DIGIRIGHTLSB, U-26
CRC, U-13 DIGIRIGHTMSB, U-26
CROM9, P-41 DIGIRLSB, U-26
CSEL, P-39 DIGIRMSB, U-26
D0D64, U-16 DIR, U-13
D0IMG, U-16 DISKIN, U-13
D0MD, U-16 DISPROWS, P-44, P-45
D0P, U-16 DIVBUSY, J-21
D0STARTSEC0, U-15, U-16 DIVISOR, S-3
D0STARTSEC1, U-15, U-16 DIVOUT, J-18, J-22
D0STARTSEC2, U-15, U-16 DMADSTMB, J-27, J-28
D0STARTSEC3, U-15, U-16 DMALADDR, J-27, J-28
D0WP, U-16 DMASRCMB, J-27, J-28
D1D64, U-16 DRQ, U-13
D1IMG, U-16 DRXD, T-9
D1MD, U-16 DRXDV, T-9
D1P, U-16 DS, U-12, U-13
D1STARTSEC0, U-15, U-16 DSKCHG, U-13
D1STARTSEC1, U-15, U-16 ECM, P-39
D1STARTSEC2, U-15, U-16 EN018B, O-23
D1STARTSEC3, U-16 ENTEREXIT, J-27, J-28
D1WP, U-16 ENV2ATTDUR, Q-3
DATA, S-3, U-12, U-13, V-11 ENV2DECDUR, Q-3
DATALOG0, V-10, V-11 ENV2RELDUR, Q-3
DATALOG1, V-10, V-11 ENV2SUSDUR, Q-3
DATARATE, U-14 ENV3ATTDUR, Q-3
DBGDIR, U-14 ENV3DECDUR, Q-3
DBGMOTORA, U-14 ENV3OUT, Q-3
DBGWDATA, U-14 ENV3RELDUR, Q-3
DBGWGATE, U-14 ENV3SUSDUR, Q-3
DBLRR, P-44 ENVXATTDUR, Q-3, Q-4
DD00DELAY, R-7, R-8 ENVXDECDUR, Q-3, Q-4
DDRA, R-3–R-5 ENVXRELDUR, Q-3, Q-4
DDRB, R-3–R-5 ENVXSUSDUR, Q-3, Q-4
DEBUGC, P-44 EQ, U-13
DENSITY, U-14 ETRIG, O-20, O-23

Index-32
ETRIGMAPD, O-20, O-23 HDSDA, S-5
EV1, U-22 HICKED, J-27, J-28
EV2, U-22 HOTREG, P-45
EXGLYPH, P-45 HPOS, P-40, P-41
EXSID, J-28 HSYNCP, P-45
EXTIRQS, P-45 HTRAP01, J-15
EXTSYNC, P-41 HTRAP02, J-15
F4502, J-28 HTRAP03, J-15
FAST, P-41 HTRAP04, J-15
FCLRHI, P-45 HTRAP05, J-15
FCLRLO, P-45 HTRAP06, J-15
FCOLMCM, P-45 HTRAP07, J-15
FDC2XSEL, U-20 HTRAP08, J-15
FDCENC, U-20 HTRAP09, J-15
FDCTIBEN, U-20 HTRAP0A, J-15
FDCVARSPD, U-20 HTRAP0B, J-15
FILLVAL, U-20 HTRAP0C, J-15
FLG, R-3, R-5 HTRAP0D, J-15
FLTRBDPASS, Q-4 HTRAP0E, J-15
FLTRCUTFRQHI, Q-3, Q-4 HTRAP0F, J-15
FLTRCUTFRQLO, Q-3, Q-4 HTRAP10, J-16
FLTRCUTV3, Q-4 HTRAP11, J-16
FLTREXTINP, Q-4 HTRAP12, J-16
FLTRHIPASS, Q-4 HTRAP13, J-16
FLTRLOPASS, Q-4 HTRAP14, J-16
FLTRRESON, Q-3, Q-4 HTRAP15, J-16
FLTRVOL, Q-3, Q-4 HTRAP16, J-16
FLTRVXOUT, Q-4 HTRAP17, J-16
FNRASTERLSB, P-43, P-45 HTRAP18, J-16
FNRASTERMSB, P-43, P-45 HTRAP19, J-16
FNRST, P-45 HTRAP1A, J-16
FNRSTCMP, P-45 HTRAP1B, J-16
FRAMECOUNT, J-17 HTRAP1C, J-16
FREE, U-13 HTRAP1D, J-16
FRMERR, S-3 HTRAP1E, J-16
GEORAMBASE, J-27, J-28 HTRAP1F, J-16
GEORAMMASK, J-27, J-28 HTRAP20, J-16
GESTUREDIR, U-22 HTRAP21, J-16
GESTUREID, U-22, U-23 HTRAP22, J-16
H1280, P-41 HTRAP23, J-16
H640, P-41 HTRAP24, J-16
HDSCL, S-5 HTRAP25, J-16

Index-33
HTRAP26, J-16 IMTXIRQ, S-3
HTRAP27, J-16 IMTXNMI, S-3
HTRAP28, J-16 INDEX, U-13
HTRAP29, J-16 INT, P-41
HTRAP2A, J-16 IR, R-3, R-5
HTRAP2B, J-16 IRQ, U-13
HTRAP2C, J-16 IRQEN, V-11
HTRAP2D, J-16 IRQFLAG, V-11
HTRAP2E, J-16 IRQRDY, V-11
HTRAP2F, J-16 IRQRDYEN, V-11
HTRAP30, J-16 IRQRX, V-11
HTRAP31, J-16 IRQRXEN, V-11
HTRAP32, J-16 IRQTO, V-11
HTRAP33, J-16 IRQTOEN, V-11
HTRAP34, J-16 ISBC, P-39
HTRAP35, J-16 ISRCLR, R-3, R-5
HTRAP36, J-16 ISSC, P-39
HTRAP37, J-16 J21H, S-4, S-5
HTRAP38, J-16 J21HDDR, S-4, S-5
HTRAP39, J-17 J21L, S-4, S-5
HTRAP3A, J-17 J21LDDR, S-4, S-5
HTRAP3B, J-17 JMP32EN, J-28
HTRAP3C, J-17 JOYSWAP, S-5
HTRAP3D, J-17 KEY, P-40–P-42, P-45
HTRAP3E, J-17 KEYLEDENA, S-5
HTRAP3F, J-17 KEYLEDREG, S-4, S-5
HTRAPXX, J-15, J-17 KEYLEDVAL, S-4, S-5
HWRNGNOTRDY, J-17 KEYLEFT, S-5
HWRNGRAND, J-17 KEYQUEUE, S-5
IFRXIRQ, S-3 KEYUP, S-5
IFRXNMI, S-3 KSCNRATE, S-4, S-5
IFTXIRQ, S-3 LATCHINT, J-21, J-22
IFTXNMI, S-3 LED, U-13
ILP, P-39 LINESTEPLSB, P-43, P-45
IMALRM, R-7, R-8 LINESTEPMSB, P-43, P-45
IMFLG, R-7, R-8 LJOYA, S-5
IMODA, R-3, R-5 LJOYB, S-5
IMODB, R-3, R-5 LOAD, R-3, R-5
IMRXIRQ, S-3 LOST, U-13
IMRXNMI, S-3 LPX, P-38, P-39
IMSP, R-7, R-8 LPY, P-38, P-39
IMTB, R-7, R-8 M65MODEL, S-4, S-5

Index-34
MACADDR2, T-9 MISBC, P-39
MACADDR3, T-9 MISSC, P-39
MACADDR4, T-9 MIXREGDATA, U-26
MACADDR5, T-9 MIXREGSEL, U-26
MACADDR6, T-9 MLSHFT, S-5
MACADDRX, T-9 MMEGA, S-5
MALT, S-5 MODKEYALT, S-6
MAPEDPAL, P-43, P-45 MODKEYCAPS, S-6
MAPHI, J-27, J-28 MODKEYCTRL, S-6
MAPHIMB, J-27, J-28 MODKEYLSHFT, S-6
MAPLO, J-27, J-28 MODKEYMEGA, S-6
MAPLOMB, J-27, J-28 MODKEYRSHFT, S-6
MATHIN0, J-19 MODKEYSCRL, S-6
MATHIN1, J-19 MONO, P-42
MATHIN2, J-19 MOTOR, U-13
MATHIN3, J-19 MRIRQ, P-39
MATHIN4, J-19 MRSHFT, S-6
MATHIN5, J-19 MSCRL, S-6
MATHIN6, J-19 MULBUSY, J-22
MATHIN7, J-19 MULTINA, J-18, J-22
MATHIN8, J-19, J-20 MULTINB, J-18, J-22
MATHIN9, J-20 MULTOUT, J-19, J-22
MATHINA, J-20 NOBUF, U-13
MATHINB, J-20 NOBUGCOMPAT, P-45
MATHINC, J-20 NOCRC, T-9
MATHIND, J-20 NOEXROM, J-17
MATHINE, J-20 NOGAME, J-17
MATHINF, J-20 NOMIX, O-23
MATHINX, J-19, J-22 NOPROM, T-9
MATRIXEN, J-28 NORRDEL, P-45
MC1, P-38–P-40, P-42, P-45 OCEANA, J-17
MC2, P-38–P-40, P-42, P-45 OMODA, R-3, R-5
MC3, P-38–P-40, P-42, P-45 OMODB, R-3, R-5
MCAPS, S-5 OSC3RNG, Q-3, Q-4
MCM, P-39 OSKALT, S-6
MCST, T-9 OSKDEBUG, S-6
MCTRL, S-5 OSKDIM, S-6
MDISABLE, S-5 OSKEN, S-6
MIIMPHY, T-9 OSKTOP, S-6
MIIMREG, T-9 OSKZEN, S-6
MIIMVLSB, T-9 OSKZON, S-6
MIIMVMSB, T-9 PADDLE1, Q-3, Q-4

Index-35
PADDLE2, Q-3, Q-4 RDREQ, U-13
PAL, P-42 READBACKLSB, U-26
PALBLUE, P-41, P-42 READBACKMSB, U-26
PALEMU, P-45 REALHW, S-7
PALGREEN, P-41, P-42 REGA, J-27, J-28
PALNTSC, P-45 REGB, J-27, J-28
PALRED, P-41, P-42 REGX, J-27, J-28
PBONA, R-3, R-5 REGZ, J-27, J-28
PBONB, R-3, R-5 RESERVED, J-21, J-22, P-46
PCH, J-27, J-28 RIRQ, P-39
PCL, J-27, J-28 RMODA, R-4, R-5
PCODE, U-12, U-13 RMODB, R-4, R-5
PETSCIIKEY, S-4, S-6 RNF, U-13
PFLAGS, J-27, J-28 ROM8, P-42
PIRQ, J-28 ROMA, P-42
PNMI, J-28 ROMC, P-42
PORT00, J-27, J-28 ROME, P-42
PORT01, J-27, J-28 ROMPROT, J-28
PORTA, R-3–R-5 RSEL, P-39
PORTB, R-3–R-5 RST, P-39, T-9
PORTF, S-4, S-6 RST41, S-7
PORTFDDR, S-4, S-6 RSTDELEN, P-46
POTAX, S-4, S-6 RSVD, J-28
POTAY, S-4, S-6 RUN, U-13
POTBX, S-4, S-6 RXBF, T-8, T-9
POTBY, S-4, S-6 RXBLKD, T-9
POWEREN, J-17 RXEN, S-3
PREFETCH, J-17 RXOVRRUN, S-3
PRESENT, V-11 RXPH, T-8, T-9
PROT, U-13, V-11 RXQ, T-9
PTYEN, S-3 RXQEN, T-9
PTYERR, S-3 RXRDY, S-3
PTYEVEN, S-3 S1X, P-37
PWMPDM, U-26 S1Y, P-37
RASCMP, P-44, P-45 S2X, P-37
RASCMPMSB, P-44, P-45 S2Y, P-37
RASLINE0, P-43, P-45 S3X, P-37
RASTERHEIGHT, P-43, P-45 S3Y, P-38
RC, P-38, P-39 S4X, P-38
RC8, P-39 S4Y, P-38
RCENABLED, T-9 S5X, P-38
RDCMD, U-13 S5Y, P-38

Index-36
S6X, P-38 SPR1COL, P-38
S6Y, P-38 SPR2COL, P-38
S7X, P-38 SPR3COL, P-38
S7Y, P-38 SPR4COL, P-38
SBC, P-38, P-39 SPR5COL, P-38
SCM, P-38, P-39 SPR6COL, P-38
SCREENCOL, P-38–P-40, P-42, SPR7COL, P-38
P-46 SPRALPHAVAL, P-44, P-46
SCRNPTRBNK, P-43, P-46 SPRBPMEN, P-42, P-43, P-46
SCRNPTRLSB, P-43, P-46 SPRENALPHA, P-43, P-46
SCRNPTRMB, P-43, P-46 SPRENV400, P-44, P-46
SCRNPTRMSB, P-43, P-46 SPRH640, P-46
SDBDRWDLSB, P-43, P-46 SPRHGHT, P-43, P-46
SDBDRWDMSB, P-43, P-46 SPRHGTEN, P-43, P-46
SDBSH, S-7 SPRMC0, P-38, P-40, P-42, P-46
SDCLK, S-7 SPRMC1, P-38, P-40, P-42, P-46
SDCS, S-7 SPRNCOL, P-38, P-40
SDDATA, S-7 SPRPALSEL, P-43, P-46
SDR, R-3–R-5 SPRPTR16, P-46
SE, P-38, P-39 SPRPTRADRLSB, P-43, P-46
SECTOR, U-12, U-13 SPRPTRADRMSB, P-43, P-46
SECTOR0, U-20 SPRPTRBNK, P-43, P-46
SECTOR1, U-20 SPRTILEN, P-43, P-46
SECTOR2, U-20 SPRX64EN, P-43, P-46
SECTOR3, U-20 SPRXSMSBS, P-43, P-47
SELSDRAM, J-17 SPRYADJ, P-43, P-47
SEXX, P-38, P-39 SPRYMSBS, P-44, P-47
SEXY, P-38, P-40 SPRYSMSBS, P-44, P-47
SHDEMU, P-46 SPTRCONT, P-47
SIDE, U-12, U-14 SSC, P-38, P-40
SIDMODE, Q-3, Q-4 STC, V-11
SILENT, U-16 STD, V-11
SLIEN, J-17 STDDIR, V-11
SLOWSDRAM, J-17 STEP, U-12, U-14
SMTH, P-46 STNODEV, V-11
SNX, P-37, P-40 STNOEOI, V-11
SNY, P-37, P-40 STRM, T-9
SP, R-4, R-5 STRTA, R-4, R-5
SPH, J-27, J-29 STRTB, R-4, R-5
SPL, J-27, J-29 STSRQ, V-11
SPMOD, R-4, R-5 STTO, V-11
SPR16EN, P-43, P-46 STVERIFY, V-11

Index-37
SWAP, U-14 UNIT1OUT, J-21
SXMSB, P-38, P-40 UNIT2INA, J-20
SYNCMOD, S-3 UNIT2INB, J-20
SYSCTL, S-4, S-7 UNIT2OUT, J-21
TA, R-4, R-5 UNIT3INA, J-20
TALATCH, R-6–R-8 UNIT3INB, J-20
TARGANY, U-16 UNIT3OUT, J-21
TB, R-4, R-6 UNIT4INA, J-20
TBDRPOS, P-42, P-47 UNIT4INB, J-20
TEXTXPOS, P-43, P-47 UNIT4OUT, J-21
TEXTYPOS, P-43, P-47 UNIT5INA, J-20
TIMERA, R-3, R-4, R-6 UNIT5INB, J-20
TIMERB, R-3, R-4, R-6 UNIT5OUT, J-21
TK0, U-14 UNIT6INA, J-20
TOD50, R-4, R-6 UNIT6INB, J-20
TODAMPM, R-4, R-6–R-8 UNIT6OUT, J-21
TODEDIT, R-4, R-6 UNIT7INA, J-20
TODHOUR, R-3–R-8 UNIT7INB, J-20
TODJIF, R-3, R-4, R-6–R-8 UNIT7OUT, J-21
TODMIN, R-3, R-4, R-6–R-8 UNIT8INA, J-20
TODSEC, R-3–R-8 UNIT8INB, J-20
TOUCH1XLSB, U-22, U-23 UNIT8OUT, J-21
TOUCH1XMSB, U-22, U-23 UNIT9INA, J-20
TOUCH1YLSB, U-22, U-23 UNIT9INB, J-20
TOUCH1YMSB, U-22, U-23 UNIT9OUT, J-21
TOUCH2XLSB, U-22, U-23 UNITAINA, J-21
TOUCH2XMSB, U-22, U-23 UNITAINB, J-21
TOUCH2YLSB, U-22, U-23 UNITAOUT, J-21
TOUCH2YMSB, U-22, U-23 UNITBINA, J-21
TRACK, U-12, U-14 UNITBINB, J-21
TXEN, S-4 UNITBOUT, J-21
TXIDLE, T-9 UNITCINA, J-21
TXPH, T-8, T-9 UNITCINB, J-21
TXQ, T-10 UNITCOUT, J-21
TXQEN, T-10 UNITDINA, J-21
TXRST, T-10 UNITDINB, J-21
TXSZLSB, T-8, T-10 UNITDOUT, J-21
TXSZMSB, T-8, T-10 UNITEINA, J-21
UARTDATA, J-27, J-29 UNITEINB, J-21
UFAST, S-7 UNITEOUT, J-21
UNIT1INA, J-20 UNITFINA, J-21
UNIT1INB, J-20 UNITFINB, J-21

Index-38
UNITFOUT, J-21 VOICE3PWHI, Q-3
UNITXINA, J-20, J-22 VOICE3PWLO, Q-3
UNITXINB, J-20, J-22 VOICE3UNSD, Q-3
UNITXOUT, J-21, J-22 VOICEXCTRLGATE, Q-4
UPDN1, U-22, U-23 VOICEXCTRLPUL, Q-4
UPDN2, U-22, U-23 VOICEXCTRLRNW, Q-4
UPSCALE, P-47 VOICEXCTRLSAW, Q-4
USEREAL0, U-16 VOICEXCTRLTRI, Q-4
USEREAL1, U-16 VOICEXCTRLTST, Q-4
UXBSADD, J-22 VOICEXFRQHI, Q-3, Q-5
UXDVADD, J-22 VOICEXFRQLO, Q-3, Q-5
UXHIOUT, J-22 VOICEXPWHI, Q-3, Q-5
UXLATCH, J-22 VOICEXPWLO, Q-3, Q-5
UXLOWOUT, J-22 VOICEXUNSD, Q-3, Q-5
UXMLADD, J-22 VPOS, P-41, P-42
V400, P-42 VRFOUND, U-21
VDRQ, U-20 VRNF, U-21
VEQINH, U-20 VS, P-38, P-40
VFAST, P-47 VSYNCP, P-47
VFDC0, U-20 VWFOUND, U-21
VFDC1, U-21 WATCHDOG, J-27, J-29
VFLOP, J-29 WGATE, U-14
VGAHDTV, P-47 WRCMD, U-14
VICIII, U-21 WREN, J-22
VICMODE, J-27, J-29 WTREQ, U-14
VIRTKEY1, S-4, S-7 XINV, U-23
VIRTKEY2, S-4, S-7 XPOSLSB, P-43, P-47
VIRTKEY3, S-4, S-7 XPOSMSB, P-43, P-47
VLOST, U-21 XSCL, P-38, P-40
VOICE1CTRLRMF, Q-4 YINV, U-23
VOICE1CTRLRMO, Q-4 YSCL, P-38, P-40
VOICE2CTRLRMF, Q-4 relational operators, 9-28
VOICE2CTRLRMO, Q-4 RENUMBER, 9-35
VOICE2FRQHI, Q-3 RESQ, K-128
VOICE2FRQLO, Q-3 revers, 19-7
VOICE2PWHI, Q-3 RLA, K-42
VOICE2PWLO, Q-3 RMB0, K-98
VOICE2UNSD, Q-3 RMB1, K-98
VOICE3CTRLRMF, Q-4 RMB2, K-98
VOICE3CTRLRMO, Q-4 RMB3, K-99
VOICE3FRQHI, Q-3 RMB4, K-99
VOICE3FRQLO, Q-3 RMB5, K-99

Index-39
RMB6, K-100 sethotregs, 19-6
RMB7, K-100 setmapedpal, 19-9
RND(), 9-41 SETMEMORY, N-20
ROL, K-43, K-100 setpalbank, 19-9
ROLQ, J-13, K-129 setpalbanka, 19-9
ROM, 5-5 setpalentry, 19-10
Upgrading, 5-10 SETPC, N-18
Version, 5-7 setscreenaddr, 19-3
Root directory, M-13 setscreensize, 19-5
ROR, K-44, K-101 SHA, K-49
RORQ, J-13, K-130 SHX, K-49
ROW, K-102 SHY, K-50
Row Mask, P-30 SLO, K-50
RRA, K-44 SMB0, K-106
RSVQ, K-131 SMB1, K-106
RTI, K-45, K-102 SMB2, K-106
RTS, K-45, K-103 SMB3, K-107
RXNORMAL, T-10 SMB4, K-107
RXONLYONE, T-10 SMB5, K-107
SMB6, K-108
SAVE, N-12 SMB7, K-108
SAX, K-46 SRE, K-51
SBC, K-46, K-47, K-103, K-132 STA, K-52, K-108, K-134
SBCQ, J-13, K-133 STARTTX, T-10
SBX, K-47 STEP, 9-12
scientific notation, 9-41 STOP, 9-36
Screen editor, 3-10 STOPTX, T-10
screen RAM, P-14 STQ, J-13, K-134
Screen Text and Colour Arrays, B-9 string, 9-12
SD card, 15-5 STX, K-52, K-109
SD Card Utility, 4-9, 4-10 STY, K-52, K-109
SD Cards, 4-9 STZ, K-110
Locations, 2-7, 4-9 SYNTAX ERROR, 9-4
Transferring Files, 7-3
SD2IEC device, 2-7, 3-14, 6-3 TAB, K-110
SEC, K-48, K-104 TAS, K-53
SED, K-48, K-104 TAX, K-53, K-111
SEE, K-105 TAY, K-54, K-111
SEI, K-49, K-105 TAZ, K-111
set16bitcharmode, 19-5 TBA, K-112
setcharsetaddr, 19-4 textcolor, 19-7
setcolramoffset, 19-4 Texture Scaling, O-15
setextendedattrib, 19-6 THEN, 9-28

Index-40
TIB, U-8, U-10 unequal, 9-28
togglecase, 19-6 Unit number (IEC devices), 6-3, 6-9
TRACE, N-20 Utility Menu, L-5
Track at once, U-10 Utility menu, 3-7, 4-3, 4-10
Track DMA, U-10
Track Information Block, U-8, U-10 variable, 9-7
TRANSFER, N-12 numeric, 9-14
TRB, K-112 string, 9-14
TSB, K-113 VERIFY, N-12
TSX, K-54, K-113 vline, 19-11
TSY, K-114
Warnings
TXA, K-55, K-114
Extra Ignored, 9-20
TXS, K-55, K-115
WATCHPOINT, N-20
TYA, K-55, K-115 wherex, 19-13
Type mismatch error, 9-15 wherey, 19-13
TYS, K-116 Windows
TZA, K-116 Escape sequences, 3-10
WINDOW command, B-272
UARTDIVISOR, N-16
underline, 19-8 XAA, K-56

Index-41
Index-42
About the MEGA65 Book
C64 and C65 program and peripheral compatibility ... amazing
sound ... true arcade-class graphics ... beautifully finished hardware
... full mechanical keyboard ... rich networking capabilities and one
of the fastest 6502-class processors avaiable make the MEGA65
truly unique for home, business or educational use.
The MEGA65 Complete Compendium collects into a single huge
volume all the information you need to know about your MEGA65.
Collecting all of the key information of the various MEGA65 user’s
guides and reference manuals in once place, this book provides
detailed information on every topic, including BASIC program-
ming, sound, graphics, networking, assembly language programming,
cross-platform development, including using high-level languages
like C or KickC, the MEGA65’s powerful 8-bit chipset, and how to
use its powerful FPGA core to implement other computer systems.
This book is the must-have reference for the MEGA65, that every
user, whether beginner or advanced, should have with them when
exploring the full potential of the MEGA65.
With authors including professional writers, university lecturers and 8-
bit experts, the content is both accessible and extensive. Beginners
will find detailed explanations of how to get started, while advanced
users will find highly detailed technical information on the inner work-
ings of every aspect of the MEGA65.
In short, this book is designed for you to get the most out of the
MEGA65’s extensive capabilities.

ISBN 123-45-67890-12-8

1 234567 890128
the MEGA Museum of Electronic Games & Art e.V. http://mega65.org
Editor: Assoc. Prof. Paul Gardner-Stephen.

You might also like