0% found this document useful (0 votes)
482 views756 pages

Commodore 128 Programmer's Reference Guide

A guide to Commodore 128 programming

Uploaded by

DSpawnZ
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
482 views756 pages

Commodore 128 Programmer's Reference Guide

A guide to Commodore 128 programming

Uploaded by

DSpawnZ
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 756

COMMODORE 128

PROGRAMMER'S
REFERENCE GUIDE

Bantam Computer Books


Ask your bookseller for the books you have missed
THE AMIGADOS MANUAL
by Commodore-Amiga, Inc.
THE APPLE //c BOOK
by Bill O'Brien
THE ART OF DESKTOP
PUBLISHING
By Tony Bove, Cheryl Rhodes,
and Wes Thomas
ARTIFICIAL INTELLIGENCE
ENTERS THE MARKETPLACE
by Larry R. Harris and
Dwight B. Davis

HOW TO GET THE MOST OUT OF


COMPUSERVE, 2d ed.
by Charles Bowen and David Peyton
HOW TO GET THE MOST OUT OF THE
SOURCE
by Charles Bowen and David Peyton
THE MACINTOSH
by Bill O'Brien
MACINTOSH C PRIMER PLUS
by The Waite Group/Stephen W. Prata
THE NEW jr. A GUIDE TO IBM'S PCjr
by Winn L. Rosch

THE BIG TIP BOOK FOR


THE APPLE II SERIES
by Bert Kersey and
Bill Sanders

ORCHESTRATING SYMPHONY
by The Waite Group/Dan Shafer with
Mary Johnson

THE COMMODORE 64 SURVIVAL


MANUAL
by Winn L. Rosch

PC-DOS/MS-DOS
User's Guide to the Most Popular Operating
System for Personal Computers
by Alan M. Boyd

COMMODORE 128 PROGRAMMER'S


REFERENCE GUIDE
by Commodore Business Machines, Inc.
THE COMPUTER AND THE BRAIN
by Scott Ladd/
The Red Feather Press
EXPLORING ARTIFICIAL INTELLIGENCE
ON YOUR APPLE II
by Tim Hartnell
EXPLORING ARTIFICIAL INTELLIGENCE
ON YOUR COMMODORE 64
by Tim Hartnell
EXPLORING ARTIFICIAL INTELLIGENCE
ON YOUR IBM PC
by Tim Hartnell
EXPLORING THE UNIX ENVIRONMENT
by The Waite Group/Irene Pasternack
FRAMEWORK FROM THE GROUND UP
by The Waite Group/Cynthia Spoor and
Robert Warren

POWER PAINTING: COMPUTER GRAPHICS


ON THE MACINTOSH
by Verne Bauman and Ronald Kidd/
illustrated by Gasper Vaccaro
SMARTER TELECOMMUNICATIONS
Hands-On Guide to On-Line Computer Services
by Charles Bowen and Stewart Schneider
SWING WITH JAZZ: LOTUS JAZZ ON THE
MACINTOSH
by Datatech Publications Corp./S. Michael McCarty
UNDERSTANDING EXPERT SYSTEMS
by The Waite Group/Mike Van Horn
USER'S GUIDE TO THE AT&T PC 6300
PERSONAL COMPUTER
by David B. Peatroy, Ricardo A. Anzaldua,
H. A. Wohlwend, and Datatech Publications
Corp.

C O M M O D O R E 128
PROGRAMMER'S
REFERENCE GUIDE

COMMODORE BUSINESS MACHINES, INC.

BANTAM BOOKS
TORONTO NEW YORK LONDON SYDNEY AUCKLAND

COMMODORE 128 PROGRAMMER S REFERENCE GUIDE

A Bantam Book / February 1986


Commodore 64 and Commodore 128 are registered trademarks of Commodore
Electronics. Ltd.
CP/M and CP/M Plus Version 3.0 are registered trademarks of Digital Research
lnc.
Perfect is a registered trademark ofPerfect Software.
TouchTone is a registered trademark ofAT&T.
WordStar is a registered trademark ofMicroPro International Corporation.
Grateful acknowledgment is made for permission to reprint two bars of Invention
13 (Inventio 13) by Johann Sebastian Bach. Sheet music copyright C. F. Peters,
Corp., New York.
Book design by Ann Gold.
Cover design by Jo Ellen Temple.

All rights reserved.


Copyright 1986 by Commodore
This book may not be reproduced
mimeograph or any other means,
For information address: Bantam

Capital, lnc.
in whole or in part, by
without permission.
Books, Inc.

ISBN 0-553-34292-4
Published simultaneously in the United States and Canada
Bantam Books are published by Bantam Books, Inc. Its trademark, consisting of
the words "Bantam Books" and the portrayal ofa rooster, is Registered in U.S.
Patent and Trademark Office and in other countries. Marca Registrada. Bantam
Books, lnc., 666 Fifth Avenue, New York, New York 10103.

P R I N T E D lN T H E U N I T E D S T A T E S O F

HL

AMERICA

CONTENTS
Chapter 1
Introduction

Chapter 2
BASIC Building Blocks and BASIC 7.0 Encyclopedia

11

Chapter 3
One Step Beyond Simple BASIC

91

Chapter 4
Commodore 128 Graphics Programming

109

Chapter 5
Machine Language on the Commodore 128

123

Chapter 6
How
to Enter
Machine
Language Programs Into the
Commodore
128
Chapter
7

181

Mixing Machine Language and BASIC

197

Chapter 8
The Power Behind Commodore 128 Graphics

207

Chapter 9
Sprites

265

Chapter 10
Programming the 80-Column (8563) Chip

291

Chapter 11
Sound and
Chapter
Input/Output
12 Music
Guideon the Commodore 128

335
371

Chapter 13
The Commodore 128 Operating System

401

Chapter 14
CP/M 3.0 on the Commodore 128

477

Chapter 15
The Commodore 128 and Commodore 64 Memory Maps

501

Chapter 16
C128 Hardware Specifications

555

Appendixes

643

Glossary

731

Index

739

ACKNOWLEDGMENTS

Written by Larry Greenley


and
Fred Bowen
Bil Herd
Dave Haynie
Terry Ryan
Von Ertwine
Kim Eckert
Mario Eisenbacher
Norman McVey
The authors are deeply indebted to the many people who have contributed to the
preparation of this book. Special thanks go to Jim Gracely of Commodore Publications,
who reviewed the entire manuscript for technical accuracy and provided important
corrections, clarifications, and user-oriented suggestions, and to Steve Beats and Dave
Middleton of Commodore Software Engineering for their programming assistance and
expertise.
We also want to recognize the contributions of Frank Palaia of Commodore Hardware
Design, who provided expertise in the operation of the Z80 hardware, and of Dave
DiOrio of Commodore Integrated Circuit Design, who provided insight into the design
of the Memory Management Unit and the C128 VIC chip enhancements.
For their extensive technical reviews of the manuscript, we wish to thank Bob Albright,
Pete Bowman, Steve Lam and Tony Porrazza of Commodore Engineering. We also
thank Dan Baker, Dave Street and Carolyn Scheppner of Commodore Software Technical Support for providing an always available source of technical assistance. In addition,
we want to acknowledge the valuable contributions of members of Commodore Software Quality Assurance, especially Mike Colligon, Karen Mackenzie, Pat McAllister,
Greg Rapp, Dave Resavy, and Stacy English.
We also thank Carol Sullivan and Donald Bein for carefully proofreading various
sections of the text, Michelle Dreisbach for typing the manuscript, Marion Dooley for
preparing the art, Jo-Ellen Temple for the cover design, and Nancy Zwack for overall
coordination assistance.
Finally, we would like to acknowledge the unflagging support and guidance provided by
senior Commodore executives Paul Goheen, Harry McCabe and Bob Kenney.

J
INTRODUCTION

COMMODORE 128

The Commodore 128 Personal Computer is a versatile, multimode computer. The


Commodore 128 is the successor to the commercially successful Commodore 64 computer. The principal features of the Commodore 128 are:

128K bytes of RAM, optionally expandable to 256K or 640K


80-column horizontal screen display
Hardware and software compatibility with Commodore 64
CP/M 3.0 operation
Enhanced BASIC language

As this Guide shows, the Commodore 128 has many other new or expanded
capabilities and features. Those listed above, however, are the most significant when
assessing the Commodore 128's capabilities against those of the Commodore 64 and
other microcomputers.
The Commodore 128 is actually three computers in one, with the following three
primary operating modes:

C128 Mode
C64 Mode
CP/M Mode

Two of these primary modes (C128 and CP/M) can operate using either a 40- or
80-column screen display. Following is a summary of the major features of each of the
three primary operating modes.

CI28 MODE
In C128 Mode, the Commodore 128 Personal Computer provides the capabilities and
memory needed to run sophisticated applications, such as word processing, spreadsheets,
and database programs.
C128 Mode features include:

8502 processor running at 1.02 or 2.04 MHz


New, enhanced C128 Kernal
Built-in machine language monitor
Commodore BASIC 7.0 language, with over 140 commands and functions
Special new BASIC 7.0 commands that provide better, quicker and easier ways
to create complex graphics, animation, sound and music programs
40-column text and bit map screen output using VIC II chip
80-column text screen output using 8563 chip

INTRODUCTION

NOTE: The 40- and 80-column screen displays can be used either singly
or simultaneously with two monitors.

Sound (three voices) using SID chip


A 92-key keyboard that includes a full numeric keypad and ESCAPE, TAB,
ALT, CAPS LOCK, HELP, LINE FEED, 40/80 DISPLAY, and NO SCROLL
keys
Access to the full capabilities of the new peripheral devices from Commodore
(1571 fast disk drive, 1902 dual 40/80-column RGBI monitor, etc.)
Access to all standard Commodore serial peripherals
RAM expansion to 256 or 640K with optional RAM expansion modules

C64 MODE
In C64 Mode, the Commodore 128 retains all the capabilities of the Commodore 64,
thus allowing you to use the wide range of available Commodore 64 software.
C64 Mode features include:

8502 processor running at 1.02 MHz


Standard C64 Kernal
BASIC 2.0 language
64K of RAM
40-column output using VIC II chip
Sound (three voices) using SID chip
Standard Commodore 64 keyboard layout except for function keys
All standard Commodore 64 keyboard functions
Access to all Commodore 64 graphics, color and sound capabilities, used
as on a Commodore 64
Compatibility with standard Commodore 64 peripherals, including user port and
serial devices, Datassette, joysticks, composite video monitors, and RF
(TV) output devices

NOTE: The 1571 disk drive will function in C64 Mode, but only
at standard 1541 speed. C64 compatibility requirements make it impossible for the 1571 to operate in C64 Mode at fast speed.

COMMODORE 128

CP/M MODE
In CP/M Mode, an onboard Z80 microprocessor gives you access to the capabilities of
Digital Research's CP/M Version 3.0, plus a number of new capabilities added by Commodore.
CP/M Mode features include:

Integral Z80 processor running at 2.04 MHz


Disk-based CP/M 3.0 System
128K bytes of RAM (in 64K banks)
40-column screen output using VlC II chip
80-column screen output using 8563 chip
Access to the full keyboard, including the numeric keypad and special keys
Access to the new fast serial disk drive (1571) and the standard serial peripherals
Ability to redefine almost any key
Ability to emulate several terminals (Lear-Siegler ADM31, ADM3A)
Support for various MFM disk formats (IBM, Kaypro, Epson, Osborne)
RAM expansion to 256 or 640K RAM with optional RAM expansion modules

The incorporation of CP/M 3.0 (also called CP/M Plus) into the Commodore 128
makes thousands of popular commercial and public domain software programs available
to the user.

HARDWARE COMPONENTS
The Commodore 128 Personal Computer incorporates the following major hardware
components:

PROCESSORS
8502: Main processor in C128, C64 Modes; I/O support for CP/M; 6502 softwarecompatible; runs at 1.02 or 2.04 MHz
Z80: CP/M Mode only; runs at 2.04 MHz

MEMORY
ROM: 64K standard (C64 Kernal plus BASIC; C128 Kernal plus BASIC, character
ROMs and CP/M BIOS); one 32K slot available for software
RAM: l28K in two 64K banks; 16K display RAM for 8563 video chip; 2K x 4 Color RAM

VIDEO
8564: 40-column video (separate versions for NTSC and PAL TV standards)
8563: 80-column video

INTRODUCTION

SOUND
6581: SID Chip

INPUT/OUTPUT
6526: Joystick ports/keyboard scan/cassette
6526: User and serial ports

MEMORY MANAGEMENT
8921: PLA (C64 plus C128 mapping modes)
8922: MMU (Custom gate array)
For details on these and other hardware components see Chapter 16, Commodore
128 Hardware Specifications.

COMPATIBILITY WITH
COMMODORE 64
The Commodore 128 system is designed as an upgrade to the Commodore 64. Accordingly, one of the major features of the Commodore 128 design is hardware and software
compatibility with the Commodore 64 when operating in C64 Mode. This means that in
C64 Mode the Commodore 128 is capable of running Commodore 64 application
software. Also, the Commodore 128 in C64 Mode supports Commodore 64 peripherals
except the CP/M 2.2 cartridge. (NOTE: The Commodore 128's built-in CP/M 3.0
capability supersedes that provided by the external cartridge. This cartridge should not
be used with the Commodore 128 in any mode.)
The C128 Mode is designed as a compatible superset to the C64. Specifically, all
Kernal functions provided by the Commodore 64 are provided in the C128 Kernal.
These functions are also provided at the same locations in the jump table of the C128
Kernal to provide compatibility with existing programs. Zero page and other system
variables are maintained at the same addresses they occupy in C64 Mode. This simplifies interfacing for many programs.
Providing Commodore 64 compatibility means that the new features of the Commodore 128 cannot be accessed in C64 Mode. For example, compatibility and memory
constraints preclude modifying the C64 Mode Kernal to support the 1571 fast serial disk
drive. As noted previously, C64 Mode sees this drive as a standard serial disk drive. For
the same reason, C64 Mode does not have an 80-column screen editor, and C64 Mode
BASIC 2.0 cannot use the second 64K bank of memory.

13

COMMODORE 128

SWITCHING FROM MODE TO MODE


As mentioned before, in the C128 and CP/M Modes the Commodore 128 can provide
both 40-column and 80-column screen displays. This means that the Commodore 128
actually has five operating modes, as follows:

C128 Mode with 80-column display


C128 Mode with 40-column display
C64 Mode (40-column display only)
CP/M Mode with 80-column display
CP/M Mode with 40-column display

Figure 1-1 summarizes the methods used to switch from mode to mode.
FROM
TO
OFF

CI28
40 COL

CI28
80 COL

C128
40 COL

1. Check that
40/80 key
is UP.
2. Make sure
that:
a)NoCP/M
system
disk is
in drive
b)No C64
cartridge
is in expansion
port
3. Turn computer ON.
~T. Press
~T. Press
40/80 key
ESC key;
DOWN.
release.
2. Turn com- 2. Press X
puter ON.
key.
OR
1. Press
40/80 key
DOWN.
2. Press
RESET
button.

C128
80 COL

C64

1. Press ESC
key;
release.
2. Press X
key.
OR
1. Check that
40/80 key
is UP.
2. Press
RESET
button.

1. Check that
40/80 key
is UP.
2. Turn computer OFF,
then ON.
3. Remove
cartridge
if present

~T. Press
40/80 key
DOWN.
2. Turn computer OFF,
then ON.
3. Remove
cartridge
if present.

Figure l - l . Commodore 128 Mode Switching Chart

CP/M

CP/M
40 COL

80 COL

1. Check that
40/80 key
is UP.
2. Turn computer OFF,
then ON.

1. Check that
40/80 key
is UP.
2. Turn computer OFF,
then ON.

Press
40/80 key
DOWN.
2. Remove
CP/M system disk
from
drive, if
necessary.
3. Turn computer OFF,
then ON.

~T Check that
40/80 key
is DOWN.
2. Remove
CP/M system disk
from
drive, if
necessary.
3. Turn computer OFF,
then ON.

INTRODUCTION

FROM
TO
OFF

C128

C128

CP/M

CP/M

40 COL

80 COL

40 COL

80 COL

1. Turn computer OFF.


2. Check that
40/80 key
is UP.
3. Hold
DOWN
O key
while
turning
computer
ON.
OR
1. Turn computer OFF.
2. Insert C64
cartridge.
3. Turn
power ON.

1. Turn computer OFF.


2. Check that
40/80 key
is UP.
3. Hold
DOWN
0 key
while turning computer ON.
OR
1. Turn computer OFF.
2. Insert C64
cartridge.
3. Turn
power
ON.

C64

C64

1. Hold
" 0 "key
DOWN.
2. Turn computer ON.
OR
1. Insert C64
cartridge.
2. Turn computer ON.

1. Type GO
64; press
RETURN.
2. The computer responds:
ARE YOU
SURE?
Type Y;
press
RETURN.

1. Type GO
64; press
RETURN.
2. The computer responds:
ARE YOU
SURE?
Type Y;
press
RETURN.

CP/M
40 COL

1. Turn disk
drive ON.
2. Insert
CP/M system disk
in drive.
3. Check that
40/80 key
is UP.
4. Turn computer ON.

1. Turn disk
drive ON.
2. Insert
CP/M system disk
in drive.
3. Check that
40/80 key
is UP.
4. Type:
BOOT
5. Press
RETURN.

1. Turn disk
drive ON.
2. Insert
CP/M system disk
in drive.
3. Check that
40/80 key
is UP.
4. Type:
BOOT
5. Press
RETURN.

1. Check that
40/80 key
is UP.
2. Turn disk
drive ON.
3. Insert
CP/M system disk
in drive.
4. Turn computer OFF.

1. Turn disk
drive ON.
2. Insert
CP/M system disk
in drive.
3. Press
40/80 key
DOWN.
4. Turn computer ON.

1. Turn disk
drive ON.
2. Insert
CP/M system disk
in drive.
3. Press
40/80 key
DOWN.
4. Type:
BOOT
5. Press
RETURN.

1. Turn disk
drive ON.
2. Insert
CP/M system disk
in drive.
3. Check that
40/80 key
is DOWN.
4. Type:
BOOT.
5. Press
RETURN.

1. Press
40/80 key
DOWN.
2. Turn disk
drive ON.
3. Insert
CP/M system disk
in drive.
4. Turn computer OFF.

CP/M
80 COL

1. Insert
CP/M utilities disk
in drive.
2. At screen
prompt,
A > type:
DEVICE
CONOUT: =
40 COL

3. Press
RETURN.
1. Insert
CP/M utilities disk
in drive.
2. At screen
prompt,
A > type:
DEVICE
CONOUT =
80 COL

3. Press
RETURN.

Figure l - l . Commodore 128 Mode Switching Chart (continued)

COMMODORE 128

NOTE: If you are using a Commodore 1902 dual monitor, remember to


move the video switch on the monitor from COMPOSITE or SEPARATED to RGBI when switching from 40-column to 80-column display;
reverse this step when switching from 80 to 40 columns. Also, when
switching between modes remove any cartridges from the expansion port.
You may also have to remove any disk (e.g., CP/M) from the disk drive.

CP/M 3.0 SYSTEM RELEASES


When you send in your C128 warranty card, your name will be added to a list
which makes you eligible for CP/M system release dates.

HOW TO USE THIS GUIDE


This guide is designed to be a reference tool that you can consult whenever you need
detailed technical information on the structure and operation of the Commodore 128
Personal Computer. Since many of the design features of the Commodore 128 can be
viewed from various aspects, it may be necessary to consult several different chapters to
find the information you want. Note that certain groups of chapters form logical sequences
that cover in detail an extended topic like BASIC, graphics, or machine language.
The following chapter summaries should help you pinpoint what chapter or
chapters are most likely to provide the answer to a specific question or problem.
C H A P T E R 2. BASIC BUILDING BLOCKS AND BASIC 7.0 ENCYCLOPEDIA
Defines and describes the structural and operational components of the BASIC
language, including constants, variables and arrays, and numeric and string expressions and operations.
C H A P T E R 3. ONE STEP BEYOND SIMPLE BASICProvides routines (menu,
keyboard buffer, loading, programming function keys) and techniques ("crunchi n g " or saving memory; debugging and merging programs; relocating BASIC)
that can be incorporated in your own programs. Provides modem-related information (how to generate TouchTone frequencies, how to detect telephone ringing,
etc.) plus technical specifications for Commodore Modemyi200 and Modem/300.
C H A P T E R 4. COMMODORE 128 GRAPHICS PROGRAMMINGDescribes the
general BASIC 7.0 graphics commands (COLOR, GRAPHIC, DRAW, LOCATE, BOX, CIRCLE, PAINT) and gives annotated examples of use, including
programs. Describes the structure and general function of the color modes and
character and bit map graphics modes that are fundamental to Commodore 128
graphics.

INTRODUCTION

C H A P T E R 5. MACHINE LANGUAGE ON THE COMMODORE 128Defines,


with examples, machine language (ML) and associated topics, including the
Kernal; the 8502 registers, binary and hexadecimal numbers, and addressing
modes. Defines, with examples, types of ML instructions (op codes, etc.).
Includes 8502 instruction and addressing table.
C H A P T E R 6. HOW TO ENTER MACHINE LANGUAGE PROGRAMS INTO THE
C O M M O D O R E 128Describes, with examples, how to enter ML programs by
using the built-in Machine Language Monitor or by POKEing decimal op-code
values with a BASIC program. Defines, with examples, the ML Monitor commands.
C H A P T E R 7. MIXING MACHINE LANGUAGE AND BASICDescribes, with
examples, how to combine BASIC and ML instructions in the same program by
using BASIC READ, DATA, POKE and SYS commands. Shows where to place
M L programs in memory.
C H A P T E R 8. THE POWER BEHIND COMMODORE 128 GRAPHICSDescribes
the C128 Mode memory banking concept and tells how to manage banked
memory. Defines the use of shadow registers. Describes how screen, color and
character memory are handled in BASIC and machine language, for both character
and bit map modes. Shows how to redefine the character set. Describes use of
split-screen modes. Includes a tabular graphics programming summary.
C H A P T E R 9. SPRITESDescribes programming of sprites or MOBs (movable object
blocks). Defines and shows how to use the BASIC 7.0 sprite-related commands
(SPRITE, SPRDEF, MOVSPR, SSHAPE, GSHAPE, SPRSAV). Provides annotated examples of use, including programs.
C H A P T E R 10. PROGRAMMING THE 8O-COLUMN (8563) CHIPDefines the
8563 registers and describes, with machine language examples, how to program
the 80-column screen in character and bit map modes.
C H A P T E R I I . SOUND AND MUSIC ON THE COMMODORE 128Defines the
BASIC 7.0 sound and music commands (SOUND, ENVELOPE, VOL, TEMPO,
PLAY, FILTER). Describes how to code a song in C128 Mode. Defines in detail
the Sound Interface Device (SID) and how to program it in machine language.
C H A P T E R 12. INPUT/OUTPUT GUIDEDescribes software control of peripheral
devices connected through I/O ports, including disk drives, printers, other User
Port and Serial Port devices, the Datassette, and Controller Port devices. Provides
pin-out diagrams and pin descriptions for all ports.
C H A P T E R 13. THE COMMODORE 128 OPERATING SYSTEMDescribes, with
examples, the operating system (Kernal), which controls the functioning of the
Commodore 128; includes the Kernal Jump Table, which lists the ROM entry
points used to call the Kernal routines; defines each Kernal routine; defines the
C128 Screen Editor. Describes the Memory Management Unit (MMU), defines
the MMU registers, tells how to select and switch banks in BASIC and ML, and
tells how to predefine memory configurations.
C H A P T E R 14. CP/M 3.0 ON THE COMMODORE 128Summarizes the Commodore version of CP/M 3.0. Defines the general system layout and the operating
system components (CCP, BIOS and BDOS). Describes the Commodore enhancements to CP/M 3.0. (Additional details on CP/M 3.0 are given in Appendix K.)

10

COMMODORE 128

C H A P T E R 15. COMMODORE 128 AND COMMODORE 64 M E M O R Y M A P S


Provides detailed memory maps for C128 and C64 modes. (The Z80 memory
map is shown in Appendix K.)
C H A P T E R 16. HARDWARE SPECIFICATIONSIncludes technical specifications for
Commodore 128 hardware components (8563, 8564, etc.).
A P P E N D I X E S A through LProvide additional technical information and/or a more
convenient grouping of information supplied elsewhere in the Guide (e.g., pinout
diagrams).
GLOSSARYProvides standard definitions of technical terms.

2
BASIC
BUILDING
BLOCKS AND
BASIC 7.0
ENCYCLOPEDIA

II

12

COMMODORE 128

The BASIC language is composed of commands, operators, constants, variables, arrays


and strings. Commands are instructions that the computer follows to perform an
operation. The other elements of BASIC perform a variety of functions, such as
assigning values to a quantity, passing values to the computer, or directing the computer
to perform a mathematical operation. This section describes the structure and functions
of the elements of the BASIC language.

COMMANDS AND STATEMENTS


By definition, commands and statements have the following distinctions. A command is
a BASIC verb which is used in immediate mode. It is not preceded by a program line
number and it executes immediately after the RETURN key is pressed. A statement is
a BASIC verb which is contained within a program and is preceded by a line number.
Program statements are executed with the RUN command followed by the RETURN key.
Most commands can be used within a program. In this case the command is
preceded by a line number and is said to be used in program mode. Many commands
also can be used outside a program in what is called direct mode. For example, LOAD
is an often-used direct mode command, but you can also include LOAD in a program.
GET and INPUT are commands that only can be used in a program; otherwise, an
ILLEGAL DIRECT ERROR occurs. While PRINT is usually included within a
program, you can also use PRINT in direct mode to output a message or numeric value
to the screen, as in the following example:
PRINT ' T h e Commodore 128''

RET U R N

Notice that the message is displayed on the screen as soon as you press the return
key. The following two lines display the same message on the screen. The first line is a
program mode statement; the second line is a direct mode command.
10 PRINT "The Commodore 128"
RUN

RETURN

RETURN

It is important to know about the concepts behind memory storage before examining the Commodore BASIC language in detail. Specifically, you need to understand
constants, variables and arrays.

NUMERIC MEMORY STORAGE:


CONSTANTS, VARIABLES AND ARRAYS
There are three ways to store numeric information in Commodore BASIC. The first way
is to use a constant. A constant is a form of memory storage in which the contents
remain the same throughout the course of a program. The second type of memory
storage unit is a variable. As the name indicates, a variable is a memory storage cell in

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

which the contents vary or change throughout the course of a program. The last way to store
information is to use an array, a series of related memory locations consisting of variables.
Each of these three units of memory storage can have three different types of
information or data assigned. The three data types are INTEGER, FLOATING-POINT
or STRING. Integer data is numeric, whole number datathat is, numbers without
decimal points. Floating-point is numeric data including fractional parts indicated with a
decimal point. String data is a sequential series of alphanumeric letters, numbers and
symbols referred to as character strings. The following paragraphs describe these three
data types and the way each memory storage unit is assigned different data type values.

CONSTANTS: INTEGER,
FLOATING-POINT AND STRING
INTEGER CONSTANTS
The value assigned to a constant remains unchanged or constant throughout a program.
Integer constants can contain a positive or negative value ranging from -32768 through
+ 32767. If the plus sign is omitted, the C128 assumes that the integer is positive.
Integer constants do not contain commas or decimal points between digits. Leading
zeros are ignored. Integers are stored in memory as two-byte binary numbers, which
means a constant requires 16 bits or two bytes of memory to store the integer as a base
two number. The following are examples of integer constants:
1
1000
-32
0
-32767

FLOATING-POINT CONSTANTS
Floating-point constants contain fractional parts that are indicated by a decimal
point. They do not contain commas to separate digits. Floating-point constants may be
positive or negative. If the plus sign is omitted, it is assumed that the number is
positive. Again, leading zeros are unnecessary and ignored. Floating-point constants are
represented in two ways depending on their value:
1.
2.

Simple Number Notation


Scientific Notation

In simple number notation, the floating-point number is calculated to ten digits of


precision and stored using five bytes, but only nine digits are displayed on the screen or
printer. If the floating-point number is greater than nine digits, it is rounded according to
the tenth digit. If the tenth digit is greater than five, the ninth digit is rounded to the next
higher digit. If the tenth digit is less than five, the ninth digit is rounded to the next
lower digit. The rounding of floating-point numbers may become a factor when calculat-

13

14

C O M M O D O R E 128

ing values based upon floating-point numbers greater than nine digits. Your program
should test floating-point results and take them into consideration when basing these
values on future calculations.
As mentioned, floating-point numbers are displayed as nine digits. If the value o f a
floating-point constant is less than .01 or greater than 999999999, the number is
displayed on the screen or printer in scientific notation. For example, the number
12345678901 is displayed as 1.23456789E+ 10. Otherwise, the simple number notation
is displayed. A floating-point constant in scientific notation appears in three parts:
1.
2.
3.

The mantissa is the leftmost number separated by a decimal point.


The letter E indicates that the number is displayed in exponential (scientific)
notation.
The exponent specifies the power of ten to which the number is raised and the
number of places the decimal point is moved in order to represent the number
in simple number notation.

The mantissa and exponent can be positive or negative. The exponent can be
within the range - 3 9 to + 3 8 . If the exponent is negative, the decimal point moves to
the left representing it as a simple number. If the exponent is positive, the decimal
point moves to the right representing it in simple number notation.
The Commodore 128 limits the size of floating-point numbers. The highest
number you can represent in scientific notation is 1.70141183E + 38. If you try to
represent a number larger than that, an OVERFLOW ERROR occurs. The smallest
number you can represent in scientific notation is 2.93873588E-39. If you try to
represent a number smaller than that, no error occurs but a zero is returned as the value.
You should therefore test floating-point values in your programs if your calculations are
based on very small numbers and the results depend on future calculations. Here are
examples of floating-point constants in simple number notation and others in scientific
notation:

SIMPLE NUMBER

SCIENTIFIC

9.99
.0234
+ 10.01
-90.23

22.33E + 20
99999.234E-23
^5.89E-11
-3.14E + 17

NOTE: The values in either column are not equivalent.

STRING CONSTANTS
A string constant, as mentioned, is a sequential series of alphanumeric characters
(numbers, letters and symbols). A string constant can be as long as a 160-character input

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

line, minus the line number and any other information appearing on that program line.
By concatenating strings together, you may form a string as long as 255 characters. The
string may contain numbers, letters, and even decimal points and commas. However,
the string cannot contain the double quote ( " ) character, since this character delimits or
marks the beginning or ending of the string. You can represent a double quote character
within a string using CHR$(34). You can omit the closing double quote character of a
string if it is the last statement in a line of a program.
A string can even be assigned a null value, meaning no characters are actually
assigned to it. Assign a string a null value by omitting characters between the double
quotes and follow the opening double quote directly with a closing double quote. Here
are some examples of string constants:
"Commodore 128"
"qwerl234!#$%()*.:,"
" " (null string)
"John and Joan"

VARIABLES: INTEGER,
FLOATING-POINT AND STRING
Variables are units of memory storage that represent varying data values within a
program. Unlike constants, variables may change in value throughout the course of a
program. The value assigned to a variable can be an integer, a floating-point number, or
a string. You can assign a value to a variable as the result of a mathematical calculation.
Variables are assigned values using an equals sign. The variable name appears to the left
of the equals sign and the constant or calculation appears to the right. When you refer to
a variable in a program before you assign it a value, the variable value becomes zero if
it is an integer or floating-point number. It becomes a null string if the variable is a
string.
Variable names can be any length, but for efficiency you should limit the size
of the variable to a few characters. Only the first two characters of a variable name
are significant. Therefore, do not begin the names of two different variables with
the same two characters. If you do, the C128 will interpret them as the same variable
name.
The first character of a variable name must be a letter. The rest of the
variable name can be any letter or number from zero to nine. A variable name
must not contain any BASIC keyword. If you include a BASIC keyword in
a variable name, a SYNTAX ERROR occurs. BASIC keywords include all
BASIC statements, commands, function names, logical operator names and reserved
variables.
You can specify the data type of a variable by following the variable name with
a percent sign (%) if the variable is an integer value, or a dollar sign if the
variable is a string. If no character is specified, the C128 assumes that the variable
value is a floating-point number. Here are some examples of variables and how they are
assigned:

15

16

COMMODORE 128

A Z% F$ T Count % =
G$ =
H$ -

3.679 (floating-point)
714 (integer)
"CELEBRATE THE COMMODORE 128" (string)
A + Z% (floating-point)
Count % + 1 (integer)
"SEEK A HIGHER LEVEL OF CONSCIOUSNESS" (string)
F$ + G$ (string)

ARRAYS: INTEGER,
FLOATING-POINT AND STRING
Although arrays were defined earlier in this chapter as series of related variables or
constants, you refer to them with a single integer, floating point or string variable name.
All elements have the same data type as the array name. To access successive elements
within the array, BASIC uses subscripts (indexed variables) to refer to each unique storage
compartment in the array. For example, the alphabet has twenty-six letters. Assume an
array called " A L P H A " is constructed and includes all the letters of the alphabet. To
access the first element of the array, which is also the first letter of the alphabet (A),
label Alpha with a subscript of zero:
ALPHA$(0)

To access the letter B, label Alpha with a subscript of one:


ALPHA$(1)

Continue in the same manner to access all of the elements of the array ALPHA, as in
the following:
ALPHA$(2)
ALPHA$(3)
ALPHA$(4)
ALPHA$(5)

C
D
E
Z

Subscripts are a convenient way to access elements within an array. If subscripts


did not exist, you would have to assign separate variables for all the data that would
normally be accessed with a subscript. The first subscript within an array is zero.
Although arrays are actually stored sequentially in memory, they can be multidimensional. Tables and matrices are easily manipulated with two-dimensional arrays.
For example, assume you have a matrix with ten rows and ten columns. You need 100
storage locations or array elements in order to store the whole matrix. Even though
your matrix is ten by ten, the elements in the array are stored in memory one
after the other for 100 hundred locations.
You specify the number of dimensions in the arrays with the DIM statement. For
example:

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

10 DIM A(99)
dimensions a one-dimensional floating-point array with 100 elements. The following are
examples of two-, three- and four-dimensional integer arrays:
20 DIM B(9, 9)
30 DIM C(20,20,20)
40 DIM D(10,l5,15,10)

(100 elements)
(9261 elements)
(30976 elements)

In theory the maximum number of dimensions in an array is 255, but you cannot
fit a DIMension statement that long on a 160-character line. The maximum number of
DIMension statements you can fit on a 160-character line is approximately fifty. The
maximum number of elements allowed in each dimension is 32767. In practice, the size
of an array is limited to the amount of available memory. Most arrays are one-, two- or
three-dimensional. If an array contains fewer than ten elements, there is no need for a
DIM statement since the C128 automatically dimensions variable names to ten elements.
The first time you refer to the name of the undimensioned array (variable) name, the
C128 assigns zero to the value if it is a numeric array, or a null string if it is a string
array.
You must separate the subscript for each dimension in your DIMension statement
with a comma. Subscripts can be integer constants, variables, or the integer result of an
arithmetic operation. Legal subscript values can be between zero and the highest
dimension assigned in the DIMension statement. If the subscript is referred to outside of
this range, a BAD SUBSCRIPT ERROR results
The type of array determines how much memory is used to store the integer,
floating-point or string data.
Floating-point string arrays take up the most memory; integer arrays require the
least amount of memory. Here's how much memory each type of array requires:

+
+
OR +
OR +
AND 4-

5
2
2
5
3
1

bytes for the array name


bytes for each dimension
bytes for each integer array element
bytes for each floating-point element
bytes for each string element
byte per character in each string element

Keep in mind the amount of storage required for each type of array. If you only
need an integer array, specify that the array be the integer type, since floating-point
arrays require much more memory than does the integer type.
Here are some example arrays:
A$(0) = "GROSS SALES"
MTH$(K%) = " J A N "
G2%(X) = 5
CNT%(G2%(X)) = CNT%( 1) FP(12*K%) = 24.8

(string array)
(string array)
(integer array)
(integer array)
(floating-point array)

17

18

COMMODORE 128

SUM(CNT%( 1)) = FP*K%


A(5) = 0
B(5,6) = 26

C(l,2,3)=100

(floating-point array)
Sets the 5th element in the 1 dimensional array
called " A " equal to 0
Sets the element in row position 5 and column
position 6 in the 2 dimensional array called " B "
equal to 26
Sets the element in row position 1, column
position 2, and depth position 3 in the 3 dimensional array called " C " equal to 100

EXPRESSIONS AND OPERATORS


Expressions are formed using constants, variables and/or arrays. An expression can be a
single constant, simple variable, or an array variable of any type. It also can be a
combination of constants and variables with arithmetic, relational or logical operators
designed to produce a single value. How operators work is explained below. Expressions can be separated into two classes:
1.
2.

ARITHMETIC
STRING

Expressions have two or more data items called operands. Each operand is
separated by a single operator to produce the desired result. This is usually done by
assigning the value of the expression to a variable name.
An operator is a special symbol the BASIC Interpreter in your Commodore 128
recognizes as representing an operation to be performed on the variables or constant
data. One or more operators, combined with one or more variables and/or constants
form an expression. Arithmetic, relational and logical operators are recognized by
Commodore 128 BASIC.

ARITHMETIC EXPRESSIONS
Arithmetic expressions yield an integer or floating-point value. The arithmetic operators
( + , - , * , / , f ) are used to perform addition, subtraction, multiplication, division and
exponentiation operations, respectively.

ARITHMETIC OPERATIONS
An arithmetic operator defines an arithmetic operation which is performed on the two
operands on either side of the operator. Arithmetic operations are performed using
floating-point numbers. Integers are converted to floating-point numbers before an
arithmetic operation is performed. The result is converted back to an integer if it is
assigned to an integer variable name.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

ADDITION ( + )
The plus sign (4-) specifies that the operand on the right is added to the operand on the
left.
EXAMPLES:

2+2
A+B+ C
X% + 1
BR+10E-2

SUBTRACTION ( - )
The minus sign (-) specifies that the operand on the right is subtracted from the operand
on the left.
EXAMPLES:
4-1
100-64
A-B
55-142
The minus also can be used as a unary minus which is the minus sign in front of a
negative number. This is equal to subtracting the number from zero (0).
EXAMPLES:
-5
-9E4
-B
4 - ( - 2 ) (same as 4 + 2)

MULTIPLICATION (*)
An asterisk (*) specifies that the operand on the left is multiplied by the operand on the
right.
EXAMPLES:
100*2
50*0
A*X1
R%*14

DIVISION (/)
The slash (/) specifies that the operand on the left is divided by the operand on the
right.

19

20

COMMODORE 128

EXAMPLES:
10/2
6400/4
A/B
4E2/XR

EXPONENTIATION ( t )
The up arrow ( f ) specifies that the operand on the left is raised to the power specified
by the operand on the right (the exponent). If the operand on the right is a 2, the number
on the left is squared; if the exponent is a 3, the number on the left is cubed, etc. The
exponent can be any number as long as the result of the operation gives a valid
floating-point number.
EXAMPLES:
2
3
4
AB
3

f
t
f
f
j

2
3
4
CD
-2

Equivalent to 2*2
Equivalent to 3*3*3
Equivalent to 4*4*4*4
Equivalent to

V3*V3

RELATIONAL OPERATORS
The relational operators ( < , = , > , < = , > = , < > ) are primarily used to compare the
values of two operands, but they also produce an arithmetic result. The relational
operators and the logical operators (AND, OR, and NOT), when used in comparisons,
produce an arithmetic true/false evaluation of an expression. If the relationship stated in
the expression is true, the result is assigned an integer value of - 1 . If it's false a value of
0 is assigned. Following are the relational operators:
<
=

>
< > =
<>

LESS THAN
EQUAL TO
GREATER THAN
LESS THAN OR EQUAL TO
GREATER THAN OR EQUAL TO
NOT EQUAL TO

EXAMPLES:
5 - 4 = 1 result true (-1)
1 4 > 6 6 result false (0)
1 5 > = 15 result true (-1)
Relational operators may be used to compare strings. For comparison purposes,
the letters of the alphabet have the order A < B < C < D , etc. Strings are compared by

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

evaluating the relationship between corresponding characters from left to right (see
string operations).
EXAMPLES:
"A" < "B"
"X" - "YY"
BB$ < > CC$

result true (-1)


result false (0)
result false (0) if they are the same

Numeric data items can only be compared (or assigned) with other numeric items.
The same is true when comparing strings; otherwise, the BASIC error message ?TYPE
MISMATCH occurs. Numeric operands are compared by first converting the values of
either or both operands from integer to floating-point form, as necessary. Then
the relationship between the floating-point values is evaluated to give a true/false
result.
At the end of all comparisons, you get an integer regardless of the data type
of the operand (even if both are strings). Because of this, a comparison of two
operands can be used as an operand in performing calculations. The result will
be - 1 or 0 and can be used as anything but a divisor, since division by zero is
illegal.

LOGICAL OPERATORS
The logical operators (AND, OR, NOT) can be used to modify the meaning of the
relational operators or to produce an arithmetic result. Logical operators can produce
results other than - 1 and 0, although any nonzero result is considered true when testing
for a true/false condition.
The logical operators (sometimes called Boolean operators) also can be used to
perform logical operations on individual binary digits (bits) in two operands. But when
you're using the NOT operator, the operation is performed only on the single operand to
the right. The operands must be in the integer range of values (-32768 to + 3 2 7 6 7 )
(floating-point numbers are converted to integers) and logical operations give an integer
result.
Logical operations are performed bit-by-corresponding-bit on the two operands.
The logical AND produces a bit result of 1 only if both operand bits are 1. The logical
OR produces a bit result of 1 if either operand bit is 1. The logical NOT is the opposite
value of each bit as a single operand. In other words, "If it's NOT 1 then it is 0. If it's
NOT 0 then it is 1 . "
The exclusive OR IF (XOR) doesn't have a logical operator but it is performed as
part of the WAIT statement or as the XOR function. Exclusive-OR means that if the
bits of two operands are set and equal, then the result is 0; otherwise the result is 1.
Logical operations are defined by groups of statements which, when taken together, constitute a Boolean "truth table" as shown in Table 2 - 1 .

21

22

COMMODORE 128

The AND operation results in a 1 only if both bits are 1:


1 AND 1 = 1
0 AND 1 - 0
1 AND 0 = 0
0 AND 0 = 0
The OR operation results in a 1 if either bit is 1:
1 OR 1 = 1
0 OR 1 = 1
1 OR 0 = 1
0 OR 0 = 0
The NOT operation logically complements each bit:
NOT 1 = 0
NOT 0 = 1
The exclusive OR (XOR) is a function (not a logical operator):
1 XOR 1 = 0
1 XOR 0 = 1
0 XOR1 = 1
0 XOR 0 = 0
Table 2-1 Boolean Truth Table

The logical operators AND, OR and NOT specify a Boolean arithmetic operation
to be performed on the two operand expressions on either side of the operator. In the
case of NOT, only the operand on the right is considered. Logical operations (or
Boolean arithmetic) aren't performed until all arithmetic and relational operations in an
expression have been evaluated.
EXAMPLES:
IF A - 100 AND B = 100 THEN 10

A = 96 AND 32: PRINT A


IF A = 100 OR B = 100 THEN 20
A = 64 OR 32: PRINT A
X = NOT 96

(if both A and B have a value of 100 then


the result is true)
(A = 32)
(if A or B is 100 then the result is true)
(A = 96)
(result is - 9 7 (two's complement))

HIERARCHY OF OPERATIONS
All expressions perform the different typesof operations according to a fixed hierarchy.
Certain operations have a higher priority and are performed before other operations. The
normal order of operations can be modified by enclosing two or more operands within

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

parentheses ( ), creating a "subexpression." The parts of an expression enclosed in parentheses will be reduced to a single value before evaluating parts outside the parentheses.
When you use parentheses in expressions, pair them so that you always have an
equal number of left and right parentheses. If you don't, the BASIC error message
7SYNTAX ERROR will occur.
Expressions that have operands inside parentheses may themselves be enclosed in
parentheses, forming complex expressions of multiple levels. This is called nesting.
Parentheses can be nested in expressions to a maximum depth of ten levelsten
matching sets of parentheses. The innermost expression has its operations performed
first. Some examples of expressions are:
A+ B
C f ( D + E)/2
( ( X - C | (D + E)/2)*10)+1
GG$>HH$
JJ$ + " M O R E "
K % = 1 AND M < > X
K% = 2 OR (A = B AND M < X )
NOT (D = E)
The BASIC Interpreter performs operations on expressions by performing arithmetic operations first, then relational operations, and logical operations last. Both arithmetic and logical operators have an order of precedence (or hierarchy of operations) within
themselves. Relational operators do not have an order of precedence and will be
performed as the expression is evaluated from left to right.
If all remaining operators in an expression have the same level of precedence, then
operations are performed from left to right. When performing operations on expressions
within parentheses, the normal order of precedence is maintained. The hierarchy of
arithmetic and logical operations is shown in Table 2-2 from first to last in order of
precedence. Note that scientific notation is resolved first.
OPERATOR

DESCRIPTION

EXAMPLE

Exponentiation

BASE t EXP

Negation (Unary Minus)

-A

*/

Multiplication
Division

AB * CD
EF/GH

Addition
Subtraction

CNT 4- 2
JK-PQ

> = <

Relational Operations

A <= B

NOT

Logical NOT
(Integer Two's Complement)

NOT K%

AND

Logical AND

OR

Logical OR

JK AND 128
PQ OR 15

Table 2-2 Hierarchy of Operations Performed on Expressions

23

24

COMMODORE 128

STRING OPERATIONS
Strings are compared using the same relational operators ( = , < > , < = , > = , < , > )
that are used for comparing numbers. String comparisons are made by taking one
character at a time (left-to-right) from each string and evaluating each character
code position from the character set. If the character codes are the same, the characters are equal. If the character codes differ, the character with the lower CBM ASCII
code number is lower in the character set. The comparison stops when the end of either
string is reached. All other factors being equal, the shorter string is considered less than
the longer string. Leading or trailing blanks are significant in string evaluations.
Regardless of the data types, all comparisons yield an integer result. This is
true even if both operands are strings. Because of this, a comparison of two string
operands can be used as an operand in performing calculations. The result will
be - 1 or 0 (true or false) and can be used in any mathematical operation but division
since division by zero is illegal.

STRING EXPRESSIONS
Expressions are treated as if an implied " < > 0 " follows them. This means that if an
expression is true, the next BASIC statement on the same program line is executed. If
the expression is false, the rest of the line is ignored and the next line in the program is
executed.
Just as with numbers, you can perform operations on string variables. The only
arithmetic string operator recognized by BASIC 7.0 is the plus sign ( + ) which is used
to perform concatenation of strings. When strings are concatenated, the string on the
right of the plus sign is appended to the string on the left, forming a third string. The
result can be printed immediately, used in a comparison, or assigned to a variable name.
If a string data item is compared with (or set equal to) a numeric item, or vice-versa, the
BASIC error message ?TYPE MISMATCH occurs. Some examples of string expressions and concatenation are:
10 A$ = " F I L E " : B$ = " N A M E "
20 NAM$ = A$ + B$
(yields the string " F I L E N A M E " )
3 0 R E S $ - " N E W " + A$ + B$ (yieldsthestring "NEWFILENAME")

ORGANIZATION OF THE
BASIC 7,0 ENCYCLOPEDIA
This section of Chapter 2 lists BASIC 7.0 language elements in an encyclopedia
format. It provides an abbreviated list of the rules (syntax) of Commodore 128
BASIC 7.0, along with a concise description of each. Consult the Commodore 128
System Guide BASIC 7.0 Encyclopedia (Chapter 5) included with your computer for a

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

more detailed description of each command. BASIC 7.0 includes all the elements of
BASIC 2.0.
The different types of BASIC operations are listed in individual sections, as
follows:
1.

2.
3.

Commands and Statements: the commands used to edit, store and erase
programs, and the BASIC program statements used in the numbered lines of a
program.
Functions: the string, numeric and print functions.
Reserved Words and Symbols: the words and symbols reserved for
use by the BASIC 7.0 language, which cannot be used for any other
purpose.

COMMAND AND
STATEMENT FORMAT
The command and statement definitions in this encyclopedia are arranged in the following format:

Command name

AUTO

Brief definition

Enable/disable automatic line numbering

Command formatDiscussion of
format and use

AUTO [line#]
This command turns on the automatic line-numbering feature.
This eases the job of entering programs, by automatically typing
the line numbers for the user. As each program line is entered by
pressing RETURN, the next line number is printed on the screen,
and the cursor is positioned two spaces to the right of the line
number. The line number argument refers to the desired increment between line numbers. AUTO without an argument turns off
the auto line numbering, as does RUN. This statement can be
used only in direct mode (outside of a program).

EXAMPLES:
AUTO 10

Automatically numbers program lines in increments of 10.

AUTO 50

Automatically numbers lines in increments of 50.

Example(s)-

AUTO

Turns off automatic line numbering.

25

26

COMMODORE 128

The boldface line that defines the format consists of the following elements:
DLOAD "program name" [,D0,U8]

keyword

argument

The parts of the command


capital letters. Words the
capitalized.
When quote marks ( "
user should include them in

additional arguments
(possibly optional)

or statement that must be typed exactly as shown are in


user supplies, such as the name of a program, are not
" ) appear (usually around a program name or filename), the
the appropriate place, according to the format example.

Keywords are words that are part of the BASIC language. They are the central part of a
command or statement, and they tell the computer what kind of action to take.
These words cannot be used as variable names. A complete list of reserved words
and symbols is given at the end of this chapter.
Keywords, also called reserved words, appear in upper-case letters. Keywords may be typed using the full word or the approved abbreviation. (A full list
of abbreviations is given in Appendix I). The keyword or abbreviation must be
entered correctly or an error will result. The BASIC and DOS error messages are
defined in Appendices A and B, respectively.
Arguments, also called parameters, appear in lower-case letters. Arguments complement keywords by providing specific information to the command or statement.
For example, the keyword LOAD tells the computer to load a program while the
argument "program name" tells the computer which specific program to load. A
second argument specifies from which drive to load the program. Arguments
include filenames, variables, line numbers, etc.
Square Brackets [ ] show optional arguments. The user selects any or none of the
arguments listed, depending on requirements.
Angle Brackets < > indicate the user MUST choose one of the arguments listed.
A Vertical Bar | separates items in a list of arguments when the choices are limited to
those arguments listed. When the vertical bar appears in a list enclosed in
SQUARE BRACKETS, the choices are limited to the items in the list, but the
user still has the option not to use any arguments. If a vertical bar appears within
angle brackets, the user MUST choose one of the listed arguments.
Ellipsis . . . (a sequence of three dots) means an option or argument can be repeated more
than once.
Quotation Marks " " enclose character strings, filenames and other expressions.
When arguments are enclosed in quotation marks, the quotation marks must be
included in the command or statement. In this encyclopedia, quotation marks are
not conventions used to describe formats; they are required parts of a command or
statement.
Parentheses ( ) When arguments are enclosed in parentheses, they must be included in
the command or statement. Parentheses are not conventions used to describe
formats; they are required parts of a command or statement.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

Variable refers to any valid BASIC variable names, such as X, A$, T%, etc.
Expression refers to any valid BASIC expressions, such as A + B + 2,.5*(X + 3),
etc.

NOTE: For all DOS commands, variables and expressions used as


arguments must be endorsed in parentheses.

BASIC COMMANDS AND


STATEMENTS
APPEND
Append data to the end of a sequential file
APPEND #logical file number,'Tilename"[,Ddrive number][<ON|,>Udevice]
EXAMPLES:
Append # 8, " M Y F I L E "

OPEN logical file 8 calied " M Y F I L E " , and prepare


to append with subsequent PRINT # statements.

Append #7,(A$),D0,U9

OPEN logical file named by the variable in A$ on


drive 0, device number 9, and prepare to APPEND.

AUTO
Enable/disable automatic line numbering
AUTO [line#]
EXAMPLES:
AUTO 10
AUTO 50
AUTO

Automatically numbers program lines in increments of 10.


Automatically numbers lines in increments of 50.
Turns off automatic line numbering.

BACKUP
Copy the entire contents from one disk to another on a dual disk drive
BACKUP source Ddrive number TO destination Ddrive number [ < O N | , >
Udevice]

NOTE: This command can be used only with a dual-disk drive.

27

28

C O M M O D O R E 128

EXAMPLES:
BACKUP DO TO D1

Copies all files from the disk in drive 0 to the disk


in drive 1, in dual disk drive unit 8.

BACKUP DO TO D1 ON U9

Copies all files from drive 0 to drive 1, in disk


drive unit 9.

BANK
Select one of the 16 BASIC banks (default memory configurations), numbered 0-15 to
be used during PEEK, POKE, SYS, and WAIT commands.
BANK bank number
Here is a table of available BANK configurations in the Commodore 128 memory:
BANK

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

CONFIGURATION

RAM(0) only
RAM(1) only
RAM(2) only (same as 0)
RAM(3) only (same as 1)
Internal ROM , RAM(0), I/O
Internal ROM , RAM(1), I/O
Internal ROM , RAM(2), I/O (same as 4)
Internal ROM , RAM(3), I/O (same as 5)
External ROM , RAM(0), I/O
External ROM , RAM(1), I/O
External ROM , RAM(2), I/O (same as 8)
External ROM , RAM(3), I/O (same as 9)
Kernal and Internal ROM (LOW), RAM(0), I/O
Kernal and External ROM (LOW), RAM(0), I/O
Kernal and BASIC ROM, RAM(0), Character ROM
Kernal and BASIC ROM, RAM(0), I/O

Banks are described in detail in Chapter 8, The Power Behind Commodore 128
Graphics and Chapter 13, The Commodore 128 Operating System.

BEGIN / BEND
A conditional statement like IF . . . THEN: ELSE, structured so that you can include
several program lines between the start (BEGIN) and end (BEND) of the structure.
Here's the format:

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

IF condition THEN BEGIN : statement


statement
statement BEND : ELSE BEGIN
statement
statement BEND
EXAMPLE
10 IF X = 1 THEN BEGIN: PRINT " X = 1 is True"
20 PRINT " S o this part of the statement is performed"
30 PRINT "When X equals 1"
40 BEND: PRINT "End of BEGlN/BEND structure":GO to 60
50 PRINT " X does not equal l":PRINT "The statements between BEGIN/
BEND are skipped"
60 PRINT "Rest of Program"

BLOAD
Load a binary file starting at the specified memory location
BLOAD "filename"[,Ddrive number][<ONI,U>device number] [,Bbank
number] [,Pstart address]
where:

filename is the name of your file


bank number selects one of the 16 BASIC banks (default memory configurations)

start address is the memory location where loading begins

EXAMPLES:
BLOAD "SPRITES", B0, P3584
BLOAD " D A T A 1 " , D0, U8, B1, P4096

LOADS the binary file " S P R I T E S "


starting in location 3584 (in BANK 0).
LOADS the binary file "DATA 1"
into location 4096 (BANK 1) from
Drive 0, unit 8.

BOOT
Load and execute a program which was saved as a binary file
BOOT "filename''[,Ddrive number][<ON|,>Udevice][,Palt LOAD ADD]
EXAMPLE:
BOOT

BOOT a bootable disk (CP/M Plus for example).

29

30

COMMODORE 128

BOOT "GRAPHICS 1", D0, U9

LOADS the binary program "GRAPHICS 1"


from unit 9, drive 0, and executes it.

BOX
Draw box at specified position on screen
BOX [color source], XI, Yl[,X2,Y2][,angle][,paint]
where:
color source

0 = Background color
1 = Foreground color (DEFAULT)
2 = Multi-color 1
3 = Multi-color 2

X1,Y1

Corner coordinate (scaled)

X2,Y2

Corner diagonally opposite X I , Y1, (scaled); default is the PC


location.

angle

Rotation in clockwise degrees; default is 0 degrees

paint

Paint shape with color


0 = Do not paint
1 = Paint
(default = 0)

EXAMPLES:
BOX 1, + 10, + 10

BOX 1, 10, 10, 60, 60


BOX , 10, 10, 60, 60, 45, 1
BOX , 30, 90, , 45, 1

Draw a box 10 pixels to the right and 10 down from


the current pixel cursor location.
Draws the outline of a rectangle.
Draws a painted, rotated box (a diamond).
Draws a filled, rotated polygon.

Any parameter can be omitted but you must include a comma in its place, as in the last
two examples.

NOTE: Wrapping occurs if the degree is greater than 360.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

BSAVE
Save a binary file from the specified memory locations
BSAVE "fflename"[,Ddrive number][<ONI,U>device number] [,Bbank
number],Pstart address TO Pend address
where:

start address is the starting address where the program is SAVEd from

end address is the last address 4- 1 in memory which is SAVEd

This is similar to the SAVE command in the Machine Language MONITOR.


EXAMPLES:
BSAVE "SPRITE DATA",B0,
P3584 TO P4096
BSAVE "PROGRAM.SCR",DO,
U9,B0,P3182 TO P7999

Saves the binary file named "SPRITE DATA",


starting at location 3584 through 4095 (BANK
0).

Saves the binary file named "PROGRAM.


S C R " in the memory address range 3182
through 7999 (BANK 0) on drive 0, unit 9.

CATALOG
Display the disk directory
CATALOG [Ddrive number][<ON|,>Udevice number][,wildcard string]
EXAMPLE:
CATALOG

Displays the disk directory on drive 0.

CHAR
Display characters at the specified position on the screen
CHAR [color source],X,Y[,string][,RVS]
This is primarily designed to display characters on a bit mapped screen, but it can also
be used on a text screen. Here's what the parameters mean:
color source

0 = Background
1 = Foreground
Character column (0-39) (VIC screen)
(0-79) (8563) screen

31

32

COMMODORE 128

Y
string
reverse

Character row (0-24)


String to print
Reverse field flag (0 = off, 1 = on)

EXAMPLE:
10
20
30
30

COLOR 2,3: REM MULTI-COLOR 1 = RED


COLOR 3,7: REM MULTI-COLOR 2 = BLUE
GRAPHIC 3,1
CHAR 0,10,10, " T E X T " , 0

CIRCLE
Draw circles, ellipses, arcs, etc., at specified positions on the screen
CIRCLE [color source],X,Y[,Xr][,Yr] [,sa][,ea][,angle][,inc]
where:
color source

0 = background color
1 = foreground color
2 = multi-color 1
3 - multi-color 2

X,Y

Center coordinate of the CIRCLE

Xr

X radius (scaled); (default = 0)

Yr

Y radius (sealed default is Xr)

sa

Starting arc angle (default 0 degrees)

ea

Ending arc angle (default 360 degrees)

angle
inc

Rotation is clockwise degrees (default is 0 degrees)


Degrees between segments (default is 2 degrees)

EXAMPLES:

o:

CIRCLE1, 160,100,65,10

Draws an ellipse.

CIRCLE1, 160,100,65,50

Draws a circle.

sa

ea

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

ClRCLEl, 60,40,20,18,,,,45

Draws an octagon.

CIRCLE1, 260,40,20,,,,,90

Draws a diamond.

CIRCLE1, 60,140,20,18,,,, 120

Draws a triangle.

CIRCLE 1, + 2, + 2,50,50

Draws a circle (two pixels down and two to the


right) relative to the original coordinates of the
pixel cursor.

C1RCLE1, 30;90

Draws a circle 30 pixels and 90 degrees to the


right of the current pixel cursor coordinate
position.

You may omit a parameter, but you must still place a comma in the appropriate
position. Omitted parameters take on the default values.

CLOSE
Close logical file
CLOSE file number
EXAMPLE:
CLOSE 2

Logical file 2 is closed.

CLR
Clear program variables
CLR

CMD
Redirect screen output to a logical disk or print file.
CMD logical file number [,write list]
EXAMPLE:
OPEN 1,4
CMD 1
LIST

Opens device 4 (printer).


All normal output now goes to the printer.
The LlSTing goes to the printer, not the screeneven the word
READY.

PRINT#1

Sends output back to the screen.

CLOSE 1

Closes the file.

33

34

COMMODORE 128

COLLECT
Free inaccessible disk space
COLLECT [Ddrive number][<ON|,>Udevice]
EXAMPLE:
COLLECT DO

Free all available space which has been incorrectly allocated to


improperly closed files. Such files are indicated with an asterisk
on the disk directory.

COLLISION
Define handling for sprite collision interrupt
COLLISION type [,statement]
type
Type of interrupt, as follows:
1 = Sprite-to-sprite collision
2 = Sprite-to-display data collision
3 = Light pen (VIC screen only)
statement
BASIC line number of a subroutine
EXAMPLE:
Collision 1, 5000
Collision 1
Collision 2, 1000

Enables a sprite-to-sprite collision and program control sent to


subroutine at line 5000.
Stops interrupt action which was initiated in above example.
Enables a sprite-to-data collision and program control directed
to subroutine in line 1000.

COLOR
Define colors for each screen area
COLOR source number, color number
This statement assigns a color to one of the seven color areas:
AREA

SOURCE

0
1
2
3
4
5
6

40-column (VIC) background


40-column (VIC) foreground
multicolor 1
multicolor 2
40-column (VIC) border
character color (40- or 80-column screen)
80-column background color

BASIC BUILDING BLOCKS AND BASIC 7.0 ENCYCLOPEDIA

Colors that are usable are in the range 1-16.

COLOR CODE

COLOR

COLOR CODE

1
2
3
4
5
6
7
8

Black
White
Red
Cyan
Purple
Green
Blue
Yellow

9
10
11
12
13
14
15
16

COLOR

Orange
Brown
Light Red
Dark Gray
Medium Gray
Light Green
Light Blue
Light Gray

Color Numbers in 40-Column O u t p u t

1
2
3
4
5
6
7
8

Black
White
Dark Red
Light Cyan
Light Purple
Dark Green
Dark Blue
Light Yellow

9
10
11
12
13
14
15
16

Dark Purple
Dark Yellow
Light Red
Dark Cyan
Medium Gray
Light Green
Light Blue
Light Gray

Color Numbers in 80-Column O u t p u t

EXAMPLES:
COLOR 0, 1:

Changes background color of 40-column screen to black.

COLOR 5, 8:

Changes character color to yellow.

CONCAT
Concatenate two data files
CONCAT "file 2" [,Ddrive number] TO "fHe 1"
[,Ddrive number][<ON|,>Udevice]
EXAMPLE:
Concat "File B " to "File A "

FILE B is attached to FILE A, and the combined


file is designated FILE A.

Concat (A$) to (B$), D1, U9

The file named by B$ becomes a new file with


the same name with the file named by A$ attached to the end of B$. This is performed on
Unit 9, drive 1 (a dual disk drive).

35

36

COMMODORE 128

Whenever a variable is used as a filename, as in the last example, the filename variable
^ must be within parentheses.

CONT
Continue program execution
CONT

COPY
Copy a file from one drive to another within a dual disk drive. Copy one file to
another with a different name within a single drive
COPY [Ddrive number,]"source fiIename"TO[Ddrive
filename"[<ON|,>Udevice]

number,]"destination

NOTE: Copying between two single or double disk drive units cannot be
done. This command does not support unit-to-unit copying.

EXAMPLES:
COPY DO, "TEST" TO D1, "TEST PROG"

Copies " t e s t " from drive 0 to drive


1, renaming it "test prog" on drive 1.

COPY DO, " S T U F F " TO D1, " S T U F F "

Copies " S T U F F " from drive 0 to


drive 1.

COPY DO TO D1

Copies all files from drive 0 to drive


1.

COPY " W O R K . P R O G " TO " B A C K U P "

Copies " W O R K . P R O G " as a file


called "BACKUP" on the same disk
(drive 0).

DATA
Define data to be used by a program
DATA list of constants
EXAMPLE:
DATA 100, 200, FRED, "HELLO, M O M " , , 3, 14, ABC123

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

DCLEAR
Clear all open channels on disk drive
DCLEAR [Ddrive number][<ON|,>Udevice]
EXAMPLES:
DCLEAR D0
DCLEAR D l , U 9

Clears all open files on drive 0, device number 8.


Clears all open files (channels) on drive 1, device number 9.

DCLOSE
Close disk file
DCLOSE [#logical file number][<ON|,>Udevice]
EXAMPLES:
DCLOSE
DCLOSE # 2
DCLOSE ON U9

Closes all channels currently open on unit 8.


Closes the channel associated with the logical file number 2 on
unit 8.
Closes all channels currently open on unit 9.

DEF FN
Define a user function
DEF FN name (variable) = expression
EXAMPLE:
10 DEF FNA(X) 20 PRINT FNA(7)

12*(34.75-X/.3) + X

The number 7 is inserted each place X is located in the formula given in the DEF
statement. In the example above, the answer returned is 144.

NOTE: If you plan to define a function in a program that will use BASIC
7.0 graphics commands, invoke the GRAPHIC command before defining
your function. The portion of memory where functions are defined and
where the graphics screen is located is shared. Once you allocate your
graphics area, the function definitions are safely placed somewhere else
in memory. If you don't take this precaution and you invoke the GRAPHIC
command after you define a function, the function definition (between
$1C00 and $4000) is destroyed.

37

38

COMMODORE 128

DELETE
Delete lines of a BASIC program in the specified range
DELETE [first line] [-last line]
EXAMPLES:
DELETE 75
DELETE 10-50
DELETE-50
DELETE 75-

Deletes line 75.


Deletes lines 10 through 50, inclusive.
Deletes all lines from the beginning of the program up to and
including line 50.
Deletes all lines from 75 to the end of the program, inclusive.

DIM
Declare number of elements in an array
DIM variable (subscripts) [,variable(subscripts)] . . .
EXAMPLE:
10 DIM A$(40),B7(15),CC%(4,4,4)
Dimension three arrays where arrays A$, B7 and CC% have 41 elements, 16 elements
and 125 elements respectively.

DIRECTORY
Display the contents of the disk directory on the screen
DIRECTORY [Ddrive number][<ON|,>Udevice][,wildcardl
EXAMPLES:
DIRECTORY
DIRECTORY D1, U9, " W O R K "
DIRECTORY "AB*

DIRECTORY D0, " 7 . B A K "

Lists all files on the disk in unit 8.


Lists the file named " W O R K , " on drive 1 of
unit 9.
Lists all files starting with the letters " A B "
like ABOVE, ABOARD, etc. on unit 8. The
asterisk specifies a wild card, where all files
starting with " A B " are displayed.
The ? is a wild card that matches any single
character in that position. For example: FILE
l.BAK, FILE 2.BAK, FILE 3.BAK all match
the string.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

DIRECTORY Dl,U9,(A$)

LISTS the filename stored in the variable A$


on device number 9, drive 1. Remember, whenever a variable is used as a filename, put the
variable in parentheses.

NOTE: To print the DIRECTORY of the disk in drive 0, unit 8, use the
following example:
LOAD"$O",8
OPEN4,4:CMD4:LIST
PRINT#4:CLOSE4

DLOAD
Load a BASIC program from the disk drive, device 8.
DLOAD "filename" [,Ddrive number][<ON|,>Udevice number]
EXAMPLES:
DLOAD " B A N K R E C S "
DLOAD (A$)

Searches the disk for the program


and LOADS it.

"BANKRECS"

LOADS a program from disk in which the name is


stored in the variable A$. An error message is given if
A$ is null. Remember, when a variable is used as a
filename, it must be enclosed in parentheses.

DO / LOOP / WHILE / UNTIL / EXIT


Define and control a program loop
DO fUNTIL condition | WHILE condition]
statements [EXIT]
LOOP [UNTIL condition | WHILE condition]
This loop structure performs the statements between the DO statement and the LOOP
statement. If no UNTIL or WHILE modifies either the DO or the LOOP statement,
execution of the statements in between continues indefinitely. If an EXIT statement is
encountered in the body of a DO loop, execution is transferred to the first statement
following the LOOP statement. DO loops may be nested, following the rules defined by
the FOR-NEXT structure. If the UNTIL parameter is specified, the program continues
looping until the condition is satisfied (becomes true). The WHILE parameter is the
opposite of the UNTIL parameter; the program continues looping as long as the
condition is TRUE. As soon as the condition is no longer true, program control resumes
with the statement immediately following the LOOP statement. An example of a
condition (boolean argument) is A = 1, or G > 6 5 .

39

40

COMMODORE 128

EXAMPLES:
10
20
30
40
50
60

X - 25
DO UNTIL X - 0
X - X-1
PRINT " X = " ; X
LOOP
PRINT "End of Loop"

This example performs the statements X = X-1


and PRINT " X - '';X until X = 0 . W h e n X - 0the
program resumes with the PRINT "End of Loop"
statement immediately following LOOP.

10 DO WHILE A $ < > CHR$ (13):GETKEY A$:PRINT A$:LOOP


20 PRINT " T H E RETURN KEY HAS BEEN PRESSED"
This DO loop waits for a key to be pressed,
receives input from the keyboard one character at
a time and prints the letter of the key which is
pressed. If the RETURN key is pressed, control is
transferred out of the loop and line 20 is executed.
10
20
30
40
50
60

DOPEN # 8 , "SEQFILE"
DO
GET # 8 , A $
PRINT A$;
LOOP UNTIL ST
DCLOSE # 8

This program opens file " S E Q F I L E " and gets


data until the ST system variable indicates all data
is input.

DOPEN
Open a disk file for a read and/or write operation
DOPEN # logical f!le number,"fllename[,<type>]"[,Lrecord length]
[,Ddrive number][<ON|,>Udevice number][,W]
where type is:
S
P
U
R
L
W

=
=
=
=
=
=

Sequential File Type


Program File Type
User File Type
Relative File Type
Record Length = the length of records in a relative file only
Write Operation (if not specified a read operation occurs)

EXAMPLES:
DOPEN#l, "ADDRESS",W

Create the sequential file number 1 (ADDRESS)


for a write operation

DOPEN#2 "RECIPES",Dl,U9

Open the sequential file number 2 (RECIPES)


for a read operation on device number 9, drive 1

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

DRAW
Draw dots, lines and shapes at specified positions on the screen
DRAW [color source] [,X1, Yl][TO X2, Y2] . . .
where:
Color source

X1,Y1
X2,Y2

0 = Bit map background


1 - Bit map foreground
2 = Multi-color 1
3 = Multi-color 2
Starting coordinate (0,0 through 319,199)
Ending coordinate (0,0 through 319,199)

EXAMPLES:
DRAW 1, 100, 50

Draw a dot.

DRAW , 10,10 TO 100,60

Draw a line.

DRAW , 10,10 TO 10,60 TO 100,60 TO 10,10

Draw a triangle.

DRAW 1, 120;45

Draw a dot 45 relative and 120 pixels


away from the current pixel cursor
position.

DRAW

Draw a dot at the present pixel cursor


position. Use LOCATE to position the
pixel cursor.

You may omit a parameter but you still must include the comma that would have
followed the unspecified parameter. Omitted parameters take on the default values.

DSAVE
Save a BASIC program file to disk
DSAVE "filename" [,Ddrive number][<ON|,>Udevice number]
EXAMPLES:
DSAVE " B A N K R E C S "
DSAVE (A$)
DSAVE "PROG 3 " , D l , U 9

Saves the program " B A N K R E C S " to disk.


Saves the disk program named in the variable A$.
Saves the program " P R O G 3 " to disk on unit number 9, drive 1.

41

42

COMMODORE 128

DVERIFY
Verify the program in memory against the one on disk
DVERIFY "filename"[,Ddrive number][<ON|,>Udevice number]
To verify Binary data, see VERIFY "filename",8,l format, under VERIFY command
description.
EXAMPLES:
DVERIFY " C 1 2 8 "
DVERIFY "SPRITES'',D0,U9

Verifies program " C 1 2 8 " on drive 0, unit 8.


Verifies program "SPRITES" on drive 0, device 9.

END
Define the end of program execution
END

ENVELOPE
Define a musical instrument envelope
ENVELOPE n[,atk] [,dec] [,sus] [,re!][,wf] [,pw]
where:
n
atk
dec
sus
rel
wf

pw

Envelope number (0-9)


Attack rate (0-15)
Decay rate (0-15)
Sustain (0-15)
Release rate (0-15)
Waveform: 0 = triangle
1 = sawtooth
2 = variable pulse (square)
3 = noise
4 = ring modulation
Pulse width (0-4095)

See the " T " option in the PLAY command to select an envelope in a PLAY string.
EXAMPLE:
ENVELOPE 1, 10, 5, 10, 0, 2, 2048

This command sets envelope 1 to Attack


= 10, Decay = 5, Sustain = 10, Release
= 0, waveform = variable pulse (2), and
the pulse width = 2048

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

FAST
Sets the 8502 microprocessor at a speed of 2MHz.
FAST
This command initiates 2MHz mode, causing the VIC 40-column screen to be turned off.
All operations are speeded up considerably. Graphics may be used, but will not be visible
until a SLOW command is issued. The Commodore 128 powers up in lMHz mode. The
DMA operations (FETCH, SWAP, STASH) must be performed at lMHz (slow) speed.

FETCH
Get data from expansion (RAM module) memory
FETCH #bytes, intsa, expsa, expb
where bytes = Number of bytes to get from expansion memory (0-65535) where 0 =
64K (65535 bytes)
intsa = Starting address of host RAM (0-65535)
expb = 64K expansion RAM bank number (0-7) where expb = 0 - 1 for 128K
and expb = 0 - 7 for up to 512K.
expsa = Starting address of expansion RAM (0-65535)
The host BANK for the ROM and I/O configuration is selected with the BANK
command. The DMA(VIC) RAM bank is selected by bits 6 and 7 of the RAM
configuration register within the MMU($D506).

FILTER
Define sound (SID chip) filter parameters
FILTER [freq][,lp] [,bp] [,hp] [,res]
where:
freq
ip
bp
hp
res

Filter cut-off frequency (0-2047)


Low-pass filter on (1), off (0)
Band-pass filter on (1), off (0)
High-pass filter on (1), off (0)
Resonance (0-15)

Unspecified parameters result in no change to the current value.


EXAMPLES:
FILTER 1024,0,1,0,2

Set the cutoff frequency at 1024, select the band pass


filter and a resonance level of 2.

FILTER 2000,1,0,1,10

Set the cutoff frequency at 2000, select both the low


pass and high pass filters (to form a notch reject) and set
the resonance level at 10.

43

44

COMMODORE 128

FOR / TO / STEP / NEXT


Define a repetitive program loop structure.
FOR variable - start value TO end value [STEP increment] NEXT variable
The logic of the FOR/NEXT statement is as follows. First, the loop variable is set to the
start value. When the program reaches a program line containing the NEXT statement, it
adds the STEP increment (default = 1) to the value of the loop variable and checks to
see if it is higher than the end value of the loop. If the loop variable is less than or equal
to the end value, the loop is executed again, starting with the statement immediately
following the FOR statement. If the loop variable is greater than the end value, the loop
terminates and the program resumes immediately following the NEXT statement. The
opposite is true if the step size is negative. See also the NEXT statement.
EXAMPLE:
10
20
30
40

FOR L = 1 TO 10
PRINT L
NEXT L
PRINT " I ' M DONE! L =

"L

This program prints the numbers from one to 10 followed by the message I'M DONE!
L - 11.
EXAMPLE:
10
20
30
40

FOR L - 1 TO 100
FOR A - 5 TO 11 STEP .5
NEXT A
NEXT L

The FOR . . . NEXT loop in lines 20 and 30 are nested inside the one in line 10 and 40.
Using a STEP increment of .5 is used to illustrate the fact that floating point indices are
valid. The inner rested loop must lie completely within the outer rested loop (lines 10
and 40).

GET
Receive input data from the keyboard, one character at a time, without waiting for a key
to be pressed.
GET variable list
EXAMPLE:
10 DO:GETA$:LOOP UNTIL A$ = " A "

This line waits for the A key to be


pressed to continue.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

20 GET B, C, D

GET numeric variables B,C and D from the keyboard without


waiting for a key to be pressed.

GETKEY
Receive input data from the keyboard, one character at a time and wait for a key to be
pressed.
GETKEY variable list
EXAMPLE:
10 GETKEY A$
This line waits for a key to be pressed. Typing any key continues the program.
10 GETKEY A$,B$,C$
This line waits for three alphanumeric characters to be entered from the keyboard.

GET#
Receive input data from a tape, disk or RS232
G E T # logical file number, variable list
EXAMPLE:
10 G E T # l , A $

This example receives one character, which is stored in the


variable A$, from logical file number 1. This example assumes
that file 1 was previously opened. See the OPEN statement.

G064
Switch to C64 mode
G064
To return to C128 mode, press the reset button, or turn off the computer power and
turn it on again.

GOSUB
Call a subroutine from the specified line number
GOSUB line number
EXAMPLE:
20 GOSUB 800

This example calls the subroutine beginning at line 800 and executes
it. All subroutines must terminate with a RETURN statement.

45

46

C O M M O D O R E 128

800 PRINT " T H E C128 WAS WORTH THE WAIT!": RETURN

GOTO / GO TO
Transfer program execution to the specified line number
GOTO line number
EXAMPLES:
10 PRINT 4 'COMMODORE''
20 GOTO 10

The GOTO in line 20 makes line 10 repeat continuously until RUN/STOP is pressed.

GOTO 100

Starts (RUNs) the program starting at line 100,


without clearing the variable storage area.

GRAPHIC
Select a graphic mode
1) GRAPHIC mode [,clear][,s]
2) GRAPHIC CLR
This statement puts the Commodore 128 in one of the six graphic modes:
MODE

DESCRIPTION

0
1
2
3
4
5

40-eolumn text (default)


standard bit-map graphics
standard bit-map graphics (split screen)
multi-color bit-map graphics
multi-color bit-map graphics (split screen)
80-column text

EXAMPLES:
GRAPHIC 1,1
GRAPHIC 4,0,10

Select standard bit map mode and clear the bit map.
Select split screen multi-color bit map mode, do not clear the
bit map and start the split screen at line 10.

GRAPHIC 0

Select 40-column text.

GRAPHIC 5

Select 80-column text.

GRAPHIC CLR

GSHAPE
See SSHAPE.

Clear and deallocate the bit map screen.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

HEADER
Format a diskette
HEADER "diskname" [,1 i.d.] [,Ddrive number]
[<ON|,>Udevice number]
Before a new disk can be used for the first time, it must be formatted with the HEADER
command. The HEADER command can also be used to erase a previously formatted
disk, which can then be reused.
When you enter a HEADER command in direct mode, the prompt ARE YOU
SURE? appears. In program mode, the prompt does not appear.
The HEADER command is analogous to the BASIC 2.0 command:
OPEN l,8,15,"N0:diskname,i.d."
EXAMPLES:
HEADER "MYDISK",I23, D0

This headers " M Y D I S K " using i.d. 23


on drive 0, (default) device number 8.

HEADER " R E C S " , 145, D1 ON U9

This headers " R E C S " using i.d. 45, on


drive 1, device number 9.

HEADER "C128 PROGRAMS", D0

HEADER (A$),I76,D0,U9

This is a quick header on drive 0, device


number 8, assuming the disk in the drive
was already formatted. The old i.d. is
used.
This example headers the diskette with
the name specified by the variable A$,
and the i.d. 76 on drive 0, device number 9.

HELP
Highlight the line where the error occurred
HELP
The HELP
is typed in
containing
line where

command is used after an error has been reported in a program. When HELP
40-column format, the line where the error occurs is listed, with the portion
the error displayed in reverse field. In 80-column format, the portion of the
the error occurs is underlined.

IF / THEN / ELSE
Evaluate a conditional expression and execute portions of a program depending on the
outcome of the expression

47

48

COMMODORE 128

IF expression THEN statements [:ELSE

else-clause]

THE IF . . . THEN statement evaluates a BASIC expression and takes one of two
possible courses of action depending upon the outcome of the expression. If the
expression is true, the statement(s) following THEN is executed. This can be any
BASIC statement or a line number. If the expression is false, the program resumes with
the program line immediately following the program line containing the IF statement,
unless an ELSE clause is present. The entire IF . . . THEN statement must be contained
within 160 characters. Also see BEGIN/BEND.
The ELSE clause, if present, must be on the same line as the IF . . . THEN
portion of the statement, and separated from the THEN clause by a colon. When an
ELSE clause is present, it is executed only when the expression is false. The expression
being evaluated may be a variable or formula, in which case it is considered true if
nonzero, and false if zero. In most cases, there is an expression involving relational
operators ( , < , > , < = , > = , < > ) .
EXAMPLE:
50 IF X > 0 THEN PRINT " O K " : ELSE END
This line checks the value of X. lf X is greater than 0, the statement immediately
following the keyword THEN (PRINT " O K " ) is executed and the ELSE clause is
ignored. If X is less than or equal to 0, the ELSE clause is executed and the statement
immediately following THEN is ignored.
10 IF X = 10 THEN 100
This example evaluates the value of X.
20 PRINT " X DOES NOT EQUAL 10" IF X equals 10, the program control is
transferred to line 100 and the message
99 STOP
" X EQUALS 10" is printed. IF X
100 PRINT " X EQUALS 10"
does not equal 10, the program resumes with line 20, the C128 prints the
prompt " X DOES NOT EQUAL 10"
and the program stops.

INPUT
Receive a data string or a number from the keyboard and wait for the user to press
RETURN
INPUT ["prompt string";] variable list
EXAMPLE:
10 INPUT "PLEASE TYPE A NUMBER";A
20 INPUT "AND YOUR NAME";A$
30 PRINT A$ " YOU TYPED THE NUMBER";A

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

INPUT #
Input data from an I/O channel into a string or numeric variable
I N P U T # file number, variable list
EXAMPLE:
10 OPEN 2,8,2
20 INPUT#2, A$, C, D$
This statement INPUTs the data stored in variables A$, C and D$ from the disk file
number 2, which was OPENed in line 10.

KEY
Define or list function key assignments
KEY [key number, string]
The maximum length for all the definitions together is 241 characters, (p. 3-41)
EXAMPLE:
KEY 7, " G R A P H I C 0 " + CHR$(13) + " L I S T " + CHR$(13)
This tells the computer to select the (VIC) text screen and list the program whenever the
F7 key is pressed (in direct mode). CHR$(13) is the ASCII character for RETURN and
performs the same action as pressing the RETURN key. Use CHR$(27) for ESCape.
Use CHR$(34) to incorporate the double quote character into a KEY string. The keys
may be redefined in a program. For example:
10 KEY 2,"PRINT D S $ " + CHR$(13)
This tells the computer to check and display the disk drive error channel variables
(PRINT DS$) each time the F2 function key is pressed.
10
20
30
40

FOR
KEY
FOR
KEY

1= 1 to 7 STEP 2
I, CHR$(I + 132):NEXT
I = 2 to 8 STEP 2
I, CHR$(I + 132):NEXT

This defines the function keys as they are defined on the Commodore 64.

LET
Assigns a value to a variable
[LET] variable = expression
EXAMPLE:
10 LET A = 5

Assign the value 5 to numeric variable A.

49

50

COMMODORE 128

20 B = 6

Assign the value 6 to numeric variable B.

30 C = A * B + 3

Assign the numeric variable C, the value resulting from 5


times 6 plus 3.

40 D$ = " H E L L O "

Assign the string " H E L L O " to string variable D$.

LIST
List the BASIC program currently in memory
LIST [first line] [- last line]
In C128 mode, LIST can be used within a program without terminating program execution.
EXAMPLES:
LIST

Shows

LIST 100-

Shows

LIST 10

Shows

LIST - 1 0 0

Shows

LIST 10-200

Shows

LOAD
Load a program from a peripheral device such as the disk drive or Datassette
LOAD "filename" [,device number] [,relocate flag]
This is the command used to recall a program stored on disk or cassette tape. Here, the
filename is a program name up to 16 characters long, in quotes. The name must be
followed by a comma (outside the quotes) and a number which acts as a device number
to determine where the program is stored (disk or tape). If no number is supplied, the
Commodore 128 assumes device number 1 (the Datassette tape recorder).
EXAMPLES:
LOAD

Reads in the next program from tape.

LOAD " H E L L O "

Searches tape for a program called HELLO, and


LOADs it if found.

LOAD (A$),8

LOADs the program from disk whose name is


stored in the variable A$.

LOAD"HELLO",8

Looks for the program called HELLO on disk drive


number 8, drive 0. (This is equivalent to DLOAD
"HELLO").

LOAD"MACHLANG",8,l

LOADs the machine language program called


" M A C H L A N G " into the location from which it
was SAVEd.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

LOCATE
Position the bit map pixel cursor on the screen
LOCATE X,Y
The LOCATE statement places the pixel cursor (PC) at any specified pixel coordinate on
the screen.
The pixel cursor (PC) is the coordinate on the bit map screen where drawing of
circles, boxes, lines and points and where PAINTing begins.
EXAMPLE:
LOCATE 160,100

Positions the PC in the center of the bit map screen. Nothing will be seen until something is drawn.

LOCATE +20,100

Move the pixel cursor 20 pixels to the right of the last PC


position and place it at Y coordinate 100.

LOCATE - 3 0 , + 20

Move the PC 30 pixels to the right and 20 down from the


previous PC position.

The PC can be found by using the RDOT(O) function to get the X-coordinate and
RDOT(l) to get the Y-coordinate. The color source of the pixel at the PC can be found
by PRINTing RDOT(2).

MONITOR
Enter the Commodore 128 machine language monitor
MONITOR
See Chapter 6 for details on the Commodore 128 Machine Language Monitor.

MOVSPR
Position or move sprite on the screen
1) MOVSPR number,X,Y
2) MOVSPR number, + / - X , + / - Y
3) MOVSPR number,X;Y

Place the specified sprite at absolute


sprite coordinate X,Y.
Move sprite relative to the position
of the sprite's current position.
Move sprite distance X at angle Y
relative to the sprite's current position.

51

52

COMMODORE 128

4) MOVSPR number, angle # speed

Move sprite at an angle relative to


its current coordinate, in the clockwise direction and at the specified
speed.

where:
number is sprite's number (1 through 8)
X,Y is coordinate of the sprite location.
angle is the angle (0-360) of motion in the clockwise direction relative to the
sprite's original coordinate.
speed is a speed (0-15) in which the sprite moves.
This statement moves a sprite to a specific location on the screen according to
the SPRITE coordinate plane (not the bit map plane) or initiates sprite motion at a
specified rate. See MOVSPR in Chapter 9 for a diagram of the sprite coordinate
system.
EXAMPLES:
MOVSPR 1,150,150

Position sprite 1 near the center of the screen, x,y


coordinate 150,150.

MOVSPR 1, + 20,-30

Move sprite 1 to the right 20 coordinates and up 30


coordinates.

MOVSPR 4, - 5 0 , + 100

Move sprite 4 to the left 50 coordinates and down 100


coordinates.

MOVSPR 5, 45 # 1 5

Move sprite 5 at a 45 degree angle in the clockwise


direction, relative to its original x and y coordinates.
The sprite moves at the fastest rate (15).

NOTE: Once you specify an angle and a speed as in the fourth example
of the MOVSPR statement, the sprite continues on its path (even if the
sprite display is disabled) after the program stops, until you set the speed
to 0 or press RUN/STOP and RESTORE. Also, keep in mind that the
SCALE command affects the MOVSPR coordinates. If you add SCALing
to your programs, you also must adjust the sprites' new coordinates so
they appear correctly on the screen.

NEW
Clear (erase) BASIC program and variable storage
NEW

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

ON
Conditionally branch to a specified program line number according to the results of the
specified expression
ON expression <GOTO/GOSUB> line # 1 [, line # 2 , . . .]
EXAMPLE:
10
20
25
30
40
50
60

INPUT X:IF X < 0 THEN 10


ON X GOTO 30, 40, 50, 60
STOP
PRINT " X - 1"
PRINT " X = 2 "
PRINT " X - 3 "
PRINT " X = 4 "

When X = 1, ON sends control to the first line


number in the list (30). When X = 2, ON sends
control to the second line (40), etc.

OPEN
Open files for input or output
OPEN logieal file number, device number [,secondary address] [<,"filename
[,f!letype[, [mode"]]|<,cmd string>]
EXAMPLES:
10 OPEN 3,3

OPEN the screen as file number


3.

20 OPEN 1,0

OPEN the keyboard as file number 1.

30 OPEN l , l , O , " D O T "

OPEN the cassette for reading, as


file number 1, using " D O T " as
the filename.

OPEN 4,4

OPEN the printer as file number 4.

OPEN 15,8,15

OPEN the command channel on


the disk as file 15, with secondary
address 15. Secondary address 15
is reserved for the disk drive error
channel.

5 OPEN 8,8,12,"TESTFILE,S,W"

OPEN a sequential disk file for


writing called TESTFILE as file
number 8, with secondary address
12.

53

54

COMMODORE 128

See also: CLOSE, CMD, G E T # , INPUT#, and PRINT# statements and system
variables ST, DS, and DS$.

PAINT
Fill area with color
PAINT [color source],X,Y[,mode]
where:
color source

0
1
2
3

=
=
=
=

bit map foreground


bit map background (default)
multi-color 1
multi-color 2

X,Y

starting coordinate, scaled (default at pixel cursor (PC))

mode

0 = paint an area defined by the color source selected


1 = paint an area defined by any nonbackground source

The PAINT command fills an area with color. It fills in the area around the specified
point until a boundary of the same specified color source is encountered. For example, if
you draw a circle in the foreground color source, start PAINTing the circle where the
coordinate assumes the background source. The Commodore 128 will only PAINT
where the specified source in the PAINT statement is different from the source of the x
and y pixel coordinate. It cannot PAINT points where the sources are the same in the
PAINT statement and the specified coordinate. The X and Y coordinate must lie
completely within the boundary of the shape you intend to PAINT, and the source of the
starting pixel coordinate and the specified color source must be different.
EXAMPLE:
10 CIRCLE 1, 160,100,65,50

Draws an outline of a circle.

20 PAINT 1, 160,100

Fills in the circle with color from source 1 (VIC


foreground), assuming point 160,100 is colored in
the background color (source 0).

10 BOX 1, 10, 10, 20, 20

Draws an outline of a box.

20 PAINT 1, 15, 15

Fills the box with color from source l, assuming


point 15,15 is colored in the background source
(0).

30 PAINT 1, + 10, + 10

PAINT the screen in the foreground color source


at the coordinate relative to the pixel cursor's
previous position plus 10 in both the vertical and
horizontal positions.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

100 PAINT 1, 100;90

Paint the screen area 90 relative to and 100


pixels away from the current pixel cursor coordinate.

PLAY
Defines and plays musical notes and elements within a string or string variable.
PLAY "Vn,On,Tn,Un,Xn,elements, notes"
where the string or string variable is composed of the following
Vn = Voice (n = 1-3)
On = Octave (n = 0-6)
Tn = Tune Envelope Defaults (n = 0-9)
0 = piano
1 = accordion
2 = calliope
3 = drum
4 = flute
5 = guitar
6 = harpsichord
7 = organ
8 = trumpet
9 = xylophone
Un = Volume (n = 0-8)
Xn = Filter on (n = 1), off(n = 0)
notes:
A,B,C,D,E,F,G
elements:
#
Sharp
$
Flat
W
Whole note
H
Half note
Q
Quarter note
I
Eighth note
S
Sixteenth note
Dotted
R
Rest
M
Wait for all voices currently playing to end
the current "measure"
The PLAY statement gives you the power to select voice, octave and tune envelope
(including ten predefined musical instrument envelopes), the volume, the filter, and the
notes you want to PLAY. All these controls are enclosed in quotes. You may include
spaces in a PLAY string for readability.
All elements except R and M precede the musical notes in a PLAY string.

55

56

COMMODORE 128

EXAMPLES:
PLAY ' ' V 1 0 4 T 0 U 5 X 0 C D E F G A B ' '

Play the notes C , D , E , F , G , A and B


in voice 1, octave 4, tune envelope
0 (piano), at volume 5, with the
filter off.

PLAY " V 3 0 5 T 6 U 7 X 1 # B $ A W . C H D Q E I F ' '

Play the notes B-sharp, A-flat, a


whole dotted-C note, a half D-note,
a quarter E-note and an eighth
F-note.

A$ = " V 3 0 5 T 6 U 3 A B C D E " : PLAY A$

PLAY the notes and elements within


A$.

PLAY ' 4 V l C V 2 E V 3 G ' '

Plays a chord in the default setting.

POKE
Change the contents of a RAM memory location
POKE address, value
EXAMPLE:
10 POKE 53280,1

Changes VIC border color

PRINT
Output to the text screen
PRINT [print list]
The word PRINT can be followed by any of the following:
Characters inside quotes
Variable names
Functions
Expressions
Punctuation marks

( ' ' text'')


(A, B, A$, X$)
(SIN(23), ABS(33))
(2 + 2),A + 3,A = B)
(;,)

EXAMPLES:
10 PRINT " H E L L O "
20A$ ="THERE":PRINT "HELLO";A$
30 A - 4:B = 2:?A + B
40 J = 41:PRINT J;:PRINT J - 1
50 PRINT A;B;:D = A + B:PRINT D;A-B
See also POS, SPC, TAB and CHAR functions.

RESULTS

HELLO
HELLO THERE

6
41 40
4 2 6

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

PRINT#
Output data to files
P R I N T # file number[, print list]
P R I N T # is followed by a number which refers to the data file previously OPENed.
EXAMPLE:
10 OPEN 4,4
20 P R I N T # 4 , " H E L L O T H E R E ! " , A $ , B $

Outputs the data " H E L L O T H E R E "


and the variables A$ and B$ to the
printer.

10 OPEN 2,8,2
20 P R I N T # 2 , A , B $ , C , D

Outputs the data variables A, B$, C


and D to the disk file number 2.

NOTE: The P R I N T # command is used by itself to close the channel to


the printer before closing the file, as follows:
10
30
40
50

OPEN 4,4
PRINT#4, "PRINT WORDS"
PRINT#4
CLOSE 4

PRINT USING
Output using format
PRINT [#fiIe number,] USING"format list"; print list
This statement defines the format of string and numeric items for printing to the text
screen, printer or other device.
EXAMPLE:
5 X = 32: Y = 100.23: A$ = " C A T "
10 PRINT USING " $ # # . # # # " ; 1 3 . 2 5 , X , Y
20 PRINT USING " # # # > # " ; " C B M " , A $
When this is RUN, line 10 prints:
$13.25 $32.00

$*****

Five asterisks (*****) are printed instead of a Y


value because Y has five digits, and this condition
does not conform to format list (as explained below).

Line 20 prints this:


CBM

CAT

Leaves two spaces before printing " C B M " as defined in format list.

57

58

COMMODORE 128

The pound sign ( # ) reserves room for a single character in the output field. If the data
item contains more characters than there are # signs in the format field, the entire field
is filled with asterisks (*): no characters are printed.
EXAMPLE:
10 PRINT USING " # # # # " ; X
For these values of X, this format displays:
A - 12.34
A = 567.89
A = 123456

12
568
****

For a STRING item, the string data is truncated at the bounds of the field. Only as many
characters are printed as there are pound signs ( # ) in the format item. Truncation occurs
on the right.
EXAMPLES:
FIELD

EXPRESSION

RESULT

COMMENT

##.#
##.#

-.1

^).1

Leading zero added.

1.0

Trailing zero added.

####

-100.5

-101

Rounded to no decimal places.

####

-1000

****

Overflow because four digits and a minus sign


cannot fit in field.

###.

10

10.

Decimal point added.

#$##

$1

Floating dollar sign.

PUDEF
Redefine symbols in PRINT USING statement
PUDEF " n n n n "
Where " n n n n " is any combination of characters, up to four in all. PUDEF allows you to
redefine any of the following four symbols in the PRINT USING statement: blanks, commas,
decimal points and dollar signs. These four symbols can be changed into some other character by placing the new character in the correct position in the PUDEF control string.
Position 1 is the filler character. The default is a blank. Place a new character here
for another character to appear in place of blanks.
Position 2 is the comma character. Default is a comma.
Position 3 is the decimal point. Default is a decimal point.
Position 4 is the dollar sign. Default is a dollar sign.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

EXAMPLES:
10 P U D E F " * "
20 P U D E F " < "

PRINT * in the place of blanks.


PRINT < in the place of commas.

READ
Read data from DATA statements and input it into a numeric or string variable)
READ variable list
This statement inputs information from DATA statements and stores it in variables,
where the data can be used by the RUNning program.
In a program, you can READ the data and then re-read it by issuing the
RESTORE statement. The RESTORE sets the sequential data pointer back to the
beginning, where the data can be read again. See the RESTORE and DATA statements.
EXAMPLES:
10 READ A, B, C
20 DATA 3, 4, 5

READ the first three numeric variables from


the closest data statement.

10 READ A$, B$, C$


20 DATA JOHN, PAUL, GEORGE

READ the first three string variables from


the nearest data statement.

10 READ A, B$, C
20 DATA 1200, NANCY, 345

READ (and input into the C128 memory) a


numeric variable, a string variable and another numeric variable.

RECORD
Position relative file pointers
R E C O R D # logical file number, record number [,byte number]
This statement positions a relative file pointer to select any byte (character) of any
record in the relative file.
When the record number value is set higher than the last record number in the file,
the following occurs:
For a write ( P R I N T # ) operation, additional records are created to expand the file
to the desired record number.
For a read ( I N P U T # ) operation, a null record is returned and a " R E C O R D NOT
PRESENT ERROR occurs". See your disk drive manual for details about relative
files.
EXAMPLES:
10
20
30
40

DOPEN#2,"FILE"
RECORD#2,10,1
PRINT#2,A$
DCLOSE#2

59

60

COMMODORE 128

This example opens an existing relative file called " F I L E " as file number 2 in
line 10. Line 20 positions the relative file pointer at the first byte in record number 10.
Line 30 actually writes the data, A$, to file number 2.

REM
Comments or remarks about the operation of a program line
REM message
EXAMPLE:
10 NEXT X:REM THIS LINE INCREMENTS X.

RENAME
Change the name of a file on disk
R E N A M E "old filename" TO "new
Udevice number]

filename"

[,Ddrive n u m b e r ] [ < O N I , >

EXAMPLES:
RENAME " T E S T " TO " F I N A L T E S T " , D 0

Change the name of the file


" T E S T " to " F I N A L T E S T " .

RENAME (A$) TO (B$),D0,U9

Change the filename specified in


A$ to the filename specified in B$
on drive 0, device number 9. Remember, whenever a variable name
is used as a filename, it must be
enclosed in parentheses.

RENUMBER
Renumber lines of a BASIC program
RENUMBER
number]

[new starting line number][,increment][,old starting line

EXAMPLES:
RENUMBER

R E N U M B E R 2 0 , 20, 1

Renumbers the program starting at 10, and increments


each additional line by 10.
Starting at line 1, renumbers the program. Line 1 becomes line 20, and other lines are numbered in increments of 20.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

RENUMBER,, 65

Starting at line 65, renumbers in increments of 10. Line


65 becomes line 10. If you omit a parameter, you must
still enter a comma in its place.

RESTORE
Reset READ pointer so the DATA can be reREAD
RESTORE [line#]
If a line number follows the RESTORE statement, the READ pointer is set to the first
data item in the specified program line. Otherwise the pointer is reset to the beginning of
the first DATA statement in the BASIC program.
EXAMPLES:
10
20
30
40
50
60
70

FOR I = 1 TO 3
READ X
ALL = X + ALL
NEXT
RESTORE
GOTO 10
DATA 10,20,30

This example READs the data in line 70 and stores it in


numeric variable X. It adds the total of all the numeric
data items. Once all the data has been READ, three
cycles through the loop, the READ pointer is RESTOREd to the beginning of the program and it returns
to line 10 and performs repetitively.

10
20
30
40
50
60

READ A , B , C
DATA 100,500,750
READ X , Y , Z
DATA 36,24,38
RESTORE 40
READ S,P,Q

Line 50 of this example RESTORES the DATA pointer


to the beginning data item in line 40. When line 60 is
executed, it will READ the DATA 36,24,38 from line
40, and store it in numeric variables S, P, and Q,
respectively.

RESUME
Define where the program will continue (RESUME) after an error has been trapped
RESUME [line number | NEXT]
This statement is used to restart program execution after TRAPping an error. With no
parameters, RESUME attempts to re-execute the statement in which the error occurred.
RESUME NEXT resumes execution at the statement immediately following the one indicating the error. RESUME followed by a line number will GOTO the specific line and
resume execution from that line number. RESUME can only be used in program mode.
EXAMPLE:
10
15
20
40

TRAP 100
INPUT 44 ENTER A N U M B E R " ; A
B - 100/A
P R I N T " T H E RESULT = " ; B

61

62

COMMODORE 128

50 INPUT " D O YOU WANT TO RUN IT AGAIN (Y/N)";Z$:IF Z$ =


THEN 10
60 STOP
100 I N P U T " E N T E R ANOTHER NUMBER (NOT Z E R O ) " ; A
110 RESUME 20

"Y"

This example traps a "DIVISION BY ZERO E R R O R " in line 20 if 0 is entered in line


15. If zero is entered, the program goes to line 100, where you are asked to input another
number besides 0. Line 110 returns to line 20 to complete the calculation. Line 50 asks
if you want to repeat the program again. If you do, press the Y key.

RETURN
Return from subroutine
RETURN
EXAMPLE:
10 PRINT " E N T E R MAIN P R O G R A M "
20 GOSUB 100
30 PRINT " E N D OF P R O G R A M "

90 STOP
100 PRINT "SUBROUTINE 1 "
110 RETURN
This example calls the subroutine at line 100 which prints the message " S U B R O U TINE 1 " and RETURNs to line 30, the rest of the program.

RUN
Execute BASIC program
1) RUN [line number]
2) RUN "filename" [,Ddrive number][<ON|,>Udevice number]
EXAMPLES:
RUN
RUN 100
RUN"PRG1"
RUN(A$)

Starts execution from the beginning of the program.


Starts program execution at line 100.
DLOADs " P R G 1 " from disk drive 8, and runs it from the
starting line number.
DLOADs the program named in the variable A$.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

SAVE
Store the program in memory to disk or tape
SAVE [' 6 filename''][,device number][,EOT flag]
EXAMPLES:
SAVE
SAVE " H E L L O "
SAVE A$,8

Stores program on tape, without a name.


Stores a program on tape, under the name HELLO.
Stores on disk, with the name stored in variable A$.

SAVE " H E L L O " , 8

Stores on disk, with name HELLO (equivalent to


DSAVE " H E L L O " ) .

SAVE " H E L L O " , 1, 2

Stores on tape, with name HELLO, and places an END


OF TAPE marker after the program.

SCALE
Alter scaling in graphics mode
SCALE n [,Xmax,Ymax]
where:
n = 1 (on) or 0 (off)
Coordinates may be scaled from 0 to 32767 (default = 1023) in both X and Y (in either
standard or multicolor bit map mode), rather than the normal scale values, which are:
multi-color mode
bit map mode

X = 0 to 159
X = 0 to 319

Y = 0 to 199
Y = 0 to 199

EXAMPLES:
10 GRAPHIC 1,1
20 SCALE l:CIRCLE 1,180,100,100,100

Enter standard bit map, turn scaling


on to default size (1023, 1023) and
draw a circle.

10 GRAPHIC 1,3
20 SCALE 1,1000,5000
30 CIRCLE 1,180,100,100,100

Enter multi-color mode, turn scaling


on to size (1000, 5000) and draw a
circle.

The SCALE command affects the sprite coordinates in the MOVSPR command. If
you add scaling to a program that contains sprites, adjust the MOVSPR coordinates
accordingly.

63

64

COMMODORE 128

SCNCLR
Clear screen
SCNCLR mode number
The modes are as follows:

MODE NUMBER

0
2
3
4
5

MODE

40 column (VIC) text


bit map
split screen bit map
multi-color bit map
split screen multi-color bit map
80 column (8563) text

This statement with no argument clears the graphic screen, if it is present, otherwise the
current text screen is cleared.
EXAMPLES:
SCNCLR 5
SCNCLR 1
SCNCLR 4

Clears 80 column text screen.


Clears the (VIC) bit map screen.
Clears the (VIC) multicolor bit map and 40-column text split screen.

SCRATCH
Delete file from the disk directory
SCRATCH "filename" [,Ddrive n u m b e r ] [ < O N | , > U d e v i c e number]
EXAMPLE:
SCRATCH " M Y B A C K " , D0
This erases the file MY BACK from the disk in drive 0.

SLEEP
Delay program for a specific period of time
SLEEP N
where N is seconds 0 < N < = 65535.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

SLOW
Return the Commodore 128 to lMHz operation
SLOW

SOUND
Output sound effects and musical notes
SOUND v,f,d[,dir][,m][,s][,w][,p]
where:

v
f
d
dir
m
s
w

=
=
=
=
=
=
=

voice (1..3)
frequency value (0..65535)
duration (0..32767)
step direction (0(up), l(down) or 2(oscillate)) default = 0
minimum frequency (if sweep is used) (0..65535) default = 0
step value for sweep (0..32767) default = 0
waveform (0 = triangle, 1 = sawtooth, 2 = variable, 3 = noise)
default = 2
= pulse width (0..4095) default = 2048

p
EXAMPLES:

SOUND 1,40960,60

Play a SOUND at frequency 40960 in voice 1


for 1 second.

SOUND 2,20000,50,0,2000,100

Output a sound by sweeping through frequencies starting at 2000 and incrementing upward
in units of 100 up to 20,000. Each frequency is
played for 50 jiffies.

SOUND3,5000,90,2,3000,500,1

This example outputs a range of sounds starting at a minimum frequency of 3000, through
5000, in increments of 500. The direction of
the sweep is back and forth (oscillating). The
selected waveform is sawtooth and the voice
selected is 3.

SPRCOLOR
Set multi-color 1 and/or multi-color 2 colors for all sprites
SPRCOLOR [smcr-l][,smcr-2]
where:
smcr-1
smcr-2

Sets multi-color 1 for all sprites.


Sets multi-color 2 for all sprites.

65

66

COMMODORE 128

Either of these parameters may be any color from 1 through 16.


EXAMPLES:
SPRCOLOR 3,7

Sets sprite multi-color 1 to red and multi-color 2 to blue.

SPRCOLOR 1,2

Sets sprite multi-color 1 to black and multi-color 2 to white.

SPRDEF
Enter the SPRite DEFinition mode to create and 6dit sprite images.
SPRDEF
The SPRDEF command defines sprites interactively
Entering the SPRDEF command displays a sprite work area on the screen which
is 24 characters wide by 21 characters tall. Each character position in the grid corresponds to a sprite pixel in the sprite displayed to the right of the work area. Here
is a summary of the SPRite DEFinition mode operations and the keys that perform
them:

USER INPUT

DESCRIPTION

1-8
A
CRSR keys
RETURN KEY
RETURN key

Seleets a sprite number at the SPRITE NUMBER? prompt only.


Turns on and off automatic cursor movement.
Moves cursor in work/area.
Moves cursor to start of next line.
Exits sprite designer mode at the SPRITE NUMBER? prompt
only.
Moves cursor to top left corner of sprite work area.
Erases entire grid.
Selects color source (enables/disables pixels).
Selects sprite foreground color (1-8).
Selects sprite foreground color (9-16).
Cancels changes and returns to prompt.
Saves sprite and returns to SPRITE NUMBER? prompt.
Expands sprite in X (horizontal) direction.
Expands sprite in Y (vertical) direction.
Multi-color sprite mode.
Copies sprite data from one sprite to another.

HOME key
CLR key
1-4
CTRL key, 1-8
Commodore key, 1-8
STOP key
SHIFT RETURN
X
Y
M
C

SPRITE
Turn on and off, color, expand and set screen priorities for a sprite
SPRITE < n u m b e r > [,on/offj[,fgnd][,priority][,x-exp] [,y-exp][,mode]
The SPRITE statement controls most of the characteristics of a sprite.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

PARAMETER

DESCRIPTION

number
on/off
foreground
priority

Sprite number (1-8)


Turn sprite on (1) or off (0)
Sprite foreground color (1-16) (default = sprite number)
Priority is 0 if sprites appear in front of objects on the screen. Priority
is 1 if sprites appear in back of objects on the screen.
Horizontal EXPansion on (1) or off (0)
Vertical EXPansion on (1) or off (0)
Select standard sprite (0) or multi-color sprite (1)

x-exp
y-exp
mode

Unspecified parameters in subsequent sprite statements take on the characteristics of the


previous SPRITE statement. You may check the characteristics of a SPRITE with the
RSPRITE function.
EXAMPLES:
SPRITE 1, 1,3

Turn on sprite number 1 and color it red.

SPRITE 2,1,7,1, 1,1

Turn on sprite number 2, color it blue, make it pass


behind objects on the screen and expand it in the vertical
and horizontal directions.

SPRITE 6,1,1,0,0, 1,1

Turn on SPRITE number 6, color it black. The first 0


tells the computer to display the sprites in front of objects
on the screen. The second 0 and the 1 following tell the
C128 to expand the sprite vertically only. The last 1
specifies multi-color mode. Use the SPRCOLOR command to select the sprite's multi-colors.

SPRSAV
Copy sprite data from a text string variable into a sprite or vice versa, or copy data trom
one sprite to another.
SPRSAV < o r i g i n > , < d e s t i n a t i o n >
Either the origin or the destination can be a sprite number or a string variable but they
both cannot be string variables. They can both be sprite numbers. If you are storing a
string into a sprite, only the first 63 bytes of data are used. The rest are ignored since a
sprite can only hold 63 data bytes.
EXAMPLES:
SPRSAV l , A $

Transfers the image (data) from sprite 1 to the string named A$.

SPRSAV B$,2

Transfers the data from string variable B$ into sprite 2.

SPRSAV 2,3

Transfers the data from sprite 2 to sprite 3.

67

68

COMMODORE 128

SSHAPE / GSHAPE
Save/retrieve shapes to/from string variables
SSHAPE and GSHAPE are used to save and load rectangular areas of bit map
screens to/from BASIC string variables. The command to save an area of the bit map
screen into a string variable is:
SSHAPE string variable, X I , Y1 [,X2,Y2]
where:
string variable
X1,Y1
X2,Y2

String name to save data in


Corner coordinate (0,0 through 319,199) (scaled)
Corner coordinate opposite (X1,Y1) (default is the PC)

The command to retrieve (load) the data from a string variable and display it on
specified screen coordinates is:
GSHAPE string variable [X,Y][,mode]
where:
string
X,Y

Contains shape to be drawn


Top left coordinate (0,0 through 319,199) telling where to draw the shape
(scaledthe default is the pixel cursor)
Replacement mode:
0 = place shape as is (default)
1 = invert shape
2 = OR shape with area
3 = AND shape with area
4 = XOR shape with area

mode

The replacement mode allows you to change the data in the string variable so you can
invert it, perform a logical OR, exclusive OR (turn off bytes that are on) or AND
operation on the image.
EXAMPLES:
SSHAPE A$,10,10

Saves a rectangular area from the coordinates 10,10


to the location of the pixel cursor, into string variable A$.

SSHAPE B$,20,30,43,50

Saves a rectangular area from top left coordinate


(20,30) through bottom right coordinate (43,50) into
string variable B$.

SSHAPE D$, 4- 10, + 10

Saves a rectangular area 10 pixels to the right and


10 pixels down from the current position of the pixel
cursor.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

GSHAPE A$,120,20

Retrieves shape contained in string variable A$ and


displays it at top left coordinate (120,20).

GSHAPE B$,30,30,1

Retrieves shape contained in string variable B$ and


displays it at top left coordinate 30,30. The shape is
inverted due to the replacement mode being selected
by the 1.

GSHAPE C$, + 20, 4- 30

Retrieves shape from string variable C$ and displays


it 20 pixels to the right and 30 pixels down from the
current position of the pixel cursor.

NOTE: Beware using modes 1-4 with multi-color shapes. You may
obtain unpredictable results.

STASH
Move contents of host memory to expansion RAM
STASH #bytes, intsa, expsa, expb
Refer to FETCH command for description of parameters.

STOP
Halt program execution
STOP

SWAP
Swap contents of host RAM with contents of expansion RAM
SWAP #bytes, intsa, expsa, expb
Refer to FETCH command for description of parameters.

SYS
Call and execute a machine language subroutine at the specified address
SYS address [,a][,x][,y][,s]
This statement calls a subroutine at a given address in a memory configuration previously
set up according to the BANK command. Optionally, arguments a,x,y and s are loaded into
the accumulator, x, y and status registers, respectively, before the subroutine is called.
The address range is 0 to 65535. The 8502 microprocessor begins executing the
machine-language program starting at the specified memory location. Also see the
BANK command.

69

70

COMMODORE 128

EXAMPLES:
SYS 32768

Calls and executes the machine-language routine at location 32768


($8000).

SYS 6144,0

Calls and executes the machine-language routine at location 6144


($1800) and loads zero into the accumulator.

TEMPO
Define the speed of the song being played
TEMPO n
where n is a relative duration between (1 and 255)
The default value is 8, and note duration increases with n.
EXAMPLES:
TEMPO 16
TEMPO 1
TEMPO 250

Defines the Tempo at 16.


Defines the TEMPO at the slowest speed.
Defines the TEMPO at 250.

TRAP
Detect and correct program errors while a BASIC program is RUNning
TRAP [line number]
The RESUME statement can be used to resume program execution. TRAP with no line
number turns off error trapping. An error in a TRAP routine cannot be trapped. Also see
system variables ST, EL, DS and DS$.
EXAMPLES:
. 100 TRAP 1000

If an error occurs, GOTO line 1000.

. 1000 7ERR$(ER);EL

Print the error message, and the error number.

.1010 RESUME

Resume with program execution.

TROFF
Turn off error tracing mode
TROFF

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

TRON
Turn on error tracing
TRON
TRON is used in program debugging. This statement begins trace mode. When you
RUN the program, the line numbers of the program appear in brackets before any action
for that line occurs.

VERIFY
Verify program in memory against one saved to disk or tape
VERIFY "filename" [,device number][,relocate flag]
Issue the VERIFY command immediately after you SAVE a program.
EXAMPLES:
VERIFY

Checks the next program on the tape.

VERIFY ' ' H E L L O ' '

Searches for HELLO on tape, checks it against memory.

VERIFY " H E L L O " , 8 , l

Searches for HELLO on disk, then checks it against


memory.

VOL
Define output level of sound for SOUND and PLAY statements
VOL volume level
EXAMPLES:
VOL 0
VOL 15

Sets volume to its lowest level.


Sets volume for SOUND and PLAY statements to its highest output.

WAIT
Pause program execution until a data condition is satisfied
WAIT < l o c a t i o n > , < m a s k - I > [ , m a s k - 2 > ]
where:
location = 0-65535
masks
= 0-255
The WAIT statement causes program execution to be suspended until a given memory
address recognizes a specified bit pattern or value.
The first example below WAITs until a key is pressed on the tape unit to
continue with the program. The second example will WAIT until a sprite collides with
the screen background.

71

72

COMMODORE 128

EXAMPLES:
WAIT 1, 32, 32
WAIT 53273, 2
WAIT 36868, 144, 16

WIDTH
Set the width of drawn lines
WIDTH n
EXAMPLES:
WIDTH 1
WIDTH 2

Set single width for graphic commands


Set double width for drawn lines

WINDOW
Define a screen window
WINDOW top left col,top left row,bot right col,bot right row[,clear]
This command defines a logical window within the 40 or 80 column text screen. The
coordinates must be in the range 0-39/79 for 40- and 80-column values respectively and
0-24 for row values. The clear flag, if provided (1), causes a screen-clear to be
performed (but only within the limits of the newly described window).
EXAMPLES:
WINDOW 5,5,35,20

Defines a window with top left corner coordinate as


5,5 and bottom right corner coordinate as 35,20.

WINDOW 10,2,33,24,1

Defines a window with upper left corner coordinate


10,2 and lower right corner coordinate 33,24. Also
clears the portion of the screen within the window as
specified by the 1.

BASIC FUNCTIONS
The format of the function description is:
FUNCTION (argument)
where the argument can be a numeric value, variable or string.
Each function description is followed by an EXAMPLE. The first line appearing
below the word "EXAMPLE" is the function you type. The second line without bold is
the computer's response.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

ABS
Return absolute value of argument X
ABS(X)
EXAMPLE:
PRINT ABS (7*(-5))
35

ASC
Return CBM ASCII code for the first character in X$
ASC(X$)
This function returns the CBM ASCII code of the first character of X$.
EXAMPLE:
X$ = " C 1 2 8 " : P R I N T ASC (X$)
67

ATN
Return the arctangent of X in radians
ATN (X)
The value returned is in the range - Tr/2 through Tr/2.
EXAMPLE:
PRINT ATN (3)
1.24904577

BUMP
Return sprite collision information
B U M P (N)
To determine which sprites have collided since the last check, use the BUMP function.
BUMP(1) records which sprites have collided with each other, and BUMP(2) records
which sprites have collided with other objects on the screen. COLLISION need not be
active to use BUMP. The bit positions (0-7) in the BUMP value correspond to sprites 1
through 8 respectively. BUMP(n) is reset to zero after each call.

73

74

COMMODORE 128

Here's how the sprite numbers and BUMP values that are returned correspond:
BUMP Value:
Sprite Number:

128

64

32

16

EXAMPLES:
PRINT BUMP (1)

12 indicates that sprites 3 and 4 have collided.

PRINT BUMP (2)

32 indicates the sprite 6 has collided with an object on the screen.

CHR$
Return character for specified CBM ASCII code X
CHR$(X)
The argument (X) must be in the range 0-255. This is the opposite of ASC and returns the
string character whose CBM ASCU code is X. Refer to Appendix E for a table of CHR$ codes.
EXAMPLES:
PRINT CHR$ (65)
A
PRINT CHR$ (147)

Prints the A character.


Clears the text screen.

COS
Return cosine for angle of X in radians
COS(X)
EXAMPLE:
PRINT COS (TT/3)
.5

FNxx
Return value from user defined function xx
FNxx(X)
This function returns the value from the user defined function xx created in a DEF
FNxx statement
EXAMPLE:
10 DEF FNAA(X) = (X-32)*5/9
20 INPUT X
30 PRINT FNAA(X)
RUN
740 (? is input prompt)
4.44444445

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

NOTE: If GRAPHIC is used in a program that defines a function, issue


the GRAPHIC command before defining the function or the function
definition is destroyed.

FRE
Return number of available bytes in memory
FRE (X)
where X is the RAM bank number. X = 0 for BASIC program storage and X = 1 to
check for available BASIC variable storage.
EXAMPLES:
PRINT FRE (0)
58109

Returns the number of free bytes for BASIC programs.

PRINT FRE (1)


64256

Returns the number of free bytes for BASIC variable storage.

HEX$
Return hexadecimal string equivalent to decimal number X
HEX$(X)
EXAMPLE:
PRINT HEX$(53280)
D020

INSTR
Return starting position of string 2 within string 1
INSTR (string 1, string 2 [,starting position])
EXAMPLE:
PRINT INSTR ( " C O M M O D O R E 1 2 8 " , " 1 2 8 " )

11

INT
Return integer form (truncated) of a floating point value
INT(X)
This function returns the integer value of the expression. If the expression is positive,
the fractional part is left out. If the expression is negative, any fraction causes the next
lower integer to be returned.

75

76

COMMODORE 128

EXAMPLES:
PRINT INT(3.14)
3
PRINT INT(-3.14)
^

JOY
Return position of joystick and the status of the fire button
JOY(N)
when N equals:
1
2

JOY returns position of joystick 1.


JOY returns postion of joystick 2.

Any value of 128 or more means that the fire button is also pressed. To find the joystick
position if the fire button is pressed subtract 128 from the JOY value. The direction is
indicated as follows.
1

8
7

6
5
EXAMPLES:
PRINT JOY (2)
135

Joystick 2 fires to the left.

IF (JOY (1) > 127) THEN PRINT " F I R E "

Determines whether the fire button


is pressed.

DIR = J O Y ( l ) AND 15

Returns direction (only) ofjoystick 1.

LEFT$
Return the leftmost characters of string
LEFT$ (string,integer)
EXAMPLE:
PRINT L E F T $ ( " C O M M O D O R E ' ' , 5 )
COMMO

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

LEN
Return the length of a string
LEN (string)
The returned integer value is in the range 0-255.
EXAMPLE:
PRINT LEN ( ' ' C O M M O D O R E 128'')

12

LOG
Return natural log of X
LOG(X)
The argument X must be greater than 0.
EXAMPLE:
PRINT LOG (37/5)
2.00148

MID$
Return a substring from a larger string
MLD$ (string,starting position[,length])
This function extracts the number of characters specified by length (0-255), from string,
starting with the character specified by starting position (1-255).
EXAMPLE:
PRINT M I D $ ( " C O M M O D O R E 128",3,5)
MMODO

PEEK
Return contents of a specified memory location
PEEK(X)
The data will be returned from the bank selected by the most recent BANK command.
See the BANK command.
EXAMPLE:
10
20
30
40

BANK 15:VlC = D E C ( " D 0 0 0 " )


FOR I = 1 TO 47
PRINT PEEK(VIC + I)
NEXT

This example displays the contents of the registers of the VIC chip (some of which
are ever-changing).

77

78

COMMODORE 128

PEN
Return X and Y coordinates of the light pen
PEN(n)
where n
n
n
n
n

=
=
=
=
=

0 PEN returns the X coordinate of light pen position on any VIC screen,
1 PEN returns the Y coordinate of light pen position on any VIC screen,
2 PEN returns the character column position of the 80 column display,
3 PEN returns the character row position of the 80 column display,
4 PEN returns the (80-column) light pen trigger value.

The VIC PEN values are not sealed and are taken from the same coordinate plane as
sprites use. Unlike the 40 column (VIC) screen, the 80 column (8563) coordinates are
character row and column positions and not pixel coordinates like the VIC screen. Both
the 40 and 80 column screen coordinate values are approximate and vary, due to the
nature of light pens. The 80-column read values are not valid until PEN(4) is true.
Light pens are always plugged in to control port 1.
EXAMPLES:
10 PRINT PEN(0);PEN(1)

Displays the X and Y coordinates of the light


pen (for the 40 column screen).

10 DO UNTIL PEN(4):LOOP

Ensures that the read values are valid (for the


80 column screen).

20 X - PEN(2)
30 Y = PEN(3)
40 REM:REST OF PROGRAM
TT
Return the value of pi (3.14159265)
TT

EXAMPLE:
PRINT TT This returns the result 3.14159265.

POINTER
Return the address of a variable
POINTER (variable name)
This function returns a zero if the variable is not defined.
EXAMPLE:
A = POINTER (Z)

This example returns the address of variable Z.


NOTE: Address returned is in RAM BANK 1.

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

POS
Return the current cursor column position within the current screen window
POS(X)
The POS function indicates where the cursor is within the defined screen window. X is a
dummy argument, which must be specified, but the value is ignored. The values
returned range from 0-39 on the VIC screen and 0-79 on the 80-column screen.
EXAMPLE:
FOR I = 1 to 10 : 7SPC(I); POS(O): NEXT
This displays the current cursor position within the defined text window.

POT
Returns the value of the game-paddle potentiometer
POT (n)
when:
n
n
n
n

=
=
=
=

1,
2,
3,
4,

POT
POT
POT
POT

returns
returns
returns
returns

the
the
the
the

position
position
position
position

of
of
of
of

paddle
paddle
paddle
paddle

# 1 (control
# 2 (control
# 3 (control
# 4 (control

port
port
port
port

1)
1)
2)
2)

The values for POT range from 0 to 255. Any value of 256 or more means that the fire
button is also depressed.
EXAMPLE:
10 PRINT POT(l)
20 lF POT(l) > 256 THEN PRINT " F I R E "
This example displays the value of game paddle 1.

RCLR
Return color of color source
RCLR(N)
This function returns the color (1 through 16) assigned to the color source N (0< = N = <
6), where the following N values apply:

79

80

C O M M O D O R E 128

SOURCE

DESCRIPTION

0
1
2
3
4
5

40-column background
bit map foreground
multi-color 1
multi-color 2
40-column border
40- or 80-column character color
80-column background color

The counterpart to the RCLR function is the COLOR command.


EXAMPLE:
10 FOR I - 0 TO 6
20 PRINT " S O U R C E " ; I ; " l S COLOR CODE";RCLR(I)
30 NEXT
This example prints the color codes for all six color sources.

RDOT
Return current position or color source of pixel cursor
RDOT (N)
where:
N = 0 returns the X coordinate of the pixel cursor
N = 1 returns the Y coordinate of the pixel cursor
N = 2 returns the color source (0-3) of the pixel cursor
This function returns the location of the current position of the pixel cursor or the
current color source of the pixel cursor.
EXAMPLES:
PRINT RDOT(O)
PRINT RDOT( 1)
PRINT RDOT(2)

Returns X position of pixel cursor


Returns Y position of pixel cursor
Returns color source of pixel cursor

RGR
Return current graphic mode
RGR(X)
This function returns the current graphic mode. X is a dummy argument, which must be
specified. The counterpart of the RGR function is the GRAPHIC command. The value
returned by RGR(X) pertains to the following modes:

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

VALUE

0
1
2
3
4
5

GRAPHIC MODE

40 column (VIC) text


Standard bit map
Split screen bit map
Multi-color bit map
Split screen Multi-color bit map
80 column (8563) text

EXAMPLE:
PRINT RGR(0)
1

Displays the current graphic mode; in this case, standard bit


map mode.

PRINT RGR(0)

Both multi-color bit map and 80-column text modes are enabled.

RIGHT$
Return sub-string from rightmost end of string
RIGHT$(string, numeric)
EXAMPLE:
PRINT RIGHT$C'BASEBALL'' ,5)
EBALL

RND
Return a random number
RND (X)
If X = 0
If X > 0

RND returns a random number based on the hardware clock.


RND generates a reproducible random number based on the seed
value below.

If X < 0

produces a random number which is used as a base called a seed.

EXAMPLES:
PRINT RND(0)
.507824123
PRINT INT(RND(l)*100 4- 1)
89

Displays a random number between 0 and 1.


Displays a random number between 1 and 100.

81

82

COMMODORE 128

RSPCOLOR
Return sprite multicolor values
RSPCOLOR (X)
When:
X = 1
X = 2

RSPCOLOR returns the sprite multi-color 1.


RSPCOLOR returns the sprite multi-color 2.

The returned color value is a value between 1 and 16. The counterpart o f t h e RSPCOLOR
function is the SPRCOLOR statement. Also see the SPRCOLOR statement.
EXAMPLE:
10 SPRITE 1,1,2,0,1,1,1
20 SPRCOLOR 5,7
30 PRINT "SPRITE MULTI-COLOR 1 IS";RSPCOLOR(l)
40 PRINT "SPRITE MULTI-COLOR 2 IS";RSPCOLOR(2)
RUN
SPRITE MULTI-COLOR 1 IS 5
SPRITE MULTI-COLOR 2 IS 7
In this example line 10 turns on sprite 1, colors it white, expands it in both the X and Y
directions and displays it in multi-color mode. Line 20 selects sprite multi-colors 1 and 2
(5 and 7 respectively). Lines 30 and 40 print the RSPCOLOR values for multi-color 1 and 2.

RSPPOS
Return the speed and position values of a sprite
RSPPOS (sprite number,position|speed)
where sprite number identifies which sprite is being checked, and position and speed
specifies X and Y coordinates or the sprite's speed.
When position equals:
0 RSPPOS returns the current X position of the specified sprite.
1 RSPPOS returns the current Y position of the specified sprite.
When speed equals:
2 RSPPOS returns the speed (0-15) of the specified sprite.
EXAMPLE:
10 SPRITE 1,1,2
20 MOVSPR 1,45#13
30 PRINT RSPPOS (l,O);RSPPOS (l,l);RSPPOS (1,2)
This example returns the current X and Y sprite coordinates and the speed (13).

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

RSPRITE
Return sprite characteristics
RSPRITE (sprite number,characteristic)
RSPRITE returns sprite characteristics that were specified in the SPRITE command.
Sprite number specifies the sprite (1-8) you are checking and the characteristic specifies
the sprite's display qualities as follows:
RSPRITE RETURNS
CHARACTERISTIC

0
1
2
3
4
5

THESE VALUES:

Enabled(l) / disabled(0)
Sprite color (1-16)
Sprites are displayed in front of (0) or behind
(1) objects on the screen
Expand in X direction
Expand in Y direction
Multi-color

yes = 1, no = 0
yes = 1, no = 0
yes = 1, no = 0

EXAMPLE:
10 FOR I = 0 TO 5
20 PRINT RSPRITE (1,1)
30 NEXT

This example prints all 6 characteristics of sprite 1.

RWINDOW
Returns the size of the current window or the number of columns of the current
screen
RWINDOW (n)
When n equals:
0 RWINDOW returns the number of lines in the current window.
1 RWINDOW returns the number of rows in the current window.
2 RWINDOW returns either of the values 40 or 80, depending on the current
screen output format you are using.
The counterpart of the RWINDOW function is the WINDOW command.
EXAMPLE:
10 WINDOW 1,1,10,10
20 PRINT RWINDOW(0);RWINDOW(l);RWINDOW(2)
RUN
9 9 40
This example returns the lines (10) and columns (10) in the current window. This
example assumes you are displaying the window in 40 column format.

83

84

COMMODORE 128

SGN
Return sign of argument X
SGN(X)
EXAMPLE:
PRINT SGN(4.5);SGN(0);SGN(-2.3)
1
0- 1

SIN
Return sine of argument
SIN(X)
EXAMPLE:
PRINT SIN (ir/3)
.866025404

SPC
Skip spaces on printed output
SPC (X)
EXAMPLE:
PRINT ''COMMODORE'';SPC(3);" 128"
COMMODORE
128

SQR
Return square root of argument
SQR (X)
EXAMPLE:
PRINT SQR(25)
5

STR$
Return string representation of number
STR$ (X)

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

EXAMPLE:
PRINT STR$(123.45)
123.45
PRINT STR$(-89.03)
-89.03
PRINT STR$(lE20)
lE + 20

TAB
Moves cursor to tab position in present statement
TAB (X)
EXAMPLE:
10 PRINT''COMMODORE"TAB(25)'' 128''
COMMODORE
128

TAN
Return tangent of argument in radians
TAN(X)
This function returns the tangent of X, where X is an angle in radians
EXAMPLE:
PRINT TAN(.785398163)
1

USR
Call user-defined subprogram
USR(X)
When this function is used, the BASIC program jumps to a machine language program
whose starting point is contained in memory locations 4633($1219) and 4634($121A), (or
785($0311) and 786($0312) in C64 mode). The parameter X is passed to the machinelanguage program in the floating-point accumulator ($63-$68 in C128 mode). A value is
returned to the BASIC program through the calling variable. You must direct the value
into a variable in your program in order to receive the value back from the floating-point
accumulator. An ILLEGAL QUANTITY ERROR results if you don't specify this
variable. This allows the user to exchange a variable between machine code and
BASIC.

93

86

COMMODORE 128

EXAMPLE:
10
20
30
40

POKE 4633,0
POKE 4634,48
A = USR(X)
PRINT A

Place starting location ($3000 = 12288:$00 = 0:$30) = 48 of machine language


routine in location 4633 and 4634. Line 30 stores the returning value from the floatingpoint accumulator. The USER vector is assumed to be in BANK 15. Your machine
language routine MUST be in RAM bank 0 below address $4000.

VAL
Return the numeric value of a number string
VAL(X$)
EXAMPLE:
10 A$ = " 1 2 0 "
20 B$ = " 3 6 5 "
30 PRINT VAL (A$ + B$)
RUN
485

XOR
Return exclusive OR value
XOR (nl,n2)
This function returns the exclusive OR of the numeric argument values nl and n2.
X = XOR (nl,n2)
where n l , n2, are 2 unsigned values (0-65535)
EXAMPLE:
PRINT XOR(128,64)
192

RESERVED SYSTEM WORDS


(KEYWORDS)
This section lists the words used to make up the BASIC 7.0 language. These words
cannot be used within a program as other than a component of the BASIC language. The
only exception is that they may be used within quotes (in a PRINT statement, for example).

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

ABS
DELETE
HELP
AND
DIM
HEX$
APPEND
DIRECTORY IF
ASC
DLOAD
INPUT
ATN
DO
INPUT#
AUTO
DOPEN
INSTR
DRAW
BACKUP
INT
BANK
DS
JOY
BEGIN
DS$
KEY
BEND
DSAVE
LEFT$
DVERIFY
BLOAD
LEN
BOOT
EL
LET
BOX
ELSE
LIST
END
BSAVE
LOAD
BUMP
ENVELOPE
LOCATE
CATALOG ER
LOG
ERR$
CHAR
LOOP
CHR$
EXIT
MID$
CIRCLE
EXP
MONITOR
FAST
CLOSE
MOVSPR
CLR
FETCH
NEW
CMD
FILTER
NEXT
COLLECT FN
NOT
COLLISION FOR
(OFF)
COLOR
FRE
ON
CONCAT
GET
OPEN
CONT
GET#
OR
COPY
G064
PAINT
COS
GOSUB
PEEK
DATA
GOTO
PEN
DCLEAR
GO TO
PLAY
DCLOSE
GRAPHIC
POINTER
DEC
GSHAPE
POKE
DEF FN
HEADER
POS

POT
PRINT
PRINT#
PUDEF
(QUIT)
RCLR
RDOT
READ
RECORD
REM
RENAME
RENUMBER
RESTORE
RESUME
RETURN
RGR
RIGHT$
RND
RREG
RSPCOLOR
RSPPOS
RSPRITE
RUN
RWINDOW
SAVE
SCALE
SCNCLR
SCRATCH
SGN
SIN
SLEEP
SLOW
SOUND
SPC

SPRCOLOR
SPRDEF
SPRITE
SPRSAV
SQR
SSHAPE
ST
STASH
STEP
STOP
STR$
SWAP
SYS
TAB
TAN
TEMPO
THEN
TI
TI$
TO
TRAP
TROFF
TRON
UNTIL
USING
USR
VAL
VERIFY
VOL
WAIT
WHILE
WIDTH
WINDOW
XOR

NOTE: Keywords shown in parentheses are not implemented in C128


BASIC 7.0.

Reserved variable names are names reserved for the variables DS, DS$, ER, EL,
ST, TI and TI$, and the function ERR$. Keywords such as TO and IF or any other
names that contain keywords, such as RUN, NEW or LOAD cannot be used.
ST is a status variable for input and output (except normal screen/keyboard
operations). The value of ST depends on the results of the last I/O operation. In general,
if the value of ST is 0, then the operation was successful.

87

88

C O M M O D O R E 128

TI and TI$ are variables that relate to the real time clock built into the Commodore
128. The system clock is updated every l/60th of a second. It starts at 0 when the
Commodore 128 is turned on, and is reset only by changing the value of TI$. The
variable TI gives the current value of the clock in l/60th of a second. TI$ is a string that
reads the value of the real time clock as a 24-hour clock. The first two characters of TI$
contain the hour, the third and fourth characters are minutes and the fifth and sixth
characters are seconds. This variable can be set to any value (so long as all characters
are numbers) and will be updated automatically as a 24-hour clock.
EXAMPLE:
TI$ = "101530"

Sets the clock to 10:15 and 30 seconds (AM).

The value of the clock is lost when the Commodore 128 is turned off. It starts at
zero when the Commodore 128 is turned on, and is reset to zero when the value of the
clock exceeds 235959 (23 hours, 59 minutes and 59 seconds).
The variable DS reads the disk drive command channel and returns the current
status of the drive. To get this information in words, PRINT DS$. These status variables
are used after a disk operation, like DLOAD or DSAVE, to find out why the error light
on the disk drive is blinking.
ER, EL and the ERR$ function are variables used in error trapping routines. They
are usually only useful within a program. ER returns the last error number encountered
since the program was RUN. EL is the line where the error occurred. ERR$ is a
function that allows the program to print one of the BASIC error messages. PRINT
ERR$(ER) prints out the proper error message.

SYMBOL

USE(S)

Plus sign

Arithmetic addition; string concatenation; relative pixel


cursor/sprite movement; declare decimal number in machine language monitor
Arithmetic subtraction; negative number; unary minus;
relative pixel cursor/ sprite movement
Arithmetic multiplication
Arithmetic division
Arithmetic exponentiation
Separate keywords and variable names
Value assignment; relationship testing
Relationship testing
Relationship testing
Format output in variable lists; command/statement function parameters

Minus sign
H

|
=
<
>

Asterisk
Slash
Up arrow
Blank space
Equal sign
Less than
Greater than
Comma

BASIC BUILDING BLOCKS A N D BASIC 7.0 ENCYCLOPEDIA

SYMBOL

USE(S)

Period
Semicolon
Colon
Quotation mark
Question mark
Left parenthesis
Right parenthesis
Percent

#
$

Number
Dollar sign

&

And sign
Pi

Decimal point in floating-point constants


Format output in variable lists; delimiter
Separate multiple BASIC statements on a program line
Enclose string constants
Abbreviation for the keyword PRINT
Expression evaluation and functions
Expression evaluation and functions
Declare a variable name as integer; declare binary number in machine language monitor
Precede the logical file number in input/output statements
Declare a variable name as a string and declare hexadecimal number in machine language monitor
Declare octal number in machine language monitor
Declare the numeric constant 3.141592654

.
5

:
ii 95

(
)

7T

89

3
ONE STEP
BEYOND
SIMPLE B A S I C

91

92

COMMODORE 128

This chapter takes you one step beyond simple BASIC and presents a collection of useful
routines. You can incorporate these routines into your own programs as needed. In most
cases the routines will require only line number changes to be fitted into your programs.

CREATING A MENU
A menu is a list of choices you select to perform a specific operation within an
application program. A menu directs the computer to a particular part of a program.
Here is a general example of a menu program:
5 REM MENU SKELETON
10 SCNCLR 0
20 PRINT"1. FIRST ITEM"
30 PRINT"2. SECOND ITEM"
40 PRINT"3. THIRD ITEM"
50 PRINT"4. FOURTH ITEM"
100 PRINT:PRINT"SELECT AN ITEM FROM ABOVE"
110 GETKEY A$
120 A=VAL (A$): IF A>4 THEN 10
130 ON A GOSUB 100 0,2000,3000,4000
140 GOTO 10:REM RETURN TO MENU
99 9 STOP
1000 REM START FIRST ROUTINE FOR ITEM ONE HERE
199 9 RETURN
2000 REM START SECOND ROUTINE HERE
2999 RETURN
3000 REM START THIRD ROUTINE HERE
3999 RETURN
40 0 0 REM START FOURTH ROUTINE HERE
4999 RETURN

Program 3 - 1 . Menu Skeleton

The SCNCLR 0 command in line 10 clears the 40-column screen. (Use SCNCLR
5 if you are using the 80-column screen. The easiest selection is by a number. You may
use as many selections as can fit on the screen. Line 100 displays a message to the user.
The GETKEY command in line 110 forces the computer to wait for a key to be pressed.
Since a key represents a character symbol, A$ is a string variable. So that it can be
interpreted as a numeric value in an ON GOTO statement, the string variable is
converted to a number with the VAL function in line 120. The IF . . . THEN statement
in line 120 screens user errors by preventing the user from selecting a number that is not
in the range of numbers used for choices (4). Line 130 directs control to the appropriate
section (i.e., line number) in your program. Since four selections are offered in this
example, you must include at least four line numbers. Line 1999 returns to the menu at
the end of each subroutine that you add at lines 1000, 2000, 3000 and 4000 in the menu
skeleton.

ONE STEP BEYOND SIMPLE BASIC

BUFFER ROUTINE
The C128 keyboard buffer can hold and dispense up to ten characters from the
keyboard. This is useful in a word processing program where it is possible at certain
moments to type faster than the software can actually process. The characters that
haven't been displayed yet are temporarily stored in the keyboard buffer. The computer
can hold the next instruction in the buffer for use when the program is ready. This buffer
allows a maximum of ten characters in queue. To see the buffer in action, enter the
command SLEEP 5 and immediately press ten different letter keys. After five seconds,
all ten characters are displayed on the screen.
Here is a buffer routine that allows you to put items in the keyboard buffer
from within a program so they are dispensed automatically as the computer is able to act
upon them.
In line 10, memory location 208 (198 in C64 mode) is filled with a number
between 0 and 10the number of keyboard characters in the keyboard buffer. In line
20, memory locations 842 through 851 (631-640 in C64 mode) are filled with any ten
characters you want placed there. In this example, seven characters are in the buffer,
each a carriage RETURN character. CHR$(13) is the character string code for the
carriage return character.
Line 40 places the text "7CHR$(156)" on the screen, but does not execute the
instruction. Line 50 displays the word " L I S T " on the screen. Neither command is
executed until the program ends. In the C128, the keyboard buffer automatically empties
when a program ends. In this case, the characters in the buffer (carriage return) are
emptied and act as though you are pressing the RETURN key manually. When this occurs
on a line where the commands from lines 40 and 50 are displayed, they are executed
as though you typed them in direct mode and pressed the RETURN key yourself. When
this program ends, the character color is changed to purple and the program is LISTED
to the screen. This technique is handy in restarting programs (with RUN or GOTO).
The next section gives a practical example of using the buffer routine.
10 POKE 208 ,7:REM SPECIFY # OF CHARS IN BUFFER
20 FOR 1=842 TO 849:POKE I,13:NEXT:REM PLACE CHARS IN BUFFER
3 0 SLEEP 2 :REM DELAY
40 SCNCLR:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT"? CHR$(156)"
50 PRINT:PRINT:PRINT:PRINT"LIST":REM PLACE LIST ON SCREEN
60 PRINT CHR$(19):PRINT:PRINT:REM GO HOME AND CURSOR DOWN TWICE
7 0 REM WHEN PROGRAM ENDS, BUFFER EMPTIES AND EXECUTES 7 RETURNS.
80 REM THIS CHANGES CHAR COLOR TO PURPLE AND LISTS THE PROGRAM AUTOMATICALLY
9 0 REM AS IF YOU PRESSED THE RETURN KEY MANUALLY

Program 3-2. Buffer Return

LOADING ROUTINE
The buffer can be used in automatic loader routines. Many programs often involve the
loading of several machine code routines as well as a BASIC program. The results of
the following loader are similar to many found on commercial software packages.

93

94

COMMODORE 128

2 COLOR 4,1:COLOR 0,1:COLOR 5,1


5 A$="PICTURE"
10 SCNCLR:PRiNT:PRINT:PRINT:PRINT"LOAD"CHR$(34)A$CHR$(34)",8,1"
15 PRINT:PRINT:PRINT"NEW"
25 B$="FILE3.BIN"
30 PRINT:PRINT:PRINT"LOAD"CHR$(34)B$CHR$(34)",8,1"
4 5 PRINT:PRINT:PRINT:PRINT:PRINT:PRINT"SYSl2*2 56"
90 PRINT CHR$(5):PRINT"
GREETINGS FROM COMMODORE"
100 PRINT"
PLEASE STAND BY - LOADING":PRINT CHR$(144)
200 PRINT CHR$(19)
3 00 POKE20 8,7:F0RI = 8 4 2T08 51:POKEI,13:NEXT

Program 3-3. Loading Routine

Line 2 colors the border, screen and characters black. Line 5 assigns A$ the
filename " P I C T U R E " , which in this example assumes that it is an 8K binary file of a
bit-mapped screen. Line 10 places the LOAD instruction for the picture file on the
screen, but does not execute it. A carriage return from the keyboard buffer executes the
load instruction once the program ends and the keyboard buffer empties. Line 15 prints
the word " N E W " on the screen. Again, this operation is not carried out until a carriage
return is executed on the same line once the keyboard buffer empties. After loading a
machine language program, a NEW is performed to set pointers to their original
positions and clear the variable storage area. Line 30 displays the second load instruction for the machine language program " F I L E 3 . B I N " . This hypothetical program
enables the bit mapped PICTURE, and anything else you want to supply in the program.
Line 45 initiates (SYS12*256), the "FILE3.BIN" program starting at 3072 ($0C00)
once the keyboard buffer empties. This is only a template sample for you to follow.
" P I C T U R E " and "FILE3.BIN" are programs you supply and are only used to illustrate
one technique of automatic loading. Since the previous character color was black, all the
loading instructions are displayed in black on a black background, so they can't be seen.
The CHR$(5) in line 90 changes the character color to white, so the only visible
messages are the ones in white in lines 90 and 100, while the disk drive is loading
" P I C T U R E " and "FILE3.BIN". Line 300 is the buffer routine.
If you were to do each step manually it would require seven " R E T U R N S " . This
program places seven carriage return characters in the keyboard buffer, and they are
dispensed automatically when the program ends. As each RETURN is accepted, the
corresponding screen instruction is enacted automatically as if you had pressed the
RETURN key manually.

PROGRAMMING THE
CI28 FUNCTION KEYS
As each of the function keys (F1 through F8) is pressed, the computer displays a BASIC
command on the screen and in some cases acts immediately. These are known as the
default values of the function keys. Enter a KEY command to get a list of function key
values at any time.

ONE STEP BEYOND SIMPLE BASIC

CHANGING FUNCTION KEYS


You can change the value assigned to any function key by entering the KEY command
followed by the number (1 through 8) of the key you want changed, a comma, and the
new key instruction in a string format. For example:
KEY1, ' ' D L O A D " + CHR$(34) + "PROGRAM N A M E "
+ CHR$(34) + CHR$( 13) + ' 'LIST'' + CHR$( 13)
This tells the computer to automatically load the BASIC program called "program
name" and list it immediately (whenever F1 is pressed). The character string code value
for the quote character is 34. It is necessary for LOAD and SAVE operations. The
character string code value for RETURN is 13 and provides immediate execution.
Otherwise, the instruction is only displayed on the screen and requires you to supply the
additional response and press the RETURN key.
The following example uses the ASCII value for the ESCape key to assign the F3
key to cause a downward scroll:
KEY 3,CHR$(27) + " W "
N O T E : All eight KEY definitions in total must not exceed 246 characters.

USING C64 FUNCTION KEY VALUES


IN CI28 MODE
Programs previously written for the C64 which incorporate the function keys may still
be used in C128 mode by first assigning the C64 ASCII values to them with this
instruction:
10J = 132:FORA= l T 0 2 : F 0 R K - A T 0 8 S T E P 2 : J - J + l : K E Y K , C H R $ ( J ) : N E X T :
NEXT

HOW TO CRUNCH B A S I C PROGRAMS


Several techniques known collectively as memory crunching allow you to get the most
out of your computer's memory. These techniques include eliminating spaces, using
multiple instructions, having syntax relief, removing remark statements, using variables,
and in general using BASIC intelligently.

ELIMINATING SPACES
In most BASIC commands, spacing is unnecessary, except inside quotes when you want
the spaces to appear on the screen. Although spaces improve readability, the extra space
consumes additional memory. Here is an instructional line presented both ways:
10INPUT"FIRST NAME";N$:FOR T = A TO M:PRINT " O K " :
10INPUT"FIRST NAME'';N$:FORT - ATOM:PRINT"OK'':

95

96

COMMODORE 128

USING MULTIPLE INSTRUCTIONS


Colons allow you to place several instructions within a single program line. Each
program line consumes additional memory. Be careful, however, crunching lF statements. Any instruction after the IF statement with the same line number can be bypassed
along with the IF . . . THEN condition. The following line is the equivalent of five
lines:
(A)
10 PRINTX:INPUTY:PRINTY. SCNCLR0: ?J
10
20
30
40
50

(B)
PRINTX
INPUTY
PRINTY
SCNCLRO
PRINTJ

Example A requires less space in memory and on disk. Example B requires 16


additional bytes; 2 bytes for each additional line number and 2 bytes for the link to the
next line number.

SYNTAX RELIEF
Some BASIC syntax is very flexible and this flexibility can be used to your advantage.
The LET statement, for example, can be written without LET. LET Y = 2 is the same as
Y = 2. Although it is good practice to initialize all variables to zero, it is not necessary
since the computer automatically sets all variables to zero, including subscripted variables. DIMension all arrays (subscripted variables) to have twelve or more elements. The
C128 automatically dimensions each variable to have eleven subscripted elements if no
dimension is specified following DIM and the variable names. Often semicolons are not
required in PRINT statements. Both of these perform the same results:
10 PRINT''A";Z$;"WORD'';CHR$(65);"NOW $ "
20 P R I N T ' ' A ' ' Z $ " W O R D " C H R $ ( 6 5 ) " N O W $ "

REMOVING REM STATEMENTS


Although REM statements are useful to the programmer, removing them makes a
considerable amount of memory available again. It might be a good idea to create a
separate listing with REM statements.

USING VARIABLES
Replace repeated numbers with a variable. This is especially important with large
numbers such as memory addresses. POKEing several numbers in sequence conserves
memory if a variable is used, such as POKE 54273 + V, etc. Of course, single-letter
variable names require the least memory. Reuse old variables such as those used in FOR
. . . NEXT loops. Whenever possible, make use of integer variables since they consume
far less memory than floating-point variables.

ONE STEP BEYOND SIMPLE BASIC

USING B A S I C

INTELLIGENTLY

If information is used repeatedly, store the data in integer arrays, if possible. Use DATA
statements where feasible. Where a similar line is used repeatedly, create a single line
with variables and access it with GOSUBs. Use TAB and SPC functions in place of
extensive cursor controls.

MASKING BITS
Any of the bits within a byte can be controlled individually, using the Boolean operators
AND and OR. Calculations with AND and OR are based on a truth table (Table 3-1)
showing the results given all possible true and false combinations of the arguments X and Y.

X AND Y

X OR Y

Table 3 - 1 . A N D and O R T r u t h Table

With " 0 " representing False and " 1 " Truth, Table 3-1 shows how the operators
AND and OR work. The result of an AND operation between two bits is only true if
both bits are true (1). Otherwise the combination is false. Any bit combination with a
zero yields a zero in an AND operation. The result of an AND operation is only true
(equal to 1) if both bits are true (equal to 1).
The result of an OR operation is only false if each bit is false. Otherwise the result
is true. Any bit combination with a one yields a one in an OR operation. ONLY two
zeros result in a zero.
Observe the following example with the numbers 5 and 6 in binary form. When
you type the command PRINT 5 AND 6, the result is 4. Here's why:

ANDed

5=
6=

0000
0000

0101
0110

4=

0000

0100

Instead of adding, ANDing performs a bit-by-bit comparison in accordance with


the rules of the AND truth table. Compare column-for-column from the right: 1 AND
0 - 0 , 0 AND 1 - 0 , 1 AND 1 = 1, 0 AND 0 - 0 . The result " 0 1 0 0 " converted to
decimal is the number 4.
What is the effect of ORing 5 and 6? Again comparing bit-by-bit, using the rules
from the OR truth table:

97

98

COMMODORE 128

ORing

5=
6=

0000
0000

0101
0110

7=

0000

0111

The result 0111 is decimal 7. Notice from the right that 1 OR 0 = 1, 0 OR 1 - 1, 1 OR


1 = 1 and 0 OR 0 = 0.
Understanding how these OR and AND combinations work gives you the power to
control individual bits within your computer's memory. Many of the 8-bit bytes utilize
each bit for separate control parameters.

USING OR A N D A N D T O MODIFY
THE BIT VALUES IN A BYTE
A byte is a group of eight binary digits labeled, from right to left, 0 to 7. Each binary
digit position represents a decimal value equal to two raised to the power of the position
number. For example, the decimal value of position 6 is 2**6 or 64. From left to right
the positions are:
7

and the corresponding values in decimal are:


128

64

32

16

To turn on a bit, place a " 1 " in its position. To turn it off, enter a " 0 " . Hence the
binary 10010000 has bits 4 and 7 on. Their values are 128 and 16. So if a particular byte
is POKED with 144 (128+ 16), these two bits are turned on. To turn bits on, store
(POKE) a new value to that bytea value equal to the sum of all the decimal
equivalents of all the bits that are enabled (on). Of course, you do not always know
which bits are already on. You may only want to turn on specific bits without
affecting the others. That's the purpose of the logical operations AND and OR.
First, obtain the decimal value of the byte by PEEKing. Then add the decimal
value of the bit you wish to turn on. The following command turns on bit 2 of memory
address " V " :
POKEV, PEEK(V) + 4
This assumes bit 2 (third bit from the right) had a value of 0. Had it already been
" o n , " it would have no effect. To prevent such confusion, the C128 uses the power of
Boolean Logic.
Ideally you want to read (PEEK) each bit. The proper approach is to OR the byte
with an operand byte which will yield the desired binary value. Suppose we want to
turn on bit 5; the operand byte becomes 00100000. By ORing this with any byte it will
affect only bit 5, because any combination involving 1 in an OR operation results in 1.
Thus no bit already ON can be inadvertently turned off.
POKEV,PEEK(V) OR 32
Just as OR turns a switch on, AND can turn a switch offwith a slight difference.
AND results in a " 1 " only if both bits compared are " 1 . " The trick is to compare the

ONE STEP BEYOND SIMPLE BASIC

byte in question with an operand byte of all ON bits except the bit you want turned off.
Bits to remain on will not be affected. To turn off bit 5, AND the byte in question with
the mirror image of 00100000 or the operand byte 11011111. In decimal this value is
always 255 minus the value of the bit(s) you want to turn off. Thus:
POKEV,PEEK(V) AND (255-32)
turns off bit 5.
Use OR to turn bits ON
Use AND to turn bits OFF
EXAMPLES:
POKEW,PEEK(W) OR 129

Turns ON bits 0 and 7 of memory address W.

POKES,PEEK(S) AND 126

Turns OFF bits 0 and 7 of memory register S


(Remember 255-129 -

POKEC,PEEK(C)AND254
POKEC,PEEK(V)OR63

126)

Turns OFF bit 0


Turns ON all bits except 6 and 7

DEBUGGING PROGRAMS
No program when first written is free of " b u g s " or errors. The process of finding errors
and removing them, debugging, combines editing with problem solving.

SYNTAX ERRORS
Syntax errors result from misspelling or misusing the guidelines and formats of BASIC
commands. An error message is displayed on the screen defining the line where the
error occurs. Typing HELP < R E T U R N > or pressing the HELP key also highlights the
line with the error. Common syntax errors include misspelled BASIC terms, misplaced
punctuation, unpaired parentheses, reserved variable names such as TI$, use of line
numbers that do not exist, etc.

LOGIC ERRORS
Sometimes errors exist in the program logic, with the result that the program doesn't do
exactly what you think it is supposed to do. Some logic errors are caused by the order of
instructions. One common fault occurs when you forget that anything on a line after an
IF statement is affected by the IF condition.
Some errors in logic require a trial-and-error investigation. This is best initiated by
asking the computer for help in BASIC.

USING A DELAY
Where the computer responds rapidly, it often helps to see a response by inserting a
SLEEP command for a temporary time delay. This gives you a chance to see exactly
what is happening in the program.

99

100

COMMODORE 128

USING PRINT A N D STOP


Insert STOP statements within your program prior to the suspect instruction line. Good
locations are at the end of specific tasks. Run the program. After the STOP statement
puts you into direct mode, use the PRINT command to identify clues to the problem by
determining the values of the various variables, especially those within loops. Check
these with what you expect. Continue the program with CONT to the next STOP
statement until you modify your program.

TRAPPING A N ERROR
Debugging is the art of detecting the source of problem. The following program is
perfectly valid; however, it produces an error when B equals zero.
10 INPUT A,B
20 PRINT A/B
30 GOTO 10
Although in this case the computer defines the error as a DIVISION BY ZERO
error, it is not always obvious how the variable B became a zero. It could have been
derived from a complex formula embedded in your program, or directly inputting the
value zero into a variable.
The BASIC TRAP command has a technique of trapping such an error in a
program without crashing. Since you can't always foresee all the possible values of the
variable B, you can screen the probable error of division of zero by including a TRAP at
the beginning of the program.
5
10
20
30
50
60
70

TRAP 50
INPUT A,B
PRINTA/B
GOTOlO
PRINT' 'DIVISION BY ZERO IS NOT POSSIBLE"
PRINT"ENTER ANOTHER NUMBER FOR B BESIDES Z E R O "
RESUME

RESUME is required after the TRAP response in order to reactivate the TRAP. If
you include the option to enter a replacement for B, RESUME without a line number
returns to the cause of the errorline 20and executes it as follows:
65

INPUT B

The use of RESUME NEXT proceeds with the next line after the TRAP command,
i.e., line 10.
TRAP tells the computer to go to a specific line number whenever an error occurs.
Do NOT use TRAP until you have removed all syntax errors first. TRAP can only catch
the error condition it is looking for. An error in the syntax or the logic of your TRAP
routine may cause an error, or may not catch the error that you are looking for. In other
words, TRAP routines are sensitive to errors, too.

ONE STEP BEYOND SIMPLE BASIC

ERROR FUNCTIONS
Several reserved variables inherent in the system store information about program
errors. ER stores the error number. EL stores the relevant program line number.
ERR$(N) returns the string representing ER or EL. In the example of division by zero,
ERR$(ER) returns "DIVISION BY Z E R O " and ERR$(EL) returns " B R E A K " . Add
this to the program in the previous section. See Appendix A for a complete listing of
errors.

DOS

ERRORS

Information on disk errors is determined from the variables DS and DS$ where DS is the
error number (See Appendix B) and DS$ provides the error number, error message, and
track and sector of the error. DS$ reads the disk error channel and is used during a disk
operation to determine why the disk drive error light is blinking.
Trying to read a directory without a disk in place results in the following error
when the PRINT DS$ command is issued:
74, DRIVE NOT READY, 00, 00
Appendix B highlights specific causes of errors. To convert a function key to read
the disk-drive error channel automatically, use:
KEY 1, "PRINT DS$ + CHR$(13)

TRACING A N ERROR
Some programs have many complex loops that are tedious to follow. A methodical
step-by-step trace is useful. The BASIC TRON and TROFF commands can be used
within a program as a debugging tool to trace specific routines.
Some errors can only be found by acting like the computer and methodically
following each instruction step-by-step, and then doing all the calculations until you
discover something wrong. Fortunately the Commodore 128 can trace errors for you.
Enter the direct command TRON prior to running a program. The program displays each
line number as they occur in brackets, followed by each result. (To slow down the
display, hold the Commodore (Qi ) key down.)
Try it with this double loop:
10
20
30
40
50

FOR A = 1T05
FOR B - 2T06
C - B*A:K - K + C:PRINTK
NEXTB:NEXTA
PRINTK

The results will start off like this:


[10] [20] [30] [30] [30]2
[40] [30] [30] [30]5
meaning the first printed result is the number 2 after operations in lines 10, 20, 30 are
performed. Then lines 40 and 30 result in 5, etc. Notice three activities were performed
in line 30. The Trace function is turned off with the direct command TROFF.

101

102

COMMODORE 128

WINDOWING
The standard screen display size is 40- or 80-columns by 25 lines. It is often convenient
to have a portion of the screen available for other work. The process of producing and
isolating small segments of your screen is called "windowing."

DEFINING A WINDOW
There are two ways to create a windoweither directly or within a program using the
WINDOW command. Using the ESCape key followed by a T or B is all that is
necessary to describe and set a window.
Here's how to define a window in direct mode:
1.
2.

Move the cursor to the upper-left corner position of the proposed window.
Press the (ESC) escape key, then press the letter T key.
Move the cursor to the bottom right corner and press the escape key (ESC)
then press the letter B key.

Now that your window is in effect, all commands and listings remain in the
window until you exit by pressing the HOME key twice. This is useful if you have a
listing on the main screen and wish to keep it while you display something else in a
window. See Chapter 13, the Commodore 128 Operating System, under the screen
editor for special ESCape controls within a window.
Although it is possible to define several windows simultaneously on the screen, only
one window can be used at a time. The other windows remain on the display, but they are
inactive. To re-enter a window you have exited, define the top and bottom corners of the
window with the ESC T and ESC B commands, respectively, as you did originally.
The second way to define a window is with the BASIC window command. The
command:
WINDOW 20,12,39,24,1
establishes a window with the top-left corner at column 20, row 12, and the bottomright corner at column 39, row 24. The 1 signifies the area to be cleared. Once this
command is specified, all activities are restricted to this window.
Use the window command within a program whenever you want to perform an
activity in an isolated area on the screen.

O N E STEP B E Y O N D SIMPLE BASIC

ADVANCED B A S I C
PROGRAMMING TECHNIQUES
FOR COMMODORE MODEMS
The following information tells you how to:
1.
2.
3.
4.

Generate Touch Tone frequencies


Detect telephone ringing
Program the telephone to be on or off the hook
Detect carrier

The programming procedures operate in C128 or C64 modes with the Modemy300.
In C128 mode, select a bank configuration which contains BASIC, I/O, and the Kernal.

GENERATING T O U C H TONE
(DTMF) FREQUENCIES
Each button on the face of a Touch Tone telephone generates a different pair of tones
(frequencies). You can simulate these tones with your Commodore 128 computer. Each
button has a row and column value in which you must store the appropriate memory
location in order to output the correct frequency. Here are the row and column
frequency values that apply to each button on the face of your Touch Tone telephone:

TOUCH TONE FREQUENCY

Row
Row
Row
Row

1 (697
2 (770
3 (852
4 (941

Hz)
Hz)
Hz)
Hz)

TABLE

COLUMN 1 (1029 HZ)

COLUMN 2 (1336 HZ)

COLUMN 3 (1477 HZ)

1
4
7
*

2
5
8
0

3
6
9
#

To generate these tones in BASIC with your Commodore 128, follow this procedure:
1.

Initialize the sound (SID) chip with the following BASIC statements:
SID POKE
POKE
POKE

2.

54272
SID + 24,15:POKE SID + 4,16
SID + 11,16:POKE SID + 5,0:POKESID + 12,0
SID + 6,15*16:POKESID + 13,15*16:POKESID + 23,0

Next, select one row and one column value for each digit in the telephone
number. The POKE statement for each row and column are as follows:

103

104

COMMODORE 128

Column 1: POKE SID, 117:POKE SID + 1,77


Column 2: POKE SID,152:POKE SID + 1,85
Column 3: POKE SID,161, POKE SID + 1,94
Row 1: POKE SID 4- 7,168:POKE SID + 8,44
Row 2: POKE SID + 7,85,:POKE SID + 8,49
Row 3: POKE SID + 7,150:POKE SID + 8,54
Row 4: POKE SID + 7,74 :POKE SID + 8,60
For example, to generate a tone for the number 1, POKE the values for row
1, column 1 as follows
POKE SlD + 7,168:POKE SID + 8,44:REM ROW 1
POKE SID,117:POKE SID + l,77:REM COLUMN 1
3.

Turn on the tones and add a time delay with these statements:
POKE SID 4- 4,17:POKE SID + ll,17:REM ENABLE TONES
FOR I = 1 TO 50:NEXT:REM TIME DELAY

4.

Turn off the tones and add a time delay with the following statements:
POKE SID 4- 4,16:POKE SID + ll,16:REM DISABLE TONES
FOR I = 1 TO 50:NEXT:REM TIME DELAY

5.
6.

Now repeat steps 2 through 4 for each digit in the telephone number you are
dialing.
Finally, disable the sound chip with this statement:
POKE SID + 24,0

DETECTING TELEPHONE RINGING


To detect whether your telephone is ringing using a Commodore 128, use the following
statement:
IF (PEEK(56577) AND 8) - 0 THEN PRINT " R I N G I N G "
If bit 3 of location 56577 contains a value other than 0, the phone is not ringing.

PROGRAMMING THE TELEPHONE


T O BE O N OR OFF THE HOOK
To program the phone to be off the hook using a Commodore 128, enter the following
statements in a program:
OH - 56577:HI - 32:LO - 255 - 32
POKE (OH 4 2),(PEEK(OH + 2) OR HI)
POKE OH,(PEEK(OH) AND LO)
To hang up the phone with a Commodore 128, enter this statement in a program:
POKE OH,(PEEK(OH) OR HI)

ONE STEP BEYOND SIMPLE BASIC

Here is the procedure to dial and originate a communication link:


1.
2.
3.
4.
5.
6.

Set the modem's answer/originate switch to the " 0 " for originate.
Program the telephone to be OFF the hook.
Wait 2 seconds (FOR I = 1 to 500:NEXT:REM 2-SECOND DELAY)
Dial each digit and follow it with a delay (FOR I - 1 TO 50:NEXT)
When a carrier (high pitched tone) is detected, the Modem/300 automatically
goes on-line with the computer you are connecting with.
Program the phone to hang up when you are finished.

Here is the procedure to answer a call:


1.
2.
3.
4.
5.

Set the modem's answer/originate switch to " A " for answer.


To manually answer, program the telephone to be OFF the hook.
To automatically answer, detect if the phone is ringing then program the
phone to be OFF the hook.
The Modem/300 automatically answers the call.
Program the phone to hang up when you are finished.

DETECTING CARRIER
Your Commodore Modem/1200 and Modem/300 are shipped from the factory with the
ability to detect a carrier on the Commodore 128.
That ability is useful in an unattended auto-answer mode. By monitoring the
carrier detect line, the computer can be programmed to hang up after loss of carrier.
Since a caller may forget to hang up, your program should monitor the transmit and
receive data lines. If there is no activity for five minutes or so, the modem itself should
hang up.
To detect carrier on the Commodore 128, the following statement can be used in a
BASIC program:
OH = 56577:
IF ((PEEK (OH) AND 16) = 0) THEN PRINT "CARRIER DETECTED"
If bit 4 of location 56577 contains a value other than 0, then no carrier is detected.

ROTARY (PULSE) DIALING


In order to dial a number with a modem, the software in the computer must generate
pulses at a prescribed rate. In the United States and Canada, the rate is between 8 and 10
pulses per second with a 58% to 64% break duty cycle. Most people, however, use 10
pulses per second with a 60% break duty cycle.
So to make a call, your software must first take the phone " o f f - h o o k " (the
equivalent of you picking up the receiver). Then to dial the first digit, a 3 for instance,

105

116

COMMODORE 128

the software must put the phone on-hook for 60 milliseconds and off-hook for 40
milliseconds. Repeat this process three times to dial a 3.
The same method is used to dial other digits, except 0, which is pulsed ten times.
Pause at least 600 milliseconds between each digit.

USING E S C APE CODES


To perform any of the escape capabilities within a program, use a line such as:
10150 PRINT CHR$(27) + " U "
to create an underline cursor (in 80-column only). For example, to clear from the cursor
to the end of a window:
10160 PRINT CHR$(27) + " @ "
(See the Screen Editor section of Chapter 13 for all the escape and control codes
available on the Commodore 128.)

RELOCATING BASIC
To relocate the beginning or ending of BASIC (in C128 mode) for additional memory or
to protect machine-language programs from being overwritten by BASIC text, it is
necessary to redefine the starting and ending pointers in required memory addresses.
The Start of BASIC pointer is located at address 45($2D) and 46($2E). The Top
of BASIC pointer is at addresses 4626($1212) and 4627($1213). The following instruction displays the default locations of the beginning and end of BASIC text, respectively
(when a VIC bit-mapped screen is not allocated):
PRINT PEEK(45),PEEK(46),PEEK(4626),PEEK(4627)
1

28

255

Since the second number in each case is the high byte value, the default start of
basic is 28*256 plus 1 or 7169 while the top is 255*256 or 65280.
The following command reduces the size of BASIC text (program) area by 4K by
lowering the top of BASIC to address 61184 (239*256):
POKE4626,239:POKE4627,0:NEW
To move the beginning of BASIC up in memory by lK, from 7168 to 8192, use
this command line:
POKE 46,32:POKE45,l:NEW
This is the case only when a bit-mapped graphics screen is not allocated. Remember, the beginning of BASIC starts at 16384($4000) when a bit-mapped screen is
allocated, and other parts of memory are shifted around.

ONE STEP BEYOND SIMPLE BASIC

MERGING PROGRAM A N D FILES


Files can be merged (combined) by opening an existing file and locating the pointer to
the end of the file so subsequent data can be written to the disk file. C128 BASIC has
included the APPEND command to accomplish this:
APPEND#5, "FILE N A M E "
opens channel 5 to a previously stored file named "FILE N A M E . " Subsequent write
(PRINT#5) statements will add further information to the file. APPEND is primarily
used for data files.
The command CONCAT allows the concatenation (combine in sequence) of two
files or programs while maintaining the name of the first.
CONCAT"PART2B" TO " P A R T 2 "
creates a new file called Part 2, consisting of the old Part 2, plus the new Part 2b in
sequence. Concatenated BASIC program files must be renumbered before they can
work. Other corrections may also be necessary.
The BASIC routines described in this chapter can greatly enchance the capabilities
of your programs. So far, BASIC has been discussed in detail. The machine language
programming introduced in Chapter 5 can extend program capabilities even further.
And, as shown in Chapter 7, for still greater flexibility and power, you can combine
BASIC and machine language in your programs.

107

4
COMMODORE 128
GRAPHICS
PROGRAMMING
HOW TO USE
THE GRAPHICS SYSTEM

109

114

COMMODORE 128

COMMODORE 128 VIDEO FEATURES


In C128 Mode, Commodore BASIC 7.0 offers fourteen high-level graphics commands
that make difficult programming jobs easy. You can now draw circles, boxes, lines,
points and other geometric shapes, with ten high level commands such as DRAW, BOX
and CIRCLE, and with four sprite commands. (The sprite commands are described in
Chapter 9.) You no longer have to be a machine language programmer, or purchase
additional graphics software packages to display intricate and visually pleasing graphics
displaysthe Commodore 128 BASIC graphics capabilities take care of this for you. Of
course, if you are a machine language programmer or a software developer, the
exceptional C128 video hardware features offer high price/performance value for any
microcomputer application.
The C128 graphics features include:
Specialized graphics and sprite commands

16 colors
6 display modes, including:
Standard character mode
Multi-color character mode
Extended background color mode
Standard bit map mode
Multi-color bit map mode
Combined bit map and character modes (split-screen)
8 programmable, movable graphic objects called SPRITES which make animation possible
Custom programmable characters
Vertical and horizontal scrolling
The Commodore 128 is capable of producing two types of video signals: 40column composite video, and 80-column RGBI video. The composite video signal,
channeled through a VIC II (Video Interface Controller) chip (8564)similar to that
used in the Commodore 64mixes all of the colors of the spectrum in a single signal to
the video monitor. The 8563 separates the colors red, green and blue to drive separate
cathode ray guns within the video monitor for a cleaner, crisper and sharper image than
composite video.
The VIC II chip supports all of the Commodore BASIC 7.0 graphics commands,
SPRITES, sixteen colors, and the graphic display modes mentioned before. The 80column chip, primarily designed for business applications, also supports sixteen colors
(a few of which are different from those of the VIC chip), standard text mode, and bit
map mode. Sprites are not available in 80-column output. Bit map mode is not
supported by the Commodore BASIC 7.0 language in 80-column output. The 80-column
screen can be bit mapped through programming the 8563 video chip with machine
language programs. See Chapter 10, Programming the 80-Column (8563) Chip, for
information on bit mapping the 80-column screen.

COMMODORE 128 GRAPHICS PROGRAMMING

This chapter discusses how to use the Commodore 128 graphics features through
BASIC using the VIC (40-column) screen. Except for the sprite commands, each
graphic command is listed in alphabetical order. The sprite commands are covered in
Chapter 9. Following the format of each command are example programs that illustrate
the features of that command. Wherever possible, machine language routines are
included to show how the machine language equivalent of a BASIC graphics command
operates.
Chapter 8, The Power Behind Commodore 128 Graphics, is a description of the
inner workings of the Commodore 128 graphics capabilities. It explains how screen,
color and character memory are used and how these memory components store and
address data in each display mode. Chapter 9 then explains how to use sprites with the
new BASIC commands. Chapter 9 also discusses the inner workings of sprites, their
storage and addressing requirements, color assignments, and describes how to control
sprites through machine language.

TYPES OF SCREEN DISPLAY


Your C128 displays information several different ways on the screen; the parameter
" s o u r c e " in the command pertains to three different modes of screen display.

TEXT DISPLAY
Text display shows only text or characters, such as letters, numbers, special symbols
and the graphics characters on the front faces of most C128 keys. The C128 can display
text in both 40-column and 80-column screen formats. Text display includes standard
character mode, multi-color character mode and extended background color mode.
The Commodore 128 normally operates in standard character mode. When you
first turn on the Commodore 128, you are automatically in standard character mode. In
addition, when you write programs, the C128 is in standard character mode. Standard
character mode displays characters in one of sixteen colors on a background of one of
sixteen colors.
Multi-color character mode gives you more control over color than the standard
graphics modes. Each screen dot, a pixel, within an 8-by-8 character grid can have one
of four colors, compared with the standard mode which has only one of two colors.
Multi-color mode uses two additional background color registers. The three background
color registers and the character color register together give you a choice of four colors
for each dot within an 8-by-8 dot character grid.
Each pixel in multi-color mode is twice as wide as a pixel in standard character
mode and standard bit map mode. As a result, multi-color mode has only half the
horizontal resolution (160 X 200) of the standard graphics modes. However, the
increased control of color more than compensates for the reduced horizontal resolution.
Extended background color mode allows you to control the background color and
foreground color of each character. Extended background color mode uses all four
background color registers. In extended color mode, however, you can only use the first
sixty-four characters of the screen code character set. The second set of sixty-four
characters is the same as the first, but they are displayed in the color assigned to

111

112

COMMODORE 128

background color register two. The same holds true for the third set of sixty-four
characters and background color register three, and the fourth set of sixty-four characters
and background color register four. The character color is controlled by color memory.
For example, in extended color mode, you can display a purple character with a yellow
background on a black screen.
Each of the character display modes receives character information from one of
two places in the Commodore 128 memory. Normally, character information is taken
from character memory stored in a separate chip called ROM (Read Only Memory).
However, the Commodore 128 gives you the option of designing your own characters
and replacing the original characters with your own. Your own programmable characters
are stored in RAM.

BIT MAP DISPLAY


Bit map mode allows you to display highly detailed graphics, pictures and intricate
drawings. This type of display mode includes standard bit map mode and multi-color bit
map mode. Bit map modes allow you to control each individual screen dot or pixel
(picture element) which provides for considerable detail in drawing pictures and other
computer art. These graphic displays are only supported in BASIC by the VIC chip.
The 80-column chip is designed primarily for character display, but you can bit
map it through your own programs. See Chapter 10, Programming the 80-Column (8563)
Chip, for detailed information.
The difference between text and bit map modes lies in the way in which each
screen addresses and stores information. The text screen can only manipulate entire
characters, each of which covers an area of 8 by 8 pixels on the screen. The more
powerful bit map mode exercises control over each pixel on your screen.
Standard bit map mode allows you to assign each screen dot one o f t w o colors. Bit
mapping is a technique that stores a bit in memory for each dot on the screen. In
standard bit map mode, if the bit in memory is turned off, the corresponding dot on the
screen becomes the color of the background. If the bit in memory is turned on, the
corresponding dot on the screen becomes the color of the foreground image. The series
of 64,000 dots on the screen and 64,000 corresponding bits in memory control the
image you see on the screen. Most of the finely detailed computer graphics you see in
demonstrations and video games are bit mapped high-resolution graphics.
Multi-color bit map mode is a combination of standard bit map mode and
multi-color character mode. You can display each screen dot in one of four colors within
an 8 X 8 character grid. Again, as in multi-color character mode, there is a tradeoff
between the horizontal resolution and color control.

SPLIT SCREEN DISPLAY


The third type of screen display, split screen, is a combination of the first two types.
The split-screen display outputs part of the screen as text and part in bit map mode
(either standard or multi-color). The C128 is capable of this since it depends on two
parts of its memory to store the two screens: one part for text, and the other for
graphics.

COMMODORE 128 GRAPHICS PROGRAMMING

COMMAND SUMMARY
Following is a brief explanation of each graphics command available in BASIC 7.0:
B O X : Draws rectangles on the bit-map screen
CHAR: Displays characters on the bit-map screen
CIRCLE: Draws circles, ellipses and other geometric shapes
COLOR: Selects colors for screen border, foreground, background and characters
DRAW: Displays lines and points on the bit-map screen
GRAPHIC: Selects a screen display (text, bit map or split-screen bit map)
GSHAPE: Gets data from a string variable and places it at a specified position on the
bit-map screen
LOCATE: Positions the bit-map pixel cursor on the screen
P A I N T : Fills area on the bit-map screen with color
SCALE: Sets the relative size of the images on the bit-map screen
SSHAPE: Stores the image of a portion of the bit-map screen into a text-string variable
W I D T H : Sets the width of lines drawn
The following paragraphs give the format and examples for each of the non-sprite
BASIC 7.0 graphic commands. For a full explanation of each of these commands, see
the BASIC 7.0 Encyclopedia in Chapter 2.

BOX
Draw a box at a specified position on the screen.
BOX [color source], XI, Yl[,X2,Y2][,angle][,paint]
where:
color source

XI, Y1
X2, Y2
angle
paint

0 = Background color
1 = Foreground color
2 = Multi-color 1
3 = Multi-color 2
Top left corner coordinate (scaled)
Bottom right corner opposite X I , Y1, is the pixel cursor
location (scaled)
Rotation in clockwise degrees; default is 0 degrees
Paint shape with color
0 = Do not paint
1 = Paint

113

114

COMMODORE 128

EXAMPLES:
10 COLOR O,l:COLOR l,6:COLOR 4,1
2 0 GRAPHIC l,l:REM SF,LECT BMM
30 BOX 1,10,10,70,70,90,1:REM DRAW FILLED GREEN BOX
40 FOR 1=20 TO 140 STEP 3
50 BOX 1,1,I,I + 6 0,1 + 60,I + 8 0:REM DRAW AND ROTATE BOXES
60 NEXT
70 BOX 1,140,140, 200, 200, 220,1:REM DRAW 2ND FILLED GREEN BOX
80 COLOR l,3:REM SWITCH TO RED
90 BOX 1 , 150 , 20 , 210 , 80 , 90 , 1 :REM DRAW FILLED RED BOX
100 FOR 1=20 TO 140 STEP 3
110 BOX 1 , 1+130 , 1 , 1 + 190 ,1 + 60 , 1 + 7 0 :REM DRAW AND ROTATE RED BOXES
120 NEXT
130 BOX 1,270,140,330,200,210,1:REM DRAW 2ND FILLED RED BOX
140 SLEEP 5 :REM DELAY
15 0 GRAPHIC 0,1:REM SWITCH TO TEXT MODE

10 COLOR O,l:COLOR 4,l:COLOR 1,6


20 GRAPHIC 1,1
30 BOX 1,0,0,319,199
40 FOR X=10 TO 160 STEP 10
50 C=X/10
6 0 COLOR 1,C
70 BOX l,X,X,320-X,320-X
8 0 NEXT
90 SLEEP 5
100 GRAPHIC 0,1

10 COLOR O,l:COLOR 4,l:COLOR 1,6


20 GRAPHIC 1,1
30 BOX 1,50,50,150,120
40 BOX 1,70,70,170,140
50 DRAW 1,50,50 TO 70,70
60 DRAW 1,150,120 TO 170,140
70 DRAW 1,50,120 TO 70,140
80 DRAW 1,150,50 TO 170,70
90 CHAR 1,20,20,"CUBE EXAMPLE"
100 SLEEP 5
110 GRAPHIC 0,1

10 COLOR l,6:COLOR 4,l:COLOR 0,1


20 GRAPHIC l,l:REM SELECT BIT MAP MODE
30 DO :REM CALCULATE RANDOM POINTS
40 Xl=INT(RND(l)*319+l)
50 X2=INT(RND(1)*319 + 1)
60 X3=INT(RND(1)*319+1)
70 X4=INT(RND(1)*319 + 1)
80 Yl=INT(RND(l)*199+l)
90 Y2=INT(RND(1)* 19 9+1)
100 Y3=INT(RND(1)* 19 9+1)
110 Y4 = INT(RND(1)* 19 9 + 1)
120 BOX l,Xl,Yl,X2,Y2:REM DRAW THE RANDOM BOXES
130 BOX l,X3,Y3,X4,Y4
140 DRAW l,Xl,Yl TO X3,Y3:REM CONNECT THE POINTS
150 DRAW l,X2,Y2 TO X4,Y4
160 DRAW l,Xl,Y2 TO X3,Y4
170 DRAW 1,X2,Y1 TO X4,Y3
180 SLEEP2:REM DELAY
190 SCNCLR
200 LOOP:REM LOOP CONTINUOUSLY

COMMODORE 128 GRAPHICS PROGRAMMING

CHAR
Display characters at the specified position on the screen.
CHAR [color source],X,Y[,string][,RVS]
This is primarily designed to display characters on a bit mapped screen, but it can also
be used on a text screen. Here's what the parameters mean:
color source
X
Y
string
RVS

0 = Background
1 = Foreground
Character column (0-79) (wraps around to the next line
in 40-column mode)
Character row (0-24)
String to print
Reverse field flag (0 = off, 1 = on)

EXAMPLE:
10
20
30
40

COLOR 2,3: REM multi-color l = R e d


COLOR 3,7: REM multi-eolor2 = Blue
GRAPHIC 3,1
CHAR 0,10,10, " T E X T " , 0

CIRCLE
Draw circles, ellipses, arcs, etc. at specified positions on the screen.
CIRCLE [color source],X,Y[,Xr][,Yr]
[,sa][,ea][,angle][,inc]
where:
color source

X,Y
Xr
Yr
sa
ea
angle
inc

0 = background color
1 = foreground color
2 = multi-color 1
3 = multi-color 2
Center coordinate of the CIRCLE
X radius (scaled)
Y radius (default is xr)
Starting arc angle (default 0 degrees)
Ending arc angle (default 360 degrees)
Rotation in clockwise degrees (default is 0 degrees)
Degrees between segments (default is 2 degrees)

EXAMPLES:
CIRCLE1, 160,100,65,10
CIRCLE1, 160,100,65,50
CIRCLE1, 60,40,20,18,,,,45

Draws an ellipse.
Draws a circle.
Draws an octagon.

115

116

COMMODORE 128

CIRCLE1, 260,40,20,,,,,90
CIRCLE1, 60,140,20,18,,,, 120
CIRCLE1, + 2, + 2,50,50

Draws a diamond.
Draws a triangle.
Draws a circle (two pixels down and two to
the right) relative to the original coordinates of
the pixel cursor.

SAMPLE PROGRAMS:
10 REM SUBMARINE TRACKING SYSTEM
2 0 COLOR O,l:COLOR 4,l:COLOR l,2:REM SELECT BKGRND, BRDR,SCREEN COLORS
3 0 GRAPHIC l,l:REM ENTER BIT MAP MODE
40 BOX 1,0,0,319,199
50 CHAR 1,7,24,"SUBMARINE TRACKING SYSTEM" :REM DISPLAY CHARS ON BIT MAP
6 0 COLOR l,3:REM SELECT RED
70 XR=0:YR=0:REM INIT X AND Y RADIUS
8 0 DO
90 CIRCLE 1,160,100,XR,YR, 0 , 360, 0 , 2 :REM DRAW CIRCLES
100 XR=XR+10:YR=YR+10:REM UPDATE RADIUS
110 LOOP UNTIL XR=9 0
120 DO
130 XR= 0:YR= 0
140 DO
150 CIRCLE 0,160,10 0,XR,YR,0,3 60,0,2 :REM ERASE CIRCLE
160 COLOR 1,2 :REM SWITCH TO WHITE
170 DRAW 1 , 160 , 100+XR:DRAW 0,160, 100 + XR:REM DRAW SUBMARINE BLIP
180 COLOR l,3:REM SWITCH BACK TO RED
190 SOUND 1,16 000,15:REM BEEP
200 CIRCLE 1,160,100,XR,YR, 0 , 360 , 0 , 2 :REM DRAW CIRCLE
210 XR=XR+10:YR=YR+10 :REM UPDATE RADIUS
220 LOOP UNTIL XR=90 :REM LOOP
2 30 LOOP
10
20
30
40
50
60
70
80
90

COLOR O,l:COLOR 4,l:COLOR 1,7


GRAPHIC l,l:REM SELECT BMM
X=150:Y= 150:XR=150:YR=15 0
DO
CIRCLE l,X,Y,XR,YR
X=X + 7 :Y=Y-5:REM INCREMENT X AND Y COORDINATES
XR=XR-5 :YR=YR-5:REM DECREMENT X AND Y RADII
LOOP UNTIL XR=0
GRAPHIC 0,1:REM SELECT TEXT MODE

COLOR
Define colors for each screen area.
COLOR source number, color number
This statement assigns a color to one of the seven color areas:
AREA

SOURCE

0
1
2
3
4
5
6

40-column (VIC) background


40-column (VIC) foreground
multi-color 1
multi-color 2
40-column (VIC) border
character color (40- or 80-column screen)
80-coIumn background color

Colors codes are in the range 1-16.

COMMODORE 128 GRAPHICS PROGRAMMING

COLOR CODE

COLOR

COLOR CODE

1
2
3
4
5
6
7
8

Black
White
Red
Cyan
Purple
Green
Blue
Yellow

9
10
11
12
13
14
15
16

COLOR

Orange
Brown
Light Red
Dark Gray
Medium Gray
Light Green
Light Blue
Light Gray

Color Codes in 40-Column ( V I C ) O u t p u t

EXAMPLE:
COLOR 0, 1:
COLOR 5, 8:

Changes background color of 40-column screen to black.


Changes character color to yellow.

SAMPLE PROGRAM:
10 REM CHANGE FOREGROUND BIT MAP COLOR
20 GRAPHIC 1,1
30 1 = 1
4 0 DO
50 COLOR 1,1
60 BOX 1,100,100,219,159
70 I=I+1:SLEEP 1
80 LOOP UNTIL 1=17
90 GRAPHIC 0,1
100 REM CHANGE BORDER COLOR

110 1=1
120
130
140
150
16 0
170
180
190
200
210
220
230
240
25 0
260
270
280
290

DO
COLOR 4,1
I=I+1:SLEEP 1
LOOP UNTIL 1=17
REM CHANGE CHARACTER COLOR
1=1
DO
COLOR 5,1
PRINT"COLOR CODE";I
I=I+1:SLEEP 1
LOOP UNTIL 1=17
REM CHANGE BACKGROUND COLOR
1=1
DO
COLOR 0,1
I = I + 1:SLEEP 1
LOOP UNTIL 1=17
COLOR O,l:COLOR 4,l:COLOR 5,2

DRAW
Draw dots, lines and shapes at specified positions on screen.
DRAW [color source], [XI, Yl][TO X2, Y2] . . .
Here are the parameter values:

117

118

COMMODORE 128

where:
color source

X1,Y1
X2,Y2

0 Bit map background


1 Bit map foreground
2 Multi-color 1
3 Multi-color 2
Starting coordinate (0,0 through 319,199) (scaled)
Ending coordinate (0,0 through 319,199) (scaled)

EXAMPLES:
Draw a dot.
DRAW 1, 100, 50
Draw a line.
DRAW , 10, 10 TO 100,60
DRAW , 10, 10 TO 10,60 TO 100,60 TO 10,10 Draw a triangle.
SAMPLE PROGRAMS:
10 REM DRAW EXAMPLES
2 0 COLOR O,l:COLOR 4,l:COLOR 1,6
30 GRAPHIC 1,1
40 CHAR 1,10,1,"THE DRAW COMMAND"
50 X=10
60 DO
70 DRAW l,X,50:REM DRAW POINTS
8 0 X=X+10
90 LOOP UNTIL X=320
100 CHAR 1,12,7 ,"DRAWS POINTS"
110 Y=7 0
120 DO
130 Y=Y+5
140 DRAW l,l,Y TO Y,Y :REM DRAW LINES
150 LOOP UNTIL Y=130
160 CHAR 1 , 18,11,"LINES"
170 DRAW 1,10,140 TO 10,199 TO 90,165 TO 40,160 TO 10,140:REM DRAW SHAPE 1
180 DRAW 1,120,145 TO 140,195 TO 195,195 TO 225,145 TO 120,145:REM DRAW SHAPE
190 DRAW 1,250,199 TO 319,199 TO 319,60 TO 250,199:REM DRAW SHAPE 3
200 CHAR l,22,15,"AND SHAPES"
210 SLEEP 5:GRAPHIC 0,1
10 COLOR 0,1:COLOR 4,l:COLOR 1,7
20 GRAPHIC l,l:REM SELECT BMM
30 Y=1
4 0 DO
50 DRAW 1,1,Y TO 3 20,Y:REM DRAW HORIZONTAL LINES
60 Y=Y+10
70 LOOP WHILE Y<200
75 X=1
8 0 DO
90 DRAW 1,X,1 TO X,200:REM DRAW VERTICAL LINES
95 X=X+10
97 LOOP WHILE X<320
100 COLOR l,3:REM SWITCH TO RED
110 DRAW 1,160,0 TO 160,200:REM DRAW X AXIS IN RED
120 DRAW 1,0,100 TO 320,100:REM DRAW Y AXIS IN RED
130 COLOR l,6:REM SWITCH TO GREEN
140 DRAW 1,0,199 TO 50,100 TO 90,50 TO 110,30 TO 150,20 TO 180,30
150 DRAW 1,180,30 TO 220,10 TO 260,80 TO 320,0:REM DRAW GROWTH CURVE
160 CHAR 1,7,23,"PROJECTED SALES THROUGH 1990"
170 CHAR 1 ,1 , 21 , "1970
1975
1980
1985
1990"
180 SLEEP 10:GRAPHIC 0,1:REM DELAY AND SWITCH TO TEXT MODE

COMMODORE 128 GRAPHICS PROGRAMMING

GRAPHIC
Select a graphic mode.
1) GRAPHIC mode [,clear][,s]
2) GRAPHIC CLR
This statement puts the Commodore 128 in one of the six graphic modes:

MODE

DESCRIPTION

0
1
2
3
4
5

40-column text
standard bit map graphics
standard bit map graphics (split screen)
multi-color bit map graphics
multi-color bit map graphics (split screen)
80-coIumn text

EXAMPLES:
GRAPHIC 1,1
GRAPHIC 4,0,10
GRAPHIC 0
GRAPHIC 5
GRAPHIC CLR

Select standard bit map mode and clear the bit map.
Select split screen multi-color bit map mode, do not clear
the bit map and start the split screen at line 10.
Select 40-column text.
Select 80-column text.
Clear and deallocate the bit map screen.

SAMPLE PROGRAM:
10 REM GRAPHIC MODES EXAMPLE
2 0 COLOR O,l:COLOR 4,l:COLOR 1,7
30 GRAPHIC l,l:REM ENTER STND BIT MAP
40 CIRCLE 1,160,100,60,60
50 CIRCLE 1,160,100,30,30
60 CHAR 1,9,24,"STANDARD BIT MAP MODE"
7 0 SLEEP 4
80 GRAPHIC 0,1:REM ENTER STND CHAR MODE
9 0 COLOR l,6:REM SWITCH TO GREEN
100 FOR I=lTO 25
110 PRINT"STANDARD CHARACTER MODE"
120 NEXT
130 SLEEP 4
140 GRAPHIC 2,l:REM SELECT SPLIT SCREEN
150 CIRCLE 1,160,70,50,50
160 CHAR 1 , 14,1, "SPLIT SCREEN"
170 CHAR 1,8,16,"STANDARD BIT MAP MODE ON TOP"
180 FOR 1=1 TO 25
190 PRINT" STANDARD CHARACTER MODE ON THE BOTTOM"
2 00 NEXT
210 SLEEP 3:REM DELAY
220 SCNCLR:REM CLEAR SCREEN
230 GRAPHIC CLR:REM DE-ALLOCATE BIT MAP

GSHAPE
Retrieve (load) the data from a string variable and display it on a specified coordinate.
GSHAPE string variable [X,Y][,mode]

119

120

COMMODORE 128

where:
string
X,Y

Contains shape to be drawn


Top left coordinate (0,0 through 319,199) telling where to
draw the shape (scaledthe default is the pixel cursor)
Replacement mode:
0 = place shape as is (default)
1 = invert shape
2 = OR shape with area
3 = AND shape with area
4 = XOR shape with area

mode

SAMPLE PROGRAM:
10 REM DRAW, SAVE AND GET THE COMMODORE SYMBOL
2 0 COLOR O,l:COLOR 4,l:COLOR 1,7
30 GRAPHIC l,l:REM SELECT BMM
40 CIRCLE 1 , 160, 100, 20,15 :REM OUTER CIRCLE
50 CIRCLE 1 , 160, 100, 10, 9:REM INNER CIRCLE
60 BOX 1 , 165 , 8 5, 18 5, 115 :REM ISOLATE AREA TO BE ERASED
70 SSHAPE A$, 166 , 8 5 , 18 5, 115 :REM SAVE THE AREA INTO A$
80 GSHAPE A$, 166 , 8 5 , 4 :REM EXCLUSIVE OR THE AREA-THIS (ERASES) TURNS OFF PIXELS
9 0 DRAW 0,165,94 TO 165,106:REM TURN OFF (DRAW IN BKGRND COLOR) PIXELS IN "C="
100 DRAW 1,166,94 TO 166,99 TO 180,99 TO 185,94 TO 166,94:REM UPPER FLAG
110 DRAW 1,166,106 TO 166,101 TO 180,101 TO 185,106 TO 166,106:REM LOWER FLAG
120 PAINT 1,160,110:REM PAINT "C"
130 PAINT 1,168,98 :REM UPPER FLAG
140 SLEEP 5:REM DELAY
150

SSHAPE

160
170
180
190
200
210
220
230
240
250
260
270
280

DO
SCNCLR
Y=10
DO
X=10
DO
GSHAPE B$,X,Y:REM GET AND DISPLAY SHAPE
X=X+50:REM UPDATE X
LOOP WHILE X<280
Y=Y+4 0:REM UPDATE Y
LOOP WHILE Y<160
SLEEP 3
LOOP

B $ , 13 7, 84 , 1 8 7 , 116 :REM SAVE

SHAPE

INTO

B$

LOCATE
Position the bit map pixel cursor (PC) on the screen.
LOCATE X, Y
EXAMPLE:
LOCATE 160,100
LOCATE +20,100
LOCATE + 30, + 20

Position the PC in the center of the bit map screen.


Nothing will be seen until something is drawn.
Move the PC 20 pixels to the right of the last PC position
and place it at Y coordinate 100,
Move the PC 30 pixels to the right and 20 down from
the previous PC position.

PAINT
Fill area with color.
PAINT [color source],X,Y[,mode]

COMMODORE 128 GRAPHICS PROGRAMMING

where:
color source

X,Y
mode

0 Bit map background


1 Bit map foreground (default)
2 Multi-color 1
3 Multi-color 2
starting coordinate, scaled (default at pixel cursor (PC))
0 = paint an area defined by the color source selected
1 = paint an area defined by any non-background source

EXAMPLE:
10 CIRCLE 1, 160,100,65,50
20 PAINT 1, 160,100

10 BOX 1, 10, 10, 20, 20


20 PAINT 1, 15, 15

Draws an outline of a circle.


Fills in the circle with color from source 1 (VIC
foreground), assuming point 160,100 is colored
in the background color (source 0).
Draws an outline of a box.
Fills the box with color from source 1, assuming
point 15,15 is colored in the background source

(0).
30 PAINT 1, + 1 0 , + 1 0

PAINT the screen in the foreground color source


at the coordinate relative to the pixel cursor's
previous position plus 10 in both the vertical and
horizontal positions.

SCALE
Alter scaling in graphics mode.
SCALE n [,Xmax,Ymax]
where:
n = 1 (on) or 0 (off)
X max = 320-32767
(default = 1023)
Y max = 200-32767
(default = 1023)
The default scale values are:
Multi-color mode
Bit map mode

X = 0 to 159 Y = 0 to 199
X = 0 to 319 Y - 0 to 199

EXAMPLES:
10 GRAPHIC 1,1
20 SCALE 1 :CIRCLE 1,180,100,100,100

Enter standard bit map, turn scaling


on to default size (1023, 1023) and
draw a circle.

121

122

COMMODORE 128

10 GRAPHIC 1,3
20 SCALE 1,1000,5000
30 CIRCLE 1,180,100,100,100

Enter multi-color mode, turn scaling


on to size (1000,5000) and draw a
circle.

SSHAPE
Save shapes to string variables.
SSHAPE and GSHAPE are used to save and load rectangular areas of multi-color or bit
mapped screens to/from BASIC string variables. The command to save an area of the
screen into a string variable is:
SSHAPE string variable, XI, Y1 [,X2,Y2]
where:
string variable
X1,Y1
X2,Y2

String name to save data in


Corner coordinate (0,0 through 319,199) (scaled)
Corner coordinate opposite (X1,Y1) (default is the PC)

EXAMPLES:
SSHAPE A$,10,10

SSHAPE B$, 20,30,47,51

SSHAPE D$, + 1 0 , + 10

Saves a rectangular area from the coordinate 10,10


to the location of the pixel cursor, into string variable A$.
Saves a rectangular area from top left coordinate
(20,30) through bottom right coordinate (47,51) into
string variable B$.
Saves a rectangular area 10 pixels to the right and 10
pixels down from the current position of the pixel
cursor.

Also, see the example program under GSHAPE for another example.

WIDTH
Set the width of drawn lines.
WIDTH n
This command sets the width of lines drawn using BASIC's graphic commands to either
single or double width. Giving n a value of 1 defines a single width line; a value of 2
defines a double width line.
EXAMPLES:
WIDTH 1 Set Single width for graphic commands
WIDTH 2 Set double width for drawn lines

5
MACHINE
LANGUAGE
O N THE
COMMODORE 128

123

124

COMMODORE 128

This chapter introduces you to 6502-based machine language programming. Read this
section if you are a beginner or novice machine language programmer. This section
explains the elementary principles behind programming your Commodore 128 in machine
language. It also introduces you to the 8502 machine language instruction set and how
to use each instruction. If you are already an experienced machine language programmer, skip this section and continue to the 8502 Instruction and Addressing Table at the
end of the chapter for reference material on machine language instructions. The 8502
instruction set is exactly the same as the 6502 microprocessor instruction set.

W H A T IS MACHINE LANGUAGE?
Every computer has its own machine language. The type of machine language depends
on which processor is built into the computer. Your Commodore 128 understands 8502
machine language, which is based on 6502 machine language, to carry out its operations. Think of the microprocessor as the brain of the computer and the instructions as
the thoughts of the brain.
Machine language is the most elementary level of code that the computer actually
interprets. True machine language is composed of binary strings of zeroes and ones.
These zeroes and ones act as switches to the hardware, and tell the circuit where to apply
voltage levels.
The machine language discussed in this chapter is symbolic 6502 Assembly
language as it appears in the C128 Machine Language Monitor. This is not the
full-blown symbolic assembly language as it appears in an Assembler package, since
symbolic addresses or other higher level utilities that an Assembler software package
would provide are not implemented.
Machine language is the lowest level language in which you can instruct your
computer. BASIC is considered a high-level language. Although your Commodore 128
has BASIC built in, the computer must first interpret and translate it to a lower level that
it can understand, before the computer can act upon BASIC instructions.
With each microinstruction, you give the computer a specific detail to perform.
The computer takes nothing for granted in machine language, unlike BASIC, where
many unnoticed machine-level functions are performed by one statement. One BASIC
statement requires several machine language instructions to perform the same operation.
Actually, when you issue a BASIC command, you are really calling a machine language
subroutine that performs a computer operation.

WHY USE MACHINE LANGUAGE?


If machine language is more intricate and complicated than BASIC, why use it? Certain
applications, such as graphics and telecommunications, require machine language because of its speed. Since the computer does not have to translate from a higher-level
language, it runs many times faster than BASIC.

MACHINE LANGUAGE O N THE COMMODORE 128

Programs such as those used in arcade games cannot operate in the relatively slow
speed of BASIC, so they are written in machine language. Other instances dictate the
use of machine language simply because those programming operations are handled
better than in a high-level language like BASIC. But some programming functions such
as string operations are easier in BASIC than in machine language. In these cases,
BASIC and machine language can be used together. You can find information on how to
mix machine language with BASIC in Chapter 7.
Inside your computer is a perpetually running program called the operating
system. The operating system program controls every function of your computer. It
performs functions at lightning speeds you are not even aware of.
The operating system program is written entirely in machine language and is
stored in a portion of the computer called the Kernal ROM. (Chapter 13 describes how
to take advantage of the machine language programs within the Kernal, and how to use
parts of the operating system in your own machine-language programs.)
Though machine language programming may seem more complicated and difficult
than BASIC at first, think back to when you didn't know BASIC or your first
programming language. That seemed difficult at first, too. If you learned BASIC or
another programming language, you can learn machine language. Although it's a good
idea to learn a higher-level language such as BASIC before you start machine language,
it's not absolutely necessary.

W H A T DOES MACHINE LANGUAGE


LOOK LIKE?
Chapter 2 describes the C128 BASIC 7.0 language. Most statements in BASIC start
with a BASIC verb or keyword, followed by an operand. The BASIC keywords
resemble English verbs. The operands are variables, or constants, that are part of an
expression. For example, A 4- B = 2, is an expression where A, B, and 2 are operands
in the expression. Machine-language instructions are similar, though they have a uniform
format. Here's the format for an 8502 symbolic machine language instruction as it
appears in the C128 Machine Language Monitor:
OP-CODE FIELD

OPERAND FIELD

OPERATION CODE (OP-CODE) FIELD


The first part of a machine-language instruction is called the operation code or op-code.
The op-code is comparable to a BASIC verb, in that it is the part of the instruction that
performs an action. A machine language op-code is also referred to in an assembly
language as a mnemonic. All 8502 (6502) machine language assembler mnemonics are
three-letter abbreviations for the functions they perform. For example, the first and most
common instruction you will learn is LDA, which stands for LoaD the Accumulator.
This chapter defines all of the mnemonics.

125

126

COMMODORE 128

OPERAND FIELD
The second portion of a machine-language instruction is the OPERAND field. In the
C128 Machine Language Monitor, the operand is separated from the op-code with at
least one space and preceded by a ($) dollar sign, ( + ) plus sign (decimal), (&)
ampersand (octal), or a (%) percent (binary) sign to signify that the operand is a
hexadecimal, decimal, octal or binary number. An ADDRESS is the name of or
reference to a specific memory location within the computer.
The number of a memory location is its address, just like houses on your street are
numbered. Addresses in your computer are necessary so they can receive, store and send
(LOAD) data back and forth to the microprocessor.
When you use the Commodore 128's built-in machine-language monitor, all
numbers and addresses default to hexadecimal numbers, but they can be represented in
decimal, octal or binary. The address is the hexadecimal number of the specified
memory location. When you use an ASSEMBLER, the addresses are referred to as
symbolic addresses. Symbolic addresses allow you to use variable names, instead of
absolute addresses that specify the actual memory location. You declare the symbolic
address to be the numeric address in the beginning of your machine language program or
allow the assembler to assign the address.
When you refer to that address later in the program, you can refer to the symbolic
address rather than to the absolute address as does the Machine Language Monitor.
Using an assembler and symbolic addresses make programming in machine language
easier than using the machine-language monitor and absolute addresses. You will
learn about the eleven addressing modes later in this chapter.
As you know, the second part of a machine-language instruction is the OPERAND. A machine language operand can be a constant; it does not necessarily have to be
an address reference. When a constant in machine language appears in place of an
address as the second part of an instruction, an operation is performed on a data value
rather than a memory location.
A pound sign ( # ) in front of the operand signifies immediate addressing, which
you will learn more about later in the chapter. The pound sign is only used as an aid for
the symbolic language programmer. The pound sign tells the computer to perform
machine-language instruction on a constant, and not an address. In the case of the
Machine Language Monitor, variable names are not allowed. To represent variables in
the monitor, you must reference a memory location where your variable data value is
stored.

EXAMPLES OF
MACHINE-LANGUAGE INSTRUCTIONS
LDA
LDA
LDA
LDA
LDA

$100
$10
($FA),Y
$2000,X
#$10

Absolute addressing
Zero page absolute addressing
Indirect indexed addressing
Indexed addressing (absolute)
Immediate addressing (constants)

MACHINE LANGUAGE O N THE COMMODORE 128

THE SIMILARITIES A N D DIFFERENCES BETWEEN A N


ASSEMBLER A N D A MACHINE LANGUAGE MONITOR
An assembler and machine-language monitor both provide for symbolic op-codes.
Assemblers typically allow symbolic operands as well, whereas the C128 machinelanguage monitor refers to addresses and operands literally (absolutely).
An assembler typically has two forms of a file: source code and object code.
Source code is the file you create when you are writing the program including symbolic
start addresses and comments.
The source code file is not executable. It must be assembled (in an intermediate
process) into object code, which is executable code.
The machine language monitor start address is determined by where you place the
actual instructions in memory. The monitor does not provide for comments. The resulting
program, once it is input, is executed immediately as a binary file. No intermediate
assembly step is needed.

THE 8502 MICROPROCESSOR REGISTERS


You have learned that an address is a reference to a specific memory location among the
2 banks of RAM within the Commodore 128. Separate and independent of those RAM
locations are special purpose work and storage areas within the microprocessor chip
itself, called registers. These registers are where the values are manipulated. The
manipulation of the microprocessor registers and their communication with the computer's memory (RAM and ROM) accomplishes all the functions of machine language and
your computer's operating system.
Figure 5-1 shows a block diagram of the 8502 microprocessor. As shown in the
figure, the 8502 microprocessor registers are:
Accumulator
X index register
Y index register
Status register
Program counter
Stack pointer
Following are descriptions of these registers.

THE ACCUMULATOR
The accumulator is one of the most important registers within the 8502 microprocessor.
As the name implies, it accumulates the results of specific operations. Think of
the accumulator as the doorway to your microprocessor. All information that enters
your computer must first pass through the accumulator (or the X or Y register).

127

128

COMMODORE 128

For example, if you want to store a value within one of the RAM locations, you must
first ioad the value into the accumulator (or the X or Y register) and then store it into the
specified RAM location. You cannot store a value directly into RAM, without placing it
into the accumulator or the index registers first. (The index registers are described in the
following section.)

Figure 5-1. 8502 Block Diagram

MACHINE LANGUAGE O N THE COMMODORE 128

All mathematical operations are performed within the arithmetic logic unit (ALU)
and stored in the accumulator. It is considered a temporary mathematical work area. For
example, you want to add two numbers, 2 + 3. First, load the accumulator with the 2.
Next add 3 with the ADC mnemonic. Now, you want to perform another operation. You
must store the answer from the accumulator into a RAM location before you perform the
next math operation. If you don't, your original answer is erased.
The accumulator is so important that it has an addressing mode of its own. All the
instructions using this mode pertain specifically to the accumulator. The following three
sample instructions pertain solely to the accumulator in its own addressing mode:
LDA - LOAD accumulator with memory
STA - STORE the accumulator in memory
ADC - ADD contents of memory to the accumulator
Details on all of the accumulator addressing commands are given later in this chapter.

THE X A N D Y INDEX REGISTERS


The second most used registers are the X and Y index registers. These index registers are
used primarily to modify an address by adding an index within a machine-language
instruction. They also can be used as temporary storage locations or to load values and
store them in RAM like the accumulator.
When modifying an address, the contents of the index registers are added to an
original address, called the base address, to find an address relative to the base address.
The resulting address yields the effective addressi.e., the location where a data value
is stored or retrieved. The effective address is acted upon by machine-language instructions. For example, you want to place the value 0 in locations 1024 through 1034. In
BASIC, here's how you do it:
10 FOR I = 1024 to 1034
20 POKE 1,0
30 NEXT
Here's how you do it in symbolic machine language by using the X or Y index
register. NOTE: Don't worry if you don't understand all of the following instructions. They
are discussed fully in the TYPES OF INSTRUCTIONS section, later in this chapter.
LDA # $ 0 0
TAX
START

STA $0400,X
INX
CPX # $ 0 B
BNE START
BRK

Load the Accumulator with 0


Transfer the contents of Accumulator (0) to X
Register.
Store contents of Accumulator in address $0400 + X
Increment the X register
Compare the X register with $0B (11 decimal)
If X register does not equal 11 branch to START.
Stop

* = In the machine-language monitor the symbolic label START is not allowed, so it


would appear as an absolute address reference (eg; $183B).

129

130

COMMODORE 128

The BASIC example above places a 0 in locations (addresses) 1024 through 1034.
Line 10 sets up a loop from memory locations 1024 to 1034. Line 20 POKEs the value 0
into the location specified by I. The first time through the loop, I equals 1024. The
second time through the loop, I equals 1025 and so on. Line 30 increments the index
variable I by 1 each time it is encountered.
The previous machine-language example accomplishes the same task as the BASIC example. LDA # $ 0 0 loads a 0 into the accumulator. TAX transfers the contents of
the accumulator into the X-index register. The following machine-language instructions
form a loop:
START

STA $0400,X
INX
CPX # $ 0 B
BNESTART

Here's what happens within the loop. STA $0400,X stores a 0 in location $0400
(hex) the first time through the loop. Location $0400 is location 1024 decimal. INX
increments the X register by 1, each cycle through the loop. CPX # $ 0 B compares the
contents of the X register with the constant 11 ($0B). If the contents of the X register do
not equal 11, the program branches back to START STA $0400,X and the loop is
repeated.
The second time through the loop, 0 is stored in address $0401 (1025 decimal) and
the X register is incremented again. The program continues to branch until the contents
of the X register equal 11.
The effective address for the first cycle through the loop is $0400 which is 1024
decimal. For the second cycle through the loop the effective address is $0400 + 1, and
so on. Now you can see how the index registers modify the address within machinelanguage instruction.

THE STATUS REGISTER


The microprocessor's status register indicates the status of certain conditions within the
8502. The status register is controlled by seven programming states of the microprocessor, and indicates the conditions with flags. The status register is one byte, so each flag
is represented by a single bit. Bit 5 is not implemented.
Branching instructions check (4 of the 7 bits in) the status register to determine
whether a condition has occurred. The conditions for branching pertain to the value of
the bits in the status register. If a condition is true, meaning the FLAG bit corresponding
to one of the four conditions is high (equal to a 1), the computer branches. If the
condition you are testing is not true, the computer does not branch and the program
resumes with the instruction immediately following the branch.
Figure 5 - 2 shows the layout of the 8502 status register and lists the conditions
the status register flags.

MACHINE LANGUAGE O N THE COMMODORE 128

N ] V 1 ] B ] p 1 I 1 Z]C]

PROCESSOR STATUS REG "P"

^ CARRY
1 = TRUE
^ZERO
1 = RESULT ZERO
^IRODISABLE
1 = DISABLE
+ DECIMAL MODE
1 = TRUE
+ BRK COMMAND
- OVERFLOW

1 = TRUE

NEGATIVE

1 = NEG

Figure 5-2. 8502 Status Register

The Carry bit (0) is set if an addition operation carries a bit into the next position
to the left of the leftmost bit. The Carry bit is set by other conditions, of which this is
one. The SEC instruction sets the Carry bit. CLear the Carry bit with the CLC
instruction.
The Zero bit (1) is set if the result of an operation equals zero. The command BEQ
stands for Branch on result EQual to Zero. The command BNE stands for Branch on
Result Not Equal to zero. If the zero bit in the status register is set, the program
branches to the address relative to the current program counter value (for a BEQ
instruction). Otherwise, the BEQ command is skipped and the program resumes with the
instruction immediately following the BEQ statement.
The IRQ Disabled bit (2) is set if your program requests interrupts to be disabled with the SEI command (Set Interrupt Disable Status). The Disable Interrupt
Status bit is cleared with the CLI command (CLear Interrupt Disable bit) to permit
interrupts to occur. You will learn more about programming interrupts in the section
entitled TYPES OF INSTRUCTIONS and in the Raster Interrupt program explanation in
Chapter 8.
The microprocessor sets the Decimal Mode bit (3) if you instruct the microprocessor to SEt Decimal Mode with the SED instruction. CLear the Decimal Mode bit with
the CLD instruction, CLear Decimal Mode.
The BRK flag (bit 4) operates similar to the IRQ disable flag. If a BRK instruction
occurs, it is set to 1. Like an IRQ interrupt, the BRK causes the contents of the
program counter to be pushed onto the stack. The contents of the status register is
pushed on top of the stack and evaluated. If the BRK flag is set, the operating system
or your application program must evaluate whether or not a BRK or interrupt has
occurred.
If the BRK flag is cleared once the status register is pushed onto the stack, the
processor handles this as an interrupt and services it. Unlike an interrupt, the BRK flag
causes the address of the program counter plus two to be saved. The microprocessor
expects this to be the address of the next instruction to be executed. You may have to

131

132

COMMODORE 128

adjust this address since it may not be the actual address of the next instruction within
your program.
The Overflow flag (bit 6) is set by a signed operation overflowing into the sign
bit (bit 7) of the status register. You can clear the Overflow bit in the status register with
the CLV instruction (CLear Overflow flag). You can conditionally branch if the
Overflow bit is set with the BVS (Branch Overflow Set) instruction. Similarly, you can
conditionally branch if the overflow bit is clear with the BVC (Branch Overflow Clear)
instruction. The BIT instruction can be used to intentionally set the overflow flag.
The microprocessor sets the negative flag (bit 7) if the result of an arithmetic
operation is less than 0. You can conditionally branch if the result of an arithmetic
operation is negative, using the BMI instruction, (Branch on result Minus) or positive
using the BPL instruction, (Branch on Result Positive).
The status register indicates seven important conditions within the microprocessor
while your machine language program is executing. Your program can test for certain
conditions, and act upon the results. It gives you a way to conditionally control certain
machine level functions depending on the value of the status flags.

THE PROGRAM COUNTER


So far all of the registers within the 8502 are 8 bits, or one byte. The program counter
is twice as wide (16 bits) as the accumulator, X or Y registers or the status register. The
program counter is a 16-bit register because it holds the current address of the next
instruction to be executed. The addresses used in an 8502-based microprocessor are all 16
bits wide. They have to be in order to address all locations within each 64K RAM
bank.
The program counter holds the address of the next instruction to be executed. It
fetches the addresses of the instructions sequentially (usually) and places them on the
16-bit address bus. The processor obtains the data or instructions at the specified 16-bit
address from the data bus. Then they are decoded and executed.

THE STACK POINTER


Within the RAM of the Commodore 128 is a temporary work area called the stack. It
starts at location decimal 256 and ends at location 511 (hex $100 to $lFF). This area of
computer RAM is referred to as page 1. Paging is explained in the next section.
The stack is used for three purposes in your computer: temporary storage, control
of subroutines, and interrupts. The stack is a LIFO (Last In, First Out) structure which
means the last value placed on the stack is the first one taken off. When you place a
value on the stack, it is referred to as pushing. When you take a value off the stack, it is
considered pulling or popping.
Think of the structure as a stack of lunch trays in a cafeteria. The first tray used is
the one that is pulled off the top. The last one used is the one on the bottom, and it is
used only if all the others are pulled off before it.
The stack pointer is the address of the top stack value (plus 1). When a value
is pulled from the stack, the stack pointer then indicates the new address of the
next item on the stack. When a subroutine is called or an interrupt occurs, the

MACHINE LANGUAGE O N THE COMMODORE 128

address where the interrupt or subroutine occurs is pushed on top of the stack. Once
the interrupt or subroutine is serviced, the address where it occurred is popped off
the stack and the computer continues where it left off when the interrupt or subroutine
occurred.

I6-BIT ADDRESSING:
THE CONCEPT OF PAGING
The Commodore 128 contains 128K of Random Access Memory (RAM). This means
you have two banks of 65536 (64K) RAM memory locations (minus two for locations 0
and 1, which are always present in a RAM bank). Since the 8502 is an 8-bit microprocessor, it needs two 8-bit bytes to represent any number between 0 and 65535. One
eight-bit byte can only represent numbers between 0 and 255. Your computer needs a
way to represent numbers as large as 65535 in order to address all the memory
locations.
Here's how your computer represents the largest number in one 8-bit byte. The
computer stores it as a binary number. You usually represent it as a hexadecimal number
in your machine-language programs. Figure 5-3 shows the relationship between binary,
hexadecimal and decimal numbers.

BINARY

HEXADECIMAL

DECIMAL

1 eight-bit Byte = 1 1 1 1 1 1 1 1

$FF

255

Figure 5-3. Comparison of N u m b e r Systems

A byte contains eight binary digits (bits). Each bit can have a value of 0 or 1. The
largest number your computer can represent in eight binary digits is 1 1 1 1 1 1 1 1,
which equals 255 in decimal. This means all eight bits are set, or equal to 1. A
bit is considered off if it is equal to 0. In converting binary to decimal, all the binary
digits that are set are equal to 2 raised to the power of the bit position. The bit
positions are labeled 0 through 7 from right to left. Figure 5^4 provides a visual
representation of converting binary to decimal.

27

26

25

24

One binary byte


=
1
1
1
1
The byte in decimal = 128 + 64 4- 32 + 16 +
Figure 5-4. Binary/Decimal Conversion

23

22

21

1
8 +

1
4 +

1
2 +

1
1 = 255

133

134

COMMODORE 128

The top of each column represents the value of 2 raised to the power of the bit
position. Since each bit is turned on when you represent the largest number in one byte,
add all the values at the bottom of each to obtain the decimal equivalent. Figure 5-5
shows another example that converts the binary number 1 1 0 0 1 0 1 0 to decimal.

27

26

25

One binary byte


=
1
1
The byte in decimal = 128 + 64 +

24

23

0
0
1
0 4- 0 4- 8 +

22

21

0
0 +

1
2 +

0
0 = 202

Figure 5-5. Binary/Decimal Conversion

Remember, only add the values of two raised to the bit position if the bit is set.
If a bit is off, it equals zero.
Now that you can convert one byte from binary to decimal, you are probably
wondering what this has to do with 16-bit addressing. We mentioned before that the
program counterthe register responsible for storing the address of the next instruction
to be executedis 16 bits wide. This means it uses two bytes side-by-side to calculate
the address.
You just learned about the low byte, the lower half of the 16 bits used to represent
an address. The upper half of the 16-bit address is called the high byte. The high byte
calculates the upper half of the address the same way as the low byte, except the bit
position numbers are labeled from 8 on the right to 15 on the left. When you raise 2 to
the power of these bit positions, and add the resulting values to the low byte of the
address, you arrive at addresses that go up to 65535. This allows your computer
to represent any number between 0 and 65535, and address any memory location
within each 64K RAM bank. Figure 5 - 6 is an illustration of a 16-bit address in
decimal:

High Byte
One binary byte =
The byte in
decimal

215

214

213

212

211

210

29

28

=32768 + 16384+ 8192 + 4096 + 2048 + 1024 + 512 + 256 = 65280

Low Byte

27

26

25

24

23

22

21

One binary byte =

The byte in
decimal

= 128 + 64 + 32 + 16 + 8 + 4 + 2 +

Figure 5-6. Example of 16-Bit Address in Decimal

1 =

255-255
65535

MACHINE LANGUAGE O N THE COMMODORE 128

You can see that the highest number of the high byte of the 16-bit address is
65280. And you know that the highest number of the low byte of the 16-bit address
equals 255. Add the highest high-byte and the highest low-byte number (65280 + 255),
to arrive at 65535, the highest address within each of the two 64K RAM banks.
When the microprocessor calculates the address of the next instruction, it looks at
the high byte of the 16-bit program counter. Try to think of the high byte of the address
as just another 8-bit byte. If this was the case, the bit positions would be labeled from 0
on the right through 7 on the left, just like the low byte of the address. Therefore, the
largest number this 8-bit byte can represent again is 255 decimal.
The value in the high byte determines which 256-byte block is accessed. These
256-byte blocks are referred to as pages. The high byte determines the page boundary of
the address, so the high byte is calculated in increments of 256 bytes. The high byte of
the program counter determines which of the possible 256 pages is being addressed. If
you multiply the number of possible pages, 255 by 256 bytes, you realize the highest
page starts at location 65280, decimal, the same number as in the high byte in Figure
5-6. Location 65280 is the highest page boundary addressable.
What if you want to address a memory location that does not lie on a page
boundary? That's where the low byte of the 16-bit address comes in.
The high byte of the program counter represents the 256-byte page boundary.
All addresses between boundaries are represented by the low byte. For example, to
address location 65380 decimal represent the high byte as 255, since 255 times
256 equals 65280. You still have to move 100 addresses higher in memory to location
65380.
The low byte contains the value 100 decimal. The low byte value is added to the
high byte to find the actual, or effective address.
When you look at the memory map of your Commodore 128, you will see
references to the low byte and high byte pointers or vectors to certain machine-language
routines within the operating system or to important system memory locations, like the
start of BASIC.
You can find out the contents of these addresses and where the routines reside in
your Commodore 128's memory by using the PEEK command in BASIC, or the
Memory command in the Machine Language Monitor. To find the effective address
using BASIC, look in the memory map for the reference to a specific routine or system
function, sometimes called a vector. PEEK the high byte, the page number of the
routine. Multiply by 256 to find the page boundary. Then PEEK the low byte and add it
to the page boundary to arrive at the effective decimal address.
Keep in mind that all the address calculations are performed in binary. They are
explained in decimal so they're easier to understand. In your machine language programs, you will usually reference memory in hexadecimal notation, explained in the
next section.

135

136

COMMODORE 128

HEXADECIMAL NOTATION
Your 8502 microprocessor only understands the binary digits 0 and 1. Although machine
language usually requires hexadecimal notation and BASIC processes decimal numbers,
those numbers are translated and processed as binary numbers. Your computer uses
three different number systems, binary (base 2), hexadecimal (base 16) and decimal
(base 10). The machine-language monitor also uses the octal number base. A number
base is also referred to as a radix; therefore, the C128 uses four radices, but the
microprocessor only understands binary at machine level.
BASIC understands decimal numbers because they are easiest for people to use.
Although BASIC doesn't process as fast as machine language, the ease of use makes up
for the loss of speed.
Machine language uses hexadecimal notation because it is closer to the binary
number system and easier to translate than decimal. Hexadecimal representation is also
used usually by machine-level programmers because it is easier for people to think of a
group of eight binary digits (a whole byte) than it is to think of them as separate digits
by themselves. How do you find it easier to represent this value:
3A (hexadecimal), or as 00111010 (binary)?
Once values are translated from the higher level language into a form that the
microprocessor can understand (binary digits or bits), they are interpreted as electronic
switches by the internal circuitry. The switches determine if an electronic impulse will
be transmitted by the integrated circuit (I.C.) to perform a specific function, such as
addressing a memory location. If the bit equals 1, the switch is interpreted as on, which
sends a voltage level (approximately 3 to 5 volts) through the I.C. If the binary digit is
equal to 0, no voltage is transmitted. Though this is a simplified illustration, you get an
idea of how the microcomputer system can translate, process and perform the instructions you give to your computer. The hardware and software merge here, at machine
level.

UNDERSTANDING HEXADECIMAL
(HEX) N O T A T I O N
The key behind understanding hexadecimal (base 16) numbers is to forget about decimal
(base 10). Hexadecimal digits are labeled from 0 through 9 and continuing with A
through F, where F equals 15 in decimal. By convention, hexadecimal numbers are
written with a dollar sign preceding the value so that they can be distinguished from
decimal values. Figure 5 - 7 provides a table of the hexadecimal digits and their decimal
and binary equivalents:

MACHINE LANGUAGE O N THE COMMODORE 128

HEXADECIMAL

$0
$1
$2
$3
$4
$5
$6
$7
$8
$9
$A
$B
$C
$D
$E
$F

DECIMAL

0
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15

BINARY

0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111

Figure 5-7. Hexadecimal/Decimal/Binary Conversion

Each hex digit represents four bits. The highest number you can represent with
four bits is 15 decimal. In machine language, you usually represent operands and
addresses as two or four hex digits. Since each hex digit of a four-digit hexadecimal
address takes up four bits, four of them represent 16 bits for addressing.
At first you'll find yourself converting decimal addresses and operands into
hexadecimal. Then you'll want to convert the other way. See the HEX$ and DEC
functions for quick and easy decimal to HEX conversions. In the machine language
monitor, use the ( + ) plus sign to represent decimal numbers. Use the conversions for
now, but eventually you should find yourself thinking hexadecimal notation instead of
always converting from decimal to hexadecimal.

ADDRESSING MODES IN
THE COMMODORE 128
Addressing is the process by which the microprocessor references memory. The 8502
microprocessor has many ways to address the internal locations in memory. The
different addressing modes require either one, two or three bytes of storage depending
on the instruction. Each instruction has a different version and op-code. For example,
LDA (LoaD the Accumulator) has eight versions, each with a different op-code to
specify the various addressing modes. See the 8502 Instruction and Addressing Table
section for the different versions of all the 8502 machine-language instructions.

137

138

COMMODORE 128

ACCUMULATOR ADDRESSING
Accumulator addressing implies that the specified operation code operates on the
accumulator. The operand field is omitted since the instruction can only perform the
operation on the accumulator. Accumulator instructions require only one byte of storage. Here are some examples of accumulator addressing instructions:

INSTRUCTION

HEX OPCODE

MEANING

ASL
LSR
ROR

$0A
$4A
$6A

Shift one bit left


Shift one bit right
Rotate one bit right

IMMEDIATE ADDRESSING
Immediate addressing specifies that the operand be a constant value rather than the
contents of a particular address. The operand is the data, not a pointer to the data. At
machine level, the microprocessor actually interprets an operand field constant
and an address in the operand field as two different op-codes, so the pound sign gives
the programmer a way to distinguish between the data and a pointer to the data.
Immediate addressing instructions require two bytes of storage. Here are some immediate addressing instruction examples:

INSTRUCTION

HEX OPCODE

MEANING

LDA #$0F

$A9

Load the accumulator with 15 ($0F)

CMP #$FF

$C9

Compare the accumulator with 255 ($FF)

SBC #$E0

$E9

Subtract 224 ($E0) from accumulator

ABSOLUTE ADDRESSING
Absolute addressing allows you to access any of the memory locations within either 64K
RAM bank. Absolute addressing requires three bytes of storage; the first byte for the
op-code, the second for the low byte of the address and the third for the high byte. Here
are some examples of absolute addressing instructions:

M A C H I N E L A N G U A G E O N T H E C O M M O D O R E 128

INSTRUCTION

HEX OPCODE

INC $4FFC

$EE

Increment the contents of address $4FFC by 1

LDX $200C

$AE

Load the X register with the contents of address


$200C

JSR $FFC3

$20

Jump to location $FFC3 and save the return address

MEANING

ZERO-PAGE ADDRESSING
Zero-page addressing requires two bytes of storage; the first byte is used for the opcode
and the second for the zero-page address. Since zero page ranges from addresses 0
through 255, the computer only needs the low byte to represent the actual address. The
high byte is assumed to be 0; therefore, it is not specified. When addressing a zero-page
location, you can still use absolute addressing; however, the execution time is not as fast
as zero-page addressing. Here are some examples:

INSTRUCTION

HEX OPCODE

MEANING

LDA $FF

$A5

Load the accumulator with the contents of zero-page


location $FF (255)

ORA $E4

$05

OR the accumulator with the contents of location


$E4

ROR $0F

$66

Rotate the contents of location $0F one bit to the


right

IMPLIED ADDRESSING
In implied addressing mode, no operand is specified because the op-code suggests the
action to be taken. Since no address or operand is specified, an implied instruction
requires only one byte for the op-code. Some examples are:

INSTRUCTION

HEX OPCODE

MEANING

DEX

$CA

Decrement the contents of the X register

INY

$C8

Increment the contents of the Y register

RTS

$60

Return from Subroutine

139

140

COMMODORE 128

RELATIVE ADDRESSING
Relative addressing is used exclusively with branch instructions. The branch instructions
(BEQ, BNE, BCC, etc.) allow you to alter the execution path depending on a particular
condition. Branch instructions are similar to IF . . . THEN statements in BASIC since
they both conditionally perform a specified set of instructions.
The operand in the branch instruction determines the destination of the conditional
branch. For example, the op-code BEQ stands for Branch on result EQual to zero. If the
zero flag in the status register is equal to 1 add the operand to the program counter and
continue execution at this new address. Figure 5 - 8 provides an example in symbolic
assembly language.

START

LDA #$01
STA TEMP
DEC TEMP
BEQ START
LDX #$01
STA COUNT
(A)

.01800 A9 01
.01802 85 FA
.01804 C6 FA
.01806 F0 FC
.01808 A2 01
.0180A 85 FB
(B)

LDA #$01
STA $FA
DEC $FA
BEQ $1804
LDX #$01
STA $FB
(C)

*NOTE: The machine language monitor does not provide for


symbolic addresses and labels like TEMP and START.

Figure 5-8. Relative Addressing

Figure 5 - 8 lists the (A) code on the left as it appears in symbolic assembly
language. The code (B) in the middle is the actual machine-level machine code
as it appears in the machine language monitor. The (C) code to the right is the symbolic
machine language as it appears in the monitor as executable code.
In this program segment, the first instruction LoaDs the Accumulator with 1.
STA is the op-code for STore the contents of the Accumulator in the variable
TEMP. The third instruction, DEC, decrements the contents of the variable TEMP. In
the third instruction, START is a label which marks the beginning of the conditional
loop. The branch instruction (BEQ) checks to see if the value stored in TEMP equals
0 as a result of the DECrement instruction. The instruction marks the end of the
loop.
The first time through this loop, the result in TEMP equals 0 so program control
branches back to the instruction specified by the label START.
The second time through the loop, TEMP is less than zero; therefore, the zero
flag in the status register is cleared, the program does not branch to START and
continues with the statement directly following the branch instruction (LDX #$01).

MACHINE LANGUAGE O N THE COMMODORE 128

Because of the way this program segment is written, a branch can occur only once, the
first time through the loop.
Under relative addressing, the first byte of the instruction is the op-code and the
second is the operand, representing an offset of a number of memory locations. The
location to branch back to is not interpreted as an absolute address but an offset relative to
the location of the branch instruction in memory.
The offset ranges from - 1 2 8 through 127. If the condition of the branch is met,
the offset is added to the program counter and the program branches to the address in
memory.
In the example in Figure 5 - 8 , notice that the operand in the branch instruction is
only one instruction past the label START. The operand START is interpreted by the
computer as an offset of three bytes backward in memory since the DEC instruction use
2 bytes and the BEQ op-code uses one byte. The 8502 can only branch forward 127
bytes and branch backward by 128 bytes.
If you enter the machine-language monitor and disassemble the machine-language
code, you'll see how the computer represents a branch instruction operand as in part (B)
of Figure 5-8. The symbolic code in part (C) operand field represents the operands as
absolute addresses but the assembled hexadecimal code to the left in part (B) of the op
code stores the operand using one byte, a number plus or minus the address of the
branch instruction. The largest number for a forward branch is $7F. A backward branch
is represented by hex numbers greater than $80. When you are within the machinelanguage monitor, subtract the operand offset from 255 ($FF) to find the actual value of
the negative offset. In this case $FF minus 3 equals $FC, which is the operand in the
branch instruction in part (B) of Figure 5-8.
Here are some examples of relative addressing branch instructions:

INSTRUCTION

HEX OP-CODE

MEANING

BEQ

$F0

Branch on result Equal to 0

BNE

$D0

Branch on result Not Equal to 0

BCC

$90

Branch on Carry Clear

INDEXED ADDRESSING MODES


The Commodore 128 has two special-purpose registers: the X and Y index registers.
In indexing addressing modes, index registers modify an address by adding their
contents to a base address to arrive at the actual or effective address. For example,
here's a program segment that illustrates the importance of address modification, using
the X and Y index registers:

141

142

C O M M O D O R E 128

LDA
LDX
LOOP STA
INX
BNE

#$0F
#$00
$2000,X
LOOP

The first instruction in this program loads the accumulator with $0F(15 decimal).
The second instruction loads the X register with 0. The third instruction stores the
contents of the accumulator into the address $2000 added to the contents of the X index
register. The first time the loop cycles, $0F is stored in address $2000 ($2000 4- 0 =
$2000). The next instruction (lNX) increments the contents of the X register. The last
instruction in the loop branches to the statement specified by the label LOOP, which is
the STA $2000, X instruction. The second time through the loop, $0F is stored in
location $2001 ($2000 + 1). The third cycle ofthe loop stores $0F in location $2002, etc.
The loop continues to cycle and stores $0F in consecutive locations until the X
register equals 0. In other words, the loop circulates 256 times until the X register
equals 0, since 255 plus 1 is represented as 0. This is because the extra bit is carried
over to the ninth bit position, which doesn't exist in an eight-bit number, so the register
is reset to zero. This is similar to when your car odometer is set at 99,999 miles. When
you travel another mile the dial resets to 00,000.
This example shows just one way to modify addresses with the index registers.
The Commodore 128 has four indexed addressing modes: (1) indexed absolute addressing (illustrated in the example just shown), (2) indexed zero-page addressing, (3)
indexed indirect addressing, and (4) indirect indexed addressing.

INDEXED ZERO-PAGE ADDRESSING


This type of addressing is similar to zero-page addressing except that the index registers
(X or Y) are used to modify addresses within page zero ($00 to $FF) of memory. Since
zero-page addressing requires no high byte to represent the page number, this type of
instruction requires only two bytes of memory. The effective (actual) address is calculated by adding the contents of the index register to the low byte of the address in the
program counter. This addressing mode is faster and more efficient than using indexed
absolute addressing in zero page.
Here are some examples of indexed zero-page addressing instructions:

INSTRUCTION

HEX OP-CODE

MEANING

INC operand, X

$F6

Increment the contents of memory by 1.


The base address (the operand) is added to the
contents of the index register (X)).

CMP operand,X

$D5

Compare the contents of the accumulator with


memory. The memory base address (the operand) is added to the contents of the index register
(X)).

MACHINE LANGUAGE O N THE COMMODORE 128

INDEXED ABSOLUTE ADDRESSING


Indexed absolute addressing allows you to access and modify any of the memory
locations in each of the two 64K banks. The effective address is calculated by adding
the contents of the index register (X or Y) to the high and low byte base address
determined by the operand. Since absolute addressing can access any of the available
memory locations, high and low bytes are required to form the 16-bit address. Therefore, this type of addressing requires three bytes.
Here are some examples of indexed absolute addressing instructions:

INSTRUCTION

HEX OP-CODE

MEANING

AND operand,Y

$39

Perform the logical AND operation on the


accumulator and the contents of memory base
address plus the contents of the register (Y).

ASL operand,X

$lE

Shift the contents of the memory (the memory


is the base address (the operand) added to the
contents of the index register (X)) one bit to the
left.

THE INDIRECT ADDRESSING CONCEPT


So far you've learned that the computer calculates the effective address as the
base address (in the program counter) plus the offset from the contents of the index
registers if indexed addressing is used. Indirect addressing calculates the effective
address differently.
Think of indirect addressing as the address of an address. Here's an illustration
using absolute indirect addressing:
JMP ($0326)
The above JuMP instruction is an example of absolute indirect addressing. This
type of instruction requires three bytes: one for the op-code, one for the low byte and
one byte for the high byte of the 16-bit address. The parentheses indicate that indirect
addressing is used. The second and third bytes of the JMP instruction specify the low and
high byte of the address. The address in the operand field is only the low byte of the effective
address. The contents of the byte immediately following the address specified in the JMP
instruction is automatically placed into the program counter as the high byte of the effective
address. In this example, the contents of location $0326 and $0327 represent the address of
the actual instructions to be executed. For example, location $0326, the low byte of
the effective address, contains the value $65 and location $0327, the high byte of the
effective address, contains the value $F2. The high- and low-byte values are placed in

143

144

COMMODORE 128

the program counter as the address $F265, the actual address of the next instruction
the computer executes then is $F265.
lf the parentheses were not present, the assembler interprets the instruction
as an absolute addressing instruction. The computer would understand the low
byte to be $26 and the high byte to be $03 and would JuMP to the instruction
located at $0326 instead of the intended address of $F265. Since this is not the
case, the high byte is automatically presumed to be the low byte address plus 1
(the contents of $0327).
The last two addressing modes, indirect indexed and indexed indirect, use the
same principle as absolute indirect addressing. Here's an explanation of each.

INDEXED INDIRECT ADDRESSING


Indexed indirect addressing is similar to absolute indirect, although it uses index
registers to modify an address. This type of addressing, sometimes called indirect X
addressing, requires two bytes of storage: the first byte is for the op-code and the second
is for the operand which is used in the effective address calculation. The address
specified in the second byte is added to the contents of the X register and the carry, if
any, is ignored. The results point to an address in page zero in which its contents
contain the low byte of the effective address. The zero page address plus 1 indicates the
high byte of the effective address. Both locations in which the low and high bytes of the
effective address are contained must be located in page zero, locations $00 through $FF.
Here's an example:
LDX # $ 0 4
LDA # $ 0 0
STA ($DF,X)
The first line loads the X register with $04. Next, the accumulator is loaded with
0. The third instruction stores zero in the effective address. Calculate the effective
address by taking the base address $DF (not the contents of it) and add the contents of
the X register ($04) to it, which equals $E3. The contents of location $E3 is the low
byte of the effective address and the contents of $E4 is the high byte of the effective
address. For example, the contents of address $E3 contain $56 and the contents of
address $E4 contain $F3. Since the contents of $E3 is the low byte and the contents of
$E4 is the high byte, the effective address is $F356. Indexed indirect addressing is
referred to as pre-indexing because the indexing occurs before the effective address is
actually obtained. Indirect X addressing is useful in addressing a series of pointers such
as the zero-page memory of the Commodore 128.

INDIRECT INDEXED ADDRESSING


This mode, also called indirect Y addressing, is post-indexed, which means the adding
of the index itself obtains the effective address. This mode operates on the principle of a
base address and a displacement. Here's how it works.
The first of two bytes is the op-code, the second is the operand, a pointer to a

MACHINE LANGUAGE O N THE COMMODORE 128

zero-page memory address. The contents of the pointer and the contents of the Y
register are added to arrive at the low byte of the effective address. The contents of the
pointer act as the base address and the contents of the Y register act as the displacement.
The carry, if any, is added to the memory location directly following the low-byte
address which becomes the high byte of the effective address. This is true indexing,
designed specifically for manipulating tables of data. In order to access different table
values, just change the contents of the Y register since the base address is already
established. Here's an example:
LDY # $ 0 8
LDA # $ 0 0
STA ($EA),Y
The first instruction loads the Y register with $08. The second instruction loads
the accumulator with 0. The third instruction stores the contents of the accumulator in
the effective address.
To find the effective address, add the contents of the zero page memory location
(base address) specified in the instruction to the contents of the Y register (displacement). In this example, the contents of the address $EA equals $F0. Add $F0 to the
contents of the Y register ($08) to arrive at $F8, the low byte of the effective address of
the next instruction. The high byte of the effective address is obtained by adding the
carry (none in this case) to the zero-page memory location immediately following the
low-byte address. For example, location $F9 contains the value $3F. Since the low byte
is $F8 and the high byte equals $3F, the effective address is $3FF8.
Notice the difference between indirect indexed and indexed indirect addressing
modes as they can be confusing. Remember, the most important difference between the
two addressing modes is the way the effective address is calculated. Indexed indirect is
X indexing, which is indexed prior to the arrival of the effective address. Indirect
indexed is post-indexed with the Y register.
You havejust covered all the addressing modes in the Commodore 128. Each calls
for different circumstances and you should use the correct mode whenever circumstances dictate it to obtain optimal performance from the microprocessor. For example,
use indexed zero-page addressing when you are manipulating zero-page locations instead of using indexed absolute.

TYPES OF INSTRUCTIONS
This section explains all the types of machine-language instructions available in the
Commodore 128. They are first covered by type of instruction, such as REGISTER TO
MEMORY and COMPARE instructions; then they are listed alphabetically by op-code
mnemonic with all the different addressing options. This section provides important
information on programming in machine language on the Commodore 128 (or any
6502-based microcomputer).

145

146

COMMODORE 128

Use this information as a reference for background on each instruction. Figure 5 - 9


provides an alphabetized list of the 8502 microprocessor op-code mnemonics. For
detailed, quick-reference information, see the following section for an alphabetic list of
instructions, their hexadecimal op-codes, the different versions of the instructions for
each addressing mode and the way they affect the flags in the status register.

8502 MICROPROCESSOR INSTRUCTION S E T ALPHABETIC SEQUENCE

ADC
AND
ASL

Add Memory to Accumulator with Carry


"AND" Memory with Accumulator
Shift Left One Bit (Memory or Accumulator)

BCC
BCS
BEQ
BIT
BMI
BNE
BPL
BRK
BVC
BVS

Branch on Carry Clear


Branch on Carry Set
Branch on Result Zero
Test Bits in Memory with Accumulator
Branch on Result Minus
Branch on Result not Zero
Branch on Result Plus
Force Break
Branch on Overflow Clear
Branch on Overflow Set

CLC
CLD
CLI
CLV
CMP
CPX
CPY

Clear Carry Flag


Clear Decimal Mode
Clear Interrupt Disable Bit
Clear Overflow Flag
Compare Memory and Accumulator
Compare Memory and Index X
Compare Memory and Index Y

DEC
DEX
DEY

Decrement Memory by One


Decrement Index X by One
Decrement Index Y by One

EOR

"Exclusive-Or" Memory with Accumulator

INC
INX
INY

Increment Memory by One


Increment Index X by One
Increment Index Y by One

JMP
JSR

Jump to New Location


Jump to New Location Saving Return Address

LDA
LDX
LDY
LSR

Load Accumulator with Memory


Load Index X with Memory
Load Index Y with Memory
Shift Right One Bit (Memory or Accumulator)

NOP

No Operation

MACHINE LANGUAGE O N THE COMMODORE 128

8502 MICROPROCESSOR INSTRUCTION S E T ALPHABETIC SEQUENCE (cont'd)

ORA

"OR" Memory with Accumulator

PHA
PHP
PLA
PLP

Push Accumulator on Stack


Push Processor Status on Stack
Pull Accumulator from Stack
Pull Processor Status from Stack

ROL
ROR
RTI
RTS

Rotate One Bit Left (Memory or Accumulator)


Rotate One Bit Right (Memory or Accumulator)
Return from Interrupt
Return from Subroutine

SBC
SEC
SED
SEI
STA
STX
STY

Subtract Memory from Accumulator with Borrow


Set Carry Flag
Set Decimal Mode
Set Interrupt Disable Status
Store Accumulator in Memory
Store Index X in Memory
Store Index Y in Memory

TAX
TAY
TSX
TXA
TXS
TYA

Transfer
Transfer
Transfer
Transfer
Transfer
Transfer

Accumulator to Index X
Accumulator to Index Y
Stack Pointer to Index X
Index X to Accumulator
Index X to Stack Pointer
Index Y to Accumulator

Figure 5-9. 8502 Op-Code Mnemonics

REGISTER TO MEMORY
INSTRUCTIONS
The REGISTER TO MEMORY instructions are:
LDA
LDX
LDY

STA
STX
STY

The register to memory instructions either place a value into the accumulator, X
register or Y register from memory, or store a value from a register (A, X, or Y) into a
memory address.

LOADING THE ACCUMULATOR


The first and most common instruction is LDA, LoaD the Accumulator. This places a value
into the accumulator, the most powerful and active register in the microprocessor. The
value is derived from the contents of a memory location or a constant. Here's an example:

147

148

COMMODORE 128

LDA $2000
This instruction loads the contents of the memory location $2000 (8192 decimal)
into the accumulator. The value in the memory location $2000 remains the same. The
value also remains in the accumulator until another value is placed there or another
operation acts upon it.
The previous example is just one of the addressing modes for loading the accumulator. Another form the LDA instruction can take is to load a constant. To load a
constant into the accumulator, you must precede the dollar sign ($) with a pound sign
( # ) . For readability, it's a good idea to place at least one space between the op-code and
the operand but it is not necessary. Here's an example of loading a constant into the
accumulator:
LDA # $ 0 A
This loads the constant $0A (10 decimal) into the accumulator. Remember,
precede a constant with a pound sign, or else the assembler interprets the instruction as
the contents of a memory address.
The LDX and LDY instructions work the same way as the LDA instruction.
Again, you can load a constant or the contents of a memory address into the X and Y
registers. Examples:
LDX # $ 0 A
LDX $2000
LDX # $ F B

STORE: THE OPPOSITE OF LOAD


You know how to place a value into a register, but how do you do the opposite? The
STORE instruction performs the opposite of a load. It places a value from the A
(accumulator), X, or Y registers into a specified memory address. As you learned in the
addressing section, the load, store and most other machine-language instructions have
several versions, depending on the type of addressing used. Here's an example:
STA $FC3E
This stores the contents of the accumulator into memory location $FC3E. The
contents of the accumulator remain the same until another instruction modifies it. The
STX and STY instructions work the same way; they store the contents of the register
into a specified memory address. There is no immediate version or pound sign version
of the store command.

COUNTER INSTRUCTIONS
The COUNTER instructions are
INC
INX
INY

DEC
DEX
DEY

Counter instructions can be used to keep track of or count the number of times an
event occurs. These instructions are used for mathematical manipulations or indexing a

MACHINE LANGUAGE O N THE COMMODORE 128

series of addresses. The counter instruction, INC, increments the contents of a memory
address by a value of 1 each time it is encountered. These instructions are used primarily
within a program loop and in conjunction with a branch instruction. Here's an example
of a loop and how INC keeps track of a number of occurrences of an event:

START

LDX # $ 0 0
TXA
STA $2000,X
INX
BNE START

The first instruction loads a 0 into the X register. The second instruction transfers
the contents of the X register into the accumulator (without erasing the X register).
Instruction three stores the contents of the accumulator (0) into location $2000 the first
time through the loop. The fourth instruction increments the contents of the X register.
The last instruction branches to the instruction specified by the label START, until the
value of the X register equals 0.
This program segment stores 0's in an entire page (256 locations) starting at $2000
and ending at $20FF. When the contents of the X register equals 255 and it is
incremented again, it is reset to 0, since it can only hold an eight-bit number. When this
occurs, the branch is skipped and the program continues with the instruction directly
following the branch instruction.
The INY instruction operates in the same way as INX, since it also only uses
implied addressing. The INC instruction, on the other hand, uses several different
addressing modes including absolute, which uses 16-bit addresses. With the INC
instruction, you can count past the capacity of an 8-bit number, though you must
separate the counter into a high byte and a low byte. For example, the low byte counts
the increments of less than a page and the high byte keeps track of the number of pages.
When low-byte counter is at 255 and is incremented, it is set back to 0. When this
occurs, increment the high-byte counter. To count up to 260 (decimal), the highbyte value equals 1 and the low byte equals 4. Here's an equation to illustrate the point:
(1 * 256) 4- 4 = 260
Here's the machine-language code that does this:

LOOP

LOOP 2

LDA # $ 0 0
STA HIGH
STA LOW
INC LOW
BNE LOOP
INC HIGH
INC LOW
LDA LOW
CMP # $ 0 4
BNE LOOP2

The DECrement instructions operate the same way as the increment instructions.
They are the negative number counterparts of the increment counters.

149

150

COMMODORE 128

COMPARE INSTRUCTIONS
The Commodore 128 has three compare instructions that check the contents of a register
with the contents of memory. A compare operation can be used to determine which
instructions to execute as a result of a conditioned value. The compare instructions are:
CMP
CPX
CPY
The CMP instruction compares the contents of the accumulator with the contents
of the specified address in the instruction. Compare instructions essentially subtract
memory from a register value but change neitherthey just set status flags. CPX
compares the contents of the X register with the specified address. CPY compares the
contents of the Y register with the specified memory location.
All three instructions have versions that will operate in immediate, zero-page and
absolute addressing modes. This means you can compare the contents of a register
(A,X, or Y) with the contents o f a zero-page location, any other address above zero page,
or against a constant. Here's an example:

ONE

LDX
LDA
STA
INX
CPX
BNE

#$00
#$00
$DF,X
#$0A
ONE

The preceding program segment stores 0's in 10 consecutive memory addresses


starting at $DF. The first instruction loads the X register with 0, the second loads 0 into
the accumulator. The third instruction stores 0 in location $DF plus the contents of the X
register. The fourth instruction increments the X register. The fifth instruction compares
the contents of the X index register with the constant $0A (10 decimal). If the contents
of the X register does not equal $0A, the program segment branches back to the store
instruction specified by the label ONE. After the loop cycles ten times, the X register
and the constant $0A are equal. Therefore the processor does not take the branch
and the program continues with the instruction immediately following BNE.
You can compare the value of a register with the contents of an absolute memory
address. Here's the same example as above using the contents of a memory address
instead of a constant:

ONE

LDA
STA
LDX
LDA
STA
INX
CPX
BNE

#$0A
$FB
#$00
#$00
$DF,X
$FB
ONE

MACHINE LANGUAGE O N THE COMMODORE 128

Remember, if you want to compare numbers larger than eight bits can represent
(greater than 255 decimal), you must separate the number into a low byte and a
high byte.
The BIT instruction can also be used for comparisons. See the logical instructions
next.

ARITHMETIC A N D
LOGICAL INSTRUCTIONS
The accumulator is responsible for all mathematical and logical operations performed in
your computer. The mathematical and logical instructions available in machine language are:
ADC
AND
BIT

EOR
ORA
SBC

Here's what each instruction means:


ADCAdd the contents of the specified memory address to the contents of the
accumulator with a carry. It is considered a good programming practice to clear
the carry bit with the CLC instruction before performing any addition. This avoids
adding the carry into the result.
ANDPerform the logical AND operation with the contents of the accumulator and the
contents of the specified memory address.
BITCompare the bits in the specified memory address with those in the accumulator. Bits 6 and 7 are transferred to the status register flags. Bit 7 is transferred to the negative status flag bit and bit 6 is sent to the overflow status flag bit.
EORPerform the exclusive OR operation with the contents of the specified memory
address and the contents of the accumulator.
ORAPerform the logical OR operation with the contents of the specified memory
address and the contents of the accumulator.
SBCSubtract the contents of the specified memory address from the contents of the
accumulator with a borrow. (It is a good practice to set the carry flag before
performing subtraction. This avoids subtracting the borrowed bit from the result.)

ARITHMETIC INSTRUCTIONS
(ADC, SBC)
The addition and subtraction instructions are easy to understand. Here's an example:
CLC
LDA
STA
ADC
SEC
SBC
ADC
STA

#$0A
$FB
#$04
#$06
$FB
$FD

151

152

COMMODORE 128

This program segment essentially performs the following mathematical operation:


(10 + 4 ) - 6 + 10= 18.
The first instruction clears the carry bit. The second instruction loads the accumulator with $0A (10 decimal). The third instruction stores the value in address $FB for
later use. The fourth instruction adds the constant $04 to the value already in the
accumulator. The SBC instruction subtracts the constant $06 from the contents of the
accumulator. The next instruction, ADC $FB, adds the contents of memory location
$FB to the contents of the accumulator. The resulting value (18($12)) of all the
mathematical operations is stored in address $FD.

LOGICAL INSTRUCTIONS
(AND, EOR, A N D ORA)
These instructions operate on the contents of a memory address and a register. The AND
operation is a binary (Boolean) algebra operation having two operands that can result in
one of two values, 0 or 1. The only way an AND operation can result in a 1 is if both
the operands equal 1; otherwise the result is 0. For example, the two operands are the
contents of a specified memory address and the contents of the accumulator. Here's an
illustration of this concept:
Memory address - 10001010
Accumulator
= 11110010
Result of AND

= 10000010

As noted, the result of an AND operation is (true) 1, only if the two operands are
equal to 1; otherwise the result is 0. Notice bit 7 (high-order bit) equals 1 because both
bit 7's in the operands are 1. The only other resulting bit equal to 1 is bit 1, since both bit
l ' s are equal to 1. The rest of the bits are equal to zero since no other bit positions in
both operands are equal to 1. A 1 and a 0 equals 0, as does a 0 and a 0.
The Boolean OR works differently. The general rule is:
If one of the operands equals 1, the resulting Boolean value equals 1.
For example, the two operands are the contents of a specified memory address and
the contents of the accumulator. Each individual bit can be treated as an operand. Here's
an illustration.
Contents of Memory Address = 10101001
Contents of Accumulator
= 10000011
Result of the OR operation

= 10101011

For all the bit positions that equal one in either operand, the resulting value of that
bit position equals 1. The result is 1 if either operand or both operands are equal to 1.
The exclusive OR works similarly to the OR operation, except if both operands
equal 1, the result is zero. This suggests the following general rule:

MACHINE LANGUAGE O N THE COMMODORE 128

If either of the operands equals 1, the resulting Boolean value is 1, except if both
operands are 1, then the result equals 0.
Here's an example using this rule:
Contents of Memory Address = 10101001
Contents of Accumulator
= 10000011
Result of the exclusive OR

= 00101010

In this example, the operands are the same as in the previous OR example. Notice
bits 0 and 7 are now equal to 0 since both operands are equal to 1. All other bit values
remain the same.

BIT
The BIT instruction performs a logical AND operation on the contents of the specified
memory address and the contents of the accumulator, but the resulting value is not
stored in the accumulator. Instead, the zero flag in the status register is set by the result
of the operation. The BIT instruction compares the contents of the accumulator and the
contents of the memory address, bit-for-bit. If the result of the operation of the
accumulator being ANDed by a memory location is 0, then the zero flag (in the status
register) is set to a 1. Otherwise the zero flag is 0.
Your machine language program can then act conditionally depending on the
result of the zero flag in the status register. In addition, bits 7 and 6 from the specified
memory address are moved into the negative-flag and overflow-flag bit positions in the
status register, respectively. These flags can also be used to perform conditional
instructions depending on the value of the flag. For example, the BIT instruction
performs the following:
7
NV
Contents of Memory Address = 10101001
Contents of Accumulator
= 11001101
Result of BIT instruction
(Not stored in accumulator)

10001001

1 0

0
BDIZC
0

Status Register

Since the resulting bit pattern is not 0, the zero flag in the status register is 0.
In addition, bits 7 and 6 are placed in the bit positions of the negative and overflow
flags, respectively, in the status register. Notice the result of the BIT instruction's AND
operation is not stored in the accumulator. The original contents of the accumulator
remain intact. See the following example of 2-bit pattern operands that result in 0 when
ANDed:

153

154

COMMODORE 128

7
NV
Contents of Memory Address = 01111010
Contents of Accumulator
- 10000100
Result of BIT instruction

00001000

0 1

0
BDIZC
1

Status Register

This time the bit patterns result in 0. Therefore, the zero flag in the status register
is set to 1. Bits 7 and 6 are also placed into their respective negative and overflow status
register bit positions from their positions in the memory location.
Now you know how each of the arithmetic and logical instructions operate. The
next section discusses branching instructions. Branching instructions are designed so
you can conditionally execute a certain set of instructions, depending on the result of a
condition. Many times the conditions are contingent on the results of an arithmetic or
logical operation, which affects the flags in the status register. The branching instructions then act according to the flags in the status register.

BRANCHING INSTRUCTIONS
The 8502 microprocessor has many conditional branching instructions. By definition, a
branch temporarily redirects the otherwise sequential execution of program instructions.
It transfers control to a location of a machine-language instruction other than the one
immediately following the branch instruction in memory.
The conditional branch instructions cause the microprocessor to examine a particular flag in the status register. The processor, depending on the value of the tested flag,
either takes the branch and transfers control of the program to another location or skips
the branch and resumes with the instruction immediately following the branch.
Think of a conditional branch as a test. For example, if the condition passes the
test, the program branches or shifts control to an instruction that is not the next
sequential instruction in the computer's memory. If it fails the test, the branch is skipped
and program control resumes with the instruction immediately following the branch
instruction in memory. Remember that program control can also be shifted to an
instruction that is out of sequential order if it fails a test. This means you can transfer
control of the execution of your program depending on the conditions you create. You
may set a condition that branches if the value of a certain flag (operand) is zero.
In another instance, you may set a condition to branch if a specific flag is set
to 1.
The conditional branch instructions available in the 8502 microprocessor are:
BCC
BCS
BEQ
BMI

BNE
BPL
BVC
BVS

Here's what the conditional branch instructions mean. The phrases in parentheses
are the literal translations of the op-code mnemonics. The remainder explains the
meaning behind the op-codes.

MACHINE LANGUAGE O N THE COMMODORE 128

BCC(Branch on Carry Clear) Branch if the Carry flag in the status register equals 0.
BCS(Branch on Carry Set) Branch if the Carry flag in the status register equals 1.
BEQ(Branch on result EQual zero) Branch if the zero flag in the status register equals 1.
BMI(Branch on result Minus) Branch if the negative flag in the status register equals 1.
BNE(Branch on result Not Equal to zero) Branch if the zero flag in the status register
equals 0.
BPL(Branch on result PLus) Branch if the negative flag in the status register equals 0.
BVC(Branch on oVerflow Clear) Branch if the overflow flag in the status register
equals 0.
BVS(Branch on oVerflow Set) Branch if the overflow flag in the status register
equals 1.
As you can see, all branching instructions depend on the value of a flag in the
status register.
Here are some branching examples.
READY.
MONITOR
PC SR AC XR YR SP
; FB000 00 00 00 00 F8

.
.
.
.
.

01828 E6 FA
0182A A5 FA
0182C D0 02
0182E E6 FB
01830 C8

INC
LDA
BNE
INC
INY

$FA
$FA
$1830
$FB

This program segment keeps track of the low and high pointers in $FA and $FB
respectively. The first instruction (INC $FA) increments the low byte address pointer.
Next, the contents of $FA is loaded into the accumulator. The branch instruction (BNE
$1830) evaluates the value of the accumulator. If the value is not equal to zero, the
branch is taken to the instruction located at address $1830 (INY). In this case the high
byte pointer is not yet ready to be incremented, so the INC $FB instruction is skipped. If
the value in the accumulator is equal to zero, the branch is skipped and the high byte
address pointer is incremented.
This is an example of the BPL (Branch on Result Plus) instruction.
READY.
MONITOR
PC SR AC XR YR SP
; FB000 00 00 00 00 F8
.
.
.
.

01858
0185B
0185E
01860

8E
2C
10
8D

00 D6 STX $D600
00 D6 BIT $D600
FB
BPL $185B
01 D6 STA $D601

This example is a routine that checks the update ready status bit for the 8563
address register, and ensures that data is valid before writing a value to an 8563 register.
The first instruction stores the contents of the X register, which was previously loaded

155

156

COMMODORE 128

with an 8563 register number, into the 8563 address register. The BIT instruction places
bit 7 of location $D600 into the negative flag in the 8502 status register. The BPL
instruction branches to the BIT instruction in location $185B as long as the value of the
negative flag is equal to 0. To the 8563 chip, this means the data is not yet valid and
cannot be written to or read from until bit 7 is set. This loop continues until the value of
bit 7 is 1, then it is transferred to the negative flag. The result now becomes negative
so the branch is skipped and control is passed to the next instruction in memory, which
stores the data into the 8563 data register. Refer to Chapter 10, Writing to an 8563
Register for an expanded version of this program.

REGISTER TRANSFER INSTRUCTIONS


Register transfer instructions move a value from one register (A, X, or Y) to another.
This instruction is useful since it only requires one byte of memory and saves the
programmer the trouble of loading the value from one register and storing it in another.
The 8502 microprocessor has the following six register transfer instructions:
TAXTransfer contents of accumulator to X index register
TAYTransfer contents of accumulator to Y index register
TSXTransfer the contents of the stack pointer to X index register
TXATransfer the contents of X index register to the accumulator
TYATransfer the contents of the Y index register to the accumulator
TXSTransfer the contents of the X register to the stack pointer
The TXS and TSX instructions transfer values from the X index register to the
stack pointer and vice versa. This is useful if you need to take a value off the stack
temporarily, in a mathematical operation (for example, to operate on it and then replace
it on the stack). Another use is to take a value off the stack, place it in the X register for
temporary storage, add a new value on the stack, and then place the old value back on
top. This could be the case when you need to sort values in ascending order.

SHIFT A N D ROTATE INSTRUCTIONS


The shift and rotate instructions manipulate the bits of the accumulator or memory.
Following are the shift and rotate instructions used by the 8502 family of microprocessors:
ASLShift the whole byte one bit to the left
LSRShift the whole byte one bit to the right
ROLRotate the whole byte one bit to the left
RORRotate the whole byte one bit to the right

SHIFT INSTRUCTIONS
The shift instructions are useful when evaluating the value of a single bit at a time in a
series of bits that control your program. For example, a joystick read routine is an
example that calls for the shift instruction. Locations $DC00 and $DC01 control the
joystick direction (bits 0-3), and the joystick fire button (bit 4). One way to evaluate
these values is to shift them to the right. This causes the value to be passed to the carry

MACHINE LANGUAGE O N THE COMMODORE 128

flag. If the carry flag is enabled (1), then the joystick is being pushed in the direction
corresponding to that bit. Here is a joystick read routine that uses the LSR instruction to
evaluate the direction of the joystick:
READY.
MONITOR
PC SR AC XR YR SP
; FB000 00 00 00 00 F8

01800
01803
01805
01807
01808
0180A
0180B
0180C
0180E
0180F
01810
01812
01813
01814
01816
01817
01818
0181A
0181C

AD
A0
A2
4A
B0
88
4A
B0
C8
4A
B0
CA
4A
B0
E8
4A
86
84
60

00 DC LDA $DC00
LDY #$00
00
LDX #$00
00
LSR
01
BCS $180B
DEY
LSR
01
BCS $180F
INY
LSR
01
BCS $1813
DEX
LSR
BCS $1817
01
INX
LSR
STX $FA
FA
STY $FB
FB
RTS

ROTATE INSTRUCTIONS
The rotate instructions operate a little differently. Instead of the shifted bit falling into
the carry flag, the bit "falling off the edge" is placed in the carry bit, then the carry bit
is placed at the opposite end of the byte. For example, if the ROR (rotate right)
instruction is specified, each bit is moved one position to the right. Now bit 7 is placed in
the carry bit and the carry bit is rotated around to the left and placed in the bit 7 bit
position. The ROL instruction operates in the same manner, except the rotation is
leftward rather than to the right. See Figure 5-10 to visualize the rotation concept of the
ROR (rotate right) instruction:

Bit Position

Figure 5-10. Concept of ROR (Rotate Right) Instruction

157

158

COMMODORE 128

SET A N D CLEAR INSTRUCTIONS


The set and clear instructions are designed to manipulate the bits (flags) within the status
register and control certain conditions within the microprocessor. These are the set and
clear instructions available in 8502 machine language:
SEC
SED
SEI

Set the Carry Flag


Set Decimal Mode
Set the Interrupt Disable Bit

CLC
CLD
CLI
CLV

Clear
Clear
Clear
Clear

the Carry Flag


Decimal Mode
the Interrupt Disable Bit
the Overflow Flag

Each of these instructions applies to a flag in the status register that controls a
particular microprocessor condition. Notice that each clear instruction has a counterpart
which sets the condition, except for CLV (Clear Overflow Flag). The overflow flag can
be set by the BIT instruction or from the result of a signed mathematical operation
overflowing into the sign bit.
Figure 5-11 shows the 8502 status register:
7
[N | V|

0
| B| p | I | Z |C|

PROCESSOR STATUS REG P"

L**CARRY
1 * TRUE
ZERO
1 = RESULT ZERO
IRQ DISABLE
1 * OISABLE
DECIMAL MODE
1 a TRUE
BRK COMMAND
OVERFLOW

1 TRUE

1 NEG

NEGATIVE

Figure 5-l I. 8502 Status Register

The flags of the status register are set for various reasons. For example, set
decimal mode when you want to perform calculations in binary coded decimal (BCD)
notation rather than hexadecimal. Set the carry flag when you are performing subtraction. Set the interrupt disable bit when you want to prevent interrupts from occurring.
An example of a split screen, smooth scrolling raster interrupt routine is given at the end
of Chapter 8.
The clear instructions operate in the reverse of the set instructions. To make sure
that a carry does not occur during an addition operation, clear the carry flag before

MACHINE LANGUAGE O N THE COMMODORE 128

adding two numbers in the accumulator. To perform mathematical operations in hexadecimal or binary numbers, clear the decimal mode flag so that your calculations are not
mistakenly performed in binary coded decimal. Whenever the result of a signed mathematical operation overflows into the sign bit an overflow error occurs. To correct this,
clear the overflow flag with the CLV op-code.
When a program requires interrupts, first set the interrupt disable bit (SEI) to
prevent interrupts from occurring. At the end of the interrupt initialization routine, issue
the CLI (Clear Interrupt Disable bit) instruction to enable (allow) interrupts to occur.

JUMP A N D RETURN INSTRUCTIONS


JUMP INSTRUCTIONS
The 8502 processor makes use of two jump instructions:
JMPJump to new location
JSRJump to new location Saving the Return address
These instructions both redirect control of the microprocessor to a location other than
the one immediately following it in memory. The first instruction, JMP, is a one-way trip
to the location specified in the operand field, or the contents of it (indirect). For example:
JMP $1800
jumps to location $1800 and executes the instruction contained in that location. This is a
direct jump.
You can also jump indirectly. For example:
JMP ($1800)
jumps to the address specified in the contents of location $1800. For instance, location
$1800 contains the value $FE and location $1801 contains the value $C0. Therefore, the
above instruction jumps to location $C0FE, and not location $1800. Jumping indirectly
is always denoted by parentheses around the address in the operand field, and it means
to jump to the location specified by the CONTENTS OF the address in the operand field.
The JSR instruction calls subroutines and saves the return address to the stack, so
when an RTS instruction is encountered at the end of the subroutine, the microprocessor
knows where to resume processing in the main (calling) program. Program control
resumes with the instruction in memory immediately following the JSR instruction. In
short, JSR is a round trip, while JMP is one way. For example:
. 01804
. 01807

20 58 18 JSR $1858
A2 0C
LDX #$0C

jumps to the subroutine starting at location $1858. The return address is saved on the
stack, so when the RTS instruction is encountered in this subroutine:

IS9

160

COMMODORE 128

01858
0185B
0185E
01860
01863

8E
2C
10
8D
60

00 D6 STX $D600
00 D6 BIT $D600
FB
BPL $185B
01 D6 STA $D601
RTS

the processor resumes with the main program instruction (LDX #$0C) in location $1807.

RETURN INSTRUCTIONS
The 8502 instruction set has two return instructions:
RTIReturn from Interrupt
RTSReturn from Subroutine
The first instruction returns from your interrupt service routine after the interrupt
disable bit is cleared (CL1) and the interrupt occurs. The RT1 is the last instruction in the
interrupt service routine. The interrupt service routine is the series of instructions which
are performed on the occurrence of an interrupt. Refer to Chapter 8, Raster Interrupt
Split Screen Program with Horizontal Scrolling for a working example of an interrupt
service routine.
The RTS instruction is the last instruction in a machine language subroutine called
from BASIC or by the machine language JSR instruction. See the Jump instructions
above for an example.

STACK INSTRUCTIONS
Four stack instructions are included in the 8502 instruction set to manipulate the values
on the stack. These instructions are as follows:
PHAPush accumulator on the stack
PHPPush processor status on the stack
PLAPull accumulator from the stack
PLPPull processor status from the stack
The term push means to place a value on the stack, while pull means to remove
a value from the stack. The only values pushed or pulled on to or off the stack are the
contents of the status register or the accumulator. The manipulation of the stack values
is important to the programmer when processing interrupts. The Raster Interrupt Split
Screen Program with Horizontal Scrolling section in Chapter 8 illustrates the manipulation of the stack values prior to returning from the interrupt.

THE NOP INSTRUCTION


The NOP instruction stands for no operation, lt is often used to add space between
program segments for readability. This instruction is not executable.

MACHINE LANGUAGE O N THE COMMODORE 128

8502 INSTRUCTION AND


ADDRESSING TABLE
The next 16 pages contain the 8502 Instruction and Addressing Table. These are the
conventions used in the table:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.

OP-CODE
Brief definition
Operation notation
Status flags
Flags affected
Addressing Modes
Assembly language form
OP-CODE (in hex)
Number of bytes
Number of instruction cycles

The following notation applies to this summary:


A
X,Y
M
P
S
/
+
A
yI
i
^
<
V
PC
PCH
PCL
OPER
#

Accumulator
Index Registers
Memory
Processor Status Register
Stack Pointer
Change
No Change
Add
Logical AND
Subtract
Logical Exclusive Or
Transfer from Stack
Transfer to Stack
Transfer to
Transfer from
Logical OR
Program Counter
Program Counter High
Program Counter Low
OPERAND
IMMEDIATE ADDRESSING MODE

161

162

COMMODORE 128

ADC

Add memory to accumulator with carry

Operation: A + M + C ^ A, C

N
J

E
J

ADC
C
J

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Immediate
Zero Page
Zero Page, X
Absolute
Absolute, X
Absolute, Y
(Indirect, X)
(Indirect), Y

ADC
ADC
ADC
ADC
ADC
ADC
ADC
ADC

69
65
75
6D
7D
79
61
71

2
2
2
3
3
3
2
2

2
3
4
4
4*
4*
6
5*

# Oper
Oper
Oper, X
Oper
Oper, X
Oper, Y
(Oper, X)
(Oper), Y

I
-

D
-

V
J

* Add 1 if page boundary is crossed.

AND

" A N D " memory

AND

with accumulator

Logical AND to the accumulator


Operation: A AM ^ A

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Immediate
Zero Page
Zero Page, X
Absolute
Absolute, X
Absolute, Y
(Indirect, X)
(Indirect), Y

AND
AND
AND
AND
AND
AND
AND
AND

29
25
35
2D
3D
39
21
31

2
2
2
3
3
3
2
2

2
3
4
4
4*
4*

# Oper
Oper
Oper, X
Oper
Oper, X
Oper, Y
(Oper, X)
(Oper), Y

* Add 1 if page boundary is crossed.

6
5

M A C H I N E L A N G U A G E O N T H E C O M M O D O R E 128

ASL

ASL Shift Left One Bit (Memory or Accumulator)

Operation: C

7 6 5 4 3 2 10

Z
J

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Accumulator
Zero Page
Zero Page, X
Absolute
Absolute, X

ASL
ASL
ASL
ASL
ASL

0A
06
16
0E
lE

1
2
2
3
3

2
5
6
6
7

BCC

A
Oper
Oper, X
Oper
Oper, X

ASL
I

BCC Branch on Carry Clear

Operation: Branch on C = 0

BCC
N

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Relative

BCC

90

2*

Oper

Add 1 if branch occurs to same page.


Add 2 if branch occurs to different page.

BCS

BCS Branch on carry set

Operation: Branch on C = 1

BCS
N

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Relative

BCS

B0

2*

Oper

* Add 1 if branch occurs to same page.


* Add 2 if branch occurs todifferentpage.

163

164

C O M M O D O R E 128

BEQ

BEQ

BEQ Branch on result zero

Operation: Branch on Z = 1

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Relative

BEQ

F0

2*

Oper

* Add 1 if branch occurs to same page.


* Add 2 if branch occurs to next page.

BIT

BIT

BIT Test bits in memory with accumulator

Operation: A A M, M7 ^ N, M6 ^ V
Bit 6 and 7 are transferred to the status register.
If the result of AAM is zero then Z = 1, otherwise
Z =0

N Z
M7 /

C
-

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Zero Page
Absolute

BIT
BIT

24
2C

2
3

3
4

BMI

Oper
Oper

I
-

D
-

V
M6

BMI

BMI Branch on result minus

Operation: Branch on N = 1

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Relative

BMI

30

2*

Oper

* Add 1 if branch occurs to same page.


* Add 2 if branch occurs to different page.

BNE

BNE

BNE Branch on result not zero


N

Operation: Branch on Z = 0

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Relative

BNE

D0

2*

Oper

* Add 1 if branch occurs to same page.


* Add 2 if branch occurs to different page.

M A C H I N E L A N G U A G E O N T H E C O M M O D O R E 128

BPL

BPL

BPL Branch on result plus

Operation: Branch on N = 0

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Relative

BPL Oper

10

2*

* Add 1 if branch occurs to same page.


* Add 2 if branch occurs to different page.

BRK

BRK

BRK Force Break

Operation: Forced Interrupt PC + 2 | P j

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

BRK

00

1. A BRK command cannot be masked by setting I.

BVC

BVC

BVC Branch on overflow clear

Operation: Branch on V = 0

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Relative

BVC

50

2*

Oper

* Add 1 if branch occurs to same page.


* Add 2 if branch occurs to different page.

BVS

BVS

BVS Branch on overflow set

Operation: Branch on V = 1

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Relative

BVS

70

2*

Oper

* Add 1 if branch occurs to same page.


* Add 2 if branch occurs to different page.

165

166

COMMODORE 128

CLC

CLC Clear carry flag

CLC
N
-

Operation: 0

Z
-

C
0

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

CLC

18

CLD

I
-

CLD

CLD Clear decimal mode

Operation: 0 ~> D

N
-

Z
-

C
-

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

CLD

D8

CLI

I
-

V
-

CL/ Clear interrupt disable bit

Operation: 0 ^ I

CLI

N
-

Z
-

C
-

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

CLI

58

CLV

I
0

D
-

V
-

CLV Clear overflow flag

Operation: 0 ^ V

CLV
N

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

CLV

B8

D
-

V
0

MACHINE LANGUAGE O N THE COMMODORE 128

CMP

CMP

CMP Compare memory and accumulator

Operation: A - M

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Immediate
Zero Page
Zero Page, X
Absolute
Absolute, X
Absolute, Y
(Indirect, X)
(Indirect), Y

CMP
CMP
CMP
CMP
CMP
CMP
CMP
CMP

C9
C5
D5
CD
DD
D9
C1
D1

2
2
2
3
3
3
2
2

2
3
4
4
4*
4*
6
5*

#Oper
Oper
Oper, X
Oper
Oper, X
Oper, Y
(Oper, X)
(Oper), Y

* Add 1 if page boundary is crossed.

CPX

CPX

CPX Compare Memory and Index X

Operation: X - M

v/

v /

v /

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Immediate
Zero Page
Absolute

CPX
CPX
CPX

E0
E4
EC

2
2
3

2
3
4

CPY

#Oper
Oper
Oper

V
-

CPY

CPY Compare memory and index Y

Operation: Y - M

N
J

Z
j

C
y

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Immediate
Zero Page
Absolute

CPY
CPY
CPY

CO
C4
CC

2
2
3

2
3
4

#Oper
Oper
Oper

167

168

COMMODORE 128

DEC

DEC

DEC Decrement memory by one

Operation: M - 1 ^ M

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Zero Page
Zero Page, X
Absolute
Absolute, X

DEC
DEC
DEC
DEC

C6
D6
CE
DE

2
2
3
3

5
6
6
7

DEX

Oper
Oper, X
Oper
Oper, X

DEX Decrement index X by one

Operation: X - 1 ^ X

DEX

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

DEX

CA

DEY

DEY

DEY Decrement index Y by one

Operation: Y - 1 ^ Y

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

DEY

88

EOR

D V

EOR

EOR "ExclusiveOr" memory with accumulator

Operation : A ^ M ^ A

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Immediate
Zero Page
Zero Page, X
Absolute
Absolute, X
Absolute, Y
(Indirect, X)
(Indirect), Y

EOR
EOR
EOR
EOR
EOR
EOR
EOR
EOR

49
45
55
4D
5D
59
41
51

2
2
2
3
3
3
2
2

2
3
4
4
4*
4*
6
5*

#Oper
Oper
Oper, X
Oper
Oper, X
Oper, Y
(Oper, X)
(Oper), Y

* Add 1whenpage boundary is crossed.

MACHINE LANGUAGE O N THE COMMODORE 128

/NC Increment memory by one

INC

Operation: M + 1

INC
C

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Zero Page
Zero Page, X
Absolute
Absolute, X

INC
INC
INC
INC

E6
F6
EE
FE

2
2
3
3

INX

Oper
Oper, X
Oper
Oper, X

INX

INX Increment Index X by one

Operation: X + 1 ^ X

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

INX

E8

INY

INY

INY Increment Index Y by one

Operation: Y + 1 ^ Y

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

INY

C8

JMP

JMP

JMP Jump to new location

Operation: (PC + 1) ^ PCL


(PC + 2) ^ PCH

N
-

Z
-

C
-

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Absolute
Indirect

JMP
JMP

4C
6C

3
5

Oper
(Oper)

I
-

D
-

V
-

169

170

C O M M O D O R E 128

JSR

JSR

JSR Jump to new location saving return address

Operation: PC + 2 1 , (PC + 1) ^ PCL


(PC + 2) ^ PCH

N Z
- -

C
-

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Absolute

JSR

20

LDA

Oper

I
-

D
-

V
-

LDA

LDA Load accumulator with memory

Operation: M ~> A

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Immediate
Zero Page
Zero Page, X
Absolute
Absolute, X
Absolute, Y
(Indirect, X)
(Indirect), Y

LDA
LDA
LDA
LDA
LDA
LDA
LDA
LDA

A9
A5
B5
AD
BD
B9
A1
B1

2
2
2
3
3
3
2
2

2
3
4
4
4*
4*
6
5*

#Oper
Oper
Oper, X
Oper
Oper, X
Oper, Y
(Oper, X)
(Oper), Y

D V

* Add 1 if page boundary is crossed.

LDX

LDX

LDX Load index X with memory

Operation: M ^ X

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Immediate
Zero Page
Zero Page, Y
Absolute
Absolute, Y

LDX
LDX
LDX
LDX
LDX

A2
A6
B6
AE
BE

2
2
2
3
3

2
3
4
4
4*

#Oper
Oper
Oper, Y
Oper
Oper, Y

* Add 1 when page boundary is crossed.

D V

MACHINE LANGUAGE O N THE COMMODORE 128

LDY

LDY

LDY Load index Y with memory

Operation: M ^ Y

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Immediate
Zero Page
Zero Page, X
Absolute
Absolute, X

LDY
LDY
LDY
LDY
LDY

AO
A4
B4
AC
BC

2
2
2
3
3

2
3
4
4
4*

#Oper
Oper
Oper, X
Oper
Oper, X

* Add 1 when page boundary is crossed.

LSR

LSR

LSR Shift right one bit (memory or accumulator)

Operation:

|7|6|5l4l3l2lllol ^

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Accumulator
Zero Page
Zero Page, X
Absolute
Absolute, X

LSR A
LSR Oper
LSR Oper, X
LSR Oper
LSR Oper, X

4A
46
56
4E
5E

1
2
2
3
3

2
5
6
6
7

NOP

o / y- - -

NOP No operation

NOP

Operation: No Operation (2 cycles)

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

NOP

EA

171

172

COMMODORE 128

ORA "OR" memory with accumulator

ORA

Operation: A V M

N 2
/

ORA

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Immediate
Zero Page
Zero Page, X
Absolute
Absolute, X
Absolute, Y
(Indirect, X)
(Indirect), Y

ORA
ORA
ORA
ORA
ORA
ORA
ORA
ORA

09
05
15
0D
lD
19
01
11

2
2
2
3
3
3
2
2

2
3
4
4
4*
4*
6
5

#Oper
Oper
Oper, X
Oper
Oper, X
Oper, Y
(Oper, X)
(Oper), Y

* Add 1 on page crossing

PHA Push accumulator on stack

PHA

ation : A |

PHA

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

PHA

48

PHP Push processor status on stack

PHP

Operation: P 1

PHP

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

PHP

08

PLA Pull accumulator from stack

PLA

Operation: A f

PLA

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

PLA

68

MACHINE LANGUAGE O N THE COMMODORE 128

PLP

PLP Pull processor status from stack

PLP

Operation: P f

C I D
From Stack

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

PLP

28

ROL Rotate one bit left (memory or accumulator)

ROL

Operation:

M or A
|7|6|5l4l3|2[l

- & H

Z
J

C
J

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Accumulator
Zero Page
Zero Page, X
Absolute
Absolute, X

ROL A
ROL Oper
ROL Oper, X
ROL Oper
ROL Oper, X

2A
26
36
2E
3E

1
2
2
3
3

2
5
6
6
7

ROL

ROR Rotate one bit right (memory or accumulator)

ROR

Operation: ^C

7_ 6 5_4 3 2 i 0

Z
J

c
/

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Accumulator
Zero Page
Zero Page, X
Absolute
Absolute, X

ROR A
ROR Oper
ROR Oper, X
ROR Oper
ROR Oper,X

6A
66
76
6E
7E

1
2
2
3
3

2
5
6
6
7

ROR

173

174

C O M M O D O R E 128

RTI

RTI

RTI Return from interrupt

Operation: P | PC |

C I D
From Stack

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

RTI

40

RTS

RTS

RTS Return from subroutine

Operation: PC | , PC + 1 ^ PC

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

RTS

60

SBC

SBC Subtract memory from accumulator with borrow

Operation: A - M - C ^ A
Note: C = Borrow

N
/

Z
J

C
/

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Immediate
Zero Page
Zero Page, X
Absolute
Absolute, X
Absolute, Y
(Indirect, X)
(Indirect), Y

SBC
SBC
SBC
SBC
SBC
SBC
SBC
SBC

E9
E5
F5
ED
FD
F9
El
F1

2
2
2
3
3
3
2
2

2
3
4
4
4*
4*

#Oper
Oper
Oper, X
Oper
Oper, X
Oper, Y
(Oper, X)
(Oper), Y

* Add 1 when page boundary is crossed.

6
5*

SBC
I
-

D
-

V
J

MACHINE LANGUAGE O N THE COMMODORE 128

SEC

SEC Set carry flag

SEC

Operation: 1 ^ C

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

SEC

38

SED

SED Set decimal mode

Operation: 1

SED

N X

C
-

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

SED

F8

SEI

I
-

D
1

V
-

SE/ Set interrupt disable status

Operation: 1 ^ I

SEI

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

SEI

78

STA

STA

STA Store accumulator in memory

Operation: A ^ M

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Zero Page
Zero Page, X
Absolute
Absolute, X
Absolute, Y
(Indirect, X)
(Indirect), Y

STA
STA
STA
STA
STA
STA
STA

85
95
8D
9D
99
81
91

2
2
3
3
3
2
2

3
4
4
5
5
6
6

Oper
Oper, X
Oper
Oper, X
Oper, Y
(Oper, X)
(Oper), Y

175

176

COMMODORE 128

STX Store index X in memory

STX

Operation: X ^ M

STX

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Zero Page
Zero Page, Y
Absolute

STX
STX
STX

86
96
8E

2
2
3

Oper
Oper, Y
Oper

D V

4
4

STY Store index Y in memory

STY

Operation: Y ^ M

STY

z c

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Zero Page
Zero Page, X
Absolute

STY
STY
STY

84
94
8C

2
2
3

3
4
4

Oper
Oper, X
Oper

TAX Transfer accumulator to index X

TAX

Operation: A ^ X

N
/

Z
J

TAX

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

TAX

AA

TAY

TAY

TAY Transfer accumulator to index Y

Operation: A ^ Y

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

TAY

A8

M A C H I N E L A N G U A G E O N T H E C O M M O D O R E 128

TSX

TSX

Transfer

stack

pointer

to index

N
y

Operation: S

TSX

Z
j

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

TSX

BA

TXA

TXA

Transfer

index

X to

Z
y

ADDRESSING

ASSEMBLY

OP

NO.

NO.

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

TXA

8A

Transfer

index

X to stack

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

TXS

9A

index

Y to

TXS

ADDRESSING

TYA Transfer

pointer

Operation: X

TYA

TXA

MODE

TXS

accumulator

Operation: X

TXS

accumulator

Operation: Y

N
J

TYA

ADDRESSING

ASSEMBLY

OP

NO.

NO.

MODE

LANGUAGE FORM

CODE

BYTES

CYCLES

Implied

TYA

98

177

178

COMMODORE 128

INSTRUCTION ADDRESSING MODES AND


RELATED EXECUTION TIMES (in clock cycles)

et
O
H
< w
H
5 <J
S 3W
p
u
u<
ADC
AND
ASL
BCC
BCS
BEQ
BIT
BMI
BNE
BPL
BRK
BVC
BVS
CLC
CLD
CLI
CLV
CMP
CPX
CPY
DEC
DEX
DEY
EOR
INC
INX
INY
JMP
JSR
LDA
LDX
LDY
LSR
NOP
ORA
PHA
PHP

.
.
2

.
.
.
.

.
.
.

2
2
.

2
2
2
.

2
.

X >w w
o o

3
3
5

3
3
3
5

3
5

w
H
< < P
&
&
o o o
X X w
W W CQ
<

X
w
H
J5
oCfl
CQ
^t!

4
4
6

4
4
6

4*
4*
7

4
.
.
6

4
6

.
.
.

.
.
.
.

.
.

fcsT
H
3

O
c
CQ

W
>
H
<
W
06

H
U
W

3
z

.
.

6
6

5*
5*

2**
2**
2**

.
.
.

.
.
.

2**
2**
2**

.
.
.

.
.
.

2
2
2
2
.

2**
2**
.
.
.
.
.

.
.
.
.
.
.
6

.
.
.
.
.
.
5*

2
2
.

.
.
.

.
.
6

.
.
5*

2
2

.
.

.
.

.
.

.
.

.
.

6
.

5*
.

2
.
3
3

.
.
.
.

.
6
.
.

.
5*
.
.

4*
4*

.
.

<

4
4
4
6

4
6

.
.
.
2

2
2
2
.

3
3
3
5

4
.
4
6

.
4
.
.

3
6
4
4
4
6

4*

4*

4* 4*
7

4*
.
4*
7

4*
4*

4* 4*

H
u
w

5
z5
w
H

J
oy>

MACHINE LANGUAGE O N THE COMMODORE 128

os
o
H
<
J
P
S
p
u
V

W
O
<
0*
O
X
w
N

<

PLA
PLP
ROL
ROR
RTI
RTS
SBC
SEC
SED
SEI
STA
STX
STY
TAX
TAY
TSX
TXA
TXS
TYA

X
w
o
<
a.
O
x
W
N

>*

w
o
<
co
X
W
N

W
H
J3
oc^
n

<

><

fcd W
H H
U
>

ow oc^
CQ

CQ

<

, ,, , , , ,
2
2

.
.

5
5

. .
. .
2 3
.
, .

6
6

.
.

, .

.
.
.

3 4
3 .
3 4

6
6

.
.

4
4
4

4* 4*

4
4

.
.

6
6

.
.

2
2
2

.
.
.

H
U
W
0*
3

>

Z&

H
U
UJ
0*
5

w
H
o
CQ

<

. .
.

7
7

.
.
4
.

W
Q >
H H
3 <| XW

H
U
w

. .
. .

5*

, ,
2
2
2
2
2
2

.
.
.
.
.
.

* Add one cycle if indexing across page boundary


** Add one cycle if branch is taken. Add one additional if branching
operation crosses page boundary

A clock cycle is the speed at which the processor operates as determined by the
number of bytes transferred from one internal logic component to another. The 8502
operates at a default speed of 1 MHz, which is equivalent to 1,000,000 cycles per
second.

179

6
HOW TO ENTER
MACHINE LANGUAGE
PROGRAMS INTO THE
COMMODORE 128

181

182

COMMODORE 128

Now that you know about addressing modes, types of instructions and opcodes, you
need to know how to actually enter machine language instructions into the Commodore
128 memory. The C128 offers three methods of inputting instructions so that they may
be operated on by the microprocessor. You can enter machine language instructions by:
1.
2.
3.

Using the built-in machine language monitor (available in C128 mode only).
POKEing the translated decimal opcode values into memory with a BASIC
program (C128 and C64 modes).
Using an additional software program called an assembler.

All three methods have advantages and disadvantages. For instance, the built-in
machine language monitor is easy to use and allows you to program in machine
language without any additional aids such as an assembler. It makes merging BASIC
and machine language easy. In addition, you can save machine language programs as
binary files with the monitor SAVE command. Since you are already working in an
object code, there is no need to compile from source code into an object code, as is
necessary with an assembler.
Though these are powerful features, the monitor does not allow the use of symbolic
operand names or commented code. The monitor produces executable (object) code;
hence, no source files are produced. The resulting coded program contains actual
(absolute) address references, whereas an assembler source code file allows the use of
symbolic addresses and arguments as well as comments. When you display a machine
language program in the monitor, you do not have the luxury of comments or symbolic
address variables, so you really have to know what you are looking for when reading
other people's code. On the other hand, an assembler source file must be compiled into
executable object code, then used often with an additional program called a loader. This
requires three steps, whereas the monitor's machine language is ready to run as soon as
you finish writing the program.
The second method, POKEing translated decimal opcode data into memory with a
BASIC program, is an alternative usually implemented only when the first two options
are not available. This is the case if you have no assembler and are writing a machine
language routine in Commodore 64 mode, which does not make the built-in monitor
available to you. However, it is sometimes handy to POKE small routines from
BASIC if the application program you are writing is more suited for BASIC and you
need the speed of machine language for only a small portion of the program (though for
the most part, this method is tedious, bulky and time-consuming). Use it only if you
have no alternative, since once it is POKED into memory, you cannot display a listing
of the machine language routine as in the monitor or the assembler.
This chapter explains how to enter machine language programs in the first two
methods described above. The third method, using an assembler, requires an additional
software package similar to the Commodore 64 Assembler Development System. For
specific details on how to enter machine language programs with the assembler, refer to
the manual that is packed with the assembler software package you buy.

HOW T O ENTER MACHINE LANGUAGE PROGRAMS INTO THE COMMODORE 128

ENTERING MACHINE LANGUAGE


INSTRUCTIONS IN THE MONITOR
Begin entering machine language instructions by entering the monitor from BASIC with
the following command:
MONITOR

RETURN

The Commodore 128 responds with the following display:


MONITOR
PC
SR AC XR YR SP
; FB000 00 00 00 00 F8
These values indicate the contents of the microprocessor registers upon entering
the monitor. The abbreviations and definitions of the register names are as follows:
PCProgram Counter
SRStatus Register
ACAccumulator
XRX Index Register
YRY Index Register
SPStack Pointer

Marks the address of the current machine language


instruction
Flags that alert the microprocessor of certain conditions
Register for all mathematical operations
Used for effective address modification
Same as X register
Indicates the address of the first available memory
location on the stack

Now you can begin to enter machine language instructions. The ASSEMBLE
command within the monitor enters the instructions into the specified memory location.
To enter instructions, follow the format of this example:
A 01800 LDA # $ 0 0
Make sure to leave at least one space between each of the fields. Here's what each
part of the instruction means:
<Assemble>

<Address in memory where opcode is stored>

<Opcode>

<Operand>

The A stands for ASSEMBLE an opcode. The second part (field) is the address
where the opcode in the instruction is placed in the Commodore 128 memory. Notice
the 5-digit hexadecimal number specifying the address. The leftmost digit (0-F) specifies the configuration of the Commodore 128 memory layout. This is the same as the
BANK command in BASIC.
Once the entire machine language program is entered, reference the address that is
contained in the first instruction you entered to start execution of the program. Execute
the program with the GO command in the monitor, or exit the monitor with the X
(EXIT) command and issue the SYS command from BASIC. If you SYS to the start of
the program, you must use the decimal equivalent of the hexadecimal address, which

183

184

COMMODORE 128

appears in the first instruction you entered. You must have an RTS instruction at the end
of the routine if you want to return to BASIC. Often, the Kernal must be resident in the
current configuration in context in order to obtain results.
The opcode is the 8502 instruction that is carried out by the microprocessor when
your program is running. See the 8502 Instruction Set Table in Chapter 5 for allowable
instructions.
The operand is the address or value that is acted upon by the opcode in the
instruction. If the operand field is preceded by a pound sign ( # ) , the opcode will act
upon a constant value. If no pound sign is specified, the microprocessor assumes the
opcode will act upon an address.
Remember to separate each field in the instruction with at least one space. If you
don't, the computer indicates that an error has occurred by displaying a question mark at
the end of the instruction.
Once a routine is displayed on the screen, the monitor allows shortcuts in entering
instructions. To display a listing of a machine language program, issue the DISASSEMBLE command as follows:
D 04000 04010

RET U R N

The " D " stands for disassemble. The first number (04000) specifies the starting
memory location in which you want the contents displayed. The second number
specifies the end address in which to display.
Now for the shortcut. Since the address where the opcodes are stored is already on
the screen, you can simply move the cursor to the opcode field, type over the existing opcode and operand on the screen, erase any unwanted characters and press
R ET U RN
. The computer registers the instruction in memory by displaying the
hexadecimal values for the opcode and operand directly to the left of the opcode
mnemonic you just entered. This is a faster and easier way of entering machinelanguage routines, rather than typing the ASSEMBLE command and the address each
time you enter an instruction.

EXECUTING (RUNNING)
YOUR MACHINE-LANGUAGE PROGRAM
Once you have finished entering your machine language routine, you may execute it in
three different ways. Within the monitor, issue the GO or JUMP to Subroutine command as follows:
GF1800
J F1800

(JMP)
(JSR)

The G stands for GO, or go to the start address of the machine language program
in memory, and begin executing it at the specified address. The value following the
letter G refers to the start address of your routine. The J stands for Jump to Subroutine, similar to the JSR mnemonic in machine language.
The third way to invoke a machine language routine is to exit the monitor by

H O W T O ENTER MACHINE LANGUAGE PROGRAMS I N T O THE COMMODORE 128

pressing the X key and R E T U R N . This places you back within the control of the
BASIC language. Next, issue the SYS command and reference the starting address in
decimal as follows:
BANK 15
SYS 6144
This SYS command is the same as the GO command (G F1800) example above.
The BANK 15 command and the leading F in the 5-digit hexadecimal number F1800
specify memory configuration 15. The Kernal, BASIC and other ROM code are
resident in this configuration. The only difference is that it executes the machine
language routine from BASIC, instead of within the monitor.
The machine language routine given below clears the text screen. Starting at
location 1024 ($0400), the value 32 ($20) is stored in each screen location. The
character string value 32 is the space character, which blanks out each character position
on the screen. When finished, an RTS instruction returns control to BASIC. Here's the
main BASIC program and the machine language screen-clear subroutine as it appears in
the machine language monitor.

10
20
30
40
50
60
70
80
90

FOR 1= 1 TO 2 5
PRINT"FILL THE SCREEN WITH CHARACTERS"
NEXT
PRINT:PRINT
PRINT"NOW CALL THE MACHINE LANGUAGE"
PRINT" ROUTINE TO CLEAR THE SCREEN"
SLEEP 5
SYS DEC("1800")
PRINT"THE SCREEN IS NOW CLEARED"

READY.
MONITOR

PC SR AC XR YR SP
; FB000 00 00 00 00 F8
.
.
.
.
.
.
.
.
.

01800
01802
01804
01807
0180A
0180D
01810
01811
01813

A2
A9
9D
9D
9D
9D
E8
D0
60

00
20
00
00
00
E7
F1

04
05
06
06

LDX
LDA
STA
STA
STA
STA
INX
BNE

#$00
#$20
$ 0 400 , X
$0500,X
$0600,X
$0 6E7,X
$1804

RTS

In this sample program, the SYS command executes the subroutine to clear the
text screen. Once the text screen is cleared, control of the microprocessor is returned to
BASIC by the RTS instruction, and the READY prompt is displayed.

185

186

C O M M O D O R E 128

MACHINE LANGUAGE
MONITOR COMMANDS

The C128's built-in machine language monitor has several additional commands that
manipulate your machine language routines once they are entered into memory. Figure
6 - 1 is a summary of all the commands available to you in the machine language
MONITOR.

FORMAT

KEYWORD

FUNCTION

ASSEMBLE

Assembles a line of 8502 code

COMPARE

Compares two sections of mem- C


ory and reports differences
Disassembles a line or lines of 8502 D
code
Fills a range of memory with spec- F
ified byte
Starts execution at the specified G
address
Hunts through memory within a H
specified range for all occurrences
H
of a set of bytes

DISASSEMBLE
FILL
GO
HUNT

GOSUB
LOAD

Jumps to the subroutine


Loads a file from tape or disk

MEMORY

Displays the hexadecimal values M


of memory locations
Displays the 8502 registers
R
Saves to tape or disk
S

REGISTERS
SAVE

J
L

<start address> <opcode>


[operand]
<start address> <end address>
<new start address>
[<start address> <end address>]
<start address> <end address>
<byte>
[address]
<start address> <end address>
<bytel> [<byte n> . . .]
<start address> <end address>
<ascii string>
[address]
"<fiIename>"[,<device # >
[,<load address>]]
[<start address>
[<end address>]]
"<filename>",<device # > ,
<start address> <last address
i
T

TRANSFER
VERIFY
EXIT
(period)
(greater than)
(semicolon)

Transfers code from one section


of memory to another
Compares memory with tape or
disk
Exits Commodore 128 MONITOR
Assembles a line of 8502 code
Modifies memory
Modifies 8502 register displays

T
V

i \
1^>

<start address> <end address>


<new start address>
"<filename>"[,<device # > [ ,
<load address>]]

X
>
5

[address]

HOW T O ENTER MACHINE LANGUAGE PROGRAMS INTO THE COMMODORE 128

FORMAT

KEYWORD

FUNCTION

(at sign)

Displays disk status, sends disk


command, displays directory
disk status
disk command
disk catalog

@
@[device # ]
@[device #],<command
string>]
@[device #],$[[<drive>:<file
spec>]]

NOTES < > enclose required parameters


[] enclose optional parameters
Figure 6 - 1 . Summary of C o m m o d o r e 128 Monitor Commands

N O T E : 5-Digit Addresses
The Commodore 128 displays 5-digit hexadecimal addresses within the
machine language monitor. Normally, a hexadecimal number is only four
digits, representing the allowable address range. The extra left-most (high
order) digit specifies the BANK configuration (at the time the given
command is executed) according to the following memory configuration
table:
0RAM 0 only
1RAM 1 only
2RAM 2 only
3RAM 3 only
4INT ROM, RAM
5INT ROM, RAM
6INT ROM, RAM
7INT ROM, RAM

0,
1,
2,
3,

I/O
I/O
I/O
I/O

8EXT ROM, RAM 0, I/O


9EXT ROM, RAM 1, I/O
AEXT ROM, RAM 2, I/O
BEXT ROM, RAM 3, I/O
CKERNAL + INT (lo). RAM 0, I/O
DKERNAL + EXT (lo), RAM 1, I/O
EKERNAL + BASIC, RAM 0, CHARROM
FKERNAL + BASIC, RAM 0, I/O

SUMMARY OF MONITOR
FIELD DESCRIPTORS
The following designators precede monitor data fields (e.g., memory dumps). When
encountered as a command, these designators instruct the monitor to alter memory or
register contents using the given data.

>
;

<period> precedes lines of disassembled code.


<right angle> precedes lines of a memory dump.
<semicolon> precedes line of a register dump.

The following designators precede number fields (e.g., address) and specify the radix
(number base) of the value. Entered as commands, these designators instruct the monitor
simply to display the given value in each of the four radices.

187

188

COMMODORE 128

$
+
&
%

< n u l l > (default) precedes hexadecimal values.


<dollar> precedes hexadecimal (base-16) values.
< p l u s > precedes decimal (base-10) values.
<ampersand> precedes octal (base-8) values.
<percent> precedes binary (base-2) values.

The following characters are used by the monitor as field delimiters or line terminators
(unless encountered within an ASCII string).

:
?

< s p a c e > delimiterseparates two fields,


< c o m m a > delimiterseparates two fields.
< c o l o n > terminatorlogical end of line.
<question> terminatorlogical end of line.

MONITOR COMMAND DESCRIPTIONS


The following are descriptions of each of the C128 Machine Language Monitor commands.

COMMAND:
PURPOSE:
SYNTAX:

Enter a line of assembly code.


A <address> <opcode mnemonic> <operand>
<address>
A number indicating the location in memory to
place the opcode. (See 5-digit address note on
previous page.)
<opcode>
A standard MOS technology assembly language
mnemonic, e.g., LDA, STX, ROR.
<operand>
The operand, when required, can be any of the
legal addresses or constants.

A R E T U R N is used to indicate the end of the assembly line. If there are


any errors on the line, a question mark is displayed to indicate an error, and the
cursor moves to the next line. The screen editor can be used to correct the error(s) on
that line.
EXAMPLE:
.A 01200 LDX # $ 0 0
.A 01202
N O T E : A period (.) is equal to the ASSEMBLE command.

EXAMPLE:
.02000 LDA # $ 2 3

H O W T O ENTER MACHINE LANGUAGE PROGRAMS I N T O THE COMMODORE 128

COMMAND:
PURPOSE:
SYNTAX:

COMMAND:
PURPOSE:
SYNTAX:

Compare two areas of memory.


C <address 1> <address 2 > <address 3 >
<address 1>
A number indicating the start address of the area
of memory to compare against,
<address 2 >
A number indicating the end address of the area
of memory to compare against,
<address 3 >
A number indicating the start address of the other
area of memory to compare with. Addresses that
do not agree are printed on the screen.

D
Disassemble machine code into assembly language mnemonics and
operands.
D [ < a d d r e s s > ] [<address 2 > ]
<address>
A number setting the address to start the disassembly.
<address 2 >
An optional ending address of code to be disassembled.

The format of the disassembly differs slightly from the input format of an assembly. The
difference is that the first character of a disassembly is a period rather than an A (for
readability), and the hexadecimal value of the op-code is listed as well.
A disassembly listing can be modified using the screen editor. Make any changes
to the mnemonic or operand on the screen, then hit the carriage return. This enters the
line and calls the assembler for further modifications.
A disassembly can be paged. Typing a D R E T U R N
causes the next page
of disassembly to be displayed.
EXAMPLE:
D3000
.03000
.03002
.03003

COMMAND:
PURPOSE:
SYNTAX:

3003
A9 00
FF
D0 2B

LDA # $ 0 0
77?
BNE $3030

F
Fill a range of locations with a specified byte.
F <address 1> <address 2 > < b y t e >
<address 1>
The first location to fill with the < b y t e > .
<address 2 >
The last location to fill with the < b y t e > .
< b y t e value>
A 1- or 2-digit hexadecimal number to be written.

This command is useful for initializing data structures or any other RAM area.

189

190

COMMODORE 128

EXAMPLE:
F0400 0518 EA
Fill memory locations from $0400 to $0518 with $EA (a NOP instruction).
COMMAND:
PURPOSE:
SYNTAX:

G
Begin execution of a program at a specified address.
G [<address>]
<address>
An address where execution is to start. When
address is left out, execution begins at the current
PC. (The current PC can be viewed using the R
command.)

The GO command restores all registers (displayable by using the R command) and
begins execution at the specified starting address. Caution is recommended in using the
GO command. To return to the Commodore 128 MONITOR after executing a machine
language program, use the BRK instruction at the end of the program.
EXAMPLE:
G 140C
Execution begins at location $140C in configuration (BANK)0. Certain applications may require that Kernal and/or I/O be present when execution begins.
Precede the four-digit hexadecimal number with the hex configuration number
which contains those appropriate portions of memory.)
COMMAND:
PURPOSE:
SYNTAX:

H
Hunt through
set of bytes.
H <address
<address
<address
<data>

memory within a specified range for all occurrences of a


1> <address 2 > < d a t a >
1>
Beginning address of hunt procedure,
2>
Ending address of hunt procedure,
Data set to search for data may be hexadecimal
for an ASCII string.

EXAMPLE:
H A000 A101 A9
Search for data $A9 from A000 to A101.
H2000 9800 'CASH'
Search for the alpha string " C A S H " .
COMMAND:
PURPOSE:
SYNTAX:

J
Jump to a machine language subroutine.
J
<address>

The JUMP to SUBROUTINE command directs program control to the machine language

H O W T O ENTER MACHINE LANGUAGE PROGRAMS I N T O THE COMMODORE 128

subroutine located at the specified address. This command saves the return address as
does the 8502 instruction JSR (Jump to Subroutine). In other words, the JUMP
command is a two-way instruction, where the application gains control of the computer.
Only after the subroutine encounters an RTS instruction does the machine language
monitor regain control.
EXAMPLE:
J 2000
Jump to the subroutine starting at $2000 in configuration 0.
COMMAND:
PURPOSE:
SYNTAX:

L
Load a file from cassette or disk.
L < " f i I e n a m e " > [ , < d e v i c e > [ , a l t load address]]
< " f i l e n a m e " > Any legal Commodore 128 file name,
<device>
A number indicating the device to load from. 1 is
cassette. 8 is disk (or 9, A, etc.).
[alt load address] Option to load a file to a specified address.

The LOAD command causes a file to be loaded into memory. The starting address is
contained in the first two bytes of the disk file (a program file). In other words, the
LOAD command always loads a file into the same place it was saved from. This is very
important in machine language work, since few programs are completely relocatable.
The file is loaded into memory until the end of file (EOF) is found.
EXAMPLE:
L " P R O G R A M " , 8 Loads the file name PROGRAM from the disk.

COMMAND:
PURPOSE:
SYNTAX:

M
To display memory as a hexadecimal and ASCII dump within the
specified address range.
M [<address 1>] [<address 2 > ]
<address 1>
First address of memory dump. Optional. If omitted, one page is displayed. The first digit is the
bank number to be displayed, the next four digits
are the first address to be displayed,
<address 2 >
Last address of memory dump. Optional. If omitted, one page is displayed. The first digit is the
bank number to be displayed; the next four digits
are the ending address to be displayed.

Memory is displayed in the following format:


>1A048 41 42 43 44 45 46 47 48:ABCDEFGH

191

192

COMMODORE 128

Memory contents may be edited using the screen editor. Move the cursor to the data to be
modified, type the desired correction and hit R E T U R N . If a syntax error
or an attempt to modify ROM has occurred, an error flag (?) is displayed. An
ASCII dump of the data is displayed in reverse (to contrast with other data displayed on
the screen) to the right of the hex data. When a character is not printable, it is displayed
as a reverse period. As with the disassembly command, paging down is accomplished by typing M and R E T U R N
EXAMPLE:
M 21C00
>21C00 41 4A 4B 4C 4D 4E 4F 50 :AJKLMNOP
N O T E : The above display is produced by the 40-column editor.

COMMAND:
PURPOSE:

Show important 8502 registers. The status register, the program counter,
the accumulator, the X and Y index registers and the stack pointer are
displayed. The data in these registers is copied into the microprocessor
registers when a " G " or " J " command is issued.

SYNTAX:
EXAMPLE:
R
PC
SR AC XR YR SP
; 01002 01 02 03 04 F6

N O T E : ; (semicolon) can be used to modify register displays in the same


fashion as > can be used to modify memory registers.

COMMAND:
PURPOSE:
SYNTAX:

Save the contents of memory onto tape or disk.


S < " f i l e n a m e " > , < d e v i c e > , < a d d r e s s 1>, <address 2 >
< " f i l e n a m e " > Any legal Commodore 128 filename. To save
the data, the file name must be enclosed in double quotes. Single quotes cannot be used,
<device>
A number indicating on which device the file is
to be placed. Cassette is 01; disk is 08, 09, etc.
<address 1>
Starting address of memory to be saved,
<address 2 >
Ending address of memory to be saved + 1. All
data up to, but not including, the byte of data at
this address is saved.

H O W T O ENTER MACHINE LANGUAGE PROGRAMS I N T O THE COMMODORE 128

The file created by this command is a program file. The first two bytes contain the
starting address <address 1> of the data. The file may be recalled, using the L
command.
EXAMPLE:
S "GAME",8,0400,0C00
Saves memory from $0400 to $OBFF onto disk.

COMMAND:
PURPOSE:
SYNTAX:

T
Transfer segments of memory from one memory area to another.
T <address 1> <address 2 > <address 3 >
<address 1>
Starting address of data to be moved,
<address 2 >
Ending address of data to be moved,
<address 3 >
Starting address of new location where data will
be moved.

Data can be moved from low memory to high memory and vice versa. Additional
memory segments of any length can be moved forward or backward. An automatic
"compare" is performed as each byte is transferred, and any differences are listed by
address.
EXAMPLE:
T1400 1600 1401
Shifts data from $1400 up to and including $1600 one byte higher in memory.

COMMAND.
PURPOSE:
SYNTAX:

V
Verify a file on cassette or disk with the memory contents.
V < " f i l e n a m e " > [ , < d e v i c e > ] [ , a l t start address]
< ' ' f i l e n a m e " > Any legal Commodore 128 file name,
<device>
A number indicating which device the file is on.
Cassette is 01; disk is 08, 09, etc.
[alt start address] Option to start vertification at this address.

The VERIFY command compares a file to memory contents. If an error is found, the
words VERIFY ERROR are displayed; if the file is successfully verified, the cursor
reappears without any message.
EXAMPLE:
V " W O R K L O A D ' ' ,08

193

194

COMMODORE 128

COMMAND:
PURPOSE:
SYNTAX:
COMMAND:
PURPOSE:
SYNTAX:

COMMAND:
PURPOSE:
SYNTAX:

Exit to BASIC.
X
> (greater than)
Can be used to assign values for one to eight memory locations at a time
(in 40-column mode; up to 16 in 80-column mode).
> <address> <data byte 1> <data byte 2 . . . 8 >
<address>
First memory address to set.
<data byte 1>
Data to be put at address,
<data byte 2 . . . 8>Data to be placed in the successive memory
locations following the first address (optional)
with a space preceding each data byte.
@ (at sign)
Can be used to send commands to the disk drive.
@ [<device number>], <disk cmd string>
<device number> Device unit number (optional),
<disk cmd string>String command to disk.

N O T E : @ alone gives the status of the disk drive.


EXAMPLES:
@
@,I

checks disk status


00, OK, 00, 00
initializes drive 8

@,$
@,$0:F*

displays disk directory on unit 8.


display all files on Drive 0, unit 8 starting with the letter F.

As a further aid to programmers, the Kernal error message facility has been automatically enabled, while in the Monitor. This means the Kernal will display T/O E R R O R # '
and the error code, should there be any failed I/O attempt from the MONITOR. The
message facility is turned off when exiting the MONITOR.

MANIPULATING TEXT WITHIN


THE MACHINE LANGUAGE MONITOR
Certain machine language application programs require the manipulation of strings of
characters. If you are using an assembler package, it contains provisions for handling
strings of characters. However, within the monitor, strings of characters must be placed
in memory, either (1) through modifying a memory dump using the screen editor, or (2)

H O W T O ENTER MACHINE LANGUAGE PROGRAMS INTO THE COMMODORE 128

by placing the ASCII values of the characters in memory locations within a program.
To modify a memory dump using the screen editor, issue the M E M O R Y command with the address range in which you want to place the character string information. For example, suppose you want to place the word " T E X T " in memory starting at
location $2000. First, enter the machine language monitor with the MONITOR command. Next, issue the memory command containing the address $2000 as follows:
M 2000
The 128 responds with this display:
02000 FF 00 FF 00 FF 00 FF 00: 7r.TT.7r.TT.
The entire screen is filled with the contents of the memory (dump) locations $2000
through $205F. For illustrative purposes, only one line of the memory dump is shown.
This line pertains to the address range $2000 through $2007. At the right of the screen is
an area that displays the corresponding ASCII character for each value within a memory
location in that line of the memory dump. The left character in the display area
corresponds to location $2000, the second character position to the right pertains to
address $2001, and so on. To place the word " T E X T " in memory starting at location
$2000, move the cursor up to the first line of the memory dump, move the cursor right
to the memory address that pertains to address $2000, and place the ASCII character
string code for the letter T in this position. To do this, type over the characters that are
there and replace them with the hexadecimal equivalent of decimal 84 ($54) and press
RETURN
. Notice that the letter T is now displayed at the right of the screen.
Refer to Appendix E, ASCII and CHR$ Codes, for a list of the Commodore ASCII
codes for each character available in the Commodore 128.
Now do the same procedure for the letters E, X and T. When you are through, the
word " T E X T " is displayed in the display area. The first line of the memory dump now
looks like this:
02000 54 45 58 54 FF 00 FF 00: TEXT 7r. 7r.
Now the character string you wish to manipulate is in memory, starting at address
$2000. Your machine language routine can now act upon the characters of the word
" T E X T " in order to display them on the screen. An efficient way of manipulating
entire words is to use the start address in memory where the text begins, in this case
$2000. Determine the length of the string, and use an index register as an offset to the
end of the word. See the section Raster Interrupt Split Screen Program with Horizontal
Scrolling in Chapter 8, for a working example of manipulating text. This chapter has
described the use of machine language. For additional information on machine language
topics, see Chapter 5, 7, 8, 9, 10, 11, and 13.

195

7
MIXING
MACHINE
LANGUAGE
AND B A S I C

197

198

COMMODORE 128

WHY MIX B A S I C AND


MACHINE LANGUAGE?
Certain application programs are better suited for a high-level language such as BASIC
rather than low-level machine language. In other cases, however, certain portions of a
program, such as displaying graphics, may require the speed of machine language while
the rest of the program lends itself to the use of BASIC. This is the main reason for
mixing BASIC programs with machine language subroutines. Another reason may be
the lack of an alternative in programming machine language. For example, in C64
mode, a machine language monitor is not ordinarily available to the user. In addition,
you may not have an assembler package, so the only alternative is to enter machine
language programs through the BASIC language. This method has disadvantages; it can
be tedious and time-consuming, and once the routine is entered into memory, you have
no way of listing it to the screen for editing. This method is recommended only if no
alternative is available.

ENTERING MACHINE LANGUAGE


SUBROUTINES THROUGH B A S I C
In Chapter 6, you saw an example of how to use the SYS command to go from BASIC
to a machine language routine that cleared the text screen. The SYS command invoked
the subroutine, cleared the screen, and returned to BASIC with the RTS instruction.
This example illustrated the SYS command within a program. You can also SYS to a
machine language subroutine outside a BASIC program, as follows:
SYS 8192
This example assumes you entered the machine language subroutine through the
monitor (and it is still in memory). What if you don't have the monitor available to you,
as in C64 mode, and you want to mix a machine language subroutine with a BASIC
program?
The answer to this is to POKE decimal data that represents the hexadecimal
opcodes and operands into memory. To activate the subroutine, you SYS to it as you did
before. This method of entering machine language programs requires these steps:
1.
2.

3.

Write your machine language program on a piece of paper.


Translate the hexadecimal op-code values into decimal. Some instructions
require 3 bytes of memory, while others only use 1 or 2 bytes of memory. For
a list of hexadecimal opcodes for the 8502 machine language instruction set,
see the 8502 Instruction and Addressing Table, in Chapter 5.
Enter the decimal equivalents of the opcodes into DATA statements in such a
way that a 2-byte instruction, for example, is entered as follows:

MIXING MACHINE LANGUAGE A N D BASIC

1000 DATA 162,0: REM - LDX # $ 0 0 = $A2, $00

4.

The hexadecimal number $A2 represents the 8502 instruction for LDX, which
equals 162 in decimal. The 0 (zero) represents the operand 0, which is
loaded into the X register in the instruction. In hex, 0 is the same as in
decimal, so the second byte of the instruction is the operand value 0. The
hexadecimal opcodes are translated into strings of binary digits (bits), so the
microprocessor can interpret and operate them. This is the true machine
language of the computer at its lowest level.
Once you have translated all the opcodes and operands into decimal, you
must place them in memory. Accomplish this by READing a DATA value in
BASIC and POKEing it into memory in an appropriate address range. For
example, to enter the LDX # $ 0 0 instruction into memory, in C128 mode,
perform the following routine:
10
20
30
40
45
50
60
70
80

ALPHA - 8192
I - 0
DO
READ A
IF A - 9 9 9 THEN EXIT
POKE ALPHA + I,A
I = 1+1
LOOP
PRINT " A L L DATA IS NOW IN M E M O R Y "

1000 DATA 162,0,-999


For C64 mode use this routine:
10
20
40
50
60

ALPHA = 8192
FOR 1 = 0 TO 1
READ A
POKE ALPHA + I,A
NEXT

80 PRINT "ALL DATA IS NOW IN M E M O R Y "

1000 DATA 162,0


The first example, in C128 mode, READs all DATA and POKEs it into
memory, starting at location 8192 ($2000), until a data item is equal to - 9 9 9 .
When the data item equals -999, EXIT the loop and print a message saying
all the data is read into memory at the specified locations. This DO . . .
LOOP allows you to enter as many data items as you please without the need
to know how many data items are in the data list, since it checks for the
terminator value -999. This programming approach makes it easy to modify
the number of data entries without having to change any of the code. This
program assumes that the bit map screen is not being used ($2000-$3FFF).

199

200

COMMODORE 128

5.

The second example, in C64 mode, uses a F O R . . . NEXT loop to


enter the data. This requires you to know how many data items are in the data
list. You can add an IF . . . THEN statement to check for a terminator value
like - 9 9 9 , as in the first example. However, this method illustrates a different
way of accomplishing the same thing.
The final step in entering machine language subroutines through BASIC is
executing the subroutine with the SYS command. Add line 90 to your BASIC
routines above as follows:
90 SYS 8192
This command executes the machine language routine that you POKEd into
memory starting at location 8192.

Although the DATA statement in the example in Step 4 does not show it, all
machine language subroutines must end with an RTS instruction so you can return to
BASIC. The decimal code for an RTS machine language instruction is 96. Your last
decimal data item in the final data statement in your program must be 96, unless you use
a terminator like -999; then - 9 9 9 will be your last decimal data item.
Figure 7-1 shows a step-by-step translation from the machine language screenclear routine as it appears in the monitor and a complete program that mixes the clear
screen routine with the BASIC program that POKEs in the data and executes the
machine language subroutine. It only operates in the 40-column (VIC) screen.

MIXING MACHINE LANGUAGE A N D BASIC

Address

Symbolic
Instruction

Hex Opcode

Decimal Equivalent
1st Byte
(Opcode)

02000
02002
02004
02007
0200A
0200D
02010
02011

A2
A9
9D
9D
9D
9D
E8
D0

02013

60

00
20
00
00
00
E7
F1

04
05
06
06

LDX
LDA
STA
STA
STA
STA
INX
BNE

#$00
#$20
$0400,X
$0500,X
$0600,X
$ 0 6E7,X

=
=
=
=

$2004

RTS

162
169
157
157
157
157
232
208

2nd Byte
3rdByte
(Operand)

0
32
0
0
0
231

4
5
6
6

241

Figure 7-1. Step-by-step Translation into Decimal


To find the hexadecimal opcodes, refer to the 8502 Instruction and Addressing Table in Chapter 5. Notice in Figure 7-1 that the hexadecimal opcodes are displayed
within the monitor, directly to the left of the symbolic instruction. These hexadecimal
numbers are the codes that you translate into decimal data items in a BASIC program.
Notice that the second byte in the BNE instruction is the value 241. ln a branch
instruction, the operand is not an absolute address, but is instead an offset to the
instruction to which it will branch. In this case, the BNE instruction branches backward
to location $2004; therefore, it branches backward 15 locations in memory to the first
store (STA) instruction.
You're probably wondering how the code 241 tells the computer to branch
backward by 15. The number 241 (decimal) is the 2's complement of the value 15.
When bit 7 is enabled, the microprocessor branches backward. The number 241
signifies to branch backward by 15 memory locations and execute the instruction in that
location. To find the root value of a 2's complement number, do this:
1.
2.
3.

Translate the value into binary:


241 = 1111 0001
Subtract 1:
- 1 1 1 1 0000 = 240
Convert each bit to its complement; in other words,
ohange each bit to the opposite value:
= 0000 1111 = 15

To find the two's complement of a number, perform steps 1 and 3 above;


then add 1 to the value instead of subtracting.
Here's the complete C128 mode program, including all the decimal DATA
equivalents of the instructions in the machine language, clear-screen subroutine above:
10 ALPHA=8192
20

1=0

30
40
45
50

DO
:
:
:

60 :

READ A
IF A=-999 THEN EXIT
POKE ALPHA+I,A

I=I+1

7 0 LOOP
80 PRINT"ALL DATA IS NOW IN MEMORY"
8 5 SLEEP 1
90 SYS 8192
1000 DATA 162, 0 , 16 9, 32 , 157 , 0, 4 , 15 7 , 0, 5, 15 7 , 0, 6 , 15 7 , 231 ,6
2000 DATA 232 , 20 8 , 241 , 96 , -999

201

202

COMMODORE 128

Here is the corresponding program in C64:

10 ALPHA=8192
20 FOR 1=0 TO 19
40 :
READ A
50 :
POKE ALPHA+I,A
6 0 NEXT
80 PRINT"ALL DATA IS NOW IN MEMORY"
85 FOR 1 = 1 TO 2500:NEXT
90 SYS 8192
1000 DATA 162,0,169,32,157,0,4,157,0,5,157,0,6,157,231,6
2000 DATA 232,208,241,96

When you run this program, the computer READs the DATA, POKEs it into
memory, and executes the machine language, clear-screen subroutine with the SYS
command. After you RUN the program, enter the machine language monitor (assuming
you are currently in C128 mode) and disassemble the code in the range $2000 through
$2015 with this command:
D 2000 2015
Notice that the subroutine you POKEd in through BASIC is the same as the
subroutine that appears in Figure 7-1. The two different methods accomplish the same
goalprogramming in 8502 machine language.

WHERE T O PLACE MACHINE


LANGUAGE PROGRAMS IN MEMORY
The Commodore 128 has 128K of RAM memory, divided into two 64K RAM banks.
Much of the 128K of RAM is overlaid by ROM, but not at the same time. The
Commodore 128 memory is layered, so RAM is beneath the overlaid ROM. The
designers of the Commodore 128 have managed to squeeze 28K of ROM and 128K of
RAM into 128K of address space. Only one bank is available or mapped in at a time,
since the highest address an 8-bit microprocessor can address is 65535 ($FFFF).
However, because the C128 is capable of banking RAM and ROM in and out so fast, it
may seem as though 128K is always available.
In the portions of memory shared by RAM and ROM, a read operation returns a
ROM data value and a write operation "bleeds through" to the RAM beneath the
layered ROM. The data is stored in the RAM memory location. If the data in RAM
beneath the ROM is a program, the ROM on top must be switched out before the
program in RAM can be executed. The RAM and ROM layout in memory is all
regulated and controlled through the Configuration Register (CR) of the Memory-

MIXING MACHINE LANGUAGE AND BASIC

Management Unit (MMU). For detailed information, refer to the sections on the
Registers of the Memory Management Unit (specifically, the discussion of the Configuration Register) in Chapter 13.

WHERE TO PLACE MACHINE LANGUAGE ROUTINES


IN CONJUNCTION WITH B A S I C
Within BASIC, the operating system takes care of the mapping in and out of ROM and
RAM. The C128 operating system provides sixteen (default) memory configurations.
They each contain different values in the Configuration Register; therefore, each has a
different configuration. This gives you sixteen different configurations of memory to
choose from. Figure 7 - 2 lists the sixteen default memory configurations available under
the control of the BASIC language.

BANK

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

CONFIGURATION

RAM(0) only
RAM(1) only
RAM(2) only
RAM(3) only
Internal ROM, RAM(0), I/O
Internal ROM, RAM(1), I/O
Internal ROM, RAM(2), I/O
Internal ROM, RAM(3), I/O
External ROM, RAM(0), I/O
External ROM, RAM(1), I/O
External ROM, RAM(2), I/O
External ROM, RAM(3), I/O
KernaI and Internal ROM (LOW), RAM(0), I/O
Kernal and External ROM (LOW), RAM(0), I/O
Kernal and BASIC ROM, RAM(0), Character ROM
Kernal and BASIC ROM, RAM(0), I/O

Figure 7 - 2 . Bank Configuration Table

If you want to place a machine language subroutine in memory while the BASIC
language is running, put the subroutine in a bank that contains RAM, preferably bank 0
since this bank is composed entirely of RAM. If you place the machine language
subroutine in a bank other than 0, not all of the RAM is available for programs, since ROM overlays some of the RAM. You must check the value of the
Configuration Register within that bank to see which addresses within these banks
contain ROM. Check the value of the Configuration Register within each of the sixteen
configurations and compare the value with the table in Figure 13-5 to see exactly where
ROM maps in.
Follow this procedure when calling machine language subroutines from BASIC:

203

204

COMMODORE 128

1.

2.

Place the subroutine, preferably in bank 0, either through the monitor or by


POKEing in the code through BASIC. Jf the Kernal, BASIC, and I/O are
required, execute your program from configuration (BASIC Bank) 15. If you
enter the subroutine through the monitor, place the routine in bank 0 by
placing the digit 0 before the 4-digit hexadecimal address where the instructions are stored. If you are POKEing the codes in through BASIC (not the
preferred method), issue the BANK 0 command within your program, assuming you are placing the routine into BANK 0; then POKE in the decimal data
for the opcodes and operands. The recommended memory range to place
machine language routines in conjunction with BASIC is between $1300 and
$lBFF. The upper part of BASIC text is also available, provided your BASIC
program is small and does not overwrite your routine.
Now, to process the rest of your BASIC program, return to bank 15 (the
default bank) with this command:
BANK 15

3.

Now call the subroutine with the SYS command. SYS to the start address
where the first machine language instruction of your program is stored in
memory. In this case, assume the subroutine starts at hex location $2000
(assuming the VIC bit map screen is not used) and enter:
SYS 8192

The RAM in configuration 0 in Figure 7 - 2 is the same RAM that appears in configurations (BANKS) 4, 8, 12, 13, 14, and 15. For example, you can enter programs into
BANK 15, but you must make sure that no ROM overlays your program area.
N O T E : If you plan to return to BASIC, make sure your subroutine ends
with an RTS instruction.

WHERE TO PLACE MACHINE LANGUAGE


ROUTINES WHEN B A S I C IS DISABLED
When you are programming in machine language and you don't require the services of
the BASIC ROM, you can disable BASIC by mapping out the BASIC ROMs. Do this
by placing certain values into the Configuration Register in your own machine language
routines as follows:
LDA # $ 0 E
STA $D501
STA $FF01

;Set up the Configuration Register value


;Write to Preconfiguration Register A
;Write to LCR A to change value of CR

You can use this sequence:


LDA # $ 0 E
STA $FF00
When you switch out BASIC, the sixteen default configurations no longer exist

MIXING MACHINE LANGUAGE A N D BASIC

via the BASIC command, so it becomes your responsibility to manage the memory
configurations by manipulating the Configuration Register in your application program.
Figure 13-5, on page 462, defines the values to place in the configuration register to
arrive at the different memory configurations.
When you switch out the BASIC ROMs, the address range where BASIC usually
resides ($4000 through $7FFF for BASIC low and $8000 through $BFFF for BASIC
high), is available for your machine language programs. Be careful when switching out
the Kernal, since the Kernal controls the entire operation of the C128, including routines
that seem transparent to the user (i.e., routines that you may take for granted).
At certain points within your machine language programs, you may need to
disable the I/O operation of the C128 temporarily. For instance, if you want to copy
portions of the character ROM into RAM when programming your own characters, you
must switch out the I/O registers $D000 through $DFFF of the C128, transfer the
character data into RAM, and then switch the I/O back in.
See the section discussing the Configuration Register, in Chapter 13, for a full
explanation of how the C128 RAM and ROM memory is configured.
This chapter has described the use of BASIC and machine language together. For
material on using BASIC alone, see Chapters 2, 3 and 4. For material on using machine
language see Chapters 5, 6, 8, 9, 10, 11 and 13.

205

8
THE POWER
BEHIND
COMMODORE 128
GRAPHICS

207

208

COMMODORE 128

THE RELATIONSHIP BETWEEN


VIDEO BANKS, RAM BANKS
AND MEMORY CONFIGURATIONS
Many of you are familiar with how the Commodore 64 manages memory. This section
explains how the Commodore 128 manages video memory, and how the video banks
relate to the currently selected memory configuration.

MANAGING BANKED MEMORY


Banking is a process in which a section of memory is addressed by the microprocessor.
The memory is said to be banked in when it is available to the microprocessor in the
current memory configuration.
The Commodore 128 is programmable in its memory configuration. BASIC and
the Machine Language Monitor give you 16 pre-programmed default configurations of
memory (referred to in BASIC as banks). For the purposes of this discussion, BASIC
banks are referred to simply as default memory configurations which are combinations
of ROM and RAM in various ranges of memory. The current configuration, whether in
BASIC or machine language, is determined by the value in the configuration register of
the C128 Memory Management Unit (MMU) chip.
The sixteen different configurations in BASIC and the Machine Language Monitor
require different values to be placed in the configuration register so that particular
combinations of ROM and RAM can be banked into memory simultaneously. For
example, the character ROM is only available in memory configuration 14 (Bank 14 in
BASIC; the fifth digit hexadecimal prefix " E " in the Machine Language Monitor),
since this configuration tells the C128 MMU to swap out the I/O registers between
$D000 and $DFFF, and replace them with the character ROM. To swap the I/O
capabilities back in, change to any configuration number that contains I/O. Figure 8-1
lists the sixteen default memory configurations available in BASIC and the Machine
Language Monitor. Information on programming the MMU is contained in Chapter 13,
The Commodore 128 Operating System.

THE T W O 64K RAM BANKS


The Commodore 128 memory is composed of two RAM banks (labeled 0 and 1), each
having 64K of RAM, giving a total of 128K. The 8502 microprocessor address bus is 16
bits wide, allowing it to address 65536 (64K) memory locations at a time. Figure 8 - 2
illustrates the two separate 64K RAM banks.
Although only 64K can be accessed at one time, the MMU has provisions for
sharing up to 16K of common RAM between the two RAM banks. Common RAM is
discussed in Chapter 13.
The 8502 microprocessor and the VIC chip can each access a different 64K RAM
bank. The 8502 RAM bank is selected by the configuration register (bits 6 and 7) and

THE POWER BEHIND COMMODORE 128 GRAPHICS

BANK

CONFIGURATION

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

RAM(0) only
RAM(1) only
RAM(2) only (same as 0)
RAM(3) only (same as 1)
Internal ROM , RAM(0), I/O
Internal ROM , RAM(1), I/O
Internal ROM , RAM(2), I/O (same as 4)
Internal ROM , RAM(3), I/O (same as 5)
External ROM , RAM(0), I/O
External ROM , RAM(1), I/O
External ROM , RAM(2), I/O (same as 8)
External ROM , RAM(3), I/O (same as 9)
Kernal and Internal ROM (LOW), RAM(0), I/O
Kernal and External ROM (LOW), RAM(0), I/O
KernaI and BASIC ROM, RAM(0), Character ROM
Kernal and BASIC ROM, RAM(0), I/O

Figure 8 - 1 . C I 2 8 Default M e m o r y Configurations

64K

64K

Figure 8 - 2 . C I 2 8 64K R A M Banks

the VIC RAM bank is selected by the RAM configuration register (bits 6 and 7). This
also is covered in detail in Chapter 13.
The configuration determined by the configuration register can be composed of
RAM and ROM, where the ROM portion overlays the RAM layer underneath, as
illustrated in Figure 8-3.

209

210

COMMODORE 128

Write
Operation
(POKE, STA $

).

-READ Operation (PEEK, LDA $----)

ROM

ROM

RAM
65535
memory
Figure 8-3. ROM Overlay

A read (PEEK) operation returns a ROM value, and a write (POKE) operation
bypasses the ROM and stores the value in the RAM underneath.
Many different combinations of memory can be constructed to comprise a 64K
configuration of accessible memory. Bits six and seven of the configuration register
specify which RAM bank lies beneath the ROM layers specified by bits zero through
five. The underlying RAM bank can be switched independently of any ROM layers on
top. For instance, you may switch from RAM Bank 0 to RAM Bank 1, while
maintaining the Kernal, BASIC and I/O.

I6K VIDEO BANKS


In C128 graphics programming, a video bank is a 16K block of memory that contains
the essential portions of memory controlling the C128 graphics system: screen and
character memory. These two types of memory, which are discussed in the following
section, must lie within the 16K range of memory referred to as a (VIC) video bank.
The VIC chip is capable of addressing 16K of memory at any one time, so all graphics
memory must be present in that 16K. Since the Commodore 128 microprocessor
addresses 64K at a time, there are four video banks in each 64K RAM bank, or a total
of eight video banks. (See Figure 8 ^ . )
Where you place the VIC video bank depends on your application program. The
Commodore 128 ROM operating system expects this bank in default video Bank 0, in
the bottom of RAM Bank 0. Screen and character memory may be located at different
positions within each 16K video bank, though in order to successfully program the VIC
chip, the current 16K bank must contain screen and character memory in their entirety.
You'll understand this after reading the next few pages.

THE POWER BEHIND COMMODORE 128 GRAPHICS

video bank 3

video bank 2

video bank 1

video bank 0

3
2

video bank 3
video bank 2

video bank 1

video bank 0

64K

64K

Figure 8 - 4 . Video Banks within R A M Banks

The four video banks in each 64K RAM bank are set up in the memory ranges
specified in Figure 8-5:
BANK

ADDRESS RANGE

0
1
2
3

$0-$3FFF
$4000-$7FFF
$8000-$BFFF
$C000-$FFFF

VALUE OF BITS 1 & 0 IN $DD00


BINARY DECIMAL

11=
10=
01=
00=

3 (DEFAULT)
2
1
0

Figure 8 - 5 . Video Banks M e m o r y Ranges

Each RAM bank (0 and 1) has this memory layout.


Bits 0 and 1 of location $DD00 select the video bank. To select a video bank in
BASIC, type this command:
POKE 56576, (PEEK(56576) AND 252) OR X
Where X is the decimal value of bits 1 and 0 in Figure 8-5.
In machine language, run the following program segment to select video banks:
LDA $DD00; load the accumulator with contents of $DD00
AND # $ F C ; preserve the upper 6 bits of $DD00
ORA # $ X ; where X is the hex value of bits 1 and 0 from Figure 8 - 5 above
STA $DD00; Place the value in $DD00

211

212

COMMODORE 128

In the third instruction, replace X with the hexadecimal value of bits 1 and 0 in
Figure 8-5. The default value is $03, which selects video bank zero.
Whenever you change video banks, you must add $4000 to the address of your
starting screen memory (video matrix) and character memory (bit map in bit map mode)
for each bank above 0. To change to video Bank 1, add $4000 to your starting screen
and character address; for Bank 2 add $8000; for Bank 3 add $C000. You must always
add an offset of $4000 to the start of your screen and character memory for each video
bank that is greater than zero.

SUMMARY OF BANKING CONCEPT


The major features of the banking concept can be summarized as follows:
1.

BASIC and the Machine Language Monitor have sixteen 64K memory configurations that give you sixteen different combinations of memory layouts.
The MMU chip, particularly the value in the configuration register, controls
most of the memory management in the Commodore 128. In order to PEEK
(read) from or POKE (write) to a particular portion of memory, you must
choose a BASIC or monitor configuration that contains the desired section of
memory. Figure 8 - 1 lists the sixteen default memory configurations available
in BASIC and the Machine Language Monitor.

2.

The 128K of memory is divided into two 64K RAM banks. Only one bank is
addressable at a time by the microprocessor. RAM bank selection is controlled by the MMU configuration register (bits 6 and 7), which is part of the
C128 I/O memory. The VIC chip and 8502 microprocessor can each access a
different 64K RAM bank. Figure 8 - 2 illustrates the two separate and independent 64K RAM banks.
Each 64K RAM bank is divided into four 16K video segments. The screen
and character memory must both lie within the selected 16K video segment in
order to successfully display graphics and characters on the screen. For each
16K video bank higher than zero, remember to add $4000 (16384 decimal) to
the start address of screen and character memory. Figure 8^4 shows how four
16K video banks fit into each of the two 64K RAM banks.

3.

Here's how the banks fit together and operate within the Commodore 128. One
64K RAM bank is always mapped into memory. Within BASIC or the Machine
Language Monitor, sixteen different memory configurations are available in a 64K bank.
To change the configuration, issue the BASIC BANK command, or precede the four
digit hexadecimal address in the Machine Language Monitor with an additional hexadecimal digit 0 through F. Outside of BASIC or the monitor, you can select other
configurations, by changing the value in the configuration register at location $FF00
(or $D500). See Chapter 13 for details.
Within the selected configuration, and part of the current 64K RAM bank, is a
16K range reserved for a video bank. The 16K video bank must encompass lK of screen
memory, and either 4K of character ROM or an 8K block of memory for the bit map
data. All these components must be present in order for graphics to operate.

THE POWER BEHIND COMMODORE 128 GRAPHICS

In essence, the bank concept can be thought of in this way: The C128 has a 16K
(VIC) video bank within a selected memory configuration within a 64K RAM bank.
Figures 8-28 through 8-32 at the end of this chapter provides a graphics programming summary.

SHADOW REGISTERS: INTERMEDIATE STORAGE


LOCATIONS USED BY THE CI28 SCREEN EDITOR
Users who are experienced in programming the Commodore 64 VIC chip will find that
most of the graphics operations of the Commodore 128 are performed in the same way
as the C64. The main difference between the Commodore 64 and the Commodore 128
graphics systems is the hardware implementation of split-screen modes.
C128 mode provides two types of split-screen displays:
1.
2.

Standard character mode and bit map mode


Standard character mode and multi-color bit map mode

Because the split-screens switch from one display mode to another at a given
time, the screen editor must be interrupt-driven. The interrupt indicates at what point
the mode is to be switched. At that point, the VIC chip is loaded with preset values
already contained in RAM. These preset values are known as shadow registers. Each
time an interrupt occurs, certain video-chip registers are cleared and refreshed with the
values in the shadow registers. These shadow registers add a variation in programming
the VIC chip compared to the way the Commodore 64 handles it.
The primary intermediate storage locations for VIC chip programming are:

NAME

INDIRECT LOCATION

ACTl AL LOCATION

DESCRIPTION

GRAPHM

BIT 7 - 216 ($00D8)

BIT 4 - 53270 ($D016)

Multicolor Mode Bit

GRAPHM

Bit 6 - 216 ($00D8)

GRAPHM

BIT 5 - 216 ($00D8)

BIT 5 - 53265 ($D011)

Bit Map Mode Bit

VM1*

BITS 7-4 - 2604 ($0A2C)

BITS 7-4 - 53272 ($D018)

Video Matrix (screen memory) Pointer

VM1

BITS 3-0 - 2604 ($0A2C)

BITS 3-0 - 53272 i$D018)

Character Base Pointer

VM2**

BITS 7-4 - 2605 ($0A2D)

BITS 7-4 - 53272 ($D018)

Video Matrix (screen memorv) Pointer

VM2

BITS 3-0 - 2605 ($0A2D)

BITS 3-0 - 53272 ($D018)

Bit Map Pointer

Split Screen Bit

* V M 1 applies o n l y to standard and m u l t i - c o l o r character (text) m o d e s .


* * V M 2 applies o n l y to standard a n d m u l t i - c o l o r bit m a p m o d e s .

213

214

COMMODORE 128

You must store to and load from the indirect locations when accessing the above
features of the VIC (8564) chip. For example, in C64 mode, this is how you set up the
video matrix and bit map mode:
10 POKE 53272, 120: REM Select bit map @ 8192, video matrix @ 7168
20 POKE 53265, PEEK(53265) OR 32: REM Enter bit map mode
Line 10 sets the video matrix at 7168 ($1C00) and the bit map at 8192 ($2000).
Line 20 enables bit map mode.
Normally, you would perform this operation with the high-level, 7.0 BASIC
command:
GRAPHIC 1
The comparable way to accomplish this with POKE commands in C128 mode is
as follows:
10 POKE 2605,120
20 POKE 216,PEEK(216) OR 32
In C128 machine language, use these instructions:
LDA #$78; set bit map @ $2000
STA $0A2D; set video matrix @ 7168
LDA $00D8
ORA # $ 2 0
STA $00D8; select bit map mode
Although these examples do more than just select bit map mode and set up the
video matrix and bit map pointer (such as wait on a video retrace when the raster is off
the visible coordinate plane), these examples give you an idea of how to perform these
programming steps.
As you can see, C128 mode requires a slight variation in programming the VIC
chip. You must keep this in mind when programming graphics in C128 mode. Usually,
the high-level BASIC 7.0 commands take care of these variations. However, if you are
programming in machine language, remember to address these indirect storage locations
and not the actual ones. If you store values directly to the actual registers, the value will
be cleared in a jiffy and no apparent action occurs.

DISABLING THE INTERRUPT DRIVEN


SCREEN EDITOR
You can disable the interrupt-driven C128 screen editor by storing the value 255
($FF) in location 216 ($00D8). The actual VIC registers are not affected, and you
can program the VIC chip the same way as the C64. This makes it unnecessary to
address the indirect shadow registers. In BASIC, enter:
POKE 216,255
In machine language, you enter:

THE POWER BEHIND COMMODORE 128 GRAPHICS

LDA # $ F F
STA $00D8
Since disabling the interrupt allows you to program the VIC chip in the same way
as the Commodore 64, you can store values directly to the actual registers. You do not
have to address the indirect storage locations for VIC chip programming. However, if
you don't disable the interrupt, it is still active and your values will be cleared upon the
first occurrence of the raster interrupt.
Remember, you must either disable the interrupt or address the indirect storage
locations. Failure to do one or the other can cause serious problems in your program.
The 80-column chip indirect memory locations are discussed in Chapter 10,
Programming the 80-Column 8563 Chip. Certain other I/O functions require the use of
indirect locations also. These are covered in Chapter 12, Input/Output Guide.

THE COMMODORE 128


GRAPHICS SYSTEM
This section describes where the SCREEN, COLOR and CHARACTER memory components in the graphics system are located in character modes and bit map modes.
Screen and character memory are addressed and stored differently in the character
modes than in the bit-map modes. The split-screen modes use a section of both the
character screen storage and the bit map screen storage.
In graphics operations, the C128 can operate in either BASIC or machine language
in both C128 and C64 modes.
This section tells you where the graphics locations and screen color character
memory are stored under each graphic mode. The next section details the inner workings
of each graphic display mode including how color and data are assigned and how
screen, color and character memory are interpreted.

SCREEN MEMORY (RAM)


The location in which screen RAM is stored in memory and the way the data are stored
within it depends on the current graphics mode and operational mode of the C128.

CI28 BASIC
In Commodore 128 BASIC, the character screen memory is located in the default address
range 1024 ($0400) through 2023 ($07E7). The text screen memory can be moved.
Remember, certain address6s use indirect memory locations to change the value of the
actual address. The shadow register for the pointer to the text screen memory is location
2604 ($0A2C). The actual location is 53272, but the screen editor uses a shadow since
the VIC screen is interrupt-driven. A direct poke to 53272 ($D018) is changed back to
its original value every sixtieth of a second. Here's how to change the location of screen
memory in C128 BASIC:

215

216

COMMODORE 128

POKE, 2604 (PEEK(2604) AND 15) OR X


where X is a value in Figure 8-6.
If you move the screen memory, make sure that the screen and character memory
do not overlap. In addition, make sure to add an offset of $4000 to the start address of
screen and character memory for each bank above 0. Additional commands are required
to make the program work. Details follow in the discussion of each graphic mode, as
well as program examples.

L O C A T IO N*

BITS

0
16
32
48
64
80
96
112
128
144
160
176
192
208
224
240

ooooxxxx
0001XXXX
0010XXXX
0011XXXX
0100XXXX
0101XXXX
0110XXXX
0111XXXX
1000XXXX
1001XXXX
1010XXXX
1011XXXX
1100XXXX
1101XXXX
1110XXXX
llllXXXX

DECIMAL

0
1024
2048
3072
4096
5120
6144
7168
8192
9216
10240
11264
12288
13312
14336
15360

HEX

$0000
$0400 (DEFAULT)
$0800
$0C00
$1000
$1400
$1800
$1C00
$2000
$2400
$2800
$2C00
$3000
$3400
$3800
$3C00

*Remember that the BANK ADDRESS offset of $4000 per


video bank must be added if changing to a higher video
bank above 0.
Figure 8^>. Screen M e m o r y Locations

This register also controls where character memory is placed in memory. The
upper four bits control the screen, the lower four control character memory. The " A N D
15" in the POKE 2604 statement ensures that the lower nybble is not upset. (If it had
been, you would not see the correct character data.)
In Commodore 128 bit map mode (standard or multi-color), the default bit map
screen memory (video matrix) is located between 7168 ($1C00) and 8167 ($lFFF).
Screen memory is interpreted differently in bit map mode than in text mode. The video
matrix in bit map mode actually supplies color information to the bit map. This is
explained in detail in the Standard Bit Map Mode section elsewhere in this chapter. To
change the location of the bit map screen memory (video matrix), use this command:
POKE 2605, (PEEK(2605) AND 15) OR X

T H E P O W E R B E H I N D C O M M O D O R E 128 G R A P H I C S

where X is a value in Figure 8-6. Location 2605 is also a shadow register for 53272, but
only for bit map mode. When you move the video matrix you must ensure that it does
not overlap the bit map (data). In addition, be sure to add an offset of $4000 to the start
address of the video matrix and the bit map for each video bank above zero.

C64 BASIC
In C64 mode, the text screen defaults to locations 1024 ($0400) through 2023
($07E7). In bit map mode, the video matrix (screen memory) also defaults to this range
though the screen memory is interpreted differently in either mode. Commodore 64
BASIC allows you to move the location of the video matrix to any one of the sixteen
locations specified in Figure 8-6. The upper four bits of location 53272 ($D018) control
the location of the screen memory. To change the location of screen memory, use the
following command:
POKE 53272, (PEEK(53272) AND 15) OR X
where X is equal to one of the values in Figure 8 - 6
NOTE: The following paragraph pertains to both C128 and C64 modes.

Bits zero and one of location 56576 ($DD00) control which of the four video
banks is selected. The default bank is 0. If you change to another video bank (from 0 to
1, for example), then for each bank higher than bank zero, you must add an offset of
$4000 to the starting video matrix (screen memory) address in Figure 8-6. This yields
the actual address of the video matrix. For example, if you're changing from bank 0 to
bank 1, add $4000. If you are going to bank 2, add $8000; if you are changing to bank
3, add $C000. Remember, this is true for both C128 and C64 modes.

MACHINE LANGUAGE
In machine language, use the commands listed underA in Figure 8 - 7 to move the C128
(VIC) text screen. Use the commands underZ? to move the C128 bit map screen memory
(video matrix). Use the commands under C to move the C64 text or bit map screen
memory (video matrix).

(A)

(B)

(C)
MOVE C64

iMOVE C128

MOVE C128

TEXT OR BIT MAP

TEXT SCREEN

BIT MAP SCREEN

SCREEN MEMORY

LDA $0A2C
AND #$0F
ORA#$X
STA $0A2C

LDA $0A2D
AND #$0F
ORA #$X
STA $0A2D

LDA $D018
AND #$0F
ORA #$X
STA $D018

Figure 8-7. Moving Screen Memory in Machine Language

217

218

COMMODORE 128

In Figure 8 - 7 , X is the hexadecimal equivalent of the decimal value X in the left


column in Figure 8-6. The second and third instructions in each example in Figure
8 - 7 make sure not to upset the lower four bits of location 53272 or its shadow registers,
2604 ($0A2C) and 2605 ($0A2D), since they control the character data for text and bit
map modes.

COLOR RAM
CI28 BASIC
Color RAM within the Commodore 128 is always stationary in memory. It occupies the
address range 55296 ($D800) through 56295 ($DBE7). In standard character mode,
screen RAM and color RAM correspond to one another on a one-to-one basis. Location
1024 gets color data from 55296, 1025 gets color from 55297 and so on. Multi-color
character mode utilizes color RAM also, but in a different manner. Additional explanations and examples are provided in the Standard Character Mode section of this chapter.

COLOR RAM BANKING


In C128 mode, the LORAM and HIRAM signal lines allow the graphics system to
make use of an additional Color RAM bank, which is not available in C64 mode. This
allows fast and clean switching of colors for the character or multi-color bit map screen.
The LORAM signal line allows the 8502 microprocessor to access one color RAM
bank, while the HIRAM control line allows the VIC chip to access either Color RAM
bank independently of the microprocessor. Bit 0 of location 1 controls the LORAM
signal line. LORAM selects color RAM bank 0 or 1 as seen by the 8502 microprocessor
depending on the value of the bit. If the bit value is low, the color RAM bank 0 is
accessed by the 8502. If the value of the bit is high, the upper color RAM bank is
accessed by the 8502 microprocessor.
Bit 1 of location 1 controls the HIRAM signal line. HIRAM selects color RAM
bank 0 or 1 as seen by the VIC chip, depending on the value of the bit. If the bit value is
low, the color RAM bank 0 is accessed by the VIC chip. If the value of the bit is high,
the upper color RAM bank 1 is accessed by the VIC chip.
These control lines add flexibility to the already powerful C128 graphics system.
This allows you to change colors of the multi-color bit map or character screen on the fly,
without any time delay. It allows you to swap color RAM banks instantly.
In standard bit map mode, color information is obtained from the bit map
screen memory (the video matrix, $1C00 through $lFFF), not color memory. Bit
map mode interprets screen memory differently than character mode. Color RAM
is used in standard character mode, multi-color bit map mode, multi-color character
mode and the split-screen mode.

C64 BASIC
In standard character mode, color RAM is located in the same place as in C128 mode:
55296 ($D800) through 56295 ($DBE7).
In bit map mode, C64 BASIC receives color information from screen memory (the

THE POWER BEHIND COMMODORE 128 GRAPHICS

video matrix) as does C128 mode, though the default location for screen memory is
1024 ($0400) through 2023 ($07E7).

MACHINE LANGUAGE
In machine language or in BASIC, standard character mode color data always comes
from the same place. Color RAM is used for multi-color character mode. In
standard bit map mode, however, color data originates from screen memory, so wherever you place screen memory, the color data for the bit map comes from the specified
screen memory (video matrix) range. Multi-color bit map mode receives color from three
places: color RAM, screen memory and background color register 0. This is explained in
depth in the sections on the multi-color character and multi-color bit map modes.

CHARACTER MEMORY (ROM)


CI28 BASIC-CHARACTER MODES
In standard character mode, character information is stored in the character ROM in the
memory range 53248 ($D000) through 57343 ($DFFF). In location 1 of the Commodore 128 memory map, the CHAREN (CHARacter ENable) signal determines whether
the character set is available in any given video bank (0-3). Bit 2 of location 1 is the
CHAREN bit. If the CHAREN bit is high (1), the Commodore character set is not
available within the currently selected video bank in context. If the value of bit 2 in
location 1 is low, equal to zero, then the C128 character set is available in the currently
selected video bank. This is true in any of the four video banks in both 64K RAM
banks. This feature allows the Commodore 128 character set to be available in any video
bank at any time. To read the character ROM, enter BANK 14 either in BASIC or the
MONITOR, and read the ROM, starting at location 53248. This configuration switches
out I/O, and maps in character ROM in the range $D000 through $DFFF. Figure 8 - 8
shows how the character sets are stored in the character ROM:

ADDRESS
BLOCK

DECIMAL

53248
53760
54272
54784
55296
55808
56320
56832

vic*
HEX

IMAGE

CONTENTS

D000-D1FF
D200-D3FF
D400-D5FF
D600-D7FF
D800-D9FF
DA00-DBFF
DC00-DDFF
DE00-DFFF

1000-11FF
1200-13FF
1400-15FF
1600-17FF
1800-19FF
1A00-1BFF
IC00-1DFF
1E00-1FFF

Upper case characters


Graphics characters
Reversed upper case characters
Reversed graphics characters
Lower case characters
Upper case & graphics characters
Reversed lower case characters
Reversed upper case & graphics
eharaeters

* = in C64 mode only

Figure 8-8. Breakdown of Character Set Storage in Character ROM

219

220

COMMODORE 128

The character memory is relocatable as is screen memory. To move standard


character memory in C128 BASIC, alter the lower four bits (nybble) of location 2604
($0A2C). Location 2604 is a shadow register for 53272 for the text screen memory
(upper four bits) and character memory (lower four bits). To move the standard
character memory use the following command:
POKE 2604, (PEEK(2604) AND 240) OR Z.
where Z is a value in Figure 8-9.

LOCATION

OF C H A R A C T E R

MEMORY

VALUE
OFZ

BITS

DECIMAL

HEX

0
2
4

xxxxooox
XXXX001X
XXXX010X

0
2048
4096

$0000-$07FF
$080a-$0FFF
$1000-$17FF

6
8
10
12
14

XXXX011X
XXXX100X
XXXX101X
XXXX110X
XXXXlllX

6144
8192
10240
12288
14336

$1800-$lFF
$2000-$27FF
$2800-$2FFF
$3000-$37FF
$3800-$3FFF

ROM IMAGE in BANK 0 & 2


(defauIt)*
ROM IMAGE in BANK 0 & 2*

* = in C64 mode only.


Figure 8 - 9 . Character M e m o r y Locations

As with the other graphic system components, character data behaves differently in
bit map mode than in text mode.
Remember, the upper nybble controls where the screen memory maps in, so make
sure not to upset those bits. The AND 240 in the POKE statement above takes care of
preserving the upper four bits.
In C128 mode the character sets are available in all video banks depending on the
value of CHAR ENable

NOTE: Remember to add an offset of $4000 to the start address of


character memory, for each bank above 0; i.e., for bank 3 add
3*$4000 = $C000

THE POWER BEHIND COMMODORE 128 GRAPHICS

CI28 BASIC-BIT MAP MODES


In bit map mode, the character memory data, also referred to as the bit map, defaults to
the range 8192 ($2000) to 16191 ($3F3F). The bit patterns of these 8000 bytes tell the
computer which pixels to turn on. This block of memory " m a p s o u t " the picture on the
screen, according to the data in this 8000-byte block. Since the standard bit map screen
is 320 x 200, 64000 pixels make up the screen image. Divide 64000 by 8 to arrive at
8000 bytes of memory for the bit map.
Besides the upper four bits for the video matrix, bit 3 of location 2605 ($0A2D) is
the only significant bit in bit map mode. Location 2605 is the indirect memory location
of 53272 for bit map mode only.
When you issue the G R A P H I C 1 command, bit 3 in 2605 is set. This specifies
the bit map (data) to start at location 8192 ($2000). Whenever you enter bit map mode
with the GRAPHIC command, bit 3 is always set. Outside of BASIC, you can specify
the bit map to start at location $0000; therefore, the value of bit 3 is zero.
If the C128 is running under the control of C128 BASIC, the bit map always starts
on a boundary of $2000 (since bit 3 is set) within a given video bank. In video bank
zero, the bit map starts at $2000. For banks 1, 2 and 3, the bit map begins at $6000,
$A000 and $E000, respectively, since you must add an offset of $4000 for each bank
number above zero. In machine language, however, bit 3 may have a value of zero or
one. Therefore the bit map may start at $0000 if bit 3 is zero, or at $2000 if bit 3 is one,
in each video bank. This means that the bit map has eight possible starting locations
(per 64K RAM bank) in machine languagetwo for each of the four video banks. In
C128 BASIC, the bit map can only start at one of the four locations.
Don't forget to add the mandatory $4000 offset for each video bank above 0. The
eight possible starting locations of a bit map in a machine language program are shown
in Figure 8 - 1 0 .
This gives you the choice of eight starting locations in which to place your bit map
data. Though only one bit map can fit in each video bank, you must leave room for the
video matrix. Since the C128 has two RAM bankseach with four video banks per
RAM bankyou may have a total of eight bit maps in memory, one for each video
bank. Each video bank can fit only one bit map, because you need l K for screen RAM,
and 8K for the bit map since a video bank has a maximum of 16K. To access another bit
map, you must switch video banks. To access a bit map in the upper RAM bank (1),
you may have to switch RAM banks and video banks.

VIDEO BANK

0
1
2
3

VALUE OF BIT 3 =

0
$0000
$4000
$8000
$C000

1
$2000
$6000
$A000
$E000

Figure 8-10. Starting Locations for Bit Map in Machine Language

221

222

COMMODORE 128

C64 BASIC-CHARACTER MODES


In standard character mode in C64 BASIC, the lower four bits of location 53272 control
where character memory is placed. As in C128 mode, the character ROM is actually
mapped into memory between 53248 ($D000) and 57343 ($DFFF). The ROM image
appears in RAM in the range 4096-8191 (in video bank 0) and 3 6 8 6 4 ^ 0 9 5 9 in bank 2,
since it must be accessible to the VIC chip in a 16K range in video banks 0 and 2. The
character sets are not accessible in video banks 1 and 3. This ROM imaging in RAM
applies only to character data as seen by the VIC chip. These memory ranges are still
usable for data and programs and have no effect on the contents of RAM as far as your
programs are concerned.
In C64 mode, the ROM image overlays the RAM underneath. A write operation
"bleeds through" to the RAM underneath, while a read returns a ROM value depending
on which memory configuration is currently in context. Since the VIC chip accesses
16K at a time, the character set images must appear in the 16K which the VIC chip is
currently addressing in video banks 0 and 2. Remember, in C128 mode, the character
sets are available in all video banks according to the value of the CHAREN bit in
location 1.
You can change the location of character memory with the following command:
POKE 53272, (PEEK(53272) AND 240) OR Z
where Z is a decimal value in the table in Figure 8-9.
The breakdown of the character sets is the same as in the C128 for the character
ROM (see Figure 8-8).

C64 BASIC BIT MAP MODE


In bit map mode, bit 3 of location 53272 specifies the start of the bit map either at
$0000 or $2000 depending whether the value of bit 3 is 0 or 1, respectively. Use the
following command:
POKE 53272 (PEEK (53272) AND 240) OR Z
where Z is zero if you want the bit map to start at $0000 in each bank, or Z = 8 if you
want to place the bit map starting at 8192 ($2000) in each video bank.
See Figure 8-10 for the arrangement of the bit map in each of the four 16K video
banks within the two RAM banks. If you switch video banks, don't forget to add the
$4000 (hex) offset for each bank above 0. See the Character Memory section under
C128 Bit Map Mode in the last section for more detail on the arrangement of bit maps in
memory.

THE POWER BEHIND COMMODORE 128 GRAPHICS

MACHINE LANGUAGE
There are three ways to select the placement of character memory, as shown in Figure
8-11. Example A places character memory using the shadow register $0A2C in place of
the actual $D018 register. Example B specifies the start of the bit map at $2000 (using
shadow register $0A2D). Example C specifies the start of the C64 bit map or character
memory.

LDA $02AC
AND #$F0
ORA #$Z
STA $02AC

LDA $02AD
AND #$F0
ORA #$08
STA $02AD

LDA $D018
AND #$F0
ORA #$Z
STA $D018

Figure 8-11. Selected Character Memory Location

In Figure 8-11, Z is a value in the table in Figure 8-9.

STANDARD CHARACTER MODE


HOW T O ENTER STANDARD
CHARACTER MODE
The C128 powers up in standard character mode. This mode displays characters on the
default screen. The character is displayed in a single color on a single color background.
This is the mode in which you write (enter) programs. When you press RUN/STOP and
RESTORE, the C128 defaults to the text screen.
Location 53265 (and its shadow register $00D8) determine whether the C128 is
operating in standard character mode. If bit 5 is 0, as it is on power-up, the C128 is in
character mode; otherwise it is in bit map mode.
Location 53270 (and its shadow register $00D8) determine whether the characters
are standard (single color) or multi-color. Bit 4 of 53270, and the shadow bit, bit 7 of
$00D8, specify multi-color mode. If these bits are equal to zero, characters are standard;
otherwise they are multi-color. See the Multi-color Character Mode section for more
details on selecting multi-color character mode.

223

224

COMMODORE 128

SCREEN LOCATION
In standard character mode, the screen memory defaults to the range 1024 ($0400) through
2023 ($07E7). This is relocatable. See the Screen Memory section in the preceding pages.
Since the screen is 40 columns by 25 lines, the text screen requires 1,000 memory
locations to store all of the screen information in memory. The final twenty-four memory
locations in screen memory do not store displayed data; they are used for other purposes.
Each column of every row you see on the screen has its own screen memory location.
The top-left screen location, referred to as HOME, is stored at address 1024 ($0400).
The second screen location marked by the cursor is 1025 ($0401), and so on. Although
the screen you see is constructed in rows and columns, the screen memory within the
computer is stored linearly, starting at 1024 ($0400) and ending at location 2023 ($07E7).
Figure 8-12 shows a screen memory map, so you can visualize how a screen memory
location corresponds to the location on the physical screen of your video monitor.
SCREEN M E M O R Y M A P
COLUMN

10

20

30
1063
*

1024
1064
1104
1144
1184
1224
1264
1304
1344
1384
1424
1464

*-

10

1584
1624
1664
1704
1744
1784
1824
1864
1904
1944
1984
t

2023
Figure 8-12. Screen M e m o r y Map

HOW THE SCREEN MEMORY DATA


IS INTERPRETED
This screen memory range stores whole characters only. The characters are not represented as ASCII character string codes (CHR$). Instead, they are stored in memory as
screen codes as shown in Appendix D. The screen codes and character string codes are

THE POWER BEHIND COMMODORE 128 GRAPHICS

different due to the way they are stored in the character ROM. Notice in Appendix D
that the screen code for an at-sign (@) is 0. The @ is numbered 0 because it is the first
character to be stored in the character ROM. The letter " A " is the second character
ROM; therefore its code is 1. The letter " B " is the third character in the character
ROM, etc. The screen code is actually an index from the starting location of the
character ROM, beginning with zero.
Jf you want to POKE a character directly into screen memory, use the screen code
rather than the ASCII character string (CHR$) code. The same holds true for the
machine language monitor. For example:
POKE 1024,1
places the letter A in the HOME position on the VIC screen. From the monitor, placing
the value 1 in location $0400 (decimal 1024) also displays the letter A in the HOME
position on the VIC screen.

COLOR DATA
In standard character mode, color information comes from color RAM, in the address
range 55296 ($D800) through 56295 ($DBE7). This memory determines the color of the
characters in each of the 1,000 screen locations. The background color of the screen is
determined by the background color register 0 which is location 53281.
The color RAM and the screen RAM locations correspond on a one-to-one basis.
Screen location 1024 pertains to color RAM location 55296; screen location 1025
corresponds to color location 55297, etc. Figure 8 - 1 3 is the color RAM memory map.
The map shows how color RAM corresponds to the locations in screen RAM and the
placement on your video display.
COLOR MEMORY MAP
C0lUMN

10

20
55335

t
55296UlJl
55336
55376
55416
__J
55456
55496
55536
55576
_TI
5i-J55616
1
|
55656
fI
TTj
TI_
55696
n_
;
JI_
55736
j| ;n
||
55776
]
j
55816
{
|
55856
_T
j"
55896
Jl
I
TjZ
55936
TTTI
"
55976
ZT
ZU J
56016
jf
|
'
56056
Jl
56096
J~
'
56136
'
56176
__3
56216
;
56256
7TT
Figure 8-13. Color Memory Map

10 o

56295

225

226

COMMODORE 128

HOW COLOR MEMORY IS


INTERPRETED
The contents of the color RAM locations contains the color codes 0-15. Each color
memory location may have a different color code. The lower four bits (nybble) of
COLOR RAM are significant. Figure 8-14 shows the COLOR RAM color codes:

0 Black
1 White
2 Red
3 Cyan
4 Purple
5 Green
6 Blue
7 Yellow

8 Orange
9 Brown
10 Light Red
11 Dark Gray
12 Medium Gray
13 Light Green
14 Light Blue
15 Light Gray

Figure 8-14. Color Codes^40 Columns

Notice these color code values are one less than the color codes used by the
keyboard and BASIC. If you want to store a value directly into COLOR RAM, store the
values in the table above, not the color codes used by BASIC and the keyboard. For
example:
POKE 55296,1
colors the character in the HOME position white. From the monitor, place the value 1 in
location $D800, and the same results occur.
Remember, these color codes only control the color of the foreground character.
The background color is controlled by background color register 0 (53281). The pixels
that make up the character image are enabled by bits in character memory. If the bit is
enabled, the pixel in the foreground is turned on in the foreground color, and is
therefore controlled by color RAM. If the bits making up the character are turned off,
they default to the color in background color register 0. The combination of on and off
bits makes up the image of the character. The value of these bits determines whether the
color data comes from color RAM or background color register 0. You'll learn more
about character patterns in the next few paragraphs.

CHARACTER MEMORY
In standard character mode, the C128 receives character data from the CHARACTER
ROM. The character ROM is stored in the range 53248 ($D000) through 57343
($DFFF). Since the VIC chip is capable of accessing 16K at a time, the C128 needs a
way to have the character ROM available in the 16K VIC range. In C128 mode, the
character ROM is available in any VIC bank in C128 mode, based on the value of

T H E P O W E R B E H I N D C O M M O D O R E 128 G R A P H I C S

CHAREN. See the chapter set availability in the Character Memory section in the
beginning of this chapter.
In C64 mode the character ROM is available only in banks 0 and 2. This is
accomplished by having a ROM IMAGE of the character ROM (53248-57343) mapped
into memory in place of RAM, in the range 4096-8191 ($1000-$lFFF) in video BANK
0, and 3 6 8 6 4 ^ 0 9 5 9 ($9000-$9FFF) in video BANK 2. In banks 1 and 3, the character
ROM is not available to the VIC chip.
Notice that the range where the character ROM is actually stored (53248-57343)
is also occupied by the I/O registers but not at the same time. When the VIC chip
accesses the character ROM, the character ROM is switched into the currently selected
video bank as a ROM image (in C64 mode only). When the character ROM is not
needed, the I/O registers are available in the usual range. It is important to note the
ROM image applies only to the character data as seen by the VIC chip. The RAM locations where the ROM image maps in are still usable for programs and data. The locations
where the VIC chip looks for the character data are relocatable. See the Character
Memory section elsewhere in this chapter for information on moving character memory.

HOW T O INTERPRET CHARACTER MEMORY


IN STANDARD CHARACTER MODE
Typically, a complete character set contains 256 characters. The C128 contains two sets
of characters, for a total of 2 times 256 or 512 characters. In 40-column (VIC) output,
only one character set is available at a time. Upon power-up, the uppercase/graphics
character set is available through the keyboard. To access the second character set, press
the Commodore key ( & ) and shift key at the same time. The second character set is
composed of the upper- and lowercase/graphics characters.
In character ROM, each character requires eight bytes of storage to make up the
character pattern. Since 256*8 is equal to 2048 bytes or 2K, and since there are two
character sets, the C128 has a total of 4K of character ROM. Figure 8-15 shows where
each character set is stored in the character ROM.

ADDRESS
BLOCK

DECIMAL

53248
53760
54272
54784
55296
55808
56320
56832

HEX

VIC-II
IMAGE

D000-D1FF
D200-D3FF
D400-D5FF
D600-D7FF
D800-D9FF
DA00-DBFF
DC00-DDFF
DE00-DFFF

1000-11FF
1200-13FF
1400-15FF
1600-17FF
1800-19FF
1A00-1BFF
1C00-1DFF
1E00-1FFF

CONTENTS

Upper case characters


Graphics characters
Reversed upper case characters
Reversed graphics characters
Lower case characters
Upper case & graphics characters
Reversed lower case characters
Reversed upper case & graphics
characters

Figure 8-15. Location of Character Sets in Character ROM

227

228

COMMODORE 128

Note that there is really 8K of character ROM4K for C64 mode and 4K for
C128 mode. The system automatically selects the appropriate character ROM for each
mode of operation.
The bit patterns stored in the character ROM have a direct relationship to the
pixels on the screen, where the character is displayed. In memory, each character
requires eight bytes of storage. On the screen, a character is made up of an 8 by 8 pixel
matrix. Think of a character as eight rows of eight pixels each. Each row of pixels
requires one byte of memory, so each pixel requires one bit.
Since a character is an 8 by 8 pixel matrix, each character requires a total of 64
bits or eight bytes. Within each byte, if a bit is equal to 1, the corresponding pixel in
that character position is turned on. If a bit in a character ROM byte is equal to 0, the
corresponding pixel within the character on that screen position is turned off. The
combination of on and off pixels creates the image of the characters on the screen.
Figure 8 - 1 6 demonstrates the correspondence between a character on the screen and the
way it is represented in the character ROM.

60
102
110
110
96
98
60
0
Character on
the Screen

Byte 1 -+
Byte 2 ^
Byte3^
Byte 4 ^
Byte 5 ^
Byte 6 ^
Byte 7 ^
Byte 8 ^

0_ 0 JL 1 1 JL 0 _0
0_ J_ jL V _0 jL JL JO
0_ J_ JL 0_J_ J_ J_ 0
0_ 1 JL 0_ JL JL jL 0_
0 J_ jL 0_ 0_ 0_5 _0
0_ J_ JL 0_ _0_ 0_ jL _0
0 0 JL T J_ jL 0L 0
0 ^cT 0 0 0 0 0 ~0

=
=
=
=
=
=
-

$D000
$D001
$D002
$D003
$D004
$D005
$D006
$D007

Character as
Represented
in Character ROM

Figure 8-16. Relationship of Screen Character to Character ROM.

In Figure 8 - 1 6 , the first eight bytes of character ROM, ($D000-$D007) are equal
to 60,102,110,110,96,98,60 and 0. These decimal numbers are calculated from the
binary value of the eight bytes that pertain to each row of pixels in the character. For
each bit that is equal to one, raise two to the bit position (0-7). For example, the first
byte of character ROM ($D000) is equal to 60, which is calculated by raising two to the
following bit positions:
2 2 + 2 3 + 2 4 + 2 5 = 4 + 8 + 16 + 32 = 60
The bits that are set (on) correspond to pixels that are enabled on the screen in the
foreground color. Bits that are clear correspond to pixels that are disabled, which are
displayed in the background color, according to background color register 0 at location
53281.
The second byte (row of pixels) of the at-sign (@) character is equal to 102
(decimal) and is obtained by the following:

THE POWER BEHIND COMMODORE 128 GRAPHICS

21 + 2 2 + 2 5 + 2 6 = 102
The last byte of the at-sign character is equal to zero, since no bits are set.
Therefore, each pixel on the screen is displayed in the background color. The values of
the binary digits on the right in Figure 8-16 are directly related to the image of the
character as it appears on the screen on the left in Figure 8-16.

ACCESSING CHARACTER ROM


CI28 BASIC
To access character ROM in C128 BASIC, type and run the following program:
10 BANK 14
20 FOR 1=53248
3 0 BANK 15

TO 5 3 2 4 8+7:PRINTPEEK(I);:NEXT

Enter Bank 14, the only BASIC bank where the character ROM is accessible.
Then print the PEEK value of the first eight bytes of the character ROM. When
finished, return to Bank 15.

MACHINE LANGUAGE
To access character ROM in C128 Machine Language, type and run the following
program:

MONITOR
PC

SR AC XR YR

SP

; FB0 0 0 0 0 0 0 0 0 0 0 F6
.
.
.
.
.
.
.
.
.
.
.

01800
01802
01805
01807
0180A
0180D
0180E
01810
01812
01814
01817

A9
8D
A2
BD
9D
E8
E0
D0
A9
8D
60

01
LDA #$01
00 FF STA $FF00
00
LDX #$00
00 D0 LDA $D000,X
40 18 STA $1840,X
INX
07
CPX #$07
F5
BNE $1807
00
LDA #$00
00 FF STA $FF00
RTS

10 SYS 6144
20 FOR 1=6208 TO 6208 +7:PRINTPEEK(I);:NEXT

These machine language and BASIC routines accomplish the same task as the preceding
four-line BASIC program. The first two machine language instructions switch in the
character ROM, and switch out I/O. The next six instructions transfer the first eight

229

230

COMMODORE 128

bytes of character ROM into locations 6208 ($1840) through 6215 ($1847). The last
three instructions switch out the character ROM, replace it with the I/O registers and
return from the machine language subroutine to BASIC.
The BASIC routine activates the machine language subroutine, then prints the
values that were temporarily stored in 6208 through 6215. See Chapter 6, How to
Enter Machine Language Programs, for details on how to input machine language
instructions on the C128.

C64 BASIC
To access character ROM in C64 BASIC, enter and run the following program:

40 POKE 5 6 3 3 4 ,PEEK( 5 6 3 3 4)AND 254


50 POKE 1,PEEK(1) AND 251
80 FOR 1=0 TO 7:POKE 6144+1, PEEK(5 3 2 4 8+I):NEXT
90 POKE 1,PEEK(1) OR 4
105 POKE 5 6 3 3 4 ,PEEK(5 6 3 3 4) OR 1
130 FOR 1=6144 TO 614 4+7:PRINTPEEK(I);:NEXT

Line 40 turns off the interrupt timer. Line 50 switches out I/O and replaces it with
character ROM. Line 80 transfers the first eight bytes of character ROM (53248-53255)
to 6144-6151. Line 90 switches out character ROM, and replaces it with the I/O
registers. Line 105 turns on the interrupt timer. Line 130 prints the first eight character
ROM values that were temporarily stored in 6144 through 6151.
You may need to transfer parts of the character ROM data into RAM if you are
creating your own character set, and you want the remainder to be from the C128
character set. This is covered in more detail later in the chapter. These methods of
looking at the character ROM demonstrate how the character ROM is accessed, what the
patterns of the characters look like and why you would want to access the character
ROM.
The next section explains how to program your own custom characters in C128
mode.

PROGRAMMABLE CHARACTERS
The Commodore 128 has a feature that allows you to redefine the character set into
custom characters of your own. In most cases, you'll want to redefine only a few
characters at most, while obtaining the rest of the character set from the Commodore
128 character ROM.
With programmable characters, you tell the C128 to get character information
from RAM. Usually, characters are taken from the character ROM. If you only want
certain characters, you can choose the ones you want, copy the character patterns into
RAM and leave the rest in ROM. You cannot write to the character data in ROM;
however, the character data placed in RAM can be redefined.
The first step in programming your own characters is to define the image. In the

THE POWER BEHIND COMMODORE 128 GRAPHICS

Standard Character Mode section, you saw how a character on the screen is stored in the
character ROM. Each character requires eight bytes of storage. Each byte corresponds to
a row of pixels on the visible screen within the 8 by 8 character matrix; therefore, eight
rows of pixels make up one character.
This section shows how to customize an uppercase cursive (script) character set
for the letters A through H. Figure 8 - 1 7 shows the design for the uppercase cursive
letter A. The grid in the figure demonstrates how the character appears on the screen
within the 8 by 8 pixel matrix. Each row of the grid determines which bits are on within
the character bit pattern, and, hence, which corresponding pixels are enabled on the
screen. The eight-bit binary strings to the right of the grid are the bit patterns as stored
in RAM. The numbers to the right of the binary strings are the decimal equivalents of
the binary bit patterns. This decimal value is the data you POKE into RAM in order to
display the character.

o
1

0
= 00001110 = 14

- 32

= 01000010 = 6 6

= 10000010 = 130
= 10000100 = 132

- 00010001 = 17
= 00100000

= 10001010 = 138

= 01110001 = 123

Figure 8-17. Design for Cursive letter " A "

The following program creates and displays the upper-case cursive characters A
through H. Enter it into the computer and RUN it. You'll see the letters A through H
change from uppercase block letters to uppercase cursive letters. When you press the
newly defined lettered keys, they are displayed in cursive form.
Line 10 selects the uppercase character set, the set being redefined. Line 20
protects the character set from being overwritten by the BASIC program and prepares a
location in RAM in which to place your character set. The end of user BASIC text and
the top of string storage is moved from 65280 to 12288 (decimal), which substantially
cuts down the size of BASIC programming space. The character set will be placed
beginning at location 12288, but it does not have to be located there. The character set
does have to be within the first 16K of memory unless another bank is selected. The
VIC chip can only access 16K at a time so each video bank consists of 16K of memory.

231

232

COMMODORE 128

10 PRINT CHR$(142) :REM SELECT UPPER CASE


20 POKE5 4 , 48 :POKE5 8 , 48:CLR:REM PROTECT CHAR SET
3 0 BANK 14 :REM SWITCH TO BANK 14 FOR CHARACTER ROM
40 FORI = l TO 511:POKEI + 12 2 88 ,PEEK(1 + 5 3 2 4 8) :NEXT:REM ROM TO RAM TRANSFER
50 BANK 15:REM SWITCH TO DEFAULT BANK
60 POKE 2 60 4, (PEEK(2 60 4 ) AND 240)+12:REM START CHAR BASE AT 12288
70 FORJ=12 2 88TOl2 28 8+71 :REM PLACE CHARACTER DATA IN RAM
8 0 READ A
90 POKEJ,A
100 NEXT J
110 SCNCLR
120 DATA 0,0,0,0,0,0,0,0:REM @
130 DATA 14 , 17 , 3 2 , 66 , 1 30 , 1 3 2 , 1 3 8 , 12 3:REM A
140 DATA 124, 66,66, 124, 66, 81,225,126:REM B
150 DATA 62 , 67 , 130 , 128 , 128 , 128 , 1 31,12 6 :REM C
160 DATA 125 , 98 , 12 5 , 6 5, 65 , 19 3,161 , 254 :REM D
170 DATA 225 , 6 6, 64 , 5 6, 120, 6 5 , 6 6 , 12 4:REM E
180 DATA 127 , 129, 2 , 4 , 14 , 228 , 68,56:REM F
190 DATA 193 , 163 , 253 , 3 3,249 , 65,99 , 190:REM G
20 0 DATA 2 27 , 16 5 , 36 , 36 , 12 6 , 36 , 3 7 , 2 31 :REM H

You can leave yourself more BASIC text area, but to do this you must enter a video
bank higher than zero. This sample program operates in Bank 0. If you place your
character set in a higher video bank, remember to add an offset of 16384 ($4000) to the
start of RAM character memory for each bank above video Bank 0.
The CLR in line 20 clears out memory starting at 12288 because, prior to the
placement of the character set there, the memory locations are filled with random bytes.
The random bytes must be cleared before new character information can be stored.
Line 30 selects BANK configuration 14. This configuration makes the character
ROM visible with a PEEK command or within the machine language monitor, and
temporarily switches out the I/O registers. Both the I/O functions and the 4K character
ROM share the same locations ($D000-$DFFF). Depending on whether bit 0 in the
configuration register (location $FF00) is on or off, the C128 addresses the I/O registers
or the character ROM. Normally the C128 powers up with bit 1 turned off; therefore,
the I/O registers in locations $D000-$DFFF are addressed. The BANK command in line
30 sets bit 0 in location $FF00; therefore, the character ROM in locations 53248-57343
($D000-$DFFF) is addressed. The character ROM is accessed in order to make the
transfer of characters to RAM.
Line 40 makes the actual transfer from ROM to RAM. Since the character ROM is
accessed in line 30, it now begins at location 53248. The first 512 bytes (the uppercase
character set) from the character ROM are POKEd into the 512 bytes of RAM beginning
at location 12288 and ending at 12800. At this point the character set is ready to be
redefined to custom characters.
Line 50 switches the I/O registers back in, meaning the character ROM is no
longer available.
Line 60 specifies the start of the character set base at location 12288. The character
set base can be stored in locations other than 12288. (See the Character Memory section
earlier in this chapter for more information on moving character memory.) Location
2604 is the intermediate memory location that the interrupt-driven C128 screen editor
uses to point to screen and character memory in character mode. You must use this
indirect location to change the value of the actual register that points to the screen and
character memory 53272. If you try to POKE directly to location 53272, the interrupt will

THE POWER BEHIND COMMODORE 128 GRAPHICS

change the value back to the original one within a sixtieth of a second. (You can, however, disable the interrupt-driven screen editor. See the Shadow Register section for details.)
The value (AND 240) or 12 is placed in address 2604 to tell the C128 to point to
character memory in RAM, starting at address 12288. If the value (AND 240) or 8 is
placed into 2604, the character set will begin at 8192 and your BASIC program must be
less than 6K, but the complete 4K of characters can be redefined. If the value (AND 240)
or 14 is placed into that location, the character set starts at 14336. Your BASIC program
then must be less than 2K, since the programmable character set must reside within a
single 16K block, but the BASIC program that creates the characters can be almost 14K.
If a number other than 12 is POKED into 2604, other program lines must be modified.
Lines 70 through 100 start a loop at the beginning of the character base (12288),
read the values from the data statements which define the new characters (lines 120 and
200), and POKE them (line 90) into the locations allocated for the character set base,
starting at location 12288. The value 12288 + 71 in line 70 sets aside seventy-two
storage locations for the data values in lines 120 through 200 for storage in locations
12288 through 12359. When more data statements are added, the value (12288 + 71)
must be increased to 12288 plus the number of data values in the data statements minus
1. For example, if more characters were defined and there were twenty data statements
with eight values in each, then line 70 would read:
70 FOR J - 12288 TO 12288 + (160-1)

MULTI-COLOR CHARACTER MODE


Standard character mode displays text in two colors: the foreground color of the
character as determined by COLOR RAM, and the background color as determined by
background color register 0 at location 53281 ($D021).
Multi-color character mode gives you the ability to display characters in four colors
within an 8 by 8 character matrix. This substantially increases the freedom of using color.
However, the horizontal resolution is only half the resolution of standard character mode
(160*200), since multi-color mode bits and screen pixels are grouped in pairs. This means
that the color definition and pixel density is twice as wide as standard character mode. The
tradeoff in horizontal resolution is compensated for by the increased freedom of using color.

HOW T O ENTER MULTI-COLOR MODE


Location 53270 and its shadow register ($00D8) determine whether the C128 is outputting standard or multi-color characters on the screen. Bit 4 of 53270 and bit 7 of 216
($00D8) control multi-color mode for character and bit map modes. If bit 4 of 53270
(and bit 7 of 216) is equal to 1, multi-color mode is enabled. Otherwise, standard mode
is enabled. Most of the new 7.0 BASIC graphics commands have provisions for multicolor mode. However, if you want to enter multi-color mode with a POKE command, type:
10 POKE 216,255: REM Disable IRQ Editor
20 POKE 53270, PEEK (53270) or 16: REM Select MCM
This enters multi-color mode, either for character mode or bit map mode.

233

234

COMMODORE 128

SCREEN LOCATION
The screen location in multi-color character mode defaults to 1024 ($0400) through 2023
($07E7), the same as standard character mode. The screen memory locations can be
relocated. See the Screen Memory section for details.

HOW SCREEN DATA IS INTERPRETED


In multi-color character mode, the screen data from screen memory is interpreted as
screen codes the same way as in standard character mode. The screen codes are listed in
Appendix D. See the screen data interpretation in the standard character memory
section. The only difference between standard character mode and multi-color character
mode is the way color is assigned to the characters on the screen.

CHARACTER MEMORY LOCATION


The character memory in multi-color character mode, as in standard character mode, is
taken from between 53248 ($D000) and 57343 ($DFF) when I/O is switched out. See
standard character mode for more detailed information on character memory.

HOW CHARACTER MEMORY IS INTERPRETED


IN MULTI-COLOR CHARACTER MODE
Character memory is interpreted virtually the same way in multi-color and in
standard character modes, except for one difference: In standard character mode, if
a bit in the character definition image is on, the pixel corresponding to that bit
is colored in the foreground color as specified by color RAM. If a bit in the character
image in the character ROM is equal to zero, the corresponding pixel on the screen is
colored in the background color, as specified by background color register 0 (location 53281).
In multi-color character mode, color assignments to the pixels that make up the
character on the screen are not in a direct one-to-one relationship to the bits in the
character ROM data patterns. Instead, the bits that make up a character are grouped in
pairs, as shown in figures 8-18, 8-19 and 8-20.

Figure 8-18. "At" Sign (@) Character as It Appears on the Screen

THE POWER BEHIND COMMODORE 128 GRAPHICS

_0_ 0_ J - J_ J_ j _ o _0
0_ 1 X 0 JL X 1 _0_
0_ 1 X _0_x T T 0
0 X 1 0_ _L j _ _j_ 0
0 J_ X 0_ o_ _o_ o_ _0
0_ J_ 1 0 o_ _o_jL 0
0_ _0_T J_ j _ j _ o_ 0
0__0__0__0__o__o _0__0
Figure 8-19. Bit Patterns of the "At" Sign (@) Character as They Appear in
Character ROM

00
01
01
01
01
01
00
00

11
10
10
10
10
10
11
00

11
01
11
11
00
00
11
00

00
10
10
10
00
10
00
00

Figure 8-20. Bit Patterns of the "At" Sign (@) Character as They Are Grouped
in Pairs in Multi-Color Character Mode
The bits are grouped in pairs, since the horizontal resolution is only half as wide in
multi-color mode. The bit pair determines the color assignments for the pixels within the
character on the screen. The following section describes how the colors are assigned in
multi-color character mode.

COLOR DATA
The color of the pixels in a multi-color character originate from four sources, depending
on the bit pairs. Since the bit pairs have four color possibilities, two bits are needed to
represent four values: 00, 01, 10 and 11. In Figure 8-21, the value of the four bit pair
combinations determines the color assignments for the pixels in a multi-color character.

BIT PAIR

00
01
10
11

COLOR REGISTER

LOCATION

Background # 0 color (screen color)


Background #1 color
Background # 2 color
Color specified by the
lower 3 bits in color memory

53281 ($D021)
53282 ($D022)
53283 ($D023)
color RAM

Figure 8-21. Truth Table for Color Data

235

236

COMMODORE 128

If the bit pair equals 00 (binary), the color ofthose two pixels corresponding to the
bit pair are colored by background color register 0 (location 53281 ($D021)). If the bit
pair equals 01 (binary), the pixels are colored by background color register 1 (location
53282 ($D022)). If the bit pair equals 10 (binary), color for those two pixels within the
character are colored from background color register 2 (location 53283 ($D023)).
Finally, if the bit pair from the character pattern equals 11 (binary), those two pixels are
colored from the color specified in the lower three bits (2, 1, 0) of color RAM. Color
RAM is located between 55296 ($D800) and 56295 ($DBE7).
When multi-color character mode is selected, you can still display standard
characters on some screen locations, and display others in multi-color mode. Bit 3 of
each color RAM location determines whether the character is displayed in standard or
multi-color mode. If bit 3 in color RAM is set (1), characters are displayed in
multi-color mode. Ifbit 3 is clear (0), characters are displayed in standard character mode.
This means that in order to display characters in multi-color mode, you must fill color
RAM with a color code greater than 7. The colors greater than 7 (the ones that are
displayed in multi-color mode) are shown in Figure 8-22.

COLOR CODE

COLOR

8
9
10
11
12
13
14
15

Orange
Brown
Light Red
Dark Gray
Medium Gray
Light Green
Light Blue
Light Gray

Figure 8-22. Color Codes

Remember, the multi-color bit (bit 3) must be set to display multi-color characters.
The following program illustrates multi-color character mode.
10

COLOR

20
30
31
32
33
35
37
40
50
60
70
85
90

COLOR 2,1
:REM MULTCLR 1 = WHITE
COLOR 3,2
:REM MULTCLR 2 = RED
FOR I = lT02 5
PRINT "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
NEXT
FOR 1=55296+512 TO 55296+1023:POKE I,7:NEXT:REM PLACE YELLOW IN COLOR RAM
POKE 216, 255:REM DISABLE SCREEN EDITOR
POKE 5 32 7 0 ,PEEK(5 3 27 0) OR 16:REM SET MULTICOLOR BIT
FOR I = lT025
PRINT "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
NEXT
FOR 1=55296 TO 55296+1023:POKE I,14:NEXT:REM FILL COLOR RAM WITH BLUE
GRAPHIC 0:REM RETURN TO STANDARD COLOR

0,1

:REM BKGND

BLACK

Lines 10, 20 and 30 place the color codes for black, white and red into background
color registers 0, 1 and 2, respectively. Lines 31 through 33 print the letters of the

THE POWER BEHIND COMMODORE 128 GRAPHICS

alphabet on the screen twenty-five times. Line 35 fills the last 512 bytes of color RAM
with yellow. Line 37 disables the IRQ VIC screen editor. Line 40 enables multi-color
mode. At this point, all the screen locations corresponding to the color RAM locations
which have a color code greater than or equal to 8 are displayed in multi-color mode.
Since the yellow color code is 7, all the color RAM locations having this code are
placed in standard character mode. The default color for color RAM is code 13 (light
green) for C128 mode, and code 14 (light blue) for C64 mode. Line 85 fills color RAM
with the light blue color code. The multi-color characters displayed on the screen are
red, white and blue on a black background.

EXTENDED BACKGROUND COLOR MODE


The third type of character display mode, extended background color mode, allows you
to display three colors at a time on the text screen. For example, you have the character
color, the background color of the screen, and an additional background color within
each 8 by 8 character matrix. This means you can display a white character with a green
background in the 8 by 8 character matrix, on a black screen background. This mode
offers the use of an additional color in an 8 by 8 character matrix, without any loss in
screen resolution.
There is one sacrifice, however. In extended background color mode, only the
first sixty-four characters of the screen code character set are available. The reason for
this is that bits 6 and 7 determine which color will be selected for the background within
the 8 by 8 pixel character matrix. This only leaves five bits for the computer to interpret
which character is currently on the screen. The highest number you can represent with
five bits is 63. This means only the screen code values between 0 and 63 are available
for display on the screen within extended background color mode.

HOW T O ENTER EXTENDED


BACKGROUND COLOR MODE
Enabling bit 6 of location 53265 selects extended background color mode. Use this
POKE in BASIC:
POKE 53265, PEEK(53265) OR 64
To turn it off, use this POKE:
POKE 53265, PEEK(53265) AND 191

SCREEN LOCATION
The screen location in extended background color mode is the same as the standard
character and multi-color character modes, 1024 ($0400) through 2023 ($07E7). This
screen range can be relocated. See the SCREEN MEMORY section for details.

237

248

C O M M O D O R E 128

HOW T O INTERPRET SCREEN DATA


The data in screen memory is interpreted as screen codes, which are actually the indexes
into the character ROM. Instead of representing the data as ASCII characters, the screen
codes represent the index into the character ROM which provide the ASCII codes. The
first character in character ROM is the at sign (^t); therefore the first screen code, 0, is the
code for the at sign.
Remember, since extended background color mode only uses five bits to determine the screen code value, only the first 64 screen code characters (0-63) are available.

COLOR DATA
The color assignments for the three colors on the screen stem from three sources. Just as
in standard character mode, the foreground color is assigned by COLOR RAM, in the
range 55296 ($D800) through 563295 ($DFE7). As described in the standard character
mode section, each color RAM location has a direct one-to-one correspondence with the
screen memory locations. See the Standard Character Mode section for screen and color
memory maps and an explanation of how the two sections of memory correspond to one
another.
The screen background color is assigned by background color register zero (location
53281 ($D021)). This is the color of the entire screen, on which the foreground and an
additional 8 by 8 character matrix background is placed.
The additional 8 by 8 character matrix background colors are determined by the
value of bits 6 and 7 of the screen code character value. Depending on the value of these
bits, the extended background color (the color within the 8 by 8 character matrix for
each character), comes from one of the four background color registers. Since there are
four choices for the extended background color, the computer needs two bits to
represent the four color choices. Figure 8-23 shows the four-bit combinations and the
corresponding background color registers associated with them.

B A C KG R0 UN D
C H A R A C T E R
RANGE

0-63
64-127
128-191
192-255

C O D E

C 0 LO R

R E G IS T ER

BIT 7

BIT 6

NUMBER

0
0
1
1

0
1
0
1

0
1
2
3

ADDRESS

53281
53282
53283
53284

($D021)
($D022)
($D023)
($D024)

Figure 8-23. Extended Background Color Registers

For example, POKE the screen code for the letter A (1) into screen location 1024.
Now POKE the screen value 65 into screen location 1025. You might expect the
character to be a reverse A, the second character of the second screen code character set.

THE POWER BEHIND COMMODORE 128 GRAPHICS

However, in this mode, you can only represent the first sixty-four characters, since you
only have five bits to represent screen characters. By trying to represent the screen code
65, bit 6 is enabled, which tells the computer to select the background color register 1
(location 53282 ($D022)), and display the same character, but with the extended
background color specified by background color register 1.
Here's a program that illustrates how extended background color mode operates:
5 SCNCLR
10 COLOR 0,1 :REM BKGRD=BLACK
20 COLOR 2,1 :REM MULTICOLOR 1
3 0 COLOR 3,2 :REM MULTICOLOR 2
40 POKE 5 3 284,3:REM BACKGRD COLOR 3
45 POKE 5 3265 ,PEEK(5 3 26 5) OR 64:REM SET EXTENDED BKGRND BIT
50 FOR 1=1024 TO 1256:POKE I,I-102 3:NEXT
60 PRINT:PRINT:PRINT:PRINT

In the program, line 5 clears the screen. Lines 10 through 40 assign colors to the
four background color registers: black, white, red and cyan, respectively. Line 45
enables extended background color mode. Line 50 POKEs 232 characters into screen
memory. Each time sixty-four characters are stored into the screen memory, the same
set of sixty-four characters is POKEd into the next sixty-four screen locations. However,
the next extended background color is displayed. First, the sixty-four characters are
displayed with a black extended background, then a white extended background, then
red, then cyan.

CHARACTER DATA
Character data is interpreted the same way as in standard character mode, except only
the first 64 characters of the screen character set are available. The character data is also
located in the same range as in standard character mode. See standard character mode
for more information on character data.

STANDARD BIT MAP MODE


Standard Bit Map Mode, also referred to as high-resolution mode, offers the ability to
display detailed graphic images in two colors. The resolution of bit map mode is
320 by 200 pixels. In this mode, the C128 no longer operates in terms of characters,
which are 8 by 8 pixel images stored in those complete units at a time. Bit map mode
allows you to address single pixels at a time, therefore exercising a substantial amount
of control over the detail of images on your screen. The smallest unit addressed in the
character display modes is an 8 by 8 pixel character. Standard bit map mode allows you
to address every individual pixel of the possible 64000 pixels that make up an entire
high-resolution screen image. Figure 8-24 shows how that bit-map coordinate plane is
set up.

239

246

COMMODORE 128

X Coordinate
0,0

319,0

Y Coordinate

0,199

319,199

Figure 8-24. Bit Map Screen Coordinates

HOW T O ENTER STANDARD BIT MAP MODE


To enter standard bit map mode, set bit 5 of location 216 ($00D8) (the shadow
register of location 53265 ($D0ll)). When you issue the GRAPHIC l , l command
in C l 2 8 BASIC, bit map mode is enabled and the bit map screen is cleared.
You can also use a POKE command as follows, but you should use the highestlevel commands wherever possible:
POKE 216, PEEK (216) OR 32
This command turns on bit 5 of the GRAPHM register, which is the interface between
the VIC chip and the interrupt-driven C128 screen editor. This indirectly turns on bit 5
in location 53265 and enters bit map mode.
You can disable the interrupt-driven screen editor and select bit map mode directly
with these commands:
POKE 216, 255
POKE 53265, PEEK (53265) OR 32
In C128 mode machine language, use this program sequence:
LDA $00D8
ORA # $ 2 0
STA $00D8
In C64 mode machine language, try this:
LDA $D011
ORA # $ 2 0
STA $D011

THE VIDEO MATRIX


(SCREEN MEMORY) LOCATION
The default location o f t h e C128 video matrix (i.e., the bit map screen memory) is 7168
($1C00) through 8167 ($lFE7).
The default location of the C64 video matrix is 1024 ($0400) through 2023

THE POWER BEHIND COMMODORE 128 GRAPHICS

($07E7). The video matrix can be moved, however. See the Screen Memory section
elsewhere in this chapter for information on relocating the video matrix.

HOW THE VIDEO MATRIX


IS INTERPRETED
ln bit map mode, the video matrix (bit map screen memory) is interpreted differently
than it is in the character display modes. In the character display modes, the screen
memory data is interpreted as screen codes corresponding to the characters in character
ROM. However, in bit map mode, the video matrix data is interpreted as the supplier of
color information for the bit map. The upper four bits (nybble) supply the color
information for the bit map foreground, and the lower nybble supplies the color code for
the bit map background.
The next section explains how pixels on the bit map screen are assigned to either
the foreground color or the background color.

BIT MAP DATA


In bit map mode, the character data, referred to as the bit map, is also interpreted
differently than in the character display modes. The character data is not taken from
character ROM at all. Instead, it is taken from an 8K section of RAM memory, known
as the bit map.
The standard high-resolution screen is composed of 200 rows of 320 pixels, so
that the entire screen is composed of 64,000 pixels. In bit map mode, one bit in memory
is dedicated to an individual pixel on the screen. Therefore 64000 pixels require 64000
bits (or 8000 bytes) of memory to store the entire bit mapped image.
If a bit in memory in the 8000 byte bit map is set, the corresponding pixel on
the screen is enabled, and becomes the color of the foreground as specified in the upper
four bits of the video matrix. If a bit in the bit map is equal to zero, the corresponding
pixel on the screen becomes the color of the background, as specified in the lower four
bits of the video matrix. The combination of on and off bits in the bit map and the
corresponding pixels on the screen define the highly detailed image on the video screen.
The bit map default location in memory ranges from 8192 ($2000) through 16191
($3F3F). This requires 8000 bytes orjust under 8K of memory. The spare bytes are used
for other purposes. Location 53272 determines the location of the video matrix and bit
map in memory. Since the screen editor is running on the IRQ, location 2605 ($0A2D)
is an indirect address you must use to place a value in location 53272 ($D018). The
upper four bits of 53272 determine where the video matrix begins and the lower four
bits determine where the bit map begins. In bit map mode, only bit 3 is significant, so
the bit map is either placed starting at location 0 or location 8192 ($2000) in each video
bank.
If you change to a higher bank number, remember to add an offset of $4000 to the
start of the bit map and the video matrix for each bank number above 0.
The video matrix is relocatable. See the Screen Memory section in the beginning
of the chapter for details on how to move the video matrix.

241

242

COMMODORE 128

The bit map tells the computer which pixels in the foreground to enable on the
screen. Like a road map, it spells out exactly which pixels to turn on (in the foreground)
and off (in the background color) in order to display a picture on the screen. For
example, if the bit map started at location 8192 (the C128 BASIC default) the first
byte of the bit map corresponds to the bit map pixel coordinates 0,0 through 0,7. The
second byte of the bit map, location 8193, corresponds to coordinates 1,0 through 1,7
and so on. See Figure 8-25 to see how the bit map data in locations 8192-16191
correspond to the pixels on the visual screen:
X Coordinate

Figure 8-25. Relationship of Bit Map Data to Screen Pixels


Now you know how bit map mode operates internally within yourC128. However,
you need an easy way to turn on and off pixels in the bit map in order to display
graphics on the screen. The new, high level BASIC 7.0 commands such as DRAW,
CIRCLE, BOX and PAINT allow you to control the turning on and off of bits and their
corresponding screen pixels. The use of the X and Y coordinates on the bit map
coordinate plane easily orient you to displaying graphics. You can display highresolution graphics in other ways, outside of the BASIC 7.0 graphics commands.
This includes using commercial software packages that employ graphics tablets or
joysticks to draw on the screen, writing your own draw routines using a joystick or
paddle, or physically entering data into the bit map (which is painfully tedious and not
recommended).

THE POWER BEHIND COMMODORE 128 GRAPHICS

Another way to display graphics, which involves manipulating bits in the bit map,
is through mathematical equations, using geometry. Several books are available which
offer geometrical equations on how to draw three-dimensional objects and to move them.
Refer to the Suggestions for Further Reading the back of the book for sources on graphics.

COLOR RAM
In standard bit map mode, color RAM is not used since the color information for the bit
map is taken from the upper and lower nybble of screen RAM. Color RAM is used,
however, in multi-color bit map mode.

MULTI-COLOR BIT MAP MODE


Multi-color bit map mode is a combination of standard bit map mode and multi-color
character mode. Multi-color bit map mode allows the display of four colors within an 8
by 8 pixel bit map area. Like multi-color character mode, the horizontal resolution is
only half of the standard bit map mode, though the tradeoff in resolution is compensated
for by the use of two additional colors within an 8 by 8 pixel, bit mapped area.

HOW T O ENTER MULTI-COLOR


BIT MAP MODE
To enter multi-color bit map mode from C128 BASIC, issue the following command:
GRAPHIC 3
You can enter this mode with a POKE command as well. But make use of the
highest level commands available for the easiest programming:
POKE 216, PEEK (216) OR 160
This POKEs the value 160 and turns on the multi-color mode bit 7 (value 128) and
the bit map mode bit 5 (value 32) in the GRAPHM register which interfaces to the C128
interrupt driven screen editor. This indirectly turns on, respectively, bit 4 (multi-color
mode) of location 53270 ($D016), and bit 5 (bit map mode) of location 53265 ($D011).
Bit 5 of location 53265 determines whether the C128 is in bit map mode or
character mode. If bit 5 is equal to 1, bit map mode is enabled. Bit 4 of location 53270
determines whether the C128 is in standard or multi-color mode. If bit 4 is set, the
C128 operates in multi-color mode, regardless of whether it is in character or bit map
mode.
In C64 mode, you can store a value directly to these registers. But in C128 mode,
the GRAPHM intermediate register must be used as a gateway to these actual registers.
Again, this is because the C128 screen editor is interrupt driven, enabling the splitscreen modes for text and simultaneous bit map displays. Since the screen editor is
interrupt driven, an indirect register is used to restore the values that you need to use for

243

244

COMMODORE 128

specific VIC registers. GRAPHM is one such register; therefore, every sixtieth of a
second, the value in the GRAPHM register is loaded into the appropriate VIC registers.

MACHINE LANGUAGE
To select multi-color bit map mode in C128 machine language, perform the following
instructions:
LDA $A0; enables bits 4 and 5 of GRAPHM, the shadow location
STA $00D8
In C64 machine language, enter:
LDA $D011
ORA #$20; select Bit map mode
STA $D011
LDA $D016
ORA #$10; select multi-color mode
STA $D016
In both cases, you must clear the screen, color RAM and the bit map in your own
program.

VIDEO MATRIX LOCATIONS


The video matrix defaults to locations 7168 ($1C00) through 8167 ($lFE7) in C128
mode.
In C64 mode, the video matrix defaults to locations 1024 ($0400) through 2023
($07E7). This is relocatable. See the Screen Memory section earlier in this chapter.

HOW T O INTERPRET THE VIDEO MATRIX


The contents of the video matrix are interpreted the same way as in standard bit map
mode. The upper nybble is the color code for the foreground color; the lower nybble is
the color code for the background color of the bit map.

ADDITIONAL COLOR DATA


The upper and lower nybbles of screen memory supply the multi-color bit map screen
with two of the color sources. This mode offers two additional colorsbackground
color register 0 (location 53281) and the lower nybble of color RAM.
As in multi-color character mode, the bit patterns of the bytes in the bit map
determine the color assignments for the pixels on the screen. The bits are similarly
grouped in pairs, within 8-bit bytes, so there are 4-bit pairs in each byte. Bits 0 and 1, 2
and 3, 4 and 5, and 6 and 7 are grouped in pairs respectively. Depending on the values
of the bit pairs, the corresponding pixels in the bit map are assigned colors from the
sources in Figure 8-26.

THE POWER BEHIND COMMODORE 128 GRAPHICS

BITS

COLOR INFORMATION COMES FROM

00
01
10
11

Background color # 0 (screen color)


Upper four bits of video matrix
Lower four bits of video matrix
Color RAM

Figure 8-26. Multi-Color Bit Map Pixel Color Assignments

THE BIT MAP


Bit patterns determine how color is assigned to the multi-color bit map screen. If the bit
pair is equal to 00 (binary), color is taken from background color register 0 (location
53281). If the bit pair is equal to 01 (binary), the color assigned to these two pixels
comes from the upper nybble of video matrix. If the bit pair in the bit map is equal to
10 (binary), then the color assigned to those two pixels comes from the lower nybble of
video matrix. Finally, if the bit pair in the bit map is equal to 11 (binary), the color is
taken from the lower four bits of color RAM. Unlike multi-color character mode, the
screen is either all standard bit map, or all multi-color bit map, unless you develop a
sophisticated interrupt-driven application program that handles the two separate bit
maps.

COLOR RAM
In multi-color bit map mode, color RAM is used if the bit pair from the bit map equals
11 (binary). Each color RAM location may have one of sixteen color codes, which
means that one 8 by 8 bit map area can have black, red, white and blue colors,
respectively, for the background color register 0, the upper nybble, the lower nybble, and
the color RAM. The 8 by 8 multi-color bit map area next to it can have black, red, white
and green colors, since each color RAM location is independent of any other. The other
three color sources usually remain constant throughout a bit map screen, though you can
change the upper and lower nybbles of the video matrix. The background color register
is almost always the same throughout a bit map screen.
The C128 has powerful and varied graphics display capabilities. Certain applications call for one type of display over another. Experiment with them all and see which
one meets your needs best. Figures 8-28 through 8-32 provide a graphics programming
summary that should be helpful in understanding graphics on the C128.

SPLIT-SCREEN MODES
The Commodore 128 has a split-screen feature that allows you to display the top portion
of the screen in bit map mode and the bottom portion in character mode. This allows you to
enter a BASIC graphics program and RUN it while the BASIC program listing is

245

246

COMMODORE 128

present and the bit map image is displayed, which saves time switching back and forth
between bit map and character modes.
Before, you would have had to enter the graphics program (in machine language),
RUN it and switch back to the text screen to make a change. Now you can display the
graphic image and have your text screen available to you all at the same time. You can
alter the program while your bit map image is still on the screen, RUN it and see the
immediate results without losing the text screen.
Without the Commodore 128's split-screen capabilities, you would have to program a split screen yourself. This involves raster interrupts which utilize either two
screen memories in two different video banks, or a fairly choppy single-screen memory,
usually with a visible raster line. With the C128 split-screen mode, all you have to do to
enter a split-screen mode is to issue the GRAPHIC command in BASIC. For example,
the command:
GRAPHIC 2,1
sets up a standard bit map screen on top and a text screen on the bottom. Similarly, the
command:
GRAPHIC 4,1
constructs a multi-color bit map screen on the top portion of the screen and a text screen
on the bottom portion. The " 1 " in these commands clears the bit map screen. To leave
the bit map screen intact, once you have already displayed an image, replace the " 1 "
with a zero (0).
The GRAPHIC command has an additional parameter that allows you to define
where the split occurs. The split-screen starting location is defined in terms of a
character row, as if the C128 were in a character display mode. For example,
GRAPHIC 4,1,15
selects a split screen with multi-color bit map mode on top of the screen and the text
screen on the bottom, starting at character row 15. If the start of the split screen is not
defined, the C128 defaults the start to line 19.

HOW SPLIT-SCREEN MODES ARE


ORGANIZED IN MEMORY
SCREEN LOCATIONS
The split-screen modes, both multi-color and standard, use two independent screen
memories. The bit map video matrix is taken from the address range 7168 ($1C00)
through 8191 ($lFFF), just as in standard and multi-color bit map modes. The text
portion of the screen takes its screen memory from default character mode screen
locations 1024 ($0400) through 2023 ($07E7), just as in standard and multi-color
character mode. The hidden portions of the screen, the bottom portion of the bit map
screen and the upper portion of the text screen, still store data, but it is invisible
since the other screen memory has overlaid it.

THE POWER BEHIND COMMODORE 128 GRAPHICS

INTERPRETING SCREEN DATA


The text portion of the split screen is interpreted according to the standard character mode
section. The bit map portion, whether standard or multi-color, is interpreted according to the
description in the bit map mode section. Consult the Standard Character Mode, Standard Bit Map
Mode and Multi-color Bit Map Mode sections for information on how screen data is interpreted.

CHARACTER MEMORY LOCATIONS


The split-screen modes also take character data from two independent parts of memory.
The bit map data, referred to simply as the bit map, is taken from the default range 8192
($2000) through 16191 ($3FE7) for both the multi-color and standard bit map mode
portions of the screen.
The character memory for the text portion of the split screen is derived from the
character ROM. The actual character ROM occupies the memory locations 53248
($D000) through 57343 ($DFFF) overlaying the I/O registers. The I/O registers must be
switched out to view the actual character ROM, in bank configuration 14, for example.
For information on how character data is interpreted in standard character, standard bit map and multi-color bit map modes, see the sections describing these modes.
See also the Color RAM Banking section.

COLOR DATA
Each of the standard bit map, multi-color bit map and standard character modes interpret
color differently. See each section for detailed information on color assignments.

MACHINE LANGUAGE
In machine language, you must program a split screen yourself. This is not the easiest of
programming tasks, since it involves raster interrupt processing, which can be tricky. In
C128 mode, bit 6 in the GRAPHM register is the split screen bit. If bit 6 of $0008
(GRAPHM) is set, a split screen is displayed. Otherwise, bit 6 is clear (0) and a single
screen is displayed.
The C64 mode has no corresponding split screen bit. C64 mode is programmed
differently for split screens. See the Raster Interrupt Split-Screen Program at the end of
the chapter to learn how to program a split screen in machine language.
CAUTION: A system crash may occur if the display mode is changed
while the interrupt-driven screen editor is enabled. See the Shadow
Register section for details.

THE INTERRUPT-DRIVEN SCREEN EDITOR


The intermediate memory locations, sometimes referred to in this guide as shadow
registers, are designed specifically for handling the split-screen modes. In order to
provide split-screen modes, the C128 screen editor has to be wedged into the system's
interrupt handling routines.

247

248

COMMODORE 128

Unlike the Commodore 64, the C128 handles interrupts exclusively according to
the raster beam. This has made it necessary to merge the C128 screen editor into the
interrupt request routines (IRQ). The C64 uses interrupt timers which makes interrupt
processing less predictable. By processing the interrupts from the raster beam, the
operating system always knows where and when the interrupt will occur. Timer interrupts made catching a raster interrupt less reliable because the operating system never
knew exactly where an interrupt would occur in relation to the raster beam.
The raster interrupt-driven screen editor made it necessary to use indirect storage
locations for certain registers of the VIC chip and 80-column chip. This way, the
intermediate memory locations refresh the actual video chip registers every sixtieth of a
second, each time the raster beam begins a new scan at the top of the screen. The raster
beam scans the entire screen sixty times a second, so on each pass of the raster beam the
intermediate memory locations refresh the actual VIC chip and 8563 chip registers.

RASTER INTERRUPT
SPLIT SCREEN PROGRAM
WITH HORIZONTAL SCROLLING
This section explains how and provides a program to perform split screen raster
interrupts in machine language. The program is explained as it applies to Commodore
64 mode, but it can be modified to run in Commodore 128 mode.
You already have a way to split the screen in C128 mode with the BASIC
GRAPHIC command. The program provided in this section splits the screen in machine
language in C64 mode. See the figure in the shadow register section to see which
addresses must be changed to make this program work in C128 Mode. A few differences will occur in the timing of the raster. In Commodore 128 mode, all interrupts
occur according to the position of the raster beam as it scans the screen. This is why
shadow registers are necessary for certain graphics locations, since the C128 screen
editor is interrupt driven to allow the split screen modes in BASIC.
The program in this section also scrolls text on the bottom quarter of a standard
character screen, while the top three quarters are displayed in multi-color bit map mode.
The standard character screen resides in video bank 0 ($0400-$07E7) while the multicolor bit map video matrix is stored in video bank 1 starting at $5C00 ($1C00 +
$4000 = $5C00). Every time an interrupt occurs, the program changes video banks,
display modes, the character memory and video matrix pointers. This program supplies
the data that scrolls at the bottom of the screen, but it assumes you have placed an 8000
byte bit map starting at address 8192 ($2000) plus an offset of 16384 ($4000) for the
change of video banks. This makes the absolute start address of the bit map 24576 ($6000).
An 8000 byte bit map is just too large to present in this book. However, the easy
way to place a bit map in this area is as follows:

THE POWER BEHIND COMMODORE 128 GRAPHICS

1.

First start in C128 mode, and enter split screen (multi-color) bit map
mode through BASIC with this command:
GRAPHIC 4,1

2.
3.
4.

Now draw on the screen with the BOX, CIRCLE, DRAW and PAINT
commands either in a program or in direct mode.
When you are finished drawing, enter the machine language monitor either by
pressing the F8 function key or by typing the MONITOR command.
Now transfer the video matrix and bit map from the C128 default locations of
$1C00 through $lFFF and $2000 through $3FFF respectively, to $5C00 through
$5FFF and $6000 through $7FFF respectively. The new start addresses are
the default locations plus an offset of $4000 for both the video matrix and bit
map pointers. The new start of the video matrix is at $5C00 ($1C00 +
$4000). The new bit map begins at address $6000 ($2000 + $4000). This
transfer can be accomplished with a single transfer command within the
machine language monitor as follows:
T 1C00 3FFF 5C00

This command transfers the contents of memory locations $1C00 through $3FFF
to $5C00 through $7FFF. Since the default locations of the video matrix and bit map are
continuous in memory, the transfer can be done with a single command. If the default
addresses of the video matrix and bit map had not been contiguous, two transfers would
have been necessary. See Chapter 6 for details on using the Machine Language Monitor.
Now that you are still within the control of the Machine Language Monitor, begin
entering the machine language instructions in the listing provided in the next few pages.
Start entering the program at address $0C00. The program, including the scrolled data
occupies memory up to address $0DF9, which means the program is a total of 505 bytes,
or almost half a kilobyte (K).
Now save the program you just painstakingly entered with the Monitor Save (S)
command as follows:
S "filename", 08, 0C00, 0DFF
If you have a C128 assembler, create a source file, assemble and load it. If your
assembler allows it, save the program as a binary file.

NOTE: If you have the Commodore 64 Assembler Development System,


create a source file (with start address $0C00), assemble and load it in
C64 mode. Then press the RESET button (not the ON/OFF switch) to enter
C128 mode. Don't worry, your program will still be in memory, but this
time it's in C128 memory. Next enter the Machine Language Monitor
and use the Monitor Save (S) command to make a binary file as described
above.

249

250

C O M M O D O R E 128

Now you are ready to enter C64 mode and run the program with the following
command:
GO 64
Reply to the question " A R E YOU SURE?" by pressing the " Y " key and
RETURN. You are now placed in C64 mode.
At this point, you may say to yourself, "After I just did all that work, why am I
going to waste it by changing modes?"
Actually, you are not wasting any effort. When you GO 64 (or press the reset
button), much of the RAM for machine language programs and data is preserved in
RAM ba