MEGA65-Book Draft PDF
MEGA65-Book Draft PDF
The MEGA65 home computer and portable computer have not been subject to FCC, EC
or other regulatory approvals as of the time of writing.
3
Reporting Errors and Omissions
This book is a work-in-progress produced by and for the MEGA65 community. The version
of this edition is:
commit 053 c 4 8 a c 7 3 d a 1 5 9 5 e 5 b 7 1 8 2 4 e f 1 b 0 6 4 2 7 3 4 b d 3 2 0
Date : Mon Aug 3 1 7 : 2 3 : 3 8 2020 +0930
We want this book to be the best that it possibly can. So if you see any errors, or find
anything that is missing, or that you would like more information on, please report them
using the MEGA65 User 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 version of this book from:
https://github.com/mega65/mega65-user-guide
5
MEGA65 REFERENCE GUIDE
Published by
the MEGA Museum of Electronic Games and Art, Germany.
and
Flinders University, Australia.
WORK IN PROGRESS
Copyright ©2019 – 2020 by Paul Gardner-Stephen, Flinders University, the Museum of
Electronic Games and Art eV., and contributors.
This reference guide 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
user guide, 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.
August 3, 2020
ii
Contents
1 Introduction xxv
2 SETUP 3
Unpacking and connecting the MEGA65 . . . . . . . . . . . . . . . . . . . . . . 5
Rear Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Side Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Connecting your MEGA65 to a screen and peripherals . . . . . . . . . . . 8
Optional Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Using the MEGA65 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
THE CURSOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3 GETTING STARTED 11
Keyboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Command Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
RETURN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
SHIFT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
iii
SHIFT LOCK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
CTRL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
RUN/STOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
RESTORE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
THE CURSOR KEYS . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
INSerT/DELete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
CLeaR/HOME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
MEGA KEY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
NO SCROLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Function Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
HELP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
ALT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
CAPS LOCK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
The Screen Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Editor Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
iv
Installing an upgrade core for the MEGA65 . . . . . . . . . . . . . . . . . . . . 45
Installing other cores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Creating cores for the MEGA65 . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Replacing the factory core in slot 0 . . . . . . . . . . . . . . . . . . . . . . . . . 49
Understanding The Core Booting Process . . . . . . . . . . . . . . . . . . . . . . 49
v
Automatic Tab Stops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
Tabs Stops and Spacing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Sample Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Palindromes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Simple Ciphers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
IV HARDWARE 139
vi
Connections and Peripherals . . . . . . . . . . . . . . . . . . . . . . . . . 146
Onboard buttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Keyboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Some key mappings with a USB keyboard . . . . . . . . . . . . . . . . . . 148
Preparing microSDHC card . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Useful Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
11 Emulators 155
Using The Xmega65 Emulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Using the Live ISO image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Creating a Bootable USB stick or DVD . . . . . . . . . . . . . . . . . . . . 157
Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Other Features of the Live ISO . . . . . . . . . . . . . . . . . . . . . . . . . 159
13 Assemblers 169
vii
15 MEGA65 Standard C Library 177
Structure and Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
conio.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
conionit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
setscreenaddr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
getscreenaddr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
clrscr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
getscreensize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
setscreensize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
set16bitcharmode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
setextendedattrib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
togglecase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
bordercolor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
bgcolor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
textcolor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
revers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
highlight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
blink . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
underline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
cellcolor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
fillrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
hline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
vline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
gohome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
gohome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
gotox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
gotoy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
viii
moveup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
movedown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
moveleft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
moveright . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
wherex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
wherey . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
cputc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
cputnc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
cputhex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
cputdec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
cputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
cputsxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
cputcxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
cputncxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
cprintf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
cgetc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
kbhit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
getkeymodstate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
flushkeybuf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
cinput . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
VIC_BASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
VI APPENDICES 199
A ACCESSORIES 203
ix
B BASIC 10 Command Reference 205
Format of Commands, Functions and Operators . . . . . . . . . . . . . . . . . . 207
Commands, Functions and Operators . . . . . . . . . . . . . . . . . . . . . . . . 209
ABS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
AND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
APPEND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
ASC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
ATN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
AUTO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
BACKGROUND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
BACKUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
BANK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
BEGIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
BEND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
BLOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
BOOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
BORDER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
BOX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
BSAVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
BUMP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
BVERIFY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
CATALOG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
CHANGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
CHAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
CHR$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
CIRCLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
CLOSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
CLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
x
CMD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
COLLECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
COLLISION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
COLOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
CONCAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
CONT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
COPY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
COS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
CURSOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
DATA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
DCLEAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
DCLOSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
DEC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
DEF FN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
DELETE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
DIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
DIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
DISK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
DLOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
DMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
DMODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
DO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
DOPEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
DPAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
DSAVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
DVERIFY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
EL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
ELLIPSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
xi
ELSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
END . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
ENVELOPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
ERASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
ER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
ERR$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
EXIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
EXP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
FAST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
FILTER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
FIND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
FN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
FOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
FOREGROUND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
FRE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
GET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
GET# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
GETKEY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
GO64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
GOSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
GOTO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
GRAPHIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
HEADER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
HELP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
HEX$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
HIGHLIGHT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
IF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
INPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
xii
INPUT# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
INSTR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
INT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
JOY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
KEY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
LEFT$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
LEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
LET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
LINE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
LIST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
LOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
LOCATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
LOG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
LOOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
LPEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
MID$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
MOD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
MONITOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
MOUSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
MOVSPR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
NEW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
NEXT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
NOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
OFF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
ON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
OPEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
OR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
PAINT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
xiii
PALETTE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
PEEK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
PEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
PLAY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
POINTER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
POKE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
POLYGON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
POS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
POT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
PRINT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
PRINT# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
PRINT USING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
PUDEF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
RCLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
RDOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
READ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
RECORD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
REM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
RENAME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
RENUMBER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
RESTORE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
RESUME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
RETURN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
RGR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
RIGHT$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
RMOUSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
RND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
RREG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
xiv
RSPCOLOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
RSPPOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
RSPRITE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
RUN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
SAVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
SCNCLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
SCRATCH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
SCREEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
SET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
SGN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
SIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
SLEEP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
SLOW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
SOUND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
SPC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
SPRCOLOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
SPRITE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
SPRSAV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
SQR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
STEP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
STOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
STR$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
SYS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
TAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
TAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
TEMPO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
THEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
TO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
xv
TRAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
TROFF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
TRON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
TYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
UNTIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
USING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
USR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
VAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
VERIFY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
VOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
WAIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
WHILE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
WINDOW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
XOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395
xvi
E Decimal, Binary and Hexadecimal 417
Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
Notations and Bases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
Decimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
Binary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
Hexadecimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
Counting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
Logic Gates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
Signed and Unsigned Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
Bit-wise Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
Converting Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
xvii
6502 Illegal Opcodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458
Read-Modify-Write Instruction Bug Compatibility . . . . . . . . . . . . . . . 458
Variable CPU Speed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459
Slow (1MHz – 3.5MHz) Operation . . . . . . . . . . . . . . . . . . . 459
Full Speed (40MHz) Instruction Timing . . . . . . . . . . . . . . . . 460
CPU Speed Fine-Tuning . . . . . . . . . . . . . . . . . . . . . . . . 460
Direct Memory Access (DMA) . . . . . . . . . . . . . . . . . . . . . 461
Accessing memory between the 64KB and 1MB points . . . . . . . . . . . 461
C64-Style Memory Banking . . . . . . . . . . . . . . . . . . . . . . 461
VIC-III “ROM” Banking . . . . . . . . . . . . . . . . . . . . . . . . . 461
VIC-III Display Address Translator . . . . . . . . . . . . . . . . . . . 462
The MAP instruction . . . . . . . . . . . . . . . . . . . . . . . . . . 462
Direct Memory Access (DMA) Controller . . . . . . . . . . . . . . . 463
Flat Memory Access . . . . . . . . . . . . . . . . . . . . . . . . . . 463
Accessing memory beyond the 1MB point . . . . . . . . . . . . . . . . . . 463
Using the MAP instruction to access >1MB . . . . . . . . . . . . . . 464
Flat-Memory Access . . . . . . . . . . . . . . . . . . . . . . . . . . 466
Virtual 32-bit Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
C64 CPU Memory Mapped Registers . . . . . . . . . . . . . . . . . . . . . . . . 469
New CPU Memory Mapped Registers . . . . . . . . . . . . . . . . . . . . . . . . 470
MEGA65 CPU Maths Unit Registers . . . . . . . . . . . . . . . . . . . . . . . . . 474
MEGA65 Hypervisor Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
Entering / Exiting Hypervisor Mode . . . . . . . . . . . . . . . . . . . . . . 482
Hypervisor Memory Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
Hypervisor Virtualisation Control Registers . . . . . . . . . . . . . . . . . . 486
Programming for Hypervisor Mode . . . . . . . . . . . . . . . . . . . . . . . 489
xviii
H 45GS02 & 6502 Instruction Sets 493
Addressing Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
Implied . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
Accumulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
Q Pseudo Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
Immediate Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
Immediate Word Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
Base Page (Zero-Page) Mode . . . . . . . . . . . . . . . . . . . . . . . . . 497
Base Page (Zero-Page) Quad Mode . . . . . . . . . . . . . . . . . . . . . 497
Base Page (Zero-Page) X Indexed Mode . . . . . . . . . . . . . . . . . . . 498
Base Page (Zero-Page) Quad X Indexed Mode . . . . . . . . . . . . . . . 498
Base Page (Zero-Page) Y Indexed Mode . . . . . . . . . . . . . . . . . . . 498
Base Page (Zero-Page) Base Y Indexed Mode . . . . . . . . . . . . . . . . 499
Base Page (Zero-Page) Z Indexed Mode . . . . . . . . . . . . . . . . . . . 499
Base Page (Zero-Page) Quad Z Indexed Mode . . . . . . . . . . . . . . . 499
Absolute Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
Absolute Quad Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
Absolute X Indexed Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
Absolute Quad X Indexed Mode . . . . . . . . . . . . . . . . . . . . . . . . 500
Absolute Y Indexed Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
Absolute Quad Y Indexed Mode . . . . . . . . . . . . . . . . . . . . . . . . 501
Absolute Z Indexed Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
Absolute Quad Z Indexed Mode . . . . . . . . . . . . . . . . . . . . . . . . 501
Absolute Indirect Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
Absolute Indirect X-Indexed Mode . . . . . . . . . . . . . . . . . . . . . . 502
Base Page Indirect X-Indexed Mode . . . . . . . . . . . . . . . . . . . . . 502
Base Page Quad Indirect X-Indexed Mode . . . . . . . . . . . . . . . . . . 502
Base Page Indirect Y-Indexed Mode . . . . . . . . . . . . . . . . . . . . . 503
xix
Base Page Quad Indirect Y-Indexed Mode . . . . . . . . . . . . . . . . . . 503
Base Page Indirect Z-Indexed Mode . . . . . . . . . . . . . . . . . . . . . 503
Base Page Quad Indirect Z-Indexed Mode . . . . . . . . . . . . . . . . . . 504
32-bit Base Page Indirect Z-Indexed Mode . . . . . . . . . . . . . . . . . 504
32-bit Base Page Indirect Quad Z-Indexed Mode . . . . . . . . . . . . . . 504
32-bit Base Page Indirect Mode . . . . . . . . . . . . . . . . . . . . . . . . 505
32-bit Base Page Indirect Mode . . . . . . . . . . . . . . . . . . . . . . . . 505
Stack Relative Indirect, Indexed by Y . . . . . . . . . . . . . . . . . . . . . 506
Relative Addressing Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
Relative Word Addressing Mode . . . . . . . . . . . . . . . . . . . . . . . . 506
6502 Instruction Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
Opcode Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
Instruction Timing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
Addressing Mode Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Official And Unintended Instructions . . . . . . . . . . . . . . . . . . . . . 510
4510 Instruction Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
Opcode Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
Instruction Timing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555
Addressing Mode Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557
45GS02 Compound Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 618
xx
J F018-Compatible Direct Memory Access (DMA) Controller 645
Audio DMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 648
Sample Address Management . . . . . . . . . . . . . . . . . . . . . . . . . 649
Sample Playback frequency and Volume . . . . . . . . . . . . . . . . . . . 649
Pure Sine Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
Sample playback control . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
MEGA65 Enhanced DMA Jobs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651
F018 “DMAgic” DMA Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . 651
MEGA65 DMA Controller Extensions . . . . . . . . . . . . . . . . . . . . . . . . 652
Unimplemented Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . 656
xxi
Why the new VIC-IV modes are Character and Bitmap modes, not Bitplane
modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 674
Displaying more than 256 unique characters via ”Super-Extended At-
tribute Mode” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 675
Using Super-Extended Attribute Mode . . . . . . . . . . . . . . . . . . . . 678
Full-Colour (256 colours per character) Text Mode . . . . . . . . . . . . . 679
Many-colour (16 colours per character) Text Mode . . . . . . . . . . . . . 679
Alpha-Blending / Anti-Aliasing . . . . . . . . . . . . . . . . . . . . . . . . 679
Flipping Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679
Variable Width Fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 680
Raster-Rewrite Buffer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 680
Sprites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 681
VIC-II/III Sprite Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 681
Extended Sprite Image Sets . . . . . . . . . . . . . . . . . . . . . . . . . . 681
Variable Sprite Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 682
Variable Sprite Resolution . . . . . . . . . . . . . . . . . . . . . . . . . . . 682
Sprite Palette Bank . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683
Full-Colour Sprite Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683
VIC-II / C64 Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686
VIC-III / C65 Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689
VIC-IV / MEGA65 Specific Registers . . . . . . . . . . . . . . . . . . . . . . . . 693
xxii
N 45E100 Fast Ethernet Controller 713
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715
Warning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737
Flashing the CPLD in the MEGA65’s Keyboard with Lattice Diamond . . . . . . . 744
Flashing the MAX10 FPGA on the MEGA65’s Mainboard with INTEL QUARTUS . 751
xxiii
R Supporters & Donors 769
Organisations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771
Volunteers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771
Individual Donors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771
INDEX 777
xxiv
CHAPTER 1
Introduction
xxvi
Congratulations on your purchase of one of the most long-awaited computers in the his-
tory of computing. The MEGA65 is a community designed computer, based on the never-
released Commodore® 651 computer, that was first designed in 1989, and intended
for public release in 1990. Twenty-eight years have passed since then, but the simple,
friendly nature of the 1980s home computers is still something that hasn’t been recre-
ated. These were computers that were simple enough that you could understand not just
how to work with your computer, but how computers themselves work.
Many of the people who grew up using the home computers of the 1980s now have
exciting and rewarding jobs in many companies, in part because of what they learnt about
computers in the comfort of their own home. We want to give you that same opportunity,
to experience the joy of learning how to use computers to solve all sorts of problems:
writing a letter to a friend, working out how much tax you owe, inventing new things, or
discovering how the universe works. This is why we made the MEGA65.
The MEGA65 team thinks that owning a computer should be like owning a home: You
don’t just use a home, you change things big and small to really make it your own, and
maybe even renovate it or add on a room or two. In this guide we will show you how to
more than just hang your own pictures on the wall, but instead how you can dream up
new ways of using the powerful capabilities of computers by coding your own computer
programmes, and even changing the computer itself!
To help you have fun with your MEGA65, we will show you how to use the exciting graphics
and sound capabilities of the MEGA65. But the MEGA65 isn’t just about writing your own
programmes. It can also run many of the thousands of games and other programmes that
were created for the Commodore® 64™2 computer.
Welcome to the world of the MEGA65!
xxvii
xxviii
PART I
GETTING TO KNOW YOUR
MEGA65
2
CHAPTER 2
SETUP
• Unpacking and connecting the MEGA65
• Rear Connections
• Side Connections
• Installation
• Optional Connections
• Operation
4
UNPACKING AND CONNECTING THE
MEGA65
Time to set up your MEGA65 home computer. The box contains the following:
• MEGA65 computer.
• A television or computer monitor with a VGA or digital video input, that is capable
of displaying an image with 800x600 pixel resolution at 50Hz or 60Hz.
You may also want to use the following to get the most out of your MEGA65:
• 3.5mm mini-jack audio cable and suitable speakers or hifi system, so that you can
enjoy the sound capabilities of your MEGA65.
• RJ45 Ethernet cable (regular network cable) and a network router or switch. This
allows the usage of the high-speed networking capabilities of your MEGA65.
5
REAR CONNECTIONS
6
SIDE CONNECTIONS
1 Power Switch
2 Controller Port 2
3 Controller Port 1
4 Reset Button
7
INSTALLATION
Connecting your MEGA65 to a screen and peripherals
8
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, 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
purchase a DVI to Digital Video adaptor.
OPTIONAL CONNECTIONS
1. The MEGA65 houses an internal 3.5” floppy disk drive. You can also connect older
Commodore® IEC serial floppy drives to the MEGA65: the Commodore® 1541,
1571 or 1581. Connect one end of your IEC cable to the Commodore® floppy
disk drive and the other end to the Disk Drive socket of the MEGA65. You can
also connect SD2IEC devices and PI1541’s. It is possible to daisy-chain additional
floppy disk drives or Commodore® compatible printers.
2. You can connect your MEGA65 to a network using a standard Ethernet cable.
3. For enjoying audio from your MEGA65, you can connect a 3.5mm stereo mini-jack
cable to an audio amplifier or speaker system. If your system has RCA connec-
tors you will need to purchase a 3.5mm mini-jack to twin RCA adaptor cable. The
MEGA65 also has a built in amplifier to allow connecting headphones.
4. A Secure Digital Card or SDCard (SDHC and SDXC) can be inserted into the rear
of the MEGA65 as a drive.
OPERATION
Using the MEGA65
1. Turn on the computer by using the switch on the left hand side of the MEGA65.
9
THE CURSOR
The flashing square underneath the READY prompt is called the cursor. The cursor in-
dicates that the computer is ready to accept input. Pressing keys on the keyboard will
print that character onto the screen. The character will be printed in the current cursor
position, and then the cursor advances to the next position.
You can type commands, for example: telling the computer to load a program. You can
even start entering program code.
10
CHAPTER 3
GETTING STARTED
• Keyboard
• The Screen Editor
• Editor Functionality
12
KEYBOARD
Now that you have everything connected, it’s time to get familiar with the MEGA65 key-
board.
You may notice that the keyboard is a little different from the standard used on computers
today. While most keys will be in familiar positions, there are some specialised keys, and
some with special graphic symbols marked on the front.
Command Keys
RETURN
RETURN
Pressing the key enters the information you have typed into the MEGA65’s memory.
The computer will either act on a command, store some information, or return you an error
if you made a mistake.
SHIFT
SHIFT
The two keys are located on the left and the right. They work very much like Shift
on a regular keyboard, however they also perform some special functions too.
SHIFT
In upper case mode, holding down and pressing any key with a graphic symbol on
SHIFT
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 the key and pressing a Function key accesses the function
SHIFT
shown on the front of that key. For example: and F1 activates F2.
13
SHIFT LOCK
SHIFT
In addition to the Shift key is LOCK . Press this key to lock down the Shift function. Now
SHIFT
any key you press prints the character to the screen as if you were holding down .
That includes special graphic characters.
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
allows you to change text colours.
There are some examples of this in the Screen Editor chapter, and all the Control Functions
are listed in Appendix C Control codes.
CTRL
If a program is being listed to the screen, holding down slows down the display of
each line on the screen.
CTRL
Holding and pressing * enters the Matrix Mode Debugger.
RUN/STOP
RUN SHIFT
Normally, pressing the STOP key stops execution of a program. Holding while
RUN
pressing STOP loads the first program from disk.
RUN
Programs are able to disable the STOP key.
RUN
You can boot your machine into the machine code monitor by holding down STOP and
pressing reset on the MEGA65.
RESTORE
The computer screen can be restored to a clean state without clearing the memory by
RUN RESTORE
holding down the STOP key and tapping . 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.
Programs are able to disable this key combination.
14
RESTORE
Enter the Freeze Menu by holding down for more than one second. You can access
the machine code monitor via the Freeze menu.
15
THE CURSOR KEYS
At the bottom right hand of the keyboard are the cursor keys. These four directional keys
allow you move the cursor to any position for onscreen editing.
INSerT/DELete
INST
This is the INSERT / DELETE key. When pressing 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 the key and press DEL . All the characters are shifted
to the right. This allows you to type a letter, number or any other character into the newly
inserted space.
CLeaR/HOME
CLR
Pressing the HOME key returns the cursor into the top left-most position of the screen.
SHIFT CLR
Holding down and pressing HOME clears the entire screen and places the cursor
into the top left-most position of the screen.
MEGA KEY
The ` key or the MEGA key provides a number of different functions and special utili-
ties.
SHIFT
Holding the key and pressing ` switches between lower and upper case char-
acter modes.
Holding ` and pressing any key with graphic symbols on the front prints the left-most
graphic symbol to the screen.
16
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 one of the colours in the second
range.
TAB
Holding ` and pressing enters the Matrix Mode Debugger.
When switching on the MEGA65 or pressing the reset button on the side, while holding
down ` switches the MEGA65 into C64 mode.
NO SCROLL
NO
If a program is being listed to the screen, pressing SCROLL freezes the screen output. Not
available in C64 mode.
Function Keys
There are seven Function keys available for use by software applications, F1 F3
F5 F7 F9 F11 and F13 to perform functions with a single press.
SHIFT
Hold to access F2 through to F14 as shown on the front of each Function
key.
HELP
HELP
The key can be used by software and acts as an F15 / F16 key.
ALT
ALT
Holding down while pressing other keys can be used by software to perform func-
tions. Not available in C64 mode.
ALT
Holding down when switching the MEGA65 on activates the Utility Menu. You can
format the SD card or enter the MEGA65 Configuration Utility to select the default video
mode and other settings, or test your keyboard.
17
CAPS LOCK
CAPS SHIFT
The LOCK works like LOCK in C65 and MEGA65 modes, but only modifies the alphabet
CAPS
keys. Also, holding the down forces the processor to run at the maximum speed.
LOCK
This can be used, for example, to speed up loading from the internal disk drive or SD card,
or to greatly speed up the de-packing process after a program is run. This can reduce
the loading and de-packing time from many seconds to as little as a 10th of a second.
The colour bars in the top left hand 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 what version and revision of BASIC is contained in the Read-only Memory.
Also displayed is the type of keyboard and whether or not there is additional hardware
present, such as a RAM expansion.
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 under the
cursor. The cursor itself advances after each key press.
You can also produce reverse text or colour bars by holding down the CTRL key and
pressing the 9 key or the R key. This enters reverse text mode.
Try holding down the SPACE BAR . A white bar will be drawn across the screen.
18
You can even change the current colour by holding down the CTRL key and pressing a
number key. Try key 8 and then hold down the SPACE BAR again. A yellow bar will
be drawn.
Change the bar to a number of other colours.
You will get an effect something like:
You can turn off the reverse text mode by holding CTRL and pressing the 0 key.
By pressing any keys, the characters will be typed out in the chosen colour.
There are a further eight colours available via the ` key. Hold the ` key and press a
key from 1 to 8 to change to one of the secondary colours. For even more colours,
see Escape Sequences in Appendix C.
You can create fun pictures just using these colours and the letters. Here’s an example of
what a year four student drew:
19
Functions
Functions using the CTRL key are called Control Functions. Functions using the
` key are called Mega Functions. There are also functions called by using the
SHIFT key. These are (not surprisingly) called Shift Functions.
For example: to switch between 40/80 column mode, press and release the ESC key.
Then press the X key.
You can see all the available Escape Sequences in Appendix C. We will cover some ex-
amples of these shortly.
There are more modes available. You can create flashing text by holding the CTRL key
and pressing the O key. Any characters you press will flash. Turn flash mode off by
pressing ESC then O .
EDITOR FUNCTIONALITY
The MEGA65 screen can allow you to do advanced tabbing, and moving quickly around
the screen in many ways to help you to be more productive.
Press the HOME key to go to the home position on the screen. Hold the CTRL key
down and press the W key several times. This is the Word Advance function which
jumps your cursor to the next word, or printable character.
You can set custom tab positions on the screen for your convenience. Press HOME and
then → to the fourth column. Hold down CTRL and press the X key to set a tab.
Move another 20 positions to the right again, and do CTRL and X again to set a
second tab.
Press the HOME key to go back to the home position. Hold the CTRL key and press
the I key. This is the Forward Tab function. Your cursor will tab to the fourth position.
20
Press CTRL and I again. Your cursor will move to position 8. Why? By default, every
8th position is already set as a tabbed position. So the 4th and 20th positions have been
added to the existing tab positions. You can continue to press the CTRL and I keys
to the 16th and 20th positions.
To find the complete set of Control codes, see Appendix C Control codes.
21
Creating a Window
You can set a window on the MEGA65 working screen. Move your cursor to the beginning
of the ”BASIC 10.0” text. Press ESC , then press T . Move the cursor 10 lines down
and 15 to the right.
Press the ESC key, then B . Anything you type will be contained within this window.
To escape from the window back to the full screen, press the HOME key twice.
Extras
Long press on RESTORE to go into the Freeze Menu. Then press J to switch joystick
ports without having to physically swap the joystick to the other port.
Go to Fast mode with poke 0, 65 or go to the freeze menu.
MEGA and SHIFT switches between text uppercase and lowercase for the entire
display.
22
CHAPTER 4
Configuring your MEGA65
• Preparing for First Use: Format-
ting SD Cards
The MEGA65 has two SD card slots: A full-size SD card slot inside, next to the trap-door,
and a microSD size slot on the rear. The current version of the MEGA65 firmware only
supports the use of one SD card at a time. If you have cards in both slots, the MEGA65 will
use the external microSD slot in preference. The exception to this, is that the MEGA65’s
FDISK/FORMAT utility can access both, allowing you to select which you wish to format or
repair.
Depending on the model, your MEGA65 may or may not come with a pre-configured SD
card. If it doesn’t, or if you wish to use a different SD card, e.g., with a larger capacity,
you must first format it for use in the MEGA65.
Only SDHC cards should be used. Older SD cards (typically with a capacity of <4GB) will
not work. Newer SDXC cards with capacities greater than 32GB may or may not work.
We would appreciate hearing your experience with such cards. It is unimportant what
file-system is currently on the card, as the MEGA65 FDISK/FORMAT utility will completely
reformat the card.
There are several reasons for this: First, in order to fit the most features into the MEGA65’s
small operating system, it is particular about the FAT32 file system it uses. Second, only
the MEGA65 FDISK/FORMAT utility can create a MEGA65 System Partition. The MEGA65
System Partition holds non-volatile configuration settings for your MEGA65, and also con-
tains the freeze slots, that make it easy to switch which programme or game you are
running on your MEGA65.
First, power the MEGA65 on while holding down the ALT key. This will present the
MEGA65 Utility Menu, which contains a selection of built-in utilities, similar to the follow-
ing:
25
The exact set of utilities depends on the model of your MEGA65 and the version of the
MEGA65 factory core which it is running. However, all versions include both the MEGA65
FDISK/FORMAT utility, and the MEGA65 Configure utility. Most models also include a
keyboard test utility, that you can use to test that your keyboard is functioning correctly.
This is the same utility used in the factory when testing brand new keyboards.
Select the number that corresponds to the FDISK/FORMAT utility. This will typically be
2. The FDISK utility will start, and attempt to detect the size of all SD cards you have
installed. If you have both an internal and external SD card installed, it will allow you to
choose which one you wish to format. The internal SD card is bus 1, and the external card
is bus 0. Note that the MEGA65 will always attempt to boot using an external microSD
card, if one is installed.
For safety when formatting we strongly recommend that you remove any SD card or mi-
croSD card that you do not intend to format, so that you do not accidentally destroy any
data. This is because formatting an SD card in the MEGA65 cannot be undone, and you
all data currently on the SD card will be lost. If you have files or data on the SD card
that you wish to retain, you should first back this up. The contents of the FAT32 partition
can be easily backed up by inserting the SD card into another computer. The contents of
the MEGA65 System Partition, including the contents of freeze slots requires the use of
specialised software.
26
You should aim to backup valuable data from your MEGA65 on a regular basis, especially
while the computer remains under development. While we take every care to avoid data
corruption or other mishaps, we cannot guarantee that the MEGA65 is free of bugs in this
regard.
If you have only an internal SD card, you might see a display similar to the following:
Once you have selected the bus, the FDISK/FORMAT utility asks you to confirm that you
wish to delete everything:
27
To avoid accidentally loss of data, you must type “DELETE EVERYTHING” in capitals and
press RETURN . Alternatively, turn the MEGA65 off and on to abort this process without
causing damage to your data.
It is also possible to attempt to recover from a lost Master Boot Record (“Boot Sector”) by
instead typing “FIX MBR,” should the need arise.
28
KERNAL should be placed at offset $E000, a C65-mode BASIC at $A000, and a suitable
character set at $D000.
Other important files include FREEZER.M65 and AUDIOMIX.M65, which allow you to use
the MEGA65’s integrated freezer. You can download the full set of support files for the
MEGA65 from:
https://github.com/mega65/mega65-files
To enter the configuration utility, turn the MEGA65 on while holding the ALT key. This
will show the utility menu, similar to the following:
29
Now press the number corresponding to the Utility Menu. The MEGA65 Configuration
Utility will launch, showing a display similar to the following:
If your MEGA65’s System Partition has become corrupt, you may be prompted to press
F14 to correct this, i.e., hold SHIFT and tap the F13 key, with a display like the
following:
30
If you do, you will need to use F7 to save the reset configuration, as otherwise the reset
data will not be saved to the MEGA65 System Partition.
Once you have dismissed that display, or if your MEGA65 System Partition was not cor-
rupted, you can begin exploring and adjusting various settings. The programme can be
controlled using the keyboard, or optionally, an Amiga(tm) or C1351 mouse.
When finished, you can press F7 to receive the option to save the changes. This will
give you four options:
31
• Exit Without Saving allows you to abandon any changes made in the MEGA65 Con-
figure utility, without saving them.
• Apply and Test Settings Now makes the settings take immediate effect. This can
be helpful for testing compatibility of your TV or monitor with PAL or NTSC video
modes. If you still see your display after applying such a change, it is safe to save
those settings.
• Restore Factory Defaults allows you to reset the MEGA65 configuration settings to
the factory defaults. It also randomly selects a new MAC address for models that
include an internal Ethernet adaptor. If you wish to commit these changes, you must
still save them.
• Save as Default and Exit commits any changes you have made to the SD card stor-
age, so that they will be used whenever your MEGA65 is turned on.
32
Input Devices
• Joystick 1 Amiga Mouse Mode allows either normal operation, where software will
see it as an Amiga mouse, or 1351 emulation mode, where the MEGA65 translates
the Amiga mouse’s movements into 1351 compatible signals. This allows you to use
an Amiga mouse with existing C64/C65 software that expect a 1351 mouse.
• Joystick 2 Amiga Mouse Mode is the same as the first option, but for the second
joystick port. This allows you to have different policies for each port.
• Joystick 2 Amiga Mouse Detection similarly provides the ability to separately control
the Amiga mouse detection algorithm for the second joystick port.
33
Chipset
• em Real-Time Clock allows setting the MEGA65’s Real-Time Clock for those models
that include one. To set the clock or calendar, simply edit the field and press the
RETURN
key. The display does not change while viewing this page, but if you use the
cursor left and right keys to select another page and return to this page, the values
will update if a Real-Time Clock is fitted and functioning.
• DMAgic Revision allows selecting the default mode of operation for the C65
DMAgic DMA controller. This option is only required for ROMs not detected by the
MEGA65’s HYPPO Hypervisor. If you see screen corruption in BASIC, try toggling
this option.
• F011 Disk Controller This option allows you to select whether the internal 3.5” floppy
drive functions using real diskettes, or whether it simply makes noises to add atmo-
sphere when using D81 disk images from the SD card. This merely sets the default
option, and you can change this setting, or select a different disk image for use as
either or both of the C65 3.5” DOS based drives.
• Default Disk Image allows you to choose the D81 disk image used with the internal
drive, if the F011 Disk Controller option above is set to use an SD card disk image.
34
Video
• Video Mode selects whether the MEGA65 starts in PAL or NTSC. The MEGA65 sup-
ports true 480p NTSC and 576p PAL double-scan modes, with exact 60Hz / 50Hz
frame-rates. This setting sets the default value, and the system can be switched
between PAL and NTSC via the Freeze Menu, or under software control by MEGA65-
enabled programmes.
35
Audio
• Audio Output selects whether the SIDs and digital audio channels are combined
to provide a mono-aural signal, or whether the left and right tagged audio sources
are separated to provide a stereo signal. Again, this setting can be varied from
in the Audio Mixer of the Freeze Menu, or under the control of MEGA65-enabled
software.
• Swap Stereo Channels allows switching the left and right sides of the stereo audio
output. This is primarily useful for software that expects left and right SIDs to be at
swapped addresses compared with the MEGA65.
• DAC Algorithm allows selecting between two different digital to analog conversion
algorithms. Both are very good, but you may have a preference for one or the other.
• Audio Amplifier allows enabling or disabling the audio amplifier contained in some
models of the MEGA65 for certain audio outputs, e.g., internal speaker or loud
speaker.
36
Network
• MAC Address allows you to set the default MAC address of your MEGA65. This can
be changed at run-time by MEGA65-enabled software
37
38
CHAPTER 5
Cores and Flashing
• What are cores, and why does it
matter?
• Selecting a core
• Installing an upgrade core for
the MEGA65
40
41
42
WHAT ARE CORES, AND WHY DOES IT
MATTER?
The MEGA65 computer uses a versatile chip called an FPGA as its heart. FPGAs are “Field
Programmable Gate Arrays”. This is a fancy way of saying that FPGAs are chips that can
be programmed to behave impersonate other chips. They do this by configuring their
arrays of logic gates to reproduce the circuits of other chips. In this way, FPGAs are not
emulation but re-creation of other chips.
FPGAs forget what chip they were pretending to be whenever the power is turned off,
or when they are “reconfigured”. This might sound annoying, but it’s actually very pow-
erful. It means that we can tell the FPGA in the MEGA65 to impersonate not just the
MEGA65 design as it currently stands, but to impersonate any improvements we make to
the design. In other words, we can upgrade the MEGA65 hardware just by providing a
new set of instructions to the FPGA. These sets of instructions are called “cores” or “bit-
streams”. For the purpose of the MEGA65, these two terms can usually be considered to
be interchangeable.
FPGAs are so flexible, that not only is it possible to teach the MEGA65 to be a better
MEGA65, but it is also possible to teach the MEGA65’s’ FPGA to be other interesting
home computers. We believe that the FPGA is powerful enough that it could pretend to
be a VIC-20 (tm), Commodore PET (tm), Apple II (tm), Spectrum (tm), BBC Micro (tm),
or even an Amiga (tm) or one of the 16-bit era game consoles. Unlike some previous
FPGA-based retro-computers, the MEGA65, its FPGA instructions, board layout and other
information is all available for free under open-source licenses. This means that anyone
is free to create other cores for the MEGA65 hardware.
To top it all off, the MEGA65 has enough storage for 7 different sets of FPGA instructions,
so that you can easily switch the MEGA65’s “personality” from being a MEGA65 to another
of these systems (once the cores are available) and back again.
The remainder of this chapter describes how to select which core to run on the MEGA65,
and how to store a core into one of the seven slots in the flash memory storage.
SELECTING A CORE
To operate the MEGA65 using an alternative core, turn off the power to the MEGA65, and
then hold the NO SCROLL key down while turning the power back on. This instructs
43
the MEGA65 to enter the flash and core menu, instead of booting normally. You should
see a display like the following:
To select a core and start it, use the cursor keys to highlight the desired core, and then
press the RETURN key. If you select a flash slot that does not contain a valid core, it
will highlight in red to indicate that it cannot be booted from:
44
Alternatively, you can press the number corresponding to the core you would like to use.
The MEGA65 immediately reconfigures the FPGA, and launches the core. If for some
reason the core is faulty, the MEGA65 may instead restart normally after a few seconds,
and depending on the circumstances, take you automatically back into the menu.
The MEGA65 will keep running the new core until you physically power it off. Pressing the
reset button will not reset which core is being run.
First, copy the core file onto the MEGA65’s SD card. You can do this by removing the SD
card and inserting it into another computer that has internet access, and downloading the
core from that computer. Alternatively you can insert an SD card that already contains the
upgrade core. Finally, you can use the MEGA65 TFTP Server program and the MEGA65’s
45
Ethernet port to copy the core upgrade file onto the SD card from another computer on
your local network.
The flash menu will preferentially use the external microSD slot over the internal SD card:
If you have both a microSD card and SD card inserted in your MEGA65, the flash menu
will currently ignore the internal SD card. Simply copy the core file(s) from the internal
SD card to the external microSD card, or temporarily remove the external microSD card
from the rear of your MEGA65, so that the flash menu will be able to find the core files.
Also note that the flash menu currently supports only DOS-style 8.3 character filenames.
If your core files have a longer name, you will need to rename them when copying them
onto your microSD or SD card.
Second, once you have the upgrade core on the MEGA65’s SD card, enter the flash and
core menu as above, i.e., turn off the power, hold the NO SCROLL key down while
turning the power on. When the flash and core menu appears, hold the CTRL key
down and press the 1 key (or CTRL and a different number if you wish to replace
the contents of a different flash slot). The MEGA65 will present you a list of core files
that are on the SD card, similar to this:
46
Select the upgrade core file you wish to install using the cursor keys, and then pressing the
RETURN key. The MEGA65 will then erase the flash slot, before writing the upgraded
core. You will see a progress bar while the MEGA65 erases the flash slot, similar to this:
The progress bar will then reset, and the MEGA65 will write the new core into the slot.
This process can take up to 15 minutes, depending on the size of the core file. If you
simply wish to erase a flash slot, you can select the “– erase slot –” option instead of a file
name. This will perform only the erasure part of the process.
It is important to not turn the power off during this process. If you do, the core file will be
only partially installed, and the MEGA65 may not start properly. While inconvenient, if this
happens, it won’t damage your MEGA65 or leave it in an unusable state: It will just fall
back to using the factory supplied core. If this happens, enter the flash and core menu as
described above, and follow the instructions again.
When the flashing process completes, you will see a message like this, indicating that the
process is complete:
47
When this happens, simply turn off the power to the MEGA65 and turn it back on for it to
start using the upgraded core. This is because the MEGA65 will always try to automati-
cally start the core in slot 1 when it is turned on.
Of course, there is nothing stopping you installing a different core in slot 1, so that the
MEGA65 behaves as a different type of computer when you turn it on. If you do this, you
can always choose to run the MEGA65 core by entering the flash and core menu, and
selecting the MEGA65 core.
48
CREATING CORES FOR THE MEGA65
If you would like to create your own cores for the MEGA65, or help contribute to the
MEGA65 core, then you may also wish to take a look at Appendix P which explains how
to use the FPGA development tools to flash the MEGA65.
49
it always starts the bitstream stored in slot 0 of the flash. If that is the MEGA65 Factory
Core, the MEGA65 HYPPO Hypervisor starts. If it is the first boot since power-on, HYPPO
starts the Flash Menu programme – but note that the Flash Menu in this mode may not
show anything on the screen to indicate that it is running!
The Flash Menu checks if the system is booting from Flash Slot 0. If it is, it checks if the NO
SCROLL key is being held. If it is, the Flash Menu programme shows its display, allowing
the user to select or re-flash a core. If the NO SCROLL key is not being pressed, then
the Flash Menu programme checks if Flash Slot 1 contains a valid core. If it does, then
the Flash menu programme attempts to start that core. If it succeeds, then the system
reconfigures to that core, after which the behaviour of the system is according to that
core. If it fails, the keyboard will show the flashing red and blue “ambulance lights” to
indicate that some first-aid is required. Note that in the ambulance light mode that the
reset button has no effect: You must turn the computer off and on again.
If the user selected a different core in the Flash 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.
50
MEGA65 Off
Power
on
Bitstream from
slot 0 starts
Hypervisor starts
flash menu programme
Power Power
Yes
off off
Bitstream
Reset Is NO SCROLL key
Yes in slot
pressed held down?
is valid
No Yes
FPGA tries
Does the bitstream MEGA65
to boot from
in Slot 1 work? Booted
specified slot
Bitstream
No in slot Try next slot
NOT valid
Keyboard showing
Show `ambulance lights' Reset
`ambulance lights',
until powered off pressed
increment slot number
51
52
PART II
FIRST STEPS IN CODING
54
CHAPTER 6
How Computers Work
• Computers are stupid. Really stupid
56
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 programmes 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 the
everyone’s pay!
Things have changed a lot since then, though. Now most people choose existing pro-
grammes 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 programme, so that
computers can be more useful to you, and as with learning any new skill, that you can
have the satisfaction and enjoyment and new adventures that this brings!
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.”
57
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 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 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 com-
puters this is called the Programme 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 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 an-
other 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.
58
Don’t worry if that sounds a bit confusing for now, specially that last one – we will go
through it in detail very soon! The best way to explain it, is to go through some examples.
59
60
CHAPTER 7
Getting Started in BASIC
• Your first BASIC programmes
• First steps with text and numbers
• Making simple decisions
• Random numbers and chance
62
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 Symbolic
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 attention, 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 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 turn 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 programme the MEGA65 as we have had
making it!
63
is running and ready for you to start programming. You don’t even need to load any
programmes – you can just get started.
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 be in
SHIFT CAPS
upper-case mode, so you don’t need to hold the or LOCK key down. When you
RETURN
have typed “HELLO COMPUTER” press the key. 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 programme.
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, com-
64
puters are quite stupid. They know only a few words, and aren’t particularly imaginative
about how they interpret them.
So let’s try that again in a way that the computer will understand. Try typing the following
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.
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 by holding down
SHIFT RETURN
the key, and then pressing 2. Don’t forget to press the key 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 the 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
RETURN
in Chapter 3. But for now, if you make a mistake just press the key and type the
messed up line again.
65
Hopefully now you will see something like the following:
This time no new SYNTAX ERROR message should appear. But if some kind of error mes-
sage has appeared, just try typing in the command again, after taking a close look to
work out where the mistake might be.
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 COM-
PUTER 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.
66
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 them
RETURN
immediately after you pressed the key. This is why typing commands in this way is
often called direct mode or 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.
Let’s try that out with a simple little programme. Type in the following three lines of input:
1 FOR I = 1 TO 10 STEP 1
2 PRINT I
3 NEXT I
67
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 on the
left 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
programme, a bit like the programme 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 programme.
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
68
associated with the variable called I with another piece of information. 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 programme, we now know that the 2nd command will try to print the piece of
information stored in the variable I. So lets 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 lets 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.
69
To see this in action, we need to tell the computer to execute the programme of commands
we typed in. We do this by using the RUN command. Because we want it to run the
programme immediately, we should use immediate mode (remember, this is another name
RETURN
for direct mode). So just type in the word RUN and press the key. You should then
see a display that looks something like the following:
70
If you wish to see the programme of remembered commands, you can use the LIST com-
mand. This commands causes the computer to display the remembered programme of
commands to the screen, like in the display here. If you would like to replace any of the
commands in the programme, 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
programme to PRINT I; by typing the following line of input and pressing the key:
2 PRINT I ;
71
You can make sure that the change has been remembered by running the LIST command
again, as we can see here. You can then use the RUN command to run the modified
programme, like this:
It is quite easy to modify your programmes 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 programme. Alternatively, you can give
a range separated by a minus sign to display only a section of the programme, e.g., LIST
1 - 2 to list the first two lines of our programme.
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 screen,
RETURN
and then press the key 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 if
RETURN
you modify multiple lines of the programme at the same time, you must press the
key on each line that has been modified. It is good practice to check that the programme
LIST
has been correctly modified. Use the command again to achieve this.
72
Exercises to try
73
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".
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 number. Do you think
that the computer will accept all four kinds of thing when it says READY.? We already
know that keywords and numbers and keywords can be entered, but what about variable
RETURN
names or strings? Let’s try typing in a variable name, say N, and pressing the key,
and see what happens. And then lets try with a string, say "THIS IS A STRING".
You should get a syntax error each time, telling you that the computer doesn’t understand
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 that is stored in a variable using the PRINT command. So we
74
could instead 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 annoying having
to type in the PRINT command all the time, that they made a short cut: 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 the key after each command to tell the computer you want it to process
what you typed. From here on, we will assume that you can remember to do that, without
being reminded.
The ? shortcut also works if you are telling the computer to remember a command as part
of a programme. So if you type 1 ? N, and then LIST, you will see 1 PRINT N, as we
can see in the following screen-shot:
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$.
75
We can experiment with these variables by using the hopefully now familiar PRINT com-
mand (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 to want 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:
76
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.
(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
programme is running. One way that we can do this, is with the INPUT command.
77
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 programme. So we
can instead do something like the following:
1 INPUT A$
2 PRINT " YOU TYPED "; A$
RUN
78
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 programme 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 programme 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.
79
RETURN
But returning to our example, if we now type something in, and press the key to tell
the computer that you are done, the programme will continue, like this:
Of course, we didn’t really know what to type in, because the programme 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:
80
Now if we run this programme, 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 programme, 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 pro-
gramme, 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 programme. It exists only in
the variable. This ability to process information that is not part of a programme is one of
the things that makes computer programmes 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.
81
For example, with our programme we run it again and again, and give it different input
each time, and the programme 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 programme 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 qualifica-
tion 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 programme 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.
82
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 obsessing
over the Space Core Directives, he would have known to type "RIMMER, BSC" (complete
with the double-quotes), to have the programme 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 programme like this:
83
If we run this programme, 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 programme:
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 programme 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 IN-
PUT 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.)
84
So if we try this with our programme, 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 programme:
Until now we have been asking the user to input information by using a PRINT command
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 programme 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 programme 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
RETURN
the cursor keys to navigate to that line, edit it on the screen, and then press the key
to tell the computer to accept the new version of the line.
85
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 programme.
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:
86
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
programme 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 programmes don’t get all cluttered up
with empty lines if you make lots of changes to your programmes.
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 10 Command Reference.
87
With that out the way, let’s run our programme and see what happens. As usual, just type
RETURN
in the RUN command and hit the key. 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:
88
Now if we run the programme, we should see what we are looking for:
Exercises to try
1. Can you make the programme 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 programme 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 programme that asks someone for their name, prints the hello
message, and then asks for their age and prints out that response?
89
At the moment, the programme expects both pieces of information at the same time. This
means the programme can’t print a message about the first message until after it has
both pieces of information. Change the programme so that you can have an interaction
like the following instead:
Clue: You will need more lines in your programme, so that you can have more than one
INPUT and PRINT command.
3. Can you write a programme 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
programme that asks them, and remembers the answers and prints them out with an ap-
propriate message. For example, running your programme could look like this:
Clue: You will need more lines in you programme, to have the various INPUT and PRINT
commands.
Clue: You will need to think carefully about which variable names you will use.
90
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 side needs to be less than the number on the right
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 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.
91
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:
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 programme. So lets make a little programme 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 programme, have a think about how you might do it, and
see if you can figure it out. The clue I 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 programme will be on the next page, to stop you peeking
before you have a think about it!
92
Did you have a go? There are lots of different ways it could be done, but here is what I
came up with:
We can then run the programme 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 programme, 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, lets the pro-
grammer create very flexible programmes.
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.
93
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 programme yourself.
Here is how I 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 programme to perform a particular task.
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 GU 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:
94
We can see that it prints the message, and it asks for a guess, and responds appropriately.
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 dis-
appears. 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
SHIFT CLR
But there are better ways. If you hold down the key, and then press the HOME
key, it clears the screen. This is much simpler and more convenient. But how can we do
something like that in our programme? 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. I 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 right key, a Ž, up Ʊ, down
CLR SHIFT CLR
ű and the HOME a ų, and if you are holding down and press HOME a Ƴ.
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:
SHIFT CLR
To do this, start by typing 2 PRINT ". Then hold the key down, and tap the HOME
key. 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 programme. You should
see your modified line with the Ƴ symbol in it.
95
RETURN
If you now run the programme by typing in RUN and pressing the key as usual, the
2nd line tells the compute to clear the screen before printing the rest of the message, like
this:
96
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, just like 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 programme again.
There are a few ways we could do this. We already saw the FOR – NEXT pattern. With
that, we could make the programme give the user a certain number of guesses. If we
followed the NEXT command with another programme line, we could even tell the user
when they have taken too many guesses. So lets have a look at our programme 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.
97
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 programme, 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 programme, 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 lets add a line like this:
15 FOR I = 1 TO 10 STEP 1
98
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
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 programme will keep
going. We’d really like the programme 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 programme, the computer tells you
where it has stopped, and you have the chance to continue the programme using the CONT
command. The END command, on the other hand, tells the computer that the programme
has reached its end, and it should go back to being READY. The END command makes
99
more sense for our programme, 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 programme, we can just add : END to
the end of the line. The line should look like this:
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 programme, 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 programme. 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 programme:
100
If you type those lines in, and LIST the programme again, you should see something like
the following:
101
We can now RUN the programme, 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.
102
But back to our programme, we can now make guesses, and the programme 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
programme as line 80:
103
Now if the user doesn’t guess the number, they will get a useful message, like this:
Exercises to try
1. Can you make the programme ask at the start for the secret number?
At the moment the programme 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 programme ask for the user’s name and give personalised
responses?
At the moment, the programme 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 programme 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.
104
3. Can you improve the appearance of the messages with colours and better spac-
ing?
We haven’t really made the programme 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 commands
to set the colour of the text, screen background and border.
4. Can you make the programme say if a guess is “warmer” or “colder” than the
previous guess?
At the moment the programme 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 com-
pare 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.
105
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:
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.
106
Now, I promised a maze, so I 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:
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 programme 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 programme so that it will run continuously:
107
If you RUN this programme, it will start drawing a maze forever, that looks like the screen
RUN
shot below. You can stop it at any time by pressing the STOP key, or you can pause it
NO NO
by pressing the SCROLL key, and unpause it by pressing the SCROLL key again. If you press
RUN
the STOPkey, the 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 pro-
gramme smaller. We don’t need to put the result of the calculation of which symbol to dis-
play on a separate line. We can put the calculation directly into brackets for the CHR$()
function:
And we can use what we learnt about the : (colon) symbol, and put the GOTO command
onto the same line as the PRINT command:
Can you see how there are often many ways to get the same effect from a programme?
This is quite normal. For complex programmes, there are many, many ways to get the
108
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.
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 I 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:
That looks much better. So lets type in our “guess the number” programme again. But this
time, lets 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 I came up with below. You might
have made a different programme 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 programme much more fun to
play. Can you beat it?
109
Exercises to try
110
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.
111
112
CHAPTER 8
Text Processing
• Characters and Strings
• String Literals
• String Variables
• String Statements
• Simple Formatting
• Sample Programs
114
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 pro-
cessing applications and word games. It is also required in natural language processing
and text-based adventure games, both of which need to understand the input. Under-
standing 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, characters 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 color to orange.
Other non-printable characters might represent a carriage return or clear the screen.
For a complete catalog of available characters, refer to Appendix C PETSCII Codes and
CHR$. 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:
Note that the ’!’ is actually visible on the display because it is a printable character.
Here’s an example of changing the foreground color to white using character codes:
115
Although no character is output, all subsequent printable characters displayed will be
colored 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 statement, outputs
the respective code number to the screen in decimal.
Here’s an example of obtaining the code number for the exclamation mark.
And here’s an example of obtaining the code number for the exclamation mark and storing
it in an integer variable:
A % = ASC ("!")
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.
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 character
116
that is alphanumeric, and end with a $ sign. Once given a value, they can be used with
PRINT.
STRING LITERALS
String literals can be joined with one or more other such string literals to form a compound
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 (" COU NTER " + " CLOCK " + " WISE ")
COUNTERCLOCKWISE
Sometimes punctuation or spaces may be required to make the final output appear cor-
rectly 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 literals.
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.
117
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 DIM A$ (6)
20 PRINT " RAI NBO W COLORS : ";
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
118
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.
In either case, pressing RETURN 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 string
and RETURN 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.
The following program asks for an input string and then prints all right substrings.
119
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)+"."
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
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.
120
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.
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.
Simple Ciphers
We now look at three simple examples of scrambling and unscrambling English language
text messages. This scrambling and unscrambling process is the study of cryptography
121
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, readable
unscrambled text is called plaintext. Encrypting plaintext results in a scrambled mess-
sage. 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. Nevertheless,
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.
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, some-
times 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
122
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 plain-
text 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.
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.
123
EROT 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 alphabet,
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 backwards. 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 ciphertext 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
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 num-
ber 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 ar-
gument 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.
124
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 mes-
sages. To encrypt a letter using the Caesar cipher we move three positions forward. 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. Instead of moving for-
ward, 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.
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.
Notice that the definitions of both the encryption and decryption functions are, in this
case, different.
125
We can generalise all three of the above methods by stating that they use the following
encryption and decryption functions:
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.
This text string, which is 43 characters long, contains 8 spaces and 35 alphabetic char-
acters. 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:
Encrypting the above text string using the Atbash cipher yields:
Encrypting the above text string using the Caesar cipher yields:
126
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 127
460 PRINT : PRINT " USE L E T T E R S AND SPACES ONLY ": PRINT
470 RETURN
If you wish to use the ROT13 cipher ensure that the following lines are changed:
If you wish to use the Atbash cipher ensure that the following lines are changed:
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
128
CHAPTER 9
C64. C65 and MEGA65 Modes
• Switching Modes from BASIC
• The KEY Register
• Accessing the MEGA65’s Extra
Memory from BASIC 10 in
C65 Mode
To switch from C65 to C64 Mode, use the familiar GO 64 command, identically to switch-
ing to C64 mode on a C128:
GO 64
ARE YOU SURE? Y
Note that, just like on the C128, any programmes in memory will be lost in the process of
switching modes.
Alternatively, you can hold down the MEGA key when pressing the reset button or turning
the computer on. Again, this is the same as on the C128.
To switch from C64 to C65 Mode, there is no official method. However the following
command switches from C64 mode to C65 mode. Note that this command does not ask
you for confirmation!
131
SYS 58552
Alternatively, you can switch back to C65 mode by pressing the reset button on the left
side of the computer, or simply turning the computer off and on again.
Another option is to long-press the RESTORE key, and then choose F5 from the freeze
menu. This simulates pressing the reset button.
Note that, just like on the C128, any programmes in memory will be lost in the process of
switching modes.
The machine code monitor can be entered by typing either the MONITOR command from
BASIC 10 in C65 mode, or by holding the RUN/STOP key down, and then pressing the
reset button on the left side of the computer.
For example, to un-hide the VIC-III’s new registers when in C64 mode, you must POKE the
values 165 and 150 into the KEY register. Make sure you are in C64 mode before trying
the following. The easiest way to do this is to turn your MEGA65 off and on again, and
type GO 64 and answer YES to enter C64 mode.
132
(If you do it from C65 mode, the computer will get rather confused, because in between
the first and second POKE commands running, none of the C65-mode extra features will
be visible to the computer, and BASIC 10 will probably crash or freeze as a result. But
don’t worry, if you accidentally do this, just turn the computer off and on again, or press
and release the reset button the left side of the computer.)
Once you are in C64 mode, try typing the following commands:
When you type these commands, the computer just returns with a READY. prompt, and
seemingly nothing else has happened. This is expected, because all we have done is un-
hide the VIC-III’s new registers (and some other C65 mode features) from the computer.
However, the C64 BASIC and KERNAL are well behaved, and don’t try to do anything
strange, and so we don’t immediately notice anything is different... But things are differ-
ent.
As an example, we will now do something that the C64 and its VIC-II can’t do: smoothly
change one colour into another. The VIC-III has registers that let you change the red,
green and blue components of the colours. So now that we have un-hidden those regis-
ters, we can 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 (hex $D100 – $D1FF). Blue is colour
6, so we want to change register 53504 + 6 = 53510 (hex $D106). We can do a nice
FOR loop to change the colour for us:
You should hopefully have seen the background of the screen fade from blue to purple. If
you would like to make the effect go faster, increase the 0.2 to a bigger number, like 0.5,
or to make it slower, make it a smaller number, like 0.02. You can also change the red
component you are changing by adding a different number to 53504. Or you might like to
change the green component (53760 – 54015, hex $D200 – $D2FF) or blue component
(54016 – 54271) – or any combination. For example, to make the border and text (since
they are both normally “light blue”) fade from blue to green, you could do:
POKE 53518,0 : FOR I = 0 TO 15 STEP 0.1 : POKE 53774,I : POKE 54030,15-I : NEXT
133
Re-hiding C65/MEGA65 Extra Registers
You can also hide the VIC-III registers again by POKEing any number you like into the KEY
register, e.g.:
POKE 53295,0
If you try the examples from above, the colours won’t change this time because the reg-
isters are hidden again. Instead, writing to those addresses changes some of the VIC-II’s
registers because on a C64 they appear several times over. Fortunately, we chose an
example where the registers don’t have any ill-effect in our case (for the curious, it is the
sprite positions that would be messed up, but since there are no sprites on the screen, we
don’t see any problems).
The MEGA65 has even more registers than the C65. To un-hide those from C64 mode,
we write two different values into the KEY register:
(Don’t forget you have to be in C64 mode, as BASIC 10 will probably crash or freeze when
the C65 / VIC-III registers get briefly hidden after the first POKE has been performed, but
the second one hasn’t yet.)
Again, you won’t see any immediate difference, just like when un-hiding C65 / VIC-III
registers. However, now the computer can access not only the C64 / VIC-II and C65
/ VIC-III registers, but also the MEGA65 / VIC-IV registers. If you like, you can try the
examples from earlier in this chapter, to assure yourself that the C65 / VIC-III registers
are accessible again. But we can also do MEGA65 specific things. For example, if we
wanted to move the start of the top border higher up the screen, we could type something
like:
POKE 53320,60
Or again, we could have some fun, and animate the screen borders moving closer and
further apart:
134
(We made this loop go backwards, so that you wouldn’t end up with only a tiny sliver of
the screen visible. But you can make it go forwards if you like. If you do get stuck with a
sliver of the screen, you can just press RUN/STOP and RESTORE. You might be wondering
why RUN/STOP and RESTORE works, when these are MEGA65 / VIC-IV registers that the
C64-mode BASIC and KERNAL don’t know about. The reason it works is because the VIC-
IV has a feature called “hot registers,” where certain C64 and C65 registers cause some
of the 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 (hex $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.)
See if you can instead make the screen shake around 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 Appendix K.
In both C64 and C65 mode, 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 C64 / VIC-II mode
whenever it is accessed. This means if you check the drive status, LOAD or SAVE a file, for
example, the KEY register will be reset, and only the C64 / VIC-II registers will be visible.
You can of course make the C65 or MEGA65 extra registers visible again by POKEing the
correct values to the KEY register again.
Using the BANK and PEEK and POKE commands, this region of memory can be easily
accessed, for example:
135
BANK 4: POKE0,123: REM PUT 123 IN LOCATION $40000
BANK 4: PRINT PEEK(0): REM SHOW CONTENTS OF LOCATION $40000
Or using the DMA command, you could copy the current contents of the screen and colour
RAM into BANK 4 with something like this:
You could then put something else on the screen, and then copy it back with something
like:
Note that there is currently no way to tell BASIC 10 to put graphics screen, variables,
arrays or program text in these extra banks of RAM.
136
PART III
SOUND AND GRAPHICS
138
PART IV
HARDWARE
140
CHAPTER 10
Using a Nexys4DDR as a
MEGA65
• Building your own MEGA65 Com-
patible Computer
143
POWER, JUMPERS, SWITCHES AND
BUTTONS
The Nexys4DDR board can be powered in two ways: using an external power supply, or
from a standard USB port.
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 Nexys4DDR’s micro-usb connector. Place the JP3 jumper
on pins 1 and 2 to select USB power. Use the switch to turn on the Nexys4DDR.
144
The MEGA65 core can consume a lot of power, and a standard USB port could poten-
tionally be too little for the Nexys4DDR 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 Nexys4DDR board, and we recommend you use this to
ensure you avoid the risk of damage to your Nexys4DDR 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 Nexys4DDR. Place the JP3
jumper on pins 2 and 3 to select WALL power. Use the switch to turn on the Nexys4DDR.
Set the following jumpers on your Nexys4DDR board to the following positions:
• JP1 - USB/SD
• JP2 - SD
All 16 switches on the lower edge of the board must be set to the off position.
145
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 Nexys4DDR 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.
Onboard buttons
146
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
you have pressed the RESTORE key, 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 posi-
tions 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.
ALT
The easiest way is to keep the key held in while turning on the Nexyx4, or resetting
the Nexyx4 with the “PROG” button. The configure menu will be presented and by pressing
3, the virtual keyboard will be presented on a black background.
147
Pressing a key on the USB keyboard will show the highlighted key on the virtual keyboard
to help you identify the key mapping.
The other way to access the virtual keyboard is from within the MEGA65. Hold ` and
press TAB 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. Alternatively:
s ffd3615 ff ff
This will open a semi-transparent virtual keyboard in the centre of the screen.
Hold ` and press TAB to exit Matrix Mode Debugger and return to the MEGA65.
148
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.
To prepare your SD card, you will need the following two separate files from the MEGA65
web site:
• Bitstream http://mega65.org/assets/bitstream.7z
• Support Files http://mega65.org/assets/fileset.7z
In addition, you will also need a C65 ROM. There were many different versions created
during the development of the Commodore 65, and the MEGA65 can use any of them.
However, we recommend you use 911001.bin, as this has the most complete BASIC and
DOS implementations.
The steps are:
• Format the SD card in a convenient computer using the FAT32 file-system. The
MEGA65 and Nexys4DDR boards do not understand other file systems, especially
the exFAT file system.
• Unzip the bitstream.7z file, and copy the 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 Nexys4DDR board.
• Turn on the Nexys4DDR board.
• Enter the Utility Menu by holding the ALT key down on the USB keyboard you have
connected to the Nexys4DDR 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, configuration data and other files live. (This partition is invisible in i.e. Win
PCs). and the other partition with type $0C = VFAT32, where KERNEL, 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 Nexys4DDR board and remove the mi-
croSDHC card from the Nexys board and put it back into your PC
• Again copy the bitstream back onto the SD card, as well as all the files from the
other 7z file downloaded from the MEGA65 website.
149
• Copy the 911001.bin ROM file onto the SD card, and rename it to MEGA65.ROM
• If you have any .D81 files, copy them onto the SD card. Make sure that they have
names that fit the old DOS 8.3 character limit, and are upper case. This restriction
will be removed in a future release.
• Remove the SD card and reinsert it into your Nexys4DDR board.
• Power the Nexys4DDR board back on. The MEGA65 should boot within 15 seconds.
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 the Configuring your MEGA65 chapter.
USEFUL TIPS
The following are some useful tips for getting familiar with the MEGA65:
• Press the RESTORE for about 2 seconds to reset the MEGA65. This
is a temporary feature that will be removed when the MEGA65 desktop
computers with built-in reset button become available.
150
• Type POKE0,65 in C64 mode to switch the CPU to full speed (40MHz). Some
software 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,
just like 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.
RUN
• Pressing SHIFT + 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 and Art welcomes your feedback,
suggestions and contributions to this open-source digital heritage preserva-
tion project.
151
152
PART V
CROSS-PLATFORM
DEVELOPMENT TOOLS
154
CHAPTER 11
Emulators
• Using The Xmega65 Emulator
• Using the Live ISO image
156
At the time of writing, there is only one emulator for the MEGA65, xmega65,
from LGB’s Xemu emulator suite. The developers of this emulator are working
hard to keep up with the development of the MEGA65. Thus some aspects of
the MEGA65 may not be perfectly emulated. However, it is typically sufficient
for developing software for the MEGA65. To be safest, you should always test
software regularly on real hardware, whether that be on a MEGA65 computer,
or on an FPGA board which is capable of running a MEGA65 core.
The source code for the MEGA65 emulator can be downloaded
from https://github.com/lgblgblgb/xemu. Pre-compiled ver-
sion can be downloaded from https://github.lgb.hu/xemu/.
There is also a live ISO image containing the emulator, documen-
tation and other tools. The link to this ISO image can be found
in on Forum64.de at https://www.forum64.de/index.php?thread/
104698-xemu-live-system-iso-file/&postID=1549927#post1549936.
The first step is to create the live ISO image. The method for doing this will
depend on your operating system, and whether you wish to install it on a USB
stick, or burn it to a DVD. Burning to a DVD is straightforward, assuming you
own a computer that has a DVD writer. If you don’t, or if you wish to in any case
make a bootable USB stick, e.g., because it will boot faster than a DVD, you
will need to use an appropriate tool to make a bootable USB stick from an
ISO image. If you are using Windows, you might consider a tool like http:
//www.isotousb.com/. On Linux, you can use the instructions at https:
//fossbytes.com/create-bootable-usb-media-from-iso-ubuntu/. For
Apple Macs, you might consider the information at https://ubuntu.com/
tutorials/create-a-usb-stick-on-macos#1-overview. Similar instruc-
tions are available for other popular computers, such as Amigas (https://
157
forum.hyperion-entertainment.com/viewtopic.php?t=3857), or Sun Ul-
traSPARC workstations (https://forums.servethehome.com/index.php?
threads/how-to-create-a-bootable-solaris-11-usb.1998/).
Getting Started
To avoid any potential problems with copyright, the bootable ISO image does
not include any proprietary ROMs for the MEGA65, such as the legacy C65
ROMs. It does include an open-source replacement ROM from our OpenROMs
project. This is sufficient to boot into a BASIC 2 like environment, that can be
used to load and execute many C64 programmes. It will result in a display
like the following:
However, if you wish to use a C65 ROM and its included BASIC 10, you will
need to download the appropriate ROM file, and place it on another USB
stick, and named MEGA65.ROM. The Live ISO will prompt you on start-up to
ask if you have such a file already downloaded:
158
If the Live ISO cannot find this file, it will ask you if you would like for it to
automatically download such a ROM for you, as can be seen below:
Naturally you will need to have an internet connection available for this to
work.
As the previous screen-shots show, the Live ISO provides various desktop
shortcuts for your convenience. On the left-hand side, we see shortcuts for
launching the MEGA65 emulator, and also the C65 emulator, if you wish to
check if your programmes can run on a standard C65 computer. As previously
mentioned, both emulators are works in progress, and thus may not be 100%
faithful in all aspects of their emulation.
Next we have a link to the MEGA65 Book, which is the all-in-one volume con-
taining the almost 800 pages of all official MEGA65 documentation. The
majority of this developer’s guide is also present in the MEGA65 Book.
Below this, there is documentation for the C65 Notepad, a programme for the
C65 and MEGA65 written by Snoopy, who also prepared the Live ISO image.
A “read me” file is also provided, that contains further information about the
Live ISO.
Finally, there is a link to access the contents of the Live ISO image via the file
explorer, should you wish to do so.
Then on the right-hand side, there are links to download a C65 ROM, and
to update the MEGA65 Book to the latest version, so that you don’t need to
create a new bootable image each time the MEGA65 Book is updated. This
is very helpful, as the MEGA65 Book continues to grow and evolve.
159
160
CHAPTER 12
Data Transfer and
Debugging Tools
• m65 command line tool
• M65Connect
• mega65_ftp
• TFTP Server
162
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 complete, 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
developed 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 remainder of this chapter focusses on methods that
access the serial monitor interface.
You can either connect a 3.3V UART adaptor to the appropriate lines, or more
conveniently, connect a TE-0790-03 JTAG debug module onto this connec-
tor. 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 -S
163
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.
To load and run a programme on the MEGA65, you can use a command like:
The -F option tells m65 to reset the MEGA65 before loading the programme.
The -4 option tells m65 to switch the MEGA65 to C64 mode before loading
the programme. If this is left off, then it will attempt to load the programme
in C65 mode.
The -r option tells m65 to run the programme immediately after loading.
Note that this command works using the normal BASIC LOAD command, and
is thus limited to loading programmes into the lower 64KB of RAM
To try out a different 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 reconfigured by this action, and programme 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.
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:
164
m65 -t s o m e t e x t
This form types the supplied text, in this case sometext, but does not simulate
RETURN RETURN
pressing the key. If you wish to simulate the pressing of the key,
use -T instead of -t, e.g.:
m65 -T list
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.
M65CONNECT
This is a cross-platform graphical tool available for Windows, Linux and Ma-
cOSX, 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.
MEGA65_FTP
The mega65_ftp utility from the https://github.com/mega65/
mega65-tools repository is a little misleadingly named: While it is a
File Transfer Programme, it does not use the File Transfer Protocol (FTP).
Rather, it uses the serial monitor interface to take remote 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
165
when a sensitive programme 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 programme is very slow to push new files to the
MEGA65, typically 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 con-
trol 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 compression, de-duplication
of identical sectors (especially when uploading disk images) and other tech-
niques. 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 trans-
fers 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, de-
pending on SD card performance. 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 con-
figured ethernet MAC address may be added in the future.
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 chal-
lenge is enabling 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 mechanism requires a pointer to the contiguous block
166
of the SD card containing the disk image. In the interim, mega65_ftp can be
used as a substitute.
167
168
CHAPTER 13
Assemblers
170
The short answer is that we recommend that you use the ACME assembler.
The mnemonics used by ACME are now considered the official onces for the
45GS02. KickAsm is also quite suitable. The long answer continues below.
There are any number of assemblers that can be used to develop for the
MEGA65. However only very few support the MEGA65’s advanced CPU fea-
tures, or even the C65 4510 instructions.
Four different assemblers have been used for different parts of the MEGA65
software, reflecting the rather haphazard history of developing assembler
support for the MEGA65. The first assembler to support the MEGA65 was
Ophis, as it seemed the easiest to patch. KickAss later gained support,
followed by ACME. ACME added support at a convenient time, when the ex-
tended instructions, their names and syntax had sufficiently stabilised.
From the perspective of the MEGA65 team, ACME has two advantages over
KickAsm: First, it is open source, which fits the ethos of the project, and ensures
long-term availability. Second, it is written in C, rather than Java, which means
that it may be possible to port to run natively on the MEGA65 at some point
in the future.
Our fork of CA65 (https://github.com/mega65/cc65), the assembler used
in CC65, also now has the ability to detect the MEGA65’s CPU, but has no
explicit support for the processor’s features. This is an important fix, however,
as otherwise software using the CC65 processor detection routine thinks that
the MEGA65 has a 65816, which can result in the execution of incompatible
instructions. This causes problems with Synthmark64 0.2, for example.
Bit Shifter’s BSA Assembler now also has support for the 45GS02. The source
for this assembler can be found at https://github.com/Edilbert/BSA.
171
172
CHAPTER 14
C and C-Like Compilers
• MEGA65 libc
174
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 programmes larger than 64KB. However, this would
require writing a suitable loader for such programmes, 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 oth-
erwise horribly 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 particularly 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 programme that can be compiled using CC65
and executed 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 already have it installed on your system. This repos-
itory should work on Linux and Mac, and on Windows under the Windows Sub-
system for Linux (WSL).
MEGA65 LIBC
A C library is being developed for the MEGA65, and which already includes a
number 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 CC65, although we would
welcome someone maintaining a KickC port of it.
175
176
CHAPTER 15
MEGA65 Standard C Library
• Structure and Usage
• conio.h
178
A C library is being developed for the MEGA65, and which already includes a
number 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 CC65, although we would
welcome someone maintaining a KickC port of it.
CONIO.H
conionit
Description:
Initializes the library internal state
Syntax: void conioinit(void)
Notes: This must be called before using any conio library function.
179
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
getscreenaddr
Description:
Returns the screen RAM start address
Syntax: long getscreenaddr(void);
clrscr
Description:
Clear the text screen.
Syntax: void clrscr(void)
getscreensize
Description:
Returns the dimensions of the text screen
Syntax: void getscreensize(unsigned char* width, unsigned
char* height)
Parameters:
180
width: Pointer to location where width will be returned
width: 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)
width: 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
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:
181
f: Set true to set the extended attributes mode
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)
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:
182
c: The color to set
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 setextendedat-
trib.
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 setextendedat-
trib.
blink
Description:
Enable the blink attribute
Syntax: void blink(unsigned char c)
Parameters:
enable: 0 to disable, 1 to enable
183
Notes: Extended attributes mode must be active. See setextendedat-
trib.
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 setextendedat-
trib.
cellcolor
Description:
Sets the color of a character cell
Syntax: void cellcolor(unsigned char x, unsigned char y,
unsigned 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
fillrect
Description:
Fill a rectangular area with character and color value
184
Syntax: void fillrect(const RECT *rc, unsigned char ch,
unsigned 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, un-
signed 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
style: The style for the box borders. Can be set
to 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.
185
Syntax: void hline(unsigned char x, unsigned char y, un-
signed 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, un-
signed 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)
Syntax: void gohome(void)
186
gohome
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
187
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
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
188
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)
wherey
Description:
Return the current position Y coordinate
Syntax: unsigned char wherey(void)
cputc
Description:
Output a single character to screen at current position
Syntax: void cputc(unsigned char c)
Parameters:
189
c: 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 character 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
es: The symbolwillbeautomaticallyaddedatbeginningof string
cputdec
Description:
Output a decimal number at current position
Syntax: void cputdec(long n, unsigned char padding, un-
signed char leadingZ)
Parameters:
n: The number to write
190
padding: The padding space to add before number
leadingZ: The leading zeros to print
cputs
Description:
Output a string at current position
Syntax: void cputs(const char* s)
Parameters:
s: The string to print
Notes: No pointer check is performed. If s is null or invalid, behavior is
undefined
cputsxy
Description:
Output a string at X,Y coordinates
Syntax: void cputsxy (unsigned char x, unsigned char y,
const char* s)
Parameters:
s: The string to print
x: The X coordinate where string will be printed
y: The Y coordinate where string will be printed
Notes: No pointer check is performed. If s is null or invalid, behavior is
undefined
cputcxy
Description:
Output a single character at X,Y coordinates
191
Syntax: void cputcxy (unsigned char x, unsigned char y,
unsigned char c)
Parameters:
x: The X coordinate where character will be printed
y: The Y coordinate where character will be printed
c: 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,
unsigned char c)
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 character to print
cprintf
Description:
Prints formatted output.
Escape strings can be used to modify attributes, move cur-
sor,etc, similar to PRINT in CBM BASIC. Available escape codes:
Cursor positioning
to next tab position (multiple of 8s) R�eturn New-line (assume
Go
l�ike in C printf)
clr
Syntax: unsigned char cprintf (const unsigned char* for-
mat, ...)
192
Parameters:
format: The string to output. See escape codes for formatting
options.
Notes: Currently no argument replacement is done with the variable ar-
guments.
cgetc
Description:
Waits until a character is in the keyboard buffer and returns it
Syntax: unsigned char cgetc (void);
kbhit
Description:
Returns the character in the keyboard buffer
Syntax: unsigned char kbhit (void);
getkeymodstate
Description:
Return the key modifiers state, where bits:
Bit Meaning Constant —————————————————- 0 Right SHIFT
state KEYMOD_RSHIFT 1 Left SHIFT state KEYMOD_LSHIFT 2
CTRL state KEYMOD_CTRL 3 MEGA/C= state KEYMOD_MEGA
4 ALT state KEYMOD_ALT 5 NOSCRL state KEYMOD_NOSCRL 6
CAPSLOCK state KEYMOD_CAPSLOCK 7 Reserved -
193
Syntax: unsigned char getkeymodstate(void)
flushkeybuf
Description:
Flush the keyboard buffer
Syntax: void flushkeybuf(void)
cinput
Description:
Get input from keyboard, printing incoming characters at current
position.
Syntax: unsigned char cinput(char* buffer, unsigned char
buflen, unsigned char flags)
Parameters:
buffer: Target character buffer preallocated by caller
buflen: Target buffer length in characters
flags: Flags for input: (default is accept all printable charac-
ters)
CINPUT_ACCEPT_NUMERIC CINPUT_ACCEPT_LETTER
CINPUT_ACCEPT_SYM CINPUT_ACCEPT_ALL CIN-
PUT_ACCEPT_ALPHA
Desription: 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.
194
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).
195
196
CHAPTER 16
BASIC Tokenisers
198
Various tokenisers for C64 BASIC exist, e.g., https://github.com/catseye/
hatoucan, https://www.c64-wiki.com/wiki/C64list, or the petcat util-
ity that is part of VICE. If you are using Ubuntu Linux, you can install petcat
by using the following command:
199
200
PART VI
APPENDICES
202
APPENDICES
204
APPENDIX A
ACCESSORIES
206
APPENDIX B
BASIC 10 Command
Reference
• Format of Commands, Functions
and Operators
209
KEY 8"FISH"
?SYNTAX ERROR
KEY 8."FISH"
?SYNTAX ERROR
It is very common for commands, functions and operators to use one or more
“expression”. An expression is just a fancy name for something that has a
value. This could be a string, such as "HELLO", or a number, like 23.7, or it could be
a calculation, that might include one or more functions or operators, such as
LEN("HELLO") * (3 XOR 7). Generally speaking, expressions can result in either a string
or numeric result. In this case we call the expressions either string expressions
or numeric expressions. For example, "HELLO" is a string expression, while 23.7
is a numeric expression.
It is important to use the correct type of expression when writing your pro-
grams. If you accidentally use the wrong type, the computer will give you a
?TYPE MISMATCH ERROR, to say that the type of expression you gave doesn’t match
what it expected, that is, there is a mismatch between the type of expression
it expected, and the one you gave. For example, we will get a ?TYPE MISMATCH
ERROR if we type the following command, because "POTATO" is a string expression
instead of a numeric expression:
KEY "POTATO","SOUP"
You can try typing this into the computer yourself now, if you like.
210
COMMANDS, FUNCTIONS AND
OPERATORS
Commands are statements that you can use directly from the READY. prompt,
or from within a program, for example:
PRINT "HELLO"
HELLO
10 PRINT "HELLO"
RUN
HELLO
211
ABS
Token: $B6
Format: ABS(x)
Usage: The numeric function ABS(x) returns the absolute value of the
numeric argument x.
x = numeric argument (integer or real expression).
Remarks: The result is of real type.
Example: Using ABS
PRINT ABS(-123)
123
PRINT ABS(4.5)
4.5
PRINT ABS(-4.5)
4.5
212
AND
Token: $AF
Format: operand AND operand
Usage: The Boolean AND operator performs a bit-wise logical AND op-
eration on two 16-bit values. Integer operands are used as they
are. Real operands are converted to a signed 16 bit integer.
Logical operands are converted to 16 bit integer using $FFFF,
decimal -1 for TRUE and $0000, decimal 0, for FALSE.
0 AND 0 -> 0
0 AND 1 -> 0
1 AND 0 -> 0
1 AND 1 -> 1
PRINT 1 AND 3
1
PRINT 128 AND 64
0
213
APPEND
Token: $FE $0E
Format: APPEND# lfn, 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.
lfn = logical file number
1 <= lfn <= 127: line terminator is CR
128 <= lfn <= 255: line terminator is CR LF
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$)
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: APPEND# functions similar to the DOPEN# command, except that if the
file already exists, the existing content of the file will be retained,
and any PRINT# commands made to the open file will cause the file
to grow longer.
Example: Open file in append mode:
APPEND#5,"DATA",U9
APPEND#130,(DD$),U(UN%)
APPEND#3,"USER FILE,U"
APPEND#2,"DATA BASE"
214
ASC
Token: $C6
Format: ASC(string)
Usage: Takes the first character of the string argument and returns its
numeric code value. The name is apparently chosen to be a
mnemonic to ASCII, but the returned value is in fact the so called
PETSCII code.
Remarks: ASC returns a zero for an empty string, which behaviour is dif-
ferent to BASIC 2, where ASC(””) gave an error. The inverse
function to ASC is CHR$.
Example: Using ASC
PRINT ASC("MEGA")
77
PRINT ASC("")
0
215
ATN
Token: $C1
Format: ATN(numeric expression)
Usage: 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.
Example: Using ATN
PRINT ATN(0.5)
.463647609
PRINT ATN(0.5) * 180 / ~
26.5650512
216
AUTO
Token: $DC
Format: AUTO [step]
Usage: Enables faster typing of BASIC programs. After submitting a new
program line to the BASIC editor with the RETURN key, 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 switches this function off.
Example: Using AUTO
217
BACKGROUND
Token: $FE $3B
Format: BACKGROUND colour
Usage: Sets the background colour of the screen to the argument, which
must be in the range 1 to 16. (See colour table).
Colours: Index and RGB values of colour palette
index red green blue colour
1 0 0 0 black
2 15 15 15 white
3 15 0 0 red
4 0 15 15 cyan
5 15 0 15 magenta
6 0 15 0 green
7 0 0 15 blue
8 15 15 0 yellow
9 15 6 0 orange
10 10 4 0 brown
11 15 7 7 pink
12 5 5 5 dark grey
13 8 8 8 medium grey
14 9 15 9 light green
15 9 9 15 light blue
16 11 11 11 light grey
Example: Using BACKGROUND
218
BACKUP
Token: $F6
Format: BACKUP D source TO D target [,U unit]
Usage: Used on dual drive disk units only (e.g. 4040, 8050, 8250). The
backup is done by the disk unit internally.
source = drive # of source disk (0 or 1).
target = drive # of target disk (0 or 1).
Remarks: The target disk is formatted and a identical copy of the source
disk is written.
This command cannot be used for unit to unit copies.
Example: Using BACKUP
219
BANK
Token: $FE $02
Format: BANK bank-number
Usage: Selects the memory configuration for BASIC commands, that use
16-bit addresses. These are LOAD, SAVE, PEEK, POKE, WAIT and
SYS. See system memory map (Appendix F) for details.
Remarks: A value > 127 selects memory mapped I/O. The default value
for the bank number is 128. This configuration has RAM from
$0000 to $1FFF and BASIC ROM’s, KERNAL ROM’s and I/O from
$2000 to $FFFF.
Example: Using BANK
220
BEGIN
Token: $FE $18
Format: BEGIN ... BEND
Usage: The BEGIN and BEND keywords act like a pair of brackets around
a compound statement to be executed after a THEN or ELSE
keyword. This overcomes the single line limitation of the stan-
dard IF ... THEN ... ELSE clause.
Remarks: Do not jump with GOTO or GOSUB into a compound statement.
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$
221
BEND
Token: $FE $19
Format: BEGIN ... BEND
Usage: The BEGIN and BEND keywords act like a pair of brackets around
a compound statement to be executed after a THEN or ELSE
keyword. This overcomes the single line limitation of the stan-
dard IF ... THEN ... ELSE clause.
Remarks: The example below shows a quirk in the implementation of the
compound statement. If the condition evaluates to FALSE, ex-
ecution does not resume right after BEND as it should, but at
the beginning of next line. Test this behaviour with the following
program:
Example: Using BEGIN and BEND
222
BLOAD
Token: $FE $11
Format: BLOAD filename [,B bank] [,P address] [,D drive] [,U unit]
Usage: ”Binary LOAD” loads a file of type PRG into RAM at address P
and bank B.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$)
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 can be used to overrule 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
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: If the loading process tries to load beyond the address $FFFF,
an ’OUT OF MEMORY’ error occurs.
Example: Using BLOAD
223
BOOT
Token: $FE $1B
Format: BOOT filename [,B bank] [,P address] [,D drive] [,U unit]
BOOT SYS
BOOT
Usage: 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 from sector 0, track 1 and unit
8 to address $0400 on bank 0 and performs a JSR $0400 af-
terwards (Jump To Subroutine).
The BOOT command with no parameter tries to load and exe-
cute a file named AUTOBOOT.C65 from the default unit 8. It’s
short for RUN ”AUTOBOOT.C65”.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$)
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 can be used to overrule 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
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: BOOT SYS copies the contents of one physical sector (two log-
ical sectors) = 512 bytes from disc to RAM, filling RAM from
$0400 to $05ff.
Example: Using BOOT
BOOT SYS
BOOT (FN$), B(BA%), P(PA), U(UN%)
BOOT
224
BORDER
Token: $FE $3C
Format: BORDER colour
Usage: Sets the border colour of the screen to the argument, which must
be in the range 1 to 16. (See colour table).
Colours: Index and RGB values of colour palette
index red green blue colour
1 0 0 0 black
2 15 15 15 white
3 15 0 0 red
4 0 15 15 cyan
5 15 0 15 magenta
6 0 15 0 green
7 0 0 15 blue
8 15 15 0 yellow
9 15 6 0 orange
10 10 4 0 brown
11 15 7 7 pink
12 5 5 5 dark grey
13 8 8 8 medium grey
14 9 15 9 light green
15 9 9 15 light blue
16 11 11 11 light grey
Example: Using BORDER
225
BOX
Token: $E1
Format: BOX X0,Y0, X1,Y1, X2,Y2, X3,Y3, SOLID
Usage: Draws a quadrangle by connecting the coordinate pairs 0 -> 1 -
> 2 -> 3 -> 0. The quadrangle is drawn using the current drawing
context set with SCREEN, PALETTE and PEN. The quadrangle is
filled, if the parameter SOLID is 1.
Remarks: A quadrangle is a geometric figure with four sides and four an-
gles. A box is a special form of a quadrangle, with all four angles
at 90 degrees. Rhomboids, kites and parallelograms are special
forms too. So the name of this command is misleading, because
it can be used to draw all kind of quadrangles, not only boxes.
It is possible to draw bow-tie shapes.
Example: Using BOX
226
BSAVE
Token: $FE $10
Format: BSAVE filename ,P start TO end [,B bank] [,D drive] [,U unit]
Usage: ”Binary SAVE” saves a memory range to a file of type PRG.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$) If the first character of the
filename is an at-sign ’@’ it is interpreted as a ”save and replace”
operation. It is dangerous to use this replace option on drives
1541 and 1571, because they contain the notorious ”save and
replace bug” in their DOS.
bank specifies the RAM bank to be used. If not specified the
current bank, as set with the last BANK statement, will be used.
start is the first address, where the saving begins. It becomes
also the load address, that is stored in the first two bytes of the
PRG file.
end Is the address, where the saving stops. end-1 is the last
address to be used for saving.
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: The length of the file is end - start + 2.
Example: Using BSAVE
227
BUMP
Token: $CE $03
Format: b = BUMP(type)
Usage: Used to detect sprite-sprite (type=1) or sprite-data (type=2) col-
lisions. the return value b is a 8-bit mask with one bit per sprite.
The bit position corresponds with the sprite number. Each bit
set in the return value indicates, that the sprite for this position
was involved in a collision since the last call of BUMP. Calling
BUMP resets the collision mask, so you get always a summary of
collisions encountered since the last call of BUMP.
Remarks: It’s possible to detect multiple collisions, but you need to evalu-
ate sprite coordinates then to detect which sprite collided with
which one.
Example: Using BUMP
228
BVERIFY
Token: $FE $28
Format: BVERIFY filename [,P address] [,B bank] [,D drive] [,U unit]
Usage: ”Binary VERIFY” compares a memory range to a file of type PRG.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$)
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.
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. 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
the command exits either with the message OK or with VERIFY
ERROR. In program mode a VERIFY ERROR either stops execu-
tion or enters the TRAP error handler, if active.
Example: Using BVERIFY
229
CATALOG
Token: $FE $0C
Format: CATALOG [filepattern] [,R] [,D drive] [,U unit]
Usage: Prints a file catalog/directory of the specified disk.
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 expression in parentheses, e.g. (DI$)
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: The command CATALOG is a synonym for DIRECTORY or DIR
and produces the same listing. The filepattern can be used to
filter the listing. The wildcard characters * and ? may be used.
Adding a ,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.
Example: 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.
230
CHANGE
Token: $FE $2C
Format: CHANGE ”find” TO ”replace” [,from-to]
Usage: Used in direct mode only. It searches the line range if specified
or the whole BASIC program else. At each occurrence of the
”find string” the line is listed and the user prompted for an action:
’Y’ <RETURN> do the change and find next string
’N’ <RETURN> do not change and find next string
’*’ <RETURN> change this and all following matches
<RETURN> exit command, don’t change.
Remarks: Instead of the quote (") each other character may be used as
delimiter for the findstring and replacestring. Using the quote as
delimiter finds text strings, that are not tokenised and therefore
not part of a keyword.
CHANGE "LOOP" TO "OOPS" will not find the BASIC keyword LOOP, because the
keyword is stored as token and not as text. However CHANGE &LOOP&
TO &OOPS& will find and replace it (probably spoiling the program).
Example: Using CHANGE
231
CHAR
Token: $E0
Format: CHAR column, row, height, width, direction, string [, address
of character set]
Usage: Displays text on a graphic screen. It can be used for all resolu-
tions.
column is the start position of the output in horizontal direction.
One column is 8 pixels wide, so a screen width of 320 has a
column range 0 -> 39, while a width of 640 has a range of 0 ->
79.
row is the start position of the output in vertical direction. Other
than column, its unit is pixel with top row having the value 0.
height is a factor applied to the vertical size of the characters.
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.
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 se-
lect a character set different from the default character set at
$29800, which is the set with upper/lower characters.
string is a string constant or expression which will be printed.
Remarks: Control characters, for example: cursor movement codes, will
be ignored (neither printed nor interpreted).
Example: Using CHAR
232
CHR$
Token: $C1
Format: CHR$(numeric expression)
Usage: Returns a string of length one character using the argument to
insert the character having this value as PETSCII code.
Remarks: The argument range is 0 -> 255, so this function may also be
used to insert control codes into strings. Even the NULL charac-
ter, with code 0, is allowed.
CHR$ is the inverse function to ASC.
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
233
CIRCLE
Token: $E2
Format: CIRCLE xcentre, ycentre, radius, [,solid]
Usage: A special case of the ELLIPSE command using the same value
for horizontal and vertical radius.
xcentre x coordinate of centre in pixels.
ycentre y coordinate of centre in pixels.
radius radius of the circle in pixels.
solid will fill the circle if not zero.
Remarks: The CIRCLE command is used to draw circles on screens with an
aspect ratio 1:1 (for example: 320 x 200 or 640 x 400). On
other resolutions (like: 640 x 200) the shape will degrade to an
ellipse.
Example: Using CIRCLE
234
CLOSE
Token: $A0
Format: CLOSE channel
Usage: Closes an input or output channel, that was established before
by an OPEN command.
channel is a value in the range 0 -> 255.
Remarks: Closing open files before the program stops is very important,
especially for output files. This command flushes output buffers
and updates directory information on disks. Failing to CLOSE
can corrupt files and disks. BASIC does NOT automatically close
channels or files when the 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
235
CLR
Token: $9C
Format: CLR
Usage: Resets all pointers, that are used for management of BASIC vari-
ables, arrays and strings. The run-time stack pointers are reset
and the table of open channels is reset. A RUN command per-
forms CLR automatically.
Remarks: CLR should not be used inside loops or subroutines because it
destroys the return address. After a CLR all variables are un-
known and will be initialised at the next usage.
Example: Using CLR
10 A=5: P$="MEGA65"
20 CLR
30 PRINT A;P$
0
READY.
236
CMD
Token: $9D
Format: CMD channel [,string]
Usage: Redirects the standard output from screen to the channel. This
enables to print listings and directories or other screen outputs.
It is also possible to redirect this output to a disk file or a modem.
channel must be opened by the OPEN command.
The optional string is sent to the channel before the redirection
begins and can be used, for example, for printer setup escape
sequences.
Remarks: The CMD mode is stopped by a PRINT# channel or by closing
the channel with CLOSE channel. It is recommended to use a
PRINT# channel before closing, to make sure, that the output
buffer is flushed.
Example: Using CMD to print a program listing:
OPEN 4,4
LIST
PRINT#4
CLOSE 4
237
COLLECT
Token: $F3
Format: COLLECT [,D drive] [,U unit]
Usage: Rebuilds the BAM (Block Availability Map) deleting splat files 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
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: While this command is useful for cleaning the disk from splat files
(for example: write files, that weren’t properly closed) it is dan-
gerous for disks with boot blocks or random access files. These
blocks are not associated with standard disk files and will there-
fore be marked as free too and may be overwritten by further
disk write operations.
Example: Using COLLECT
COLLECT
COLLECT U9
COLLECT D0, U9
238
COLLISION
Token: $FE $17
Format: COLLISION type [,linenumber]
Usage: Enables or disables an user programmed interrupt handler. A
call without linenumber disables the handler, while a call with
linenumber enables it. After the execution of COLLISION with
linenumber a sprite collision of the same type, as specified in
the COLLISION call, interrupts the BASIC program and perform
a GOSUB to linenumber which is expected to contain the user
code for handling sprite collisions. This handler must give control
back with a RETURN.
type specifies the collision type for this interrupt handler:
1 = sprite - sprite collision
2 = sprite - data - collision
3 = light pen
linenumber must point to a subroutine which holds code for
handling sprite collision and ends with a RETURN.
Remarks: It is possible to enable interrupt handler for all types, but only
one can execute at any time. A interrupt handler cannot be
interrupted by another interrupt handler. Functions like BUMP,
RSPPOS and LPEN may be used for evaluation of the sprites
which are involved and their positions.
Example: Using COLLISION
239
COLOR
Token: $E7
Format: COLOR <ON|OFF>
Usage: Enables or disables handling of the character attributes on the
screen. If COLOR is ON, the screen routines take care for both
character RAM and attribute RAM. E.g. if the screen is scrolled
for text, the attributes are scrolled too, so each character keeps
his attribute or colour. If COLOR is OFF, the attribute or colour
RAM is fixed and character movement is only done for screen
characters. This speeds up screen handling, if moving characters
with different colours is not intended.
Example: COLOR ON - with colour/attribute handling
COLOR OFF - no colour/attribute handling
240
CONCAT
Token: $FE $13
Format: CONCAT appendfile [,D drive] TO targetfile [,D drive] [,U
unit]
Usage: The CONCAT (concatenation) appends the contents of ap-
pendfile to the 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 expression in parentheses, for example: (FN$)
targetfile is either a quoted string, for example: ”safe” or a
string expression in parentheses, for example: (FS$)
If the disk unit has dual drives, it is possible to apply the CON-
CAT command to files, which are stored on different disks. In
this case, it is necessary to specify the drive# for both files in
the command. This is necessary too, 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
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: The CONCAT commands is executed in the DOS of the disk
drive. Both files must exist and no pattern matching is allowed.
Only sequential files of type SEQ may be concatenated.
Example: Using CONCAT
241
CONT
Token: $9A
Format: CONT
Usage: Used to resume program execution after a break or stop caused
by an END or STOP statement or by pressing the STOP KEY.
This is a useful debug tool. The BASIC program may be stopped
and variables can be examined and even changed. The CONT
statement then resumes execution.
Remarks: CONT cannot be used, if the program stops due to errors. Also
any editing of the program inhibits continuation. Stopping and
continuation can spoil the screen output or interfere with in-
put/output operations.
Example: Using CONT
10 I=I+1:GOTO 10
RUN
BREAK IN 10
READY.
PRINT I
947
CONT
242
COPY
Token: $F4
Format: COPY source [,D drive] TO target [,D drive] [,U unit]
Usage: Copies the contents of source to the target. It is used to copy
either single files or, by using wildcard characters, multiple files.
source is either a quoted string, e.g. ”data” or a string expres-
sion in parentheses, e.g. (FN$).
target is either a quoted string, e.g. ”backup” or a string ex-
pression in parentheses, e.g. (FS$)
If the disk unit has dual drives, it is possible to copy files from
disk to disk. In this case, it is necessary to specify the drive# for
source and target in the command. This is necessary too, 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
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: The COPY command is executed in the DOS of the disk drive. It
can copy all regular file types (PRG, SEQ, USR, REL). The source
file must exist, the target file must not exist. if source and target
are on the same disk, the target filename must be different from
the source file name.
Example: Using COPY
243
COS
Token: $BE
Format: COS(numeric expression)
Usage: The COS function returns the cosine of the argument. The argu-
ment is expected in units of [radians]. The result is in the range
(-1.0 to +1.0)
Remarks: An argument in units of [degrees] can be converted to [radi-
ans] by multiplication with π/180.
Example: Using COS
PRINT COS(0.7)
.764842187
244
CURSOR
Format: CURSOR [<ON/OFF>] [,column] [,row] [,style]
Usage: Moves the text cursor to the specified position on the current
text screen.
ON or OFF displays or hides the cursor.
column and row specify the new position.
style defines a solid (1) or flashing (0) cursor.
Example: Using CURSOR
245
DATA
Token: $83
Format: DATA [list of constants]
Usage: Used to define constants which can be read by READ statements
somewhere in the program. All type of constants (integer, real,
strings) are allowed, but no expressions. Items are separated by
commas. Strings containing commas, colons or spaces must be
put in quotes.
A RUN command initialises the data pointer to the first item of
the first DATA statement and advances it for every read item. It
is in the responsibility of the programmer, 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.
The RESTORE command may be used to set the data pointer to
a specific line for subsequent readings.
Remarks: It is good programming style to put large amount of DATA state-
ments at the end of the program. Otherwise GOTO and GO-
SUB statements, with target lines lower than the current one,
start their search for linenumber at the beginning of the program
and have to skip through DATA lines wasting time.
Example: Using 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 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
246
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
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: The DOS inside the disk unit will close all open files, clear all
channels, free buffers and reread the BAM. This command should
be used together with a DCLOSE to make sure, that the com-
puter and the drive agree on the status, otherwise strange side
effects may occur.
Example: Using DCLEAR
DCLOSE :DCLEAR
DCLOSE U9:DCLEAR U9
DCLOSE U9:DCLEAR D0, U9
247
DCLOSE
Token: $FE $0F
Format: DCLOSE [#channel] [,U unit]
Usage: Closes a single file or all files for the specified unit.
channel = channel # assigned with the DOPEN statement.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
The DCLOSE command is used either with a channel argument
or a unit number, but never both.
Remarks: It is important to close all open files before the program ends.
Otherwise buffers will not be freed and even worse, open write
files will be incomplete (splat files) and no more usable.
Example: Using DCLOSE
248
DEC
Token: $D1
Format: DEC(string expression)
Usage: Returns the decimal value of the argument, that is written as
a hex string. The argument range is ”0000” to ”FFFF” or 0 to
65535 respectively. The argument must have 1-4 hex digits.
Remarks: Allowed digits in uppercase/graphics mode are:
0123456789ABCDEF and in lowercase/uppercase mode:
0123456789abcdef.
Example: Using DEC
PRINT DEC("D000")
53248
POKE DEC("600"),255
249
DEF FN
Token: $96
Format: DEF FN name(real variable)
Usage: Defines a single statement user function with one argument of
real type returning a real value. The definition must be executed
before the function can be used in expressions. The argument
is a dummy variable, which will be replaced by the argument in
the function usage.
Remarks: The value of the dummy variable will not be changed and the
variable may be used in other context without side effects.
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
250
DELETE
Token: $F7
Format: DELETE [line range]
DELETE filename [,D drive] [,U unit] [,R]
Usage: Used either to delete a range of lines from the BASIC program
or to delete a disk file.
line range consist of the first and the last line to delete or a sin-
gle 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 expression in parentheses, for example: (FS$)
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. 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: The DELETE filename command works like the SCRATCH file-
name command.
Example: Using DELETE
251
DIM
Token: $86
Format: DIM name(limits) [,name(limits)]...
Usage: Declares the shape, the 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 dimensions. 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
declared. The rules for variable names apply for array names
too. There are integer arrays, 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: Integer arrays consume two bytes per element, real arrays five
bytes and string arrays three bytes for the string descriptor plus
the length of the string.
If an array identifier is used without previous declaration, an im-
plicit declaration of an one dimensional array with limit 10 is
performed.
Example: Using DIM
252
DIR
Token: $EE (DIR) $FE $29 (ECTORY)
Format: DIR[ECTORY] [filepattern] [,R] [,D drive] [,U unit]
Usage: Prints a file directory/catalog of the specified disk.
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 expression in parentheses, e.g. (DI$)
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: The command DIR is a synonym for CATALOG or DIRECTORY
and produces the same listing. The filepattern can be used to
filter the listing. The wildcard characters * and ? may be used.
Adding a ,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.
Example: Using DIRECTORY
DIRECTORY
0 "BLACK SMURF " BS 2A
508 "STORY PHOBOS" SEQ
27 "C8096" PRG
25 "C128" PRG
104 BLOCKS FREE.
DIRECTORY "*,T=S"
0 "BLACK SMURF " BS 2A
508 "STORY PHOBOS" SEQ
104 BLOCKS FREE.
253
DISK
Token: $FE $40
Format: DISK command [,U unit]
Usage: Sends a command string to the specified disk unit.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
command is a string expression.
Remarks: The command string is interpreted by the disk unit and must be
compatible to the used DOS version. Read the disk drive manual
for possible commands.
Example: Using DISK
254
DLOAD
Token: $F0
Format: DLOAD filename [,D drive] [,U unit]
Usage: ”Disk LOAD” loads a file of type PRG into memory reserved for
BASIC program source.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$)
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: The load address, stored in the first two bytes of the file is ig-
nored. The program is loaded into the BASIC memory. This en-
ables loading of BASIC programs, that were saved on other com-
puters with different memory configurations. After loading the
program is re-linked and ready to run or edit. It is possible to use
DLOAD in a running program (Called overlay or chaining). Then
the new loaded program replaces the current one and the exe-
cution starts automatically on the first line of the new program.
Variables, arrays and strings from the current run are preserved
and can be used by the new loaded program.
Example: Using DLOAD
DLOAD "APOCALYPSE"
DLOAD "MEGA TOOLS",U9
DLOAD (FN$),U(UN%)
255
DMA
Token: $FE $1F
Format: DMA command [,length, source address, source bank, tar-
get address, target bank, sub]
Usage: The DMA (”Direct Memory Access”) command is the fastest
method to manipulate memory areas using the DMA controller.
command 0 = copy, 1 = mix, 2 = swap, 3 = fill
length = number of 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: The DMA controller has access to the whole 16 MB address
range organised in 256 banks of 64 K.
Example: Using DMA
256
DMODE
Token: $FE $35
Format: DMODE jam,complement,inverse,stencil,style,thick
Usage: ”Display MODE” sets several parameter of the graphical context
for drawing commands.
jam 0 - 1
complement 0 - 1
inverse 0 - 1
stencil 0 - 1
style 0 - 3
thick 1 - 8
257
DO
Token: $EB
Format: DO ... LOOP
DO [ <UNTIL | WHILE> <logical expr.>]
. . . statements [EXIT]
LOOP [ <UNTIL | WHILE> <logical expr.>]
Usage: The DO and LOOP keywords define the start and end of the most
versatile BASIC loop. Using DO and LOOP alone, without any
modifiers creates an infinite loop, that can be left by the EXIT
statement only. The loop can be controlled by adding an UNTIL
or a WHILE statement after the DO or LOOP.
Remarks: DO loops may be nested. An EXIT statement exits the current
loop only.
Example: Using DO and LOOP
10 PW$="":DO
20 GET A$:PW$=PW$+A$
30 LOOP UNTIL LEN(PW$)>7 OR A$=CHR$(13)
258
DOPEN
Token: $FE $0D
Format: DOPEN# lfn, filename [,L[reclen]] [,W] [,D drive] [,U unit]
Usage: Opens a file for reading, writing or modifying.
lfn = logical file number
1 <= lfn <= 127: line terminator is CR
128 <= lfn <= 255: line terminator is CR LF
L indicates, that the file is a relative file, which is opened for
read/write and random access. The reclength is mandatory for
creating relative files. For existing relative files, the reclen is
used as a safety check, if given.
W opens a file for write access. The file must not exist.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$)
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. 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 program files or ”,U” for
USR files.
The usage of the ”save-and-replace” character ’@’ at the begin-
ning of the filename is not recommended, because many Com-
modore disk drives have a bug, that can cause data loss when
using this feature.
259
Example: 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
260
DPAT
Token: $FE $36
Format: DPAT type [,number, pattern, ...]
Usage: ”Drawing PATtern” sets pattern of the graphical context for
drawing commands.
type 0 - 63
number 1 - 4
pattern 0 - 255
261
DSAVE
Token: $EF
Format: DSAVE filename [,D drive] [,U unit]
Usage: ”Disk SAVE” saves a BASIC program to a file of type PRG.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$) 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 dangerous to use this replace option on drives 1541 and
1571, because they contain the notorious ”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
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: The 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
262
DVERIFY
Token: $FE $14
Format: DVERIFY filename [,D drive] [,U unit]
Usage: ”Disk VERIFY” compares a BASIC program in memory with a disk
file of type PRG.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$)
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. 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. The command
exits either with the message OK or with VERIFY ERROR.
Example: Using DVERIFY
DVERIFY "ADVENTURE"
DVERIFY "ZORK-I",U9
DVERIFY "DUNGEON",D1,U10
263
EL
Format: EL is a reserved system variable
Usage: EL has the value of the line, where the latest BASIC error oc-
curred or the value -1 if there was no error.
This variable is typically used in a TRAP routine, where the error
line is taken from EL.
Example: Using EL
10 TRAP 100
264
ELLIPSE
Token: $FE $30
Format: ELLIPSE xcentre, ycentre, xradius, yradius, [,solid]
Usage: As the name says, it draws an ellipse.
xcentre x coordinate of centre in pixels.
ycentre y coordinate of centre in pixels.
xradius x radius of the ellipse in pixels.
yradius y radius of the ellipse in pixels.
solid will fill the ellipse if not zero.
Remarks: The ELLIPSE command is used to draw ellipses on screens with
various resolutions. It can also be used to draw circles.
Example: Using ELLIPSE
265
ELSE
Token: $D5
Format: IF expression THEN true clause ELSE false clause
Usage: The ELSE keyword is part of an IF statement.
expression is a logical or numeric expression. A numerical ex-
pression is evaluated as FALSE if the value is zero and TRUE for
any non zero value.
true clause are one or more statements starting directly after
THEN on the same line. A linenumber after THEN performs a
GOTO to that line.
false clause are one or more statements starting directly af-
ter ELSE on the same line. A linenumber after ELSE performs a
GOTO to that line.
Remarks: The standard IF ... THEN ... ELSE structure is restricted to a single
line. But the true clause or false clause may be expanded to
several lines using a compound statement bracketed with the
keywords BEGIN and BEND.
Example: Using ELSE
266
END
Token: $80
Format: END
Usage: Ends the execution of the BASIC program. The READY. prompt
appears and the computer goes into direct mode waiting for
keyboard input.
Remarks: END does not clear channels or close files. Also variable defi-
nitions are still valid after END. The program may be continued
with the CONT statement. After executing the very last line of
the program END is executed automatically.
Example: Using END
267
ENVELOPE
Token: $FE $0A
Format: ENVELOPE n, [attack,decay,sustain,release, waveform,pw]
Usage: Used to define the parameters for the synthesis of a musical in-
strument.
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 = pulse.
There are 10 slots for storing tunes, preset with following 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
268
ERASE
Token: $FE $2A
Format: ERASE filename [,D drive] [,U unit] [,R]
Usage: Used to erase a disk file.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$)
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. 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 file.
Remarks: The ERASE filename command works like the SCRATCH file-
name command.
The success and the number of erased files can be examined
by printing or using the system variable DS$. The second last
number, which reports the track number in case of an disk error,
now reports the number of successfully erased files.
Example: Using ERASE
269
ER
Format: ER is a reserved system variable
Usage: ER has the value of the latest BASIC error occurred or the value
-1 if there was no error.
This variable is typically used in a TRAP routine, where the error
number is taken from ER.
Example: Using ER
10 TRAP 100
270
ERR$
Token: $D3
Format: ERR$(number)
Usage: Used to convert an error number to an error string.
number is 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
271
EXIT
Token: $FD
Format: EXIT
Usage: Exits the current DO .. LOOP and continues execution at the first
statement after the next LOOP statement.
Remarks: In nested loops EXIT exits only one loop continuing executing in
the next outer loop if there is one.
Example: Using EXIT
10 DO
20 INPUT "ENTER YOUR AGE";AGE%
30 IF AGE% < 18 THEN EXIT
40 INPUT "ENTER YOUR CREDIT CARD #";CR$
50 LOOP UNTIL LEN(CR$) = 12
60 IF AGE% >= 18 THEN GOSUB 1000:REM VALIDATE CREDIT CARD
70 IF AGE% < 18 THEN PRINT "TOO YOUNG":END
272
EXP
Token: $BD
Format: EXP(numeric expression)
Usage: The EXP (EXPonential function) computes the value of the math-
ematical constant Euler’s number e = 2.71828183 raised to the
power of the argument.
Remarks: An argument greater than 88 produces an OVERFLOW ERROR:
Example: Using EXP
PRINT EXP(1)
2.71828183
PRINT EXP(0)
1
PRINT EXP(LOG(2))
2
273
FAST
Token: $FE $25
Format: FAST
Usage: Sets the system speed to maximum (3.58 MHz). The system de-
fault is FAST. However after using SLOW for access to slow de-
vices, FAST can be used to return to fast mode.
Example: Using FAST
10 SLOW
20 GOSUB 1000:REM DO SOME SLOW I/O
30 FAST
274
FILTER
Token: $FE $03
Format: FILTER [freq, lp, bp, hp, res]
Usage: Sets the parameters for sound filter.
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 parameter 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
275
FIND
Token: $FE $2B
Format: FIND ”string” [,from-to]
Usage: FIND is an editor command and can be used in direct mode only.
It searches the line range (if specified) or the whole BASIC pro-
gram else. At each occurrence of the ”find string” the line is
listed with the string highlighted. The <NO-SCROLL> key can be
used to pause the output.
Remarks: Instead of the quote (”) each other character may be used as
delimiter for the find string. Using the quote as delimiter finds
text strings, that are not tokenised and therefore not part of a
keyword.
FIND "LOOP" will not find the BASIC keyword LOOP, because the key-
word is stored as token and not as text. However FIND &LOOP& will
find it.
Example: Using FIND
276
FN
Token: $A5
Format: FN name(numeric expression)
Usage: The FN functions are user defined functions, that accept a nu-
meric expression as argument and return a real value. They must
be defined with DEF FN before the first usage.
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
277
FOR
Token: $81
Format: FOR index=start TO end [STEP step] ... NEXT [index]
Usage: The FOR statement starts the definition of a BASIC loop with an
index variable.
The index variable 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.
The start value is used to initialise the index.
The end value is used at the end of the loop and controls,
whether the next iteration will be started or the loop exited.
The step value defines the change applied to to the index vari-
able at the end of the loop. Positive step values increment it,
while negative values decrement it. It defaults to 1.0 if not spec-
ified.
Remarks: For positive increments end must be greater or equal than start,
for negative increments end must be less or equal than start.
It is bad programming style to change the value of the index
variable inside the loop or to jump into or out of the loop body
with GOTO.
Example: Using FOR
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
278
FOREGROUND
Token: $FE $39
Format: FOREGROUND colour
Usage: Sets the foreground colour (text colour) of the screen to the ar-
gument, which must be in the range 1 to 16. (See colour table).
Example: FOREGROUND 8 - select foreground colour yellow.
Colours: Index and RGB values of colour palette
index red green blue colour
1 0 0 0 black
2 15 15 15 white
3 15 0 0 red
4 0 15 15 cyan
5 15 0 15 magenta
6 0 15 0 green
7 0 0 15 blue
8 15 15 0 yellow
9 15 6 0 orange
10 10 4 0 brown
11 15 7 7 pink
12 5 5 5 dark grey
13 8 8 8 medium grey
14 9 15 9 light green
15 9 9 15 light blue
16 11 11 11 light grey
279
FRE
Token: $B8
Format: FRE(mode)
Usage: Returns the number of free bytes for modes 0 and 1.
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. A usage of FRE(1)
also triggers the ”garbage collection”, a process, that collects
used strings at the top of the bank, thereby defragmenting string
memory.
FRE(2) returns the number of expansion RAM banks, that are
available RAM banks above the standard RAM banks 0 and 1,
that are used by BASIC.
Example: Using FRE:
10 PM = FRE(0)
20 VM = FRE(1)
30 EM = FRE(2)
40 PRINT PM;" FREE FOR PROGRAM"
50 PRINT VM;" FREE FOR VARIABLES"
60 PRINT EM;" EXPANSION RAM BANKS"
280
GET
Token: $A1
Format: GET string variable
Usage: Gets the next character from the keyboard queue. If the queue
is empty an empty string is assigned to the variable, otherwise a
one character string is created and assigned to the string vari-
able. This command does not wait for keyboard input, so it’s
useful to check for key presses in regular intervals or loops.
Remarks: It is syntactically OK to use GET with a numerical variable, but
this is dangerous, because hitting a non numerical key will pro-
duce an error message and stop the program. The command
GETKEY is similar, but waits until a key was hit.
Example: Using GET:
281
GET#
Token: $A1 ’#’
Format: GET# channel, list of string variables
Usage: Reads as many bytes as necessary from the channel argument
and assigns strings of length one to each variable in the list. This
is useful to read characters or bytes from an input stream one
by one.
Remarks: All values from 0 to 255 are valid, so this command can also
be used to read binary data. A value of 0 generates a string of
length 1 containing CHR$(0) as character value.
Example: Using GET#:
282
GETKEY
Token: $A1 $F9 (GET token and KEY token)
Format: GETKEY string variable
Usage: Gets the next character from the keyboard queue. If the queue is
empty the program waits until a key is hit. Then a one character
string is created and assigned to the string variable.
Remarks: It is syntactically OK to use GETKEY with a numerical variable,
but this is dangerous, because hitting a non numerical key will
produce an error message and stop the program.
Example: Using GETKEY:
283
GO64
Token: $CB $36 $34 (GO token and 64 )
Format: GO64
Usage: Switches the computer to the C64 compatible mode. In direct
mode a security prompt ARE YOU SURE? is printed, which must be re-
sponded with ’Y’ to continue. Use SYS58552 to switch back to C65
mode.
Example: Using GO64:
GO64
ARE YOU SURE?
284
GOSUB
Token: $8D
Format: GOSUB line
Usage: The GOSUB (GOto SUBroutine) command 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 resume of the execution after the GOSUB state-
ment, once a RETURN statement in the called subroutine was
executed. Calls to subroutines via GOSUB may be nested but
the end of the subroutine code must always be a RETURN. Oth-
erwise a stack overflow may occur.
Remarks: Unlike other programming languages, this BASIC version does
not support arguments or local variables for subroutines.
Programs can be optimised by grouping subroutines at the be-
ginning of the program source. The GOSUB calls will then have
low line numbers with only few digits to decode. Also the sub-
routines will be found faster, because the search for subroutines
starts very often at the start of the program.
Example: Using GOSUB:
285
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.
The GOTO command written as a single word executes faster
than the GO TO command.
Remarks: The new line number will be searched by scanning the BASIC
source linearly upwards. If the target line number is higher than
the current one, the search starts from the current line upwards.
If the target line number is lower, the search starts from the start
of the program. Knowing this mechanism it is possible to opti-
mise the run-time by grouping often used targets at the start of
the program.
Example: Using GOTO:
286
GRAPHIC
Token: $DE
Format: GRAPHIC CLR
Usage: Initialises the BASIC graphic system. It clears the graphics mem-
ory and screen and sets all parameters of the graphics context
to the default values.
Remarks: A second form of the GRAPHIC command, which serves as an
interface to internal subroutines may be added later.
Example: Using GRAPHIC:
287
HEADER
Token: $F1
Format: HEADER diskname [,Iid] [,D drive] [,U unit]
Usage: Used to format or clear a diskette or disk.
diskname is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (DN$) The maximum length of the
diskname is 16 characters.
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: For new diskettes or disks, which are not already formatted it is
absolutely necessary to specify the disk ID with the parameter
Iid. This switches the format command to the full format, which
writes sector IDs and erases all contents. This will need some
time, because every block on the disk will be written.
If the Iid parameter is omitted, a quick format will be performed.
This is only possible, if the disk is formatted already. A quick
format writes a new disk name and clears the block allocation
map, marking all blocks as free. The disk ID is not changed, the
blocks are not overwritten, so contents may be recovered with
the ERASE R command.
Example: Using HEADER
HEADER "ADVENTURE",IBS
HEADER "ZORK-I",U9
HEADER "DUNGEON",D1,U10
288
HELP
Token: $EA
Format: HELP
Usage: When the BASIC program stops due to an error, type HELP for
further information. The interpreted line is listed, with the erro-
neous statement highlighted or underlined.
Remarks: Displays BASIC errors. For errors in disk I/O one should print the
disk status variable DS or the disk status string DS$.
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
289
HEX$
Token: $D2
Format: HEX$(numeric expression)
Usage: Returns a four character string in hexadecimal notation con-
verted from the argument. The argument must be in the range 0
-> 65535 corresponding to the hex numbers 0000 -> FFFF.
Remarks: If real numbers are used as arguments, the fractional part will
be cut off, not rounded.
Example: Using HEX$:
PRINT HEX$(10),HEX$(100),HEX$(1000.9)
000A 0064 03E8
290
HIGHLIGHT
Token: $FE $3D
Format: HIGHLIGHT colour
Usage: Sets the colour to be used for the ”highlight” text attribute. The
colour index must be in the range 1 to 16. (See colour table).
Remarks: The highlight text attribute is used to mark text in listings gener-
ated by the HELP FIND CHANGE commands.
Example: HIGHLIGHT 8 - select highlight colour yellow.
Colours: Index and RGB values of colour palette
index red green blue colour
1 0 0 0 black
2 15 15 15 white
3 15 0 0 red
4 0 15 15 cyan
5 15 0 15 magenta
6 0 15 0 green
7 0 0 15 blue
8 15 15 0 yellow
9 15 6 0 orange
10 10 4 0 brown
11 15 7 7 pink
12 5 5 5 dark grey
13 8 8 8 medium grey
14 9 15 9 light green
15 9 9 15 light blue
16 11 11 11 light grey
291
IF
Token: $8B
Format: IF expression THEN true clause ELSE false clause
Usage: Starts a conditional execution statement.
expression is a logical or numeric expression. A numerical ex-
pression is evaluated as FALSE if the value is zero and TRUE for
any non zero value.
true clause are one or more statements starting directly after
THEN on the same line. A linenumber after THEN performs a
GOTO to that line.
false clause are one or more statements starting directly af-
ter ELSE on the same line. A linenumber after ELSE performs a
GOTO to that line.
Remarks: The standard IF ... THEN ... ELSE structure is restricted to a single
line. But the true clause or false clause may be expanded to
several lines using a compound statement bracketed with the
keywords BEGIN and BEND.
Example: Using IF
292
INPUT
Token: $85
Format: INPUT [prompt <,|;>] variable list
Usage: Prints an optional prompt string and question mark to the screen,
flashes the cursor and waits for user input from the keyboard.
prompt = string expression to be printed as prompt. It may be
omitted.
If the separator between prompt and variable list is a comma,
the cursor is placed directly after the prompt. If the separator
is a semicolon, a question mark and a space is added to the
prompt.
variable list = list of one or more variables, that receive the
input.
The input will be processed after the user hits RETURN.
Remarks: The user must take care to enter the correct type of input match-
ing variable types. Also the number of input items must match
the number of variables. Entering non numeric characters for
integer or real variables will produce a TYPE MISMATCH ERROR.
Strings for string variables have to be put in quotes if they con-
tain spaces or commas.
Many programs, that need a safe input routine use LINE INPUT
and use an own parser, in order to avoid program breaks by
wrong user input.
Example: Using INPUT:
10 DIM N$(100),A%(100),S$(100):
20 DO
30 INPUT "NAME, AGE, SEX";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 "SEX?":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"
293
INPUT#
Token: $84
Format: INPUT# channel, variable list
Usage: Reads a record from an input device, e.g. a disk file or a RS232
device and assigns the read data to the variables in the list.
channel = channel number assigned by a DOPEN or OPEN com-
mand.
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.
The command LINE INPUT# may be used to read a whole record
into a single string variable.
Example: Using INPUT#:
10 DIM N$(100),A%(100),S$(100):
20 DOPEN#2,"DATA"
30 FOR I=0 TO 100
40 INPUT#2,N$(I),A%(I),S$(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"
294
INSTR
Token: $D4
Format: INSTR(haystack, needle [,start])
Usage: Locates the position of the string expression ”needle” in the string
expression ”haystack” and returns the index of the first occur-
rence or zero, if there is no match.
The string expression haystack is searched for the occurrence
of the string expression needle.
The optional argument start is an integer expression, which de-
fines 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.
Example: Using INSTR:
I = INSTR("ABCDEF","CD") : REM I = 3
I = INSTR("ABCDEF","XY") : REM I = 0
I = INSTR("ABCDEF","E",3) : REM I = 5
I = INSTR("ABCDEF","E",6) : REM I = 0
I = INSTR(A$+B$,C$)
295
INT
Token: $B5
Format: INT(numeric expression)
Usage: Searches the greatest integer value, that is less or equal to the
argument and returns this value as a real number. This function
is NOT limited to the typical 16-bit integer range (-32768 ->
32767), because it uses real arithmetic. The allowed range is
therefore determined by the size of the real mantissas
(32-bit) : (-2147483648 -> 2147483647).
Remarks: It is not necessary to use the INT function for assigning real val-
ues to integer variables, because this conversion will be done
implicitly, but then for the 16-bit range.
Example: Using INT:
296
JOY
Token: $CF
Format: JOY(port)
Usage: Returns the state of the joystick for the selected 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
297
KEY
Token: $F9
Format: KEY [ ON | OFF | number, string]
Usage: The function keys can either send their key code when pressed, or
a string assigned to this key. After power up or reset this feature
is activated and the keys have default assignments.
KEY OFF: switch off function key strings. The keys will send their
character code if pressed.
KEY ON: switch on function key strings. The keys will send as-
signed strings if pressed.
KEY: list current assignments.
KEY number, string assigns the string to the key with that num-
ber.
Default assignments:
key number string
F1 1 "GRAPHIC"
F2 2 "DLOAD"+CHR$(34)
F3 3 "DIRECTORY"+CHR$(13)
F4 4 "SCNCLR"+CHR$(13)
F5 5 "DSAVE"+CHR$(34)
F6 6 "RUN"+CHR$(13)
F7 7 "LIST"+CHR$(13)
F8 8 "MONITOR"+CHR$(13)
HELP 15 "HELP"+CHR$(13)
RUN 16 "RUN"+CHR$(34)+"*"+CHR$(34)+CHR$(13)
Remarks: The sum of the lengths of all assigned strings must not exceed
240 characters. Special characters like RETURN or QUOTE are
entered using their codes with the CHR$(code) function.
Example: Using KEY:
298
LEFT$
Token: $C8
Format: LEFT$(string, n)
Usage: Returns a string containing the first n characters from the argu-
ment 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 LEFT$:
PRINT LEFT$("MEGA-65",4)
MEGA
299
LEN
Token: $C3
Format: LEN(string)
Usage: Returns the length of the string.
string = a string expression
Remarks: There is no terminating character, like the NULL character in C
programs. The length of the string is internally stored in an extra
byte of the string descriptor.
Example: Using LEN:
PRINT LEN("MEGA-65"+CHR$(13))
8
300
LET
Token: $88
Format: LET variable = expression
Usage: The LET statement is obsolete and not needed. Assignment to
variables can be done without using LET.
Example: Using LET:
301
LINE
Token: $E5
Format: LINE xbeg,ybeg [,xend,yend]
Usage: Draws a pixel at (xbeg/ybeg), if only one coordinate pair is
given. If both coordinate pairs are defined, a line is drawn on the
current graphics screen from the coordinate (xbeg/ybeg) to the
coordinate (xend/yend). All currently defined modes and values
of the graphic context are used.
Example: Using LINE:
302
LIST
Token: $9B
Format: LIST [line range]
Usage: Used to list a range of lines from the BASIC program.
line range consist of the first and the last line to list 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.
Remarks: The LIST command’s output can be redirected to other devices
via the CMD command.
Example: Using LIST
303
LOAD
Token: $93
Format: LOAD filename [,U unit [,flag]]
Usage: This command is obsolete in BASIC-10, where the commands
DLOAD and BLOAD are better alternatives.
The LOAD loads a file of type PRG into RAM bank 0, which is also
used for BASIC program source.
filename is either a quoted string, e.g. ”prog” or a string ex-
pression.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
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: This command is implemented in BASIC-10 to keep it backward
compatible to BASIC-2.
Example: Using LOAD
LOAD "APOCALYPSE"
LOAD "MEGA TOOLS",9
LOAD "*",8,1
304
LOCATE
Token: $E6
Format: LOCATE x,y
Usage: Moves the graphical cursor to the specified position on the cur-
rent graphic screen.
Remarks: The graphical cursor is not visible, it’s just the starting point for
follow up graphics commands. The current position can be ex-
amined with the RDOT function.
Example: Using LOCATE
305
LOG
Token: $BC
Format: LOG(numeric expression)
Usage: Computes the value of the natural logarithm of the argument.
The natural logarithm uses Euler’s number e = 2.71828183 as
base, not the number 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).
Example: Using LOG
PRINT LOG(1)
0
PRINT LOG(0)
?ILLEGAL QUANTITY ERROR
PRINT LOG(4)
1.38629436
306
LOOP
Token: $EC
Format: DO ... LOOP
DO [ <UNTIL | WHILE> <logical expr.>]
. . . statements [EXIT]
LOOP [ <UNTIL | WHILE> <logical expr.>]
Usage: The DO and LOOP keywords define the start and end of the most
versatile BASIC loop. Using DO and LOOP alone, without any
modifiers creates an infinite loop, that can be left by the EXIT
statement only. The loop can be controlled by adding an UNTIL
or a WHILE statement after the DO or LOOP.
Remarks: DO loops may be nested. An EXIT statement exits the current
loop only.
Example: Using DO and LOOP
10 PW$="":DO
20 GET A$:PW$=PW$+A$
30 LOOP UNTIL LEN(PW$)>7 OR A$=CHR$(13)
307
LPEN
Token: $CE $04
Format: LPEN(coordinate)
Usage: This function requires the use of a CRT monitor or TV and a light
pen. It will not work with a 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, LPEN(0) returns therefore only even
numbers. A bright background colour is needed to trigger the
light pen. The COLLISION statement may be used to install an
interrupt handler.
Example: Using LPEN
308
MID$
Token: $CA
Format: variable$ = MID$(string, index, n)
MID$(string, index, n) = string expression
Usage: MID$ can be used either as a function, which returns a string or
as a statement for inserting sub-strings into an existing string.
string = a string expression
index = start index (0 -> 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
309
MOD
Token: $NN
Format: MOD(dividend,divisor)
Usage: The MOD function returns the remainder of the division.
Remarks: In other programming languages, like C, this function is imple-
mented as an operator. Here it is used as function.
Example: Using MOD:
310
MONITOR
Token: $FA
Format: MONITOR
Usage: Calls the machine language monitor program, which is mainly
used for debugging.
Remarks: Using the MONITOR requires knowledge of the CSG4510 /
6502 / 6510 CPU and the assembler language.
Example: Using MONITOR:
MONITOR
311
MOUSE
Token: $FE $3E
Format: MOUSE ON [,port [,sprite [,pos]]]
MOUSE OFF
Usage: Enables the mouse driver and connects the mouse at the speci-
fied port with the mouse pointer sprite.
port = mouse port 1, 2 (default) or 3 (both).
sprite = sprite number for mouse pointer (default 0).
pos = initial mouse position (x,y).
The MOUSE OFF command disables the mouse driver and frees
the associated sprite.
Remarks: The ”hot spot” of the mouse pointer is the upper left pixel of the
sprite.
Example: Using MOUSE:
312
MOVSPR
Token: $FE $06
Format: MOVSPR sprite, x, y
MOVSPR sprite, <+|->xrel, <+|->yrel
MOVSPR sprite, angle # speed
Usage: MOVSPR performs, depending on the argument format, three
different tasks:
The first form MOVSPR sprite, x, y uses no signs for the argu-
ments and sets the absolute position of the sprite to the screen
pixel coordinates x and y.
The second form MOVSPR sprite, <+|->xrel, <+|->yrel uses signs
’+’ or ’-’ to indicate a relative displacement to the current posi-
tion.
The third form MOVSPR sprite, angle # speed does not set the
position of sprite n, but defines motion parameters. The format
is recognised by putting a hash sign ’#’ between the last two
arguments.
sprite = sprite number
x = absolute screen coordinate [pixel].
y = absolute screen coordinate [pixel].
xrel = relative screen coordinate [pixel].
yrel = relative screen coordinate [pixel].
angle = direction for sprite movement [degrees]. 0 = up, 90 =
right, 180 = down, 270 = left.
speed = speed of movement (0 -> 15).
Remarks: The ”hot spot” is the upper left pixel of the sprite.
Example: Using MOVSPR:
313
NEW
Token: $A2
Format: NEW
NEW RESTORE
Usage: Resets all BASIC parameters to their default values. After NEW
the maximum RAM is available for program and data storage.
Because NEW resets parameters and pointers, but does not
physically overwrite the address range of a BASIC program, that
was in memory before NEW, it is possible to recover the program.
If there were no LOAD operations or editing after the NEW com-
mand, the program can be restored with the command
NEW RESTORE.
Example: Using NEW:
314
NEXT
Token: $82
Format: FOR index=start TO end [STEP step] ... NEXT [index]
Usage: Terminates the definition of a BASIC loop with an index variable.
The index variable may be incremented or decremented by a
constant value step on each iteration. The default is to incre-
ment the variable by 1. The index variable must be a real vari-
able.
The start value is used to initialise the index.
The end value is used at the end of the loop and controls,
whether the next iteration will be started or the loop exited.
The step value defines the change applied to to the index vari-
able at the end of the loop. Positive step values increment it,
while negative values decrement it. It defaults to 1.0 if not spec-
ified.
Remarks: The index variable after NEXT is optional. If it is missing, 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 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
315
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. Real operands are con-
verted to a signed 16 bit integer. Logical operands are con-
verted to 16 bit integer using $FFFF, decimal -1 for TRUE and
$0000, decimal 0, for FALSE.
NOT 0 -> 1
NOT 1 -> 0
PRINT NOT 3
-4
PRINT NOT 64
-65
316
OFF
Token: $FE $24
Format: keyword OFF
Usage: OFF is a secondary keyword used in combination with primary
keywords like COLOR, KEY, MOUSE.
Remarks: The keyword OFF cannot be used on its own.
Example: Using OFF
317
ON
Token: $91
Format: ON expression GOSUB line list
ON expression GOTO line list
keyword ON
Usage: The ON keyword starts either a computed GOSUB or GOTO
statement. Dependent on the value of the expression, the tar-
get for the GOSUB or GOTO is chosen from the table of line
addresses at the end of the statement.
As a secondary keyword, ON is used in combination with primary
keywords like COLOR, KEY, MOUSE.
expression is a positive numeric value. Real values are cut to
integer.
line list is a comma separated list of valid line numbers.
Remarks: Negative values for expression will stop the program with an
error message. The line list specifies the targets for values of
1,2,3,...
An expression value of zero or a value, that is greater than the
number of target lines will do nothing and continue program ex-
ecution with the next statement.
318
Example: Using ON
319
OPEN
Token: $9F
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 special values for IEC disk
units, 0:load, 1:save, 15:command channel. The values 2 -> 14
may be used for disk files.
320
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"
321
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 con-
verted to a signed 16-bit integer. Logical operands are con-
verted to 16-bit integer using $FFFF, decimal -1 for TRUE and
$0000, decimal 0, for FALSE.
0 OR 0 -> 0
0 OR 1 -> 1
1 OR 0 -> 1
1 OR 1 -> 1
PRINT 1 OR 3
3
PRINT 128 OR 64
192
322
PAINT
Token: $DF
Format: PAINT x, y, mode [,colour]
Usage: Performs a flood fill of an enclosed graphics area.
x, y is a coordinate pair, which must lie inside the area to be
filled.
mode specifies the fill mode.
0: use the colour to fill the area.
1: use the colour of pixel (x,y) to fill the area.
Example: Using PAINT
323
PALETTE
Token: $FE $34
Format: PALETTE [screen|COLOR], colour, red, green, blue
PALETTE RESTORE
Usage: The PALETTE command 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 val-
ues.
screen = screen number (0 or 1).
COLOR = keyword for changing system palette.
colour = index to palette 0 -> 255.
red = red intensity 0 -> 15.
green = green intensity 0 -> 15.
blue = blue intensity 0 -> 15.
Example: Using PALETTE
324
PEEK
Token: $C2
Format: PEEK(address)
Usage: Returns a byte value read from the 16 bit address and the cur-
rent memory bank (set by BANK).
address = a value 0 -> 65535.
Remarks: Banks 0 -> 127 give access to RAM or ROM banks. Banks > 127
are used to access I/O and SYSTEM like VIC, SID, FDC, etc.
Example: Using PEEK
325
PEN
Token: $FE $33
Format: PEN pen colour
Usage: Sets the colour for the graphic pen.
pen = pen number ( 0 -> 2 )
colour = palette index.
Remarks: PEN defined colours are used by all following drawing com-
mands.
Example: Using PEN
326
PLAY
Token: $FE $04
Format: PLAY string
Usage: Starts playing a tune with notes and directives embedded in the
argument string.
A musical note is a letter (A,B,C,D,E,F,G) which may be preceded
by an optional modifier.
Possible modifiers are:
char effect
# sharp
$ flat
. dotted
H half note
I eighth note
M wait for end
Q quarter note
R pause (rest)
S sixteenth note
W whole note
Embedded directives consist of a letter followed by a digit:
char directive argument range
O octave 0 - 6
T tune envelope 0 - 9
U volume 0 - 9
V voice 1 - 3
X filter 0 - 1
327
The envelope slots may be changed using the ENVELOPE state-
ment. The default setting for the envelopes are:
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
Remarks: The PLAY statement sets up an interrupt driven routine that starts
parsing the string and playing the tune. The execution continues
with the next statement with no need waiting for the tune to be
finished. However this can be forced, using the ’M’ modifier.
Example: Using PLAY
10 ENVELOPE 9,10,5,10,5,2,4000
20 PLAY "T9"
30 VOL 8
40 TEMPO 100
50 PLAY "C D E F G A B"
60 PLAY "U5 V1 C D E F G A B"
328
POINTER
Token: $CE $0A
Format: POINTER(variable)
Usage: Returns the current address of a variable or an array element
in bank 1. For string variables, it is the address of the string
descriptor, not the string itself. The string descriptor consists of
the three bytes (length,string address low, string address high).
Remarks: The address values of arrays and their elements change for every
new declaration (first usage) of scalar variables.
The addresses of strings (not their descriptors) may change at
any time due to ”garbage collection” in memory management.
Example: Using POINTER
329
POKE
Token: $97
Format: POKE address, byte [,byte ...]
Usage: Puts on or more bytes into memory or memory mapped I/O, start-
ing at 16-bit address. The current memory bank as set by BANK
is used.
address = a value 0 -> 65535.
byte = a value 0 -> 255.
Remarks: The address is increased by one for each data byte, so a memory
range may be filled with a single command.
Banks > 127 are used to access I/O and SYSTEM like VIC, SID,
FDC, etc.
Example: Using POKE
330
POLYGON
Token: $FE $2F
Format: POLYGON x, y, xrad, yrad, solid, angle, sides, n
Usage: 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.
solid = fill (1) or outline (0).
angle = start angle.
sides = sides to draw (<= n).
n = number of sides or edges.
Remarks: A regular polygon is both isogonal and isotoxal, meaning all sides
and angles are alike.
Example: Using POLYGON
POLYGON 320,100,50,50,0,0,6,6
331
POS
Token: $B9
Format: POS(dummy)
Usage: 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
332
POT
Token: $CE $02
Format: POT(paddle)
Usage: Returns the position of a paddle.
paddle = paddle number 1 -> 4.
The low byte of the return value is the paddle value with 0 at the
clockwise limit and 255 at the counterclockwise limit.
A value > 255 indicates the simultaneous press of the fire button.
Remarks: Analogue paddles are noisy and inexact. The range may be less
than 0 - 255 and there is some jitter in the data.
Example: Using POT
333
PRINT
Token: $99
Format: PRINT arguments
Usage: Evaluates the argument list and prints the values formatted to
the current screen window. Standard formatting is used depen-
dent on the argument type. For user controlled formatting see
PRINT USING. Following argument types are processed:
numeric : The printout starts with a space for positive and zero
values or a minus sign for negative values. Integer values are
printed with the necessary number of digits. Real values are
printed either in fixed point format with typically 9 digits or in
scientific format, if the value is outside the range of 0.01 ->
999999999.
string : The string may consist of printable characters and con-
trol codes. Printable characters are printed to the cursor posi-
tion, while control codes are executed.
, : A comma acts like a tabulator.
; : A semicolon acts as a separator between arguments of the
list. Other than the comma character it does not put in any ad-
ditional characters. A semicolon at the end of the argument list
suppresses the automatic return character.
Remarks: The SPC and TAB functions may be used in the argument list for
positioning. The CMD command can be used for redirection.
Example: Using PRINT
334
PRINT#
Token: $98
Format: PRINT# channel, arguments
Usage: Evaluates the argument list and prints the values formatted to
the device assigned to channel. Standard formatting is used
dependent on the argument type. For user controlled formatting
see PRINT# USING. Following argument types are processed:
channel : must be opened for output by an OPEN or DOPEN
statement.
numeric : The printout starts with a space for positive and zero
values or a minus sign for negative values. Integer values are
printed with the necessary number of digits. Real values are
printed either in fixed point format with typically 9 digits or in
scientific format, if the value is outside the range of 0.01 ->
999999999.
string : The string may consist of printable characters and con-
trol codes. Printable characters are printed to the cursor posi-
tion, while control codes are executed.
, : A comma acts like a tabulator.
; : A semicolon acts as a separator between arguments of the
list. Other than the comma character it does not put in any ad-
ditional characters. A semicolon at the end of the argument list
suppresses the automatic return character.
Remarks: The SPC and TAB functions are not suitable for devices other
than the screen.
Example: Using PRINT#
10 DOPEN#2,"TABLE",W,U9
20 FOR I=1 TO 10 : REM START LOOP
30 PRINT#2,I,I*I,SQR(I)
40 NEXT
50 DCLOSE#2
335
PRINT USING
Token: $98 $FB or $99 $FB
Format: PRINT [# channel,] USING, format, arguments
Usage: Parses the format string and evaluates the argument list. The
values are printed following the directives of the format string.
channel : must be opened for output by an OPEN or DOPEN
statement. If no channel is specified, the output goes to the
screen.
format : A string which defines the rules for formatting.
numeric argument : The ’#’ characters set the position and with
of the output string.
’+’ or ’-’ set the sign option.
’.’ sets the position of the decimal point.
’,’ can be inserted into large numbers.
’$’ sets the position of the currency symbol.
^^^^ reserves place for the exponent.
string argument : The string may consist of printable characters
and control codes. Printable characters are printed to the cursor
position, while control codes are executed. The number of ’#’
characters sets the width of the output, a ’=’ sign centres and a
’>’ character right justifies the output.
, : A comma acts like a tabulator. ; : A semicolon acts as a sep-
arator between arguments of the list. Other than the comma
character it does not put in any additional characters. A semi-
colon at the end of the argument list suppresses the automatic
return character.
Remarks: The SPC and TAB functions may be used for screen output.
336
Example: Using PRINT# USING
10 X = 12.34: A$ = "MEGA65"
30 PRINT USING "###.##"; X : REM "12.34"
40 PRINT USING "###"; X : REM " 12"
50 PRINT USING "####"; A$ : REM "MEGA"
60 PRINT USING "#########"; A$ : REM "MEGA65 "
70 PRINT USING "=########"; A$ : REM " MEGA65 "
80 PRINT USING "#######>#"; A$ : REM " MEGA65"
337
PUDEF
Token: $DD
Format: PUDEF string
Usage: Redefines up to four special characters, that are used in the
PRINT USING routine.
string = definition string (max. 4 characters).
1st.: fill character
2nd.: comma separator
3rd.: decimal point
4th.: currency symbol
The system default is " ,.$"
The new definition string overrides the system default and is of-
ten used for localisation. A string ” .,” would change the punc-
tuation to German style.
It is not necessary to redefine all four characters. Any length
between 1 and 4 is allowed.
Remarks: PUDEF changes the output of PRINT USING only. PRINT and
PRINT# are not affected. The control characters of the format
string cannot be changed.
Example: Using PUDEF
10 X = 123456.78
20 PUDEF " .,"
30 PRINT USING "###,###.#"; X : REM 123.456,8
338
RCLR
Token: $CD
Format: RCLR(colour source)
Usage: Returns the current colour index for the selected colour source.
Colour sources are:
0: 40 column background
1: graphical foreground
2: multi-colour mode 1
3: multi-colour mode 2
4: frame colour
5: 80 column text
6: 80 column background
Example: Using RCLR
339
RDOT
Token: $D0
Format: RDOT(n)
Usage: Returns information about the graphical cursor.
n = kind of information.
0: x-position
1: y-position
2: colour index
Example: Using RDOT
10 X = RDOT(0)
20 Y = RDOT(1)
30 C = RDOT(2)
40 PRINT "THE COLOUR INDEX AT (";X;"/";Y;") IS:";C
340
READ
Token: $87
Format: READ variable list
Usage: Reads values from program source into variables.
variable list = any legal variables.
All type of constants (integer, real, strings) can be read, but no
expressions. Items are separated by commas. Strings containing
commas, colons or spaces must be put in quotes.
A RUN command initialises the data pointer to the first item of
the first DATA statement and advances it for every read item. It
is in the responsibility of the programmer, 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.
The RESTORE command may be used to set the data pointer to
a specific line for subsequent readings.
Remarks: It is good programming style to put large amount of DATA state-
ments at the end of the program. Otherwise GOTO and GO-
SUB statements, with target lines lower than the current one,
start their search for linenumber at the beginning of the program
and have to skip through DATA lines wasting time.
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
341
RECORD
Token: $FE $12
Format: RECORD#lfn, record, [,byte]
Usage: Positions the read/write pointer of a relative file.
lfn = logical file number
record = target record ( 1 -> 65535 ).
byte = byte position in record.
This command can be used only for files of type REL, which are
relative files capable of direct access.
The RECORD command positions the file pointer to the specified
record number. If this record number does not exist and the disk
capacity is high enough, the file is expanded to this record count
by adding empty records. This is not an error, but the disk status
will give the message RECORD NOT PRESENT.
Any INPUT# or PRINT# command will then proceed on the se-
lected record position.
Remarks: The original Commodore disk drives all had a bug in their DOS,
which could destroy data by using relative files. A recommended
workaround was to issue each RECORD command twice, before
and after the I/O operation.
Example: Using RECORD
342
REM
Token: $8F
Format: REM
Usage: Marks the rest of the line as comment.
All characters after REM are never executed but skipped.
Example: Using REM
343
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 parentheses, e.g. (FN$).
new is either a quoted string, e.g. ”backup” or a string expres-
sion in parentheses, e.g. (FS$)
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: The RENAME command is executed in the DOS of the disk drive.
It can rename all regular file types (PRG, SEQ, USR, REL). The old
file must exist, the new file must not exist. Only single files can
be renamed, wild characters like ’*’ and ’?’ are not allowed. The
file type cannot be changed.
Example: Using RENAME
344
RENUMBER
Token: $F8
Format: RENUMBER [new, inc, old]
Usage: Used to renumber all or a range of lines of a BASIC program.
new is the new starting line of the line range to renumber. The
default value is 10.
inc is the increment to be used. The default value is 10.
old is the old starting line of the line range to renumber. The
default value is the first line.
The RENUMBER changes all line numbers in the chosen range
and also changes all references from statements like GOTO,
GOSUB, TRAP, RESTORE, RUN etc.
RENUMBER can be executed in direct mode only. If it detects
a problem, like memory overflow, unresolved references or line
number overflow (greater than 64000) it will stop with an error
message and leave the program unchanged.
The command may be called with 0-3 parameters. Unspecified
parameters use their default values.
Remarks: The RENUMBER command may need several minutes to execute
for large programs.
Example: Using RENUMBER
345
RESTORE
Token: $8C
Format: RESTORE [line]
Usage: Set or reset the internal pointer for READ from DATA statements.
line is the new position for the pointer to point at. The default
is the first program line.
Remarks: The new pointer target line needs not to contain DATA state-
ments. Every READ will automatically advance the pointer to
the next DATA statement.
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$
346
RESUME
Token: $D6
Format: RESUME [line | NEXT]
Usage: is used inside a TRAP routine to resume normal program execu-
tion after handling the exception.
line : program execution resumes at the given line number.
NEXT : the keyword NEXT resumes execution at the statement
following the statement, that caused the error.
RESUME with no parameters tries to re-execute the statement,
that caused the error. The TRAP routine should have examined
and corrected the variables in this case.
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
347
RETURN
Token: $8E
Format: RETURN
Usage: Returns control from a subroutine, which 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 to call the handler.
Example: Using RETURN
10 DOPEN#2,"DATA":GOSUB 100
20 FOR I=1 TO 100
30 INPUT#2,A$:GOSUB 100
40 PRINT A$
50 NEXT
60 DCLOSE#2
70 END
100 IF DS THEN PRINT DS$:STOP :REM DISK ERROR
110 RETURN :REM OK
348
RGR
Token: $CC
Format: RGR(dummy)
Usage: Returns information about the graphic mode.
dummy = unused numeric expression.
In text mode RGR returns zero. in graphics mode RGR returns a
non zero value.
Example: Using RGR
10 M = RGR(0)
20 IF M THEN CHAR 0,0,1,1,2,"TITLE": ELSE PRINT "TITLE"
349
RIGHT$
Token: $C9
Format: RIGHT$(string, n)
Usage: Returns a string containing the last n characters from the argu-
ment 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
350
RMOUSE
Token: $FE $3F
Format: RMOUSE xvar, yvar, butvar
Usage: Reads mouse position and button status.
xvar = numerical variable receiving x-position.
yvar = numerical variable receiving y-position.
butvar = numerical variable receiving button status.
left button sets bit 7, while right button sets bit 0.
value status
0 no button
1 right button
128 left button
129 both buttons
The command puts a -1 into all variables, if the mouse is not
connected or disabled.
Remarks: Two active mice on both ports merge the results.
Example: Using RMOUSE:
351
RND
Token: $BB
Format: RND(type)
Usage: Returns a pseudo random number
This is called a ”pseudo” random number, because the num-
bers are not really random, but are derived from another number
called ”seed” and generate reproducible sequences. The type
argument determines, which seed is used.
type = 0: use system clock.
type < 0: use the value of type as seed.
type > 0: derive value from previous random number.
Remarks: Seeded random number sequences produce the same sequence
for identical seeds.
Example: Using RND:
352
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 = variable gets accumulator value.
xreg = variable gets X register value.
yreg = variable gets Y register value.
zreg = variable gets Z register value.
sreg = variable gets status register value.
Remarks: The register values after a SYS call are stored in system memory.
This enables the command RREG to retrieve these values.
Example: Using RREG:
10 BANK 128
20 BLOAD "ML PROG",8192
30 SYS 8192
40 RREG A,X,Y,Z,S
50 PRINT "REGISTER:";A;X;Y;Z;S
353
RSPCOLOR
Token: $CE $07
Format: RSPCOLOR(n)
Usage: Returns multi-colour sprite colours.
n = 1 : get multi-colour # 1.
n = 2 : get multi-colour # 2.
Remarks: See also SPRITE and SPRCOLOR.
Example: Using RSPCOLOR:
354
RSPPOS
Token: $CE $05
Format: RSPPOS(sprite,n)
Usage: Returns sprite’s position and speed
sprite : sprite number.
n = 0 : get X position.
n = 1 : get Y position.
n = 2 : get speed.
Remarks: See also SPRITE and MOVSPR.
Example: Using RSPPOS:
355
RSPRITE
Token: $CE $06
Format: RSPRITE(sprite,n)
Usage: Returns sprite’s parameter.
sprite : sprite number (0 -> 7)
n = 0 : turned on (0 or 1).
n = 1 : foreground colour (0 -> 15)
n = 2 : background priority (0 or 1).
n = 3 : X-expanded (0 or 1).
n = 4 : Y-expanded (0 or 1).
n = 5 : multi-colour (0 or 1).
Remarks: See also SPRITE and MOVSPR.
Example: Using RSPRITE:
356
RUN
Token: $8A
Format: RUN [line number]
RUN filename [,D drive] [,U unit]
Usage: Run a BASIC program.
If a filename is given, the program file is loaded into memory,
otherwise the program that is currently in memory is used.
line number an existing line number of the program in memory.
filename is either a quoted string, e.g. ”prog” or a string ex-
pression in parentheses, 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
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
RUN resets first all internal pointers to their starting values.
Therefore there are no variables, arrays and strings defined, the
run-time stack is reset and the table of open files is cleared.
Remarks: In order to start or continue program execution without resetting
everything, use the GOTO command.
Example: Using RUN
357
SAVE
Token: $94
Format: SAVE filename [,unit]
Usage: ”Saves a BASIC program to a file of type PRG.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$) 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 dangerous to use this replace
option on drives 1541 and 1571, because they contain the no-
torious ”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 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: This is an obsolete command, implemented only for compatibility
to older BASIC dialects. The command DSAVE should be used
instead.
Example: Using SAVE
SAVE "ADVENTURE"
SAVE "ZORK-I",8
SAVE "1:DUNGEON",9
358
SCNCLR
Token: $E8
Format: SCNCLR [colour]
Usage: Clears a text window or 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 it with the
colour.
Example: Using SCNCLR:
359
SCRATCH
Token: $F2
Format: SCRATCH filename [,D drive] [,U unit] [,R]
Usage: Used to erase a disk file.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$)
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. 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 file.
Remarks: The SCRATCH filename command works like the ERASE file-
name command.
The success and the number of erased files can be examined
by printing or using the system variable DS$. The second last
number, which reports the track number in case of an disk error,
now reports the number of successfully erased files.
Example: Using SCRATCH
360
SCREEN
Token: $FE $2E
Format: SCREEN CLR
SCREEN DEF
SCREEN SET
SCREEN OPEN screen [,errvar]
SCREEN CLOSE screen
Usage: SCREEN performs one of five actions, selected by the secondary
keyword after it.
SCREEN CLR colour clear graphics screen by filling it with
colour.
SCREEN DEF screen, width, height, depth defines resolution
parameters for the chosen screen.
SCREEN SET draw view sets screen numbers ( 0 or 1 ) for the
drawing and the viewing screen.
SCREEN OPEN screen allocates resources and initialises the
graphic context for the selected screen ( 0 or 1). An optional
variable name as a further argument, gets the result of the com-
mand and can be tested afterwards for success.
SCREEN CLOSE screen closes screen ( 0 or 1 ) and frees re-
sources.
Remarks: The SCREEN command cannot be used alone. It must always be
used together with a secondary keyword.
Example: Using SCREEN:
361
SET
Token: $FE $2D
Format: SET DEF unit
SET DISK old to new
Usage: SET DEF unit 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 old to new is used to change the unit number of a disk
drive temporarily.
Remarks: These settings are valid until a reset or shutdown.
Example: Using SET:
362
SGN
Token: $B4
Format: SGN(numeric expression)
Usage: The SGN function extracts the sign from the argument and re-
turns it as a number:
-1 for a negative argument
0 for a zero
1 for a positive, non zero argument
Example: Using SGN
363
SIN
Token: $BE
Format: SIN(numeric expression)
Usage: The SIN function returns the sine of the argument. The argument
is expected in units of [radians]. The result is in the range (-1.0
to +1.0)
Remarks: An argument in units of [degrees] can be converted to [radi-
ans] by multiplication with π/180.
Example: Using SIN
PRINT SIN(0.7)
.644217687
364
SLEEP
Token: $FE $0B
Format: SLEEP seconds
Usage: The SLEEP commands pauses the execution for the given dura-
tion ( 1 - 65535).
Example: Using SLEEP
365
SLOW
Token: $FE $26
Format: SLOW
Usage: Slow down system clock to 1 MHz.
Example: Using SLOW
366
SOUND
Token: $DA
Format: SOUND voice, freq, dur [,dir ,min, sweep, wave, pulse]
Usage: plays a sound effect.
voice = voice number ( 1 -> 6 ).
freq = frequency ( 0 -> 65535 ).
dur = duration ( 0 -> 32767) .
dir = direction (0:up, 1:down, 2:oscillate).
min = minimum frequency ( 0 -> 65535 ).
sweep = sweep range ( 0 -> 65535 ).
wave = waveform (0:triangle, 1:saw, 2:square, 3:noise).
pulse = pulse width ( 0 -> 5095 ).
For details on sound programming, read the SOUND chapter.
Remarks: The SOUND command starts playing the sound effect and im-
mediately continues with the execution of the next BASIC state-
ment, while the sound effect is played. This enables showing
graphics or text and playing sounds simultaneously.
Example: Using SOUND
367
SPC
Token: $A6
Format: SPC(columns)
Usage: The SPC function skips columns.
The effect is like printing column times a cursor right charac-
ter.
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
368
SPRCOLOR
Token: $FE $08
Format: SPRCOLOR [mc1] [,mc2]
Usage: Sets multi-colour sprite colours.
The SPRITE command, which sets the attributes of a sprite, sets
only the foreground colour. For the setting of the additional two
colours, of multi-colour sprites, SPRCOLOR has to be used.
Remarks: See also SPRITE.
Example: Using SPRCOLOR:
369
SPRITE
Token: $FE $07
Format: SPRITE no [switch, colour, prio, expx, expy, mode]
Usage: Switches a sprite on or off and sets its attributes.
no = sprite number
switch = 1:ON, 0:OFF
colour = sprite foreground colour
prio = sprite(1) or screen(0) priority
expx = 1:sprite X expansion
expy = 1:sprite Y expansion
mode = 1:multi colour sprite
Remarks: The command SPRCOLOR must be used to set additional colours
for multi colour sprites (mode = 1)
Example: Using SPRITE:
370
SPRSAV
Token: $FE $16
Format: SPRSAV source, destination
Usage: Copies sprite data.
source = sprite number or string variable.
destination = sprite number or string variable.
Remarks: Both, source and destination can be either a sprite number or a
string variable. But they must not be both a string variable. A
simple string assignment can be used for such cases.
Example: Using SPRSAV:
371
SQR
Token: $BA
Format: SQR(numeric expression)
Usage: The SQR function returns the square root of the argument.
Remarks: The argument must not be negative.
Example: Using SQR
PRINT SQR(2)
1.41421356
372
STEP
Token: $A9
Format: FOR index=start TO end [STEP step] ... NEXT [index]
Usage: The STEP keyword is an optional part of a FOR loop.
The index variable 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.
The start value is used to initialise the index.
The end value is used at the end of the loop and controls,
whether the next iteration will be started or the loop exited.
The step value defines the change applied to to the index vari-
able at the end of the loop. Positive step values increment it,
while negative values decrement it. It defaults to 1.0 if not spec-
ified.
Remarks: For positive increments end must be greater or equal than start,
for negative increments end must be less or equal than start.
It is bad programming style to change the value of the index
variable inside the loop or to jump into or out of the loop body
with GOTO.
Example: Using STEP
373
STOP
Token: $90
Format: STOP
Usage: Stops the execution of the BASIC program. A message tells the
line number of the break. The READY. prompt appears and the
computer goes into direct mode waiting for keyboard input. The
program execution can be resumed with the command CONT.
Remarks: All variable definitions are still valid after STOP. They may be
inspected or altered and the program may be continued with the
CONT statement. Every editing of the program source makes
continuation impossible, however.
Example: Using STOP
374
STR$
Token: $C4
Format: STR$(numeric expression)
Usage: Returns a string containing the formatted value of the argument,
as if it were printed to the string.
Example: Using STR$:
375
SYS
Token: $9E
Format: SYS address [, areg, xreg, yreg, zreg, sreg]
Usage: Calls a machine language subroutine. This can be a ROM resi-
dent kernel or BASIC subroutine or a routine in RAM, which was
loaded or poked to RAM before.
The CPU registers are loaded with the arguments, if specified.
Then a subroutine call JSR address is performed. The called
routine should exit with a RTS instruction. Then the register con-
tents will be saved and the execution of the BASIC program con-
tinues.
address = start address of the subroutine.
areg = variable gets accumulator value.
xreg = variable gets X register value.
yreg = variable gets Y register value.
zreg = variable gets Z register value.
sreg = variable gets status register value.
The SYS command uses the current bank as set with the BANK
command.
Remarks: The register values after a SYS call are stored in system memory.
This enables the command RREG to retrieve these values.
Remarks: The system leaves the memory setup in a somewhat strange
state, which may or may not be a bug in BASIC 10. If you want
to write an assembly routine that can access an entire memory
bank, but with IO mapped, you need to set the CPU register $01,
like on the C64, and then also use the 4510’s MAP instruction
to set the memory map. For BANK 0, you could use the following
sequence:
376
; Disable interrupts, because the C65 ROM won't be visible to
; handle them.
SEI
; Make IO visible
LDA #$37
STA $01
; Prepare for MAP operation that resets memory map to BANK 0
LDA #$00
TAX
TAY
TAZ
MAP
; End MAPing sequence
NOP
; Now comes your routine!
loop:
INC $D020
JMP loop
Remarks: You can alternatively use BANK 128, and place your routine in
the lower-half of RAM, e.g., in the unallocated memory area at
$1600 – $1FFF
Remarks: The RREG command can be useful for reading the register values
when your routine completes.
Example: Using SYS:
10 BANK 128
20 BLOAD "ML PROG",8192
30 SYS 8192
40 RREG A,X,Y,Z,S
50 PRINT "REGISTER:";A;X;Y;Z;S
377
TAB
Token: $A3
Format: TAB(column)
Usage: Positions the cursor at column.
This is only done, if the target column is right of the current cursor
column, otherwise nothing happens. The column count starts
with 0 for the left most column.
Remarks: This function must not be confused with the TAB key, which ad-
vances the cursor 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 *
378
TAN
Token: $C0
Format: TAN(numeric expression)
Usage: Returns the tangent of the argument. The argument is expected
in units of [radians].
Remarks: An argument in units of [degrees] can be converted to [radi-
ans] by multiplication with π/180.
Example: Using TAN
PRINT TAN(0.7)
.84228838
379
TEMPO
Token: $FE $05
Format: TEMPO speed
Usage: Sets the playback speed for the PLAY command.
speed = 1 -> 255.
The duration of a whole note is computed with duration =
24/speed.
Example: Using TEMPO
380
THEN
Token: $A7
Format: IF expression THEN true clause ELSE false clause
Usage: The THEN keyword is part of an IF statement.
expression is a logical or numeric expression. A numerical ex-
pression is evaluated as FALSE if the value is zero and TRUE for
any non zero value.
true clause are one or more statements starting directly after
THEN on the same line. A linenumber after THEN performs a
GOTO to that line.
false clause are one or more statements starting directly af-
ter ELSE on the same line. A linenumber after ELSE performs a
GOTO to that line.
Remarks: The standard IF ... THEN ... ELSE structure is restricted to a single
line. But the true clause or false clause may be expanded to
several lines using a compound statement bracketed with the
keywords BEGIN and BEND.
Example: Using THEN
381
TO
Token: $A4
Format: keyword TO
Usage: TO is a secondary keyword used in combination with primary
keywords like GO, FOR, BACKUP, BSAVE, CHANGE, CONCAT,
COPY, RENAME and SET DISK
Remarks: The keyword TO cannot be used on its own.
Example: Using TO
382
TRAP
Token: $D7
Format: TRAP [line number]
Usage: TRAP with a valid line number activates the BASIC error han-
dler with following consequences: In case of an error the BASIC
interpreter does not stop with an error message, but saves ex-
ecution pointer and line number, places the error number into
the system variable ER and jumps to the line number of the TRAP
command. The trapping routine can examine ER and decide,
whether to STOP or RESUME execution.
TRAP with no argument disables the error handler. Errors will 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
383
TROFF
Token: $D9
Format: TROFF
Usage: Turns off trace mode (switched on by TRON).
Example: Using TROFF
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.
384
TRON
Token: $D8
Format: TRON
Usage: Turns on trace mode.
Example: Using TRON
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.
385
TYPE
Token: $FE $27
Format: TYPE filename [,D drive] [,U unit]
Usage: types the contents of a file containing text in PETSCII code.
filename is either a quoted string, e.g. ”data” or a string ex-
pression in parentheses, e.g. (FN$)
drive = drive # in dual drive disk units.
The drive # defaults to 0 and can be omitted on single drive units
like the 1581, 1571 or 1541 series.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: This command cannot be used to type BASIC programs. Use
LIST for programs. TYPE can only process SEQ or USR files con-
taining records of PETSCII text, delimited by the CR = CHR$(13)
character.
Example: Using TYPE
TYPE "README"
TYPE "README 1ST",U9
386
UNTIL
Token: $FC
Format: DO ... LOOP
DO [ <UNTIL | WHILE> <logical expr.>]
. . . statements [EXIT]
LOOP [ <UNTIL | WHILE> <logical expr.>]
Usage: The DO and LOOP keywords define the start and end of the most
versatile BASIC loop. Using DO and LOOP alone, without any
modifiers creates an infinite loop, that can be left by the EXIT
statement only. The loop can be controlled by adding an UNTIL
or a WHILE statement after the DO or LOOP.
Remarks: DO loops may be nested. An EXIT statement exits the current
loop only.
Example: Using DO and LOOP.
10 PW$="":DO
20 GET A$:PW$=PW$+A$
30 LOOP UNTIL LEN(PW$)>7 OR A$=CHR$(13)
387
USING
Token: $FB
Format: PRINT [# channel,] USING, format, arguments
Usage: USING is a secondary keyword used after PRINT or PRINT#.
It defines the format string for the argument list. The values are
printed following the directives of the format string.
channel : must be opened for output by an OPEN or DOPEN
statement. If no channel is specified, the output goes to the
screen.
format : A string which defines the rules for formatting.
numeric argument : The ’#’ characters set the position and with
of the output string.
’+’ or ’-’ set the sign option.
’.’ sets the position of the decimal point.
’,’ can be inserted into large numbers.
’$’ sets the position of the currency symbol.
^^^^ reserves place for the exponent.
string argument : The string may consist of printable characters
and control codes. Printable characters are printed to the cursor
position, while control codes are executed. The number of ’#’
characters sets the width of the output, a ’=’ sign centres and a
’>’ character right justifies the output.
, : A comma acts like a tabulator. ; : A semicolon acts as a sep-
arator between arguments of the list. Other than the comma
character it does not put in any additional characters. A semi-
colon at the end of the argument list suppresses the automatic
return character.
388
Example: Using PRINT USING
10 X = 12.34: A$ = "MEGA65"
30 PRINT USING "###.##"; X : REM "12.34"
40 PRINT USING "###"; X : REM " 12"
50 PRINT USING "####"; A$ : REM "MEGA"
60 PRINT USING "#########"; A$ : REM "MEGA65 "
70 PRINT USING "=########"; A$ : REM " MEGA65 "
80 PRINT USING "#######>#"; A$ : REM " MEGA65"
389
USR
Token: $B7
Format: USR(numeric expression)
Usage: Using the function USR(X) in a numeric expression, puts the ar-
gument into the floating point accumulator 1 and jumps to the
address $02F7 expecting the address of the machine language
user routine in $02F8 - $02F9. After executing the user routine,
BASIC returns the contents of the floating point accumulator 1,
which should be set by the user routine..
Remarks: Banks 0 -> 127 give access to RAM or ROM banks. Banks > 127
are used to access I/O and SYSTEM like VIC, SID, FDC, etc.
Example: Using USR
390
VAL
Token: $C5
Format: VAL(string expression)
Usage: Converts a string to a floating point value.
This function acts like reading from a string.
Remarks: A string containing not a valid number will not produce an error
but return 0 as result.
Example: Using VAL
PRINT VAL("78E2")
7800
PRINT VAL("7+5")
7
PRINT VAL("1.256")
1.256
PRINT VAL("$FFFF")
0
391
VERIFY
Token: $95
Format: VERIFY filename [,unit [,binflag]]
Usage: This command is obsolete in BASIC-10, where the commands
DVERIFY and BVERIFY are better alternatives.
VERIFY with no binflag compares a BASIC program in memory
with a disk file of type PRG. It does the same as DVERIFY, but
with a different syntax.
VERIFY with binflag compares a binary file in memory with a
disk file of type PRG. It does the same as BVERIFY, but with a
different syntax.
filename is either a quoted string, e.g. ”prog” or a string ex-
pression.
unit = device number on the IEC bus. Typically in the range 8 to
11 for disk units. If a variable is used, it must be put in paren-
theses. The unit # defaults to 8.
Remarks: VERIFY can only test for equality. It gives no information about
the number or position of different valued bytes. The command
exits either with the message OK or with VERIFY ERROR.
Example: Using VERIFY
VERIFY "ADVENTURE"
VERIFY "ZORK-I",9
VERIFY "1:DUNGEON",10
392
VOL
Token: $DB
Format: VOL volume
Usage: Sets the volume for sound output with SOUND or PLAY.
volume = 0 (off) -> 15 (loudest).
Remarks: This volume setting affects all voices.
Example: Using VOL
393
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 nonzero, otherwise the reading is
repeated. This may hang the computer infinitely, if the condition
is never met.
Remarks: This command 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 special raster line.
Example: Using WAIT
10 BANK 128
20 WAIT 211,1 :REM WAIT FOR SHIFT KEY BEING PRESSED
394
WHILE
Token: $ED
Format: DO ... LOOP
DO [ <UNTIL | WHILE> <logical expr.>]
. . . statements [EXIT]
LOOP [ <UNTIL | WHILE> <logical expr.>]
Usage: The DO and LOOP keywords define the start and end of the most
versatile BASIC loop. Using DO and LOOP alone, without any
modifiers creates an infinite loop, that can be left by the EXIT
statement only. The loop can be controlled by adding an UNTIL
or a WHILE statement after the DO or LOOP.
Remarks: DO loops may be nested. An EXIT statement exits the current
loop only.
Example: Using DO and LOOP
10 PW$="":DO
20 GET A$:PW$=PW$+A$
30 LOOP UNTIL LEN(PW$)>7 OR A$=CHR$(13)
395
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
The row values count from 0 to 24.
The column values count from 0 to 79 or 39 depending on the
screen mode.
Remarks: There can be only one window on the screen. Striking the HOME
key twice or printing CHR$(19)CHR$(19) will reset the window
to the default full screen.
Example: Using WINDOW
396
XOR
Token: $CE $08
Format: XOR(operand,operand)
Usage: The Boolean XOR function belongs to the group of Boolean op-
erators like NOT, AND, OR, but is implemented as function in this
BASIC interpreter. It performs a bit-wise logical XOR (eXclusive
OR) operation on two 16-bit values. Integer operands are used
as they are. Real operands are converted to a signed 16 bit in-
teger. Logical operands are converted to 16 bit integer using
$FFFF, decimal -1 for TRUE and $0000, decimal 0, for FALSE.
XOR(0,0) -> 0
XOR(0,1) -> 1
XOR(1,0) -> 1
XOR(1,1) -> 0
397
398
APPENDIX C
Special Keyboard Controls
and Sequences
• PETSCII Codes and CHR$
• Control codes
• Shifted codes
• Escape Sequences
400
PETSCII CODES AND CHR$
You can use the PRINT CHR$(X) statement to print a character. Below is the full
table of PETSCII codes you can print by index. For example, by using index
65 from the table below as: PRINT CHR$(65) you will print the letter A.
You can also do the reverse with the ASC statement. For example: PRINT ASC("A")
will output 65, which matches with the code in the table.
0 22 45 - 68 D
1 23 46 . 69 E
2 UNDERLINE ON 24 47 / 70 F
3 25 48 0 71 G
4 26 49 1 72 H
5 WHITE 27 ESCAPE 50 2 73 I
6 28 RED 51 3 74 J
7 BELL 29 → 52 4 75 K
SHIFT
8 DISABLE ` 30 GREEN 53 5 76 L
9 ENABLE
SHIFT
` 31 BLUE 54 6 77 M
10 LINEFEED 32 SPACE 55 7 78 N
11 33 ! 56 8 79 O
12 34 ” 57 9 80 P
13 RETURN 35 # 58 : 81 Q
14 LOWER CASE 36 $ 59 ; 82 R
15 BLINK ON 37 % 60 < 83 S
16 38 & 61 = 84 T
17 ↓ 39 ’ 62 > 85 U
RVS ON 40 ( 63 ? 86 V
18
41 ) 64 @ 87 W
CLR
19 HOME
42 * 65 A 88 X
INST
20 DEL 43 + 66 B 89 Y
21 44 , 67 C 90 Z
401
91 [ 117 U 142 UPPERCASE 166 =
92 £ 118 V 143 BLINK OFF 167 m
93 ] 119 W 144 BLACK 168 /
94 ↑ 120 X 145 ↑ 169 ?
95 ← 121 Y RVS
170 v
146 OFF
96 C 122 Z 171 q
CLR
97 A 147 HOME 172 d
123 +
98 B 124 - 148
INST 173 z
DEL
NOTE: Codes for 192 to 223 are the equal to 96-127. Codes 224 to 254
equal to 160-190 and code 255 equal to 126.
402
CONTROL CODES
403
Keyboard Control Function
turns on underline text mode. Turn
CTRL + B off underline mode by pressing
ESC then O .
404
SHIFTED CODES
405
ESCAPE SEQUENCES
To perform an Escape Sequence, press and release the ESC key. Then
press one of the following keys to perform the sequence:
Key Sequence
Clears the screen and toggles
X
between 40 and 80 column modes.
406
Key Sequence
Moves the cursor to start of current
J
line.
Move to end of the last
K non-white-space character on the
current line.
Enables scrolling when the cursor
L down key is pressed at the bottom
of the screen.
Disables scrolling. When pressing
the cursor down key at the bottom
on the screen, the cursor will move
M
to the top of the screen. The cursor
is restricted at the top of the screen
with the Cursor up key.
Cancels the quote, reverse,
O
underline and flash modes.
Erases all characters from the cursor
P
to the start of current line.
Erases all characters from the cursor
Q
to the end of current line.
Switches the VIC-IV to colour range
16-31. These colours can be
S accessed with CTRL and keys
1 to 8 or ` and keys 1
to 8 .
Set top-left window area of the
screen at the cursor position. All
T typed characters and screen activity
will be restricted to the area. Also
see ESC then B .
Switches the VIC-IV to colour range
0-15. These colours can be
U accessed with CTRL and keys
1 to 8 or ` and keys 1
to 8 .
407
Key Sequence
V Scrolls the entire screen up one line.
Scrolls the entire screen down one
W
line.
Toggles the 40/80 column display.
X
The screen will also clear home.
Set the default tab stops (every 8
Y
spaces) for the entire screen.
Clears all the tab stops. Any tabbing
Z with CTRL and I will move the
cursor to the end of the line.
Choose from the second range of
1 to 8
colours.
408
APPENDIX D
The MEGA65 Keyboard
• Hardware Accelerated Key-
board Scanning
HARDWARE ACCELERATED
KEYBOARD SCANNING
To make use of the new extended keyboard easier, the MEGA65 features
a hardware accelerated keyboard scan circuit, that provides ASCII (not
PETSCII!) codes for keys and key-combinations. This makes it very simple to use
the full capabilities of the MEGA65’s keyboard, including the entry of ASCII
symbols such as {, _ and |, which are not possible to type on a normal C64
and C128 keyboards.
The hardware accelerated keyboard scanner has a buffer of 3 keys, which
helps to make it easier to read from the keyboard without having check it too
regularly. Further, the hardware acclerated keyboard scanner supports most
Latin-1 code-page characters, allowing the entry of many accented charac-
ters. These keys are entered by holding down the ` key and pressing other
keys or key-combinations. The use of ASCII or Latin-1 symbols not present
in the PETSCII character set requires the use of a font that contains these
symbols, and software which supports them.
The hardware accelerated keyboard scanner is very simple to use: First, make
sure that you have the MEGA65 IO context activated, then read memory lo-
cation $D610 (decimal 54800). If the register contains zero, no key has been
pressed. Otherwise the value will be the ASCII code of the most recent key or
key-combination that has been pressed. Reading $D610 again will continue
to read the same value until you POKE any value into $D610. This clears the
key from the input buffer.
The hardware accelerated keyboard scanner also provides a register that in-
dicates which of the modifier keys are currently being held down. This is ac-
cessed via the read-only register $D611 (decimal 54801):
SHIFT CTRL
Bit 0 Right Bit 2
SHIFT
Bit 1 Left Bit 3 `
411
ALT CAPS
Bit 4 Bit 6 LOCK
NO
Bit 5 SCROLL Bit 7 Reserved
412
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 corre-
sponding 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.
←
RETURN
1 W R Y I P * TAB
2 → A D G J L ;
CTRL
ALT
CLR HELP
3 F7 4 6 8 0 - HOME 2
SHIFT
4 F1 Z C B M . right SPC F9
5 F3 S F H K : = ` F11
6 F5 E T O U O @ ↑ 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 shift key applied. This enables them to work from in
CAPS
C64 mode. The LOCK key 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 num-
bers down the left indicate the rows. The unique scan code of a key is calcu-
lated by multiplying the column by eight, and adding the row. For example,
key is in column 6 and row 3. Thus its scan code is 6 × 8 + 3 = 51.
CLR
the HOME
413
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 that key is being
RESTORE
held down. The key exists outside of the keyboard matrix, as on the
RESTORE
C64. To simulate holding the key down, write $52 (ASCII code for a
RESTORE
capital R), and to simulate a quick tap of the , write $72 (ASCII code for
a lower-case R). Another value must be written after the $72 value has been
RESTORE
written, if you wish to simulate multiple presses of the key.
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:
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!
414
1 left-half of DRIVE LED, GREEN
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 cur-
rently selected in $D61D. Therefore to safely change the intensity of one spe-
cific LED ensure $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 configuration for approximately one millisecond to
give the keyboard logic enough time to pick up the new intensity value for the
selected LED.
For example to pulse the keyboard LEDs red and blue, the following pro-
gramme could be used:
415
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
0
F5
9 8
1 9 10 U
2 I 11 J
3 K 12 M
4 < 13 →
INST
5 DEL 14 £
6
CLR
HOME
15 =
7 O 16 F1
8 F3 17 7
416
18 Y 46
HELP
19 H RETURN
47
20 N ALT
48
21 ↓
49 3
22 -
50 W
23 ;
51 S
24 Reserved
52 X
25 6
53 ↑ (cursor up)
26 T
54 F13
27 G
55 ↑ (next to *)
28 B
29 ← (cursor left) 56
ESC
30 + 57 2
31 : 58 Q
32
NO
SCRL
59 A
33 5 60 Z
SHIFT
34 R 61 right
35 F 62 F11
36 V 63 *
37 SPACE 64 Reserved
38 0 65 1
39 L 66 Reserved
40
CAPS
LOCK
67 Reserved
SHIFT SHIFT
41 4 68 left and LOCK
42 E 69 /
43 D 70 F9
44 C 71 @
RUN
45 Reserved 72 STOP
417
73 ← (next to 1) 76 `
TAB
77 >
74
78 F7
CTRL
75 79 P
418
APPENDIX E
Decimal, Binary and
Hexadecimal
• Numbers
• Notations and Bases
• Operations
• Signed and Unsigned Numbers
• Bit-wise Logical Operators
• Converting Numbers
420
NUMBERS
Simple computer programs, such as most of the introductory BASIC programs
in this book, do not require an understanding of mathematics or much knowl-
edge about the inner workings of the computer. This is because BASIC is con-
sidered a high-level programming 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 concern 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 of-
ten 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 knowl-
edge 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 sometimes 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 BACKGROUND 1 statement). Data
421
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 computer does not distinguish between instructions and data,
nor does it have separate areas of memory for each kind of information. In-
stead, both are stored in whichever memory location is considered convenient.
Whether a given memory location’s contents is part of the program’s instruc-
tions or is part of the program’s data largely depends 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
programmers to manipulate the computer’s memory efficiently. The statement
PEEK lets us read the information from a specified memory location: we can
inspect the contents 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.
422
tation. 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 re-
flects 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 asso-
ciated with off and the number 1 is associated with on. Binary is the simplest
notation that captures this idea. In order to express large numbers 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.
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 com-
monly 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 no-
tations 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 calculators can convert between bases with the press of a button. They
can also add, subtract, multiply and divide, and perform various bit-wise log-
ical operations. See Appendix O Reference Tables as it contains a Base Con-
423
version 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 num-
ber is for a different power of 10. The rightmost position represents the num-
ber 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 col-
umn. Columns to the left of it are labelled tens (because 101 = 10), hundreds
(because 102 = 100), thousands (because 103 = 1000), and so on.
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 )
424
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 num-
ber 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 hexadecimal numbers will have a sub-scripted 16.
Another useful concept is the idea of signed and unsigned decimal integers.
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 deci-
mal number. For example, the statement 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 un-
signed 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 unsigned
425
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 represented using eight binary digits (eight bits). Also, the memory ad-
dresses 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
As an example, the integer %1101 0011 uses exactly eight binary digits and
represents 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.
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.
426
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
427
is %1111 1111 1111 1111 and this corresponds to the largest 16-bit num-
ber.
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
428
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.
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 leftmost digit is the most significant.
Each memory location can store an integer between 0 and 255, and this cor-
responds to the hexadecimal numbers $00 and $FF. The hexadecimal number
$FFFF corresponds 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 hex-
adecimal digit is equal to exactly four bits. So a two-digit hexadecimal num-
ber comprises of eight bits with the low nybble equalling the right digit and
the high nybble equalling the left digit.
Note that the largest number expressible using d hexadecimal digits is (in dec-
imal) 16d − 1. (This number will have d $F symbols in its representation.)
429
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 capabili-
ties.
Counting
If we consider carefully the process of counting in decimal, this will help us to
understand 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.
430
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
Now we’ll look at counting in hexadecimal. The list of numerals for hexadec-
imal 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.
431
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, ex-
cept that we use base 2 or base 16 as appropriate. Consider the following
example for the addition of two binary numbers.
%110
+%111
%1101
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.
$7D
+$69
$E6
432
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.
$3D
-$1F
$1E
433
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.
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
434
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
435
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.
436
PRINT (NOT 0)
-1
The AND statement must be given two 16-bit signed decimal integers as pa-
rameters. 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).
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 pa-
rameters. 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
437
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).
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
Notice that when the bits are equal the resulting bit is 0. Otherwise the re-
sulting bit is 1.
Much of the utility of these bit-wise logical operators comes through combin-
ing them together into a compound statement. For example, the VIC II register
to enable sprites is memory address 53269. There are eight sprites (numbered
438
0 to 7) with each bit corresponding to a sprite’s status. Now suppose we want
to turn off sprite 5 and turn 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.
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 common.
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”.
To execute the program, type RUN and press the RETURN key.
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.
439
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"
420 PRINT "{SPACE*2}[R]{SPACE*2}RETURN TO TOP MENU"
440
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 ***
810 H$=""
820 PRINT: INPUT "ENTER HEXADECIMAL INTEGER (UP TO 4 DIGITS): ",H$
441
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
1190 BEND
1200 D$ = STR$(I): D = I: RETURN
1210 REM *** VALIDATE HEXADECIMAL INPUT ***
442
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
1550 : IF (D > DE) THEN GOTO 1630
1560 : NEXT K
443
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
444
APPENDIX F
System Memory Map
• Introduction
• MEGA65 Native Memory Map
• $D000 – $DFFF IO Personalities
• CPU Memory Banking
• C64/C65 ROM Emulation
446
INTRODUCTION
The MEGA65 computer has a large 28-bit address space, which allows it to
address up to 256MiB 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 compat-
ibility 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 flexibly memory map.
In this appendix, we will begin by describing the MEGA65’s native memory
map, that is, where all of the memory, IO devices and other features appear in
the 28-bit address space. We will then explain how C64 and C65 compatible
memory maps are accessed from this 28-bit address space.
447
MEGA65 NATIVE MEMORY MAP
The First Sixteen 64KB Banks
The MEGA65 uses a similar memory map to that of the C65 for the first MiB of
memory, i.e., 16 memory banks of 64KiB each. This is because the C65’s 4510
CPU can access only 1MiB of address space. These banks can be accessed
from BASIC 10 using the BANK, DMA, PEEK and POKE commands. The following
table summarises the contents of the first 16 banks:
448
…continued
HEX DEC Address Contents
E 14 $Exxxx Additional RAM (1MiB or larger chip-
RAM models)
F 15 $Fxxxx Additional RAM (1MiB or larger chip-
RAM models)
The key features of this address space are the 128KiB of RAM in the first two
banks, which is also present on the C65. If you intend to write programmes
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 128KiB 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 programme which will start from C64 mode, or other-
wise 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 pro-
grammes. This gives a total of 192KiB of RAM, which is available on all models
of the MEGA65.
On models that have 384KiB or more of chip RAM, BANK 4 and 5 are also
available. Similarly, models which provide 1MiB or more of chip RAM will have
BANK 6 through 15 also available, giving a total of 896KiB (or 960KiB, if only
the C64 part of the ROM is required) of RAM available for your programmes.
Note that the MEGA65’s built-in freeze cartridge currently freezes only the
first 384KiB 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 32KiB or 64KiB of colour RAM is
located at $FF80000. This is most easily access 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
449
MEGA65, allowing access to the full colour RAM via BANK 15 or an equivalent
DMA job.
450
…continued
HEX DEC Size Contents
FFCC000 255.80 MiB –
16 KiB Emulated C1541 ROM
– FFCFFFF 255.81 MiB
FFD0000 255.81 MiB –
4 KiB C64 $Dxxx IO Personality
– FFD0FFF 255.81 MiB
FFD1000 255.81 MiB –
4 KiB C65 $Dxxx IO Personality
– FFD1FFF 255.82 MiB
FFD2000 255.82 MiB –
4 KiB MEGA65 $Dxxx Ethernet IO Personality
– FFD2FFF 255.82 MiB
FFD3000 255.82 MiB –
4 KiB MEGA65 $Dxxx Normal IO Personality
– FFD3FFF 255.82 MiB
FFD4000 255.82 MiB –
8 KiB Reserved
– FFD5FFF 255.83 MiB
FFD6000 255.83 MiB –
2 KiB Hypervisor scratch space
– FFD67FF 255.83 MiB
FFD6000 255.83 MiB –
3 KiB Hypervisor scratch space
– FFD6BFF 255.83 MiB
FFD6C00 255.83 MiB –
512 F011 floppy controller sector buffer
– FFD6DFF 255.83 MiB
FFD6E00 – 255.83 MiB –
512 SD Card controller sector buffer
FFD6FFF 255.83 MiB
FFD7000 255.83 MiB –
256 MEGAphone r1 I2C peripherals
– FFD70FF 255.83 MiB
FFD7100 255.83 MiB –
256 MEGA65 r2 I2C peripherals
– FFD71FF 255.83 MiB
FFD7200 – 255.83 MiB –
256 MEGA65 HDMI I2C registers (only for
FFD72FF 255.83 MiB
models fitted with the ADV7511 HDMI
driver chip)
FFD7300 255.83 MiB – 3.25
Reserved for future I2C peripherals
– FFD7FFF 255.84 MiB KiB
FFD8000 255.83 MiB –
16 KiB Hypervisor ROM (only visible in Hypervi-
– FFDBFFF 255.86 MiB
sor Mode)
FFDC000 255.86 MiB –
8 KiB Reserved for Hypervisor Mode ROM ex-
– FFDDFFF 255.87 MiB
pansion
FFDE000 – 255.87 MiB –
2 KiB Reserved for Ethernet buffer expansion
FFDE7FF 255.87 MiB
FFDE800 – 255.87 MiB –
2 KiB Ethernet frame read buffer (read only)
FFDEFFF 255.87 MiB
and Ethernet frame write buffer (write
only)
continued …
451
…continued
HEX DEC Size Contents
FFDF000 – 255.87 MiB –
4 KiB Virtual FPGA registers (selected models
FFDFFFF 255.87 MiB
only)
FFE0000 – 255.87 MiB – 128
Reserved
FFFFFFF 256 MiB KiB
452
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 IO /
$DE00 – $DFFF CART IO CART IO
Buffer SD SECTOR
1
In the C64 IO personality, $D030 behaves as on C128, allowing
toggling between 1MHz and 2MHz CPU speed.
2
The additional MEGA65 SIDs are visible in all IO personalities.
3
Some models may replace the repeated images of the first four
SIDs with four additional SIDs, for a total of 8 SIDs.
453
CPU MEMORY BANKING
The 45GS10 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 existing the MEGA65:
1. C65-style MAP instruction banking
2. C65-style $D030 banking
3. C64-style cartridge banking
4. C64-style $00 / $01 banking
It is important to understand that these different banking modes have a priority
order: If a higher priority form of banking is being used, it takes priority over a
lower priority form. The C65 banking methods take priority of the C64 mode
banking methods. So, for example, if the 45GS10 MAP instruction has been
used to provide a particular memory layout, the C64-style $00 / $01 banking
will not be visible.
This makes the overall banking scheme more complex than on the C64. Thus
to understand what the actual memory layout will be, you should start by con-
sidering the effects of C64 memory banking, and then if any C65 MAP instruc-
tion memory banking is enabled, using that to override the C64-style memory
banking. Then if any C65 $D030 memory banking is used, that overrides both
the C64 and C65 MAP instruction memory banking. Finally, if IO is banked,
or if there are any cartridges inserted and active, their effects are made.
The following diagram shows the different types of banking that can apply to
the different areas of the 64KB that the CPU can see. The higher layers take
priority over the lower layers, as described in the previous paragraph.
CART CART CART
IO/CART IO
ROMLO ROMHI ROMHI
INTER-
C65 BASIC BASIC KERNAL
FACE
MAP LO MAP HI
MAP
(4 x 8KB slabs) (4 x 8KB slabs)
CHAR
C64 BASIC KERNAL
ROM
RAM RAM* RAM RAM RAM RAM RAM
$0000 – $8000 – $A000 – $C000 – $D000 – $E000 –
$7FFF $9FFF $BFFF $CFFF $DFFF $FFFF
454
(There are actually a few further complications. For example, if the cartridge
selects the UltiMAX(tm) game mode, then only the first 4KB of RAM will be
visible, and the remaining address space will be un-mapped, and able to be
supplied by the cartridge.)
For example, using $D030 to bank in C65 ROM at $A000, this will take priority
over the C64 BASIC 2 ROM at the same address.
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.
LDA # $70
STA $D640
NOP
455
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
$3C000 – $3DFFF 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 C64 CHARSET
$2C000 – $2CFFF INTERFACE
$24000 – $27FFF 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.
456
APPENDIX G
45GS02 Microprocessor
• Introduction
• Differences to the 6502
• C64 CPU Memory Mapped Registers
• New CPU Memory Mapped Registers
• MEGA65 CPU Maths Unit Registers
• MEGA65 Hypervisor Mode
458
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 com-
puter 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 IO registers of the 45GS02.
Supervisor/Hypervisor Privileged
Mode
Unlike the earlier 6502 variants, the 45GS02 has a privileged mode of oper-
ation. This mode is intended for use by an operating system or type-1 hypervi-
sor. The ambiguity between operating system and Hypervisor on the MEGA65
stems from the fact that the operating system of the MEGA65 is effectively lit-
tle 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 16KiB memory area is mapped to $8000 - $BFFF, which is used
to contain both the program and data of the Hypervisor / supervisor pro-
gram. 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.
459
• The 64 SYSCALL trap registers in the MEGA65 IO-mode at $D640 -
$D67F are replaced by the virtualisation control registers. These regis-
ters 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.
460
increased value. For most purposes, this did not cause any problems. How-
ever, 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) ac-
knowledges the interrupt. his 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. Unfor-
tunately, it also meant that a lot of existing C64 software simply won’t run
on a C65, unless the interrupt acknowledgement 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
compatibility 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 compatibility, without
sacrificing the speed improvement for all other uses of these instructions.
In these modes, the 45GS02 processor slows down, so that the same number
of instructions 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 correct 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. How-
ever memory accesses within an instruction are not guaranteed to occur in the
461
same cycle as on a 1MHz 6502. Normally the effect is that instructions com-
plete 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 Posi-
tion (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 prob-
lems 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.
It is also possible to more smoothly vary the CPU speed using the SPEEDBIAS
register located at $F7FA (55290), when MEGA65 IO mode is enabled. The
default value is $80 (128), which means no bias on the CPU speed. Higher
values increase the CPU speed, with $FF meaning 2× the expected speed.
Lower values slow the processor down, with $00 bring the CPU to a complete
stand-still. Thus the speed can be varied between 0× and 2× the intended
value.
Note that this register has no effect when the processor is running at full-
speed, because it only affects the way in which VIC-IV video cycle indication
pulses are processed by the CPU.
462
Direct Memory Access (DMA)
Direct Memory Access (DMA) is a method for quickly filling, copying or swap-
ping memory regions. The MEGA65 implements an improved version of the
F018 “DMAgic” DMA 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 Appendix J
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.
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:
463
$D030 Signal 20-bit 16-bit Read-Write
Bit Name Address Address Access?
$1F800 –
$1FFFF, $D800 –
0 CRAM2K Y
$FF80000 $DFFF
– $FF807FF
$38000 – $8000 –
3 ROM8 N
$39FFF $9FFF
$3A000 – $A000 –
4 ROMA N
$3BFFF $BFFF
$2C000 – $C000 –
5 ROMC N
$2CFFF $CFFF
$29000 – $D000 –
6 CROM9 N
$29FFF $DFFF
$3E000 – $E000 –
7 ROME N
$3FFFF $FFFF
The CRAM2K signal causes the normal 1KB of colour RAM, which is located
at $1F800 – $1FBFF and is visible at $D800 – $DBFF, to instead be visible
from $D800 – $DFFF. That is, the entire range $1F800 – $1FFFF is visible,
and can be both read from and written to. 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.
Note that these VIC-III memory banking signals take precedence over the
C64-style memory banking.
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 docu-
mented in Appendix K.
464
blocks of 8KB each. For each of these blocks, the block may either be ac-
cessed 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 off-
set, the lower offset, and the second 32KB uses another, the upper offset.
Re-mapping of memory using the MAP instruction takes precedence over the
C64-style memory banking, but not the C65’s ROM banking mechanism.
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. Note that there is no way to use
the MAP instruction to determine the current memory mapping configuration,
which somewhat limits its effectiveness.
See under “Using the MAP instruction to access >1MB” for further explanation
and an example.
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 en-
hancements to this, refer to Appendix J
465
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 execut-
ing instructions 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.
To give a very simple example of how the MAP instruction can be used to map
an area of memory 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 example as simple as possible, we assume
that the code is running from in the bottom 64KB of RAM, and not in the region
between $6000 – $8000.
XXX - Diagram needed for this.
As the MAP instruction normally is only aware of the C65-style 20-bit ad-
dresses, 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 ad-
dress 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 incompat-
ibility 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.
466
The same approach applies to the upper 32KB, but using the Z and Y regis-
ters instead of the X and A registers. However, in this case, we do not need
to re-map the upper 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 sec-
ond 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:
; Ethernet controller really lives $FFDE000 - $FFDEFFF, so select $FF megabyte section for MAP LO
LDA #$ff
LDX #$0f
LDY #$00
LDZ #$00
map
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,
467
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 map-
ping address had not been updated.
No example in BASIC for the MAP instruction is possible, because the MAP is
an machine code instruction of the 4510 / 45GS02 processors.
Flat-Memory Access
The 45GS02 makes it easy to read or write a byte from anywhere in memory
by allowing 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 Indirect 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 43 12.
This method is much more efficient and also simpler than either using the MAP
instruction 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 memory. 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.
468
Virtual 32-bit Register
The 45GS02 allows the use of its four general purpose registers, A, X ,Y and Z
as a single virtual 32-bit 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:
; Or to write out the bottom bytes, we can just write the contents 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:
469
; Clear carry before performing addition, as normal
CLC
LDQ $1234 ; Load the contents of $1234-$1237 into A,X,Y and Z respectively
; And again, for the addition
ADCQ $1238 ; Add the contents of $1238-$123B
; The result of the addition is now in A, X, Y and Z.
; And can be written out in whole or part
; Or to write out the bottom bytes, we can just write the contents of A and X as normal
STA $1240
STX $1241
The virtual 32-bit addressing mode works with any addressing mode. How-
ever, indexed 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, 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
470
can load the A, X, Y and Z registers with the immediate value, and then use
ADCQ with the memory address, e.g.:
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 pro-
gramme will take the same number of cycles to execute.
471
HEX DEC Signal Description
0000 0 PORTDDR 6510/45GS10 CPU port DDR
0001 1 PORT 6510/45GS10 CPU port data
472
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
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
D679 54905 HTRAP39
D67A 54906 HTRAP3A
D67B 54907 HTRAP3B
D67C 54908 HTRAP3C
D67D 54909 HTRAP3D
D67E 54910 HTRAP3E
D67F 54911 HTRAP3F
D7FA 55290 SPEEDBIAS
D7FB 55291 – CARTEN BRCOST
continued …
473
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D7FD 55293 NOEXROM POWEREN –
D7FE 55294 – PREFETCH
474
• HTRAP17 Writing triggers hypervisor trap $17
• HTRAP18 Writing triggers hypervisor trap $18
• HTRAP19 Writing triggers hypervisor trap $19
• HTRAP1A Writing triggers hypervisor trap $1A
• HTRAP1B Writing triggers hypervisor trap $1B
• HTRAP1C Writing triggers hypervisor trap $1C
• HTRAP1D Writing triggers hypervisor trap $1D
• HTRAP1E Writing triggers hypervisor trap $1E
• HTRAP1F Writing triggers hypervisor trap $1F
• HTRAP20 Writing triggers hypervisor trap $20
• HTRAP21 Writing triggers hypervisor trap $21
• HTRAP22 Writing triggers hypervisor trap $22
• HTRAP23 Writing triggers hypervisor trap $23
• HTRAP24 Writing triggers hypervisor trap $24
• HTRAP25 Writing triggers hypervisor trap $25
• HTRAP26 Writing triggers hypervisor trap $26
• HTRAP27 Writing triggers hypervisor trap $27
• HTRAP28 Writing triggers hypervisor trap $28
• HTRAP29 Writing triggers hypervisor trap $29
• HTRAP2A Writing triggers hypervisor trap $2A
• HTRAP2B Writing triggers hypervisor trap $2B
• HTRAP2C Writing triggers hypervisor trap $2C
• HTRAP2D Writing triggers hypervisor trap $2D
• HTRAP2E Writing triggers hypervisor trap $2E
• HTRAP2F Writing triggers hypervisor trap $2F
• HTRAP30 Writing triggers hypervisor trap $30
• HTRAP31 Writing triggers hypervisor trap $31
• HTRAP32 Writing triggers hypervisor trap $32
475
• HTRAP33 Writing triggers hypervisor trap $33
• HTRAP34 Writing triggers hypervisor trap $34
• HTRAP35 Writing triggers hypervisor trap $35
• HTRAP36 Writing triggers hypervisor trap $36
• HTRAP37 Writing triggers hypervisor trap $37
• HTRAP38 Writing triggers hypervisor trap $38
• HTRAP39 Writing triggers hypervisor trap $39
• HTRAP3A Writing triggers hypervisor trap $3A
• HTRAP3B Writing triggers hypervisor trap $3B
• HTRAP3C Writing triggers hypervisor trap $3C
• HTRAP3D Writing triggers hypervisor trap $3D
• HTRAP3E Writing triggers hypervisor trap $3E
• HTRAP3F Writing triggers hypervisor trap $3F
• NOEXROM Override for /EXROM : Must be 0 to enable /EXROM signal
• NOGAME Override for /GAME : Must be 0 to enable /GAME signal
• POWEREN Set to zero to power off computer on supported systems.
WRITE ONLY.
• PREFETCH Enable expansion RAM pre-fetch logic
• SPEEDBIAS 1/2/3.5MHz CPU speed fine adjustment
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D768 55144 MULTOUT
D769 55145 MULTOUT
continued …
476
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D76A 55146 MULTOUT
D76B 55147 MULTOUT
D76C 55148 MULTOUT
D76D 55149 MULTOUT
D76E 55150 MULTOUT
D76F 55151 MULTOUT
D770 55152 MULTINA
D771 55153 MULTINA
D772 55154 MULTINA
D773 55155 MULTINA
D774 55156 MULTINB
D775 55157 MULTINB
D776 55158 MULTINB
D777 55159 MULTINB
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
continued …
477
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
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
D7A1 55201 MATHIN8
D7A2 55202 MATHIN8
D7A3 55203 MATHIN8
D7A4 55204 MATHIN9
D7A5 55205 MATHIN9
D7A6 55206 MATHIN9
D7A7 55207 MATHIN9
D7A8 55208 MATHIN10
D7A9 55209 MATHIN10
D7AA 55210 MATHIN10
D7AB 55211 MATHIN10
D7AC 55212 MATHIN11
D7AD 55213 MATHIN11
D7AE 55214 MATHIN11
D7AF 55215 MATHIN11
D7B0 55216 MATHIN12
D7B1 55217 MATHIN12
D7B2 55218 MATHIN12
D7B3 55219 MATHIN12
D7B4 55220 MATHIN13
D7B5 55221 MATHIN13
continued …
478
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D7B6 55222 MATHIN13
D7B7 55223 MATHIN13
D7B8 55224 MATHIN14
D7B9 55225 MATHIN14
D7BA 55226 MATHIN14
D7BB 55227 MATHIN14
D7BC 55228 MATHIN15
D7BD 55229 MATHIN15
D7BE 55230 MATHIN15
D7BF 55231 MATHIN15
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
D7CA 55242 UNIT10INB UNIT10INA
D7CB 55243 UNIT11INB UNIT11INA
D7CC 55244 UNIT12INB UNIT12INA
D7CD 55245 UNIT13INB UNIT13INA
D7CE 55246 UNIT14INB UNIT14INA
D7CF 55247 UNIT15INB UNIT15INA
D7D0 55248 – UNIT0OUT
D7D1 55249 – UNIT1OUT
D7D2 55250 – UNIT2OUT
D7D3 55251 – UNIT3OUT
D7D4 55252 – UNIT4OUT
D7D5 55253 – UNIT5OUT
D7D6 55254 – UNIT6OUT
D7D7 55255 – UNIT7OUT
D7D8 55256 – UNIT8OUT
D7D9 55257 – UNIT9OUT
D7DA 55258 – UNIT10OUT
D7DB 55259 – UNIT11OUT
continued …
479
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D7DC 55260 – UNIT12OUT
D7DD 55261 – UNIT13OUT
D7DE 55262 – UNIT14OUT
D7DF 55263 – UNIT15OUT
D7E0 55264 LATCHINT
D7E1 55265 – CALCEN WREN
D7E2 55266 RESERVED
D7E3 55267 RESERVED
480
• MULTOUT 64-bit output of MULTINA ÷ MULTINB
• RESERVED Reserved
• UNIT0INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 0.
• UNIT0INB Select which of the 16 32-bit math registers is input B for
Math Function Unit 0.
• UNIT0OUT Select which of the 16 32-bit math registers receives the
output of Math Function Unit 0
• UNIT10INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 10.
• UNIT10INB Select which of the 16 32-bit math registers is input B for
Math Function Unit 10.
• UNIT10OUT Select which of the 16 32-bit math registers receives the
output of Math Function Unit A
• UNIT11INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 11.
• UNIT11INB Select which of the 16 32-bit math registers is input B for
Math Function Unit 11.
• UNIT11OUT Select which of the 16 32-bit math registers receives the
output of Math Function Unit B
• UNIT12INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 12.
• UNIT12INB Select which of the 16 32-bit math registers is input B for
Math Function Unit 12.
• UNIT12OUT Select which of the 16 32-bit math registers receives the
output of Math Function Unit C
• UNIT13INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 13.
• UNIT13INB Select which of the 16 32-bit math registers is input B for
Math Function Unit 13.
• UNIT13OUT Select which of the 16 32-bit math registers receives the
output of Math Function Unit D
• UNIT14INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 14.
481
• UNIT14INB Select which of the 16 32-bit math registers is input B for
Math Function Unit 14.
• UNIT14OUT Select which of the 16 32-bit math registers receives the
output of Math Function Unit E
• UNIT15INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 15.
• UNIT15INB Select which of the 16 32-bit math registers is input B for
Math Function Unit 15.
• UNIT15OUT Select which of the 16 32-bit math registers receives the
output of Math Function Unit F
• UNIT1INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 1.
• UNIT1INB Select which of the 16 32-bit math registers is input B for
Math Function Unit 1.
• UNIT1OUT Select which of the 16 32-bit math registers receives the
output of Math Function Unit 1
• UNIT2INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 2.
• UNIT2INB Select which of the 16 32-bit math registers is input B for
Math Function Unit 2.
• UNIT2OUT Select which of the 16 32-bit math registers receives the
output of Math Function Unit 2
• UNIT3INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 3.
• UNIT3INB Select which of the 16 32-bit math registers is input B for
Math Function Unit 3.
• UNIT3OUT Select which of the 16 32-bit math registers receives the
output of Math Function Unit 3
• UNIT4INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 4.
• UNIT4INB Select which of the 16 32-bit math registers is input B for
Math Function Unit 4.
• UNIT4OUT Select which of the 16 32-bit math registers receives the
output of Math Function Unit 4
482
• UNIT5INA Select which of the 16 32-bit math registers is input A for
Math Function Unit 5.
483
MEGA65 HYPERVISOR MODE
Reset
On power-up or reset, the MEGA65 starts up in hypervisor mode, and expects
to find a program in the 16KiB hypervisor memory, and begins executing in-
structions 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 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.
• Page Fault On MEGA65s that feature virtual memory, a page fault will
cause a trap to hypervisor mode.
• Certain keyboard events Pressing the RESTORE key for >0.5 sec-
onds, or the ALT + TAB key combination traps to the hypervisor.
Typically the first is used to launch the freeze menu an the second to
toggle the display of debug interface.
484
• Accessing virtualised IO 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 un-
documented opcodes on the 6502 will cause the CPU to lockup. On
the MEGA65, instead of locking up, the computer will trap to the hyper-
visor. 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 in-
terrupts. 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
registers.
3. The hypervisor mode memory layout is activated, the CPU decimal flag
and special purpose registers are all set to appropriate values. The con-
tents 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 programme 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].
485
The full list of SYSCALLs and traps is:
486
…continued
HEX DEC Name Description
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
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
continued …
487
…continued
HEX DEC Name Description
33048
811C –
– RESERVED Reserved traps point entry
81FB
33275
KIL instruction in 6502-mode trap entry
81FC 33276 CPUKIL
point
The remainder of the 16KiB hypervisor memory is available for use by the pro-
grammer, but will typically use the last 512 bytes for the stack and zero-page,
giving an overall memory map as follows:
The stack is used for holding the return address of function calls. The zero-
page storage is typically used for holding variables and other short-term stor-
age, as is customary on the 6502.
488
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
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
D670 54896 GEORAMBASE
D671 54897 GEORAMMASK
D672 54898 – MATRIXEN –
D67C 54908 UARTDATA
D67D 54909 WATCHDOG
D67E 54910 HICKED
D67F 54911 ENTEREXIT
489
• 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
490
• SPH Hypervisor SPH register storage
• VFLOP 1=Virtualise SD/Floppy access (usually for access via serial de-
bugger interface)
This file instructs KickC’s assembler to create a 16KiB file with the 512 byte
SYSCALL/trap entry point region at the start, followed by code and data ar-
eas, 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.:
491
// XMega65 KERNAL Development Template
// Each function of the KERNAL is a no-args function
// The functions are placed in the SYSCALLS table surrounded by JMP and NOP
import "string"
// Use a linker definition file (put the previous listing into that file)
#pragma link("mega65hyper.ld")
// Some definitions of addresses and special values that this program uses
const char* RASTER = 0xd012;
const char* VIC_MEMORY = 0xd018;
const char* SCREEN = 0x0400;
const char* BGCOL = 0xd021;
const char* COLS = 0xd800;
const char BLACK = 0;
const char WHITE = 1;
void main() {
// Initialise screen memory, and select correct font
*VIC_MEMORY = 0x14;
// Fill the screen with spaces
memset(SCREEN, ' ', 40*25);
// Set the colour of every character on the screen to white
memset(COLS, WHITE, 40*25);
// Print the "hello world!" message
char* sc = SCREEN+40; // Display it one line down on the screen
char* msg = MESSAGE; // The massage to display
// A simple copy routine to copy the string
while(*msg) {
*sc++ = *msg++;
}
// Loop forever showing two white lines as raster bars
while(true) {
if(*RASTER==54 || *RASTER==66) {
*BGCOL = WHITE;
} else {
*BGCOL = BLACK;
}
}
}
492
// Here are a couple sample SYSCALL handlers that just display a character on the screen
void syscall1() {
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 mega65hyper
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:
493
494
APPENDIX H
45GS02 & 6502 Instruction
Sets
• Addressing Modes
• 6502 Instruction Set
• 4510 Instruction Set
• 45GS02 Compound Instructions
496
The 45GS02 CPU is able to operate in native mode, where it is compati-
ble with the CSG 4510, and in 6502 compatibility mode, where 6502 un-
documented instructions, also known as illegal instructions, are supported for
compatibility.
When in 4510 compatibility mode, the 45GS02 also supports a number of ex-
tensions through compound instructions. These work be prefixing the desired
instruction’s opcode with one or more prefix bytes, which represent sequences
of instructions that should not normally occur. For example, two NEG instruc-
tions in a row acts as a prefix 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.
ADDRESSING MODES
The 45GS02 supports 36 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.
497
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 ex-
ample, INC A increments 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, ASL Q shifts the value in the Q Pseudo Register left one bit.
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 assem-
blers 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:
LDA #5
498
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.
499
by setting the Base Page Register using the TAB instruction. Base Page Mode
allows faster access to a 256 region of memory, and uses less instruction
bytes to do so.
The argument is encoded as a single byte that immediately follows the in-
struction opcode. For example, LDQ $12 would read the value stored in locations
$12 – $15 in the Base Page, and put them into the Q Pseudo Register.
500
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.
501
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 up-
per 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 Accumulator Register. This would be encoded as $AD $34 $12.
502
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 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.
503
Absolute Indirect Mode
In this mode, the 16-bit argument is the address that points to, i.e., contains
the address 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.
504
Base Page Indirect Y-Indexed
Mode
This addressing mode differs from the X-Indexed Indirect modes, in that the Y
Register 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 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.
505
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 identical to Base Page Mode, except that it is prefixed by $42, $42.
LDA #$06
LDZ #$01
STA [$12],Z
506
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.
LDA #$06
STA [$12]
Note: The ACME assembler is the only assembler that currently supports this
addressing mode. For other assemblers, you can achieve the same result by
using a NOP instruction to prefix the equivalent Base Page Indirect, Indexed
by Z instruction.
LDA #$06
NOP
STA ($12),Z
The encoding for this addressing mode is identical to Base Page Mode.
507
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.
508
$x0 $x1 $x2 $x3 $x4 $x5 $x6 $x7 $x8 $x9 $xA $xB $xC $xD $xE $xF
$0x BRK ORA KIL SLO NOP ORA ASL SLO PHP ORA ASL ANC NOP ORA ASL SLO
$1x BPL ORA KIL SLO NOP ORA ASL SLO CLC ORA NOP SLO NOP ORA ASL SLO
$2x JSR AND KIL RLA BIT AND ROL RLA PLP AND ROL ANC BIT AND ROL RLA
$3x BMI AND KIL RLA NOP AND ROL RLA SEC AND NOP RLA NOP AND ROL RLA
$4x RTI EOR KIL SRE NOP EOR LSR SRE PHA EOR LSR ALR JMP EOR LSR SRE
$5x BVC EOR KIL SRE NOP EOR LSR SRE CLI EOR NOP SRE NOP EOR LSR SRE
$6x RTS ADC KIL RRA NOP ADC ROR RRA PLA ADC ROR ARR JMP ADC ROR RRA
509
$7x BVS ADC KIL RRA NOP ADC ROR RRA SEI ADC NOP RRA NOP ADC ROR RRA
$8x NOP STA NOP SAX STY STA STX SAX DEY NOP TXA XAA STY STA STX SAX
$9x BCC STA KIL SHA STY STA STX SAX TYA STA TXS TAS SHY STA SHX SHA
$Ax LDY LDA LDX LAX LDY LDA LDX LAX TAY LDA TAX LAX LDY LDA LDX LAX
Opcode Map
$Bx BCS LDA KIL LAX LDY LDA LDX LAX CLV LDA TSX LAS LDY LDA LDX LAX
$Cx CPY CMP NOP DCP CPY CMP DEC DCP INY CMP DEX SBX CPY CMP DEC DCP
$Dx BNE CMP KIL DCP NOP CMP DEC DCP CLD CMP NOP DCP NOP CMP DEC DCP
$Ex CPX SBC NOP ISC CPX SBC INC ISC INX SBC NOP SBC CPX SBC INC ISC
$Fx BEQ SBC KIL ISC NOP SBC INC ISC SED SBC NOP ISC NOP SBC INC ISC
The following table summarises the base instruction timing for 6502 mode.
Please also read the information for 4510 mode, as it discusses a number of
$x0 $x1 $x2 $x3 $x4 $x5 $x6 $x7 $x8 $x9 $xA $xB $xC $xD $xE $xF
$0x 7 6 9 8 3 3 5 5 3 2 2 2 4 4 6 6
$1x 2b 5p 9 8 4 4p 6 6 2 4p 2 7 4p 4p 7 7
$2x 6 6 9 8 3 3 5 5 4 2 2 2 4 4 6 6
$3x 2b 5p 9 8 4 4 6 6 2 4p 2 7 4p 4p 7 7
$4x 6 6 9 8 3 3 5 5 3 2 2 2 3 4 6 6
$5x 2b 5p 9 8 4 4 6 6 2 4p 2 7 4p 4p 7 7
$6x 6 6 9 8 3 3 5 5 4 2 2 2 5 4 6 6
important factors that affect these figures.
$7x 2b 5p 9 8 4 4 6 6 2 4p 2 7 4p 4p 7 7
510
Instruction Timing
$8x 2 6 2 6 3 3 3 3 2 2 2 2 4 4 4 4
$9x 2b 6 9 6 4 4 4 4 2 5 2 5 5 5 5 5
$Ax 2 6 2 6 3 3 3 3 2 2 2 2 4 4 4 4
$Bx 2b 5p 9 5p 4 4 4 4 2 4p 2 4p 4p 4p 4p 4p
$Cx 2 6 2 8 3 3 5 5 2 2 2 2 4 4 6 6
$Dx 2b 5p 9 8 4 4 6 6 2 4p 2 7 4p 4p 7 7
$Ex 2 6 2 8 3 3 5 5 2 2 2 2 4 4 6 6
$Fx 2b 5p 9 8 4 4 6 6 2 4p 2 7 4p 4p 7 7
b Add one cycle if branch crosses a page boundary.
p Add one cycle if indexing crosses a page boundary.
$x0 $x1 $x2 $x3 $x4 $x5 $x6 $x7 $x8 $x9 $xA $xB $xC $xD $xE $xF
Addressing Mode Table
$0x ($nn,X) ($nn,X) $nn $nn $nn $nn #$nn A #$nn $nnnn $nnnn $nnnn $nnnn
$1x $rr ($nn),Y ($nn),Y $nn,X $nn,X $nn,X $nn,X $nnnn,Y $nnnn,Y $nnnn,X $nnnn,X $nnnn,X $nnnn,X
$2x $nnnn ($nn,X) ($nn,X) $nn $nn $nn $nn #$nn A #$nn $nnnn $nnnn $nnnn $nnnn
$3x $rr ($nn),Y ($nn),Y $nn,X $nn,X $nn,X $nn,X $nnnn,Y $nnnn,Y $nnnn,X $nnnn,X $nnnn,X $nnnn,X
$4x ($nn,X) ($nn,X) $nn $nn $nn $nn #$nn A #$nn $nnnn $nnnn $nnnn $nnnn
$5x $rr ($nn),Y ($nn),Y $nn,X $nn,X $nn,X $nn,X $nnnn,Y $nnnn,Y $nnnn,X $nnnn,X $nnnn,X $nnnn,X
$6x ($nn,X) ($nn,X) $nn $nn $nn $nn #$nn A #$nn ($nnnn) $nnnn $nnnn $nnnn
511
$7x $rr ($nn),Y ($nn),Y $nn,X $nn,X $nn,X $nn,X $nnnn,Y $nnnn,Y $nnnn,X $nnnn,X $nnnn,X $nnnn,X
$8x #$nn ($nn,X) #$nn ($nn,X) $nn $nn $nn $nn #$nn #$nn $nnnn $nnnn $nnnn $nnnn
$9x $rr ($nn),Y ($nn),Y $nn,X $nn,X $nn,Y $nn,Y $nnnn,Y $nnnn,Y $nnnn,X $nnnn,X $nnnn,Y $nnnn,Y
$Ax #$nn ($nn,X) #$nn ($nn,X) $nn $nn $nn $nn #$nn #$nn $nnnn $nnnn $nnnn $nnnn
$Bx $rr ($nn),Y ($nn),Y $nn,X $nn,X $nn,Y $nn,Y $nnnn,Y $nnnn,Y $nnnn,X $nnnn,X $nnnn,Y $nnnn,Y
$Cx #$nn ($nn,X) #$nn ($nn,X) $nn $nn $nn $nn #$nn #$nn $nnnn $nnnn $nnnn $nnnn
$Dx $rr ($nn),Y ($nn),Y $nn,X $nn,X $nn,X $nn,X $nnnn,Y $nnnn,Y $nnnn,X $nnnn,X $nnnn,X $nnnn,X
$Ex #$nn ($nn,X) #$nn ($nn,X) $nn $nn $nn $nn #$nn #$nn $nnnn $nnnn $nnnn $nnnn
$Fx $rr ($nn),Y ($nn),Y $nn,X $nn,X $nn,X $nn,X $nnnn,Y $nnnn,Y $nnnn,X $nnnn,X $nnnn,X $nnnn,X
Official And Unintended Instruc-
tions
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 in-
structions of this legal set are headed by a blue coloured mnemonic.
The remaining opcodes form the set of the unintended instructions (some-
times 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.
The unintended instructions are implemented in the 6502 mode, but are not
guaranteed 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.
ADC
This instruction adds the argument to the contents of the Accumulator Register
and the Carry Flag. 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The V flag will be set if the result has a different sign to both of the
arguments, else 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.
512
ADC : Add with carry 6502
A ← A+M+C
N Z I C D V E
+ + · + · + ·
ALR
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., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted.
513
ANC
This instructions performs a binary AND operation of the argument with the
accumulator, 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 completion. 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, else it will be cleared.
• The C flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
ANC : Binary AND, and Set Carry 6502
A ← A AN D M, C ← A7 AN D M7
N Z I C D V E
+ + · · · · ·
AND
This instructions performs a binary AND operation of the argument with the
accumulator, 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 completion.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
514
AND : Binary AND 6502
A ← A AN D M
N Z I C D V E
+ + · · · · ·
ARR
This instruction shifts the Accumulator one bit right after performing a binary
AND of the Accumulator and the immediate mode argument. Bit 7 is ex-
changed with the carry.
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
515
ASL
This instruction shifts either the Accumulator or contents of the provided mem-
ory location 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., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else 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 6502
A ← A<<1 or M ← M<<1
N Z I C D V E
+ + · + · · ·
BCC
This instruction branches to the indicated address if the Carry Flag is clear.
BCC : Branch on Carry Flag Clear 6502
PC ← PC + R8
N Z I C D V E
· · · · · · ·
516
BCS
This instruction branches to the indicated address if the Carry Flag is set.
BEQ
This instruction branches to the indicated address if the Zero Flag is set.
BIT
This instruction is used to test the bits stored in a memory location. 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 performing the binary AND of the Accumulator Register and the contents
of the indicated memory location.
517
Side effects
• The N flag will be set if the bit 7 of the memory location is set, else it will
be cleared.
• The V flag will be set if the bit 6 of the memory location is set, else it will
be cleared.
BMI
This instruction branches to the indicated address if the Negative Flag is set.
BNE
This instruction branches to the indicated address if the Zero Flag is clear.
518
BNE : Branch on Zero Flag Clear 6502
PC ← PC + R8
N Z I C D V E
· · · · · · ·
BPL
This instruction branches to the indicated address if the Negative Flag is clear.
BPL : Branch on Negative Flag Clear 6502
PC ← PC + R8
N Z I C D V E
· · · · · · ·
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:
519
”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.
BVC
This instruction branches to the indicated address if the Overflow (V) Flag is
clear.
BVC : Branch on Overflow Flag Clear 6502
PC ← PC + R8
N Z I C D V E
· · · · · · ·
BVS
This instruction branches to the indicated address if the Overflow (V) Flag is
set.
520
BVS : Branch on Overflow Flag Set 6502
PC ← PC + R8
N Z I C D V E
· · · · · · ·
CLC
This instruction clears the Carry Flag.
Side effects
CLD
This instruction clears the Decimal Flag. Arithmetic operations will use normal
binary arithmetic, instead of Binary-Coded Decimal (BCD).
Side effects
521
CLD : Clear Decimal Flag 6502
D←0
N Z I C D V E
· · · · · · ·
CLI
This instruction clears the Interrupt Disable Flag. Interrupts will now be able
to occur.
Side effects
CLV
This instruction clears the Overflow Flag.
Side effects
522
CLV : Clear Overflow Flag 6502
V←0
N Z I C D V E
· · · · · · ·
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. bit 7 is set in
the result, else 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, else it will be cleared.
• The Z flag will be set if the result of A − M is zero, else it will be cleared.
N Z I C D V E
+ + · + · · ·
523
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. bit 7 is set in
the result, else 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, else it will be cleared.
• The Z flag will be set if the result of X − M is zero, else it will be cleared.
CPX : Compare X Register 6502
N Z I C D V E
+ + · + · · ·
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. bit 7 is set in
the result, else 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, else it will be cleared.
• The Z flag will be set if the result of Y − M is zero, else it will be cleared.
524
CPY : Compare Y Register 6502
N Z I C D V E
+ + · + · · ·
DCP
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. bit 7 is set in
the result, else it will be cleared.
• The Z flag will be set if the result of A − M is zero, else it will be cleared.
525
DEC
This instruction decrements the Accumulator Register or indicated memory
location.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
DEC : Decrement Memory or Accumulator 6502
A ← A - 1 or M ← M - 1
N Z I C D V E
+ + · · · · ·
DEX
This instruction decrements the X Register.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
DEX : Decrement X Register 6502
X←X-1
N Z I C D V E
+ + · · · · ·
526
DEY
This instruction decrements the Y Register.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
EOR
This instructions performs a binary XOR 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
527
EOR : Binary Exclusive OR 6502
A ← A XOR M
N Z I C D V E
+ + · · · · ·
INC
This instruction increments the Accumulator Register or indicated memory lo-
cation.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
528
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
529
ISC
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. bit 7 is set in
the result, else 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, else it will be cleared.
• The V flag will be set if the result has a different sign to both of the
arguments, else 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, else 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
+ + · + · + ·
JMP
This instruction sets the Programme Counter (PC) Register to the address in-
dicated by the instruction, causing execution to continue from that address.
530
JMP : Jump to Address 6502
PC ← M2:M1
N Z I C D V E
· · · · · · ·
JSR
This instruction saves the address of the instruction following the JSR instruc-
tion onto the stack, and then sets the Programme 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 address on popping it from the stack, before setting the Pro-
gramme Counter (PC) register.
JSR : Jump to Sub-Routine 6502
PC ← M2:M1, Stack ← PCH:PCL
N Z I C D V E
· · · · · · ·
KIL
On a 6502, these instructions cause the processor to enter an infinite loop
in their internal logic that can only be aborted by resetting the computer.
On the 45GS02 these instructions cause Hypervisor Traps. Or rather, they
will, 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 programme to be aborted or crash.
531
KIL : Lock-up 6502 Processor 6502
N Z I C D V E
· · · · · · ·
LAS
NOTE: This monstrosity of an instruction, aside from being devoid of any con-
ceivable 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
532
LAS : Set Accumulator, X Register and SPL Register With Useless Value 650
SP, A, X ← SP AN D M
N Z I C D V E
· · · · · · ·
LAX
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
533
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
LDX
This instruction loads the X Register with the indicated value, or with the con-
tents of the indicated location.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
534
LDX : Load X Register 6502
X←M
N Z I C D V E
+ + · · · · ·
LDY
This instruction loads the Y Register with the indicated value, or with the con-
tents of the indicated location.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
535
LSR
This instruction shifts either the Accumulator or contents of the provided mem-
ory location 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., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted.
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.
536
NOP : No-Operation (some are unintended opcodes) 6502
N Z I C D V E
· · · · · · ·
ORA
This instructions performs a binary OR operation of the argument with the
accumulator, and stores the result in the accumulator. Only bits that were
537
already set in the accumulator, 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
PHA
This instruction pushes the contents of the Accumulator Register onto the
stack, and decrements the value of the Stack Pointer by 1.
538
PHP
This instruction pushes the contents of the Processor Flags onto the stack, and
decrements the value of the Stack Pointer by 1.
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.
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)
539
PLP : Pull Accumulator Register from the Stack 6502
A ← STACK, SP ← SP + 1
N Z I C D V E
+ + + + + + ·
RLA
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.
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
540
ROL
This instruction shifts either the Accumulator or contents of the provided mem-
ory 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
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
ROL : Rotate Left Memory or Accumulator 6502
M ← M<<1, C ← M(7), M(0) ← C
N Z I C D V E
+ + · + · · ·
ROR
This instruction shifts either the Accumulator or contents of the provided mem-
ory 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
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
541
ROR : Rotate Right Memory or Accumulator 6502
M ← M>>1, C ← M(0), M(7) ← C
N Z I C D V E
+ + · + · · ·
RRA
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.
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if the addition results in an overflow in the Accu-
mulator.
RRA : Rotate Right Memory, and Add to Accumulator 6502
M ← M>>1, C ← M(0), M(7) ← C, A ← A + M>>1 + C
N Z I C D V E
+ + · + · · ·
542
RTI
This instruction pops the processor flags from the stack, and then pops the
Programme Counter (PC) register from the stack, allowing an interrupted pro-
gramme 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, SP ← SP + 3
N Z I C D V E
+ · + + + + ·
RTS
This instruction adds optional argument to the Stack Pointer (SP) Register,
and then pops the Programme Counter (PC) register from the stack, allowing
a routine to return to its caller.
RTS : Return From Subroutine 6502
PC ← STACK + N, SP ← SP + 2 + N
N Z I C D V E
· · · · · · ·
SAX
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.
543
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. bit 7 is set in
the result, else 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, else it will be cleared.
• The V flag will be set if the result has a different sign to both of the
arguments, else 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, else it will be cleared.
SAX : AND Accumulator and X, and Subtract Without Carry 6502
X ← (A AN D X) - Value
N Z I C D V E
+ + · + · + ·
SBC
This instruction performs A − M - 1 + C, and sets the processor flags accord-
ingly. 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. bit 7 is set in
the result, else 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, else it will be cleared.
544
• The V flag will be set if the result has a different sign to both of the
arguments, else 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, else it will be cleared.
SBX
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if the result is zero or positive, else it will be cleared.
545
SBX : AND and Subtract 6502
X ← ( A AN D X ) - V
N Z I C D V E
+ + · · · · ·
SEC
This instruction sets the Carry Flag.
Side effects
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
546
SED : Set Decimal Flag 6502
D←1
N Z I C D V E
· · · · · · ·
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
SHA
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 Reg-
ister, X Register and the third byte of the instruction into the indicated loca-
tion.
547
SHA : Store binary AND of A, X and 3rd Instruction Byte 6502
M ← A AN D X AN D B3
N Z I C D V E
· · · · · · ·
SHX
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.
SHX : Store Binary AND of X Register and 3rd Instruction Byte 6502
M ← X AN D B3
N Z I C D V E
· · · · · · ·
SHY
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 AN D B3
N Z I C D V E
· · · · · · ·
548
SLO
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., if bit 7 of the Accumu-
lator is set after the instruction completes, else it will be cleared.
• The Z flag will be set if the Accumulator contains $00 after the instruction
has completed, else it will be cleared.
• The C flag will be set if bit 7 of the memory contents was set, prior to
being shifted.
SRE
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.
549
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted.
STA
This instruction stores the contents of the Accumulator Register into the indi-
cated location.
STA : Store Accumulator 6502
M←A
N Z I C D V E
· · · · · · ·
550
STX
This instruction stores the contents of the X Register into the indicated loca-
tion.
STX : Store X Register 6502
M←X
N Z I C D V E
· · · · · · ·
STY
This instruction stores the contents of the Y Register into the indicated loca-
tion.
STY : Store Y Register 6502
M←Y
N Z I C D V E
· · · · · · ·
TAS
NOTE: This monstrosity of an instruction, aside from being devoid of any con-
ceivable 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.
551
Side effects
TAX
This instruction loads the X Register with the contents of the Accumulator Reg-
ister.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
TAX : Transfer Accumulator Register into the X Register 6502
X←A
N Z I C D V E
+ + · · · · ·
TAY
This instruction loads the Y Register with the contents of the Accumulator Reg-
ister.
552
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
TSX
This instruction loads the X Register with the contents of the Stack Pointer
High (SPL) Register.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
TSX : Transfer Stack Pointer High Register into the X Register 6502
X ← SPH
N Z I C D V E
+ + · · · · ·
TXA
This instruction loads the Accumulator Register with the contents of the X Reg-
ister.
553
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
TXS
This instruction sets the low byte of the Stack Pointer (SPL) register to the
contents of the X Register.
TYA
This instruction loads the Accumulator Register with the contents of the Y Reg-
ister.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
554
TYA : Transfer Y Register into the Accumulator Register 6502
A←Y
N Z I C D V E
+ + · · · · ·
XAA
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
XAA : Transfer X into the Accumulator and AND with operand 6502
A ← X AN D VALUE
N Z I C D V E
+ + · · · · ·
555
$x0 $x1 $x2 $x3 $x4 $x5 $x6 $x7 $x8 $x9 $xA $xB $xC $xD $xE $xF
$0x BRK ORA CLE SEE TSB ORA ASL RMB0 PHP ORA ASL TSY TSB ORA ASL BBR0
$1x BPL ORA ORA BPL TRB ORA ASL RMB1 CLC ORA INC INZ TRB ORA ASL BBR1
$2x JSR AND JSR JSR BIT AND ROL RMB2 PLP AND ROL TYS BIT AND ROL BBR2
$3x BMI AND AND BMI BIT AND ROL RMB3 SEC AND DEC DEZ BIT AND ROL BBR3
$4x RTI EOR NEG ASR ASR EOR LSR RMB4 PHA EOR LSR TAZ JMP EOR LSR BBR4
$5x BVC EOR EOR BVC ASR EOR LSR RMB5 CLI EOR PHY TAB MAP EOR LSR BBR5
$6x RTS ADC RTS BSR STZ ADC ROR RMB6 PLA ADC ROR TZA JMP ADC ROR BBR6
556
$7x BVS ADC ADC BVS STZ ADC ROR RMB7 SEI ADC PLY TBA JMP ADC ROR BBR7
$8x BRA STA STA BRA STY STA STX SMB0 DEY BIT TXA STY STY STA STX BBS0
$9x BCC STA STA BCC STY STA STX SMB1 TYA STA TXS STX STZ STA STZ BBS1
$Ax LDY LDA LDX LDZ LDY LDA LDX SMB2 TAY LDA TAX LDZ LDY LDA LDX BBS2
Opcode Map
$Bx BCS LDA LDA BCS LDY LDA LDX SMB3 CLV LDA TSX LDZ LDY LDA LDX BBS3
$Cx CPY CMP CPZ DEW CPY CMP DEC SMB4 INY CMP DEX ASW CPY CMP DEC BBS4
$Dx BNE CMP CMP BNE CPZ CMP DEC SMB5 CLD CMP PHX PHZ CPZ CMP DEC BBS5
$Ex CPX SBC LDA INW CPX SBC INC SMB6 INX SBC EOM ROW CPX SBC INC BBS6
$Fx BEQ SBC SBC BEQ PHW SBC INC SMB7 SED SBC PLX PLZ PHW SBC INC BBS7
Instruction Timing
The following table lists the base cycle count for each opcode. 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:
Note that it is possible that further changes to processor timing will occur.
557
$x0 $x1 $x2 $x3 $x4 $x5 $x6 $x7 $x8 $x9 $xA $xB $xC $xD $xE $xF
$0x 7 6pr 1s 1s 3r 3r 4r 4br 2 2 1s 1s 5r 4r 5r
$1x 2b 5pr 5pr 3b 5r 3r 4r 4br 1s 4r 1s 1s 4r 4pr 5pr 5b
$2x 5 5pr 5r 5pr 3r 3r 4r 4r 4m 2 1s 1s 4r 4r 5r 5b
$3x 2r 5pr 5pr 3b 3pr 4pr 5pr 4r 1s 4r 1s 1s 4pr 4pr 5pr 4b
$4x 6m 5r 1s 1s 4r 3r 4r 4r 2 2 1s 1s 3 4r 5r 4br
$5x 2b 5pr 5pr 3b 5pr 3p 3pr 4r 1s 4pr 2 1s 1s 4pr 5pr 4br
$6x 6m 5r 4 3b 3 3r 5r 5r 4m 2 1s 1s 5r 4r 6r 4br
$7x 2b 5pr 5pr 3b 3 3r 4r 4r
$8x
$9x
558
$Ax
$Bx
$Cx
$Dx
$Ex
$Fx
b Add one cycle if branch crosses a page boundary.
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.
$x0 $x1 $x2 $x3 $x4 $x5 $x6 $x7 $x8 $x9 $xA $xB $xC $xD $xE $xF
Addressing Mode Table
$0x ($nn,X) $nn $nn $nn $nn #$nn A $nnnn $nnnn $nnnn $nn,$rr
$1x $rr ($nn),Y ($nn),Z $rrrr $nn $nn,X $nn,X $nn $nnnn,Y A $nnnn $nnnn,X $nnnn,X $nn,$rr
$2x $nnnn ($nn,X) ($nnnn) ($nnnn,X) $nn $nn $nn $nn #$nn A $nnnn $nnnn $nnnn $nn,$rr
$3x $rr ($nn),Y ($nn),Z $rrrr $nn,X $nn,X $nn,X $nn $nnnn,Y A $nnnn,X $nnnn,X $nnnn,X $nn,$rr
$4x ($nn,X) A A $nn $nn $nn $nn #$nn A $nnnn $nnnn $nnnn $nn,$rr
$5x $rr ($nn),Y ($nn),Z $rrrr $nn,X $nn,X $nn,X $nn $nnnn,Y $nnnn,X $nnnn,X $nn,$rr
$6x ($nn,X) #$nn $rrrr $nn $nn $nn $nn #$nn A ($nnnn) $nnnn $nnnn $nn,$rr
559
$7x $rr ($nn),Y ($nn),Z $rrrr $nn,X $nn,X $nn,X $nn $nnnn,Y ($nnnn,X) $nnnn,X $nnnn,X $nn,$rr
$8x $rr ($nn,X) ($nn,SP),Y $rrrr $nn $nn $nn $nn #$nn $nnnn,X $nnnn $nnnn $nnnn $nn,$rr
$9x $rr ($nn),Y ($nn),Z $rrrr $nn,X $nn,X $nn,Y $nn $nnnn,Y $nnnn,Y $nnnn $nnnn,X $nnnn,X $nn,$rr
$Ax #$nn ($nn,X) #$nn #$nn $nn $nn $nn $nn #$nn $nnnn $nnnn $nnnn $nnnn $nn,$rr
$Bx $rr ($nn),Y ($nn),Z $rrrr $nn,X $nn,X $nn,Y $nn $nnnn,Y $nnnn,X $nnnn,X $nnnn,X $nnnn,Y $nn,$rr
$Cx #$nn ($nn,X) #$nn $nn $nn $nn $nn $nn #$nn $nnnn $nnnn $nnnn $nnnn $nn,$rr
$Dx $rr ($nn),Y ($nn),Z $rrrr $nn $nn,X $nn,X $nn $nnnn,Y $nnnn $nnnn,X $nnnn,X $nn,$rr
$Ex #$nn ($nn,X) ($nn,SP),Y $nn $nn $nn $nn $nn #$nn $nnnn $nnnn $nnnn $nnnn $nn,$rr
$Fx $rr ($nn),Y ($nn),Z $rrrr #$nnnn $nn,X $nn,X $nn $nnnn,Y $nnnn $nnnn,X $nnnn,X $nn,$rr
ADC
This instruction adds the argument to the contents of the Accumulator Register
and the Carry Flag. 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The V flag will be set if the result has a different sign to both of the
arguments, else 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
+ + · + · + ·
AND
This instructions performs a binary AND operation of the argument with the
accumulator, and stores the result in the accumulator. Only bits that were
560
already set in the accumulator, and that are set in the argument will be set in
the accumulator on completion.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
AND : Binary AND 4510
A ← A AN D M
N Z I C D V E
+ + · · · · ·
ASL
This instruction shifts either the Accumulator or contents of the provided mem-
ory location 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., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
561
ASL : Arithmetic Shift Left 4510
A ← A<<1 or M ← M<<1
N Z I C D V E
+ + · + · · ·
ASR
This instruction shifts either the Accumulator or contents of the provided mem-
ory location 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., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted.
562
ASR : Arithmetic Shift Right 4510
A ← A>>1 or M ← M>>1
N Z I C D V E
+ + · + · · ·
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 containing $53, and the Carry Flag being set.
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 of the upper
byte is set after the operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 7 of the upper byte was set, prior to being
shifted.
ASW : Arithmetic Shift Word Left 4510
M ← M<<1
N Z I C D V E
+ + · + · · ·
563
BBR0
This instruction branches to the indicated address if bit 0 is clear in the indi-
cated base-page memory location.
BBR1
This instruction branches to the indicated address if bit 1 is clear in the indi-
cated base-page memory location.
BBR2
This instruction branches to the indicated address if bit 2 is clear in the indi-
cated base-page memory location.
564
BBR2 : Branch on Bit 2 Reset 4510
PC ← PC + R8
N Z I C D V E
· · · · · · ·
BBR3
This instruction branches to the indicated address if bit 3 is clear in the indi-
cated base-page memory location.
BBR3 : Branch on Bit 3 Reset 4510
PC ← PC + R8
N Z I C D V E
· · · · · · ·
BBR4
This instruction branches to the indicated address if bit 4 is clear in the indi-
cated base-page memory location.
BBR4 : Branch on Bit 4 Reset 4510
PC ← PC + R8
N Z I C D V E
· · · · · · ·
565
BBR5
This instruction branches to the indicated address if bit 5 is clear in the indi-
cated base-page memory location.
BBR6
This instruction branches to the indicated address if bit 6 is clear in the indi-
cated base-page memory location.
BBR7
This instruction branches to the indicated address if bit 7 is clear in the indi-
cated base-page memory location.
566
BBR7 : Branch on Bit 7 Reset 4510
PC ← PC + R8
N Z I C D V E
· · · · · · ·
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
PC ← PC + R8
N Z I C D V E
· · · · · · ·
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
PC ← PC + R8
N Z I C D V E
· · · · · · ·
BBS2
This instruction branches to the indicated address if bit 2 is set in the indicated
base-page memory location.
567
BBS2 : Branch on Bit 2 Set 4510
PC ← PC + R8
N Z I C D V E
· · · · · · ·
BBS3
This instruction branches to the indicated address if bit 3 is set in the indicated
base-page memory location.
BBS3 : Branch on Bit 3 Set 4510
PC ← PC + R8
N Z I C D V E
· · · · · · ·
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
PC ← PC + R8
N Z I C D V E
· · · · · · ·
BBS5
This instruction branches to the indicated address if bit 5 is set in the indicated
base-page memory location.
568
BBS5 : Branch on Bit 5 Set 4510
PC ← PC + R8
N Z I C D V E
· · · · · · ·
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
PC ← PC + R8
N Z I C D V E
· · · · · · ·
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
PC ← PC + R8
N Z I C D V E
· · · · · · ·
BCC
This instruction branches to the indicated address if the Carry Flag is clear.
569
BCC : Branch on Carry Flag Clear 4510
PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
BCS
This instruction branches to the indicated address if the Carry Flag is set.
BEQ
This instruction branches to the indicated address if the Zero Flag is set.
570
BIT
This instruction is used to test the bits stored in a memory location. 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 performing the binary AND of the Accumulator Register and the contents
of the indicated memory location.
Side effects
• The N flag will be set if the bit 7 of the memory location is set, else it will
be cleared.
• The V flag will be set if the bit 6 of the memory location is set, else it will
be cleared.
BMI
This instruction branches to the indicated address if the Negative Flag is set.
571
BMI : Branch on Negative Flag Set 4510
PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
BNE
This instruction branches to the indicated address if the Zero Flag is clear.
BNE : Branch on Zero Flag Clear 4510
PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
BPL
This instruction branches to the indicated address if the Negative Flag is clear.
BPL : Branch on Negative Flag Clear 4510
PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
572
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
· · · · · · ·
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:
”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.
573
BRK : Break to Interrupt 4510
PC ← ($FFFE)
N Z I C D V E
· · · · · · ·
BSR
This instruction branches to the indicated address, saving the address of the
caller on the stack, so that the routine can be returned from using an RTS
instruction.
BVC
This instruction branches to the indicated address if the Overflow (V) Flag is
clear.
574
BVC : Branch on Overflow Flag Clear 4510
PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
BVS
This instruction branches to the indicated address if the Overflow (V) Flag is
set.
BVS : Branch on Overflow Flag Set 4510
PC ← PC + R8 or PC ← PC + R16
N Z I C D V E
· · · · · · ·
CLC
This instruction clears the Carry Flag.
Side effects
575
CLC : Clear Carry Flag 4510
C←0
N Z I C D V E
· · · · · · ·
CLD
This instruction clears the Decimal Flag. Arithmetic operations will use normal
binary arithmetic, instead of Binary-Coded Decimal (BCD).
Side effects
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
576
CLE : Clear Extended Stack Disable Flag 4510
E←0
N Z I C D V E
· · · · · · ·
CLI
This instruction clears the Interrupt Disable Flag. Interrupts will now be able
to occur.
Side effects
CLV
This instruction clears the Overflow Flag.
Side effects
577
CLV : Clear Overflow Flag 4510
V←0
N Z I C D V E
· · · · · · ·
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. bit 7 is set in
the result, else 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, else it will be cleared.
• The Z flag will be set if the result of A − M is zero, else it will be cleared.
N Z I C D V E
+ + · + · · ·
578
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. bit 7 is set in
the result, else 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, else it will be cleared.
• The Z flag will be set if the result of X − M is zero, else it will be cleared.
CPX : Compare X Register 4510
N Z I C D V E
+ + · + · · ·
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. bit 7 is set in
the result, else 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, else it will be cleared.
• The Z flag will be set if the result of Y − M is zero, else it will be cleared.
579
CPY : Compare Y Register 4510
N Z I C D V E
+ + · + · · ·
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. bit 7 is set in
the result, else 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, else it will be cleared.
• The Z flag will be set if the result of Z − M is zero, else it will be cleared.
CPZ : Compare Z Register 4510
N Z I C D V E
+ + · + · · ·
DEC
This instruction decrements the Accumulator Register or indicated memory
location.
580
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
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 to be set to $77.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
581
DEX
This instruction decrements the X Register.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
DEY
This instruction decrements the Y Register.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
582
DEZ
This instruction decrements the Z Register.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
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 in-
struction, allowing interrupts to occur again.
Second, it instructs the processor that if the following instruction uses Base-
Page Indirect 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 ad-
dressing mode causes a two cycle penalty, caused by the time required to
read the extra two bytes of the pointer.
583
Side effects
• Removes the prohibition on all interrupts caused by the the MAP instruc-
tion, allowing Non-Maskable Interrupts to again occur, and IRQ inter-
rupts, if the Interrupt Disable Flag is not set.
N Z I C D V E
· · · · · · ·
EOR
This instructions performs a binary XOR 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
584
EOR : Binary Exclusive OR 4510
A ← A XOR M
N Z I C D V E
+ + · · · · ·
INC
This instruction increments the Accumulator Register or indicated memory lo-
cation.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
INC : Increment Memory or Accumulator 4510
A ← A + 1 or M ← M + 1
N Z I C D V E
+ + · · · · ·
585
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 DEW $12 would cause memory location to be set to $79.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
INW : Increment Memory Word 4510
M16 ← M16 + 1
N Z I C D V E
+ + · · · · ·
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
INX : Increment X Register 4510
X←X+1
N Z I C D V E
+ + · · · · ·
586
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
INZ
This instruction increments the Z Register, i.e., adds 1 to it.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
587
JMP
This instruction sets the Programme Counter (PC) Register to the address in-
dicated 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
· · · · · · ·
JSR
This instruction saves the address of the instruction following the JSR instruc-
tion onto the stack, and then sets the Programme 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 address on popping it from the stack, before setting the Pro-
gramme Counter (PC) register.
JSR : Jump to Sub-Routine 4510
PC ← M2:M1, Stack ← PCH:PCL
N Z I C D V E
· · · · · · ·
588
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
LDA : Load Accumulator 4510
A←M
N Z I C D V E
+ + · · · · ·
LDX
This instruction loads the X Register with the indicated value, or with the con-
tents of the indicated location.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
589
LDX : Load X Register 4510
X←M
N Z I C D V E
+ + · · · · ·
LDY
This instruction loads the Y Register with the indicated value, or with the con-
tents of the indicated location.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
LDY : Load Y Register 4510
Y←M
N Z I C D V E
+ + · · · · ·
LDZ
This instruction loads the Z Register with the indicated value, or with the con-
tents of the indicated location.
590
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
LSR
This instruction shifts either the Accumulator or contents of the provided mem-
ory location 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., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted.
591
LSR : Logical Shift Right 4510
A ← A>>1, C ← A(0) or M ← M>>1
N Z I C D V E
+ + · + · · ·
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 instruc-
tion. Failure to do so will result in unpredictable results.
Further information on this instruction is available in Appendix G.
Side effects
N Z I C D V E
· · · · · · ·
592
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
ORA
This instructions 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 accumulator, 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
593
ORA : Decrement Memory or Accumulator 4510
A ← A + 1 or M ← M + 1
N Z I C D V E
+ + · · · · ·
PHA
This instruction pushes the contents of the Accumulator Register onto the
stack, and decrements the value of the Stack Pointer by 1.
PHP
This instruction pushes the contents of the Processor Flags onto the stack, and
decrements the value of the Stack Pointer by 1.
594
PHP : Push Processor Flags onto the Stack 4510
STACK ← P, SP ← SP - 1
N Z I C D V E
· · · · · · ·
PHW
This instruction pushes either a 16 bit literal value or the memory word indi-
cated onto the stack, and decrements the value of the Stack Pointer by 2.
PHX
This instruction pushes the contents of the X Register onto the stack, and
decrements the value of the Stack Pointer by 1.
595
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
· · · · · · ·
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
· · · · · · ·
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
+ + · · · · ·
596
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)
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.
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.
597
PLY : Pull Y Register from the Stack 4510
Y ← STACK, SP ← SP + 1
N Z I C D V E
+ + · · · · ·
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.
RMB0
This instruction clears bit zero of the indicated address. No flags are modified,
regardless of the result.
598
RMB1
This instruction clears bit 1 of the indicated address. No flags are modified,
regardless of the result.
RMB2
This instruction clears bit 2 of the indicated address. No flags are modified,
regardless of the result.
RMB3
This instruction clears bit 3 of the indicated address. No flags are modified,
regardless of the result.
599
RMB3 : Reset Bit 3 in Base Page 4510
M(3) ← 0
N Z I C D V E
· · · · · · ·
RMB4
This instruction clears bit 4 of the indicated address. No flags are modified,
regardless of the result.
RMB5
This instruction clears bit 5 of the indicated address. No flags are modified,
regardless of the result.
600
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
· · · · · · ·
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
· · · · · · ·
ROL
This instruction shifts either the Accumulator or contents of the provided mem-
ory 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
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 is set after the
operation, else it will be cleared.
601
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
ROR
This instruction shifts either the Accumulator or contents of the provided mem-
ory 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
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
602
ROR : Rotate Right Memory or Accumulator 4510
M ← M>>1, C ← M(0), M(7) ← C
N Z I C D V E
+ + · + · · ·
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., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else 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
+ + · + · · ·
603
RTI
This instruction pops the processor flags from the stack, and then pops the
Programme Counter (PC) register from the stack, allowing an interrupted pro-
gramme 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, SP ← SP + 3
N Z I C D V E
+ · + + + + ·
RTS
This instruction adds optional argument to the Stack Pointer (SP) Register,
and then pops the Programme Counter (PC) register from the stack, allowing
a routine to return to its caller.
RTS : Return From Subroutine 4510
PC ← STACK + N, SP ← SP + 2 + N
N Z I C D V E
· · · · · · ·
SBC
This instruction performs A − M - 1 + C, and sets the processor flags accord-
ingly. The result is stored in the Accumulator Register.
604
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. bit 7 is set in
the result, else 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, else it will be cleared.
• The V flag will be set if the result has a different sign to both of the
arguments, else 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, else it will be cleared.
SBC : Subtract With Carry 4510
A←-M-1+C
N Z I C D V E
+ + · + · + ·
SEC
This instruction sets the Carry Flag.
Side effects
605
SEC : Set Carry Flag 4510
C←1
N Z I C D V E
· · · · · · ·
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
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.
606
Side effects
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
SMB0
This instruction sets bit zero of the indicated address. No flags are modified,
regardless of the result.
607
SMB0 : Set Bit 0 in Base Page 4510
M(0) ← 1
N Z I C D V E
· · · · · · ·
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
· · · · · · ·
SMB2
This instruction sets bit 2 of the indicated address. No flags are modified,
regardless of the result.
SMB2 : Set Bit 2 in Base Page 4510
M(2) ← 1
N Z I C D V E
· · · · · · ·
SMB3
This instruction sets bit 3 of the indicated address. No flags are modified,
regardless of the result.
608
SMB3 : Set Bit 3 in Base Page 4510
M(3) ← 1
N Z I C D V E
· · · · · · ·
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
· · · · · · ·
SMB5
This instruction sets bit 5 of the indicated address. No flags are modified,
regardless of the result.
SMB5 : Set Bit 5 in Base Page 4510
M(5) ← 1
N Z I C D V E
· · · · · · ·
SMB6
This instruction sets bit 6 of the indicated address. No flags are modified,
regardless of the result.
609
SMB6 : Set Bit 6 in Base Page 4510
M(6) ← 1
N Z I C D V E
· · · · · · ·
SMB7
This instruction sets bit 7 of the indicated address. No flags are modified,
regardless of the result.
STA
This instruction stores the contents of the Accumulator Register into the indi-
cated location.
610
STA : Store Accumulator 4510
M←A
N Z I C D V E
· · · · · · ·
STX
This instruction stores the contents of the X Register into the indicated loca-
tion.
STY
This instruction stores the contents of the Y Register into the indicated loca-
tion.
611
STY : Store Y Register 4510
M←Y
N Z I C D V E
· · · · · · ·
STZ
This instruction stores the contents of the Z Register into the indicated loca-
tion.
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.
612
TAB : Transfer Accumulator into Base Page Register 4510
B←A
N Z I C D V E
· · · · · · ·
TAX
This instruction loads the X Register with the contents of the Accumulator Reg-
ister.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
TAX : Transfer Accumulator Register into the X Register 4510
X←A
N Z I C D V E
+ + · · · · ·
TAY
This instruction loads the Y Register with the contents of the Accumulator Reg-
ister.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
613
TAY : Transfer Accumulator Register into the Y Register 4510
Y←A
N Z I C D V E
+ + · · · · ·
TAZ
This instruction loads the Z Register with the contents of the Accumulator Reg-
ister.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
TAZ : Transfer Accumulator Register into the Z Register 4510
Z←A
N Z I C D V E
+ + · · · · ·
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
614
TBA : Transfer Base Page Register into the Accumulator 4510
A←B
N Z I C D V E
+ + · · · · ·
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.
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.
615
TSB
This instruction sets performs a binary OR of the Accumulator Register and the
indicated 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
· + · · · · ·
TSX
This instruction loads the X Register with the contents of the Stack Pointer
High (SPL) Register.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
616
TSX : Transfer Stack Pointer High Register into the X Register 4510
X ← SPH
N Z I C D V E
+ + · · · · ·
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
TSY : Transfer Stack Pointer High Register into the Y Register 4510
Y ← SPH
N Z I C D V E
+ + · · · · ·
TXA
This instruction loads the Accumulator Register with the contents of the X Reg-
ister.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
617
TXA : Transfer X Register into the Accumulator Register 4510
A←X
N Z I C D V E
+ + · · · · ·
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
· · · · · · ·
TYA
This instruction loads the Accumulator Register with the contents of the Y Reg-
ister.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
TYA : Transfer Y Register into the Accumulator Register 4510
A←Y
N Z I C D V E
+ + · · · · ·
618
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.
TZA
This instruction loads the Accumulator Register with the contents of the Z Reg-
ister.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
619
45GS02 COMPOUND
INSTRUCTIONS
As the 4510 has no unallocated opcodes, the 45GS02 uses compound in-
structions to implement its extension. These compound instructions consist
of one or more single-byte instructions placed immediately before a conven-
tional instruction. These prefixes instruct the 45GS02 to treat the following
instruction differently, as described in Chapter G.
ADC
This instruction adds the argument to the contents of the Accumulator Register
and the Carry Flag. 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The V flag will be set if the result has a different sign to both of the
arguments, else 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
+ + · + · + ·
620
ADCQ
This instruction adds the argument to the contents of the 32-bit Q pseudo-
register Register and the Carry Flag. If the D flag is set, then the operation is
undefined, and is subject to change.
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The V flag will be set if the result has a different sign to both of the
arguments, else 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 if the D flag is clear.
AND
This instructions performs a binary AND operation of the argument with the
accumulator, 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 completion.
621
Side effects
• The N flag will be set if the result is negative, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
ANDQ
This instructions 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 that 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
622
ANDQ : Binary AND 45GS02
Q ← Q AN D M
N Z I C D V E
+ + · · · · ·
ASLQ
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
623
ASLQ : Arithmetic Shift Left 45GS02
Q ← Q<<1 or M ← M<<1
N Z I C D V E
+ + · + · · ·
ASRQ
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
624
ASRQ : Arithmetic Shift Left 45GS02
Q ← Q<<1 or M ← M<<1
N Z I C D V E
· · · · · · ·
BITQ
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 i31 will be
shifted out into the Carry Flag
Side effects
• The N flag will be set if the result is negative, i.e., if bit 7 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 7 of the value was set, prior to being shifted.
625
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. bit 7 is set in
the result, else 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, else it will be cleared.
• The Z flag will be set if the result of A − M is zero, else it will be cleared.
CMP : Compare Accumulator 45GS02
N Z I C D V E
+ + · + · · ·
CMPQ
This instruction performs Q − M, and sets the processor flags accordingly,
but does not modify the contents of the Q Register. The memory location is
treated as the address of a little-endian 32-bit value.
Side effects
• The N flag will be set if the result of A − M is negative, i.e. bit 31 is set
in the result, else 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, else it will be cleared.
• The Z flag will be set if the result of A − M is zero, else it will be cleared.
626
CMPQ : Compare Q Pseudo Register 45GS02
N Z I C D V E
+ + · + · · ·
DEQ
Note that 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
627
DEQ : Decrement Memory or Q 45GS02
Q ← Q - 1 or M ← M - 1
N Z I C D V E
+ + · · · · ·
EOR
This instructions performs a binary XOR 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
628
EORQ
This instructions performs a binary XOR 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., bit 31 is set, else it will
be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
EORQ : Binary Exclusive OR 45GS02
Q ← Q XOR M
N Z I C D V E
+ + · · · · ·
INQ
This instruction increments the Q pseudo register or indicated memory loca-
tion.
Note that 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, else it will be cleared.
629
• The Z flag will be set if the result is zero, else it will be cleared.
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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
630
LDQ
This instruction loads the Q pseudo register with the indicated value, or with
the contents 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., bit 31 is set, else it will
be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
LDQ : Load Q Pseudo Register 45GS02
Q←M
N Z I C D V E
+ + · · · · ·
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.
631
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., if bit 31 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 0 of the value was set, prior to being shifted.
LSRQ : Logical Shift Right 45GS02
Q ← Q>>1, C ← A(0) or M ← M>>1
N Z I C D V E
+ + · + · · ·
ORA
This instructions 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 accumulator, 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
632
ORA : Decrement Memory or Accumulator 45GS02
A ← A + 1 or M ← M + 1
N Z I C D V E
+ + · · · · ·
ORQ
This instructions 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, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
ORQ : Decrement Memory or Q 45GS02
Q ← Q + 1 or M ← M + 1
N Z I C D V E
+ + · · · · ·
633
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 programme.
634
ROLQ
This instruction shifts either the Accumulator or contents of the provided mem-
ory 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.
Side effects
• The N flag will be set if the result is negative, i.e., if bit 31 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 31 of the value was set, prior to being shifted.
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
635
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., if bit 31 is set after the
operation, else it will be cleared.
• The Z flag will be set if the result is zero, else it will be cleared.
• The C flag will be set if bit 31 of the value was set, prior to being shifted.
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 programme.
636
RSVQ : Reserved extended opcode 45GS02
UNDEFINED
N Z I C D V E
· · · · · · ·
SBC
This instruction performs A − M - 1 + C, and sets the processor flags accord-
ingly. 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. bit 7 is set in
the result, else 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, else it will be cleared.
637
• The V flag will be set if the result has a different sign to both of the
arguments, else 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, else it will be cleared.
SBCQ
This instruction performs Q − M - 1 + C, and sets the processor flags accord-
ingly. The result is stored in the Q pseudi register.
Note: that the indicated memory location is treated as the first byte of a 32-
bit little-endian value.
Note: The decimal (D) flag must be clear. Operation is reserved when D flag
is set.
Side effects
• The N flag will be set if the result of A − M is negative, i.e. bit 31 is set
in the result, else it will be cleared.
• The V flag will be set if the result has a different sign to both of the
arguments, else 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, else it will be cleared.
638
SBCQ : Subtract With Carry 45GS02
Q←-M-1+C
N Z I C D V E
+ + · + · + ·
STA
This instruction stores the contents of the Accumulator Register into the indi-
cated location.
STA : Store Accumulator 45GS02
M←A
N Z I C D V E
· · · · · · ·
STQ
This instruction stores the contents of the Q pseudo register into the indicated
location.
639
STQ : Store Q 45GS02
M ← Q = M+0 ← A, ... , M+3 ← Z
N Z I C D V E
· · · · · · ·
640
APPENDIX I
Machine Language Monitor
• Introduction
• Table of monitor commands
• calling the monitor
642
INTRODUCTION
The machine language monitor is a debugging tool for machine language
programs. It includes a mini-assembler, a disassembler and many useful com-
mands. When the program execution encounters the code 00 (zero) alias BRK,
the default action of the operating system is, to call the monitor. This features
allows the debugging of programs by setting breakpoints.
643
The monitor responds with a display of register contents and waits for a com-
mand:
PC SR AC XR YR ZR SP
; 000000 00 00 00 00 00 f8
D : DISASSEMBLE
Usage: Prints a machine language listing for the specified address range
assuming, that it contains code. If only one argument is present,
the disassembler disassembles the next 21 bytes. If no argument
is given, the disassembly continues with the last used disassem-
ble address. The contents 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 mem-
ory, if writable RAM is there. See monitor command ..
Example: Using D
644
M : MEMORY
Format: M [from [,to]]
Usage: Prints a memory dump for the given address range. The dump
displays memory contents, organized 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. ar-
gument 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 editing 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
645
646
APPENDIX J
F018-Compatible Direct
Memory Access (DMA)
Controller
• Audio DMA
• MEGA65 Enhanced DMA Jobs
• F018 “DMAgic” DMA Controller
• MEGA65 DMA Controller Extensions
• Unimplemented Functionality
648
The MEGA65 includes an F018/F018A backward-compatible DMA con-
troller. 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.
649
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 simultane-
ously 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 proces-
sor 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
650
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 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.
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.
651
Volume is controlled by setting $D629. 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 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 play-
ing to produce various effects.
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.
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 nybl 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.
652
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 fol-
lows the end of job options token ($00). Job option tokens which take an
argument have the most-significant bit set, and always 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 future revi-
sions of the DMAgic to add support for additional options, without breaking
backward compatibility.
The list of valid job option tokens is:
$00 End of job option list
$06 Enable use of transparent value
$07 Disable use of transparent value
$0A Use 11-byte F011A DMA list format
$0B Use 12-byte F011B DMA list format
$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)
653
…continued
HEX DEC Signal Description
DMA list address bank (address bits 16
D702 55042 ADDRBANK
– 22). Writing clears $D704.
654
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D732 55090 CH1BADDR
D733 55091 CH1BADDR
D734 55092 CH1FREQ
D735 55093 CH1FREQ
D736 55094 CH1FREQ
D737 55095 CH1TADDR
D738 55096 CH1TADDR
D739 55097 CH1VOLUME
D73A 55098 CH1FREQ
D73B 55099 CH1FREQ
D73C 55100 CH1FREQ
D73D 55101 CH1FREQ
D73E 55102 CH1FREQ
D73F 55103 CH1FREQ
D740 55104 CH2EN CH2LOOP CH2SGN CH2SINE CH2STP – CH1SBITS
D741 55105 CH2BADDR
D742 55106 CH2BADDR
D743 55107 CH2BADDR
D744 55108 CH2FREQ
D745 55109 CH2FREQ
D746 55110 CH2FREQ
D747 55111 CH2TADDR
D748 55112 CH2TADDR
D749 55113 CH2VOLUME
D74A 55114 CH2FREQ
D74B 55115 CH2FREQ
D74C 55116 CH2FREQ
D74D 55117 CH2FREQ
D74E 55118 CH2FREQ
D74F 55119 CH2FREQ
D750 55120 CH3EN CH3LOOP CH3SGN CH3SINE CH3STP – CH3SBITS
D751 55121 CH3BADDR
D752 55122 CH3BADDR
D753 55123 CH3BADDR
D754 55124 CH3FREQ
D755 55125 CH3FREQ
D756 55126 CH3FREQ
D757 55127 CH3TADDR
continued …
655
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D758 55128 CH3TADDR
D759 55129 CH3VOLUME
D75A 55130 CH3FREQ
D75B 55131 CH3FREQ
D75C 55132 CH3FREQ
D75D 55133 CH3FREQ
D75E 55134 CH3FREQ
D75F 55135 CH3FREQ
• ADDRLSB DMA list address low byte (address bits 0 – 7) WITHOUT START-
ING 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
• CH0BADDR Audio DMA channel 0 base address LSB
• CH0EN Enable Audio DMA channel 0
• CH0FREQ Audio DMA channel 0 frequency LSB
• CH0LOOP Enable Audio DMA channel 0 looping
• CH0RVOL Audio DMA channel 0 right channel volume
• CH0SBITS Audio DMA channel 0 sample bits (11=16, 10=8, 01=upper
nybl, 00=lower nybl)
• CH0SGN Enable Audio DMA channel 0 signed samples
• CH0SINE Audio DMA channel 0 play 32-sample sine wave instead of
DMA data
• CH0STP Audio DMA channel 0 stop flag
• CH0TADDR Audio DMA channel 0 top address LSB
• CH0VOLUME Audio DMA channel 0 playback volume
• CH1BADDR Audio DMA channel 1 base address LSB
656
• CH1EN Enable Audio DMA channel 1
• CH1FREQ Audio DMA channel 1 frequency LSB
• CH1LOOP Enable Audio DMA channel 1 looping
• CH1RVOL Audio DMA channel 1 right channel volume
• CH1SBITS Audio DMA channel 1 sample bits (11=16, 10=8, 01=upper
nybl, 00=lower nybl)
• CH1SGN Enable Audio DMA channel 1 signed samples
• CH1SINE Audio DMA channel 1 play 32-sample sine wave instead of
DMA data
• CH1STP Audio DMA channel 1 stop flag
• CH1TADDR Audio DMA channel 1 top address LSB
• CH1VOLUME Audio DMA channel 1 playback volume
• CH2BADDR Audio DMA channel 2 base address LSB
• CH2EN Enable Audio DMA channel 2
• CH2FREQ Audio DMA channel 2 frequency LSB
• CH2LOOP Enable Audio DMA channel 2 looping
• CH2LVOL Audio DMA channel 2 left channel volume
• CH2SGN Enable Audio DMA channel 2 signed samples
• CH2SINE Audio DMA channel 2 play 32-sample sine wave instead of
DMA data
• CH2STP Audio DMA channel 2 stop flag
• CH2TADDR Audio DMA channel 2 top address LSB
• CH2VOLUME Audio DMA channel 2 playback volume
• CH3BADDR Audio DMA channel 3 base address LSB
• CH3EN Enable Audio DMA channel 3
• CH3FREQ Audio DMA channel 3 frequency LSB
• CH3LOOP Enable Audio DMA channel 3 looping
• CH3LVOL Audio DMA channel 3 left channel volume
• CH3SBITS Audio DMA channel 3 sample bits (11=16, 10=8, 01=upper
nybl, 00=lower nybl)
657
• CH3SGN Enable Audio DMA channel 3 signed samples
• CH3SINE Audio DMA channel 3 play 32-sample sine wave instead of
DMA data
• CH3STP Audio DMA channel 3 stop flag
• CH3TADDR Audio DMA channel 3 top address LSB
• CH3VOLUME Audio DMA channel 3 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 (uses DMA option list)
• NOMIX Audio DMA bypasses audio mixer
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 address incrementing which allows efficient texture copying
and scaling. Also there exists no known software which ever used this facil-
ity, 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.
658
APPENDIX K
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-II / C64 Registers
• VIC-III / C65 Registers
• VIC-IV / MEGA65 Specific Registers
660
661
662
FEATURES
The VIC-IV is a fourth generation Video Interface Controller developed espe-
cially 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 tran-
sition 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-IV).
• 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 colour-
ful 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 po-
sition 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
663
• 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.
• Super-extended attribute mode which uses two screen RAM bytes and
two colour RAM bytes per character mode, which supports a wide va-
riety of new features including alpha-blending/anti-aliasing, hard-
ware kerning/variable-width characters, hardware horizontal/verti-
cal flipping, alternate palette selection and other powerful features that
make it easy to create highly dynamic and colourful displays.
• Multiple 8-bit colour play-fields are also possible using the Raster-
Rewrite Buffer.
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.
664
VIC-II/III/IV REGISTER ACCESS
CONTROL
Because the new features of the VIC-IV are all extensions to the existing VIC-
II/III designs, 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:
Detecting VIC-II/III/IV
Detecting which generation of the VIC-II/III/IV a machine is fitted with can
be important for programs that support only particular generations, or that
665
wish to vary their graphical display based on the capabilities of the machine.
While there are many possibilities for this, the following is a simple and effec-
tive method. It relies on the fact that the VIC-III and VIC-IV do not repeat
the VIC-II registers throughout the IO address 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 register, 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 gen-
eration 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:
666
50 is like line 30, but as it appears after a VIC-III knock, it allows the detec-
tion 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.
1. We didn’t invent a new connector for it: We instead used the most com-
mon digital video connector already in use. So your existing cables
should work fine!
667
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 interoper-
ability, these should, in most cases, function with the MEGA65 without diffi-
culty. 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 prob-
lem 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, includ-
ing 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:
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 char-
668
acters. Nor does it follow the VIC-II’s policy of having such changes take
effect immediately. Instead, 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 com-
patibility 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
669
double scanned, with two 31.5 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.
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 us-
able 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 cor-
responding 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.
670
858 Horizontal Ticks
(32 μSec per line)
As these HDTV video modes are not supported by all VGA monitors, a compat-
ibility 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.:
671
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 Def-
inition 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 312 626
NTSC 65 263 526
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 exactly.
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 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.
672
MEMORY INTERFACE
The VIC-IV supports up to 64KB of colour RAM and, in principle, 16MB of
direct access RAM for video data. However in typical installations 32KB of
colour RAM and 384KB of addressable RAM is present. In MEGA65 systems,
the second 128KB of RAM is typically used to hold a C65-compatible ROM,
leaving 256KB available, unless software is written to avoid the need to use
C65 ROM routines, in which case all 384KB can be used.
The VIC-IV supports all legacy VIC-II and VIC-III methods for accessing this
RAM, including 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.
673
For example, to indicate that character generator data should be sourced be-
ginning at $41200 (266752 decimal), the following could be used. Note that
the AND binary operator only works with arguments between 0 and 65,535.
Therefore we first subtract 4×65,536 = 262,144 from the address (the 4
is determined by calculating INT(266752/65536) ), before we use the AND
operator to compute the lower part of the address:
674
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. 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:
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:
POKE2040 , INT ( 7 6 8 / 2 5 6 )
POKE2041 ,768 -256* INT ( 7 6 8 / 2 5 6 )
HOT REGISTERS
Because of the availability of precise vernier registers to set a wide range of
video parameters directly, $D011 (53265 decimal), $D016 (53270 decimal)
and other VIC-II and VIC-III video mode registers are implemented as virtual
registers: by default, writing to any of these results in computed consistent
675
values being applied to all of the relevant vernier registers. This means that
writing to any of these virtual registers will reset the video mode. Thus some
care has to be taken when using new VIC-IV features to not touch any of the
“hot” VIC-II and VIC-III registers.
The “hot” registers to be careful with are:
$D011, $D016, $D018, $D031 (53265, 53270, 53272 and 53297 deci-
mal) and the VIC-II bank bits of $DD00 (56576 decimal).
If you write to any of those, various VIC-IV registers will need to be re-written
with the values you wish to maintain.
This “hot” register behaviour is intended primarily for legacy software. It can
be disabled by clearing the HOTREG signal (bit 7 of $D05D, 53341 decimal).
NEW MODES
Why the new VIC-IV modes are
Character 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 increased computational burden, which
676
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 provide 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 dis-
play, 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 memory 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 im-
provements that were trivial to make, and it thus seemed foolish to not
implement, in case they find use.
677
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 acces-
sible. 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. The default is as follows:
Bit(s) Function
Lower 8 bits of character number, the same as the VIC-II
Screen RAM byte 0
and VIC-III
Screen RAM byte 1, Upper 5 bits of character number, allowing addressing of
bits 0 - 4 8,192 unique characters
Screen RAM byte 1,
Trim pixels from right side of character (bits 0 - 2)
bits 5 - 7
Colour RAM byte 0,
Vertically flip the character
bit 7
Colour RAM byte 0,
Horizontally flip the character
bit 6
Colour RAM byte 0,
Alpha blend mode (leave 0, discussed later)
bit 5
Colour RAM byte 0, GOTO X (allows repositioning of characters along a raster
bit 4 via the Raster-Rewrite Buffer, discussed later)
If set, Full-Colour characters use 4 bits per pixel and are
Colour RAM byte 0, 16 pixels wide (less any right side trim bits), instead of
bits 3 using 8 bits per pixel. When using 8 bits per pixels, the
characters are the normal 8 pixels wide
Colour RAM byte 0,
Trim pixels from right side of character (bit 3)
bits 2
Colour RAM byte 0,
Number of pixels to trim from top or bottom of character
bits 0 - 1
Colour RAM byte 1,
Low 4 bits of colour of character
bits 0 - 3
Colour RAM byte 1, Hardware blink of character (if VIC-III extended attributes
bit 4 are enabled)
Colour RAM byte 1, Hardware reverse video enable of character (if VIC-III
bit 5 extended attributes are enabled)*
continued …
678
…continued
Bit(s) Function
Colour RAM byte 1, Hardware bold attribute of character (if VIC-III extended
bit 6 attributes are enabled)*
Colour RAM byte 1, Hardware underlining of character (if VIC-III extended
bit 7 attributes are enabled)
* 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.
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 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 de-
scribes the behaviour when more than one of these are used together, most
of which are logical, but there are a few combinations that behave differ-
ently 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.
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 other-
wise 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.
679
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 re-
quired to define each character, instead of one. The screen RAM can be
located anywhere in the 384KiB of main memory using registers $D060 –
$D062 (53344 – 53346 decimal). The colour RAM can be located any-
where in the 32KiB colour RAM. Only the first 1 or 2 KiB 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 may be required
to access the full amount of colour RAM. Thus we will initially discuss using
Super-Extender Attribute Mode with a 40x25 character display.
The easiest way to use Super-Extended Attribute Mode is from C65 mode,
with the screen set to 80 columns, as the C65 ROM sets up 2KiB for both the
screen RAM and colour RAM. The user need only to treat each character pair
as a single Super-Extended Attribute character.
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.
680
The following descriptions assume that you have implemented one of the
methods described above to set the screen and colour RAM.
Alpha-Blending / Anti-Aliasing
XXX
Flipping Characters
XXX
681
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 char-
acters, 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 ef-
ficient 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 that on modern systems, but
that are still efficient enough to be implemented 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 Example program
Raster-Rewrite Buffer
If the GOTO bit is set for a character in Super-Extended Attribute Mode, in-
stead 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 com-
bination 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 ma-
terial is limited only by the raster time of the VIC-IV. Some experimentation
will be required to determine how much can be achieved in PAL and NTSC
modes.
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
682
play-fields on other computers, such as the Amiga, but without the disadvan-
tages of bitplanes.
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.
683
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.
684
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 elements 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.
685
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:
686
0 AD = 56* 6 4: IF PEEK ( 5 3 2 7 2 ) AND 32 THEN GOTO 30: REM C65 / C64 MODE DETECT
10 POKE 53295 , ASC (" G "): POKE 53295 , ASC (" S "): REM ENABLE MEGA65 VIC - IV F E A T U R E S
20 AD = 7 6 8 + 6 4 : REM $0340 HEX FOR SPRITE
30 FOR I = AD TO AD +168: POKEI ,0: NEXT I
40 POKE 2040 , AD /64: REM SET SPRITE NUMBER
50 POKE 53269 ,1: REM ENABLE SPRITE 0
60 POKE 53248 ,100: POKE 53249 ,100: REM PUT SPRITE ON SCREEN
70 POKE 53355 ,1: REM MAKE SPRITE 0 16 - COLOUR
80 POKE 53335 ,1: REM MAKE SPRITE 0 USE 64 BITS OF DATA = 16 X 4 - BIT PIXELS
90 POKE 53287 ,10: REM MAKE PINK THE T R A N S P A R E N T COLOUR
100 GOSUB 900: REM READ MULTI - COLOUR SPRITE
899 END
688
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
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
D030 53296 – C128FAST
689
• MISBC mask sprite:bitmap collision IRQ
• MISSC mask sprite:sprite collision IRQ
• MRIRQ mask raster IRQ
• RC 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
• S0X sprite 0 horizontal position
• S0Y sprite 0 vertical position
• S1X sprite 1 horizontal position
• S1Y sprite 1 vertical position
• S2X sprite 2 horizontal position
• S2Y sprite 2 vertical position
• S3X sprite 3 horizontal position
• S3Y sprite 3 vertical position
• S4X sprite 4 horizontal position
• S4Y sprite 4 vertical position
• S5X sprite 5 horizontal position
• S5Y sprite 5 vertical position
• S6X sprite 6 horizontal position
• S6Y sprite 6 vertical position
• S7X sprite 7 horizontal position
• S7Y sprite 7 vertical position
• 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
690
• SEXY sprite vertical expansion enable bits
• SPR0COL sprite 0 colour / 16-colour sprite transparency colour (lower
nybl)
• SPR1COL sprite 1 colour / 16-colour sprite transparency colour (lower
nybl)
• SPR2COL sprite 2 colour / 16-colour sprite transparency colour (lower
nybl)
• SPR3COL sprite 3 colour / 16-colour sprite transparency colour (lower
nybl)
• SPR4COL sprite 4 colour / 16-colour sprite transparency colour (lower
nybl)
• SPR5COL sprite 5 colour / 16-colour sprite transparency colour (lower
nybl)
• SPR6COL sprite 6 colour / 16-colour sprite transparency colour (lower
nybl)
• SPR7COL sprite 7 colour / 16-colour sprite transparency colour (lower
nybl)
• SPRMC0 Sprite multi-colour 0
• SPRMC1 Sprite multi-colour 1
• 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
691
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
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
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
53504
D100 –
– PALRED
D1FF
53759
53760
D200 –
– PALGREEN
D2FF
54015
54016
D300 –
– PALBLUE
D3FF
54271
692
• B0ADEVN - Bitplane 0 address, even lines
• B0ADODD - Bitplane 0 address, odd lines
• B0PIX Display Address Translater (DAT) Bitplane 0 port
• B1ADEVN - Bitplane 1 address, even lines
• B1ADODD - Bitplane 1 address, odd lines
• B1PIX Display Address Translater (DAT) Bitplane 1 port
• B2ADEVN - Bitplane 2 address, even lines
• B2ADODD - Bitplane 2 address, odd lines
• B2PIX Display Address Translater (DAT) Bitplane 2 port
• B3ADEVN - Bitplane 3 address, even lines
• B3ADODD - Bitplane 3 address, odd lines
• B3PIX Display Address Translater (DAT) Bitplane 3 port
• B4ADEVN - Bitplane 4 address, even lines
• B4ADODD - Bitplane 4 address, odd lines
• B4PIX Display Address Translater (DAT) Bitplane 4 port
• B5ADEVN - Bitplane 5 address, even lines
• B5ADODD - Bitplane 5 address, odd lines
• B5PIX Display Address Translater (DAT) Bitplane 5 port
• B6ADEVN - Bitplane 6 address, even lines
• B6ADODD - Bitplane 6 address, odd lines
• B6PIX Display Address Translater (DAT) Bitplane 6 port
• B7ADEVN - Bitplane 7 address, even lines
• B7ADODD - Bitplane 7 address, odd lines
• B7PIX Display Address Translater (DAT) Bitplane 7 port
• BORDERCOL display border colour (256 colour)
• BPCOMP Complement bitplane flags
• BPM Bit-Plane Mode
• BPX Bitplane X
693
• BPY Bitplane Y
• 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 A5then96 to enable C65/VIC-III IO registers
• MC1 multi-colour 1 (256 colour)
• MC2 multi-colour 2 (256 colour)
• MC3 multi-colour 3 (256 colour)
• MONO Enable VIC-III MONO video output (not implemented)
• PAL Use PALETTE ROM or RAM 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
694
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
D04B 53323 SPRBPMEN BBDRPOS
D04C 53324 TEXTXPOS
D04D 53325 SPRTILEN TEXTXPOS
D04E 53326 TEXTYPOS
D04F 53327 SPRTILEN TEXTYPOS
D050 53328 – XPOS
D051 53329 XPOS
D052 53330 FNRASTER
D053 53331 FNRST – FNRASTER
D054 53332 ALPHEN VFAST PALEMU SPR640 SMTH FCLRHI FCLRLO CHR16
D055 53333 SPRHGTEN
D056 53334 SPRHGHT
D057 53335 SPRX64EN
D058 53336 CHARSTEP
D059 53337 CHARSTEP
D05A 53338 CHRXSCL
D05B 53339 CHRYSCL
D05C 53340 SIDBDRWD
D05D 53341 HOTREG RSTDELEN SIDBDRWD
D05E 53342 CHRCOUNT
D05F 53343 SPRXSMSBS
D060 53344 SCRNPTR
continued …
695
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D061 53345 SCRNPTR
D062 53346 SCRNPTR
D063 53347 EXGLYPH – SCRNPTR
D064 53348 COLPTR
D065 53349 COLPTR
D068 53352 CHARPTR
D069 53353 CHARPTR
D06A 53354 CHARPTR
D06B 53355 SPR16EN
D06C 53356 SPRPTRADR
D06D 53357 SPRPTRADR
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
D075 53365 SPRALPHAVAL
D076 53366 SPRENV400
D077 53367 SRPYMSBS
D078 53368 SPRYSMSBS
D079 53369 RSTCOMP
D07A 53370 FNRSTCMP RESERVED RSTCMP
D07B 53371 Number
D07C 53372 RESERVED VSYNCP HSYNCP RESERVED
696
• CHARSTEP characters per logical text row (LSB)
• CHR16 enable 16-bit character numbers (two screen bytes per charac-
ter)
• CHRCOUNT Number of characters to display per row
• 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)
• COLPTR colour RAM base address (bits 0 - 7)
• EXGLYPH source full-colour character data from expansion RAM
• FCLRHI enable full-colour mode for character numbers >$FF
• FCLRLO enable full-colour mode for character numbers <=$FF
• FNRASTER Read physical raster position
• FNRST Raster compare source (1=VIC-IV fine raster, 0=VIC-II raster)
• FNRSTCMP Raster compare is in physical rasters if set, or VIC-II raster if
clear
• HOTREG Enable VIC-II hot registers. When enabled, touching many VIC-
II registers causes the VIC-IV to recalculate display parameters, such as
border positions and sizes
• HSYNCP hsync polarity
• KEY Write 47then53 to enable C65GS/VIC-IV IO registers
• 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)
• Number of text rows to display
• PALEMU video output pal simulation
• PALNTSC NTSC emulation mode (max raster = 262)
• RASLINE0 first VIC-II raster line
• RASTERHEIGHT physical rasters per VIC-II raster (1 to 16)
697
• RESERVED
• RSTCMP Raster compare value MSB
• RSTCOMP Raster compare value
• RSTDELEN Enable raster delay (delays raster counter and interrupts by
one line to match output pipeline latency)
• SCREENCOL screen colour (256 colour)
• SCRNPTR screen RAM precise base address (bits 0 - 7)
• SIDBDRWD Width of single side border
• SMTH video output horizontal smoothing enable
• SPR16EN sprite 16-colour mode enables
• SPR640 Sprite H640 enable;
• SPRALPHAVAL Sprite alpha-blend value
• SPRBPMEN Sprite bitplane-modify-mode enables
• SPRENALPHA Sprite alpha-blend enable
• SPRENV400 Sprite V400 enables
• 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)
• SPRPTRADR sprite pointer address (bits 7 - 0)
• SPRPTRBNK sprite pointer address (bits 22 - 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)
• SPRXSMSBS Sprite H640 X Super-MSBs
• SPRYADJ Sprite Y position adjustment
698
• SPRYSMSBS Sprite V400 Y position super MSBs
• SRPYMSBS Sprite V400 Y position MSBs
• TBDRPOS top border position
• TEXTXPOS character generator horizontal position
• TEXTYPOS Character generator vertical position
• VFAST C65GS FAST mode (48MHz)
• VGAHDTV Select more VGA-compatible mode if set, instead of HD-
MI/HDTV VIC-II cycle-exact frame timing. May help to produce a func-
tional display on older VGA monitors.
• VSYNCP vsync polarity
• XPOS Read horizontal raster scan position
699
700
APPENDIX L
6526 Complex Interface
Adaptor (CIA) Registers
• CIA 6526 Registers
• CIA 6526 Hypervisor Registers
702
CIA 6526 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 – TODSEC
DC0B 56331 TODAMPM – TODHOUR
DC0C 56332 SDR
DC0D 56333 IR – FLG SP ALRM TB TA
DC0E 56334 TOD50 SPMOD IMODA – RMODA OMODA PBONA STRTA
DC0F 56335 – IMODB LOAD RMODB OMODB PBONB STRTB
703
• 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
• TODHOUR TOD hours
• TODJIF TOD tenths of seconds
• TODSEC TOD seconds
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
DC0F 56335 TODEDIT –
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
DD09 56585 – TODSEC
DD0A 56586 – TODSEC
DD0B 56587 TODAMPM – TODHOUR
DD0C 56588 SDR
continued …
704
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
DD0D 56589 – FLG SP ALRM TB TA
DD0E 56590 TOD50 SPMOD IMODA – RMODA OMODA PBONA STRTA
DD0F 56591 TODEDIT IMODB LOAD RMODB OMODB PBONB STRTB
705
• 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
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
DC1B 56347 TODAMPM TODHOUR
DC1C 56348 ALRMJIF
DC1D 56349 ALRMSEC
DC1E 56350 ALRMMIN
DC1F 56351 ALRMAMPM ALRMHOUR
706
• ALRMHOUR TOD Alarm hours value
• ALRMJIF TOD Alarm 10ths of seconds value
• ALRMMIN TOD Alarm minutes value
• ALRMSEC TOD Alarm seconds value
• 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
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
DD17 56599 TALATCH
DD18 56600 IMFLG IMSP IMALRM IMTB TODJIF
DD19 56601 TODSEC
DD1A 56602 TODMIN
DD1B 56603 TODAMPM TODHOUR
DD1C 56604 ALRMJIF
DD1D 56605 ALRMSEC
DD1E 56606 ALRMMIN
DD1F 56607 ALRMAMPM ALRMHOUR
707
• ALRMJIF TOD Alarm 10ths of seconds value
• ALRMMIN TOD Alarm minutes value
• ALRMSEC TOD Alarm seconds value
• 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
708
APPENDIX M
4551 UART, GPIO and Utility
Controller
• C65 6551 UART Registers
• 4551 General Purpose IO & Mis-
cellaneous Interface Reg-
isters
710
C65 6551 UART REGISTERS
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D600 54784 DATA
D601 54785 – FRMERR PTYERR RXOVRRUN RXRDY
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)
711
• 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)
• TXEN UART enable transmit
712
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D620 54816 POTAX
D621 54817 POTAY
D622 54818 POTBX
D623 54819 POTBY
713
• OSKEN Enable display of on-screen keyboard composited overlay
• OSKTOP 1=Display on-screen keyboard at top, 0=Disply on-screen key-
board 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
• 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 set-
tings.
• POTBX Read Port B paddle X, without having to fiddle with SID/CIA set-
tings.
• POTBY Read Port B paddle Y, without having to fiddle with SID/CIA set-
tings.
• 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
• UFAST C65 UART BAUD clock source: 1 = 7.09375MHz, 0 = 80MHz
(VIC-IV pixel clock)
• UNUSED port o output value
• 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.
714
APPENDIX N
45E100 Fast Ethernet
Controller
• Overview
• Memory Mapped Registers
• Example Programs
716
OVERVIEW
The 45E100 is a new and simple Fast Ethernet controller that has been de-
signed specially for the MEGA65 and for 8-bit computers generally. In addi-
tion to supporting 100Mbit Fast Ethernet, it is radically different from other
Ethernet controllers, such as the RR-NET.
The 45E100 includes dual receive buffers, allowing one frame to be pro-
cessed while another is receiving. It includes automatic CRC32 checking on
reception, and automatic CRC32 generation for transmit, considerably re-
ducing the burden on the processor and allowing for very simple programs.
It 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, al-
lowing greatly improved real-world performance. When especially low latency
is required, it is also possible to immediately abort the transmission of the cur-
rent 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.
717
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.
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 integrated DMA controller it is quite possible to achieve transfer
rates of several mega-bytes per second – some 100x faster than the RR-NET.
718
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 programmer should use the receive interrupt feature, enabled by setting
RXQEN (bit 7 of $D6E1). Polling is possible as an alternative, but is not rec-
ommended with the 45E100, because at the 100Mbit Fast Ethernet speed,
packets can arrive as often as every 10 microseconds. Fortunately, at the
MEGA65’s 40MHz full speed mode, and using the 20MiB per second DMA
copy functionality, it is possible to keep up with such high data rates.
719
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 into the normal C64/C65 $D000 IO address space.
Care must be taken as mapping the ethernet frame buffers into the $D000
IO address space causes all other IO devices to unavailable during this time.
Therefore interrupts MUST be disabled before doing so, whether using BA-
SIC 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 Appendix G.
While for C65’s BASIC 10, the following must instead be used, because a
VIC-III raster interrupt is used instead of a CIA-based timer interrupt:
Once this has been done, the IO 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:
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 normal C64, C65 or MEGA65 IO 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
IO context by writing $47 (71 decimal) in and $53 (83 in decimal) to the KEY
register, for example:
720
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
POKE53274 ,129
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 inter-
face. 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.
721
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.
The 45E100 also supports several features to assist in the diagnosis of eth-
ernet problems. First, if the NOCRC bit is set, then even ethernet frames that
have invalid CRC32 values will be received. This can help debug faulty eth-
ernet devices on a network.
If the STRM bit is set, the ethernet transmitter transmits a continuous stream of
debugging frames supplied via a special high-bandwidth logging interface.
By default, the 45E100 emits a stream of approximately 2,200 byte ethernet
frames that contain compressed video provided by a VIC-IV or compatible
video controller that supports 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 com-
patible 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, depending on the particular
instruction mix.
722
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 re-
ception 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.
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
D6E0 55008 TXIDLE RXBLKD –
KEYEN DRXDV DRXD RST
D6E1 55009 RXQEN TXQEN RXQ
TXQ STRM RXBU RXBM –
D6E2 55010 TXSZLSB
D6E3 55011 TXSZMSB
D6E4 55012 COMMAND
D6E5 55013 – MCST BCST RXPH NOCRC NOPROM
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
723
• DRXD Read ethernet RX bits currently on the wire
• DRXDV Read ethernet RX data valid (debug)
• KEYEN Allow remote keyboard input via magic ethernet frames
• MACADDR1 Ethernet MAC address
• MACADDR2 Ethernet MAC address
• MACADDR3 Ethernet MAC address
• MACADDR4 Ethernet MAC address
• MACADDR5 Ethernet MAC address
• MACADDR6 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
• RST Write 0 to hold ethernet controller under reset
• RXBLKD Indicate if ethernet RX is blocked until RX buffers rotated
• RXBM Set which RX buffer is memory mapped
• RXBU Indicate which RX buffer was most recently used
• 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
• TXQ Ethernet TX IRQ status
724
• TXQEN Enable ethernet TX IRQ
• TXSZLSB TX Packet size (low byte)
• TXSZMSB TX Packet size (high byte)
POKE55012 ,1
725
EXAMPLE PROGRAMS
Example programs for the ethernet controller exist in imperfect for in the
MEGA65 Core repository on github in the src/tests and src/examples direc-
tories.
726
APPENDIX O
Reference Tables
• Units of Storage
• Base Conversion
728
UNITS OF STORAGE
Unit Equals Abbreviation
1 Bit
1 Nybble 4 Bits
1 Byte 8 bits B
1 Kilobyte 1024 B KB
1 Megabyte 1024 KB or 1,048,576 B MB
729
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
730
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
731
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
732
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
733
734
APPENDIX P
Flashing the FPGAs and
CPLDs in the MEGA65
• Warning
Lattice Diamond
• Flashing the MAX10 FPGA on
736
737
738
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 are probably looking
for Chapter on Cores and Flashing instead. This chapter is more intended for
people who want to help develop cores for the MEGA65.
These re-programmable chips are called Field Programmable Gate Arrays
(FPGAs) or Complex Programmable Logic Devices (CPLDs), and can imple-
ment a wide variety of circuits. They are normally programmed using a lan-
guage like VHDL or Verilog. These are languages that are not commonly en-
countered by most people. They are also quite different in some ways to “nor-
mal” 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.
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 recom-
mend a computer with at least 8GB 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 peo-
ple have written, then most computers running a recent version of Windows or
Linux should be able to cope.
WARNING
Before we go any further, we do have to provide a warning about reprogram-
ming the FPGAs and CPLDs in the MEGA65. Re-programming the MEGA65
FPGA can potentially cause damage, or leave your MEGA65 in an unrespon-
sive 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 con-
tains, 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!
739
FLASHING THE MAIN FPGA OF A
MEGA65 R2/R3 USING VIVADO
If you choose to proceed, you will need a TE0790-03 JTAG programming
module and a functioning installation of Xilinx’s Vivado software. This can be
done on either Windows or Linux, but in either case 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.
740
Figure P.1: Step 1: To access the Hardware Manager, open a project
in Vivado or create an empty one, if you do not have any projects yet.
Figure P.2: Step 2: In the left column, select ”Open Hardware Manager”
at the very bottom.
741
Figure P.3: Step 3: To connect to FPGA under ”Hardware Manager”,
choose ”Open Target”, then ”Auto Connect”.
742
Figure P.5: Step 5: Under ”Hardware Manager”, choose ”Add Config-
uration Memory Device”, then ”xc7a100t_0”.
Figure P.6: Step 6: Select Memory Part: In the newly opened dialogue,
type ”S25fl256s” (without quotes), then select ”s25fl256sxxxxxxx0-spi-
x1_x2_x4” (the upper one) and click ”OK”.
743
Figure P.7: Step 7: Set programming options: In the next dialogue, choose
your local Configuration file, namely a bitstream with file suffix ”.mcs”. Leave
all other parameters as they are (see P.7).
Figure P.8: 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.
744
Figure P.9: Step 9: If your screen looks like P.9, your new bistream has
been successfully flashed into the main FPGA!
Figure P.10: 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.
745
FLASHING THE CPLD IN THE
MEGA65’S KEYBOARD WITH
LATTICE DIAMOND
If you choose to proceed, you will need a TE0790-03 JTAG programming mod-
ule 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.
746
On the PCB R2 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 ”Police Mode” (blue and red blinking
LEDs) when set correctly.
747
Connect your non-8-bit computer to the FPGA programming device using a
mini-USB cable. Switch the MEGA65 computer ON. Open the Diamond Pro-
grammer which can be downloaded from the Internet.
748
Figure P.13: Step 3: Select cable: You have now created a new project
which should display ”MachXO2” under ”Device Family” and ”LCMXO2-
1200HC” under ”Device”
Figure P.16: Step 6: Select project file: Click the three dots under ”File
Name” to set the correct path and find the file ending with ”.jed”.
750
Figure P.17: Step 7: Choose correct path of .jed file: Select the file
ending with ”.jed” and click ”OK”.
Figure P.18: Step 8: Select .jed file: Click on the icon with the green
arrow facing down ”PROGRAM”, which looks similar to the Diamond Pro-
grammer program icon.
751
Figure P.19: Step 9: Select cable: After a moment the Output win-
dow should display ”INFO - Operation: successful.” and the ”Status”
cell should go green (does not always happen).
Figure P.20: Step 10: Operation successful: You have now successfully
flashed the MEGA65 keyboard. If you wish you can now save the project
for later use.
752
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 Programmer 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 between 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 MEGA65 mainboard, all dip switches must be in the OFF po-
sition. The main FPGA of the MEGA65 R2 must not contain a valid bitstream.
See section Flashing the main FPGA of a MEGA65 R2/R3 using Vivado on
how to erase the bitstream from the main FPGA.
753
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.
754
Figure P.21: Step 1: Open Quartus Prime Programmer Lite Edition:
Click the ”Hardware Setup” button in the top left corner of the Quartus
Prime Programmer window.
Figure P.22: Step 2: Enter Hardware Setup: In the newly appeared win-
dow under ”Currently selected hardware” choose ”Arrow-USB-Blaster”.
If ”Arrow-USB-Blaster” does not appear, verify cable and drivers being
correctly installed.
755
Figure P.23: Step 3: Select Arrow USB-Blaster: Click the ”Add File”
button from the left row and choose the latest ”.pof” file. Then click
”Open”.
756
Figure P.24: 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.
757
While keeping the Reset-Button pressed, switch the MEGA65 computer ON.
The keyboard will go into ”Police Mode” (blue and red blinking LEDs). 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.
758
APPENDIX Q
Model Specific Features
• MEGA65 Desktop Computer, Re-
vision 2 onwards
sions 1 and 2
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 registers 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 10 in C65 mode):
This program works by setting up a DMA list in memory at 1,024 (hex $0400)
(unused normally on the C65), followed by a routine at 1,042 (hex $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 (hex $0400 – $0407), and interprets them appropriately to
print the time.
761
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:
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.
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
– RTCSEC
FFD7110 268267792
– RTCMIN
FFD7111 268267793
– RTCDAY
FFD7113 268267795
– RTCMONTH
FFD7114 268267796
RTCYEAR
FFD7115 268267797
– RTCDOW
FFD7116 268267798
– RTCDST –
FFD7117 268267799
continued …
762
…continued
HEX DEC DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
RTCNVRAM00
FFD7140 268267840
RTCNVRAM01
FFD7141 268267841
RTCNVRAM02
FFD7142 268267842
RTCNVRAM03
FFD7143 268267843
• RTCAMPM Real-time Clock AM/PM flag (1 = PM) (only for when not in
24 hour mode)
• RTCDAY Real-time Clock day of month value (1 – 31) (binary coded dec-
imal)
763
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 accelerome-
ter, including analog to digital converters (ADCs), amplifier controller for loud
speakers, and several I2C IO expanders, that are used to connect the joy-pad
and other peripherals. The IO expanders are fully integrated into the MEGA-
phone design, and thus there should be no normal need to read these registers
directly. The IO expanders are, however, also responsible for power control
of the various sub-systems of the MEGAphone.
NOTE: These registers are not yet fully documented.
764
…continued
HEX DEC Signal Description
IO1R4 IO Expander 3, Register 4
FFD7014 268267540
IO1R5 IO Expander 3, Register 5
FFD7015 268267541
IO1R6 IO Expander 3, Register 6
FFD7016 268267542
IO1R7 IO Expander 3, Register 7
FFD7017 268267543
RTCR0 Real-Time Clock, Register 0
FFD7018 268267544
RTCR1 Real-Time Clock, Register 1
FFD7019 268267545
RTCR2 Real-Time Clock, Register 2
FFD701A 268267546
RTCR3 Real-Time Clock, Register 3
FFD701B 268267547
RTCR4 Real-Time Clock, Register 4
FFD701C 268267548
RTCR5 Real-Time Clock, Register 5
FFD701D 268267549
RTCR6 Real-Time Clock, Register 6
FFD701E 268267550
RTCR7 Real-Time Clock, Register 7
FFD701F 268267551
RTCR8 Real-Time Clock, Register 8
FFD7020 268267552
RTCR9 Real-Time Clock, Register 9
FFD7021 268267553
RTCRA Real-Time Clock, Register A
FFD7022 268267554
RTCRB Real-Time Clock, Register B
FFD7023 268267555
RTCRC Real-Time Clock, Register C
FFD7024 268267556
RTCRD Real-Time Clock, Register D
FFD7025 268267557
RTCRE Real-Time Clock, Register E
FFD7026 268267558
RTCRF Real-Time Clock, Register F
FFD7027 268267559
continued …
765
…continued
HEX DEC Signal Description
RTCR10 Real-Time Clock, Register 10
FFD7028 268267560
RTCR11 Real-Time Clock, Register 11
FFD7029 268267561
RTCR12 Real-Time Clock, Register 12
FFD702A 268267562
RTCR13 Real-Time Clock, Register 13
FFD702B 268267563
RTCR14 Real-Time Clock, Register 14
FFD702C 268267564
RTCR15 Real-Time Clock, Register 15
FFD702D 268267565
RTCR16 Real-Time Clock, Register 16
FFD702E 268267566
RTCR17 Real-Time Clock, Register 17
FFD702F 268267567
AMPR0 Speaker Amplifier, Register 0
FFD7030 268267568
AMPR1 Speaker Amplifier, Register 1
FFD7031 268267569
AMPR2 Speaker Amplifier, Register 2
FFD7032 268267570
AMPR3 Speaker Amplifier, Register 3
FFD7033 268267571
AMPR4 Speaker Amplifier, Register 4
FFD7034 268267572
AMPR5 Speaker Amplifier, Register 5
FFD7035 268267573
AMPR6 Speaker Amplifier, Register 6
FFD7036 268267574
AMPR7 Speaker Amplifier, Register 7
FFD7037 268267575
AMPR8 Speaker Amplifier, Register 8
FFD7038 268267576
AMPR9 Speaker Amplifier, Register 9
FFD7039 268267577
AMPRA Speaker Amplifier, Register A
FFD703A 268267578
AMPRB Speaker Amplifier, Register B
FFD703B 268267579
continued …
766
…continued
HEX DEC Signal Description
AMPRC Speaker Amplifier, Register C
FFD703C 268267580
AMPRD Speaker Amplifier, Register D
FFD703D 268267581
AMPRE Speaker Amplifier, Register E
FFD703E 268267582
AMPRF Speaker Amplifier, Register F
FFD703F 268267583
ACCELR0 Accelerometer, Register 0
FFD7040 268267584
ACCELR1 Accelerometer, Register 1
FFD7041 268267585
ACCELR2 Accelerometer, Register 2
FFD7042 268267586
ACCELR3 Accelerometer, Register 3
FFD7043 268267587
ACCELR4 Accelerometer, Register 4
FFD7044 268267588
ACCELR5 Accelerometer, Register 5
FFD7045 268267589
ACCELR6 Accelerometer, Register 6
FFD7046 268267590
ACCELR7 Accelerometer, Register 7
FFD7047 268267591
ACCELR8 Accelerometer, Register 8
FFD7048 268267592
ACCELR9 Accelerometer, Register 9
FFD7049 268267593
ACCELRA Accelerometer, Register A
FFD704A 268267594
ACCELRB Accelerometer, Register B
FFD704B 268267595
ACCELRC Accelerometer, Register C
FFD704C 268267596
ACCELRD Accelerometer, Register D
FFD704D 268267597
ACCELRE Accelerometer, Register E
FFD704E 268267598
ACCELRF Accelerometer, Register F
FFD704F 268267599
continued …
767
…continued
HEX DEC Signal Description
ACCELR10 Accelerometer, Register 10
FFD7050 268267600
ACCELR11 Accelerometer, Register 11
FFD7051 268267601
ACCELR12 Accelerometer, Register 12
FFD7052 268267602
ACCELR13 Accelerometer, Register 13
FFD7053 268267603
ACCELR14 Accelerometer, Register 14
FFD7054 268267604
ACCELR15 Accelerometer, Register 15
FFD7055 268267605
ACCELR16 Accelerometer, Register 16
FFD7056 268267606
ACCELR17 Accelerometer, Register 17
FFD7057 268267607
ACCELR18 Accelerometer, Register 18
FFD7058 268267608
ACCELR19 Accelerometer, Register 19
FFD7059 268267609
ACCELR1A Accelerometer, Register 1A
FFD705A 268267610
ACCELR1B Accelerometer, Register 1B
FFD705B 268267611
ACCELR1C Accelerometer, Register 1C
FFD705C 268267612
ACCELR1D Accelerometer, Register 1D
FFD705D 268267613
ACCELR1E Accelerometer, Register 1E
FFD705E 268267614
ACCELR1F Accelerometer, Register 1F
FFD705F 268267615
ACCELR20 Accelerometer, Register 20
FFD7060 268267616
ACCELR21 Accelerometer, Register 21
FFD7061 268267617
ACCELR22 Accelerometer, Register 22
FFD7062 268267618
ACCELR23 Accelerometer, Register 23
FFD7063 268267619
continued …
768
…continued
HEX DEC Signal Description
ACCELR24 Accelerometer, Register 24
FFD7064 268267620
ACCELR25 Accelerometer, Register 25
FFD7065 268267621
ACCELR26 Accelerometer, Register 26
FFD7066 268267622
ACCELR27 Accelerometer, Register 27
FFD7067 268267623
ACCELR28 Accelerometer, Register 28
FFD7068 268267624
ACCELR29 Accelerometer, Register 29
FFD7069 268267625
ACCELR2A Accelerometer, Register 2A
FFD706A 268267626
ACCELR2B Accelerometer, Register 2B
FFD706B 268267627
ACCELR2C Accelerometer, Register 2C
FFD706C 268267628
ACCELR2D Accelerometer, Register 2D
FFD706D 268267629
ACCELR2E Accelerometer, Register 2E
FFD706E 268267630
ACCELR2F Accelerometer, Register 2F
FFD706F 268267631
ACCELR30 Accelerometer, Register 30
FFD7070 268267632
ACCELR31 Accelerometer, Register 31
FFD7071 268267633
ACCELR32 Accelerometer, Register 32
FFD7072 268267634
ACCELR33 Accelerometer, Register 33
FFD7073 268267635
ACCELR34 Accelerometer, Register 34
FFD7074 268267636
ACCELR35 Accelerometer, Register 35
FFD7075 268267637
ACCELR36 Accelerometer, Register 36
FFD7076 268267638
ACCELR37 Accelerometer, Register 37
FFD7077 268267639
continued …
769
…continued
HEX DEC Signal Description
ACCELR38 Accelerometer, Register 38
FFD7078 268267640
ACCELR39 Accelerometer, Register 39
FFD7079 268267641
ACCELR3A Accelerometer, Register 3A
FFD707A 268267642
ACCELR3B Accelerometer, Register 3B
FFD707B 268267643
ACCELR3C Accelerometer, Register 3C
FFD707C 268267644
ACCELR3D Accelerometer, Register 3D
FFD707D 268267645
ACCELR3E Accelerometer, Register 3E
FFD707E 268267646
ACCELR3F Accelerometer, Register 3F
FFD707F 268267647
ADC1LSB smoothed value (LSB)
FFD70F0 268267760
ADC1MSB smoothed value (MSB)
FFD70F1 268267761
ADC2LSB smoothed value (LSB)
FFD70F2 268267762
ADC2MSB smoothed value (MSB)
FFD70F3 268267763
ADC3LSB smoothed value (LSB)
FFD70F4 268267764
ADC3MSB smoothed value (MSB)
FFD70F5 268267765
770
APPENDIX R
Supporters & Donors
• Organisations
• Volunteers
• Individual Donors
772
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 recog-
nise the contribution of everyone who has made the MEGA65 possible, and
into the great retro-computing project that it has become.
ORGANISATIONS
• M.E.G.A. Museum of Electronic Games and Art, e.V., Germany
EVERYTHING
VOLUNTEERS
• Detlef Hastik FOUNDER CAT HERDING TESTING HOSTING
INDIVIDUAL DONORS
773
774
Bibliography
776
[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] X. S. me, “”vic-ii for beginners: Screen modes, cheaper by the dozen,”
XXX Set me. [Online]. Available: http://dustlayer.com/vic-ii/2013/4/
26/vic-ii-for-beginners-screen-modes-cheaper-by-the-dozen
777
778
INDEX
780
, (comma), 82, 100 CIRCLE, 234
: (colon), 82, 100 CLOSE, 235
<> (not equal to), 91 CLR, 236
CMD, 237
ABS, 212 COLLECT, 238
ADC, 512, 560, 620 COLLISION, 239
ADCQ, 469, 621 COLOR, 240
ALR, 513 CONCAT, 241
ANC, 514 CONT, 99, 242
AND, 105, 213, 514, 560, 621 COPY, 243
ANDQ, 469, 622 CURSOR, 245
APPEND, 214 DATA, 246
ARR, 515 DCLEAR, 247
ASC, 215 DCLOSE, 248
ASL, 516, 561 DEF FN, 250
ASLQ, 469, 623 DELETE, 251
ASR, 562
DIM, 252
ASRQ, 624
DIR, 253
ASW, 563
DISK, 254
ATN, 216
DLOAD, 255
AUTO, 217
DMA, 256, 448
BACKGROUND, 105, 218 DMODE, 257
BACKUP, 219 DO, 258
BANK, 220 DOPEN, 259
BASIC 10 Commands, 374 DPAT, 261
APPEND, 214 DSAVE, 262
AUTO, 217 DVERIFY, 263
BACKGROUND, 105, 218 ELLIPSE, 265
BACKUP, 219 ELSE, 266
BANK, 220, 448 END, 99, 267
BEGIN, 221 ENVELOPE, 268
BEND, 222 ERASE, 269
BLOAD, 223 EXIT, 272
BOOT, 224 FAST, 274
BORDER, 105, 225 FILTER, 275
BOX, 226 FIND, 276
BSAVE, 227 FOR, 67, 278
BUMP, 228 FOREGROUND, 105, 279
BVERIFY, 229 GET, 281
CATALOG, 230 GET#, 282
CHANGE, 231 GETKEY, 283
CHAR, 232 GO64, 284
781
GOSUB, 285 RMOUSE, 351
GOTO, 107, 286 RREG, 353
GRAPHIC, 287 RUN, 357
HEADER, 288 SAVE, 358
HELP, 289 SCNCLR, 359
HIGHLIGHT, 291 SCRATCH, 360
IF, 90, 292 SCREEN, 361
INPUT, 77, 84, 293 SET, 362
INPUT#, 294 SLEEP, 365
INSTR, 295 SLOW, 366
KEY, 298 SOUND, 367
LET, 76, 301 SPRCOLOR, 369
LINE, 302 SPRITE, 370
LIST, 71, 72, 303 SPRSAV, 371
LOAD, 304 STEP, 73, 373
LOCATE, 305 STOP, 99
LOOP, 307 SYS, 376
MONITOR, 311 TEMPO, 380
MOUSE, 312 THEN, 90, 381
MOVSPR, 313 TO, 382
NEW, 314 TRAP, 383
NEXT, 315 TROFF, 384
OFF, 317 TRON, 385
ON, 318 TYPE, 386
OPEN, 320 UNTIL, 387
PAINT, 323 USING, 388
PALETTE, 324 VERIFY, 392
PEN, 326 VOL, 393
PLAY, 327 WAIT, 394
POLYGON, 331 WHILE, 395
PRINT, 71, 334 WINDOW, 396
PRINT USING, 336 BASIC 10 Functions
PRINT#, 335 ABS, 212
PUDEF, 338 ASC, 215
READ, 341 ATN, 216
RECORD, 342 CHR$, 233
REM, 343 COS, 244
RENAME, 344 DEC, 249
RENUMBER, 98, 345 ERR$, 271
RESTORE, 346 EXP, 273
RESUME, 347 FN, 250, 277
RETURN, 348 FRE, 280
782
HEX$, 290 BBR3, 565
INT, 296 BBR4, 565
JOY, 297 BBR5, 566
LEFT$, 299 BBR6, 566
LEN, 300 BBR7, 566
LOG, 306 BBS0, 567
LPEN, 308 BBS1, 567
MID$, 309 BBS2, 567
MOD, 310 BBS3, 568
PEEK, 325 BBS4, 568
POINTER, 329 BBS5, 568
POKE, 330 BBS6, 569
POS, 332 BBS7, 569
POT, 333 BCC, 516, 569
RCLR, 339 BCS, 517, 570
RDOT, 340 BEGIN, 221
RGR, 349 BEND, 222
RIGHT$, 350 BEQ, 517, 570
RND, 106, 352 bgcolor, 182
RSPCOLOR, 354 BIT, 517, 571
RSPPOS, 355 BITQ, 469, 625
blink, 183
RSPRITE, 356
BLOAD, 223
SGN, 363
blocked, 81
SIN, 364
BMI, 518, 571
SPC, 368
BNE, 518, 572
SQR, 372
BOOT, 224
STR$, 375
BORDER, 105, 225
TAB, 378
bordercolor, 182
TAN, 379
BOX, 226
USR, 390 box, 185
VAL, 391 BPL, 519, 572
BASIC 10 Operators BRA, 573
AND, 105, 213 BRK, 519, 573
NOT, 316 BSAVE, 227
OR, 322 BSR, 574
XOR, 397 BUMP, 228
BASIC 10 System Variables BVC, 520, 574
EL, 264 BVERIFY, 229
ER, 270 BVS, 520, 575
BBR0, 564
BBR1, 564 CATALOG, 230
BBR2, 564 cellcolor, 184
783
cgetc, 193 CURSOR, 245
CHANGE, 231
CHAR, 232 DATA, 246
character, 73 DCLEAR, 247
character set, 73 DCLOSE, 248
CHR$, 233 DCP, 525
cinput, 194 DEC, 249, 526, 580
CIRCLE, 234 DEF FN, 250
CLC, 521, 575 DELETE, 251
CLD, 521, 576 DEQ, 469, 627
CLE, 576 DEW, 581
CLI, 522, 577 DEX, 526, 582
CLOSE, 235 DEY, 527, 582
CLR, 236 DEZ, 583
clrscr, 180 digital video, 668
CLV, 522, 577 DIM, 252
DIR, 253
CMD, 237
Direct Mode, 78
CMP, 523, 545, 578, 626
DISASSEMBLE, 644
CMPQ, 626
DISK, 254
COLLECT, 238
DLOAD, 255
COLLISION, 239
DMA, 256
COLOR, 240
DMODE, 257
CONCAT, 241
DO, 258
conionit, 179
DOPEN, 259
CONT, 99, 242
DPAT, 261
context dependent, 79
DSAVE, 262
COPY, 243 DVERIFY, 263
copyright, ii
COS, 244 EL, 264
CPQ, 469 ELLIPSE, 265
cprintf, 192 ELSE, 266
cputc, 189 END, 99, 267
cputcxy, 191 ENVELOPE, 268
cputdec, 190 EOM, 583
cputhex, 190 EOR, 527, 584, 628
cputnc, 190 EORQ, 469, 629
cputncxy, 192 ER, 270
cputs, 191 ERASE, 269
cputsxy, 191 ERR$, 271
CPX, 524, 579 Errors
CPY, 524, 579 Extra Ignored, 82
CPZ, 580 Illegal Direct, 78
784
Syntax, 64 INC, 528, 585
Type mismatch, 77 INPUT, 77, 84, 293
EXIT, 272 INPUT#, 294
EXP, 273 INQ, 469, 629
Extra Ignored, 82 INSTR, 295
INT, 296
FAST, 274 Integrated Marvellous Digital
fillrect, 184 Hookup™, 667
FILTER, 275 INW, 586
FIND, 276 INX, 529, 586
flushkeybuf, 194 INY, 529, 587
FN, 250, 277 INZ, 587
FOR, 67, 278 IO
FOREGROUND, 105, 279 blocking, 81
FRE, 280 ISC, 530
785
LOCATE, 305 PEEK, 325
LOG, 306 PEN, 326
LOOP, 307 PHA, 538, 594
LPEN, 308 PHP, 539, 594
LSR, 536, 591 PHW, 595
LSRQ, 469, 631 PHX, 595
PHY, 596
MAP, 592 PHZ, 596
MEMORY, 645 PLA, 539, 596
MID$, 309 PLAY, 327
MOD, 310 PLP, 539, 597
MONITOR, 311 PLX, 597
MONITOR Commands PLY, 597
DISASSEMBLE, 644 PLZ, 598
MEMORY, 645 POINTER, 329
MOUSE, 312 POKE, 330
movedown, 188 POLYGON, 331
moveleft, 188 POS, 332
moveright, 189 POT, 333
moveup, 188 PRINT, 71, 334
MOVSPR, 313 PRINT USING, 336
PRINT#, 335
name spaces, 77 Programmes
NEG, 593 editing, 85
NEW, 314 replacing lines, 85
NEXT, 315 PUDEF, 338
NO SCROLL, 108
NOP, 536 quote mode, 95
NOT, 316
not equal, 91 RCLR, 339
RDOT, 340
OFF, 317 READ, 341
ON, 318 RECORD, 342
OPEN, 320 relational operators, 91
OpenROMs, 158 REM, 343
operators RENAME, 344
relational, 91 RENUMBER, 98, 345
OR, 322 RESQ, 634
ORA, 537, 593, 632 RESTORE, 346
ORQ, 469, 633 RESUME, 347
RETURN, 348
PAINT, 323 revers, 183
PALETTE, 324 RGR, 349
786
RIGHT$, 350 setextendedattrib, 181
RLA, 540 setscreenaddr, 180
RMB0, 598 setscreensize, 181
RMB1, 599 SGN, 363
RMB2, 599 SHA, 547
RMB3, 599 SHX, 548
RMB4, 600 SHY, 548
RMB5, 600 SIN, 364
RMB6, 601 SLEEP, 365
RMB7, 601 SLO, 549
RMOUSE, 351 SLOW, 366
RND, 352 SMB0, 607
RND(), 106 SMB1, 608
ROL, 541, 601 SMB2, 608
ROLQ, 469, 635 SMB3, 608
ROR, 541, 602 SMB4, 609
RORQ, 469, 635 SMB5, 609
ROW, 603 SMB6, 609
RRA, 542 SMB7, 610
RREG, 353 SOUND, 367
RSPCOLOR, 354 SPC, 368
RSPPOS, 355 SPRCOLOR, 369
RSPRITE, 356 SPRITE, 370
RSVQ, 636 SPRSAV, 371
RTI, 543, 604 SQR, 372
RTS, 543, 604 SRE, 549
RUN, 357 STA, 550, 610, 639
STEP, 73, 373
SAVE, 358 STOP, 99, 374
SAX, 543 STQ, 469, 639
SBC, 544, 545, 604, 637 STR$, 375
SBCQ, 469, 638 string, 73
SBX, 545 STX, 551, 611
scientific notation, 106 STY, 551, 611
SCNCLR, 359 STZ, 612
SCRATCH, 360 SYNTAX ERROR, 64
SCREEN, 361 SYS, 376
SEC, 546, 605
SED, 546, 606 TAB, 378, 612
SEE, 606 TAN, 379
SEI, 547, 607 TAS, 551
SET, 362 TAX, 552, 613
set16bitcharmode, 181 TAY, 552, 613
787
TAZ, 614 unequal, 91
TBA, 614 UNTIL, 387
TEMPO, 380 USING, 388
textcolor, 182 USR, 390
THEN, 90, 381
TO, 382 VAL, 391
togglecase, 182 variable, 68
TRAP, 383 numeric, 75
TRB, 615 string, 75
TROFF, 384 VERIFY, 392
TRON, 385 vline, 186
TSB, 616 VOL, 393
TSX, 553, 616
TSY, 617 WAIT, 394
TXA, 553, 617 Warnings
TXS, 554, 618 Extra Ignored, 82
TYA, 554, 618 wherex, 189
TYPE, 386 wherey, 189
Type mismatch error, 77 WHILE, 395
TYS, 619 WINDOW, 396
TZA, 619
XAA, 555
underline, 184 XOR, 397
788